aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/agp/generic.c11
-rw-r--r--drivers/char/agp/intel-agp.c62
2 files changed, 50 insertions, 23 deletions
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 883a36a27833..3491d6f84bc6 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -965,6 +965,9 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
965 if (!bridge) 965 if (!bridge)
966 return -EINVAL; 966 return -EINVAL;
967 967
968 if (mem->page_count == 0)
969 return 0;
970
968 temp = bridge->current_size; 971 temp = bridge->current_size;
969 972
970 switch (bridge->driver->size_type) { 973 switch (bridge->driver->size_type) {
@@ -1016,8 +1019,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
1016 1019
1017 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++) {
1018 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);
1019 readl(bridge->gatt_table+j); /* PCI Posting. */
1020 } 1022 }
1023 readl(bridge->gatt_table+j-1); /* PCI Posting. */
1021 1024
1022 bridge->driver->tlb_flush(mem); 1025 bridge->driver->tlb_flush(mem);
1023 return 0; 1026 return 0;
@@ -1034,6 +1037,9 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
1034 if (!bridge) 1037 if (!bridge)
1035 return -EINVAL; 1038 return -EINVAL;
1036 1039
1040 if (mem->page_count == 0)
1041 return 0;
1042
1037 if (type != 0 || mem->type != 0) { 1043 if (type != 0 || mem->type != 0) {
1038 /* The generic routines know nothing of memory types */ 1044 /* The generic routines know nothing of memory types */
1039 return -EINVAL; 1045 return -EINVAL;
@@ -1042,10 +1048,9 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
1042 /* AK: bogus, should encode addresses > 4GB */ 1048 /* AK: bogus, should encode addresses > 4GB */
1043 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 1049 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
1044 writel(bridge->scratch_page, bridge->gatt_table+i); 1050 writel(bridge->scratch_page, bridge->gatt_table+i);
1045 readl(bridge->gatt_table+i); /* PCI Posting. */
1046 } 1051 }
1052 readl(bridge->gatt_table+i-1); /* PCI Posting. */
1047 1053
1048 global_cache_flush();
1049 bridge->driver->tlb_flush(mem); 1054 bridge->driver->tlb_flush(mem);
1050 return 0; 1055 return 0;
1051} 1056}
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 555b3a8ab49c..029d7f697567 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}
@@ -576,6 +588,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
576 int i,j,num_entries; 588 int i,j,num_entries;
577 void *temp; 589 void *temp;
578 590
591 if (mem->page_count == 0)
592 return 0;
593
579 temp = agp_bridge->current_size; 594 temp = agp_bridge->current_size;
580 num_entries = A_SIZE_FIX(temp)->num_entries; 595 num_entries = A_SIZE_FIX(temp)->num_entries;
581 596
@@ -598,16 +613,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)) 613 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
599 return -EINVAL; 614 return -EINVAL;
600 615
601 global_cache_flush(); /* FIXME: Necessary ?*/ 616 if (!mem->is_flushed) {
617 global_cache_flush();
618 mem->is_flushed = TRUE;
619 }
602 620
603 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 621 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
604 writel(agp_bridge->driver->mask_memory(agp_bridge, 622 writel(agp_bridge->driver->mask_memory(agp_bridge,
605 mem->memory[i], mem->type), 623 mem->memory[i], mem->type),
606 intel_i830_private.registers+I810_PTE_BASE+(j*4)); 624 intel_i830_private.registers+I810_PTE_BASE+(j*4));
607 readl(intel_i830_private.registers+I810_PTE_BASE+(j*4)); /* PCI Posting. */
608 } 625 }
626 readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
609 627
610 global_cache_flush();
611 agp_bridge->driver->tlb_flush(mem); 628 agp_bridge->driver->tlb_flush(mem);
612 return 0; 629 return 0;
613} 630}
@@ -617,7 +634,8 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
617{ 634{
618 int i; 635 int i;
619 636
620 global_cache_flush(); 637 if (mem->page_count == 0)
638 return 0;
621 639
622 if (pg_start < intel_i830_private.gtt_entries) { 640 if (pg_start < intel_i830_private.gtt_entries) {
623 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); 641 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
@@ -626,10 +644,9 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
626 644
627 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 645 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)); 646 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 } 647 }
648 readl(intel_i830_private.registers+I810_PTE_BASE+((i-1)*4));
631 649
632 global_cache_flush();
633 agp_bridge->driver->tlb_flush(mem); 650 agp_bridge->driver->tlb_flush(mem);
634 return 0; 651 return 0;
635} 652}
@@ -686,6 +703,9 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
686 int i,j,num_entries; 703 int i,j,num_entries;
687 void *temp; 704 void *temp;
688 705
706 if (mem->page_count == 0)
707 return 0;
708
689 temp = agp_bridge->current_size; 709 temp = agp_bridge->current_size;
690 num_entries = A_SIZE_FIX(temp)->num_entries; 710 num_entries = A_SIZE_FIX(temp)->num_entries;
691 711
@@ -708,15 +728,17 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
708 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) 728 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
709 return -EINVAL; 729 return -EINVAL;
710 730
711 global_cache_flush(); 731 if (!mem->is_flushed) {
732 global_cache_flush();
733 mem->is_flushed = TRUE;
734 }
712 735
713 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 736 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
714 writel(agp_bridge->driver->mask_memory(agp_bridge, 737 writel(agp_bridge->driver->mask_memory(agp_bridge,
715 mem->memory[i], mem->type), intel_i830_private.gtt+j); 738 mem->memory[i], mem->type), intel_i830_private.gtt+j);
716 readl(intel_i830_private.gtt+j); /* PCI Posting. */
717 } 739 }
740 readl(intel_i830_private.gtt+j-1);
718 741
719 global_cache_flush();
720 agp_bridge->driver->tlb_flush(mem); 742 agp_bridge->driver->tlb_flush(mem);
721 return 0; 743 return 0;
722} 744}
@@ -726,7 +748,8 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
726{ 748{
727 int i; 749 int i;
728 750
729 global_cache_flush(); 751 if (mem->page_count == 0)
752 return 0;
730 753
731 if (pg_start < intel_i830_private.gtt_entries) { 754 if (pg_start < intel_i830_private.gtt_entries) {
732 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); 755 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
@@ -735,10 +758,9 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
735 758
736 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 759 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
737 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i); 760 writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
738 readl(intel_i830_private.gtt+i);
739 } 761 }
762 readl(intel_i830_private.gtt+i-1);
740 763
741 global_cache_flush();
742 agp_bridge->driver->tlb_flush(mem); 764 agp_bridge->driver->tlb_flush(mem);
743 return 0; 765 return 0;
744} 766}