diff options
Diffstat (limited to 'drivers/char/agp/amd64-agp.c')
-rw-r--r-- | drivers/char/agp/amd64-agp.c | 85 |
1 files changed, 26 insertions, 59 deletions
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 13665db363d6..481ffe87c716 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -16,28 +16,9 @@ | |||
16 | #include <asm/page.h> /* PAGE_SIZE */ | 16 | #include <asm/page.h> /* PAGE_SIZE */ |
17 | #include <asm/e820.h> | 17 | #include <asm/e820.h> |
18 | #include <asm/k8.h> | 18 | #include <asm/k8.h> |
19 | #include <asm/gart.h> | ||
19 | #include "agp.h" | 20 | #include "agp.h" |
20 | 21 | ||
21 | /* PTE bits. */ | ||
22 | #define GPTE_VALID 1 | ||
23 | #define GPTE_COHERENT 2 | ||
24 | |||
25 | /* Aperture control register bits. */ | ||
26 | #define GARTEN (1<<0) | ||
27 | #define DISGARTCPU (1<<4) | ||
28 | #define DISGARTIO (1<<5) | ||
29 | |||
30 | /* GART cache control register bits. */ | ||
31 | #define INVGART (1<<0) | ||
32 | #define GARTPTEERR (1<<1) | ||
33 | |||
34 | /* K8 On-cpu GART registers */ | ||
35 | #define AMD64_GARTAPERTURECTL 0x90 | ||
36 | #define AMD64_GARTAPERTUREBASE 0x94 | ||
37 | #define AMD64_GARTTABLEBASE 0x98 | ||
38 | #define AMD64_GARTCACHECTL 0x9c | ||
39 | #define AMD64_GARTEN (1<<0) | ||
40 | |||
41 | /* NVIDIA K8 registers */ | 22 | /* NVIDIA K8 registers */ |
42 | #define NVIDIA_X86_64_0_APBASE 0x10 | 23 | #define NVIDIA_X86_64_0_APBASE 0x10 |
43 | #define NVIDIA_X86_64_1_APBASE1 0x50 | 24 | #define NVIDIA_X86_64_1_APBASE1 0x50 |
@@ -165,29 +146,18 @@ static int amd64_fetch_size(void) | |||
165 | * In a multiprocessor x86-64 system, this function gets | 146 | * In a multiprocessor x86-64 system, this function gets |
166 | * called once for each CPU. | 147 | * called once for each CPU. |
167 | */ | 148 | */ |
168 | static u64 amd64_configure (struct pci_dev *hammer, u64 gatt_table) | 149 | static u64 amd64_configure(struct pci_dev *hammer, u64 gatt_table) |
169 | { | 150 | { |
170 | u64 aperturebase; | 151 | u64 aperturebase; |
171 | u32 tmp; | 152 | u32 tmp; |
172 | u64 addr, aper_base; | 153 | u64 aper_base; |
173 | 154 | ||
174 | /* Address to map to */ | 155 | /* Address to map to */ |
175 | pci_read_config_dword (hammer, AMD64_GARTAPERTUREBASE, &tmp); | 156 | pci_read_config_dword(hammer, AMD64_GARTAPERTUREBASE, &tmp); |
176 | aperturebase = tmp << 25; | 157 | aperturebase = tmp << 25; |
177 | aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK); | 158 | aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK); |
178 | 159 | ||
179 | /* address of the mappings table */ | 160 | enable_gart_translation(hammer, gatt_table); |
180 | addr = (u64) gatt_table; | ||
181 | addr >>= 12; | ||
182 | tmp = (u32) addr<<4; | ||
183 | tmp &= ~0xf; | ||
184 | pci_write_config_dword (hammer, AMD64_GARTTABLEBASE, tmp); | ||
185 | |||
186 | /* Enable GART translation for this hammer. */ | ||
187 | pci_read_config_dword(hammer, AMD64_GARTAPERTURECTL, &tmp); | ||
188 | tmp |= GARTEN; | ||
189 | tmp &= ~(DISGARTCPU | DISGARTIO); | ||
190 | pci_write_config_dword(hammer, AMD64_GARTAPERTURECTL, tmp); | ||
191 | 161 | ||
192 | return aper_base; | 162 | return aper_base; |
193 | } | 163 | } |
@@ -226,9 +196,9 @@ static void amd64_cleanup(void) | |||
226 | for (i = 0; i < num_k8_northbridges; i++) { | 196 | for (i = 0; i < num_k8_northbridges; i++) { |
227 | struct pci_dev *dev = k8_northbridges[i]; | 197 | struct pci_dev *dev = k8_northbridges[i]; |
228 | /* disable gart translation */ | 198 | /* disable gart translation */ |
229 | pci_read_config_dword (dev, AMD64_GARTAPERTURECTL, &tmp); | 199 | pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &tmp); |
230 | tmp &= ~AMD64_GARTEN; | 200 | tmp &= ~AMD64_GARTEN; |
231 | pci_write_config_dword (dev, AMD64_GARTAPERTURECTL, tmp); | 201 | pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, tmp); |
232 | } | 202 | } |
233 | } | 203 | } |
234 | 204 | ||
@@ -258,24 +228,10 @@ static const struct agp_bridge_driver amd_8151_driver = { | |||
258 | }; | 228 | }; |
259 | 229 | ||
260 | /* Some basic sanity checks for the aperture. */ | 230 | /* Some basic sanity checks for the aperture. */ |
261 | static int __devinit aperture_valid(u64 aper, u32 size) | 231 | static int __devinit agp_aperture_valid(u64 aper, u32 size) |
262 | { | 232 | { |
263 | if (aper == 0) { | 233 | if (!aperture_valid(aper, size, 32*1024*1024)) |
264 | printk(KERN_ERR PFX "No aperture\n"); | ||
265 | return 0; | ||
266 | } | ||
267 | if (size < 32*1024*1024) { | ||
268 | printk(KERN_ERR PFX "Aperture too small (%d MB)\n", size>>20); | ||
269 | return 0; | ||
270 | } | ||
271 | if ((u64)aper + size > 0x100000000ULL) { | ||
272 | printk(KERN_ERR PFX "Aperture out of bounds\n"); | ||
273 | return 0; | 234 | return 0; |
274 | } | ||
275 | if (e820_any_mapped(aper, aper + size, E820_RAM)) { | ||
276 | printk(KERN_ERR PFX "Aperture pointing to RAM\n"); | ||
277 | return 0; | ||
278 | } | ||
279 | 235 | ||
280 | /* Request the Aperture. This catches cases when someone else | 236 | /* Request the Aperture. This catches cases when someone else |
281 | already put a mapping in there - happens with some very broken BIOS | 237 | already put a mapping in there - happens with some very broken BIOS |
@@ -308,11 +264,11 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, | |||
308 | u32 nb_order, nb_base; | 264 | u32 nb_order, nb_base; |
309 | u16 apsize; | 265 | u16 apsize; |
310 | 266 | ||
311 | pci_read_config_dword(nb, 0x90, &nb_order); | 267 | pci_read_config_dword(nb, AMD64_GARTAPERTURECTL, &nb_order); |
312 | nb_order = (nb_order >> 1) & 7; | 268 | nb_order = (nb_order >> 1) & 7; |
313 | pci_read_config_dword(nb, 0x94, &nb_base); | 269 | pci_read_config_dword(nb, AMD64_GARTAPERTUREBASE, &nb_base); |
314 | nb_aper = nb_base << 25; | 270 | nb_aper = nb_base << 25; |
315 | if (aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) { | 271 | if (agp_aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) { |
316 | return 0; | 272 | return 0; |
317 | } | 273 | } |
318 | 274 | ||
@@ -331,12 +287,23 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, | |||
331 | pci_read_config_dword(agp, 0x10, &aper_low); | 287 | pci_read_config_dword(agp, 0x10, &aper_low); |
332 | pci_read_config_dword(agp, 0x14, &aper_hi); | 288 | pci_read_config_dword(agp, 0x14, &aper_hi); |
333 | aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); | 289 | aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); |
290 | |||
291 | /* | ||
292 | * On some sick chips APSIZE is 0. This means it wants 4G | ||
293 | * so let double check that order, and lets trust the AMD NB settings | ||
294 | */ | ||
295 | if (order >=0 && aper + (32ULL<<(20 + order)) > 0x100000000ULL) { | ||
296 | printk(KERN_INFO "Aperture size %u MB is not right, using settings from NB\n", | ||
297 | 32 << order); | ||
298 | order = nb_order; | ||
299 | } | ||
300 | |||
334 | printk(KERN_INFO PFX "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order); | 301 | printk(KERN_INFO PFX "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order); |
335 | if (order < 0 || !aperture_valid(aper, (32*1024*1024)<<order)) | 302 | if (order < 0 || !agp_aperture_valid(aper, (32*1024*1024)<<order)) |
336 | return -1; | 303 | return -1; |
337 | 304 | ||
338 | pci_write_config_dword(nb, 0x90, order << 1); | 305 | pci_write_config_dword(nb, AMD64_GARTAPERTURECTL, order << 1); |
339 | pci_write_config_dword(nb, 0x94, aper >> 25); | 306 | pci_write_config_dword(nb, AMD64_GARTAPERTUREBASE, aper >> 25); |
340 | 307 | ||
341 | return 0; | 308 | return 0; |
342 | } | 309 | } |