[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     ! 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