diff options
author | anholt <anholt@FreeBSD.org> | 2005-09-16 22:59:47 +0000 |
---|---|---|
committer | anholt <anholt@FreeBSD.org> | 2005-09-16 22:59:47 +0000 |
commit | cd7e9610083fb288a1e9f23608cb1c5fa19700da (patch) | |
tree | d3c98f55b36bf230b35c25c4dc903d82e2c38506 /sys/pci/agp_nvidia.c | |
parent | 6adebfab812a023e8d2e349fa2ea5c3bd91e708d (diff) | |
download | FreeBSD-src-cd7e9610083fb288a1e9f23608cb1c5fa19700da.zip FreeBSD-src-cd7e9610083fb288a1e9f23608cb1c5fa19700da.tar.gz |
Fix agp_nvidia.c to behave more like the linux driver, fixing DRI on Radeon
9200 according to one responder. The primary issue was not setting some bits
to say that the entries were active, but also fix one place where some memory
wasn't being used as volatile as it should. While here, change some use of ffs
to a relatively short case statement, to make it more obvious what's going on.
PR: kern/71638, kern/72372, kern/71547?
Submitted by: Andrew J. Caines <A.J.Caines@halplant.com>,
Robin Schoonover <end@endif.cjb.net>,
Jason Henson <jason@ec.rr.com>
Diffstat (limited to 'sys/pci/agp_nvidia.c')
-rw-r--r-- | sys/pci/agp_nvidia.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/sys/pci/agp_nvidia.c b/sys/pci/agp_nvidia.c index e49c140..5e26622 100644 --- a/sys/pci/agp_nvidia.c +++ b/sys/pci/agp_nvidia.c @@ -148,8 +148,8 @@ agp_nvidia_attach (device_t dev) sc->wbc_mask = 0x80000000; break; default: - sc->wbc_mask = 0; - break; + device_printf(dev, "Bad chip id\n"); + return (ENODEV); } /* AGP Controller */ @@ -227,8 +227,7 @@ agp_nvidia_attach (device_t dev) for (i = 0; i < 8; i++) { pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_ATTBASE(i), (sc->gatt->ag_physical + - (i % sc->num_dirs) * 64 * 1024), - 4); + (i % sc->num_dirs) * 64 * 1024) | 1, 4); } /* GTLB Control */ @@ -279,10 +278,17 @@ agp_nvidia_detach (device_t dev) static u_int32_t agp_nvidia_get_aperture(device_t dev) { - u_int8_t key; - - key = ffs(pci_read_config(dev, AGP_NVIDIA_0_APSIZE, 1) & 0x0f); - return (1 << (24 + (key ? key : 5))); + switch (pci_read_config(dev, AGP_NVIDIA_0_APSIZE, 1) & 0x0f) { + case 0: return (512 * 1024 * 1024); break; + case 8: return (256 * 1024 * 1024); break; + case 12: return (128 * 1024 * 1024); break; + case 14: return (64 * 1024 * 1024); break; + case 15: return (32 * 1024 * 1024); break; + default: + device_printf(dev, "Invalid aperture setting 0x%x", + pci_read_config(dev, AGP_NVIDIA_0_APSIZE, 1)); + return 0; + } } static int @@ -318,7 +324,7 @@ agp_nvidia_bind_page(device_t dev, int offset, vm_offset_t physical) return (EINVAL); index = (sc->pg_offset + offset) >> AGP_PAGE_SHIFT; - sc->gatt->ag_virtual[index] = physical; + sc->gatt->ag_virtual[index] = physical | 1; return (0); } @@ -343,6 +349,7 @@ agp_nvidia_flush_tlb (device_t dev, int offset) { struct agp_nvidia_softc *sc; u_int32_t wbc_reg, temp; + volatile u_int32_t *ag_virtual; int i; sc = (struct agp_nvidia_softc *)device_get_softc(dev); @@ -366,11 +373,13 @@ agp_nvidia_flush_tlb (device_t dev, int offset) "TLB flush took more than 3 seconds.\n"); } + ag_virtual = (volatile u_int32_t *)sc->gatt->ag_virtual; + /* Flush TLB entries. */ for(i = 0; i < 32 + 1; i++) - temp = sc->gatt->ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)]; + temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)]; for(i = 0; i < 32 + 1; i++) - temp = sc->gatt->ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)]; + temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)]; return (0); } |