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

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

1.1     ! nbrk        1: /*     $OpenBSD: bwtwo.c,v 1.17 2006/12/17 22:18:16 miod Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2002 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: #define        BWTWO_CTRL_OFFSET       0x400000
        !            54: #define        BWTWO_CTRL_SIZE (sizeof(u_int32_t) * 8)
        !            55: #define        BWTWO_VID_OFFSET        0x800000
        !            56: #define        BWTWO_VID_SIZE  (1024 * 1024)
        !            57:
        !            58: #define        FBC_CTRL        0x10            /* control */
        !            59: #define        FBC_STAT        0x11            /* status */
        !            60: #define        FBC_START       0x12            /* cursor start */
        !            61: #define        FBC_END         0x13            /* cursor end */
        !            62: #define        FBC_VCTRL       0x14            /* 12 bytes of timing goo */
        !            63:
        !            64: #define        FBC_CTRL_IENAB          0x80    /* interrupt enable */
        !            65: #define        FBC_CTRL_VENAB          0x40    /* video enable */
        !            66: #define        FBC_CTRL_TIME           0x20    /* timing enable */
        !            67: #define        FBC_CTRL_CURS           0x10    /* cursor compare enable */
        !            68: #define        FBC_CTRL_XTAL           0x0c    /* xtal select (0,1,2,test): */
        !            69: #define        FBC_CTRL_XTAL_0         0x00    /*  0 */
        !            70: #define        FBC_CTRL_XTAL_1         0x04    /*  0 */
        !            71: #define        FBC_CTRL_XTAL_2         0x08    /*  0 */
        !            72: #define        FBC_CTRL_XTAL_TEST      0x0c    /*  0 */
        !            73: #define        FBC_CTRL_DIV            0x03    /* divisor (1,2,3,4): */
        !            74: #define        FBC_CTRL_DIV_1          0x00    /*  / 1 */
        !            75: #define        FBC_CTRL_DIV_2          0x01    /*  / 2 */
        !            76: #define        FBC_CTRL_DIV_3          0x02    /*  / 3 */
        !            77: #define        FBC_CTRL_DIV_4          0x03    /*  / 4 */
        !            78:
        !            79: #define        FBC_STAT_INTR           0x80    /* interrupt pending */
        !            80: #define        FBC_STAT_RES            0x70    /* monitor sense: */
        !            81: #define        FBC_STAT_RES_1024       0x10    /*  1024x768 */
        !            82: #define        FBC_STAT_RES_1280       0x40    /*  1280x1024 */
        !            83: #define        FBC_STAT_RES_1152       0x30    /*  1152x900 */
        !            84: #define        FBC_STAT_RES_1152A      0x40    /*  1152x900x76, A */
        !            85: #define        FBC_STAT_RES_1600       0x50    /*  1600x1200 */
        !            86: #define        FBC_STAT_RES_1152B      0x60    /*  1152x900x86, B */
        !            87: #define        FBC_STAT_ID             0x0f    /* id mask: */
        !            88: #define        FBC_STAT_ID_COLOR       0x01    /*  color */
        !            89: #define        FBC_STAT_ID_MONO        0x02    /*  monochrome */
        !            90: #define        FBC_STAT_ID_MONOECL     0x03    /*  monochrome, ecl */
        !            91:
        !            92: #define        FBC_READ(sc, reg) \
        !            93:     bus_space_read_1((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg))
        !            94: #define        FBC_WRITE(sc, reg, val) \
        !            95:     bus_space_write_1((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg), (val))
        !            96:
        !            97: struct bwtwo_softc {
        !            98:        struct sunfb sc_sunfb;
        !            99:        bus_space_tag_t sc_bustag;
        !           100:        bus_addr_t sc_paddr;
        !           101:        bus_space_handle_t sc_ctrl_regs;
        !           102:        bus_space_handle_t sc_vid_regs;
        !           103:        int sc_nscreens;
        !           104: };
        !           105:
        !           106: int bwtwo_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !           107: int bwtwo_alloc_screen(void *, const struct wsscreen_descr *, void **,
        !           108:     int *, int *, long *);
        !           109: void bwtwo_free_screen(void *, void *);
        !           110: int bwtwo_show_screen(void *, void *, int, void (*cb)(void *, int, int),
        !           111:     void *);
        !           112: paddr_t bwtwo_mmap(void *, off_t, int);
        !           113: int bwtwo_is_console(int);
        !           114: void bwtwo_burner(void *, u_int, u_int);
        !           115:
        !           116: struct wsdisplay_accessops bwtwo_accessops = {
        !           117:        bwtwo_ioctl,
        !           118:        bwtwo_mmap,
        !           119:        bwtwo_alloc_screen,
        !           120:        bwtwo_free_screen,
        !           121:        bwtwo_show_screen,
        !           122:        NULL,   /* load_font */
        !           123:        NULL,   /* scrollback */
        !           124:        NULL,   /* getchar */
        !           125:        bwtwo_burner,
        !           126: };
        !           127:
        !           128: int    bwtwomatch(struct device *, void *, void *);
        !           129: void   bwtwoattach(struct device *, struct device *, void *);
        !           130:
        !           131: struct cfattach bwtwo_ca = {
        !           132:        sizeof (struct bwtwo_softc), bwtwomatch, bwtwoattach
        !           133: };
        !           134:
        !           135: struct cfdriver bwtwo_cd = {
        !           136:        NULL, "bwtwo", DV_DULL
        !           137: };
        !           138:
        !           139: int
        !           140: bwtwomatch(parent, vcf, aux)
        !           141:        struct device *parent;
        !           142:        void *vcf, *aux;
        !           143: {
        !           144:        struct cfdata *cf = vcf;
        !           145:        struct sbus_attach_args *sa = aux;
        !           146:
        !           147:        return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0);
        !           148: }
        !           149:
        !           150: void
        !           151: bwtwoattach(parent, self, aux)
        !           152:        struct device *parent, *self;
        !           153:        void *aux;
        !           154: {
        !           155:        struct bwtwo_softc *sc = (struct bwtwo_softc *)self;
        !           156:        struct sbus_attach_args *sa = aux;
        !           157:        int node, console;
        !           158:        const char *nam;
        !           159:
        !           160:        node = sa->sa_node;
        !           161:        sc->sc_bustag = sa->sa_bustag;
        !           162:        sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset);
        !           163:
        !           164:        fb_setsize(&sc->sc_sunfb, 1, 1152, 900, node, 0);
        !           165:
        !           166:        if (sa->sa_nreg != 1) {
        !           167:                printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
        !           168:                goto fail;
        !           169:        }
        !           170:
        !           171:        /*
        !           172:         * Map just CTRL and video RAM.
        !           173:         */
        !           174:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           175:            sa->sa_reg[0].sbr_offset + BWTWO_CTRL_OFFSET,
        !           176:            BWTWO_CTRL_SIZE, 0, 0, &sc->sc_ctrl_regs) != 0) {
        !           177:                printf(": cannot map ctrl registers\n");
        !           178:                goto fail_ctrl;
        !           179:        }
        !           180:
        !           181:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           182:            sa->sa_reg[0].sbr_offset + BWTWO_VID_OFFSET,
        !           183:            sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR,
        !           184:            0, &sc->sc_vid_regs) != 0) {
        !           185:                printf(": cannot map vid registers\n");
        !           186:                goto fail_vid;
        !           187:        }
        !           188:
        !           189:        nam = getpropstring(node, "model");
        !           190:        if (*nam == '\0')
        !           191:                nam = sa->sa_name;
        !           192:        printf(": %s", nam);
        !           193:
        !           194:        console = bwtwo_is_console(node);
        !           195:
        !           196:        bwtwo_burner(sc, 1, 0);
        !           197:
        !           198:        printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
        !           199:
        !           200:        sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag,
        !           201:            sc->sc_vid_regs);
        !           202:        sc->sc_sunfb.sf_ro.ri_hw = sc;
        !           203:        fbwscons_init(&sc->sc_sunfb, console ? 0 : RI_CLEAR);
        !           204:
        !           205:        if (console) {
        !           206:                fbwscons_console_init(&sc->sc_sunfb, -1);
        !           207:        }
        !           208:
        !           209:        fbwscons_attach(&sc->sc_sunfb, &bwtwo_accessops, console);
        !           210:
        !           211:        return;
        !           212:
        !           213: fail_vid:
        !           214:        bus_space_unmap(sa->sa_bustag, sc->sc_ctrl_regs, BWTWO_CTRL_SIZE);
        !           215: fail_ctrl:
        !           216: fail:
        !           217: ;
        !           218: }
        !           219:
        !           220: int
        !           221: bwtwo_ioctl(v, cmd, data, flags, p)
        !           222:        void *v;
        !           223:        u_long cmd;
        !           224:        caddr_t data;
        !           225:        int flags;
        !           226:        struct proc *p;
        !           227: {
        !           228:        struct bwtwo_softc *sc = v;
        !           229:        struct wsdisplay_fbinfo *wdf;
        !           230:
        !           231:        switch (cmd) {
        !           232:        case WSDISPLAYIO_GTYPE:
        !           233:                *(u_int *)data = WSDISPLAY_TYPE_SUNBW;
        !           234:                break;
        !           235:        case WSDISPLAYIO_GINFO:
        !           236:                wdf = (void *)data;
        !           237:                wdf->height = sc->sc_sunfb.sf_height;
        !           238:                wdf->width  = sc->sc_sunfb.sf_width;
        !           239:                wdf->depth  = sc->sc_sunfb.sf_depth;
        !           240:                wdf->cmsize = 0;
        !           241:                break;
        !           242:        case WSDISPLAYIO_LINEBYTES:
        !           243:                *(u_int *)data = sc->sc_sunfb.sf_linebytes;
        !           244:                break;
        !           245:
        !           246:        case WSDISPLAYIO_GETCMAP:
        !           247:        case WSDISPLAYIO_PUTCMAP:
        !           248:                break;
        !           249:
        !           250:        case WSDISPLAYIO_SVIDEO:
        !           251:        case WSDISPLAYIO_GVIDEO:
        !           252:                break;
        !           253:
        !           254:        case WSDISPLAYIO_GCURPOS:
        !           255:        case WSDISPLAYIO_SCURPOS:
        !           256:        case WSDISPLAYIO_GCURMAX:
        !           257:        case WSDISPLAYIO_GCURSOR:
        !           258:        case WSDISPLAYIO_SCURSOR:
        !           259:        default:
        !           260:                return -1; /* not supported yet */
        !           261:         }
        !           262:
        !           263:        return (0);
        !           264: }
        !           265:
        !           266: int
        !           267: bwtwo_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
        !           268:        void *v;
        !           269:        const struct wsscreen_descr *type;
        !           270:        void **cookiep;
        !           271:        int *curxp, *curyp;
        !           272:        long *attrp;
        !           273: {
        !           274:        struct bwtwo_softc *sc = v;
        !           275:
        !           276:        if (sc->sc_nscreens > 0)
        !           277:                return (ENOMEM);
        !           278:
        !           279:        *cookiep = &sc->sc_sunfb.sf_ro;
        !           280:        *curyp = 0;
        !           281:        *curxp = 0;
        !           282:        sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
        !           283:            0, 0, 0, attrp);
        !           284:        sc->sc_nscreens++;
        !           285:        return (0);
        !           286: }
        !           287:
        !           288: void
        !           289: bwtwo_free_screen(v, cookie)
        !           290:        void *v;
        !           291:        void *cookie;
        !           292: {
        !           293:        struct bwtwo_softc *sc = v;
        !           294:
        !           295:        sc->sc_nscreens--;
        !           296: }
        !           297:
        !           298: int
        !           299: bwtwo_show_screen(v, cookie, waitok, cb, cbarg)
        !           300:        void *v;
        !           301:        void *cookie;
        !           302:        int waitok;
        !           303:        void (*cb)(void *, int, int);
        !           304:        void *cbarg;
        !           305: {
        !           306:        return (0);
        !           307: }
        !           308:
        !           309: #define        START           (128 * 1024 + 128 * 1024)
        !           310: #define        NOOVERLAY       (0x04000000)
        !           311:
        !           312: paddr_t
        !           313: bwtwo_mmap(v, offset, prot)
        !           314:        void *v;
        !           315:        off_t offset;
        !           316:        int prot;
        !           317: {
        !           318:        struct bwtwo_softc *sc = v;
        !           319:
        !           320:        if (offset & PGOFSET)
        !           321:                return (-1);
        !           322:
        !           323:        if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize)
        !           324:                return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
        !           325:                    BWTWO_VID_OFFSET + offset, prot, BUS_SPACE_MAP_LINEAR));
        !           326:
        !           327:        return (-1);
        !           328: }
        !           329:
        !           330: int
        !           331: bwtwo_is_console(node)
        !           332:        int node;
        !           333: {
        !           334:        extern int fbnode;
        !           335:
        !           336:        return (fbnode == node);
        !           337: }
        !           338:
        !           339: void
        !           340: bwtwo_burner(vsc, on, flags)
        !           341:        void *vsc;
        !           342:        u_int on, flags;
        !           343: {
        !           344:        struct bwtwo_softc *sc = vsc;
        !           345:        int s;
        !           346:        u_int8_t fbc;
        !           347:
        !           348:        s = splhigh();
        !           349:        fbc = FBC_READ(sc, FBC_CTRL);
        !           350:        if (on)
        !           351:                fbc |= FBC_CTRL_VENAB | FBC_CTRL_TIME;
        !           352:        else {
        !           353:                fbc &= ~FBC_CTRL_VENAB;
        !           354:                if (flags & WSDISPLAY_BURN_VBLANK)
        !           355:                        fbc &= ~FBC_CTRL_TIME;
        !           356:        }
        !           357:        FBC_WRITE(sc, FBC_CTRL, fbc);
        !           358:        splx(s);
        !           359: }

CVSweb