diff mbox

[15/34] drm/i915: Tie context to PPGTT

Message ID 1369510028-3343-16-git-send-email-ben@bwidawsk.net (mailing list archive)
State New, archived
Headers show

Commit Message

Ben Widawsky May 25, 2013, 7:26 p.m. UTC
This is the second half to the previous patch in that now if PPGTT fails
to come up, contexts are disabled, and we don't even try to bring up
contexts when we don't have PPGTT support.

NB: PPGTT cleanup is now done in context unreference.
NB2: Chris finally gets to disable HW contexts via the PPGTT parameter
since they're now tied.

Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_dma.c         |  2 --
 drivers/gpu/drm/i915/i915_drv.h         |  4 +--
 drivers/gpu/drm/i915/i915_gem.c         | 47 ++++++++++++---------------------
 drivers/gpu/drm/i915/i915_gem_context.c | 11 +++++++-
 drivers/gpu/drm/i915/i915_gem_gtt.c     | 12 ---------
 5 files changed, 29 insertions(+), 47 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 3ae8298..9745fe0 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1361,7 +1361,6 @@  cleanup_gem:
 	i915_gem_cleanup_ringbuffer(dev);
 	i915_gem_context_fini(dev);
 	mutex_unlock(&dev->struct_mutex);
-	i915_gem_cleanup_aliasing_ppgtt(dev);
 	drm_mm_takedown(&dev_priv->mm.gtt_space);
 cleanup_irq:
 	drm_irq_uninstall(dev);
@@ -1773,7 +1772,6 @@  int i915_driver_unload(struct drm_device *dev)
 		i915_gem_cleanup_ringbuffer(dev);
 		i915_gem_context_fini(dev);
 		mutex_unlock(&dev->struct_mutex);
-		i915_gem_cleanup_aliasing_ppgtt(dev);
 		i915_gem_cleanup_stolen(dev);
 
 		if (!I915_NEED_GFX_HWS(dev))
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6210ecd..d803512 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1362,8 +1362,9 @@  struct drm_i915_file_private {
 #define HAS_LLC(dev)            (INTEL_INFO(dev)->has_llc)
 #define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)
 
-#define HAS_HW_CONTEXTS(dev)	(INTEL_INFO(dev)->gen >= 6)
 #define HAS_ALIASING_PPGTT(dev)	(INTEL_INFO(dev)->gen >=6 && !IS_VALLEYVIEW(dev))
+#define HAS_HW_CONTEXTS(dev)	(INTEL_INFO(dev)->gen >= 6 && \
+				 HAS_ALIASING_PPGTT(dev))
 
 #define HAS_OVERLAY(dev)		(INTEL_INFO(dev)->has_overlay)
 #define OVERLAY_NEEDS_PHYSICAL(dev)	(INTEL_INFO(dev)->overlay_needs_physical)
@@ -1740,7 +1741,6 @@  int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
 /* i915_gem_gtt.c */
 bool intel_enable_ppgtt(struct drm_device *dev);
 int i915_gem_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt);
-void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev);
 void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
 			    struct drm_i915_gem_object *obj,
 			    enum i915_cache_level cache_level);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index fc35447..dfb1a84c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4042,26 +4042,26 @@  i915_gem_init_hw(struct drm_device *dev)
 	 * goes with our code better). Context switching requires rings (for
 	 * the do_switch), but before enabling PPGTT. So don't move this.
 	 */
-	if (i915_gem_context_enable(dev_priv)) {
-		i915_gem_context_fini(dev);
-		dev_priv->hw_contexts_disabled = true;
-	}
+	ret = i915_gem_context_enable(dev_priv);
+	if (ret || WARN_ON(!dev_priv->mm.aliasing_ppgtt))
+		goto disable_ctx_out;
 
-	if (dev_priv->mm.aliasing_ppgtt) {
-		ret = dev_priv->mm.aliasing_ppgtt->enable(dev);
-		if (ret) {
-			i915_gem_cleanup_aliasing_ppgtt(dev);
-			DRM_INFO("PPGTT enable failed. This is not fatal, but unexpected\n");
-		}
-	}
+	ret = dev_priv->mm.aliasing_ppgtt->enable(dev);
+	if (ret)
+		goto disable_ctx_out;
 
 	return 0;
+
+disable_ctx_out:
+	i915_gem_context_fini(dev);
+	dev_priv->hw_contexts_disabled = true;
+	return ret;
 }
 
 int i915_gem_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	int ret = -ENODEV;
