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