|
@@ -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);
|