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

Annotation of sys/dev/sbus/cgthree.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: cgthree.c,v 1.43 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:
        !            53: #include <dev/ic/bt458reg.h>
        !            54:
        !            55: #define        CGTHREE_CTRL_OFFSET     0x400000
        !            56: #define        CGTHREE_CTRL_SIZE       (sizeof(u_int32_t) * 8)
        !            57: #define        CGTHREE_VID_OFFSET      0x800000
        !            58: #define        CGTHREE_VID_SIZE        (1024 * 1024)
        !            59:
        !            60: union bt_cmap {
        !            61:        u_int8_t cm_map[256][3];        /* 256 r/b/g entries */
        !            62:        u_int32_t cm_chip[256 * 3 / 4]; /* the way the chip is loaded */
        !            63: };
        !            64:
        !            65: #define        BT_ADDR         0x00            /* map address register */
        !            66: #define        BT_CMAP         0x04            /* colormap data register */
        !            67: #define        BT_CTRL         0x08            /* control register */
        !            68: #define        BT_OMAP         0x0c            /* overlay (cursor) map register */
        !            69: #define        CG3_FBC_CTRL    0x10            /* control */
        !            70: #define        CG3_FBC_STAT    0x11            /* status */
        !            71: #define        CG3_FBC_START   0x12            /* cursor start */
        !            72: #define        CG3_FBC_END     0x13            /* cursor end */
        !            73: #define        CG3_FBC_VCTRL   0x14            /* 12 bytes of timing goo */
        !            74:
        !            75: #define        BT_WRITE(sc, reg, val) \
        !            76:     bus_space_write_4((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg), (val))
        !            77: #define        BT_READ(sc, reg) \
        !            78:     bus_space_read_4((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg))
        !            79: #define        BT_BARRIER(sc,reg,flags) \
        !            80:     bus_space_barrier((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg), \
        !            81:        sizeof(u_int32_t), (flags))
        !            82:
        !            83: #define        BT_D4M3(x)      ((((x) >> 2) << 1) + ((x) >> 2)) /* (x / 4) * 3 */
        !            84: #define        BT_D4M4(x)      ((x) & ~3)                       /* (x / 4) * 4 */
        !            85:
        !            86: #define        FBC_CTRL_IENAB          0x80    /* interrupt enable */
        !            87: #define        FBC_CTRL_VENAB          0x40    /* video enable */
        !            88: #define        FBC_CTRL_TIME           0x20    /* timing enable */
        !            89: #define        FBC_CTRL_CURS           0x10    /* cursor compare enable */
        !            90: #define        FBC_CTRL_XTAL           0x0c    /* xtal select (0,1,2,test): */
        !            91: #define        FBC_CTRL_XTAL_0         0x00    /*  0 */
        !            92: #define        FBC_CTRL_XTAL_1         0x04    /*  0 */
        !            93: #define        FBC_CTRL_XTAL_2         0x08    /*  0 */
        !            94: #define        FBC_CTRL_XTAL_TEST      0x0c    /*  0 */
        !            95: #define        FBC_CTRL_DIV            0x03    /* divisor (1,2,3,4): */
        !            96: #define        FBC_CTRL_DIV_1          0x00    /*  / 1 */
        !            97: #define        FBC_CTRL_DIV_2          0x01    /*  / 2 */
        !            98: #define        FBC_CTRL_DIV_3          0x02    /*  / 3 */
        !            99: #define        FBC_CTRL_DIV_4          0x03    /*  / 4 */
        !           100:
        !           101: #define        FBC_STAT_INTR           0x80    /* interrupt pending */
        !           102: #define        FBC_STAT_RES            0x70    /* monitor sense: */
        !           103: #define        FBC_STAT_RES_1024       0x10    /*  1024x768 */
        !           104: #define        FBC_STAT_RES_1280       0x40    /*  1280x1024 */
        !           105: #define        FBC_STAT_RES_1152       0x30    /*  1152x900 */
        !           106: #define        FBC_STAT_RES_1152A      0x40    /*  1152x900x76, A */
        !           107: #define        FBC_STAT_RES_1600       0x50    /*  1600x1200 */
        !           108: #define        FBC_STAT_RES_1152B      0x60    /*  1152x900x86, B */
        !           109: #define        FBC_STAT_ID             0x0f    /* id mask: */
        !           110: #define        FBC_STAT_ID_COLOR       0x01    /*  color */
        !           111: #define        FBC_STAT_ID_MONO        0x02    /*  monochrome */
        !           112: #define        FBC_STAT_ID_MONOECL     0x03    /*  monochrome, ecl */
        !           113:
        !           114: #define        FBC_READ(sc, reg) \
        !           115:     bus_space_read_1((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg))
        !           116: #define        FBC_WRITE(sc, reg, val) \
        !           117:     bus_space_write_1((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg), (val))
        !           118:
        !           119: struct cgthree_softc {
        !           120:        struct sunfb sc_sunfb;
        !           121:        bus_space_tag_t sc_bustag;
        !           122:        bus_addr_t sc_paddr;
        !           123:        bus_space_handle_t sc_ctrl_regs;
        !           124:        bus_space_handle_t sc_vid_regs;
        !           125:        int sc_nscreens;
        !           126:        union bt_cmap sc_cmap;
        !           127:        u_int sc_mode;
        !           128: };
        !           129:
        !           130: int cgthree_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !           131: int cgthree_alloc_screen(void *, const struct wsscreen_descr *, void **,
        !           132:     int *, int *, long *);
        !           133: void cgthree_free_screen(void *, void *);
        !           134: int cgthree_show_screen(void *, void *, int, void (*cb)(void *, int, int),
        !           135:     void *);
        !           136: paddr_t cgthree_mmap(void *, off_t, int);
        !           137: int cgthree_is_console(int);
        !           138: void cgthree_loadcmap(struct cgthree_softc *, u_int, u_int);
        !           139: int cg3_bt_putcmap(union bt_cmap *, struct wsdisplay_cmap *);
        !           140: int cg3_bt_getcmap(union bt_cmap *, struct wsdisplay_cmap *);
        !           141: void cgthree_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
        !           142: void cgthree_burner(void *, u_int, u_int);
        !           143: void cgthree_reset(struct cgthree_softc *);
        !           144:
        !           145: struct wsdisplay_accessops cgthree_accessops = {
        !           146:        cgthree_ioctl,
        !           147:        cgthree_mmap,
        !           148:        cgthree_alloc_screen,
        !           149:        cgthree_free_screen,
        !           150:        cgthree_show_screen,
        !           151:        NULL,   /* load_font */
        !           152:        NULL,   /* scrollback */
        !           153:        NULL,   /* getchar */
        !           154:        cgthree_burner,
        !           155: };
        !           156:
        !           157: int    cgthreematch(struct device *, void *, void *);
        !           158: void   cgthreeattach(struct device *, struct device *, void *);
        !           159:
        !           160: struct cfattach cgthree_ca = {
        !           161:        sizeof (struct cgthree_softc), cgthreematch, cgthreeattach
        !           162: };
        !           163:
        !           164: struct cfdriver cgthree_cd = {
        !           165:        NULL, "cgthree", DV_DULL
        !           166: };
        !           167:
        !           168: #define        CG3_TYPE_DEFAULT        0
        !           169: #define        CG3_TYPE_76HZ           1
        !           170: #define        CG3_TYPE_SMALL          2
        !           171:
        !           172: struct cg3_videoctrl {
        !           173:        u_int8_t        sense;
        !           174:        u_int8_t        vctrl[12];
        !           175:        u_int8_t        ctrl;
        !           176: } cg3_videoctrl[] = {
        !           177:        {       /* cpd-1790 */
        !           178:                0x31,
        !           179:                { 0xbb, 0x2b, 0x04, 0x14, 0xae, 0x03,
        !           180:                  0xa8, 0x24, 0x01, 0x05, 0xff, 0x01 },
        !           181:                FBC_CTRL_XTAL_0 | FBC_CTRL_DIV_1
        !           182:        },
        !           183:        {       /* gdm-20e20 */
        !           184:                0x41,
        !           185:                { 0xb7, 0x27, 0x03, 0x0f, 0xae, 0x03,
        !           186:                  0xae, 0x2a, 0x01, 0x09, 0xff, 0x01 },
        !           187:                FBC_CTRL_XTAL_1 | FBC_CTRL_DIV_1
        !           188:        },
        !           189:        {       /* defaults, should be last */
        !           190:                0xff,
        !           191:                { 0xbb, 0x2b, 0x03, 0x0b, 0xb3, 0x03,
        !           192:                  0xaf, 0x2b, 0x02, 0x0a, 0xff, 0x01 },
        !           193:                0,
        !           194:        },
        !           195: };
        !           196:
        !           197: int
        !           198: cgthreematch(struct device *parent, void *vcf, void *aux)
        !           199: {
        !           200:        struct cfdata *cf = vcf;
        !           201:        struct sbus_attach_args *sa = aux;
        !           202:
        !           203:        return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0);
        !           204: }
        !           205:
        !           206: void
        !           207: cgthreeattach(struct device *parent, struct device *self, void *aux)
        !           208: {
        !           209:        struct cgthree_softc *sc = (struct cgthree_softc *)self;
        !           210:        struct sbus_attach_args *sa = aux;
        !           211:        int node, console;
        !           212:        const char *nam;
        !           213:
        !           214:        node = sa->sa_node;
        !           215:        sc->sc_bustag = sa->sa_bustag;
        !           216:        sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset);
        !           217:
        !           218:        fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);
        !           219:
        !           220:        if (sa->sa_nreg != 1) {
        !           221:                printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
        !           222:                goto fail;
        !           223:        }
        !           224:
        !           225:        /*
        !           226:         * Map just CTRL and video RAM.
        !           227:         */
        !           228:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           229:            sa->sa_reg[0].sbr_offset + CGTHREE_CTRL_OFFSET,
        !           230:            CGTHREE_CTRL_SIZE, 0, 0, &sc->sc_ctrl_regs) != 0) {
        !           231:                printf(": cannot map ctrl registers\n");
        !           232:                goto fail_ctrl;
        !           233:        }
        !           234:
        !           235:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           236:            sa->sa_reg[0].sbr_offset + CGTHREE_VID_OFFSET,
        !           237:            sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR,
        !           238:            0, &sc->sc_vid_regs) != 0) {
        !           239:                printf(": cannot map vid registers\n");
        !           240:                goto fail_vid;
        !           241:        }
        !           242:
        !           243:        nam = getpropstring(node, "model");
        !           244:        if (*nam == '\0')
        !           245:                nam = sa->sa_name;
        !           246:        printf(": %s", nam);
        !           247:
        !           248:        console = cgthree_is_console(node);
        !           249:
        !           250:        cgthree_reset(sc);
        !           251:        cgthree_burner(sc, 1, 0);
        !           252:
        !           253:        sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag,
        !           254:            sc->sc_vid_regs);
        !           255:        sc->sc_sunfb.sf_ro.ri_hw = sc;
        !           256:
        !           257:        printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
        !           258:
        !           259:        /*
        !           260:         * If the framebuffer width is under 1024x768, which is the case for
        !           261:         * some clones on laptops, as well as with the VS10-EK, switch from
        !           262:         * the PROM font to the more adequate 8x16 font here.
        !           263:         * However, we need to adjust two things in this case:
        !           264:         * - the display row should be overrided from the current PROM metrics,
        !           265:         *   to prevent us from overwriting the last few lines of text.
        !           266:         * - if the 80x34 screen would make a large margin appear around it,
        !           267:         *   choose to clear the screen rather than keeping old prom output in
        !           268:         *   the margins.
        !           269:         * XXX there should be a rasops "clear margins" feature
        !           270:         */
        !           271:        fbwscons_init(&sc->sc_sunfb, console &&
        !           272:            (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR);
        !           273:
        !           274:        fbwscons_setcolormap(&sc->sc_sunfb, cgthree_setcolor);
        !           275:
        !           276:        if (console) {
        !           277:                fbwscons_console_init(&sc->sc_sunfb,
        !           278:                    sc->sc_sunfb.sf_width >= 1024 ? -1 : 0);
        !           279:        }
        !           280:
        !           281:        fbwscons_attach(&sc->sc_sunfb, &cgthree_accessops, console);
        !           282:
        !           283:        return;
        !           284:
        !           285: fail_vid:
        !           286:        bus_space_unmap(sa->sa_bustag, sc->sc_ctrl_regs, CGTHREE_CTRL_SIZE);
        !           287: fail_ctrl:
        !           288: fail:
        !           289: ;
        !           290: }
        !           291:
        !           292: int
        !           293: cgthree_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
        !           294: {
        !           295:        struct cgthree_softc *sc = v;
        !           296:        struct wsdisplay_fbinfo *wdf;
        !           297:        struct wsdisplay_cmap *cm;
        !           298:        int error;
        !           299:
        !           300:        switch (cmd) {
        !           301:        case WSDISPLAYIO_GTYPE:
        !           302:                *(u_int *)data = WSDISPLAY_TYPE_SUNCG3;
        !           303:                break;
        !           304:        case WSDISPLAYIO_SMODE:
        !           305:                sc->sc_mode = *(u_int *)data;
        !           306:                break;
        !           307:        case WSDISPLAYIO_GINFO:
        !           308:                wdf = (void *)data;
        !           309:                wdf->height = sc->sc_sunfb.sf_height;
        !           310:                wdf->width  = sc->sc_sunfb.sf_width;
        !           311:                wdf->depth  = sc->sc_sunfb.sf_depth;
        !           312:                wdf->cmsize = 256;
        !           313:                break;
        !           314:        case WSDISPLAYIO_LINEBYTES:
        !           315:                *(u_int *)data = sc->sc_sunfb.sf_linebytes;
        !           316:                break;
        !           317:
        !           318:        case WSDISPLAYIO_GETCMAP:
        !           319:                cm = (struct wsdisplay_cmap *)data;
        !           320:                error = cg3_bt_getcmap(&sc->sc_cmap, cm);
        !           321:                if (error)
        !           322:                        return (error);
        !           323:                break;
        !           324:
        !           325:        case WSDISPLAYIO_PUTCMAP:
        !           326:                cm = (struct wsdisplay_cmap *)data;
        !           327:                error = cg3_bt_putcmap(&sc->sc_cmap, cm);
        !           328:                if (error)
        !           329:                        return (error);
        !           330:                cgthree_loadcmap(sc, cm->index, cm->count);
        !           331:                break;
        !           332:
        !           333:        case WSDISPLAYIO_SVIDEO:
        !           334:        case WSDISPLAYIO_GVIDEO:
        !           335:                break;
        !           336:
        !           337:        case WSDISPLAYIO_GCURPOS:
        !           338:        case WSDISPLAYIO_SCURPOS:
        !           339:        case WSDISPLAYIO_GCURMAX:
        !           340:        case WSDISPLAYIO_GCURSOR:
        !           341:        case WSDISPLAYIO_SCURSOR:
        !           342:        default:
        !           343:                return -1; /* not supported yet */
        !           344:         }
        !           345:
        !           346:        return (0);
        !           347: }
        !           348:
        !           349: int
        !           350: cgthree_alloc_screen(void *v, const struct wsscreen_descr *type,
        !           351:     void **cookiep, int *curxp, int *curyp, long *attrp)
        !           352: {
        !           353:        struct cgthree_softc *sc = v;
        !           354:
        !           355:        if (sc->sc_nscreens > 0)
        !           356:                return (ENOMEM);
        !           357:
        !           358:        *cookiep = &sc->sc_sunfb.sf_ro;
        !           359:        *curyp = 0;
        !           360:        *curxp = 0;
        !           361:        sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
        !           362:            WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp);
        !           363:        sc->sc_nscreens++;
        !           364:        return (0);
        !           365: }
        !           366:
        !           367: void
        !           368: cgthree_free_screen(void *v, void *cookie)
        !           369: {
        !           370:        struct cgthree_softc *sc = v;
        !           371:
        !           372:        sc->sc_nscreens--;
        !           373: }
        !           374:
        !           375: int
        !           376: cgthree_show_screen(void *v, void *cookie, int waitok,
        !           377:     void (*cb)(void *, int, int), void *cbarg)
        !           378: {
        !           379:        return (0);
        !           380: }
        !           381:
        !           382: #define        START           (128 * 1024 + 128 * 1024)
        !           383: #define        NOOVERLAY       (0x04000000)
        !           384:
        !           385: paddr_t
        !           386: cgthree_mmap(void *v, off_t offset, int prot)
        !           387: {
        !           388:        struct cgthree_softc *sc = v;
        !           389:
        !           390:        if (offset & PGOFSET || offset < 0)
        !           391:                return (-1);
        !           392:
        !           393:        switch (sc->sc_mode) {
        !           394:        case WSDISPLAYIO_MODE_MAPPED:
        !           395:                if (offset >= NOOVERLAY)
        !           396:                        offset -= NOOVERLAY;
        !           397:                else if (offset >= START)
        !           398:                        offset -= START;
        !           399:                else
        !           400:                        offset = 0;
        !           401:                if (offset >= sc->sc_sunfb.sf_fbsize)
        !           402:                        return (-1);
        !           403:                return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
        !           404:                    CGTHREE_VID_OFFSET + offset, prot, BUS_SPACE_MAP_LINEAR));
        !           405:        case WSDISPLAYIO_MODE_DUMBFB:
        !           406:                if (offset < sc->sc_sunfb.sf_fbsize)
        !           407:                        return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
        !           408:                            CGTHREE_VID_OFFSET + offset, prot,
        !           409:                            BUS_SPACE_MAP_LINEAR));
        !           410:                break;
        !           411:        }
        !           412:        return (-1);
        !           413: }
        !           414:
        !           415: int
        !           416: cgthree_is_console(int node)
        !           417: {
        !           418:        extern int fbnode;
        !           419:
        !           420:        return (fbnode == node);
        !           421: }
        !           422:
        !           423: void
        !           424: cgthree_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
        !           425: {
        !           426:        struct cgthree_softc *sc = v;
        !           427:        union bt_cmap *bcm = &sc->sc_cmap;
        !           428:
        !           429:        bcm->cm_map[index][0] = r;
        !           430:        bcm->cm_map[index][1] = g;
        !           431:        bcm->cm_map[index][2] = b;
        !           432:        cgthree_loadcmap(sc, index, 1);
        !           433: }
        !           434:
        !           435: void
        !           436: cgthree_loadcmap(struct cgthree_softc *sc, u_int start, u_int ncolors)
        !           437: {
        !           438:        u_int cstart;
        !           439:        int count;
        !           440:
        !           441:        cstart = BT_D4M3(start);
        !           442:        count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
        !           443:        BT_WRITE(sc, BT_ADDR, BT_D4M4(start));
        !           444:        while (--count >= 0) {
        !           445:                BT_WRITE(sc, BT_CMAP, sc->sc_cmap.cm_chip[cstart]);
        !           446:                cstart++;
        !           447:        }
        !           448: }
        !           449:
        !           450: int
        !           451: cg3_bt_getcmap(union bt_cmap *bcm, struct wsdisplay_cmap *rcm)
        !           452: {
        !           453:        u_int index = rcm->index, count = rcm->count, i;
        !           454:        int error;
        !           455:
        !           456:        if (index >= 256 || count > 256 - index)
        !           457:                return (EINVAL);
        !           458:        for (i = 0; i < count; i++) {
        !           459:                if ((error = copyout(&bcm->cm_map[index + i][0],
        !           460:                    &rcm->red[i], 1)) != 0)
        !           461:                        return (error);
        !           462:                if ((error = copyout(&bcm->cm_map[index + i][1],
        !           463:                    &rcm->green[i], 1)) != 0)
        !           464:                        return (error);
        !           465:                if ((error = copyout(&bcm->cm_map[index + i][2],
        !           466:                    &rcm->blue[i], 1)) != 0)
        !           467:                        return (error);
        !           468:        }
        !           469:        return (0);
        !           470: }
        !           471:
        !           472: int
        !           473: cg3_bt_putcmap(union bt_cmap *bcm, struct wsdisplay_cmap *rcm)
        !           474: {
        !           475:        u_int index = rcm->index, count = rcm->count, i;
        !           476:        int error;
        !           477:
        !           478:        if (index >= 256 || count > 256 - index)
        !           479:                return (EINVAL);
        !           480:        for (i = 0; i < count; i++) {
        !           481:                if ((error = copyin(&rcm->red[i],
        !           482:                    &bcm->cm_map[index + i][0], 1)) != 0)
        !           483:                        return (error);
        !           484:                if ((error = copyin(&rcm->green[i],
        !           485:                    &bcm->cm_map[index + i][1], 1)) != 0)
        !           486:                        return (error);
        !           487:                if ((error = copyin(&rcm->blue[i],
        !           488:                    &bcm->cm_map[index + i][2], 1)) != 0)
        !           489:                        return (error);
        !           490:        }
        !           491:        return (0);
        !           492: }
        !           493:
        !           494: void
        !           495: cgthree_reset(struct cgthree_softc *sc)
        !           496: {
        !           497:        int i, j;
        !           498:        u_int8_t sts, ctrl;
        !           499:
        !           500:        sts = FBC_READ(sc, CG3_FBC_STAT);
        !           501:        ctrl = FBC_READ(sc, CG3_FBC_CTRL);
        !           502:
        !           503:        if (ctrl & FBC_CTRL_TIME) {
        !           504:                /* already initialized */
        !           505:                return;
        !           506:        }
        !           507:
        !           508:        for (i = 0; i <  sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]); i++) {
        !           509:                if (cg3_videoctrl[i].sense == 0xff ||
        !           510:                    (cg3_videoctrl[i].sense ==
        !           511:                     (sts & (FBC_STAT_RES | FBC_STAT_ID)))) {
        !           512:                        for (j = 0; j < 12; j++)
        !           513:                                FBC_WRITE(sc, CG3_FBC_VCTRL + j,
        !           514:                                    cg3_videoctrl[i].vctrl[j]);
        !           515:                        ctrl &= ~(FBC_CTRL_XTAL | FBC_CTRL_DIV);
        !           516:                        ctrl |= cg3_videoctrl[i].ctrl |
        !           517:                            FBC_CTRL_TIME;
        !           518:                        FBC_WRITE(sc, CG3_FBC_CTRL, ctrl);
        !           519:                        break;
        !           520:                }
        !           521:        }
        !           522:
        !           523:        /* enable all the bit planes */
        !           524:        BT_WRITE(sc, BT_ADDR, BT_RMR);
        !           525:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
        !           526:        BT_WRITE(sc, BT_CTRL, 0xff);
        !           527:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
        !           528:
        !           529:        /* no plane should blink */
        !           530:        BT_WRITE(sc, BT_ADDR, BT_BMR);
        !           531:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
        !           532:        BT_WRITE(sc, BT_CTRL, 0x00);
        !           533:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
        !           534:
        !           535:        /*
        !           536:         * enable the RAMDAC, disable blink, disable overlay 0 and 1,
        !           537:         * use 4:1 multiplexor.
        !           538:         */
        !           539:        BT_WRITE(sc, BT_ADDR, BT_CR);
        !           540:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
        !           541:        BT_WRITE(sc, BT_CTRL,
        !           542:            (BTCR_MPLX_4 | BTCR_RAMENA | BTCR_BLINK_6464));
        !           543:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
        !           544:
        !           545:        /* disable the D/A read pins */
        !           546:        BT_WRITE(sc, BT_ADDR, BT_CTR);
        !           547:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
        !           548:        BT_WRITE(sc, BT_CTRL, 0x00);
        !           549:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
        !           550: }
        !           551:
        !           552: void
        !           553: cgthree_burner(void *vsc, u_int on, u_int flags)
        !           554: {
        !           555:        struct cgthree_softc *sc = vsc;
        !           556:        int s;
        !           557:        u_int8_t fbc;
        !           558:
        !           559:        s = splhigh();
        !           560:        fbc = FBC_READ(sc, CG3_FBC_CTRL);
        !           561:        if (on)
        !           562:                fbc |= FBC_CTRL_VENAB | FBC_CTRL_TIME;
        !           563:        else {
        !           564:                fbc &= ~FBC_CTRL_VENAB;
        !           565:                if (flags & WSDISPLAY_BURN_VBLANK)
        !           566:                        fbc &= ~FBC_CTRL_TIME;
        !           567:        }
        !           568:        FBC_WRITE(sc, CG3_FBC_CTRL, fbc);
        !           569:        splx(s);
        !           570: }

CVSweb