summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authormacallan <macallan@NetBSD.org>2011-05-04 23:36:21 +0000
committermacallan <macallan@NetBSD.org>2011-05-04 23:36:21 +0000
commitb64fd334fba80faa5dda47b691658608fcf5a4d2 (patch)
tree6b467e529cda4eb59401a9d8fbd6540ffec3e34b /sys/dev
parent9b00f3cd6ba17f117bb23a9e23a79d6ec61006aa (diff)
add support for (ancient) Mach64 CX and GX, while there make sure the visible
vram area starts at the same offset as the area we're going to draw into - zero that is. from David Riley
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/machfb.c92
1 files changed, 68 insertions, 24 deletions
diff --git a/sys/dev/pci/machfb.c b/sys/dev/pci/machfb.c
index 2d85c3ef475..27727baa515 100644
--- a/sys/dev/pci/machfb.c
+++ b/sys/dev/pci/machfb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: machfb.c,v 1.63 2011/01/22 15:14:28 cegger Exp $ */
+/* $NetBSD: machfb.c,v 1.64 2011/05/04 23:36:21 macallan Exp $ */
/*
* Copyright (c) 2002 Bang Jun-Young
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(0,
- "$NetBSD: machfb.c,v 1.63 2011/01/22 15:14:28 cegger Exp $");
+ "$NetBSD: machfb.c,v 1.64 2011/05/04 23:36:21 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -169,6 +169,8 @@ static struct {
uint16_t chip_id;
uint32_t ramdac_freq;
} const mach64_info[] = {
+ { PCI_PRODUCT_ATI_MACH64_GX, 135000 },
+ { PCI_PRODUCT_ATI_MACH64_CX, 135000 },
{ PCI_PRODUCT_ATI_MACH64_CT, 135000 },
{ PCI_PRODUCT_ATI_RAGE_PRO_AGP, 230000 },
{ PCI_PRODUCT_ATI_RAGE_PRO_AGP1X, 230000 },
@@ -184,12 +186,11 @@ static struct {
{ PCI_PRODUCT_ATI_RAGE_IIC_AGP_B, 230000 },
{ PCI_PRODUCT_ATI_RAGE_IIC_AGP_P, 230000 },
#if 0
- { PCI_PRODUCT_ATI_RAGE_LT_PRO_AGP, 230000 },
{ PCI_PRODUCT_ATI_RAGE_MOB_M3_PCI, 230000 },
{ PCI_PRODUCT_ATI_RAGE_MOB_M3_AGP, 230000 },
{ PCI_PRODUCT_ATI_RAGE_MOBILITY, 230000 },
- { PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 },
#endif
+ { PCI_PRODUCT_ATI_RAGE_LT_PRO_AGP, 230000 },
{ PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 },
{ PCI_PRODUCT_ATI_RAGE_LT, 230000 },
{ PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI, 230000 },
@@ -201,6 +202,11 @@ static struct {
static int mach64_chip_id, mach64_chip_rev;
static struct videomode default_mode = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
+static const char *mach64_gx_memtype_names[] = {
+ "DRAM", "VRAM", "VRAM", "DRAM",
+ "DRAM", "VRAM", "VRAM", "(unknown type)"
+};
+
static const char *mach64_memtype_names[] = {
"(N/A)", "DRAM", "EDO DRAM", "EDO DRAM", "SDRAM", "SGRAM", "WRAM",
"(unknown type)"
@@ -507,7 +513,9 @@ mach64_attach(device_t parent, device_t self, void *aux)
prop_data_t edid_data;
const struct videomode *mode = NULL;
char devinfo[256];
- int bar, id;
+ int bar, id, expected_id;
+ int is_gx;
+ const char **memtype_names;
struct wsemuldisplaydev_attach_args aa;
long defattr;
int setmode, width, height;
@@ -566,6 +574,13 @@ mach64_attach(device_t parent, device_t self, void *aux)
}
sc->sc_aperture = (void *)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
+ /* If the BAR was never mapped, fix it up in MMIO. */
+ if(sc->sc_regsize == 0) {
+ sc->sc_regsize = MACH64_REG_SIZE;
+ sc->sc_regbase = sc->sc_aperbase + MACH64_REG_OFF;
+ sc->sc_regphys = sc->sc_aperphys + MACH64_REG_OFF;
+ }
+
sc->sc_regt = sc->sc_memt;
bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
sc->sc_regsize, &sc->sc_regh);
@@ -608,19 +623,36 @@ mach64_attach(device_t parent, device_t self, void *aux)
printf("mode: %s\n", mode->name);
}
}
- if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_CT ||
- ((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
- mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) &&
- (mach64_chip_rev & 0x07) == 0))
- sc->has_dsp = 0;
- else
- sc->has_dsp = 1;
+
+ is_gx = 0;
+ switch(mach64_chip_id) {
+ case PCI_PRODUCT_ATI_MACH64_GX:
+ case PCI_PRODUCT_ATI_MACH64_CX:
+ is_gx = 1;
+ case PCI_PRODUCT_ATI_MACH64_CT:
+ sc->has_dsp = 0;
+ break;
+ case PCI_PRODUCT_ATI_MACH64_VT:
+ case PCI_PRODUCT_ATI_RAGE_II:
+ if((mach64_chip_rev & 0x07) == 0) {
+ sc->has_dsp = 0;
+ break;
+ }
+ /* Otherwise fall through. */
+ default:
+ sc->has_dsp = 1;
+ }
+
+ memtype_names = is_gx ? mach64_gx_memtype_names : mach64_memtype_names;
sc->memsize = mach64_get_memsize(sc);
if (sc->memsize == 8192)
/* The last page is used as register aperture. */
sc->memsize -= 4;
- sc->memtype = regr(sc, CONFIG_STAT0) & 0x07;
+ if(is_gx)
+ sc->memtype = (regr(sc, CONFIG_STAT0) >> 3) & 0x07;
+ else
+ sc->memtype = regr(sc, CONFIG_STAT0) & 0x07;
/* XXX is there any way to calculate reference frequency from
known values? */
@@ -649,14 +681,26 @@ mach64_attach(device_t parent, device_t self, void *aux)
aprint_normal_dev(sc->sc_dev,
"%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n",
(u_long)sc->memsize,
- mach64_memtype_names[sc->memtype],
+ memtype_names[sc->memtype],
sc->mem_freq / 1000, sc->mem_freq % 1000,
sc->ramdac_freq / 1000);
id = regr(sc, CONFIG_CHIP_ID) & 0xffff;
- if (id != mach64_chip_id) {
+ switch(mach64_chip_id) {
+ case PCI_PRODUCT_ATI_MACH64_GX:
+ expected_id = 0x00d7;
+ break;
+ case PCI_PRODUCT_ATI_MACH64_CX:
+ expected_id = 0x0057;
+ break;
+ default:
+ /* Most chip IDs match their PCI product ID. */
+ expected_id = mach64_chip_id;
+ }
+
+ if (id != expected_id) {
aprint_error_dev(sc->sc_dev,
- "chip ID mismatch, 0x%x != 0x%x\n", id, mach64_chip_id);
+ "chip ID mismatch, 0x%x != 0x%x\n", id, expected_id);
return;
}
@@ -706,11 +750,6 @@ mach64_attach(device_t parent, device_t self, void *aux)
if (setmode)
mach64_modeswitch(sc, sc->sc_my_mode);
-#if 0
- mach64_adjust_frame(0, 0);
- if (sc->bits_per_pixel == 8)
- mach64_init_lut(sc);
-#endif
aprint_normal_dev(sc->sc_dev,
"initial resolution %dx%d at %d bpp\n",
@@ -732,6 +771,7 @@ mach64_attach(device_t parent, device_t self, void *aux)
machfb_blank(sc, 0); /* unblank the screen */
if (sc->sc_console) {
+
vcons_init_screen(&sc->vd, &mach64_console_screen, 1,
&defattr);
mach64_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
@@ -741,6 +781,7 @@ mach64_attach(device_t parent, device_t self, void *aux)
mach64_defaultscreen.capabilities = ri->ri_caps;
mach64_defaultscreen.nrows = ri->ri_rows;
mach64_defaultscreen.ncols = ri->ri_cols;
+
wsdisplay_cnattach(&mach64_defaultscreen, ri, 0, 0, defattr);
vcons_replay_msgbuf(&mach64_console_screen);
} else {
@@ -1045,6 +1086,9 @@ mach64_init_engine(struct mach64_softc *sc)
regw(sc, DST_OFF_PITCH, (pitch_value / 8) << 22);
+ /* make sure the visible area starts where we're going to draw */
+ regw(sc, CRTC_OFF_PITCH, (sc->virt_x >> 3) << 22);
+
regw(sc, DST_Y_X, 0);
regw(sc, DST_HEIGHT, 0);
regw(sc, DST_BRES_ERR, 0);
@@ -1090,13 +1134,13 @@ mach64_init_engine(struct mach64_softc *sc)
wait_for_fifo(sc, 2);
switch (sc->bits_per_pixel) {
case 8:
- regw(sc, DP_PIX_WIDTH, HOST_8BPP | SRC_8BPP | DST_8BPP);
+ regw(sc, DP_PIX_WIDTH, HOST_1BPP | SRC_8BPP | DST_8BPP);
regw(sc, DP_CHAIN_MASK, DP_CHAIN_8BPP);
/* We want 8 bit per channel */
regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
break;
case 32:
- regw(sc, DP_PIX_WIDTH, HOST_32BPP | SRC_32BPP | DST_32BPP);
+ regw(sc, DP_PIX_WIDTH, HOST_1BPP | SRC_32BPP | DST_32BPP);
regw(sc, DP_CHAIN_MASK, DP_CHAIN_32BPP);
regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
break;
@@ -1610,7 +1654,7 @@ mach64_feed_bytes(struct mach64_softc *sc, int count, uint8_t *data)
int shift = 0;
int reg = 0;
- for (i=0;i<count;i++) {
+ for (i = 0; i < count; i++) {
bork = data[i];
latch |= (bork << shift);
if (shift == 24) {