Commit e7778be1 authored by Thomas Daniel's avatar Thomas Daniel Committed by Daniel Vetter

drm/i915: Fix startup failure in LRC mode after recent init changes

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: default avatarThomas Daniel <thomas.daniel@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent d972d6ee
...@@ -408,14 +408,25 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv) ...@@ -408,14 +408,25 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
BUG_ON(!dev_priv->ring[RCS].default_context); BUG_ON(!dev_priv->ring[RCS].default_context);
if (i915.enable_execlists) if (i915.enable_execlists) {
return 0; 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) { } else
ret = i915_switch_context(ring, ring->default_context); for_each_ring(ring, dev_priv, i) {
if (ret) ret = i915_switch_context(ring, ring->default_context);
return ret; if (ret)
} return ret;
}
return 0; return 0;
} }
......
...@@ -1336,6 +1336,18 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf) ...@@ -1336,6 +1336,18 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf)
return 0; 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 * intel_logical_ring_cleanup() - deallocate the Engine Command Streamer
* *
...@@ -1409,7 +1421,7 @@ static int logical_render_ring_init(struct drm_device *dev) ...@@ -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->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
ring->init_hw = gen8_init_render_ring; 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->cleanup = intel_fini_pipe_control;
ring->get_seqno = gen8_get_seqno; ring->get_seqno = gen8_get_seqno;
ring->set_seqno = gen8_set_seqno; ring->set_seqno = gen8_set_seqno;
...@@ -1904,21 +1916,17 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, ...@@ -1904,21 +1916,17 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
if (ctx == ring->default_context) if (ctx == ring->default_context)
lrc_setup_hardware_status_page(ring, ctx_obj); lrc_setup_hardware_status_page(ring, ctx_obj);
else if (ring->id == RCS && !ctx->rcs_initialized) {
if (ring->id == RCS && !ctx->rcs_initialized) {
if (ring->init_context) { if (ring->init_context) {
ret = ring->init_context(ring, ctx); ret = ring->init_context(ring, ctx);
if (ret) if (ret) {
DRM_ERROR("ring init context: %d\n", 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; ctx->rcs_initialized = true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment