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

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

1.1       nbrk        1: /*     $OpenBSD: cgsix.c,v 1.56 2006/12/17 22:18:16 miod Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2001 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:  * Effort sponsored in part by the Defense Advanced Research Projects
                     29:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
                     30:  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
                     31:  *
                     32:  */
                     33:
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/kernel.h>
                     37: #include <sys/errno.h>
                     38: #include <sys/device.h>
                     39: #include <sys/ioctl.h>
                     40: #include <sys/malloc.h>
                     41:
                     42: #include <machine/bus.h>
                     43: #include <machine/intr.h>
                     44: #include <machine/autoconf.h>
                     45: #include <machine/openfirm.h>
                     46:
                     47: #include <dev/sbus/sbusvar.h>
                     48: #include <dev/wscons/wsconsio.h>
                     49: #include <dev/wscons/wsdisplayvar.h>
                     50: #include <dev/rasops/rasops.h>
                     51: #include <machine/fbvar.h>
                     52: #include <dev/sbus/cgsixreg.h>
                     53: #include <dev/ic/bt458reg.h>
                     54:
                     55: int cgsix_ioctl(void *, u_long, caddr_t, int, struct proc *);
                     56: int cgsix_alloc_screen(void *, const struct wsscreen_descr *, void **,
                     57:     int *, int *, long *);
                     58: void cgsix_free_screen(void *, void *);
                     59: int cgsix_show_screen(void *, void *, int, void (*cb)(void *, int, int),
                     60:     void *);
                     61: paddr_t cgsix_mmap(void *, off_t, int);
                     62: int cgsix_is_console(int);
                     63: int cg6_bt_getcmap(union bt_cmap *, struct wsdisplay_cmap *);
                     64: int cg6_bt_putcmap(union bt_cmap *, struct wsdisplay_cmap *);
                     65: void cgsix_loadcmap_immediate(struct cgsix_softc *, u_int, u_int);
                     66: void cgsix_loadcmap_deferred(struct cgsix_softc *, u_int, u_int);
                     67: void cgsix_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
                     68: void cgsix_reset(struct cgsix_softc *, u_int32_t);
                     69: void cgsix_hardreset(struct cgsix_softc *);
                     70: void cgsix_burner(void *, u_int, u_int);
                     71: int cgsix_intr(void *);
                     72: void cgsix_ras_init(struct cgsix_softc *);
                     73: void cgsix_ras_copyrows(void *, int, int, int);
                     74: void cgsix_ras_copycols(void *, int, int, int, int);
                     75: void cgsix_ras_erasecols(void *, int, int, int, long int);
                     76: void cgsix_ras_eraserows(void *, int, int, long int);
                     77: void cgsix_ras_do_cursor(struct rasops_info *);
                     78: int cgsix_setcursor(struct cgsix_softc *, struct wsdisplay_cursor *);
                     79: int cgsix_updatecursor(struct cgsix_softc *, u_int);
                     80:
                     81: struct wsdisplay_accessops cgsix_accessops = {
                     82:        cgsix_ioctl,
                     83:        cgsix_mmap,
                     84:        cgsix_alloc_screen,
                     85:        cgsix_free_screen,
                     86:        cgsix_show_screen,
                     87:        NULL,   /* load_font */
                     88:        NULL,   /* scrollback */
                     89:        NULL,   /* getchar */
                     90:        cgsix_burner,
                     91: };
                     92:
                     93: int    cgsixmatch(struct device *, void *, void *);
                     94: void   cgsixattach(struct device *, struct device *, void *);
                     95:
                     96: struct cfattach cgsix_ca = {
                     97:        sizeof (struct cgsix_softc), cgsixmatch, cgsixattach
                     98: };
                     99:
                    100: struct cfdriver cgsix_cd = {
                    101:        NULL, "cgsix", DV_DULL
                    102: };
                    103:
                    104: int
                    105: cgsixmatch(struct device *parent, void *vcf, void *aux)
                    106: {
                    107:        struct cfdata *cf = vcf;
                    108:        struct sbus_attach_args *sa = aux;
                    109:
                    110:        return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0);
                    111: }
                    112:
                    113: void
                    114: cgsixattach(struct device *parent, struct device *self, void *aux)
                    115: {
                    116:        struct cgsix_softc *sc = (struct cgsix_softc *)self;
                    117:        struct sbus_attach_args *sa = aux;
                    118:        int node, console;
                    119:        u_int32_t fhc, rev;
                    120:        const char *nam;
                    121:
                    122:        node = sa->sa_node;
                    123:        sc->sc_bustag = sa->sa_bustag;
                    124:        sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset);
                    125:
                    126:        if (sa->sa_nreg != 1) {
                    127:                printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
                    128:                goto fail;
                    129:        }
                    130:
                    131:        fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);
                    132:
                    133:        /*
                    134:         * Map just BT, FHC, FBC, THC, and video RAM.
                    135:         */
                    136:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
                    137:            sa->sa_reg[0].sbr_offset + CGSIX_BT_OFFSET,
                    138:            CGSIX_BT_SIZE, 0, 0, &sc->sc_bt_regs) != 0) {
                    139:                printf(": cannot map bt registers\n");
                    140:                goto fail_bt;
                    141:        }
                    142:
                    143:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
                    144:            sa->sa_reg[0].sbr_offset + CGSIX_FHC_OFFSET,
                    145:            CGSIX_FHC_SIZE, 0, 0, &sc->sc_fhc_regs) != 0) {
                    146:                printf(": cannot map fhc registers\n");
                    147:                goto fail_fhc;
                    148:        }
                    149:
                    150:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
                    151:            sa->sa_reg[0].sbr_offset + CGSIX_THC_OFFSET,
                    152:            CGSIX_THC_SIZE, 0, 0, &sc->sc_thc_regs) != 0) {
                    153:                printf(": cannot map thc registers\n");
                    154:                goto fail_thc;
                    155:        }
                    156:
                    157:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
                    158:            sa->sa_reg[0].sbr_offset + CGSIX_VID_OFFSET,
                    159:            sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR,
                    160:            0, &sc->sc_vid_regs) != 0) {
                    161:                printf(": cannot map vid registers\n");
                    162:                goto fail_vid;
                    163:        }
                    164:
                    165:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
                    166:            sa->sa_reg[0].sbr_offset + CGSIX_TEC_OFFSET,
                    167:            CGSIX_TEC_SIZE, 0, 0, &sc->sc_tec_regs) != 0) {
                    168:                printf(": cannot map tec registers\n");
                    169:                goto fail_tec;
                    170:        }
                    171:
                    172:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
                    173:            sa->sa_reg[0].sbr_offset + CGSIX_FBC_OFFSET,
                    174:            CGSIX_FBC_SIZE, 0, 0, &sc->sc_fbc_regs) != 0) {
                    175:                printf(": cannot map fbc registers\n");
                    176:                goto fail_fbc;
                    177:        }
                    178:
                    179:        if ((sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri,
                    180:            IPL_TTY, 0, cgsix_intr, sc, self->dv_xname)) == NULL) {
                    181:                printf(": couldn't establish interrupt, pri %d\n%s",
                    182:                    INTLEV(sa->sa_pri), self->dv_xname);
                    183:        }
                    184:
                    185:        /* if prom didn't initialize us, do it the hard way */
                    186:        if (OF_getproplen(node, "width") != sizeof(u_int32_t))
                    187:                cgsix_hardreset(sc);
                    188:
                    189:        nam = getpropstring(node, "model");
                    190:        if (*nam == '\0')
                    191:                nam = sa->sa_name;
                    192:        printf(": %s", nam);
                    193:
                    194:        console = cgsix_is_console(node);
                    195:
                    196:        fhc = FHC_READ(sc);
                    197:        rev = (fhc & FHC_REV_MASK) >> FHC_REV_SHIFT;
                    198:        cgsix_reset(sc, rev);
                    199:
                    200:        cgsix_burner(sc, 1, 0);
                    201:
                    202:        sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag,
                    203:            sc->sc_vid_regs);
                    204:        sc->sc_sunfb.sf_ro.ri_hw = sc;
                    205:        fbwscons_init(&sc->sc_sunfb, console ? 0 : RI_CLEAR);
                    206:
                    207:        /*
                    208:         * Old rev. cg6 cards do not like the current acceleration code.
                    209:         *
                    210:         * Some hints from Sun point out at timing and cache problems, which
                    211:         * will be investigated later.
                    212:         */
                    213:        if (rev < 5)
                    214:                sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags |= CG6_CFFLAG_NOACCEL;
                    215:
                    216:        if ((sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags & CG6_CFFLAG_NOACCEL)
                    217:            == 0) {
                    218:                sc->sc_sunfb.sf_ro.ri_ops.copyrows = cgsix_ras_copyrows;
                    219:                sc->sc_sunfb.sf_ro.ri_ops.copycols = cgsix_ras_copycols;
                    220:                sc->sc_sunfb.sf_ro.ri_ops.eraserows = cgsix_ras_eraserows;
                    221:                sc->sc_sunfb.sf_ro.ri_ops.erasecols = cgsix_ras_erasecols;
                    222:                sc->sc_sunfb.sf_ro.ri_do_cursor = cgsix_ras_do_cursor;
                    223:                cgsix_ras_init(sc);
                    224:        }
                    225:
                    226:        printf(", %dx%d, rev %d\n", sc->sc_sunfb.sf_width,
                    227:            sc->sc_sunfb.sf_height, rev);
                    228:
                    229:        fbwscons_setcolormap(&sc->sc_sunfb, cgsix_setcolor);
                    230:
                    231:        if (console) {
                    232:                fbwscons_console_init(&sc->sc_sunfb, -1);
                    233:        }
                    234:
                    235:        fbwscons_attach(&sc->sc_sunfb, &cgsix_accessops, console);
                    236:
                    237:        return;
                    238:
                    239: fail_fbc:
                    240:        bus_space_unmap(sa->sa_bustag, sc->sc_tec_regs, CGSIX_TEC_SIZE);
                    241: fail_tec:
                    242:        bus_space_unmap(sa->sa_bustag, sc->sc_vid_regs, sc->sc_sunfb.sf_fbsize);
                    243: fail_vid:
                    244:        bus_space_unmap(sa->sa_bustag, sc->sc_thc_regs, CGSIX_THC_SIZE);
                    245: fail_thc:
                    246:        bus_space_unmap(sa->sa_bustag, sc->sc_fhc_regs, CGSIX_FHC_SIZE);
                    247: fail_fhc:
                    248:        bus_space_unmap(sa->sa_bustag, sc->sc_bt_regs, CGSIX_BT_SIZE);
                    249: fail_bt:
                    250: fail:
                    251:        return;
                    252: }
                    253:
                    254: int
                    255: cgsix_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
                    256: {
                    257:        struct cgsix_softc *sc = v;
                    258:        struct wsdisplay_cmap *cm;
                    259:        struct wsdisplay_fbinfo *wdf;
                    260:        struct wsdisplay_cursor *curs;
                    261:        struct wsdisplay_curpos *pos;
                    262:        u_char r[2], g[2], b[2];
                    263:        int error, s;
                    264:        u_int mode;
                    265:
                    266:        switch (cmd) {
                    267:        case WSDISPLAYIO_GTYPE:
                    268:                *(u_int *)data = WSDISPLAY_TYPE_SUNCG6;
                    269:                break;
                    270:        case WSDISPLAYIO_SMODE:
                    271:                mode = *(u_int *)data;
                    272:                if ((sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags &
                    273:                    CG6_CFFLAG_NOACCEL) == 0) {
                    274:                        if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL &&
                    275:                            mode == WSDISPLAYIO_MODE_EMUL)
                    276:                                cgsix_ras_init(sc);
                    277:                }
                    278:                sc->sc_mode = mode;
                    279:                break;
                    280:        case WSDISPLAYIO_GINFO:
                    281:                wdf = (void *)data;
                    282:                wdf->height = sc->sc_sunfb.sf_height;
                    283:                wdf->width  = sc->sc_sunfb.sf_width;
                    284:                wdf->depth  = sc->sc_sunfb.sf_depth;
                    285:                wdf->cmsize = 256;
                    286:                break;
                    287:        case WSDISPLAYIO_LINEBYTES:
                    288:                *(u_int *)data = sc->sc_sunfb.sf_linebytes;
                    289:                break;
                    290:        case WSDISPLAYIO_GETCMAP:
                    291:                cm = (struct wsdisplay_cmap *)data;
                    292:                error = cg6_bt_getcmap(&sc->sc_cmap, cm);
                    293:                if (error)
                    294:                        return (error);
                    295:                break;
                    296:        case WSDISPLAYIO_PUTCMAP:
                    297:                cm = (struct wsdisplay_cmap *)data;
                    298:                error = cg6_bt_putcmap(&sc->sc_cmap, cm);
                    299:                if (error)
                    300:                        return (error);
                    301:                /* if we can handle interrupts, defer the update */
                    302:                if (sc->sc_ih != NULL)
                    303:                        cgsix_loadcmap_deferred(sc, cm->index, cm->count);
                    304:                else
                    305:                        cgsix_loadcmap_immediate(sc, cm->index, cm->count);
                    306:                break;
                    307:        case WSDISPLAYIO_SCURSOR:
                    308:                curs = (struct wsdisplay_cursor *)data;
                    309:                return (cgsix_setcursor(sc, curs));
                    310:        case WSDISPLAYIO_GCURSOR:
                    311:                curs = (struct wsdisplay_cursor *)data;
                    312:                if (curs->which & WSDISPLAY_CURSOR_DOCUR)
                    313:                        curs->enable = sc->sc_curs_enabled;
                    314:                if (curs->which & WSDISPLAY_CURSOR_DOPOS) {
                    315:                        curs->pos.x = sc->sc_curs_pos.x;
                    316:                        curs->pos.y = sc->sc_curs_pos.y;
                    317:                }
                    318:                if (curs->which & WSDISPLAY_CURSOR_DOHOT) {
                    319:                        curs->hot.x = sc->sc_curs_hot.x;
                    320:                        curs->hot.y = sc->sc_curs_hot.y;
                    321:                }
                    322:                if (curs->which & WSDISPLAY_CURSOR_DOCMAP) {
                    323:                        curs->cmap.index = 0;
                    324:                        curs->cmap.count = 2;
                    325:                        r[0] = sc->sc_curs_fg >> 16;
                    326:                        g[0] = sc->sc_curs_fg >> 8;
                    327:                        b[0] = sc->sc_curs_fg >> 0;
                    328:                        r[1] = sc->sc_curs_bg >> 16;
                    329:                        g[1] = sc->sc_curs_bg >> 8;
                    330:                        b[1] = sc->sc_curs_bg >> 0;
                    331:                        error = copyout(r, curs->cmap.red, sizeof(r));
                    332:                        if (error)
                    333:                                return (error);
                    334:                        error = copyout(g, curs->cmap.green, sizeof(g));
                    335:                        if (error)
                    336:                                return (error);
                    337:                        error = copyout(b, curs->cmap.blue, sizeof(b));
                    338:                        if (error)
                    339:                                return (error);
                    340:                }
                    341:                if (curs->which & WSDISPLAY_CURSOR_DOSHAPE) {
                    342:                        size_t l;
                    343:
                    344:                        curs->size.x = sc->sc_curs_size.x;
                    345:                        curs->size.y = sc->sc_curs_size.y;
                    346:                        l = (sc->sc_curs_size.x * sc->sc_curs_size.y) / NBBY;
                    347:                        error = copyout(sc->sc_curs_image, curs->image, l);
                    348:                        if (error)
                    349:                                return (error);
                    350:                        error = copyout(sc->sc_curs_mask, curs->mask, l);
                    351:                        if (error)
                    352:                                return (error);
                    353:                }
                    354:                break;
                    355:        case WSDISPLAYIO_GCURPOS:
                    356:                pos = (struct wsdisplay_curpos *)data;
                    357:                pos->x = sc->sc_curs_pos.x;
                    358:                pos->y = sc->sc_curs_pos.y;
                    359:                break;
                    360:        case WSDISPLAYIO_SCURPOS:
                    361:                pos = (struct wsdisplay_curpos *)data;
                    362:                s = spltty();
                    363:                sc->sc_curs_pos.x = pos->x;
                    364:                sc->sc_curs_pos.y = pos->y;
                    365:                cgsix_updatecursor(sc, WSDISPLAY_CURSOR_DOPOS);
                    366:                splx(s);
                    367:                break;
                    368:        case WSDISPLAYIO_GCURMAX:
                    369:                pos = (struct wsdisplay_curpos *)data;
                    370:                pos->x = pos->y = 32;
                    371:                break;
                    372:        case WSDISPLAYIO_SVIDEO:
                    373:        case WSDISPLAYIO_GVIDEO:
                    374:                break;
                    375:        default:
                    376:                return -1; /* not supported */
                    377:         }
                    378:
                    379:        return (0);
                    380: }
                    381:
                    382: int
                    383: cgsix_setcursor(struct cgsix_softc *sc, struct wsdisplay_cursor *curs)
                    384: {
                    385:        u_int8_t r[2], g[2], b[2], image[128], mask[128];
                    386:        int s, error;
                    387:        size_t imcount;
                    388:
                    389:        /*
                    390:         * Do stuff that can generate errors first, then we'll blast it
                    391:         * all at once.
                    392:         */
                    393:        if (curs->which & WSDISPLAY_CURSOR_DOCMAP) {
                    394:                if (curs->cmap.count < 2)
                    395:                        return (EINVAL);
                    396:                error = copyin(curs->cmap.red, r, sizeof(r));
                    397:                if (error)
                    398:                        return (error);
                    399:                error = copyin(curs->cmap.green, g, sizeof(g));
                    400:                if (error)
                    401:                        return (error);
                    402:                error = copyin(curs->cmap.blue, b, sizeof(b));
                    403:                if (error)
                    404:                        return (error);
                    405:        }
                    406:
                    407:        if (curs->which & WSDISPLAY_CURSOR_DOSHAPE) {
                    408:                if (curs->size.x > CG6_MAX_CURSOR ||
                    409:                    curs->size.y > CG6_MAX_CURSOR)
                    410:                        return (EINVAL);
                    411:                imcount = (curs->size.x * curs->size.y) / NBBY;
                    412:                error = copyin(curs->image, image, imcount);
                    413:                if (error)
                    414:                        return (error);
                    415:                error = copyin(curs->mask, mask, imcount);
                    416:                if (error)
                    417:                        return (error);
                    418:        }
                    419:
                    420:        /*
                    421:         * Ok, everything is in kernel space and sane, update state.
                    422:         */
                    423:        s = spltty();
                    424:
                    425:        if (curs->which & WSDISPLAY_CURSOR_DOCUR)
                    426:                sc->sc_curs_enabled = curs->enable;
                    427:        if (curs->which & WSDISPLAY_CURSOR_DOPOS) {
                    428:                sc->sc_curs_pos.x = curs->pos.x;
                    429:                sc->sc_curs_pos.y = curs->pos.y;
                    430:        }
                    431:        if (curs->which & WSDISPLAY_CURSOR_DOHOT) {
                    432:                sc->sc_curs_hot.x = curs->hot.x;
                    433:                sc->sc_curs_hot.y = curs->hot.y;
                    434:        }
                    435:        if (curs->which & WSDISPLAY_CURSOR_DOCMAP) {
                    436:                sc->sc_curs_fg = ((r[0] << 16) | (g[0] << 8) | (b[0] << 0));
                    437:                sc->sc_curs_bg = ((r[1] << 16) | (g[1] << 8) | (b[1] << 0));
                    438:        }
                    439:        if (curs->which & WSDISPLAY_CURSOR_DOSHAPE) {
                    440:                sc->sc_curs_size.x = curs->size.x;
                    441:                sc->sc_curs_size.y = curs->size.y;
                    442:                bcopy(image, sc->sc_curs_image, imcount);
                    443:                bcopy(mask, sc->sc_curs_mask, imcount);
                    444:        }
                    445:
                    446:        cgsix_updatecursor(sc, curs->which);
                    447:        splx(s);
                    448:
                    449:        return (0);
                    450: }
                    451:
                    452: int
                    453: cgsix_updatecursor(struct cgsix_softc *sc, u_int which)
                    454: {
                    455:        if (which & WSDISPLAY_CURSOR_DOCMAP) {
                    456:                BT_WRITE(sc, BT_ADDR, BT_OV1 << 24);
                    457:                BT_WRITE(sc, BT_OMAP,
                    458:                    ((sc->sc_curs_fg & 0x00ff0000) >> 16) << 24);
                    459:                BT_WRITE(sc, BT_OMAP,
                    460:                    ((sc->sc_curs_fg & 0x0000ff00) >> 8) << 24);
                    461:                BT_WRITE(sc, BT_OMAP,
                    462:                    ((sc->sc_curs_fg & 0x000000ff) >> 0) << 24);
                    463:
                    464:                BT_WRITE(sc, BT_ADDR, BT_OV3 << 24);
                    465:                BT_WRITE(sc, BT_OMAP,
                    466:                    ((sc->sc_curs_bg & 0x00ff0000) >> 16) << 24);
                    467:                BT_WRITE(sc, BT_OMAP,
                    468:                    ((sc->sc_curs_bg & 0x0000ff00) >> 8) << 24);
                    469:                BT_WRITE(sc, BT_OMAP,
                    470:                    ((sc->sc_curs_bg & 0x000000ff) >> 0) << 24);
                    471:        }
                    472:
                    473:        if (which & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
                    474:                u_int32_t x, y;
                    475:
                    476:                x = sc->sc_curs_pos.x + CG6_MAX_CURSOR - sc->sc_curs_hot.x;
                    477:                y = sc->sc_curs_pos.y + CG6_MAX_CURSOR - sc->sc_curs_hot.y;
                    478:                THC_WRITE(sc, CG6_THC_CURSXY,
                    479:                    ((x & 0xffff) << 16) | (y & 0xffff));
                    480:        }
                    481:
                    482:        if (which & WSDISPLAY_CURSOR_DOCUR) {
                    483:                u_int32_t c;
                    484:
                    485:                /* Enable or disable the cursor overlay planes */
                    486:                if (sc->sc_curs_enabled) {
                    487:                        BT_WRITE(sc, BT_ADDR, BT_CR << 24);
                    488:                        c = BT_READ(sc, BT_CTRL);
                    489:                        c |= (BTCR_DISPENA_OV0 | BTCR_DISPENA_OV1) << 24;
                    490:                        BT_WRITE(sc, BT_CTRL, c);
                    491:                } else {
                    492:                        BT_WRITE(sc, BT_ADDR, BT_CR << 24);
                    493:                        c = BT_READ(sc, BT_CTRL);
                    494:                        c &= ~((BTCR_DISPENA_OV0 | BTCR_DISPENA_OV1) << 24);
                    495:                        BT_WRITE(sc, BT_CTRL, c);
                    496:                        THC_WRITE(sc, CG6_THC_CURSXY, THC_CURSOFF);
                    497:                }
                    498:        }
                    499:
                    500:        return (0);
                    501: }
                    502:
                    503: int
                    504: cgsix_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
                    505:     int *curxp, int *curyp, long *attrp)
                    506: {
                    507:        struct cgsix_softc *sc = v;
                    508:
                    509:        if (sc->sc_nscreens > 0)
                    510:                return (ENOMEM);
                    511:
                    512:        *cookiep = &sc->sc_sunfb.sf_ro;
                    513:        *curyp = 0;
                    514:        *curxp = 0;
                    515:        sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
                    516:            WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp);
                    517:        sc->sc_nscreens++;
                    518:        return (0);
                    519: }
                    520:
                    521: void
                    522: cgsix_free_screen(void *v, void *cookie)
                    523: {
                    524:        struct cgsix_softc *sc = v;
                    525:
                    526:        sc->sc_nscreens--;
                    527: }
                    528:
                    529: int
                    530: cgsix_show_screen(void *v, void *cookie, int waitok,
                    531:     void (*cb)(void *, int, int), void *cbarg)
                    532: {
                    533:        return (0);
                    534: }
                    535:
                    536: struct mmo {
                    537:        off_t mo_uaddr;
                    538:        bus_size_t mo_size;
                    539:        bus_size_t mo_physoff;
                    540: };
                    541:
                    542: paddr_t
                    543: cgsix_mmap(void *v, off_t off, int prot)
                    544: {
                    545:        struct cgsix_softc *sc = v;
                    546:        struct mmo *mo;
                    547:        bus_addr_t u;
                    548:        bus_size_t sz;
                    549:
                    550:        static struct mmo mmo[] = {
                    551:                { CG6_USER_RAM, 0, CGSIX_VID_OFFSET },
                    552:
                    553:                /* do not actually know how big most of these are! */
                    554:                { CG6_USER_FBC, 1, CGSIX_FBC_OFFSET },
                    555:                { CG6_USER_TEC, 1, CGSIX_TEC_OFFSET },
                    556:                { CG6_USER_BTREGS, 8192 /* XXX */, CGSIX_BT_OFFSET },
                    557:                { CG6_USER_FHC, 1, CGSIX_FHC_OFFSET },
                    558:                { CG6_USER_THC, CGSIX_THC_SIZE, CGSIX_THC_OFFSET },
                    559:                { CG6_USER_ROM, 65536, CGSIX_ROM_OFFSET },
                    560:                { CG6_USER_DHC, 1, CGSIX_DHC_OFFSET },
                    561:        };
                    562: #define        NMMO (sizeof mmo / sizeof *mmo)
                    563:
                    564:        if (off & PGOFSET || off < 0)
                    565:                return (-1);
                    566:
                    567:        switch (sc->sc_mode) {
                    568:        case WSDISPLAYIO_MODE_MAPPED:
                    569:                for (mo = mmo; mo < &mmo[NMMO]; mo++) {
                    570:                        if (off < mo->mo_uaddr)
                    571:                                continue;
                    572:                        u = off - mo->mo_uaddr;
                    573:                        sz = mo->mo_size ? mo->mo_size : sc->sc_sunfb.sf_fbsize;
                    574:                        if (u < sz) {
                    575:                                return (bus_space_mmap(sc->sc_bustag,
                    576:                                    sc->sc_paddr, u + mo->mo_physoff,
                    577:                                    prot, BUS_SPACE_MAP_LINEAR));
                    578:                        }
                    579:                }
                    580:                break;
                    581:
                    582:        case WSDISPLAYIO_MODE_DUMBFB:
                    583:                /* Allow mapping as a dumb framebuffer from offset 0 */
                    584:                if (off >= 0 && off < sc->sc_sunfb.sf_fbsize)
                    585:                        return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
                    586:                            off + CGSIX_VID_OFFSET, prot,
                    587:                            BUS_SPACE_MAP_LINEAR));
                    588:                break;
                    589:        }
                    590:
                    591:        return (-1);
                    592: }
                    593:
                    594: int
                    595: cgsix_is_console(int node)
                    596: {
                    597:        extern int fbnode;
                    598:
                    599:        return (fbnode == node);
                    600: }
                    601:
                    602: int
                    603: cg6_bt_getcmap(union bt_cmap *bcm, struct wsdisplay_cmap *rcm)
                    604: {
                    605:        u_int index = rcm->index, count = rcm->count, i;
                    606:        int error;
                    607:
                    608:        if (index >= 256 || count > 256 - index)
                    609:                return (EINVAL);
                    610:        for (i = 0; i < count; i++) {
                    611:                if ((error = copyout(&bcm->cm_map[index + i][0],
                    612:                    &rcm->red[i], 1)) != 0)
                    613:                        return (error);
                    614:                if ((error = copyout(&bcm->cm_map[index + i][1],
                    615:                    &rcm->green[i], 1)) != 0)
                    616:                        return (error);
                    617:                if ((error = copyout(&bcm->cm_map[index + i][2],
                    618:                    &rcm->blue[i], 1)) != 0)
                    619:                        return (error);
                    620:        }
                    621:        return (0);
                    622: }
                    623:
                    624: int
                    625: cg6_bt_putcmap(union bt_cmap *bcm, struct wsdisplay_cmap *rcm)
                    626: {
                    627:        u_int index = rcm->index, count = rcm->count, i;
                    628:        int error;
                    629:
                    630:        if (index >= 256 || count > 256 - index)
                    631:                return (EINVAL);
                    632:        for (i = 0; i < count; i++) {
                    633:                if ((error = copyin(&rcm->red[i],
                    634:                    &bcm->cm_map[index + i][0], 1)) != 0)
                    635:                        return (error);
                    636:                if ((error = copyin(&rcm->green[i],
                    637:                    &bcm->cm_map[index + i][1], 1)) != 0)
                    638:                        return (error);
                    639:                if ((error = copyin(&rcm->blue[i],
                    640:                    &bcm->cm_map[index + i][2], 1)) != 0)
                    641:                        return (error);
                    642:        }
                    643:        return (0);
                    644: }
                    645:
                    646: void
                    647: cgsix_loadcmap_deferred(struct cgsix_softc *sc, u_int start, u_int ncolors)
                    648: {
                    649:        u_int32_t thcm;
                    650:
                    651:        thcm = THC_READ(sc, CG6_THC_MISC);
                    652:        thcm &= ~THC_MISC_RESET;
                    653:        thcm |= THC_MISC_INTEN;
                    654:        THC_WRITE(sc, CG6_THC_MISC, thcm);
                    655: }
                    656:
                    657: void
                    658: cgsix_loadcmap_immediate(struct cgsix_softc *sc, u_int start, u_int ncolors)
                    659: {
                    660:        u_int cstart;
                    661:        u_int32_t v;
                    662:        int count;
                    663:
                    664:        cstart = BT_D4M3(start);
                    665:        count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
                    666:        BT_WRITE(sc, BT_ADDR, BT_D4M4(start) << 24);
                    667:        while (--count >= 0) {
                    668:                v = sc->sc_cmap.cm_chip[cstart];
                    669:                BT_WRITE(sc, BT_CMAP, v << 0);
                    670:                BT_WRITE(sc, BT_CMAP, v << 8);
                    671:                BT_WRITE(sc, BT_CMAP, v << 16);
                    672:                BT_WRITE(sc, BT_CMAP, v << 24);
                    673:                cstart++;
                    674:        }
                    675: }
                    676:
                    677: void
                    678: cgsix_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
                    679: {
                    680:        struct cgsix_softc *sc = v;
                    681:        union bt_cmap *bcm = &sc->sc_cmap;
                    682:
                    683:        bcm->cm_map[index][0] = r;
                    684:        bcm->cm_map[index][1] = g;
                    685:        bcm->cm_map[index][2] = b;
                    686:        cgsix_loadcmap_immediate(sc, index, 1);
                    687: }
                    688:
                    689: void
                    690: cgsix_reset(struct cgsix_softc *sc, u_int32_t fhcrev)
                    691: {
                    692:        u_int32_t fhc;
                    693:
                    694:        /* hide the cursor, just in case */
                    695:        THC_WRITE(sc, CG6_THC_CURSXY, THC_CURSOFF);
                    696:
                    697:        TEC_WRITE(sc, CG6_TEC_MV, 0);
                    698:        TEC_WRITE(sc, CG6_TEC_CLIP, 0);
                    699:        TEC_WRITE(sc, CG6_TEC_VDC, 0);
                    700:
                    701:        /* take core of hardware bugs in old revisions */
                    702:        if (fhcrev < 5) {
                    703:                /*
                    704:                 * Keep current resolution; set cpu to 68020, set test
                    705:                 * window (size 1Kx1K), and for rev 1, disable dest cache.
                    706:                 */
                    707:                fhc = FHC_READ(sc);
                    708:                fhc &= FHC_RES_MASK;
                    709:                fhc |= FHC_CPU_68020 | FHC_TEST |
                    710:                    (11 << FHC_TESTX_SHIFT) | (11 << FHC_TESTY_SHIFT);
                    711:                if (fhcrev < 2)
                    712:                        fhc |= FHC_DST_DISABLE;
                    713:                FHC_WRITE(sc, fhc);
                    714:        }
                    715:
                    716:        /* enable cursor overlays in brooktree DAC */
                    717:        BT_WRITE(sc, BT_ADDR, BT_CR << 24);
                    718:        BT_WRITE(sc, BT_CTRL, BT_READ(sc, BT_CTRL) |
                    719:            ((BTCR_DISPENA_OV1 | BTCR_DISPENA_OV0) << 24));
                    720: }
                    721:
                    722: void
                    723: cgsix_hardreset(struct cgsix_softc *sc)
                    724: {
                    725:        u_int32_t fhc, rev;
                    726:
                    727:        /* enable all of the bit planes */
                    728:        BT_WRITE(sc, BT_ADDR, BT_RMR << 24);
                    729:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
                    730:        BT_WRITE(sc, BT_CTRL, 0xff << 24);
                    731:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
                    732:
                    733:        /* no bit planes should blink */
                    734:        BT_WRITE(sc, BT_ADDR, BT_BMR << 24);
                    735:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
                    736:        BT_WRITE(sc, BT_CTRL, 0x00 << 24);
                    737:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
                    738:
                    739:        /*
                    740:         * enable the RAMDAC, disable blink, disable overlay 0 and 1,
                    741:         * use 4:1 multiplexor.
                    742:         */
                    743:        BT_WRITE(sc, BT_ADDR, BT_CR << 24);
                    744:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
                    745:        BT_WRITE(sc, BT_CTRL,
                    746:            (BTCR_MPLX_4 | BTCR_RAMENA | BTCR_BLINK_6464) << 24);
                    747:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
                    748:
                    749:        /* disable the D/A read pins */
                    750:        BT_WRITE(sc, BT_ADDR, BT_CTR << 24);
                    751:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
                    752:        BT_WRITE(sc, BT_CTRL, 0x00 << 24);
                    753:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
                    754:
                    755:        /* configure thc */
                    756:        THC_WRITE(sc, CG6_THC_MISC, THC_MISC_RESET | THC_MISC_INTR |
                    757:            THC_MISC_CYCLS);
                    758:        THC_WRITE(sc, CG6_THC_MISC, THC_MISC_INTR | THC_MISC_CYCLS);
                    759:
                    760:        THC_WRITE(sc, CG6_THC_HSYNC1, 0x10009);
                    761:        THC_WRITE(sc, CG6_THC_HSYNC2, 0x570000);
                    762:        THC_WRITE(sc, CG6_THC_HSYNC3, 0x15005d);
                    763:        THC_WRITE(sc, CG6_THC_VSYNC1, 0x10005);
                    764:        THC_WRITE(sc, CG6_THC_VSYNC2, 0x2403a8);
                    765:        THC_WRITE(sc, CG6_THC_REFRESH, 0x16b);
                    766:
                    767:        THC_WRITE(sc, CG6_THC_MISC, THC_MISC_RESET | THC_MISC_INTR |
                    768:            THC_MISC_CYCLS);
                    769:        THC_WRITE(sc, CG6_THC_MISC, THC_MISC_INTR | THC_MISC_CYCLS);
                    770:
                    771:        /* configure fhc (1152x900) */
                    772:        fhc = FHC_READ(sc);
                    773:        rev = (fhc & FHC_REV_MASK) >> FHC_REV_SHIFT;
                    774:
                    775:        fhc = FHC_RES_1152 | FHC_CPU_68020 | FHC_TEST;
                    776:        if (rev < 1)
                    777:                fhc |= FHC_FROP_DISABLE;
                    778:        if (rev < 2)
                    779:                fhc |= FHC_DST_DISABLE;
                    780:        FHC_WRITE(sc, fhc);
                    781: }
                    782:
                    783: void
                    784: cgsix_burner(void *vsc, u_int on, u_int flags)
                    785: {
                    786:        struct cgsix_softc *sc = vsc;
                    787:        int s;
                    788:        u_int32_t thcm;
                    789:
                    790:        s = splhigh();
                    791:        thcm = THC_READ(sc, CG6_THC_MISC);
                    792:        if (on)
                    793:                thcm |= THC_MISC_VIDEN | THC_MISC_SYNCEN;
                    794:        else {
                    795:                thcm &= ~THC_MISC_VIDEN;
                    796:                if (flags & WSDISPLAY_BURN_VBLANK)
                    797:                        thcm &= ~THC_MISC_SYNCEN;
                    798:        }
                    799:        THC_WRITE(sc, CG6_THC_MISC, thcm);
                    800:        splx(s);
                    801: }
                    802:
                    803: int
                    804: cgsix_intr(void *vsc)
                    805: {
                    806:        struct cgsix_softc *sc = vsc;
                    807:        u_int32_t thcm;
                    808:
                    809:        thcm = THC_READ(sc, CG6_THC_MISC);
                    810:        if ((thcm & (THC_MISC_INTEN | THC_MISC_INTR)) !=
                    811:            (THC_MISC_INTEN | THC_MISC_INTR)) {
                    812:                /* Not expecting an interrupt, it's not for us. */
                    813:                return (0);
                    814:        }
                    815:
                    816:        /* Acknowledge the interrupt and disable it. */
                    817:        thcm &= ~(THC_MISC_RESET | THC_MISC_INTEN);
                    818:        thcm |= THC_MISC_INTR;
                    819:        THC_WRITE(sc, CG6_THC_MISC, thcm);
                    820:        cgsix_loadcmap_immediate(sc, 0, 256);
                    821:        return (1);
                    822: }
                    823:
                    824: void
                    825: cgsix_ras_init(struct cgsix_softc *sc)
                    826: {
                    827:        u_int32_t m;
                    828:
                    829:        CG6_DRAIN(sc);
                    830:        m = FBC_READ(sc, CG6_FBC_MODE);
                    831:        m &= ~FBC_MODE_MASK;
                    832:        m |= FBC_MODE_VAL;
                    833:        FBC_WRITE(sc, CG6_FBC_MODE, m);
                    834: }
                    835:
                    836: void
                    837: cgsix_ras_copyrows(void *cookie, int src, int dst, int n)
                    838: {
                    839:        struct rasops_info *ri = cookie;
                    840:        struct cgsix_softc *sc = ri->ri_hw;
                    841:
                    842:        if (dst == src)
                    843:                return;
                    844:        if (src < 0) {
                    845:                n += src;
                    846:                src = 0;
                    847:        }
                    848:        if (src + n > ri->ri_rows)
                    849:                n = ri->ri_rows - src;
                    850:        if (dst < 0) {
                    851:                n += dst;
                    852:                dst = 0;
                    853:        }
                    854:        if (dst + n > ri->ri_rows)
                    855:                n = ri->ri_rows - dst;
                    856:        if (n <= 0)
                    857:                return;
                    858:        n *= ri->ri_font->fontheight;
                    859:        src *= ri->ri_font->fontheight;
                    860:        dst *= ri->ri_font->fontheight;
                    861:
                    862:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
                    863:        FBC_WRITE(sc, CG6_FBC_S, 0);
                    864:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
                    865:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
                    866:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
                    867:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
                    868:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
                    869:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
                    870:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_COPY);
                    871:        FBC_WRITE(sc, CG6_FBC_X0, ri->ri_xorigin);
                    872:        FBC_WRITE(sc, CG6_FBC_Y0, ri->ri_yorigin + src);
                    873:        FBC_WRITE(sc, CG6_FBC_X1, ri->ri_xorigin + ri->ri_emuwidth - 1);
                    874:        FBC_WRITE(sc, CG6_FBC_Y1, ri->ri_yorigin + src + n - 1);
                    875:        FBC_WRITE(sc, CG6_FBC_X2, ri->ri_xorigin);
                    876:        FBC_WRITE(sc, CG6_FBC_Y2, ri->ri_yorigin + dst);
                    877:        FBC_WRITE(sc, CG6_FBC_X3, ri->ri_xorigin + ri->ri_emuwidth - 1);
                    878:        FBC_WRITE(sc, CG6_FBC_Y3, ri->ri_yorigin + dst + n - 1);
                    879:        CG6_BLIT_WAIT(sc);
                    880:        CG6_DRAIN(sc);
                    881: }
                    882:
                    883: void
                    884: cgsix_ras_copycols(void *cookie, int row, int src, int dst, int n)
                    885: {
                    886:        struct rasops_info *ri = cookie;
                    887:        struct cgsix_softc *sc = ri->ri_hw;
                    888:
                    889:        if (dst == src)
                    890:                return;
                    891:        if ((row < 0) || (row >= ri->ri_rows))
                    892:                return;
                    893:        if (src < 0) {
                    894:                n += src;
                    895:                src = 0;
                    896:        }
                    897:        if (src + n > ri->ri_cols)
                    898:                n = ri->ri_cols - src;
                    899:        if (dst < 0) {
                    900:                n += dst;
                    901:                dst = 0;
                    902:        }
                    903:        if (dst + n > ri->ri_cols)
                    904:                n = ri->ri_cols - dst;
                    905:        if (n <= 0)
                    906:                return;
                    907:        n *= ri->ri_font->fontwidth;
                    908:        src *= ri->ri_font->fontwidth;
                    909:        dst *= ri->ri_font->fontwidth;
                    910:        row *= ri->ri_font->fontheight;
                    911:
                    912:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
                    913:        FBC_WRITE(sc, CG6_FBC_S, 0);
                    914:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
                    915:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
                    916:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
                    917:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
                    918:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
                    919:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
                    920:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_COPY);
                    921:        FBC_WRITE(sc, CG6_FBC_X0, ri->ri_xorigin + src);
                    922:        FBC_WRITE(sc, CG6_FBC_Y0, ri->ri_yorigin + row);
                    923:        FBC_WRITE(sc, CG6_FBC_X1, ri->ri_xorigin + src + n - 1);
                    924:        FBC_WRITE(sc, CG6_FBC_Y1,
                    925:            ri->ri_yorigin + row + ri->ri_font->fontheight - 1);
                    926:        FBC_WRITE(sc, CG6_FBC_X2, ri->ri_xorigin + dst);
                    927:        FBC_WRITE(sc, CG6_FBC_Y2, ri->ri_yorigin + row);
                    928:        FBC_WRITE(sc, CG6_FBC_X3, ri->ri_xorigin + dst + n - 1);
                    929:        FBC_WRITE(sc, CG6_FBC_Y3,
                    930:            ri->ri_yorigin + row + ri->ri_font->fontheight - 1);
                    931:        CG6_BLIT_WAIT(sc);
                    932:        CG6_DRAIN(sc);
                    933: }
                    934:
                    935: void
                    936: cgsix_ras_erasecols(void *cookie, int row, int col, int n, long int attr)
                    937: {
                    938:        struct rasops_info *ri = cookie;
                    939:        struct cgsix_softc *sc = ri->ri_hw;
                    940:        int fg, bg;
                    941:
                    942:        if ((row < 0) || (row >= ri->ri_rows))
                    943:                return;
                    944:        if (col < 0) {
                    945:                n += col;
                    946:                col = 0;
                    947:        }
                    948:        if (col + n > ri->ri_cols)
                    949:                n = ri->ri_cols - col;
                    950:        if (n <= 0)
                    951:                return;
                    952:        n *= ri->ri_font->fontwidth;
                    953:        col *= ri->ri_font->fontwidth;
                    954:        row *= ri->ri_font->fontheight;
                    955:
                    956:        ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
                    957:
                    958:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
                    959:        FBC_WRITE(sc, CG6_FBC_S, 0);
                    960:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
                    961:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
                    962:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
                    963:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
                    964:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
                    965:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
                    966:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_FILL);
                    967:        FBC_WRITE(sc, CG6_FBC_FG, ri->ri_devcmap[bg]);
                    968:        FBC_WRITE(sc, CG6_FBC_ARECTY, ri->ri_yorigin + row);
                    969:        FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_xorigin + col);
                    970:        FBC_WRITE(sc, CG6_FBC_ARECTY,
                    971:            ri->ri_yorigin + row + ri->ri_font->fontheight - 1);
                    972:        FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_xorigin + col + n - 1);
                    973:        CG6_DRAW_WAIT(sc);
                    974:        CG6_DRAIN(sc);
                    975: }
                    976:
                    977: void
                    978: cgsix_ras_eraserows(void *cookie, int row, int n, long int attr)
                    979: {
                    980:        struct rasops_info *ri = cookie;
                    981:        struct cgsix_softc *sc = ri->ri_hw;
                    982:        int fg, bg;
                    983:
                    984:        if (row < 0) {
                    985:                n += row;
                    986:                row = 0;
                    987:        }
                    988:        if (row + n > ri->ri_rows)
                    989:                n = ri->ri_rows - row;
                    990:        if (n <= 0)
                    991:                return;
                    992:
                    993:        ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
                    994:
                    995:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
                    996:        FBC_WRITE(sc, CG6_FBC_S, 0);
                    997:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
                    998:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
                    999:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
                   1000:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
                   1001:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
                   1002:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
                   1003:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_FILL);
                   1004:        FBC_WRITE(sc, CG6_FBC_FG, ri->ri_devcmap[bg]);
                   1005:        if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) {
                   1006:                FBC_WRITE(sc, CG6_FBC_ARECTY, 0);
                   1007:                FBC_WRITE(sc, CG6_FBC_ARECTX, 0);
                   1008:                FBC_WRITE(sc, CG6_FBC_ARECTY, ri->ri_height - 1);
                   1009:                FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_width - 1);
                   1010:        } else {
                   1011:                row *= ri->ri_font->fontheight;
                   1012:                FBC_WRITE(sc, CG6_FBC_ARECTY, ri->ri_yorigin + row);
                   1013:                FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_xorigin);
                   1014:                FBC_WRITE(sc, CG6_FBC_ARECTY,
                   1015:                    ri->ri_yorigin + row + (n * ri->ri_font->fontheight) - 1);
                   1016:                FBC_WRITE(sc, CG6_FBC_ARECTX,
                   1017:                    ri->ri_xorigin + ri->ri_emuwidth - 1);
                   1018:        }
                   1019:        CG6_DRAW_WAIT(sc);
                   1020:        CG6_DRAIN(sc);
                   1021: }
                   1022:
                   1023: void
                   1024: cgsix_ras_do_cursor(struct rasops_info *ri)
                   1025: {
                   1026:        struct cgsix_softc *sc = ri->ri_hw;
                   1027:        int row, col;
                   1028:
                   1029:        row = ri->ri_crow * ri->ri_font->fontheight;
                   1030:        col = ri->ri_ccol * ri->ri_font->fontwidth;
                   1031:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
                   1032:        FBC_WRITE(sc, CG6_FBC_S, 0);
                   1033:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
                   1034:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
                   1035:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
                   1036:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
                   1037:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
                   1038:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
                   1039:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_FLIP);
                   1040:        FBC_WRITE(sc, CG6_FBC_ARECTY, ri->ri_yorigin + row);
                   1041:        FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_xorigin + col);
                   1042:        FBC_WRITE(sc, CG6_FBC_ARECTY,
                   1043:            ri->ri_yorigin + row + ri->ri_font->fontheight - 1);
                   1044:        FBC_WRITE(sc, CG6_FBC_ARECTX,
                   1045:            ri->ri_xorigin + col + ri->ri_font->fontwidth - 1);
                   1046:        CG6_DRAW_WAIT(sc);
                   1047:        CG6_DRAIN(sc);
                   1048: }

CVSweb