[BACK]Return to zx.c CVS log [TXT][DIR] Up to [local] / sys / dev / sbus

Annotation of sys/dev/sbus/zx.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: zx.c,v 1.13 2007/03/13 19:40:49 miod Exp $    */
                      2: /*     $NetBSD: zx.c,v 1.5 2002/10/02 16:52:46 thorpej Exp $   */
                      3:
                      4: /*
                      5:  * Copyright (c) 2003, Miodrag Vallat.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     19:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     20:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     21:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     22:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     23:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     25:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     26:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     27:  * POSSIBILITY OF SUCH DAMAGE.
                     28:  *
                     29:  * Derived from NetBSD syssrc/sys/dev/sbus/zx.c under the following licence
                     30:  * terms:
                     31:  *
                     32:  *  Copyright (c) 2002 The NetBSD Foundation, Inc.
                     33:  *  All rights reserved.
                     34:  *
                     35:  *  This code is derived from software contributed to The NetBSD Foundation
                     36:  *  by Andrew Doran.
                     37:  *
                     38:  *  Redistribution and use in source and binary forms, with or without
                     39:  *  modification, are permitted provided that the following conditions
                     40:  *  are met:
                     41:  *  1. Redistributions of source code must retain the above copyright
                     42:  *     notice, this list of conditions and the following disclaimer.
                     43:  *  2. Redistributions in binary form must reproduce the above copyright
                     44:  *     notice, this list of conditions and the following disclaimer in the
                     45:  *     documentation and/or other materials provided with the distribution.
                     46:  *  3. All advertising materials mentioning features or use of this software
                     47:  *     must display the following acknowledgement:
                     48:  *         This product includes software developed by the NetBSD
                     49:  *         Foundation, Inc. and its contributors.
                     50:  *  4. Neither the name of The NetBSD Foundation nor the names of its
                     51:  *     contributors may be used to endorse or promote products derived
                     52:  *     from this software without specific prior written permission.
                     53:  *
                     54:  *  THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     55:  *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     56:  *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     57:  *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     58:  *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     59:  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     60:  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     61:  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     62:  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     63:  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     64:  *  POSSIBILITY OF SUCH DAMAGE.
                     65:  */
                     66:
                     67: /*
                     68:  * Driver for the Sun ZX display adapter.  This would be called 'leo', but
                     69:  * NetBSD/amiga already has a driver by that name.  The XFree86 and Linux
                     70:  * drivers were used as "living documentation" when writing this; thanks
                     71:  * to the authors.
                     72:  */
                     73:
                     74: #include <sys/param.h>
                     75: #include <sys/systm.h>
                     76: #include <sys/device.h>
                     77: #include <sys/ioctl.h>
                     78: #include <sys/malloc.h>
                     79: #include <sys/mman.h>
                     80: #include <sys/tty.h>
                     81: #include <sys/conf.h>
                     82:
                     83: #include <uvm/uvm_extern.h>
                     84:
                     85: #include <machine/autoconf.h>
                     86: #include <machine/bus.h>
                     87: #include <machine/cpu.h>
                     88: #include <machine/conf.h>
                     89:
                     90: #include <dev/wscons/wsconsio.h>
                     91: #include <dev/wscons/wsdisplayvar.h>
                     92: #include <dev/rasops/rasops.h>
                     93: #include <machine/fbvar.h>
                     94:
                     95: #include <dev/sbus/zxreg.h>
                     96: #include <dev/sbus/sbusvar.h>
                     97:
                     98: #define        ZX_WID_SHARED_8         0
                     99: #define        ZX_WID_SHARED_24        1
                    100: #define        ZX_WID_DBL_8            2
                    101: #define        ZX_WID_DBL_24           3
                    102:
                    103: /*
                    104:  * Per-instance data.
                    105:  */
                    106:
                    107: struct zx_cmap {
                    108:        u_int8_t        cm_red[256];
                    109:        u_int8_t        cm_green[256];
                    110:        u_int8_t        cm_blue[256];
                    111: };
                    112:
                    113: struct zx_softc {
                    114:        struct  sunfb   sc_sunfb;
                    115:
                    116:        bus_space_tag_t sc_bustag;
                    117:        bus_addr_t      sc_paddr;
                    118:
                    119:        struct  zx_cmap sc_cmap;        /* shadow color map for overlay plane */
                    120:
                    121:        volatile struct zx_command *sc_zc;
                    122:        volatile struct zx_cross *sc_zx;
                    123:        volatile struct zx_draw *sc_zd_ss0;
                    124:        volatile struct zx_draw_ss1 *sc_zd_ss1;
                    125:        volatile struct zx_cursor *sc_zcu;
                    126:
                    127:        int     sc_nscreens;
                    128: };
                    129:
                    130: int zx_ioctl(void *, u_long, caddr_t, int, struct proc *);
                    131: int zx_alloc_screen(void *, const struct wsscreen_descr *, void **,
                    132:     int *, int *, long *);
                    133: void zx_free_screen(void *, void *);
                    134: int zx_show_screen(void *, void *, int, void (*)(void *, int, int), void *);
                    135: paddr_t zx_mmap(void *, off_t, int);
                    136: void zx_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
                    137: void zx_reset(struct zx_softc *, u_int);
                    138: void zx_burner(void *, u_int, u_int);
                    139:
                    140: struct wsdisplay_accessops zx_accessops = {
                    141:        zx_ioctl,
                    142:        zx_mmap,
                    143:        zx_alloc_screen,
                    144:        zx_free_screen,
                    145:        zx_show_screen,
                    146:        NULL,   /* load_font */
                    147:        NULL,   /* scrollback */
                    148:        NULL,   /* getchar */
                    149:        zx_burner
                    150: };
                    151:
                    152: /* Force 32-bit writes. */
                    153: #define        SETREG(r, v)    (*((volatile u_int32_t *)&r) = (v))
                    154:
                    155: #define        ZX_STD_ROP      (ZX_ROP_NEW | ZX_ATTR_WE_ENABLE | \
                    156:     ZX_ATTR_OE_ENABLE | ZX_ATTR_FORCE_WID)
                    157:
                    158: #define        ZX_BWIDTH       13
                    159: #define        ZX_WWIDTH       11      /* word width */
                    160:
                    161: #define        ZX_COORDS(x, y) ((x) | ((y) << ZX_WWIDTH))
                    162:
                    163: void   zx_attach(struct device *, struct device *, void *);
                    164: int    zx_match(struct device *, void *, void *);
                    165:
                    166: int    zx_putcmap(struct zx_softc *);
                    167: void   zx_copyrect(struct rasops_info *, int, int, int, int, int, int);
                    168: int    zx_cross_loadwid(struct zx_softc *, u_int, u_int, u_int);
                    169: int    zx_cross_wait(struct zx_softc *);
                    170: void   zx_fillrect(struct rasops_info *, int, int, int, int, long, int);
                    171: int    zx_intr(void *);
                    172: void   zx_prom(void *);
                    173:
                    174: void   zx_putchar(void *, int, int, u_int, long);
                    175: void   zx_copycols(void *, int, int, int, int);
                    176: void   zx_erasecols(void *, int, int, int, long);
                    177: void   zx_copyrows(void *, int, int, int);
                    178: void   zx_eraserows(void *, int, int, long);
                    179: void   zx_do_cursor(struct rasops_info *);
                    180:
                    181: struct cfattach zx_ca = {
                    182:        sizeof(struct zx_softc), zx_match, zx_attach
                    183: };
                    184:
                    185: struct cfdriver zx_cd = {
                    186:        NULL, "zx", DV_DULL
                    187: };
                    188:
                    189: int
                    190: zx_match(struct device *parent, void *vcf, void *aux)
                    191: {
                    192:        struct sbus_attach_args *sa = aux;
                    193:
                    194:        if (strcmp(sa->sa_name, "SUNW,leo") == 0)
                    195:                return (1);
                    196:
                    197:        return (0);
                    198: }
                    199:
                    200: void
                    201: zx_attach(struct device *parent, struct device *self, void *args)
                    202: {
                    203:        struct zx_softc *sc = (struct zx_softc *)self;
                    204:        struct sbus_attach_args *sa = args;
                    205:        struct rasops_info *ri;
                    206:        bus_space_tag_t bt;
                    207:        bus_space_handle_t bh;
                    208:        int node, isconsole = 0;
                    209:        const char *nam;
                    210:
                    211:        bt = sa->sa_bustag;
                    212:        ri = &sc->sc_sunfb.sf_ro;
                    213:        node = sa->sa_node;
                    214:
                    215:        /*
                    216:         * Map the various parts of the card.
                    217:         */
                    218:        sc->sc_bustag = bt;
                    219:        sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset);
                    220:
                    221:        if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LC_SS0_USR,
                    222:            sizeof(struct zx_command), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
                    223:                printf(": couldn't map command registers\n");
                    224:                return;
                    225:        }
                    226:        sc->sc_zc = (struct zx_command *)bus_space_vaddr(bt, bh);
                    227:
                    228:        if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0,
                    229:            sizeof(struct zx_draw), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
                    230:                printf(": couldn't map ss0 drawing registers\n");
                    231:                return;
                    232:        }
                    233:        sc->sc_zd_ss0 = (struct zx_draw *)bus_space_vaddr(bt, bh);
                    234:
                    235:        if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1,
                    236:            sizeof(struct zx_draw_ss1), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
                    237:                printf(": couldn't map ss1 drawing registers\n");
                    238:                return;
                    239:        }
                    240:        sc->sc_zd_ss1 = (struct zx_draw_ss1 *)bus_space_vaddr(bt, bh);
                    241:
                    242:        if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS,
                    243:            sizeof(struct zx_cross), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
                    244:                printf(": couldn't map cross registers\n");
                    245:                return;
                    246:        }
                    247:        sc->sc_zx = (struct zx_cross *)bus_space_vaddr(bt, bh);
                    248:
                    249:        if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR,
                    250:            sizeof(struct zx_cursor), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
                    251:                printf(": couldn't map cursor registers\n");
                    252:                return;
                    253:        }
                    254:        sc->sc_zcu = (struct zx_cursor *)bus_space_vaddr(bt, bh);
                    255:
                    256:        nam = getpropstring(node, "model");
                    257:        if (*nam == '\0')
                    258:                nam = sa->sa_name;
                    259:        printf(": %s", nam);
                    260:
                    261:        isconsole = node == fbnode;
                    262:
                    263:        /*
                    264:         * The console is using the 8-bit overlay plane, while the prom
                    265:         * will correctly report 32 bit depth.
                    266:         * The following is an equivalent for
                    267:         *    fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
                    268:         * forcing the depth value not to be overwritten.
                    269:         * Furthermore, the linebytes value is in fact 8192 bytes.
                    270:         */
                    271:        sc->sc_sunfb.sf_depth = 8;
                    272:        sc->sc_sunfb.sf_width = getpropint(node, "width", 1152);
                    273:        sc->sc_sunfb.sf_height = getpropint(node, "height", 900);
                    274:        sc->sc_sunfb.sf_linebytes = 1 << ZX_BWIDTH;
                    275:        sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height << ZX_BWIDTH;
                    276:
                    277:        printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
                    278:
                    279:        if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0,
                    280:            round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR,
                    281:            0, &bh) != 0) {
                    282:                printf("%s: couldn't map video memory\n", self->dv_xname);
                    283:                return;
                    284:        }
                    285:        ri->ri_bits = bus_space_vaddr(bt, bh);
                    286:        ri->ri_hw = sc;
                    287:
                    288:        fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
                    289:
                    290:        /*
                    291:         * Watch out! rasops_init() invoked via fbwscons_init() did not
                    292:         * compute ri_bits correctly when centering the display, because
                    293:         * it has been tricked with the low depth value.
                    294:         * Recompute now.
                    295:         */
                    296:        ri->ri_emustride = ri->ri_emuwidth * 4;
                    297:        ri->ri_delta = ri->ri_stride - ri->ri_emustride;
                    298:        ri->ri_pelbytes = 4;
                    299:        ri->ri_xscale = ri->ri_font->fontwidth * 4;
                    300:        ri->ri_bits = ri->ri_origbits;
                    301:        ri->ri_bits += (((ri->ri_width * 4) - ri->ri_emustride) >> 1) & ~3;
                    302:        ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
                    303:            ri->ri_stride;
                    304:        ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
                    305:            / ri->ri_stride;
                    306:        ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
                    307:            % ri->ri_stride) / 4);
                    308:
                    309:        ri->ri_ops.copyrows = zx_copyrows;
                    310:        ri->ri_ops.copycols = zx_copycols;
                    311:        ri->ri_ops.eraserows = zx_eraserows;
                    312:        ri->ri_ops.erasecols = zx_erasecols;
                    313:        ri->ri_ops.putchar = zx_putchar;
                    314:        ri->ri_do_cursor = zx_do_cursor;
                    315:
                    316:        if (isconsole) {
                    317:                /* zx_reset() below will clear screen, so restart at 1st row */
                    318:                fbwscons_console_init(&sc->sc_sunfb, 0);
                    319:        }
                    320:
                    321:        /* reset cursor & frame buffer controls */
                    322:        zx_reset(sc, WSDISPLAYIO_MODE_EMUL);
                    323:
                    324:        /* enable video */
                    325:        zx_burner(sc, 1, 0);
                    326:
                    327:        fbwscons_attach(&sc->sc_sunfb, &zx_accessops, isconsole);
                    328: }
                    329:
                    330: int
                    331: zx_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p)
                    332: {
                    333:        struct zx_softc *sc = dev;
                    334:        struct wsdisplay_fbinfo *wdf;
                    335:
                    336:        /*
                    337:         * Note that, although the emulation (text) mode is running in
                    338:         * a 8-bit plane, we advertize the frame buffer as the full-blown
                    339:         * 32-bit beast it is.
                    340:         */
                    341:        switch (cmd) {
                    342:        case WSDISPLAYIO_GTYPE:
                    343:                *(u_int *)data = WSDISPLAY_TYPE_SUN24;
                    344:                break;
                    345:        case WSDISPLAYIO_GINFO:
                    346:                wdf = (struct wsdisplay_fbinfo *)data;
                    347:                wdf->height = sc->sc_sunfb.sf_height;
                    348:                wdf->width = sc->sc_sunfb.sf_width;
                    349:                wdf->depth = 32;
                    350:                wdf->cmsize = 0;
                    351:                break;
                    352:        case WSDISPLAYIO_GETSUPPORTEDDEPTH:
                    353:                *(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
                    354:                break;
                    355:        case WSDISPLAYIO_LINEBYTES:
                    356:                *(u_int *)data = sc->sc_sunfb.sf_linebytes;
                    357:                break;
                    358:
                    359:        case WSDISPLAYIO_GETCMAP:
                    360:        case WSDISPLAYIO_PUTCMAP:
                    361:                break;
                    362:
                    363:        case WSDISPLAYIO_SMODE:
                    364:                zx_reset(sc, *(u_int *)data);
                    365:                break;
                    366:
                    367:        case WSDISPLAYIO_SVIDEO:
                    368:        case WSDISPLAYIO_GVIDEO:
                    369:                break;
                    370:
                    371:        default:
                    372:                return (-1);
                    373:        }
                    374:
                    375:        return (0);
                    376: }
                    377:
                    378: int
                    379: zx_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
                    380:     int *curxp, int *curyp, long *attrp)
                    381: {
                    382:        struct zx_softc *sc = v;
                    383:
                    384:        if (sc->sc_nscreens > 0)
                    385:                return (ENOMEM);
                    386:
                    387:        *cookiep = &sc->sc_sunfb.sf_ro;
                    388:        *curyp = 0;
                    389:        *curxp = 0;
                    390:        sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
                    391:            WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp);
                    392:        sc->sc_nscreens++;
                    393:        return (0);
                    394: }
                    395:
                    396: void
                    397: zx_free_screen(void *v, void *cookie)
                    398: {
                    399:        struct zx_softc *sc = v;
                    400:
                    401:        sc->sc_nscreens--;
                    402: }
                    403:
                    404: int
                    405: zx_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int),
                    406:     void *cbarg)
                    407: {
                    408:        return (0);
                    409: }
                    410:
                    411: /*
                    412:  * Return the address that would map the given device at the given
                    413:  * offset, allowing for the given protection, or return -1 for error.
                    414:  */
                    415: paddr_t
                    416: zx_mmap(void *v, off_t offset, int prot)
                    417: {
                    418:        struct zx_softc *sc = v;
                    419:
                    420:        if (offset & PGOFSET)
                    421:                return (-1);
                    422:
                    423:        /* Allow mapping as a dumb framebuffer from offset 0 */
                    424:        if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
                    425:                return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
                    426:                    ZX_OFF_SS0 + offset, prot, BUS_SPACE_MAP_LINEAR));
                    427:        }
                    428:
                    429:        return (-1);
                    430: }
                    431:
                    432: void
                    433: zx_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
                    434: {
                    435:        struct zx_softc *sc = v;
                    436:
                    437:        sc->sc_cmap.cm_red[index] = r;
                    438:        sc->sc_cmap.cm_green[index] = g;
                    439:        sc->sc_cmap.cm_blue[index] = b;
                    440: }
                    441:
                    442: void
                    443: zx_reset(struct zx_softc *sc, u_int mode)
                    444: {
                    445:        volatile struct zx_draw *zd;
                    446:        volatile struct zx_command *zc;
                    447:        u_int32_t i;
                    448:        const u_char *color;
                    449:        u_int8_t *r, *g, *b;
                    450:
                    451:        zd = sc->sc_zd_ss0;
                    452:        zc = sc->sc_zc;
                    453:
                    454:        if (mode == WSDISPLAYIO_MODE_EMUL) {
                    455:                /* Back from X11 to emulation mode, or first reset */
                    456:                zx_cross_loadwid(sc, ZX_WID_DBL_8, 0, 0x2c0);
                    457:                zx_cross_loadwid(sc, ZX_WID_DBL_8, 1, 0x30);
                    458:                zx_cross_loadwid(sc, ZX_WID_DBL_8, 2, 0x20);
                    459:                zx_cross_loadwid(sc, ZX_WID_DBL_24, 1, 0x30);
                    460:
                    461:                i = sc->sc_zd_ss1->zd_misc;
                    462:                i |= ZX_SS1_MISC_ENABLE;
                    463:                SETREG(sc->sc_zd_ss1->zd_misc, i);
                    464:
                    465:                /*
                    466:                 * XXX
                    467:                 * If zc_fill is not set to that value, there will be black
                    468:                 * bars left in the margins. But then with this value, the
                    469:                 * screen gets cleared. Go figure.
                    470:                 */
                    471:                SETREG(zd->zd_wid, 0xffffffff);
                    472:                SETREG(zd->zd_wmask, 0xffff);
                    473:                SETREG(zd->zd_vclipmin, 0);
                    474:                SETREG(zd->zd_vclipmax, (sc->sc_sunfb.sf_width - 1) |
                    475:                    ((sc->sc_sunfb.sf_height - 1) << 16));
                    476:                SETREG(zd->zd_fg, 0);
                    477:                SETREG(zd->zd_planemask, 0xff000000);
                    478:                SETREG(zd->zd_rop, ZX_STD_ROP);
                    479:                SETREG(zd->zd_widclip, 0);
                    480:
                    481:                SETREG(zc->zc_extent, ZX_COORDS(sc->sc_sunfb.sf_width - 1,
                    482:                    sc->sc_sunfb.sf_height - 1));
                    483:                SETREG(zc->zc_addrspace, ZX_ADDRSPC_FONT_OBGR);
                    484:                SETREG(zc->zc_fill, ZX_COORDS(0, 0) | ZX_EXTENT_DIR_BACKWARDS);
                    485:                SETREG(zc->zc_fontt, 0);
                    486:
                    487:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    488:                        ;
                    489:
                    490:                /*
                    491:                 * Initialize the 8-bit colormap
                    492:                 */
                    493:                r = sc->sc_cmap.cm_red;
                    494:                g = sc->sc_cmap.cm_green;
                    495:                b = sc->sc_cmap.cm_blue;
                    496:                color = rasops_cmap;
                    497:                for (i = 0; i < 256; i++) {
                    498:                        *r++ = *color++;
                    499:                        *g++ = *color++;
                    500:                        *b++ = *color++;
                    501:                }
                    502:                fbwscons_setcolormap(&sc->sc_sunfb, zx_setcolor);
                    503:                zx_putcmap(sc);
                    504:        } else {
                    505:                /* Starting X11 - switch to 24bit WID */
                    506:                SETREG(zd->zd_wid, 1);
                    507:                SETREG(zd->zd_widclip, 0);
                    508:                SETREG(zd->zd_wmask, 0xffff);
                    509:                SETREG(zd->zd_planemask, 0x00ffffff);
                    510:                SETREG(zc->zc_extent, ZX_COORDS(sc->sc_sunfb.sf_width - 1,
                    511:                    sc->sc_sunfb.sf_height - 1));
                    512:                SETREG(zc->zc_fill, 0);
                    513:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    514:                        ;
                    515:
                    516:                SETREG(zc->zc_addrspace, ZX_ADDRSPC_OBGR);
                    517:                SETREG(zd->zd_rop, ZX_ATTR_RGBE_ENABLE |
                    518:                    ZX_ROP_NEW /* | ZX_ATTR_FORCE_WID */);
                    519:        }
                    520: }
                    521:
                    522: int
                    523: zx_cross_wait(struct zx_softc *sc)
                    524: {
                    525:        volatile struct zx_cross *zx;
                    526:        int i;
                    527:
                    528:        zx = sc->sc_zx;
                    529:
                    530:        for (i = 300000; i != 0; i--) {
                    531:                if ((zx->zx_csr & ZX_CROSS_CSR_PROGRESS) == 0)
                    532:                        break;
                    533:                DELAY(1);
                    534:        }
                    535:
                    536:        if (i == 0)
                    537:                printf("%s: zx_cross_wait: timed out\n",
                    538:                    sc->sc_sunfb.sf_dev.dv_xname);
                    539:
                    540:        return (i);
                    541: }
                    542:
                    543: int
                    544: zx_cross_loadwid(struct zx_softc *sc, u_int type, u_int index, u_int value)
                    545: {
                    546:        volatile struct zx_cross *zx;
                    547:        u_int tmp;
                    548:
                    549:        zx = sc->sc_zx;
                    550:        SETREG(zx->zx_type, ZX_CROSS_TYPE_WID);
                    551:
                    552:        if (!zx_cross_wait(sc))
                    553:                return (1);
                    554:
                    555:        if (type == ZX_WID_DBL_8)
                    556:                tmp = (index & 0x0f) + 0x40;
                    557:        else if (type == ZX_WID_DBL_24)
                    558:                tmp = index & 0x3f;
                    559:
                    560:        SETREG(zx->zx_type, 0x5800 + tmp);
                    561:        SETREG(zx->zx_value, value);
                    562:        SETREG(zx->zx_type, ZX_CROSS_TYPE_WID);
                    563:        SETREG(zx->zx_csr, ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2);
                    564:
                    565:        return (0);
                    566: }
                    567:
                    568: int
                    569: zx_putcmap(struct zx_softc *sc)
                    570: {
                    571:        volatile struct zx_cross *zx;
                    572:        u_int32_t i;
                    573:        u_int8_t *r, *g, *b;
                    574:
                    575:        zx = sc->sc_zx;
                    576:
                    577:        SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUT0);
                    578:        if (!zx_cross_wait(sc))
                    579:                return (1);
                    580:
                    581:        SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUTDATA);
                    582:
                    583:        r = sc->sc_cmap.cm_red;
                    584:        g = sc->sc_cmap.cm_green;
                    585:        b = sc->sc_cmap.cm_blue;
                    586:        for (i = 0; i < 256; i++) {
                    587:                SETREG(zx->zx_value, *r++ | (*g++ << 8) | (*b++ << 16));
                    588:        }
                    589:
                    590:        SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUT0);
                    591:        i = zx->zx_csr;
                    592:        i = i | ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2;
                    593:        SETREG(zx->zx_csr, i);
                    594:        return (0);
                    595: }
                    596:
                    597: void
                    598: zx_burner(void *v, u_int on, u_int flags)
                    599: {
                    600:        struct zx_softc *sc = v;
                    601:        volatile struct zx_cross *zx;
                    602:        u_int32_t i;
                    603:
                    604:        zx = sc->sc_zx;
                    605:
                    606:        SETREG(zx->zx_type, ZX_CROSS_TYPE_VIDEO);
                    607:        i = zx->zx_csr;
                    608:        if (on) {
                    609:                i |= ZX_CROSS_CSR_ENABLE;
                    610:        } else {
                    611:                i &= ~ZX_CROSS_CSR_ENABLE;
                    612:        }
                    613:        SETREG(zx->zx_csr, i);
                    614: }
                    615:
                    616: void
                    617: zx_fillrect(struct rasops_info *ri, int x, int y, int w, int h, long attr,
                    618:            int rop)
                    619: {
                    620:        struct zx_softc *sc;
                    621:        volatile struct zx_command *zc;
                    622:        volatile struct zx_draw *zd;
                    623:        int fg, bg;
                    624:
                    625:        sc = ri->ri_hw;
                    626:        zc = sc->sc_zc;
                    627:        zd = sc->sc_zd_ss0;
                    628:
                    629:        ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, NULL);
                    630:        x = x * ri->ri_font->fontwidth + ri->ri_xorigin;
                    631:        y = y * ri->ri_font->fontheight + ri->ri_yorigin;
                    632:        w = ri->ri_font->fontwidth * w - 1;
                    633:        h = ri->ri_font->fontheight * h - 1;
                    634:
                    635:        while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    636:                ;
                    637:
                    638:        SETREG(zd->zd_rop, rop);
                    639:        SETREG(zd->zd_fg, ri->ri_devcmap[bg] << 24);
                    640:        SETREG(zc->zc_extent, ZX_COORDS(w, h));
                    641:        SETREG(zc->zc_fill, ZX_COORDS(x, y) | ZX_EXTENT_DIR_BACKWARDS);
                    642: }
                    643:
                    644: void
                    645: zx_copyrect(struct rasops_info *ri, int sx, int sy, int dx, int dy, int w,
                    646:            int h)
                    647: {
                    648:        struct zx_softc *sc;
                    649:        volatile struct zx_command *zc;
                    650:        volatile struct zx_draw *zd;
                    651:        int dir;
                    652:
                    653:        sc = ri->ri_hw;
                    654:        zc = sc->sc_zc;
                    655:        zd = sc->sc_zd_ss0;
                    656:
                    657:        sx = sx * ri->ri_font->fontwidth + ri->ri_xorigin;
                    658:        sy = sy * ri->ri_font->fontheight + ri->ri_yorigin;
                    659:        dx = dx * ri->ri_font->fontwidth + ri->ri_xorigin;
                    660:        dy = dy * ri->ri_font->fontheight + ri->ri_yorigin;
                    661:        w = w * ri->ri_font->fontwidth - 1;
                    662:        h = h * ri->ri_font->fontheight - 1;
                    663:
                    664:        if (sy < dy || sx < dx) {
                    665:                dir = ZX_EXTENT_DIR_BACKWARDS;
                    666:                sx += w;
                    667:                sy += h;
                    668:                dx += w;
                    669:                dy += h;
                    670:        } else
                    671:                dir = ZX_EXTENT_DIR_FORWARDS;
                    672:
                    673:        while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    674:                ;
                    675:
                    676:        SETREG(zd->zd_rop, ZX_STD_ROP);
                    677:        SETREG(zc->zc_extent, ZX_COORDS(w, h) | dir);
                    678:        SETREG(zc->zc_src, ZX_COORDS(sx, sy));
                    679:        SETREG(zc->zc_copy, ZX_COORDS(dx, dy));
                    680: }
                    681:
                    682: void
                    683: zx_do_cursor(struct rasops_info *ri)
                    684: {
                    685:
                    686:        zx_fillrect(ri, ri->ri_ccol, ri->ri_crow, 1, 1, WSCOL_BLACK << 16,
                    687:            ZX_ROP_NEW_XOR_OLD | ZX_ATTR_WE_ENABLE | ZX_ATTR_OE_ENABLE |
                    688:            ZX_ATTR_FORCE_WID);
                    689: }
                    690:
                    691: void
                    692: zx_erasecols(void *cookie, int row, int col, int num, long attr)
                    693: {
                    694:        struct rasops_info *ri;
                    695:
                    696:        ri = (struct rasops_info *)cookie;
                    697:
                    698:        zx_fillrect(ri, col, row, num, 1, attr, ZX_STD_ROP);
                    699: }
                    700:
                    701: void
                    702: zx_eraserows(void *cookie, int row, int num, long attr)
                    703: {
                    704:        struct rasops_info *ri;
                    705:        struct zx_softc *sc;
                    706:        volatile struct zx_command *zc;
                    707:        volatile struct zx_draw *zd;
                    708:        int fg, bg;
                    709:
                    710:        ri = (struct rasops_info *)cookie;
                    711:
                    712:        if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) {
                    713:                sc = ri->ri_hw;
                    714:                zc = sc->sc_zc;
                    715:                zd = sc->sc_zd_ss0;
                    716:
                    717:                ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
                    718:
                    719:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    720:                        ;
                    721:
                    722:                SETREG(zd->zd_rop, ZX_STD_ROP);
                    723:                SETREG(zd->zd_fg, ri->ri_devcmap[bg] << 24);
                    724:                SETREG(zc->zc_extent,
                    725:                    ZX_COORDS(ri->ri_width - 1, ri->ri_height - 1));
                    726:                SETREG(zc->zc_fill, ZX_COORDS(0, 0) | ZX_EXTENT_DIR_BACKWARDS);
                    727:        } else
                    728:                zx_fillrect(ri, 0, row, ri->ri_cols, num, attr, ZX_STD_ROP);
                    729: }
                    730:
                    731: void
                    732: zx_copyrows(void *cookie, int src, int dst, int num)
                    733: {
                    734:        struct rasops_info *ri;
                    735:
                    736:        ri = (struct rasops_info *)cookie;
                    737:
                    738:        zx_copyrect(ri, 0, src, 0, dst, ri->ri_cols, num);
                    739: }
                    740:
                    741: void
                    742: zx_copycols(void *cookie, int row, int src, int dst, int num)
                    743: {
                    744:        struct rasops_info *ri;
                    745:
                    746:        ri = (struct rasops_info *)cookie;
                    747:
                    748:        zx_copyrect(ri, src, row, dst, row, num, 1);
                    749: }
                    750:
                    751: void
                    752: zx_putchar(void *cookie, int row, int col, u_int uc, long attr)
                    753: {
                    754:        struct rasops_info *ri;
                    755:        struct zx_softc *sc;
                    756:        struct wsdisplay_font *font;
                    757:        volatile struct zx_command *zc;
                    758:        volatile struct zx_draw *zd;
                    759:        volatile u_int32_t *dp;
                    760:        u_int8_t *fb;
                    761:        int fs, i, fg, bg, ul;
                    762:
                    763:        ri = (struct rasops_info *)cookie;
                    764:        font = ri->ri_font;
                    765:        ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, &ul);
                    766:        fg = ri->ri_devcmap[fg];
                    767:        bg = ri->ri_devcmap[bg];
                    768:
                    769:        dp = (volatile u_int32_t *)ri->ri_bits +
                    770:            ZX_COORDS(col * font->fontwidth, row * font->fontheight);
                    771:
                    772:        if (uc == ' ') {
                    773:                zx_fillrect(ri, col, row, 1, 1, attr, ZX_STD_ROP);
                    774:                if (ul == 0)
                    775:                        return;
                    776:
                    777:                dp += font->fontheight << ZX_WWIDTH;
                    778:
                    779:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    780:                        ;
                    781:
                    782:                SETREG(zd->zd_rop, ZX_STD_ROP);
                    783:                SETREG(zd->zd_fg, fg << 24);
                    784:                SETREG(zd->zd_bg, bg << 24);
                    785:                SETREG(zc->zc_fontmsk, 0xffffffff << (32 - font->fontwidth));
                    786:        } else {
                    787:                sc = ri->ri_hw;
                    788:                zc = sc->sc_zc;
                    789:                zd = sc->sc_zd_ss0;
                    790:
                    791:                fb = (u_int8_t *)font->data + (uc - font->firstchar) *
                    792:                    ri->ri_fontscale;
                    793:                fs = font->stride;
                    794:
                    795:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    796:                        ;
                    797:
                    798:                SETREG(zd->zd_rop, ZX_STD_ROP);
                    799:                SETREG(zd->zd_fg, fg << 24);
                    800:                SETREG(zd->zd_bg, bg << 24);
                    801:                SETREG(zc->zc_fontmsk, 0xffffffff << (32 - font->fontwidth));
                    802:
                    803:                if (font->fontwidth <= 8) {
                    804:                        for (i = font->fontheight; i != 0;
                    805:                            i--, dp += 1 << ZX_WWIDTH) {
                    806:                                *dp = *fb << 24;
                    807:                                fb += fs;
                    808:                        }
                    809:                } else {
                    810:                        for (i = font->fontheight; i != 0;
                    811:                            i--, dp += 1 << ZX_WWIDTH) {
                    812:                                *dp = *((u_int16_t *)fb) << 16;
                    813:                                fb += fs;
                    814:                        }
                    815:                }
                    816:        }
                    817:
                    818:        /* underline */
                    819:        if (ul) {
                    820:                dp -= 2 << ZX_WWIDTH;
                    821:                *dp = 0xffffffff;
                    822:        }
                    823: }

CVSweb