blob: d1ede7db5a12f46027174a41ae52c2692b180bf9 [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
Linus Torvalds1da177e2005-04-16 15:20:36 -070027/* Intel 815 register */
28#define INTEL_815_APCONT 0x51
29#define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF
30
31/* Intel i820 registers */
32#define INTEL_I820_RDCR 0x51
33#define INTEL_I820_ERRSTS 0xc8
34
35/* Intel i840 registers */
36#define INTEL_I840_MCHCFG 0x50
37#define INTEL_I840_ERRSTS 0xc8
38
39/* Intel i850 registers */
40#define INTEL_I850_MCHCFG 0x50
41#define INTEL_I850_ERRSTS 0xc8
42
43/* intel 915G registers */
44#define I915_GMADDR 0x18
45#define I915_MMADDR 0x10
46#define I915_PTEADDR 0x1C
47#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4)
48#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4)
49
Eric Anholt65c25aa2006-09-06 11:57:18 -040050/* Intel 965G registers */
51#define I965_MSAC 0x62
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
53/* Intel 7505 registers */
54#define INTEL_I7505_APSIZE 0x74
55#define INTEL_I7505_NCAPID 0x60
56#define INTEL_I7505_NISTAT 0x6c
57#define INTEL_I7505_ATTBASE 0x78
58#define INTEL_I7505_ERRSTS 0x42
59#define INTEL_I7505_AGPCTRL 0x70
60#define INTEL_I7505_MCHCFG 0x50
61
62static struct aper_size_info_fixed intel_i810_sizes[] =
63{
64 {64, 16384, 4},
65 /* The 32M mode still requires a 64k gatt */
66 {32, 8192, 4}
67};
68
69#define AGP_DCACHE_MEMORY 1
70#define AGP_PHYS_MEMORY 2
71
72static struct gatt_mask intel_i810_masks[] =
73{
74 {.mask = I810_PTE_VALID, .type = 0},
75 {.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY},
76 {.mask = I810_PTE_VALID, .type = 0}
77};
78
79static struct _intel_i810_private {
80 struct pci_dev *i810_dev; /* device one */
81 volatile u8 __iomem *registers;
82 int num_dcache_entries;
83} intel_i810_private;
84
85static int intel_i810_fetch_size(void)
86{
87 u32 smram_miscc;
88 struct aper_size_info_fixed *values;
89
90 pci_read_config_dword(agp_bridge->dev, I810_SMRAM_MISCC, &smram_miscc);
91 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
92
93 if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
94 printk(KERN_WARNING PFX "i810 is disabled\n");
95 return 0;
96 }
97 if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
98 agp_bridge->previous_size =
99 agp_bridge->current_size = (void *) (values + 1);
100 agp_bridge->aperture_size_idx = 1;
101 return values[1].size;
102 } else {
103 agp_bridge->previous_size =
104 agp_bridge->current_size = (void *) (values);
105 agp_bridge->aperture_size_idx = 0;
106 return values[0].size;
107 }
108
109 return 0;
110}
111
112static int intel_i810_configure(void)
113{
114 struct aper_size_info_fixed *current_size;
115 u32 temp;
116 int i;
117
118 current_size = A_SIZE_FIX(agp_bridge->current_size);
119
120 pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
121 temp &= 0xfff80000;
122
123 intel_i810_private.registers = ioremap(temp, 128 * 4096);
124 if (!intel_i810_private.registers) {
125 printk(KERN_ERR PFX "Unable to remap memory.\n");
126 return -ENOMEM;
127 }
128
129 if ((readl(intel_i810_private.registers+I810_DRAM_CTL)
130 & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
131 /* This will need to be dynamically assigned */
132 printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
133 intel_i810_private.num_dcache_entries = 1024;
134 }
135 pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
136 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
137 writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_i810_private.registers+I810_PGETBL_CTL);
138 readl(intel_i810_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
139
140 if (agp_bridge->driver->needs_scratch_page) {
141 for (i = 0; i < current_size->num_entries; i++) {
142 writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
143 readl(intel_i810_private.registers+I810_PTE_BASE+(i*4)); /* PCI posting. */
144 }
145 }
146 global_cache_flush();
147 return 0;
148}
149
150static void intel_i810_cleanup(void)
151{
152 writel(0, intel_i810_private.registers+I810_PGETBL_CTL);
153 readl(intel_i810_private.registers); /* PCI Posting. */
154 iounmap(intel_i810_private.registers);
155}
156
157static void intel_i810_tlbflush(struct agp_memory *mem)
158{
159 return;
160}
161
162static void intel_i810_agp_enable(struct agp_bridge_data *bridge, u32 mode)
163{
164 return;
165}
166
167/* Exists to support ARGB cursors */
168static void *i8xx_alloc_pages(void)
169{
170 struct page * page;
171
172 page = alloc_pages(GFP_KERNEL, 2);
173 if (page == NULL)
174 return NULL;
175
176 if (change_page_attr(page, 4, PAGE_KERNEL_NOCACHE) < 0) {
177 global_flush_tlb();
178 __free_page(page);
179 return NULL;
180 }
181 global_flush_tlb();
182 get_page(page);
183 SetPageLocked(page);
184 atomic_inc(&agp_bridge->current_memory_agp);
185 return page_address(page);
186}
187
188static void i8xx_destroy_pages(void *addr)
189{
190 struct page *page;
191
192 if (addr == NULL)
193 return;
194
195 page = virt_to_page(addr);
196 change_page_attr(page, 4, PAGE_KERNEL);
197 global_flush_tlb();
198 put_page(page);
199 unlock_page(page);
200 free_pages((unsigned long)addr, 2);
201 atomic_dec(&agp_bridge->current_memory_agp);
202}
203
204static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
205 int type)
206{
207 int i, j, num_entries;
208 void *temp;
209
210 temp = agp_bridge->current_size;
211 num_entries = A_SIZE_FIX(temp)->num_entries;
212
Dave Jones6a92a4e2006-02-28 00:54:25 -0500213 if ((pg_start + mem->page_count) > num_entries)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 return -EINVAL;
Dave Jones6a92a4e2006-02-28 00:54:25 -0500215
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 for (j = pg_start; j < (pg_start + mem->page_count); j++) {
217 if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+j)))
218 return -EBUSY;
219 }
220
221 if (type != 0 || mem->type != 0) {
222 if ((type == AGP_DCACHE_MEMORY) && (mem->type == AGP_DCACHE_MEMORY)) {
223 /* special insert */
224 global_cache_flush();
225 for (i = pg_start; i < (pg_start + mem->page_count); i++) {
226 writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID, intel_i810_private.registers+I810_PTE_BASE+(i*4));
227 readl(intel_i810_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
228 }
229 global_cache_flush();
230 agp_bridge->driver->tlb_flush(mem);
231 return 0;
232 }
Dave Jones6a92a4e2006-02-28 00:54:25 -0500233 if ((type == AGP_PHYS_MEMORY) && (mem->type == AGP_PHYS_MEMORY))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 goto insert;
235 return -EINVAL;
236 }
237
238insert:
239 global_cache_flush();
240 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
241 writel(agp_bridge->driver->mask_memory(agp_bridge,
242 mem->memory[i], mem->type),
243 intel_i810_private.registers+I810_PTE_BASE+(j*4));
244 readl(intel_i810_private.registers+I810_PTE_BASE+(j*4)); /* PCI Posting. */
245 }
246 global_cache_flush();
247
248 agp_bridge->driver->tlb_flush(mem);
249 return 0;
250}
251
252static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
253 int type)
254{
255 int i;
256
257 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
258 writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
259 readl(intel_i810_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
260 }
261
262 global_cache_flush();
263 agp_bridge->driver->tlb_flush(mem);
264 return 0;
265}
266
267/*
268 * The i810/i830 requires a physical address to program its mouse
269 * pointer into hardware.
270 * However the Xserver still writes to it through the agp aperture.
271 */
272static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
273{
274 struct agp_memory *new;
275 void *addr;
276
277 if (pg_count != 1 && pg_count != 4)
278 return NULL;
279
280 switch (pg_count) {
281 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge);
Alan Hourihane88d51962005-11-06 23:35:34 -0800282 global_flush_tlb();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 break;
284 case 4:
285 /* kludge to get 4 physical pages for ARGB cursor */
286 addr = i8xx_alloc_pages();
287 break;
288 default:
289 return NULL;
290 }
291
292 if (addr == NULL)
293 return NULL;
294
295 new = agp_create_memory(pg_count);
296 if (new == NULL)
297 return NULL;
298
Keir Fraser07eee782005-03-30 13:17:04 -0800299 new->memory[0] = virt_to_gart(addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 if (pg_count == 4) {
301 /* kludge to get 4 physical pages for ARGB cursor */
302 new->memory[1] = new->memory[0] + PAGE_SIZE;
303 new->memory[2] = new->memory[1] + PAGE_SIZE;
304 new->memory[3] = new->memory[2] + PAGE_SIZE;
305 }
306 new->page_count = pg_count;
307 new->num_scratch_pages = pg_count;
308 new->type = AGP_PHYS_MEMORY;
309 new->physical = new->memory[0];
310 return new;
311}
312
313static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
314{
315 struct agp_memory *new;
316
317 if (type == AGP_DCACHE_MEMORY) {
318 if (pg_count != intel_i810_private.num_dcache_entries)
319 return NULL;
320
321 new = agp_create_memory(1);
322 if (new == NULL)
323 return NULL;
324
325 new->type = AGP_DCACHE_MEMORY;
326 new->page_count = pg_count;
327 new->num_scratch_pages = 0;
328 vfree(new->memory);
329 return new;
330 }
331 if (type == AGP_PHYS_MEMORY)
332 return alloc_agpphysmem_i8xx(pg_count, type);
333
334 return NULL;
335}
336
337static void intel_i810_free_by_type(struct agp_memory *curr)
338{
339 agp_free_key(curr->key);
Dave Jones6a92a4e2006-02-28 00:54:25 -0500340 if (curr->type == AGP_PHYS_MEMORY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 if (curr->page_count == 4)
Keir Fraser07eee782005-03-30 13:17:04 -0800342 i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
Alan Hourihane88d51962005-11-06 23:35:34 -0800343 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 agp_bridge->driver->agp_destroy_page(
Keir Fraser07eee782005-03-30 13:17:04 -0800345 gart_to_virt(curr->memory[0]));
Alan Hourihane88d51962005-11-06 23:35:34 -0800346 global_flush_tlb();
347 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 vfree(curr->memory);
349 }
350 kfree(curr);
351}
352
353static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge,
354 unsigned long addr, int type)
355{
356 /* Type checking must be done elsewhere */
357 return addr | bridge->driver->masks[type].mask;
358}
359
360static struct aper_size_info_fixed intel_i830_sizes[] =
361{
362 {128, 32768, 5},
363 /* The 64M mode still requires a 128k gatt */
364 {64, 16384, 5},
365 {256, 65536, 6},
Eric Anholt65c25aa2006-09-06 11:57:18 -0400366 {512, 131072, 7},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367};
368
369static struct _intel_i830_private {
370 struct pci_dev *i830_dev; /* device one */
371 volatile u8 __iomem *registers;
372 volatile u32 __iomem *gtt; /* I915G */
373 int gtt_entries;
374} intel_i830_private;
375
376static void intel_i830_init_gtt_entries(void)
377{
378 u16 gmch_ctrl;
379 int gtt_entries;
380 u8 rdct;
381 int local = 0;
382 static const int ddt[4] = { 0, 16, 32, 64 };
383 int size;
384
385 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
386
387 /* We obtain the size of the GTT, which is also stored (for some
388 * reason) at the top of stolen memory. Then we add 4KB to that
389 * for the video BIOS popup, which is also stored in there. */
Eric Anholt65c25aa2006-09-06 11:57:18 -0400390
391 if (IS_I965)
392 size = 512 + 4;
393 else
394 size = agp_bridge->driver->fetch_size() + 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395
396 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
397 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
398 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
399 case I830_GMCH_GMS_STOLEN_512:
400 gtt_entries = KB(512) - KB(size);
401 break;
402 case I830_GMCH_GMS_STOLEN_1024:
403 gtt_entries = MB(1) - KB(size);
404 break;
405 case I830_GMCH_GMS_STOLEN_8192:
406 gtt_entries = MB(8) - KB(size);
407 break;
408 case I830_GMCH_GMS_LOCAL:
409 rdct = readb(intel_i830_private.registers+I830_RDRAM_CHANNEL_TYPE);
410 gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
411 MB(ddt[I830_RDRAM_DDT(rdct)]);
412 local = 1;
413 break;
414 default:
415 gtt_entries = 0;
416 break;
417 }
418 } else {
419 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
420 case I855_GMCH_GMS_STOLEN_1M:
421 gtt_entries = MB(1) - KB(size);
422 break;
423 case I855_GMCH_GMS_STOLEN_4M:
424 gtt_entries = MB(4) - KB(size);
425 break;
426 case I855_GMCH_GMS_STOLEN_8M:
427 gtt_entries = MB(8) - KB(size);
428 break;
429 case I855_GMCH_GMS_STOLEN_16M:
430 gtt_entries = MB(16) - KB(size);
431 break;
432 case I855_GMCH_GMS_STOLEN_32M:
433 gtt_entries = MB(32) - KB(size);
434 break;
435 case I915_GMCH_GMS_STOLEN_48M:
436 /* Check it's really I915G */
437 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
Alan Hourihaned0de98f2005-05-31 19:50:49 +0100438 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +0000439 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
Eric Anholt65c25aa2006-09-06 11:57:18 -0400440 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965 )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 gtt_entries = MB(48) - KB(size);
442 else
443 gtt_entries = 0;
444 break;
445 case I915_GMCH_GMS_STOLEN_64M:
446 /* Check it's really I915G */
447 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
Alan Hourihaned0de98f2005-05-31 19:50:49 +0100448 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +0000449 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
Eric Anholt65c25aa2006-09-06 11:57:18 -0400450 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 gtt_entries = MB(64) - KB(size);
452 else
453 gtt_entries = 0;
454 default:
455 gtt_entries = 0;
456 break;
457 }
458 }
459 if (gtt_entries > 0)
460 printk(KERN_INFO PFX "Detected %dK %s memory.\n",
461 gtt_entries / KB(1), local ? "local" : "stolen");
462 else
463 printk(KERN_INFO PFX
464 "No pre-allocated video memory detected.\n");
465 gtt_entries /= KB(4);
466
467 intel_i830_private.gtt_entries = gtt_entries;
468}
469
470/* The intel i830 automatically initializes the agp aperture during POST.
471 * Use the memory already set aside for in the GTT.
472 */
473static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
474{
475 int page_order;
476 struct aper_size_info_fixed *size;
477 int num_entries;
478 u32 temp;
479
480 size = agp_bridge->current_size;
481 page_order = size->page_order;
482 num_entries = size->num_entries;
483 agp_bridge->gatt_table_real = NULL;
484
485 pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
486 temp &= 0xfff80000;
487
488 intel_i830_private.registers = ioremap(temp,128 * 4096);
489 if (!intel_i830_private.registers)
490 return -ENOMEM;
491
492 temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
493 global_cache_flush(); /* FIXME: ?? */
494
495 /* we have to call this as early as possible after the MMIO base address is known */
496 intel_i830_init_gtt_entries();
497
498 agp_bridge->gatt_table = NULL;
499
500 agp_bridge->gatt_bus_addr = temp;
501
502 return 0;
503}
504
505/* Return the gatt table to a sane state. Use the top of stolen
506 * memory for the GTT.
507 */
508static int intel_i830_free_gatt_table(struct agp_bridge_data *bridge)
509{
510 return 0;
511}
512
513static int intel_i830_fetch_size(void)
514{
515 u16 gmch_ctrl;
516 struct aper_size_info_fixed *values;
517
518 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
519
520 if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB &&
521 agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) {
522 /* 855GM/852GM/865G has 128MB aperture size */
523 agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
524 agp_bridge->aperture_size_idx = 0;
525 return values[0].size;
526 }
527
528 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
529
530 if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
531 agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
532 agp_bridge->aperture_size_idx = 0;
533 return values[0].size;
534 } else {
535 agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + 1);
536 agp_bridge->aperture_size_idx = 1;
537 return values[1].size;
538 }
539
540 return 0;
541}
542
543static int intel_i830_configure(void)
544{
545 struct aper_size_info_fixed *current_size;
546 u32 temp;
547 u16 gmch_ctrl;
548 int i;
549
550 current_size = A_SIZE_FIX(agp_bridge->current_size);
551
552 pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
553 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
554
555 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
556 gmch_ctrl |= I830_GMCH_ENABLED;
557 pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
558
559 writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
560 readl(intel_i830_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
561
562 if (agp_bridge->driver->needs_scratch_page) {
563 for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
564 writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
565 readl(intel_i830_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
566 }
567 }
568
569 global_cache_flush();
570 return 0;
571}
572
573static void intel_i830_cleanup(void)
574{
575 iounmap(intel_i830_private.registers);
576}
577
578static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type)
579{
580 int i,j,num_entries;
581 void *temp;
582
583 temp = agp_bridge->current_size;
584 num_entries = A_SIZE_FIX(temp)->num_entries;
585
586 if (pg_start < intel_i830_private.gtt_entries) {
587 printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
588 pg_start,intel_i830_private.gtt_entries);
589
590 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
591 return -EINVAL;
592 }
593
594 if ((pg_start + mem->page_count) > num_entries)
595 return -EINVAL;
596
597 /* The i830 can't check the GTT for entries since its read only,
598 * depend on the caller to make the correct offset decisions.
599 */
600
601 if ((type != 0 && type != AGP_PHYS_MEMORY) ||
602 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
603 return -EINVAL;
604
605 global_cache_flush(); /* FIXME: Necessary ?*/
606
607 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
608 writel(agp_bridge->driver->mask_memory(agp_bridge,
609 mem->memory[i], mem->type),
610 intel_i830_private.registers+I810_PTE_BASE+(j*4));
611 readl(intel_i830_private.registers+I810_PTE_BASE+(j*4)); /* PCI Posting. */
612 }
613
614 global_cache_flush();
615 agp_bridge->driver->tlb_flush(mem);
616 return 0;
617}
618
619static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
620 int type)
621{
622 int i;
623
624 global_cache_flush();
625
626 if (pg_start < intel_i830_private.gtt_entries) {
627 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
628 return -EINVAL;
629 }
630
631 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
632 writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
633 readl(intel_i830_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
634 }
635
636 global_cache_flush();
637 agp_bridge->driver->tlb_flush(mem);
638 return 0;
639}
640
641static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
642{
643 if (type == AGP_PHYS_MEMORY)
644 return alloc_agpphysmem_i8xx(pg_count, type);
645
646 /* always return NULL for other allocation types for now */
647 return NULL;
648}
649
650static int intel_i915_configure(void)
651{
652 struct aper_size_info_fixed *current_size;
653 u32 temp;
654 u16 gmch_ctrl;
655 int i;
656
657 current_size = A_SIZE_FIX(agp_bridge->current_size);
658
659 pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp);
660
661 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
662
663 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
664 gmch_ctrl |= I830_GMCH_ENABLED;
665 pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
666
667 writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
668 readl(intel_i830_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
669
670 if (agp_bridge->driver->needs_scratch_page) {
671 for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
672 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
673 readl(intel_i830_private.gtt+i); /* PCI Posting. */
674 }
675 }
676
677 global_cache_flush();
678 return 0;
679}
680
681static void intel_i915_cleanup(void)
682{
683 iounmap(intel_i830_private.gtt);
684 iounmap(intel_i830_private.registers);
685}
686
687static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
688 int type)
689{
690 int i,j,num_entries;
691 void *temp;
692
693 temp = agp_bridge->current_size;
694 num_entries = A_SIZE_FIX(temp)->num_entries;
695
696 if (pg_start < intel_i830_private.gtt_entries) {
697 printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
698 pg_start,intel_i830_private.gtt_entries);
699
700 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
701 return -EINVAL;
702 }
703
704 if ((pg_start + mem->page_count) > num_entries)
705 return -EINVAL;
706
707 /* The i830 can't check the GTT for entries since its read only,
708 * depend on the caller to make the correct offset decisions.
709 */
710
711 if ((type != 0 && type != AGP_PHYS_MEMORY) ||
712 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
713 return -EINVAL;
714
715 global_cache_flush();
716
717 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
718 writel(agp_bridge->driver->mask_memory(agp_bridge,
719 mem->memory[i], mem->type), intel_i830_private.gtt+j);
720 readl(intel_i830_private.gtt+j); /* PCI Posting. */
721 }
722
723 global_cache_flush();
724 agp_bridge->driver->tlb_flush(mem);
725 return 0;
726}
727
728static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
729 int type)
730{
731 int i;
732
733 global_cache_flush();
734
735 if (pg_start < intel_i830_private.gtt_entries) {
736 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
737 return -EINVAL;
738 }
739
740 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
741 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
742 readl(intel_i830_private.gtt+i);
743 }
744
745 global_cache_flush();
746 agp_bridge->driver->tlb_flush(mem);
747 return 0;
748}
749
750static int intel_i915_fetch_size(void)
751{
752 struct aper_size_info_fixed *values;
Dave Jones01af2fa2006-05-30 18:22:07 -0400753 u32 temp, offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754
755#define I915_256MB_ADDRESS_MASK (1<<27)
756
757 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
758
759 pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp);
760 if (temp & I915_256MB_ADDRESS_MASK)
761 offset = 0; /* 128MB aperture */
762 else
763 offset = 2; /* 256MB aperture */
764 agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
765 return values[offset].size;
766}
767
768/* The intel i915 automatically initializes the agp aperture during POST.
769 * Use the memory already set aside for in the GTT.
770 */
771static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
772{
773 int page_order;
774 struct aper_size_info_fixed *size;
775 int num_entries;
776 u32 temp, temp2;
777
778 size = agp_bridge->current_size;
779 page_order = size->page_order;
780 num_entries = size->num_entries;
781 agp_bridge->gatt_table_real = NULL;
782
783 pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
784 pci_read_config_dword(intel_i830_private.i830_dev, I915_PTEADDR,&temp2);
785
786 intel_i830_private.gtt = ioremap(temp2, 256 * 1024);
787 if (!intel_i830_private.gtt)
788 return -ENOMEM;
789
790 temp &= 0xfff80000;
791
792 intel_i830_private.registers = ioremap(temp,128 * 4096);
793 if (!intel_i830_private.registers)
794 return -ENOMEM;
795
796 temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
797 global_cache_flush(); /* FIXME: ? */
798
799 /* we have to call this as early as possible after the MMIO base address is known */
800 intel_i830_init_gtt_entries();
801
802 agp_bridge->gatt_table = NULL;
803
804 agp_bridge->gatt_bus_addr = temp;
805
806 return 0;
807}
Eric Anholt65c25aa2006-09-06 11:57:18 -0400808static int intel_i965_fetch_size(void)
809{
810 struct aper_size_info_fixed *values;
811 u32 offset = 0;
812 u8 temp;
813
814#define I965_512MB_ADDRESS_MASK (3<<1)
815
816 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
817
818 pci_read_config_byte(intel_i830_private.i830_dev, I965_MSAC, &temp);
819 temp &= I965_512MB_ADDRESS_MASK;
820 switch (temp) {
821 case 0x00:
822 offset = 0; /* 128MB */
823 break;
824 case 0x06:
825 offset = 3; /* 512MB */
826 break;
827 default:
828 case 0x02:
829 offset = 2; /* 256MB */
830 break;
831 }
832
833 agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
834
835 return values[offset].size;
836}
837
838/* The intel i965 automatically initializes the agp aperture during POST.
839+ * Use the memory already set aside for in the GTT.
840+ */
841static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
842{
843 int page_order;
844 struct aper_size_info_fixed *size;
845 int num_entries;
846 u32 temp;
847
848 size = agp_bridge->current_size;
849 page_order = size->page_order;
850 num_entries = size->num_entries;
851 agp_bridge->gatt_table_real = NULL;
852
853 pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
854
855 temp &= 0xfff00000;
856 intel_i830_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
857
858 if (!intel_i830_private.gtt)
859 return -ENOMEM;
860
861
862 intel_i830_private.registers = ioremap(temp,128 * 4096);
863 if (!intel_i830_private.registers)
864 return -ENOMEM;
865
866 temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
867 global_cache_flush(); /* FIXME: ? */
868
869 /* we have to call this as early as possible after the MMIO base address is known */
870 intel_i830_init_gtt_entries();
871
872 agp_bridge->gatt_table = NULL;
873
874 agp_bridge->gatt_bus_addr = temp;
875
876 return 0;
877}
878
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
880static int intel_fetch_size(void)
881{
882 int i;
883 u16 temp;
884 struct aper_size_info_16 *values;
885
886 pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
887 values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
888
889 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
890 if (temp == values[i].size_value) {
891 agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
892 agp_bridge->aperture_size_idx = i;
893 return values[i].size;
894 }
895 }
896
897 return 0;
898}
899
900static int __intel_8xx_fetch_size(u8 temp)
901{
902 int i;
903 struct aper_size_info_8 *values;
904
905 values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
906
907 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
908 if (temp == values[i].size_value) {
909 agp_bridge->previous_size =
910 agp_bridge->current_size = (void *) (values + i);
911 agp_bridge->aperture_size_idx = i;
912 return values[i].size;
913 }
914 }
915 return 0;
916}
917
918static int intel_8xx_fetch_size(void)
919{
920 u8 temp;
921
922 pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
923 return __intel_8xx_fetch_size(temp);
924}
925
926static int intel_815_fetch_size(void)
927{
928 u8 temp;
929
930 /* Intel 815 chipsets have a _weird_ APSIZE register with only
931 * one non-reserved bit, so mask the others out ... */
932 pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
933 temp &= (1 << 3);
934
935 return __intel_8xx_fetch_size(temp);
936}
937
938static void intel_tlbflush(struct agp_memory *mem)
939{
940 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
941 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
942}
943
944
945static void intel_8xx_tlbflush(struct agp_memory *mem)
946{
947 u32 temp;
948 pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
949 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));
950 pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
951 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
952}
953
954
955static void intel_cleanup(void)
956{
957 u16 temp;
958 struct aper_size_info_16 *previous_size;
959
960 previous_size = A_SIZE_16(agp_bridge->previous_size);
961 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
962 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
963 pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
964}
965
966
967static void intel_8xx_cleanup(void)
968{
969 u16 temp;
970 struct aper_size_info_8 *previous_size;
971
972 previous_size = A_SIZE_8(agp_bridge->previous_size);
973 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
974 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
975 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
976}
977
978
979static int intel_configure(void)
980{
981 u32 temp;
982 u16 temp2;
983 struct aper_size_info_16 *current_size;
984
985 current_size = A_SIZE_16(agp_bridge->current_size);
986
987 /* aperture size */
988 pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
989
990 /* address to map to */
991 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
992 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
993
994 /* attbase - aperture base */
995 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
996
997 /* agpctrl */
998 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
999
1000 /* paccfg/nbxcfg */
1001 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
1002 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,
1003 (temp2 & ~(1 << 10)) | (1 << 9));
1004 /* clear any possible error conditions */
1005 pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);
1006 return 0;
1007}
1008
1009static int intel_815_configure(void)
1010{
1011 u32 temp, addr;
1012 u8 temp2;
1013 struct aper_size_info_8 *current_size;
1014
1015 /* attbase - aperture base */
1016 /* the Intel 815 chipset spec. says that bits 29-31 in the
1017 * ATTBASE register are reserved -> try not to write them */
1018 if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {
1019 printk (KERN_EMERG PFX "gatt bus addr too high");
1020 return -EINVAL;
1021 }
1022
1023 current_size = A_SIZE_8(agp_bridge->current_size);
1024
1025 /* aperture size */
1026 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
1027 current_size->size_value);
1028
1029 /* address to map to */
1030 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1031 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1032
1033 pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr);
1034 addr &= INTEL_815_ATTBASE_MASK;
1035 addr |= agp_bridge->gatt_bus_addr;
1036 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, addr);
1037
1038 /* agpctrl */
1039 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1040
1041 /* apcont */
1042 pci_read_config_byte(agp_bridge->dev, INTEL_815_APCONT, &temp2);
1043 pci_write_config_byte(agp_bridge->dev, INTEL_815_APCONT, temp2 | (1 << 1));
1044
1045 /* clear any possible error conditions */
1046 /* Oddness : this chipset seems to have no ERRSTS register ! */
1047 return 0;
1048}
1049
1050static void intel_820_tlbflush(struct agp_memory *mem)
1051{
1052 return;
1053}
1054
1055static void intel_820_cleanup(void)
1056{
1057 u8 temp;
1058 struct aper_size_info_8 *previous_size;
1059
1060 previous_size = A_SIZE_8(agp_bridge->previous_size);
1061 pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp);
1062 pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR,
1063 temp & ~(1 << 1));
1064 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
1065 previous_size->size_value);
1066}
1067
1068
1069static int intel_820_configure(void)
1070{
1071 u32 temp;
1072 u8 temp2;
1073 struct aper_size_info_8 *current_size;
1074
1075 current_size = A_SIZE_8(agp_bridge->current_size);
1076
1077 /* aperture size */
1078 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1079
1080 /* address to map to */
1081 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1082 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1083
1084 /* attbase - aperture base */
1085 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1086
1087 /* agpctrl */
1088 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1089
1090 /* global enable aperture access */
1091 /* This flag is not accessed through MCHCFG register as in */
1092 /* i850 chipset. */
1093 pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp2);
1094 pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp2 | (1 << 1));
1095 /* clear any possible AGP-related error conditions */
1096 pci_write_config_word(agp_bridge->dev, INTEL_I820_ERRSTS, 0x001c);
1097 return 0;
1098}
1099
1100static int intel_840_configure(void)
1101{
1102 u32 temp;
1103 u16 temp2;
1104 struct aper_size_info_8 *current_size;
1105
1106 current_size = A_SIZE_8(agp_bridge->current_size);
1107
1108 /* aperture size */
1109 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1110
1111 /* address to map to */
1112 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1113 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1114
1115 /* attbase - aperture base */
1116 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1117
1118 /* agpctrl */
1119 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1120
1121 /* mcgcfg */
1122 pci_read_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, &temp2);
1123 pci_write_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));
1124 /* clear any possible error conditions */
1125 pci_write_config_word(agp_bridge->dev, INTEL_I840_ERRSTS, 0xc000);
1126 return 0;
1127}
1128
1129static int intel_845_configure(void)
1130{
1131 u32 temp;
1132 u8 temp2;
1133 struct aper_size_info_8 *current_size;
1134
1135 current_size = A_SIZE_8(agp_bridge->current_size);
1136
1137 /* aperture size */
1138 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1139
Matthew Garrettb0825482005-07-29 14:03:39 -07001140 if (agp_bridge->apbase_config != 0) {
1141 pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
1142 agp_bridge->apbase_config);
1143 } else {
1144 /* address to map to */
1145 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1146 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1147 agp_bridge->apbase_config = temp;
1148 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149
1150 /* attbase - aperture base */
1151 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1152
1153 /* agpctrl */
1154 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1155
1156 /* agpm */
1157 pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
1158 pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
1159 /* clear any possible error conditions */
1160 pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
1161 return 0;
1162}
1163
1164static int intel_850_configure(void)
1165{
1166 u32 temp;
1167 u16 temp2;
1168 struct aper_size_info_8 *current_size;
1169
1170 current_size = A_SIZE_8(agp_bridge->current_size);
1171
1172 /* aperture size */
1173 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1174
1175 /* address to map to */
1176 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1177 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1178
1179 /* attbase - aperture base */
1180 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1181
1182 /* agpctrl */
1183 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1184
1185 /* mcgcfg */
1186 pci_read_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, &temp2);
1187 pci_write_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));
1188 /* clear any possible AGP-related error conditions */
1189 pci_write_config_word(agp_bridge->dev, INTEL_I850_ERRSTS, 0x001c);
1190 return 0;
1191}
1192
1193static int intel_860_configure(void)
1194{
1195 u32 temp;
1196 u16 temp2;
1197 struct aper_size_info_8 *current_size;
1198
1199 current_size = A_SIZE_8(agp_bridge->current_size);
1200
1201 /* aperture size */
1202 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1203
1204 /* address to map to */
1205 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1206 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1207
1208 /* attbase - aperture base */
1209 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1210
1211 /* agpctrl */
1212 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1213
1214 /* mcgcfg */
1215 pci_read_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, &temp2);
1216 pci_write_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));
1217 /* clear any possible AGP-related error conditions */
1218 pci_write_config_word(agp_bridge->dev, INTEL_I860_ERRSTS, 0xf700);
1219 return 0;
1220}
1221
1222static int intel_830mp_configure(void)
1223{
1224 u32 temp;
1225 u16 temp2;
1226 struct aper_size_info_8 *current_size;
1227
1228 current_size = A_SIZE_8(agp_bridge->current_size);
1229
1230 /* aperture size */
1231 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1232
1233 /* address to map to */
1234 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1235 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1236
1237 /* attbase - aperture base */
1238 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1239
1240 /* agpctrl */
1241 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1242
1243 /* gmch */
1244 pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
1245 pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp2 | (1 << 9));
1246 /* clear any possible AGP-related error conditions */
1247 pci_write_config_word(agp_bridge->dev, INTEL_I830_ERRSTS, 0x1c);
1248 return 0;
1249}
1250
1251static int intel_7505_configure(void)
1252{
1253 u32 temp;
1254 u16 temp2;
1255 struct aper_size_info_8 *current_size;
1256
1257 current_size = A_SIZE_8(agp_bridge->current_size);
1258
1259 /* aperture size */
1260 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1261
1262 /* address to map to */
1263 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1264 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1265
1266 /* attbase - aperture base */
1267 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
1268
1269 /* agpctrl */
1270 pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
1271
1272 /* mchcfg */
1273 pci_read_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, &temp2);
1274 pci_write_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, temp2 | (1 << 9));
1275
1276 return 0;
1277}
1278
1279/* Setup function */
1280static struct gatt_mask intel_generic_masks[] =
1281{
1282 {.mask = 0x00000017, .type = 0}
1283};
1284
1285static struct aper_size_info_8 intel_815_sizes[2] =
1286{
1287 {64, 16384, 4, 0},
1288 {32, 8192, 3, 8},
1289};
1290
1291static struct aper_size_info_8 intel_8xx_sizes[7] =
1292{
1293 {256, 65536, 6, 0},
1294 {128, 32768, 5, 32},
1295 {64, 16384, 4, 48},
1296 {32, 8192, 3, 56},
1297 {16, 4096, 2, 60},
1298 {8, 2048, 1, 62},
1299 {4, 1024, 0, 63}
1300};
1301
1302static struct aper_size_info_16 intel_generic_sizes[7] =
1303{
1304 {256, 65536, 6, 0},
1305 {128, 32768, 5, 32},
1306 {64, 16384, 4, 48},
1307 {32, 8192, 3, 56},
1308 {16, 4096, 2, 60},
1309 {8, 2048, 1, 62},
1310 {4, 1024, 0, 63}
1311};
1312
1313static struct aper_size_info_8 intel_830mp_sizes[4] =
1314{
1315 {256, 65536, 6, 0},
1316 {128, 32768, 5, 32},
1317 {64, 16384, 4, 48},
1318 {32, 8192, 3, 56}
1319};
1320
1321static struct agp_bridge_driver intel_generic_driver = {
1322 .owner = THIS_MODULE,
1323 .aperture_sizes = intel_generic_sizes,
1324 .size_type = U16_APER_SIZE,
1325 .num_aperture_sizes = 7,
1326 .configure = intel_configure,
1327 .fetch_size = intel_fetch_size,
1328 .cleanup = intel_cleanup,
1329 .tlb_flush = intel_tlbflush,
1330 .mask_memory = agp_generic_mask_memory,
1331 .masks = intel_generic_masks,
1332 .agp_enable = agp_generic_enable,
1333 .cache_flush = global_cache_flush,
1334 .create_gatt_table = agp_generic_create_gatt_table,
1335 .free_gatt_table = agp_generic_free_gatt_table,
1336 .insert_memory = agp_generic_insert_memory,
1337 .remove_memory = agp_generic_remove_memory,
1338 .alloc_by_type = agp_generic_alloc_by_type,
1339 .free_by_type = agp_generic_free_by_type,
1340 .agp_alloc_page = agp_generic_alloc_page,
1341 .agp_destroy_page = agp_generic_destroy_page,
1342};
1343
1344static struct agp_bridge_driver intel_810_driver = {
1345 .owner = THIS_MODULE,
1346 .aperture_sizes = intel_i810_sizes,
1347 .size_type = FIXED_APER_SIZE,
1348 .num_aperture_sizes = 2,
1349 .needs_scratch_page = TRUE,
1350 .configure = intel_i810_configure,
1351 .fetch_size = intel_i810_fetch_size,
1352 .cleanup = intel_i810_cleanup,
1353 .tlb_flush = intel_i810_tlbflush,
1354 .mask_memory = intel_i810_mask_memory,
1355 .masks = intel_i810_masks,
1356 .agp_enable = intel_i810_agp_enable,
1357 .cache_flush = global_cache_flush,
1358 .create_gatt_table = agp_generic_create_gatt_table,
1359 .free_gatt_table = agp_generic_free_gatt_table,
1360 .insert_memory = intel_i810_insert_entries,
1361 .remove_memory = intel_i810_remove_entries,
1362 .alloc_by_type = intel_i810_alloc_by_type,
1363 .free_by_type = intel_i810_free_by_type,
1364 .agp_alloc_page = agp_generic_alloc_page,
1365 .agp_destroy_page = agp_generic_destroy_page,
1366};
1367
1368static struct agp_bridge_driver intel_815_driver = {
1369 .owner = THIS_MODULE,
1370 .aperture_sizes = intel_815_sizes,
1371 .size_type = U8_APER_SIZE,
1372 .num_aperture_sizes = 2,
1373 .configure = intel_815_configure,
1374 .fetch_size = intel_815_fetch_size,
1375 .cleanup = intel_8xx_cleanup,
1376 .tlb_flush = intel_8xx_tlbflush,
1377 .mask_memory = agp_generic_mask_memory,
1378 .masks = intel_generic_masks,
1379 .agp_enable = agp_generic_enable,
1380 .cache_flush = global_cache_flush,
1381 .create_gatt_table = agp_generic_create_gatt_table,
1382 .free_gatt_table = agp_generic_free_gatt_table,
1383 .insert_memory = agp_generic_insert_memory,
1384 .remove_memory = agp_generic_remove_memory,
1385 .alloc_by_type = agp_generic_alloc_by_type,
1386 .free_by_type = agp_generic_free_by_type,
1387 .agp_alloc_page = agp_generic_alloc_page,
1388 .agp_destroy_page = agp_generic_destroy_page,
1389};
1390
1391static struct agp_bridge_driver intel_830_driver = {
1392 .owner = THIS_MODULE,
1393 .aperture_sizes = intel_i830_sizes,
1394 .size_type = FIXED_APER_SIZE,
Dave Jonesc14635e2006-09-06 11:59:35 -04001395 .num_aperture_sizes = 4,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 .needs_scratch_page = TRUE,
1397 .configure = intel_i830_configure,
1398 .fetch_size = intel_i830_fetch_size,
1399 .cleanup = intel_i830_cleanup,
1400 .tlb_flush = intel_i810_tlbflush,
1401 .mask_memory = intel_i810_mask_memory,
1402 .masks = intel_i810_masks,
1403 .agp_enable = intel_i810_agp_enable,
1404 .cache_flush = global_cache_flush,
1405 .create_gatt_table = intel_i830_create_gatt_table,
1406 .free_gatt_table = intel_i830_free_gatt_table,
1407 .insert_memory = intel_i830_insert_entries,
1408 .remove_memory = intel_i830_remove_entries,
1409 .alloc_by_type = intel_i830_alloc_by_type,
1410 .free_by_type = intel_i810_free_by_type,
1411 .agp_alloc_page = agp_generic_alloc_page,
1412 .agp_destroy_page = agp_generic_destroy_page,
1413};
1414
1415static struct agp_bridge_driver intel_820_driver = {
1416 .owner = THIS_MODULE,
1417 .aperture_sizes = intel_8xx_sizes,
1418 .size_type = U8_APER_SIZE,
1419 .num_aperture_sizes = 7,
1420 .configure = intel_820_configure,
1421 .fetch_size = intel_8xx_fetch_size,
1422 .cleanup = intel_820_cleanup,
1423 .tlb_flush = intel_820_tlbflush,
1424 .mask_memory = agp_generic_mask_memory,
1425 .masks = intel_generic_masks,
1426 .agp_enable = agp_generic_enable,
1427 .cache_flush = global_cache_flush,
1428 .create_gatt_table = agp_generic_create_gatt_table,
1429 .free_gatt_table = agp_generic_free_gatt_table,
1430 .insert_memory = agp_generic_insert_memory,
1431 .remove_memory = agp_generic_remove_memory,
1432 .alloc_by_type = agp_generic_alloc_by_type,
1433 .free_by_type = agp_generic_free_by_type,
1434 .agp_alloc_page = agp_generic_alloc_page,
1435 .agp_destroy_page = agp_generic_destroy_page,
1436};
1437
1438static struct agp_bridge_driver intel_830mp_driver = {
1439 .owner = THIS_MODULE,
1440 .aperture_sizes = intel_830mp_sizes,
1441 .size_type = U8_APER_SIZE,
1442 .num_aperture_sizes = 4,
1443 .configure = intel_830mp_configure,
1444 .fetch_size = intel_8xx_fetch_size,
1445 .cleanup = intel_8xx_cleanup,
1446 .tlb_flush = intel_8xx_tlbflush,
1447 .mask_memory = agp_generic_mask_memory,
1448 .masks = intel_generic_masks,
1449 .agp_enable = agp_generic_enable,
1450 .cache_flush = global_cache_flush,
1451 .create_gatt_table = agp_generic_create_gatt_table,
1452 .free_gatt_table = agp_generic_free_gatt_table,
1453 .insert_memory = agp_generic_insert_memory,
1454 .remove_memory = agp_generic_remove_memory,
1455 .alloc_by_type = agp_generic_alloc_by_type,
1456 .free_by_type = agp_generic_free_by_type,
1457 .agp_alloc_page = agp_generic_alloc_page,
1458 .agp_destroy_page = agp_generic_destroy_page,
1459};
1460
1461static struct agp_bridge_driver intel_840_driver = {
1462 .owner = THIS_MODULE,
1463 .aperture_sizes = intel_8xx_sizes,
1464 .size_type = U8_APER_SIZE,
1465 .num_aperture_sizes = 7,
1466 .configure = intel_840_configure,
1467 .fetch_size = intel_8xx_fetch_size,
1468 .cleanup = intel_8xx_cleanup,
1469 .tlb_flush = intel_8xx_tlbflush,
1470 .mask_memory = agp_generic_mask_memory,
1471 .masks = intel_generic_masks,
1472 .agp_enable = agp_generic_enable,
1473 .cache_flush = global_cache_flush,
1474 .create_gatt_table = agp_generic_create_gatt_table,
1475 .free_gatt_table = agp_generic_free_gatt_table,
1476 .insert_memory = agp_generic_insert_memory,
1477 .remove_memory = agp_generic_remove_memory,
1478 .alloc_by_type = agp_generic_alloc_by_type,
1479 .free_by_type = agp_generic_free_by_type,
1480 .agp_alloc_page = agp_generic_alloc_page,
1481 .agp_destroy_page = agp_generic_destroy_page,
1482};
1483
1484static struct agp_bridge_driver intel_845_driver = {
1485 .owner = THIS_MODULE,
1486 .aperture_sizes = intel_8xx_sizes,
1487 .size_type = U8_APER_SIZE,
1488 .num_aperture_sizes = 7,
1489 .configure = intel_845_configure,
1490 .fetch_size = intel_8xx_fetch_size,
1491 .cleanup = intel_8xx_cleanup,
1492 .tlb_flush = intel_8xx_tlbflush,
1493 .mask_memory = agp_generic_mask_memory,
1494 .masks = intel_generic_masks,
1495 .agp_enable = agp_generic_enable,
1496 .cache_flush = global_cache_flush,
1497 .create_gatt_table = agp_generic_create_gatt_table,
1498 .free_gatt_table = agp_generic_free_gatt_table,
1499 .insert_memory = agp_generic_insert_memory,
1500 .remove_memory = agp_generic_remove_memory,
1501 .alloc_by_type = agp_generic_alloc_by_type,
1502 .free_by_type = agp_generic_free_by_type,
1503 .agp_alloc_page = agp_generic_alloc_page,
1504 .agp_destroy_page = agp_generic_destroy_page,
1505};
1506
1507static struct agp_bridge_driver intel_850_driver = {
1508 .owner = THIS_MODULE,
1509 .aperture_sizes = intel_8xx_sizes,
1510 .size_type = U8_APER_SIZE,
1511 .num_aperture_sizes = 7,
1512 .configure = intel_850_configure,
1513 .fetch_size = intel_8xx_fetch_size,
1514 .cleanup = intel_8xx_cleanup,
1515 .tlb_flush = intel_8xx_tlbflush,
1516 .mask_memory = agp_generic_mask_memory,
1517 .masks = intel_generic_masks,
1518 .agp_enable = agp_generic_enable,
1519 .cache_flush = global_cache_flush,
1520 .create_gatt_table = agp_generic_create_gatt_table,
1521 .free_gatt_table = agp_generic_free_gatt_table,
1522 .insert_memory = agp_generic_insert_memory,
1523 .remove_memory = agp_generic_remove_memory,
1524 .alloc_by_type = agp_generic_alloc_by_type,
1525 .free_by_type = agp_generic_free_by_type,
1526 .agp_alloc_page = agp_generic_alloc_page,
1527 .agp_destroy_page = agp_generic_destroy_page,
1528};
1529
1530static struct agp_bridge_driver intel_860_driver = {
1531 .owner = THIS_MODULE,
1532 .aperture_sizes = intel_8xx_sizes,
1533 .size_type = U8_APER_SIZE,
1534 .num_aperture_sizes = 7,
1535 .configure = intel_860_configure,
1536 .fetch_size = intel_8xx_fetch_size,
1537 .cleanup = intel_8xx_cleanup,
1538 .tlb_flush = intel_8xx_tlbflush,
1539 .mask_memory = agp_generic_mask_memory,
1540 .masks = intel_generic_masks,
1541 .agp_enable = agp_generic_enable,
1542 .cache_flush = global_cache_flush,
1543 .create_gatt_table = agp_generic_create_gatt_table,
1544 .free_gatt_table = agp_generic_free_gatt_table,
1545 .insert_memory = agp_generic_insert_memory,
1546 .remove_memory = agp_generic_remove_memory,
1547 .alloc_by_type = agp_generic_alloc_by_type,
1548 .free_by_type = agp_generic_free_by_type,
1549 .agp_alloc_page = agp_generic_alloc_page,
1550 .agp_destroy_page = agp_generic_destroy_page,
1551};
1552
1553static struct agp_bridge_driver intel_915_driver = {
1554 .owner = THIS_MODULE,
1555 .aperture_sizes = intel_i830_sizes,
1556 .size_type = FIXED_APER_SIZE,
Dave Jonesc14635e2006-09-06 11:59:35 -04001557 .num_aperture_sizes = 4,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558 .needs_scratch_page = TRUE,
1559 .configure = intel_i915_configure,
1560 .fetch_size = intel_i915_fetch_size,
1561 .cleanup = intel_i915_cleanup,
1562 .tlb_flush = intel_i810_tlbflush,
1563 .mask_memory = intel_i810_mask_memory,
1564 .masks = intel_i810_masks,
1565 .agp_enable = intel_i810_agp_enable,
1566 .cache_flush = global_cache_flush,
1567 .create_gatt_table = intel_i915_create_gatt_table,
1568 .free_gatt_table = intel_i830_free_gatt_table,
1569 .insert_memory = intel_i915_insert_entries,
1570 .remove_memory = intel_i915_remove_entries,
1571 .alloc_by_type = intel_i830_alloc_by_type,
1572 .free_by_type = intel_i810_free_by_type,
1573 .agp_alloc_page = agp_generic_alloc_page,
1574 .agp_destroy_page = agp_generic_destroy_page,
1575};
1576
Eric Anholt65c25aa2006-09-06 11:57:18 -04001577static struct agp_bridge_driver intel_i965_driver = {
1578 .owner = THIS_MODULE,
1579 .aperture_sizes = intel_i830_sizes,
1580 .size_type = FIXED_APER_SIZE,
1581 .num_aperture_sizes = 4,
1582 .needs_scratch_page = TRUE,
1583 .configure = intel_i915_configure,
1584 .fetch_size = intel_i965_fetch_size,
1585 .cleanup = intel_i915_cleanup,
1586 .tlb_flush = intel_i810_tlbflush,
1587 .mask_memory = intel_i810_mask_memory,
1588 .masks = intel_i810_masks,
1589 .agp_enable = intel_i810_agp_enable,
1590 .cache_flush = global_cache_flush,
1591 .create_gatt_table = intel_i965_create_gatt_table,
1592 .free_gatt_table = intel_i830_free_gatt_table,
1593 .insert_memory = intel_i915_insert_entries,
1594 .remove_memory = intel_i915_remove_entries,
1595 .alloc_by_type = intel_i830_alloc_by_type,
1596 .free_by_type = intel_i810_free_by_type,
1597 .agp_alloc_page = agp_generic_alloc_page,
1598 .agp_destroy_page = agp_generic_destroy_page,
1599};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600
1601static struct agp_bridge_driver intel_7505_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_7505_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,
1622};
1623
1624static int find_i810(u16 device)
1625{
1626 struct pci_dev *i810_dev;
1627
1628 i810_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
1629 if (!i810_dev)
1630 return 0;
1631 intel_i810_private.i810_dev = i810_dev;
1632 return 1;
1633}
1634
1635static int find_i830(u16 device)
1636{
1637 struct pci_dev *i830_dev;
1638
1639 i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
1640 if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
1641 i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
1642 device, i830_dev);
1643 }
1644
1645 if (!i830_dev)
1646 return 0;
1647
1648 intel_i830_private.i830_dev = i830_dev;
1649 return 1;
1650}
1651
1652static int __devinit agp_intel_probe(struct pci_dev *pdev,
1653 const struct pci_device_id *ent)
1654{
1655 struct agp_bridge_data *bridge;
1656 char *name = "(unknown)";
1657 u8 cap_ptr = 0;
1658 struct resource *r;
1659
1660 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
1661
1662 bridge = agp_alloc_bridge();
1663 if (!bridge)
1664 return -ENOMEM;
1665
1666 switch (pdev->device) {
1667 case PCI_DEVICE_ID_INTEL_82443LX_0:
1668 bridge->driver = &intel_generic_driver;
1669 name = "440LX";
1670 break;
1671 case PCI_DEVICE_ID_INTEL_82443BX_0:
1672 bridge->driver = &intel_generic_driver;
1673 name = "440BX";
1674 break;
1675 case PCI_DEVICE_ID_INTEL_82443GX_0:
1676 bridge->driver = &intel_generic_driver;
1677 name = "440GX";
1678 break;
1679 case PCI_DEVICE_ID_INTEL_82810_MC1:
1680 name = "i810";
1681 if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG1))
1682 goto fail;
1683 bridge->driver = &intel_810_driver;
1684 break;
1685 case PCI_DEVICE_ID_INTEL_82810_MC3:
1686 name = "i810 DC100";
1687 if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG3))
1688 goto fail;
1689 bridge->driver = &intel_810_driver;
1690 break;
1691 case PCI_DEVICE_ID_INTEL_82810E_MC:
1692 name = "i810 E";
1693 if (!find_i810(PCI_DEVICE_ID_INTEL_82810E_IG))
1694 goto fail;
1695 bridge->driver = &intel_810_driver;
1696 break;
1697 case PCI_DEVICE_ID_INTEL_82815_MC:
1698 /*
1699 * The i815 can operate either as an i810 style
1700 * integrated device, or as an AGP4X motherboard.
1701 */
1702 if (find_i810(PCI_DEVICE_ID_INTEL_82815_CGC))
1703 bridge->driver = &intel_810_driver;
1704 else
1705 bridge->driver = &intel_815_driver;
1706 name = "i815";
1707 break;
1708 case PCI_DEVICE_ID_INTEL_82820_HB:
1709 case PCI_DEVICE_ID_INTEL_82820_UP_HB:
1710 bridge->driver = &intel_820_driver;
1711 name = "i820";
1712 break;
1713 case PCI_DEVICE_ID_INTEL_82830_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001714 if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 bridge->driver = &intel_830_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001716 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 bridge->driver = &intel_830mp_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 name = "830M";
1719 break;
1720 case PCI_DEVICE_ID_INTEL_82840_HB:
1721 bridge->driver = &intel_840_driver;
1722 name = "i840";
1723 break;
1724 case PCI_DEVICE_ID_INTEL_82845_HB:
1725 bridge->driver = &intel_845_driver;
1726 name = "i845";
1727 break;
1728 case PCI_DEVICE_ID_INTEL_82845G_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001729 if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 bridge->driver = &intel_830_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001731 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 bridge->driver = &intel_845_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 name = "845G";
1734 break;
1735 case PCI_DEVICE_ID_INTEL_82850_HB:
1736 bridge->driver = &intel_850_driver;
1737 name = "i850";
1738 break;
1739 case PCI_DEVICE_ID_INTEL_82855PM_HB:
1740 bridge->driver = &intel_845_driver;
1741 name = "855PM";
1742 break;
1743 case PCI_DEVICE_ID_INTEL_82855GM_HB:
1744 if (find_i830(PCI_DEVICE_ID_INTEL_82855GM_IG)) {
1745 bridge->driver = &intel_830_driver;
1746 name = "855";
1747 } else {
1748 bridge->driver = &intel_845_driver;
1749 name = "855GM";
1750 }
1751 break;
1752 case PCI_DEVICE_ID_INTEL_82860_HB:
1753 bridge->driver = &intel_860_driver;
1754 name = "i860";
1755 break;
1756 case PCI_DEVICE_ID_INTEL_82865_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001757 if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 bridge->driver = &intel_830_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001759 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 bridge->driver = &intel_845_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 name = "865";
1762 break;
1763 case PCI_DEVICE_ID_INTEL_82875_HB:
1764 bridge->driver = &intel_845_driver;
1765 name = "i875";
1766 break;
1767 case PCI_DEVICE_ID_INTEL_82915G_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001768 if (find_i830(PCI_DEVICE_ID_INTEL_82915G_IG))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 bridge->driver = &intel_915_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001770 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 bridge->driver = &intel_845_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 name = "915G";
1773 break;
1774 case PCI_DEVICE_ID_INTEL_82915GM_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001775 if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 bridge->driver = &intel_915_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001777 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 bridge->driver = &intel_845_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 name = "915GM";
1780 break;
Alan Hourihaned0de98f2005-05-31 19:50:49 +01001781 case PCI_DEVICE_ID_INTEL_82945G_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001782 if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG))
Alan Hourihaned0de98f2005-05-31 19:50:49 +01001783 bridge->driver = &intel_915_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001784 else
Alan Hourihaned0de98f2005-05-31 19:50:49 +01001785 bridge->driver = &intel_845_driver;
Alan Hourihaned0de98f2005-05-31 19:50:49 +01001786 name = "945G";
1787 break;
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00001788 case PCI_DEVICE_ID_INTEL_82945GM_HB:
Dave Jones6a92a4e2006-02-28 00:54:25 -05001789 if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG))
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00001790 bridge->driver = &intel_915_driver;
Dave Jones6a92a4e2006-02-28 00:54:25 -05001791 else
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00001792 bridge->driver = &intel_845_driver;
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00001793 name = "945GM";
1794 break;
Eric Anholt65c25aa2006-09-06 11:57:18 -04001795 case PCI_DEVICE_ID_INTEL_82946GZ_HB:
1796 if (find_i830(PCI_DEVICE_ID_INTEL_82946GZ_IG))
1797 bridge->driver = &intel_i965_driver;
1798 else
1799 bridge->driver = &intel_845_driver;
1800 name = "946GZ";
1801 break;
1802 case PCI_DEVICE_ID_INTEL_82965G_1_HB:
1803 if (find_i830(PCI_DEVICE_ID_INTEL_82965G_1_IG))
1804 bridge->driver = &intel_i965_driver;
1805 else
1806 bridge->driver = &intel_845_driver;
1807 name = "965G";
1808 break;
1809 case PCI_DEVICE_ID_INTEL_82965Q_HB:
1810 if (find_i830(PCI_DEVICE_ID_INTEL_82965Q_IG))
1811 bridge->driver = &intel_i965_driver;
1812 else
1813 bridge->driver = &intel_845_driver;
1814 name = "965Q";
1815 break;
1816 case PCI_DEVICE_ID_INTEL_82965G_HB:
1817 if (find_i830(PCI_DEVICE_ID_INTEL_82965G_IG))
1818 bridge->driver = &intel_i965_driver;
1819 else
1820 bridge->driver = &intel_845_driver;
1821 name = "965G";
1822 break;
1823
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 case PCI_DEVICE_ID_INTEL_7505_0:
1825 bridge->driver = &intel_7505_driver;
1826 name = "E7505";
1827 break;
1828 case PCI_DEVICE_ID_INTEL_7205_0:
1829 bridge->driver = &intel_7505_driver;
1830 name = "E7205";
1831 break;
1832 default:
1833 if (cap_ptr)
1834 printk(KERN_WARNING PFX "Unsupported Intel chipset (device id: %04x)\n",
1835 pdev->device);
1836 agp_put_bridge(bridge);
1837 return -ENODEV;
1838 };
1839
1840 bridge->dev = pdev;
1841 bridge->capndx = cap_ptr;
1842
1843 if (bridge->driver == &intel_810_driver)
1844 bridge->dev_private_data = &intel_i810_private;
1845 else if (bridge->driver == &intel_830_driver)
1846 bridge->dev_private_data = &intel_i830_private;
1847
1848 printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
1849
1850 /*
1851 * The following fixes the case where the BIOS has "forgotten" to
1852 * provide an address range for the GART.
1853 * 20030610 - hamish@zot.org
1854 */
1855 r = &pdev->resource[0];
1856 if (!r->start && r->end) {
Dave Jones6a92a4e2006-02-28 00:54:25 -05001857 if (pci_assign_resource(pdev, 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 printk(KERN_ERR PFX "could not assign resource 0\n");
1859 agp_put_bridge(bridge);
1860 return -ENODEV;
1861 }
1862 }
1863
1864 /*
1865 * If the device has not been properly setup, the following will catch
1866 * the problem and should stop the system from crashing.
1867 * 20030610 - hamish@zot.org
1868 */
1869 if (pci_enable_device(pdev)) {
1870 printk(KERN_ERR PFX "Unable to Enable PCI device\n");
1871 agp_put_bridge(bridge);
1872 return -ENODEV;
1873 }
1874
1875 /* Fill in the mode register */
1876 if (cap_ptr) {
1877 pci_read_config_dword(pdev,
1878 bridge->capndx+PCI_AGP_STATUS,
1879 &bridge->mode);
1880 }
1881
1882 pci_set_drvdata(pdev, bridge);
1883 return agp_add_bridge(bridge);
1884
1885fail:
1886 printk(KERN_ERR PFX "Detected an Intel %s chipset, "
1887 "but could not find the secondary device.\n", name);
1888 agp_put_bridge(bridge);
1889 return -ENODEV;
1890}
1891
1892static void __devexit agp_intel_remove(struct pci_dev *pdev)
1893{
1894 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
1895
1896 agp_remove_bridge(bridge);
1897
1898 if (intel_i810_private.i810_dev)
1899 pci_dev_put(intel_i810_private.i810_dev);
1900 if (intel_i830_private.i830_dev)
1901 pci_dev_put(intel_i830_private.i830_dev);
1902
1903 agp_put_bridge(bridge);
1904}
1905
Alexey Dobriyan85be7d62006-08-12 02:02:02 +04001906#ifdef CONFIG_PM
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907static int agp_intel_resume(struct pci_dev *pdev)
1908{
1909 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
1910
1911 pci_restore_state(pdev);
1912
1913 if (bridge->driver == &intel_generic_driver)
1914 intel_configure();
1915 else if (bridge->driver == &intel_850_driver)
1916 intel_850_configure();
1917 else if (bridge->driver == &intel_845_driver)
1918 intel_845_configure();
1919 else if (bridge->driver == &intel_830mp_driver)
1920 intel_830mp_configure();
1921 else if (bridge->driver == &intel_915_driver)
1922 intel_i915_configure();
1923 else if (bridge->driver == &intel_830_driver)
1924 intel_i830_configure();
1925 else if (bridge->driver == &intel_810_driver)
1926 intel_i810_configure();
Dave Jones08da3f42006-09-10 21:09:26 -04001927 else if (bridge->driver == &intel_i965_driver)
1928 intel_i915_configure();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929
1930 return 0;
1931}
Alexey Dobriyan85be7d62006-08-12 02:02:02 +04001932#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
1934static struct pci_device_id agp_intel_pci_table[] = {
1935#define ID(x) \
1936 { \
1937 .class = (PCI_CLASS_BRIDGE_HOST << 8), \
1938 .class_mask = ~0, \
1939 .vendor = PCI_VENDOR_ID_INTEL, \
1940 .device = x, \
1941 .subvendor = PCI_ANY_ID, \
1942 .subdevice = PCI_ANY_ID, \
1943 }
1944 ID(PCI_DEVICE_ID_INTEL_82443LX_0),
1945 ID(PCI_DEVICE_ID_INTEL_82443BX_0),
1946 ID(PCI_DEVICE_ID_INTEL_82443GX_0),
1947 ID(PCI_DEVICE_ID_INTEL_82810_MC1),
1948 ID(PCI_DEVICE_ID_INTEL_82810_MC3),
1949 ID(PCI_DEVICE_ID_INTEL_82810E_MC),
1950 ID(PCI_DEVICE_ID_INTEL_82815_MC),
1951 ID(PCI_DEVICE_ID_INTEL_82820_HB),
1952 ID(PCI_DEVICE_ID_INTEL_82820_UP_HB),
1953 ID(PCI_DEVICE_ID_INTEL_82830_HB),
1954 ID(PCI_DEVICE_ID_INTEL_82840_HB),
1955 ID(PCI_DEVICE_ID_INTEL_82845_HB),
1956 ID(PCI_DEVICE_ID_INTEL_82845G_HB),
1957 ID(PCI_DEVICE_ID_INTEL_82850_HB),
1958 ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
1959 ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
1960 ID(PCI_DEVICE_ID_INTEL_82860_HB),
1961 ID(PCI_DEVICE_ID_INTEL_82865_HB),
1962 ID(PCI_DEVICE_ID_INTEL_82875_HB),
1963 ID(PCI_DEVICE_ID_INTEL_7505_0),
1964 ID(PCI_DEVICE_ID_INTEL_7205_0),
1965 ID(PCI_DEVICE_ID_INTEL_82915G_HB),
1966 ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
Alan Hourihaned0de98f2005-05-31 19:50:49 +01001967 ID(PCI_DEVICE_ID_INTEL_82945G_HB),
Alan Hourihane3b0e8ea2006-01-19 14:08:40 +00001968 ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
Eric Anholt65c25aa2006-09-06 11:57:18 -04001969 ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
1970 ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
1971 ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
1972 ID(PCI_DEVICE_ID_INTEL_82965G_HB),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973 { }
1974};
1975
1976MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
1977
1978static struct pci_driver agp_intel_pci_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979 .name = "agpgart-intel",
1980 .id_table = agp_intel_pci_table,
1981 .probe = agp_intel_probe,
1982 .remove = __devexit_p(agp_intel_remove),
Alexey Dobriyan85be7d62006-08-12 02:02:02 +04001983#ifdef CONFIG_PM
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 .resume = agp_intel_resume,
Alexey Dobriyan85be7d62006-08-12 02:02:02 +04001985#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986};
1987
1988static int __init agp_intel_init(void)
1989{
1990 if (agp_off)
1991 return -EINVAL;
1992 return pci_register_driver(&agp_intel_pci_driver);
1993}
1994
1995static void __exit agp_intel_cleanup(void)
1996{
1997 pci_unregister_driver(&agp_intel_pci_driver);
1998}
1999
2000module_init(agp_intel_init);
2001module_exit(agp_intel_cleanup);
2002
2003MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
2004MODULE_LICENSE("GPL and additional rights");