aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/pageattr.c1
-rw-r--r--drivers/char/agp/intel-agp.c30
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c10
3 files changed, 24 insertions, 17 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 7e600c1962db..5866b28eede1 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -143,6 +143,7 @@ void clflush_cache_range(void *vaddr, unsigned int size)
143 143
144 mb(); 144 mb();
145} 145}
146EXPORT_SYMBOL_GPL(clflush_cache_range);
146 147
147static void __cpa_flush_all(void *arg) 148static void __cpa_flush_all(void *arg)
148{ 149{
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index c17291715031..e8dc75fc33cc 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -682,23 +682,39 @@ static void intel_i830_setup_flush(void)
682 if (!intel_private.i8xx_page) 682 if (!intel_private.i8xx_page)
683 return; 683 return;
684 684
685 /* make page uncached */
686 map_page_into_agp(intel_private.i8xx_page);
687
688 intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page); 685 intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page);
689 if (!intel_private.i8xx_flush_page) 686 if (!intel_private.i8xx_flush_page)
690 intel_i830_fini_flush(); 687 intel_i830_fini_flush();
691} 688}
692 689
690static void
691do_wbinvd(void *null)
692{
693 wbinvd();
694}
695
696/* The chipset_flush interface needs to get data that has already been
697 * flushed out of the CPU all the way out to main memory, because the GPU
698 * doesn't snoop those buffers.
699 *
700 * The 8xx series doesn't have the same lovely interface for flushing the
701 * chipset write buffers that the later chips do. According to the 865
702 * specs, it's 64 octwords, or 1KB. So, to get those previous things in
703 * that buffer out, we just fill 1KB and clflush it out, on the assumption
704 * that it'll push whatever was in there out. It appears to work.
705 */
693static void intel_i830_chipset_flush(struct agp_bridge_data *bridge) 706static void intel_i830_chipset_flush(struct agp_bridge_data *bridge)
694{ 707{
695 unsigned int *pg = intel_private.i8xx_flush_page; 708 unsigned int *pg = intel_private.i8xx_flush_page;
696 int i;
697 709
698 for (i = 0; i < 256; i += 2) 710 memset(pg, 0, 1024);
699 *(pg + i) = i;
700 711
701 wmb(); 712 if (cpu_has_clflush) {
713 clflush_cache_range(pg, 1024);
714 } else {
715 if (on_each_cpu(do_wbinvd, NULL, 1) != 0)
716 printk(KERN_ERR "Timed out waiting for cache flush.\n");
717 }
702} 718}
703 719
704/* The intel i830 automatically initializes the agp aperture during POST. 720/* The intel i830 automatically initializes the agp aperture during POST.
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f3758f9fc979..30ea4b6b0219 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2511,16 +2511,6 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
2511 if (obj_priv->pages == NULL) 2511 if (obj_priv->pages == NULL)
2512 return; 2512 return;
2513 2513
2514 /* XXX: The 865 in particular appears to be weird in how it handles
2515 * cache flushing. We haven't figured it out, but the
2516 * clflush+agp_chipset_flush doesn't appear to successfully get the
2517 * data visible to the PGU, while wbinvd + agp_chipset_flush does.
2518 */
2519 if (IS_I865G(obj->dev)) {
2520 wbinvd();
2521 return;
2522 }
2523
2524 drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE); 2514 drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE);
2525} 2515}
2526 2516