aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/agp')
-rw-r--r--drivers/char/agp/Kconfig4
-rw-r--r--drivers/char/agp/agp.h4
-rw-r--r--drivers/char/agp/amd-k7-agp.c5
-rw-r--r--drivers/char/agp/amd64-agp.c9
-rw-r--r--drivers/char/agp/ati-agp.c36
-rw-r--r--drivers/char/agp/generic.c36
-rw-r--r--drivers/char/agp/intel-agp.c181
-rw-r--r--drivers/char/agp/sgi-agp.c9
-rw-r--r--drivers/char/agp/via-agp.c21
9 files changed, 204 insertions, 101 deletions
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index c603bf291580..a9f9c48c2424 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -86,7 +86,7 @@ config AGP_NVIDIA
86 86
87config AGP_SIS 87config AGP_SIS
88 tristate "SiS chipset support" 88 tristate "SiS chipset support"
89 depends on AGP 89 depends on AGP && X86
90 help 90 help
91 This option gives you AGP support for the GLX component of 91 This option gives you AGP support for the GLX component of
92 X on Silicon Integrated Systems [SiS] chipsets. 92 X on Silicon Integrated Systems [SiS] chipsets.
@@ -103,7 +103,7 @@ config AGP_SWORKS
103 103
104config AGP_VIA 104config AGP_VIA
105 tristate "VIA chipset support" 105 tristate "VIA chipset support"
106 depends on AGP 106 depends on AGP && X86
107 help 107 help
108 This option gives you AGP support for the GLX component of 108 This option gives you AGP support for the GLX component of
109 X on VIA MVP3/Apollo Pro chipsets. 109 X on VIA MVP3/Apollo Pro chipsets.
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 8b3317fd46c9..1d59e2a5b9aa 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -225,6 +225,10 @@ struct agp_bridge_data {
225#define I810_GMS_DISABLE 0x00000000 225#define I810_GMS_DISABLE 0x00000000
226#define I810_PGETBL_CTL 0x2020 226#define I810_PGETBL_CTL 0x2020
227#define I810_PGETBL_ENABLED 0x00000001 227#define I810_PGETBL_ENABLED 0x00000001
228#define I965_PGETBL_SIZE_MASK 0x0000000e
229#define I965_PGETBL_SIZE_512KB (0 << 1)
230#define I965_PGETBL_SIZE_256KB (1 << 1)
231#define I965_PGETBL_SIZE_128KB (2 << 1)
228#define I810_DRAM_CTL 0x3000 232#define I810_DRAM_CTL 0x3000
229#define I810_DRAM_ROW_0 0x00000001 233#define I810_DRAM_ROW_0 0x00000001
230#define I810_DRAM_ROW_0_SDRAM 0x00000001 234#define I810_DRAM_ROW_0_SDRAM 0x00000001
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 51d0d562d01e..c85c8cadb6df 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -101,6 +101,11 @@ static int amd_create_gatt_pages(int nr_tables)
101 for (i = 0; i < nr_tables; i++) { 101 for (i = 0; i < nr_tables; i++) {
102 entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL); 102 entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL);
103 if (entry == NULL) { 103 if (entry == NULL) {
104 while (i > 0) {
105 kfree(tables[i-1]);
106 i--;
107 }
108 kfree(tables);
104 retval = -ENOMEM; 109 retval = -ENOMEM;
105 break; 110 break;
106 } 111 }
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 2f2c4efff8a3..93d2209fee4c 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -650,6 +650,15 @@ static struct pci_device_id agp_amd64_pci_table[] = {
650 .subvendor = PCI_ANY_ID, 650 .subvendor = PCI_ANY_ID,
651 .subdevice = PCI_ANY_ID, 651 .subdevice = PCI_ANY_ID,
652 }, 652 },
653 /* VIA K8M890 / K8N890 */
654 {
655 .class = (PCI_CLASS_BRIDGE_HOST << 8),
656 .class_mask = ~0,
657 .vendor = PCI_VENDOR_ID_VIA,
658 .device = PCI_DEVICE_ID_VIA_VT3336,
659 .subvendor = PCI_ANY_ID,
660 .subdevice = PCI_ANY_ID,
661 },
653 /* VIA K8T890 */ 662 /* VIA K8T890 */
654 { 663 {
655 .class = (PCI_CLASS_BRIDGE_HOST << 8), 664 .class = (PCI_CLASS_BRIDGE_HOST << 8),
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index f244c6682738..9987dc2e0c3f 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -41,18 +41,18 @@ static struct gatt_mask ati_generic_masks[] =
41}; 41};
42 42
43 43
44typedef struct _ati_page_map { 44struct ati_page_map {
45 unsigned long *real; 45 unsigned long *real;
46 unsigned long __iomem *remapped; 46 unsigned long __iomem *remapped;
47} ati_page_map; 47};
48 48
49static struct _ati_generic_private { 49static struct _ati_generic_private {
50 volatile u8 __iomem *registers; 50 volatile u8 __iomem *registers;
51 ati_page_map **gatt_pages; 51 struct ati_page_map **gatt_pages;
52 int num_tables; 52 int num_tables;
53} ati_generic_private; 53} ati_generic_private;
54 54
55static int ati_create_page_map(ati_page_map *page_map) 55static int ati_create_page_map(struct ati_page_map *page_map)
56{ 56{
57 int i, err = 0; 57 int i, err = 0;
58 58
@@ -82,7 +82,7 @@ static int ati_create_page_map(ati_page_map *page_map)
82} 82}
83 83
84 84
85static void ati_free_page_map(ati_page_map *page_map) 85static void ati_free_page_map(struct ati_page_map *page_map)
86{ 86{
87 unmap_page_from_agp(virt_to_page(page_map->real)); 87 unmap_page_from_agp(virt_to_page(page_map->real));
88 iounmap(page_map->remapped); 88 iounmap(page_map->remapped);
@@ -94,8 +94,8 @@ static void ati_free_page_map(ati_page_map *page_map)
94static void ati_free_gatt_pages(void) 94static void ati_free_gatt_pages(void)
95{ 95{
96 int i; 96 int i;
97 ati_page_map **tables; 97 struct ati_page_map **tables;
98 ati_page_map *entry; 98 struct ati_page_map *entry;
99 99
100 tables = ati_generic_private.gatt_pages; 100 tables = ati_generic_private.gatt_pages;
101 for (i = 0; i < ati_generic_private.num_tables; i++) { 101 for (i = 0; i < ati_generic_private.num_tables; i++) {
@@ -112,30 +112,30 @@ static void ati_free_gatt_pages(void)
112 112
113static int ati_create_gatt_pages(int nr_tables) 113static int ati_create_gatt_pages(int nr_tables)
114{ 114{
115 ati_page_map **tables; 115 struct ati_page_map **tables;
116 ati_page_map *entry; 116 struct ati_page_map *entry;
117 int retval = 0; 117 int retval = 0;
118 int i; 118 int i;
119 119
120 tables = kzalloc((nr_tables + 1) * sizeof(ati_page_map *),GFP_KERNEL); 120 tables = kzalloc((nr_tables + 1) * sizeof(struct ati_page_map *),GFP_KERNEL);
121 if (tables == NULL) 121 if (tables == NULL)
122 return -ENOMEM; 122 return -ENOMEM;
123 123
124 for (i = 0; i < nr_tables; i++) { 124 for (i = 0; i < nr_tables; i++) {
125 entry = kzalloc(sizeof(ati_page_map), GFP_KERNEL); 125 entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL);
126 if (entry == NULL) { 126 if (entry == NULL) {
127 while (i>0) { 127 while (i > 0) {
128 kfree (tables[i-1]); 128 kfree(tables[i-1]);
129 i--; 129 i--;
130 } 130 }
131 kfree (tables); 131 kfree(tables);
132 tables = NULL;
133 retval = -ENOMEM; 132 retval = -ENOMEM;
134 break; 133 break;
135 } 134 }
136 tables[i] = entry; 135 tables[i] = entry;
137 retval = ati_create_page_map(entry); 136 retval = ati_create_page_map(entry);
138 if (retval != 0) break; 137 if (retval != 0)
138 break;
139 } 139 }
140 ati_generic_private.num_tables = nr_tables; 140 ati_generic_private.num_tables = nr_tables;
141 ati_generic_private.gatt_pages = tables; 141 ati_generic_private.gatt_pages = tables;
@@ -340,7 +340,7 @@ static int ati_remove_memory(struct agp_memory * mem, off_t pg_start,
340static int ati_create_gatt_table(struct agp_bridge_data *bridge) 340static int ati_create_gatt_table(struct agp_bridge_data *bridge)
341{ 341{
342 struct aper_size_info_lvl2 *value; 342 struct aper_size_info_lvl2 *value;
343 ati_page_map page_dir; 343 struct ati_page_map page_dir;
344 unsigned long addr; 344 unsigned long addr;
345 int retval; 345 int retval;
346 u32 temp; 346 u32 temp;
@@ -400,7 +400,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge)
400 400
401static int ati_free_gatt_table(struct agp_bridge_data *bridge) 401static int ati_free_gatt_table(struct agp_bridge_data *bridge)
402{ 402{
403 ati_page_map page_dir; 403 struct ati_page_map page_dir;
404 404
405 page_dir.real = (unsigned long *)agp_bridge->gatt_table_real; 405 page_dir.real = (unsigned long *)agp_bridge->gatt_table_real;
406 page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table; 406 page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table;
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 5ff457b41efb..3491d6f84bc6 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -419,6 +419,31 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
419 *requested_mode &= ~AGP2_RESERVED_MASK; 419 *requested_mode &= ~AGP2_RESERVED_MASK;
420 } 420 }
421 421
422 /*
423 * Some dumb bridges are programmed to disobey the AGP2 spec.
424 * This is likely a BIOS misprogramming rather than poweron default, or
425 * it would be a lot more common.
426 * https://bugs.freedesktop.org/show_bug.cgi?id=8816
427 * AGPv2 spec 6.1.9 states:
428 * The RATE field indicates the data transfer rates supported by this
429 * device. A.G.P. devices must report all that apply.
430 * Fix them up as best we can.
431 */
432 switch (*bridge_agpstat & 7) {
433 case 4:
434 *bridge_agpstat |= (AGPSTAT2_2X | AGPSTAT2_1X);
435 printk(KERN_INFO PFX "BIOS bug. AGP bridge claims to only support x4 rate"
436 "Fixing up support for x2 & x1\n");
437 break;
438 case 2:
439 *bridge_agpstat |= AGPSTAT2_1X;
440 printk(KERN_INFO PFX "BIOS bug. AGP bridge claims to only support x2 rate"
441 "Fixing up support for x1\n");
442 break;
443 default:
444 break;
445 }
446
422 /* Check the speed bits make sense. Only one should be set. */ 447 /* Check the speed bits make sense. Only one should be set. */
423 tmp = *requested_mode & 7; 448 tmp = *requested_mode & 7;
424 switch (tmp) { 449 switch (tmp) {
@@ -940,6 +965,9 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
940 if (!bridge) 965 if (!bridge)
941 return -EINVAL; 966 return -EINVAL;
942 967
968 if (mem->page_count == 0)
969 return 0;
970
943 temp = bridge->current_size; 971 temp = bridge->current_size;
944 972
945 switch (bridge->driver->size_type) { 973 switch (bridge->driver->size_type) {
@@ -991,8 +1019,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
991 1019
992 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 1020 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
993 writel(bridge->driver->mask_memory(bridge, mem->memory[i], mem->type), bridge->gatt_table+j); 1021 writel(bridge->driver->mask_memory(bridge, mem->memory[i], mem->type), bridge->gatt_table+j);
994 readl(bridge->gatt_table+j); /* PCI Posting. */
995 } 1022 }
1023 readl(bridge->gatt_table+j-1); /* PCI Posting. */
996 1024
997 bridge->driver->tlb_flush(mem); 1025 bridge->driver->tlb_flush(mem);
998 return 0; 1026 return 0;
@@ -1009,6 +1037,9 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
1009 if (!bridge) 1037 if (!bridge)
1010 return -EINVAL; 1038 return -EINVAL;
1011 1039
1040 if (mem->page_count == 0)
1041 return 0;
1042
1012 if (type != 0 || mem->type != 0) { 1043 if (type != 0 || mem->type != 0) {
1013 /* The generic routines know nothing of memory types */ 1044 /* The generic routines know nothing of memory types */
1014 return -EINVAL; 1045 return -EINVAL;
@@ -1017,10 +1048,9 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
1017 /* AK: bogus, should encode addresses > 4GB */ 1048 /* AK: bogus, should encode addresses > 4GB */
1018 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 1049 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
1019 writel(bridge->scratch_page, bridge->gatt_table+i); 1050 writel(bridge->scratch_page, bridge->gatt_table+i);
1020 readl(bridge->gatt_table+i); /* PCI Posting. */
1021 } 1051 }
1052 readl(bridge->gatt_table+i-1); /* PCI Posting. */
1022 1053
1023 global_cache_flush();
1024 bridge->driver->tlb_flush(mem); 1054 bridge->driver->tlb_flush(mem);
1025 return 0; 1055 return 0;
1026} 1056}
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 555b3a8ab49c..a3011de51f7c 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -207,6 +207,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
207 int i, j, num_entries; 207 int i, j, num_entries;
208 void *temp; 208 void *temp;
209 209
210 if (mem->page_count == 0)
211 return 0;
212
210 temp = agp_bridge->current_size; 213 temp = agp_bridge->current_size;
211 num_entries = A_SIZE_FIX(temp)->num_entries; 214 num_entries = A_SIZE_FIX(temp)->num_entries;
212 215
@@ -221,12 +224,16 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
221 if (type != 0 || mem->type != 0) { 224 if (type != 0 || mem->type != 0) {
222 if ((type == AGP_DCACHE_MEMORY) && (mem->type == AGP_DCACHE_MEMORY)) { 225 if ((type == AGP_DCACHE_MEMORY) && (mem->type == AGP_DCACHE_MEMORY)) {
223 /* special insert */ 226 /* special insert */
224 global_cache_flush(); 227 if (!mem->is_flushed) {
228 global_cache_flush();
229 mem->is_flushed = TRUE;
230 }
231
225 for (i = pg_start; i < (pg_start + mem->page_count); i++) { 232 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)); 233 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 } 234 }
229 global_cache_flush(); 235 readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI Posting. */
236
230 agp_bridge->driver->tlb_flush(mem); 237 agp_bridge->driver->tlb_flush(mem);
231 return 0; 238 return 0;
232 } 239 }
@@ -236,14 +243,17 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
236 } 243 }
237 244
238insert: 245insert:
239 global_cache_flush(); 246 if (!mem->is_flushed) {
247 global_cache_flush();
248 mem->is_flushed = TRUE;
249 }
250
240 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 251 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
241 writel(agp_bridge->driver->mask_memory(agp_bridge, 252 writel(agp_bridge->driver->mask_memory(agp_bridge,
242 mem->memory[i], mem->type), 253 mem->memory[i], mem->type),
243 intel_i810_private.registers+I810_PTE_BASE+(j*4)); 254 intel_i810_private.registers+I810_PTE_BASE+(j*4));
244 readl(intel_i810_private.registers+I810_PTE_BASE+(j*4)); /* PCI Posting. */
245 } 255 }
246 global_cache_flush(); 256 readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4)); /* PCI Posting. */
247 257
248 agp_bridge->driver->tlb_flush(mem); 258 agp_bridge->driver->tlb_flush(mem);
249 return 0; 259 return 0;
@@ -254,12 +264,14 @@ static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
254{ 264{
255 int i; 265 int i;
256 266
267 if (mem->page_count == 0)
268 return 0;
269
257 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 270 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)); 271 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 } 272 }
273 readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
261 274
262 global_cache_flush();
263 agp_bridge->driver->tlb_flush(mem); 275 agp_bridge->driver->tlb_flush(mem);
264 return 0; 276 return 0;
265} 277}
@@ -370,6 +382,11 @@ static struct _intel_i830_private {
370 struct pci_dev *i830_dev; /* device one */ 382 struct pci_dev *i830_dev; /* device one */
371 volatile u8 __iomem *registers; 383 volatile u8 __iomem *registers;
372 volatile u32 __iomem *gtt; /* I915G */ 384 volatile u32 __iomem *gtt; /* I915G */
385 /* gtt_entries is the number of gtt entries that are already mapped
386 * to stolen memory. Stolen memory is larger than the memory mapped
387 * through gtt_entries, as it includes some reserved space for the BIOS
388 * popup and for the GTT.
389 */
373 int gtt_entries; 390 int gtt_entries;
374} intel_i830_private; 391} intel_i830_private;
375 392
@@ -380,14 +397,41 @@ static void intel_i830_init_gtt_entries(void)
380 u8 rdct; 397 u8 rdct;
381 int local = 0; 398 int local = 0;
382 static const int ddt[4] = { 0, 16, 32, 64 }; 399 static const int ddt[4] = { 0, 16, 32, 64 };
383 int size; 400 int size; /* reserved space (in kb) at the top of stolen memory */
384 401
385 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); 402 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
386 403
387 /* We obtain the size of the GTT, which is also stored (for some 404 if (IS_I965) {
388 * reason) at the top of stolen memory. Then we add 4KB to that 405 u32 pgetbl_ctl;
389 * for the video BIOS popup, which is also stored in there. */ 406
390 size = agp_bridge->driver->fetch_size() + 4; 407 pci_read_config_dword(agp_bridge->dev, I810_PGETBL_CTL,
408 &pgetbl_ctl);
409 /* The 965 has a field telling us the size of the GTT,
410 * which may be larger than what is necessary to map the
411 * aperture.
412 */
413 switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {
414 case I965_PGETBL_SIZE_128KB:
415 size = 128;
416 break;
417 case I965_PGETBL_SIZE_256KB:
418 size = 256;
419 break;
420 case I965_PGETBL_SIZE_512KB:
421 size = 512;
422 break;
423 default:
424 printk(KERN_INFO PFX "Unknown page table size, "
425 "assuming 512KB\n");
426 size = 512;
427 }
428 size += 4; /* add in BIOS popup space */
429 } else {
430 /* On previous hardware, the GTT size was just what was
431 * required to map the aperture.
432 */
433 size = agp_bridge->driver->fetch_size() + 4;
434 }
391 435
392 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB || 436 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
393 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { 437 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
@@ -576,6 +620,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
576 int i,j,num_entries; 620 int i,j,num_entries;
577 void *temp; 621 void *temp;
578 622
623 if (mem->page_count == 0)
624 return 0;
625
579 temp = agp_bridge->current_size; 626 temp = agp_bridge->current_size;
580 num_entries = A_SIZE_FIX(temp)->num_entries; 627 num_entries = A_SIZE_FIX(temp)->num_entries;
581 628
@@ -598,16 +645,18 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
598 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) 645 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
599 return -EINVAL; 646 return -EINVAL;
600 647
601 global_cache_flush(); /* FIXME: Necessary ?*/ 648 if (!mem->is_flushed) {
649 global_cache_flush();
650 mem->is_flushed = TRUE;
651 }
602 652
603 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 653 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
604 writel(agp_bridge->driver->mask_memory(agp_bridge, 654 writel(agp_bridge->driver->mask_memory(agp_bridge,
605 mem->memory[i], mem->type), 655 mem->memory[i], mem->type),
606 intel_i830_private.registers+I810_PTE_BASE+(j*4)); 656 intel_i830_private.registers+I810_PTE_BASE+(j*4));
607 readl(intel_i830_private.registers+I810_PTE_BASE+(j*4)); /* PCI Posting. */
608 } 657 }
658 readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
609 659
610 global_cache_flush();
611 agp_bridge->driver->tlb_flush(mem); 660 agp_bridge->driver->tlb_flush(mem);
612 return 0; 661 return 0;
613} 662}
@@ -617,7 +666,8 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
617{ 666{
618 int i; 667 int i;
619 668
620 global_cache_flush(); 669 if (mem->page_count == 0)
670 return 0;
621 671
622 if (pg_start < intel_i830_private.gtt_entries) { 672 if (pg_start < intel_i830_private.gtt_entries) {
623 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); 673 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
@@ -626,10 +676,9 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
626 676
627 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 677 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
628 writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4)); 678 writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
629 readl(intel_i830_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
630 } 679 }
680 readl(intel_i830_private.registers+I810_PTE_BASE+((i-1)*4));
631 681
632 global_cache_flush();
633 agp_bridge->driver->tlb_flush(mem); 682 agp_bridge->driver->tlb_flush(mem);
634 return 0; 683 return 0;
635} 684}
@@ -686,6 +735,9 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
686 int i,j,num_entries; 735 int i,j,num_entries;
687 void *temp; 736 void *temp;
688 737
738 if (mem->page_count == 0)
739 return 0;
740
689 temp = agp_bridge->current_size; 741 temp = agp_bridge->current_size;
690 num_entries = A_SIZE_FIX(temp)->num_entries; 742 num_entries = A_SIZE_FIX(temp)->num_entries;
691 743
@@ -708,15 +760,17 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
708 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) 760 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
709 return -EINVAL; 761 return -EINVAL;
710 762
711 global_cache_flush(); 763 if (!mem->is_flushed) {
764 global_cache_flush();
765 mem->is_flushed = TRUE;
766 }
712 767
713 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 768 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
714 writel(agp_bridge->driver->mask_memory(agp_bridge, 769 writel(agp_bridge->driver->mask_memory(agp_bridge,
715 mem->memory[i], mem->type), intel_i830_private.gtt+j); 770 mem->memory[i], mem->type), intel_i830_private.gtt+j);
716 readl(intel_i830_private.gtt+j); /* PCI Posting. */
717 } 771 }
772 readl(intel_i830_private.gtt+j-1);
718 773
719 global_cache_flush();
720 agp_bridge->driver->tlb_flush(mem); 774 agp_bridge->driver->tlb_flush(mem);
721 return 0; 775 return 0;
722} 776}
@@ -726,7 +780,8 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
726{ 780{
727 int i; 781 int i;
728 782
729 global_cache_flush(); 783 if (mem->page_count == 0)
784 return 0;
730 785
731 if (pg_start < intel_i830_private.gtt_entries) { 786 if (pg_start < intel_i830_private.gtt_entries) {
732 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); 787 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
@@ -735,30 +790,34 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
735 790
736 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 791 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
737 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i); 792 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
738 readl(intel_i830_private.gtt+i);
739 } 793 }
794 readl(intel_i830_private.gtt+i-1);
740 795
741 global_cache_flush();
742 agp_bridge->driver->tlb_flush(mem); 796 agp_bridge->driver->tlb_flush(mem);
743 return 0; 797 return 0;
744} 798}
745 799
746static int intel_i915_fetch_size(void) 800/* Return the aperture size by just checking the resource length. The effect
801 * described in the spec of the MSAC registers is just changing of the
802 * resource size.
803 */
804static int intel_i9xx_fetch_size(void)
747{ 805{
748 struct aper_size_info_fixed *values; 806 int num_sizes = sizeof(intel_i830_sizes) / sizeof(*intel_i830_sizes);
749 u32 temp, offset; 807 int aper_size; /* size in megabytes */
808 int i;
750 809
751#define I915_256MB_ADDRESS_MASK (1<<27) 810 aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
752 811
753 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); 812 for (i = 0; i < num_sizes; i++) {
813 if (aper_size == intel_i830_sizes[i].size) {
814 agp_bridge->current_size = intel_i830_sizes + i;
815 agp_bridge->previous_size = agp_bridge->current_size;
816 return aper_size;
817 }
818 }
754 819
755 pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp); 820 return 0;
756 if (temp & I915_256MB_ADDRESS_MASK)
757 offset = 0; /* 128MB aperture */
758 else
759 offset = 2; /* 256MB aperture */
760 agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
761 return values[offset].size;
762} 821}
763 822
764/* The intel i915 automatically initializes the agp aperture during POST. 823/* The intel i915 automatically initializes the agp aperture during POST.
@@ -821,40 +880,9 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
821 return addr | bridge->driver->masks[type].mask; 880 return addr | bridge->driver->masks[type].mask;
822} 881}
823 882
824static int intel_i965_fetch_size(void)
825{
826 struct aper_size_info_fixed *values;
827 u32 offset = 0;
828 u8 temp;
829
830#define I965_512MB_ADDRESS_MASK (3<<1)
831
832 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
833
834 pci_read_config_byte(intel_i830_private.i830_dev, I965_MSAC, &temp);
835 temp &= I965_512MB_ADDRESS_MASK;
836 switch (temp) {
837 case 0x00:
838 offset = 0; /* 128MB */
839 break;
840 case 0x06:
841 offset = 3; /* 512MB */
842 break;
843 default:
844 case 0x02:
845 offset = 2; /* 256MB */
846 break;
847 }
848
849 agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
850
851 /* The i965 GTT is always sized as if it had a 512kB aperture size */
852 return 512;
853}
854
855/* The intel i965 automatically initializes the agp aperture during POST. 883/* The intel i965 automatically initializes the agp aperture during POST.
856+ * Use the memory already set aside for in the GTT. 884 * Use the memory already set aside for in the GTT.
857+ */ 885 */
858static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) 886static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
859{ 887{
860 int page_order; 888 int page_order;
@@ -1574,7 +1602,7 @@ static struct agp_bridge_driver intel_915_driver = {
1574 .num_aperture_sizes = 4, 1602 .num_aperture_sizes = 4,
1575 .needs_scratch_page = TRUE, 1603 .needs_scratch_page = TRUE,
1576 .configure = intel_i915_configure, 1604 .configure = intel_i915_configure,
1577 .fetch_size = intel_i915_fetch_size, 1605 .fetch_size = intel_i9xx_fetch_size,
1578 .cleanup = intel_i915_cleanup, 1606 .cleanup = intel_i915_cleanup,
1579 .tlb_flush = intel_i810_tlbflush, 1607 .tlb_flush = intel_i810_tlbflush,
1580 .mask_memory = intel_i810_mask_memory, 1608 .mask_memory = intel_i810_mask_memory,
@@ -1598,7 +1626,7 @@ static struct agp_bridge_driver intel_i965_driver = {
1598 .num_aperture_sizes = 4, 1626 .num_aperture_sizes = 4,
1599 .needs_scratch_page = TRUE, 1627 .needs_scratch_page = TRUE,
1600 .configure = intel_i915_configure, 1628 .configure = intel_i915_configure,
1601 .fetch_size = intel_i965_fetch_size, 1629 .fetch_size = intel_i9xx_fetch_size,
1602 .cleanup = intel_i915_cleanup, 1630 .cleanup = intel_i915_cleanup,
1603 .tlb_flush = intel_i810_tlbflush, 1631 .tlb_flush = intel_i810_tlbflush,
1604 .mask_memory = intel_i965_mask_memory, 1632 .mask_memory = intel_i965_mask_memory,
@@ -1927,6 +1955,15 @@ static int agp_intel_resume(struct pci_dev *pdev)
1927 1955
1928 pci_restore_state(pdev); 1956 pci_restore_state(pdev);
1929 1957
1958 /* We should restore our graphics device's config space,
1959 * as host bridge (00:00) resumes before graphics device (02:00),
1960 * then our access to its pci space can work right.
1961 */
1962 if (intel_i810_private.i810_dev)
1963 pci_restore_state(intel_i810_private.i810_dev);
1964 if (intel_i830_private.i830_dev)
1965 pci_restore_state(intel_i830_private.i830_dev);
1966
1930 if (bridge->driver == &intel_generic_driver) 1967 if (bridge->driver == &intel_generic_driver)
1931 intel_configure(); 1968 intel_configure();
1932 else if (bridge->driver == &intel_850_driver) 1969 else if (bridge->driver == &intel_850_driver)
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index d73be4c2db8a..902648db7efa 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -281,10 +281,11 @@ static int __devinit agp_sgi_init(void)
281 else 281 else
282 return 0; 282 return 0;
283 283
284 sgi_tioca_agp_bridges = 284 sgi_tioca_agp_bridges = kmalloc(tioca_gart_found *
285 (struct agp_bridge_data **)kmalloc(tioca_gart_found * 285 sizeof(struct agp_bridge_data *),
286 sizeof(struct agp_bridge_data *), 286 GFP_KERNEL);
287 GFP_KERNEL); 287 if (!sgi_tioca_agp_bridges)
288 return -ENOMEM;
288 289
289 j = 0; 290 j = 0;
290 list_for_each_entry(info, &tioca_list, ca_list) { 291 list_for_each_entry(info, &tioca_list, ca_list) {
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index c149ac9ce9a7..2ded7a280d7f 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -380,9 +380,23 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
380 /* P4M800CE */ 380 /* P4M800CE */
381 { 381 {
382 .device_id = PCI_DEVICE_ID_VIA_P4M800CE, 382 .device_id = PCI_DEVICE_ID_VIA_P4M800CE,
383 .chipset_name = "P4M800CE", 383 .chipset_name = "VT3314",
384 },
385 /* CX700 */
386 {
387 .device_id = PCI_DEVICE_ID_VIA_CX700,
388 .chipset_name = "CX700",
389 },
390 /* VT3336 */
391 {
392 .device_id = PCI_DEVICE_ID_VIA_VT3336,
393 .chipset_name = "VT3336",
394 },
395 /* P4M890 */
396 {
397 .device_id = PCI_DEVICE_ID_VIA_P4M890,
398 .chipset_name = "P4M890",
384 }, 399 },
385
386 { }, /* dummy final entry, always present */ 400 { }, /* dummy final entry, always present */
387}; 401};
388 402
@@ -524,6 +538,9 @@ static const struct pci_device_id agp_via_pci_table[] = {
524 ID(PCI_DEVICE_ID_VIA_83_87XX_1), 538 ID(PCI_DEVICE_ID_VIA_83_87XX_1),
525 ID(PCI_DEVICE_ID_VIA_3296_0), 539 ID(PCI_DEVICE_ID_VIA_3296_0),
526 ID(PCI_DEVICE_ID_VIA_P4M800CE), 540 ID(PCI_DEVICE_ID_VIA_P4M800CE),
541 ID(PCI_DEVICE_ID_VIA_CX700),
542 ID(PCI_DEVICE_ID_VIA_VT3336),
543 ID(PCI_DEVICE_ID_VIA_P4M890),
527 { } 544 { }
528}; 545};
529 546