[BACK]Return to cgsix.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / sun

Annotation of src/sys/dev/sun/cgsix.c, Revision 1.3

1.3     ! eeh         1: /*     $NetBSD: cgsix.c,v 1.2 2000/08/26 16:06:22 eeh Exp $ */
1.1       pk          2:
                      3: /*-
                      4:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Paul Kranenburg.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *        This product includes software developed by the NetBSD
                     21:  *        Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: /*
                     40:  * Copyright (c) 1993
                     41:  *     The Regents of the University of California.  All rights reserved.
                     42:  *
                     43:  * This software was developed by the Computer Systems Engineering group
                     44:  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
                     45:  * contributed to Berkeley.
                     46:  *
                     47:  * All advertising materials mentioning features or use of this software
                     48:  * must display the following acknowledgement:
                     49:  *     This product includes software developed by the University of
                     50:  *     California, Lawrence Berkeley Laboratory.
                     51:  *
                     52:  * Redistribution and use in source and binary forms, with or without
                     53:  * modification, are permitted provided that the following conditions
                     54:  * are met:
                     55:  * 1. Redistributions of source code must retain the above copyright
                     56:  *    notice, this list of conditions and the following disclaimer.
                     57:  * 2. Redistributions in binary form must reproduce the above copyright
                     58:  *    notice, this list of conditions and the following disclaimer in the
                     59:  *    documentation and/or other materials provided with the distribution.
                     60:  * 3. All advertising materials mentioning features or use of this software
                     61:  *    must display the following acknowledgement:
                     62:  *     This product includes software developed by the University of
                     63:  *     California, Berkeley and its contributors.
                     64:  * 4. Neither the name of the University nor the names of its contributors
                     65:  *    may be used to endorse or promote products derived from this software
                     66:  *    without specific prior written permission.
                     67:  *
                     68:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     69:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     70:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     71:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     72:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     73:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     74:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     75:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     76:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     77:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     78:  * SUCH DAMAGE.
                     79:  *
                     80:  *     @(#)cgsix.c     8.4 (Berkeley) 1/21/94
                     81:  */
                     82:
                     83: /*
                     84:  * color display (cgsix) driver.
                     85:  *
                     86:  * Does not handle interrupts, even though they can occur.
                     87:  *
                     88:  * XXX should defer colormap updates to vertical retrace interrupts
                     89:  */
                     90:
                     91: #include <sys/param.h>
                     92: #include <sys/systm.h>
                     93: #include <sys/buf.h>
                     94: #include <sys/device.h>
                     95: #include <sys/ioctl.h>
                     96: #include <sys/malloc.h>
                     97: #include <sys/mman.h>
                     98: #include <sys/tty.h>
                     99: #include <sys/conf.h>
                    100:
                    101: #ifdef DEBUG
                    102: #include <sys/proc.h>
                    103: #include <sys/syslog.h>
                    104: #endif
                    105:
                    106: #include <uvm/uvm_extern.h>
                    107:
                    108: #include <machine/bus.h>
                    109:
                    110: #include <dev/sun/fbio.h>
                    111: #include <dev/sun/fbvar.h>
                    112:
                    113: #include <dev/sun/btreg.h>
                    114: #include <dev/sun/btvar.h>
                    115: #include <dev/sun/cgsixreg.h>
                    116: #include <dev/sun/cgsixvar.h>
                    117: #include <dev/sun/pfourreg.h>
                    118:
                    119: #ifdef RASTERCONSOLE
                    120: #include <dev/rasops/rasops.h>
                    121: #include <dev/wscons/wsconsio.h>
                    122: #endif
                    123:
                    124: #include <machine/conf.h>
                    125:
                    126: static void    cg6_unblank(struct device *);
                    127:
                    128: /* cdevsw prototypes */
                    129: cdev_decl(cgsix);
                    130:
                    131: extern struct cfdriver cgsix_cd;
                    132:
                    133: /* frame buffer generic driver */
                    134: static struct fbdriver cg6_fbdriver = {
                    135:        cg6_unblank, cgsixopen, cgsixclose, cgsixioctl, cgsixpoll, cgsixmmap
                    136: };
                    137:
                    138: static void cg6_reset (struct cgsix_softc *);
                    139: static void cg6_loadcmap (struct cgsix_softc *, int, int);
                    140: static void cg6_loadomap (struct cgsix_softc *);
                    141: static void cg6_setcursor (struct cgsix_softc *);/* set position */
                    142: static void cg6_loadcursor (struct cgsix_softc *);/* set shape */
                    143:
                    144: #ifdef RASTERCONSOLE
                    145: int cgsix_use_rasterconsole = 1;
                    146:
                    147: /*
                    148:  * cg6 accelerated console routines.
                    149:  *
                    150:  * Note that buried in this code in several places is the assumption
                    151:  * that pixels are exactly one byte wide.  Since this is cg6-specific
                    152:  * code, this seems safe.  This assumption resides in things like the
                    153:  * use of ri_emuwidth without messing around with ri_pelbytes, or the
                    154:  * assumption that ri_font->fontwidth is the right thing to multiply
                    155:  * character-cell counts by to get byte counts.
                    156:  */
                    157:
                    158: /*
                    159:  * Magic values for blitter
                    160:  */
                    161:
                    162: /* Value for the alu register for screen-to-screen copies */
                    163: #define CG6_ALU_COPY   (                                               \
                    164:          0x80000000 /* GX_PLANE_ONES (ignore planemask register) */    \
                    165:        | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */    \
                    166:        | 0x00800000 /* GX_ATTR_SUPP (function unknown) */              \
                    167:        | 0x00000000 /* GX_RAST_BOOL (function unknown) */              \
                    168:        | 0x00000000 /* GX_PLOT_PLOT (function unknown) */              \
                    169:        | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */             \
                    170:        | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */  \
                    171:        | 0x0000cccc /* ALU = src */                                    \
                    172: )
                    173:
                    174: /* Value for the alu register for region fills */
                    175: #define CG6_ALU_FILL   (                                               \
                    176:          0x80000000 /* GX_PLANE_ONES (ignore planemask register) */    \
                    177:        | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */    \
                    178:        | 0x00800000 /* GX_ATTR_SUPP (function unknown) */              \
                    179:        | 0x00000000 /* GX_RAST_BOOL (function unknown) */              \
                    180:        | 0x00000000 /* GX_PLOT_PLOT (function unknown) */              \
                    181:        | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */             \
                    182:        | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */  \
                    183:        | 0x0000ff00 /* ALU = fg color */                               \
                    184: )
                    185:
                    186: /* Value for the alu register for toggling an area */
                    187: #define CG6_ALU_FLIP   (                                               \
                    188:          0x80000000 /* GX_PLANE_ONES (ignore planemask register) */    \
                    189:        | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */    \
                    190:        | 0x00800000 /* GX_ATTR_SUPP (function unknown) */              \
                    191:        | 0x00000000 /* GX_RAST_BOOL (function unknown) */              \
                    192:        | 0x00000000 /* GX_PLOT_PLOT (function unknown) */              \
                    193:        | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */             \
                    194:        | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */  \
                    195:        | 0x00005555 /* ALU = ~dst */                                   \
                    196: )
                    197:
                    198: /*
                    199:  * Wait for a blit to finish.
                    200:  * 0x8000000 bit: function unknown; 0x20000000 bit: GX_BLT_INPROGRESS
                    201:  */
                    202: #define CG6_BLIT_WAIT(fbc) do {                                                \
                    203:        while (((fbc)->fbc_blit & 0xa0000000) == 0xa0000000)            \
                    204:                /*EMPTY*/;                                              \
                    205: } while (0)
                    206:
                    207: /*
                    208:  * Wait for a drawing operation to finish, or at least get queued.
                    209:  * 0x8000000 bit: function unknown; 0x20000000 bit: GX_FULL
                    210:  */
                    211: #define CG6_DRAW_WAIT(fbc) do {                                                \
                    212:                while (((fbc)->fbc_draw & 0xa0000000) == 0xa0000000)            \
                    213:                /*EMPTY*/;                                              \
                    214: } while (0)
                    215:
                    216: /*
                    217:  * Wait for the whole engine to go idle.  This may not matter in our case;
                    218:  * I'm not sure whether blits are actually queued or not.  It more likely
                    219:  * is intended for lines and such that do get queued.
                    220:  * 0x10000000 bit: GX_INPROGRESS
                    221:  */
                    222: #define CG6_DRAIN(fbc) do {                                            \
                    223:        while ((fbc)->fbc_s & 0x10000000)                               \
                    224:                /*EMPTY*/;                                              \
                    225: } while (0)
                    226:
                    227: static void
                    228: cg6_ras_copyrows(void *cookie, int src, int dst, int n)
                    229: {
                    230:        struct rasops_info *ri;
                    231:        volatile struct cg6_fbc *fbc;
                    232:
                    233:        ri = cookie;
                    234:        if (dst == src)
                    235:                return;
                    236:        if (src < 0) {
                    237:                n += src;
                    238:                src = 0;
                    239:        }
                    240:        if (src+n > ri->ri_rows)
                    241:                n = ri->ri_rows - src;
                    242:        if (dst < 0) {
                    243:                n += dst;
                    244:                dst = 0;
                    245:        }
                    246:        if (dst+n > ri->ri_rows)
                    247:                n = ri->ri_rows - dst;
                    248:        if (n <= 0)
                    249:                return;
                    250:        n *= ri->ri_font->fontheight;
                    251:        src *= ri->ri_font->fontheight;
                    252:        dst *= ri->ri_font->fontheight;
                    253:        fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
                    254:        fbc->fbc_clip = 0;
                    255:        fbc->fbc_s = 0;
                    256:        fbc->fbc_offx = 0;
                    257:        fbc->fbc_offy = 0;
                    258:        fbc->fbc_clipminx = 0;
                    259:        fbc->fbc_clipminy = 0;
                    260:        fbc->fbc_clipmaxx = ri->ri_width - 1;
                    261:        fbc->fbc_clipmaxy = ri->ri_height - 1;
                    262:        fbc->fbc_alu = CG6_ALU_COPY;
                    263:        fbc->fbc_x0 = ri->ri_xorigin;
                    264:        fbc->fbc_y0 = ri->ri_yorigin + src;
                    265:        fbc->fbc_x1 = ri->ri_xorigin + ri->ri_emuwidth - 1;
                    266:        fbc->fbc_y1 = ri->ri_yorigin + src + n - 1;
                    267:        fbc->fbc_x2 = ri->ri_xorigin;
                    268:        fbc->fbc_y2 = ri->ri_yorigin + dst;
                    269:        fbc->fbc_x3 = ri->ri_xorigin + ri->ri_emuwidth - 1;
                    270:        fbc->fbc_y3 = ri->ri_yorigin + dst + n - 1;
                    271:        CG6_BLIT_WAIT(fbc);
                    272:        CG6_DRAIN(fbc);
                    273: }
                    274:
                    275: static void
                    276: cg6_ras_copycols(void *cookie, int row, int src, int dst, int n)
                    277: {
                    278:        struct rasops_info *ri;
                    279:        volatile struct cg6_fbc *fbc;
                    280:
                    281:        ri = cookie;
                    282:        if (dst == src)
                    283:                return;
                    284:        if ((row < 0) || (row >= ri->ri_rows))
                    285:                return;
                    286:        if (src < 0) {
                    287:                n += src;
                    288:                src = 0;
                    289:        }
                    290:        if (src+n > ri->ri_cols)
                    291:                n = ri->ri_cols - src;
                    292:        if (dst < 0) {
                    293:                n += dst;
                    294:                dst = 0;
                    295:        }
                    296:        if (dst+n > ri->ri_cols)
                    297:                n = ri->ri_cols - dst;
                    298:        if (n <= 0)
                    299:                return;
                    300:        n *= ri->ri_font->fontwidth;
                    301:        src *= ri->ri_font->fontwidth;
                    302:        dst *= ri->ri_font->fontwidth;
                    303:        row *= ri->ri_font->fontheight;
                    304:        fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
                    305:        fbc->fbc_clip = 0;
                    306:        fbc->fbc_s = 0;
                    307:        fbc->fbc_offx = 0;
                    308:        fbc->fbc_offy = 0;
                    309:        fbc->fbc_clipminx = 0;
                    310:        fbc->fbc_clipminy = 0;
                    311:        fbc->fbc_clipmaxx = ri->ri_width - 1;
                    312:        fbc->fbc_clipmaxy = ri->ri_height - 1;
                    313:        fbc->fbc_alu = CG6_ALU_COPY;
                    314:        fbc->fbc_x0 = ri->ri_xorigin + src;
                    315:        fbc->fbc_y0 = ri->ri_yorigin + row;
                    316:        fbc->fbc_x1 = ri->ri_xorigin + src + n - 1;
                    317:        fbc->fbc_y1 = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
                    318:        fbc->fbc_x2 = ri->ri_xorigin + dst;
                    319:        fbc->fbc_y2 = ri->ri_yorigin + row;
                    320:        fbc->fbc_x3 = ri->ri_xorigin + dst + n - 1;
                    321:        fbc->fbc_y3 = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
                    322:        CG6_BLIT_WAIT(fbc);
                    323:        CG6_DRAIN(fbc);
                    324: }
                    325:
                    326: static void
                    327: cg6_ras_erasecols(void *cookie, int row, int col, int n, long int attr)
                    328: {
                    329:        struct rasops_info *ri;
                    330:        volatile struct cg6_fbc *fbc;
                    331:
                    332:        ri = cookie;
                    333:        if ((row < 0) || (row >= ri->ri_rows))
                    334:                return;
                    335:        if (col < 0) {
                    336:                n += col;
                    337:                col = 0;
                    338:        }
                    339:        if (col+n > ri->ri_cols)
                    340:                n = ri->ri_cols - col;
                    341:        if (n <= 0)
                    342:                return;
                    343:        n *= ri->ri_font->fontwidth;
                    344:        col *= ri->ri_font->fontwidth;
                    345:        row *= ri->ri_font->fontheight;
                    346:        fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
                    347:        fbc->fbc_clip = 0;
                    348:        fbc->fbc_s = 0;
                    349:        fbc->fbc_offx = 0;
                    350:        fbc->fbc_offy = 0;
                    351:        fbc->fbc_clipminx = 0;
                    352:        fbc->fbc_clipminy = 0;
                    353:        fbc->fbc_clipmaxx = ri->ri_width - 1;
                    354:        fbc->fbc_clipmaxy = ri->ri_height - 1;
                    355:        fbc->fbc_alu = CG6_ALU_FILL;
                    356:        fbc->fbc_fg = ri->ri_devcmap[(attr >> 16) & 0xf];
                    357:        fbc->fbc_arecty = ri->ri_yorigin + row;
                    358:        fbc->fbc_arectx = ri->ri_xorigin + col;
                    359:        fbc->fbc_arecty = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
                    360:        fbc->fbc_arectx = ri->ri_xorigin + col + n - 1;
                    361:        CG6_DRAW_WAIT(fbc);
                    362:        CG6_DRAIN(fbc);
                    363: }
                    364:
                    365: static void
                    366: cg6_ras_eraserows(void *cookie, int row, int n, long int attr)
                    367: {
                    368:        struct rasops_info *ri;
                    369:        volatile struct cg6_fbc *fbc;
                    370:
                    371:        ri = cookie;
                    372:        if (row < 0) {
                    373:                n += row;
                    374:                row = 0;
                    375:        }
                    376:        if (row+n > ri->ri_rows)
                    377:                n = ri->ri_rows - row;
                    378:        if (n <= 0)
                    379:                return;
                    380:        fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
                    381:        fbc->fbc_clip = 0;
                    382:        fbc->fbc_s = 0;
                    383:        fbc->fbc_offx = 0;
                    384:        fbc->fbc_offy = 0;
                    385:        fbc->fbc_clipminx = 0;
                    386:        fbc->fbc_clipminy = 0;
                    387:        fbc->fbc_clipmaxx = ri->ri_width - 1;
                    388:        fbc->fbc_clipmaxy = ri->ri_height - 1;
                    389:        fbc->fbc_alu = CG6_ALU_FILL;
                    390:        fbc->fbc_fg = ri->ri_devcmap[(attr >> 16) & 0xf];
                    391:        if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) {
                    392:                fbc->fbc_arecty = 0;
                    393:                fbc->fbc_arectx = 0;
                    394:                fbc->fbc_arecty = ri->ri_height - 1;
                    395:                fbc->fbc_arectx = ri->ri_width - 1;
                    396:        } else {
                    397:                row *= ri->ri_font->fontheight;
                    398:                fbc->fbc_arecty = ri->ri_yorigin + row;
                    399:                fbc->fbc_arectx = ri->ri_xorigin;
                    400:                fbc->fbc_arecty = ri->ri_yorigin + row + (n * ri->ri_font->fontheight) - 1;
                    401:                fbc->fbc_arectx = ri->ri_xorigin + ri->ri_emuwidth - 1;
                    402:        }
                    403:        CG6_DRAW_WAIT(fbc);
                    404:        CG6_DRAIN(fbc);
                    405: }
                    406:
                    407: /*
                    408:  * Really want something more like fg^bg here, but that would be more
                    409:  * or less impossible to migrate to colors.  So we hope there's
                    410:  * something not too inappropriate in the colormap...besides, it's what
                    411:  * the non-accelerated code did. :-)
                    412:  */
                    413: static void
                    414: cg6_ras_do_cursor(struct rasops_info *ri)
                    415: {
                    416:        volatile struct cg6_fbc *fbc;
                    417:        int row;
                    418:        int col;
                    419:
                    420:        row = ri->ri_crow * ri->ri_font->fontheight;
                    421:        col = ri->ri_ccol * ri->ri_font->fontwidth;
                    422:        fbc = ((struct cgsix_softc *)ri->ri_hw)->sc_fbc;
                    423:        fbc->fbc_clip = 0;
                    424:        fbc->fbc_s = 0;
                    425:        fbc->fbc_offx = 0;
                    426:        fbc->fbc_offy = 0;
                    427:        fbc->fbc_clipminx = 0;
                    428:        fbc->fbc_clipminy = 0;
                    429:        fbc->fbc_clipmaxx = ri->ri_width - 1;
                    430:        fbc->fbc_clipmaxy = ri->ri_height - 1;
                    431:        fbc->fbc_alu = CG6_ALU_FLIP;
                    432:        fbc->fbc_arecty = ri->ri_yorigin + row;
                    433:        fbc->fbc_arectx = ri->ri_xorigin + col;
                    434:        fbc->fbc_arecty = ri->ri_yorigin + row + ri->ri_font->fontheight - 1;
                    435:        fbc->fbc_arectx = ri->ri_xorigin + col + ri->ri_font->fontwidth - 1;
                    436:        CG6_DRAW_WAIT(fbc);
                    437:        CG6_DRAIN(fbc);
                    438: }
                    439: #endif /* RASTERCONSOLE */
                    440:
                    441: void
                    442: cg6attach(sc, name, isconsole)
                    443:        struct cgsix_softc *sc;
                    444:        char *name;
                    445:        int isconsole;
                    446: {
                    447:        struct fbdevice *fb = &sc->sc_fb;
                    448:
                    449:        fb->fb_driver = &cg6_fbdriver;
                    450:
                    451:        /* Don't have to map the pfour register on the cgsix. */
                    452:        fb->fb_pfour = NULL;
                    453:
                    454:        fb->fb_type.fb_cmsize = 256;
                    455:        fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
                    456:        printf(": %s, %d x %d", name,
                    457:               fb->fb_type.fb_width, fb->fb_type.fb_height);
                    458:
                    459:        sc->sc_fhcrev = (*sc->sc_fhc >> FHC_REV_SHIFT) &
                    460:                        (FHC_REV_MASK >> FHC_REV_SHIFT);
                    461:
                    462:        printf(", rev %d", sc->sc_fhcrev);
                    463:
                    464:        /* reset cursor & frame buffer controls */
                    465:        cg6_reset(sc);
                    466:
                    467:        /* enable video */
                    468:        sc->sc_thc->thc_misc |= THC_MISC_VIDEN;
                    469:
                    470:        if (isconsole) {
                    471:                printf(" (console)");
                    472: #ifdef RASTERCONSOLE
                    473:                if (cgsix_use_rasterconsole) {
                    474:                        fbrcons_init(&sc->sc_fb);
                    475:                        sc->sc_fb.fb_rinfo.ri_hw = sc;
                    476:                        sc->sc_fb.fb_rinfo.ri_ops.copyrows = cg6_ras_copyrows;
                    477:                        sc->sc_fb.fb_rinfo.ri_ops.copycols = cg6_ras_copycols;
                    478:                        sc->sc_fb.fb_rinfo.ri_ops.erasecols = cg6_ras_erasecols;
                    479:                        sc->sc_fb.fb_rinfo.ri_ops.eraserows = cg6_ras_eraserows;
                    480:                        sc->sc_fb.fb_rinfo.ri_do_cursor = cg6_ras_do_cursor;
                    481:                }
                    482: #endif
                    483:        }
                    484:
                    485:        printf("\n");
                    486:        fb_attach(&sc->sc_fb, isconsole);
                    487: }
                    488:
                    489:
                    490: int
                    491: cgsixopen(dev, flags, mode, p)
                    492:        dev_t dev;
                    493:        int flags, mode;
                    494:        struct proc *p;
                    495: {
                    496:        int unit = minor(dev);
                    497:
                    498:        if (unit >= cgsix_cd.cd_ndevs || cgsix_cd.cd_devs[unit] == NULL)
                    499:                return (ENXIO);
                    500:        return (0);
                    501: }
                    502:
                    503: int
                    504: cgsixclose(dev, flags, mode, p)
                    505:        dev_t dev;
                    506:        int flags, mode;
                    507:        struct proc *p;
                    508: {
                    509:        struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
                    510:
                    511:        cg6_reset(sc);
                    512:
                    513:        /* (re-)initialize the default color map */
                    514:        bt_initcmap(&sc->sc_cmap, 256);
                    515:        cg6_loadcmap(sc, 0, 256);
                    516:
                    517:        return (0);
                    518: }
                    519:
                    520: int
                    521: cgsixioctl(dev, cmd, data, flags, p)
                    522:        dev_t dev;
                    523:        u_long cmd;
                    524:        caddr_t data;
                    525:        int flags;
                    526:        struct proc *p;
                    527: {
                    528:        struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
                    529:        u_int count;
                    530:        int v, error;
                    531:        union cursor_cmap tcm;
                    532:
                    533:        switch (cmd) {
                    534:
                    535:        case FBIOGTYPE:
                    536:                *(struct fbtype *)data = sc->sc_fb.fb_type;
                    537:                break;
                    538:
                    539:        case FBIOGATTR:
                    540: #define fba ((struct fbgattr *)data)
                    541:                fba->real_type = sc->sc_fb.fb_type.fb_type;
                    542:                fba->owner = 0;         /* XXX ??? */
                    543:                fba->fbtype = sc->sc_fb.fb_type;
                    544:                fba->sattr.flags = 0;
                    545:                fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
                    546:                fba->sattr.dev_specific[0] = -1;
                    547:                fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
                    548:                fba->emu_types[1] = -1;
                    549: #undef fba
                    550:                break;
                    551:
                    552:        case FBIOGETCMAP:
                    553: #define        p ((struct fbcmap *)data)
                    554:                return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
                    555:
                    556:        case FBIOPUTCMAP:
                    557:                /* copy to software map */
                    558:                error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
                    559:                if (error)
                    560:                        return (error);
                    561:                /* now blast them into the chip */
                    562:                /* XXX should use retrace interrupt */
                    563:                cg6_loadcmap(sc, p->index, p->count);
                    564: #undef p
                    565:                break;
                    566:
                    567:        case FBIOGVIDEO:
                    568:                *(int *)data = sc->sc_blanked;
                    569:                break;
                    570:
                    571:        case FBIOSVIDEO:
                    572:                if (*(int *)data)
                    573:                        cg6_unblank(&sc->sc_dev);
                    574:                else if (!sc->sc_blanked) {
                    575:                        sc->sc_blanked = 1;
                    576:                        sc->sc_thc->thc_misc &= ~THC_MISC_VIDEN;
                    577:                }
                    578:                break;
                    579:
                    580: /* these are for both FBIOSCURSOR and FBIOGCURSOR */
                    581: #define p ((struct fbcursor *)data)
                    582: #define cc (&sc->sc_cursor)
                    583:
                    584:        case FBIOGCURSOR:
                    585:                /* do not quite want everything here... */
                    586:                p->set = FB_CUR_SETALL; /* close enough, anyway */
                    587:                p->enable = cc->cc_enable;
                    588:                p->pos = cc->cc_pos;
                    589:                p->hot = cc->cc_hot;
                    590:                p->size = cc->cc_size;
                    591:
                    592:                /* begin ugh ... can we lose some of this crap?? */
                    593:                if (p->image != NULL) {
                    594:                        count = cc->cc_size.y * 32 / NBBY;
                    595:                        error = copyout((caddr_t)cc->cc_bits[1],
                    596:                            (caddr_t)p->image, count);
                    597:                        if (error)
                    598:                                return (error);
                    599:                        error = copyout((caddr_t)cc->cc_bits[0],
                    600:                            (caddr_t)p->mask, count);
                    601:                        if (error)
                    602:                                return (error);
                    603:                }
                    604:                if (p->cmap.red != NULL) {
                    605:                        error = bt_getcmap(&p->cmap,
                    606:                            (union bt_cmap *)&cc->cc_color, 2, 1);
                    607:                        if (error)
                    608:                                return (error);
                    609:                } else {
                    610:                        p->cmap.index = 0;
                    611:                        p->cmap.count = 2;
                    612:                }
                    613:                /* end ugh */
                    614:                break;
                    615:
                    616:        case FBIOSCURSOR:
                    617:                /*
                    618:                 * For setcmap and setshape, verify parameters, so that
                    619:                 * we do not get halfway through an update and then crap
                    620:                 * out with the software state screwed up.
                    621:                 */
                    622:                v = p->set;
                    623:                if (v & FB_CUR_SETCMAP) {
                    624:                        /*
                    625:                         * This use of a temporary copy of the cursor
                    626:                         * colormap is not terribly efficient, but these
                    627:                         * copies are small (8 bytes)...
                    628:                         */
                    629:                        tcm = cc->cc_color;
                    630:                        error = bt_putcmap(&p->cmap, (union bt_cmap *)&tcm, 2, 1);
                    631:                        if (error)
                    632:                                return (error);
                    633:                }
                    634:                if (v & FB_CUR_SETSHAPE) {
                    635:                        if ((u_int)p->size.x > 32 || (u_int)p->size.y > 32)
                    636:                                return (EINVAL);
                    637:                        count = p->size.y * 32 / NBBY;
                    638:                        if (!uvm_useracc(p->image, count, B_READ) ||
                    639:                            !uvm_useracc(p->mask, count, B_READ))
                    640:                                return (EFAULT);
                    641:                }
                    642:
                    643:                /* parameters are OK; do it */
                    644:                if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {
                    645:                        if (v & FB_CUR_SETCUR)
                    646:                                cc->cc_enable = p->enable;
                    647:                        if (v & FB_CUR_SETPOS)
                    648:                                cc->cc_pos = p->pos;
                    649:                        if (v & FB_CUR_SETHOT)
                    650:                                cc->cc_hot = p->hot;
                    651:                        cg6_setcursor(sc);
                    652:                }
                    653:                if (v & FB_CUR_SETCMAP) {
                    654:                        cc->cc_color = tcm;
                    655:                        cg6_loadomap(sc); /* XXX defer to vertical retrace */
                    656:                }
                    657:                if (v & FB_CUR_SETSHAPE) {
                    658:                        cc->cc_size = p->size;
                    659:                        count = p->size.y * 32 / NBBY;
                    660:                        bzero((caddr_t)cc->cc_bits, sizeof cc->cc_bits);
1.3     ! eeh       661:                        copyin(p->mask, (caddr_t)cc->cc_bits[0], count);
        !           662:                        copyin(p->image, (caddr_t)cc->cc_bits[1], count);
1.1       pk        663:                        cg6_loadcursor(sc);
                    664:                }
                    665:                break;
                    666:
                    667: #undef p
                    668: #undef cc
                    669:
                    670:        case FBIOGCURPOS:
                    671:                *(struct fbcurpos *)data = sc->sc_cursor.cc_pos;
                    672:                break;
                    673:
                    674:        case FBIOSCURPOS:
                    675:                sc->sc_cursor.cc_pos = *(struct fbcurpos *)data;
                    676:                cg6_setcursor(sc);
                    677:                break;
                    678:
                    679:        case FBIOGCURMAX:
                    680:                /* max cursor size is 32x32 */
                    681:                ((struct fbcurpos *)data)->x = 32;
                    682:                ((struct fbcurpos *)data)->y = 32;
                    683:                break;
                    684:
                    685:        default:
                    686: #ifdef DEBUG
                    687:                log(LOG_NOTICE, "cgsixioctl(0x%lx) (%s[%d])\n", cmd,
                    688:                    p->p_comm, p->p_pid);
                    689: #endif
                    690:                return (ENOTTY);
                    691:        }
                    692:        return (0);
                    693: }
                    694:
                    695: int
                    696: cgsixpoll(dev, events, p)
                    697:        dev_t dev;
                    698:        int events;
                    699:        struct proc *p;
                    700: {
                    701:
                    702:        return (seltrue(dev, events, p));
                    703: }
                    704:
                    705: /*
                    706:  * Clean up hardware state (e.g., after bootup or after X crashes).
                    707:  */
                    708: static void
                    709: cg6_reset(sc)
                    710:        struct cgsix_softc *sc;
                    711: {
                    712:        volatile struct cg6_tec_xxx *tec;
                    713:        int fhc;
                    714:        volatile struct bt_regs *bt;
                    715:
                    716:        /* hide the cursor, just in case */
                    717:        sc->sc_thc->thc_cursxy = (THC_CURSOFF << 16) | THC_CURSOFF;
                    718:
                    719:        /* turn off frobs in transform engine (makes X11 work) */
                    720:        tec = sc->sc_tec;
                    721:        tec->tec_mv = 0;
                    722:        tec->tec_clip = 0;
                    723:        tec->tec_vdc = 0;
                    724:
                    725:        /* take care of hardware bugs in old revisions */
                    726:        if (sc->sc_fhcrev < 5) {
                    727:                /*
                    728:                 * Keep current resolution; set cpu to 68020, set test
                    729:                 * window (size 1Kx1K), and for rev 1, disable dest cache.
                    730:                 */
                    731:                fhc = (*sc->sc_fhc & FHC_RES_MASK) | FHC_CPU_68020 |
                    732:                    FHC_TEST |
                    733:                    (11 << FHC_TESTX_SHIFT) | (11 << FHC_TESTY_SHIFT);
                    734:                if (sc->sc_fhcrev < 2)
                    735:                        fhc |= FHC_DST_DISABLE;
                    736:                *sc->sc_fhc = fhc;
                    737:        }
                    738:
                    739:        /* Enable cursor in Brooktree DAC. */
                    740:        bt = sc->sc_bt;
                    741:        bt->bt_addr = 0x06 << 24;
                    742:        bt->bt_ctrl |= 0x03 << 24;
                    743: }
                    744:
                    745: static void
                    746: cg6_setcursor(sc)
                    747:        struct cgsix_softc *sc;
                    748: {
                    749:
                    750:        /* we need to subtract the hot-spot value here */
                    751: #define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)
                    752:        sc->sc_thc->thc_cursxy = sc->sc_cursor.cc_enable ?
                    753:            ((COORD(x) << 16) | (COORD(y) & 0xffff)) :
                    754:            (THC_CURSOFF << 16) | THC_CURSOFF;
                    755: #undef COORD
                    756: }
                    757:
                    758: static void
                    759: cg6_loadcursor(sc)
                    760:        struct cgsix_softc *sc;
                    761: {
                    762:        volatile struct cg6_thc *thc;
                    763:        u_int edgemask, m;
                    764:        int i;
                    765:
                    766:        /*
                    767:         * Keep the top size.x bits.  Here we *throw out* the top
                    768:         * size.x bits from an all-one-bits word, introducing zeros in
                    769:         * the top size.x bits, then invert all the bits to get what
                    770:         * we really wanted as our mask.  But this fails if size.x is
                    771:         * 32---a sparc uses only the low 5 bits of the shift count---
                    772:         * so we have to special case that.
                    773:         */
                    774:        edgemask = ~0;
                    775:        if (sc->sc_cursor.cc_size.x < 32)
                    776:                edgemask = ~(edgemask >> sc->sc_cursor.cc_size.x);
                    777:        thc = sc->sc_thc;
                    778:        for (i = 0; i < 32; i++) {
                    779:                m = sc->sc_cursor.cc_bits[0][i] & edgemask;
                    780:                thc->thc_cursmask[i] = m;
                    781:                thc->thc_cursbits[i] = m & sc->sc_cursor.cc_bits[1][i];
                    782:        }
                    783: }
                    784:
                    785: /*
                    786:  * Load a subset of the current (new) colormap into the color DAC.
                    787:  */
                    788: static void
                    789: cg6_loadcmap(sc, start, ncolors)
                    790:        struct cgsix_softc *sc;
                    791:        int start, ncolors;
                    792: {
                    793:        volatile struct bt_regs *bt;
                    794:        u_int *ip, i;
                    795:        int count;
                    796:
                    797:        ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)];      /* start/4 * 3 */
                    798:        count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
                    799:        bt = sc->sc_bt;
                    800:        bt->bt_addr = BT_D4M4(start) << 24;
                    801:        while (--count >= 0) {
                    802:                i = *ip++;
                    803:                /* hardware that makes one want to pound boards with hammers */
                    804:                bt->bt_cmap = i;
                    805:                bt->bt_cmap = i << 8;
                    806:                bt->bt_cmap = i << 16;
                    807:                bt->bt_cmap = i << 24;
                    808:        }
                    809: }
                    810:
                    811: /*
                    812:  * Load the cursor (overlay `foreground' and `background') colors.
                    813:  */
                    814: static void
                    815: cg6_loadomap(sc)
                    816:        struct cgsix_softc *sc;
                    817: {
                    818:        volatile struct bt_regs *bt;
                    819:        u_int i;
                    820:
                    821:        bt = sc->sc_bt;
                    822:        bt->bt_addr = 0x01 << 24;       /* set background color */
                    823:        i = sc->sc_cursor.cc_color.cm_chip[0];
                    824:        bt->bt_omap = i;                /* R */
                    825:        bt->bt_omap = i << 8;           /* G */
                    826:        bt->bt_omap = i << 16;          /* B */
                    827:
                    828:        bt->bt_addr = 0x03 << 24;       /* set foreground color */
                    829:        bt->bt_omap = i << 24;          /* R */
                    830:        i = sc->sc_cursor.cc_color.cm_chip[1];
                    831:        bt->bt_omap = i;                /* G */
                    832:        bt->bt_omap = i << 8;           /* B */
                    833: }
                    834:
                    835: static void
                    836: cg6_unblank(dev)
                    837:        struct device *dev;
                    838: {
                    839:        struct cgsix_softc *sc = (struct cgsix_softc *)dev;
                    840:
                    841:        if (sc->sc_blanked) {
                    842:                sc->sc_blanked = 0;
                    843:                sc->sc_thc->thc_misc |= THC_MISC_VIDEN;
                    844:        }
                    845: }
                    846:
                    847: /* XXX the following should be moved to a "user interface" header */
                    848: /*
                    849:  * Base addresses at which users can mmap() the various pieces of a cg6.
                    850:  * Note that although the Brooktree color registers do not occupy 8K,
                    851:  * the X server dies if we do not allow it to map 8K there (it just maps
                    852:  * from 0x70000000 forwards, as a contiguous chunk).
                    853:  */
                    854: #define        CG6_USER_FBC    0x70000000
                    855: #define        CG6_USER_TEC    0x70001000
                    856: #define        CG6_USER_BTREGS 0x70002000
                    857: #define        CG6_USER_FHC    0x70004000
                    858: #define        CG6_USER_THC    0x70005000
                    859: #define        CG6_USER_ROM    0x70006000
                    860: #define        CG6_USER_RAM    0x70016000
                    861: #define        CG6_USER_DHC    0x80000000
                    862:
                    863: struct mmo {
1.2       eeh       864:        u_long  mo_uaddr;       /* user (virtual) address */
                    865:        u_long  mo_size;        /* size, or 0 for video ram size */
                    866:        u_long  mo_physoff;     /* offset from sc_physadr */
1.1       pk        867: };
                    868:
                    869: /*
                    870:  * Return the address that would map the given device at the given
                    871:  * offset, allowing for the given protection, or return -1 for error.
                    872:  *
                    873:  * XXX needs testing against `demanding' applications (e.g., aviator)
                    874:  */
                    875: paddr_t
                    876: cgsixmmap(dev, off, prot)
                    877:        dev_t dev;
                    878:        off_t off;
                    879:        int prot;
                    880: {
                    881:        struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
                    882:        struct mmo *mo;
                    883:        u_int u, sz;
                    884:        static struct mmo mmo[] = {
                    885:                { CG6_USER_RAM, 0, CGSIX_RAM_OFFSET },
                    886:
                    887:                /* do not actually know how big most of these are! */
                    888:                { CG6_USER_FBC, 1, CGSIX_FBC_OFFSET },
                    889:                { CG6_USER_TEC, 1, CGSIX_TEC_OFFSET },
                    890:                { CG6_USER_BTREGS, 8192 /* XXX */, CGSIX_BT_OFFSET },
                    891:                { CG6_USER_FHC, 1, CGSIX_FHC_OFFSET },
                    892:                { CG6_USER_THC, sizeof(struct cg6_thc), CGSIX_THC_OFFSET },
                    893:                { CG6_USER_ROM, 65536, CGSIX_ROM_OFFSET },
                    894:                { CG6_USER_DHC, 1, CGSIX_DHC_OFFSET },
                    895:        };
                    896: #define NMMO (sizeof mmo / sizeof *mmo)
                    897:
                    898:        if (off & PGOFSET)
                    899:                panic("cgsixmmap");
                    900:
                    901:        /*
                    902:         * Entries with size 0 map video RAM (i.e., the size in fb data).
                    903:         *
                    904:         * Since we work in pages, the fact that the map offset table's
                    905:         * sizes are sometimes bizarre (e.g., 1) is effectively ignored:
                    906:         * one byte is as good as one page.
                    907:         */
                    908:        for (mo = mmo; mo < &mmo[NMMO]; mo++) {
1.2       eeh       909:                if ((u_long)off < mo->mo_uaddr)
1.1       pk        910:                        continue;
                    911:                u = off - mo->mo_uaddr;
                    912:                sz = mo->mo_size ? mo->mo_size : sc->sc_fb.fb_type.fb_size;
                    913:                if (u < sz) {
                    914:                        bus_space_handle_t bh;
                    915:                        if (bus_space_mmap(sc->sc_bustag,
                    916:                                           sc->sc_btype,
                    917:                                           sc->sc_paddr+u+mo->mo_physoff,
                    918:                                           BUS_SPACE_MAP_LINEAR, &bh))
                    919:                                return (-1);
                    920:
                    921:                        return ((paddr_t)bh);
                    922:                }
                    923:        }
                    924:
                    925: #ifdef DEBUG
                    926:        {
                    927:          struct proc *p = curproc;     /* XXX */
                    928:          log(LOG_NOTICE, "cgsixmmap(0x%x) (%s[%d])\n",
                    929:                off, p->p_comm, p->p_pid);
                    930:        }
                    931: #endif
                    932:        return (-1);    /* not a user-map offset */
                    933: }

CVSweb <webmaster@jp.NetBSD.org>