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 | } |
