diff options
author | Nathan Binkert <nate@cvs.openbsd.org> | 2001-03-18 04:37:22 +0000 |
---|---|---|
committer | Nathan Binkert <nate@cvs.openbsd.org> | 2001-03-18 04:37:22 +0000 |
commit | fed835890b5b4934a8011286e8a0ced955ca2ca7 (patch) | |
tree | 1749629de87784e2b7e035cc46675a43e27562e7 /sys | |
parent | 6dc1bedf87bfac8d15c8428b44c4f4d13643a16d (diff) |
New TGA driver for alpha. Takes advantage of rasops code.
This now gives a working console on alpha when using TGA.
Code from NetBSD.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/files.pci | 4 | ||||
-rw-r--r-- | sys/dev/pci/tga.c | 1565 | ||||
-rw-r--r-- | sys/dev/pci/tga_conf.c | 263 | ||||
-rw-r--r-- | sys/dev/pci/tgareg.h | 4 | ||||
-rw-r--r-- | sys/dev/pci/tgavar.h | 156 |
5 files changed, 1240 insertions, 752 deletions
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index e11fb3c216b..85f3feb9254 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $OpenBSD: files.pci,v 1.96 2001/03/07 23:59:02 mickey Exp $ +# $OpenBSD: files.pci,v 1.97 2001/03/18 04:37:20 nate Exp $ # $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $ # # Config file and device description for machine-independent PCI code. @@ -16,7 +16,7 @@ file dev/pci/pci_subr.c pci attach vga at pci with vga_pci file dev/pci/vga_pci.c vga_pci needs-flag -device tga: wsemuldisplaydev, wsrasteremulops +device tga: wsemuldisplaydev, rasops8, rasops32 attach tga at pci file dev/pci/tga.c tga needs-flag file dev/pci/tga_conf.c tga diff --git a/sys/dev/pci/tga.c b/sys/dev/pci/tga.c index f95c12018e4..3f0e5e3be8a 100644 --- a/sys/dev/pci/tga.c +++ b/sys/dev/pci/tga.c @@ -1,5 +1,5 @@ -/* $OpenBSD: tga.c,v 1.4 2001/02/01 18:06:35 art Exp $ */ -/* $NetBSD: tga.c,v 1.15 1999/12/06 19:25:59 drochner Exp $ */ +/* $OpenBSD: tga.c,v 1.5 2001/03/18 04:37:21 nate Exp $ */ +/* $NetBSD: tga.c,v 1.31 2001/02/11 19:34:58 nathanw Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -37,8 +37,6 @@ #include <sys/buf.h> #include <sys/ioctl.h> -#include <vm/vm.h> - #include <machine/bus.h> #include <machine/intr.h> @@ -49,11 +47,23 @@ #include <dev/pci/tgavar.h> #include <dev/ic/bt485reg.h> #include <dev/ic/bt485var.h> +#include <dev/ic/bt463reg.h> +#include <dev/ic/bt463var.h> -#include <dev/rcons/raster.h> #include <dev/wscons/wsconsio.h> #include <dev/wscons/wscons_raster.h> -#include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> +#include <dev/wsfont/wsfont.h> + +#include <vm/vm.h> +#include <uvm/uvm_extern.h> + +#ifdef __alpha__ +#include <machine/pte.h> +#endif +#ifdef __mips__ +#include <mips/pte.h> +#endif int tgamatch __P((struct device *, struct cfdata *, void *)); void tgaattach __P((struct device *, struct device *, void *)); @@ -67,10 +77,10 @@ struct cfattach tga_ca = { sizeof(struct tga_softc), (cfmatch_t)tgamatch, tgaattach, }; -int tga_identify __P((tga_reg_t *)); +int tga_identify __P((struct tga_devconfig *)); const struct tga_conf *tga_getconf __P((int)); -void tga_getdevconfig __P((bus_space_tag_t memt, pci_chipset_tag_t pc, - pcitag_t tag, struct tga_devconfig *dc)); +void tga_getdevconfig __P((bus_space_tag_t memt, pci_chipset_tag_t pc, + pcitag_t tag, struct tga_devconfig *dc)); struct tga_devconfig tga_console_dc; @@ -83,35 +93,42 @@ static int tga_alloc_screen __P((void *, const struct wsscreen_descr *, static void tga_free_screen __P((void *, void *)); static int tga_show_screen __P((void *, void *, int, void (*) (void *, int, int), void *)); -static int tga_rop __P((struct raster *, int, int, int, int, int, - struct raster *, int, int)); -static int tga_rop_nosrc __P((struct raster *, int, int, int, int, int)); -static int tga_rop_htov __P((struct raster *, int, int, int, int, - int, struct raster *, int, int )); -static int tga_rop_vtov __P((struct raster *, int, int, int, int, - int, struct raster *, int, int )); - +static int tga_rop __P((struct rasops_info *, int, int, int, int, int, + struct rasops_info *, int, int)); +static int tga_rop_vtov __P((struct rasops_info *, int, int, int, int, + int, struct rasops_info *, int, int )); +static void tga_putchar __P((void *c, int row, int col, + u_int uc, long attr)); +static void tga_eraserows __P((void *, int, int, long)); +static void tga_erasecols __P((void *, int, int, int, long)); void tga2_init __P((struct tga_devconfig *, int)); +void tga_config_interrupts __P((struct device *)); + /* RAMDAC interface functions */ -int tga_sched_update __P((void *, void (*)(void *))); -void tga_ramdac_wr __P((void *, u_int, u_int8_t)); -u_int8_t tga_ramdac_rd __P((void *, u_int)); -void tga2_ramdac_wr __P((void *, u_int, u_int8_t)); -u_int8_t tga2_ramdac_rd __P((void *, u_int)); +int tga_sched_update __P((void *, void (*)(void *))); +void tga_ramdac_wr __P((void *, u_int, u_int8_t)); +u_int8_t tga_ramdac_rd __P((void *, u_int)); +void tga_bt463_wr __P((void *, u_int, u_int8_t)); +u_int8_t tga_bt463_rd __P((void *, u_int)); +void tga2_ramdac_wr __P((void *, u_int, u_int8_t)); +u_int8_t tga2_ramdac_rd __P((void *, u_int)); /* Interrupt handler */ -int tga_intr __P((void *)); +int tga_intr __P((void *)); +/* The NULL entries will get filled in by rasops_init(). + * XXX and the non-NULL ones will be overwritten; reset after calling it. + */ struct wsdisplay_emulops tga_emulops = { - rcons_cursor, /* could use hardware cursor; punt */ - rcons_mapchar, - rcons_putchar, + NULL, + NULL, + tga_putchar, tga_copycols, - rcons_erasecols, + tga_erasecols, tga_copyrows, - rcons_eraserows, - rcons_alloc_attr + tga_eraserows, + NULL, }; struct wsscreen_descr tga_stdscreen = { @@ -143,6 +160,15 @@ struct wsdisplay_accessops tga_accessops = { void tga_blank __P((struct tga_devconfig *)); void tga_unblank __P((struct tga_devconfig *)); +#ifdef TGA_DEBUG +#define DPRINTF(...) printf (__VA_ARGS__) +#define DPRINTFN(n, ...) if (tgadebug > (n)) printf (__VA_ARGS__) +int tgadebug = 0; +#else +#define DPRINTF(...) +#define DPRINTFN(n,...) +#endif + int tgamatch(parent, match, aux) struct device *parent; @@ -152,16 +178,16 @@ tgamatch(parent, match, aux) struct pci_attach_args *pa = aux; if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_DEC) - return (0); - - switch (PCI_PRODUCT(pa->pa_id)) { - case PCI_PRODUCT_DEC_21030: - case PCI_PRODUCT_DEC_PBXGB: - return 10; - default: - return 0; - } - return (0); + return (0); + + switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_DEC_21030: + case PCI_PRODUCT_DEC_PBXGB: + return 10; + default: + return 0; + } + return (0); } void @@ -172,41 +198,55 @@ tga_getdevconfig(memt, pc, tag, dc) struct tga_devconfig *dc; { const struct tga_conf *tgac; - struct raster *rap; - struct rcons *rcp; + struct rasops_info *rip; + int cookie; bus_size_t pcisize; int i, cacheable; dc->dc_memt = memt; - dc->dc_pc = pc; dc->dc_pcitag = tag; + DPRINTF("tga_getdevconfig: Getting map info\n"); /* XXX magic number */ - pci_mem_find(pc, tag, 0x10, &dc->dc_pcipaddr, &pcisize, &cacheable); + if (pci_mapreg_info(pc, tag, 0x10, + PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, + &dc->dc_pcipaddr, &pcisize, &cacheable)) + return; if (!cacheable) panic("tga memory not cacheable"); - /* XXX XXX XXX */ - if ((i = bus_space_map(memt, dc->dc_pcipaddr, pcisize, 1, &dc->dc_vaddr))) { -printf("bus_space_map(%x, %x, %x, 0, %p): %d\n", memt, dc->dc_pcipaddr, pcisize, &dc->dc_vaddr, i); - DELAY(90000000); + DPRINTF("tga_getdevconfig: preparing to map\n"); +#ifdef __OpenBSD__ + if (bus_space_map(memt, dc->dc_pcipaddr, pcisize, 1, &dc->dc_memh)) return; - } + dc->dc_vaddr = dc->dc_memh; +#else + if (bus_space_map(memt, dc->dc_pcipaddr, pcisize, + BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, &dc->dc_memh)) + return; + dc->dc_vaddr = (vaddr_t) bus_space_vaddr(memt, dc->dc_memh); +#endif + DPRINTF("tga_getdevconfig: mapped\n"); + #ifdef __alpha__ dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */ -#else -#error "find a way to deal w/ paddr here" #endif +#ifdef arc + bus_space_paddr(memt, dc->dc_memh, &dc->dc_paddr); +#endif + DPRINTF("tga_getdevconfig: allocating subregion\n"); + bus_space_subregion(dc->dc_memt, dc->dc_memh, + TGA_MEM_CREGS, TGA_CREGS_SIZE, + &dc->dc_regs); - dc->dc_regs = (tga_reg_t *)(dc->dc_vaddr + TGA_MEM_CREGS); - dc->dc_tga_type = tga_identify(dc->dc_regs); + DPRINTF("tga_getdevconfig: going to identify\n"); + dc->dc_tga_type = tga_identify(dc); + DPRINTF("tga_getdevconfig: preparing to get config\n"); tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type); - if (tgac == NULL) { -printf("tgac==0\n"); + if (tgac == NULL) return; - } #if 0 /* XXX on the Alpha, pcisize = 4 * cspace_size. */ @@ -214,7 +254,8 @@ printf("tgac==0\n"); panic("tga_getdevconfig: memory size mismatch?"); #endif - switch (dc->dc_regs[TGA_REG_GREV] & 0xff) { + DPRINTF("tga_getdevconfig: get revno\n"); + switch (TGARREG(dc, TGA_REG_GREV) & 0xff) { case 0x01: case 0x02: case 0x03: @@ -231,13 +272,16 @@ printf("tgac==0\n"); } if (dc->dc_tga2) { - int monitor; + int monitor; - monitor = (~dc->dc_regs[TGA_REG_GREV] >> 16) & 0x0f; + monitor = (~TGARREG(dc, TGA_REG_GREV) >> 16) & 0x0f; + DPRINTF("tga_getdevconfig: tga2_init\n"); tga2_init(dc, monitor); } - - switch (dc->dc_regs[TGA_REG_VHCR] & 0x1ff) { /* XXX */ + + i = TGARREG(dc, TGA_REG_VHCR) & 0x1ff; + DPRINTF("tga_getdevconfig: TGA_REG_VHCR & 0x1ff = %d\n", i); + switch (i) { /* XXX */ case 0: dc->dc_wid = 8192; break; @@ -247,64 +291,115 @@ printf("tgac==0\n"); break; default: - dc->dc_wid = (dc->dc_regs[TGA_REG_VHCR] & 0x1ff) * 4; /* XXX */ + dc->dc_wid = (TGARREG(dc, TGA_REG_VHCR) & 0x1ff) * 4; /* XXX */ break; } - dc->dc_rowbytes = dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8); - - if ((dc->dc_regs[TGA_REG_VHCR] & 0x00000001) != 0 && /* XXX */ - (dc->dc_regs[TGA_REG_VHCR] & 0x80000000) != 0) { /* XXX */ + DPRINTF("tga_getdevconfig: dc->dc_wid = %d\n", dc->dc_wid); + /* + * XXX XXX Turning off "odd" shouldn't be necessary, + * XXX XXX but I can't make X work with the weird size. + */ + DPRINTF("tga_getdevconfig: beginning magic incantation\n"); + if ((TGARREG(dc, TGA_REG_VHCR) & 0x00000001) != 0 && /* XXX */ + (TGARREG(dc, TGA_REG_VHCR) & 0x80000000) != 0) { /* XXX */ + TGAWREG(dc, TGA_REG_VHCR, + (TGARREG(dc, TGA_REG_VHCR) & ~0x80000001)); dc->dc_wid -= 4; - /* - * XXX XXX turning off 'odd' shouldn't be necesssary, - * XXX XXX but i can't make X work with the weird size. - */ - dc->dc_regs[TGA_REG_VHCR] &= ~0x80000001; - dc->dc_rowbytes = - dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8); } - dc->dc_ht = (dc->dc_regs[TGA_REG_VVCR] & 0x7ff); /* XXX */ + dc->dc_rowbytes = dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8); + dc->dc_ht = (TGARREG(dc, TGA_REG_VVCR) & 0x7ff); /* XXX */ + DPRINTF("tga_getdevconfig: rowbytes = %d, tgac_phys_depth = %d\n" + " dc_wid = %d, dc_ht = %d\n", + dc->dc_rowbytes, dc->dc_tgaconf->tgac_phys_depth, + dc->dc_wid, dc->dc_ht); /* XXX this seems to be what DEC does */ - dc->dc_regs[TGA_REG_CCBR] = 0; - dc->dc_regs[TGA_REG_VVBR] = 1; + DPRINTF("tga_getdevconfig: more magic\n"); + TGAWREG(dc, TGA_REG_CCBR, 0); + TGAWREG(dc, TGA_REG_VVBR, 1); dc->dc_videobase = dc->dc_vaddr + tgac->tgac_dbuf[0] + 1 * tgac->tgac_vvbr_units; dc->dc_blanked = 1; tga_unblank(dc); + DPRINTF("tga_getdevconfig: dc_videobase = 0x%016llx\n" + " dc_vaddr = 0x%016llx\n" + " tgac_dbuf[0] = %d\n" + " tgac_vvbr_units = %d\n", + dc->dc_videobase, dc->dc_vaddr, tgac->tgac_dbuf[0], + tgac->tgac_vvbr_units); + /* * Set all bits in the pixel mask, to enable writes to all pixels. * It seems that the console firmware clears some of them * under some circumstances, which causes cute vertical stripes. */ - dc->dc_regs[TGA_REG_GPXR_P] = 0xffffffff; + DPRINTF("tga_getdevconfig: set pixel mask\n"); + TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff); /* clear the screen */ + DPRINTF("tga_getdevconfig: clear screen\n"); for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t)) *(u_int32_t *)(dc->dc_videobase + i) = 0; - /* initialize the raster */ - rap = &dc->dc_raster; - rap->width = dc->dc_wid; - rap->height = dc->dc_ht; - rap->depth = tgac->tgac_phys_depth; - rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t); - rap->pixels = (u_int32_t *)dc->dc_videobase; - rap->data = (caddr_t)dc; - - /* initialize the raster console blitter */ - rcp = &dc->dc_rcons; - rcp->rc_sp = rap; - rcp->rc_crow = rcp->rc_ccol = -1; - rcp->rc_crowp = &rcp->rc_crow; - rcp->rc_ccolp = &rcp->rc_ccol; - rcons_init(rcp, 34, 80); - - tga_stdscreen.nrows = dc->dc_rcons.rc_maxrow; - tga_stdscreen.ncols = dc->dc_rcons.rc_maxcol; + DPRINTF("tga_getdevconfig: raster ops\n"); + /* Initialize rasops descriptor */ + rip = &dc->dc_rinfo; + rip->ri_flg = RI_CENTER; + rip->ri_depth = tgac->tgac_phys_depth; + rip->ri_bits = (void *)dc->dc_videobase; + rip->ri_width = dc->dc_wid; + rip->ri_height = dc->dc_ht; + rip->ri_stride = dc->dc_rowbytes; + rip->ri_hw = dc; + + if (tgac->tgac_phys_depth == 32) { + rip->ri_rnum = 8; + rip->ri_gnum = 8; + rip->ri_bnum = 8; + rip->ri_rpos = 16; + rip->ri_gpos = 8; + rip->ri_bpos = 0; + } + + DPRINTF("tga_getdevconfig: wsfont_init\n"); + wsfont_init(); + /* prefer 8 pixel wide font */ + if ((cookie = wsfont_find(NULL, 8, 0, 0)) <= 0) + cookie = wsfont_find(NULL, 0, 0, 0); + if (cookie <= 0) { + printf("tga: no appropriate fonts.\n"); + return; + } + + /* the accelerated tga_putchar() needs LSbit left */ + if (wsfont_lock(cookie, &dc->dc_rinfo.ri_font, + WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0) { + printf("tga: couldn't lock font\n"); + return; + } + dc->dc_rinfo.ri_wsfcookie = cookie; + rasops_init(rip, 34, 80); + + /* add our accelerated functions */ + /* XXX shouldn't have to do this; rasops should leave non-NULL + * XXX entries alone. + */ + dc->dc_rinfo.ri_ops.copyrows = tga_copyrows; + dc->dc_rinfo.ri_ops.eraserows = tga_eraserows; + dc->dc_rinfo.ri_ops.erasecols = tga_erasecols; + dc->dc_rinfo.ri_ops.copycols = tga_copycols; + dc->dc_rinfo.ri_ops.putchar = tga_putchar; + + tga_stdscreen.nrows = dc->dc_rinfo.ri_rows; + tga_stdscreen.ncols = dc->dc_rinfo.ri_cols; + tga_stdscreen.textops = &dc->dc_rinfo.ri_ops; + tga_stdscreen.capabilities = dc->dc_rinfo.ri_caps; + + + dc->dc_intrenabled = 0; } void @@ -320,7 +415,7 @@ tgaattach(parent, self, aux) u_int8_t rev; int console; -#ifdef __alpha__ +#if defined(__alpha__) || defined(arc) console = (pa->pa_tag == tga_console_dc.dc_pcitag); #else console = 0; @@ -332,97 +427,126 @@ tgaattach(parent, self, aux) sc->sc_dc = (struct tga_devconfig *) malloc(sizeof(struct tga_devconfig), M_DEVBUF, M_WAITOK); bzero(sc->sc_dc, sizeof(struct tga_devconfig)); - tga_getdevconfig(pa->pa_memt, pa->pa_pc, pa->pa_tag, - sc->sc_dc); + tga_getdevconfig(pa->pa_memt, pa->pa_pc, pa->pa_tag, + sc->sc_dc); } if (sc->sc_dc->dc_vaddr == NULL) { printf(": couldn't map memory space; punt!\n"); return; } - /* XXX say what's going on. */ - intrstr = NULL; - if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, - pa->pa_intrline, &intrh)) { - printf(": couldn't map interrupt"); - return; - } - intrstr = pci_intr_string(pa->pa_pc, intrh); - sc->sc_intr = pci_intr_establish(pa->pa_pc, intrh, IPL_TTY, tga_intr, - sc->sc_dc, sc->sc_dev.dv_xname); - if (sc->sc_intr == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf("at %s", intrstr); - printf("\n"); - return; - } - - rev = PCI_REVISION(pa->pa_class); - switch (rev) { - case 0x1: - case 0x2: - case 0x3: - printf(": DC21030 step %c", 'A' + rev - 1); - break; - case 0x20: - printf(": TGA2 abstract software model"); - break; - case 0x21: + /* XXX say what's going on. */ + intrstr = NULL; + if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, + pa->pa_intrline, &intrh)) { + printf(": couldn't map interrupt"); + return; + } + intrstr = pci_intr_string(pa->pa_pc, intrh); + sc->sc_intr = pci_intr_establish(pa->pa_pc, intrh, IPL_TTY, tga_intr, + sc->sc_dc, sc->sc_dev.dv_xname); + if (sc->sc_intr == NULL) { + printf(": couldn't establish interrupt"); + if (intrstr != NULL) + printf("at %s", intrstr); + printf("\n"); + return; + } + + rev = PCI_REVISION(pa->pa_class); + switch (rev) { + case 0x1: + case 0x2: + case 0x3: + printf(": DC21030 step %c", 'A' + rev - 1); + break; + case 0x20: + printf(": TGA2 abstract software model"); + break; + case 0x21: case 0x22: - printf(": TGA2 pass %d", rev - 0x20); - break; - - default: - printf("unknown stepping (0x%x)", rev); - break; - } - printf(", "); - - /* - * Get RAMDAC function vectors and call the RAMDAC functions - * to allocate its private storage and pass that back to us. - */ - sc->sc_dc->dc_ramdac_funcs = bt485_funcs(); - if (!sc->sc_dc->dc_tga2) { - sc->sc_dc->dc_ramdac_cookie = bt485_register( - sc->sc_dc, tga_sched_update, tga_ramdac_wr, - tga_ramdac_rd); - } else { - sc->sc_dc->dc_ramdac_cookie = bt485_register( - sc->sc_dc, tga_sched_update, tga2_ramdac_wr, - tga2_ramdac_rd); - } - - /* - * Initialize the RAMDAC. Initialization includes disabling - * cursor, setting a sane colormap, etc. - */ - (*sc->sc_dc->dc_ramdac_funcs->ramdac_init)(sc->sc_dc->dc_ramdac_cookie); - sc->sc_dc->dc_regs[TGA_REG_SISR] = 0x00000001; /* XXX */ - - if (sc->sc_dc->dc_tgaconf == NULL) { - printf("unknown board configuration\n"); - return; - } - printf("board type %s\n", sc->sc_dc->dc_tgaconf->tgac_name); - printf("%s: %d x %d, %dbpp, %s RAMDAC\n", sc->sc_dev.dv_xname, - sc->sc_dc->dc_wid, sc->sc_dc->dc_ht, - sc->sc_dc->dc_tgaconf->tgac_phys_depth, - sc->sc_dc->dc_ramdac_funcs->ramdac_name); - - if (intrstr != NULL) - printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, - intrstr); - - aa.console = console; - aa.scrdata = &tga_screenlist; - aa.accessops = &tga_accessops; - aa.accesscookie = sc; - - config_found(self, &aa, wsemuldisplaydevprint); + printf(": TGA2 pass %d", rev - 0x20); + break; + + default: + printf("unknown stepping (0x%x)", rev); + break; + } + printf(", "); + + /* + * Get RAMDAC function vectors and call the RAMDAC functions + * to allocate its private storage and pass that back to us. + */ + + DPRINTF("tgaattach: Get RAMDAC functions\n"); + sc->sc_dc->dc_ramdac_funcs = sc->sc_dc->dc_tgaconf->ramdac_funcs(); + if (!sc->sc_dc->dc_tga2) { + DPRINTF("tgaattach: !sc->sc_dc->dc_tga2\n"); + DPRINTF("tgaattach: sc->sc_dc->dc_tgaconf->ramdac_funcs %s " + "bt485_funcs\n", + (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs) + ? "==" : "!="); + if (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs) + sc->sc_dc->dc_ramdac_cookie = + sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc, + tga_sched_update, tga_ramdac_wr, tga_ramdac_rd); + else + sc->sc_dc->dc_ramdac_cookie = + sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc, + tga_sched_update, tga_bt463_wr, tga_bt463_rd); + } else { + DPRINTF("tgaattach: sc->sc_dc->dc_tga2\n"); + sc->sc_dc->dc_ramdac_cookie = + sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc, + tga_sched_update, tga2_ramdac_wr, tga2_ramdac_rd); + } + + DPRINTF("tgaattach: sc->sc_dc->dc_ramdac_cookie = 0x%016llx\n", + sc->sc_dc->dc_ramdac_cookie); + /* + * Initialize the RAMDAC. Initialization includes disabling + * cursor, setting a sane colormap, etc. + */ + DPRINTF("tgaattach: Initializing RAMDAC.\n"); + (*sc->sc_dc->dc_ramdac_funcs->ramdac_init)(sc->sc_dc->dc_ramdac_cookie); + TGAWREG(sc->sc_dc, TGA_REG_SISR, 0x00000001); /* XXX */ + + if (sc->sc_dc->dc_tgaconf == NULL) { + printf("unknown board configuration\n"); + return; + } + printf("board type %s\n", sc->sc_dc->dc_tgaconf->tgac_name); + printf("%s: %d x %d, %dbpp, %s RAMDAC\n", sc->sc_dev.dv_xname, + sc->sc_dc->dc_wid, sc->sc_dc->dc_ht, + sc->sc_dc->dc_tgaconf->tgac_phys_depth, + sc->sc_dc->dc_ramdac_funcs->ramdac_name); + + if (intrstr != NULL) + printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, + intrstr); + + aa.console = console; + aa.scrdata = &tga_screenlist; + aa.accessops = &tga_accessops; + aa.accesscookie = sc; + + config_found(self, &aa, wsemuldisplaydevprint); + +#ifdef __NetBSD__ + config_interrupts(self, tga_config_interrupts); +#endif } +void +tga_config_interrupts (d) + struct device *d; +{ + struct tga_softc *sc = (struct tga_softc *)d; + sc->sc_dc->dc_intrenabled = 1; +} + + int tga_ioctl(v, cmd, data, flag, p) void *v; @@ -433,91 +557,121 @@ tga_ioctl(v, cmd, data, flag, p) { struct tga_softc *sc = v; struct tga_devconfig *dc = sc->sc_dc; - struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; - struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; - - switch (cmd) { - case WSDISPLAYIO_GTYPE: - *(u_int *)data = WSDISPLAY_TYPE_TGA; - return (0); - - case WSDISPLAYIO_GINFO: -#define wsd_fbip ((struct wsdisplay_fbinfo *)data) - wsd_fbip->height = sc->sc_dc->dc_ht; - wsd_fbip->width = sc->sc_dc->dc_wid; - wsd_fbip->depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth; - wsd_fbip->cmsize = 256; /* XXX ??? */ + struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; + struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; + + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_TGA; + return (0); + + case WSDISPLAYIO_GINFO: +#define wsd_fbip ((struct wsdisplay_fbinfo *)data) + wsd_fbip->height = sc->sc_dc->dc_ht; + wsd_fbip->width = sc->sc_dc->dc_wid; + wsd_fbip->depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth; + wsd_fbip->cmsize = 256; /* XXX ??? */ #undef wsd_fbip - return (0); - - case WSDISPLAYIO_GETCMAP: - return (*dcrf->ramdac_get_cmap)(dcrc, - (struct wsdisplay_cmap *)data); - - case WSDISPLAYIO_PUTCMAP: - return (*dcrf->ramdac_set_cmap)(dcrc, - (struct wsdisplay_cmap *)data); - - case WSDISPLAYIO_SVIDEO: - if (*(u_int *)data == WSDISPLAYIO_VIDEO_OFF) - tga_blank(sc->sc_dc); - else - tga_unblank(sc->sc_dc); - return (0); - - case WSDISPLAYIO_GVIDEO: - *(u_int *)data = dc->dc_blanked ? - WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON; - return (0); - - case WSDISPLAYIO_GCURPOS: - return (*dcrf->ramdac_get_curpos)(dcrc, - (struct wsdisplay_curpos *)data); - - case WSDISPLAYIO_SCURPOS: - return (*dcrf->ramdac_set_curpos)(dcrc, - (struct wsdisplay_curpos *)data); - - case WSDISPLAYIO_GCURMAX: - return (*dcrf->ramdac_get_curmax)(dcrc, - (struct wsdisplay_curpos *)data); - - case WSDISPLAYIO_GCURSOR: - return (*dcrf->ramdac_get_cursor)(dcrc, - (struct wsdisplay_cursor *)data); - - case WSDISPLAYIO_SCURSOR: - return (*dcrf->ramdac_set_cursor)(dcrc, - (struct wsdisplay_cursor *)data); - } - return (-1); + return (0); + + case WSDISPLAYIO_GETCMAP: + return (*dcrf->ramdac_get_cmap)(dcrc, + (struct wsdisplay_cmap *)data); + + case WSDISPLAYIO_PUTCMAP: + return (*dcrf->ramdac_set_cmap)(dcrc, + (struct wsdisplay_cmap *)data); + + case WSDISPLAYIO_SVIDEO: + if (*(u_int *)data == WSDISPLAYIO_VIDEO_OFF) + tga_blank(sc->sc_dc); + else + tga_unblank(sc->sc_dc); + return (0); + + case WSDISPLAYIO_GVIDEO: + *(u_int *)data = dc->dc_blanked ? + WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON; + return (0); + + case WSDISPLAYIO_GCURPOS: + return (*dcrf->ramdac_get_curpos)(dcrc, + (struct wsdisplay_curpos *)data); + + case WSDISPLAYIO_SCURPOS: + return (*dcrf->ramdac_set_curpos)(dcrc, + (struct wsdisplay_curpos *)data); + + case WSDISPLAYIO_GCURMAX: + return (*dcrf->ramdac_get_curmax)(dcrc, + (struct wsdisplay_curpos *)data); + + case WSDISPLAYIO_GCURSOR: + return (*dcrf->ramdac_get_cursor)(dcrc, + (struct wsdisplay_cursor *)data); + + case WSDISPLAYIO_SCURSOR: + return (*dcrf->ramdac_set_cursor)(dcrc, + (struct wsdisplay_cursor *)data); + } + return (-1); } int tga_sched_update(v, f) - void *v; - void (*f) __P((void *)); + void *v; + void (*f) __P((void *)); { - struct tga_devconfig *dc = v; + struct tga_devconfig *dc = v; - dc->dc_regs[TGA_REG_SISR] = 0x00010000; - dc->dc_ramdac_intr = f; - return 0; + if (dc->dc_intrenabled) { + /* Arrange for f to be called at the next end-of-frame interrupt */ + dc->dc_ramdac_intr = f; + TGAWREG(dc, TGA_REG_SISR, 0x00010000); + } else { + /* Spin until the end-of-frame, then call f */ + TGAWREG(dc, TGA_REG_SISR, 0x00010001); + TGAREGWB(dc, TGA_REG_SISR, 1); + while ((TGARREG(dc, TGA_REG_SISR) & 0x00000001) == 0) + ; + f(dc->dc_ramdac_cookie); + TGAWREG(dc, TGA_REG_SISR, 0x00000001); + TGAREGWB(dc, TGA_REG_SISR, 1); + } + + return 0; } int tga_intr(v) - void *v; + void *v; { - struct tga_devconfig *dc = v; - struct ramdac_cookie *dcrc= dc->dc_ramdac_cookie; - - if ((dc->dc_regs[TGA_REG_SISR] & 0x00010001) != 0x00010001) - return 0; - dc->dc_ramdac_intr(dcrc); - dc->dc_ramdac_intr = NULL; - dc->dc_regs[TGA_REG_SISR] = 0x00000001; - return (1); + struct tga_devconfig *dc = v; + struct ramdac_cookie *dcrc= dc->dc_ramdac_cookie; + + u_int32_t reg; + + reg = TGARREG(dc, TGA_REG_SISR); + if (( reg & 0x00010001) != 0x00010001) { + /* Odd. We never set any of the other interrupt enables. */ + if ((reg & 0x1f) != 0) { + /* Clear the mysterious pending interrupts. */ + TGAWREG(dc, TGA_REG_SISR, (reg & 0x1f)); + TGAREGWB(dc, TGA_REG_SISR, 1); + /* This was our interrupt, even if we're puzzled as to why + * we got it. Don't make the interrupt handler think it + * was a stray. + */ + return -1; + } else { + return 0; + } + } + dc->dc_ramdac_intr(dcrc); + dc->dc_ramdac_intr = NULL; + TGAWREG(dc, TGA_REG_SISR, 0x00000001); + TGAREGWB(dc, TGA_REG_SISR, 1); + return (1); } paddr_t @@ -529,12 +683,18 @@ tga_mmap(v, offset, prot) /* XXX NEW MAPPING CODE... */ -#ifdef __alpha__ +#if defined(__alpha__) struct tga_softc *sc = v; if (offset >= sc->sc_dc->dc_tgaconf->tgac_cspace_size || offset < 0) return -1; return alpha_btop(sc->sc_dc->dc_paddr + offset); +#elif defined(__mips__) + struct tga_softc *sc = v; + + if (offset >= sc->sc_dc->dc_tgaconf->tgac_cspace_size || offset < 0) + return -1; + return mips_btop(sc->sc_dc->dc_paddr + offset); #else return (-1); #endif @@ -554,10 +714,11 @@ tga_alloc_screen(v, type, cookiep, curxp, curyp, attrp) if (sc->nscreens > 0) return (ENOMEM); - *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */ + *cookiep = &sc->sc_dc->dc_rinfo; /* one and only for now */ *curxp = 0; *curyp = 0; - rcons_alloc_attr(&sc->sc_dc->dc_rcons, 0, 0, 0, &defattr); + sc->sc_dc->dc_rinfo.ri_ops.alloc_attr(&sc->sc_dc->dc_rinfo, + 0, 0, 0, &defattr); *attrp = defattr; sc->nscreens++; return (0); @@ -597,9 +758,8 @@ tga_cnattach(iot, memt, pc, bus, device, function) struct tga_devconfig *dcp = &tga_console_dc; long defattr; - /* XXX -- we know this isn't a TGA2 for now. rcd */ - tga_getdevconfig(memt, pc, - pci_make_tag(pc, bus, device, function), dcp); + tga_getdevconfig(memt, pc, + pci_make_tag(pc, bus, device, function), dcp); /* sanity checks */ if (dcp->dc_vaddr == NULL) @@ -614,22 +774,21 @@ tga_cnattach(iot, memt, pc, bus, device, function) * Initialization includes disabling cursor, setting a sane * colormap, etc. It will be reinitialized in tgaattach(). */ - - /* XXX -- this only works for bt485, but then we only support that, - * currently. - */ - if (dcp->dc_tga2) + if (dcp->dc_tga2) bt485_cninit(dcp, tga_sched_update, tga2_ramdac_wr, - tga2_ramdac_rd); - else - bt485_cninit(dcp, tga_sched_update, tga_ramdac_wr, - tga_ramdac_rd); - - rcons_alloc_attr(&dcp->dc_rcons, 0, 0, 0, &defattr); - - wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rcons, - 0, 0, defattr); - + tga2_ramdac_rd); + else { + if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs) + bt485_cninit(dcp, tga_sched_update, tga_ramdac_wr, + tga_ramdac_rd); + else { + bt463_cninit(dcp, tga_sched_update, tga_bt463_wr, + tga_bt463_rd); + } + } + dcp->dc_rinfo.ri_ops.alloc_attr(&dcp->dc_rinfo, 0, 0, 0, &defattr); + wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rinfo, 0, 0, defattr); + return(0); } @@ -643,7 +802,8 @@ tga_blank(dc) if (!dc->dc_blanked) { dc->dc_blanked = 1; - dc->dc_regs[TGA_REG_VVVR] |= VVR_BLANK; /* XXX */ + /* XXX */ + TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | VVR_BLANK); } } @@ -654,7 +814,8 @@ tga_unblank(dc) if (dc->dc_blanked) { dc->dc_blanked = 0; - dc->dc_regs[TGA_REG_VVVR] &= ~VVR_BLANK; /* XXX */ + /* XXX */ + TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~VVR_BLANK); } } @@ -666,8 +827,8 @@ tga_builtin_set_cursor(dc, cursorp) struct tga_devconfig *dc; struct wsdisplay_cursor *cursorp; { - struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; - struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; + struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; + struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; int count, error, v; v = cursorp->which; @@ -682,13 +843,8 @@ tga_builtin_set_cursor(dc, cursorp) return (EINVAL); /* The cursor is 2 bits deep, and there is no mask */ count = (cursorp->size.y * 64 * 2) / NBBY; -#if defined(UVM) if (!uvm_useracc(cursorp->image, count, B_READ)) return (EFAULT); -#else - if (!useracc(cursorp->image, count, B_READ)) - return (EFAULT); -#endif } if (v & WSDISPLAY_CURSOR_DOHOT) /* not supported */ return EINVAL; @@ -696,13 +852,15 @@ tga_builtin_set_cursor(dc, cursorp) /* parameters are OK; do it */ if (v & WSDISPLAY_CURSOR_DOCUR) { if (cursorp->enable) - dc->dc_regs[TGA_REG_VVVR] |= 0x04; /* XXX */ + /* XXX */ + TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 0x04); else - dc->dc_regs[TGA_REG_VVVR] &= ~0x04; /* XXX */ + /* XXX */ + TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~0x04); } if (v & WSDISPLAY_CURSOR_DOPOS) { - dc->dc_regs[TGA_REG_CXYR] = ((cursorp->pos.y & 0xfff) << 12) | - (cursorp->pos.x & 0xfff); + TGAWREG(dc, TGA_REG_CXYR, + ((cursorp->pos.y & 0xfff) << 12) | (cursorp->pos.x & 0xfff)); } if (v & WSDISPLAY_CURSOR_DOCMAP) { /* can't fail. */ @@ -710,11 +868,10 @@ tga_builtin_set_cursor(dc, cursorp) } if (v & WSDISPLAY_CURSOR_DOSHAPE) { count = ((64 * 2) / NBBY) * cursorp->size.y; - dc->dc_regs[TGA_REG_CCBR] = - (dc->dc_regs[TGA_REG_CCBR] & ~0xfc00) | - (cursorp->size.y << 10); + TGAWREG(dc, TGA_REG_CCBR, + (TGARREG(dc, TGA_REG_CCBR) & ~0xfc00) | (cursorp->size.y << 10)); copyin(cursorp->image, (char *)(dc->dc_vaddr + - (dc->dc_regs[TGA_REG_CCBR] & 0x3ff)), + (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)), count); /* can't fail. */ } return (0); @@ -725,29 +882,29 @@ tga_builtin_get_cursor(dc, cursorp) struct tga_devconfig *dc; struct wsdisplay_cursor *cursorp; { - struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; - struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; - int count, error; - - cursorp->which = WSDISPLAY_CURSOR_DOALL & - ~(WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCMAP); - cursorp->enable = (dc->dc_regs[TGA_REG_VVVR] & 0x04) != 0; - cursorp->pos.x = dc->dc_regs[TGA_REG_CXYR] & 0xfff; - cursorp->pos.y = (dc->dc_regs[TGA_REG_CXYR] >> 12) & 0xfff; - cursorp->size.x = 64; - cursorp->size.y = (dc->dc_regs[TGA_REG_CCBR] >> 10) & 0x3f; - - if (cursorp->image != NULL) { - count = (cursorp->size.y * 64 * 2) / NBBY; - error = copyout((char *)(dc->dc_vaddr + - (dc->dc_regs[TGA_REG_CCBR] & 0x3ff)), - cursorp->image, count); - if (error) - return (error); - /* No mask */ - } - error = dcrf->ramdac_get_curcmap(dcrc, cursorp); - return (error); + struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; + struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; + int count, error; + + cursorp->which = WSDISPLAY_CURSOR_DOALL & + ~(WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCMAP); + cursorp->enable = (TGARREG(dc, TGA_REG_VVVR) & 0x04) != 0; + cursorp->pos.x = TGARREG(dc, TGA_REG_CXYR) & 0xfff; + cursorp->pos.y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff; + cursorp->size.x = 64; + cursorp->size.y = (TGARREG(dc, TGA_REG_CCBR) >> 10) & 0x3f; + + if (cursorp->image != NULL) { + count = (cursorp->size.y * 64 * 2) / NBBY; + error = copyout((char *)(dc->dc_vaddr + + (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)), + cursorp->image, count); + if (error) + return (error); + /* No mask */ + } + error = dcrf->ramdac_get_curcmap(dcrc, cursorp); + return (error); } int @@ -756,8 +913,8 @@ tga_builtin_set_curpos(dc, curposp) struct wsdisplay_curpos *curposp; { - dc->dc_regs[TGA_REG_CXYR] = - ((curposp->y & 0xfff) << 12) | (curposp->x & 0xfff); + TGAWREG(dc, TGA_REG_CXYR, + ((curposp->y & 0xfff) << 12) | (curposp->x & 0xfff)); return (0); } @@ -767,8 +924,8 @@ tga_builtin_get_curpos(dc, curposp) struct wsdisplay_curpos *curposp; { - curposp->x = dc->dc_regs[TGA_REG_CXYR] & 0xfff; - curposp->y = (dc->dc_regs[TGA_REG_CXYR] >> 12) & 0xfff; + curposp->x = TGARREG(dc, TGA_REG_CXYR) & 0xfff; + curposp->y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff; return (0); } @@ -790,17 +947,17 @@ tga_copycols(id, row, srccol, dstcol, ncols) void *id; int row, srccol, dstcol, ncols; { - struct rcons *rc = id; + struct rasops_info *ri = id; int y, srcx, dstx, nx; - y = rc->rc_yorigin + rc->rc_font->height * row; - srcx = rc->rc_xorigin + rc->rc_font->width * srccol; - dstx = rc->rc_xorigin + rc->rc_font->width * dstcol; - nx = rc->rc_font->width * ncols; + y = ri->ri_font->fontheight * row; + srcx = ri->ri_font->fontwidth * srccol; + dstx = ri->ri_font->fontwidth * dstcol; + nx = ri->ri_font->fontwidth * ncols; - tga_rop(rc->rc_sp, dstx, y, - nx, rc->rc_font->height, RAS_SRC, - rc->rc_sp, srcx, y); + tga_rop(ri, dstx, y, + nx, ri->ri_font->fontheight, RAS_SRC, + ri, srcx, y); } /* @@ -811,23 +968,23 @@ tga_copyrows(id, srcrow, dstrow, nrows) void *id; int srcrow, dstrow, nrows; { - struct rcons *rc = id; + struct rasops_info *ri = id; int srcy, dsty, ny; - srcy = rc->rc_yorigin + rc->rc_font->height * srcrow; - dsty = rc->rc_yorigin + rc->rc_font->height * dstrow; - ny = rc->rc_font->height * nrows; + srcy = ri->ri_font->fontheight * srcrow; + dsty = ri->ri_font->fontheight * dstrow; + ny = ri->ri_font->fontheight * nrows; - tga_rop(rc->rc_sp, rc->rc_xorigin, dsty, - rc->rc_raswidth, ny, RAS_SRC, - rc->rc_sp, rc->rc_xorigin, srcy); + tga_rop(ri, 0, dsty, + ri->ri_emuwidth, ny, RAS_SRC, + ri, 0, srcy); } /* Do we need the src? */ -static int needsrc[16] = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0 }; +int needsrc[16] = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0 }; /* A mapping between our API and the TGA card */ -static int map_rop[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, +int map_rop[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf }; @@ -836,19 +993,17 @@ static int map_rop[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, * This covers all possible raster ops, and * clips the sizes and all of that. */ -static int +int tga_rop(dst, dx, dy, w, h, rop, src, sx, sy) - struct raster *dst; + struct rasops_info *dst; int dx, dy, w, h, rop; - struct raster *src; + struct rasops_info *src; int sx, sy; { if (!dst) return -1; - if (dst->data == NULL) - return -1; /* we should be writing to a screen */ if (needsrc[RAS_GETOP(rop)]) { - if (src == (struct raster *) 0) + if (src == NULL) return -1; /* We want a src */ /* Clip against src */ if (sx < 0) { @@ -859,12 +1014,12 @@ tga_rop(dst, dx, dy, w, h, rop, src, sx, sy) h += sy; sy = 0; } - if (sx + w > src->width) - w = src->width - sx; - if (sy + h > src->height) - h = src->height - sy; + if (sx + w > src->ri_emuwidth) + w = src->ri_emuwidth - sx; + if (sy + h > src->ri_emuheight) + h = src->ri_emuheight - sy; } else { - if (src != (struct raster *) 0) + if (src != NULL) return -1; /* We need no src */ } /* Clip against dst. We modify src regardless of using it, @@ -880,76 +1035,54 @@ tga_rop(dst, dx, dy, w, h, rop, src, sx, sy) sy -= dy; dy = 0; } - if (dx + w > dst->width) - w = dst->width - dx; - if (dy + h > dst->height) - h = dst->height - dy; + if (dx + w > dst->ri_emuwidth) + w = dst->ri_emuwidth - dx; + if (dy + h > dst->ri_emuheight) + h = dst->ri_emuheight - dy; if (w <= 0 || h <= 0) return 0; /* Vacuously true; */ - if (!src) - return tga_rop_nosrc(dst, dx, dy, w, h, rop); - if (src->data == NULL) - return tga_rop_htov(dst, dx, dy, w, h, rop, src, sx, sy); - else - return tga_rop_vtov(dst, dx, dy, w, h, rop, src, sx, sy); + if (!src) { + /* XXX Punt! */ + return -1; + } + return tga_rop_vtov(dst, dx, dy, w, h, rop, src, sx, sy); } -/* - * No source raster ops. - * This function deals with all raster ops that don't require a src. - */ -static int -tga_rop_nosrc(dst, dx, dy, w, h, rop) - struct raster *dst; - int dx, dy, w, h, rop; -{ - return raster_op(dst, dx, dy, w, h, rop, NULL, 0, 0); -} -/* - * Host to Video raster ops. - * This function deals with all raster ops that have a src that is host memory. - */ -static int -tga_rop_htov(dst, dx, dy, w, h, rop, src, sx, sy) - struct raster *dst; - int dx, dy, w, h, rop; - struct raster *src; - int sx, sy; -{ - return raster_op(dst, dx, dy, w, h, rop, src, sx, sy); -} /* * Video to Video raster ops. * This function deals with all raster ops that have a src and dst * that are on the card. */ -static int +int tga_rop_vtov(dst, dx, dy, w, h, rop, src, sx, sy) - struct raster *dst; + struct rasops_info *dst; int dx, dy, w, h, rop; - struct raster *src; + struct rasops_info *src; int sx, sy; { - struct tga_devconfig *dc = (struct tga_devconfig *)dst->data; - tga_reg_t *regs0 = dc->dc_regs; - tga_reg_t *regs1 = regs0 + 16 * 1024; /* register alias 1 */ - tga_reg_t *regs2 = regs1 + 16 * 1024; /* register alias 2 */ - tga_reg_t *regs3 = regs2 + 16 * 1024; /* register alias 3 */ - int srcb, dstb; - int x, y; - int xstart, xend, xdir, xinc; + struct tga_devconfig *dc = (struct tga_devconfig *)dst->ri_hw; + int srcb, dstb, tga_srcb, tga_dstb; + int x, y, wb; + int xstart, xend, xdir; int ystart, yend, ydir, yinc; + int xleft, lastx, lastleft; int offset = 1 * dc->dc_tgaconf->tgac_vvbr_units; /* * I don't yet want to deal with unaligned guys, really. And we don't * deal with copies from one card to another. */ - if (dx % 8 != 0 || sx % 8 != 0 || src != dst) - return raster_op(dst, dx, dy, w, h, rop, src, sx, sy); + if (dx % 8 != 0 || sx % 8 != 0 || src != dst) { + /* XXX Punt! */ + /* XXX should never happen, since it's only being used to + * XXX copy 8-pixel-wide characters. + */ + return -1; + } + wb = w * (dst->ri_depth / 8); if (sy >= dy) { ystart = 0; yend = h; @@ -959,226 +1092,542 @@ tga_rop_vtov(dst, dx, dy, w, h, rop, src, sx, sy) yend = 0; ydir = -1; } - if (sx >= dx) { + if (sx >= dx) { /* moving to the left */ xstart = 0; - xend = w * (dst->depth / 8); + xend = w * (dst->ri_depth / 8) - 4; xdir = 1; - } else { - xstart = w * (dst->depth / 8); + } else { /* moving to the right */ + xstart = wb - ( wb >= 4*64 ? 4*64 : wb >= 64 ? 64 : 4 ); xend = 0; xdir = -1; } - xinc = xdir * 4 * 64; - yinc = ydir * dst->linelongs * 4; - ystart *= dst->linelongs * 4; - yend *= dst->linelongs * 4; - srcb = offset + sy * src->linelongs * 4 + sx; - dstb = offset + dy * dst->linelongs * 4 + dx; - regs3[TGA_REG_GMOR] = 0x0007; /* Copy mode */ - regs3[TGA_REG_GOPR] = map_rop[rop]; /* Set up the op */ - for (y = ystart; (ydir * y) < (ydir * yend); y += yinc) { - for (x = xstart; (xdir * x) < (xdir * xend); x += xinc) { - regs0[TGA_REG_GCSR] = srcb + y + x + 3 * 64; - regs0[TGA_REG_GCDR] = dstb + y + x + 3 * 64; - regs1[TGA_REG_GCSR] = srcb + y + x + 2 * 64; - regs1[TGA_REG_GCDR] = dstb + y + x + 2 * 64; - regs2[TGA_REG_GCSR] = srcb + y + x + 1 * 64; - regs2[TGA_REG_GCDR] = dstb + y + x + 1 * 64; - regs3[TGA_REG_GCSR] = srcb + y + x + 0 * 64; - regs3[TGA_REG_GCDR] = dstb + y + x + 0 * 64; +#define XINC4 4 +#define XINC64 64 +#define XINC256 (64*4) + yinc = ydir * dst->ri_stride; + ystart *= dst->ri_stride; + yend *= dst->ri_stride; + + srcb = sy * src->ri_stride + sx * (src->ri_depth/8); + dstb = dy * dst->ri_stride + dx * (dst->ri_depth/8); + tga_srcb = offset + (sy + src->ri_yorigin) * src->ri_stride + + (sx + src->ri_xorigin) * (src->ri_depth/8); + tga_dstb = offset + (dy + dst->ri_yorigin) * dst->ri_stride + + (dx + dst->ri_xorigin) * (dst->ri_depth/8); + + TGAWALREG(dc, TGA_REG_GMOR, 3, 0x0007); /* Copy mode */ + TGAWALREG(dc, TGA_REG_GOPR, 3, map_rop[rop]); /* Set up the op */ + + /* + * we have 3 sizes of pixels to move in X direction: + * 4 * 64 (unrolled TGA ops) + * 64 (single TGA op) + * 4 (CPU, using long word) + */ + + if (xdir == 1) { /* move to the left */ + + for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) { + + /* 4*64 byte chunks */ + for (xleft = wb, x = xstart; + x <= xend && xleft >= 4*64; + x += XINC256, xleft -= XINC256) { + + /* XXX XXX Eight writes to different addresses should fill + * XXX XXX up the write buffers on 21064 and 21164 chips, + * XXX XXX but later CPUs might have larger write buffers which + * XXX XXX require further unrolling of this loop, or the + * XXX XXX insertion of memory barriers. + */ + TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64); + TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 1 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 1 * 64); + TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 2 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 2 * 64); + TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 3 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 3 * 64); + } + + /* 64 byte chunks */ + for ( ; x <= xend && xleft >= 64; + x += XINC64, xleft -= XINC64) { + TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64); + } + lastx = x; lastleft = xleft; /* remember for CPU loop */ + + } + TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */ + TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */ + + for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) { + /* 4 byte granularity */ + for (x = lastx, xleft = lastleft; + x <= xend && xleft >= 4; + x += XINC4, xleft -= XINC4) { + *(uint32_t *)(dst->ri_bits + dstb + y + x) = + *(uint32_t *)(dst->ri_bits + srcb + y + x); + } + } + } + else { /* above move to the left, below move to the right */ + + for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) { + + /* 4*64 byte chunks */ + for (xleft = wb, x = xstart; + x >= xend && xleft >= 4*64; + x -= XINC256, xleft -= XINC256) { + + /* XXX XXX Eight writes to different addresses should fill + * XXX XXX up the write buffers on 21064 and 21164 chips, + * XXX XXX but later CPUs might have larger write buffers which + * XXX XXX require further unrolling of this loop, or the + * XXX XXX insertion of memory barriers. + */ + TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 3 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 3 * 64); + TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 2 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 2 * 64); + TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 1 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 1 * 64); + TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 0 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 0 * 64); + } + + if (xleft) x += XINC256 - XINC64; + + /* 64 byte chunks */ + for ( ; x >= xend && xleft >= 64; + x -= XINC64, xleft -= XINC64) { + TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64); + TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64); + } + if (xleft) x += XINC64 - XINC4; + lastx = x; lastleft = xleft; /* remember for CPU loop */ + } + TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */ + TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */ + + for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) { + /* 4 byte granularity */ + for (x = lastx, xleft = lastleft; + x >= xend && xleft >= 4; + x -= XINC4, xleft -= XINC4) { + *(uint32_t *)(dst->ri_bits + dstb + y + x) = + *(uint32_t *)(dst->ri_bits + srcb + y + x); + } } } - regs0[TGA_REG_GOPR] = 0x0003; /* op -> dst = src */ - regs0[TGA_REG_GMOR] = 0x0000; /* Simple mode */ return 0; } + +void tga_putchar (c, row, col, uc, attr) + void *c; + int row, col; + u_int uc; + long attr; +{ + struct rasops_info *ri = c; + struct tga_devconfig *dc = ri->ri_hw; + int fs, height, width; + u_char *fr; + int32_t *rp; + + rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); + + height = ri->ri_font->fontheight; + width = ri->ri_font->fontwidth; + + uc -= ri->ri_font->firstchar; + fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale; + fs = ri->ri_font->stride; + + /* Set foreground and background color. XXX memoize this somehow? + * The rasops code has already expanded the color entry to 32 bits + * for us, even for 8-bit displays, so we don't have to do anything. + */ + TGAWREG(dc, TGA_REG_GFGR, ri->ri_devcmap[(attr >> 24) & 15]); + TGAWREG(dc, TGA_REG_GBGR, ri->ri_devcmap[(attr >> 16) & 15]); + + /* Set raster operation to "copy"... */ + if (ri->ri_depth == 8) + TGAWREG(dc, TGA_REG_GOPR, 0x3); + else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */ + TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8)); + + /* Set which pixels we're drawing (of a possible 32). */ + TGAWREG(dc, TGA_REG_GPXR_P, (1 << width) - 1); + + /* Set drawing mode to opaque stipple. */ + TGAWREG(dc, TGA_REG_GMOR, 0x1); + + /* Insert write barrier before actually sending data */ + /* XXX Abuses the fact that there is only one write barrier on Alphas */ + TGAREGWB(dc, TGA_REG_GMOR, 1); + + while(height--) { + /* The actual stipple write */ + *rp = fr[0] | (fr[1] << 8) | (fr[2] << 16) | (fr[3] << 24); + + fr += fs; + rp = (int32_t *)((caddr_t)rp + ri->ri_stride); + } + + /* Do underline */ + if ((attr & 1) != 0) { + rp = (int32_t *)((caddr_t)rp - (ri->ri_stride << 1)); + *rp = 0xffffffff; + } + + /* Set grapics mode back to normal. */ + TGAWREG(dc, TGA_REG_GMOR, 0); + TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff); + +} + +void +tga_eraserows(c, row, num, attr) + void *c; + int row, num; + long attr; +{ + struct rasops_info *ri = c; + struct tga_devconfig *dc = ri->ri_hw; + int32_t color, lines, pixels; + int32_t *rp; + + color = ri->ri_devcmap[(attr >> 16) & 15]; + rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale); + lines = num * ri->ri_font->fontheight; + pixels = ri->ri_emuwidth - 1; + + /* Set fill color in block-color registers */ + TGAWREG(dc, TGA_REG_GBCR0, color); + TGAWREG(dc, TGA_REG_GBCR1, color); + if (ri->ri_depth != 8) { + TGAWREG(dc, TGA_REG_GBCR2, color); + TGAWREG(dc, TGA_REG_GBCR3, color); + TGAWREG(dc, TGA_REG_GBCR4, color); + TGAWREG(dc, TGA_REG_GBCR5, color); + TGAWREG(dc, TGA_REG_GBCR6, color); + TGAWREG(dc, TGA_REG_GBCR7, color); + } + + /* Set raster operation to "copy"... */ + if (ri->ri_depth == 8) + TGAWREG(dc, TGA_REG_GOPR, 0x3); + else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */ + TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8)); + + /* Set which pixels we're drawing (of a possible 32). */ + TGAWREG(dc, TGA_REG_GDAR, 0xffffffff); + + /* Set drawing mode to block fill. */ + TGAWREG(dc, TGA_REG_GMOR, 0x2d); + + /* Insert write barrier before actually sending data */ + /* XXX Abuses the fact that there is only one write barrier on Alphas */ + TGAREGWB(dc, TGA_REG_GMOR, 1); + + while (lines--) { + *rp = pixels; + rp = (int32_t *)((caddr_t)rp + ri->ri_stride); + } + + /* Set grapics mode back to normal. */ + TGAWREG(dc, TGA_REG_GMOR, 0); + +} + +void +tga_erasecols (c, row, col, num, attr) +void *c; +int row, col, num; +long attr; +{ + struct rasops_info *ri = c; + struct tga_devconfig *dc = ri->ri_hw; + int32_t color, lines, pixels; + int32_t *rp; + + color = ri->ri_devcmap[(attr >> 16) & 15]; + rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); + lines = ri->ri_font->fontheight; + pixels = (num * ri->ri_font->fontwidth) - 1; + + /* Set fill color in block-color registers */ + TGAWREG(dc, TGA_REG_GBCR0, color); + TGAWREG(dc, TGA_REG_GBCR1, color); + if (ri->ri_depth != 8) { + TGAWREG(dc, TGA_REG_GBCR2, color); + TGAWREG(dc, TGA_REG_GBCR3, color); + TGAWREG(dc, TGA_REG_GBCR4, color); + TGAWREG(dc, TGA_REG_GBCR5, color); + TGAWREG(dc, TGA_REG_GBCR6, color); + TGAWREG(dc, TGA_REG_GBCR7, color); + } + + /* Set raster operation to "copy"... */ + if (ri->ri_depth == 8) + TGAWREG(dc, TGA_REG_GOPR, 0x3); + else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */ + TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8)); + + /* Set which pixels we're drawing (of a possible 32). */ + TGAWREG(dc, TGA_REG_GDAR, 0xffffffff); + + /* Set drawing mode to block fill. */ + TGAWREG(dc, TGA_REG_GMOR, 0x2d); + + /* Insert write barrier before actually sending data */ + /* XXX Abuses the fact that there is only one write barrier on Alphas */ + TGAREGWB(dc, TGA_REG_GMOR, 1); + + while (lines--) { + *rp = pixels; + rp = (int32_t *)((caddr_t)rp + ri->ri_stride); + } + + /* Set grapics mode back to normal. */ + TGAWREG(dc, TGA_REG_GMOR, 0); +} + + void tga_ramdac_wr(v, btreg, val) - void *v; - u_int btreg; - u_int8_t val; + void *v; + u_int btreg; + u_int8_t val; { - struct tga_devconfig *dc = v; - volatile tga_reg_t *tgaregs = dc->dc_regs; + struct tga_devconfig *dc = v; - if (btreg > BT485_REG_MAX) - panic("tga_ramdac_wr: reg %d out of range\n", btreg); + if (btreg > BT485_REG_MAX) + panic("tga_ramdac_wr: reg %d out of range\n", btreg); - tgaregs[TGA_REG_EPDR] = (btreg << 9) | (0 << 8 ) | val; /* XXX */ -#ifdef __alpha__ - alpha_mb(); -#endif + TGAWREG(dc, TGA_REG_EPDR, (btreg << 9) | (0 << 8 ) | val); /* XXX */ + TGAREGWB(dc, TGA_REG_EPDR, 1); } void tga2_ramdac_wr(v, btreg, val) - void *v; - u_int btreg; - u_int8_t val; + void *v; + u_int btreg; + u_int8_t val; { - struct tga_devconfig *dc = v; - volatile tga_reg_t *ramdac; + struct tga_devconfig *dc = v; + bus_space_handle_t ramdac; - if (btreg > BT485_REG_MAX) - panic("tga_ramdac_wr: reg %d out of range\n", btreg); + if (btreg > BT485_REG_MAX) + panic("tga_ramdac_wr: reg %d out of range\n", btreg); - ramdac = (tga_reg_t *)(dc->dc_vaddr + TGA2_MEM_RAMDAC + - (0xe << 12) + (btreg << 8)); - *ramdac = val & 0xff; -#ifdef __alpha__ - alpha_mb(); -#endif + bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC + + (0xe << 12) + (btreg << 8), 4, &ramdac); + bus_space_write_4(dc->dc_memt, ramdac, 0, val & 0xff); + bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_WRITE); } u_int8_t -tga_ramdac_rd(v, btreg) - void *v; - u_int btreg; +tga_bt463_rd(v, btreg) + void *v; + u_int btreg; { - struct tga_devconfig *dc = v; - volatile tga_reg_t *tgaregs = dc->dc_regs; - tga_reg_t rdval; + struct tga_devconfig *dc = v; + tga_reg_t rdval; - if (btreg > BT485_REG_MAX) - panic("tga_ramdac_rd: reg %d out of range\n", btreg); + /* + * Strobe CE# (high->low->high) since status and data are latched on + * the falling and rising edges (repsectively) of this active-low signal. + */ + + TGAREGWB(dc, TGA_REG_EPSR, 1); + TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1); + TGAREGWB(dc, TGA_REG_EPSR, 1); + TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 0); - tgaregs[TGA_REG_EPSR] = (btreg << 1) | 0x1; /* XXX */ -#ifdef __alpha__ - alpha_mb(); -#endif + TGAREGRB(dc, TGA_REG_EPSR, 1); + + rdval = TGARREG(dc, TGA_REG_EPDR); + TGAREGWB(dc, TGA_REG_EPSR, 1); + TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1); + + return (rdval >> 16) & 0xff; +} + +void +tga_bt463_wr(v, btreg, val) + void *v; + u_int btreg; + u_int8_t val; +{ + struct tga_devconfig *dc = v; + + /* + * In spite of the 21030 documentation, to set the MPU bus bits for + * a write, you set them in the upper bits of EPDR, not EPSR. + */ + + /* + * Strobe CE# (high->low->high) since status and data are latched on + * the falling and rising edges of this active-low signal. + */ + + TGAREGWB(dc, TGA_REG_EPDR, 1); + TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val); + TGAREGWB(dc, TGA_REG_EPDR, 1); + TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x000 | val); + TGAREGWB(dc, TGA_REG_EPDR, 1); + TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val); - rdval = tgaregs[TGA_REG_EPDR]; - return (rdval >> 16) & 0xff; /* XXX */ } u_int8_t -tga2_ramdac_rd(v, btreg) - void *v; - u_int btreg; +tga_ramdac_rd(v, btreg) + void *v; + u_int btreg; { - struct tga_devconfig *dc = v; - volatile tga_reg_t *ramdac; - u_int8_t retval; + struct tga_devconfig *dc = v; + tga_reg_t rdval; - if (btreg > BT485_REG_MAX) - panic("tga_ramdac_rd: reg %d out of range\n", btreg); + if (btreg > BT485_REG_MAX) + panic("tga_ramdac_rd: reg %d out of range\n", btreg); - ramdac = (tga_reg_t *)(dc->dc_vaddr + TGA2_MEM_RAMDAC + - (0xe << 12) + (btreg << 8)); - retval = (u_int8_t)(*ramdac & 0xff); -#ifdef __alpha__ - alpha_mb(); -#endif - return retval; + TGAWREG(dc, TGA_REG_EPSR, (btreg << 1) | 0x1); /* XXX */ + TGAREGWB(dc, TGA_REG_EPSR, 1); + + rdval = TGARREG(dc, TGA_REG_EPDR); + return (rdval >> 16) & 0xff; /* XXX */ +} + +u_int8_t +tga2_ramdac_rd(v, btreg) + void *v; + u_int btreg; +{ + struct tga_devconfig *dc = v; + bus_space_handle_t ramdac; + u_int8_t retval; + + if (btreg > BT485_REG_MAX) + panic("tga_ramdac_rd: reg %d out of range\n", btreg); + + bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC + + (0xe << 12) + (btreg << 8), 4, &ramdac); + retval = bus_space_read_4(dc->dc_memt, ramdac, 0) & 0xff; + bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_READ); + return retval; } #include <dev/ic/decmonitors.c> void tga2_ics9110_wr __P(( - struct tga_devconfig *dc, - int dotclock + struct tga_devconfig *dc, + int dotclock )); void tga2_init(dc, m) - struct tga_devconfig *dc; - int m; + struct tga_devconfig *dc; + int m; { - tga2_ics9110_wr(dc, decmonitors[m].dotclock); - dc->dc_regs[TGA_REG_VHCR] = - ((decmonitors[m].hbp / 4) << 21) | - ((decmonitors[m].hsync / 4) << 14) | + tga2_ics9110_wr(dc, decmonitors[m].dotclock); #if 0 - (((decmonitors[m].hfp - 4) / 4) << 9) | - ((decmonitors[m].cols + 4) / 4); + TGAWREG(dc, TGA_REG_VHCR, + ((decmonitors[m].hbp / 4) << 21) | + ((decmonitors[m].hsync / 4) << 14) | + (((decmonitors[m].hfp - 4) / 4) << 9) | + ((decmonitors[m].cols + 4) / 4)); #else - (((decmonitors[m].hfp) / 4) << 9) | - ((decmonitors[m].cols) / 4); + TGAWREG(dc, TGA_REG_VHCR, + ((decmonitors[m].hbp / 4) << 21) | + ((decmonitors[m].hsync / 4) << 14) | + (((decmonitors[m].hfp) / 4) << 9) | + ((decmonitors[m].cols) / 4)); #endif - dc->dc_regs[TGA_REG_VVCR] = - (decmonitors[m].vbp << 22) | - (decmonitors[m].vsync << 16) | - (decmonitors[m].vfp << 11) | - (decmonitors[m].rows); - dc->dc_regs[TGA_REG_VVBR] = 1; alpha_mb(); - dc->dc_regs[TGA_REG_VVVR] |= 1; alpha_mb(); - dc->dc_regs[TGA_REG_GPMR] = 0xffffffff; alpha_mb(); + TGAWREG(dc, TGA_REG_VVCR, + (decmonitors[m].vbp << 22) | + (decmonitors[m].vsync << 16) | + (decmonitors[m].vfp << 11) | + (decmonitors[m].rows)); + TGAWREG(dc, TGA_REG_VVBR, 1); + TGAREGRWB(dc, TGA_REG_VHCR, 3); + TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 1); + TGAREGRWB(dc, TGA_REG_VVVR, 1); + TGAWREG(dc, TGA_REG_GPMR, 0xffffffff); + TGAREGRWB(dc, TGA_REG_GPMR, 1); } void tga2_ics9110_wr(dc, dotclock) - struct tga_devconfig *dc; - int dotclock; + struct tga_devconfig *dc; + int dotclock; { - volatile tga_reg_t *clock; - u_int32_t valU; - int N, M, R, V, X; - int i; - - switch (dotclock) { - case 130808000: - N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break; - case 119840000: - N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break; - case 108180000: - N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break; - case 103994000: - N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break; - case 175000000: - N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break; - case 75000000: - N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break; - case 74000000: - N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break; - case 69000000: - N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break; - case 65000000: - N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break; - case 50000000: - N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break; - case 40000000: - N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break; - case 31500000: - N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break; - case 25175000: - N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break; - case 135000000: - N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break; - case 110000000: - N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break; - case 202500000: - N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break; - default: - panic("unrecognized clock rate %d\n", dotclock); - } - - /* XXX -- hard coded, bad */ - valU = N | ( M << 7 ) | (V << 14); - valU |= (X << 15) | (R << 17); - valU |= 0x17 << 19; - - - clock = (tga_reg_t *)(dc->dc_vaddr + TGA2_MEM_EXTDEV + - TGA2_MEM_CLOCK + (0xe << 12)); /* XXX */ - - for (i=24; i>0; i--) { - u_int32_t writeval; + bus_space_handle_t clock; + u_int32_t valU; + int N, M, R, V, X; + int i; + + switch (dotclock) { + case 130808000: + N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break; + case 119840000: + N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break; + case 108180000: + N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break; + case 103994000: + N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break; + case 175000000: + N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break; + case 75000000: + N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break; + case 74000000: + N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break; + case 69000000: + N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break; + case 65000000: + N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break; + case 50000000: + N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break; + case 40000000: + N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break; + case 31500000: + N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break; + case 25175000: + N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break; + case 135000000: + N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break; + case 110000000: + N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break; + case 202500000: + N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break; + default: + panic("unrecognized clock rate %d\n", dotclock); + } + + /* XXX -- hard coded, bad */ + valU = N | ( M << 7 ) | (V << 14); + valU |= (X << 15) | (R << 17); + valU |= 0x17 << 19; + + bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV + + TGA2_MEM_CLOCK + (0xe << 12), 4, &clock); /* XXX */ + + for (i=24; i>0; i--) { + u_int32_t writeval; - writeval = valU & 0x1; - if (i == 1) - writeval |= 0x2; - valU >>= 1; - *clock = writeval; -#ifdef __alpha__ - alpha_mb(); -#endif + writeval = valU & 0x1; + if (i == 1) + writeval |= 0x2; + valU >>= 1; + bus_space_write_4(dc->dc_memt, clock, 0, writeval); + bus_space_barrier(dc->dc_memt, clock, 0, 4, BUS_SPACE_BARRIER_WRITE); } - clock = (tga_reg_t *)(dc->dc_vaddr + TGA2_MEM_EXTDEV + - TGA2_MEM_CLOCK + (0xe << 12) + (0x1 << 11)); /* XXX */ - clock += 0x1 << 9; - *clock = 0x0; -#ifdef __alpha__ - alpha_mb(); -#endif + bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV + + TGA2_MEM_CLOCK + (0xe << 12) + (0x1 << 11) + (0x1 << 11), 4, + &clock); /* XXX */ + bus_space_write_4(dc->dc_memt, clock, 0, 0x0); + bus_space_barrier(dc->dc_memt, clock, 0, 0, BUS_SPACE_BARRIER_WRITE); } diff --git a/sys/dev/pci/tga_conf.c b/sys/dev/pci/tga_conf.c index 3fa75ee9df8..7834a9f05fa 100644 --- a/sys/dev/pci/tga_conf.c +++ b/sys/dev/pci/tga_conf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: tga_conf.c,v 1.3 2000/10/14 18:04:07 aaron Exp $ */ -/* $NetBSD: tga_conf.c,v 1.4 2000/04/02 18:59:32 nathanw Exp $ */ +/* $OpenBSD: tga_conf.c,v 1.4 2001/03/18 04:37:21 nate Exp $ */ +/* $NetBSD: tga_conf.c,v 1.3 2000/03/12 05:32:29 nathanw Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -39,148 +39,153 @@ #include <dev/ic/bt463var.h> #undef KB -#define KB * 1024 +#define KB * 1024 #undef MB -#define MB * 1024 * 1024 +#define MB * 1024 * 1024 static const struct tga_conf tga_configs[TGA_TYPE_UNKNOWN] = { - /* TGA_TYPE_T8_01 */ - { - "T8-01", - bt485_funcs, - 8, - 4 MB, - 2 KB, - 1, { 2 MB, 0 }, { 1 MB, 0 }, - 0, { 0, 0 }, { 0, 0 }, - }, - /* TGA_TYPE_T8_02 */ - { - "T8-02", - bt485_funcs, - 8, - 4 MB, - 4 KB, - 1, { 2 MB, 0 }, { 2 MB, 0 }, - 0, { 0, 0 }, { 0, 0 }, - }, - /* TGA_TYPE_T8_22 */ - { - "T8-22", - bt485_funcs, - 8, - 8 MB, - 4 KB, - 1, { 4 MB, 0 }, { 2 MB, 0 }, - 1, { 6 MB, 0 }, { 2 MB, 0 }, - }, - /* TGA_TYPE_T8_44 */ - { - "T8-44", - bt485_funcs, - 8, - 16 MB, - 4 KB, - 2, { 8 MB, 12 MB }, { 2 MB, 2 MB }, - 2, { 10 MB, 14 MB }, { 2 MB, 2 MB }, - }, - /* TGA_TYPE_T32_04 */ - { - "T32-04", - bt463_funcs, - 32, - 16 MB, - 8 KB, - 1, { 8 MB, 0 }, { 4 MB, 0 }, - 0, { 0, 0 }, { 0, 0 }, - }, - /* TGA_TYPE_T32_08 */ - { - "T32-08", - bt463_funcs, - 32, - 16 MB, - 16 KB, - 1, { 8 MB, 0 }, { 8 MB, 0 }, - 0, { 0, 0 }, { 0, 0 }, - }, - /* TGA_TYPE_T32_88 */ - { - "T32-88", - bt463_funcs, - 32, - 32 MB, - 16 KB, - 1, { 16 MB, 0 }, { 8 MB, 0 }, - 1, { 24 MB, 0 }, { 8 MB, 0 }, - }, + /* TGA_TYPE_T8_01 */ + { + "T8-01", + bt485_funcs, + 8, + 4 MB, + 2 KB, + 1, { 2 MB, 0 }, { 1 MB, 0 }, + 0, { 0, 0 }, { 0, 0 }, + }, + /* TGA_TYPE_T8_02 */ + { + "T8-02", + bt485_funcs, + 8, + 4 MB, + 4 KB, + 1, { 2 MB, 0 }, { 2 MB, 0 }, + 0, { 0, 0 }, { 0, 0 }, + }, + /* TGA_TYPE_T8_22 */ + { + "T8-22", + bt485_funcs, + 8, + 8 MB, + 4 KB, + 1, { 4 MB, 0 }, { 2 MB, 0 }, + 1, { 6 MB, 0 }, { 2 MB, 0 }, + }, + /* TGA_TYPE_T8_44 */ + { + "T8-44", + bt485_funcs, + 8, + 16 MB, + 4 KB, + 2, { 8 MB, 12 MB }, { 2 MB, 2 MB }, + 2, { 10 MB, 14 MB }, { 2 MB, 2 MB }, + }, + /* TGA_TYPE_T32_04 */ + { + "T32-04", + bt463_funcs, + 32, + 16 MB, + 8 KB, + 1, { 8 MB, 0 }, { 4 MB, 0 }, + 0, { 0, 0 }, { 0, 0 }, + }, + /* TGA_TYPE_T32_08 */ + { + "T32-08", + bt463_funcs, + 32, + 16 MB, + 16 KB, + 1, { 8 MB, 0 }, { 8 MB, 0 }, + 0, { 0, 0 }, { 0, 0 }, + }, + /* TGA_TYPE_T32_88 */ + { + "T32-88", + bt463_funcs, + 32, + 32 MB, + 16 KB, + 1, { 16 MB, 0 }, { 8 MB, 0 }, + 1, { 24 MB, 0 }, { 8 MB, 0 }, + }, }; #undef KB #undef MB int -tga_identify(regs) - tga_reg_t *regs; +tga_identify(dc) + struct tga_devconfig *dc; { - int type; - int deep, addrmask, wide; - - deep = (regs[TGA_REG_GDER] & 0x1) != 0; /* XXX */ - addrmask = ((regs[TGA_REG_GDER] >> 2) & 0x7); /* XXX */ - wide = (regs[TGA_REG_GDER] & 0x200) == 0; /* XXX */ - - type = TGA_TYPE_UNKNOWN; - - if (!deep) { - /* 8bpp frame buffer */ - - if (addrmask == 0x0) { - /* 4MB core map; T8-01 or T8-02 */ - - if (!wide) - type = TGA_TYPE_T8_01; - else - type = TGA_TYPE_T8_02; - } else if (addrmask == 0x1) { - /* 8MB core map; T8-22 */ - - if (wide) /* sanity */ - type = TGA_TYPE_T8_22; - } else if (addrmask == 0x3) { - /* 16MB core map; T8-44 */ - - if (wide) /* sanity */ - type = TGA_TYPE_T8_44; - } - } else { - /* 32bpp frame buffer */ - - if (addrmask == 0x3) { - /* 16MB core map; T32-04 or T32-08 */ - - if (!wide) - type = TGA_TYPE_T32_04; - else - type = TGA_TYPE_T32_08; - } else if (addrmask == 0x7) { - /* 32MB core map; T32-88 */ - - if (wide) /* sanity */ - type = TGA_TYPE_T32_88; - } - } - - return (type); + int type; + int gder; + int deep, addrmask, wide; + + gder = TGARREG(dc, TGA_REG_GDER); + + deep = (gder & 0x1) != 0; /* XXX */ + addrmask = (gder >> 2) & 0x7; /* XXX */ + wide = (gder & 0x200) == 0; /* XXX */ + + + type = TGA_TYPE_UNKNOWN; + + if (!deep) { + /* 8bpp frame buffer */ + + if (addrmask == 0x0) { + /* 4MB core map; T8-01 or T8-02 */ + + if (!wide) + type = TGA_TYPE_T8_01; + else + type = TGA_TYPE_T8_02; + } else if (addrmask == 0x1) { + /* 8MB core map; T8-22 */ + + if (wide) /* sanity */ + type = TGA_TYPE_T8_22; + } else if (addrmask == 0x3) { + /* 16MB core map; T8-44 */ + + if (wide) /* sanity */ + type = TGA_TYPE_T8_44; + } + } else { + /* 32bpp frame buffer */ + + if (addrmask == 0x3) { + /* 16MB core map; T32-04 or T32-08 */ + + if (!wide) + type = TGA_TYPE_T32_04; + else + type = TGA_TYPE_T32_08; + } else if (addrmask == 0x7) { + /* 32MB core map; T32-88 */ + + if (wide) /* sanity */ + type = TGA_TYPE_T32_88; + } + } + + return (type); } const struct tga_conf * tga_getconf(type) - int type; + int type; { - if (type >= 0 && type < TGA_TYPE_UNKNOWN) - return &tga_configs[type]; + if (type >= 0 && type < TGA_TYPE_UNKNOWN) + return &tga_configs[type]; - return (NULL); + return (NULL); } + diff --git a/sys/dev/pci/tgareg.h b/sys/dev/pci/tgareg.h index 33699c1e3b1..9dc7ff8132e 100644 --- a/sys/dev/pci/tgareg.h +++ b/sys/dev/pci/tgareg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tgareg.h,v 1.3 2000/10/14 18:04:07 aaron Exp $ */ +/* $OpenBSD: tgareg.h,v 1.4 2001/03/18 04:37:21 nate Exp $ */ /* $NetBSD: tgareg.h,v 1.3 2000/03/04 10:28:00 elric Exp $ */ /* @@ -46,6 +46,8 @@ #define TGA_MEM_ALTROM 0x0000000 /* 0MB -- Alternate ROM space */ #define TGA2_MEM_EXTDEV 0x0000000 /* 0MB -- External Device Access */ #define TGA_MEM_CREGS 0x0100000 /* 1MB -- Core Registers */ +#define TGA_CREGS_SIZE 0x0100000 /* Core registers occupy 1MB */ +#define TGA_CREGS_ALIAS 0x0000400 /* Register copies every 1kB */ #define TGA2_MEM_CLOCK 0x0060000 /* TGA2 Clock access */ #define TGA2_MEM_RAMDAC 0x0080000 /* TGA2 RAMDAC access */ diff --git a/sys/dev/pci/tgavar.h b/sys/dev/pci/tgavar.h index c23030799ac..068452f513b 100644 --- a/sys/dev/pci/tgavar.h +++ b/sys/dev/pci/tgavar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tgavar.h,v 1.3 2000/10/14 18:04:07 aaron Exp $ */ +/* $OpenBSD: tgavar.h,v 1.4 2001/03/18 04:37:21 nate Exp $ */ /* $NetBSD: tgavar.h,v 1.8 2000/04/02 19:01:11 nathanw Exp $ */ /* @@ -30,9 +30,10 @@ #include <dev/ic/ramdac.h> #include <dev/pci/tgareg.h> -#include <dev/rcons/raster.h> #include <dev/wscons/wsconsio.h> #include <dev/wscons/wscons_raster.h> +#include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> struct tga_devconfig; struct fbcmap; @@ -40,95 +41,126 @@ struct fbcursor; struct fbcurpos; struct tga_conf { - char *tgac_name; /* name for this board type */ + char *tgac_name; /* name for this board type */ - struct ramdac_funcs *(*ramdac_funcs) __P((void)); + struct ramdac_funcs *(*ramdac_funcs) __P((void)); - int tgac_phys_depth; /* physical frame buffer depth */ - vsize_t tgac_cspace_size; /* core space size */ - vsize_t tgac_vvbr_units; /* what '1' in the VVBR means */ + int tgac_phys_depth; /* physical frame buffer depth */ + vsize_t tgac_cspace_size; /* core space size */ + vsize_t tgac_vvbr_units; /* what '1' in the VVBR means */ - int tgac_ndbuf; /* number of display buffers */ - vaddr_t tgac_dbuf[2]; /* display buffer offsets/addresses */ - vsize_t tgac_dbufsz[2]; /* display buffer sizes */ + int tgac_ndbuf; /* number of display buffers */ + vaddr_t tgac_dbuf[2]; /* display buffer offsets/addresses */ + vsize_t tgac_dbufsz[2]; /* display buffer sizes */ - int tgac_nbbuf; /* number of display buffers */ - vaddr_t tgac_bbuf[2]; /* back buffer offsets/addresses */ - vsize_t tgac_bbufsz[2]; /* back buffer sizes */ + int tgac_nbbuf; /* number of display buffers */ + vaddr_t tgac_bbuf[2]; /* back buffer offsets/addresses */ + vsize_t tgac_bbufsz[2]; /* back buffer sizes */ }; struct tga_devconfig { - bus_space_tag_t dc_memt; - pci_chipset_tag_t dc_pc; - pcitag_t dc_pcitag; /* PCI tag */ - bus_addr_t dc_pcipaddr; /* PCI phys addr. */ + bus_space_tag_t dc_memt; + bus_space_handle_t dc_memh; - tga_reg_t *dc_regs; /* registers; XXX: need aliases */ - int dc_tga_type; /* the device type; see below */ - int dc_tga2; /* True if it is a TGA2 */ - const struct tga_conf *dc_tgaconf; /* device buffer configuration */ + pcitag_t dc_pcitag; /* PCI tag */ + bus_addr_t dc_pcipaddr; /* PCI phys addr. */ - struct ramdac_funcs - *dc_ramdac_funcs; /* The RAMDAC functions */ - struct ramdac_cookie - *dc_ramdac_cookie; /* the RAMDAC type; see above */ + bus_space_handle_t dc_regs; /* registers; XXX: need aliases */ - vaddr_t dc_vaddr; /* memory space virtual base address */ - paddr_t dc_paddr; /* memory space physical base address */ + int dc_tga_type; /* the device type; see below */ + int dc_tga2; /* True if it is a TGA2 */ + const struct tga_conf *dc_tgaconf; /* device buffer configuration */ - int dc_wid; /* width of frame buffer */ - int dc_ht; /* height of frame buffer */ - int dc_rowbytes; /* bytes in a FB scan line */ + struct ramdac_funcs + *dc_ramdac_funcs; /* The RAMDAC functions */ + struct ramdac_cookie + *dc_ramdac_cookie; /* the RAMDAC type; see above */ - vaddr_t dc_videobase; /* base of flat frame buffer */ + vaddr_t dc_vaddr; /* memory space virtual base address */ + paddr_t dc_paddr; /* memory space physical base address */ - struct raster dc_raster; /* raster description */ - struct rcons dc_rcons; /* raster blitter control info */ + int dc_wid; /* width of frame buffer */ + int dc_ht; /* height of frame buffer */ + int dc_rowbytes; /* bytes in a FB scan line */ - int dc_blanked; /* currently had video disabled */ - void *dc_ramdac_private; /* RAMDAC private storage */ + vaddr_t dc_videobase; /* base of flat frame buffer */ - void (*dc_ramdac_intr) __P((void *)); - int dc_intrenabled; /* can we depend on interrupts yet? */ + struct rasops_info dc_rinfo; /* raster display data */ + + int dc_blanked; /* currently had video disabled */ + void *dc_ramdac_private; /* RAMDAC private storage */ + + void (*dc_ramdac_intr) __P((void *)); + int dc_intrenabled; /* can we depend on interrupts yet? */ }; - + struct tga_softc { - struct device sc_dev; + struct device sc_dev; - struct tga_devconfig *sc_dc; /* device configuration */ - void *sc_intr; /* interrupt handler info */ - /* XXX should record intr fns/arg */ + struct tga_devconfig *sc_dc; /* device configuration */ + void *sc_intr; /* interrupt handler info */ + /* XXX should record intr fns/arg */ - int nscreens; + int nscreens; }; -#define TGA_TYPE_T8_01 0 /* 8bpp, 1MB */ -#define TGA_TYPE_T8_02 1 /* 8bpp, 2MB */ -#define TGA_TYPE_T8_22 2 /* 8bpp, 4MB */ -#define TGA_TYPE_T8_44 3 /* 8bpp, 8MB */ -#define TGA_TYPE_T32_04 4 /* 32bpp, 4MB */ -#define TGA_TYPE_T32_08 5 /* 32bpp, 8MB */ -#define TGA_TYPE_T32_88 6 /* 32bpp, 16MB */ -#define TGA_TYPE_UNKNOWN 7 /* unknown */ +#define TGA_TYPE_T8_01 0 /* 8bpp, 1MB */ +#define TGA_TYPE_T8_02 1 /* 8bpp, 2MB */ +#define TGA_TYPE_T8_22 2 /* 8bpp, 4MB */ +#define TGA_TYPE_T8_44 3 /* 8bpp, 8MB */ +#define TGA_TYPE_T32_04 4 /* 32bpp, 4MB */ +#define TGA_TYPE_T32_08 5 /* 32bpp, 8MB */ +#define TGA_TYPE_T32_88 6 /* 32bpp, 16MB */ +#define TGA_TYPE_UNKNOWN 7 /* unknown */ -#define DEVICE_IS_TGA(class, id) \ - (((PCI_VENDOR(id) == PCI_VENDOR_DEC && \ - PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21030) || \ - PCI_PRODUCT(id) == PCI_PRODUCT_DEC_PBXGB) ? 10 : 0) +#define DEVICE_IS_TGA(class, id) \ + (((PCI_VENDOR(id) == PCI_VENDOR_DEC && \ + PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21030) || \ + PCI_PRODUCT(id) == PCI_PRODUCT_DEC_PBXGB) ? 10 : 0) int tga_cnattach __P((bus_space_tag_t, bus_space_tag_t, pci_chipset_tag_t, - int, int, int)); + int, int, int)); -int tga_identify __P((tga_reg_t *)); +int tga_identify __P((struct tga_devconfig *)); const struct tga_conf *tga_getconf __P((int)); int tga_builtin_set_cursor __P((struct tga_devconfig *, - struct wsdisplay_cursor *)); + struct wsdisplay_cursor *)); int tga_builtin_get_cursor __P((struct tga_devconfig *, - struct wsdisplay_cursor *)); + struct wsdisplay_cursor *)); int tga_builtin_set_curpos __P((struct tga_devconfig *, - struct wsdisplay_curpos *)); + struct wsdisplay_curpos *)); int tga_builtin_get_curpos __P((struct tga_devconfig *, - struct wsdisplay_curpos *)); + struct wsdisplay_curpos *)); int tga_builtin_get_curmax __P((struct tga_devconfig *, - struct wsdisplay_curpos *)); + struct wsdisplay_curpos *)); + +/* Read a TGA register */ +#define TGARREG(dc,reg) (bus_space_read_4((dc)->dc_memt, (dc)->dc_regs, \ + (reg) << 2)) + +/* Write a TGA register */ +#define TGAWREG(dc,reg,val) bus_space_write_4((dc)->dc_memt, (dc)->dc_regs, \ + (reg) << 2, (val)) + +/* Write a TGA register at an alternate aliased location */ +#define TGAWALREG(dc,reg,alias,val) bus_space_write_4( \ + (dc)->dc_memt, (dc)->dc_regs, \ + ((alias) * TGA_CREGS_ALIAS) + ((reg) << 2), \ + (val)) + +/* Insert a write barrier */ +#define TGAREGWB(dc,reg, nregs) bus_space_barrier( \ + (dc)->dc_memt, (dc)->dc_regs, \ + ((reg) << 2), 4 * (nregs), BUS_SPACE_BARRIER_WRITE) + +/* Insert a read barrier */ +#define TGAREGRB(dc,reg, nregs) bus_space_barrier( \ + (dc)->dc_memt, (dc)->dc_regs, \ + ((reg) << 2), 4 * (nregs), BUS_SPACE_BARRIER_READ) + +/* Insert a read/write barrier */ +#define TGAREGRWB(dc,reg, nregs) bus_space_barrier( \ + (dc)->dc_memt, (dc)->dc_regs, \ + ((reg) << 2), 4 * (nregs), \ + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) |