aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/amd64-agp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/agp/amd64-agp.c')
-rw-r--r--drivers/char/agp/amd64-agp.c81
1 files changed, 27 insertions, 54 deletions
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index ac3c33a2e37d..f690ee8cb732 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
56static int nr_garts;
57static struct pci_dev * hammers[MAX_HAMMER_GARTS];
58
59static struct resource *aperture_resource; 54static struct resource *aperture_resource;
60static int __initdata agp_try_unsupported = 1; 55static int __initdata agp_try_unsupported = 1;
61 56
62#define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++)
63
64static 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
73static void amd64_tlbflush(struct agp_memory *temp) 57static 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
80static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type) 62static 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] =
222static int amd_8151_configure(void) 201static 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)
236static void amd64_cleanup(void) 216static 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
@@ -311,7 +292,7 @@ static int __devinit aperture_valid(u64 aper, u32 size)
311/* 292/*
312 * W*s centric BIOS sometimes only set up the aperture in the AGP 293 * W*s centric BIOS sometimes only set up the aperture in the AGP
313 * bridge, not the northbridge. On AMD64 this is handled early 294 * bridge, not the northbridge. On AMD64 this is handled early
314 * in aperture.c, but when GART_IOMMU is not enabled or we run 295 * in aperture.c, but when IOMMU is not enabled or we run
315 * on a 32bit kernel this needs to be redone. 296 * on a 32bit kernel this needs to be redone.
316 * Unfortunately it is impossible to fix the aperture here because it's too late 297 * Unfortunately it is impossible to fix the aperture here because it's too late
317 * to allocate that much memory. But at least error out cleanly instead of 298 * to allocate that much memory. But at least error out cleanly instead of
@@ -361,17 +342,15 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
361 342
362static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) 343static __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 = {
754int __init agp_amd64_init(void) 731int __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 */
@@ -802,7 +775,7 @@ static void __exit agp_amd64_cleanup(void)
802 775
803/* On AMD64 the PCI driver needs to initialize this driver early 776/* On AMD64 the PCI driver needs to initialize this driver early
804 for the IOMMU, so it has to be called via a backdoor. */ 777 for the IOMMU, so it has to be called via a backdoor. */
805#ifndef CONFIG_GART_IOMMU 778#ifndef CONFIG_IOMMU
806module_init(agp_amd64_init); 779module_init(agp_amd64_init);
807module_exit(agp_amd64_cleanup); 780module_exit(agp_amd64_cleanup);
808#endif 781#endif