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

Annotation of sys/arch/sparc64/dev/creator.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: creator.c,v 1.39 2007/03/06 23:10:26 kettenis Exp $   */
                      2:
                      3: /*
                      4:  * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     19:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     22:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     25:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     26:  * POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28:
                     29: #include <sys/types.h>
                     30: #include <sys/param.h>
                     31: #include <sys/systm.h>
                     32: #include <sys/kernel.h>
                     33: #include <sys/device.h>
                     34: #include <sys/conf.h>
                     35: #include <sys/timeout.h>
                     36:
                     37: #include <machine/bus.h>
                     38: #include <machine/autoconf.h>
                     39: #include <machine/openfirm.h>
                     40:
                     41: #include <dev/wscons/wsconsio.h>
                     42: #include <dev/wscons/wsdisplayvar.h>
                     43: #include <dev/rasops/rasops.h>
                     44: #include <machine/fbvar.h>
                     45:
                     46: #include <sparc64/dev/creatorreg.h>
                     47: #include <sparc64/dev/creatorvar.h>
                     48:
                     49: int    creator_match(struct device *, void *, void *);
                     50: void   creator_attach(struct device *, struct device *, void *);
                     51: int    creator_ioctl(void *, u_long, caddr_t, int, struct proc *);
                     52: int    creator_alloc_screen(void *, const struct wsscreen_descr *, void **,
                     53:            int *, int *, long *);
                     54: void   creator_free_screen(void *, void *);
                     55: int    creator_show_screen(void *, void *, int, void (*cb)(void *, int, int),
                     56:            void *);
                     57: paddr_t creator_mmap(void *, off_t, int);
                     58: void   creator_ras_fifo_wait(struct creator_softc *, int);
                     59: void   creator_ras_wait(struct creator_softc *);
                     60: void   creator_ras_init(struct creator_softc *);
                     61: void   creator_ras_copyrows(void *, int, int, int);
                     62: void   creator_ras_erasecols(void *, int, int, int, long int);
                     63: void   creator_ras_eraserows(void *, int, int, long int);
                     64: void   creator_ras_fill(struct creator_softc *);
                     65: void   creator_ras_setfg(struct creator_softc *, int32_t);
                     66: int    creator_setcursor(struct creator_softc *, struct wsdisplay_cursor *);
                     67: int    creator_updatecursor(struct creator_softc *, u_int);
                     68: void   creator_curs_enable(struct creator_softc *, u_int);
                     69:
                     70: struct wsdisplay_accessops creator_accessops = {
                     71:        creator_ioctl,
                     72:        creator_mmap,
                     73:        creator_alloc_screen,
                     74:        creator_free_screen,
                     75:        creator_show_screen,
                     76:        NULL,   /* load font */
                     77:        NULL,   /* scrollback */
                     78:        NULL,   /* getchar */
                     79:        NULL,   /* burner */
                     80: };
                     81:
                     82: struct cfdriver creator_cd = {
                     83:        NULL, "creator", DV_DULL
                     84: };
                     85:
                     86: struct cfattach creator_ca = {
                     87:        sizeof(struct creator_softc), creator_match, creator_attach
                     88: };
                     89:
                     90: int
                     91: creator_match(parent, match, aux)
                     92:        struct device *parent;
                     93:        void *match, *aux;
                     94: {
                     95:        struct mainbus_attach_args *ma = aux;
                     96:
                     97:        if (strcmp(ma->ma_name, "SUNW,ffb") == 0 ||
                     98:            strcmp(ma->ma_name, "SUNW,afb") == 0)
                     99:                return (1);
                    100:        return (0);
                    101: }
                    102:
                    103: void
                    104: creator_attach(parent, self, aux)
                    105:        struct device *parent, *self;
                    106:        void *aux;
                    107: {
                    108:        struct creator_softc *sc = (struct creator_softc *)self;
                    109:        struct mainbus_attach_args *ma = aux;
                    110:        extern int fbnode;
                    111:        int i, nregs;
                    112:        char *model;
                    113:        int btype;
                    114:
                    115:        sc->sc_bt = ma->ma_bustag;
                    116:
                    117:        nregs = min(ma->ma_nreg, FFB_NREGS);
                    118:
                    119:        if (nregs <= FFB_REG_DFB24) {
                    120:                printf(": no dfb24 regs found\n");
                    121:                return;
                    122:        }
                    123:
                    124:        if (bus_space_map(sc->sc_bt, ma->ma_reg[FFB_REG_DFB24].ur_paddr,
                    125:            ma->ma_reg[FFB_REG_DFB24].ur_len, BUS_SPACE_MAP_LINEAR,
                    126:            &sc->sc_pixel_h)) {
                    127:                printf(": failed to map dfb24\n");
                    128:                return;
                    129:        }
                    130:
                    131:        if (bus_space_map(sc->sc_bt, ma->ma_reg[FFB_REG_FBC].ur_paddr,
                    132:            ma->ma_reg[FFB_REG_FBC].ur_len, 0, &sc->sc_fbc_h)) {
                    133:                printf(": failed to map fbc\n");
                    134:                goto unmap_dfb24;
                    135:        }
                    136:
                    137:        if (bus_space_map(sc->sc_bt, ma->ma_reg[FFB_REG_DAC].ur_paddr,
                    138:            ma->ma_reg[FFB_REG_DAC].ur_len, 0, &sc->sc_dac_h)) {
                    139:                printf(": failed to map dac\n");
                    140:                goto unmap_fbc;
                    141:        }
                    142:
                    143:        for (i = 0; i < nregs; i++) {
                    144:                sc->sc_addrs[i] = ma->ma_reg[i].ur_paddr;
                    145:                sc->sc_sizes[i] = ma->ma_reg[i].ur_len;
                    146:        }
                    147:        sc->sc_nreg = nregs;
                    148:
                    149:        sc->sc_console = (fbnode == ma->ma_node);
                    150:        sc->sc_node = ma->ma_node;
                    151:
                    152:        if (strcmp(ma->ma_name, "SUNW,afb") == 0)
                    153:                sc->sc_type = FFB_AFB;
                    154:
                    155:        /*
                    156:         * Prom reports only the length of the fcode header, we need
                    157:         * the whole thing.
                    158:         */
                    159:        sc->sc_sizes[0] = 0x00400000;
                    160:
                    161:        if (sc->sc_type == FFB_CREATOR) {
                    162:                btype = getpropint(sc->sc_node, "board_type", 0);
                    163:                if ((btype & 7) == 3)
                    164:                        printf(": Creator3D");
                    165:                else
                    166:                        printf(": Creator");
                    167:        } else
                    168:                printf(": Elite3D");
                    169:
                    170:        model = getpropstring(sc->sc_node, "model");
                    171:        if (model == NULL || strlen(model) == 0)
                    172:                model = "unknown";
                    173:
                    174:        DAC_WRITE(sc, FFB_DAC_TYPE, DAC_TYPE_GETREV);
                    175:        sc->sc_dacrev = DAC_READ(sc, FFB_DAC_VALUE) >> 28;
                    176:
                    177:        printf(", model %s, dac %u\n", model, sc->sc_dacrev);
                    178:
                    179:        if (sc->sc_type == FFB_AFB)
                    180:                sc->sc_dacrev = 10;
                    181:
                    182:        fb_setsize(&sc->sc_sunfb, 32, 1152, 900, sc->sc_node, 0);
                    183:        /* linesize has a fixed value, compensate */
                    184:        sc->sc_sunfb.sf_linebytes = 8192;
                    185:        sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height * 8192;
                    186:
                    187:        sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bt,
                    188:            sc->sc_pixel_h);
                    189:        sc->sc_sunfb.sf_ro.ri_hw = sc;
                    190:        fbwscons_init(&sc->sc_sunfb, sc->sc_console ? 0 : RI_CLEAR);
                    191:
                    192:        if ((sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags & CREATOR_CFFLAG_NOACCEL)
                    193:            == 0) {
                    194:                sc->sc_sunfb.sf_ro.ri_ops.eraserows = creator_ras_eraserows;
                    195:                sc->sc_sunfb.sf_ro.ri_ops.erasecols = creator_ras_erasecols;
                    196:                sc->sc_sunfb.sf_ro.ri_ops.copyrows = creator_ras_copyrows;
                    197:                creator_ras_init(sc);
                    198:        }
                    199:
                    200:        if (sc->sc_console) {
                    201:                fbwscons_console_init(&sc->sc_sunfb, -1);
                    202:        }
                    203:
                    204:        fbwscons_attach(&sc->sc_sunfb, &creator_accessops, sc->sc_console);
                    205:        return;
                    206:
                    207: unmap_fbc:
                    208:        bus_space_unmap(sc->sc_bt, sc->sc_fbc_h,
                    209:            ma->ma_reg[FFB_REG_FBC].ur_len);
                    210: unmap_dfb24:
                    211:        bus_space_unmap(sc->sc_bt, sc->sc_pixel_h,
                    212:            ma->ma_reg[FFB_REG_DFB24].ur_len);
                    213: }
                    214:
                    215: int
                    216: creator_ioctl(v, cmd, data, flags, p)
                    217:        void *v;
                    218:        u_long cmd;
                    219:        caddr_t data;
                    220:        int flags;
                    221:        struct proc *p;
                    222: {
                    223:        struct creator_softc *sc = v;
                    224:        struct wsdisplay_cursor *curs;
                    225:        struct wsdisplay_fbinfo *wdf;
                    226:        struct wsdisplay_curpos *pos;
                    227:        u_char r[2], g[2], b[2];
                    228:        int error;
                    229:
                    230:        switch (cmd) {
                    231:        case WSDISPLAYIO_GTYPE:
                    232:                *(u_int *)data = WSDISPLAY_TYPE_SUNFFB;
                    233:                break;
                    234:        case WSDISPLAYIO_SMODE:
                    235:                sc->sc_mode = *(u_int *)data;
                    236:                break;
                    237:        case WSDISPLAYIO_GINFO:
                    238:                wdf = (void *)data;
                    239:                wdf->height = sc->sc_sunfb.sf_height;
                    240:                wdf->width  = sc->sc_sunfb.sf_width;
                    241:                wdf->depth  = 32;
                    242:                wdf->cmsize = 0;
                    243:                break;
                    244:        case WSDISPLAYIO_GETSUPPORTEDDEPTH:
                    245:                *(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
                    246:                break;
                    247:        case WSDISPLAYIO_LINEBYTES:
                    248:                *(u_int *)data = sc->sc_sunfb.sf_linebytes;
                    249:                break;
                    250:        case WSDISPLAYIO_GCURSOR:
                    251:                curs = (struct wsdisplay_cursor *)data;
                    252:                if (curs->which & WSDISPLAY_CURSOR_DOCUR)
                    253:                        curs->enable = sc->sc_curs_enabled;
                    254:                if (curs->which & WSDISPLAY_CURSOR_DOPOS) {
                    255:                        curs->pos.x = sc->sc_curs_pos.x;
                    256:                        curs->pos.y = sc->sc_curs_pos.y;
                    257:                }
                    258:                if (curs->which & WSDISPLAY_CURSOR_DOHOT) {
                    259:                        curs->hot.x = sc->sc_curs_hot.x;
                    260:                        curs->hot.y = sc->sc_curs_hot.y;
                    261:                }
                    262:                if (curs->which & WSDISPLAY_CURSOR_DOCMAP) {
                    263:                        curs->cmap.index = 0;
                    264:                        curs->cmap.count = 2;
                    265:                        r[0] = sc->sc_curs_fg >> 0;
                    266:                        g[0] = sc->sc_curs_fg >> 8;
                    267:                        b[0] = sc->sc_curs_fg >> 16;
                    268:                        r[1] = sc->sc_curs_bg >> 0;
                    269:                        g[1] = sc->sc_curs_bg >> 8;
                    270:                        b[1] = sc->sc_curs_bg >> 16;
                    271:                        error = copyout(r, curs->cmap.red, sizeof(r));
                    272:                        if (error)
                    273:                                return (error);
                    274:                        error = copyout(g, curs->cmap.green, sizeof(g));
                    275:                        if (error)
                    276:                                return (error);
                    277:                        error = copyout(b, curs->cmap.blue, sizeof(b));
                    278:                        if (error)
                    279:                                return (error);
                    280:                }
                    281:                if (curs->which & WSDISPLAY_CURSOR_DOSHAPE) {
                    282:                        size_t l;
                    283:
                    284:                        curs->size.x = sc->sc_curs_size.x;
                    285:                        curs->size.y = sc->sc_curs_size.y;
                    286:                        l = (sc->sc_curs_size.x * sc->sc_curs_size.y) / NBBY;
                    287:                        error = copyout(sc->sc_curs_image, curs->image, l);
                    288:                        if (error)
                    289:                                return (error);
                    290:                        error = copyout(sc->sc_curs_mask, curs->mask, l);
                    291:                        if (error)
                    292:                                return (error);
                    293:                }
                    294:                break;
                    295:        case WSDISPLAYIO_SCURPOS:
                    296:                pos = (struct wsdisplay_curpos *)data;
                    297:                sc->sc_curs_pos.x = pos->x;
                    298:                sc->sc_curs_pos.y = pos->y;
                    299:                creator_updatecursor(sc, WSDISPLAY_CURSOR_DOPOS);
                    300:                break;
                    301:        case WSDISPLAYIO_GCURPOS:
                    302:                pos = (struct wsdisplay_curpos *)data;
                    303:                pos->x = sc->sc_curs_pos.x;
                    304:                pos->y = sc->sc_curs_pos.y;
                    305:                break;
                    306:        case WSDISPLAYIO_SCURSOR:
                    307:                curs = (struct wsdisplay_cursor *)data;
                    308:                return (creator_setcursor(sc, curs));
                    309:        case WSDISPLAYIO_GCURMAX:
                    310:                pos = (struct wsdisplay_curpos *)data;
                    311:                pos->x = CREATOR_CURS_MAX;
                    312:                pos->y = CREATOR_CURS_MAX;
                    313:                break;
                    314:        case WSDISPLAYIO_SVIDEO:
                    315:        case WSDISPLAYIO_GVIDEO:
                    316:                break;
                    317:
                    318:        case WSDISPLAYIO_GETCMAP:
                    319:        case WSDISPLAYIO_PUTCMAP:
                    320:        default:
                    321:                return -1; /* not supported yet */
                    322:         }
                    323:
                    324:        return (0);
                    325: }
                    326:
                    327: int
                    328: creator_setcursor(struct creator_softc *sc, struct wsdisplay_cursor *curs)
                    329: {
                    330:        u_int8_t r[2], g[2], b[2], image[128], mask[128];
                    331:        int error;
                    332:        size_t imcount;
                    333:
                    334:        /*
                    335:         * Do stuff that can generate errors first, then we'll blast it
                    336:         * all at once.
                    337:         */
                    338:        if (curs->which & WSDISPLAY_CURSOR_DOCMAP) {
                    339:                if (curs->cmap.count < 2)
                    340:                        return (EINVAL);
                    341:                error = copyin(curs->cmap.red, r, sizeof(r));
                    342:                if (error)
                    343:                        return (error);
                    344:                error = copyin(curs->cmap.green, g, sizeof(g));
                    345:                if (error)
                    346:                        return (error);
                    347:                error = copyin(curs->cmap.blue, b, sizeof(b));
                    348:                if (error)
                    349:                        return (error);
                    350:        }
                    351:
                    352:        if (curs->which & WSDISPLAY_CURSOR_DOSHAPE) {
                    353:                if (curs->size.x > CREATOR_CURS_MAX ||
                    354:                    curs->size.y > CREATOR_CURS_MAX)
                    355:                        return (EINVAL);
                    356:                imcount = (curs->size.x * curs->size.y) / NBBY;
                    357:                error = copyin(curs->image, image, imcount);
                    358:                if (error)
                    359:                        return (error);
                    360:                error = copyin(curs->mask, mask, imcount);
                    361:                if (error)
                    362:                        return (error);
                    363:        }
                    364:
                    365:        /*
                    366:         * Ok, everything is in kernel space and sane, update state.
                    367:         */
                    368:
                    369:        if (curs->which & WSDISPLAY_CURSOR_DOCUR)
                    370:                sc->sc_curs_enabled = curs->enable;
                    371:        if (curs->which & WSDISPLAY_CURSOR_DOPOS) {
                    372:                sc->sc_curs_pos.x = curs->pos.x;
                    373:                sc->sc_curs_pos.y = curs->pos.y;
                    374:        }
                    375:        if (curs->which & WSDISPLAY_CURSOR_DOHOT) {
                    376:                sc->sc_curs_hot.x = curs->hot.x;
                    377:                sc->sc_curs_hot.y = curs->hot.y;
                    378:        }
                    379:        if (curs->which & WSDISPLAY_CURSOR_DOCMAP) {
                    380:                sc->sc_curs_fg = ((r[0] << 0) | (g[0] << 8) | (b[0] << 16));
                    381:                sc->sc_curs_bg = ((r[1] << 0) | (g[1] << 8) | (b[1] << 16));
                    382:        }
                    383:        if (curs->which & WSDISPLAY_CURSOR_DOSHAPE) {
                    384:                sc->sc_curs_size.x = curs->size.x;
                    385:                sc->sc_curs_size.y = curs->size.y;
                    386:                bcopy(image, sc->sc_curs_image, imcount);
                    387:                bcopy(mask, sc->sc_curs_mask, imcount);
                    388:        }
                    389:
                    390:        creator_updatecursor(sc, curs->which);
                    391:
                    392:        return (0);
                    393: }
                    394:
                    395: void
                    396: creator_curs_enable(struct creator_softc *sc, u_int ena)
                    397: {
                    398:        u_int32_t v;
                    399:
                    400:        DAC_WRITE(sc, FFB_DAC_TYPE2, DAC_TYPE2_CURSENAB);
                    401:        if (sc->sc_dacrev <= 2)
                    402:                v = ena ? 3 : 0;
                    403:        else
                    404:                v = ena ? 0 : 3;
                    405:        DAC_WRITE(sc, FFB_DAC_VALUE2, v);
                    406: }
                    407:
                    408: int
                    409: creator_updatecursor(struct creator_softc *sc, u_int which)
                    410: {
                    411:        creator_curs_enable(sc, 0);
                    412:
                    413:        if (which & WSDISPLAY_CURSOR_DOCMAP) {
                    414:                DAC_WRITE(sc, FFB_DAC_TYPE2, DAC_TYPE2_CURSCMAP);
                    415:                DAC_WRITE(sc, FFB_DAC_VALUE2, sc->sc_curs_fg);
                    416:                DAC_WRITE(sc, FFB_DAC_VALUE2, sc->sc_curs_bg);
                    417:        }
                    418:
                    419:        if (which & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
                    420:                u_int32_t x, y;
                    421:
                    422:                x = sc->sc_curs_pos.x + CREATOR_CURS_MAX - sc->sc_curs_hot.x;
                    423:                y = sc->sc_curs_pos.y + CREATOR_CURS_MAX - sc->sc_curs_hot.y;
                    424:                DAC_WRITE(sc, FFB_DAC_TYPE2, DAC_TYPE2_CURSPOS);
                    425:                DAC_WRITE(sc, FFB_DAC_VALUE2,
                    426:                    ((x & 0xffff) << 16) | (y & 0xffff));
                    427:        }
                    428:
                    429:        if (which & WSDISPLAY_CURSOR_DOCUR)
                    430:                creator_curs_enable(sc, sc->sc_curs_enabled);
                    431:
                    432:        return (0);
                    433: }
                    434:
                    435: int
                    436: creator_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
                    437:        void *v;
                    438:        const struct wsscreen_descr *type;
                    439:        void **cookiep;
                    440:        int *curxp, *curyp;
                    441:        long *attrp;
                    442: {
                    443:        struct creator_softc *sc = v;
                    444:
                    445:        if (sc->sc_nscreens > 0)
                    446:                return (ENOMEM);
                    447:
                    448:        *cookiep = &sc->sc_sunfb.sf_ro;
                    449:        *curyp = 0;
                    450:        *curxp = 0;
                    451:        sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
                    452:            WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp);
                    453:        sc->sc_nscreens++;
                    454:        return (0);
                    455: }
                    456:
                    457: void
                    458: creator_free_screen(v, cookie)
                    459:        void *v;
                    460:        void *cookie;
                    461: {
                    462:        struct creator_softc *sc = v;
                    463:
                    464:        sc->sc_nscreens--;
                    465: }
                    466:
                    467: int
                    468: creator_show_screen(v, cookie, waitok, cb, cbarg)
                    469:        void *v;
                    470:        void *cookie;
                    471:        int waitok;
                    472:        void (*cb)(void *, int, int);
                    473:        void *cbarg;
                    474: {
                    475:        return (0);
                    476: }
                    477:
                    478: const struct creator_mappings {
                    479:        bus_addr_t uoff;
                    480:        bus_addr_t poff;
                    481:        bus_size_t ulen;
                    482: } creator_map[] = {
                    483:        { FFB_VOFF_SFB8R, FFB_POFF_SFB8R, FFB_VLEN_SFB8R },
                    484:        { FFB_VOFF_SFB8G, FFB_POFF_SFB8G, FFB_VLEN_SFB8G },
                    485:        { FFB_VOFF_SFB8B, FFB_POFF_SFB8B, FFB_VLEN_SFB8B },
                    486:        { FFB_VOFF_SFB8X, FFB_POFF_SFB8X, FFB_VLEN_SFB8X },
                    487:        { FFB_VOFF_SFB32, FFB_POFF_SFB32, FFB_VLEN_SFB32 },
                    488:        { FFB_VOFF_SFB64, FFB_POFF_SFB64, FFB_VLEN_SFB64 },
                    489:        { FFB_VOFF_FBC_REGS, FFB_POFF_FBC_REGS, FFB_VLEN_FBC_REGS },
                    490:        { FFB_VOFF_BM_FBC_REGS, FFB_POFF_BM_FBC_REGS, FFB_VLEN_BM_FBC_REGS },
                    491:        { FFB_VOFF_DFB8R, FFB_POFF_DFB8R, FFB_VLEN_DFB8R },
                    492:        { FFB_VOFF_DFB8G, FFB_POFF_DFB8G, FFB_VLEN_DFB8G },
                    493:        { FFB_VOFF_DFB8B, FFB_POFF_DFB8B, FFB_VLEN_DFB8B },
                    494:        { FFB_VOFF_DFB8X, FFB_POFF_DFB8X, FFB_VLEN_DFB8X },
                    495:        { FFB_VOFF_DFB24, FFB_POFF_DFB24, FFB_VLEN_DFB24 },
                    496:        { FFB_VOFF_DFB32, FFB_POFF_DFB32, FFB_VLEN_DFB32 },
                    497:        { FFB_VOFF_DFB422A, FFB_POFF_DFB422A, FFB_VLEN_DFB422A },
                    498:        { FFB_VOFF_DFB422AD, FFB_POFF_DFB422AD, FFB_VLEN_DFB422AD },
                    499:        { FFB_VOFF_DFB24B, FFB_POFF_DFB24B, FFB_VLEN_DFB24B },
                    500:        { FFB_VOFF_DFB422B, FFB_POFF_DFB422B, FFB_VLEN_DFB422B },
                    501:        { FFB_VOFF_DFB422BD, FFB_POFF_DFB422BD, FFB_VLEN_DFB422BD },
                    502:        { FFB_VOFF_SFB16Z, FFB_POFF_SFB16Z, FFB_VLEN_SFB16Z },
                    503:        { FFB_VOFF_SFB8Z, FFB_POFF_SFB8Z, FFB_VLEN_SFB8Z },
                    504:        { FFB_VOFF_SFB422, FFB_POFF_SFB422, FFB_VLEN_SFB422 },
                    505:        { FFB_VOFF_SFB422D, FFB_POFF_SFB422D, FFB_VLEN_SFB422D },
                    506:        { FFB_VOFF_FBC_KREGS, FFB_POFF_FBC_KREGS, FFB_VLEN_FBC_KREGS },
                    507:        { FFB_VOFF_DAC, FFB_POFF_DAC, FFB_VLEN_DAC },
                    508:        { FFB_VOFF_PROM, FFB_POFF_PROM, FFB_VLEN_PROM },
                    509:        { FFB_VOFF_EXP, FFB_POFF_EXP, FFB_VLEN_EXP },
                    510: };
                    511: #define        CREATOR_NMAPPINGS       (sizeof(creator_map)/sizeof(creator_map[0]))
                    512:
                    513: paddr_t
                    514: creator_mmap(vsc, off, prot)
                    515:        void *vsc;
                    516:        off_t off;
                    517:        int prot;
                    518: {
                    519:        paddr_t x;
                    520:        struct creator_softc *sc = vsc;
                    521:        int i;
                    522:
                    523:        switch (sc->sc_mode) {
                    524:        case WSDISPLAYIO_MODE_MAPPED:
                    525:                /* Turn virtual offset into physical offset */
                    526:                for (i = 0; i < CREATOR_NMAPPINGS; i++) {
                    527:                        if (off >= creator_map[i].uoff &&
                    528:                            off < (creator_map[i].uoff + creator_map[i].ulen))
                    529:                                break;
                    530:                }
                    531:                if (i == CREATOR_NMAPPINGS)
                    532:                        break;
                    533:
                    534:                off -= creator_map[i].uoff;
                    535:                off += creator_map[i].poff;
                    536:                off += sc->sc_addrs[0];
                    537:
                    538:                /* Map based on physical offset */
                    539:                for (i = 0; i < sc->sc_nreg; i++) {
                    540:                        /* Before this set? */
                    541:                        if (off < sc->sc_addrs[i])
                    542:                                continue;
                    543:                        /* After this set? */
                    544:                        if (off >= (sc->sc_addrs[i] + sc->sc_sizes[i]))
                    545:                                continue;
                    546:
                    547:                        x = bus_space_mmap(sc->sc_bt, 0, off, prot,
                    548:                            BUS_SPACE_MAP_LINEAR);
                    549:                        return (x);
                    550:                }
                    551:                break;
                    552:        case WSDISPLAYIO_MODE_DUMBFB:
                    553:                if (sc->sc_nreg <= FFB_REG_DFB24)
                    554:                        break;
                    555:                if (off >= 0 && off < sc->sc_sizes[FFB_REG_DFB24])
                    556:                        return (bus_space_mmap(sc->sc_bt,
                    557:                            sc->sc_addrs[FFB_REG_DFB24], off, prot,
                    558:                            BUS_SPACE_MAP_LINEAR));
                    559:                break;
                    560:        }
                    561:
                    562:        return (-1);
                    563: }
                    564:
                    565: void
                    566: creator_ras_fifo_wait(sc, n)
                    567:        struct creator_softc *sc;
                    568:        int n;
                    569: {
                    570:        int32_t cache = sc->sc_fifo_cache;
                    571:
                    572:        if (cache < n) {
                    573:                do {
                    574:                        cache = FBC_READ(sc, FFB_FBC_UCSR);
                    575:                        cache = (cache & FBC_UCSR_FIFO_MASK) - 8;
                    576:                } while (cache < n);
                    577:        }
                    578:        sc->sc_fifo_cache = cache - n;
                    579: }
                    580:
                    581: void
                    582: creator_ras_wait(sc)
                    583:        struct creator_softc *sc;
                    584: {
                    585:        u_int32_t ucsr, r;
                    586:
                    587:        while (1) {
                    588:                ucsr = FBC_READ(sc, FFB_FBC_UCSR);
                    589:                if ((ucsr & (FBC_UCSR_FB_BUSY|FBC_UCSR_RP_BUSY)) == 0)
                    590:                        break;
                    591:                r = ucsr & (FBC_UCSR_READ_ERR | FBC_UCSR_FIFO_OVFL);
                    592:                if (r != 0)
                    593:                        FBC_WRITE(sc, FFB_FBC_UCSR, r);
                    594:        }
                    595: }
                    596:
                    597: void
                    598: creator_ras_init(sc)
                    599:        struct creator_softc *sc;
                    600: {
                    601:        creator_ras_fifo_wait(sc, 7);
                    602:        FBC_WRITE(sc, FFB_FBC_PPC,
                    603:            FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE |
                    604:            FBC_PPC_APE_DIS | FBC_PPC_CS_CONST);
                    605:        FBC_WRITE(sc, FFB_FBC_FBC,
                    606:            FFB_FBC_WB_A | FFB_FBC_RB_A | FFB_FBC_SB_BOTH |
                    607:            FFB_FBC_XE_OFF | FFB_FBC_RGBE_MASK);
                    608:        FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW);
                    609:        FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE);
                    610:        FBC_WRITE(sc, FFB_FBC_PMASK, 0xffffffff);
                    611:        FBC_WRITE(sc, FFB_FBC_FONTINC, 0x10000);
                    612:        sc->sc_fg_cache = 0;
                    613:        FBC_WRITE(sc, FFB_FBC_FG, sc->sc_fg_cache);
                    614:        creator_ras_wait(sc);
                    615: }
                    616:
                    617: void
                    618: creator_ras_eraserows(cookie, row, n, attr)
                    619:        void *cookie;
                    620:        int row, n;
                    621:        long int attr;
                    622: {
                    623:        struct rasops_info *ri = cookie;
                    624:        struct creator_softc *sc = ri->ri_hw;
                    625:        int bg, fg;
                    626:
                    627:        if (row < 0) {
                    628:                n += row;
                    629:                row = 0;
                    630:        }
                    631:        if (row + n > ri->ri_rows)
                    632:                n = ri->ri_rows - row;
                    633:        if (n <= 0)
                    634:                return;
                    635:
                    636:        ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
                    637:        creator_ras_fill(sc);
                    638:        creator_ras_setfg(sc, ri->ri_devcmap[bg]);
                    639:        creator_ras_fifo_wait(sc, 4);
                    640:        if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) {
                    641:                FBC_WRITE(sc, FFB_FBC_BY, 0);
                    642:                FBC_WRITE(sc, FFB_FBC_BX, 0);
                    643:                FBC_WRITE(sc, FFB_FBC_BH, ri->ri_height);
                    644:                FBC_WRITE(sc, FFB_FBC_BW, ri->ri_width);
                    645:        } else {
                    646:                row *= ri->ri_font->fontheight;
                    647:                FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + row);
                    648:                FBC_WRITE(sc, FFB_FBC_BX, ri->ri_xorigin);
                    649:                FBC_WRITE(sc, FFB_FBC_BH, n * ri->ri_font->fontheight);
                    650:                FBC_WRITE(sc, FFB_FBC_BW, ri->ri_emuwidth);
                    651:        }
                    652:        creator_ras_wait(sc);
                    653: }
                    654:
                    655: void
                    656: creator_ras_erasecols(cookie, row, col, n, attr)
                    657:        void *cookie;
                    658:        int row, col, n;
                    659:        long int attr;
                    660: {
                    661:        struct rasops_info *ri = cookie;
                    662:        struct creator_softc *sc = ri->ri_hw;
                    663:        int fg, bg;
                    664:
                    665:        if ((row < 0) || (row >= ri->ri_rows))
                    666:                return;
                    667:        if (col < 0) {
                    668:                n += col;
                    669:                col = 0;
                    670:        }
                    671:        if (col + n > ri->ri_cols)
                    672:                n = ri->ri_cols - col;
                    673:        if (n <= 0)
                    674:                return;
                    675:        n *= ri->ri_font->fontwidth;
                    676:        col *= ri->ri_font->fontwidth;
                    677:        row *= ri->ri_font->fontheight;
                    678:
                    679:        ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
                    680:        creator_ras_fill(sc);
                    681:        creator_ras_setfg(sc, ri->ri_devcmap[bg]);
                    682:        creator_ras_fifo_wait(sc, 4);
                    683:        FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + row);
                    684:        FBC_WRITE(sc, FFB_FBC_BX, ri->ri_xorigin + col);
                    685:        FBC_WRITE(sc, FFB_FBC_BH, ri->ri_font->fontheight);
                    686:        FBC_WRITE(sc, FFB_FBC_BW, n - 1);
                    687:        creator_ras_wait(sc);
                    688: }
                    689:
                    690: void
                    691: creator_ras_fill(sc)
                    692:        struct creator_softc *sc;
                    693: {
                    694:        creator_ras_fifo_wait(sc, 2);
                    695:        FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW);
                    696:        FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE);
                    697:        creator_ras_wait(sc);
                    698: }
                    699:
                    700: void
                    701: creator_ras_copyrows(cookie, src, dst, n)
                    702:        void *cookie;
                    703:        int src, dst, n;
                    704: {
                    705:        struct rasops_info *ri = cookie;
                    706:        struct creator_softc *sc = ri->ri_hw;
                    707:
                    708:        if (dst == src)
                    709:                return;
                    710:        if (src < 0) {
                    711:                n += src;
                    712:                src = 0;
                    713:        }
                    714:        if ((src + n) > ri->ri_rows)
                    715:                n = ri->ri_rows - src;
                    716:        if (dst < 0) {
                    717:                n += dst;
                    718:                dst = 0;
                    719:        }
                    720:        if ((dst + n) > ri->ri_rows)
                    721:                n = ri->ri_rows - dst;
                    722:        if (n <= 0)
                    723:                return;
                    724:        n *= ri->ri_font->fontheight;
                    725:        src *= ri->ri_font->fontheight;
                    726:        dst *= ri->ri_font->fontheight;
                    727:
                    728:        creator_ras_fifo_wait(sc, 8);
                    729:        FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_OLD | (FBC_ROP_OLD << 8));
                    730:        FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_VSCROLL);
                    731:        FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + src);
                    732:        FBC_WRITE(sc, FFB_FBC_BX, ri->ri_xorigin);
                    733:        FBC_WRITE(sc, FFB_FBC_DY, ri->ri_yorigin + dst);
                    734:        FBC_WRITE(sc, FFB_FBC_DX, ri->ri_xorigin);
                    735:        FBC_WRITE(sc, FFB_FBC_BH, n);
                    736:        FBC_WRITE(sc, FFB_FBC_BW, ri->ri_emuwidth);
                    737:        creator_ras_wait(sc);
                    738: }
                    739:
                    740: void
                    741: creator_ras_setfg(sc, fg)
                    742:        struct creator_softc *sc;
                    743:        int32_t fg;
                    744: {
                    745:        creator_ras_fifo_wait(sc, 1);
                    746:        if (fg == sc->sc_fg_cache)
                    747:                return;
                    748:        sc->sc_fg_cache = fg;
                    749:        FBC_WRITE(sc, FFB_FBC_FG, fg);
                    750:        creator_ras_wait(sc);
                    751: }

CVSweb