summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drm_objects.h1
-rw-r--r--linux-core/drm_ttm.c7
-rw-r--r--linux-core/i915_buffer.c33
-rw-r--r--linux-core/i915_drv.c1
-rw-r--r--shared-core/i915_drv.h2
5 files changed, 41 insertions, 3 deletions
diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h
index 8b14ac6f..cea811eb 100644
--- a/linux-core/drm_objects.h
+++ b/linux-core/drm_objects.h
@@ -464,6 +464,7 @@ struct drm_bo_driver {
uint32_t(*evict_mask) (struct drm_buffer_object *bo);
int (*move) (struct drm_buffer_object * bo,
int evict, int no_wait, struct drm_bo_mem_reg * new_mem);
+ void (*ttm_cache_flush)(struct drm_ttm *ttm);
};
/*
diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c
index 33bbe1d4..df9e7e44 100644
--- a/linux-core/drm_ttm.c
+++ b/linux-core/drm_ttm.c
@@ -207,6 +207,7 @@ struct page *drm_ttm_get_page(struct drm_ttm * ttm, int index)
}
return p;
}
+EXPORT_SYMBOL(drm_ttm_get_page);
int drm_ttm_populate(struct drm_ttm * ttm)
{
@@ -311,7 +312,7 @@ void drm_ttm_unbind(struct drm_ttm * ttm)
int drm_bind_ttm(struct drm_ttm * ttm, struct drm_bo_mem_reg *bo_mem)
{
-
+ struct drm_bo_driver *bo_driver = ttm->dev->driver->bo_driver;
int ret = 0;
struct drm_ttm_backend *be;
@@ -328,7 +329,9 @@ int drm_bind_ttm(struct drm_ttm * ttm, struct drm_bo_mem_reg *bo_mem)
if (ttm->state == ttm_unbound && !(bo_mem->flags & DRM_BO_FLAG_CACHED)) {
drm_set_caching(ttm, DRM_TTM_PAGE_UNCACHED);
- }
+ } else if ((bo_mem->flags & DRM_BO_FLAG_CACHED) &&
+ bo_driver->ttm_cache_flush)
+ bo_driver->ttm_cache_flush(ttm);
if ((ret = be->func->bind(be, bo_mem))) {
ttm->state = ttm_evicted;
diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c
index f81def8f..bbc7e1db 100644
--- a/linux-core/i915_buffer.c
+++ b/linux-core/i915_buffer.c
@@ -249,3 +249,36 @@ int i915_move(struct drm_buffer_object * bo,
}
return 0;
}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+static inline void clflush(volatile void *__p)
+{
+ asm volatile("clflush %0" : "+m" (*(char __force *)__p));
+}
+#endif
+
+static inline void drm_cache_flush_addr(void *virt)
+{
+ int i;
+
+ for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
+ clflush(virt+i);
+}
+
+static inline void drm_cache_flush_page(struct page *p)
+{
+ drm_cache_flush_addr(page_address(p));
+}
+
+void i915_flush_ttm(struct drm_ttm *ttm)
+{
+ int i;
+
+ if (!ttm)
+ return;
+
+ DRM_MEMORYBARRIER();
+ for (i = ttm->num_pages-1; i >= 0; i--)
+ drm_cache_flush_page(drm_ttm_get_page(ttm, i));
+ DRM_MEMORYBARRIER();
+}
diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c
index f34d218c..124db68f 100644
--- a/linux-core/i915_drv.c
+++ b/linux-core/i915_drv.c
@@ -66,6 +66,7 @@ static struct drm_bo_driver i915_bo_driver = {
.init_mem_type = i915_init_mem_type,
.evict_mask = i915_evict_mask,
.move = i915_move,
+ .ttm_cache_flush = i915_flush_ttm,
};
#endif
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index 6716f28f..9f69d841 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -310,7 +310,7 @@ extern int i915_init_mem_type(struct drm_device *dev, uint32_t type,
extern uint32_t i915_evict_mask(struct drm_buffer_object *bo);
extern int i915_move(struct drm_buffer_object *bo, int evict,
int no_wait, struct drm_bo_mem_reg *new_mem);
-
+void i915_flush_ttm(struct drm_ttm *ttm);
#endif
#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))