The "mi" TGA driver. It's still not of much use on anything but alpha

because it depends on initialization by the firmware.
Further, an mi mmap() is needed...
This commit is contained in:
drochner 1998-04-15 20:16:30 +00:00
parent f82e238b10
commit eda73f204f
7 changed files with 1878 additions and 0 deletions

64
sys/dev/ic/bt485reg.h Normal file
View File

@ -0,0 +1,64 @@
/* $NetBSD: bt485reg.h,v 1.1 1998/04/15 20:16:30 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.
*/
/*
* Register definitions for the Brooktree Bt485A 170MHz Monolithic
* CMOS True-Color RAMDAC.
*/
/*
* Directly-addressed registers.
*/
#define BT485_REG_PCRAM_WRADDR 0x00
#define BT485_REG_PALETTE 0x01
#define BT485_REG_PIXMASK 0x02
#define BT485_REG_PCRAM_RDADDR 0x03
#define BT485_REG_COC_WRADDR 0x04
#define BT485_REG_COCDATA 0x05
#define BT485_REG_COMMAND_0 0x06
#define BT485_REG_COC_RDADDR 0x07
#define BT485_REG_COMMAND_1 0x08
#define BT485_REG_COMMAND_2 0x09
#define BT485_REG_STATUS 0x0a
#define BT485_REG_EXTENDED BT485_REG_STATUS
#define BT485_REG_CURSOR_RAM 0x0b
#define BT485_REG_CURSOR_X_LOW 0x0c
#define BT485_REG_CURSOR_X_HIGH 0x0d
#define BT485_REG_CURSOR_Y_LOW 0x0e
#define BT485_REG_CURSOR_Y_HIGH 0x0f
#define BT485_REG_MAX 0x0f
#define BT485_IREG_STATUS 0x00
#define BT485_IREG_COMMAND_3 0x01
#define BT485_IREG_COMMAND_4 0x02
#define BT485_IREG_RSA 0x20
#define BT485_IREG_GSA 0x21
#define BT485_IREG_BSA 0x22

652
sys/dev/pci/tga.c Normal file
View File

@ -0,0 +1,652 @@
/* $NetBSD: tga.c,v 1.1 1998/04/15 20:16:31 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 <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>
#ifdef __alpha__
#include <machine/pte.h>
#endif
int tgamatch __P((struct device *, struct cfdata *, void *));
void tgaattach __P((struct device *, struct device *, void *));
int tgaprint __P((void *, const char *));
struct cfattach tga_ca = {
sizeof(struct tga_softc), 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;
struct wsdisplay_emulops tga_emulops = {
rcons_cursor, /* could use hardware cursor; punt */
rcons_putstr,
rcons_copycols,
rcons_erasecols,
rcons_copyrows,
rcons_eraserows,
};
struct wsscreen_descr tga_stdscreen = {
"std",
0, 0, /* will be filled in */
&tga_emulops,
0, 0
};
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
};
int tga_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
int tga_mmap __P((void *, off_t, int));
static int tga_alloc_screen __P((void *, const struct wsscreen_descr *,
void **, int *, int *));
static void tga_free_screen __P((void *, void *));
static void tga_show_screen __P((void *, void *));
static int tga_load_font __P((void *, void *, int, int, int, void *));
struct wsdisplay_accessops tga_accessops = {
tga_ioctl,
tga_mmap,
tga_alloc_screen,
tga_free_screen,
tga_show_screen,
tga_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, flags;
dc->dc_memt = memt;
dc->dc_pc = pc;
dc->dc_pcitag = tag;
/* XXX magic number */
if (pci_mapreg_info(pc, tag, 0x10,
PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
&dc->dc_pcipaddr, &pcisize, &flags))
return;
if ((flags & BUS_SPACE_MAP_CACHEABLE) == 0) /* XXX */
panic("tga memory not cacheable");
if (bus_space_map(memt, dc->dc_pcipaddr, pcisize,
BUS_SPACE_MAP_CACHEABLE | BUS_SPACE_MAP_LINEAR, &dc->dc_vaddr))
return;
#ifdef __alpha__
dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */
#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)
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;
/* 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);
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);
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 fbt
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_GVIDEO:
if (*(u_int *)data == WSDISPLAYIO_VIDEO_OFF)
tga_blank(sc->sc_dc);
else
tga_unblank(sc->sc_dc);
return (0);
case WSDISPLAYIO_SVIDEO:
*(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)
return -1;
return alpha_btop(sc->sc_dc->dc_paddr + offset);
#else
return (-1);
#endif
}
int
tga_alloc_screen(v, type, cookiep, curxp, curyp)
void *v;
const struct wsscreen_descr *type;
void **cookiep;
int *curxp, *curyp;
{
struct tga_softc *sc = v;
if (sc->nscreens > 0)
return (ENOMEM);
*cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */
*curxp = 0;
*curyp = 0;
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--;
}
void
tga_show_screen(v, cookie)
void *v;
void *cookie;
{
}
static int
tga_load_font(v, cookie, first, num, stride, data)
void *v;
void *cookie;
int first, num, stride;
void *data;
{
return (EINVAL);
}
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;
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);
wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rcons,
0, 0);
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] |= 0x02; /* XXX */
}
}
void
tga_unblank(dc)
struct tga_devconfig *dc;
{
if (dc->dc_blanked) {
dc->dc_blanked = 0;
dc->dc_regs[TGA_REG_VVVR] &= ~0x02; /* 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 v;
#if 0
int count;
#endif
v = cursorp->which;
#if 0
if (v & WSDISPLAY_CURSOR_DOCMAP) /* XXX should be supported */
return EINVAL;
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 (!useracc(cursorp->image, count, B_READ))
return (EFAULT);
}
if (v & WSDISPLAY_CURSOR_DOHOT) /* not supported */
return EINVAL;
#endif
/* 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 0
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) {
/* XXX */
}
if (v & WSDISPLAY_CURSOR_DOSHAPE) {
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. */
}
#endif
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 */
}
/* XXX No color map */
return (0);
}
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);
}