+	int ret;
 
 	mutex_lock(&dev->struct_mutex);
 
@@ -4072,9 +4072,7 @@  int i915_gem_init(struct drm_device *dev)
 			DRM_DEBUG_DRIVER("allow wake ack timed out\n");
 	}
 
-	if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) {
-		struct i915_hw_ppgtt *ppgtt;
-
+	if (intel_enable_ppgtt(dev) && HAS_HW_CONTEXTS(dev)) {
 		i915_gem_setup_global_gtt(dev, 0, dev_priv->gtt.mappable_end,
 					  dev_priv->gtt.total, false);
 		i915_gem_context_init(dev);
@@ -4082,30 +4080,19 @@  int i915_gem_init(struct drm_device *dev)
 			drm_mm_takedown(&dev_priv->mm.gtt_space);
 			goto ggtt_only;
 		}
-
-		ppgtt = &dev_priv->ring[RCS].default_context->ppgtt;
-
-		ret = i915_gem_ppgtt_init(dev, ppgtt);
-		if (ret) {
-			drm_mm_takedown(&dev_priv->mm.gtt_space);
-			goto ggtt_only;
-		}
-
-		dev_priv->mm.aliasing_ppgtt = ppgtt;
 	}
 
 ggtt_only:
-	if (ret) {
-		DRM_DEBUG_DRIVER("Aliased PPGTT setup failed %d\n", ret);
+	if (!dev_priv->mm.aliasing_ppgtt) {
+		if (HAS_HW_CONTEXTS(dev))
+			DRM_DEBUG_DRIVER("Context setup failed\n");
 		i915_gem_setup_global_gtt(dev, 0, dev_priv->gtt.mappable_end,
 					  dev_priv->gtt.total, true);
 	}
 
 	ret = i915_gem_init_hw(dev);
-	if (ret) {
-		i915_gem_cleanup_aliasing_ppgtt(dev);
+	if (ret)
 		i915_gem_context_fini(dev);
-	}
 	mutex_unlock(&dev->struct_mutex);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 454a2b5..4eeca1b 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -129,6 +129,7 @@  void i915_gem_context_free(struct kref *ctx_ref)
 	struct i915_hw_context *ctx = container_of(ctx_ref,
 						   typeof(*ctx), ref);
 
+	ctx->ppgtt.cleanup(&ctx->ppgtt);
 	drm_gem_object_unreference(&ctx->obj->base);
 	kfree(ctx);
 }
@@ -167,14 +168,20 @@  create_hw_context(struct drm_device *dev,
 	 */
 	ctx->ring = &dev_priv->ring[RCS];
 
+	ret = i915_gem_ppgtt_init(dev, &ctx->ppgtt);
+	if (ret)
+		goto err_out;
+
 	/* Default context will never have a file_priv */
 	if (file_priv == NULL)
 		return ctx;
 
 	ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0,
 			GFP_KERNEL);
-	if (ret < 0)
+	if (ret < 0) {
+		ctx->ppgtt.cleanup(&ctx->ppgtt);
 		goto err_out;
+	}
 
 	ctx->file_priv = file_priv;
 	ctx->id = ret;
@@ -220,6 +227,7 @@  static int create_default_context(struct drm_i915_private *dev_priv)
 	}
 
 	dev_priv->ring[RCS].default_context = ctx;
+	dev_priv->mm.aliasing_ppgtt = &ctx->ppgtt;
 
 	DRM_DEBUG_DRIVER("Default HW context loaded\n");
 	return 0;
@@ -293,6 +301,7 @@  void i915_gem_context_fini(struct drm_device *dev)
 	i915_gem_context_unreference(dctx);
 	dev_priv->ring[RCS].default_context = NULL;
 	dev_priv->ring[RCS].last_context = NULL;
+	dev_priv->mm.aliasing_ppgtt = NULL;
 }
 
 int i915_gem_context_enable(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index a126955..15ca68c 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -375,18 +375,6 @@  int i915_gem_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
 	return ret;
 }
 
-void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
-
-	if (!ppgtt)
-		return;
-
-	ppgtt->cleanup(ppgtt);
-	dev_priv->mm.aliasing_ppgtt = NULL;
-}
-
 void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
 			    struct drm_i915_gem_object *obj,
 			    enum i915_cache_level cache_level)