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

Annotation of sys/dev/pci/tga.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: tga.c,v 1.29 2006/12/17 22:18:16 miod Exp $ */
                      2: /* $NetBSD: tga.c,v 1.40 2002/03/13 15:05:18 ad Exp $ */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Author: Chris G. Demetriou
                      9:  *
                     10:  * Permission to use, copy, modify and distribute this software and
                     11:  * its documentation is hereby granted, provided that both the copyright
                     12:  * notice and this permission notice appear in all copies of the
                     13:  * software, derivative works or modified versions, and any portions
                     14:  * thereof, and that both notices appear in supporting documentation.
                     15:  *
                     16:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     17:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
                     18:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     19:  *
                     20:  * Carnegie Mellon requests users of this software to return to
                     21:  *
                     22:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     23:  *  School of Computer Science
                     24:  *  Carnegie Mellon University
                     25:  *  Pittsburgh PA 15213-3890
                     26:  *
                     27:  * any improvements or extensions that they make and grant Carnegie the
                     28:  * rights to redistribute these changes.
                     29:  */
                     30:
                     31: #include <sys/param.h>
                     32: #include <sys/systm.h>
                     33: #include <sys/kernel.h>
                     34: #include <sys/device.h>
                     35: #include <sys/conf.h>
                     36: #include <sys/malloc.h>
                     37: #include <sys/buf.h>
                     38: #include <sys/ioctl.h>
                     39:
                     40: #include <machine/bus.h>
                     41: #include <machine/intr.h>
                     42:
                     43: #include <dev/pci/pcireg.h>
                     44: #include <dev/pci/pcivar.h>
                     45: #include <dev/pci/pcidevs.h>
                     46: #include <dev/pci/tgareg.h>
                     47: #include <dev/pci/tgavar.h>
                     48: #include <dev/ic/bt485reg.h>
                     49: #include <dev/ic/bt485var.h>
                     50: #include <dev/ic/bt463reg.h>
                     51: #include <dev/ic/bt463var.h>
                     52: #include <dev/ic/ibm561var.h>
                     53:
                     54: #include <dev/wscons/wsconsio.h>
                     55: #include <dev/rasops/rasops.h>
                     56: #include <dev/wsfont/wsfont.h>
                     57:
                     58: #if defined(__alpha__) || defined(__mips__)
                     59: #include <uvm/uvm_extern.h>
                     60: #endif
                     61:
                     62: #ifdef __alpha__
                     63: #include <machine/pte.h>
                     64: #endif
                     65: #ifdef __mips__
                     66: #include <mips/pte.h>
                     67: #endif
                     68:
                     69: int    tgamatch(struct device *, struct cfdata *, void *);
                     70: void   tgaattach(struct device *, struct device *, void *);
                     71: int    tgaprint(void *, const char *);
                     72:
                     73: struct cfdriver tga_cd = {
                     74:        NULL, "tga", DV_DULL
                     75: };
                     76:
                     77: struct cfattach tga_ca = {
                     78:        sizeof(struct tga_softc), (cfmatch_t)tgamatch, tgaattach,
                     79: };
                     80:
                     81: int    tga_identify(struct tga_devconfig *);
                     82: const struct tga_conf *tga_getconf(int);
                     83: void   tga_getdevconfig(bus_space_tag_t memt, pci_chipset_tag_t pc,
                     84:            pcitag_t tag, struct tga_devconfig *dc);
                     85: unsigned tga_getdotclock(struct tga_devconfig *dc);
                     86:
                     87: struct tga_devconfig tga_console_dc;
                     88:
                     89: int    tga_ioctl(void *, u_long, caddr_t, int, struct proc *);
                     90: paddr_t        tga_mmap(void *, off_t, int);
                     91: void   tga_copyrows(void *, int, int, int);
                     92: void   tga_copycols(void *, int, int, int, int);
                     93: int    tga_alloc_screen(void *, const struct wsscreen_descr *,
                     94:            void **, int *, int *, long *);
                     95: void   tga_free_screen(void *, void *);
                     96: int    tga_show_screen(void *, void *, int,
                     97:                           void (*) (void *, int, int), void *);
                     98: void   tga_burner(void *, u_int, u_int);
                     99: int    tga_rop(struct rasops_info *, int, int, int, int,
                    100:        struct rasops_info *, int, int);
                    101: int    tga_rop_vtov(struct rasops_info *, int, int, int,
                    102:        int, struct rasops_info *, int, int );
                    103: void   tga_putchar(void *c, int row, int col, u_int uc, long attr);
                    104: void   tga_eraserows(void *, int, int, long);
                    105: void   tga_erasecols(void *, int, int, int, long);
                    106: void   tga2_init(struct tga_devconfig *);
                    107:
                    108: void   tga_config_interrupts(struct device *);
                    109:
                    110: /* RAMDAC interface functions */
                    111: int     tga_sched_update(void *, void (*)(void *));
                    112: void    tga_ramdac_wr(void *, u_int, u_int8_t);
                    113: u_int8_t tga_ramdac_rd(void *, u_int);
                    114: void    tga_bt463_wr(void *, u_int, u_int8_t);
                    115: u_int8_t tga_bt463_rd(void *, u_int);
                    116: void    tga2_ramdac_wr(void *, u_int, u_int8_t);
                    117: u_int8_t tga2_ramdac_rd(void *, u_int);
                    118:
                    119: /* Interrupt handler */
                    120: int    tga_intr(void *);
                    121:
                    122: /* The NULL entries will get filled in by rasops_init().
                    123:  * XXX and the non-NULL ones will be overwritten; reset after calling it.
                    124:  */
                    125: struct wsdisplay_emulops tga_emulops = {
                    126:        NULL,
                    127:        NULL,
                    128:        tga_putchar,
                    129:        tga_copycols,
                    130:        tga_erasecols,
                    131:        tga_copyrows,
                    132:        tga_eraserows,
                    133:        NULL,
                    134:        NULL
                    135: };
                    136:
                    137: struct wsscreen_descr tga_stdscreen = {
                    138:        "std",
                    139:        0, 0,   /* will be filled in -- XXX shouldn't, it's global */
                    140:        &tga_emulops,
                    141:        0, 0,
                    142:        WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
                    143:            WSSCREEN_WSCOLORS | WSSCREEN_REVERSE
                    144: };
                    145:
                    146: const struct wsscreen_descr *_tga_scrlist[] = {
                    147:        &tga_stdscreen,
                    148:        /* XXX other formats, graphics screen? */
                    149: };
                    150:
                    151: struct wsscreen_list tga_screenlist = {
                    152:        sizeof(_tga_scrlist) / sizeof(struct wsscreen_descr *), _tga_scrlist
                    153: };
                    154:
                    155: struct wsdisplay_accessops tga_accessops = {
                    156:        tga_ioctl,
                    157:        tga_mmap,
                    158:        tga_alloc_screen,
                    159:        tga_free_screen,
                    160:        tga_show_screen,
                    161:        NULL,                   /* load_font */
                    162:        NULL,                   /* scrollback */
                    163:        NULL,                   /* getchar */
                    164:        tga_burner,
                    165: };
                    166:
                    167: void   tga_blank(struct tga_devconfig *);
                    168: void   tga_unblank(struct tga_devconfig *);
                    169:
                    170: #ifdef TGA_DEBUG
                    171: #define DPRINTF(...)      printf (__VA_ARGS__)
                    172: #define DPRINTFN(n, ...)   if (tgadebug > (n)) printf (__VA_ARGS__)
                    173: int tgadebug = 0;
                    174: #else
                    175: #define DPRINTF(...)
                    176: #define DPRINTFN(n,...)
                    177: #endif
                    178:
                    179: const struct pci_matchid tga_devices[] = {
                    180:        { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21030 },
                    181:        { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_PBXGB },
                    182: };
                    183:
                    184: int
                    185: tgamatch(parent, match, aux)
                    186:        struct device *parent;
                    187:        struct cfdata *match;
                    188:        void *aux;
                    189: {
                    190:        if (pci_matchbyid((struct pci_attach_args *)aux, tga_devices,
                    191:            sizeof(tga_devices) / sizeof(tga_devices[0])))
                    192:                return (10);    /* need to return more than vga_pci here! */
                    193:
                    194:        return (0);
                    195: }
                    196:
                    197: void
                    198: tga_getdevconfig(memt, pc, tag, dc)
                    199:        bus_space_tag_t memt;
                    200:        pci_chipset_tag_t pc;
                    201:        pcitag_t tag;
                    202:        struct tga_devconfig *dc;
                    203: {
                    204:        const struct tga_conf *tgac;
                    205:        struct rasops_info *rip;
                    206:        int cookie;
                    207:        bus_size_t pcisize;
                    208:        int i;
                    209:
                    210:        dc->dc_memt = memt;
                    211:
                    212:        dc->dc_pcitag = tag;
                    213:
                    214:        DPRINTF("tga_getdevconfig: Getting map info\n");
                    215:        /* XXX magic number */
                    216:        if (pci_mapreg_info(pc, tag, 0x10,
                    217:            PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
                    218:            &dc->dc_pcipaddr, &pcisize, NULL))
                    219:                return;
                    220:
                    221:        DPRINTF("tga_getdevconfig: preparing to map\n");
                    222: #ifdef __OpenBSD__
                    223:        if (bus_space_map(memt, dc->dc_pcipaddr, pcisize, 1, &dc->dc_memh))
                    224:                return;
                    225:        dc->dc_vaddr = dc->dc_memh;
                    226: #else
                    227:        if (bus_space_map(memt, dc->dc_pcipaddr, pcisize,
                    228:            BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, &dc->dc_memh))
                    229:                return;
                    230:        dc->dc_vaddr = (vaddr_t) bus_space_vaddr(memt, dc->dc_memh);
                    231: #endif
                    232:        DPRINTF("tga_getdevconfig: mapped\n");
                    233:
                    234: #ifdef __alpha__
                    235:        dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr);       /* XXX */
                    236: #endif
                    237: #ifdef arc
                    238:        bus_space_paddr(memt, dc->dc_memh, &dc->dc_paddr);
                    239: #endif
                    240:        DPRINTF("tga_getdevconfig: allocating subregion\n");
                    241:        bus_space_subregion(dc->dc_memt, dc->dc_memh,
                    242:                            TGA_MEM_CREGS, TGA_CREGS_SIZE,
                    243:                            &dc->dc_regs);
                    244:
                    245:        DPRINTF("tga_getdevconfig: going to identify\n");
                    246:        dc->dc_tga_type = tga_identify(dc);
                    247:
                    248:        DPRINTF("tga_getdevconfig: preparing to get config\n");
                    249:        tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type);
                    250:        if (tgac == NULL)
                    251:                return;
                    252:
                    253: #if 0
                    254:        /* XXX on the Alpha, pcisize = 4 * cspace_size. */
                    255:        if (tgac->tgac_cspace_size != pcisize)                  /* sanity */
                    256:                panic("tga_getdevconfig: memory size mismatch?");
                    257: #endif
                    258:
                    259:        DPRINTF("tga_getdevconfig: get revno\n");
                    260:        switch (TGARREG(dc, TGA_REG_GREV) & 0xff) {
                    261:        case 0x01:
                    262:        case 0x02:
                    263:        case 0x03:
                    264:        case 0x04:
                    265:                dc->dc_tga2 = 0;
                    266:                break;
                    267:        case 0x20:
                    268:        case 0x21:
                    269:        case 0x22:
                    270:                dc->dc_tga2 = 1;
                    271:                break;
                    272:        default:
                    273:                panic("tga_getdevconfig: TGA Revision not recognized");
                    274:        }
                    275:
                    276:        if (dc->dc_tga2) {
                    277:                tga2_init(dc);
                    278:        }
                    279:
                    280:        i = TGARREG(dc, TGA_REG_VHCR) & 0x1ff;
                    281:        DPRINTF("tga_getdevconfig: TGA_REG_VHCR & 0x1ff = %d\n", i);
                    282:        switch (i) {            /* XXX */
                    283:        case 0:
                    284:                dc->dc_wid = 8192;
                    285:                break;
                    286:
                    287:        case 1:
                    288:                dc->dc_wid = 8196;
                    289:                break;
                    290:
                    291:        default:
                    292:                dc->dc_wid = (TGARREG(dc, TGA_REG_VHCR) & 0x1ff) * 4; /* XXX */
                    293:                break;
                    294:        }
                    295:
                    296:        DPRINTF("tga_getdevconfig: dc->dc_wid = %d\n", dc->dc_wid);
                    297:        /*
                    298:         * XXX XXX Turning off "odd" shouldn't be necessary,
                    299:         * XXX XXX but I can't make X work with the weird size.
                    300:         */
                    301:        DPRINTF("tga_getdevconfig: beginning magic incantation\n");
                    302:        if ((TGARREG(dc, TGA_REG_VHCR) & 0x00000001) != 0 &&    /* XXX */
                    303:            (TGARREG(dc, TGA_REG_VHCR) & 0x80000000) != 0) {    /* XXX */
                    304:                TGAWREG(dc, TGA_REG_VHCR,
                    305:                    (TGARREG(dc, TGA_REG_VHCR) & ~0x80000001));
                    306:                dc->dc_wid -= 4;
                    307:        }
                    308:
                    309:        dc->dc_rowbytes = dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8);
                    310:        dc->dc_ht = (TGARREG(dc, TGA_REG_VVCR) & 0x7ff);        /* XXX */
                    311:        DPRINTF("tga_getdevconfig: rowbytes = %d, tgac_phys_depth = %d\n"
                    312:                "                  dc_wid = %d, dc_ht = %d\n",
                    313:                dc->dc_rowbytes, dc->dc_tgaconf->tgac_phys_depth,
                    314:                dc->dc_wid, dc->dc_ht);
                    315:
                    316:        /* XXX this seems to be what DEC does */
                    317:        DPRINTF("tga_getdevconfig: more magic\n");
                    318:        TGAWREG(dc, TGA_REG_CCBR, 0);
                    319:        TGAWREG(dc, TGA_REG_VVBR, 1);
                    320:        dc->dc_videobase = dc->dc_vaddr + tgac->tgac_dbuf[0] +
                    321:            1 * tgac->tgac_vvbr_units;
                    322:        dc->dc_blanked = 1;
                    323:        tga_unblank(dc);
                    324:
                    325:        DPRINTF("tga_getdevconfig: dc_videobase = 0x%016llx\n"
                    326:                "                  dc_vaddr = 0x%016llx\n"
                    327:                "                  tgac_dbuf[0] = %d\n"
                    328:                "                  tgac_vvbr_units = %d\n",
                    329:                dc->dc_videobase, dc->dc_vaddr, tgac->tgac_dbuf[0],
                    330:                tgac->tgac_vvbr_units);
                    331:
                    332:        /*
                    333:         * Set all bits in the pixel mask, to enable writes to all pixels.
                    334:         * It seems that the console firmware clears some of them
                    335:         * under some circumstances, which causes cute vertical stripes.
                    336:         */
                    337:        DPRINTF("tga_getdevconfig: set pixel mask\n");
                    338:        TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff);
                    339:
                    340:        /* clear the screen */
                    341:        DPRINTF("tga_getdevconfig: clear screen\n");
                    342:        for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
                    343:                *(u_int32_t *)(dc->dc_videobase + i) = 0;
                    344:
                    345:        DPRINTF("tga_getdevconfig: raster ops\n");
                    346:        /* Initialize rasops descriptor */
                    347:        rip = &dc->dc_rinfo;
                    348:        rip->ri_flg = RI_CENTER;
                    349:        rip->ri_depth = tgac->tgac_phys_depth;
                    350:        rip->ri_bits = (void *)dc->dc_videobase;
                    351:        rip->ri_width = dc->dc_wid;
                    352:        rip->ri_height = dc->dc_ht;
                    353:        rip->ri_stride = dc->dc_rowbytes;
                    354:        rip->ri_hw = dc;
                    355:
                    356:        if (tgac->tgac_phys_depth == 32) {
                    357:                rip->ri_rnum = 8;
                    358:                rip->ri_gnum = 8;
                    359:                rip->ri_bnum = 8;
                    360:                rip->ri_rpos = 16;
                    361:                rip->ri_gpos = 8;
                    362:                rip->ri_bpos = 0;
                    363:        }
                    364:
                    365:        DPRINTF("tga_getdevconfig: wsfont_init\n");
                    366:        wsfont_init();
                    367:        if (rip->ri_width > 80*12)
                    368:                /* High res screen, choose a big font */
                    369:                cookie = wsfont_find(NULL, 12, 0, 0);
                    370:        else
                    371:                /*  lower res, choose a 8 pixel wide font */
                    372:                cookie = wsfont_find(NULL, 8, 0, 0);
                    373:        if (cookie <= 0)
                    374:                cookie = wsfont_find(NULL, 0, 0, 0);
                    375:        if (cookie <= 0) {
                    376:                printf("tga: no appropriate fonts.\n");
                    377:                return;
                    378:        }
                    379:
                    380:        /* the accelerated tga_putchar() needs LSbit left */
                    381:        if (wsfont_lock(cookie, &rip->ri_font,
                    382:            WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0) {
                    383:                printf("tga: couldn't lock font\n");
                    384:                return;
                    385:        }
                    386:        rip->ri_wsfcookie = cookie;
                    387:        /* fill screen size */
                    388:        rasops_init(rip, rip->ri_height / rip->ri_font->fontheight,
                    389:            rip->ri_width / rip->ri_font->fontwidth);
                    390:
                    391:        /* add our accelerated functions */
                    392:        /* XXX shouldn't have to do this; rasops should leave non-NULL
                    393:         * XXX entries alone.
                    394:         */
                    395:        rip->ri_ops.copyrows = tga_copyrows;
                    396:        rip->ri_ops.eraserows = tga_eraserows;
                    397:        rip->ri_ops.erasecols = tga_erasecols;
                    398:        rip->ri_ops.copycols = tga_copycols;
                    399:        rip->ri_ops.putchar = tga_putchar;
                    400:
                    401:        tga_stdscreen.nrows = rip->ri_rows;
                    402:        tga_stdscreen.ncols = rip->ri_cols;
                    403:        tga_stdscreen.textops = &rip->ri_ops;
                    404:        tga_stdscreen.capabilities = rip->ri_caps;
                    405:
                    406:        dc->dc_intrenabled = 0;
                    407: }
                    408:
                    409: void
                    410: tgaattach(parent, self, aux)
                    411:        struct device *parent, *self;
                    412:        void *aux;
                    413: {
                    414:        struct pci_attach_args *pa = aux;
                    415:        struct tga_softc *sc = (struct tga_softc *)self;
                    416:        struct wsemuldisplaydev_attach_args aa;
                    417:        pci_intr_handle_t intrh;
                    418:        const char *intrstr;
                    419:        u_int8_t rev;
                    420:        int console;
                    421:
                    422: #if defined(__alpha__) || defined(arc)
                    423:        console = (pa->pa_tag == tga_console_dc.dc_pcitag);
                    424: #else
                    425:        console = 0;
                    426: #endif
                    427:        if (console) {
                    428:                sc->sc_dc = &tga_console_dc;
                    429:                sc->nscreens = 1;
                    430:        } else {
                    431:                sc->sc_dc = (struct tga_devconfig *)
                    432:                    malloc(sizeof(struct tga_devconfig), M_DEVBUF, M_NOWAIT);
                    433:                if (sc->sc_dc == NULL)
                    434:                        return;
                    435:                bzero(sc->sc_dc, sizeof(struct tga_devconfig));
                    436:                tga_getdevconfig(pa->pa_memt, pa->pa_pc, pa->pa_tag,
                    437:                    sc->sc_dc);
                    438:        }
                    439:        if (sc->sc_dc->dc_vaddr == NULL) {
                    440:                printf(": couldn't map memory space; punt!\n");
                    441:                return;
                    442:        }
                    443:
                    444:        /* XXX say what's going on. */
                    445:        intrstr = NULL;
                    446:        if (pci_intr_map(pa, &intrh)) {
                    447:                printf(": couldn't map interrupt");
                    448:                return;
                    449:        }
                    450:        intrstr = pci_intr_string(pa->pa_pc, intrh);
                    451:        sc->sc_intr = pci_intr_establish(pa->pa_pc, intrh, IPL_TTY, tga_intr,
                    452:            sc->sc_dc, sc->sc_dev.dv_xname);
                    453:        if (sc->sc_intr == NULL) {
                    454:                printf(": couldn't establish interrupt");
                    455:                if (intrstr != NULL)
                    456:                        printf("at %s", intrstr);
                    457:                printf("\n");
                    458:                return;
                    459:        }
                    460:
                    461:        rev = PCI_REVISION(pa->pa_class);
                    462:        switch (rev) {
                    463:        case 0x1:
                    464:        case 0x2:
                    465:        case 0x3:
                    466:                printf(": DC21030 step %c", 'A' + rev - 1);
                    467:                break;
                    468:        case 0x20:
                    469:                printf(": TGA2 abstract software model");
                    470:                break;
                    471:        case 0x21:
                    472:        case 0x22:
                    473:                printf(": TGA2 pass %d", rev - 0x20);
                    474:                break;
                    475:
                    476:        default:
                    477:                printf("unknown stepping (0x%x)", rev);
                    478:                break;
                    479:        }
                    480:        printf(", ");
                    481:
                    482:        /*
                    483:         * Get RAMDAC function vectors and call the RAMDAC functions
                    484:         * to allocate its private storage and pass that back to us.
                    485:         */
                    486:
                    487:        DPRINTF("tgaattach: Get RAMDAC functions\n");
                    488:        sc->sc_dc->dc_ramdac_funcs = sc->sc_dc->dc_tgaconf->ramdac_funcs();
                    489:        if (!sc->sc_dc->dc_tga2) {
                    490:            DPRINTF("tgaattach: !sc->sc_dc->dc_tga2\n");
                    491:            DPRINTF("tgaattach: sc->sc_dc->dc_tgaconf->ramdac_funcs %s "
                    492:                    "bt485_funcs\n",
                    493:                    (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs)
                    494:                    ? "==" : "!=");
                    495:            if (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs)
                    496:                  sc->sc_dc->dc_ramdac_cookie =
                    497:                        sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
                    498:                    tga_sched_update, tga_ramdac_wr, tga_ramdac_rd);
                    499:                else
                    500:                  sc->sc_dc->dc_ramdac_cookie =
                    501:                        sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
                    502:                    tga_sched_update, tga_bt463_wr, tga_bt463_rd);
                    503:        } else {
                    504:                DPRINTF("tgaattach: sc->sc_dc->dc_tga2\n");
                    505:                sc->sc_dc->dc_ramdac_cookie =
                    506:                        sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
                    507:                        tga_sched_update, tga2_ramdac_wr, tga2_ramdac_rd);
                    508:
                    509:                /* XXX this is a bit of a hack, setting the dotclock here */
                    510:                if (sc->sc_dc->dc_tgaconf->ramdac_funcs != bt485_funcs)
                    511:                        (*sc->sc_dc->dc_ramdac_funcs->ramdac_set_dotclock)
                    512:                                (sc->sc_dc->dc_ramdac_cookie,
                    513:                                 tga_getdotclock(sc->sc_dc));
                    514:        }
                    515:        DPRINTF("tgaattach: sc->sc_dc->dc_ramdac_cookie = 0x%016llx\n",
                    516:                sc->sc_dc->dc_ramdac_cookie);
                    517:        /*
                    518:         * Initialize the RAMDAC.  Initialization includes disabling
                    519:         * cursor, setting a sane colormap, etc.
                    520:         */
                    521:        DPRINTF("tgaattach: Initializing RAMDAC.\n");
                    522:        (*sc->sc_dc->dc_ramdac_funcs->ramdac_init)(sc->sc_dc->dc_ramdac_cookie);
                    523:        TGAWREG(sc->sc_dc, TGA_REG_SISR, 0x00000001); /* XXX */
                    524:
                    525:        if (sc->sc_dc->dc_tgaconf == NULL) {
                    526:                printf("unknown board configuration\n");
                    527:                return;
                    528:        }
                    529:        printf("board type %s\n", sc->sc_dc->dc_tgaconf->tgac_name);
                    530:        printf("%s: %d x %d, %dbpp, %s RAMDAC\n", sc->sc_dev.dv_xname,
                    531:            sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
                    532:            sc->sc_dc->dc_tgaconf->tgac_phys_depth,
                    533:            sc->sc_dc->dc_ramdac_funcs->ramdac_name);
                    534:
                    535:        if (intrstr != NULL)
                    536:                printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname,
                    537:                    intrstr);
                    538:
                    539:        aa.console = console;
                    540:        aa.scrdata = &tga_screenlist;
                    541:        aa.accessops = &tga_accessops;
                    542:        aa.accesscookie = sc;
                    543:        aa.defaultscreens = 0;
                    544:
                    545:        config_found(self, &aa, wsemuldisplaydevprint);
                    546:
                    547: #ifdef __NetBSD__
                    548:        config_interrupts(self, tga_config_interrupts);
                    549: #else
                    550:        tga_config_interrupts(self);
                    551: #endif
                    552: }
                    553:
                    554: void
                    555: tga_config_interrupts (d)
                    556:        struct device *d;
                    557: {
                    558:        struct tga_softc *sc = (struct tga_softc *)d;
                    559:        sc->sc_dc->dc_intrenabled = 1;
                    560: }
                    561:
                    562:
                    563: int
                    564: tga_ioctl(v, cmd, data, flag, p)
                    565:        void *v;
                    566:        u_long cmd;
                    567:        caddr_t data;
                    568:        int flag;
                    569:        struct proc *p;
                    570: {
                    571:        struct tga_softc *sc = v;
                    572:        struct tga_devconfig *dc = sc->sc_dc;
                    573:        struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
                    574:        struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
                    575:
                    576:        switch (cmd) {
                    577:        case WSDISPLAYIO_GTYPE:
                    578:                *(u_int *)data = WSDISPLAY_TYPE_TGA;
                    579:                break;
                    580:
                    581:        case WSDISPLAYIO_SMODE:
                    582:                sc->sc_mode = *(u_int *)data;
                    583:                switch (sc->sc_mode) {
                    584:                case WSDISPLAYIO_MODE_DUMBFB:
                    585:                        /* in dump fb mode start the framebuffer at 0 */
                    586:                        TGAWREG(dc, TGA_REG_VVBR, 0);
                    587:                        break;
                    588:                default:
                    589:                        /* XXX it this useful, except for not breaking Xtga? */
                    590:                        TGAWREG(dc, TGA_REG_VVBR, 1);
                    591:                        break;
                    592:                }
                    593:                break;
                    594:
                    595:        case WSDISPLAYIO_GINFO:
                    596: #define        wsd_fbip ((struct wsdisplay_fbinfo *)data)
                    597:                wsd_fbip->height = sc->sc_dc->dc_ht;
                    598:                wsd_fbip->width = sc->sc_dc->dc_wid;
                    599:                wsd_fbip->depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth;
                    600:                wsd_fbip->cmsize = 1024;                /* XXX ??? */
                    601: #undef wsd_fbip
                    602:                break;
                    603:
                    604:        case WSDISPLAYIO_LINEBYTES:
                    605:                *(u_int *)data = sc->sc_dc->dc_rowbytes;
                    606:                break;
                    607:
                    608:        case WSDISPLAYIO_GETCMAP:
                    609:                return (*dcrf->ramdac_get_cmap)(dcrc,
                    610:                    (struct wsdisplay_cmap *)data);
                    611:        case WSDISPLAYIO_PUTCMAP:
                    612:                return (*dcrf->ramdac_set_cmap)(dcrc,
                    613:                    (struct wsdisplay_cmap *)data);
                    614:
                    615:        case WSDISPLAYIO_SVIDEO:
                    616:        case WSDISPLAYIO_GVIDEO:
                    617:                break;
                    618:
                    619:        case WSDISPLAYIO_GCURPOS:
                    620:                return (*dcrf->ramdac_get_curpos)(dcrc,
                    621:                    (struct wsdisplay_curpos *)data);
                    622:
                    623:        case WSDISPLAYIO_SCURPOS:
                    624:                return (*dcrf->ramdac_set_curpos)(dcrc,
                    625:                    (struct wsdisplay_curpos *)data);
                    626:
                    627:        case WSDISPLAYIO_GCURMAX:
                    628:                return (*dcrf->ramdac_get_curmax)(dcrc,
                    629:                    (struct wsdisplay_curpos *)data);
                    630:
                    631:        case WSDISPLAYIO_GCURSOR:
                    632:                return (*dcrf->ramdac_get_cursor)(dcrc,
                    633:                    (struct wsdisplay_cursor *)data);
                    634:
                    635:        case WSDISPLAYIO_SCURSOR:
                    636:                return (*dcrf->ramdac_set_cursor)(dcrc,
                    637:                    (struct wsdisplay_cursor *)data);
                    638:
                    639:        default:
                    640:                return (-1);
                    641:        }
                    642:
                    643:        return (0);
                    644: }
                    645:
                    646: int
                    647: tga_sched_update(v, f)
                    648:        void    *v;
                    649:        void    (*f)(void *);
                    650: {
                    651:        struct tga_devconfig *dc = v;
                    652:
                    653:        if (dc->dc_intrenabled) {
                    654:                /* Arrange for f to be called at the next end-of-frame interrupt */
                    655:                dc->dc_ramdac_intr = f;
                    656:                TGAWREG(dc, TGA_REG_SISR, 0x00010000);
                    657:        } else {
                    658:                /* Spin until the end-of-frame, then call f */
                    659:                TGAWREG(dc, TGA_REG_SISR, 0x00010001);
                    660:                TGAREGWB(dc, TGA_REG_SISR, 1);
                    661:                while ((TGARREG(dc, TGA_REG_SISR) & 0x00000001) == 0)
                    662:                        ;
                    663:                f(dc->dc_ramdac_cookie);
                    664:                TGAWREG(dc, TGA_REG_SISR, 0x00000001);
                    665:                TGAREGWB(dc, TGA_REG_SISR, 1);
                    666:        }
                    667:
                    668:        return 0;
                    669: }
                    670:
                    671: int
                    672: tga_intr(v)
                    673:        void *v;
                    674: {
                    675:        struct tga_devconfig *dc = v;
                    676:        struct ramdac_cookie *dcrc= dc->dc_ramdac_cookie;
                    677:
                    678:        u_int32_t reg;
                    679:
                    680:        reg = TGARREG(dc, TGA_REG_SISR);
                    681:        if (( reg & 0x00010001) != 0x00010001) {
                    682:                /* Odd. We never set any of the other interrupt enables. */
                    683:                if ((reg & 0x1f) != 0) {
                    684:                        /* Clear the mysterious pending interrupts. */
                    685:                        TGAWREG(dc, TGA_REG_SISR, (reg & 0x1f));
                    686:                        TGAREGWB(dc, TGA_REG_SISR, 1);
                    687:                        /* This was our interrupt, even if we're puzzled as to why
                    688:                         * we got it.  Don't make the interrupt handler think it
                    689:                         * was a stray.
                    690:                         */
                    691:                        return -1;
                    692:                } else {
                    693:                        return 0;
                    694:                }
                    695:        }
                    696:        /* if we have something to do, do it */
                    697:        if (dc->dc_ramdac_intr) {
                    698:                dc->dc_ramdac_intr(dcrc);
                    699:                dc->dc_ramdac_intr = NULL;
                    700:        }
                    701:        TGAWREG(dc, TGA_REG_SISR, 0x00000001);
                    702:        TGAREGWB(dc, TGA_REG_SISR, 1);
                    703:        return (1);
                    704: }
                    705:
                    706: paddr_t
                    707: tga_mmap(v, offset, prot)
                    708:        void *v;
                    709:        off_t offset;
                    710:        int prot;
                    711: {
                    712:        struct tga_softc *sc = v;
                    713:        struct tga_devconfig *dc = sc->sc_dc;
                    714:
                    715:        if (offset >= dc->dc_tgaconf->tgac_cspace_size || offset < 0)
                    716:                return -1;
                    717:
                    718:        if (sc->sc_mode == WSDISPLAYIO_MODE_DUMBFB) {
                    719:                /*
                    720:                 * The framebuffer starts at the upper half of tga mem
                    721:                 */
                    722:                offset += dc->dc_tgaconf->tgac_cspace_size / 2;
                    723:        }
                    724: #if defined(__alpha__) || defined(__mips__)
                    725:        return atop(sc->sc_dc->dc_paddr + offset);
                    726: #else
                    727:        return (-1);
                    728: #endif
                    729: }
                    730:
                    731: int
                    732: tga_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
                    733:        void *v;
                    734:        const struct wsscreen_descr *type;
                    735:        void **cookiep;
                    736:        int *curxp, *curyp;
                    737:        long *attrp;
                    738: {
                    739:        struct tga_softc *sc = v;
                    740:        long defattr;
                    741:
                    742:        if (sc->nscreens > 0)
                    743:                return (ENOMEM);
                    744:
                    745:        *cookiep = &sc->sc_dc->dc_rinfo; /* one and only for now */
                    746:        *curxp = 0;
                    747:        *curyp = 0;
                    748:        sc->sc_dc->dc_rinfo.ri_ops.alloc_attr(&sc->sc_dc->dc_rinfo,
                    749:                0, 0, 0, &defattr);
                    750:        *attrp = defattr;
                    751:        sc->nscreens++;
                    752:        return (0);
                    753: }
                    754:
                    755: void
                    756: tga_free_screen(v, cookie)
                    757:        void *v;
                    758:        void *cookie;
                    759: {
                    760:        struct tga_softc *sc = v;
                    761:
                    762:        if (sc->sc_dc == &tga_console_dc)
                    763:                panic("tga_free_screen: console");
                    764:
                    765:        sc->nscreens--;
                    766: }
                    767:
                    768: int
                    769: tga_show_screen(v, cookie, waitok, cb, cbarg)
                    770:        void *v;
                    771:        void *cookie;
                    772:        int waitok;
                    773:        void (*cb)(void *, int, int);
                    774:        void *cbarg;
                    775: {
                    776:
                    777:        return (0);
                    778: }
                    779:
                    780: int
                    781: tga_cnattach(iot, memt, pc, bus, device, function)
                    782:        bus_space_tag_t iot, memt;
                    783:        pci_chipset_tag_t pc;
                    784:        int bus, device, function;
                    785: {
                    786:        struct tga_devconfig *dcp = &tga_console_dc;
                    787:        long defattr;
                    788:
                    789:        tga_getdevconfig(memt, pc,
                    790:            pci_make_tag(pc, bus, device, function), dcp);
                    791:
                    792:        /* sanity checks */
                    793:        if (dcp->dc_vaddr == NULL)
                    794:                panic("tga_console(%d, %d): couldn't map memory space",
                    795:                    device, function);
                    796:        if (dcp->dc_tgaconf == NULL)
                    797:                panic("tga_console(%d, %d): unknown board configuration",
                    798:                    device, function);
                    799:
                    800:        /*
                    801:         * Initialize the RAMDAC but DO NOT allocate any private storage.
                    802:         * Initialization includes disabling cursor, setting a sane
                    803:         * colormap, etc.  It will be reinitialized in tgaattach().
                    804:         */
                    805:        if (dcp->dc_tga2) {
                    806:                if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
                    807:                        bt485_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
                    808:                                     tga2_ramdac_rd);
                    809:                else
                    810:                        ibm561_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
                    811:                                      tga2_ramdac_rd, tga_getdotclock(dcp));
                    812:        } else {
                    813:                if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
                    814:                        bt485_cninit(dcp, tga_sched_update, tga_ramdac_wr,
                    815:                                tga_ramdac_rd);
                    816:                else {
                    817:                        bt463_cninit(dcp, tga_sched_update, tga_bt463_wr,
                    818:                                tga_bt463_rd);
                    819:                }
                    820:        }
                    821:        dcp->dc_rinfo.ri_ops.alloc_attr(&dcp->dc_rinfo, 0, 0, 0, &defattr);
                    822:        wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rinfo, 0, 0, defattr);
                    823:
                    824:        return(0);
                    825: }
                    826:
                    827: /*
                    828:  * Functions to blank and unblank the display.
                    829:  */
                    830: void
                    831: tga_burner(v, on, flags)
                    832:        void *v;
                    833:        u_int on, flags;
                    834: {
                    835:        struct tga_softc *sc = v;
                    836:
                    837:        if (on) {
                    838:                tga_unblank(sc->sc_dc);
                    839:        } else {
                    840:                tga_blank(sc->sc_dc);
                    841:        }
                    842: }
                    843:
                    844: void
                    845: tga_blank(dc)
                    846:        struct tga_devconfig *dc;
                    847: {
                    848:
                    849:        if (!dc->dc_blanked) {
                    850:                dc->dc_blanked = 1;
                    851:                /* XXX */
                    852:                TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | VVR_BLANK);
                    853:        }
                    854: }
                    855:
                    856: void
                    857: tga_unblank(dc)
                    858:        struct tga_devconfig *dc;
                    859: {
                    860:
                    861:        if (dc->dc_blanked) {
                    862:                dc->dc_blanked = 0;
                    863:                /* XXX */
                    864:                TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~VVR_BLANK);
                    865:        }
                    866: }
                    867:
                    868: /*
                    869:  * Functions to manipulate the built-in cursor handing hardware.
                    870:  */
                    871: int
                    872: tga_builtin_set_cursor(dc, cursorp)
                    873:        struct tga_devconfig *dc;
                    874:        struct wsdisplay_cursor *cursorp;
                    875: {
                    876:        struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
                    877:        struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
                    878:        u_int count, v;
                    879:        int error;
                    880:
                    881:        v = cursorp->which;
                    882:        if (v & WSDISPLAY_CURSOR_DOCMAP) {
                    883:                error = dcrf->ramdac_check_curcmap(dcrc, cursorp);
                    884:                if (error)
                    885:                        return (error);
                    886:        }
                    887:        if (v & WSDISPLAY_CURSOR_DOSHAPE) {
                    888:                if ((u_int)cursorp->size.x != 64 ||
                    889:                    (u_int)cursorp->size.y > 64)
                    890:                        return (EINVAL);
                    891:        }
                    892:        if (v & WSDISPLAY_CURSOR_DOHOT)         /* not supported */
                    893:                return EINVAL;
                    894:
                    895:        /* parameters are OK; do it */
                    896:        if (v & WSDISPLAY_CURSOR_DOCUR) {
                    897:                if (cursorp->enable)
                    898:                        /* XXX */
                    899:                        TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 0x04);
                    900:                else
                    901:                        /* XXX */
                    902:                        TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~0x04);
                    903:        }
                    904:        if (v & WSDISPLAY_CURSOR_DOPOS) {
                    905:                TGAWREG(dc, TGA_REG_CXYR,
                    906:                    ((cursorp->pos.y & 0xfff) << 12) | (cursorp->pos.x & 0xfff));
                    907:        }
                    908:        if (v & WSDISPLAY_CURSOR_DOCMAP) {
                    909:                /* can't fail. */
                    910:                dcrf->ramdac_set_curcmap(dcrc, cursorp);
                    911:        }
                    912:        if (v & WSDISPLAY_CURSOR_DOSHAPE) {
                    913:                /* The cursor is 2 bits deep, and there is no mask */
                    914:                count = (cursorp->size.y * 64 * 2) / NBBY;
                    915:                TGAWREG(dc, TGA_REG_CCBR,
                    916:                    (TGARREG(dc, TGA_REG_CCBR) & ~0xfc00) | (cursorp->size.y << 10));
                    917:                if ((error = copyin(cursorp->image,(char *)(dc->dc_vaddr +
                    918:                    (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)), count)) != 0)
                    919:                        return (error);
                    920:        }
                    921:        return (0);
                    922: }
                    923:
                    924: int
                    925: tga_builtin_get_cursor(dc, cursorp)
                    926:        struct tga_devconfig *dc;
                    927:        struct wsdisplay_cursor *cursorp;
                    928: {
                    929:        struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
                    930:        struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
                    931:        int error;
                    932:        u_int count;
                    933:
                    934:        cursorp->which = WSDISPLAY_CURSOR_DOALL &
                    935:            ~(WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCMAP);
                    936:        cursorp->enable = (TGARREG(dc, TGA_REG_VVVR) & 0x04) != 0;
                    937:        cursorp->pos.x = TGARREG(dc, TGA_REG_CXYR) & 0xfff;
                    938:        cursorp->pos.y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff;
                    939:        cursorp->size.x = 64;
                    940:        cursorp->size.y = (TGARREG(dc, TGA_REG_CCBR) >> 10) & 0x3f;
                    941:
                    942:        if (cursorp->image != NULL) {
                    943:                count = (cursorp->size.y * 64 * 2) / NBBY;
                    944:                error = copyout((char *)(dc->dc_vaddr +
                    945:                      (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)),
                    946:                    cursorp->image, count);
                    947:                if (error)
                    948:                        return (error);
                    949:                /* No mask */
                    950:        }
                    951:        error = dcrf->ramdac_get_curcmap(dcrc, cursorp);
                    952:        return (error);
                    953: }
                    954:
                    955: int
                    956: tga_builtin_set_curpos(dc, curposp)
                    957:        struct tga_devconfig *dc;
                    958:        struct wsdisplay_curpos *curposp;
                    959: {
                    960:
                    961:        TGAWREG(dc, TGA_REG_CXYR,
                    962:            ((curposp->y & 0xfff) << 12) | (curposp->x & 0xfff));
                    963:        return (0);
                    964: }
                    965:
                    966: int
                    967: tga_builtin_get_curpos(dc, curposp)
                    968:        struct tga_devconfig *dc;
                    969:        struct wsdisplay_curpos *curposp;
                    970: {
                    971:
                    972:        curposp->x = TGARREG(dc, TGA_REG_CXYR) & 0xfff;
                    973:        curposp->y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff;
                    974:        return (0);
                    975: }
                    976:
                    977: int
                    978: tga_builtin_get_curmax(dc, curposp)
                    979:        struct tga_devconfig *dc;
                    980:        struct wsdisplay_curpos *curposp;
                    981: {
                    982:
                    983:        curposp->x = curposp->y = 64;
                    984:        return (0);
                    985: }
                    986:
                    987: /*
                    988:  * Copy columns (characters) in a row (line).
                    989:  */
                    990: void
                    991: tga_copycols(id, row, srccol, dstcol, ncols)
                    992:        void *id;
                    993:        int row, srccol, dstcol, ncols;
                    994: {
                    995:        struct rasops_info *ri = id;
                    996:        int y, srcx, dstx, nx;
                    997:
                    998:        y = ri->ri_font->fontheight * row;
                    999:        srcx = ri->ri_font->fontwidth * srccol;
                   1000:        dstx = ri->ri_font->fontwidth * dstcol;
                   1001:        nx = ri->ri_font->fontwidth * ncols;
                   1002:
                   1003:        tga_rop(ri, dstx, y, nx, ri->ri_font->fontheight, ri, srcx, y);
                   1004: }
                   1005:
                   1006: /*
                   1007:  * Copy rows (lines).
                   1008:  */
                   1009: void
                   1010: tga_copyrows(id, srcrow, dstrow, nrows)
                   1011:        void *id;
                   1012:        int srcrow, dstrow, nrows;
                   1013: {
                   1014:        struct rasops_info *ri = id;
                   1015:        int srcy, dsty, ny;
                   1016:
                   1017:        srcy = ri->ri_font->fontheight * srcrow;
                   1018:        dsty = ri->ri_font->fontheight * dstrow;
                   1019:        ny = ri->ri_font->fontheight * nrows;
                   1020:
                   1021:        tga_rop(ri, 0, dsty, ri->ri_emuwidth, ny, ri, 0, srcy);
                   1022: }
                   1023:
                   1024: /*
                   1025:  *  Generic TGA raster op.
                   1026:  *   This covers all possible raster ops, and
                   1027:  *   clips the sizes and all of that.
                   1028:  */
                   1029: int
                   1030: tga_rop(dst, dx, dy, w, h, src, sx, sy)
                   1031:        struct rasops_info *dst;
                   1032:        int dx, dy, w, h;
                   1033:        struct rasops_info *src;
                   1034:        int sx, sy;
                   1035: {
                   1036:        if (dst == NULL || src == NULL)
                   1037:                return -1;
                   1038:
                   1039:        /* Clip against src */
                   1040:        if (sx < 0) {
                   1041:                w += sx;
                   1042:                sx = 0;
                   1043:        }
                   1044:        if (sy < 0) {
                   1045:                h += sy;
                   1046:                sy = 0;
                   1047:        }
                   1048:        if (sx + w > src->ri_emuwidth)
                   1049:                w = src->ri_emuwidth - sx;
                   1050:        if (sy + h > src->ri_emuheight)
                   1051:                h = src->ri_emuheight - sy;
                   1052:
                   1053:        /* Clip against dst.  We modify src regardless of using it,
                   1054:         * since it really doesn't matter.
                   1055:         */
                   1056:        if (dx < 0) {
                   1057:                w += dx;
                   1058:                sx -= dx;
                   1059:                dx = 0;
                   1060:        }
                   1061:        if (dy < 0) {
                   1062:                h += dy;
                   1063:                sy -= dy;
                   1064:                dy = 0;
                   1065:        }
                   1066:        if (dx + w > dst->ri_emuwidth)
                   1067:                w = dst->ri_emuwidth - dx;
                   1068:        if (dy + h > dst->ri_emuheight)
                   1069:                h = dst->ri_emuheight - dy;
                   1070:        if (w <= 0 || h <= 0)
                   1071:                return 0;       /* Vacuously true; */
                   1072:
                   1073:        return tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy);
                   1074: }
                   1075:
                   1076:
                   1077:
                   1078: /*
                   1079:  * Video to Video raster ops.
                   1080:  * This function deals with all raster ops that have a src and dst
                   1081:  * that are on the card.
                   1082:  */
                   1083: int
                   1084: tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy)
                   1085:        struct rasops_info *dst;
                   1086:        int dx, dy, w, h;
                   1087:        struct rasops_info *src;
                   1088:        int sx, sy;
                   1089: {
                   1090:        struct tga_devconfig *dc = (struct tga_devconfig *)dst->ri_hw;
                   1091:        int srcb, dstb, tga_srcb, tga_dstb;
                   1092:        int x, y, wb;
                   1093:        int xstart, xend, xdir;
                   1094:        int ystart, yend, ydir, yinc;
                   1095:        int xleft, lastx, lastleft;
                   1096:        int offset = 1 * dc->dc_tgaconf->tgac_vvbr_units;
                   1097:
                   1098:        /*
                   1099:         * I don't yet want to deal with unaligned guys, really.  And we don't
                   1100:         * deal with copies from one card to another.
                   1101:         */
                   1102:        if (dx % 8 != 0 || sx % 8 != 0 || src != dst) {
                   1103:                /* XXX Punt! */
                   1104:                /* XXX should never happen, since it's only being used to
                   1105:                 * XXX copy 8-pixel-wide characters.
                   1106:                 */
                   1107:                return -1;
                   1108:        }
                   1109:
                   1110:         wb = w * (dst->ri_depth / 8);
                   1111:        if (sy >= dy) {
                   1112:                ystart = 0;
                   1113:                yend = h;
                   1114:                ydir = 1;
                   1115:        } else {
                   1116:                ystart = h;
                   1117:                yend = 0;
                   1118:                ydir = -1;
                   1119:        }
                   1120:        if (sx >= dx) {      /* moving to the left */
                   1121:                xstart = 0;
                   1122:                xend = w * (dst->ri_depth / 8) - 4;
                   1123:                xdir = 1;
                   1124:        } else {             /* moving to the right */
                   1125:                xstart = wb - ( wb >= 4*64 ? 4*64 : wb >= 64 ? 64 : 4 );
                   1126:                xend = 0;
                   1127:                xdir = -1;
                   1128:        }
                   1129: #define XINC4   4
                   1130: #define XINC64  64
                   1131: #define XINC256 (64*4)
                   1132:        yinc = ydir * dst->ri_stride;
                   1133:        ystart *= dst->ri_stride;
                   1134:        yend *= dst->ri_stride;
                   1135:
                   1136:        srcb = sy * src->ri_stride + sx * (src->ri_depth/8);
                   1137:        dstb = dy * dst->ri_stride + dx * (dst->ri_depth/8);
                   1138:        tga_srcb = offset + (sy + src->ri_yorigin) * src->ri_stride +
                   1139:                (sx + src->ri_xorigin) * (src->ri_depth/8);
                   1140:        tga_dstb = offset + (dy + dst->ri_yorigin) * dst->ri_stride +
                   1141:                (dx + dst->ri_xorigin) * (dst->ri_depth/8);
                   1142:
                   1143:        TGAWALREG(dc, TGA_REG_GMOR, 3, 0x0007); /* Copy mode */
                   1144:        TGAWALREG(dc, TGA_REG_GOPR, 3, 0x0003); /* SRC */
                   1145:
                   1146:        /*
                   1147:         * we have 3 sizes of pixels to move in X direction:
                   1148:         * 4 * 64   (unrolled TGA ops)
                   1149:         *     64   (single TGA op)
                   1150:         *      4   (CPU, using long word)
                   1151:         */
                   1152:
                   1153:        if (xdir == 1) {   /* move to the left */
                   1154:
                   1155:                for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
                   1156:
                   1157:                        /* 4*64 byte chunks */
                   1158:                        for (xleft = wb, x = xstart;
                   1159:                             x <= xend && xleft >= 4*64;
                   1160:                             x += XINC256, xleft -= XINC256) {
                   1161:
                   1162:                                /* XXX XXX Eight writes to different addresses should fill
                   1163:                                 * XXX XXX up the write buffers on 21064 and 21164 chips,
                   1164:                                 * XXX XXX but later CPUs might have larger write buffers which
                   1165:                                 * XXX XXX require further unrolling of this loop, or the
                   1166:                                 * XXX XXX insertion of memory barriers.
                   1167:                                 */
                   1168:                                TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
                   1169:                                TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
                   1170:                                TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 1 * 64);
                   1171:                                TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 1 * 64);
                   1172:                                TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 2 * 64);
                   1173:                                TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 2 * 64);
                   1174:                                TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 3 * 64);
                   1175:                                TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 3 * 64);
                   1176:                        }
                   1177:
                   1178:                        /* 64 byte chunks */
                   1179:                        for ( ; x <= xend && xleft >= 64;
                   1180:                              x += XINC64, xleft -= XINC64) {
                   1181:                                TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
                   1182:                                TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
                   1183:                        }
                   1184:                        lastx = x; lastleft = xleft;  /* remember for CPU loop */
                   1185:
                   1186:                }
                   1187:                TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */
                   1188:                TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */
                   1189:
                   1190:                for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
                   1191:                        /* 4 byte granularity */
                   1192:                        for (x = lastx, xleft = lastleft;
                   1193:                             x <= xend && xleft >= 4;
                   1194:                             x += XINC4, xleft -= XINC4) {
                   1195:                                *(uint32_t *)(dst->ri_bits + dstb + y + x) =
                   1196:                                        *(uint32_t *)(dst->ri_bits + srcb + y + x);
                   1197:                        }
                   1198:                }
                   1199:        }
                   1200:        else {    /* above move to the left, below move to the right */
                   1201:
                   1202:                for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
                   1203:
                   1204:                        /* 4*64 byte chunks */
                   1205:                        for (xleft = wb, x = xstart;
                   1206:                             x >= xend && xleft >= 4*64;
                   1207:                             x -= XINC256, xleft -= XINC256) {
                   1208:
                   1209:                                /* XXX XXX Eight writes to different addresses should fill
                   1210:                                 * XXX XXX up the write buffers on 21064 and 21164 chips,
                   1211:                                 * XXX XXX but later CPUs might have larger write buffers which
                   1212:                                 * XXX XXX require further unrolling of this loop, or the
                   1213:                                 * XXX XXX insertion of memory barriers.
                   1214:                                 */
                   1215:                                TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 3 * 64);
                   1216:                                TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 3 * 64);
                   1217:                                TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 2 * 64);
                   1218:                                TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 2 * 64);
                   1219:                                TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 1 * 64);
                   1220:                                TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 1 * 64);
                   1221:                                TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 0 * 64);
                   1222:                                TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 0 * 64);
                   1223:                        }
                   1224:
                   1225:                        if (xleft) x += XINC256 - XINC64;
                   1226:
                   1227:                        /* 64 byte chunks */
                   1228:                        for ( ; x >= xend && xleft >= 64;
                   1229:                              x -= XINC64, xleft -= XINC64) {
                   1230:                                TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
                   1231:                                TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
                   1232:                        }
                   1233:                        if (xleft) x += XINC64 - XINC4;
                   1234:                        lastx = x; lastleft = xleft;  /* remember for CPU loop */
                   1235:                }
                   1236:                TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */
                   1237:                TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */
                   1238:
                   1239:                for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
                   1240:                        /* 4 byte granularity */
                   1241:                        for (x = lastx, xleft = lastleft;
                   1242:                             x >= xend && xleft >= 4;
                   1243:                             x -= XINC4, xleft -= XINC4) {
                   1244:                                *(uint32_t *)(dst->ri_bits + dstb + y + x) =
                   1245:                                        *(uint32_t *)(dst->ri_bits + srcb + y + x);
                   1246:                        }
                   1247:                }
                   1248:        }
                   1249:        return 0;
                   1250: }
                   1251:
                   1252:
                   1253: void
                   1254: tga_putchar(c, row, col, uc, attr)
                   1255:        void *c;
                   1256:        int row, col;
                   1257:        u_int uc;
                   1258:        long attr;
                   1259: {
                   1260:        struct rasops_info *ri = c;
                   1261:        struct tga_devconfig *dc = ri->ri_hw;
                   1262:        int fs, height, width;
                   1263:        int fg, bg, ul;
                   1264:        u_char *fr;
                   1265:        int32_t *rp;
                   1266:
                   1267:        rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
                   1268:
                   1269:        height = ri->ri_font->fontheight;
                   1270:        width = ri->ri_font->fontwidth;
                   1271:
                   1272:        uc -= ri->ri_font->firstchar;
                   1273:        fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
                   1274:        fs = ri->ri_font->stride;
                   1275:
                   1276:        /* Set foreground and background color. XXX memoize this somehow?
                   1277:         * The rasops code has already expanded the color entry to 32 bits
                   1278:         * for us, even for 8-bit displays, so we don't have to do anything.
                   1279:         */
                   1280:        ri->ri_ops.unpack_attr(c, attr, &fg, &bg, &ul);
                   1281:        TGAWREG(dc, TGA_REG_GFGR, ri->ri_devcmap[fg]);
                   1282:        TGAWREG(dc, TGA_REG_GBGR, ri->ri_devcmap[bg]);
                   1283:
                   1284:        /* Set raster operation to "copy"... */
                   1285:        if (ri->ri_depth == 8)
                   1286:                TGAWREG(dc, TGA_REG_GOPR, 0x3);
                   1287:        else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
                   1288:                TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
                   1289:
                   1290:        /* Set which pixels we're drawing (of a possible 32). */
                   1291:        TGAWREG(dc, TGA_REG_GPXR_P, (1 << width) - 1);
                   1292:
                   1293:        /* Set drawing mode to opaque stipple. */
                   1294:        TGAWREG(dc, TGA_REG_GMOR, 0x1);
                   1295:
                   1296:        /* Insert write barrier before actually sending data */
                   1297:        /* XXX Abuses the fact that there is only one write barrier on Alphas */
                   1298:        TGAREGWB(dc, TGA_REG_GMOR, 1);
                   1299:
                   1300:        while (height--) {
                   1301:                /* The actual stipple write */
                   1302:                *rp = fr[0] | (fr[1] << 8) | (fr[2] << 16) | (fr[3] << 24);
                   1303:
                   1304:                fr += fs;
                   1305:                rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
                   1306:        }
                   1307:
                   1308:        /* Do underline */
                   1309:        if (ul) {
                   1310:                rp = (int32_t *)((caddr_t)rp - (ri->ri_stride << 1));
                   1311:                *rp = 0xffffffff;
                   1312:        }
                   1313:
                   1314:        /* Set grapics mode back to normal. */
                   1315:        TGAWREG(dc, TGA_REG_GMOR, 0);
                   1316:        TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff);
                   1317: }
                   1318:
                   1319: void
                   1320: tga_eraserows(c, row, num, attr)
                   1321:        void *c;
                   1322:        int row, num;
                   1323:        long attr;
                   1324: {
                   1325:        struct rasops_info *ri = c;
                   1326:        struct tga_devconfig *dc = ri->ri_hw;
                   1327:        int32_t color, lines, pixels;
                   1328:        int fg, bg;
                   1329:        int32_t *rp;
                   1330:
                   1331:        ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL);
                   1332:        color = ri->ri_devcmap[bg];
                   1333:        rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale);
                   1334:        lines = num * ri->ri_font->fontheight;
                   1335:        pixels = ri->ri_emuwidth - 1;
                   1336:
                   1337:        /* Set fill color in block-color registers */
                   1338:        TGAWREG(dc, TGA_REG_GBCR0, color);
                   1339:        TGAWREG(dc, TGA_REG_GBCR1, color);
                   1340:        if (ri->ri_depth != 8) {
                   1341:                TGAWREG(dc, TGA_REG_GBCR2, color);
                   1342:                TGAWREG(dc, TGA_REG_GBCR3, color);
                   1343:                TGAWREG(dc, TGA_REG_GBCR4, color);
                   1344:                TGAWREG(dc, TGA_REG_GBCR5, color);
                   1345:                TGAWREG(dc, TGA_REG_GBCR6, color);
                   1346:                TGAWREG(dc, TGA_REG_GBCR7, color);
                   1347:        }
                   1348:
                   1349:        /* Set raster operation to "copy"... */
                   1350:        if (ri->ri_depth == 8)
                   1351:                TGAWREG(dc, TGA_REG_GOPR, 0x3);
                   1352:        else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
                   1353:                TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
                   1354:
                   1355:        /* Set which pixels we're drawing (of a possible 32). */
                   1356:        TGAWREG(dc, TGA_REG_GDAR, 0xffffffff);
                   1357:
                   1358:        /* Set drawing mode to block fill. */
                   1359:        TGAWREG(dc, TGA_REG_GMOR, 0x2d);
                   1360:
                   1361:        /* Insert write barrier before actually sending data */
                   1362:        /* XXX Abuses the fact that there is only one write barrier on Alphas */
                   1363:        TGAREGWB(dc, TGA_REG_GMOR, 1);
                   1364:
                   1365:        while (lines--) {
                   1366:                *rp = pixels;
                   1367:                rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
                   1368:        }
                   1369:
                   1370:        /* Set grapics mode back to normal. */
                   1371:        TGAWREG(dc, TGA_REG_GMOR, 0);
                   1372:
                   1373: }
                   1374:
                   1375: void
                   1376: tga_erasecols (c, row, col, num, attr)
                   1377:        void *c;
                   1378:        int row, col, num;
                   1379:        long attr;
                   1380: {
                   1381:        struct rasops_info *ri = c;
                   1382:        struct tga_devconfig *dc = ri->ri_hw;
                   1383:        int32_t color, lines, pixels;
                   1384:        int fg, bg;
                   1385:        int32_t *rp;
                   1386:
                   1387:        ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL);
                   1388:        color = ri->ri_devcmap[bg];
                   1389:        rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
                   1390:        lines = ri->ri_font->fontheight;
                   1391:        pixels = (num * ri->ri_font->fontwidth) - 1;
                   1392:
                   1393:        /* Set fill color in block-color registers */
                   1394:        TGAWREG(dc, TGA_REG_GBCR0, color);
                   1395:        TGAWREG(dc, TGA_REG_GBCR1, color);
                   1396:        if (ri->ri_depth != 8) {
                   1397:                TGAWREG(dc, TGA_REG_GBCR2, color);
                   1398:                TGAWREG(dc, TGA_REG_GBCR3, color);
                   1399:                TGAWREG(dc, TGA_REG_GBCR4, color);
                   1400:                TGAWREG(dc, TGA_REG_GBCR5, color);
                   1401:                TGAWREG(dc, TGA_REG_GBCR6, color);
                   1402:                TGAWREG(dc, TGA_REG_GBCR7, color);
                   1403:        }
                   1404:
                   1405:        /* Set raster operation to "copy"... */
                   1406:        if (ri->ri_depth == 8)
                   1407:                TGAWREG(dc, TGA_REG_GOPR, 0x3);
                   1408:        else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
                   1409:                TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
                   1410:
                   1411:        /* Set which pixels we're drawing (of a possible 32). */
                   1412:        TGAWREG(dc, TGA_REG_GDAR, 0xffffffff);
                   1413:
                   1414:        /* Set drawing mode to block fill. */
                   1415:        TGAWREG(dc, TGA_REG_GMOR, 0x2d);
                   1416:
                   1417:        /* Insert write barrier before actually sending data */
                   1418:        /* XXX Abuses the fact that there is only one write barrier on Alphas */
                   1419:        TGAREGWB(dc, TGA_REG_GMOR, 1);
                   1420:
                   1421:        while (lines--) {
                   1422:                *rp = pixels;
                   1423:                rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
                   1424:        }
                   1425:
                   1426:        /* Set grapics mode back to normal. */
                   1427:        TGAWREG(dc, TGA_REG_GMOR, 0);
                   1428: }
                   1429:
                   1430:
                   1431: void
                   1432: tga_ramdac_wr(v, btreg, val)
                   1433:        void *v;
                   1434:        u_int btreg;
                   1435:        u_int8_t val;
                   1436: {
                   1437:        struct tga_devconfig *dc = v;
                   1438:
                   1439:        if (btreg > BT485_REG_MAX)
                   1440:                panic("tga_ramdac_wr: reg %d out of range", btreg);
                   1441:
                   1442:        TGAWREG(dc, TGA_REG_EPDR, (btreg << 9) | (0 << 8 ) | val); /* XXX */
                   1443:        TGAREGWB(dc, TGA_REG_EPDR, 1);
                   1444: }
                   1445:
                   1446: void
                   1447: tga2_ramdac_wr(v, btreg, val)
                   1448:        void *v;
                   1449:        u_int btreg;
                   1450:        u_int8_t val;
                   1451: {
                   1452:        struct tga_devconfig *dc = v;
                   1453:        bus_space_handle_t ramdac;
                   1454:
                   1455:        if (btreg > BT485_REG_MAX)
                   1456:                panic("tga_ramdac_wr: reg %d out of range", btreg);
                   1457:
                   1458:        bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC +
                   1459:                (0xe << 12) + (btreg << 8), 4, &ramdac);
                   1460:        bus_space_write_4(dc->dc_memt, ramdac, 0, val & 0xff);
                   1461:        bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_WRITE);
                   1462: }
                   1463:
                   1464: u_int8_t
                   1465: tga_bt463_rd(v, btreg)
                   1466:        void *v;
                   1467:        u_int btreg;
                   1468: {
                   1469:        struct tga_devconfig *dc = v;
                   1470:        tga_reg_t rdval;
                   1471:
                   1472:        /*
                   1473:         * Strobe CE# (high->low->high) since status and data are latched on
                   1474:         * the falling and rising edges (repsectively) of this active-low signal.
                   1475:         */
                   1476:
                   1477:        TGAREGWB(dc, TGA_REG_EPSR, 1);
                   1478:        TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
                   1479:        TGAREGWB(dc, TGA_REG_EPSR, 1);
                   1480:        TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 0);
                   1481:
                   1482:        TGAREGRB(dc, TGA_REG_EPSR, 1);
                   1483:
                   1484:        rdval = TGARREG(dc, TGA_REG_EPDR);
                   1485:        TGAREGWB(dc, TGA_REG_EPSR, 1);
                   1486:        TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
                   1487:
                   1488:        return (rdval >> 16) & 0xff;
                   1489: }
                   1490:
                   1491: void
                   1492: tga_bt463_wr(v, btreg, val)
                   1493:        void *v;
                   1494:        u_int btreg;
                   1495:        u_int8_t val;
                   1496: {
                   1497:        struct tga_devconfig *dc = v;
                   1498:
                   1499:        /*
                   1500:         * In spite of the 21030 documentation, to set the MPU bus bits for
                   1501:         * a write, you set them in the upper bits of EPDR, not EPSR.
                   1502:         */
                   1503:
                   1504:        /*
                   1505:         * Strobe CE# (high->low->high) since status and data are latched on
                   1506:         * the falling and rising edges of this active-low signal.
                   1507:         */
                   1508:
                   1509:        TGAREGWB(dc, TGA_REG_EPDR, 1);
                   1510:        TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
                   1511:        TGAREGWB(dc, TGA_REG_EPDR, 1);
                   1512:        TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x000 | val);
                   1513:        TGAREGWB(dc, TGA_REG_EPDR, 1);
                   1514:        TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
                   1515:
                   1516: }
                   1517:
                   1518: u_int8_t
                   1519: tga_ramdac_rd(v, btreg)
                   1520:        void *v;
                   1521:        u_int btreg;
                   1522: {
                   1523:        struct tga_devconfig *dc = v;
                   1524:        tga_reg_t rdval;
                   1525:
                   1526:        if (btreg > BT485_REG_MAX)
                   1527:                panic("tga_ramdac_rd: reg %d out of range", btreg);
                   1528:
                   1529:        TGAWREG(dc, TGA_REG_EPSR, (btreg << 1) | 0x1); /* XXX */
                   1530:        TGAREGWB(dc, TGA_REG_EPSR, 1);
                   1531:
                   1532:        rdval = TGARREG(dc, TGA_REG_EPDR);
                   1533:        return (rdval >> 16) & 0xff;                            /* XXX */
                   1534: }
                   1535:
                   1536: u_int8_t
                   1537: tga2_ramdac_rd(v, btreg)
                   1538:        void *v;
                   1539:        u_int btreg;
                   1540: {
                   1541:        struct tga_devconfig *dc = v;
                   1542:        bus_space_handle_t ramdac;
                   1543:        u_int8_t retval;
                   1544:
                   1545:        if (btreg > BT485_REG_MAX)
                   1546:                panic("tga_ramdac_rd: reg %d out of range", btreg);
                   1547:
                   1548:        bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC +
                   1549:                (0xe << 12) + (btreg << 8), 4, &ramdac);
                   1550:        retval = bus_space_read_4(dc->dc_memt, ramdac, 0) & 0xff;
                   1551:        bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_READ);
                   1552:        return retval;
                   1553: }
                   1554:
                   1555: #include <dev/ic/decmonitors.c>
                   1556: void tga2_ics9110_wr(
                   1557:        struct tga_devconfig *dc,
                   1558:        int dotclock
                   1559: );
                   1560:
                   1561: struct monitor *tga_getmonitor(struct tga_devconfig *dc);
                   1562:
                   1563: void
                   1564: tga2_init(dc)
                   1565:        struct tga_devconfig *dc;
                   1566: {
                   1567:        struct  monitor *m = tga_getmonitor(dc);
                   1568:
                   1569:
                   1570:        /* Deal with the dot clocks.
                   1571:         */
                   1572:        if (dc->dc_tga_type == TGA_TYPE_POWERSTORM_4D20) {
                   1573:                /* Set this up as a reference clock for the
                   1574:                 * ibm561's PLL.
                   1575:                 */
                   1576:                tga2_ics9110_wr(dc, 14300000);
                   1577:                /* XXX Can't set up the dotclock properly, until such time
                   1578:                 * as the RAMDAC is configured.
                   1579:                 */
                   1580:        } else {
                   1581:                /* otherwise the ics9110 is our clock. */
                   1582:                tga2_ics9110_wr(dc, m->dotclock);
                   1583:        }
                   1584: #if 0
                   1585:        TGAWREG(dc, TGA_REG_VHCR,
                   1586:             ((m->hbp / 4) << 21) |
                   1587:             ((m->hsync / 4) << 14) |
                   1588:            (((m->hfp - 4) / 4) << 9) |
                   1589:             ((m->cols + 4) / 4));
                   1590: #else
                   1591:        TGAWREG(dc, TGA_REG_VHCR,
                   1592:             ((m->hbp / 4) << 21) |
                   1593:             ((m->hsync / 4) << 14) |
                   1594:            (((m->hfp) / 4) << 9) |
                   1595:             ((m->cols) / 4));
                   1596: #endif
                   1597:        TGAWREG(dc, TGA_REG_VVCR,
                   1598:            (m->vbp << 22) |
                   1599:            (m->vsync << 16) |
                   1600:            (m->vfp << 11) |
                   1601:            (m->rows));
                   1602:        TGAWREG(dc, TGA_REG_VVBR, 1);
                   1603:        TGAREGRWB(dc, TGA_REG_VHCR, 3);
                   1604:        TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 1);
                   1605:        TGAREGRWB(dc, TGA_REG_VVVR, 1);
                   1606:        TGAWREG(dc, TGA_REG_GPMR, 0xffffffff);
                   1607:        TGAREGRWB(dc, TGA_REG_GPMR, 1);
                   1608: }
                   1609:
                   1610: void
                   1611: tga2_ics9110_wr(dc, dotclock)
                   1612:        struct tga_devconfig *dc;
                   1613:        int dotclock;
                   1614: {
                   1615:        bus_space_handle_t clock;
                   1616:        u_int32_t valU;
                   1617:        int N, M, R, V, X;
                   1618:        int i;
                   1619:
                   1620:        switch (dotclock) {
                   1621:        case 130808000:
                   1622:                N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break;
                   1623:        case 119840000:
                   1624:                N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break;
                   1625:        case 108180000:
                   1626:                N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break;
                   1627:        case 103994000:
                   1628:                N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break;
                   1629:        case 175000000:
                   1630:                N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break;
                   1631:        case  75000000:
                   1632:                N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break;
                   1633:        case  74000000:
                   1634:                N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break;
                   1635:        case  69000000:
                   1636:                N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break;
                   1637:        case  65000000:
                   1638:                N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break;
                   1639:        case  50000000:
                   1640:                N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break;
                   1641:        case  40000000:
                   1642:                N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break;
                   1643:        case  31500000:
                   1644:                N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break;
                   1645:        case  25175000:
                   1646:                N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break;
                   1647:        case 135000000:
                   1648:                N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break;
                   1649:        case 110000000:
                   1650:                N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
                   1651:        case 202500000:
                   1652:                N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
                   1653:        case  14300000:         /* this one is just a ref clock */
                   1654:                N = 0x03; M = 0x03; V = 0x1; X = 0x1; R = 0x3; break;
                   1655:        default:
                   1656:                panic("unrecognized clock rate %d", dotclock);
                   1657:        }
                   1658:
                   1659:        /* XXX -- hard coded, bad */
                   1660:        valU  = N | ( M << 7 ) | (V << 14);
                   1661:        valU |= (X << 15) | (R << 17);
                   1662:        valU |= 0x17 << 19;
                   1663:
                   1664:        bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV +
                   1665:            TGA2_MEM_CLOCK + (0xe << 12), 4, &clock); /* XXX */
                   1666:
                   1667:        for (i = 24; i > 0; i--) {
                   1668:                u_int32_t writeval;
                   1669:
                   1670:                writeval = valU & 0x1;
                   1671:                if (i == 1)
                   1672:                        writeval |= 0x2;
                   1673:                valU >>= 1;
                   1674:                bus_space_write_4(dc->dc_memt, clock, 0, writeval);
                   1675:                bus_space_barrier(dc->dc_memt, clock, 0, 4, BUS_SPACE_BARRIER_WRITE);
                   1676:         }
                   1677:        bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV +
                   1678:            TGA2_MEM_CLOCK + (0xe << 12) + (0x1 << 11) + (0x1 << 11), 4,
                   1679:                &clock); /* XXX */
                   1680:        bus_space_write_4(dc->dc_memt, clock, 0, 0x0);
                   1681:        bus_space_barrier(dc->dc_memt, clock, 0, 0, BUS_SPACE_BARRIER_WRITE);
                   1682: }
                   1683:
                   1684: struct monitor *
                   1685: tga_getmonitor(dc)
                   1686:        struct tga_devconfig *dc;
                   1687: {
                   1688:        return &decmonitors[(~TGARREG(dc, TGA_REG_GREV) >> 16) & 0x0f];
                   1689: }
                   1690:
                   1691: unsigned
                   1692: tga_getdotclock(dc)
                   1693:        struct tga_devconfig *dc;
                   1694: {
                   1695:        return tga_getmonitor(dc)->dotclock;
                   1696: }

CVSweb