diff options
-rw-r--r-- | drivers/char/agp/generic.c | 11 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 62 |
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 | ||
238 | insert: | 245 | insert: |
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 | } |