50
sys/dev/pci/tga_bt463.c Normal file
View File

@ -0,0 +1,50 @@
/* $NetBSD: tga_bt463.c,v 1.1 1998/04/15 20:16:31 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>
#include <dev/ic/bt485reg.h>
const struct tga_ramdac_conf tga_ramdac_bt463 = {
"Bt463",
#if 0
NULL, /* XXX SET CMAP */
NULL, /* XXX GET CMAP */
tga_builtin_set_cursor,
tga_builtin_get_cursor,
tga_builtin_set_curpos,
tga_builtin_get_curpos,
tga_builtin_get_curmax,
#endif
};

623
sys/dev/pci/tga_bt485.c Normal file
View File

@ -0,0 +1,623 @@
/* $NetBSD: tga_bt485.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/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>
#include "opt_uvm.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,
};
/*
* 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->cmap_r[index], count);
copyin(cursorp->cmap.green, &data->cmap_g[index], count);
copyin(cursorp->cmap.blue, &data->cmap_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);
}

183
sys/dev/pci/tga_conf.c Normal file
View File

@ -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);
}

159
sys/dev/pci/tgareg.h Normal file
View File

@ -0,0 +1,159 @@
/* $NetBSD: tgareg.h,v 1.1 1998/04/15 20:16:33 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.
*/
#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 */
#endif /* _ALPHA_INCLUDE_TGAREG_H_ */

147
sys/dev/pci/tgavar.h Normal file
View File

@ -0,0 +1,147 @@
/* $NetBSD: tgavar.h,v 1.1 1998/04/15 20:16:34 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 <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 *));
};
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 */
vm_size_t tgac_cspace_size; /* core space size */
vm_size_t tgac_vvbr_units; /* what '1' in the VVBR means */
int tgac_ndbuf; /* number of display buffers */
vm_offset_t tgac_dbuf[2]; /* display buffer offsets/addresses */
vm_size_t tgac_dbufsz[2]; /* display buffer sizes */
int tgac_nbbuf; /* number of display buffers */
vm_offset_t tgac_bbuf[2]; /* back buffer offsets/addresses */
vm_size_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 */
vm_offset_t dc_vaddr; /* memory space virtual base address */
vm_offset_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 */
vm_offset_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 *));