1/* 2 * AMD K7 AGPGART routines. 3 */ 4 5#include <linux/module.h> 6#include <linux/pci.h> 7#include <linux/init.h> 8#include <linux/agp_backend.h> 9#include <linux/page-flags.h> 10#include <linux/mm.h> 11#include <linux/slab.h> 12#include "agp.h" 13 14#define AMD_MMBASE_BAR 1 15#define AMD_APSIZE 0xac 16#define AMD_MODECNTL 0xb0 17#define AMD_MODECNTL2 0xb2 18#define AMD_GARTENABLE 0x02 /* In mmio region (16-bit register) */ 19#define AMD_ATTBASE 0x04 /* In mmio region (32-bit register) */ 20#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */ 21#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */ 22 23static struct pci_device_id agp_amdk7_pci_table[]; 24 25struct amd_page_map { 26 unsigned long *real; 27 unsigned long __iomem *remapped; 28}; 29 30static struct _amd_irongate_private { 31 volatile u8 __iomem *registers; 32 struct amd_page_map **gatt_pages; 33 int num_tables; 34} amd_irongate_private; 35 36static int amd_create_page_map(struct amd_page_map *page_map) 37{ 38 int i; 39 40 page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL); 41 if (page_map->real == NULL) 42 return -ENOMEM; 43 44 set_memory_uc((unsigned long)page_map->real, 1); 45 page_map->remapped = page_map->real; 46 47 for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) { 48 writel(agp_bridge->scratch_page, page_map->remapped+i); 49 readl(page_map->remapped+i); /* PCI Posting. */ 50 } 51 52 return 0; 53} 54 55static void amd_free_page_map(struct amd_page_map *page_map) 56{ 57 set_memory_wb((unsigned long)page_map->real, 1); 58 free_page((unsigned long) page_map->real); 59} 60 61static void amd_free_gatt_pages(void) 62{ 63 int i; 64 struct amd_page_map **tables; 65 struct amd_page_map *entry; 66 67 tables = amd_irongate_private.gatt_pages; 68 for (i = 0; i < amd_irongate_private.num_tables; i++) { 69 entry = tables[i]; 70 if (entry != NULL) { 71 if (entry->real != NULL) 72 amd_free_page_map(entry); 73 kfree(entry); 74 } 75 } 76 kfree(tables); 77 amd_irongate_private.gatt_pages = NULL; 78} 79 80static int amd_create_gatt_pages(int nr_tables) 81{ 82 struct amd_page_map **tables; 83 struct amd_page_map *entry; 84 int retval = 0; 85 int i; 86 87 tables = kzalloc((nr_tables + 1) * sizeof(struct amd_page_map *),GFP_KERNEL); 88 if (tables == NULL) 89 return -ENOMEM; 90 91 for (i = 0; i < nr_tables; i++) { 92 entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL); 93 tables[i] = entry; 94 if (entry == NULL) { 95 retval = -ENOMEM; 96 break; 97 } 98 retval = amd_create_page_map(entry); 99 if (retval != 0) 100 break; 101 } 102 amd_irongate_private.num_tables = i; 103 amd_irongate_private.gatt_pages = tables; 104 105 if (retval != 0) 106 amd_free_gatt_pages(); 107 108 return retval; 109} 110 111/* Since we don't need contiguous memory we just try 112 * to get the gatt table once 113 */ 114 115#define GET_PAGE_DIR_OFF(addr) (addr >> 22) 116#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \ 117 GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr)) 118#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) 119#define GET_GATT(addr) (amd_irongate_private.gatt_pages[\ 120 GET_PAGE_DIR_IDX(addr)]->remapped) 121 122static int amd_create_gatt_table(struct agp_bridge_data *bridge) 123{ 124 struct aper_size_info_lvl2 *value; 125 struct amd_page_map page_dir; 126 unsigned long __iomem *cur_gatt; 127 unsigned long addr; 128 int retval; 129 int i; 130 131 value = A_SIZE_LVL2(agp_bridge->current_size); 132 retval = amd_create_page_map(&page_dir); 133 if (retval != 0) 134 return retval; 135 136 retval = amd_create_gatt_pages(value->num_entries / 1024); 137 if (retval != 0) { 138 amd_free_page_map(&page_dir); 139 return retval; 140 } 141 142 agp_bridge->gatt_table_real = (u32 *)page_dir.real; 143 agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; 144 agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); 145 146 /* Get the address for the gart region. 147 * This is a bus address even on the alpha, b/c its 148 * used to program the agp master not the cpu 149 */ 150 151 addr = pci_bus_address(agp_bridge->dev, AGP_APERTURE_BAR); 152 agp_bridge->gart_bus_addr = addr; 153 154 /* Calculate the agp offset */ 155 for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { 156 writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1, 157 page_dir.remapped+GET_PAGE_DIR_OFF(addr)); 158 readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ 159 } 160 161 for (i = 0; i < value->num_entries; i++) { 162 addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; 163 cur_gatt = GET_GATT(addr); 164 writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr)); 165 readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ 166 } 167 168 return 0; 169} 170 171static int amd_free_gatt_table(struct agp_bridge_data *bridge) 172{ 173 struct amd_page_map page_dir; 174 175 page_dir.real = (unsigned long *)agp_bridge->gatt_table_real; 176 page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table; 177 178 amd_free_gatt_pages(); 179 amd_free_page_map(&page_dir); 180 return 0; 181} 182 183static int amd_irongate_fetch_size(void) 184{ 185 int i; 186 u32 temp; 187 struct aper_size_info_lvl2 *values; 188 189 pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp); 190 temp = (temp & 0x0000000e); 191 values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes); 192 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { 193 if (temp == values[i].size_value) { 194 agp_bridge->previous_size = 195 agp_bridge->current_size = (void *) (values + i); 196 197 agp_bridge->aperture_size_idx = i; 198 return values[i].size; 199 } 200 } 201 202 return 0; 203} 204 205static int amd_irongate_configure(void) 206{ 207 struct aper_size_info_lvl2 *current_size; 208 phys_addr_t reg; 209 u32 temp; 210 u16 enable_reg; 211 212 current_size = A_SIZE_LVL2(agp_bridge->current_size); 213 214 if (!amd_irongate_private.registers) { 215 /* Get the memory mapped registers */ 216 reg = pci_resource_start(agp_bridge->dev, AMD_MMBASE_BAR); 217 amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(reg, 4096); 218 if (!amd_irongate_private.registers) 219 return -ENOMEM; 220 } 221 222 /* Write out the address of the gatt table */ 223 writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); 224 readl(amd_irongate_private.registers+AMD_ATTBASE); /* PCI Posting. */ 225 226 /* Write the Sync register */ 227 pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL, 0x80); 228 229 /* Set indexing mode */ 230 pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL2, 0x00); 231 232 /* Write the enable register */ 233 enable_reg = readw(amd_irongate_private.registers+AMD_GARTENABLE); 234 enable_reg = (enable_reg | 0x0004); 235 writew(enable_reg, amd_irongate_private.registers+AMD_GARTENABLE); 236 readw(amd_irongate_private.registers+AMD_GARTENABLE); /* PCI Posting. */ 237 238 /* Write out the size register */ 239 pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp); 240 temp = (((temp & ~(0x0000000e)) | current_size->size_value) | 1); 241 pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp); 242 243 /* Flush the tlb */ 244 writel(1, amd_irongate_private.registers+AMD_TLBFLUSH); 245 readl(amd_irongate_private.registers+AMD_TLBFLUSH); /* PCI Posting.*/ 246 return 0; 247} 248 249static void amd_irongate_cleanup(void) 250{ 251 struct aper_size_info_lvl2 *previous_size; 252 u32 temp; 253 u16 enable_reg; 254 255 previous_size = A_SIZE_LVL2(agp_bridge->previous_size); 256 257 enable_reg = readw(amd_irongate_private.registers+AMD_GARTENABLE); 258 enable_reg = (enable_reg & ~(0x0004)); 259 writew(enable_reg, amd_irongate_private.registers+AMD_GARTENABLE); 260 readw(amd_irongate_private.registers+AMD_GARTENABLE); /* PCI Posting. */ 261 262 /* Write back the previous size and disable gart translation */ 263 pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp); 264 temp = ((temp & ~(0x0000000f)) | previous_size->size_value); 265 pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp); 266 iounmap((void __iomem *) amd_irongate_private.registers); 267} 268 269/* 270 * This routine could be implemented by taking the addresses 271 * written to the GATT, and flushing them individually. However 272 * currently it just flushes the whole table. Which is probably 273 * more efficient, since agp_memory blocks can be a large number of 274 * entries. 275 */ 276 277static void amd_irongate_tlbflush(struct agp_memory *temp) 278{ 279 writel(1, amd_irongate_private.registers+AMD_TLBFLUSH); 280 readl(amd_irongate_private.registers+AMD_TLBFLUSH); /* PCI Posting. */ 281} 282 283static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type) 284{ 285 int i, j, num_entries; 286 unsigned long __iomem *cur_gatt; 287 unsigned long addr; 288 289 num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; 290 291 if (type != mem->type || 292 agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) 293 return -EINVAL; 294 295 if ((pg_start + mem->page_count) > num_entries) 296 return -EINVAL; 297 298 j = pg_start; 299 while (j < (pg_start + mem->page_count)) { 300 addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; 301 cur_gatt = GET_GATT(addr); 302 if (!PGE_EMPTY(agp_bridge, readl(cur_gatt+GET_GATT_OFF(addr)))) 303 return -EBUSY; 304 j++; 305 } 306 307 if (!mem->is_flushed) { 308 global_cache_flush(); 309 mem->is_flushed = true; 310 } 311 312 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 313 addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; 314 cur_gatt = GET_GATT(addr); 315 writel(agp_generic_mask_memory(agp_bridge, 316 page_to_phys(mem->pages[i]), 317 mem->type), 318 cur_gatt+GET_GATT_OFF(addr)); 319 readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ 320 } 321 amd_irongate_tlbflush(mem); 322 return 0; 323} 324 325static int amd_remove_memory(struct agp_memory *mem, off_t pg_start, int type) 326{ 327 int i; 328 unsigned long __iomem *cur_gatt; 329 unsigned long addr; 330 331 if (type != mem->type || 332 agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) 333 return -EINVAL; 334 335 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 336 addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; 337 cur_gatt = GET_GATT(addr); 338 writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr)); 339 readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ 340 } 341 342 amd_irongate_tlbflush(mem); 343 return 0; 344} 345 346static const struct aper_size_info_lvl2 amd_irongate_sizes[7] = 347{ 348 {2048, 524288, 0x0000000c}, 349 {1024, 262144, 0x0000000a}, 350 {512, 131072, 0x00000008}, 351 {256, 65536, 0x00000006}, 352 {128, 32768, 0x00000004}, 353 {64, 16384, 0x00000002}, 354 {32, 8192, 0x00000000} 355}; 356 357static const struct gatt_mask amd_irongate_masks[] = 358{ 359 {.mask = 1, .type = 0} 360}; 361 362static const struct agp_bridge_driver amd_irongate_driver = { 363 .owner = THIS_MODULE, 364 .aperture_sizes = amd_irongate_sizes, 365 .size_type = LVL2_APER_SIZE, 366 .num_aperture_sizes = 7, 367 .needs_scratch_page = true, 368 .configure = amd_irongate_configure, 369 .fetch_size = amd_irongate_fetch_size, 370 .cleanup = amd_irongate_cleanup, 371 .tlb_flush = amd_irongate_tlbflush, 372 .mask_memory = agp_generic_mask_memory, 373 .masks = amd_irongate_masks, 374 .agp_enable = agp_generic_enable, 375 .cache_flush = global_cache_flush, 376 .create_gatt_table = amd_create_gatt_table, 377 .free_gatt_table = amd_free_gatt_table, 378 .insert_memory = amd_insert_memory, 379 .remove_memory = amd_remove_memory, 380 .alloc_by_type = agp_generic_alloc_by_type, 381 .free_by_type = agp_generic_free_by_type, 382 .agp_alloc_page = agp_generic_alloc_page, 383 .agp_alloc_pages = agp_generic_alloc_pages, 384 .agp_destroy_page = agp_generic_destroy_page, 385 .agp_destroy_pages = agp_generic_destroy_pages, 386 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 387}; 388 389static struct agp_device_ids amd_agp_device_ids[] = 390{ 391 { 392 .device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006, 393 .chipset_name = "Irongate", 394 }, 395 { 396 .device_id = PCI_DEVICE_ID_AMD_FE_GATE_700E, 397 .chipset_name = "761", 398 }, 399 { 400 .device_id = PCI_DEVICE_ID_AMD_FE_GATE_700C, 401 .chipset_name = "760MP", 402 }, 403 { }, /* dummy final entry, always present */ 404}; 405 406static int agp_amdk7_probe(struct pci_dev *pdev, 407 const struct pci_device_id *ent) 408{ 409 struct agp_bridge_data *bridge; 410 u8 cap_ptr; 411 int j; 412 413 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); 414 if (!cap_ptr) 415 return -ENODEV; 416 417 j = ent - agp_amdk7_pci_table; 418 dev_info(&pdev->dev, "AMD %s chipset\n", 419 amd_agp_device_ids[j].chipset_name); 420 421 bridge = agp_alloc_bridge(); 422 if (!bridge) 423 return -ENOMEM; 424 425 bridge->driver = &amd_irongate_driver; 426 bridge->dev_private_data = &amd_irongate_private, 427 bridge->dev = pdev; 428 bridge->capndx = cap_ptr; 429 430 /* 751 Errata (22564_B-1.PDF) 431 erratum 20: strobe glitch with Nvidia NV10 GeForce cards. 432 system controller may experience noise due to strong drive strengths 433 */ 434 if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_7006) { 435 struct pci_dev *gfxcard=NULL; 436 437 cap_ptr = 0; 438 while (!cap_ptr) { 439 gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard); 440 if (!gfxcard) { 441 dev_info(&pdev->dev, "no AGP VGA controller\n"); 442 return -ENODEV; 443 } 444 cap_ptr = pci_find_capability(gfxcard, PCI_CAP_ID_AGP); 445 } 446 447 /* With so many variants of NVidia cards, it's simpler just 448 to blacklist them all, and then whitelist them as needed 449 (if necessary at all). */ 450 if (gfxcard->vendor == PCI_VENDOR_ID_NVIDIA) { 451 agp_bridge->flags |= AGP_ERRATA_1X; 452 dev_info(&pdev->dev, "AMD 751 chipset with NVidia GeForce; forcing 1X due to errata\n"); 453 } 454 pci_dev_put(gfxcard); 455 } 456 457 /* 761 Errata (23613_F.pdf) 458 * Revisions B0/B1 were a disaster. 459 * erratum 44: SYSCLK/AGPCLK skew causes 2X failures -- Force mode to 1X 460 * erratum 45: Timing problem prevents fast writes -- Disable fast write. 461 * erratum 46: Setup violation on AGP SBA pins - Disable side band addressing. 462 * With this lot disabled, we should prevent lockups. */ 463 if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_700E) { 464 if (pdev->revision == 0x10 || pdev->revision == 0x11) { 465 agp_bridge->flags = AGP_ERRATA_FASTWRITES; 466 agp_bridge->flags |= AGP_ERRATA_SBA; 467 agp_bridge->flags |= AGP_ERRATA_1X; 468 dev_info(&pdev->dev, "AMD 761 chipset with errata; disabling AGP fast writes & SBA and forcing to 1X\n"); 469 } 470 } 471 472 /* Fill in the mode register */ 473 pci_read_config_dword(pdev, 474 bridge->capndx+PCI_AGP_STATUS, 475 &bridge->mode); 476 477 pci_set_drvdata(pdev, bridge); 478 return agp_add_bridge(bridge); 479} 480 481static void agp_amdk7_remove(struct pci_dev *pdev) 482{ 483 struct agp_bridge_data *bridge = pci_get_drvdata(pdev); 484 485 agp_remove_bridge(bridge); 486 agp_put_bridge(bridge); 487} 488 489#ifdef CONFIG_PM 490 491static int agp_amdk7_suspend(struct pci_dev *pdev, pm_message_t state) 492{ 493 pci_save_state(pdev); 494 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 495 496 return 0; 497} 498 499static int agp_amdk7_resume(struct pci_dev *pdev) 500{ 501 pci_set_power_state(pdev, PCI_D0); 502 pci_restore_state(pdev); 503 504 return amd_irongate_driver.configure(); 505} 506 507#endif /* CONFIG_PM */ 508 509/* must be the same order as name table above */ 510static struct pci_device_id agp_amdk7_pci_table[] = { 511 { 512 .class = (PCI_CLASS_BRIDGE_HOST << 8), 513 .class_mask = ~0, 514 .vendor = PCI_VENDOR_ID_AMD, 515 .device = PCI_DEVICE_ID_AMD_FE_GATE_7006, 516 .subvendor = PCI_ANY_ID, 517 .subdevice = PCI_ANY_ID, 518 }, 519 { 520 .class = (PCI_CLASS_BRIDGE_HOST << 8), 521 .class_mask = ~0, 522 .vendor = PCI_VENDOR_ID_AMD, 523 .device = PCI_DEVICE_ID_AMD_FE_GATE_700E, 524 .subvendor = PCI_ANY_ID, 525 .subdevice = PCI_ANY_ID, 526 }, 527 { 528 .class = (PCI_CLASS_BRIDGE_HOST << 8), 529 .class_mask = ~0, 530 .vendor = PCI_VENDOR_ID_AMD, 531 .device = PCI_DEVICE_ID_AMD_FE_GATE_700C, 532 .subvendor = PCI_ANY_ID, 533 .subdevice = PCI_ANY_ID, 534 }, 535 { } 536}; 537 538MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table); 539 540static struct pci_driver agp_amdk7_pci_driver = { 541 .name = "agpgart-amdk7", 542 .id_table = agp_amdk7_pci_table, 543 .probe = agp_amdk7_probe, 544 .remove = agp_amdk7_remove, 545#ifdef CONFIG_PM 546 .suspend = agp_amdk7_suspend, 547 .resume = agp_amdk7_resume, 548#endif 549}; 550 551static int __init agp_amdk7_init(void) 552{ 553 if (agp_off) 554 return -EINVAL; 555 return pci_register_driver(&agp_amdk7_pci_driver); 556} 557 558static void __exit agp_amdk7_cleanup(void) 559{ 560 pci_unregister_driver(&agp_amdk7_pci_driver); 561} 562 563module_init(agp_amdk7_init); 564module_exit(agp_amdk7_cleanup); 565 566MODULE_LICENSE("GPL and additional rights"); 567