7 #include <linux/module.h>
17 #define NVIDIA_0_APSIZE 0x80
18 #define NVIDIA_1_WBC 0xf0
19 #define NVIDIA_2_GARTCTRL 0xd0
20 #define NVIDIA_2_APBASE 0xd8
21 #define NVIDIA_2_APLIMIT 0xdc
22 #define NVIDIA_2_ATTBASE(i) (0xe0 + (i) * 4)
23 #define NVIDIA_3_APBASE 0x50
24 #define NVIDIA_3_APLIMIT 0x54
27 static struct _nvidia_private {
32 int num_active_entries;
38 static int nvidia_fetch_size(
void)
48 for (i = 0; i <
agp_bridge->driver->num_aperture_sizes; i++) {
49 if (size_value == values[i].size_value) {
51 agp_bridge->current_size = (
void *) (values + i);
53 return values[
i].
size;
60 #define SYSCFG 0xC0010010
61 #define IORR_BASE0 0xC0010016
62 #define IORR_MASK0 0xC0010017
63 #define AMD_K7_NUM_IORR 2
65 static int nvidia_init_iorr(
u32 base,
u32 size)
70 u32 iorr_addr, free_iorr_addr;
79 if ((base_lo & 0xfffff000) == (base & 0xfffff000))
82 if ((mask_lo & 0x00000800) == 0)
83 free_iorr_addr = iorr_addr;
86 if (iorr_addr >= AMD_K7_NUM_IORR) {
87 iorr_addr = free_iorr_addr;
88 if (iorr_addr >= AMD_K7_NUM_IORR)
92 base_lo = (base & ~0xfff) | 0x18;
94 mask_lo = ((~(size - 1)) & 0xfffff000) | 0x800;
105 static int nvidia_configure(
void)
122 aplimit = apbase + (current_size->
size * 1024 * 1024) - 1;
127 if (0 != (rc = nvidia_init_iorr(apbase, current_size->
size * 1024 * 1024)))
131 num_dirs = current_size->
size / 64;
132 nvidia_private.num_active_entries = current_size->
num_entries;
133 nvidia_private.pg_offset = 0;
136 nvidia_private.num_active_entries /= (64 / current_size->
size);
137 nvidia_private.pg_offset = (apbase & (64 * 1024 * 1024 - 1) &
142 for (i = 0; i < 8; i++) {
144 (
agp_bridge->gatt_bus_addr + (i % num_dirs) * 64 * 1024) | 1);
156 nvidia_private.aperture =
159 if (!nvidia_private.aperture)
165 static void nvidia_cleanup(
void)
188 previous_size->
size * 1024 * 1024);
206 if (mask_type != 0 || type != mem->
type)
213 (nvidia_private.num_active_entries - agp_memory_reserved/
PAGE_SIZE))
216 for (j = pg_start; j < (pg_start + mem->
page_count); j++) {
225 for (i = 0, j = pg_start; i < mem->
page_count; i++, j++) {
228 agp_bridge->gatt_table+nvidia_private.pg_offset+
j);
239 static int nvidia_remove_memory(
struct agp_memory *mem,
off_t pg_start,
int type)
246 if (mask_type != 0 || type != mem->
type)
252 for (i = pg_start; i < (mem->
page_count + pg_start); i++)
260 static void nvidia_tlbflush(
struct agp_memory *mem)
267 if (nvidia_private.wbc_mask) {
268 pci_read_config_dword(nvidia_private.dev_1,
NVIDIA_1_WBC, &wbc_reg);
269 wbc_reg |= nvidia_private.wbc_mask;
270 pci_write_config_dword(nvidia_private.dev_1,
NVIDIA_1_WBC, wbc_reg);
274 pci_read_config_dword(nvidia_private.dev_1,
278 "TLB flush took more than 3 seconds.\n");
280 }
while (wbc_reg & nvidia_private.wbc_mask);
284 for (i = 0; i < 32 + 1; i++)
286 for (i = 0; i < 32 + 1; i++)
302 static const struct gatt_mask nvidia_generic_masks[] =
304 { .mask = 1, .type = 0}
310 .aperture_sizes = nvidia_generic_sizes,
312 .num_aperture_sizes = 5,
313 .needs_scratch_page =
true,
314 .configure = nvidia_configure,
315 .fetch_size = nvidia_fetch_size,
316 .cleanup = nvidia_cleanup,
317 .tlb_flush = nvidia_tlbflush,
319 .masks = nvidia_generic_masks,
324 .insert_memory = nvidia_insert_memory,
325 .remove_memory = nvidia_remove_memory,
341 nvidia_private.dev_1 =
343 nvidia_private.dev_2 =
345 nvidia_private.dev_3 =
348 if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) {
350 "chipset, but could not find the secondary devices.\n");
361 nvidia_private.wbc_mask = 0x00010000;
365 nvidia_private.wbc_mask = 0x80000000;
377 bridge->
driver = &nvidia_driver;
383 pci_read_config_dword(pdev,
387 pci_set_drvdata(pdev, bridge);
408 static int agp_nvidia_resume(
struct pci_dev *pdev)
444 static struct pci_driver agp_nvidia_pci_driver = {
445 .name =
"agpgart-nvidia",
446 .id_table = agp_nvidia_pci_table,
447 .probe = agp_nvidia_probe,
448 .remove = agp_nvidia_remove,
450 .suspend = agp_nvidia_suspend,
451 .resume = agp_nvidia_resume,
455 static int __init agp_nvidia_init(
void)
459 return pci_register_driver(&agp_nvidia_pci_driver);
462 static void __exit agp_nvidia_cleanup(
void)