aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/k8.h13
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c4
-rw-r--r--arch/x86/kernel/k8.c52
-rw-r--r--arch/x86/kernel/pci-gart_64.c27
-rw-r--r--drivers/char/agp/amd64-agp.c33
-rw-r--r--drivers/edac/amd64_edac.c2
6 files changed, 82 insertions, 49 deletions
diff --git a/arch/x86/include/asm/k8.h b/arch/x86/include/asm/k8.h
index af00bd1d2089..9cee145dcace 100644
--- a/arch/x86/include/asm/k8.h
+++ b/arch/x86/include/asm/k8.h
@@ -7,24 +7,27 @@ extern struct pci_device_id k8_nb_ids[];
7struct bootnode; 7struct bootnode;
8 8
9extern int early_is_k8_nb(u32 value); 9extern int early_is_k8_nb(u32 value);
10extern struct pci_dev **k8_northbridges;
11extern int num_k8_northbridges;
12extern int cache_k8_northbridges(void); 10extern int cache_k8_northbridges(void);
13extern void k8_flush_garts(void); 11extern void k8_flush_garts(void);
14extern int k8_get_nodes(struct bootnode *nodes); 12extern int k8_get_nodes(struct bootnode *nodes);
15extern int k8_numa_init(unsigned long start_pfn, unsigned long end_pfn); 13extern int k8_numa_init(unsigned long start_pfn, unsigned long end_pfn);
16extern int k8_scan_nodes(void); 14extern int k8_scan_nodes(void);
17 15
16struct k8_northbridge_info {
17 u16 num;
18 u8 gart_supported;
19 struct pci_dev **nb_misc;
20};
21extern struct k8_northbridge_info k8_northbridges;
22
18#ifdef CONFIG_K8_NB 23#ifdef CONFIG_K8_NB
19extern int num_k8_northbridges;
20 24
21static inline struct pci_dev *node_to_k8_nb_misc(int node) 25static inline struct pci_dev *node_to_k8_nb_misc(int node)
22{ 26{
23 return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL; 27 return (node < k8_northbridges.num) ? k8_northbridges.nb_misc[node] : NULL;
24} 28}
25 29
26#else 30#else
27#define num_k8_northbridges 0
28 31
29static inline struct pci_dev *node_to_k8_nb_misc(int node) 32static inline struct pci_dev *node_to_k8_nb_misc(int node)
30{ 33{
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 2521cdcb877e..6fdfb0b20f8c 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -369,7 +369,7 @@ static void __cpuinit amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf,
369 return; 369 return;
370 370
371 /* not in virtualized environments */ 371 /* not in virtualized environments */
372 if (num_k8_northbridges == 0) 372 if (k8_northbridges.num == 0)
373 return; 373 return;
374 374
375 /* 375 /*
@@ -377,7 +377,7 @@ static void __cpuinit amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf,
377 * never freed but this is done only on shutdown so it doesn't matter. 377 * never freed but this is done only on shutdown so it doesn't matter.
378 */ 378 */
379 if (!l3_caches) { 379 if (!l3_caches) {
380 int size = num_k8_northbridges * sizeof(struct amd_l3_cache *); 380 int size = k8_northbridges.num * sizeof(struct amd_l3_cache *);
381 381
382 l3_caches = kzalloc(size, GFP_ATOMIC); 382 l3_caches = kzalloc(size, GFP_ATOMIC);
383 if (!l3_caches) 383 if (!l3_caches)
diff --git a/arch/x86/kernel/k8.c b/arch/x86/kernel/k8.c
index 0f7bc20cfcde..5de1b6b39639 100644
--- a/arch/x86/kernel/k8.c
+++ b/arch/x86/kernel/k8.c
@@ -10,9 +10,6 @@
10#include <linux/spinlock.h> 10#include <linux/spinlock.h>
11#include <asm/k8.h> 11#include <asm/k8.h>
12 12
13int num_k8_northbridges;
14EXPORT_SYMBOL(num_k8_northbridges);
15
16static u32 *flush_words; 13static u32 *flush_words;
17 14
18struct pci_device_id k8_nb_ids[] = { 15struct pci_device_id k8_nb_ids[] = {
@@ -22,7 +19,7 @@ struct pci_device_id k8_nb_ids[] = {
22}; 19};
23EXPORT_SYMBOL(k8_nb_ids); 20EXPORT_SYMBOL(k8_nb_ids);
24 21
25struct pci_dev **k8_northbridges; 22struct k8_northbridge_info k8_northbridges;
26EXPORT_SYMBOL(k8_northbridges); 23EXPORT_SYMBOL(k8_northbridges);
27 24
28static struct pci_dev *next_k8_northbridge(struct pci_dev *dev) 25static struct pci_dev *next_k8_northbridge(struct pci_dev *dev)
@@ -40,36 +37,44 @@ int cache_k8_northbridges(void)
40 int i; 37 int i;
41 struct pci_dev *dev; 38 struct pci_dev *dev;
42 39
43 if (num_k8_northbridges) 40 if (k8_northbridges.num)
44 return 0; 41 return 0;
45 42
46 dev = NULL; 43 dev = NULL;
47 while ((dev = next_k8_northbridge(dev)) != NULL) 44 while ((dev = next_k8_northbridge(dev)) != NULL)
48 num_k8_northbridges++; 45 k8_northbridges.num++;
46
47 /* some CPU families (e.g. family 0x11) do not support GART */
48 if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10)
49 k8_northbridges.gart_supported = 1;
49 50
50 k8_northbridges = kmalloc((num_k8_northbridges + 1) * sizeof(void *), 51 k8_northbridges.nb_misc = kmalloc((k8_northbridges.num + 1) *
51 GFP_KERNEL); 52 sizeof(void *), GFP_KERNEL);
52 if (!k8_northbridges) 53 if (!k8_northbridges.nb_misc)
53 return -ENOMEM; 54 return -ENOMEM;
54 55
55 if (!num_k8_northbridges) { 56 if (!k8_northbridges.num) {
56 k8_northbridges[0] = NULL; 57 k8_northbridges.nb_misc[0] = NULL;
57 return 0; 58 return 0;
58 } 59 }
59 60
60 flush_words = kmalloc(num_k8_northbridges * sizeof(u32), GFP_KERNEL); 61 if (k8_northbridges.gart_supported) {
61 if (!flush_words) { 62 flush_words = kmalloc(k8_northbridges.num * sizeof(u32),
62 kfree(k8_northbridges); 63 GFP_KERNEL);
63 return -ENOMEM; 64 if (!flush_words) {
65 kfree(k8_northbridges.nb_misc);
66 return -ENOMEM;
67 }
64 } 68 }
65 69
66 dev = NULL; 70 dev = NULL;
67 i = 0; 71 i = 0;
68 while ((dev = next_k8_northbridge(dev)) != NULL) { 72 while ((dev = next_k8_northbridge(dev)) != NULL) {
69 k8_northbridges[i] = dev; 73 k8_northbridges.nb_misc[i] = dev;
70 pci_read_config_dword(dev, 0x9c, &flush_words[i++]); 74 if (k8_northbridges.gart_supported)
75 pci_read_config_dword(dev, 0x9c, &flush_words[i++]);
71 } 76 }
72 k8_northbridges[i] = NULL; 77 k8_northbridges.nb_misc[i] = NULL;
73 return 0; 78 return 0;
74} 79}
75EXPORT_SYMBOL_GPL(cache_k8_northbridges); 80EXPORT_SYMBOL_GPL(cache_k8_northbridges);
@@ -93,22 +98,25 @@ void k8_flush_garts(void)
93 unsigned long flags; 98 unsigned long flags;
94 static DEFINE_SPINLOCK(gart_lock); 99 static DEFINE_SPINLOCK(gart_lock);
95 100
101 if (!k8_northbridges.gart_supported)
102 return;
103
96 /* Avoid races between AGP and IOMMU. In theory it's not needed 104 /* Avoid races between AGP and IOMMU. In theory it's not needed
97 but I'm not sure if the hardware won't lose flush requests 105 but I'm not sure if the hardware won't lose flush requests
98 when another is pending. This whole thing is so expensive anyways 106 when another is pending. This whole thing is so expensive anyways
99 that it doesn't matter to serialize more. -AK */ 107 that it doesn't matter to serialize more. -AK */
100 spin_lock_irqsave(&gart_lock, flags); 108 spin_lock_irqsave(&gart_lock, flags);
101 flushed = 0; 109 flushed = 0;
102 for (i = 0; i < num_k8_northbridges; i++) { 110 for (i = 0; i < k8_northbridges.num; i++) {
103 pci_write_config_dword(k8_northbridges[i], 0x9c, 111 pci_write_config_dword(k8_northbridges.nb_misc[i], 0x9c,
104 flush_words[i]|1); 112 flush_words[i]|1);
105 flushed++; 113 flushed++;
106 } 114 }
107 for (i = 0; i < num_k8_northbridges; i++) { 115 for (i = 0; i < k8_northbridges.num; i++) {
108 u32 w; 116 u32 w;
109 /* Make sure the hardware actually executed the flush*/ 117 /* Make sure the hardware actually executed the flush*/
110 for (;;) { 118 for (;;) {
111 pci_read_config_dword(k8_northbridges[i], 119 pci_read_config_dword(k8_northbridges.nb_misc[i],
112 0x9c, &w); 120 0x9c, &w);
113 if (!(w & 1)) 121 if (!(w & 1))
114 break; 122 break;
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 0f7f130caa67..8f214a2643fa 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -560,8 +560,11 @@ static void enable_gart_translations(void)
560{ 560{
561 int i; 561 int i;
562 562
563 for (i = 0; i < num_k8_northbridges; i++) { 563 if (!k8_northbridges.gart_supported)
564 struct pci_dev *dev = k8_northbridges[i]; 564 return;
565
566 for (i = 0; i < k8_northbridges.num; i++) {
567 struct pci_dev *dev = k8_northbridges.nb_misc[i];
565 568
566 enable_gart_translation(dev, __pa(agp_gatt_table)); 569 enable_gart_translation(dev, __pa(agp_gatt_table));
567 } 570 }
@@ -592,10 +595,13 @@ static void gart_fixup_northbridges(struct sys_device *dev)
592 if (!fix_up_north_bridges) 595 if (!fix_up_north_bridges)
593 return; 596 return;
594 597
598 if (!k8_northbridges.gart_supported)
599 return;
600
595 pr_info("PCI-DMA: Restoring GART aperture settings\n"); 601 pr_info("PCI-DMA: Restoring GART aperture settings\n");
596 602
597 for (i = 0; i < num_k8_northbridges; i++) { 603 for (i = 0; i < k8_northbridges.num; i++) {
598 struct pci_dev *dev = k8_northbridges[i]; 604 struct pci_dev *dev = k8_northbridges.nb_misc[i];
599 605
600 /* 606 /*
601 * Don't enable translations just yet. That is the next 607 * Don't enable translations just yet. That is the next
@@ -649,8 +655,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
649 655
650 aper_size = aper_base = info->aper_size = 0; 656 aper_size = aper_base = info->aper_size = 0;
651 dev = NULL; 657 dev = NULL;
652 for (i = 0; i < num_k8_northbridges; i++) { 658 for (i = 0; i < k8_northbridges.num; i++) {
653 dev = k8_northbridges[i]; 659 dev = k8_northbridges.nb_misc[i];
654 new_aper_base = read_aperture(dev, &new_aper_size); 660 new_aper_base = read_aperture(dev, &new_aper_size);
655 if (!new_aper_base) 661 if (!new_aper_base)
656 goto nommu; 662 goto nommu;
@@ -718,10 +724,13 @@ static void gart_iommu_shutdown(void)
718 if (!no_agp) 724 if (!no_agp)
719 return; 725 return;
720 726
721 for (i = 0; i < num_k8_northbridges; i++) { 727 if (!k8_northbridges.gart_supported)
728 return;
729
730 for (i = 0; i < k8_northbridges.num; i++) {
722 u32 ctl; 731 u32 ctl;
723 732
724 dev = k8_northbridges[i]; 733 dev = k8_northbridges.nb_misc[i];
725 pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl); 734 pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl);
726 735
727 ctl &= ~GARTEN; 736 ctl &= ~GARTEN;
@@ -739,7 +748,7 @@ int __init gart_iommu_init(void)
739 unsigned long scratch; 748 unsigned long scratch;
740 long i; 749 long i;
741 750
742 if (num_k8_northbridges == 0) 751 if (!k8_northbridges.gart_supported)
743 return 0; 752 return 0;
744 753
745#ifndef CONFIG_AGP_AMD64 754#ifndef CONFIG_AGP_AMD64
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 70312da4c968..bdf00d583d79 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -124,7 +124,7 @@ static int amd64_fetch_size(void)
124 u32 temp; 124 u32 temp;
125 struct aper_size_info_32 *values; 125 struct aper_size_info_32 *values;
126 126
127 dev = k8_northbridges[0]; 127 dev = k8_northbridges.nb_misc[0];
128 if (dev==NULL) 128 if (dev==NULL)
129 return 0; 129 return 0;
130 130
@@ -181,10 +181,14 @@ static int amd_8151_configure(void)
181 unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real); 181 unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real);
182 int i; 182 int i;
183 183
184 if (!k8_northbridges.gart_supported)
185 return 0;
186
184 /* Configure AGP regs in each x86-64 host bridge. */ 187 /* Configure AGP regs in each x86-64 host bridge. */
185 for (i = 0; i < num_k8_northbridges; i++) { 188 for (i = 0; i < k8_northbridges.num; i++) {
186 agp_bridge->gart_bus_addr = 189 agp_bridge->gart_bus_addr =
187 amd64_configure(k8_northbridges[i], gatt_bus); 190 amd64_configure(k8_northbridges.nb_misc[i],
191 gatt_bus);
188 } 192 }
189 k8_flush_garts(); 193 k8_flush_garts();
190 return 0; 194 return 0;
@@ -195,8 +199,12 @@ static void amd64_cleanup(void)
195{ 199{
196 u32 tmp; 200 u32 tmp;
197 int i; 201 int i;
198 for (i = 0; i < num_k8_northbridges; i++) { 202
199 struct pci_dev *dev = k8_northbridges[i]; 203 if (!k8_northbridges.gart_supported)
204 return;
205
206 for (i = 0; i < k8_northbridges.num; i++) {
207 struct pci_dev *dev = k8_northbridges.nb_misc[i];
200 /* disable gart translation */ 208 /* disable gart translation */
201 pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &tmp); 209 pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &tmp);
202 tmp &= ~AMD64_GARTEN; 210 tmp &= ~AMD64_GARTEN;
@@ -319,16 +327,19 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
319 return 0; 327 return 0;
320} 328}
321 329
322static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) 330static __devinit int cache_nbs(struct pci_dev *pdev, u32 cap_ptr)
323{ 331{
324 int i; 332 int i;
325 333
326 if (cache_k8_northbridges() < 0) 334 if (cache_k8_northbridges() < 0)
327 return -ENODEV; 335 return -ENODEV;
328 336
337 if (!k8_northbridges.gart_supported)
338 return -ENODEV;
339
329 i = 0; 340 i = 0;
330 for (i = 0; i < num_k8_northbridges; i++) { 341 for (i = 0; i < k8_northbridges.num; i++) {
331 struct pci_dev *dev = k8_northbridges[i]; 342 struct pci_dev *dev = k8_northbridges.nb_misc[i];
332 if (fix_northbridge(dev, pdev, cap_ptr) < 0) { 343 if (fix_northbridge(dev, pdev, cap_ptr) < 0) {
333 dev_err(&dev->dev, "no usable aperture found\n"); 344 dev_err(&dev->dev, "no usable aperture found\n");
334#ifdef __x86_64__ 345#ifdef __x86_64__
@@ -405,7 +416,8 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
405 } 416 }
406 417
407 /* shadow x86-64 registers into ULi registers */ 418 /* shadow x86-64 registers into ULi registers */
408 pci_read_config_dword (k8_northbridges[0], AMD64_GARTAPERTUREBASE, &httfea); 419 pci_read_config_dword (k8_northbridges.nb_misc[0], AMD64_GARTAPERTUREBASE,
420 &httfea);
409 421
410 /* if x86-64 aperture base is beyond 4G, exit here */ 422 /* if x86-64 aperture base is beyond 4G, exit here */
411 if ((httfea & 0x7fff) >> (32 - 25)) { 423 if ((httfea & 0x7fff) >> (32 - 25)) {
@@ -472,7 +484,8 @@ static int nforce3_agp_init(struct pci_dev *pdev)
472 pci_write_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, tmp); 484 pci_write_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, tmp);
473 485
474 /* shadow x86-64 registers into NVIDIA registers */ 486 /* shadow x86-64 registers into NVIDIA registers */
475 pci_read_config_dword (k8_northbridges[0], AMD64_GARTAPERTUREBASE, &apbase); 487 pci_read_config_dword (k8_northbridges.nb_misc[0], AMD64_GARTAPERTUREBASE,
488 &apbase);
476 489
477 /* if x86-64 aperture base is beyond 4G, exit here */ 490 /* if x86-64 aperture base is beyond 4G, exit here */
478 if ( (apbase & 0x7fff) >> (32 - 25) ) { 491 if ( (apbase & 0x7fff) >> (32 - 25) ) {
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index e7d5d6b5dcf6..5babf6f48058 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2927,7 +2927,7 @@ static int __init amd64_edac_init(void)
2927 * to finish initialization of the MC instances. 2927 * to finish initialization of the MC instances.
2928 */ 2928 */
2929 err = -ENODEV; 2929 err = -ENODEV;
2930 for (nb = 0; nb < num_k8_northbridges; nb++) { 2930 for (nb = 0; nb < k8_northbridges.num; nb++) {
2931 if (!pvt_lookup[nb]) 2931 if (!pvt_lookup[nb])
2932 continue; 2932 continue;
2933 2933