2 * Copyright 2001-2003 SuSE Labs.
3 * Distributed under the GNU public license, v2.
5 * This is a GART driver for the AMD Opteron/Athlon64 on-CPU northbridge.
6 * It also includes support for the AMD 8151 AGP bridge,
7 * although it doesn't actually do much, as all the real
8 * work is done in the northbridge(s).
11 #include <linux/module.h>
12 #include <linux/pci.h>
13 #include <linux/init.h>
14 #include <linux/agp_backend.h>
17 /* Will need to be increased if hammer ever goes >8-way. */
19 #define MAX_HAMMER_GARTS 8
21 #define MAX_HAMMER_GARTS 1
26 #define GPTE_COHERENT 2
28 /* Aperture control register bits. */
30 #define DISGARTCPU 1<<4
31 #define DISGARTIO 1<<5
33 /* GART cache control register bits. */
35 #define GARTPTEERR 1<<1
38 static struct pci_dev * hammers[MAX_HAMMER_GARTS];
40 static int __initdata agp_try_unsupported;
42 static int gart_iterator;
43 #define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++)
45 static void flush_x86_64_tlb(struct pci_dev *dev)
49 pci_read_config_dword (dev, AMD_X86_64_GARTCACHECTL, &tmp);
51 pci_write_config_dword (dev, AMD_X86_64_GARTCACHECTL, tmp);
54 static void amd_x86_64_tlbflush(struct agp_memory *temp)
57 flush_x86_64_tlb(hammers[gart_iterator]);
60 static int x86_64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
62 int i, j, num_entries;
66 num_entries = agp_num_entries();
68 if (type != 0 || mem->type != 0)
71 /* Make sure we can fit the range in the gatt table. */
72 /* FIXME: could wrap */
73 if (((unsigned long)pg_start + mem->page_count) > num_entries)
78 /* gatt table should be empty. */
79 while (j < (pg_start + mem->page_count)) {
80 if (!PGE_EMPTY(agp_bridge, agp_bridge->gatt_table[j]))
85 if (mem->is_flushed == FALSE) {
87 mem->is_flushed = TRUE;
90 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
91 tmp = agp_bridge->driver->mask_memory(mem->memory[i], mem->type);
93 BUG_ON(tmp & 0xffffff0000000ffc);
94 pte = (tmp & 0x000000ff00000000) >> 28;
95 pte |=(tmp & 0x00000000fffff000);
96 pte |= GPTE_VALID | GPTE_COHERENT;
98 agp_bridge->gatt_table[j] = pte;
100 amd_x86_64_tlbflush(mem);
105 * This hack alters the order element according
106 * to the size of a long. It sucks. I totally disown this, even
107 * though it does appear to work for the most part.
109 static struct aper_size_info_32 x86_64_aperture_sizes[7] =
111 {32, 8192, 3+(sizeof(long)/8), 0 },
112 {64, 16384, 4+(sizeof(long)/8), 1<<1 },
113 {128, 32768, 5+(sizeof(long)/8), 1<<2 },
114 {256, 65536, 6+(sizeof(long)/8), 1<<1 | 1<<2 },
115 {512, 131072, 7+(sizeof(long)/8), 1<<3 },
116 {1024, 262144, 8+(sizeof(long)/8), 1<<1 | 1<<3},
117 {2048, 524288, 9+(sizeof(long)/8), 1<<2 | 1<<3}
122 * Get the current Aperture size from the x86-64.
123 * Note, that there may be multiple x86-64's, but we just return
124 * the value from the first one we find. The set_size functions
125 * keep the rest coherent anyway. Or at least should do.
127 static int amd_x86_64_fetch_size(void)
132 struct aper_size_info_32 *values;
138 pci_read_config_dword(dev, AMD_X86_64_GARTAPERTURECTL, &temp);
140 values = A_SIZE_32(x86_64_aperture_sizes);
142 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
143 if (temp == values[i].size_value) {
144 agp_bridge->previous_size =
145 agp_bridge->current_size = (void *) (values + i);
147 agp_bridge->aperture_size_idx = i;
148 return values[i].size;
155 * In a multiprocessor x86-64 system, this function gets
156 * called once for each CPU.
158 static u64 amd_x86_64_configure (struct pci_dev *hammer, u64 gatt_table)
164 /* Address to map to */
165 pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
166 aperturebase = tmp << 25;
167 aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK);
169 /* address of the mappings table */
170 addr = (u64) gatt_table;
174 pci_write_config_dword (hammer, AMD_X86_64_GARTTABLEBASE, tmp);
176 /* Enable GART translation for this hammer. */
177 pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp);
179 tmp &= ~(DISGARTCPU | DISGARTIO);
180 pci_write_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, tmp);
182 /* keep CPU's coherent. */
183 flush_x86_64_tlb (hammer);
189 static struct aper_size_info_32 amd_8151_sizes[7] =
191 {2048, 524288, 9, 0x00000000 }, /* 0 0 0 0 0 0 */
192 {1024, 262144, 8, 0x00000400 }, /* 1 0 0 0 0 0 */
193 {512, 131072, 7, 0x00000600 }, /* 1 1 0 0 0 0 */
194 {256, 65536, 6, 0x00000700 }, /* 1 1 1 0 0 0 */
195 {128, 32768, 5, 0x00000720 }, /* 1 1 1 1 0 0 */
196 {64, 16384, 4, 0x00000730 }, /* 1 1 1 1 1 0 */
197 {32, 8192, 3, 0x00000738 } /* 1 1 1 1 1 1 */
200 static int amd_8151_configure(void)
202 unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real);
204 /* Configure AGP regs in each x86-64 host bridge. */
206 agp_bridge->gart_bus_addr =
207 amd_x86_64_configure(hammers[gart_iterator],gatt_bus);
213 static void amd_8151_cleanup(void)
218 /* disable gart translation */
219 pci_read_config_dword (hammers[gart_iterator], AMD_X86_64_GARTAPERTURECTL, &tmp);
220 tmp &= ~(AMD_X86_64_GARTEN);
221 pci_write_config_dword (hammers[gart_iterator], AMD_X86_64_GARTAPERTURECTL, tmp);
226 struct agp_bridge_driver amd_8151_driver = {
227 .owner = THIS_MODULE,
228 .aperture_sizes = amd_8151_sizes,
229 .size_type = U32_APER_SIZE,
230 .num_aperture_sizes = 7,
231 .configure = amd_8151_configure,
232 .fetch_size = amd_x86_64_fetch_size,
233 .cleanup = amd_8151_cleanup,
234 .tlb_flush = amd_x86_64_tlbflush,
235 .mask_memory = agp_generic_mask_memory,
237 .agp_enable = agp_generic_enable,
238 .cache_flush = global_cache_flush,
239 .create_gatt_table = agp_generic_create_gatt_table,
240 .free_gatt_table = agp_generic_free_gatt_table,
241 .insert_memory = x86_64_insert_memory,
242 .remove_memory = agp_generic_remove_memory,
243 .alloc_by_type = agp_generic_alloc_by_type,
244 .free_by_type = agp_generic_free_by_type,
245 .agp_alloc_page = agp_generic_alloc_page,
246 .agp_destroy_page = agp_generic_destroy_page,
249 /* Some basic sanity checks for the aperture. */
250 static int __init aperture_valid(u64 aper, u32 size)
252 static int not_first_call;
255 printk(KERN_ERR "No aperture\n");
258 if (size < 32*1024*1024) {
259 printk(KERN_ERR "Aperture too small (%d MB)\n", size>>20);
262 if (aper + size > 0xffffffff) {
263 printk(KERN_ERR "Aperture out of bounds\n");
266 pfn = aper >> PAGE_SHIFT;
267 for (c = 0; c < size/PAGE_SIZE; c++) {
268 if (!pfn_valid(pfn + c))
270 if (!PageReserved(pfn_to_page(pfn + c))) {
271 printk(KERN_ERR "Aperture pointing to RAM\n");
276 /* Request the Aperture. This catches cases when someone else
277 already put a mapping in there - happens with some very broken BIOS
279 Maybe better to use pci_assign_resource/pci_enable_device instead trusting
281 if (!not_first_call && request_mem_region(aper, size, "aperture") < 0) {
282 printk(KERN_ERR "Aperture conflicts with PCI mapping.\n");
291 * W*s centric BIOS sometimes only set up the aperture in the AGP
292 * bridge, not the northbridge. On AMD64 this is handled early
293 * in aperture.c, but when GART_IOMMU is not enabled or we run
294 * on a 32bit kernel this needs to be redone.
295 * Unfortunately it is impossible to fix the aperture here because it's too late
296 * to allocate that much memory. But at least error out cleanly instead of
299 static __init int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
302 u32 aper_low, aper_hi;
305 u32 nb_order, nb_base;
308 printk("fix northbridge\n");
310 pci_read_config_dword(nb, 0x90, &nb_order);
311 nb_order = (nb_order >> 1) & 7;
312 pci_read_config_dword(nb, 0x94, &nb_base);
313 nb_aper = nb_base << 25;
314 if (aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) {
315 printk("aperture valid\n");
319 /* Northbridge seems to contain crap. Try the AGP bridge. */
321 pci_read_config_word(agp, cap+0x14, &apsize);
322 if (apsize == 0xffff)
326 /* Some BIOS use weird encodings not in the AGPv3 table. */
329 order = 7 - hweight16(apsize);
331 pci_read_config_dword(agp, 0x10, &aper_low);
332 pci_read_config_dword(agp, 0x14, &aper_hi);
333 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
334 printk(KERN_INFO "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order);
335 if (order < 0 || !aperture_valid(aper, (32*1024*1024)<<order)) {
336 printk("bad aperture\n");
340 pci_write_config_dword(nb, 0x90, order << 1);
341 pci_write_config_dword(nb, 0x94, aper >> 25);
346 static __init int cache_nbs (struct pci_dev *pdev, u32 cap_ptr)
348 struct pci_dev *loop_dev = NULL;
351 /* cache pci_devs of northbridges. */
352 while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev))
354 if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) {
355 printk("No usable aperture found.\n");
357 /* should port this to i386 */
358 printk("Consider rebooting with iommu=memaper=2 to get a good aperture.\n");
362 hammers[i++] = loop_dev;
364 if (i == MAX_HAMMER_GARTS) {
365 printk(KERN_INFO "Too many northbridges for AGP\n");
369 return i == 0 ? -1 : 0;
372 static int __init agp_amdk8_probe(struct pci_dev *pdev,
373 const struct pci_device_id *ent)
375 struct agp_bridge_data *bridge;
380 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
384 /* Could check for AGPv3 here */
386 bridge = agp_alloc_bridge();
390 if (pdev->vendor == PCI_VENDOR_ID_AMD &&
391 pdev->device == PCI_DEVICE_ID_AMD_8151_0) {
393 pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
395 case 0x01: revstring="A0";
397 case 0x02: revstring="A1";
399 case 0x11: revstring="B0";
401 case 0x12: revstring="B1";
403 case 0x13: revstring="B2";
405 default: revstring="??";
408 printk (KERN_INFO PFX "Detected AMD 8151 AGP Bridge rev %s\n", revstring);
410 * Work around errata.
411 * Chips before B2 stepping incorrectly reporting v3.5
414 printk (KERN_INFO PFX "Correcting AGP revision (reports 3.5, is really 3.0)\n");
415 bridge->major_version = 3;
416 bridge->minor_version = 0;
419 printk(KERN_INFO PFX "Detected AGP bridge %x\n",
423 bridge->driver = &amd_8151_driver;
425 bridge->capndx = cap_ptr;
427 /* Fill in the mode register */
428 pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
430 if (cache_nbs(pdev, cap_ptr) == -1) {
431 agp_put_bridge(bridge);
435 pci_set_drvdata(pdev, bridge);
436 return agp_add_bridge(bridge);
439 static void __devexit agp_amdk8_remove(struct pci_dev *pdev)
441 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
443 release_mem_region(virt_to_phys(bridge->gatt_table_real),
444 x86_64_aperture_sizes[bridge->aperture_size_idx].size);
445 agp_remove_bridge(bridge);
446 agp_put_bridge(bridge);
449 static struct pci_device_id agp_amdk8_pci_table[] = {
451 .class = (PCI_CLASS_BRIDGE_HOST << 8),
453 .vendor = PCI_VENDOR_ID_AMD,
454 .device = PCI_DEVICE_ID_AMD_8151_0,
455 .subvendor = PCI_ANY_ID,
456 .subdevice = PCI_ANY_ID,
459 .class = (PCI_CLASS_BRIDGE_HOST << 8),
461 .vendor = PCI_VENDOR_ID_VIA,
462 .device = PCI_DEVICE_ID_VIA_K8T400M_0,
463 .subvendor = PCI_ANY_ID,
464 .subdevice = PCI_ANY_ID,
467 .class = (PCI_CLASS_BRIDGE_HOST << 8),
469 .vendor = PCI_VENDOR_ID_SI,
470 .device = PCI_DEVICE_ID_SI_755,
471 .subvendor = PCI_ANY_ID,
472 .subdevice = PCI_ANY_ID,
477 MODULE_DEVICE_TABLE(pci, agp_amdk8_pci_table);
479 static struct pci_driver agp_amdk8_pci_driver = {
480 .name = "agpgart-amd-k8",
481 .id_table = agp_amdk8_pci_table,
482 .probe = agp_amdk8_probe,
483 .remove = agp_amdk8_remove,
487 /* Not static due to IOMMU code calling it early. */
488 int __init agp_amdk8_init(void)
493 err = pci_module_init(&agp_amdk8_pci_driver);
494 if (err == -ENODEV) {
496 if (!agp_try_unsupported) {
497 printk(KERN_INFO "No supported AGP bridge found.\n");
498 printk(KERN_INFO "You can try agp_try_unsupported=1\n");
502 /* First check that we have at least one K8 NB */
503 if (!pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, NULL))
506 /* Look for any AGP bridge */
508 while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev))) {
509 if (!pci_find_capability(dev, PCI_CAP_ID_AGP))
511 if (agp_amdk8_probe(dev, NULL) == 0)
518 static void __exit agp_amdk8_cleanup(void)
520 pci_unregister_driver(&agp_amdk8_pci_driver);
523 /* On x86-64 the PCI driver needs to initialize this driver early
524 for the IOMMU, so it has to be called via a backdoor. */
525 #ifndef CONFIG_GART_IOMMU
526 module_init(agp_amdk8_init);
527 module_exit(agp_amdk8_cleanup);
530 MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
531 MODULE_PARM(agp_try_unsupported, "1i");
532 MODULE_LICENSE("GPL and additional rights");