[BACK]Return to sfb.c CVS log [TXT][DIR] Up to [local] / sys / arch / alpha / tc

Annotation of sys/arch/alpha/tc/sfb.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: sfb.c,v 1.18 2006/11/29 12:13:51 miod Exp $   */
                      2: /*     $NetBSD: sfb.c,v 1.7 1996/12/05 01:39:44 cgd Exp $      */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Author: Chris G. Demetriou
                      9:  *
                     10:  * Permission to use, copy, modify and distribute this software and
                     11:  * its documentation is hereby granted, provided that both the copyright
                     12:  * notice and this permission notice appear in all copies of the
                     13:  * software, derivative works or modified versions, and any portions
                     14:  * thereof, and that both notices appear in supporting documentation.
                     15:  *
                     16:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     17:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
                     18:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     19:  *
                     20:  * Carnegie Mellon requests users of this software to return to
                     21:  *
                     22:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     23:  *  School of Computer Science
                     24:  *  Carnegie Mellon University
                     25:  *  Pittsburgh PA 15213-3890
                     26:  *
                     27:  * any improvements or extensions that they make and grant Carnegie the
                     28:  * rights to redistribute these changes.
                     29:  */
                     30:
                     31: #include <sys/param.h>
                     32: #include <sys/systm.h>
                     33: #include <sys/kernel.h>
                     34: #include <sys/device.h>
                     35: #include <sys/malloc.h>
                     36: #include <sys/buf.h>
                     37: #include <sys/conf.h>
                     38: #include <sys/ioctl.h>
                     39:
                     40: #include <uvm/uvm_extern.h>
                     41:
                     42: #include <machine/bus.h>
                     43: #include <machine/intr.h>
                     44:
                     45: #include <dev/tc/tcvar.h>
                     46: #include <machine/sfbreg.h>
                     47: #include <alpha/tc/sfbvar.h>
                     48:
                     49: #include <dev/rcons/raster.h>
                     50: #include <dev/wscons/wscons_raster.h>
                     51: #include <dev/wscons/wsdisplayvar.h>
                     52: #include <machine/fbio.h>
                     53:
                     54: #include <machine/autoconf.h>
                     55: #include <machine/pte.h>
                     56:
                     57: int    sfbmatch(struct device *, void *, void *);
                     58: void   sfbattach(struct device *, struct device *, void *);
                     59:
                     60: struct cfattach sfb_ca = {
                     61:        sizeof(struct sfb_softc), sfbmatch, sfbattach,
                     62: };
                     63:
                     64: struct cfdriver sfb_cd = {
                     65:        NULL, "sfb", DV_DULL,
                     66: };
                     67:
                     68: void   sfb_getdevconfig(tc_addr_t dense_addr, struct sfb_devconfig *dc);
                     69: struct sfb_devconfig sfb_console_dc;
                     70: tc_addr_t sfb_consaddr;
                     71:
                     72: struct wsdisplay_emulops sfb_emulfuncs = {
                     73:         rcons_cursor,                        /* could use hardware cursor; punt */
                     74:         rcons_mapchar,
                     75:         rcons_putchar,
                     76:         rcons_copycols,
                     77:         rcons_erasecols,
                     78:         rcons_copyrows,
                     79:         rcons_eraserows,
                     80:         rcons_alloc_attr
                     81: };
                     82:
                     83: struct wsscreen_descr sfb_stdscreen = {
                     84:         "std",
                     85:         0, 0,        /* will be filled in -- XXX shouldn't, it's global */
                     86:         &sfb_emulfuncs,
                     87:         0, 0
                     88: };
                     89: const struct wsscreen_descr *_sfb_scrlist[] = {
                     90:         &sfb_stdscreen,
                     91:         /* XXX other formats, graphics screen? */
                     92: };
                     93:
                     94: struct wsscreen_list sfb_screenlist = {
                     95:         sizeof(_sfb_scrlist) / sizeof(struct wsscreen_descr *), _sfb_scrlist
                     96: };
                     97:
                     98: int    sfbioctl(void *, u_long, caddr_t, int, struct proc *);
                     99: paddr_t        sfbmmap(void *, off_t, int);
                    100:
                    101: static int      sfb_alloc_screen(void *, const struct wsscreen_descr *,
                    102:                    void **, int *, int *, long *);
                    103: static void     sfb_free_screen(void *, void *);
                    104: static int      sfb_show_screen(void *, void *, int,
                    105:                    void (*) (void *, int, int), void *);
                    106:
                    107: #if 0
                    108: void   sfb_blank(struct sfb_devconfig *);
                    109: void   sfb_unblank(struct sfb_devconfig *);
                    110: #endif
                    111:
                    112: struct wsdisplay_accessops sfb_accessops = {
                    113:         sfbioctl,
                    114:         sfbmmap,
                    115:         sfb_alloc_screen,
                    116:         sfb_free_screen,
                    117:         sfb_show_screen,
                    118: };
                    119:
                    120: int
                    121: sfbmatch(parent, match, aux)
                    122:        struct device *parent;
                    123:        void *match;
                    124:        void *aux;
                    125: {
                    126:        struct tc_attach_args *ta = aux;
                    127:
                    128:        if (strncmp("PMAGB-BA", ta->ta_modname, TC_ROM_LLEN) != 0)
                    129:                return (0);
                    130:
                    131:        return (10);
                    132: }
                    133:
                    134: void
                    135: sfb_getdevconfig(dense_addr, dc)
                    136:        tc_addr_t dense_addr;
                    137:        struct sfb_devconfig *dc;
                    138: {
                    139:        struct raster *rap;
                    140:        struct rcons *rcp;
                    141:        char *regp, *ramdacregp;
                    142:        int i;
                    143:
                    144:        dc->dc_vaddr = dense_addr;
                    145:        dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr);       /* XXX */
                    146:        dc->dc_size = SFB_SIZE;
                    147:
                    148:        regp = (char *)dc->dc_vaddr + SFB_ASIC_OFFSET;
                    149:        ramdacregp = (char *)dc->dc_vaddr + SFB_RAMDAC_OFFSET;
                    150:
                    151:        dc->dc_wid =
                    152:            (*(volatile u_int32_t *)(regp + SFB_ASIC_VIDEO_HSETUP) & 0x1ff) * 4;
                    153:        dc->dc_ht =
                    154:            (*(volatile u_int32_t *)(regp + SFB_ASIC_VIDEO_VSETUP) & 0x7ff);
                    155:
                    156:        switch (*(volatile u_int32_t *)(regp + SFB_ASIC_DEEP)) {
                    157:        case 0:
                    158:        case 1:                                 /* XXX by the book; wrong? */
                    159:                dc->dc_depth = 8;               /* 8 plane */
                    160:                break;
                    161:        case 2:
                    162:                dc->dc_depth = 16;              /* 16 plane */
                    163:                break;
                    164:        case 4:
                    165:                dc->dc_depth = 32;              /* 32 plane */
                    166:                break;
                    167:        default:
                    168:                dc->dc_depth = 8;               /* XXX can't happen? */
                    169:                break;
                    170:        }
                    171:
                    172:        dc->dc_rowbytes = dc->dc_wid * (dc->dc_depth / 8);
                    173:
                    174:        dc->dc_videobase = dc->dc_vaddr + SFB_FB_OFFSET +
                    175:            ((*(volatile u_int32_t *)(regp + SFB_ASIC_VIDEO_BASE)) *
                    176:             4096 * (dc->dc_depth / 8));
                    177:
                    178:        (*(volatile u_int32_t *)(regp + SFB_ASIC_MODE)) = 0;
                    179:        tc_wmb();
                    180:        (*(volatile u_int32_t *)(regp + SFB_ASIC_VIDEO_VALID)) = 1;
                    181:        tc_wmb();
                    182:
                    183:        /*
                    184:         * Set all bits in the pixel mask, to enable writes to all pixels.
                    185:         * It seems that the console firmware clears some of them
                    186:         * under some circumstances, which causes cute vertical stripes.
                    187:         */
                    188:        (*(volatile u_int32_t *)(regp + SFB_ASIC_PIXELMASK)) = 0xffffffff;
                    189:        tc_wmb();
                    190:        (*(volatile u_int32_t *)(regp + SFB_ASIC_PLANEMASK)) = 0xffffffff;
                    191:        tc_wmb();
                    192:
                    193:        /* Initialize the RAMDAC/colormap */
                    194:        /* start XXX XXX XXX */
                    195:        (*(volatile u_int32_t *)(ramdacregp + SFB_RAMDAC_ADDRLOW)) = 0;
                    196:        (*(volatile u_int32_t *)(ramdacregp + SFB_RAMDAC_ADDRHIGH)) = 0;
                    197:        tc_wmb();
                    198:        for (i = 0; i < 256; i++) {
                    199:                (*(volatile u_int32_t *)(ramdacregp + SFB_RAMDAC_CMAPDATA)) =
                    200:                    i ? 0xff : 0;
                    201:                tc_wmb();
                    202:                (*(volatile u_int32_t *)(ramdacregp + SFB_RAMDAC_CMAPDATA)) =
                    203:                    i ? 0xff : 0;
                    204:                tc_wmb();
                    205:                (*(volatile u_int32_t *)(ramdacregp + SFB_RAMDAC_CMAPDATA)) =
                    206:                    i ? 0xff : 0;
                    207:                tc_wmb();
                    208:        }
                    209:        /* end XXX XXX XXX */
                    210:
                    211:        /* clear the screen */
                    212:        for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
                    213:                *(u_int32_t *)(dc->dc_videobase + i) = 0x00000000;
                    214:
                    215:        /* initialize the raster */
                    216:        rap = &dc->dc_raster;
                    217:        rap->width = dc->dc_wid;
                    218:        rap->height = dc->dc_ht;
                    219:        rap->depth = 8;
                    220:        rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t);
                    221:        rap->pixels = (u_int32_t *)dc->dc_videobase;
                    222:
                    223:        /* initialize the raster console blitter */
                    224:        rcp = &dc->dc_rcons;
                    225:        rcp->rc_sp = rap;
                    226:        rcp->rc_crow = rcp->rc_ccol = -1;
                    227:        rcp->rc_crowp = &rcp->rc_crow;
                    228:        rcp->rc_ccolp = &rcp->rc_ccol;
                    229:        rcons_init(rcp, 34, 80);
                    230:
                    231:         sfb_stdscreen.nrows = dc->dc_rcons.rc_maxrow;
                    232:         sfb_stdscreen.ncols = dc->dc_rcons.rc_maxcol;
                    233: }
                    234:
                    235: void
                    236: sfbattach(parent, self, aux)
                    237:        struct device *parent, *self;
                    238:        void *aux;
                    239: {
                    240:        struct sfb_softc *sc = (struct sfb_softc *)self;
                    241:        struct tc_attach_args *ta = aux;
                    242:        struct wsemuldisplaydev_attach_args waa;
                    243:        int console;
                    244:
                    245:        console = (ta->ta_addr == sfb_consaddr);
                    246:        if (console) {
                    247:                sc->sc_dc = &sfb_console_dc;
                    248:                sc->nscreens = 1;
                    249:        } else {
                    250:                sc->sc_dc = (struct sfb_devconfig *)
                    251:                    malloc(sizeof(struct sfb_devconfig), M_DEVBUF, M_WAITOK);
                    252:                sfb_getdevconfig(ta->ta_addr, sc->sc_dc);
                    253:        }
                    254:        if (sc->sc_dc->dc_vaddr == NULL) {
                    255:                printf(": couldn't map memory space; punt!\n");
                    256:                return;
                    257:        }
                    258:        printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
                    259:            sc->sc_dc->dc_depth);
                    260:
                    261: #if 0
                    262:        x = (char *)ta->ta_addr + SFB_ASIC_OFFSET;
                    263:        printf("%s: Video Base Address = 0x%x\n", self->dv_xname,
                    264:            *(u_int32_t *)(x + SFB_ASIC_VIDEO_BASE));
                    265:        printf("%s: Horizontal Setup = 0x%x\n", self->dv_xname,
                    266:            *(u_int32_t *)(x + SFB_ASIC_VIDEO_HSETUP));
                    267:        printf("%s: Vertical Setup = 0x%x\n", self->dv_xname,
                    268:            *(u_int32_t *)(x + SFB_ASIC_VIDEO_VSETUP));
                    269: #endif
                    270:
                    271:         waa.console = console;
                    272:         waa.scrdata = &sfb_screenlist;
                    273:         waa.accessops = &sfb_accessops;
                    274:         waa.accesscookie = sc;
                    275:        waa.defaultscreens = 0;
                    276:
                    277:         config_found(self, &waa, wsemuldisplaydevprint);
                    278: }
                    279:
                    280: int
                    281: sfbioctl(v, cmd, data, flag, p)
                    282:        void *v;
                    283:        u_long cmd;
                    284:        caddr_t data;
                    285:        int flag;
                    286:        struct proc *p;
                    287: {
                    288:        struct sfb_softc *sc = v;
                    289:        struct sfb_devconfig *dc = sc->sc_dc;
                    290:
                    291:        switch (cmd) {
                    292:        case FBIOGTYPE:
                    293: #define fbt ((struct fbtype *)data)
                    294:                fbt->fb_type = FBTYPE_SFB;
                    295:                fbt->fb_height = sc->sc_dc->dc_ht;
                    296:                fbt->fb_width = sc->sc_dc->dc_wid;
                    297:                fbt->fb_depth = sc->sc_dc->dc_depth;
                    298:                fbt->fb_cmsize = 256;           /* XXX ??? */
                    299:                fbt->fb_size = sc->sc_dc->dc_size;
                    300: #undef fbt
                    301:                return (0);
                    302:
                    303: #if 0
                    304:        case FBIOPUTCMAP:
                    305:                return (*tgar->tgar_set_cmap)(dc, (struct fbcmap *)data);
                    306:
                    307:        case FBIOGETCMAP:
                    308:                return (*tgar->tgar_get_cmap)(dc, (struct fbcmap *)data);
                    309: #endif
                    310:
                    311:        case FBIOGATTR:
                    312:                return (ENOTTY);                        /* XXX ? */
                    313:
                    314: #if 0
                    315:        case FBIOSVIDEO:
                    316:                if (*(int *)data == FBVIDEO_OFF)
                    317:                        sfb_blank(sc->sc_dc);
                    318:                else
                    319:                        sfb_unblank(sc->sc_dc);
                    320:                return (0);
                    321: #endif
                    322:
                    323:        case FBIOGVIDEO:
                    324:                *(int *)data = dc->dc_blanked ? FBVIDEO_OFF : FBVIDEO_ON;
                    325:                return (0);
                    326:
                    327: #if 0
                    328:        case FBIOSCURSOR:
                    329:                return (*tgar->tgar_set_cursor)(dc, (struct fbcursor *)data);
                    330:
                    331:        case FBIOGCURSOR:
                    332:                return (*tgar->tgar_get_cursor)(dc, (struct fbcursor *)data);
                    333:
                    334:        case FBIOSCURPOS:
                    335:                return (*tgar->tgar_set_curpos)(dc, (struct fbcurpos *)data);
                    336:
                    337:        case FBIOGCURPOS:
                    338:                return (*tgar->tgar_get_curpos)(dc, (struct fbcurpos *)data);
                    339:
                    340:        case FBIOGCURMAX:
                    341:                return (*tgar->tgar_get_curmax)(dc, (struct fbcurpos *)data);
                    342: #endif
                    343:        }
                    344:        return (-1);
                    345: }
                    346:
                    347: paddr_t
                    348: sfbmmap(v, offset, prot)
                    349:        void *v;
                    350:        off_t offset;
                    351:        int prot;
                    352: {
                    353:        struct sfb_softc *sc = v;
                    354:
                    355:        if (offset >= SFB_SIZE || offset < 0)
                    356:                return (-1);
                    357:        return atop(sc->sc_dc->dc_paddr + offset);
                    358: }
                    359:
                    360: int
                    361: sfb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
                    362:         void *v;
                    363:         const struct wsscreen_descr *type;
                    364:         void **cookiep;
                    365:         int *curxp, *curyp;
                    366:        long *attrp;
                    367: {
                    368:         struct sfb_softc *sc = v;
                    369:        long defattr;
                    370:
                    371:         if (sc->nscreens > 0)
                    372:                 return (ENOMEM);
                    373:
                    374:         *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */
                    375:         *curxp = 0;
                    376:         *curyp = 0;
                    377:        rcons_alloc_attr(&sc->sc_dc->dc_rcons, 0, 0, 0, &defattr);
                    378:        *attrp = defattr;
                    379:        sc->nscreens++;
                    380:         return (0);
                    381: }
                    382:
                    383: void
                    384: sfb_free_screen(v, cookie)
                    385:         void *v;
                    386:         void *cookie;
                    387: {
                    388:         struct sfb_softc *sc = v;
                    389:
                    390:         if (sc->sc_dc == &sfb_console_dc)
                    391:                 panic("sfb_free_screen: console");
                    392:
                    393:         sc->nscreens--;
                    394: }
                    395:
                    396: int
                    397: sfb_show_screen(v, cookie, waitok, cb, cbarg)
                    398:         void *v;
                    399:         void *cookie;
                    400:         int waitok;
                    401:         void (*cb)(void *, int, int);
                    402:         void *cbarg;
                    403: {
                    404:
                    405:         return (0);
                    406: }
                    407:
                    408: #if 0
                    409: int
                    410: sfb_cnattach(addr)
                    411:         tc_addr_t addr;
                    412: {
                    413:         struct sfb_devconfig *dcp = &sfb_console_dc;
                    414:        long defattr;
                    415:
                    416:         sfb_getdevconfig(addr, dcp);
                    417:
                    418:        rcons_alloc_attr(&dcp->dc_rcons, 0, 0, 0, &defattr);
                    419:
                    420:         wsdisplay_cnattach(&sfb_stdscreen, &dcp->dc_rcons,
                    421:                            0, 0, defattr);
                    422:         sfb_consaddr = addr;
                    423:         return(0);
                    424: }
                    425: #endif
                    426:
                    427: #if 0
                    428: /*
                    429:  * Functions to blank and unblank the display.
                    430:  */
                    431: void
                    432: sfb_blank(dc)
                    433:        struct sfb_devconfig *dc;
                    434: {
                    435:        char *regp = (char *)dc->dc_vaddr + SFB_ASIC_OFFSET;
                    436:
                    437:        if (!dc->dc_blanked) {
                    438:                dc->dc_blanked = 1;
                    439:                *(volatile u_int32_t *)(regp + SFB_ASIC_VIDEO_VALID) = 0;
                    440:                tc_wmb();
                    441:        }
                    442: }
                    443:
                    444: void
                    445: sfb_unblank(dc)
                    446:        struct sfb_devconfig *dc;
                    447: {
                    448:        char *regp = (char *)dc->dc_vaddr + SFB_ASIC_OFFSET;
                    449:
                    450:        if (dc->dc_blanked) {
                    451:                dc->dc_blanked = 0;
                    452:                *(volatile u_int32_t *)(regp + SFB_ASIC_VIDEO_VALID) = 1;
                    453:                tc_wmb();
                    454:        }
                    455: }
                    456: #endif

CVSweb