via-agp.c (14005B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * VIA AGPGART routines. 4 */ 5 6#include <linux/types.h> 7#include <linux/module.h> 8#include <linux/pci.h> 9#include <linux/init.h> 10#include <linux/agp_backend.h> 11#include "agp.h" 12 13static const struct pci_device_id agp_via_pci_table[]; 14 15#define VIA_GARTCTRL 0x80 16#define VIA_APSIZE 0x84 17#define VIA_ATTBASE 0x88 18 19#define VIA_AGP3_GARTCTRL 0x90 20#define VIA_AGP3_APSIZE 0x94 21#define VIA_AGP3_ATTBASE 0x98 22#define VIA_AGPSEL 0xfd 23 24static int via_fetch_size(void) 25{ 26 int i; 27 u8 temp; 28 struct aper_size_info_8 *values; 29 30 values = A_SIZE_8(agp_bridge->driver->aperture_sizes); 31 pci_read_config_byte(agp_bridge->dev, VIA_APSIZE, &temp); 32 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { 33 if (temp == values[i].size_value) { 34 agp_bridge->previous_size = 35 agp_bridge->current_size = (void *) (values + i); 36 agp_bridge->aperture_size_idx = i; 37 return values[i].size; 38 } 39 } 40 printk(KERN_ERR PFX "Unknown aperture size from AGP bridge (0x%x)\n", temp); 41 return 0; 42} 43 44 45static int via_configure(void) 46{ 47 struct aper_size_info_8 *current_size; 48 49 current_size = A_SIZE_8(agp_bridge->current_size); 50 /* aperture size */ 51 pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, 52 current_size->size_value); 53 /* address to map to */ 54 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev, 55 AGP_APERTURE_BAR); 56 57 /* GART control register */ 58 pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000000f); 59 60 /* attbase - aperture GATT base */ 61 pci_write_config_dword(agp_bridge->dev, VIA_ATTBASE, 62 (agp_bridge->gatt_bus_addr & 0xfffff000) | 3); 63 return 0; 64} 65 66 67static void via_cleanup(void) 68{ 69 struct aper_size_info_8 *previous_size; 70 71 previous_size = A_SIZE_8(agp_bridge->previous_size); 72 pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, 73 previous_size->size_value); 74 /* Do not disable by writing 0 to VIA_ATTBASE, it screws things up 75 * during reinitialization. 76 */ 77} 78 79 80static void via_tlbflush(struct agp_memory *mem) 81{ 82 u32 temp; 83 84 pci_read_config_dword(agp_bridge->dev, VIA_GARTCTRL, &temp); 85 temp |= (1<<7); 86 pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, temp); 87 temp &= ~(1<<7); 88 pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, temp); 89} 90 91 92static const struct aper_size_info_8 via_generic_sizes[9] = 93{ 94 {256, 65536, 6, 0}, 95 {128, 32768, 5, 128}, 96 {64, 16384, 4, 192}, 97 {32, 8192, 3, 224}, 98 {16, 4096, 2, 240}, 99 {8, 2048, 1, 248}, 100 {4, 1024, 0, 252}, 101 {2, 512, 0, 254}, 102 {1, 256, 0, 255} 103}; 104 105 106static int via_fetch_size_agp3(void) 107{ 108 int i; 109 u16 temp; 110 struct aper_size_info_16 *values; 111 112 values = A_SIZE_16(agp_bridge->driver->aperture_sizes); 113 pci_read_config_word(agp_bridge->dev, VIA_AGP3_APSIZE, &temp); 114 temp &= 0xfff; 115 116 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { 117 if (temp == values[i].size_value) { 118 agp_bridge->previous_size = 119 agp_bridge->current_size = (void *) (values + i); 120 agp_bridge->aperture_size_idx = i; 121 return values[i].size; 122 } 123 } 124 return 0; 125} 126 127 128static int via_configure_agp3(void) 129{ 130 u32 temp; 131 132 /* address to map to */ 133 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev, 134 AGP_APERTURE_BAR); 135 136 /* attbase - aperture GATT base */ 137 pci_write_config_dword(agp_bridge->dev, VIA_AGP3_ATTBASE, 138 agp_bridge->gatt_bus_addr & 0xfffff000); 139 140 /* 1. Enable GTLB in RX90<7>, all AGP aperture access needs to fetch 141 * translation table first. 142 * 2. Enable AGP aperture in RX91<0>. This bit controls the enabling of the 143 * graphics AGP aperture for the AGP3.0 port. 144 */ 145 pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp); 146 pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp | (3<<7)); 147 return 0; 148} 149 150 151static void via_cleanup_agp3(void) 152{ 153 struct aper_size_info_16 *previous_size; 154 155 previous_size = A_SIZE_16(agp_bridge->previous_size); 156 pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, previous_size->size_value); 157} 158 159 160static void via_tlbflush_agp3(struct agp_memory *mem) 161{ 162 u32 temp; 163 164 pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp); 165 pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp & ~(1<<7)); 166 pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp); 167} 168 169 170static const struct agp_bridge_driver via_agp3_driver = { 171 .owner = THIS_MODULE, 172 .aperture_sizes = agp3_generic_sizes, 173 .size_type = U8_APER_SIZE, 174 .num_aperture_sizes = 10, 175 .needs_scratch_page = true, 176 .configure = via_configure_agp3, 177 .fetch_size = via_fetch_size_agp3, 178 .cleanup = via_cleanup_agp3, 179 .tlb_flush = via_tlbflush_agp3, 180 .mask_memory = agp_generic_mask_memory, 181 .masks = NULL, 182 .agp_enable = agp_generic_enable, 183 .cache_flush = global_cache_flush, 184 .create_gatt_table = agp_generic_create_gatt_table, 185 .free_gatt_table = agp_generic_free_gatt_table, 186 .insert_memory = agp_generic_insert_memory, 187 .remove_memory = agp_generic_remove_memory, 188 .alloc_by_type = agp_generic_alloc_by_type, 189 .free_by_type = agp_generic_free_by_type, 190 .agp_alloc_page = agp_generic_alloc_page, 191 .agp_alloc_pages = agp_generic_alloc_pages, 192 .agp_destroy_page = agp_generic_destroy_page, 193 .agp_destroy_pages = agp_generic_destroy_pages, 194 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 195}; 196 197static const struct agp_bridge_driver via_driver = { 198 .owner = THIS_MODULE, 199 .aperture_sizes = via_generic_sizes, 200 .size_type = U8_APER_SIZE, 201 .num_aperture_sizes = 9, 202 .needs_scratch_page = true, 203 .configure = via_configure, 204 .fetch_size = via_fetch_size, 205 .cleanup = via_cleanup, 206 .tlb_flush = via_tlbflush, 207 .mask_memory = agp_generic_mask_memory, 208 .masks = NULL, 209 .agp_enable = agp_generic_enable, 210 .cache_flush = global_cache_flush, 211 .create_gatt_table = agp_generic_create_gatt_table, 212 .free_gatt_table = agp_generic_free_gatt_table, 213 .insert_memory = agp_generic_insert_memory, 214 .remove_memory = agp_generic_remove_memory, 215 .alloc_by_type = agp_generic_alloc_by_type, 216 .free_by_type = agp_generic_free_by_type, 217 .agp_alloc_page = agp_generic_alloc_page, 218 .agp_alloc_pages = agp_generic_alloc_pages, 219 .agp_destroy_page = agp_generic_destroy_page, 220 .agp_destroy_pages = agp_generic_destroy_pages, 221 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 222}; 223 224static struct agp_device_ids via_agp_device_ids[] = 225{ 226 { 227 .device_id = PCI_DEVICE_ID_VIA_82C597_0, 228 .chipset_name = "Apollo VP3", 229 }, 230 231 { 232 .device_id = PCI_DEVICE_ID_VIA_82C598_0, 233 .chipset_name = "Apollo MVP3", 234 }, 235 236 { 237 .device_id = PCI_DEVICE_ID_VIA_8501_0, 238 .chipset_name = "Apollo MVP4", 239 }, 240 241 /* VT8601 */ 242 { 243 .device_id = PCI_DEVICE_ID_VIA_8601_0, 244 .chipset_name = "Apollo ProMedia/PLE133Ta", 245 }, 246 247 /* VT82C693A / VT28C694T */ 248 { 249 .device_id = PCI_DEVICE_ID_VIA_82C691_0, 250 .chipset_name = "Apollo Pro 133", 251 }, 252 253 { 254 .device_id = PCI_DEVICE_ID_VIA_8371_0, 255 .chipset_name = "KX133", 256 }, 257 258 /* VT8633 */ 259 { 260 .device_id = PCI_DEVICE_ID_VIA_8633_0, 261 .chipset_name = "Pro 266", 262 }, 263 264 { 265 .device_id = PCI_DEVICE_ID_VIA_XN266, 266 .chipset_name = "Apollo Pro266", 267 }, 268 269 /* VT8361 */ 270 { 271 .device_id = PCI_DEVICE_ID_VIA_8361, 272 .chipset_name = "KLE133", 273 }, 274 275 /* VT8365 / VT8362 */ 276 { 277 .device_id = PCI_DEVICE_ID_VIA_8363_0, 278 .chipset_name = "Twister-K/KT133x/KM133", 279 }, 280 281 /* VT8753A */ 282 { 283 .device_id = PCI_DEVICE_ID_VIA_8753_0, 284 .chipset_name = "P4X266", 285 }, 286 287 /* VT8366 */ 288 { 289 .device_id = PCI_DEVICE_ID_VIA_8367_0, 290 .chipset_name = "KT266/KY266x/KT333", 291 }, 292 293 /* VT8633 (for CuMine/ Celeron) */ 294 { 295 .device_id = PCI_DEVICE_ID_VIA_8653_0, 296 .chipset_name = "Pro266T", 297 }, 298 299 /* KM266 / PM266 */ 300 { 301 .device_id = PCI_DEVICE_ID_VIA_XM266, 302 .chipset_name = "PM266/KM266", 303 }, 304 305 /* CLE266 */ 306 { 307 .device_id = PCI_DEVICE_ID_VIA_862X_0, 308 .chipset_name = "CLE266", 309 }, 310 311 { 312 .device_id = PCI_DEVICE_ID_VIA_8377_0, 313 .chipset_name = "KT400/KT400A/KT600", 314 }, 315 316 /* VT8604 / VT8605 / VT8603 317 * (Apollo Pro133A chipset with S3 Savage4) */ 318 { 319 .device_id = PCI_DEVICE_ID_VIA_8605_0, 320 .chipset_name = "ProSavage PM133/PL133/PN133" 321 }, 322 323 /* P4M266x/P4N266 */ 324 { 325 .device_id = PCI_DEVICE_ID_VIA_8703_51_0, 326 .chipset_name = "P4M266x/P4N266", 327 }, 328 329 /* VT8754 */ 330 { 331 .device_id = PCI_DEVICE_ID_VIA_8754C_0, 332 .chipset_name = "PT800", 333 }, 334 335 /* P4X600 */ 336 { 337 .device_id = PCI_DEVICE_ID_VIA_8763_0, 338 .chipset_name = "P4X600" 339 }, 340 341 /* KM400 */ 342 { 343 .device_id = PCI_DEVICE_ID_VIA_8378_0, 344 .chipset_name = "KM400/KM400A", 345 }, 346 347 /* PT880 */ 348 { 349 .device_id = PCI_DEVICE_ID_VIA_PT880, 350 .chipset_name = "PT880", 351 }, 352 353 /* PT880 Ultra */ 354 { 355 .device_id = PCI_DEVICE_ID_VIA_PT880ULTRA, 356 .chipset_name = "PT880 Ultra", 357 }, 358 359 /* PT890 */ 360 { 361 .device_id = PCI_DEVICE_ID_VIA_8783_0, 362 .chipset_name = "PT890", 363 }, 364 365 /* PM800/PN800/PM880/PN880 */ 366 { 367 .device_id = PCI_DEVICE_ID_VIA_PX8X0_0, 368 .chipset_name = "PM800/PN800/PM880/PN880", 369 }, 370 /* KT880 */ 371 { 372 .device_id = PCI_DEVICE_ID_VIA_3269_0, 373 .chipset_name = "KT880", 374 }, 375 /* KTxxx/Px8xx */ 376 { 377 .device_id = PCI_DEVICE_ID_VIA_83_87XX_1, 378 .chipset_name = "VT83xx/VT87xx/KTxxx/Px8xx", 379 }, 380 /* P4M800 */ 381 { 382 .device_id = PCI_DEVICE_ID_VIA_3296_0, 383 .chipset_name = "P4M800", 384 }, 385 /* P4M800CE */ 386 { 387 .device_id = PCI_DEVICE_ID_VIA_P4M800CE, 388 .chipset_name = "VT3314", 389 }, 390 /* VT3324 / CX700 */ 391 { 392 .device_id = PCI_DEVICE_ID_VIA_VT3324, 393 .chipset_name = "CX700", 394 }, 395 /* VT3336 - this is a chipset for AMD Athlon/K8 CPU. Due to K8's unique 396 * architecture, the AGP resource and behavior are different from 397 * the traditional AGP which resides only in chipset. AGP is used 398 * by 3D driver which wasn't available for the VT3336 and VT3364 399 * generation until now. Unfortunately, by testing, VT3364 works 400 * but VT3336 doesn't. - explanation from via, just leave this as 401 * as a placeholder to avoid future patches adding it back in. 402 */ 403#if 0 404 { 405 .device_id = PCI_DEVICE_ID_VIA_VT3336, 406 .chipset_name = "VT3336", 407 }, 408#endif 409 /* P4M890 */ 410 { 411 .device_id = PCI_DEVICE_ID_VIA_P4M890, 412 .chipset_name = "P4M890", 413 }, 414 /* P4M900 */ 415 { 416 .device_id = PCI_DEVICE_ID_VIA_VT3364, 417 .chipset_name = "P4M900", 418 }, 419 { }, /* dummy final entry, always present */ 420}; 421 422 423/* 424 * VIA's AGP3 chipsets do magick to put the AGP bridge compliant 425 * with the same standards version as the graphics card. 426 */ 427static void check_via_agp3 (struct agp_bridge_data *bridge) 428{ 429 u8 reg; 430 431 pci_read_config_byte(bridge->dev, VIA_AGPSEL, ®); 432 /* Check AGP 2.0 compatibility mode. */ 433 if ((reg & (1<<1))==0) 434 bridge->driver = &via_agp3_driver; 435} 436 437 438static int agp_via_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 439{ 440 struct agp_device_ids *devs = via_agp_device_ids; 441 struct agp_bridge_data *bridge; 442 int j = 0; 443 u8 cap_ptr; 444 445 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); 446 if (!cap_ptr) 447 return -ENODEV; 448 449 j = ent - agp_via_pci_table; 450 printk (KERN_INFO PFX "Detected VIA %s chipset\n", devs[j].chipset_name); 451 452 bridge = agp_alloc_bridge(); 453 if (!bridge) 454 return -ENOMEM; 455 456 bridge->dev = pdev; 457 bridge->capndx = cap_ptr; 458 bridge->driver = &via_driver; 459 460 /* 461 * Garg, there are KT400s with KT266 IDs. 462 */ 463 if (pdev->device == PCI_DEVICE_ID_VIA_8367_0) { 464 /* Is there a KT400 subsystem ? */ 465 if (pdev->subsystem_device == PCI_DEVICE_ID_VIA_8377_0) { 466 printk(KERN_INFO PFX "Found KT400 in disguise as a KT266.\n"); 467 check_via_agp3(bridge); 468 } 469 } 470 471 /* If this is an AGP3 bridge, check which mode its in and adjust. */ 472 get_agp_version(bridge); 473 if (bridge->major_version >= 3) 474 check_via_agp3(bridge); 475 476 /* Fill in the mode register */ 477 pci_read_config_dword(pdev, 478 bridge->capndx+PCI_AGP_STATUS, &bridge->mode); 479 480 pci_set_drvdata(pdev, bridge); 481 return agp_add_bridge(bridge); 482} 483 484static void agp_via_remove(struct pci_dev *pdev) 485{ 486 struct agp_bridge_data *bridge = pci_get_drvdata(pdev); 487 488 agp_remove_bridge(bridge); 489 agp_put_bridge(bridge); 490} 491 492#define agp_via_suspend NULL 493 494static int __maybe_unused agp_via_resume(struct device *dev) 495{ 496 struct agp_bridge_data *bridge = dev_get_drvdata(dev); 497 498 if (bridge->driver == &via_agp3_driver) 499 return via_configure_agp3(); 500 else if (bridge->driver == &via_driver) 501 return via_configure(); 502 503 return 0; 504} 505 506/* must be the same order as name table above */ 507static const struct pci_device_id agp_via_pci_table[] = { 508#define ID(x) \ 509 { \ 510 .class = (PCI_CLASS_BRIDGE_HOST << 8), \ 511 .class_mask = ~0, \ 512 .vendor = PCI_VENDOR_ID_VIA, \ 513 .device = x, \ 514 .subvendor = PCI_ANY_ID, \ 515 .subdevice = PCI_ANY_ID, \ 516 } 517 ID(PCI_DEVICE_ID_VIA_82C597_0), 518 ID(PCI_DEVICE_ID_VIA_82C598_0), 519 ID(PCI_DEVICE_ID_VIA_8501_0), 520 ID(PCI_DEVICE_ID_VIA_8601_0), 521 ID(PCI_DEVICE_ID_VIA_82C691_0), 522 ID(PCI_DEVICE_ID_VIA_8371_0), 523 ID(PCI_DEVICE_ID_VIA_8633_0), 524 ID(PCI_DEVICE_ID_VIA_XN266), 525 ID(PCI_DEVICE_ID_VIA_8361), 526 ID(PCI_DEVICE_ID_VIA_8363_0), 527 ID(PCI_DEVICE_ID_VIA_8753_0), 528 ID(PCI_DEVICE_ID_VIA_8367_0), 529 ID(PCI_DEVICE_ID_VIA_8653_0), 530 ID(PCI_DEVICE_ID_VIA_XM266), 531 ID(PCI_DEVICE_ID_VIA_862X_0), 532 ID(PCI_DEVICE_ID_VIA_8377_0), 533 ID(PCI_DEVICE_ID_VIA_8605_0), 534 ID(PCI_DEVICE_ID_VIA_8703_51_0), 535 ID(PCI_DEVICE_ID_VIA_8754C_0), 536 ID(PCI_DEVICE_ID_VIA_8763_0), 537 ID(PCI_DEVICE_ID_VIA_8378_0), 538 ID(PCI_DEVICE_ID_VIA_PT880), 539 ID(PCI_DEVICE_ID_VIA_PT880ULTRA), 540 ID(PCI_DEVICE_ID_VIA_8783_0), 541 ID(PCI_DEVICE_ID_VIA_PX8X0_0), 542 ID(PCI_DEVICE_ID_VIA_3269_0), 543 ID(PCI_DEVICE_ID_VIA_83_87XX_1), 544 ID(PCI_DEVICE_ID_VIA_3296_0), 545 ID(PCI_DEVICE_ID_VIA_P4M800CE), 546 ID(PCI_DEVICE_ID_VIA_VT3324), 547 ID(PCI_DEVICE_ID_VIA_P4M890), 548 ID(PCI_DEVICE_ID_VIA_VT3364), 549 { } 550}; 551 552MODULE_DEVICE_TABLE(pci, agp_via_pci_table); 553 554static SIMPLE_DEV_PM_OPS(agp_via_pm_ops, agp_via_suspend, agp_via_resume); 555 556static struct pci_driver agp_via_pci_driver = { 557 .name = "agpgart-via", 558 .id_table = agp_via_pci_table, 559 .probe = agp_via_probe, 560 .remove = agp_via_remove, 561 .driver.pm = &agp_via_pm_ops, 562}; 563 564 565static int __init agp_via_init(void) 566{ 567 if (agp_off) 568 return -EINVAL; 569 return pci_register_driver(&agp_via_pci_driver); 570} 571 572static void __exit agp_via_cleanup(void) 573{ 574 pci_unregister_driver(&agp_via_pci_driver); 575} 576 577module_init(agp_via_init); 578module_exit(agp_via_cleanup); 579 580MODULE_LICENSE("GPL"); 581MODULE_AUTHOR("Dave Jones");