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 13665db363d..481ffe87c71 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 | } |
