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

Annotation of sys/arch/luna88k/dev/lunafb.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: lunafb.c,v 1.8 2006/11/29 12:13:54 miod Exp $ */
                      2: /* $NetBSD: lunafb.c,v 1.7.6.1 2002/08/07 01:48:34 lukem Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2000 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Tohru Nishimura.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the NetBSD
                     22:  *     Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/conf.h>
                     43: #include <sys/device.h>
                     44: #include <sys/ioctl.h>
                     45: #include <sys/malloc.h>
                     46: #include <sys/mman.h>
                     47: #include <sys/proc.h>
                     48: #include <sys/tty.h>
                     49: #include <sys/errno.h>
                     50: #include <sys/buf.h>
                     51:
                     52: #include <uvm/uvm_extern.h>
                     53:
                     54: #include <dev/wscons/wsconsio.h>
                     55: #include <dev/wscons/wsdisplayvar.h>
                     56: #include <dev/rasops/rasops.h>
                     57:
                     58: #include <machine/cpu.h>
                     59: #include <machine/autoconf.h>
                     60:
                     61: struct bt454 {
                     62:        u_int8_t bt_addr;               /* map address register */
                     63:        u_int8_t bt_cmap;               /* colormap data register */
                     64: };
                     65:
                     66: struct bt458 {
                     67:        u_int8_t bt_addr;               /* map address register */
                     68:                unsigned :24;
                     69:        u_int8_t bt_cmap;               /* colormap data register */
                     70:                unsigned :24;
                     71:        u_int8_t bt_ctrl;               /* control register */
                     72:                unsigned :24;
                     73:        u_int8_t bt_omap;               /* overlay (cursor) map register */
                     74:                unsigned :24;
                     75: };
                     76:
                     77: #define        OMFB_RFCNT      0xB1000000      /* video h-origin/v-origin */
                     78: #define        OMFB_PLANEMASK  0xB1040000      /* planemask register */
                     79: #define        OMFB_FB_WADDR   0xB1080008      /* common plane */
                     80: #define        OMFB_FB_RADDR   0xB10C0008      /* plane #0 */
                     81: #define        OMFB_ROPFUNC    0xB12C0000      /* ROP function code */
                     82: #define        OMFB_RAMDAC     0xC1100000      /* Bt454/Bt458 RAMDAC */
                     83: #define        OMFB_SIZE       (0xB1300000 - 0xB1080000 + NBPG)
                     84:
                     85: struct om_hwdevconfig {
                     86:        int     dc_wid;                 /* width of frame buffer */
                     87:        int     dc_ht;                  /* height of frame buffer */
                     88:        int     dc_depth;               /* depth, bits per pixel */
                     89:        int     dc_rowbytes;            /* bytes in a FB scan line */
                     90:        int     dc_cmsize;              /* colormap size */
                     91:        vaddr_t dc_videobase;           /* base of flat frame buffer */
                     92:        struct rasops_info dc_ri;       /* raster blitter variables */
                     93: };
                     94:
                     95: struct hwcmap {
                     96: #define CMAP_SIZE 256
                     97:        u_int8_t r[CMAP_SIZE];
                     98:        u_int8_t g[CMAP_SIZE];
                     99:        u_int8_t b[CMAP_SIZE];
                    100: };
                    101:
                    102: struct omfb_softc {
                    103:        struct device sc_dev;           /* base device */
                    104:        struct om_hwdevconfig *sc_dc;   /* device configuration */
                    105:        struct hwcmap sc_cmap;          /* software copy of colormap */
                    106:        int nscreens;
                    107: };
                    108:
                    109: int  omgetcmap(struct omfb_softc *, struct wsdisplay_cmap *);
                    110: int  omsetcmap(struct omfb_softc *, struct wsdisplay_cmap *);
                    111:
                    112: struct om_hwdevconfig omfb_console_dc;
                    113: void omfb_getdevconfig(paddr_t, struct om_hwdevconfig *);
                    114:
                    115: /* in omrasops.c */
                    116: void   om_cursor(void *, int, int, int);
                    117: void   om_putchar(void *, int, int, u_int, long);
                    118: void   om_copycols(void *, int, int, int, int);
                    119: void   om_copyrows(void *, int, int, int num);
                    120: void   om_erasecols(void *, int, int, int, long);
                    121: void   om_eraserows(void *, int, int, long);
                    122:
                    123: struct wsscreen_descr omfb_stdscreen = {
                    124:        "std"
                    125: };
                    126:
                    127: const struct wsscreen_descr *_omfb_scrlist[] = {
                    128:        &omfb_stdscreen,
                    129: };
                    130:
                    131: const struct wsscreen_list omfb_screenlist = {
                    132:        sizeof(_omfb_scrlist) / sizeof(struct wsscreen_descr *), _omfb_scrlist
                    133: };
                    134:
                    135: int   omfbioctl(void *, u_long, caddr_t, int, struct proc *);
                    136: paddr_t omfbmmap(void *, off_t, int);
                    137: int   omfb_alloc_screen(void *, const struct wsscreen_descr *,
                    138:                                      void **, int *, int *, long *);
                    139: void  omfb_free_screen(void *, void *);
                    140: int   omfb_show_screen(void *, void *, int,
                    141:                                void (*) (void *, int, int), void *);
                    142:
                    143: const struct wsdisplay_accessops omfb_accessops = {
                    144:        omfbioctl,
                    145:        omfbmmap,
                    146:        omfb_alloc_screen,
                    147:        omfb_free_screen,
                    148:        omfb_show_screen,
                    149:        NULL,   /* load_font */
                    150:        NULL,   /* scrollback */
                    151:        NULL,   /* getchar */
                    152:        NULL    /* burner */
                    153: };
                    154:
                    155: int  omfbmatch(struct device *, void *, void *);
                    156: void omfbattach(struct device *, struct device *, void *);
                    157:
                    158: const struct cfattach fb_ca = {
                    159:        sizeof(struct omfb_softc), omfbmatch, omfbattach
                    160: };
                    161:
                    162: struct cfdriver fb_cd = {
                    163:         NULL, "fb", DV_DULL
                    164: };
                    165:
                    166: extern int hwplanebits;        /* hardware plane bits; retrieved at boot */
                    167:
                    168: int omfb_console;
                    169: int omfb_cnattach(void);
                    170:
                    171: int
                    172: omfbmatch(parent, cf, aux)
                    173:        struct device *parent;
                    174:        void *cf, *aux;
                    175: {
                    176:        struct mainbus_attach_args *ma = aux;
                    177:
                    178:        if (strcmp(ma->ma_name, fb_cd.cd_name))
                    179:                return (0);
                    180: #if 0  /* XXX badaddr() bombs if no framebuffer is installed */
                    181:        if (badaddr((caddr_t)ma->ma_addr, 4))
                    182:                return (0);
                    183: #else
                    184:        if (hwplanebits == 0)
                    185:                return (0);
                    186: #endif
                    187:        return (1);
                    188: }
                    189:
                    190: void
                    191: omfbattach(parent, self, args)
                    192:        struct device *parent, *self;
                    193:        void *args;
                    194: {
                    195:        struct omfb_softc *sc = (struct omfb_softc *)self;
                    196:        struct wsemuldisplaydev_attach_args waa;
                    197:
                    198:        if (omfb_console) {
                    199:                sc->sc_dc = &omfb_console_dc;
                    200:                sc->nscreens = 1;
                    201:        }
                    202:        else {
                    203:                sc->sc_dc = (struct om_hwdevconfig *)
                    204:                    malloc(sizeof(struct om_hwdevconfig), M_DEVBUF, M_WAITOK);
                    205:                omfb_getdevconfig(OMFB_FB_WADDR, sc->sc_dc);
                    206:        }
                    207:        printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
                    208:            sc->sc_dc->dc_depth);
                    209:
                    210: #if 0  /* WHITE on BLACK */
                    211:        cm = &sc->sc_cmap;
                    212:        memset(cm, 255, sizeof(struct hwcmap));
                    213:        cm->r[0] = cm->g[0] = cm->b[0] = 0;
                    214: #endif
                    215:        waa.console = omfb_console;
                    216:        waa.scrdata = &omfb_screenlist;
                    217:        waa.accessops = &omfb_accessops;
                    218:        waa.accesscookie = sc;
                    219:        waa.defaultscreens = 0;
                    220:
                    221:        config_found(self, &waa, wsemuldisplaydevprint);
                    222: }
                    223:
                    224: /* EXPORT */ int
                    225: omfb_cnattach()
                    226: {
                    227:        struct om_hwdevconfig *dc = &omfb_console_dc;
                    228:        struct rasops_info *ri = &dc->dc_ri;
                    229:        long defattr;
                    230:
                    231:        omfb_getdevconfig(OMFB_FB_WADDR, dc);
                    232:        ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
                    233:        wsdisplay_cnattach(&omfb_stdscreen, ri, 0, 0, defattr);
                    234:        omfb_console = 1;
                    235:        return (0);
                    236: }
                    237:
                    238: int
                    239: omfbioctl(v, cmd, data, flag, p)
                    240:        void *v;
                    241:        u_long cmd;
                    242:        caddr_t data;
                    243:        int flag;
                    244:        struct proc *p;
                    245: {
                    246:        struct omfb_softc *sc = v;
                    247:        struct om_hwdevconfig *dc = sc->sc_dc;
                    248:
                    249:        switch (cmd) {
                    250:        case WSDISPLAYIO_GTYPE:
                    251:                *(u_int *)data = WSDISPLAY_TYPE_LUNA;
                    252:                break;
                    253:
                    254:        case WSDISPLAYIO_GINFO:
                    255: #define        wsd_fbip ((struct wsdisplay_fbinfo *)data)
                    256:                wsd_fbip->height = dc->dc_ht;
                    257:                wsd_fbip->width = dc->dc_wid;
                    258:                wsd_fbip->depth = dc->dc_depth;
                    259:                wsd_fbip->cmsize = dc->dc_cmsize;
                    260: #undef fbt
                    261:                break;
                    262:
                    263:        case WSDISPLAYIO_GETCMAP:
                    264:                return omgetcmap(sc, (struct wsdisplay_cmap *)data);
                    265:
                    266:        case WSDISPLAYIO_PUTCMAP:
                    267:                return omsetcmap(sc, (struct wsdisplay_cmap *)data);
                    268:
                    269:        case WSDISPLAYIO_SVIDEO:
                    270:        case WSDISPLAYIO_GVIDEO:
                    271:                break;
                    272:
                    273:        case WSDISPLAYIO_GCURPOS:
                    274:        case WSDISPLAYIO_SCURPOS:
                    275:        case WSDISPLAYIO_GCURMAX:
                    276:        case WSDISPLAYIO_GCURSOR:
                    277:        case WSDISPLAYIO_SCURSOR:
                    278:        default:
                    279:                return (-1);
                    280:        }
                    281:
                    282:        return (0);
                    283: }
                    284:
                    285: /*
                    286:  * Return the address that would map the given device at the given
                    287:  * offset, allowing for the given protection, or return -1 for error.
                    288:  */
                    289:
                    290: paddr_t
                    291: omfbmmap(v, offset, prot)
                    292:        void *v;
                    293:        off_t offset;
                    294:        int prot;
                    295: {
                    296:        struct omfb_softc *sc = v;
                    297:
                    298:        if (offset & PGOFSET)
                    299:                return (-1);
                    300:        if (offset >= OMFB_SIZE || offset < 0)
                    301:                return (-1);
                    302:
                    303:        return atop(trunc_page(sc->sc_dc->dc_videobase) + offset);
                    304: }
                    305:
                    306: int
                    307: omgetcmap(sc, p)
                    308:        struct omfb_softc *sc;
                    309:        struct wsdisplay_cmap *p;
                    310: {
                    311:        u_int index = p->index, count = p->count;
                    312:         unsigned int cmsize;
                    313:        int error;
                    314:
                    315:        cmsize = sc->sc_dc->dc_cmsize;
                    316:        if (index >= cmsize || count > cmsize - index)
                    317:                return (EINVAL);
                    318:
                    319:        error = copyout(&sc->sc_cmap.r[index], p->red, count);
                    320:        if (error != 0)
                    321:                return (error);
                    322:        error = copyout(&sc->sc_cmap.g[index], p->green, count);
                    323:        if (error != 0)
                    324:                return (error);
                    325:        error = copyout(&sc->sc_cmap.b[index], p->blue, count);
                    326:        if (error != 0)
                    327:                return (error);
                    328:
                    329:        return (0);
                    330: }
                    331:
                    332: int
                    333: omsetcmap(sc, p)
                    334:        struct omfb_softc *sc;
                    335:        struct wsdisplay_cmap *p;
                    336: {
                    337:        u_int index = p->index, count = p->count;
                    338:         unsigned int cmsize, i;
                    339:        int error;
                    340:
                    341:        cmsize = sc->sc_dc->dc_cmsize;
                    342:        if (index >= cmsize || count > cmsize - index)
                    343:                return (EINVAL);
                    344:
                    345:        error = copyin(p->red, &sc->sc_cmap.r[index], count);
                    346:        if (error != 0)
                    347:                return (error);
                    348:        error = copyin(p->green, &sc->sc_cmap.g[index], count);
                    349:        if (error != 0)
                    350:                return (error);
                    351:        error = copyin(p->blue, &sc->sc_cmap.b[index], count);
                    352:        if (error != 0)
                    353:                return (error);
                    354:
                    355:        if (hwplanebits == 4) {
                    356:                struct bt454 *odac = (struct bt454 *)OMFB_RAMDAC;
                    357:                odac->bt_addr = index;
                    358:                for (i = index; i < count; i++) {
                    359:                        odac->bt_cmap = sc->sc_cmap.r[i];
                    360:                        odac->bt_cmap = sc->sc_cmap.g[i];
                    361:                        odac->bt_cmap = sc->sc_cmap.b[i];
                    362:                }
                    363:        }
                    364:        else if (hwplanebits == 8) {
                    365:                struct bt458 *ndac = (struct bt458 *)OMFB_RAMDAC;
                    366:                ndac->bt_addr = index;
                    367:                for (i = index; i < count; i++) {
                    368:                        ndac->bt_cmap = sc->sc_cmap.r[i];
                    369:                        ndac->bt_cmap = sc->sc_cmap.g[i];
                    370:                        ndac->bt_cmap = sc->sc_cmap.b[i];
                    371:                }
                    372:        }
                    373:        return (0);
                    374: }
                    375:
                    376: void
                    377: omfb_getdevconfig(paddr, dc)
                    378:        paddr_t paddr;
                    379:        struct om_hwdevconfig *dc;
                    380: {
                    381:        int bpp, i;
                    382:        struct rasops_info *ri;
                    383:        union {
                    384:                struct { short h, v; } p;
                    385:                u_int32_t u;
                    386:        } rfcnt;
                    387:
                    388:        switch (hwplanebits) {
                    389:        case 8:
                    390:                bpp = 8;        /* XXX check monochrome bit in DIPSW */
                    391:                break;
                    392:        default:
                    393:        case 4:
                    394:                bpp = 4;        /* XXX check monochrome bit in DIPSW */
                    395:                break;
                    396:        case 1:
                    397:                bpp = 1;
                    398:                break;
                    399:        }
                    400:        dc->dc_wid = 1280;
                    401:        dc->dc_ht = 1024;
                    402:        dc->dc_depth = bpp;
                    403:        dc->dc_rowbytes = 2048 / 8;
                    404:        dc->dc_cmsize = (bpp == 1) ? 0 : 1 << bpp;
                    405:        dc->dc_videobase = paddr;
                    406:
                    407: #if 0 /* WHITE on BLACK XXX experiment resulted in WHITE on SKYBLUE... */
                    408:        if (hwplanebits == 4) {
                    409:                /* XXX Need Bt454 initialization */
                    410:                struct bt454 *odac = (struct bt454 *)OMFB_RAMDAC;
                    411:                odac->bt_addr = 0;
                    412:                odac->bt_cmap = 0;
                    413:                odac->bt_cmap = 0;
                    414:                odac->bt_cmap = 0;
                    415:                for (i = 1; i < 16; i++) {
                    416:                        odac->bt_cmap = 255;
                    417:                        odac->bt_cmap = 255;
                    418:                        odac->bt_cmap = 255;
                    419:                }
                    420:        }
                    421:        else if (hwplanebits == 8) {
                    422:                struct bt458 *ndac = (struct bt458 *)OMFB_RAMDAC;
                    423:
                    424:                ndac->bt_addr = 0x04;
                    425:                ndac->bt_ctrl = 0xff; /* all planes will be read */
                    426:                ndac->bt_ctrl = 0x00; /* all planes have non-blink */
                    427:                ndac->bt_ctrl = 0x43; /* pallete enabled, ovly plane */
                    428:                ndac->bt_ctrl = 0x00; /* no test mode */
                    429:                ndac->bt_addr = 0;
                    430:                ndac->bt_cmap = 0;
                    431:                ndac->bt_cmap = 0;
                    432:                ndac->bt_cmap = 0;
                    433:                for (i = 1; i < 256; i++) {
                    434:                        ndac->bt_cmap = 255;
                    435:                        ndac->bt_cmap = 255;
                    436:                        ndac->bt_cmap = 255;
                    437:                }
                    438:        }
                    439: #endif
                    440:
                    441:        /* adjust h/v origin on screen */
                    442:        rfcnt.p.h = 7;
                    443:        rfcnt.p.v = -27;
                    444:        *(u_int32_t *)OMFB_RFCNT = rfcnt.u; /* single write of 0x007ffe6 */
                    445:
                    446:        /* clear the screen */
                    447:        *(u_int32_t *)OMFB_PLANEMASK = 0xff;
                    448:        ((u_int32_t *)OMFB_ROPFUNC)[5] = ~0;    /* ROP copy */
                    449:        for (i = 0; i < dc->dc_ht * dc->dc_rowbytes / sizeof(u_int32_t); i++)
                    450:                *((u_int32_t *)dc->dc_videobase + i) = 0;
                    451:        *(u_int32_t *)OMFB_PLANEMASK = 0x01;
                    452:
                    453:        /* initialize the raster */
                    454:        ri = &dc->dc_ri;
                    455:        ri->ri_width = dc->dc_wid;
                    456:        ri->ri_height = dc->dc_ht;
                    457:        ri->ri_depth = 1;       /* since planes are independently addressed */
                    458:        ri->ri_stride = dc->dc_rowbytes;
                    459:        ri->ri_bits = (void *)dc->dc_videobase;
                    460:        ri->ri_flg = RI_CENTER;
                    461:        ri->ri_hw = dc;
                    462:
                    463:        rasops_init(ri, 35, 80);
                    464:
                    465:        omfb_stdscreen.ncols = ri->ri_cols;
                    466:        omfb_stdscreen.nrows = ri->ri_rows;
                    467:        ri->ri_ops.cursor = om_cursor;
                    468:        ri->ri_ops.putchar = om_putchar;
                    469:        ri->ri_ops.copycols = om_copycols;
                    470:        ri->ri_ops.erasecols = om_erasecols;
                    471:        ri->ri_ops.copyrows = om_copyrows;
                    472:        ri->ri_ops.eraserows = om_eraserows;
                    473:        omfb_stdscreen.textops = &ri->ri_ops;
                    474:        omfb_stdscreen.fontwidth = ri->ri_font->fontwidth;
                    475:        omfb_stdscreen.fontheight = ri->ri_font->fontheight;
                    476:        omfb_stdscreen.capabilities = ri->ri_caps & ~WSSCREEN_UNDERLINE;
                    477: }
                    478:
                    479: int
                    480: omfb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
                    481:        void *v;
                    482:        const struct wsscreen_descr *type;
                    483:        void **cookiep;
                    484:        int *curxp, *curyp;
                    485:        long *attrp;
                    486: {
                    487:        struct omfb_softc *sc = v;
                    488:        struct rasops_info *ri = &sc->sc_dc->dc_ri;
                    489:
                    490:        if (sc->nscreens > 0)
                    491:                return (ENOMEM);
                    492:
                    493:        *cookiep = ri;
                    494:        *curxp = 0;
                    495:        *curyp = 0;
                    496:        ri->ri_ops.alloc_attr(ri, 0, 0, 0, attrp);
                    497:        sc->nscreens++;
                    498:        return (0);
                    499: }
                    500:
                    501: void
                    502: omfb_free_screen(v, cookie)
                    503:        void *v;
                    504:        void *cookie;
                    505: {
                    506:        struct omfb_softc *sc = v;
                    507:
                    508:        sc->nscreens--;
                    509: }
                    510:
                    511: int
                    512: omfb_show_screen(v, cookie, waitok, cb, cbarg)
                    513:        void *v;
                    514:        void *cookie;
                    515:        int waitok;
                    516:        void (*cb)(void *, int, int);
                    517:        void *cbarg;
                    518: {
                    519:        return 0;
                    520: }

CVSweb