925 lines · c
1/*2 * Intel AGPGART routines.3 */4 5#include <linux/module.h>6#include <linux/pci.h>7#include <linux/slab.h>8#include <linux/init.h>9#include <linux/kernel.h>10#include <linux/pagemap.h>11#include <linux/agp_backend.h>12#include <asm/smp.h>13#include "agp.h"14#include "intel-agp.h"15#include <drm/intel/intel-gtt.h>16 17static int intel_fetch_size(void)18{19 int i;20 u16 temp;21 struct aper_size_info_16 *values;22 23 pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);24 values = A_SIZE_16(agp_bridge->driver->aperture_sizes);25 26 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {27 if (temp == values[i].size_value) {28 agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);29 agp_bridge->aperture_size_idx = i;30 return values[i].size;31 }32 }33 34 return 0;35}36 37static int __intel_8xx_fetch_size(u8 temp)38{39 int i;40 struct aper_size_info_8 *values;41 42 values = A_SIZE_8(agp_bridge->driver->aperture_sizes);43 44 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {45 if (temp == values[i].size_value) {46 agp_bridge->previous_size =47 agp_bridge->current_size = (void *) (values + i);48 agp_bridge->aperture_size_idx = i;49 return values[i].size;50 }51 }52 return 0;53}54 55static int intel_8xx_fetch_size(void)56{57 u8 temp;58 59 pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);60 return __intel_8xx_fetch_size(temp);61}62 63static int intel_815_fetch_size(void)64{65 u8 temp;66 67 /* Intel 815 chipsets have a _weird_ APSIZE register with only68 * one non-reserved bit, so mask the others out ... */69 pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);70 temp &= (1 << 3);71 72 return __intel_8xx_fetch_size(temp);73}74 75static void intel_tlbflush(struct agp_memory *mem)76{77 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);78 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);79}80 81 82static void intel_8xx_tlbflush(struct agp_memory *mem)83{84 u32 temp;85 pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);86 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));87 pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);88 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));89}90 91 92static void intel_cleanup(void)93{94 u16 temp;95 struct aper_size_info_16 *previous_size;96 97 previous_size = A_SIZE_16(agp_bridge->previous_size);98 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);99 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));100 pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);101}102 103 104static void intel_8xx_cleanup(void)105{106 u16 temp;107 struct aper_size_info_8 *previous_size;108 109 previous_size = A_SIZE_8(agp_bridge->previous_size);110 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);111 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));112 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);113}114 115 116static int intel_configure(void)117{118 u16 temp2;119 struct aper_size_info_16 *current_size;120 121 current_size = A_SIZE_16(agp_bridge->current_size);122 123 /* aperture size */124 pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);125 126 /* address to map to */127 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,128 AGP_APERTURE_BAR);129 130 /* attbase - aperture base */131 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);132 133 /* agpctrl */134 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);135 136 /* paccfg/nbxcfg */137 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);138 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,139 (temp2 & ~(1 << 10)) | (1 << 9));140 /* clear any possible error conditions */141 pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);142 return 0;143}144 145static int intel_815_configure(void)146{147 u32 addr;148 u8 temp2;149 struct aper_size_info_8 *current_size;150 151 /* attbase - aperture base */152 /* the Intel 815 chipset spec. says that bits 29-31 in the153 * ATTBASE register are reserved -> try not to write them */154 if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {155 dev_emerg(&agp_bridge->dev->dev, "gatt bus addr too high");156 return -EINVAL;157 }158 159 current_size = A_SIZE_8(agp_bridge->current_size);160 161 /* aperture size */162 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,163 current_size->size_value);164 165 /* address to map to */166 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,167 AGP_APERTURE_BAR);168 169 pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr);170 addr &= INTEL_815_ATTBASE_MASK;171 addr |= agp_bridge->gatt_bus_addr;172 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, addr);173 174 /* agpctrl */175 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);176 177 /* apcont */178 pci_read_config_byte(agp_bridge->dev, INTEL_815_APCONT, &temp2);179 pci_write_config_byte(agp_bridge->dev, INTEL_815_APCONT, temp2 | (1 << 1));180 181 /* clear any possible error conditions */182 /* Oddness : this chipset seems to have no ERRSTS register ! */183 return 0;184}185 186static void intel_820_tlbflush(struct agp_memory *mem)187{188 return;189}190 191static void intel_820_cleanup(void)192{193 u8 temp;194 struct aper_size_info_8 *previous_size;195 196 previous_size = A_SIZE_8(agp_bridge->previous_size);197 pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp);198 pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR,199 temp & ~(1 << 1));200 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,201 previous_size->size_value);202}203 204 205static int intel_820_configure(void)206{207 u8 temp2;208 struct aper_size_info_8 *current_size;209 210 current_size = A_SIZE_8(agp_bridge->current_size);211 212 /* aperture size */213 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);214 215 /* address to map to */216 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,217 AGP_APERTURE_BAR);218 219 /* attbase - aperture base */220 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);221 222 /* agpctrl */223 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);224 225 /* global enable aperture access */226 /* This flag is not accessed through MCHCFG register as in */227 /* i850 chipset. */228 pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp2);229 pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp2 | (1 << 1));230 /* clear any possible AGP-related error conditions */231 pci_write_config_word(agp_bridge->dev, INTEL_I820_ERRSTS, 0x001c);232 return 0;233}234 235static int intel_840_configure(void)236{237 u16 temp2;238 struct aper_size_info_8 *current_size;239 240 current_size = A_SIZE_8(agp_bridge->current_size);241 242 /* aperture size */243 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);244 245 /* address to map to */246 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,247 AGP_APERTURE_BAR);248 249 /* attbase - aperture base */250 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);251 252 /* agpctrl */253 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);254 255 /* mcgcfg */256 pci_read_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, &temp2);257 pci_write_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));258 /* clear any possible error conditions */259 pci_write_config_word(agp_bridge->dev, INTEL_I840_ERRSTS, 0xc000);260 return 0;261}262 263static int intel_845_configure(void)264{265 u8 temp2;266 struct aper_size_info_8 *current_size;267 268 current_size = A_SIZE_8(agp_bridge->current_size);269 270 /* aperture size */271 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);272 273 if (agp_bridge->apbase_config != 0) {274 pci_write_config_dword(agp_bridge->dev, AGP_APBASE,275 agp_bridge->apbase_config);276 } else {277 /* address to map to */278 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,279 AGP_APERTURE_BAR);280 agp_bridge->apbase_config = agp_bridge->gart_bus_addr;281 }282 283 /* attbase - aperture base */284 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);285 286 /* agpctrl */287 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);288 289 /* agpm */290 pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);291 pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));292 /* clear any possible error conditions */293 pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);294 return 0;295}296 297static int intel_850_configure(void)298{299 u16 temp2;300 struct aper_size_info_8 *current_size;301 302 current_size = A_SIZE_8(agp_bridge->current_size);303 304 /* aperture size */305 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);306 307 /* address to map to */308 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,309 AGP_APERTURE_BAR);310 311 /* attbase - aperture base */312 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);313 314 /* agpctrl */315 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);316 317 /* mcgcfg */318 pci_read_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, &temp2);319 pci_write_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));320 /* clear any possible AGP-related error conditions */321 pci_write_config_word(agp_bridge->dev, INTEL_I850_ERRSTS, 0x001c);322 return 0;323}324 325static int intel_860_configure(void)326{327 u16 temp2;328 struct aper_size_info_8 *current_size;329 330 current_size = A_SIZE_8(agp_bridge->current_size);331 332 /* aperture size */333 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);334 335 /* address to map to */336 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,337 AGP_APERTURE_BAR);338 339 /* attbase - aperture base */340 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);341 342 /* agpctrl */343 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);344 345 /* mcgcfg */346 pci_read_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, &temp2);347 pci_write_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));348 /* clear any possible AGP-related error conditions */349 pci_write_config_word(agp_bridge->dev, INTEL_I860_ERRSTS, 0xf700);350 return 0;351}352 353static int intel_830mp_configure(void)354{355 u16 temp2;356 struct aper_size_info_8 *current_size;357 358 current_size = A_SIZE_8(agp_bridge->current_size);359 360 /* aperture size */361 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);362 363 /* address to map to */364 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,365 AGP_APERTURE_BAR);366 367 /* attbase - aperture base */368 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);369 370 /* agpctrl */371 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);372 373 /* gmch */374 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);375 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp2 | (1 << 9));376 /* clear any possible AGP-related error conditions */377 pci_write_config_word(agp_bridge->dev, INTEL_I830_ERRSTS, 0x1c);378 return 0;379}380 381static int intel_7505_configure(void)382{383 u16 temp2;384 struct aper_size_info_8 *current_size;385 386 current_size = A_SIZE_8(agp_bridge->current_size);387 388 /* aperture size */389 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);390 391 /* address to map to */392 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,393 AGP_APERTURE_BAR);394 395 /* attbase - aperture base */396 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);397 398 /* agpctrl */399 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);400 401 /* mchcfg */402 pci_read_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, &temp2);403 pci_write_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, temp2 | (1 << 9));404 405 return 0;406}407 408/* Setup function */409static const struct gatt_mask intel_generic_masks[] =410{411 {.mask = 0x00000017, .type = 0}412};413 414static const struct aper_size_info_8 intel_815_sizes[2] =415{416 {64, 16384, 4, 0},417 {32, 8192, 3, 8},418};419 420static const struct aper_size_info_8 intel_8xx_sizes[7] =421{422 {256, 65536, 6, 0},423 {128, 32768, 5, 32},424 {64, 16384, 4, 48},425 {32, 8192, 3, 56},426 {16, 4096, 2, 60},427 {8, 2048, 1, 62},428 {4, 1024, 0, 63}429};430 431static const struct aper_size_info_16 intel_generic_sizes[7] =432{433 {256, 65536, 6, 0},434 {128, 32768, 5, 32},435 {64, 16384, 4, 48},436 {32, 8192, 3, 56},437 {16, 4096, 2, 60},438 {8, 2048, 1, 62},439 {4, 1024, 0, 63}440};441 442static const struct aper_size_info_8 intel_830mp_sizes[4] =443{444 {256, 65536, 6, 0},445 {128, 32768, 5, 32},446 {64, 16384, 4, 48},447 {32, 8192, 3, 56}448};449 450static const struct agp_bridge_driver intel_generic_driver = {451 .owner = THIS_MODULE,452 .aperture_sizes = intel_generic_sizes,453 .size_type = U16_APER_SIZE,454 .num_aperture_sizes = 7,455 .needs_scratch_page = true,456 .configure = intel_configure,457 .fetch_size = intel_fetch_size,458 .cleanup = intel_cleanup,459 .tlb_flush = intel_tlbflush,460 .mask_memory = agp_generic_mask_memory,461 .masks = intel_generic_masks,462 .agp_enable = agp_generic_enable,463 .cache_flush = global_cache_flush,464 .create_gatt_table = agp_generic_create_gatt_table,465 .free_gatt_table = agp_generic_free_gatt_table,466 .insert_memory = agp_generic_insert_memory,467 .remove_memory = agp_generic_remove_memory,468 .alloc_by_type = agp_generic_alloc_by_type,469 .free_by_type = agp_generic_free_by_type,470 .agp_alloc_page = agp_generic_alloc_page,471 .agp_alloc_pages = agp_generic_alloc_pages,472 .agp_destroy_page = agp_generic_destroy_page,473 .agp_destroy_pages = agp_generic_destroy_pages,474 .agp_type_to_mask_type = agp_generic_type_to_mask_type,475};476 477static const struct agp_bridge_driver intel_815_driver = {478 .owner = THIS_MODULE,479 .aperture_sizes = intel_815_sizes,480 .size_type = U8_APER_SIZE,481 .num_aperture_sizes = 2,482 .needs_scratch_page = true,483 .configure = intel_815_configure,484 .fetch_size = intel_815_fetch_size,485 .cleanup = intel_8xx_cleanup,486 .tlb_flush = intel_8xx_tlbflush,487 .mask_memory = agp_generic_mask_memory,488 .masks = intel_generic_masks,489 .agp_enable = agp_generic_enable,490 .cache_flush = global_cache_flush,491 .create_gatt_table = agp_generic_create_gatt_table,492 .free_gatt_table = agp_generic_free_gatt_table,493 .insert_memory = agp_generic_insert_memory,494 .remove_memory = agp_generic_remove_memory,495 .alloc_by_type = agp_generic_alloc_by_type,496 .free_by_type = agp_generic_free_by_type,497 .agp_alloc_page = agp_generic_alloc_page,498 .agp_alloc_pages = agp_generic_alloc_pages,499 .agp_destroy_page = agp_generic_destroy_page,500 .agp_destroy_pages = agp_generic_destroy_pages,501 .agp_type_to_mask_type = agp_generic_type_to_mask_type,502};503 504static const struct agp_bridge_driver intel_820_driver = {505 .owner = THIS_MODULE,506 .aperture_sizes = intel_8xx_sizes,507 .size_type = U8_APER_SIZE,508 .num_aperture_sizes = 7,509 .needs_scratch_page = true,510 .configure = intel_820_configure,511 .fetch_size = intel_8xx_fetch_size,512 .cleanup = intel_820_cleanup,513 .tlb_flush = intel_820_tlbflush,514 .mask_memory = agp_generic_mask_memory,515 .masks = intel_generic_masks,516 .agp_enable = agp_generic_enable,517 .cache_flush = global_cache_flush,518 .create_gatt_table = agp_generic_create_gatt_table,519 .free_gatt_table = agp_generic_free_gatt_table,520 .insert_memory = agp_generic_insert_memory,521 .remove_memory = agp_generic_remove_memory,522 .alloc_by_type = agp_generic_alloc_by_type,523 .free_by_type = agp_generic_free_by_type,524 .agp_alloc_page = agp_generic_alloc_page,525 .agp_alloc_pages = agp_generic_alloc_pages,526 .agp_destroy_page = agp_generic_destroy_page,527 .agp_destroy_pages = agp_generic_destroy_pages,528 .agp_type_to_mask_type = agp_generic_type_to_mask_type,529};530 531static const struct agp_bridge_driver intel_830mp_driver = {532 .owner = THIS_MODULE,533 .aperture_sizes = intel_830mp_sizes,534 .size_type = U8_APER_SIZE,535 .num_aperture_sizes = 4,536 .needs_scratch_page = true,537 .configure = intel_830mp_configure,538 .fetch_size = intel_8xx_fetch_size,539 .cleanup = intel_8xx_cleanup,540 .tlb_flush = intel_8xx_tlbflush,541 .mask_memory = agp_generic_mask_memory,542 .masks = intel_generic_masks,543 .agp_enable = agp_generic_enable,544 .cache_flush = global_cache_flush,545 .create_gatt_table = agp_generic_create_gatt_table,546 .free_gatt_table = agp_generic_free_gatt_table,547 .insert_memory = agp_generic_insert_memory,548 .remove_memory = agp_generic_remove_memory,549 .alloc_by_type = agp_generic_alloc_by_type,550 .free_by_type = agp_generic_free_by_type,551 .agp_alloc_page = agp_generic_alloc_page,552 .agp_alloc_pages = agp_generic_alloc_pages,553 .agp_destroy_page = agp_generic_destroy_page,554 .agp_destroy_pages = agp_generic_destroy_pages,555 .agp_type_to_mask_type = agp_generic_type_to_mask_type,556};557 558static const struct agp_bridge_driver intel_840_driver = {559 .owner = THIS_MODULE,560 .aperture_sizes = intel_8xx_sizes,561 .size_type = U8_APER_SIZE,562 .num_aperture_sizes = 7,563 .needs_scratch_page = true,564 .configure = intel_840_configure,565 .fetch_size = intel_8xx_fetch_size,566 .cleanup = intel_8xx_cleanup,567 .tlb_flush = intel_8xx_tlbflush,568 .mask_memory = agp_generic_mask_memory,569 .masks = intel_generic_masks,570 .agp_enable = agp_generic_enable,571 .cache_flush = global_cache_flush,572 .create_gatt_table = agp_generic_create_gatt_table,573 .free_gatt_table = agp_generic_free_gatt_table,574 .insert_memory = agp_generic_insert_memory,575 .remove_memory = agp_generic_remove_memory,576 .alloc_by_type = agp_generic_alloc_by_type,577 .free_by_type = agp_generic_free_by_type,578 .agp_alloc_page = agp_generic_alloc_page,579 .agp_alloc_pages = agp_generic_alloc_pages,580 .agp_destroy_page = agp_generic_destroy_page,581 .agp_destroy_pages = agp_generic_destroy_pages,582 .agp_type_to_mask_type = agp_generic_type_to_mask_type,583};584 585static const struct agp_bridge_driver intel_845_driver = {586 .owner = THIS_MODULE,587 .aperture_sizes = intel_8xx_sizes,588 .size_type = U8_APER_SIZE,589 .num_aperture_sizes = 7,590 .needs_scratch_page = true,591 .configure = intel_845_configure,592 .fetch_size = intel_8xx_fetch_size,593 .cleanup = intel_8xx_cleanup,594 .tlb_flush = intel_8xx_tlbflush,595 .mask_memory = agp_generic_mask_memory,596 .masks = intel_generic_masks,597 .agp_enable = agp_generic_enable,598 .cache_flush = global_cache_flush,599 .create_gatt_table = agp_generic_create_gatt_table,600 .free_gatt_table = agp_generic_free_gatt_table,601 .insert_memory = agp_generic_insert_memory,602 .remove_memory = agp_generic_remove_memory,603 .alloc_by_type = agp_generic_alloc_by_type,604 .free_by_type = agp_generic_free_by_type,605 .agp_alloc_page = agp_generic_alloc_page,606 .agp_alloc_pages = agp_generic_alloc_pages,607 .agp_destroy_page = agp_generic_destroy_page,608 .agp_destroy_pages = agp_generic_destroy_pages,609 .agp_type_to_mask_type = agp_generic_type_to_mask_type,610};611 612static const struct agp_bridge_driver intel_850_driver = {613 .owner = THIS_MODULE,614 .aperture_sizes = intel_8xx_sizes,615 .size_type = U8_APER_SIZE,616 .num_aperture_sizes = 7,617 .needs_scratch_page = true,618 .configure = intel_850_configure,619 .fetch_size = intel_8xx_fetch_size,620 .cleanup = intel_8xx_cleanup,621 .tlb_flush = intel_8xx_tlbflush,622 .mask_memory = agp_generic_mask_memory,623 .masks = intel_generic_masks,624 .agp_enable = agp_generic_enable,625 .cache_flush = global_cache_flush,626 .create_gatt_table = agp_generic_create_gatt_table,627 .free_gatt_table = agp_generic_free_gatt_table,628 .insert_memory = agp_generic_insert_memory,629 .remove_memory = agp_generic_remove_memory,630 .alloc_by_type = agp_generic_alloc_by_type,631 .free_by_type = agp_generic_free_by_type,632 .agp_alloc_page = agp_generic_alloc_page,633 .agp_alloc_pages = agp_generic_alloc_pages,634 .agp_destroy_page = agp_generic_destroy_page,635 .agp_destroy_pages = agp_generic_destroy_pages,636 .agp_type_to_mask_type = agp_generic_type_to_mask_type,637};638 639static const struct agp_bridge_driver intel_860_driver = {640 .owner = THIS_MODULE,641 .aperture_sizes = intel_8xx_sizes,642 .size_type = U8_APER_SIZE,643 .num_aperture_sizes = 7,644 .needs_scratch_page = true,645 .configure = intel_860_configure,646 .fetch_size = intel_8xx_fetch_size,647 .cleanup = intel_8xx_cleanup,648 .tlb_flush = intel_8xx_tlbflush,649 .mask_memory = agp_generic_mask_memory,650 .masks = intel_generic_masks,651 .agp_enable = agp_generic_enable,652 .cache_flush = global_cache_flush,653 .create_gatt_table = agp_generic_create_gatt_table,654 .free_gatt_table = agp_generic_free_gatt_table,655 .insert_memory = agp_generic_insert_memory,656 .remove_memory = agp_generic_remove_memory,657 .alloc_by_type = agp_generic_alloc_by_type,658 .free_by_type = agp_generic_free_by_type,659 .agp_alloc_page = agp_generic_alloc_page,660 .agp_alloc_pages = agp_generic_alloc_pages,661 .agp_destroy_page = agp_generic_destroy_page,662 .agp_destroy_pages = agp_generic_destroy_pages,663 .agp_type_to_mask_type = agp_generic_type_to_mask_type,664};665 666static const struct agp_bridge_driver intel_7505_driver = {667 .owner = THIS_MODULE,668 .aperture_sizes = intel_8xx_sizes,669 .size_type = U8_APER_SIZE,670 .num_aperture_sizes = 7,671 .needs_scratch_page = true,672 .configure = intel_7505_configure,673 .fetch_size = intel_8xx_fetch_size,674 .cleanup = intel_8xx_cleanup,675 .tlb_flush = intel_8xx_tlbflush,676 .mask_memory = agp_generic_mask_memory,677 .masks = intel_generic_masks,678 .agp_enable = agp_generic_enable,679 .cache_flush = global_cache_flush,680 .create_gatt_table = agp_generic_create_gatt_table,681 .free_gatt_table = agp_generic_free_gatt_table,682 .insert_memory = agp_generic_insert_memory,683 .remove_memory = agp_generic_remove_memory,684 .alloc_by_type = agp_generic_alloc_by_type,685 .free_by_type = agp_generic_free_by_type,686 .agp_alloc_page = agp_generic_alloc_page,687 .agp_alloc_pages = agp_generic_alloc_pages,688 .agp_destroy_page = agp_generic_destroy_page,689 .agp_destroy_pages = agp_generic_destroy_pages,690 .agp_type_to_mask_type = agp_generic_type_to_mask_type,691};692 693/* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of694 * driver and gmch_driver must be non-null, and find_gmch will determine695 * which one should be used if a gmch_chip_id is present.696 */697static const struct intel_agp_driver_description {698 unsigned int chip_id;699 char *name;700 const struct agp_bridge_driver *driver;701} intel_agp_chipsets[] = {702 { PCI_DEVICE_ID_INTEL_82443LX_0, "440LX", &intel_generic_driver },703 { PCI_DEVICE_ID_INTEL_82443BX_0, "440BX", &intel_generic_driver },704 { PCI_DEVICE_ID_INTEL_82443GX_0, "440GX", &intel_generic_driver },705 { PCI_DEVICE_ID_INTEL_82815_MC, "i815", &intel_815_driver },706 { PCI_DEVICE_ID_INTEL_82820_HB, "i820", &intel_820_driver },707 { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver },708 { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver },709 { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver },710 { PCI_DEVICE_ID_INTEL_82845_HB, "i845", &intel_845_driver },711 { PCI_DEVICE_ID_INTEL_82845G_HB, "845G", &intel_845_driver },712 { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver },713 { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver },714 { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver },715 { PCI_DEVICE_ID_INTEL_82855GM_HB, "855GM", &intel_845_driver },716 { PCI_DEVICE_ID_INTEL_82860_HB, "i860", &intel_860_driver },717 { PCI_DEVICE_ID_INTEL_82865_HB, "865", &intel_845_driver },718 { PCI_DEVICE_ID_INTEL_82875_HB, "i875", &intel_845_driver },719 { PCI_DEVICE_ID_INTEL_7505_0, "E7505", &intel_7505_driver },720 { PCI_DEVICE_ID_INTEL_7205_0, "E7205", &intel_7505_driver },721 { 0, NULL, NULL }722};723 724static int agp_intel_probe(struct pci_dev *pdev,725 const struct pci_device_id *ent)726{727 struct agp_bridge_data *bridge;728 u8 cap_ptr = 0;729 struct resource *r;730 int i, err;731 732 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);733 734 bridge = agp_alloc_bridge();735 if (!bridge)736 return -ENOMEM;737 738 bridge->capndx = cap_ptr;739 740 if (intel_gmch_probe(pdev, NULL, bridge))741 goto found_gmch;742 743 for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {744 /* In case that multiple models of gfx chip may745 stand on same host bridge type, this can be746 sure we detect the right IGD. */747 if (pdev->device == intel_agp_chipsets[i].chip_id) {748 bridge->driver = intel_agp_chipsets[i].driver;749 break;750 }751 }752 753 if (!bridge->driver) {754 if (cap_ptr)755 dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n",756 pdev->vendor, pdev->device);757 agp_put_bridge(bridge);758 return -ENODEV;759 }760 761 bridge->dev = pdev;762 bridge->dev_private_data = NULL;763 764 dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);765 766 /*767 * The following fixes the case where the BIOS has "forgotten" to768 * provide an address range for the GART.769 * 20030610 - hamish@zot.org770 * This happens before pci_enable_device() intentionally;771 * calling pci_enable_device() before assigning the resource772 * will result in the GART being disabled on machines with such773 * BIOSs (the GART ends up with a BAR starting at 0, which774 * conflicts a lot of other devices).775 */776 r = &pdev->resource[0];777 if (!r->start && r->end) {778 if (pci_assign_resource(pdev, 0)) {779 dev_err(&pdev->dev, "can't assign resource 0\n");780 agp_put_bridge(bridge);781 return -ENODEV;782 }783 }784 785 /*786 * If the device has not been properly setup, the following will catch787 * the problem and should stop the system from crashing.788 * 20030610 - hamish@zot.org789 */790 if (pci_enable_device(pdev)) {791 dev_err(&pdev->dev, "can't enable PCI device\n");792 agp_put_bridge(bridge);793 return -ENODEV;794 }795 796 /* Fill in the mode register */797 if (cap_ptr) {798 pci_read_config_dword(pdev,799 bridge->capndx+PCI_AGP_STATUS,800 &bridge->mode);801 }802 803found_gmch:804 pci_set_drvdata(pdev, bridge);805 err = agp_add_bridge(bridge);806 return err;807}808 809static void agp_intel_remove(struct pci_dev *pdev)810{811 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);812 813 agp_remove_bridge(bridge);814 815 intel_gmch_remove();816 817 agp_put_bridge(bridge);818}819 820static int agp_intel_resume(struct device *dev)821{822 struct pci_dev *pdev = to_pci_dev(dev);823 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);824 825 bridge->driver->configure();826 827 return 0;828}829 830static const struct pci_device_id agp_intel_pci_table[] = {831#define ID(x) \832 { \833 .class = (PCI_CLASS_BRIDGE_HOST << 8), \834 .class_mask = ~0, \835 .vendor = PCI_VENDOR_ID_INTEL, \836 .device = x, \837 .subvendor = PCI_ANY_ID, \838 .subdevice = PCI_ANY_ID, \839 }840 ID(PCI_DEVICE_ID_INTEL_82441), /* for HAS2 support */841 ID(PCI_DEVICE_ID_INTEL_82443LX_0),842 ID(PCI_DEVICE_ID_INTEL_82443BX_0),843 ID(PCI_DEVICE_ID_INTEL_82443GX_0),844 ID(PCI_DEVICE_ID_INTEL_82810_MC1),845 ID(PCI_DEVICE_ID_INTEL_82810_MC3),846 ID(PCI_DEVICE_ID_INTEL_82810E_MC),847 ID(PCI_DEVICE_ID_INTEL_82815_MC),848 ID(PCI_DEVICE_ID_INTEL_82820_HB),849 ID(PCI_DEVICE_ID_INTEL_82820_UP_HB),850 ID(PCI_DEVICE_ID_INTEL_82830_HB),851 ID(PCI_DEVICE_ID_INTEL_82840_HB),852 ID(PCI_DEVICE_ID_INTEL_82845_HB),853 ID(PCI_DEVICE_ID_INTEL_82845G_HB),854 ID(PCI_DEVICE_ID_INTEL_82850_HB),855 ID(PCI_DEVICE_ID_INTEL_82854_HB),856 ID(PCI_DEVICE_ID_INTEL_82855PM_HB),857 ID(PCI_DEVICE_ID_INTEL_82855GM_HB),858 ID(PCI_DEVICE_ID_INTEL_82860_HB),859 ID(PCI_DEVICE_ID_INTEL_82865_HB),860 ID(PCI_DEVICE_ID_INTEL_82875_HB),861 ID(PCI_DEVICE_ID_INTEL_7505_0),862 ID(PCI_DEVICE_ID_INTEL_7205_0),863 ID(PCI_DEVICE_ID_INTEL_E7221_HB),864 ID(PCI_DEVICE_ID_INTEL_82915G_HB),865 ID(PCI_DEVICE_ID_INTEL_82915GM_HB),866 ID(PCI_DEVICE_ID_INTEL_82945G_HB),867 ID(PCI_DEVICE_ID_INTEL_82945GM_HB),868 ID(PCI_DEVICE_ID_INTEL_82945GME_HB),869 ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB),870 ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB),871 ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),872 ID(PCI_DEVICE_ID_INTEL_82G35_HB),873 ID(PCI_DEVICE_ID_INTEL_82965Q_HB),874 ID(PCI_DEVICE_ID_INTEL_82965G_HB),875 ID(PCI_DEVICE_ID_INTEL_82965GM_HB),876 ID(PCI_DEVICE_ID_INTEL_82965GME_HB),877 ID(PCI_DEVICE_ID_INTEL_G33_HB),878 ID(PCI_DEVICE_ID_INTEL_Q35_HB),879 ID(PCI_DEVICE_ID_INTEL_Q33_HB),880 ID(PCI_DEVICE_ID_INTEL_GM45_HB),881 ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB),882 ID(PCI_DEVICE_ID_INTEL_Q45_HB),883 ID(PCI_DEVICE_ID_INTEL_G45_HB),884 ID(PCI_DEVICE_ID_INTEL_G41_HB),885 ID(PCI_DEVICE_ID_INTEL_B43_HB),886 ID(PCI_DEVICE_ID_INTEL_B43_1_HB),887 ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),888 ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB),889 ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),890 ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),891 ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),892 { }893};894 895MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);896 897static DEFINE_SIMPLE_DEV_PM_OPS(agp_intel_pm_ops, NULL, agp_intel_resume);898 899static struct pci_driver agp_intel_pci_driver = {900 .name = "agpgart-intel",901 .id_table = agp_intel_pci_table,902 .probe = agp_intel_probe,903 .remove = agp_intel_remove,904 .driver.pm = &agp_intel_pm_ops,905};906 907static int __init agp_intel_init(void)908{909 if (agp_off)910 return -EINVAL;911 return pci_register_driver(&agp_intel_pci_driver);912}913 914static void __exit agp_intel_cleanup(void)915{916 pci_unregister_driver(&agp_intel_pci_driver);917}918 919module_init(agp_intel_init);920module_exit(agp_intel_cleanup);921 922MODULE_AUTHOR("Dave Jones, Various @Intel");923MODULE_DESCRIPTION("Intel AGPGART routines");924MODULE_LICENSE("GPL and additional rights");925