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

Annotation of sys/arch/sparc/dev/cgtwo.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: cgtwo.c,v 1.36 2006/12/03 16:40:06 miod Exp $ */
        !             2: /*     $NetBSD: cgtwo.c,v 1.22 1997/05/24 20:16:12 pk Exp $ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 2002 Miodrag Vallat.  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:  *
        !            29:  * Copyright (c) 1992, 1993
        !            30:  *     The Regents of the University of California.  All rights reserved.
        !            31:  *
        !            32:  * This software was developed by the Computer Systems Engineering group
        !            33:  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
        !            34:  * contributed to Berkeley.
        !            35:  *
        !            36:  * All advertising materials mentioning features or use of this software
        !            37:  * must display the following acknowledgement:
        !            38:  *     This product includes software developed by the University of
        !            39:  *     California, Lawrence Berkeley Laboratory.
        !            40:  *
        !            41:  * Redistribution and use in source and binary forms, with or without
        !            42:  * modification, are permitted provided that the following conditions
        !            43:  * are met:
        !            44:  * 1. Redistributions of source code must retain the above copyright
        !            45:  *    notice, this list of conditions and the following disclaimer.
        !            46:  * 2. Redistributions in binary form must reproduce the above copyright
        !            47:  *    notice, this list of conditions and the following disclaimer in the
        !            48:  *    documentation and/or other materials provided with the distribution.
        !            49:  * 3. Neither the name of the University nor the names of its contributors
        !            50:  *    may be used to endorse or promote products derived from this software
        !            51:  *    without specific prior written permission.
        !            52:  *
        !            53:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            54:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            55:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            56:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            57:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            58:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            59:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            60:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            61:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            62:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            63:  * SUCH DAMAGE.
        !            64:  *
        !            65:  *     from: @(#)cgthree.c     8.2 (Berkeley) 10/30/93
        !            66:  */
        !            67:
        !            68: /*
        !            69:  * color display (cgtwo) driver.
        !            70:  *
        !            71:  * Does not handle interrupts, even though they can occur.
        !            72:  *
        !            73:  * XXX should defer colormap updates to vertical retrace interrupts
        !            74:  */
        !            75:
        !            76: #include <sys/param.h>
        !            77: #include <sys/systm.h>
        !            78: #include <sys/buf.h>
        !            79: #include <sys/device.h>
        !            80: #include <sys/ioctl.h>
        !            81: #include <sys/malloc.h>
        !            82: #include <sys/mman.h>
        !            83: #include <sys/tty.h>
        !            84: #include <sys/conf.h>
        !            85:
        !            86: #include <uvm/uvm_extern.h>
        !            87:
        !            88: #include <machine/autoconf.h>
        !            89: #include <machine/pmap.h>
        !            90: #if defined(SUN4)
        !            91: #include <machine/eeprom.h>
        !            92: #endif
        !            93: #include <machine/conf.h>
        !            94:
        !            95: #include <sparc/dev/cgtworeg.h>
        !            96:
        !            97: #include <dev/wscons/wsconsio.h>
        !            98: #include <dev/wscons/wsdisplayvar.h>
        !            99: #include <dev/rasops/rasops.h>
        !           100: #include <machine/fbvar.h>
        !           101:
        !           102:
        !           103: /* per-display variables */
        !           104: struct cgtwo_softc {
        !           105:        struct  sunfb sc_sunfb;         /* common base part */
        !           106:        struct  rom_reg sc_phys;        /* display RAM (phys addr) */
        !           107:        volatile struct cg2statusreg *sc_reg;   /* CG2 control registers */
        !           108:        volatile u_short *sc_ppmask;
        !           109:        volatile u_short *sc_cmap;
        !           110: #define sc_redmap(cmap)                ((cmap))
        !           111: #define sc_greenmap(cmap)      ((cmap) + CG2_CMSIZE)
        !           112: #define sc_bluemap(cmap)       ((cmap) + 2 * CG2_CMSIZE)
        !           113: };
        !           114:
        !           115: void   cgtwo_burner(void *, u_int, u_int);
        !           116: int    cgtwo_getcmap(struct cgtwo_softc *, struct wsdisplay_cmap *);
        !           117: int    cgtwo_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !           118: paddr_t        cgtwo_mmap(void *, off_t, int);
        !           119: int    cgtwo_putcmap(struct cgtwo_softc *, struct wsdisplay_cmap *);
        !           120: void   cgtwo_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
        !           121:
        !           122: struct wsdisplay_accessops cgtwo_accessops = {
        !           123:        cgtwo_ioctl,
        !           124:        cgtwo_mmap,
        !           125:        NULL,   /* alloc_screen */
        !           126:        NULL,   /* free_screen */
        !           127:        NULL,   /* show_screen */
        !           128:        NULL,   /* load_font */
        !           129:        NULL,   /* scrollback */
        !           130:        NULL,   /* getchar */
        !           131:        cgtwo_burner,
        !           132:        NULL    /* pollc */
        !           133: };
        !           134:
        !           135: int    cgtwomatch(struct device *, void *, void *);
        !           136: void   cgtwoattach(struct device *, struct device *, void *);
        !           137:
        !           138: struct cfattach cgtwo_ca = {
        !           139:        sizeof(struct cgtwo_softc), cgtwomatch, cgtwoattach
        !           140: };
        !           141:
        !           142: struct cfdriver cgtwo_cd = {
        !           143:        NULL, "cgtwo", DV_DULL
        !           144: };
        !           145:
        !           146: int
        !           147: cgtwomatch(struct device *parent, void *vcf, void *aux)
        !           148: {
        !           149:        struct cfdata *cf = vcf;
        !           150:        struct confargs *ca = aux;
        !           151:        struct romaux *ra = &ca->ca_ra;
        !           152:        caddr_t tmp;
        !           153:
        !           154:        if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
        !           155:                return (0);
        !           156:
        !           157:        if (!CPU_ISSUN4 || ca->ca_bustype != BUS_VME16)
        !           158:                return (0);
        !           159:
        !           160:        /* XXX - Must do our own mapping at CG2_CTLREG_OFF */
        !           161:        bus_untmp();
        !           162:        tmp = (caddr_t)mapdev(ra->ra_reg, TMPMAP_VA, CG2_CTLREG_OFF, NBPG);
        !           163:        if (probeget(tmp, 2) != -1)
        !           164:                return (1);
        !           165:
        !           166:        return (0);
        !           167: }
        !           168:
        !           169: void
        !           170: cgtwoattach(struct device *parent, struct device *self, void *args)
        !           171: {
        !           172:        struct cgtwo_softc *sc = (struct cgtwo_softc *)self;
        !           173:        struct confargs *ca = args;
        !           174:        int node = 0;
        !           175:        int isconsole = 0;
        !           176:
        !           177:        if (CPU_ISSUN4) {
        !           178:                struct eeprom *eep = (struct eeprom *)eeprom_va;
        !           179:                /*
        !           180:                 * Assume this is the console if there's no eeprom info
        !           181:                 * to be found.
        !           182:                 */
        !           183:                if (eep == NULL || eep->eeConsole == EE_CONS_COLOR)
        !           184:                        isconsole = 1;
        !           185:        }
        !           186:
        !           187:        /*
        !           188:         * When the ROM has mapped in a cgtwo display, the address
        !           189:         * maps only the video RAM, so in any case we have to map the
        !           190:         * registers ourselves.
        !           191:         */
        !           192:        sc->sc_phys = ca->ca_ra.ra_reg[0];
        !           193:        /* Apparently, the pixels are 32-bit data space */
        !           194:        sc->sc_phys.rr_iospace = PMAP_VME32;
        !           195:
        !           196:        sc->sc_reg = (volatile struct cg2statusreg *)
        !           197:            mapiodev(ca->ca_ra.ra_reg,
        !           198:                CG2_ROPMEM_OFF + offsetof(struct cg2fb, status.reg),
        !           199:                sizeof(struct cg2statusreg));
        !           200:
        !           201:        sc->sc_ppmask = (volatile u_short *)
        !           202:            mapiodev(ca->ca_ra.ra_reg,
        !           203:                CG2_ROPMEM_OFF + offsetof(struct cg2fb, ppmask.reg),
        !           204:                sizeof(u_short));
        !           205:
        !           206:        sc->sc_cmap = (volatile u_short *)
        !           207:            mapiodev(ca->ca_ra.ra_reg,
        !           208:                     CG2_ROPMEM_OFF + offsetof(struct cg2fb, redmap),
        !           209:                     3 * CG2_CMSIZE * sizeof(u_short));
        !           210:
        !           211:        /* enable video */
        !           212:        *sc->sc_ppmask = 0xffff;        /* enable all color planes... */
        !           213:        cgtwo_burner(sc, 1, 0);         /* ... and video signals */
        !           214:
        !           215:        fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
        !           216:        sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, CG2_PIXMAP_OFF,
        !           217:            round_page(sc->sc_sunfb.sf_fbsize));
        !           218:        sc->sc_sunfb.sf_ro.ri_hw = sc;
        !           219:        fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
        !           220:        fbwscons_setcolormap(&sc->sc_sunfb, cgtwo_setcolor);
        !           221:
        !           222:        printf(": %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
        !           223:
        !           224:        if (isconsole) {
        !           225:                fbwscons_console_init(&sc->sc_sunfb, -1);
        !           226:        }
        !           227:
        !           228:        fbwscons_attach(&sc->sc_sunfb, &cgtwo_accessops, isconsole);
        !           229: }
        !           230:
        !           231: int
        !           232: cgtwo_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
        !           233: {
        !           234:        struct cgtwo_softc *sc = v;
        !           235:        struct wsdisplay_fbinfo *wdf;
        !           236:        struct wsdisplay_cmap *cm;
        !           237:        int error;
        !           238:
        !           239:        switch (cmd) {
        !           240:        case WSDISPLAYIO_GTYPE:
        !           241:                *(u_int *)data = WSDISPLAY_TYPE_SUNCG2;
        !           242:                break;
        !           243:        case WSDISPLAYIO_GINFO:
        !           244:                wdf = (struct wsdisplay_fbinfo *)data;
        !           245:                wdf->height = sc->sc_sunfb.sf_height;
        !           246:                wdf->width  = sc->sc_sunfb.sf_width;
        !           247:                wdf->depth  = sc->sc_sunfb.sf_depth;
        !           248:                wdf->cmsize = CG2_CMSIZE;
        !           249:                break;
        !           250:        case WSDISPLAYIO_LINEBYTES:
        !           251:                *(u_int *)data = sc->sc_sunfb.sf_linebytes;
        !           252:                break;
        !           253:
        !           254:        case WSDISPLAYIO_GETCMAP:
        !           255:                cm = (struct wsdisplay_cmap *)data;
        !           256:                error = cgtwo_getcmap(sc, cm);
        !           257:                if (error)
        !           258:                        return (error);
        !           259:                break;
        !           260:
        !           261:        case WSDISPLAYIO_PUTCMAP:
        !           262:                cm = (struct wsdisplay_cmap *)data;
        !           263:                error = cgtwo_putcmap(sc, cm);
        !           264:                if (error)
        !           265:                        return (error);
        !           266:                break;
        !           267:
        !           268:        case WSDISPLAYIO_SVIDEO:
        !           269:        case WSDISPLAYIO_GVIDEO:
        !           270:                break;
        !           271:
        !           272:        case WSDISPLAYIO_GCURPOS:
        !           273:        case WSDISPLAYIO_SCURPOS:
        !           274:        case WSDISPLAYIO_GCURMAX:
        !           275:        case WSDISPLAYIO_GCURSOR:
        !           276:        case WSDISPLAYIO_SCURSOR:
        !           277:        default:
        !           278:                return (-1);    /* not supported yet */
        !           279:        }
        !           280:
        !           281:        return (0);
        !           282: }
        !           283:
        !           284: paddr_t
        !           285: cgtwo_mmap(void *v, off_t offset, int prot)
        !           286: {
        !           287:        struct cgtwo_softc *sc = v;
        !           288:
        !           289:        if (offset & PGOFSET)
        !           290:                return (-1);
        !           291:
        !           292:        if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
        !           293:                return (REG2PHYS(&sc->sc_phys,
        !           294:                    CG2_PIXMAP_OFF + offset) | PMAP_NC);
        !           295:        }
        !           296:
        !           297:        return (-1);
        !           298: }
        !           299:
        !           300: void
        !           301: cgtwo_burner(void *v, u_int on, u_int flags)
        !           302: {
        !           303:        struct cgtwo_softc *sc = v;
        !           304:        int s;
        !           305:
        !           306:        s = splhigh();
        !           307:        if (on)
        !           308:                sc->sc_reg->video_enab = 1;
        !           309:        else
        !           310:                sc->sc_reg->video_enab = 0;
        !           311:        splx(s);
        !           312: }
        !           313:
        !           314: int
        !           315: cgtwo_getcmap(struct cgtwo_softc *sc, struct wsdisplay_cmap *cmap)
        !           316: {
        !           317:        u_int index = cmap->index, count = cmap->count, i;
        !           318:        u_char red[CG2_CMSIZE], green[CG2_CMSIZE], blue[CG2_CMSIZE];
        !           319:        volatile u_short *hwcmap = sc->sc_cmap;
        !           320:        int error;
        !           321:        volatile u_short *p;
        !           322:
        !           323:
        !           324:        if (index >= CG2_CMSIZE || count >= CG2_CMSIZE - index)
        !           325:                return (EINVAL);
        !           326:
        !           327:        while (sc->sc_reg->retrace == 0)
        !           328:                DELAY(1);
        !           329:
        !           330:        sc->sc_reg->update_cmap = 0;
        !           331:
        !           332:        /* Copy hardware to local arrays. */
        !           333:        p = &sc_redmap(hwcmap)[index];
        !           334:        for (i = 0; i < count; i++)
        !           335:                red[i] = *p++;
        !           336:        p = &sc_greenmap(hwcmap)[index];
        !           337:        for (i = 0; i < count; i++)
        !           338:                green[i] = *p++;
        !           339:        p = &sc_bluemap(hwcmap)[index];
        !           340:        for (i = 0; i < count; i++)
        !           341:                blue[i] = *p++;
        !           342:
        !           343:        sc->sc_reg->update_cmap = 1;
        !           344:
        !           345:        /* Copy local arrays to user space. */
        !           346:        if ((error = copyout(red, cmap->red, count)) != 0)
        !           347:                return (error);
        !           348:        if ((error = copyout(green, cmap->green, count)) != 0)
        !           349:                return (error);
        !           350:        if ((error = copyout(blue, cmap->blue, count)) != 0)
        !           351:                return (error);
        !           352:
        !           353:        return (0);
        !           354: }
        !           355:
        !           356: int
        !           357: cgtwo_putcmap(struct cgtwo_softc *sc, struct wsdisplay_cmap *cmap)
        !           358: {
        !           359:        u_int index = cmap->index, count = cmap->count, i;
        !           360:        u_char red[CG2_CMSIZE], green[CG2_CMSIZE], blue[CG2_CMSIZE];
        !           361:        volatile u_short *hwcmap = sc->sc_cmap;
        !           362:        int error;
        !           363:        volatile u_short *p;
        !           364:
        !           365:        if (index >= CG2_CMSIZE || count >= CG2_CMSIZE - index)
        !           366:                return (EINVAL);
        !           367:
        !           368:        /* Copy from user space to local arrays. */
        !           369:        if ((error = copyin(cmap->red, red, count)) != 0)
        !           370:                return (error);
        !           371:        if ((error = copyin(cmap->green, green, count)) != 0)
        !           372:                return (error);
        !           373:        if ((error = copyin(cmap->blue, blue, count)) != 0)
        !           374:                return (error);
        !           375:
        !           376:        while (sc->sc_reg->retrace == 0)
        !           377:                DELAY(1);
        !           378:
        !           379:        sc->sc_reg->update_cmap = 0;
        !           380:
        !           381:        /* Copy from local arrays to hardware. */
        !           382:        p = &sc_redmap(hwcmap)[index];
        !           383:        for (i = 0; i < count; i++)
        !           384:                *p++ = red[i];
        !           385:        p = &sc_greenmap(hwcmap)[index];
        !           386:        for (i = 0; i < count; i++)
        !           387:                *p++ = green[i];
        !           388:        p = &sc_bluemap(hwcmap)[index];
        !           389:        for (i = 0; i < count; i++)
        !           390:                *p++ = blue[i];
        !           391:
        !           392:        sc->sc_reg->update_cmap = 1;
        !           393:
        !           394:        return (0);
        !           395: }
        !           396:
        !           397: void
        !           398: cgtwo_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
        !           399: {
        !           400:        struct cgtwo_softc *sc = v;
        !           401:
        !           402:        while (sc->sc_reg->retrace == 0)
        !           403:                DELAY(1);
        !           404:
        !           405:        sc->sc_reg->update_cmap = 0;
        !           406:
        !           407:        sc_redmap(sc->sc_cmap)[index] = r;
        !           408:        sc_greenmap(sc->sc_cmap)[index] = g;
        !           409:        sc_bluemap(sc->sc_cmap)[index] = b;
        !           410:
        !           411:        sc->sc_reg->update_cmap = 1;
        !           412: }

CVSweb