summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2000-07-03 19:30:25 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2000-07-03 19:30:25 +0000
commitff1778621a8b0ab188efd9fed2b26f79a8e83475 (patch)
treedb9923395070a7781170d8bfd437ba71a62ff905 /sys/dev/pci
parente698fd70260d37f50e69e932cd47c047dcfb3750 (diff)
closer approximation to an alpha using new wscons.
tga moved to dev/pci. by request from alpha people.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/files.pci11
-rw-r--r--sys/dev/pci/tga.c891
-rw-r--r--sys/dev/pci/tga.c.orig0
-rw-r--r--sys/dev/pci/tga_bt463.c605
-rw-r--r--sys/dev/pci/tga_bt463.c.orig0
-rw-r--r--sys/dev/pci/tga_bt485.c624
-rw-r--r--sys/dev/pci/tga_bt485.c.orig0
-rw-r--r--sys/dev/pci/tga_conf.c183
-rw-r--r--sys/dev/pci/tga_conf.c.orig0
-rw-r--r--sys/dev/pci/tgareg.h174
-rw-r--r--sys/dev/pci/tgareg.h.orig0
-rw-r--r--sys/dev/pci/tgavar.h155
-rw-r--r--sys/dev/pci/tgavar.h.orig0
13 files changed, 2641 insertions, 2 deletions
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index 71c451f45fb..dd97e0fa83c 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.77 2000/06/30 03:28:07 art Exp $
+# $OpenBSD: files.pci,v 1.78 2000/07/03 19:30:22 mickey 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.
@@ -14,12 +14,19 @@ file dev/pci/pci_subr.c pci
# Generic VGA
attach vga at pci with vga_pci
-file dev/pci/vga_pci.c vga_pci needs-flag
+file dev/pci/vga_pci.c vga_pci needs-flag
# Generic VGA Framebuffer version
attach vgafb at pci with vgafb_pci
file dev/pci/vgafb_pci.c vgafb_pci needs-flag
+device tga: wsemuldisplaydev, wsrasteremulops
+attach tga at pci
+file dev/pci/tga.c tga needs-flag
+file dev/pci/tga_conf.c tga
+file dev/pci/tga_bt463.c tga
+file dev/pci/tga_bt485.c tga
+
# Cypress 82c693 hyperCache(tm) Stand-Alone PCI Peripheral Controller
# with USB. This is a combo chip:
#
diff --git a/sys/dev/pci/tga.c b/sys/dev/pci/tga.c
new file mode 100644
index 00000000000..d7033c29ddb
--- /dev/null
+++ b/sys/dev/pci/tga.c
@@ -0,0 +1,891 @@
+/* $NetBSD: tga.c,v 1.15 1999/12/06 19:25:59 drochner Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/conf.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/ioctl.h>
+
+#include <vm/vm.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/tgareg.h>
+#include <dev/pci/tgavar.h>
+#include <dev/ic/bt485reg.h>
+
+#include <dev/rcons/raster.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wscons_raster.h>
+#include <dev/wscons/wsdisplayvar.h>
+
+int tgamatch __P((struct device *, struct cfdata *, void *));
+void tgaattach __P((struct device *, struct device *, void *));
+int tgaprint __P((void *, const char *));
+
+struct cfdriver tga_cd = {
+ NULL, "tga", DV_DULL
+};
+
+struct cfattach tga_ca = {
+ sizeof(struct tga_softc), (cfmatch_t)tgamatch, tgaattach,
+};
+
+int tga_identify __P((tga_reg_t *));
+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));
+
+struct tga_devconfig tga_console_dc;
+
+int tga_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
+int tga_mmap __P((void *, off_t, int));
+static void tga_copyrows __P((void *, int, int, int));
+static void tga_copycols __P((void *, int, int, int, int));
+static int tga_alloc_screen __P((void *, const struct wsscreen_descr *,
+ void **, int *, int *, long *));
+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 ));
+
+struct wsdisplay_emulops tga_emulops = {
+ rcons_cursor, /* could use hardware cursor; punt */
+ rcons_mapchar,
+ rcons_putchar,
+ tga_copycols,
+ rcons_erasecols,
+ tga_copyrows,
+ rcons_eraserows,
+ rcons_alloc_attr
+};
+
+struct wsscreen_descr tga_stdscreen = {
+ "std",
+ 0, 0, /* will be filled in -- XXX shouldn't, it's global */
+ &tga_emulops,
+ 0, 0,
+ WSSCREEN_REVERSE
+};
+
+const struct wsscreen_descr *_tga_scrlist[] = {
+ &tga_stdscreen,
+ /* XXX other formats, graphics screen? */
+};
+
+struct wsscreen_list tga_screenlist = {
+ sizeof(_tga_scrlist) / sizeof(struct wsscreen_descr *), _tga_scrlist
+};
+
+struct wsdisplay_accessops tga_accessops = {
+ tga_ioctl,
+ tga_mmap,
+ tga_alloc_screen,
+ tga_free_screen,
+ tga_show_screen,
+ 0 /* load_font */
+};
+
+void tga_blank __P((struct tga_devconfig *));
+void tga_unblank __P((struct tga_devconfig *));
+
+int
+tgamatch(parent, match, aux)
+ struct device *parent;
+ struct cfdata *match;
+ void *aux;
+{
+ struct pci_attach_args *pa = aux;
+
+ if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_DEC ||
+ PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_DEC_21030)
+ return (0);
+
+ return (10);
+}
+
+void
+tga_getdevconfig(memt, pc, tag, dc)
+ bus_space_tag_t memt;
+ pci_chipset_tag_t pc;
+ pcitag_t tag;
+ struct tga_devconfig *dc;
+{
+ const struct tga_conf *tgac;
+ const struct tga_ramdac_conf *tgar;
+ struct raster *rap;
+ struct rcons *rcp;
+ bus_size_t pcisize;
+ int i, cacheable;
+
+ dc->dc_memt = memt;
+ dc->dc_pc = pc;
+
+ dc->dc_pcitag = tag;
+
+ /* XXX magic number */
+ pci_mem_find(pc, tag, 0x10, &dc->dc_pcipaddr, &pcisize, &cacheable);
+ 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);
+ return;
+ }
+#ifdef __alpha__
+ dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */
+#else
+#error "find a way to deal w/ paddr here"
+#endif
+
+ dc->dc_regs = (tga_reg_t *)(dc->dc_vaddr + TGA_MEM_CREGS);
+ dc->dc_tga_type = tga_identify(dc->dc_regs);
+ tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type);
+ if (tgac == NULL) {
+printf("tgac==0\n");
+ return;
+ }
+
+#if 0
+ /* XXX on the Alpha, pcisize = 4 * cspace_size. */
+ if (tgac->tgac_cspace_size != pcisize) /* sanity */
+ panic("tga_getdevconfig: memory size mismatch?");
+#endif
+
+ tgar = tgac->tgac_ramdac;
+
+ switch (dc->dc_regs[TGA_REG_VHCR] & 0x1ff) { /* XXX */
+ case 0:
+ dc->dc_wid = 8192;
+ break;
+
+ case 1:
+ dc->dc_wid = 8196;
+ break;
+
+ default:
+ dc->dc_wid = (dc->dc_regs[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 */
+ 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 */
+
+ /* XXX this seems to be what DEC does */
+ dc->dc_regs[TGA_REG_CCBR] = 0;
+ dc->dc_regs[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);
+
+ /*
+ * 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;
+
+ /* clear the screen */
+ 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;
+}
+
+void
+tgaattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct pci_attach_args *pa = aux;
+ struct tga_softc *sc = (struct tga_softc *)self;
+ struct wsemuldisplaydev_attach_args aa;
+ pci_intr_handle_t intrh;
+ const char *intrstr;
+ u_int8_t rev;
+ int console;
+
+#ifdef __alpha__
+ console = (pa->pa_tag == tga_console_dc.dc_pcitag);
+#else
+ console = 0;
+#endif
+ if (console) {
+ sc->sc_dc = &tga_console_dc;
+ sc->nscreens = 1;
+ } else {
+ 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);
+ }
+ 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 (sc->sc_dc->dc_tgaconf->tgac_ramdac->tgar_intr != 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,
+ sc->sc_dc->dc_tgaconf->tgac_ramdac->tgar_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;
+ }
+ }
+
+ /*
+ * Initialize the RAMDAC and allocate any private storage it needs.
+ * Initialization includes disabling cursor, setting a sane
+ * colormap, etc.
+ */
+ (*sc->sc_dc->dc_tgaconf->tgac_ramdac->tgar_init)(sc->sc_dc, 1);
+
+ printf(": DC21030 ");
+ rev = PCI_REVISION(pa->pa_class);
+ switch (rev) {
+ case 1: case 2: case 3:
+ printf("step %c", 'A' + rev - 1);
+ break;
+
+ default:
+ printf("unknown stepping (0x%x)", rev);
+ break;
+ }
+ printf(", ");
+
+ 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_tgaconf->tgac_ramdac->tgar_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);
+}
+
+int
+tga_ioctl(v, cmd, data, flag, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ struct tga_softc *sc = v;
+ struct tga_devconfig *dc = sc->sc_dc;
+ const struct tga_ramdac_conf *tgar = dc->dc_tgaconf->tgac_ramdac;
+
+ 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 (*tgar->tgar_get_cmap)(dc,
+ (struct wsdisplay_cmap *)data);
+
+ case WSDISPLAYIO_PUTCMAP:
+ return (*tgar->tgar_set_cmap)(dc,
+ (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 (*tgar->tgar_get_curpos)(dc,
+ (struct wsdisplay_curpos *)data);
+
+ case WSDISPLAYIO_SCURPOS:
+ return (*tgar->tgar_set_curpos)(dc,
+ (struct wsdisplay_curpos *)data);
+
+ case WSDISPLAYIO_GCURMAX:
+ return (*tgar->tgar_get_curmax)(dc,
+ (struct wsdisplay_curpos *)data);
+
+ case WSDISPLAYIO_GCURSOR:
+ return (*tgar->tgar_get_cursor)(dc,
+ (struct wsdisplay_cursor *)data);
+
+ case WSDISPLAYIO_SCURSOR:
+ return (*tgar->tgar_set_cursor)(dc,
+ (struct wsdisplay_cursor *)data);
+ }
+ return (-1);
+}
+
+int
+tga_mmap(v, offset, prot)
+ void *v;
+ off_t offset;
+ int prot;
+{
+
+ /* XXX NEW MAPPING CODE... */
+
+#ifdef __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);
+#else
+ return (-1);
+#endif
+}
+
+int
+tga_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
+ void *v;
+ const struct wsscreen_descr *type;
+ void **cookiep;
+ int *curxp, *curyp;
+ long *attrp;
+{
+ struct tga_softc *sc = v;
+ long defattr;
+
+ if (sc->nscreens > 0)
+ return (ENOMEM);
+
+ *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */
+ *curxp = 0;
+ *curyp = 0;
+ rcons_alloc_attr(&sc->sc_dc->dc_rcons, 0, 0, 0, &defattr);
+ *attrp = defattr;
+ sc->nscreens++;
+ return (0);
+}
+
+void
+tga_free_screen(v, cookie)
+ void *v;
+ void *cookie;
+{
+ struct tga_softc *sc = v;
+
+ if (sc->sc_dc == &tga_console_dc)
+ panic("tga_free_screen: console");
+
+ sc->nscreens--;
+}
+
+int
+tga_show_screen(v, cookie, waitok, cb, cbarg)
+ void *v;
+ void *cookie;
+ int waitok;
+ void (*cb) __P((void *, int, int));
+ void *cbarg;
+{
+
+ return (0);
+}
+
+int
+tga_cnattach(iot, memt, pc, bus, device, function)
+ bus_space_tag_t iot, memt;
+ pci_chipset_tag_t pc;
+ int bus, device, function;
+{
+ struct tga_devconfig *dcp = &tga_console_dc;
+ long defattr;
+
+ tga_getdevconfig(memt, pc,
+ pci_make_tag(pc, bus, device, function), dcp);
+
+ /* sanity checks */
+ if (dcp->dc_vaddr == NULL)
+ panic("tga_console(%d, %d): couldn't map memory space",
+ device, function);
+ if (dcp->dc_tgaconf == NULL)
+ panic("tga_console(%d, %d): unknown board configuration",
+ device, function);
+
+ /*
+ * Initialize the RAMDAC but DO NOT allocate any private storage.
+ * Initialization includes disabling cursor, setting a sane
+ * colormap, etc. It will be reinitialized in tgaattach().
+ */
+ (*dcp->dc_tgaconf->tgac_ramdac->tgar_init)(dcp, 0);
+
+ rcons_alloc_attr(&dcp->dc_rcons, 0, 0, 0, &defattr);
+
+ wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rcons,
+ 0, 0, defattr);
+
+ return(0);
+}
+
+/*
+ * Functions to blank and unblank the display.
+ */
+void
+tga_blank(dc)
+ struct tga_devconfig *dc;
+{
+
+ if (!dc->dc_blanked) {
+ dc->dc_blanked = 1;
+ dc->dc_regs[TGA_REG_VVVR] |= VVR_BLANK; /* XXX */
+ }
+}
+
+void
+tga_unblank(dc)
+ struct tga_devconfig *dc;
+{
+
+ if (dc->dc_blanked) {
+ dc->dc_blanked = 0;
+ dc->dc_regs[TGA_REG_VVVR] &= ~VVR_BLANK; /* XXX */
+ }
+}
+
+/*
+ * Functions to manipulate the built-in cursor handing hardware.
+ */
+int
+tga_builtin_set_cursor(dc, cursorp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cursor *cursorp;
+{
+ int count, error, v;
+
+ v = cursorp->which;
+ if (v & WSDISPLAY_CURSOR_DOCMAP) {
+ error = (*dc->dc_tgaconf->tgac_ramdac->tgar_check_curcmap)(dc,
+ cursorp);
+ if (error)
+ return (error);
+ }
+ if (v & WSDISPLAY_CURSOR_DOSHAPE) {
+ if ((u_int)cursorp->size.x != 64 ||
+ (u_int)cursorp->size.y > 64)
+ 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;
+
+ /* parameters are OK; do it */
+ if (v & WSDISPLAY_CURSOR_DOCUR) {
+ if (cursorp->enable)
+ dc->dc_regs[TGA_REG_VVVR] |= 0x04; /* XXX */
+ else
+ dc->dc_regs[TGA_REG_VVVR] &= ~0x04; /* XXX */
+ }
+ if (v & WSDISPLAY_CURSOR_DOPOS) {
+ dc->dc_regs[TGA_REG_CXYR] = ((cursorp->pos.y & 0xfff) << 12) |
+ (cursorp->pos.x & 0xfff);
+ }
+ if (v & WSDISPLAY_CURSOR_DOCMAP) {
+ /* can't fail. */
+ (*dc->dc_tgaconf->tgac_ramdac->tgar_set_curcmap)(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);
+ copyin(cursorp->image, (char *)(dc->dc_vaddr +
+ (dc->dc_regs[TGA_REG_CCBR] & 0x3ff)),
+ count); /* can't fail. */
+ }
+ return (0);
+}
+
+int
+tga_builtin_get_cursor(dc, cursorp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cursor *cursorp;
+{
+ 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 = (*dc->dc_tgaconf->tgac_ramdac->tgar_get_curcmap)(dc, cursorp);
+ return (error);
+}
+
+int
+tga_builtin_set_curpos(dc, curposp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_curpos *curposp;
+{
+
+ dc->dc_regs[TGA_REG_CXYR] =
+ ((curposp->y & 0xfff) << 12) | (curposp->x & 0xfff);
+ return (0);
+}
+
+int
+tga_builtin_get_curpos(dc, curposp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_curpos *curposp;
+{
+
+ curposp->x = dc->dc_regs[TGA_REG_CXYR] & 0xfff;
+ curposp->y = (dc->dc_regs[TGA_REG_CXYR] >> 12) & 0xfff;
+ return (0);
+}
+
+int
+tga_builtin_get_curmax(dc, curposp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_curpos *curposp;
+{
+
+ curposp->x = curposp->y = 64;
+ return (0);
+}
+
+/*
+ * Copy columns (characters) in a row (line).
+ */
+void
+tga_copycols(id, row, srccol, dstcol, ncols)
+ void *id;
+ int row, srccol, dstcol, ncols;
+{
+ struct rcons *rc = 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;
+
+ tga_rop(rc->rc_sp, dstx, y,
+ nx, rc->rc_font->height, RAS_SRC,
+ rc->rc_sp, srcx, y);
+}
+
+/*
+ * Copy rows (lines).
+ */
+void
+tga_copyrows(id, srcrow, dstrow, nrows)
+ void *id;
+ int srcrow, dstrow, nrows;
+{
+ struct rcons *rc = 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;
+
+ tga_rop(rc->rc_sp, rc->rc_xorigin, dsty,
+ rc->rc_raswidth, ny, RAS_SRC,
+ rc->rc_sp, rc->rc_xorigin, 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 };
+
+/* A mapping between our API and the TGA card */
+static int map_rop[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6,
+ 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
+};
+
+/*
+ * Generic TGA raster op.
+ * This covers all possible raster ops, and
+ * clips the sizes and all of that.
+ */
+static int
+tga_rop(dst, dx, dy, w, h, rop, src, sx, sy)
+ struct raster *dst;
+ int dx, dy, w, h, rop;
+ struct raster *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)
+ return -1; /* We want a src */
+ /* Clip against src */
+ if (sx < 0) {
+ w += sx;
+ sx = 0;
+ }
+ if (sy < 0) {
+ h += sy;
+ sy = 0;
+ }
+ if (sx + w > src->width)
+ w = src->width - sx;
+ if (sy + h > src->height)
+ h = src->height - sy;
+ } else {
+ if (src != (struct raster *) 0)
+ return -1; /* We need no src */
+ }
+ /* Clip against dst. We modify src regardless of using it,
+ * since it really doesn't matter.
+ */
+ if (dx < 0) {
+ w += dx;
+ sx -= dx;
+ dx = 0;
+ }
+ if (dy < 0) {
+ h += dy;
+ sy -= dy;
+ dy = 0;
+ }
+ if (dx + w > dst->width)
+ w = dst->width - dx;
+ if (dy + h > dst->height)
+ h = dst->height - 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);
+}
+
+/*
+ * 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
+tga_rop_vtov(dst, dx, dy, w, h, rop, src, sx, sy)
+ struct raster *dst;
+ int dx, dy, w, h, rop;
+ struct raster *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;
+ int ystart, yend, ydir, yinc;
+ 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 (sy >= dy) {
+ ystart = 0;
+ yend = h;
+ ydir = 1;
+ } else {
+ ystart = h;
+ yend = 0;
+ ydir = -1;
+ }
+ if (sx >= dx) {
+ xstart = 0;
+ xend = w * (dst->depth / 8);
+ xdir = 1;
+ } else {
+ xstart = w * (dst->depth / 8);
+ 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;
+ }
+ }
+ regs0[TGA_REG_GOPR] = 0x0003; /* op -> dst = src */
+ regs0[TGA_REG_GMOR] = 0x0000; /* Simple mode */
+ return 0;
+}
diff --git a/sys/dev/pci/tga.c.orig b/sys/dev/pci/tga.c.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/sys/dev/pci/tga.c.orig
diff --git a/sys/dev/pci/tga_bt463.c b/sys/dev/pci/tga_bt463.c
new file mode 100644
index 00000000000..1ffcf23b924
--- /dev/null
+++ b/sys/dev/pci/tga_bt463.c
@@ -0,0 +1,605 @@
+/* $NetBSD: tga_bt463.c,v 1.4 1999/04/30 02:47:42 nathanw Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <vm/vm.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/tgareg.h>
+#include <dev/pci/tgavar.h>
+#include <dev/ic/bt463reg.h>
+
+#include <dev/wscons/wsconsio.h>
+
+/*
+ * Functions exported via the RAMDAC configuration table.
+ */
+void tga_bt463_init __P((struct tga_devconfig *, int));
+int tga_bt463_intr __P((void *));
+int tga_bt463_set_cmap __P((struct tga_devconfig *,
+ struct wsdisplay_cmap *));
+int tga_bt463_get_cmap __P((struct tga_devconfig *,
+ struct wsdisplay_cmap *));
+
+int tga_bt463_check_curcmap __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *cursorp));
+void tga_bt463_set_curcmap __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *cursorp));
+int tga_bt463_get_curcmap __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *cursorp));
+
+const struct tga_ramdac_conf tga_ramdac_bt463 = {
+ "Bt463",
+ tga_bt463_init,
+ tga_bt463_intr,
+ tga_bt463_set_cmap,
+ tga_bt463_get_cmap,
+ tga_builtin_set_cursor,
+ tga_builtin_get_cursor,
+ tga_builtin_set_curpos,
+ tga_builtin_get_curpos,
+ tga_builtin_get_curmax,
+ tga_bt463_check_curcmap,
+ tga_bt463_set_curcmap,
+ tga_bt463_get_curcmap,
+};
+
+/*
+ * Private data.
+ */
+struct bt463data {
+ int changed; /* what changed; see below */
+ char curcmap_r[2]; /* cursor colormap */
+ char curcmap_g[2];
+ char curcmap_b[2];
+ char cmap_r[BT463_NCMAP_ENTRIES]; /* colormap */
+ char cmap_g[BT463_NCMAP_ENTRIES];
+ char cmap_b[BT463_NCMAP_ENTRIES];
+ int window_type[16]; /* 16 24-bit window type table entries */
+};
+
+#define DATA_CURCMAP_CHANGED 0x01 /* cursor colormap changed */
+#define DATA_CMAP_CHANGED 0x02 /* colormap changed */
+#define DATA_WTYPE_CHANGED 0x04 /* window type table changed */
+#define DATA_ALL_CHANGED 0x07
+
+/*
+ * Internal functions.
+ */
+inline void tga_bt463_wr_d __P((bus_space_tag_t, bus_space_handle_t,
+ u_int, u_int8_t));
+inline u_int8_t tga_bt463_rd_d __P((bus_space_tag_t, bus_space_handle_t,
+ u_int));
+inline void tga_bt463_wraddr __P((bus_space_tag_t, bus_space_handle_t,
+ u_int16_t));
+
+void tga_bt463_update __P((bus_space_tag_t, bus_space_handle_t,
+ struct bt463data *));
+
+#define tga_bt463_sched_update(tag,regs) \
+ bus_space_write_4((tag), (regs), (TGA_REG_SISR*4), (0x00010000))
+
+/*****************************************************************************/
+
+/*
+ * Functions exported via the RAMDAC configuration table.
+ */
+
+void
+tga_bt463_init(dc, alloc)
+ struct tga_devconfig *dc;
+ int alloc;
+{
+ struct bt463data tmp, *data;
+ bus_space_tag_t tag;
+ bus_space_handle_t regs;
+ int i;
+
+ /*
+ * Init the BT463 for normal operation.
+ */
+
+ tag = dc->dc_memt;
+ bus_space_subregion(tag, dc->dc_vaddr, TGA_MEM_CREGS, 512,
+ &regs);
+ /*
+ * Setup:
+ * reg 0: 4:1 multiplexing, 25/75 blink.
+ * reg 1: Overlay mapping: mapped to common palette,
+ * 14 window type entries, 24-plane configuration mode,
+ * 4 overlay planes, underlays disabled, no cursor.
+ * reg 2: sync-on-green disabled, pedestal enabled.
+ */
+ tga_bt463_wraddr(tag, regs, BT463_IREG_COMMAND_0);
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA, 0x40);
+
+ tga_bt463_wraddr(tag, regs, BT463_IREG_COMMAND_1);
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA, 0x48);
+
+ tga_bt463_wraddr(tag, regs, BT463_IREG_COMMAND_2);
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA, 0x40);
+
+ /*
+ * Initialize the read mask.
+ */
+ tga_bt463_wraddr(tag, regs, BT463_IREG_READ_MASK_P0_P7);
+ for (i = 0; i < 3; i++)
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA, 0xff);
+
+ /*
+ * Initialize the blink mask.
+ */
+ tga_bt463_wraddr(tag, regs, BT463_IREG_BLINK_MASK_P0_P7);
+ for (i = 0; i < 3; i++)
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA, 0);
+
+ /*
+ * Clear test register
+ */
+ tga_bt463_wraddr(tag, regs, BT463_IREG_TEST);
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA, 0);
+
+ /*
+ * If we should allocate a new private info struct, do so.
+ * Otherwise, use the one we have (if it's there), or
+ * use the temporary one on the stack.
+ */
+ if (alloc) {
+ if (dc->dc_ramdac_private != NULL)
+ panic("tga_bt463_init: already have private struct");
+ dc->dc_ramdac_private = malloc(sizeof *data, M_DEVBUF,
+ M_WAITOK);
+ }
+ if (dc->dc_ramdac_private != NULL)
+ data = dc->dc_ramdac_private;
+ else
+ data = &tmp;
+
+ /*
+ * Initalize the RAMDAC info struct to hold all of our
+ * data, and fill it in.
+ */
+ data->changed = DATA_ALL_CHANGED;
+
+ /* initial cursor colormap: 0 is black, 1 is white */
+ data->curcmap_r[0] = data->curcmap_g[0] = data->curcmap_b[0] = 0;
+ data->curcmap_r[1] = data->curcmap_g[1] = data->curcmap_b[1] = 0xff;
+
+ /* Initial colormap: 0 is black, everything else is white */
+ data->cmap_r[0] = data->cmap_g[0] = data->cmap_b[0] = 0;
+ for (i = 1; i < 256; i++)
+ data->cmap_r[i] = data->cmap_g[i] = data->cmap_b[i] = 255;
+
+
+ /* Initialize the window type table:
+ * Entry 0: 8-plane pseudocolor in the bottom 8 bits,
+ * overlays disabled, colormap starting at 0.
+ *
+ * Lookup table bypass: no ( 0 << 23 & 0x800000) 0
+ * Colormap address: 0x000 (0x000 << 17 & 0x7e0000) 0
+ * Overlay mask: 0x0 ( 0 << 13 & 0x01e000) 0
+ * Overlay location: P<27:24> ( 0 << 12 & 0x001000) 0
+ * Display mode: Pseudocolor ( 1 << 9 & 0x000e00) 0x200
+ * Number of planes: 8 ( 8 << 5 & 0x0001e0) 0x100
+ * Plane shift: 16 ( 16 << 0 & 0x00001f) 10
+ * --------
+ * 0x310
+ */
+ data->window_type[0] = 0x310;
+ /* The colormap interface to the world only supports one colormap,
+ * so having an entry for the 'alternate' colormap in the bt463
+ * probably isn't useful.
+ */
+ /* Entry 1: 24-plane truecolor, overlays disabled. */
+ data->window_type[1] = 0x200;
+
+ /* Fill the remaining table entries with clones of entry 0 until we
+ * figure out a better use for them.
+ */
+
+ for (i = 2; i < BT463_NWTYPE_ENTRIES; i++) {
+ data->window_type[i] = 0x310;
+ }
+
+ /* The Bt463 won't accept window type table data
+ * except during a blanking interval. Normally we would
+ * do this by scheduling an interrupt, but this is run
+ * during autoconfiguration, when interrupts are disabled.
+ * So we spin on the end-of-frame interrupt bit.
+ */
+
+ bus_space_write_4(tag, regs, TGA_REG_SISR*4, 0x00010001);
+ bus_space_barrier(tag, regs, TGA_REG_SISR*4, 4, BUS_BARRIER_WRITE);
+ while ((bus_space_read_4(tag, regs, (TGA_REG_SISR * 4))& 0x00000001) == 0);
+
+ tga_bt463_update(tag, regs, data);
+
+ bus_space_write_4(tag, regs, TGA_REG_SISR*4, 0x00000001);
+ bus_space_barrier(tag, regs, TGA_REG_SISR*4, 4, BUS_BARRIER_WRITE);
+
+ tga_bt463_sched_update(tag, regs);
+
+}
+
+int
+tga_bt463_set_cmap(dc, cmapp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cmap *cmapp;
+{
+ struct bt463data *data = dc->dc_ramdac_private;
+ bus_space_tag_t tag = dc->dc_memt;
+ bus_space_handle_t regs;
+ int count, index, s;
+
+ bus_space_subregion(tag, dc->dc_vaddr, TGA_MEM_CREGS, 512,
+ &regs);
+
+
+ if ((u_int)cmapp->index >= BT463_NCMAP_ENTRIES ||
+ ((u_int)cmapp->index + (u_int)cmapp->count) > BT463_NCMAP_ENTRIES)
+ return (EINVAL);
+#ifdef UVM
+ if (!uvm_useracc(cmapp->red, cmapp->count, B_READ) ||
+ !uvm_useracc(cmapp->green, cmapp->count, B_READ) ||
+ !uvm_useracc(cmapp->blue, cmapp->count, B_READ))
+ return (EFAULT);
+#else
+ if (!useracc(cmapp->red, cmapp->count, B_READ) ||
+ !useracc(cmapp->green, cmapp->count, B_READ) ||
+ !useracc(cmapp->blue, cmapp->count, B_READ))
+ return (EFAULT);
+#endif
+
+ s = spltty();
+
+ index = cmapp->index;
+ count = cmapp->count;
+ copyin(cmapp->red, &data->cmap_r[index], count);
+ copyin(cmapp->green, &data->cmap_g[index], count);
+ copyin(cmapp->blue, &data->cmap_b[index], count);
+
+ data->changed |= DATA_CMAP_CHANGED;
+
+ tga_bt463_sched_update(tag, regs);
+ splx(s);
+
+ return (0);
+}
+
+int
+tga_bt463_get_cmap(dc, cmapp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cmap *cmapp;
+{
+ struct bt463data *data = dc->dc_ramdac_private;
+ int error, count, index;
+
+ if ((u_int)cmapp->index >= BT463_NCMAP_ENTRIES ||
+ ((u_int)cmapp->index + (u_int)cmapp->count) > BT463_NCMAP_ENTRIES)
+ return (EINVAL);
+
+ count = cmapp->count;
+ index = cmapp->index;
+
+ error = copyout(&data->cmap_r[index], cmapp->red, count);
+ if (error)
+ return (error);
+ error = copyout(&data->cmap_g[index], cmapp->green, count);
+ if (error)
+ return (error);
+ error = copyout(&data->cmap_b[index], cmapp->blue, count);
+ return (error);
+}
+
+int
+tga_bt463_check_curcmap(dc, cursorp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cursor *cursorp;
+{
+ int count;
+
+ if ((u_int)cursorp->cmap.index > 2 ||
+ ((u_int)cursorp->cmap.index +
+ (u_int)cursorp->cmap.count) > 2)
+ return (EINVAL);
+ count = cursorp->cmap.count;
+#ifdef UVM
+ if (!uvm_useracc(cursorp->cmap.red, count, B_READ) ||
+ !uvm_useracc(cursorp->cmap.green, count, B_READ) ||
+ !uvm_useracc(cursorp->cmap.blue, count, B_READ))
+ return (EFAULT);
+#else
+ if (!useracc(cursorp->cmap.red, count, B_READ) ||
+ !useracc(cursorp->cmap.green, count, B_READ) ||
+ !useracc(cursorp->cmap.blue, count, B_READ))
+ return (EFAULT);
+#endif
+ return (0);
+}
+
+void
+tga_bt463_set_curcmap(dc, cursorp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cursor *cursorp;
+{
+ struct bt463data *data = dc->dc_ramdac_private;
+ int count, index;
+ bus_space_tag_t tag = dc->dc_memt;
+ bus_space_handle_t regs;
+
+ bus_space_subregion(tag, dc->dc_vaddr, TGA_MEM_CREGS, 512,
+ &regs);
+
+ /* can't fail; parameters have already been checked. */
+ count = cursorp->cmap.count;
+ index = cursorp->cmap.index;
+ copyin(cursorp->cmap.red, &data->curcmap_r[index], count);
+ copyin(cursorp->cmap.green, &data->curcmap_g[index], count);
+ copyin(cursorp->cmap.blue, &data->curcmap_b[index], count);
+ data->changed |= DATA_CURCMAP_CHANGED;
+ tga_bt463_sched_update(tag, regs);
+}
+
+int
+tga_bt463_get_curcmap(dc, cursorp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cursor *cursorp;
+{
+ struct bt463data *data = dc->dc_ramdac_private;
+ int error;
+
+ cursorp->cmap.index = 0; /* DOCMAP */
+ cursorp->cmap.count = 2;
+ if (cursorp->cmap.red != NULL) {
+ error = copyout(data->curcmap_r, cursorp->cmap.red, 2);
+ if (error)
+ return (error);
+ }
+ if (cursorp->cmap.green != NULL) {
+ error = copyout(data->curcmap_g, cursorp->cmap.green, 2);
+ if (error)
+ return (error);
+ }
+ if (cursorp->cmap.blue != NULL) {
+ error = copyout(data->curcmap_b, cursorp->cmap.blue, 2);
+ if (error)
+ return (error);
+ }
+ return (0);
+}
+
+int
+tga_bt463_intr(v)
+ void *v;
+{
+ struct tga_devconfig *dc = v;
+ bus_space_tag_t tag = dc->dc_memt;
+ bus_space_handle_t regs;
+
+ bus_space_subregion(tag, dc->dc_vaddr, TGA_MEM_CREGS, 512,
+ &regs);
+
+ if ( (bus_space_read_4(tag, regs, TGA_REG_SISR*4) & 0x00010001) !=
+ 0x00010001) {
+ printf("Spurious interrupt");
+ return 0;
+ }
+
+ tga_bt463_update(tag, regs, dc->dc_ramdac_private);
+
+ bus_space_write_4(tag, regs, TGA_REG_SISR*4, 0x00000001);
+ bus_space_barrier(tag, regs, TGA_REG_SISR*4, 4, BUS_BARRIER_WRITE);
+ return (1);
+}
+
+/*****************************************************************************/
+
+/*
+ * Internal functions.
+ */
+
+inline void
+tga_bt463_wr_d(tag, regs, btreg, val)
+ bus_space_tag_t tag;
+ bus_space_handle_t regs;
+ u_int btreg;
+ u_int8_t val;
+{
+
+ if (btreg > BT463_REG_MAX)
+ panic("tga_bt463_wr_d: reg %d out of range\n", btreg);
+
+ /*
+ * 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.
+ */
+
+ bus_space_barrier(tag, regs, TGA_REG_EPDR*4, 4, BUS_BARRIER_WRITE);
+ bus_space_write_4(tag, regs, TGA_REG_EPDR*4, (btreg << 10 ) | 0x100 | val);
+ bus_space_barrier(tag, regs, TGA_REG_EPDR*4, 4, BUS_BARRIER_WRITE);
+ bus_space_write_4(tag, regs, TGA_REG_EPDR*4, (btreg << 10 ) | 0x000 | val);
+ bus_space_barrier(tag, regs, TGA_REG_EPDR*4, 4, BUS_BARRIER_WRITE);
+ bus_space_write_4(tag, regs, TGA_REG_EPDR*4, (btreg << 10 ) | 0x100 | val);
+}
+
+inline u_int8_t
+tga_bt463_rd_d(tag, regs, btreg)
+ bus_space_tag_t tag;
+ bus_space_handle_t regs;
+ u_int btreg;
+{
+ tga_reg_t rdval;
+
+ if (btreg > BT463_REG_MAX)
+ panic("tga_bt463_rd_d: reg %d out of range\n", btreg);
+
+ /*
+ * Strobe CE# (high->low->high) since status and data are latched on
+ * the falling and rising edges of this active-low signal.
+ */
+
+ bus_space_barrier(tag, regs, TGA_REG_EPSR*4, 4, BUS_BARRIER_WRITE);
+ bus_space_write_4(tag, regs, TGA_REG_EPSR*4, (btreg << 2) | 2 | 1);
+ bus_space_barrier(tag, regs, TGA_REG_EPSR*4, 4, BUS_BARRIER_WRITE);
+ bus_space_write_4(tag, regs, TGA_REG_EPSR*4, (btreg << 2) | 2 | 0);
+
+ bus_space_barrier(tag, regs, TGA_REG_EPSR*4, 4, BUS_BARRIER_READ);
+
+ rdval = bus_space_read_4(tag, regs, TGA_REG_EPDR*4);
+ bus_space_barrier(tag, regs, TGA_REG_EPSR*4, 4, BUS_BARRIER_WRITE);
+ bus_space_write_4(tag, regs, TGA_REG_EPSR*4, (btreg << 2) | 2 | 1);
+
+ return (rdval >> 16) & 0xff;
+}
+
+inline void
+tga_bt463_wraddr(tag, regs, ireg)
+ bus_space_tag_t tag;
+ bus_space_handle_t regs;
+ u_int16_t ireg;
+{
+ tga_bt463_wr_d(tag, regs, BT463_REG_ADDR_LOW, ireg & 0xff);
+ tga_bt463_wr_d(tag, regs, BT463_REG_ADDR_HIGH, (ireg >> 8) & 0xff);
+}
+
+void
+tga_bt463_update(tag, regs, data)
+ bus_space_tag_t tag;
+ bus_space_handle_t regs;
+ struct bt463data *data;
+{
+ int i, v, valid, blanked;
+
+ v = data->changed;
+
+ /* The Bt463 won't accept window type data except during a blanking
+ * interval. So we (1) do this early in the interrupt, in case it
+ * takes a long time, and (2) blank the screen while doing so, in case
+ * we run out normal vertical blanking.
+ */
+ if (v & DATA_WTYPE_CHANGED) {
+ valid = bus_space_read_4(tag, regs, TGA_REG_VVVR*4);
+ blanked = valid | VVR_BLANK;
+ bus_space_write_4(tag, regs, TGA_REG_VVVR*4, blanked);
+ bus_space_barrier(tag, regs, TGA_REG_VVVR*4, 4,
+ BUS_BARRIER_WRITE);
+ /* spit out the window type data */
+ for (i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
+ tga_bt463_wraddr(tag, regs, BT463_IREG_WINDOW_TYPE_TABLE + i);
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA,
+ (data->window_type[i]) & 0xff); /* B0-7 */
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA,
+ (data->window_type[i] >> 8) & 0xff); /* B8-15 */
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA,
+ (data->window_type[i] >> 16) & 0xff); /* B16-23 */
+
+ }
+ bus_space_write_4(tag, regs, TGA_REG_VVVR*4, valid);
+ bus_space_barrier(tag, regs, TGA_REG_VVVR*4, 4,
+ BUS_BARRIER_WRITE);
+ }
+
+ if (v & DATA_CURCMAP_CHANGED) {
+ tga_bt463_wraddr(tag, regs, BT463_IREG_CURSOR_COLOR_0);
+ /* spit out the cursor data */
+ for (i = 0; i < 2; i++) {
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA,
+ data->curcmap_r[i]);
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA,
+ data->curcmap_g[i]);
+ tga_bt463_wr_d(tag, regs, BT463_REG_IREG_DATA,
+ data->curcmap_b[i]);
+ }
+ }
+
+ if (v & DATA_CMAP_CHANGED) {
+
+ tga_bt463_wraddr(tag, regs, BT463_IREG_CPALETTE_RAM);
+ /* spit out the colormap data */
+ for (i = 0; i < BT463_NCMAP_ENTRIES; i++) {
+ tga_bt463_wr_d(tag, regs, BT463_REG_CMAP_DATA,
+ data->cmap_r[i]);
+ tga_bt463_wr_d(tag, regs, BT463_REG_CMAP_DATA,
+ data->cmap_g[i]);
+ tga_bt463_wr_d(tag, regs, BT463_REG_CMAP_DATA,
+ data->cmap_b[i]);
+ }
+ }
+
+ data->changed = 0;
+
+
+}
diff --git a/sys/dev/pci/tga_bt463.c.orig b/sys/dev/pci/tga_bt463.c.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/sys/dev/pci/tga_bt463.c.orig
diff --git a/sys/dev/pci/tga_bt485.c b/sys/dev/pci/tga_bt485.c
new file mode 100644
index 00000000000..91b7b4049df
--- /dev/null
+++ b/sys/dev/pci/tga_bt485.c
@@ -0,0 +1,624 @@
+/* $NetBSD: tga_bt485.c,v 1.3 1998/08/18 08:22:49 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <vm/vm.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/tgareg.h>
+#include <dev/pci/tgavar.h>
+#include <dev/ic/bt485reg.h>
+
+#include <dev/wscons/wsconsio.h>
+
+/*
+ * Functions exported via the RAMDAC configuration table.
+ */
+void tga_bt485_init __P((struct tga_devconfig *, int));
+int tga_bt485_intr __P((void *));
+int tga_bt485_set_cmap __P((struct tga_devconfig *,
+ struct wsdisplay_cmap *));
+int tga_bt485_get_cmap __P((struct tga_devconfig *,
+ struct wsdisplay_cmap *));
+int tga_bt485_set_cursor __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *));
+int tga_bt485_get_cursor __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *));
+int tga_bt485_set_curpos __P((struct tga_devconfig *,
+ struct wsdisplay_curpos *));
+int tga_bt485_get_curpos __P((struct tga_devconfig *,
+ struct wsdisplay_curpos *));
+int tga_bt485_get_curmax __P((struct tga_devconfig *,
+ struct wsdisplay_curpos *));
+
+const struct tga_ramdac_conf tga_ramdac_bt485 = {
+ "Bt485",
+ tga_bt485_init,
+ tga_bt485_intr,
+ tga_bt485_set_cmap,
+ tga_bt485_get_cmap,
+ tga_bt485_set_cursor,
+ tga_bt485_get_cursor,
+ tga_bt485_set_curpos,
+ tga_bt485_get_curpos,
+ tga_bt485_get_curmax,
+ NULL, /* check_curcmap; not needed */
+ NULL, /* set_curcmap; not needed */
+ NULL, /* get_curcmap; not needed */
+};
+
+/*
+ * Private data.
+ */
+struct bt485data {
+ int changed; /* what changed; see below */
+ int curenb; /* cursor enabled */
+ struct wsdisplay_curpos curpos; /* current cursor position */
+ struct wsdisplay_curpos curhot; /* cursor hotspot */
+ char curcmap_r[2]; /* cursor colormap */
+ char curcmap_g[2];
+ char curcmap_b[2];
+ struct wsdisplay_curpos cursize; /* current cursor size */
+ char curimage[512]; /* cursor image data */
+ char curmask[512]; /* cursor mask data */
+ char cmap_r[256]; /* colormap */
+ char cmap_g[256];
+ char cmap_b[256];
+};
+
+#define DATA_ENB_CHANGED 0x01 /* cursor enable changed */
+#define DATA_CURCMAP_CHANGED 0x02 /* cursor colormap changed */
+#define DATA_CURSHAPE_CHANGED 0x04 /* cursor size, image, mask changed */
+#define DATA_CMAP_CHANGED 0x08 /* colormap changed */
+#define DATA_ALL_CHANGED 0x0f
+
+#define CURSOR_MAX_SIZE 64
+
+/*
+ * Internal functions.
+ */
+inline void tga_bt485_wr_d __P((volatile tga_reg_t *, u_int, u_int8_t));
+inline u_int8_t tga_bt485_rd_d __P((volatile tga_reg_t *, u_int));
+inline void tga_bt485_wr_i __P((volatile tga_reg_t *, u_int8_t, u_int8_t));
+inline u_int8_t tga_bt485_rd_i __P((volatile tga_reg_t *, u_int8_t));
+void tga_bt485_update __P((struct tga_devconfig *, struct bt485data *));
+void tga_bt485_update_curpos __P((struct tga_devconfig *, struct bt485data *));
+
+#define tga_bt485_sched_update(dc) \
+ ((dc)->dc_regs[TGA_REG_SISR] = 0x00010000) /* XXX */
+
+/*****************************************************************************/
+
+/*
+ * Functions exported via the RAMDAC configuration table.
+ */
+
+void
+tga_bt485_init(dc, alloc)
+ struct tga_devconfig *dc;
+ int alloc;
+{
+ u_int8_t regval;
+ struct bt485data tmp, *data;
+ int i;
+
+ /*
+ * Init the BT485 for normal operation.
+ */
+
+ /*
+ * Allow indirect register access. (Actually, this is
+ * already enabled. In fact, if it is _disabled_, for
+ * some reason the monitor appears to lose sync!!! (?!?!)
+ */
+ regval = tga_bt485_rd_d(dc->dc_regs, BT485_REG_COMMAND_0);
+ regval |= 0x80;
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_COMMAND_0, regval);
+
+ /* Set the RAMDAC to 8BPP (no interestion options). */
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_COMMAND_1, 0x40);
+
+ /* Disable the cursor (for now) */
+ regval = tga_bt485_rd_d(dc->dc_regs, BT485_REG_COMMAND_2);
+ regval &= ~0x03;
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_COMMAND_2, regval);
+
+ /* Use a 64x64x2 cursor */
+ regval = tga_bt485_rd_d(dc->dc_regs, BT485_IREG_COMMAND_3);
+ regval |= 0x04;
+ tga_bt485_wr_d(dc->dc_regs, BT485_IREG_COMMAND_3, regval);
+
+ /*
+ * If we should allocate a new private info struct, do so.
+ * Otherwise, use the one we have (if it's there), or
+ * use the temporary one on the stack.
+ */
+ if (alloc) {
+ if (dc->dc_ramdac_private != NULL)
+ panic("tga_bt485_init: already have private struct");
+ dc->dc_ramdac_private = malloc(sizeof *data, M_DEVBUF,
+ M_WAITOK);
+ }
+ if (dc->dc_ramdac_private != NULL)
+ data = dc->dc_ramdac_private;
+ else
+ data = &tmp;
+
+ /*
+ * Initalize the RAMDAC info struct to hold all of our
+ * data, and fill it in.
+ */
+ data->changed = DATA_ALL_CHANGED;
+
+ data->curenb = 0; /* cursor disabled */
+ data->curpos.x = data->curpos.y = 0; /* right now at 0,0 */
+ data->curhot.x = data->curhot.y = 0; /* hot spot at 0,0 */
+
+ /* initial cursor colormap: 0 is black, 1 is white */
+ data->curcmap_r[0] = data->curcmap_g[0] = data->curcmap_b[0] = 0;
+ data->curcmap_r[1] = data->curcmap_g[1] = data->curcmap_b[1] = 0xff;
+
+ /* initial cursor data: 64x64 block of white. */
+ data->cursize.x = data->cursize.y = 64;
+ for (i = 0; i < 512; i++)
+ data->curimage[i] = data->curmask[i] = 0xff;
+
+ /* Initial colormap: 0 is black, everything else is white */
+ data->cmap_r[0] = data->cmap_g[0] = data->cmap_b[0] = 0;
+ for (i = 1; i < 256; i++)
+ data->cmap_r[i] = data->cmap_g[i] = data->cmap_b[i] = 255;
+
+ tga_bt485_update(dc, data);
+
+ dc->dc_regs[TGA_REG_SISR] = 0x00000001; /* XXX */
+}
+
+int
+tga_bt485_set_cmap(dc, cmapp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cmap *cmapp;
+{
+ struct bt485data *data = dc->dc_ramdac_private;
+ int count, index, s;
+
+ if ((u_int)cmapp->index >= 256 ||
+ ((u_int)cmapp->index + (u_int)cmapp->count) > 256)
+ return (EINVAL);
+#ifdef UVM
+ if (!uvm_useracc(cmapp->red, cmapp->count, B_READ) ||
+ !uvm_useracc(cmapp->green, cmapp->count, B_READ) ||
+ !uvm_useracc(cmapp->blue, cmapp->count, B_READ))
+ return (EFAULT);
+#else
+ if (!useracc(cmapp->red, cmapp->count, B_READ) ||
+ !useracc(cmapp->green, cmapp->count, B_READ) ||
+ !useracc(cmapp->blue, cmapp->count, B_READ))
+ return (EFAULT);
+#endif
+
+ s = spltty();
+
+ index = cmapp->index;
+ count = cmapp->count;
+ copyin(cmapp->red, &data->cmap_r[index], count);
+ copyin(cmapp->green, &data->cmap_g[index], count);
+ copyin(cmapp->blue, &data->cmap_b[index], count);
+
+ data->changed |= DATA_CMAP_CHANGED;
+
+ tga_bt485_sched_update(dc);
+ splx(s);
+
+ return (0);
+}
+
+int
+tga_bt485_get_cmap(dc, cmapp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cmap *cmapp;
+{
+ struct bt485data *data = dc->dc_ramdac_private;
+ int error, count, index;
+
+ if ((u_int)cmapp->index >= 256 ||
+ ((u_int)cmapp->index + (u_int)cmapp->count) > 256)
+ return (EINVAL);
+
+ count = cmapp->count;
+ index = cmapp->index;
+
+ error = copyout(&data->cmap_r[index], cmapp->red, count);
+ if (error)
+ return (error);
+ error = copyout(&data->cmap_g[index], cmapp->green, count);
+ if (error)
+ return (error);
+ error = copyout(&data->cmap_b[index], cmapp->blue, count);
+ return (error);
+}
+
+int
+tga_bt485_set_cursor(dc, cursorp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cursor *cursorp;
+{
+ struct bt485data *data = dc->dc_ramdac_private;
+ int count, index, v, s;
+
+ v = cursorp->which;
+
+ /*
+ * For DOCMAP and DOSHAPE, verify that parameters are OK
+ * before we do anything that we can't recover from.
+ */
+ if (v & WSDISPLAY_CURSOR_DOCMAP) {
+ if ((u_int)cursorp->cmap.index > 2 ||
+ ((u_int)cursorp->cmap.index +
+ (u_int)cursorp->cmap.count) > 2)
+ return (EINVAL);
+ count = cursorp->cmap.count;
+#ifdef UVM
+ if (!uvm_useracc(cursorp->cmap.red, count, B_READ) ||
+ !uvm_useracc(cursorp->cmap.green, count, B_READ) ||
+ !uvm_useracc(cursorp->cmap.blue, count, B_READ))
+ return (EFAULT);
+#else
+ if (!useracc(cursorp->cmap.red, count, B_READ) ||
+ !useracc(cursorp->cmap.green, count, B_READ) ||
+ !useracc(cursorp->cmap.blue, count, B_READ))
+ return (EFAULT);
+#endif
+ }
+ if (v & WSDISPLAY_CURSOR_DOSHAPE) {
+ if ((u_int)cursorp->size.x > CURSOR_MAX_SIZE ||
+ (u_int)cursorp->size.y > CURSOR_MAX_SIZE)
+ return (EINVAL);
+ count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y;
+#ifdef UVM
+ if (!uvm_useracc(cursorp->image, count, B_READ) ||
+ !uvm_useracc(cursorp->mask, count, B_READ))
+ return (EFAULT);
+#else
+ if (!useracc(cursorp->image, count, B_READ) ||
+ !useracc(cursorp->mask, count, B_READ))
+ return (EFAULT);
+#endif
+ }
+
+ if (v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOCUR)) {
+ if (v & WSDISPLAY_CURSOR_DOPOS)
+ data->curpos = cursorp->pos;
+ if (v & WSDISPLAY_CURSOR_DOCUR)
+ data->curhot = cursorp->hot;
+ tga_bt485_update_curpos(dc, data);
+ }
+
+ s = spltty();
+
+ /* Parameters are OK; perform the requested operations. */
+ if (v & WSDISPLAY_CURSOR_DOCUR) {
+ data->curenb = cursorp->enable;
+ data->changed |= DATA_ENB_CHANGED;
+ }
+ if (v & WSDISPLAY_CURSOR_DOCMAP) {
+ count = cursorp->cmap.count;
+ index = cursorp->cmap.index;
+ copyin(cursorp->cmap.red, &data->curcmap_r[index], count);
+ copyin(cursorp->cmap.green, &data->curcmap_g[index], count);
+ copyin(cursorp->cmap.blue, &data->curcmap_b[index], count);
+ data->changed |= DATA_CURCMAP_CHANGED;
+ }
+ if (v & WSDISPLAY_CURSOR_DOSHAPE) {
+ data->cursize = cursorp->size;
+ count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y;
+ bzero(data->curimage, sizeof data->curimage);
+ bzero(data->curmask, sizeof data->curmask);
+ copyin(cursorp->image, data->curimage, count); /* can't fail */
+ copyin(cursorp->mask, data->curmask, count); /* can't fail */
+ data->changed |= DATA_CURSHAPE_CHANGED;
+ }
+
+ if (data->changed)
+ tga_bt485_sched_update(dc);
+ splx(s);
+
+ return (0);
+}
+
+int
+tga_bt485_get_cursor(dc, cursorp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_cursor *cursorp;
+{
+ struct bt485data *data = dc->dc_ramdac_private;
+ int error, count;
+
+ /* we return everything they want */
+ cursorp->which = WSDISPLAY_CURSOR_DOALL;
+
+ cursorp->enable = data->curenb; /* DOCUR */
+ cursorp->pos = data->curpos; /* DOPOS */
+ cursorp->hot = data->curhot; /* DOHOT */
+
+ cursorp->cmap.index = 0; /* DOCMAP */
+ cursorp->cmap.count = 2;
+ if (cursorp->cmap.red != NULL) {
+ error = copyout(data->curcmap_r, cursorp->cmap.red, 2);
+ if (error)
+ return (error);
+ }
+ if (cursorp->cmap.green != NULL) {
+ error = copyout(data->curcmap_g, cursorp->cmap.green, 2);
+ if (error)
+ return (error);
+ }
+ if (cursorp->cmap.blue != NULL) {
+ error = copyout(data->curcmap_b, cursorp->cmap.blue, 2);
+ if (error)
+ return (error);
+ }
+
+ cursorp->size = data->cursize; /* DOSHAPE */
+ if (cursorp->image != NULL) {
+ count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y;
+ error = copyout(data->curimage, cursorp->image, count);
+ if (error)
+ return (error);
+ error = copyout(data->curmask, cursorp->mask, count);
+ if (error)
+ return (error);
+ }
+
+ return (0);
+}
+
+int
+tga_bt485_set_curpos(dc, curposp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_curpos *curposp;
+{
+ struct bt485data *data = dc->dc_ramdac_private;
+
+ data->curpos = *curposp;
+ tga_bt485_update_curpos(dc, data);
+
+ return (0);
+}
+
+int
+tga_bt485_get_curpos(dc, curposp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_curpos *curposp;
+{
+ struct bt485data *data = dc->dc_ramdac_private;
+
+ *curposp = data->curpos;
+ return (0);
+}
+
+int
+tga_bt485_get_curmax(dc, curposp)
+ struct tga_devconfig *dc;
+ struct wsdisplay_curpos *curposp;
+{
+
+ curposp->x = curposp->y = CURSOR_MAX_SIZE;
+ return (0);
+}
+
+int
+tga_bt485_intr(v)
+ void *v;
+{
+ struct tga_devconfig *dc = v;
+
+ if ((dc->dc_regs[TGA_REG_SISR] & 0x00010001) != 0x00010001)
+ return 0;
+ tga_bt485_update(dc, dc->dc_ramdac_private);
+ dc->dc_regs[TGA_REG_SISR] = 0x00000001;
+ return (1);
+}
+
+/*****************************************************************************/
+
+/*
+ * Internal functions.
+ */
+
+inline void
+tga_bt485_wr_d(tgaregs, btreg, val)
+ volatile tga_reg_t *tgaregs;
+ u_int btreg;
+ u_int8_t val;
+{
+
+ if (btreg > BT485_REG_MAX)
+ panic("tga_bt485_wr_d: reg %d out of range\n", btreg);
+
+ tgaregs[TGA_REG_EPDR] = (btreg << 9) | (0 << 8 ) | val; /* XXX */
+#ifdef __alpha__
+ alpha_mb();
+#endif
+}
+
+inline u_int8_t
+tga_bt485_rd_d(tgaregs, btreg)
+ volatile tga_reg_t *tgaregs;
+ u_int btreg;
+{
+ tga_reg_t rdval;
+
+ if (btreg > BT485_REG_MAX)
+ panic("tga_bt485_rd_d: reg %d out of range\n", btreg);
+
+ tgaregs[TGA_REG_EPSR] = (btreg << 1) | 0x1; /* XXX */
+#ifdef __alpha__
+ alpha_mb();
+#endif
+
+ rdval = tgaregs[TGA_REG_EPDR];
+ return (rdval >> 16) & 0xff; /* XXX */
+}
+
+inline void
+tga_bt485_wr_i(tgaregs, ireg, val)
+ volatile tga_reg_t *tgaregs;
+ u_int8_t ireg;
+ u_int8_t val;
+{
+ tga_bt485_wr_d(tgaregs, BT485_REG_PCRAM_WRADDR, ireg);
+ tga_bt485_wr_d(tgaregs, BT485_REG_EXTENDED, val);
+}
+
+inline u_int8_t
+tga_bt485_rd_i(tgaregs, ireg)
+ volatile tga_reg_t *tgaregs;
+ u_int8_t ireg;
+{
+ tga_bt485_wr_d(tgaregs, BT485_REG_PCRAM_WRADDR, ireg);
+ return (tga_bt485_rd_d(tgaregs, BT485_REG_EXTENDED));
+}
+
+void
+tga_bt485_update(dc, data)
+ struct tga_devconfig *dc;
+ struct bt485data *data;
+{
+ u_int8_t regval;
+ int count, i, v;
+
+ v = data->changed;
+ data->changed = 0;
+
+ if (v & DATA_ENB_CHANGED) {
+ regval = tga_bt485_rd_d(dc->dc_regs, BT485_REG_COMMAND_2);
+ if (data->curenb)
+ regval |= 0x01;
+ else
+ regval &= ~0x03;
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_COMMAND_2, regval);
+ }
+
+ if (v & DATA_CURCMAP_CHANGED) {
+ /* addr[9:0] assumed to be 0 */
+ /* set addr[7:0] to 1 */
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_COC_WRADDR, 0x01);
+
+ /* spit out the cursor data */
+ for (i = 0; i < 2; i++) {
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_COCDATA,
+ data->curcmap_r[i]);
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_COCDATA,
+ data->curcmap_g[i]);
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_COCDATA,
+ data->curcmap_b[i]);
+ }
+ }
+
+ if (v & DATA_CURSHAPE_CHANGED) {
+ count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y;
+
+ /*
+ * Write the cursor image data:
+ * set addr[9:8] to 0,
+ * set addr[7:0] to 0,
+ * spit it all out.
+ */
+ regval = tga_bt485_rd_i(dc->dc_regs,
+ BT485_IREG_COMMAND_3);
+ regval &= ~0x03;
+ tga_bt485_wr_i(dc->dc_regs, BT485_IREG_COMMAND_3,
+ regval);
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_PCRAM_WRADDR, 0);
+ for (i = 0; i < count; i++)
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_RAM,
+ data->curimage[i]);
+
+ /*
+ * Write the cursor mask data:
+ * set addr[9:8] to 2,
+ * set addr[7:0] to 0,
+ * spit it all out.
+ */
+ regval = tga_bt485_rd_i(dc->dc_regs,
+ BT485_IREG_COMMAND_3);
+ regval &= ~0x03; regval |= 0x02;
+ tga_bt485_wr_i(dc->dc_regs, BT485_IREG_COMMAND_3,
+ regval);
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_PCRAM_WRADDR, 0);
+ for (i = 0; i < count; i++)
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_RAM,
+ data->curmask[i]);
+
+ /* set addr[9:0] back to 0 */
+ regval = tga_bt485_rd_i(dc->dc_regs, BT485_IREG_COMMAND_3);
+ regval &= ~0x03;
+ tga_bt485_wr_i(dc->dc_regs, BT485_IREG_COMMAND_3, regval);
+ }
+
+ if (v & DATA_CMAP_CHANGED) {
+ /* addr[9:0] assumed to be 0 */
+ /* set addr[7:0] to 0 */
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_PCRAM_WRADDR, 0x00);
+
+ /* spit out the cursor data */
+ for (i = 0; i < 256; i++) {
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_PALETTE,
+ data->cmap_r[i]);
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_PALETTE,
+ data->cmap_g[i]);
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_PALETTE,
+ data->cmap_b[i]);
+ }
+ }
+}
+
+void
+tga_bt485_update_curpos(dc, data)
+ struct tga_devconfig *dc;
+ struct bt485data *data;
+{
+ int s, x, y;
+
+ s = spltty();
+
+ x = data->curpos.x + CURSOR_MAX_SIZE - data->curhot.x;
+ y = data->curpos.y + CURSOR_MAX_SIZE - data->curhot.y;
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_X_LOW, x & 0xff);
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_X_HIGH, (x >> 8) & 0x0f);
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_Y_LOW, y & 0xff);
+ tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_Y_HIGH, (y >> 8) & 0x0f);
+
+ splx(s);
+}
diff --git a/sys/dev/pci/tga_bt485.c.orig b/sys/dev/pci/tga_bt485.c.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/sys/dev/pci/tga_bt485.c.orig
diff --git a/sys/dev/pci/tga_conf.c b/sys/dev/pci/tga_conf.c
new file mode 100644
index 00000000000..88b5e206dc1
--- /dev/null
+++ b/sys/dev/pci/tga_conf.c
@@ -0,0 +1,183 @@
+/* $NetBSD: tga_conf.c,v 1.1 1998/04/15 20:16:32 drochner Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/tgareg.h>
+#include <dev/pci/tgavar.h>
+
+#undef KB
+#define KB * 1024
+#undef MB
+#define MB * 1024 * 1024
+
+static const struct tga_conf tga_configs[TGA_TYPE_UNKNOWN] = {
+ /* TGA_TYPE_T8_01 */
+ {
+ "T8-01",
+ &tga_ramdac_bt485,
+ 8,
+ 4 MB,
+ 2 KB,
+ 1, { 2 MB, 0 }, { 1 MB, 0 },
+ 0, { 0, 0 }, { 0, 0 },
+ },
+ /* TGA_TYPE_T8_02 */
+ {
+ "T8-02",
+ &tga_ramdac_bt485,
+ 8,
+ 4 MB,
+ 4 KB,
+ 1, { 2 MB, 0 }, { 2 MB, 0 },
+ 0, { 0, 0 }, { 0, 0 },
+ },
+ /* TGA_TYPE_T8_22 */
+ {
+ "T8-22",
+ &tga_ramdac_bt485,
+ 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",
+ &tga_ramdac_bt485,
+ 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",
+ &tga_ramdac_bt463,
+ 32,
+ 16 MB,
+ 8 KB,
+ 1, { 8 MB, 0 }, { 4 MB, 0 },
+ 0, { 0, 0 }, { 0, 0 },
+ },
+ /* TGA_TYPE_T32_08 */
+ {
+ "T32-08",
+ &tga_ramdac_bt463,
+ 32,
+ 16 MB,
+ 16 KB,
+ 1, { 8 MB, 0 }, { 8 MB, 0 },
+ 0, { 0, 0 }, { 0, 0 },
+ },
+ /* TGA_TYPE_T32_88 */
+ {
+ "T32-88",
+ &tga_ramdac_bt463,
+ 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;
+{
+ 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);
+}
+
+const struct tga_conf *
+tga_getconf(type)
+ int type;
+{
+
+ if (type >= 0 && type < TGA_TYPE_UNKNOWN)
+ return &tga_configs[type];
+
+ return (NULL);
+}
+
diff --git a/sys/dev/pci/tga_conf.c.orig b/sys/dev/pci/tga_conf.c.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/sys/dev/pci/tga_conf.c.orig
diff --git a/sys/dev/pci/tgareg.h b/sys/dev/pci/tgareg.h
new file mode 100644
index 00000000000..d47033fce82
--- /dev/null
+++ b/sys/dev/pci/tgareg.h
@@ -0,0 +1,174 @@
+/* $NetBSD: tgareg.h,v 1.2 1998/04/29 02:11:19 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _ALPHA_INCLUDE_TGAREG_H_
+#define _ALPHA_INCLUDE_TGAREG_H_
+
+/*
+ * Device-specific PCI register offsets and contents.
+ */
+
+#define TGA_PCIREG_PVRR 0x40 /* PCI Address Extension Register */
+
+#define TGA_PCIREG_PAER 0x44 /* PCI VGA Redirect Register */
+
+/*
+ * TGA Memory Space offsets
+ */
+
+#define TGA_MEM_ALTROM 0x0000000 /* 0MB -- Alternate ROM space */
+#define TGA_MEM_CREGS 0x0100000 /* 1MB -- Core Registers */
+/* Display and Back Buffers mapped at config-dependent addresses */
+
+/*
+ * TGA Core Space register numbers and contents.
+ */
+
+typedef u_int32_t tga_reg_t;
+
+#define TGA_REG_GCBR0 0x000 /* Copy buffer 0 */
+#define TGA_REG_GCBR1 0x001 /* Copy buffer 1 */
+#define TGA_REG_GCBR2 0x002 /* Copy buffer 2 */
+#define TGA_REG_GCBR3 0x003 /* Copy buffer 3 */
+#define TGA_REG_GCBR4 0x004 /* Copy buffer 4 */
+#define TGA_REG_GCBR5 0x005 /* Copy buffer 5 */
+#define TGA_REG_GCBR6 0x006 /* Copy buffer 6 */
+#define TGA_REG_GCBR7 0x007 /* Copy buffer 7 */
+
+#define TGA_REG_GFGR 0x008 /* Foreground */
+#define TGA_REG_GBGR 0x009 /* Background */
+#define TGA_REG_GPMR 0x00a /* Plane Mask */
+#define TGA_REG_GPXR_S 0x00b /* Pixel Mask (one-shot) */
+#define TGA_REG_GMOR 0x00c /* Mode */
+#define TGA_REG_GOPR 0x00d /* Raster Operation */
+#define TGA_REG_GPSR 0x00e /* Pixel Shift */
+#define TGA_REG_GADR 0x00f /* Address */
+
+#define TGA_REG_GB1R 0x010 /* Bresenham 1 */
+#define TGA_REG_GB2R 0x011 /* Bresenham 2 */
+#define TGA_REG_GB3R 0x012 /* Bresenham 3 */
+
+#define TGA_REG_GCTR 0x013 /* Continue */
+#define TGA_REG_GDER 0x014 /* Deep */
+/* reserved 0x015 */
+#define TGA_REG_GSMR 0x016 /* Stencil Mode */
+#define TGA_REG_GPXR_P 0x017 /* Pixel Mask (persistent) */
+#define TGA_REG_CCBR 0x018 /* Cursor Base Address */
+#define TGA_REG_VHCR 0x019 /* Horizontal Control */
+#define TGA_REG_VVCR 0x01a /* Vertical Control */
+#define TGA_REG_VVBR 0x01b /* Video Base Address */
+#define TGA_REG_VVVR 0x01c /* Video Valid */
+#define TGA_REG_CXYR 0x01d /* Cursor XY */
+#define TGA_REG_VSAR 0x01e /* Video Shift Address */
+#define TGA_REG_SISR 0x01f /* Interrupt Status */
+#define TGA_REG_GDAR 0x020 /* Data */
+#define TGA_REG_GRIR 0x021 /* Red Increment */
+#define TGA_REG_GGIR 0x022 /* Green Increment */
+#define TGA_REG_GBIR 0x023 /* Blue Increment */
+#define TGA_REG_GZIR_L 0x024 /* Z-increment Low */
+#define TGA_REG_GZIR_H 0x025 /* Z-Increment High */
+#define TGA_REG_GDBR 0x026 /* DMA Base Address */
+#define TGA_REG_GBWR 0x027 /* Bresenham Width */
+#define TGA_REG_GZVR_L 0x028 /* Z-value Low */
+#define TGA_REG_GZVR_H 0x029 /* Z-value High */
+#define TGA_REG_GZBR 0x02a /* Z-base address */
+/* GADR alias 0x02b */
+#define TGA_REG_GRVR 0x02c /* Red Value */
+#define TGA_REG_GGVR 0x02d /* Green Value */
+#define TGA_REG_GBVR 0x02e /* Blue Value */
+#define TGA_REG_GSWR 0x02f /* Span Width */
+#define TGA_REG_EPSR 0x030 /* Pallete and DAC Setup */
+
+/* reserved 0x031 - 0x3f */
+
+#define TGA_REG_GSNR0 0x040 /* Slope-no-go 0 */
+#define TGA_REG_GSNR1 0x041 /* Slope-no-go 1 */
+#define TGA_REG_GSNR2 0x042 /* Slope-no-go 2 */
+#define TGA_REG_GSNR3 0x043 /* Slope-no-go 3 */
+#define TGA_REG_GSNR4 0x044 /* Slope-no-go 4 */
+#define TGA_REG_GSNR5 0x045 /* Slope-no-go 5 */
+#define TGA_REG_GSNR6 0x046 /* Slope-no-go 6 */
+#define TGA_REG_GSNR7 0x047 /* Slope-no-go 7 */
+
+#define TGA_REG_GSLR0 0x048 /* Slope 0 */
+#define TGA_REG_GSLR1 0x049 /* Slope 1 */
+#define TGA_REG_GSLR2 0x04a /* Slope 2 */
+#define TGA_REG_GSLR3 0x04b /* Slope 3 */
+#define TGA_REG_GSLR4 0x04c /* Slope 4 */
+#define TGA_REG_GSLR5 0x04d /* Slope 5 */
+#define TGA_REG_GSLR6 0x04e /* Slope 6 */
+#define TGA_REG_GSLR7 0x04f /* Slope 7 */
+
+#define TGA_REG_GBCR0 0x050 /* Block Color 0 */
+#define TGA_REG_GBCR1 0x051 /* Block Color 1 */
+#define TGA_REG_GBCR2 0x052 /* Block Color 2 */
+#define TGA_REG_GBCR3 0x053 /* Block Color 3 */
+#define TGA_REG_GBCR4 0x054 /* Block Color 4 */
+#define TGA_REG_GBCR5 0x055 /* Block Color 5 */
+#define TGA_REG_GBCR6 0x056 /* Block Color 6 */
+#define TGA_REG_GBCR7 0x057 /* Block Color 7 */
+
+#define TGA_REG_GCSR 0x058 /* Copy 64 Source */
+#define TGA_REG_GCDR 0x059 /* Copy 64 Destination */
+/* GC[SD]R aliases 0x05a - 0x05f */
+
+/* reserved 0x060 - 0x077 */
+
+#define TGA_REG_ERWR 0x078 /* EEPROM write */
+
+/* reserved 0x079 */
+
+#define TGA_REG_ECGR 0x07a /* Clock */
+
+/* reserved 0x07b */
+
+#define TGA_REG_EPDR 0x07c /* Pallete and DAC Data */
+
+/* reserved 0x07d */
+
+#define TGA_REG_SCSR 0x07e /* Command Status */
+
+/* reserved 0x07f */
+
+/*
+ * Video Valid Register
+ */
+#define VVR_VIDEOVALID 0x00000001 /* 0 VGA, 1 TGA2 (TGA2 only) */
+#define VVR_BLANK 0x00000002 /* 0 active, 1 blank */
+#define VVR_CURSOR 0x00000004 /* 0 disable, 1 enable (TGA2 R/O) */
+#define VVR_INTERLACE 0x00000008 /* 0 N/Int, 1 Int. (TGA2 R/O) */
+#define VVR_DPMS_MASK 0x00000030 /* See "DMPS mask" below */
+#define VVR_DPMS_SHIFT 4
+#define VVR_DDC 0x00000040 /* DDC-in pin value (R/O) */
+#define VVR_TILED 0x00000400 /* 0 linear, 1 tiled (not on TGA2) */
+#define VVR_LDDLY_MASK 0x01ff0000 /* load delay in quad pixel clock ticks
+ (not on TGA2) */
+#define VVR_LDDLY_SHIFT 16
+
+#endif /* _ALPHA_INCLUDE_TGAREG_H_ */
diff --git a/sys/dev/pci/tgareg.h.orig b/sys/dev/pci/tgareg.h.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/sys/dev/pci/tgareg.h.orig
diff --git a/sys/dev/pci/tgavar.h b/sys/dev/pci/tgavar.h
new file mode 100644
index 00000000000..59d9b1017af
--- /dev/null
+++ b/sys/dev/pci/tgavar.h
@@ -0,0 +1,155 @@
+/* $NetBSD: tgavar.h,v 1.4 1998/08/18 08:23:46 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <dev/pci/tgareg.h>
+#include <dev/rcons/raster.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wscons_raster.h>
+
+struct tga_devconfig;
+struct fbcmap;
+struct fbcursor;
+struct fbcurpos;
+
+struct tga_ramdac_conf {
+ char *tgar_name;
+ void (*tgar_init) __P((struct tga_devconfig *, int));
+ int (*tgar_intr) __P((void *));
+ int (*tgar_set_cmap) __P((struct tga_devconfig *,
+ struct wsdisplay_cmap *));
+ int (*tgar_get_cmap) __P((struct tga_devconfig *,
+ struct wsdisplay_cmap *));
+ int (*tgar_set_cursor) __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *));
+ int (*tgar_get_cursor) __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *));
+ int (*tgar_set_curpos) __P((struct tga_devconfig *,
+ struct wsdisplay_curpos *));
+ int (*tgar_get_curpos) __P((struct tga_devconfig *,
+ struct wsdisplay_curpos *));
+ int (*tgar_get_curmax) __P((struct tga_devconfig *,
+ struct wsdisplay_curpos *));
+
+ /* Only called from the TGA built-in cursor handling code. */
+ int (*tgar_check_curcmap) __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *));
+ void (*tgar_set_curcmap) __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *));
+ int (*tgar_get_curcmap) __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *));
+};
+
+struct tga_conf {
+ char *tgac_name; /* name for this board type */
+
+ const struct tga_ramdac_conf
+ *tgac_ramdac; /* the RAMDAC type; see above */
+ 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_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. */
+
+ tga_reg_t *dc_regs; /* registers; XXX: need aliases */
+
+ int dc_tga_type; /* the device type; see below */
+ const struct tga_conf *dc_tgaconf; /* device buffer configuration */
+
+ vaddr_t dc_vaddr; /* memory space virtual base address */
+ paddr_t dc_paddr; /* memory space physical base address */
+
+ int dc_wid; /* width of frame buffer */
+ int dc_ht; /* height of frame buffer */
+ int dc_rowbytes; /* bytes in a FB scan line */
+
+ vaddr_t dc_videobase; /* base of flat frame buffer */
+
+ struct raster dc_raster; /* raster description */
+ struct rcons dc_rcons; /* raster blitter control info */
+
+ int dc_blanked; /* currently had video disabled */
+ void *dc_ramdac_private; /* RAMDAC private storage */
+};
+
+struct tga_softc {
+ struct device sc_dev;
+
+ struct tga_devconfig *sc_dc; /* device configuration */
+ void *sc_intr; /* interrupt handler info */
+ /* XXX should record intr fns/arg */
+
+ 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 DEVICE_IS_TGA(class, id) \
+ ((PCI_VENDOR(id) == PCI_VENDOR_DEC && \
+ PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21030) ? 10 : 0)
+
+int tga_cnattach __P((bus_space_tag_t, bus_space_tag_t, pci_chipset_tag_t,
+ int, int, int));
+
+int tga_identify __P((tga_reg_t *));
+const struct tga_conf *tga_getconf __P((int));
+
+extern const struct tga_ramdac_conf tga_ramdac_bt463;
+extern const struct tga_ramdac_conf tga_ramdac_bt485;
+
+int tga_builtin_set_cursor __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *));
+int tga_builtin_get_cursor __P((struct tga_devconfig *,
+ struct wsdisplay_cursor *));
+int tga_builtin_set_curpos __P((struct tga_devconfig *,
+ struct wsdisplay_curpos *));
+int tga_builtin_get_curpos __P((struct tga_devconfig *,
+ struct wsdisplay_curpos *));
+int tga_builtin_get_curmax __P((struct tga_devconfig *,
+ struct wsdisplay_curpos *));
diff --git a/sys/dev/pci/tgavar.h.orig b/sys/dev/pci/tgavar.h.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/sys/dev/pci/tgavar.h.orig