From 4c46ed51b6a77c5564f4afd16e8573fd55845951 Mon Sep 17 00:00:00 2001 From: jkim Date: Mon, 14 Nov 2005 21:54:20 +0000 Subject: [PATCH] 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. --- sys/dev/agp/agp_amd64.c | 88 +++++++++++++++++++++++++++++++++-------- sys/pci/agp_amd64.c | 88 +++++++++++++++++++++++++++++++++-------- 2 files changed, 144 insertions(+), 32 deletions(-) diff --git a/sys/dev/agp/agp_amd64.c b/sys/dev/agp/agp_amd64.c index a8f36d6d2ba6..e0b47b6165af 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; @@ -130,6 +133,20 @@ agp_amd64_nvidia_match(uint16_t devid) return 0; } +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) { @@ -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 a8f36d6d2ba6..e0b47b6165af 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; @@ -130,6 +133,20 @@ agp_amd64_nvidia_match(uint16_t devid) return 0; } +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) { @@ -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),