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>
This commit is contained in:
Eric Anholt 2005-09-16 22:59:47 +00:00
parent 4ece38b4ec
commit 695b15ca91
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=150235
2 changed files with 40 additions and 22 deletions

View file

@ -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);
}

View file

@ -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);
}