[BACK]Return to gbox.c CVS log [TXT][DIR] Up to [local] / sys / arch / hp300 / dev

Annotation of sys/arch/hp300/dev/gbox.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: gbox.c,v 1.15 2007/01/07 15:13:52 miod Exp $  */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005, Miodrag Vallat
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     18:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     19:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     20:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     21:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     23:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     24:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     25:  * POSSIBILITY OF SUCH DAMAGE.
                     26:  */
                     27: /*
                     28:  * Copyright (c) 1996 Jason R. Thorpe.  All rights reserved.
                     29:  * Copyright (c) 1988 University of Utah.
                     30:  * Copyright (c) 1990, 1993
                     31:  *     The Regents of the University of California.  All rights reserved.
                     32:  *
                     33:  * This code is derived from software contributed to Berkeley by
                     34:  * the Systems Programming Group of the University of Utah Computer
                     35:  * Science Department.
                     36:  *
                     37:  * Redistribution and use in source and binary forms, with or without
                     38:  * modification, are permitted provided that the following conditions
                     39:  * are met:
                     40:  * 1. Redistributions of source code must retain the above copyright
                     41:  *    notice, this list of conditions and the following disclaimer.
                     42:  * 2. Redistributions in binary form must reproduce the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer in the
                     44:  *    documentation and/or other materials provided with the distribution.
                     45:  * 3. Neither the name of the University nor the names of its contributors
                     46:  *    may be used to endorse or promote products derived from this software
                     47:  *    without specific prior written permission.
                     48:  *
                     49:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     50:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     51:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     52:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     53:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     54:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     55:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     56:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     57:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     58:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     59:  * SUCH DAMAGE.
                     60:  *
                     61:  * from: Utah $Hdr: grf_gb.c 1.18 93/08/13$
                     62:  *
                     63:  *     @(#)grf_gb.c    8.4 (Berkeley) 1/12/94
                     64:  */
                     65:
                     66: /*
                     67:  * Graphics routines for the Gatorbox.
                     68:  *
                     69:  * Note: In the context of this system, "gator" and "gatorbox" both refer to
                     70:  *       HP 987x0 graphics systems.  "Gator" is not used for high res mono.
                     71:  *       (as in 9837 Gator systems)
                     72:  */
                     73:
                     74: #include <sys/param.h>
                     75: #include <sys/systm.h>
                     76: #include <sys/conf.h>
                     77: #include <sys/device.h>
                     78: #include <sys/proc.h>
                     79: #include <sys/ioctl.h>
                     80:
                     81: #include <machine/autoconf.h>
                     82: #include <machine/bus.h>
                     83: #include <machine/cpu.h>
                     84:
                     85: #include <hp300/dev/dioreg.h>
                     86: #include <hp300/dev/diovar.h>
                     87: #include <hp300/dev/diodevs.h>
                     88: #include <hp300/dev/intiovar.h>
                     89:
                     90: #include <dev/wscons/wsconsio.h>
                     91: #include <dev/wscons/wsdisplayvar.h>
                     92: #include <dev/rasops/rasops.h>
                     93:
                     94: #include <hp300/dev/diofbreg.h>
                     95: #include <hp300/dev/diofbvar.h>
                     96: #include <hp300/dev/gboxreg.h>
                     97:
                     98: struct gbox_softc {
                     99:        struct device   sc_dev;
                    100:        struct diofb    *sc_fb;
                    101:        struct diofb    sc_fb_store;
                    102:        int             sc_scode;
                    103: };
                    104:
                    105: int    gbox_dio_match(struct device *, void *, void *);
                    106: void   gbox_dio_attach(struct device *, struct device *, void *);
                    107: int    gbox_intio_match(struct device *, void *, void *);
                    108: void   gbox_intio_attach(struct device *, struct device *, void *);
                    109:
                    110: struct cfattach gbox_dio_ca = {
                    111:        sizeof(struct gbox_softc), gbox_dio_match, gbox_dio_attach
                    112: };
                    113:
                    114: struct cfattach gbox_intio_ca = {
                    115:        sizeof(struct gbox_softc), gbox_intio_match, gbox_intio_attach
                    116: };
                    117:
                    118: struct cfdriver gbox_cd = {
                    119:        NULL, "gbox", DV_DULL
                    120: };
                    121:
                    122: int    gbox_reset(struct diofb *, int, struct diofbreg *);
                    123: void   gbox_restore(struct diofb *);
                    124: int    gbox_setcmap(struct diofb *, struct wsdisplay_cmap *);
                    125: void   gbox_setcolor(struct diofb *, u_int);
                    126: int    gbox_windowmove(struct diofb *, u_int16_t, u_int16_t, u_int16_t,
                    127:            u_int16_t, u_int16_t, u_int16_t, int16_t, int16_t);
                    128:
                    129: int    gbox_ioctl(void *, u_long, caddr_t, int, struct proc *);
                    130: void   gbox_burner(void *, u_int, u_int);
                    131:
                    132: struct wsdisplay_accessops     gbox_accessops = {
                    133:        gbox_ioctl,
                    134:        diofb_mmap,
                    135:        diofb_alloc_screen,
                    136:        diofb_free_screen,
                    137:        diofb_show_screen,
                    138:        NULL,   /* load_font */
                    139:        NULL,   /* scrollback */
                    140:        NULL,   /* getchar */
                    141:        gbox_burner
                    142: };
                    143:
                    144: /*
                    145:  * Attachment glue
                    146:  */
                    147: int
                    148: gbox_intio_match(struct device *parent, void *match, void *aux)
                    149: {
                    150:        struct intio_attach_args *ia = aux;
                    151:        struct diofbreg *fbr;
                    152:
                    153:        fbr = (struct diofbreg *)IIOV(GRFIADDR);
                    154:
                    155:        if (badaddr((caddr_t)fbr))
                    156:                return (0);
                    157:
                    158:        if (fbr->id == GRFHWID && fbr->fbid == GID_GATORBOX) {
                    159:                ia->ia_addr = (caddr_t)GRFIADDR;
                    160:                return (1);
                    161:        }
                    162:
                    163:        return (0);
                    164: }
                    165:
                    166: void
                    167: gbox_intio_attach(struct device *parent, struct device *self, void *aux)
                    168: {
                    169:        struct gbox_softc *sc = (struct gbox_softc *)self;
                    170:        struct diofbreg *fbr;
                    171:
                    172:        fbr = (struct diofbreg *)IIOV(GRFIADDR);
                    173:        sc->sc_scode = CONSCODE_INTERNAL;
                    174:
                    175:        if (sc->sc_scode == conscode) {
                    176:                sc->sc_fb = &diofb_cn;
                    177:        } else {
                    178:                sc->sc_fb = &sc->sc_fb_store;
                    179:                gbox_reset(sc->sc_fb, sc->sc_scode, fbr);
                    180:        }
                    181:
                    182:        diofb_end_attach(sc, &gbox_accessops, sc->sc_fb,
                    183:            sc->sc_scode == conscode, NULL);
                    184: }
                    185:
                    186: int
                    187: gbox_dio_match(struct device *parent, void *match, void *aux)
                    188: {
                    189:        struct dio_attach_args *da = aux;
                    190:
                    191:        /* We can not appear in DIO-II space */
                    192:        if (DIO_ISDIOII(da->da_scode))
                    193:                return (0);
                    194:
                    195:        if (da->da_id == DIO_DEVICE_ID_FRAMEBUFFER &&
                    196:            da->da_secid == DIO_DEVICE_SECID_GATORBOX)
                    197:                return (1);
                    198:
                    199:        return (0);
                    200: }
                    201:
                    202: void
                    203: gbox_dio_attach(struct device *parent, struct device *self, void *aux)
                    204: {
                    205:        struct gbox_softc *sc = (struct gbox_softc *)self;
                    206:        struct dio_attach_args *da = aux;
                    207:        struct diofbreg * fbr;
                    208:
                    209:        sc->sc_scode = da->da_scode;
                    210:        if (sc->sc_scode == conscode) {
                    211:                fbr = (struct diofbreg *)conaddr;       /* already mapped */
                    212:                sc->sc_fb = &diofb_cn;
                    213:        } else {
                    214:                sc->sc_fb = &sc->sc_fb_store;
                    215:                fbr = (struct diofbreg *)
                    216:                    iomap(dio_scodetopa(sc->sc_scode), da->da_size);
                    217:                if (fbr == NULL ||
                    218:                    gbox_reset(sc->sc_fb, sc->sc_scode, fbr) != 0) {
                    219:                        printf(": can't map framebuffer\n");
                    220:                        return;
                    221:                }
                    222:        }
                    223:
                    224:        diofb_end_attach(sc, &gbox_accessops, sc->sc_fb,
                    225:            sc->sc_scode == conscode, NULL);
                    226: }
                    227:
                    228: /*
                    229:  * Initialize hardware and display routines.
                    230:  */
                    231:
                    232: const u_int8_t crtc_init_data[] = {
                    233:     0x29, 0x20, 0x23, 0x04, 0x30, 0x0b, 0x30,
                    234:     0x30, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00
                    235: };
                    236:
                    237: int
                    238: gbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr)
                    239: {
                    240:        int rc;
                    241:        u_int i;
                    242:
                    243:        /* XXX don't trust hardware, force defaults */
                    244:        fb->fbwidth = 1024;
                    245:        fb->fbheight = 1024;
                    246:        fb->dwidth = 1024;
                    247:        fb->dheight = 768;
                    248:        if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0)
                    249:                return (rc);
                    250:
                    251:        fb->bmv = gbox_windowmove;
                    252:        gbox_restore(fb);
                    253:
                    254:        /*
                    255:         * Find out how many colors are available by determining
                    256:         * which planes are installed.  That is, write all ones to
                    257:         * a frame buffer location, see how many ones are read back.
                    258:         */
                    259:        if (1 /* fb->planes == 0 */) {
                    260:                volatile u_int8_t *fbp;
                    261:                u_int8_t save;
                    262:
                    263:                fbp = (u_int8_t *)fb->fbkva;
                    264:                save = *fbp;
                    265:                *fbp = 0xff;
                    266:                fb->planemask = *fbp;
                    267:                *fbp = save;
                    268:
                    269:                for (fb->planes = 1; fb->planemask >= (1 << fb->planes);
                    270:                    fb->planes++);
                    271:                if (fb->planes > 8)
                    272:                        fb->planes = 8;
                    273:                fb->planemask = (1 << fb->planes) - 1;
                    274:        }
                    275:
                    276:        diofb_fbsetup(fb);
                    277:        for (i = 0; i <= fb->planemask; i++)
                    278:                gbox_setcolor(fb, i);
                    279:
                    280:        return (0);
                    281: }
                    282:
                    283: void
                    284: gbox_restore(struct diofb *fb)
                    285: {
                    286:        volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva;
                    287:        u_int i;
                    288:
                    289:        /*
                    290:         * The minimal info here is from the Gatorbox X driver.
                    291:         */
                    292:        gb->write_protect = 0x0;
                    293:        gb->regs.interrupt = 0x4;
                    294:        gb->rep_rule = RR_COPY;
                    295:        gb->blink1 = 0xff;
                    296:        gb->blink2 = 0xff;
                    297:
                    298:        /*
                    299:         * Program the 6845.
                    300:         */
                    301:        for (i = 0; i < sizeof(crtc_init_data); i++) {
                    302:                gb->crtc_address = i;
                    303:                gb->crtc_data = crtc_init_data[i];
                    304:        }
                    305:
                    306:        tile_mover_waitbusy(gb);
                    307:
                    308:        /* Enable display */
                    309:        gb->regs.sec_interrupt = 0x01;
                    310: }
                    311:
                    312: int
                    313: gbox_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
                    314: {
                    315:        struct diofb *fb = v;
                    316:        struct wsdisplay_fbinfo *wdf;
                    317:        u_int i;
                    318:
                    319:        switch (cmd) {
                    320:        case WSDISPLAYIO_GTYPE:
                    321:                *(u_int *)data = WSDISPLAY_TYPE_GBOX;
                    322:                break;
                    323:        case WSDISPLAYIO_SMODE:
                    324:                fb->mapmode = *(u_int *)data;
                    325:                if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) {
                    326:                        gbox_restore(fb);
                    327:                        for (i = 0; i <= fb->planemask; i++)
                    328:                                gbox_setcolor(fb, i);
                    329:                }
                    330:                break;
                    331:        case WSDISPLAYIO_GINFO:
                    332:                wdf = (void *)data;
                    333:                wdf->width = fb->ri.ri_width;
                    334:                wdf->height = fb->ri.ri_height;
                    335:                wdf->depth = fb->ri.ri_depth;
                    336:                wdf->cmsize = 1 << fb->planes;
                    337:                break;
                    338:        case WSDISPLAYIO_LINEBYTES:
                    339:                *(u_int *)data = fb->ri.ri_stride;
                    340:                break;
                    341:        case WSDISPLAYIO_GETCMAP:
                    342:                return (diofb_getcmap(fb, (struct wsdisplay_cmap *)data));
                    343:        case WSDISPLAYIO_PUTCMAP:
                    344:                return (gbox_setcmap(fb, (struct wsdisplay_cmap *)data));
                    345:        case WSDISPLAYIO_GVIDEO:
                    346:        case WSDISPLAYIO_SVIDEO:
                    347:                break;
                    348:        default:
                    349:                return (-1);
                    350:        }
                    351:
                    352:        return (0);
                    353: }
                    354:
                    355: void
                    356: gbox_burner(void *v, u_int on, u_int flags)
                    357: {
                    358:        struct diofb *fb = v;
                    359:        volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva;
                    360:
                    361:        if (on)
                    362:                gb->regs.sec_interrupt = 0x01;
                    363:        else
                    364:                gb->regs.sec_interrupt = 0x00;
                    365: }
                    366:
                    367: void
                    368: gbox_setcolor(struct diofb *fb, u_int index)
                    369: {
                    370:        volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva;
                    371:
                    372:        gb->creg_select = index;
                    373:        gb->cmap_red = fb->cmap.r[index];
                    374:        gb->cmap_grn = fb->cmap.g[index];
                    375:        gb->cmap_blu = fb->cmap.b[index];
                    376:        gb->cmap_write = !!index;
                    377:        gbcm_waitbusy(gb);
                    378: }
                    379:
                    380: int
                    381: gbox_setcmap(struct diofb *fb, struct wsdisplay_cmap *cm)
                    382: {
                    383:        u_int8_t r[256], g[256], b[256];
                    384:        u_int index = cm->index, count = cm->count;
                    385:        u_int colcount = 1 << fb->planes;
                    386:        int error;
                    387:
                    388:        if (index >= colcount || count > colcount - index)
                    389:                return (EINVAL);
                    390:
                    391:        if ((error = copyin(cm->red, r, count)) != 0)
                    392:                return (error);
                    393:        if ((error = copyin(cm->green, g, count)) != 0)
                    394:                return (error);
                    395:        if ((error = copyin(cm->blue, b, count)) != 0)
                    396:                return (error);
                    397:
                    398:        bcopy(r, fb->cmap.r + index, count);
                    399:        bcopy(g, fb->cmap.g + index, count);
                    400:        bcopy(b, fb->cmap.b + index, count);
                    401:
                    402:        while (count-- != 0)
                    403:                gbox_setcolor(fb, index++);
                    404:
                    405:        return (0);
                    406: }
                    407:
                    408: int
                    409: gbox_windowmove(struct diofb *fb, u_int16_t sx, u_int16_t sy,
                    410:     u_int16_t dx, u_int16_t dy, u_int16_t cx, u_int16_t cy, int16_t rop,
                    411:     int16_t planemask)
                    412: {
                    413:        volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva;
                    414:        int src, dest;
                    415:
                    416:        if (planemask != 0xff)
                    417:                return (EINVAL);
                    418:
                    419:        src  = (sy * 1024) + sx; /* upper left corner in pixels */
                    420:        dest = (dy * 1024) + dx;
                    421:
                    422:        tile_mover_waitbusy(gb);
                    423:
                    424:        gb->width = -(cx / 4);
                    425:        gb->height = -(cy / 4);
                    426:        if (src < dest)
                    427:                gb->rep_rule = MOVE_DOWN_RIGHT | rop;
                    428:        else {
                    429:                gb->rep_rule = MOVE_UP_LEFT | rop;
                    430:                /*
                    431:                 * Adjust to top of lower right tile of the block.
                    432:                 */
                    433:                src = src + ((cy - 4) * 1024) + (cx - 4);
                    434:                dest= dest + ((cy - 4) * 1024) + (cx - 4);
                    435:        }
                    436:        *(volatile u_int8_t *)(fb->fbkva + dest) =
                    437:            *(volatile u_int8_t *)(fb->fbkva + src);
                    438:
                    439:        tile_mover_waitbusy(gb);
                    440:
                    441:        return (0);
                    442: }
                    443:
                    444: /*
                    445:  * Gatorbox console support
                    446:  */
                    447:
                    448: void
                    449: gboxcninit()
                    450: {
                    451:        gbox_reset(&diofb_cn, conscode, (struct diofbreg *)conaddr);
                    452:        diofb_cnattach(&diofb_cn);
                    453: }

CVSweb