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
This commit is contained in:
macallan 2011-05-04 23:36:21 +00:00
parent 9e66d3e091
commit bcb7f01345

View File

@ -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) {