diff options
author | Tvrtko Ursulin | 2017-03-09 14:20:04 +0100 |
---|---|---|
committer | Tvrtko Ursulin | 2017-03-10 08:47:12 +0100 |
commit | cbf4b77af11ba93ea2ed7effa37da2a39e970851 (patch) | |
tree | 30592ccf9c19cca8fd44a201ba7769e5cf6c6646 /drivers/gpu/drm/i915/i915_guc_submission.c | |
parent | drm/i915: Ignore skl+ for debugfs/i915_sr_status (diff) | |
download | kernel-qcow2-linux-cbf4b77af11ba93ea2ed7effa37da2a39e970851.tar.gz kernel-qcow2-linux-cbf4b77af11ba93ea2ed7effa37da2a39e970851.tar.xz kernel-qcow2-linux-cbf4b77af11ba93ea2ed7effa37da2a39e970851.zip |
drm/i915/guc: Fix request re-submission after reset
In order to ensure no missed interrupts we must first re-direct
the interrupts to GuC, and only then re-submit the requests to
be replayed after a GPU reset. Otherwise context switch can fire
before GuC has been set up to receive it triggering more hangs.
v2: Rebase.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Oscar Mateo <oscar.mateo@intel.com>
Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170309132005.1317-1-tvrtko.ursulin@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/i915_guc_submission.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_guc_submission.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index beb38e30d0e9..41f2dd87b413 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -936,6 +936,26 @@ static void guc_reset_wq(struct i915_guc_client *client) client->wq_tail = 0; } +static void guc_interrupts_capture(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + int irqs; + + /* tell all command streamers to forward interrupts (but not vblank) to GuC */ + irqs = _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); + for_each_engine(engine, dev_priv, id) + I915_WRITE(RING_MODE_GEN7(engine), irqs); + + /* route USER_INTERRUPT to Host, all others are sent to GuC. */ + irqs = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT | + GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; + /* These three registers have the same bit definitions */ + I915_WRITE(GUC_BCS_RCS_IER, ~irqs); + I915_WRITE(GUC_VCS2_VCS1_IER, ~irqs); + I915_WRITE(GUC_WD_VECS_IER, ~irqs); +} + int i915_guc_submission_enable(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; @@ -953,13 +973,17 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) /* Take over from manual control of ELSP (execlists) */ for_each_engine(engine, dev_priv, id) { - const int wqi_size = sizeof(struct guc_wq_item); - struct drm_i915_gem_request *rq; - engine->submit_request = i915_guc_submit; engine->schedule = NULL; + } + + guc_interrupts_capture(dev_priv); + + /* Replay the current set of previously submitted requests */ + for_each_engine(engine, dev_priv, id) { + const int wqi_size = sizeof(struct guc_wq_item); + struct drm_i915_gem_request *rq; - /* Replay the current set of previously submitted requests */ spin_lock_irq(&engine->timeline->lock); list_for_each_entry(rq, &engine->timeline->requests, link) { guc_client_update_wq_rsvd(client, wqi_size); |