summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2005-11-14 21:54:20 +0000
committerjkim <jkim@FreeBSD.org>2005-11-14 21:54:20 +0000
commit4c46ed51b6a77c5564f4afd16e8573fd55845951 (patch)
treec76d798498ba8009635a90746ea3cd9c89763dfd /sys
parentddc146912f5620802f80ce0d25adc2019b8487a8 (diff)
downloadFreeBSD-src-4c46ed51b6a77c5564f4afd16e8573fd55845951.zip
FreeBSD-src-4c46ed51b6a77c5564f4afd16e8573fd55845951.tar.gz
0xb1881106 seems to be an AGP bridge and some BIOSes incorrectly handle
the bridge. Therefore, we give the same treatment as we did for nForce3-250 and ULi chipsets. VIA AGPv3 code was copied from agp_via.c.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/agp/agp_amd64.c88
-rw-r--r--sys/pci/agp_amd64.c88
2 files changed, 144 insertions, 32 deletions
diff --git a/sys/dev/agp/agp_amd64.c b/sys/dev/agp/agp_amd64.c
index a8f36d6..e0b47b6 100644
--- a/sys/dev/agp/agp_amd64.c
+++ b/sys/dev/agp/agp_amd64.c
@@ -64,6 +64,10 @@ static int agp_amd64_nvidia_match(uint16_t);
static void agp_amd64_nvidia_init(device_t);
static int agp_amd64_nvidia_set_aperture(device_t, uint32_t);
+static int agp_amd64_via_match(void);
+static void agp_amd64_via_init(device_t);
+static int agp_amd64_via_set_aperture(device_t, uint32_t);
+
MALLOC_DECLARE(M_AGP);
#define AMD64_MAX_MCTRL 8
@@ -75,6 +79,7 @@ struct agp_amd64_softc {
uint32_t apbase;
int mctrl[AMD64_MAX_MCTRL];
int n_mctrl;
+ int via_agp;
};
static const char*
@@ -110,8 +115,6 @@ agp_amd64_match(device_t dev)
return ("VIA K8T800Pro host to PCI bridge");
case 0x31881106:
return ("VIA 8385 host to PCI bridge");
- case 0xb1881106:
- return ("VIA 838X host to PCI bridge");
};
return NULL;
@@ -131,6 +134,20 @@ agp_amd64_nvidia_match(uint16_t devid)
}
static int
+agp_amd64_via_match(void)
+{
+ /* XXX Some VIA bridge requires secondary AGP bridge at 0:1:0. */
+ if (pci_cfgregread(0, 1, 0, PCIR_CLASS, 1) != PCIC_BRIDGE ||
+ pci_cfgregread(0, 1, 0, PCIR_SUBCLASS, 1) != PCIS_BRIDGE_PCI ||
+ pci_cfgregread(0, 1, 0, PCIR_VENDOR, 2) != 0x1106 ||
+ pci_cfgregread(0, 1, 0, PCIR_DEVICE, 2) != 0xb188 ||
+ (pci_cfgregread(0, 1, 0, AGP_VIA_AGPSEL, 1) & 2))
+ return 0;
+
+ return 1;
+}
+
+static int
agp_amd64_probe(device_t dev)
{
const char *desc;
@@ -178,20 +195,6 @@ agp_amd64_attach(device_t dev)
sc->initial_aperture = AGP_GET_APERTURE(dev);
- switch (pci_get_vendor(dev)) {
- case 0x10b9: /* ULi */
- agp_amd64_uli_init(dev);
- if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture))
- return ENXIO;
- break;
-
- case 0x10de: /* nVidia */
- agp_amd64_nvidia_init(dev);
- if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture))
- return ENXIO;
- break;
- }
-
for (;;) {
gatt = agp_alloc_gatt(dev);
if (gatt)
@@ -208,6 +211,30 @@ agp_amd64_attach(device_t dev)
}
sc->gatt = gatt;
+ switch (pci_get_vendor(dev)) {
+ case 0x10b9: /* ULi */
+ agp_amd64_uli_init(dev);
+ if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture))
+ return ENXIO;
+ break;
+
+ case 0x10de: /* nVidia */
+ agp_amd64_nvidia_init(dev);
+ if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture))
+ return ENXIO;
+ break;
+
+ case 0x1106: /* VIA */
+ sc->via_agp = agp_amd64_via_match();
+ if (sc->via_agp) {
+ agp_amd64_via_init(dev);
+ if (agp_amd64_via_set_aperture(dev,
+ sc->initial_aperture))
+ return ENXIO;
+ }
+ break;
+ }
+
/* Install the gatt and enable aperture. */
for (i = 0; i < sc->n_mctrl; i++) {
pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_ATTBASE,
@@ -299,6 +326,11 @@ agp_amd64_set_aperture(device_t dev, uint32_t aperture)
case 0x10de: /* nVidia */
return (agp_amd64_nvidia_set_aperture(dev, aperture));
break;
+
+ case 0x1106: /* VIA */
+ if (sc->via_agp)
+ return (agp_amd64_via_set_aperture(dev, aperture));
+ break;
}
return 0;
@@ -427,6 +459,30 @@ agp_amd64_nvidia_set_aperture(device_t dev, uint32_t aperture)
return 0;
}
+static void
+agp_amd64_via_init(device_t dev)
+{
+ struct agp_amd64_softc *sc = device_get_softc(dev);
+
+ agp_amd64_apbase_fixup(dev);
+ pci_cfgregwrite(0, 1, 0, AGP3_VIA_ATTBASE, sc->gatt->ag_physical, 4);
+ pci_cfgregwrite(0, 1, 0, AGP3_VIA_GARTCTRL,
+ pci_cfgregread(0, 1, 0, AGP3_VIA_ATTBASE, 4) | 0x180, 4);
+}
+
+static int
+agp_amd64_via_set_aperture(device_t dev, uint32_t aperture)
+{
+ uint32_t apsize;
+
+ apsize = ((aperture - 1) >> 20) ^ 0xff;
+ if ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1 != aperture)
+ return EINVAL;
+ pci_cfgregwrite(0, 1, 0, AGP3_VIA_APSIZE, apsize, 1);
+
+ return 0;
+}
+
static device_method_t agp_amd64_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_amd64_probe),
diff --git a/sys/pci/agp_amd64.c b/sys/pci/agp_amd64.c
index a8f36d6..e0b47b6 100644
--- a/sys/pci/agp_amd64.c
+++ b/sys/pci/agp_amd64.c
@@ -64,6 +64,10 @@ static int agp_amd64_nvidia_match(uint16_t);
static void agp_amd64_nvidia_init(device_t);
static int agp_amd64_nvidia_set_aperture(device_t, uint32_t);
+static int agp_amd64_via_match(void);
+static void agp_amd64_via_init(device_t);
+static int agp_amd64_via_set_aperture(device_t, uint32_t);
+
MALLOC_DECLARE(M_AGP);
#define AMD64_MAX_MCTRL 8
@@ -75,6 +79,7 @@ struct agp_amd64_softc {
uint32_t apbase;
int mctrl[AMD64_MAX_MCTRL];
int n_mctrl;
+ int via_agp;
};
static const char*
@@ -110,8 +115,6 @@ agp_amd64_match(device_t dev)
return ("VIA K8T800Pro host to PCI bridge");
case 0x31881106:
return ("VIA 8385 host to PCI bridge");
- case 0xb1881106:
- return ("VIA 838X host to PCI bridge");
};
return NULL;
@@ -131,6 +134,20 @@ agp_amd64_nvidia_match(uint16_t devid)
}
static int
+agp_amd64_via_match(void)
+{
+ /* XXX Some VIA bridge requires secondary AGP bridge at 0:1:0. */
+ if (pci_cfgregread(0, 1, 0, PCIR_CLASS, 1) != PCIC_BRIDGE ||
+ pci_cfgregread(0, 1, 0, PCIR_SUBCLASS, 1) != PCIS_BRIDGE_PCI ||
+ pci_cfgregread(0, 1, 0, PCIR_VENDOR, 2) != 0x1106 ||
+ pci_cfgregread(0, 1, 0, PCIR_DEVICE, 2) != 0xb188 ||
+ (pci_cfgregread(0, 1, 0, AGP_VIA_AGPSEL, 1) & 2))
+ return 0;
+
+ return 1;
+}
+
+static int
agp_amd64_probe(device_t dev)
{
const char *desc;
@@ -178,20 +195,6 @@ agp_amd64_attach(device_t dev)
sc->initial_aperture = AGP_GET_APERTURE(dev);
- switch (pci_get_vendor(dev)) {
- case 0x10b9: /* ULi */
- agp_amd64_uli_init(dev);
- if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture))
- return ENXIO;
- break;
-
- case 0x10de: /* nVidia */
- agp_amd64_nvidia_init(dev);
- if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture))
- return ENXIO;
- break;
- }
-
for (;;) {
gatt = agp_alloc_gatt(dev);
if (gatt)
@@ -208,6 +211,30 @@ agp_amd64_attach(device_t dev)
}
sc->gatt = gatt;
+ switch (pci_get_vendor(dev)) {
+ case 0x10b9: /* ULi */
+ agp_amd64_uli_init(dev);
+ if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture))
+ return ENXIO;
+ break;
+
+ case 0x10de: /* nVidia */
+ agp_amd64_nvidia_init(dev);
+ if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture))
+ return ENXIO;
+ break;
+
+ case 0x1106: /* VIA */
+ sc->via_agp = agp_amd64_via_match();
+ if (sc->via_agp) {
+ agp_amd64_via_init(dev);
+ if (agp_amd64_via_set_aperture(dev,
+ sc->initial_aperture))
+ return ENXIO;
+ }
+ break;
+ }
+
/* Install the gatt and enable aperture. */
for (i = 0; i < sc->n_mctrl; i++) {
pci_cfgregwrite(0, sc->mctrl[i], 3, AGP_AMD64_ATTBASE,
@@ -299,6 +326,11 @@ agp_amd64_set_aperture(device_t dev, uint32_t aperture)
case 0x10de: /* nVidia */
return (agp_amd64_nvidia_set_aperture(dev, aperture));
break;
+
+ case 0x1106: /* VIA */
+ if (sc->via_agp)
+ return (agp_amd64_via_set_aperture(dev, aperture));
+ break;
}
return 0;
@@ -427,6 +459,30 @@ agp_amd64_nvidia_set_aperture(device_t dev, uint32_t aperture)
return 0;
}
+static void
+agp_amd64_via_init(device_t dev)
+{
+ struct agp_amd64_softc *sc = device_get_softc(dev);
+
+ agp_amd64_apbase_fixup(dev);
+ pci_cfgregwrite(0, 1, 0, AGP3_VIA_ATTBASE, sc->gatt->ag_physical, 4);
+ pci_cfgregwrite(0, 1, 0, AGP3_VIA_GARTCTRL,
+ pci_cfgregread(0, 1, 0, AGP3_VIA_ATTBASE, 4) | 0x180, 4);
+}
+
+static int
+agp_amd64_via_set_aperture(device_t dev, uint32_t aperture)
+{
+ uint32_t apsize;
+
+ apsize = ((aperture - 1) >> 20) ^ 0xff;
+ if ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1 != aperture)
+ return EINVAL;
+ pci_cfgregwrite(0, 1, 0, AGP3_VIA_APSIZE, apsize, 1);
+
+ return 0;
+}
+
static device_method_t agp_amd64_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, agp_amd64_probe),
OpenPOWER on IntegriCloud