diff options
Diffstat (limited to 'drivers/char/agp/amd64-agp.c')
| -rw-r--r-- | drivers/char/agp/amd64-agp.c | 77 |
1 files changed, 25 insertions, 52 deletions
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index ac3c33a2e37d..229d015757f9 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
| @@ -15,11 +15,9 @@ | |||
| 15 | #include <linux/agp_backend.h> | 15 | #include <linux/agp_backend.h> |
| 16 | #include <linux/mmzone.h> | 16 | #include <linux/mmzone.h> |
| 17 | #include <asm/page.h> /* PAGE_SIZE */ | 17 | #include <asm/page.h> /* PAGE_SIZE */ |
| 18 | #include <asm/k8.h> | ||
| 18 | #include "agp.h" | 19 | #include "agp.h" |
| 19 | 20 | ||
| 20 | /* Will need to be increased if AMD64 ever goes >8-way. */ | ||
| 21 | #define MAX_HAMMER_GARTS 8 | ||
| 22 | |||
| 23 | /* PTE bits. */ | 21 | /* PTE bits. */ |
| 24 | #define GPTE_VALID 1 | 22 | #define GPTE_VALID 1 |
| 25 | #define GPTE_COHERENT 2 | 23 | #define GPTE_COHERENT 2 |
| @@ -53,28 +51,12 @@ | |||
| 53 | #define ULI_X86_64_HTT_FEA_REG 0x50 | 51 | #define ULI_X86_64_HTT_FEA_REG 0x50 |
| 54 | #define ULI_X86_64_ENU_SCR_REG 0x54 | 52 | #define ULI_X86_64_ENU_SCR_REG 0x54 |
| 55 | 53 | ||
| 56 | static int nr_garts; | ||
| 57 | static struct pci_dev * hammers[MAX_HAMMER_GARTS]; | ||
| 58 | |||
| 59 | static struct resource *aperture_resource; | 54 | static struct resource *aperture_resource; |
| 60 | static int __initdata agp_try_unsupported = 1; | 55 | static int __initdata agp_try_unsupported = 1; |
| 61 | 56 | ||
| 62 | #define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++) | ||
| 63 | |||
| 64 | static void flush_amd64_tlb(struct pci_dev *dev) | ||
| 65 | { | ||
| 66 | u32 tmp; | ||
| 67 | |||
| 68 | pci_read_config_dword (dev, AMD64_GARTCACHECTL, &tmp); | ||
| 69 | tmp |= INVGART; | ||
| 70 | pci_write_config_dword (dev, AMD64_GARTCACHECTL, tmp); | ||
| 71 | } | ||
| 72 | |||
| 73 | static void amd64_tlbflush(struct agp_memory *temp) | 57 | static void amd64_tlbflush(struct agp_memory *temp) |
| 74 | { | 58 | { |
| 75 | int gart_iterator; | 59 | k8_flush_garts(); |
| 76 | for_each_nb() | ||
| 77 | flush_amd64_tlb(hammers[gart_iterator]); | ||
| 78 | } | 60 | } |
| 79 | 61 | ||
| 80 | static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | 62 | static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type) |
| @@ -153,7 +135,7 @@ static int amd64_fetch_size(void) | |||
| 153 | u32 temp; | 135 | u32 temp; |
| 154 | struct aper_size_info_32 *values; | 136 | struct aper_size_info_32 *values; |
| 155 | 137 | ||
| 156 | dev = hammers[0]; | 138 | dev = k8_northbridges[0]; |
| 157 | if (dev==NULL) | 139 | if (dev==NULL) |
| 158 | return 0; | 140 | return 0; |
| 159 | 141 | ||
| @@ -201,9 +183,6 @@ static u64 amd64_configure (struct pci_dev *hammer, u64 gatt_table) | |||
| 201 | tmp &= ~(DISGARTCPU | DISGARTIO); | 183 | tmp &= ~(DISGARTCPU | DISGARTIO); |
| 202 | pci_write_config_dword(hammer, AMD64_GARTAPERTURECTL, tmp); | 184 | pci_write_config_dword(hammer, AMD64_GARTAPERTURECTL, tmp); |
| 203 | 185 | ||
| 204 | /* keep CPU's coherent. */ | ||
| 205 | flush_amd64_tlb (hammer); | ||
| 206 | |||
| 207 | return aper_base; | 186 | return aper_base; |
| 208 | } | 187 | } |
| 209 | 188 | ||
| @@ -222,13 +201,14 @@ static struct aper_size_info_32 amd_8151_sizes[7] = | |||
| 222 | static int amd_8151_configure(void) | 201 | static int amd_8151_configure(void) |
| 223 | { | 202 | { |
| 224 | unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); | 203 | unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); |
| 225 | int gart_iterator; | 204 | int i; |
| 226 | 205 | ||
| 227 | /* Configure AGP regs in each x86-64 host bridge. */ | 206 | /* Configure AGP regs in each x86-64 host bridge. */ |
| 228 | for_each_nb() { | 207 | for (i = 0; i < num_k8_northbridges; i++) { |
| 229 | agp_bridge->gart_bus_addr = | 208 | agp_bridge->gart_bus_addr = |
| 230 | amd64_configure(hammers[gart_iterator],gatt_bus); | 209 | amd64_configure(k8_northbridges[i], gatt_bus); |
| 231 | } | 210 | } |
| 211 | k8_flush_garts(); | ||
| 232 | return 0; | 212 | return 0; |
| 233 | } | 213 | } |
| 234 | 214 | ||
| @@ -236,12 +216,13 @@ static int amd_8151_configure(void) | |||
| 236 | static void amd64_cleanup(void) | 216 | static void amd64_cleanup(void) |
| 237 | { | 217 | { |
| 238 | u32 tmp; | 218 | u32 tmp; |
| 239 | int gart_iterator; | 219 | int i; |
| 240 | for_each_nb() { | 220 | for (i = 0; i < num_k8_northbridges; i++) { |
| 221 | struct pci_dev *dev = k8_northbridges[i]; | ||
| 241 | /* disable gart translation */ | 222 | /* disable gart translation */ |
| 242 | pci_read_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, &tmp); | 223 | pci_read_config_dword (dev, AMD64_GARTAPERTURECTL, &tmp); |
| 243 | tmp &= ~AMD64_GARTEN; | 224 | tmp &= ~AMD64_GARTEN; |
| 244 | pci_write_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, tmp); | 225 | pci_write_config_dword (dev, AMD64_GARTAPERTURECTL, tmp); |
| 245 | } | 226 | } |
| 246 | } | 227 | } |
| 247 | 228 | ||
| @@ -361,17 +342,15 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, | |||
| 361 | 342 | ||
| 362 | static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) | 343 | static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) |
| 363 | { | 344 | { |
| 364 | struct pci_dev *loop_dev = NULL; | 345 | int i; |
| 365 | int i = 0; | 346 | |
| 366 | 347 | if (cache_k8_northbridges() < 0) | |
| 367 | /* cache pci_devs of northbridges. */ | 348 | return -ENODEV; |
| 368 | while ((loop_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) | 349 | |
| 369 | != NULL) { | 350 | i = 0; |
| 370 | if (i == MAX_HAMMER_GARTS) { | 351 | for (i = 0; i < num_k8_northbridges; i++) { |
| 371 | printk(KERN_ERR PFX "Too many northbridges for AGP\n"); | 352 | struct pci_dev *dev = k8_northbridges[i]; |
| 372 | return -1; | 353 | if (fix_northbridge(dev, pdev, cap_ptr) < 0) { |
| 373 | } | ||
| 374 | if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) { | ||
| 375 | printk(KERN_ERR PFX "No usable aperture found.\n"); | 354 | printk(KERN_ERR PFX "No usable aperture found.\n"); |
| 376 | #ifdef __x86_64__ | 355 | #ifdef __x86_64__ |
| 377 | /* should port this to i386 */ | 356 | /* should port this to i386 */ |
| @@ -379,10 +358,8 @@ static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) | |||
| 379 | #endif | 358 | #endif |
| 380 | return -1; | 359 | return -1; |
| 381 | } | 360 | } |
| 382 | hammers[i++] = loop_dev; | ||
| 383 | } | 361 | } |
| 384 | nr_garts = i; | 362 | return 0; |
| 385 | return i == 0 ? -1 : 0; | ||
| 386 | } | 363 | } |
| 387 | 364 | ||
| 388 | /* Handle AMD 8151 quirks */ | 365 | /* Handle AMD 8151 quirks */ |
| @@ -450,7 +427,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) | |||
| 450 | } | 427 | } |
| 451 | 428 | ||
| 452 | /* shadow x86-64 registers into ULi registers */ | 429 | /* shadow x86-64 registers into ULi registers */ |
| 453 | pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &httfea); | 430 | pci_read_config_dword (k8_northbridges[0], AMD64_GARTAPERTUREBASE, &httfea); |
| 454 | 431 | ||
| 455 | /* if x86-64 aperture base is beyond 4G, exit here */ | 432 | /* if x86-64 aperture base is beyond 4G, exit here */ |
| 456 | if ((httfea & 0x7fff) >> (32 - 25)) | 433 | if ((httfea & 0x7fff) >> (32 - 25)) |
| @@ -513,7 +490,7 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev) | |||
| 513 | pci_write_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, tmp); | 490 | pci_write_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, tmp); |
| 514 | 491 | ||
| 515 | /* shadow x86-64 registers into NVIDIA registers */ | 492 | /* shadow x86-64 registers into NVIDIA registers */ |
| 516 | pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase); | 493 | pci_read_config_dword (k8_northbridges[0], AMD64_GARTAPERTUREBASE, &apbase); |
| 517 | 494 | ||
| 518 | /* if x86-64 aperture base is beyond 4G, exit here */ | 495 | /* if x86-64 aperture base is beyond 4G, exit here */ |
| 519 | if ( (apbase & 0x7fff) >> (32 - 25) ) { | 496 | if ( (apbase & 0x7fff) >> (32 - 25) ) { |
| @@ -754,10 +731,6 @@ static struct pci_driver agp_amd64_pci_driver = { | |||
| 754 | int __init agp_amd64_init(void) | 731 | int __init agp_amd64_init(void) |
| 755 | { | 732 | { |
| 756 | int err = 0; | 733 | int err = 0; |
| 757 | static struct pci_device_id amd64nb[] = { | ||
| 758 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) }, | ||
| 759 | { }, | ||
| 760 | }; | ||
| 761 | 734 | ||
| 762 | if (agp_off) | 735 | if (agp_off) |
| 763 | return -EINVAL; | 736 | return -EINVAL; |
| @@ -774,7 +747,7 @@ int __init agp_amd64_init(void) | |||
| 774 | } | 747 | } |
| 775 | 748 | ||
| 776 | /* First check that we have at least one AMD64 NB */ | 749 | /* First check that we have at least one AMD64 NB */ |
| 777 | if (!pci_dev_present(amd64nb)) | 750 | if (!pci_dev_present(k8_nb_ids)) |
| 778 | return -ENODEV; | 751 | return -ENODEV; |
| 779 | 752 | ||
| 780 | /* Look for any AGP bridge */ | 753 | /* Look for any AGP bridge */ |
