drm/i915: Fix startup failure in LRC mode after recent init changes
authorThomas Daniel <thomas.daniel@intel.com>
Tue, 2 Dec 2014 12:50:48 +0000 (12:50 +0000)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 3 Dec 2014 08:35:30 +0000 (09:35 +0100)
A previous commit introduced engine init changes:

    commit 372ee59699d9 ("drm/i915: Only init engines once")

This broke execlists as intel_lr_context_render_state_init was trying to emit
commands to the RCS for the default context before the ring->init_hw was called.

Made a new gen8_init_rcs_context function and assign in to render ring
init_context.  Moved call to intel_logical_ring_workarounds_emit into
gen8_init_rcs_context to maintain previous functionality.

Moved call to render_state_init from lr_context_deferred_create into
gen8_init_rcs_context, and modified deferred_create to call ring->init_context
for non-default contexts.

Modified i915_gem_context_enable to call ring->init_context for the default
context.

So init_context will now always be called when the hw is ready - in
i915_gem_context_enable for the default context and in lr_context_deferred_create
for other contexts.

Signed-off-by: Thomas Daniel <thomas.daniel@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/intel_lrc.c

index 3c3a9ff9eb5446594f56cb36c6ebc9b290742e1f..5cd2b97aa76e532d4d988148af9fd92444943869 100644 (file)
@@ -408,14 +408,25 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
 
        BUG_ON(!dev_priv->ring[RCS].default_context);
 
-       if (i915.enable_execlists)
-               return 0;
+       if (i915.enable_execlists) {
+               for_each_ring(ring, dev_priv, i) {
+                       if (ring->init_context) {
+                               ret = ring->init_context(ring,
+                                               ring->default_context);
+                               if (ret) {
+                                       DRM_ERROR("ring init context: %d\n",
+                                                       ret);
+                                       return ret;
+                               }
+                       }
+               }
 
-       for_each_ring(ring, dev_priv, i) {
-               ret = i915_switch_context(ring, ring->default_context);
-               if (ret)
-                       return ret;
-       }
+       } else
+               for_each_ring(ring, dev_priv, i) {
+                       ret = i915_switch_context(ring, ring->default_context);
+                       if (ret)
+                               return ret;
+               }
 
        return 0;
 }
index d6f82532ac1d6219a782d5607bda7bcb30ebec1b..52e9952206d9dae1811c1e5126e2e4a4276c0d8c 100644 (file)
@@ -1336,6 +1336,18 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf)
        return 0;
 }
 
+static int gen8_init_rcs_context(struct intel_engine_cs *ring,
+                      struct intel_context *ctx)
+{
+       int ret;
+
+       ret = intel_logical_ring_workarounds_emit(ring, ctx);
+       if (ret)
+               return ret;
+
+       return intel_lr_context_render_state_init(ring, ctx);
+}
+
 /**
  * intel_logical_ring_cleanup() - deallocate the Engine Command Streamer
  *
@@ -1409,7 +1421,7 @@ static int logical_render_ring_init(struct drm_device *dev)
                ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
 
        ring->init_hw = gen8_init_render_ring;
-       ring->init_context = intel_logical_ring_workarounds_emit;
+       ring->init_context = gen8_init_rcs_context;
        ring->cleanup = intel_fini_pipe_control;
        ring->get_seqno = gen8_get_seqno;
        ring->set_seqno = gen8_set_seqno;
@@ -1904,21 +1916,17 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
 
        if (ctx == ring->default_context)
                lrc_setup_hardware_status_page(ring, ctx_obj);
-
-       if (ring->id == RCS && !ctx->rcs_initialized) {
+       else if (ring->id == RCS && !ctx->rcs_initialized) {
                if (ring->init_context) {
                        ret = ring->init_context(ring, ctx);
-                       if (ret)
+                       if (ret) {
                                DRM_ERROR("ring init context: %d\n", ret);
+                               ctx->engine[ring->id].ringbuf = NULL;
+                               ctx->engine[ring->id].state = NULL;
+                               goto error;
+                       }
                }
 
-               ret = intel_lr_context_render_state_init(ring, ctx);
-               if (ret) {
-                       DRM_ERROR("Init render state failed: %d\n", ret);
-                       ctx->engine[ring->id].ringbuf = NULL;
-                       ctx->engine[ring->id].state = NULL;
-                       goto error;
-               }
                ctx->rcs_initialized = true;
        }