blob: 4e455f03b4f0bb6426df6aae671c2e676b4beb3a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Intel AGPGART routines.
3 */
4
Linus Torvalds1da177e2005-04-16 15:20:36 -07005#include <linux/module.h>
6#include <linux/pci.h>
7#include <linux/init.h>
8#include <linux/pagemap.h>
9#include <linux/agp_backend.h>
10#include "agp.h"
11
Eric Anholt65c25aa2006-09-06 11:57:18 -040012#define PCI_DEVICE_ID_INTEL_82946GZ_HB 0x2970
13#define PCI_DEVICE_ID_INTEL_82946GZ_IG 0x2972
14#define PCI_DEVICE_ID_INTEL_82965G_1_HB 0x2980
15#define PCI_DEVICE_ID_INTEL_82965G_1_IG 0x2982
16#define PCI_DEVICE_ID_INTEL_82965Q_HB 0x2990
17#define PCI_DEVICE_ID_INTEL_82965Q_IG 0x2992
18#define PCI_DEVICE_ID_INTEL_82965G_HB 0x29A0
19#define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2
20
21#define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
22 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
23 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
24 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB)
25
26
Thomas Hellstroma030ce42007-01-23 10:33:43 +010027extern int agp_memory_reserved;
28
29
Linus Torvalds1da177e2005-04-16 15:20:36 -070030/* Intel 815 register */
31#define INTEL_815_APCONT 0x51
32#define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF
33
34/* Intel i820 registers */
35#define INTEL_I820_RDCR 0x51
36#define INTEL_I820_ERRSTS 0xc8
37
38/* Intel i840 registers */
39#define INTEL_I840_MCHCFG 0x50
40#define INTEL_I840_ERRSTS 0xc8
41
42/* Intel i850 registers */
43#define INTEL_I850_MCHCFG 0x50
44#define INTEL_I850_ERRSTS 0xc8
45
46/* intel 915G registers */
47#define I915_GMADDR 0x18
48#define I915_MMADDR 0x10
49#define I915_PTEADDR 0x1C
50#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4)
51#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4)
52
Eric Anholt65c25aa2006-09-06 11:57:18 -040053/* Intel 965G registers */
54#define I965_MSAC 0x62
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56/* Intel 7505 registers */
57#define INTEL_I7505_APSIZE 0x74
58#define INTEL_I7505_NCAPID 0x60
59#define INTEL_I7505_NISTAT 0x6c
60#define INTEL_I7505_ATTBASE 0x78
61#define INTEL_I7505_ERRSTS 0x42
62#define INTEL_I7505_AGPCTRL 0x70
63#define INTEL_I7505_MCHCFG 0x50
64
65static struct aper_size_info_fixed intel_i810_sizes[] =
66{
67 {64, 16384, 4},
68 /* The 32M mode still requires a 64k gatt */
69 {32, 8192, 4}
70};
71
72#define AGP_DCACHE_MEMORY 1
73#define AGP_PHYS_MEMORY 2
Thomas Hellstroma030ce42007-01-23 10:33:43 +010074#define INTEL_AGP_CACHED_MEMORY 3
Linus Torvalds1da177e2005-04-16 15:20:36 -070075
76static struct gatt_mask intel_i810_masks[] =
77{
78 {.mask = I810_PTE_VALID, .type = 0},
79 {.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY},
Thomas Hellstroma030ce42007-01-23 10:33:43 +010080 {.mask = I810_PTE_VALID, .type = 0},
81 {.mask = I810_PTE_VALID | I830_PTE_SYSTEM_CACHED,
82 .type = INTEL_AGP_CACHED_MEMORY}
Linus Torvalds1da177e2005-04-16 15:20:36 -070083};
84
85static struct _intel_i810_private {
86 struct pci_dev *i810_dev; /* device one */
87 volatile u8 __iomem *registers;
88 int num_dcache_entries;
89} intel_i810_private;
90
Thomas Hellstroma030ce42007-01-23 10:33:43 +010091
Linus Torvalds1da177e2005-04-16 15:20:36 -070092static int intel_i810_fetch_size(void)
93{
94 u32 smram_miscc;
95 struct aper_size_info_fixed *values;
96
97 pci_read_config_dword(agp_bridge->dev, I810_SMRAM_MISCC, &smram_miscc);
98 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
99
100 if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
101 printk(KERN_WARNING PFX "i810 is disabled\n");
102 return 0;
103 }
104 if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
105 agp_bridge->previous_size =
106 agp_bridge->current_size = (void *) (values + 1);
107 agp_bridge->aperture_size_idx = 1;
108 return values[1].size;
109 } else {
110 agp_bridge->previous_size =
111 agp_bridge->current_size = (void *) (values);
112 agp_bridge->aperture_size_idx = 0;
113 return values[0].size;
114 }
115
116 return 0;
117}
118
119static int intel_i810_configure(void)
120{
121 struct aper_size_info_fixed *current_size;
122 u32 temp;
123 int i;
124
125 current_size = A_SIZE_FIX(agp_bridge->current_size);
126
127 pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
128 temp &= 0xfff80000;
129
130 intel_i810_private.registers = ioremap(temp, 128 * 4096);
131 if (!intel_i810_private.registers) {
132 printk(KERN_ERR PFX "Unable to remap memory.\n");
133 return -ENOMEM;
134 }
135
136 if ((readl(intel_i810_private.registers+I810_DRAM_CTL)
137 & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
138 /* This will need to be dynamically assigned */
139 printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
140 intel_i810_private.num_dcache_entries = 1024;
141 }
142 pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
143 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
144 writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_i810_private.registers+I810_PGETBL_CTL);
145 readl(intel_i810_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
146
147 if (agp_bridge->driver->needs_scratch_page) {
148 for (i = 0; i < current_size->num_entries; i++) {
149 writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
150 readl(intel_i810_private.registers+I810_PTE_BASE+(i*4)); /* PCI posting. */
151 }
152 }
153 global_cache_flush();
154 return 0;
155}
156
157static void intel_i810_cleanup(void)
158{
159 writel(0, intel_i810_private.registers+I810_PGETBL_CTL);
160 readl(intel_i810_private.registers); /* PCI Posting. */
161 iounmap(intel_i810_private.registers);
162}
163
164static void intel_i810_tlbflush(struct agp_memory *mem)
165{
166 return;
167}
168
169static void intel_i810_agp_enable(struct agp_bridge_data *bridge, u32 mode)
170{
171 return;
172}
173
174/* Exists to support ARGB cursors */
175static void *i8xx_alloc_pages(void)
176{
177 struct page * page;
178
Linus Torvalds66c669b2006-11-22 14:55:29 -0800179 page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 if (page == NULL)
181 return NULL;
182
183 if (change_page_attr(page, 4, PAGE_KERNEL_NOCACHE) < 0) {
184 global_flush_tlb();
185 __free_page(page);
186 return NULL;
187 }
188 global_flush_tlb();
189 get_page(page);
190 SetPageLocked(page);
191 atomic_inc(&agp_bridge->current_memory_agp);
192 return page_address(page);
193}
194
195static void i8xx_destroy_pages(void *addr)
196{
197 struct page *page;
198
199 if (addr == NULL)
200 return;
201
202 page = virt_to_page(addr);
203 change_page_attr(page, 4, PAGE_KERNEL);
204 global_flush_tlb();
205 put_page(page);
206 unlock_page(page);
207 free_pages((unsigned long)addr, 2);
208 atomic_dec(&agp_bridge->current_memory_agp);
209}
210
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100211static int intel_i830_type_to_mask_type(struct agp_bridge_data *bridge,
212 int type)
213{
214 if (type < AGP_USER_TYPES)
215 return type;
216 else if (type == AGP_USER_CACHED_MEMORY)
217 return INTEL_AGP_CACHED_MEMORY;
218 else
219 return 0;
220}
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
223 int type)
224{
225 int i, j, num_entries;
226 void *temp;
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100227 int ret = -EINVAL;
228 int mask_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100230 if (mem->page_count == 0)
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100231 goto out;
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100232
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 temp = agp_bridge->current_size;
234 num_entries = A_SIZE_FIX(temp)->num_entries;
235
Dave Jones6a92a4e2006-02-28 00:54:25 -0500236 if ((pg_start + mem->page_count) > num_entries)
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100237 goto out_err;
238
Dave Jones6a92a4e2006-02-28 00:54:25 -0500239
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 for (j = pg_start; j < (pg_start + mem->page_count); j++) {
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100241 if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+j))) {
242 ret = -EBUSY;
243 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 }
246
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100247 if (type != mem->type)
248 goto out_err;
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100249
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100250 mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
251
252 switch (mask_type) {
253 case AGP_DCACHE_MEMORY:
254 if (!mem->is_flushed)
255 global_cache_flush();
256 for (i = pg_start; i < (pg_start + mem->page_count); i++) {
257 writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID,
258 intel_i810_private.registers+I810_PTE_BASE+(i*4));
259 }
260 readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
261 break;
262 case AGP_PHYS_MEMORY:
263 case AGP_NORMAL_MEMORY:
264 if (!mem->is_flushed)
265 global_cache_flush();
266 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
267 writel(agp_bridge->driver->mask_memory(agp_bridge,
268 mem->memory[i],
269 mask_type),
270 intel_i810_private.registers+I810_PTE_BASE+(j*4));
271 }
272 readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4));
273 break;
274 default:
275 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
278 agp_bridge->driver->tlb_flush(mem);
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100279out:
280 ret = 0;
281out_err:
282 mem->is_flushed = 1;
283 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284}
285
286static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
287 int type)
288{
289 int i;
290
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100291 if (mem->page_count == 0)
292 return 0;
293
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
295 writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 }
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100297 readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 agp_bridge->driver->tlb_flush(mem);
300 return 0;
301}
302
303/*
304 * The i810/i830 requires a physical address to program its mouse
305 * pointer into hardware.
306 * However the Xserver still writes to it through the agp aperture.
307 */
308static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
309{
310 struct agp_memory *new;
311 void *addr;
312
313 if (pg_count != 1 && pg_count != 4)
314 return NULL;
315
316 switch (pg_count) {
317 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge);
Alan Hourihane88d51962005-11-06 23:35:34 -0800318 global_flush_tlb();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 break;
320 case 4:
321 /* kludge to get 4 physical pages for ARGB cursor */
322 addr = i8xx_alloc_pages();
323 break;
324 default:
325 return NULL;
326 }
327
328 if (addr == NULL)
329 return NULL;
330
331 new = agp_create_memory(pg_count);
332 if (new == NULL)
333 return NULL;
334
Keir Fraser07eee782005-03-30 13:17:04 -0800335 new->memory[0] = virt_to_gart(addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 if (pg_count == 4) {
337 /* kludge to get 4 physical pages for ARGB cursor */
338 new->memory[1] = new->memory[0] + PAGE_SIZE;
339 new->memory[2] = new->memory[1] + PAGE_SIZE;
340 new->memory[3] = new->memory[2] + PAGE_SIZE;
341 }
342 new->page_count = pg_count;
343 new->num_scratch_pages = pg_count;
344 new->type = AGP_PHYS_MEMORY;
345 new->physical = new->memory[0];
346 return new;
347}
348
349static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
350{
351 struct agp_memory *new;
352
353 if (type == AGP_DCACHE_MEMORY) {
354 if (pg_count != intel_i810_private.num_dcache_entries)
355 return NULL;
356
357 new = agp_create_memory(1);
358 if (new == NULL)
359 return NULL;
360
361 new->type = AGP_DCACHE_MEMORY;
362 new->page_count = pg_count;
363 new->num_scratch_pages = 0;
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100364 agp_free_page_array(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 return new;
366 }
367 if (type == AGP_PHYS_MEMORY)
368 return alloc_agpphysmem_i8xx(pg_count, type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 return NULL;
370}
371
372static void intel_i810_free_by_type(struct agp_memory *curr)
373{
374 agp_free_key(curr->key);
Dave Jones6a92a4e2006-02-28 00:54:25 -0500375 if (curr->type == AGP_PHYS_MEMORY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 if (curr->page_count == 4)
Keir Fraser07eee782005-03-30 13:17:04 -0800377 i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
Alan Hourihane88d51962005-11-06 23:35:34 -0800378 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 agp_bridge->driver->agp_destroy_page(
Keir Fraser07eee782005-03-30 13:17:04 -0800380 gart_to_virt(curr->memory[0]));
Alan Hourihane88d51962005-11-06 23:35:34 -0800381 global_flush_tlb();
382 }
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100383 agp_free_page_array(curr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 }
385 kfree(curr);
386}
387
388static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge,
389 unsigned long addr, int type)
390{
391 /* Type checking must be done elsewhere */
392 return addr | bridge->driver->masks[type].mask;
393}
394
395static struct aper_size_info_fixed intel_i830_sizes[] =
396{
397 {128, 32768, 5},
398 /* The 64M mode still requires a 128k gatt */
399 {64, 16384, 5},
400 {256, 65536, 6},
Eric Anholt65c25aa2006-09-06 11:57:18 -0400401 {512, 131072, 7},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402};
403
404static struct _intel_i830_private {
405 struct pci_dev *i830_dev; /* device one */
406 volatile u8 __iomem *registers;
407 volatile u32 __iomem *gtt; /* I915G */
Eric Anholtc41e0de2006-12-19 12:57:24 -0800408 /* gtt_entries is the number of gtt entries that are already mapped
409 * to stolen memory. Stolen memory is larger than the memory mapped
410 * through gtt_entries, as it includes some reserved space for the BIOS
411 * popup and for the GTT.
412 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 int gtt_entries;
414} intel_i830_private;
415
416static void intel_i830_init_gtt_entries(void)
417{
418 u16 gmch_ctrl;
419 int gtt_entries;
420 u8 rdct;
421 int local = 0;
422 static const int ddt[4] = { 0, 16, 32, 64 };
Eric Anholtc41e0de2006-12-19 12:57:24 -0800423 int size; /* reserved space (in kb) at the top of stolen memory */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
425 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
426
Eric Anholtc41e0de2006-12-19 12:57:24 -0800427 if (IS_I965) {
428 u32 pgetbl_ctl;
429
430 pci_read_config_dword(agp_bridge->dev, I810_PGETBL_CTL,
431 &pgetbl_ctl);
432 /* The 965 has a field telling us the size of the GTT,
433 * which may be larger than what is necessary to map the
434 * aperture.
435 */
436 switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {
437 case I965_PGETBL_SIZE_128KB:
438 size = 128;
439 break;
440 case I965_PGETBL_SIZE_256KB:
441 size = 256;
442 break;
443 case I965_PGETBL_SIZE_512KB:
444 size = 512;
445 break;
446 default:
447 printk(KERN_INFO PFX "Unknown page table size, "
448 "assuming 512KB\n");
449 size = 512;
450 }
451 size += 4; /* add in BIOS popup space */
452 } else {
453 /* On previous hardware, the GTT size was just what was
454 * required to map the aperture.
455 */
456 size = agp_bridge->driver->fetch_size() + 4;
457 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
459 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
460 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
461 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
462 case I830_GMCH_GMS_STOLEN_512:
463 gtt_entries = KB(512) - KB(size);
464 break;
465 case I830_GMCH_GMS_STOLEN_1024:
466 gtt_entries = MB(1) - KB(size);
467 break;
468 case I830_GMCH_GMS_STOLEN_8192:
469 gtt_entries = MB(8) - KB(size);
470 break;
471 case I830_GMCH_GMS_LOCAL:
472 rdct = readb(intel_i830_private.registers+I830_RDRAM_CHANNEL_TYPE);
473 gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
474 MB(ddt[I830_RDRAM_DDT(rdct)]);
475 local = 1;
476 break;
477 default:
478 gtt_entries = 0;
479 break;
480 }
481 } else {
482 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
483 case I855_GMCH_GMS_STOLEN_1M:
484 gtt_entries = MB(1) - KB(size);
485 break;
486 case I855_GMCH_GMS_STOLEN_4M:
487 gtt_entries = MB(4) - KB(size);
488 break;
489 case I855_GMCH_GMS_STOLEN_8M:
490 gtt_entries = MB(8) - KB(size);
491 break;
492 case I855_GMCH_GMS_STOLEN_16M:
493 gtt_entries = MB(16) - KB(size);
494 break;
495 case I855_GMCH_GMS_STOLEN_32M:
496 gtt_entries = MB(32) - KB(size);
497 break;
498 case I915_GMCH_GMS_STOLEN_48M:
499 /* Check it's really I915G */
500 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
Alan Hourihaned0de98f2005-05-31 19:50:49 +0100501 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +0000502 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
Eric Anholt65c25aa2006-09-06 11:57:18 -0400503 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965 )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 gtt_entries = MB(48) - KB(size);
505 else
506 gtt_entries = 0;
507 break;
508 case I915_GMCH_GMS_STOLEN_64M:
509 /* Check it's really I915G */
510 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
Alan Hourihaned0de98f2005-05-31 19:50:49 +0100511 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +0000512 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
Eric Anholt65c25aa2006-09-06 11:57:18 -0400513 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 gtt_entries = MB(64) - KB(size);
515 else
516 gtt_entries = 0;
517 default:
518 gtt_entries = 0;
519 break;
520 }
521 }
522 if (gtt_entries > 0)
523 printk(KERN_INFO PFX "Detected %dK %s memory.\n",
524 gtt_entries / KB(1), local ? "local" : "stolen");
525 else
526 printk(KERN_INFO PFX
527 "No pre-allocated video memory detected.\n");
528 gtt_entries /= KB(4);
529
530 intel_i830_private.gtt_entries = gtt_entries;
531}
532
533/* The intel i830 automatically initializes the agp aperture during POST.
534 * Use the memory already set aside for in the GTT.
535 */
536static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
537{
538 int page_order;
539 struct aper_size_info_fixed *size;
540 int num_entries;
541 u32 temp;
542
543 size = agp_bridge->current_size;
544 page_order = size->page_order;
545 num_entries = size->num_entries;
546 agp_bridge->gatt_table_real = NULL;
547
548 pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
549 temp &= 0xfff80000;
550
551 intel_i830_private.registers = ioremap(temp,128 * 4096);
552 if (!intel_i830_private.registers)
553 return -ENOMEM;
554
555 temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
556 global_cache_flush(); /* FIXME: ?? */
557
558 /* we have to call this as early as possible after the MMIO base address is known */
559 intel_i830_init_gtt_entries();
560
561 agp_bridge->gatt_table = NULL;
562
563 agp_bridge->gatt_bus_addr = temp;
564
565 return 0;
566}
567
568/* Return the gatt table to a sane state. Use the top of stolen
569 * memory for the GTT.
570 */
571static int intel_i830_free_gatt_table(struct agp_bridge_data *bridge)
572{
573 return 0;
574}
575
576static int intel_i830_fetch_size(void)
577{
578 u16 gmch_ctrl;
579 struct aper_size_info_fixed *values;
580
581 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
582
583 if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB &&
584 agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) {
585 /* 855GM/852GM/865G has 128MB aperture size */
586 agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
587 agp_bridge->aperture_size_idx = 0;
588 return values[0].size;
589 }
590
591 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
592
593 if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
594 agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
595 agp_bridge->aperture_size_idx = 0;
596 return values[0].size;
597 } else {
598 agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + 1);
599 agp_bridge->aperture_size_idx = 1;
600 return values[1].size;
601 }
602
603 return 0;
604}
605
606static int intel_i830_configure(void)
607{
608 struct aper_size_info_fixed *current_size;
609 u32 temp;
610 u16 gmch_ctrl;
611 int i;
612
613 current_size = A_SIZE_FIX(agp_bridge->current_size);
614
615 pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
616 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
617
618 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
619 gmch_ctrl |= I830_GMCH_ENABLED;
620 pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
621
622 writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
623 readl(intel_i830_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
624
625 if (agp_bridge->driver->needs_scratch_page) {
626 for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
627 writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
628 readl(intel_i830_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
629 }
630 }
631
632 global_cache_flush();
633 return 0;
634}
635
636static void intel_i830_cleanup(void)
637{
638 iounmap(intel_i830_private.registers);
639}
640
641static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type)
642{
643 int i,j,num_entries;
644 void *temp;
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100645 int ret = -EINVAL;
646 int mask_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100648 if (mem->page_count == 0)
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100649 goto out;
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 temp = agp_bridge->current_size;
652 num_entries = A_SIZE_FIX(temp)->num_entries;
653
654 if (pg_start < intel_i830_private.gtt_entries) {
655 printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
656 pg_start,intel_i830_private.gtt_entries);
657
658 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100659 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 }
661
662 if ((pg_start + mem->page_count) > num_entries)
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100663 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664
665 /* The i830 can't check the GTT for entries since its read only,
666 * depend on the caller to make the correct offset decisions.
667 */
668
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100669 if (type != mem->type)
670 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100672 mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
673
674 if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
675 mask_type != INTEL_AGP_CACHED_MEMORY)
676 goto out_err;
677
678 if (!mem->is_flushed)
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100679 global_cache_flush();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680
681 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
682 writel(agp_bridge->driver->mask_memory(agp_bridge,
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100683 mem->memory[i], mask_type),
684 intel_i830_private.registers+I810_PTE_BASE+(j*4));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 }
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100686 readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 agp_bridge->driver->tlb_flush(mem);
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100688
689out:
690 ret = 0;
691out_err:
692 mem->is_flushed = 1;
693 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694}
695
696static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
697 int type)
698{
699 int i;
700
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100701 if (mem->page_count == 0)
702 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703
704 if (pg_start < intel_i830_private.gtt_entries) {
705 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
706 return -EINVAL;
707 }
708
709 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
710 writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 }
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100712 readl(intel_i830_private.registers+I810_PTE_BASE+((i-1)*4));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 agp_bridge->driver->tlb_flush(mem);
715 return 0;
716}
717
718static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
719{
720 if (type == AGP_PHYS_MEMORY)
721 return alloc_agpphysmem_i8xx(pg_count, type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 /* always return NULL for other allocation types for now */
723 return NULL;
724}
725
726static int intel_i915_configure(void)
727{
728 struct aper_size_info_fixed *current_size;
729 u32 temp;
730 u16 gmch_ctrl;
731 int i;
732
733 current_size = A_SIZE_FIX(agp_bridge->current_size);
734
735 pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp);
736
737 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
738
739 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
740 gmch_ctrl |= I830_GMCH_ENABLED;
741 pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
742
743 writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
744 readl(intel_i830_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
745
746 if (agp_bridge->driver->needs_scratch_page) {
747 for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
748 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
749 readl(intel_i830_private.gtt+i); /* PCI Posting. */
750 }
751 }
752
753 global_cache_flush();
754 return 0;
755}
756
757static void intel_i915_cleanup(void)
758{
759 iounmap(intel_i830_private.gtt);
760 iounmap(intel_i830_private.registers);
761}
762
763static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
764 int type)
765{
766 int i,j,num_entries;
767 void *temp;
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100768 int ret = -EINVAL;
769 int mask_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100771 if (mem->page_count == 0)
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100772 goto out;
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100773
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 temp = agp_bridge->current_size;
775 num_entries = A_SIZE_FIX(temp)->num_entries;
776
777 if (pg_start < intel_i830_private.gtt_entries) {
778 printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
779 pg_start,intel_i830_private.gtt_entries);
780
781 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100782 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 }
784
785 if ((pg_start + mem->page_count) > num_entries)
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100786 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100788 /* The i915 can't check the GTT for entries since its read only,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 * depend on the caller to make the correct offset decisions.
790 */
791
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100792 if (type != mem->type)
793 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100795 mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
796
797 if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
798 mask_type != INTEL_AGP_CACHED_MEMORY)
799 goto out_err;
800
801 if (!mem->is_flushed)
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100802 global_cache_flush();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803
804 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
805 writel(agp_bridge->driver->mask_memory(agp_bridge,
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100806 mem->memory[i], mask_type), intel_i830_private.gtt+j);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 }
808
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100809 readl(intel_i830_private.gtt+j-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 agp_bridge->driver->tlb_flush(mem);
Thomas Hellstroma030ce42007-01-23 10:33:43 +0100811
812 out:
813 ret = 0;
814 out_err:
815 mem->is_flushed = 1;
816 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817}
818
819static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
820 int type)
821{
822 int i;
823
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100824 if (mem->page_count == 0)
825 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826
827 if (pg_start < intel_i830_private.gtt_entries) {
828 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
829 return -EINVAL;
830 }
831
832 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
833 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 }
Thomas Hellstrom5aa80c72006-12-20 16:33:41 +0100835 readl(intel_i830_private.gtt+i-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 agp_bridge->driver->tlb_flush(mem);
838 return 0;
839}
840
Eric Anholtc41e0de2006-12-19 12:57:24 -0800841/* Return the aperture size by just checking the resource length. The effect
842 * described in the spec of the MSAC registers is just changing of the
843 * resource size.
844 */
845static int intel_i9xx_fetch_size(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846{
Eric Anholtc41e0de2006-12-19 12:57:24 -0800847 int num_sizes = sizeof(intel_i830_sizes) / sizeof(*intel_i830_sizes);
848 int aper_size; /* size in megabytes */
849 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850
Eric Anholtc41e0de2006-12-19 12:57:24 -0800851 aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852
Eric Anholtc41e0de2006-12-19 12:57:24 -0800853 for (i = 0; i < num_sizes; i++) {
854 if (aper_size == intel_i830_sizes[i].size) {
855 agp_bridge->current_size = intel_i830_sizes + i;
856 agp_bridge->previous_size = agp_bridge->current_size;
857 return aper_size;
858 }
859 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860
Eric Anholtc41e0de2006-12-19 12:57:24 -0800861 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862}
863
864/* The intel i915 automatically initializes the agp aperture during POST.
865 * Use the memory already set aside for in the GTT.
866 */
867static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
868{
869 int page_order;
870 struct aper_size_info_fixed *size;
871 int num_entries;
872 u32 temp, temp2;
873
874 size = agp_bridge->current_size;
875 page_order = size->page_order;
876 num_entries = size->num_entries;
877 agp_bridge->gatt_table_real = NULL;
878
879 pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
880 pci_read_config_dword(intel_i830_private.i830_dev, I915_PTEADDR,&temp2);
881
882 intel_i830_private.gtt = ioremap(temp2, 256 * 1024);
883 if (!intel_i830_private.gtt)
884 return -ENOMEM;
885
886 temp &= 0xfff80000;
887
888 intel_i830_private.registers = ioremap(temp,128 * 4096);
889 if (!intel_i830_private.registers)
890 return -ENOMEM;
891
892 temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
893 global_cache_flush(); /* FIXME: ? */
894
895 /* we have to call this as early as possible after the MMIO base address is known */
896 intel_i830_init_gtt_entries();
897
898 agp_bridge->gatt_table = NULL;
899
900 agp_bridge->gatt_bus_addr = temp;
901
902 return 0;
903}
Linus Torvalds7d915a32006-11-22 09:37:54 -0800904
905/*
906 * The i965 supports 36-bit physical addresses, but to keep
907 * the format of the GTT the same, the bits that don't fit
908 * in a 32-bit word are shifted down to bits 4..7.
909 *
910 * Gcc is smart enough to notice that "(addr >> 28) & 0xf0"
911 * is always zero on 32-bit architectures, so no need to make
912 * this conditional.
913 */
914static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
915 unsigned long addr, int type)
916{
917 /* Shift high bits down */
918 addr |= (addr >> 28) & 0xf0;
919
920 /* Type checking must be done elsewhere */
921 return addr | bridge->driver->masks[type].mask;
922}
923
Eric Anholt65c25aa2006-09-06 11:57:18 -0400924/* The intel i965 automatically initializes the agp aperture during POST.
Eric Anholtc41e0de2006-12-19 12:57:24 -0800925 * Use the memory already set aside for in the GTT.
926 */
Eric Anholt65c25aa2006-09-06 11:57:18 -0400927static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
928{
929 int page_order;
930 struct aper_size_info_fixed *size;
931 int num_entries;
932 u32 temp;
933
934 size = agp_bridge->current_size;
935 page_order = size->page_order;
936 num_entries = size->num_entries;
937 agp_bridge->gatt_table_real = NULL;
938
939 pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
940
941 temp &= 0xfff00000;
942 intel_i830_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
943
944 if (!intel_i830_private.gtt)
945 return -ENOMEM;
946
947
948 intel_i830_private.registers = ioremap(temp,128 * 4096);
949 if (!intel_i830_private.registers)
950 return -ENOMEM;
951
952 temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
953 global_cache_flush(); /* FIXME: ? */
954
955 /* we have to call this as early as possible after the MMIO base address is known */
956 intel_i830_init_gtt_entries();
957
958 agp_bridge->gatt_table = NULL;
959
960 agp_bridge->gatt_bus_addr = temp;
961
962 return 0;
963}
964
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965
966static int intel_fetch_size(void)
967{
968 int i;
969 u16 temp;
970 struct aper_size_info_16 *values;
971
972 pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
973 values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
974
975 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
976 if (temp == values[i].size_value) {
977 agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
978 agp_bridge->aperture_size_idx = i;
979 return values[i].size;
980 }
981 }
982
983 return 0;
984}
985
986static int __intel_8xx_fetch_size(u8 temp)
987{
988 int i;
989 struct aper_size_info_8 *values;
990
991 values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
992
993 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
994 if (temp == values[i].size_value) {
995 agp_bridge->previous_size =
996 agp_bridge->current_size = (void *) (values + i);
997 agp_bridge->aperture_size_idx = i;
998 return values[i].size;
999 }
1000 }
1001 return 0;
1002}
1003
1004static int intel_8xx_fetch_size(void)
1005{
1006 u8 temp;
1007
1008 pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
1009 return __intel_8xx_fetch_size(temp);
1010}
1011
1012static int intel_815_fetch_size(void)
1013{
1014 u8 temp;
1015
1016 /* Intel 815 chipsets have a _weird_ APSIZE register with only
1017 * one non-reserved bit, so mask the others out ... */
1018 pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
1019 temp &= (1 << 3);
1020
1021 return __intel_8xx_fetch_size(temp);
1022}
1023
1024static void intel_tlbflush(struct agp_memory *mem)
1025{
1026 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
1027 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
1028}
1029
1030
1031static void intel_8xx_tlbflush(struct agp_memory *mem)
1032{
1033 u32 temp;
1034 pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
1035 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));
1036 pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
1037 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
1038}
1039
1040
1041static void intel_cleanup(void)
1042{
1043 u16 temp;
1044 struct aper_size_info_16 *previous_size;
1045
1046 previous_size = A_SIZE_16(agp_bridge->previous_size);
1047 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
1048 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
1049 pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
1050}
1051
1052
1053static void intel_8xx_cleanup(void)
1054{
1055 u16 temp;
1056 struct aper_size_info_8 *previous_size;
1057
1058 previous_size = A_SIZE_8(agp_bridge->previous_size);
1059 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
1060 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
1061 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
1062}
1063
1064
1065static int intel_configure(void)
1066{
1067 u32 temp;
1068 u16 temp2;
1069 struct aper_size_info_16 *current_size;
1070
1071 current_size = A_SIZE_16(agp_bridge->current_size);
1072
1073 /* aperture size */
1074 pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1075
1076 /* address to map to */
1077 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1078 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1079
1080 /* attbase - aperture base */
1081 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1082
1083 /* agpctrl */
1084 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
1085
1086 /* paccfg/nbxcfg */
1087 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
1088 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,
1089 (temp2 & ~(1 << 10)) | (1 << 9));
1090 /* clear any possible error conditions */
1091 pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);
1092 return 0;
1093}
1094
1095static int intel_815_configure(void)
1096{
1097 u32 temp, addr;
1098 u8 temp2;
1099 struct aper_size_info_8 *current_size;
1100
1101 /* attbase - aperture base */
1102 /* the Intel 815 chipset spec. says that bits 29-31 in the
1103 * ATTBASE register are reserved -> try not to write them */
1104 if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {
1105 printk (KERN_EMERG PFX "gatt bus addr too high");
1106 return -EINVAL;
1107 }
1108
1109 current_size = A_SIZE_8(agp_bridge->current_size);
1110
1111 /* aperture size */
1112 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
1113 current_size->size_value);
1114
1115 /* address to map to */
1116 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1117 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1118
1119 pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr);
1120 addr &= INTEL_815_ATTBASE_MASK;
1121 addr |= agp_bridge->gatt_bus_addr;
1122 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, addr);
1123
1124 /* agpctrl */
1125 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1126
1127 /* apcont */
1128 pci_read_config_byte(agp_bridge->dev, INTEL_815_APCONT, &temp2);
1129 pci_write_config_byte(agp_bridge->dev, INTEL_815_APCONT, temp2 | (1 << 1));
1130
1131 /* clear any possible error conditions */
1132 /* Oddness : this chipset seems to have no ERRSTS register ! */
1133 return 0;
1134}
1135
1136static void intel_820_tlbflush(struct agp_memory *mem)
1137{
1138 return;
1139}
1140
1141static void intel_820_cleanup(void)
1142{
1143 u8 temp;
1144 struct aper_size_info_8 *previous_size;
1145
1146 previous_size = A_SIZE_8(agp_bridge->previous_size);
1147 pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp);
1148 pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR,
1149 temp & ~(1 << 1));
1150 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
1151 previous_size->size_value);
1152}
1153
1154
1155static int intel_820_configure(void)
1156{
1157 u32 temp;
1158 u8 temp2;
1159 struct aper_size_info_8 *current_size;
1160
1161 current_size = A_SIZE_8(agp_bridge->current_size);
1162
1163 /* aperture size */
1164 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1165
1166 /* address to map to */
1167 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1168 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1169
1170 /* attbase - aperture base */
1171 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1172
1173 /* agpctrl */
1174 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1175
1176 /* global enable aperture access */
1177 /* This flag is not accessed through MCHCFG register as in */
1178 /* i850 chipset. */
1179 pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp2);
1180 pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp2 | (1 << 1));
1181 /* clear any possible AGP-related error conditions */
1182 pci_write_config_word(agp_bridge->dev, INTEL_I820_ERRSTS, 0x001c);
1183 return 0;
1184}
1185
1186static int intel_840_configure(void)
1187{
1188 u32 temp;
1189 u16 temp2;
1190 struct aper_size_info_8 *current_size;
1191
1192 current_size = A_SIZE_8(agp_bridge->current_size);
1193
1194 /* aperture size */
1195 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1196
1197 /* address to map to */
1198 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1199 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1200
1201 /* attbase - aperture base */
1202 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1203
1204 /* agpctrl */
1205 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1206
1207 /* mcgcfg */
1208 pci_read_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, &temp2);
1209 pci_write_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));
1210 /* clear any possible error conditions */
1211 pci_write_config_word(agp_bridge->dev, INTEL_I840_ERRSTS, 0xc000);
1212 return 0;
1213}
1214
1215static int intel_845_configure(void)
1216{
1217 u32 temp;
1218 u8 temp2;
1219 struct aper_size_info_8 *current_size;
1220
1221 current_size = A_SIZE_8(agp_bridge->current_size);
1222
1223 /* aperture size */
1224 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1225
Matthew Garrettb0825482005-07-29 14:03:39 -07001226 if (agp_bridge->apbase_config != 0) {
1227 pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
1228 agp_bridge->apbase_config);
1229 } else {
1230 /* address to map to */
1231 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1232 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1233 agp_bridge->apbase_config = temp;
1234 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
1236 /* attbase - aperture base */
1237 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1238
1239 /* agpctrl */
1240 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1241
1242 /* agpm */
1243 pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
1244 pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
1245 /* clear any possible error conditions */
1246 pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
1247 return 0;
1248}
1249
1250static int intel_850_configure(void)
1251{
1252 u32 temp;
1253 u16 temp2;
1254 struct aper_size_info_8 *current_size;
1255
1256 current_size = A_SIZE_8(agp_bridge->current_size);
1257
1258 /* aperture size */
1259 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1260
1261 /* address to map to */
1262 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1263 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1264
1265 /* attbase - aperture base */
1266 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1267
1268 /* agpctrl */
1269 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1270
1271 /* mcgcfg */
1272 pci_read_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, &temp2);
1273 pci_write_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));
1274 /* clear any possible AGP-related error conditions */
1275 pci_write_config_word(agp_bridge->dev, INTEL_I850_ERRSTS, 0x001c);
1276 return 0;
1277}
1278
1279static int intel_860_configure(void)
1280{
1281 u32 temp;
1282 u16 temp2;
1283 struct aper_size_info_8 *current_size;
1284
1285 current_size = A_SIZE_8(agp_bridge->current_size);
1286
1287 /* aperture size */
1288 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1289
1290 /* address to map to */
1291 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1292 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1293
1294 /* attbase - aperture base */
1295 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1296
1297 /* agpctrl */
1298 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1299
1300 /* mcgcfg */
1301 pci_read_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, &temp2);
1302 pci_write_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));
1303 /* clear any possible AGP-related error conditions */
1304 pci_write_config_word(agp_bridge->dev, INTEL_I860_ERRSTS, 0xf700);
1305 return 0;
1306}
1307
1308static int intel_830mp_configure(void)
1309{
1310 u32 temp;
1311 u16 temp2;
1312 struct aper_size_info_8 *current_size;
1313
1314 current_size = A_SIZE_8(agp_bridge->current_size);
1315
1316 /* aperture size */
1317 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1318
1319 /* address to map to */
1320 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1321 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1322
1323 /* attbase - aperture base */
1324 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1325
1326 /* agpctrl */
1327 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1328
1329 /* gmch */
1330 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
1331 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp2 | (1 << 9));
1332 /* clear any possible AGP-related error conditions */
1333 pci_write_config_word(agp_bridge->dev, INTEL_I830_ERRSTS, 0x1c);
1334 return 0;
1335}
1336
1337static int intel_7505_configure(void)
1338{
1339 u32 temp;
1340 u16 temp2;
1341 struct aper_size_info_8 *current_size;
1342
1343 current_size = A_SIZE_8(agp_bridge->current_size);
1344
1345 /* aperture size */
1346 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1347
1348 /* address to map to */
1349 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1350 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1351
1352 /* attbase - aperture base */
1353 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1354
1355 /* agpctrl */
1356 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1357
1358 /* mchcfg */
1359 pci_read_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, &temp2);
1360 pci_write_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, temp2 | (1 << 9));
1361
1362 return 0;
1363}
1364
1365/* Setup function */
1366static struct gatt_mask intel_generic_masks[] =
1367{
1368 {.mask = 0x00000017, .type = 0}
1369};
1370
1371static struct aper_size_info_8 intel_815_sizes[2] =
1372{
1373 {64, 16384, 4, 0},
1374 {32, 8192, 3, 8},
1375};
1376
1377static struct aper_size_info_8 intel_8xx_sizes[7] =
1378{
1379 {256, 65536, 6, 0},
1380 {128, 32768, 5, 32},
1381 {64, 16384, 4, 48},
1382 {32, 8192, 3, 56},
1383 {16, 4096, 2, 60},
1384 {8, 2048, 1, 62},
1385 {4, 1024, 0, 63}
1386};
1387
1388static struct aper_size_info_16 intel_generic_sizes[7] =
1389{
1390 {256, 65536, 6, 0},
1391 {128, 32768, 5, 32},
1392 {64, 16384, 4, 48},
1393 {32, 8192, 3, 56},
1394 {16, 4096, 2, 60},
1395 {8, 2048, 1, 62},
1396 {4, 1024, 0, 63}
1397};
1398
1399static struct aper_size_info_8 intel_830mp_sizes[4] =
1400{
1401 {256, 65536, 6, 0},
1402 {128, 32768, 5, 32},
1403 {64, 16384, 4, 48},
1404 {32, 8192, 3, 56}
1405};
1406
1407static struct agp_bridge_driver intel_generic_driver = {
1408 .owner = THIS_MODULE,
1409 .aperture_sizes = intel_generic_sizes,
1410 .size_type = U16_APER_SIZE,
1411 .num_aperture_sizes = 7,
1412 .configure = intel_configure,
1413 .fetch_size = intel_fetch_size,
1414 .cleanup = intel_cleanup,
1415 .tlb_flush = intel_tlbflush,
1416 .mask_memory = agp_generic_mask_memory,
1417 .masks = intel_generic_masks,
1418 .agp_enable = agp_generic_enable,
1419 .cache_flush = global_cache_flush,
1420 .create_gatt_table = agp_generic_create_gatt_table,
1421 .free_gatt_table = agp_generic_free_gatt_table,
1422 .insert_memory = agp_generic_insert_memory,
1423 .remove_memory = agp_generic_remove_memory,
1424 .alloc_by_type = agp_generic_alloc_by_type,
1425 .free_by_type = agp_generic_free_by_type,
1426 .agp_alloc_page = agp_generic_alloc_page,
1427 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001428 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429};
1430
1431static struct agp_bridge_driver intel_810_driver = {
1432 .owner = THIS_MODULE,
1433 .aperture_sizes = intel_i810_sizes,
1434 .size_type = FIXED_APER_SIZE,
1435 .num_aperture_sizes = 2,
1436 .needs_scratch_page = TRUE,
1437 .configure = intel_i810_configure,
1438 .fetch_size = intel_i810_fetch_size,
1439 .cleanup = intel_i810_cleanup,
1440 .tlb_flush = intel_i810_tlbflush,
1441 .mask_memory = intel_i810_mask_memory,
1442 .masks = intel_i810_masks,
1443 .agp_enable = intel_i810_agp_enable,
1444 .cache_flush = global_cache_flush,
1445 .create_gatt_table = agp_generic_create_gatt_table,
1446 .free_gatt_table = agp_generic_free_gatt_table,
1447 .insert_memory = intel_i810_insert_entries,
1448 .remove_memory = intel_i810_remove_entries,
1449 .alloc_by_type = intel_i810_alloc_by_type,
1450 .free_by_type = intel_i810_free_by_type,
1451 .agp_alloc_page = agp_generic_alloc_page,
1452 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001453 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454};
1455
1456static struct agp_bridge_driver intel_815_driver = {
1457 .owner = THIS_MODULE,
1458 .aperture_sizes = intel_815_sizes,
1459 .size_type = U8_APER_SIZE,
1460 .num_aperture_sizes = 2,
1461 .configure = intel_815_configure,
1462 .fetch_size = intel_815_fetch_size,
1463 .cleanup = intel_8xx_cleanup,
1464 .tlb_flush = intel_8xx_tlbflush,
1465 .mask_memory = agp_generic_mask_memory,
1466 .masks = intel_generic_masks,
1467 .agp_enable = agp_generic_enable,
1468 .cache_flush = global_cache_flush,
1469 .create_gatt_table = agp_generic_create_gatt_table,
1470 .free_gatt_table = agp_generic_free_gatt_table,
1471 .insert_memory = agp_generic_insert_memory,
1472 .remove_memory = agp_generic_remove_memory,
1473 .alloc_by_type = agp_generic_alloc_by_type,
1474 .free_by_type = agp_generic_free_by_type,
1475 .agp_alloc_page = agp_generic_alloc_page,
1476 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001477 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478};
1479
1480static struct agp_bridge_driver intel_830_driver = {
1481 .owner = THIS_MODULE,
1482 .aperture_sizes = intel_i830_sizes,
1483 .size_type = FIXED_APER_SIZE,
Dave Jonesc14635e2006-09-06 11:59:35 -04001484 .num_aperture_sizes = 4,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 .needs_scratch_page = TRUE,
1486 .configure = intel_i830_configure,
1487 .fetch_size = intel_i830_fetch_size,
1488 .cleanup = intel_i830_cleanup,
1489 .tlb_flush = intel_i810_tlbflush,
1490 .mask_memory = intel_i810_mask_memory,
1491 .masks = intel_i810_masks,
1492 .agp_enable = intel_i810_agp_enable,
1493 .cache_flush = global_cache_flush,
1494 .create_gatt_table = intel_i830_create_gatt_table,
1495 .free_gatt_table = intel_i830_free_gatt_table,
1496 .insert_memory = intel_i830_insert_entries,
1497 .remove_memory = intel_i830_remove_entries,
1498 .alloc_by_type = intel_i830_alloc_by_type,
1499 .free_by_type = intel_i810_free_by_type,
1500 .agp_alloc_page = agp_generic_alloc_page,
1501 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001502 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503};
1504
1505static struct agp_bridge_driver intel_820_driver = {
1506 .owner = THIS_MODULE,
1507 .aperture_sizes = intel_8xx_sizes,
1508 .size_type = U8_APER_SIZE,
1509 .num_aperture_sizes = 7,
1510 .configure = intel_820_configure,
1511 .fetch_size = intel_8xx_fetch_size,
1512 .cleanup = intel_820_cleanup,
1513 .tlb_flush = intel_820_tlbflush,
1514 .mask_memory = agp_generic_mask_memory,
1515 .masks = intel_generic_masks,
1516 .agp_enable = agp_generic_enable,
1517 .cache_flush = global_cache_flush,
1518 .create_gatt_table = agp_generic_create_gatt_table,
1519 .free_gatt_table = agp_generic_free_gatt_table,
1520 .insert_memory = agp_generic_insert_memory,
1521 .remove_memory = agp_generic_remove_memory,
1522 .alloc_by_type = agp_generic_alloc_by_type,
1523 .free_by_type = agp_generic_free_by_type,
1524 .agp_alloc_page = agp_generic_alloc_page,
1525 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001526 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527};
1528
1529static struct agp_bridge_driver intel_830mp_driver = {
1530 .owner = THIS_MODULE,
1531 .aperture_sizes = intel_830mp_sizes,
1532 .size_type = U8_APER_SIZE,
1533 .num_aperture_sizes = 4,
1534 .configure = intel_830mp_configure,
1535 .fetch_size = intel_8xx_fetch_size,
1536 .cleanup = intel_8xx_cleanup,
1537 .tlb_flush = intel_8xx_tlbflush,
1538 .mask_memory = agp_generic_mask_memory,
1539 .masks = intel_generic_masks,
1540 .agp_enable = agp_generic_enable,
1541 .cache_flush = global_cache_flush,
1542 .create_gatt_table = agp_generic_create_gatt_table,
1543 .free_gatt_table = agp_generic_free_gatt_table,
1544 .insert_memory = agp_generic_insert_memory,
1545 .remove_memory = agp_generic_remove_memory,
1546 .alloc_by_type = agp_generic_alloc_by_type,
1547 .free_by_type = agp_generic_free_by_type,
1548 .agp_alloc_page = agp_generic_alloc_page,
1549 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001550 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551};
1552
1553static struct agp_bridge_driver intel_840_driver = {
1554 .owner = THIS_MODULE,
1555 .aperture_sizes = intel_8xx_sizes,
1556 .size_type = U8_APER_SIZE,
1557 .num_aperture_sizes = 7,
1558 .configure = intel_840_configure,
1559 .fetch_size = intel_8xx_fetch_size,
1560 .cleanup = intel_8xx_cleanup,
1561 .tlb_flush = intel_8xx_tlbflush,
1562 .mask_memory = agp_generic_mask_memory,
1563 .masks = intel_generic_masks,
1564 .agp_enable = agp_generic_enable,
1565 .cache_flush = global_cache_flush,
1566 .create_gatt_table = agp_generic_create_gatt_table,
1567 .free_gatt_table = agp_generic_free_gatt_table,
1568 .insert_memory = agp_generic_insert_memory,
1569 .remove_memory = agp_generic_remove_memory,
1570 .alloc_by_type = agp_generic_alloc_by_type,
1571 .free_by_type = agp_generic_free_by_type,
1572 .agp_alloc_page = agp_generic_alloc_page,
1573 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001574 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575};
1576
1577static struct agp_bridge_driver intel_845_driver = {
1578 .owner = THIS_MODULE,
1579 .aperture_sizes = intel_8xx_sizes,
1580 .size_type = U8_APER_SIZE,
1581 .num_aperture_sizes = 7,
1582 .configure = intel_845_configure,
1583 .fetch_size = intel_8xx_fetch_size,
1584 .cleanup = intel_8xx_cleanup,
1585 .tlb_flush = intel_8xx_tlbflush,
1586 .mask_memory = agp_generic_mask_memory,
1587 .masks = intel_generic_masks,
1588 .agp_enable = agp_generic_enable,
1589 .cache_flush = global_cache_flush,
1590 .create_gatt_table = agp_generic_create_gatt_table,
1591 .free_gatt_table = agp_generic_free_gatt_table,
1592 .insert_memory = agp_generic_insert_memory,
1593 .remove_memory = agp_generic_remove_memory,
1594 .alloc_by_type = agp_generic_alloc_by_type,
1595 .free_by_type = agp_generic_free_by_type,
1596 .agp_alloc_page = agp_generic_alloc_page,
1597 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001598 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599};
1600
1601static struct agp_bridge_driver intel_850_driver = {
1602 .owner = THIS_MODULE,
1603 .aperture_sizes = intel_8xx_sizes,
1604 .size_type = U8_APER_SIZE,
1605 .num_aperture_sizes = 7,
1606 .configure = intel_850_configure,
1607 .fetch_size = intel_8xx_fetch_size,
1608 .cleanup = intel_8xx_cleanup,
1609 .tlb_flush = intel_8xx_tlbflush,
1610 .mask_memory = agp_generic_mask_memory,
1611 .masks = intel_generic_masks,
1612 .agp_enable = agp_generic_enable,
1613 .cache_flush = global_cache_flush,
1614 .create_gatt_table = agp_generic_create_gatt_table,
1615 .free_gatt_table = agp_generic_free_gatt_table,
1616 .insert_memory = agp_generic_insert_memory,
1617 .remove_memory = agp_generic_remove_memory,
1618 .alloc_by_type = agp_generic_alloc_by_type,
1619 .free_by_type = agp_generic_free_by_type,
1620 .agp_alloc_page = agp_generic_alloc_page,
1621 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001622 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623};
1624
1625static struct agp_bridge_driver intel_860_driver = {
1626 .owner = THIS_MODULE,
1627 .aperture_sizes = intel_8xx_sizes,
1628 .size_type = U8_APER_SIZE,
1629 .num_aperture_sizes = 7,
1630 .configure = intel_860_configure,
1631 .fetch_size = intel_8xx_fetch_size,
1632 .cleanup = intel_8xx_cleanup,
1633 .tlb_flush = intel_8xx_tlbflush,
1634 .mask_memory = agp_generic_mask_memory,
1635 .masks = intel_generic_masks,
1636 .agp_enable = agp_generic_enable,
1637 .cache_flush = global_cache_flush,
1638 .create_gatt_table = agp_generic_create_gatt_table,
1639 .free_gatt_table = agp_generic_free_gatt_table,
1640 .insert_memory = agp_generic_insert_memory,
1641 .remove_memory = agp_generic_remove_memory,
1642 .alloc_by_type = agp_generic_alloc_by_type,
1643 .free_by_type = agp_generic_free_by_type,
1644 .agp_alloc_page = agp_generic_alloc_page,
1645 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001646 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647};
1648
1649static struct agp_bridge_driver intel_915_driver = {
1650 .owner = THIS_MODULE,
1651 .aperture_sizes = intel_i830_sizes,
1652 .size_type = FIXED_APER_SIZE,
Dave Jonesc14635e2006-09-06 11:59:35 -04001653 .num_aperture_sizes = 4,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 .needs_scratch_page = TRUE,
1655 .configure = intel_i915_configure,
Eric Anholtc41e0de2006-12-19 12:57:24 -08001656 .fetch_size = intel_i9xx_fetch_size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 .cleanup = intel_i915_cleanup,
1658 .tlb_flush = intel_i810_tlbflush,
1659 .mask_memory = intel_i810_mask_memory,
1660 .masks = intel_i810_masks,
1661 .agp_enable = intel_i810_agp_enable,
1662 .cache_flush = global_cache_flush,
1663 .create_gatt_table = intel_i915_create_gatt_table,
1664 .free_gatt_table = intel_i830_free_gatt_table,
1665 .insert_memory = intel_i915_insert_entries,
1666 .remove_memory = intel_i915_remove_entries,
1667 .alloc_by_type = intel_i830_alloc_by_type,
1668 .free_by_type = intel_i810_free_by_type,
1669 .agp_alloc_page = agp_generic_alloc_page,
1670 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001671 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672};
1673
Eric Anholt65c25aa2006-09-06 11:57:18 -04001674static struct agp_bridge_driver intel_i965_driver = {
1675 .owner = THIS_MODULE,
1676 .aperture_sizes = intel_i830_sizes,
1677 .size_type = FIXED_APER_SIZE,
1678 .num_aperture_sizes = 4,
1679 .needs_scratch_page = TRUE,
1680 .configure = intel_i915_configure,
Eric Anholtc41e0de2006-12-19 12:57:24 -08001681 .fetch_size = intel_i9xx_fetch_size,
Eric Anholt65c25aa2006-09-06 11:57:18 -04001682 .cleanup = intel_i915_cleanup,
1683 .tlb_flush = intel_i810_tlbflush,
Linus Torvalds7d915a32006-11-22 09:37:54 -08001684 .mask_memory = intel_i965_mask_memory,
Eric Anholt65c25aa2006-09-06 11:57:18 -04001685 .masks = intel_i810_masks,
1686 .agp_enable = intel_i810_agp_enable,
1687 .cache_flush = global_cache_flush,
1688 .create_gatt_table = intel_i965_create_gatt_table,
1689 .free_gatt_table = intel_i830_free_gatt_table,
1690 .insert_memory = intel_i915_insert_entries,
1691 .remove_memory = intel_i915_remove_entries,
1692 .alloc_by_type = intel_i830_alloc_by_type,
1693 .free_by_type = intel_i810_free_by_type,
1694 .agp_alloc_page = agp_generic_alloc_page,
1695 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001696 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
Eric Anholt65c25aa2006-09-06 11:57:18 -04001697};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698
1699static struct agp_bridge_driver intel_7505_driver = {
1700 .owner = THIS_MODULE,
1701 .aperture_sizes = intel_8xx_sizes,
1702 .size_type = U8_APER_SIZE,
1703 .num_aperture_sizes = 7,
1704 .configure = intel_7505_configure,
1705 .fetch_size = intel_8xx_fetch_size,
1706 .cleanup = intel_8xx_cleanup,
1707 .tlb_flush = intel_8xx_tlbflush,
1708 .mask_memory = agp_generic_mask_memory,
1709 .masks = intel_generic_masks,
1710 .agp_enable = agp_generic_enable,
1711 .cache_flush = global_cache_flush,
1712 .create_gatt_table = agp_generic_create_gatt_table,
1713 .free_gatt_table = agp_generic_free_gatt_table,
1714 .insert_memory = agp_generic_insert_memory,
1715 .remove_memory = agp_generic_remove_memory,
1716 .alloc_by_type = agp_generic_alloc_by_type,
1717 .free_by_type = agp_generic_free_by_type,
1718 .agp_alloc_page = agp_generic_alloc_page,
1719 .agp_destroy_page = agp_generic_destroy_page,
Thomas Hellstroma030ce42007-01-23 10:33:43 +01001720 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721};
1722
1723static int find_i810(u16 device)
1724{
1725 struct pci_dev *i810_dev;
1726
1727 i810_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
1728 if (!i810_dev)
1729 return 0;
1730 intel_i810_private.i810_dev = i810_dev;
1731 return 1;
1732}
1733
1734static int find_i830(u16 device)
1735{
1736 struct pci_dev *i830_dev;
1737
1738 i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
1739 if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
1740 i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
1741 device, i830_dev);
1742 }
1743
1744 if (!i830_dev)
1745 return 0;
1746
1747 intel_i830_private.i830_dev = i830_dev;
1748 return 1;
1749}
1750
1751static int __devinit agp_intel_probe(struct pci_dev *pdev,
1752 const struct pci_device_id *ent)
1753{
1754 struct agp_bridge_data *bridge;
1755 char *name = "(unknown)";
1756 u8 cap_ptr = 0;
1757 struct resource *r;
1758
1759 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
1760
1761 bridge = agp_alloc_bridge();
1762 if (!bridge)
1763 return -ENOMEM;
1764
1765 switch (pdev->device) {
1766 case PCI_DEVICE_ID_INTEL_82443LX_0:
1767 bridge->driver = &intel_generic_driver;
1768 name = "440LX";
1769 break;
1770 case PCI_DEVICE_ID_INTEL_82443BX_0:
1771 bridge->driver = &intel_generic_driver;
1772 name = "440BX";
1773 break;
1774 case PCI_DEVICE_ID_INTEL_82443GX_0:
1775 bridge->driver = &intel_generic_driver;
1776 name = "440GX";
1777 break;
1778 case PCI_DEVICE_ID_INTEL_82810_MC1:
1779 name = "i810";
1780 if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG1))
1781 goto fail;
1782 bridge->driver = &intel_810_driver;
1783 break;
1784 case PCI_DEVICE_ID_INTEL_82810_MC3:
1785 name = "i810 DC100";
1786 if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG3))
1787 goto fail;
1788 bridge->driver = &intel_810_driver;
1789 break;
1790 case PCI_DEVICE_ID_INTEL_82810E_MC:
1791 name = "i810 E";
1792 if (!find_i810(PCI_DEVICE_ID_INTEL_82810E_IG))
1793 goto fail;
1794 bridge->driver = &intel_810_driver;
1795 break;
1796 case PCI_DEVICE_ID_INTEL_82815_MC:
1797 /*
1798 * The i815 can operate either as an i810 style
1799 * integrated device, or as an AGP4X motherboard.
1800 */
1801 if (find_i810(PCI_DEVICE_ID_INTEL_82815_CGC))
1802 bridge->driver = &intel_810_driver;
1803 else
1804 bridge->driver = &intel_815_driver;
1805 name = "i815";
1806 break;
1807 case PCI_DEVICE_ID_INTEL_82820_HB:
1808 case PCI_DEVICE_ID_INTEL_82820_UP_HB:
1809 bridge->driver = &intel_820_driver;
1810 name = "i820";
1811 break;
1812 case PCI_DEVICE_ID_INTEL_82830_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001813 if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 bridge->driver = &intel_830_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001815 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 bridge->driver = &intel_830mp_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 name = "830M";
1818 break;
1819 case PCI_DEVICE_ID_INTEL_82840_HB:
1820 bridge->driver = &intel_840_driver;
1821 name = "i840";
1822 break;
1823 case PCI_DEVICE_ID_INTEL_82845_HB:
1824 bridge->driver = &intel_845_driver;
1825 name = "i845";
1826 break;
1827 case PCI_DEVICE_ID_INTEL_82845G_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001828 if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 bridge->driver = &intel_830_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001830 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 bridge->driver = &intel_845_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 name = "845G";
1833 break;
1834 case PCI_DEVICE_ID_INTEL_82850_HB:
1835 bridge->driver = &intel_850_driver;
1836 name = "i850";
1837 break;
1838 case PCI_DEVICE_ID_INTEL_82855PM_HB:
1839 bridge->driver = &intel_845_driver;
1840 name = "855PM";
1841 break;
1842 case PCI_DEVICE_ID_INTEL_82855GM_HB:
1843 if (find_i830(PCI_DEVICE_ID_INTEL_82855GM_IG)) {
1844 bridge->driver = &intel_830_driver;
1845 name = "855";
1846 } else {
1847 bridge->driver = &intel_845_driver;
1848 name = "855GM";
1849 }
1850 break;
1851 case PCI_DEVICE_ID_INTEL_82860_HB:
1852 bridge->driver = &intel_860_driver;
1853 name = "i860";
1854 break;
1855 case PCI_DEVICE_ID_INTEL_82865_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001856 if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 bridge->driver = &intel_830_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001858 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 bridge->driver = &intel_845_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 name = "865";
1861 break;
1862 case PCI_DEVICE_ID_INTEL_82875_HB:
1863 bridge->driver = &intel_845_driver;
1864 name = "i875";
1865 break;
1866 case PCI_DEVICE_ID_INTEL_82915G_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001867 if (find_i830(PCI_DEVICE_ID_INTEL_82915G_IG))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 bridge->driver = &intel_915_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001869 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 bridge->driver = &intel_845_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871 name = "915G";
1872 break;
1873 case PCI_DEVICE_ID_INTEL_82915GM_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001874 if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 bridge->driver = &intel_915_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001876 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 bridge->driver = &intel_845_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 name = "915GM";
1879 break;
Alan Hourihaned0de98f2005-05-31 19:50:49 +01001880 case PCI_DEVICE_ID_INTEL_82945G_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001881 if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG))
Alan Hourihaned0de98f2005-05-31 19:50:49 +01001882 bridge->driver = &intel_915_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001883 else
Alan Hourihaned0de98f2005-05-31 19:50:49 +01001884 bridge->driver = &intel_845_driver;
Alan Hourihaned0de98f2005-05-31 19:50:49 +01001885 name = "945G";
1886 break;
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00001887 case PCI_DEVICE_ID_INTEL_82945GM_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001888 if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG))
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00001889 bridge->driver = &intel_915_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001890 else
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00001891 bridge->driver = &intel_845_driver;
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00001892 name = "945GM";
1893 break;
Eric Anholt65c25aa2006-09-06 11:57:18 -04001894 case PCI_DEVICE_ID_INTEL_82946GZ_HB:
1895 if (find_i830(PCI_DEVICE_ID_INTEL_82946GZ_IG))
1896 bridge->driver = &intel_i965_driver;
1897 else
1898 bridge->driver = &intel_845_driver;
1899 name = "946GZ";
1900 break;
1901 case PCI_DEVICE_ID_INTEL_82965G_1_HB:
1902 if (find_i830(PCI_DEVICE_ID_INTEL_82965G_1_IG))
1903 bridge->driver = &intel_i965_driver;
1904 else
1905 bridge->driver = &intel_845_driver;
1906 name = "965G";
1907 break;
1908 case PCI_DEVICE_ID_INTEL_82965Q_HB:
1909 if (find_i830(PCI_DEVICE_ID_INTEL_82965Q_IG))
1910 bridge->driver = &intel_i965_driver;
1911 else
1912 bridge->driver = &intel_845_driver;
1913 name = "965Q";
1914 break;
1915 case PCI_DEVICE_ID_INTEL_82965G_HB:
1916 if (find_i830(PCI_DEVICE_ID_INTEL_82965G_IG))
1917 bridge->driver = &intel_i965_driver;
1918 else
1919 bridge->driver = &intel_845_driver;
1920 name = "965G";
1921 break;
1922
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 case PCI_DEVICE_ID_INTEL_7505_0:
1924 bridge->driver = &intel_7505_driver;
1925 name = "E7505";
1926 break;
1927 case PCI_DEVICE_ID_INTEL_7205_0:
1928 bridge->driver = &intel_7505_driver;
1929 name = "E7205";
1930 break;
1931 default:
1932 if (cap_ptr)
1933 printk(KERN_WARNING PFX "Unsupported Intel chipset (device id: %04x)\n",
1934 pdev->device);
1935 agp_put_bridge(bridge);
1936 return -ENODEV;
1937 };
1938
1939 bridge->dev = pdev;
1940 bridge->capndx = cap_ptr;
1941
1942 if (bridge->driver == &intel_810_driver)
1943 bridge->dev_private_data = &intel_i810_private;
1944 else if (bridge->driver == &intel_830_driver)
1945 bridge->dev_private_data = &intel_i830_private;
1946
1947 printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
1948
1949 /*
1950 * The following fixes the case where the BIOS has "forgotten" to
1951 * provide an address range for the GART.
1952 * 20030610 - hamish@zot.org
1953 */
1954 r = &pdev->resource[0];
1955 if (!r->start && r->end) {
Dave Jones6a92a4e2006-02-28 00:54:25 -05001956 if (pci_assign_resource(pdev, 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 printk(KERN_ERR PFX "could not assign resource 0\n");
1958 agp_put_bridge(bridge);
1959 return -ENODEV;
1960 }
1961 }
1962
1963 /*
1964 * If the device has not been properly setup, the following will catch
1965 * the problem and should stop the system from crashing.
1966 * 20030610 - hamish@zot.org
1967 */
1968 if (pci_enable_device(pdev)) {
1969 printk(KERN_ERR PFX "Unable to Enable PCI device\n");
1970 agp_put_bridge(bridge);
1971 return -ENODEV;
1972 }
1973
1974 /* Fill in the mode register */
1975 if (cap_ptr) {
1976 pci_read_config_dword(pdev,
1977 bridge->capndx+PCI_AGP_STATUS,
1978 &bridge->mode);
1979 }
1980
1981 pci_set_drvdata(pdev, bridge);
1982 return agp_add_bridge(bridge);
1983
1984fail:
1985 printk(KERN_ERR PFX "Detected an Intel %s chipset, "
1986 "but could not find the secondary device.\n", name);
1987 agp_put_bridge(bridge);
1988 return -ENODEV;
1989}
1990
1991static void __devexit agp_intel_remove(struct pci_dev *pdev)
1992{
1993 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
1994
1995 agp_remove_bridge(bridge);
1996
1997 if (intel_i810_private.i810_dev)
1998 pci_dev_put(intel_i810_private.i810_dev);
1999 if (intel_i830_private.i830_dev)
2000 pci_dev_put(intel_i830_private.i830_dev);
2001
2002 agp_put_bridge(bridge);
2003}
2004
Alexey Dobriyan85be7d62006-08-12 02:02:02 +04002005#ifdef CONFIG_PM
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006static int agp_intel_resume(struct pci_dev *pdev)
2007{
2008 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
2009
2010 pci_restore_state(pdev);
2011
Wang Zhenyu4b953202007-01-17 11:07:54 +08002012 /* We should restore our graphics device's config space,
2013 * as host bridge (00:00) resumes before graphics device (02:00),
2014 * then our access to its pci space can work right.
2015 */
2016 if (intel_i810_private.i810_dev)
2017 pci_restore_state(intel_i810_private.i810_dev);
2018 if (intel_i830_private.i830_dev)
2019 pci_restore_state(intel_i830_private.i830_dev);
2020
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021 if (bridge->driver == &intel_generic_driver)
2022 intel_configure();
2023 else if (bridge->driver == &intel_850_driver)
2024 intel_850_configure();
2025 else if (bridge->driver == &intel_845_driver)
2026 intel_845_configure();
2027 else if (bridge->driver == &intel_830mp_driver)
2028 intel_830mp_configure();
2029 else if (bridge->driver == &intel_915_driver)
2030 intel_i915_configure();
2031 else if (bridge->driver == &intel_830_driver)
2032 intel_i830_configure();
2033 else if (bridge->driver == &intel_810_driver)
2034 intel_i810_configure();
Dave Jones08da3f42006-09-10 21:09:26 -04002035 else if (bridge->driver == &intel_i965_driver)
2036 intel_i915_configure();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037
2038 return 0;
2039}
Alexey Dobriyan85be7d62006-08-12 02:02:02 +04002040#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041
2042static struct pci_device_id agp_intel_pci_table[] = {
2043#define ID(x) \
2044 { \
2045 .class = (PCI_CLASS_BRIDGE_HOST << 8), \
2046 .class_mask = ~0, \
2047 .vendor = PCI_VENDOR_ID_INTEL, \
2048 .device = x, \
2049 .subvendor = PCI_ANY_ID, \
2050 .subdevice = PCI_ANY_ID, \
2051 }
2052 ID(PCI_DEVICE_ID_INTEL_82443LX_0),
2053 ID(PCI_DEVICE_ID_INTEL_82443BX_0),
2054 ID(PCI_DEVICE_ID_INTEL_82443GX_0),
2055 ID(PCI_DEVICE_ID_INTEL_82810_MC1),
2056 ID(PCI_DEVICE_ID_INTEL_82810_MC3),
2057 ID(PCI_DEVICE_ID_INTEL_82810E_MC),
2058 ID(PCI_DEVICE_ID_INTEL_82815_MC),
2059 ID(PCI_DEVICE_ID_INTEL_82820_HB),
2060 ID(PCI_DEVICE_ID_INTEL_82820_UP_HB),
2061 ID(PCI_DEVICE_ID_INTEL_82830_HB),
2062 ID(PCI_DEVICE_ID_INTEL_82840_HB),
2063 ID(PCI_DEVICE_ID_INTEL_82845_HB),
2064 ID(PCI_DEVICE_ID_INTEL_82845G_HB),
2065 ID(PCI_DEVICE_ID_INTEL_82850_HB),
2066 ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
2067 ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
2068 ID(PCI_DEVICE_ID_INTEL_82860_HB),
2069 ID(PCI_DEVICE_ID_INTEL_82865_HB),
2070 ID(PCI_DEVICE_ID_INTEL_82875_HB),
2071 ID(PCI_DEVICE_ID_INTEL_7505_0),
2072 ID(PCI_DEVICE_ID_INTEL_7205_0),
2073 ID(PCI_DEVICE_ID_INTEL_82915G_HB),
2074 ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
Alan Hourihaned0de98f2005-05-31 19:50:49 +01002075 ID(PCI_DEVICE_ID_INTEL_82945G_HB),
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00002076 ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
Eric Anholt65c25aa2006-09-06 11:57:18 -04002077 ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
2078 ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
2079 ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
2080 ID(PCI_DEVICE_ID_INTEL_82965G_HB),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081 { }
2082};
2083
2084MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
2085
2086static struct pci_driver agp_intel_pci_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087 .name = "agpgart-intel",
2088 .id_table = agp_intel_pci_table,
2089 .probe = agp_intel_probe,
2090 .remove = __devexit_p(agp_intel_remove),
Alexey Dobriyan85be7d62006-08-12 02:02:02 +04002091#ifdef CONFIG_PM
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092 .resume = agp_intel_resume,
Alexey Dobriyan85be7d62006-08-12 02:02:02 +04002093#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002094};
2095
2096static int __init agp_intel_init(void)
2097{
2098 if (agp_off)
2099 return -EINVAL;
2100 return pci_register_driver(&agp_intel_pci_driver);
2101}
2102
2103static void __exit agp_intel_cleanup(void)
2104{
2105 pci_unregister_driver(&agp_intel_pci_driver);
2106}
2107
2108module_init(agp_intel_init);
2109module_exit(agp_intel_cleanup);
2110
2111MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
2112MODULE_LICENSE("GPL and additional rights");