aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/generic.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas@tungstengraphics.com>2006-12-20 10:33:41 -0500
committerDave Jones <davej@redhat.com>2006-12-22 22:44:09 -0500
commit5aa80c72263904f1e52eee8ed8cb75887b1d1dc3 (patch)
tree1ab5970066b59a07067765135645224c630424de /drivers/char/agp/generic.c
parentd5cb8d38cd0029b3573e1c8d5d99d99c86dbdbd6 (diff)
[AGPGART] Remove unnecessary flushes when inserting and removing pages.
This patch is to speed up flipping of pages in and out of the AGP aperture as needed by the new drm memory manager. A number of global cache flushes are removed as well as some PCI posting flushes. The following guidelines have been used: 1) Memory that is only mapped uncached and that has been subject to a global cache flush after the mapping was changed to uncached does not need any more cache flushes. Neither before binding to the aperture nor after unbinding. 2) Only do one PCI posting flush after a sequence of writes modifying page entries in the GATT. Signed-off-by: Thomas Hellstrom <thomas@tungstengraphics.com> Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers/char/agp/generic.c')
-rw-r--r--drivers/char/agp/generic.c11
1 files changed, 8 insertions, 3 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}