153931Shibler /* 253931Shibler * Copyright (c) 1991 University of Utah. 363151Sbostic * Copyright (c) 1990, 1993 463151Sbostic * The Regents of the University of California. All rights reserved. 553931Shibler * 653931Shibler * This code is derived from software contributed to Berkeley by 753931Shibler * the Systems Programming Group of the University of Utah Computer 853931Shibler * Science Department and Mark Davies of the Department of Computer 953931Shibler * Science, Victoria University of Wellington, New Zealand. 1053931Shibler * 1153931Shibler * %sccs.include.redist.c% 1253931Shibler * 1364472Shibler * from: Utah $Hdr: grf_hy.c 1.2 93/08/13$ 1453931Shibler * 15*65632Sbostic * @(#)grf_hy.c 8.4 (Berkeley) 01/12/94 1653931Shibler */ 1753931Shibler 1853931Shibler #include "grf.h" 1953931Shibler #if NGRF > 0 2053931Shibler 2153931Shibler /* 2253931Shibler * Graphics routines for HYPERION frame buffer 2353931Shibler */ 2456507Sbostic #include <sys/param.h> 2556507Sbostic #include <sys/errno.h> 2653931Shibler 2756507Sbostic #include <hp/dev/grfioctl.h> 2856507Sbostic #include <hp/dev/grfvar.h> 2956507Sbostic #include <hp300/dev/grf_hyreg.h> 3053931Shibler 3156507Sbostic #include <machine/cpu.h> 3253931Shibler 3353931Shibler caddr_t badhyaddr = (caddr_t) -1; 3453931Shibler 3553931Shibler /* 3653931Shibler * Initialize hardware. 3753931Shibler * Must fill in the grfinfo structure in g_softc. 3853931Shibler * Returns 0 if hardware not present, non-zero ow. 3953931Shibler */ 4053931Shibler hy_init(gp, addr) 4153931Shibler struct grf_softc *gp; 4253931Shibler caddr_t addr; 4353931Shibler { 4453931Shibler register struct hyboxfb *hy = (struct hyboxfb *) addr; 4553931Shibler struct grfinfo *gi = &gp->g_display; 4653931Shibler int fboff; 4753931Shibler extern caddr_t sctopa(), iomap(); 4853931Shibler 4953931Shibler if (ISIIOVA(addr)) 5053931Shibler gi->gd_regaddr = (caddr_t) IIOP(addr); 5153931Shibler else 5253931Shibler gi->gd_regaddr = sctopa(vatosc(addr)); 5353931Shibler gi->gd_regsize = 0x20000; 5453931Shibler gi->gd_fbwidth = (hy->fbwmsb << 8) | hy->fbwlsb; 5553931Shibler gi->gd_fbheight = (hy->fbhmsb << 8) | hy->fbhlsb; 5653931Shibler gi->gd_fbsize = (gi->gd_fbwidth * gi->gd_fbheight) >> 3; 5753931Shibler fboff = (hy->fbomsb << 8) | hy->fbolsb; 5853931Shibler gi->gd_fbaddr = (caddr_t) (*((u_char *)addr + fboff) << 16); 5953931Shibler if (gi->gd_regaddr >= (caddr_t)DIOIIBASE) { 6053931Shibler /* 6153931Shibler * For DIO II space the fbaddr just computed is the offset 6253931Shibler * from the select code base (regaddr) of the framebuffer. 6353931Shibler * Hence it is also implicitly the size of the register set. 6453931Shibler */ 6553931Shibler gi->gd_regsize = (int) gi->gd_fbaddr; 6653931Shibler gi->gd_fbaddr += (int) gi->gd_regaddr; 6753931Shibler gp->g_regkva = addr; 6853931Shibler gp->g_fbkva = addr + gi->gd_regsize; 6953931Shibler } else { 7053931Shibler /* 7153931Shibler * For DIO space we need to map the seperate framebuffer. 7253931Shibler */ 7353931Shibler gp->g_regkva = addr; 7453931Shibler gp->g_fbkva = iomap(gi->gd_fbaddr, gi->gd_fbsize); 7553931Shibler } 7653931Shibler gi->gd_dwidth = (hy->dwmsb << 8) | hy->dwlsb; 7753931Shibler gi->gd_dheight = (hy->dhmsb << 8) | hy->dhlsb; 7853931Shibler gi->gd_planes = hy->num_planes; 7953931Shibler gi->gd_colors = 1 << gi->gd_planes; 8053931Shibler 8153931Shibler return(1); 8253931Shibler } 8353931Shibler 8453931Shibler /* 8553931Shibler * Change the mode of the display. 8653931Shibler * Right now all we can do is grfon/grfoff. 8753931Shibler * Return a UNIX error number or 0 for success. 8853931Shibler * Function may not be needed anymore. 8953931Shibler */ 9064472Shibler hy_mode(gp, cmd, data) 9153931Shibler struct grf_softc *gp; 92*65632Sbostic int cmd; 9364472Shibler caddr_t data; 9453931Shibler { 9553931Shibler int error = 0; 9653931Shibler 9753931Shibler switch (cmd) { 9853931Shibler case GM_GRFON: 9953931Shibler case GM_GRFOFF: 10053931Shibler break; 10164472Shibler 10264472Shibler /* 10364472Shibler * Remember UVA of mapping for GCDESCRIBE. 10464472Shibler * XXX this should be per-process. 10564472Shibler */ 10664472Shibler case GM_MAP: 10764472Shibler gp->g_data = data; 10864472Shibler break; 10964472Shibler 11064472Shibler case GM_UNMAP: 11164472Shibler gp->g_data = 0; 11264472Shibler break; 11364472Shibler 11464472Shibler #ifdef HPUXCOMPAT 11564472Shibler case GM_DESCRIBE: 11664472Shibler { 11764472Shibler struct grf_fbinfo *fi = (struct grf_fbinfo *)data; 11864472Shibler struct grfinfo *gi = &gp->g_display; 11965487Sbostic int i; 12064472Shibler 12164472Shibler /* feed it what HP-UX expects */ 12264472Shibler fi->id = gi->gd_id; 12364472Shibler fi->mapsize = gi->gd_fbsize; 12464472Shibler fi->dwidth = gi->gd_dwidth; 12564472Shibler fi->dlength = gi->gd_dheight; 12664472Shibler fi->width = gi->gd_fbwidth; 12764472Shibler fi->length = gi->gd_fbheight; 12864472Shibler fi->bpp = NBBY; 12964472Shibler fi->xlen = (fi->width * fi->bpp) / NBBY; 13064472Shibler fi->npl = gi->gd_planes; 13164472Shibler fi->bppu = fi->npl; 13264472Shibler fi->nplbytes = fi->xlen * ((fi->length * fi->bpp) / NBBY); 13364472Shibler bcopy("A1096A", fi->name, 7); /* ?? */ 13464472Shibler fi->attr = 0; /* ?? */ 13564472Shibler /* 13664472Shibler * If mapped, return the UVA where mapped. 13764472Shibler */ 13864472Shibler if (gp->g_data) { 13964472Shibler fi->regbase = gp->g_data; 14064472Shibler fi->fbbase = fi->regbase + gp->g_display.gd_regsize; 14164472Shibler } else { 14264472Shibler fi->fbbase = 0; 14364472Shibler fi->regbase = 0; 14464472Shibler } 14564472Shibler for (i = 0; i < 6; i++) 14664472Shibler fi->regions[i] = 0; 14764472Shibler break; 14864472Shibler } 14964472Shibler #endif 15064472Shibler 15153931Shibler default: 15253931Shibler error = EINVAL; 15353931Shibler break; 15453931Shibler } 15553931Shibler return(error); 15653931Shibler } 15753931Shibler #endif 158