diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-21 08:10:09 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-21 08:10:09 -0700 |
commit | 44040f107e64d689ccd3211ac62c6bc44f3f0775 (patch) | |
tree | f85059028aa570e758c7fb272fd8cf823ab4f119 /drivers/gpu/drm/drm_cache.c | |
parent | 388dba30471c236a290c4082bce5f2b5cd1a7a06 (diff) | |
parent | 28d520433b6375740990ab99d69b0d0067fd656b (diff) |
Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (133 commits)
drm/vgaarb: add VGA arbitration support to the drm and kms.
drm/radeon: some r420s have a CP race with the DMA engine.
drm/radeon/r600/kms: rv670 is not DCE3
drm/radeon/kms: r420 idle after programming GA_ENHANCE
drm/radeon/kms: more fixes to rv770 suspend/resume path.
drm/radeon/kms: more alignment for rv770.c with r600.c
drm/radeon/kms: rv770 blit init called too late.
drm/radeon/kms: move around new init path code to avoid posting at init
drm/radeon/r600: fix some issues with suspend/resume.
drm/radeon/kms: disable VGA rendering engine before taking over VRAM
drm/radeon/kms: Move radeon_get_clock_info() call out of radeon_clocks_init().
drm/radeon/kms: add initial connector properties
drm/radeon/kms: Use surfaces for scanout / cursor byte swapping on big endian.
drm/radeon/kms: don't fail if we fail to init GPU acceleration
drm/r600/kms: fixup number of loops per blit calculation.
drm/radeon/kms: reprogram format in set base.
drm/radeon: avivo chips have no separate int bit for display
drm/radeon/r600: don't do interrupts
drm: fix _DRM_GEM addmap error message
drm: update crtc x/y when only fb changes
...
Fixed up trivial conflicts in firmware/Makefile due to network driver
(cxgb3) and drm (mga/r128/radeon) firmware being listed next to each
other.
Diffstat (limited to 'drivers/gpu/drm/drm_cache.c')
-rw-r--r-- | drivers/gpu/drm/drm_cache.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index 0e994a0e46d4..0e3bd5b54b78 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -45,6 +45,23 @@ drm_clflush_page(struct page *page) clflush(page_virtual + i); kunmap_atomic(page_virtual, KM_USER0); } + +static void drm_cache_flush_clflush(struct page *pages[], + unsigned long num_pages) +{ + unsigned long i; + + mb(); + for (i = 0; i < num_pages; i++) + drm_clflush_page(*pages++); + mb(); +} + +static void +drm_clflush_ipi_handler(void *null) +{ + wbinvd(); +} #endif void @@ -53,17 +70,30 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) #if defined(CONFIG_X86) if (cpu_has_clflush) { - unsigned long i; - - mb(); - for (i = 0; i < num_pages; ++i) - drm_clflush_page(*pages++); - mb(); - + drm_cache_flush_clflush(pages, num_pages); return; } - wbinvd(); + if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) + printk(KERN_ERR "Timed out waiting for cache flush.\n"); + +#elif defined(__powerpc__) + unsigned long i; + for (i = 0; i < num_pages; i++) { + struct page *page = pages[i]; + void *page_virtual; + + if (unlikely(page == NULL)) + continue; + + page_virtual = kmap_atomic(page, KM_USER0); + flush_dcache_range((unsigned long)page_virtual, + (unsigned long)page_virtual + PAGE_SIZE); + kunmap_atomic(page_virtual, KM_USER0); + } +#else + printk(KERN_ERR "Architecture has no drm_cache.c support\n"); + WARN_ON_ONCE(1); #endif } EXPORT_SYMBOL(drm_clflush_pages); |