Merge branch 'akpm'
[linux-2.6/next.git] / drivers / char / agp / intel-agp.c
blobb427711be4be385c2704d4c971dc5cd512ed85c4
1 /*
2 * Intel AGPGART routines.
3 */
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"
16 int intel_agp_enabled;
17 EXPORT_SYMBOL(intel_agp_enabled);
19 static int intel_fetch_size(void)
21 int i;
22 u16 temp;
23 struct aper_size_info_16 *values;
25 pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
26 values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
28 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
29 if (temp == values[i].size_value) {
30 agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
31 agp_bridge->aperture_size_idx = i;
32 return values[i].size;
36 return 0;
39 static int __intel_8xx_fetch_size(u8 temp)
41 int i;
42 struct aper_size_info_8 *values;
44 values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
46 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
47 if (temp == values[i].size_value) {
48 agp_bridge->previous_size =
49 agp_bridge->current_size = (void *) (values + i);
50 agp_bridge->aperture_size_idx = i;
51 return values[i].size;
54 return 0;
57 static int intel_8xx_fetch_size(void)
59 u8 temp;
61 pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
62 return __intel_8xx_fetch_size(temp);
65 static int intel_815_fetch_size(void)
67 u8 temp;
69 /* Intel 815 chipsets have a _weird_ APSIZE register with only
70 * one non-reserved bit, so mask the others out ... */
71 pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
72 temp &= (1 << 3);
74 return __intel_8xx_fetch_size(temp);
77 static void intel_tlbflush(struct agp_memory *mem)
79 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
80 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
84 static void intel_8xx_tlbflush(struct agp_memory *mem)
86 u32 temp;
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 pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
90 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
94 static void intel_cleanup(void)
96 u16 temp;
97 struct aper_size_info_16 *previous_size;
99 previous_size = A_SIZE_16(agp_bridge->previous_size);
100 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
101 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
102 pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
106 static void intel_8xx_cleanup(void)
108 u16 temp;
109 struct aper_size_info_8 *previous_size;
111 previous_size = A_SIZE_8(agp_bridge->previous_size);
112 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
113 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
114 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
118 static int intel_configure(void)
120 u32 temp;
121 u16 temp2;
122 struct aper_size_info_16 *current_size;
124 current_size = A_SIZE_16(agp_bridge->current_size);
126 /* aperture size */
127 pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
129 /* address to map to */
130 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
131 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
133 /* attbase - aperture base */
134 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
136 /* agpctrl */
137 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
139 /* paccfg/nbxcfg */
140 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
141 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,
142 (temp2 & ~(1 << 10)) | (1 << 9));
143 /* clear any possible error conditions */
144 pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);
145 return 0;
148 static int intel_815_configure(void)
150 u32 temp, addr;
151 u8 temp2;
152 struct aper_size_info_8 *current_size;
154 /* attbase - aperture base */
155 /* the Intel 815 chipset spec. says that bits 29-31 in the
156 * ATTBASE register are reserved -> try not to write them */
157 if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {
158 dev_emerg(&agp_bridge->dev->dev, "gatt bus addr too high");
159 return -EINVAL;
162 current_size = A_SIZE_8(agp_bridge->current_size);
164 /* aperture size */
165 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
166 current_size->size_value);
168 /* address to map to */
169 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
170 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
172 pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr);
173 addr &= INTEL_815_ATTBASE_MASK;
174 addr |= agp_bridge->gatt_bus_addr;
175 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, addr);
177 /* agpctrl */
178 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
180 /* apcont */
181 pci_read_config_byte(agp_bridge->dev, INTEL_815_APCONT, &temp2);
182 pci_write_config_byte(agp_bridge->dev, INTEL_815_APCONT, temp2 | (1 << 1));
184 /* clear any possible error conditions */
185 /* Oddness : this chipset seems to have no ERRSTS register ! */
186 return 0;
189 static void intel_820_tlbflush(struct agp_memory *mem)
191 return;
194 static void intel_820_cleanup(void)
196 u8 temp;
197 struct aper_size_info_8 *previous_size;
199 previous_size = A_SIZE_8(agp_bridge->previous_size);
200 pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp);
201 pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR,
202 temp & ~(1 << 1));
203 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
204 previous_size->size_value);
208 static int intel_820_configure(void)
210 u32 temp;
211 u8 temp2;
212 struct aper_size_info_8 *current_size;
214 current_size = A_SIZE_8(agp_bridge->current_size);
216 /* aperture size */
217 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
219 /* address to map to */
220 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
221 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
223 /* attbase - aperture base */
224 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
226 /* agpctrl */
227 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
229 /* global enable aperture access */
230 /* This flag is not accessed through MCHCFG register as in */
231 /* i850 chipset. */
232 pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp2);
233 pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp2 | (1 << 1));
234 /* clear any possible AGP-related error conditions */
235 pci_write_config_word(agp_bridge->dev, INTEL_I820_ERRSTS, 0x001c);
236 return 0;
239 static int intel_840_configure(void)
241 u32 temp;
242 u16 temp2;
243 struct aper_size_info_8 *current_size;
245 current_size = A_SIZE_8(agp_bridge->current_size);
247 /* aperture size */
248 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
250 /* address to map to */
251 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
252 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
254 /* attbase - aperture base */
255 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
257 /* agpctrl */
258 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
260 /* mcgcfg */
261 pci_read_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, &temp2);
262 pci_write_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));
263 /* clear any possible error conditions */
264 pci_write_config_word(agp_bridge->dev, INTEL_I840_ERRSTS, 0xc000);
265 return 0;
268 static int intel_845_configure(void)
270 u32 temp;
271 u8 temp2;
272 struct aper_size_info_8 *current_size;
274 current_size = A_SIZE_8(agp_bridge->current_size);
276 /* aperture size */
277 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
279 if (agp_bridge->apbase_config != 0) {
280 pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
281 agp_bridge->apbase_config);
282 } else {
283 /* address to map to */
284 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
285 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
286 agp_bridge->apbase_config = temp;
289 /* attbase - aperture base */
290 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
292 /* agpctrl */
293 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
295 /* agpm */
296 pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
297 pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
298 /* clear any possible error conditions */
299 pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
300 return 0;
303 static int intel_850_configure(void)
305 u32 temp;
306 u16 temp2;
307 struct aper_size_info_8 *current_size;
309 current_size = A_SIZE_8(agp_bridge->current_size);
311 /* aperture size */
312 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
314 /* address to map to */
315 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
316 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
318 /* attbase - aperture base */
319 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
321 /* agpctrl */
322 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
324 /* mcgcfg */
325 pci_read_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, &temp2);
326 pci_write_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));
327 /* clear any possible AGP-related error conditions */
328 pci_write_config_word(agp_bridge->dev, INTEL_I850_ERRSTS, 0x001c);
329 return 0;
332 static int intel_860_configure(void)
334 u32 temp;
335 u16 temp2;
336 struct aper_size_info_8 *current_size;
338 current_size = A_SIZE_8(agp_bridge->current_size);
340 /* aperture size */
341 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
343 /* address to map to */
344 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
345 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
347 /* attbase - aperture base */
348 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
350 /* agpctrl */
351 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
353 /* mcgcfg */
354 pci_read_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, &temp2);
355 pci_write_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));
356 /* clear any possible AGP-related error conditions */
357 pci_write_config_word(agp_bridge->dev, INTEL_I860_ERRSTS, 0xf700);
358 return 0;
361 static int intel_830mp_configure(void)
363 u32 temp;
364 u16 temp2;
365 struct aper_size_info_8 *current_size;
367 current_size = A_SIZE_8(agp_bridge->current_size);
369 /* aperture size */
370 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
372 /* address to map to */
373 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
374 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
376 /* attbase - aperture base */
377 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
379 /* agpctrl */
380 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
382 /* gmch */
383 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
384 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp2 | (1 << 9));
385 /* clear any possible AGP-related error conditions */
386 pci_write_config_word(agp_bridge->dev, INTEL_I830_ERRSTS, 0x1c);
387 return 0;
390 static int intel_7505_configure(void)
392 u32 temp;
393 u16 temp2;
394 struct aper_size_info_8 *current_size;
396 current_size = A_SIZE_8(agp_bridge->current_size);
398 /* aperture size */
399 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
401 /* address to map to */
402 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
403 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
405 /* attbase - aperture base */
406 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
408 /* agpctrl */
409 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
411 /* mchcfg */
412 pci_read_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, &temp2);
413 pci_write_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, temp2 | (1 << 9));
415 return 0;
418 /* Setup function */
419 static const struct gatt_mask intel_generic_masks[] =
421 {.mask = 0x00000017, .type = 0}
424 static const struct aper_size_info_8 intel_815_sizes[2] =
426 {64, 16384, 4, 0},
427 {32, 8192, 3, 8},
430 static const struct aper_size_info_8 intel_8xx_sizes[7] =
432 {256, 65536, 6, 0},
433 {128, 32768, 5, 32},
434 {64, 16384, 4, 48},
435 {32, 8192, 3, 56},
436 {16, 4096, 2, 60},
437 {8, 2048, 1, 62},
438 {4, 1024, 0, 63}
441 static const struct aper_size_info_16 intel_generic_sizes[7] =
443 {256, 65536, 6, 0},
444 {128, 32768, 5, 32},
445 {64, 16384, 4, 48},
446 {32, 8192, 3, 56},
447 {16, 4096, 2, 60},
448 {8, 2048, 1, 62},
449 {4, 1024, 0, 63}
452 static const struct aper_size_info_8 intel_830mp_sizes[4] =
454 {256, 65536, 6, 0},
455 {128, 32768, 5, 32},
456 {64, 16384, 4, 48},
457 {32, 8192, 3, 56}
460 static const struct agp_bridge_driver intel_generic_driver = {
461 .owner = THIS_MODULE,
462 .aperture_sizes = intel_generic_sizes,
463 .size_type = U16_APER_SIZE,
464 .num_aperture_sizes = 7,
465 .needs_scratch_page = true,
466 .configure = intel_configure,
467 .fetch_size = intel_fetch_size,
468 .cleanup = intel_cleanup,
469 .tlb_flush = intel_tlbflush,
470 .mask_memory = agp_generic_mask_memory,
471 .masks = intel_generic_masks,
472 .agp_enable = agp_generic_enable,
473 .cache_flush = global_cache_flush,
474 .create_gatt_table = agp_generic_create_gatt_table,
475 .free_gatt_table = agp_generic_free_gatt_table,
476 .insert_memory = agp_generic_insert_memory,
477 .remove_memory = agp_generic_remove_memory,
478 .alloc_by_type = agp_generic_alloc_by_type,
479 .free_by_type = agp_generic_free_by_type,
480 .agp_alloc_page = agp_generic_alloc_page,
481 .agp_alloc_pages = agp_generic_alloc_pages,
482 .agp_destroy_page = agp_generic_destroy_page,
483 .agp_destroy_pages = agp_generic_destroy_pages,
484 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
487 static const struct agp_bridge_driver intel_815_driver = {
488 .owner = THIS_MODULE,
489 .aperture_sizes = intel_815_sizes,
490 .size_type = U8_APER_SIZE,
491 .num_aperture_sizes = 2,
492 .needs_scratch_page = true,
493 .configure = intel_815_configure,
494 .fetch_size = intel_815_fetch_size,
495 .cleanup = intel_8xx_cleanup,
496 .tlb_flush = intel_8xx_tlbflush,
497 .mask_memory = agp_generic_mask_memory,
498 .masks = intel_generic_masks,
499 .agp_enable = agp_generic_enable,
500 .cache_flush = global_cache_flush,
501 .create_gatt_table = agp_generic_create_gatt_table,
502 .free_gatt_table = agp_generic_free_gatt_table,
503 .insert_memory = agp_generic_insert_memory,
504 .remove_memory = agp_generic_remove_memory,
505 .alloc_by_type = agp_generic_alloc_by_type,
506 .free_by_type = agp_generic_free_by_type,
507 .agp_alloc_page = agp_generic_alloc_page,
508 .agp_alloc_pages = agp_generic_alloc_pages,
509 .agp_destroy_page = agp_generic_destroy_page,
510 .agp_destroy_pages = agp_generic_destroy_pages,
511 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
514 static const struct agp_bridge_driver intel_820_driver = {
515 .owner = THIS_MODULE,
516 .aperture_sizes = intel_8xx_sizes,
517 .size_type = U8_APER_SIZE,
518 .num_aperture_sizes = 7,
519 .needs_scratch_page = true,
520 .configure = intel_820_configure,
521 .fetch_size = intel_8xx_fetch_size,
522 .cleanup = intel_820_cleanup,
523 .tlb_flush = intel_820_tlbflush,
524 .mask_memory = agp_generic_mask_memory,
525 .masks = intel_generic_masks,
526 .agp_enable = agp_generic_enable,
527 .cache_flush = global_cache_flush,
528 .create_gatt_table = agp_generic_create_gatt_table,
529 .free_gatt_table = agp_generic_free_gatt_table,
530 .insert_memory = agp_generic_insert_memory,
531 .remove_memory = agp_generic_remove_memory,
532 .alloc_by_type = agp_generic_alloc_by_type,
533 .free_by_type = agp_generic_free_by_type,
534 .agp_alloc_page = agp_generic_alloc_page,
535 .agp_alloc_pages = agp_generic_alloc_pages,
536 .agp_destroy_page = agp_generic_destroy_page,
537 .agp_destroy_pages = agp_generic_destroy_pages,
538 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
541 static const struct agp_bridge_driver intel_830mp_driver = {
542 .owner = THIS_MODULE,
543 .aperture_sizes = intel_830mp_sizes,
544 .size_type = U8_APER_SIZE,
545 .num_aperture_sizes = 4,
546 .needs_scratch_page = true,
547 .configure = intel_830mp_configure,
548 .fetch_size = intel_8xx_fetch_size,
549 .cleanup = intel_8xx_cleanup,
550 .tlb_flush = intel_8xx_tlbflush,
551 .mask_memory = agp_generic_mask_memory,
552 .masks = intel_generic_masks,
553 .agp_enable = agp_generic_enable,
554 .cache_flush = global_cache_flush,
555 .create_gatt_table = agp_generic_create_gatt_table,
556 .free_gatt_table = agp_generic_free_gatt_table,
557 .insert_memory = agp_generic_insert_memory,
558 .remove_memory = agp_generic_remove_memory,
559 .alloc_by_type = agp_generic_alloc_by_type,
560 .free_by_type = agp_generic_free_by_type,
561 .agp_alloc_page = agp_generic_alloc_page,
562 .agp_alloc_pages = agp_generic_alloc_pages,
563 .agp_destroy_page = agp_generic_destroy_page,
564 .agp_destroy_pages = agp_generic_destroy_pages,
565 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
568 static const struct agp_bridge_driver intel_840_driver = {
569 .owner = THIS_MODULE,
570 .aperture_sizes = intel_8xx_sizes,
571 .size_type = U8_APER_SIZE,
572 .num_aperture_sizes = 7,
573 .needs_scratch_page = true,
574 .configure = intel_840_configure,
575 .fetch_size = intel_8xx_fetch_size,
576 .cleanup = intel_8xx_cleanup,
577 .tlb_flush = intel_8xx_tlbflush,
578 .mask_memory = agp_generic_mask_memory,
579 .masks = intel_generic_masks,
580 .agp_enable = agp_generic_enable,
581 .cache_flush = global_cache_flush,
582 .create_gatt_table = agp_generic_create_gatt_table,
583 .free_gatt_table = agp_generic_free_gatt_table,
584 .insert_memory = agp_generic_insert_memory,
585 .remove_memory = agp_generic_remove_memory,
586 .alloc_by_type = agp_generic_alloc_by_type,
587 .free_by_type = agp_generic_free_by_type,
588 .agp_alloc_page = agp_generic_alloc_page,
589 .agp_alloc_pages = agp_generic_alloc_pages,
590 .agp_destroy_page = agp_generic_destroy_page,
591 .agp_destroy_pages = agp_generic_destroy_pages,
592 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
595 static const struct agp_bridge_driver intel_845_driver = {
596 .owner = THIS_MODULE,
597 .aperture_sizes = intel_8xx_sizes,
598 .size_type = U8_APER_SIZE,
599 .num_aperture_sizes = 7,
600 .needs_scratch_page = true,
601 .configure = intel_845_configure,
602 .fetch_size = intel_8xx_fetch_size,
603 .cleanup = intel_8xx_cleanup,
604 .tlb_flush = intel_8xx_tlbflush,
605 .mask_memory = agp_generic_mask_memory,
606 .masks = intel_generic_masks,
607 .agp_enable = agp_generic_enable,
608 .cache_flush = global_cache_flush,
609 .create_gatt_table = agp_generic_create_gatt_table,
610 .free_gatt_table = agp_generic_free_gatt_table,
611 .insert_memory = agp_generic_insert_memory,
612 .remove_memory = agp_generic_remove_memory,
613 .alloc_by_type = agp_generic_alloc_by_type,
614 .free_by_type = agp_generic_free_by_type,
615 .agp_alloc_page = agp_generic_alloc_page,
616 .agp_alloc_pages = agp_generic_alloc_pages,
617 .agp_destroy_page = agp_generic_destroy_page,
618 .agp_destroy_pages = agp_generic_destroy_pages,
619 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
622 static const struct agp_bridge_driver intel_850_driver = {
623 .owner = THIS_MODULE,
624 .aperture_sizes = intel_8xx_sizes,
625 .size_type = U8_APER_SIZE,
626 .num_aperture_sizes = 7,
627 .needs_scratch_page = true,
628 .configure = intel_850_configure,
629 .fetch_size = intel_8xx_fetch_size,
630 .cleanup = intel_8xx_cleanup,
631 .tlb_flush = intel_8xx_tlbflush,
632 .mask_memory = agp_generic_mask_memory,
633 .masks = intel_generic_masks,
634 .agp_enable = agp_generic_enable,
635 .cache_flush = global_cache_flush,
636 .create_gatt_table = agp_generic_create_gatt_table,
637 .free_gatt_table = agp_generic_free_gatt_table,
638 .insert_memory = agp_generic_insert_memory,
639 .remove_memory = agp_generic_remove_memory,
640 .alloc_by_type = agp_generic_alloc_by_type,
641 .free_by_type = agp_generic_free_by_type,
642 .agp_alloc_page = agp_generic_alloc_page,
643 .agp_alloc_pages = agp_generic_alloc_pages,
644 .agp_destroy_page = agp_generic_destroy_page,
645 .agp_destroy_pages = agp_generic_destroy_pages,
646 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
649 static const struct agp_bridge_driver intel_860_driver = {
650 .owner = THIS_MODULE,
651 .aperture_sizes = intel_8xx_sizes,
652 .size_type = U8_APER_SIZE,
653 .num_aperture_sizes = 7,
654 .needs_scratch_page = true,
655 .configure = intel_860_configure,
656 .fetch_size = intel_8xx_fetch_size,
657 .cleanup = intel_8xx_cleanup,
658 .tlb_flush = intel_8xx_tlbflush,
659 .mask_memory = agp_generic_mask_memory,
660 .masks = intel_generic_masks,
661 .agp_enable = agp_generic_enable,
662 .cache_flush = global_cache_flush,
663 .create_gatt_table = agp_generic_create_gatt_table,
664 .free_gatt_table = agp_generic_free_gatt_table,
665 .insert_memory = agp_generic_insert_memory,
666 .remove_memory = agp_generic_remove_memory,
667 .alloc_by_type = agp_generic_alloc_by_type,
668 .free_by_type = agp_generic_free_by_type,
669 .agp_alloc_page = agp_generic_alloc_page,
670 .agp_alloc_pages = agp_generic_alloc_pages,
671 .agp_destroy_page = agp_generic_destroy_page,
672 .agp_destroy_pages = agp_generic_destroy_pages,
673 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
676 static const struct agp_bridge_driver intel_7505_driver = {
677 .owner = THIS_MODULE,
678 .aperture_sizes = intel_8xx_sizes,
679 .size_type = U8_APER_SIZE,
680 .num_aperture_sizes = 7,
681 .needs_scratch_page = true,
682 .configure = intel_7505_configure,
683 .fetch_size = intel_8xx_fetch_size,
684 .cleanup = intel_8xx_cleanup,
685 .tlb_flush = intel_8xx_tlbflush,
686 .mask_memory = agp_generic_mask_memory,
687 .masks = intel_generic_masks,
688 .agp_enable = agp_generic_enable,
689 .cache_flush = global_cache_flush,
690 .create_gatt_table = agp_generic_create_gatt_table,
691 .free_gatt_table = agp_generic_free_gatt_table,
692 .insert_memory = agp_generic_insert_memory,
693 .remove_memory = agp_generic_remove_memory,
694 .alloc_by_type = agp_generic_alloc_by_type,
695 .free_by_type = agp_generic_free_by_type,
696 .agp_alloc_page = agp_generic_alloc_page,
697 .agp_alloc_pages = agp_generic_alloc_pages,
698 .agp_destroy_page = agp_generic_destroy_page,
699 .agp_destroy_pages = agp_generic_destroy_pages,
700 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
703 /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of
704 * driver and gmch_driver must be non-null, and find_gmch will determine
705 * which one should be used if a gmch_chip_id is present.
707 static const struct intel_agp_driver_description {
708 unsigned int chip_id;
709 char *name;
710 const struct agp_bridge_driver *driver;
711 } intel_agp_chipsets[] = {
712 { PCI_DEVICE_ID_INTEL_82443LX_0, "440LX", &intel_generic_driver },
713 { PCI_DEVICE_ID_INTEL_82443BX_0, "440BX", &intel_generic_driver },
714 { PCI_DEVICE_ID_INTEL_82443GX_0, "440GX", &intel_generic_driver },
715 { PCI_DEVICE_ID_INTEL_82815_MC, "i815", &intel_815_driver },
716 { PCI_DEVICE_ID_INTEL_82820_HB, "i820", &intel_820_driver },
717 { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver },
718 { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver },
719 { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver },
720 { PCI_DEVICE_ID_INTEL_82845_HB, "i845", &intel_845_driver },
721 { PCI_DEVICE_ID_INTEL_82845G_HB, "845G", &intel_845_driver },
722 { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver },
723 { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver },
724 { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver },
725 { PCI_DEVICE_ID_INTEL_82855GM_HB, "855GM", &intel_845_driver },
726 { PCI_DEVICE_ID_INTEL_82860_HB, "i860", &intel_860_driver },
727 { PCI_DEVICE_ID_INTEL_82865_HB, "865", &intel_845_driver },
728 { PCI_DEVICE_ID_INTEL_82875_HB, "i875", &intel_845_driver },
729 { PCI_DEVICE_ID_INTEL_7505_0, "E7505", &intel_7505_driver },
730 { PCI_DEVICE_ID_INTEL_7205_0, "E7205", &intel_7505_driver },
731 { 0, NULL, NULL }
734 static int __devinit agp_intel_probe(struct pci_dev *pdev,
735 const struct pci_device_id *ent)
737 struct agp_bridge_data *bridge;
738 u8 cap_ptr = 0;
739 struct resource *r;
740 int i, err;
742 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
744 bridge = agp_alloc_bridge();
745 if (!bridge)
746 return -ENOMEM;
748 bridge->capndx = cap_ptr;
750 if (intel_gmch_probe(pdev, bridge))
751 goto found_gmch;
753 for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
754 /* In case that multiple models of gfx chip may
755 stand on same host bridge type, this can be
756 sure we detect the right IGD. */
757 if (pdev->device == intel_agp_chipsets[i].chip_id) {
758 bridge->driver = intel_agp_chipsets[i].driver;
759 break;
763 if (!bridge->driver) {
764 if (cap_ptr)
765 dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n",
766 pdev->vendor, pdev->device);
767 agp_put_bridge(bridge);
768 return -ENODEV;
771 bridge->dev = pdev;
772 bridge->dev_private_data = NULL;
774 dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);
777 * The following fixes the case where the BIOS has "forgotten" to
778 * provide an address range for the GART.
779 * 20030610 - hamish@zot.org
780 * This happens before pci_enable_device() intentionally;
781 * calling pci_enable_device() before assigning the resource
782 * will result in the GART being disabled on machines with such
783 * BIOSs (the GART ends up with a BAR starting at 0, which
784 * conflicts a lot of other devices).
786 r = &pdev->resource[0];
787 if (!r->start && r->end) {
788 if (pci_assign_resource(pdev, 0)) {
789 dev_err(&pdev->dev, "can't assign resource 0\n");
790 agp_put_bridge(bridge);
791 return -ENODEV;
796 * If the device has not been properly setup, the following will catch
797 * the problem and should stop the system from crashing.
798 * 20030610 - hamish@zot.org
800 if (pci_enable_device(pdev)) {
801 dev_err(&pdev->dev, "can't enable PCI device\n");
802 agp_put_bridge(bridge);
803 return -ENODEV;
806 /* Fill in the mode register */
807 if (cap_ptr) {
808 pci_read_config_dword(pdev,
809 bridge->capndx+PCI_AGP_STATUS,
810 &bridge->mode);
813 found_gmch:
814 pci_set_drvdata(pdev, bridge);
815 err = agp_add_bridge(bridge);
816 if (!err)
817 intel_agp_enabled = 1;
818 return err;
821 static void __devexit agp_intel_remove(struct pci_dev *pdev)
823 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
825 agp_remove_bridge(bridge);
827 intel_gmch_remove(pdev);
829 agp_put_bridge(bridge);
832 #ifdef CONFIG_PM
833 static int agp_intel_resume(struct pci_dev *pdev)
835 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
837 bridge->driver->configure();
839 return 0;
841 #endif
843 static struct pci_device_id agp_intel_pci_table[] = {
844 #define ID(x) \
846 .class = (PCI_CLASS_BRIDGE_HOST << 8), \
847 .class_mask = ~0, \
848 .vendor = PCI_VENDOR_ID_INTEL, \
849 .device = x, \
850 .subvendor = PCI_ANY_ID, \
851 .subdevice = PCI_ANY_ID, \
853 ID(PCI_DEVICE_ID_INTEL_82443LX_0),
854 ID(PCI_DEVICE_ID_INTEL_82443BX_0),
855 ID(PCI_DEVICE_ID_INTEL_82443GX_0),
856 ID(PCI_DEVICE_ID_INTEL_82810_MC1),
857 ID(PCI_DEVICE_ID_INTEL_82810_MC3),
858 ID(PCI_DEVICE_ID_INTEL_82810E_MC),
859 ID(PCI_DEVICE_ID_INTEL_82815_MC),
860 ID(PCI_DEVICE_ID_INTEL_82820_HB),
861 ID(PCI_DEVICE_ID_INTEL_82820_UP_HB),
862 ID(PCI_DEVICE_ID_INTEL_82830_HB),
863 ID(PCI_DEVICE_ID_INTEL_82840_HB),
864 ID(PCI_DEVICE_ID_INTEL_82845_HB),
865 ID(PCI_DEVICE_ID_INTEL_82845G_HB),
866 ID(PCI_DEVICE_ID_INTEL_82850_HB),
867 ID(PCI_DEVICE_ID_INTEL_82854_HB),
868 ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
869 ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
870 ID(PCI_DEVICE_ID_INTEL_82860_HB),
871 ID(PCI_DEVICE_ID_INTEL_82865_HB),
872 ID(PCI_DEVICE_ID_INTEL_82875_HB),
873 ID(PCI_DEVICE_ID_INTEL_7505_0),
874 ID(PCI_DEVICE_ID_INTEL_7205_0),
875 ID(PCI_DEVICE_ID_INTEL_E7221_HB),
876 ID(PCI_DEVICE_ID_INTEL_82915G_HB),
877 ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
878 ID(PCI_DEVICE_ID_INTEL_82945G_HB),
879 ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
880 ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
881 ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB),
882 ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB),
883 ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
884 ID(PCI_DEVICE_ID_INTEL_82G35_HB),
885 ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
886 ID(PCI_DEVICE_ID_INTEL_82965G_HB),
887 ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
888 ID(PCI_DEVICE_ID_INTEL_82965GME_HB),
889 ID(PCI_DEVICE_ID_INTEL_G33_HB),
890 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
891 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
892 ID(PCI_DEVICE_ID_INTEL_GM45_HB),
893 ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB),
894 ID(PCI_DEVICE_ID_INTEL_Q45_HB),
895 ID(PCI_DEVICE_ID_INTEL_G45_HB),
896 ID(PCI_DEVICE_ID_INTEL_G41_HB),
897 ID(PCI_DEVICE_ID_INTEL_B43_HB),
898 ID(PCI_DEVICE_ID_INTEL_B43_1_HB),
899 ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
900 ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
901 ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
902 ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
903 ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
904 ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
905 ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB),
906 ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB),
907 ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB),
908 ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB),
912 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
914 static struct pci_driver agp_intel_pci_driver = {
915 .name = "agpgart-intel",
916 .id_table = agp_intel_pci_table,
917 .probe = agp_intel_probe,
918 .remove = __devexit_p(agp_intel_remove),
919 #ifdef CONFIG_PM
920 .resume = agp_intel_resume,
921 #endif
924 static int __init agp_intel_init(void)
926 if (agp_off)
927 return -EINVAL;
928 return pci_register_driver(&agp_intel_pci_driver);
931 static void __exit agp_intel_cleanup(void)
933 pci_unregister_driver(&agp_intel_pci_driver);
936 module_init(agp_intel_init);
937 module_exit(agp_intel_cleanup);
939 MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
940 MODULE_LICENSE("GPL and additional rights");