[PATCH 17/49] drm/i915/bdw: A bit more advanced context init/fini

oscar.mateo
2014-03-27T17:09:31Z

From: Ben Widawsky <benjamin.widawsky@intel.com>

There are a few big differences between context init and fini with the
previous implementation of hardware contexts. One of them is
demonstrated in this patch: we must do a context initialization for
every ring.

The patch will still fail at context setup, and therefore won't break
existing code or platform support.

Regarding the context size, reading the register to calculate the sizes
can work, I think, however the docs are very clear about the actual
context sizes on GEN8, so just hardcode that and use it.

Signed-off-by: Ben Widawsky <ben@bwidawsk.net>

v2: Rebased on top of the Full PPGTT series. It is important to notice
that at this point we have one global default context per engine, all
of them using the aliasing PPGTT (as opposed to the single global
default context we have with legacy HW contexts).

Signed-off-by: Oscar Mateo <oscar.mateo@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_gem_context.c | 5 +++++
drivers/gpu/drm/i915/i915_lrc.c | 40 ++++++++++++++++++++++++++++++++-
3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 264ea67..ff6a33c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2316,6 +2316,7 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,

/* i915_lrc.c */
int gen8_gem_context_init(struct drm_device *dev);
+void gen8_gem_context_fini(struct drm_device *dev);

/* i915_gem_evict.c */
int __must_check i915_gem_evict_something(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index e92b9c5..4a6f1b0 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -440,6 +440,11 @@ void i915_gem_context_fini(struct drm_device *dev)
* other code, leading to spurious errors. */
intel_gpu_reset(dev);

+ if (dev_priv->lrc_enabled) {
+ gen8_gem_context_fini(dev);
+ return;
+ }
+
/* When default context is created and switched to, base object refcount
* will be 2 (+1 from object creation and +1 from do_switch()).
* i915_gem_context_fini() will be called after gpu_idle() has switched
diff --git a/drivers/gpu/drm/i915/i915_lrc.c b/drivers/gpu/drm/i915/i915_lrc.c
index 3a93e99..10e6dbc 100644
--- a/drivers/gpu/drm/i915/i915_lrc.c
+++ b/drivers/gpu/drm/i915/i915_lrc.c
@@ -41,7 +41,45 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"

+#define GEN8_LR_CONTEXT_SIZE (21 * PAGE_SIZE)
+
+void gen8_gem_context_fini(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_engine *ring;
+ int unused;
+
+ for_each_ring(ring, dev_priv, unused) {
+ if (ring->default_context) {
+ i915_gem_object_ggtt_unpin(ring->default_context->obj);
+ i915_gem_context_unreference(ring->default_context);
+ ring->default_context = NULL;
+ }
+ }
+
+ dev_priv->mm.aliasing_ppgtt = NULL;
+}
+
int gen8_gem_context_init(struct drm_device *dev)
{
- return -ENOSYS;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_engine *ring;
+ int ret = -ENOSYS, ring_id;
+
+ dev_priv->hw_context_size = round_up(GEN8_LR_CONTEXT_SIZE, 4096);
+
+ for_each_ring(ring, dev_priv, ring_id) {
+ ring->default_context = i915_gem_create_context(dev,
+ NULL, (ring_id == RCS));
+ if (IS_ERR_OR_NULL(ring->default_context)) {
+ ret = PTR_ERR(ring->default_context);
+ DRM_DEBUG_DRIVER("Create ctx failed: %d\n", ret);
+ ring->default_context = NULL;
+ goto err_out;
+ }
+ }
+
+err_out:
+ gen8_gem_context_fini(dev);
+ return ret;
}
--
1.9.0