[Intel-gfx] [PATCH 17/25] drm/i915: ValleyView cacheability is different

Jesse Barnes jbarnes at virtuousgeek.org
Wed Mar 21 20:48:38 CET 2012


The GT can snoop CPU writes, but doesn't snoop into the CPU cache when
it does writes, so we can't use the cache bits the same way.

So map the status and pipe control pages as uncached on ValleyView, and
only set the pages to cached if we're on a supported platform.

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_drv.c         |    2 +
 drivers/gpu/drm/i915/intel_ringbuffer.c |   35 ++++++++++++++++++++++++------
 2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index e4fa294..a636703 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -255,6 +255,7 @@ static const struct intel_device_info intel_valleyview_m_info = {
 	.has_bsd_ring = 1,
 	.has_blt_ring = 1,
 	.is_valleyview = 1,
+	.has_llc = 0,
 };
 
 static const struct intel_device_info intel_valleyview_d_info = {
@@ -264,6 +265,7 @@ static const struct intel_device_info intel_valleyview_d_info = {
 	.has_bsd_ring = 1,
 	.has_blt_ring = 1,
 	.is_valleyview = 1,
+	.has_llc = 0,
 };
 
 static const struct pci_device_id pciidlist[] = {		/* aka */
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index ca3972f..f52abc4 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -319,6 +319,8 @@ init_pipe_control(struct intel_ring_buffer *ring)
 {
 	struct pipe_control *pc;
 	struct drm_i915_gem_object *obj;
+	int cache_level = HAS_LLC(ring->dev) ? I915_CACHE_LLC : I915_CACHE_NONE;
+	struct drm_device *dev;
 	int ret;
 
 	if (ring->private)
@@ -335,14 +337,19 @@ init_pipe_control(struct intel_ring_buffer *ring)
 		goto err;
 	}
 
-	i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
+	i915_gem_object_set_cache_level(obj, cache_level);
 
 	ret = i915_gem_object_pin(obj, 4096, true);
 	if (ret)
 		goto err_unref;
-
+	dev = obj->base.dev;
 	pc->gtt_offset = obj->gtt_offset;
-	pc->cpu_page =  kmap(obj->pages[0]);
+	if (!HAS_LLC(ring->dev))
+		pc->cpu_page = ioremap(dev->agp->base +
+				       obj->gtt_offset,
+				       PAGE_SIZE);
+	else
+		pc->cpu_page =  kmap(obj->pages[0]);
 	if (pc->cpu_page == NULL)
 		goto err_unpin;
 
@@ -364,12 +371,17 @@ cleanup_pipe_control(struct intel_ring_buffer *ring)
 {
 	struct pipe_control *pc = ring->private;
 	struct drm_i915_gem_object *obj;
+	struct drm_device *dev;
 
 	if (!ring->private)
 		return;
 
 	obj = pc->obj;
-	kunmap(obj->pages[0]);
+	dev = obj->base.dev;
+	if (IS_VALLEYVIEW(dev))
+		iounmap(pc->cpu_page);
+	else
+		kunmap(obj->pages[0]);
 	i915_gem_object_unpin(obj);
 	drm_gem_object_unreference(&obj->base);
 
@@ -929,7 +941,10 @@ static void cleanup_status_page(struct intel_ring_buffer *ring)
 	if (obj == NULL)
 		return;
 
-	kunmap(obj->pages[0]);
+	if (IS_VALLEYVIEW(dev_priv->dev))
+		iounmap(ring->status_page.page_addr);
+	else
+		kunmap(obj->pages[0]);
 	i915_gem_object_unpin(obj);
 	drm_gem_object_unreference(&obj->base);
 	ring->status_page.obj = NULL;
@@ -942,6 +957,7 @@ static int init_status_page(struct intel_ring_buffer *ring)
 	struct drm_device *dev = ring->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct drm_i915_gem_object *obj;
+	int cache_level = HAS_LLC(ring->dev) ? I915_CACHE_LLC : I915_CACHE_NONE;
 	int ret;
 
 	obj = i915_gem_alloc_object(dev, 4096);
@@ -951,7 +967,7 @@ static int init_status_page(struct intel_ring_buffer *ring)
 		goto err;
 	}
 
-	i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
+	i915_gem_object_set_cache_level(obj, cache_level);
 
 	ret = i915_gem_object_pin(obj, 4096, true);
 	if (ret != 0) {
@@ -959,7 +975,12 @@ static int init_status_page(struct intel_ring_buffer *ring)
 	}
 
 	ring->status_page.gfx_addr = obj->gtt_offset;
-	ring->status_page.page_addr = kmap(obj->pages[0]);
+	if (!HAS_LLC(ring->dev))
+		ring->status_page.page_addr = ioremap(dev->agp->base +
+						      obj->gtt_offset,
+						      PAGE_SIZE);
+	else
+		ring->status_page.page_addr = kmap(obj->pages[0]);
 	if (ring->status_page.page_addr == NULL) {
 		memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
 		goto err_unpin;
-- 
1.7.5.4




More information about the Intel-gfx mailing list