drm/i915: Initialize workarounds in logical ring mode too
authorMichel Thierry <michel.thierry@intel.com>
Tue, 11 Nov 2014 16:47:33 +0000 (16:47 +0000)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 14 Nov 2014 09:29:25 +0000 (10:29 +0100)
Following the legacy ring submission example, update the
ring->init_context() hook to support the execlist submission mode.

v2: update to use the new workaround macros and cleanup unused code.
This takes care of both bdw and chv workarounds.

v2.1: Add missing call to init_context() during deferred context creation.

v3: Split init_context (emit) in legacy/lrc modes. For lrc, get the ringbuf
from the context (Mika/Daniel).

v4: Merge init_context interfaces back, the legacy mode only needs the ring,
but the lrc mode needs the ring and context (Mika).

Issue: VIZ-4092
Issue: GMIN-3475
Change-Id: Ie3d093b2542ab0e2a44b90460533e2f979788d6c
Cc: Deepak S <deepak.s@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Arun Siluvery <arun.siluvery@linux.intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
[danvet: Align function paramater lists properly.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index 1fb00008623d648549fc71113031e378d7292be2..d17ff435f2767fa31c51ed08ef5e3130aa4dddbd 100644 (file)
@@ -635,7 +635,7 @@ done:
 
        if (uninitialized) {
                if (ring->init_context) {
-                       ret = ring->init_context(ring);
+                       ret = ring->init_context(ring, to);
                        if (ret)
                                DRM_ERROR("ring init context: %d\n", ret);
                }
index 6025ac754c37594edda70817c33d5e9efd2e4c1c..2a1a7193342055da367d8f5d38d765c735917004 100644 (file)
@@ -989,6 +989,44 @@ int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords)
        return 0;
 }
 
+static int intel_logical_ring_workarounds_emit(struct intel_engine_cs *ring,
+                                              struct intel_context *ctx)
+{
+       int ret, i;
+       struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf;
+       struct drm_device *dev = ring->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct i915_workarounds *w = &dev_priv->workarounds;
+
+       if (WARN_ON(w->count == 0))
+               return 0;
+
+       ring->gpu_caches_dirty = true;
+       ret = logical_ring_flush_all_caches(ringbuf);
+       if (ret)
+               return ret;
+
+       ret = intel_logical_ring_begin(ringbuf, w->count * 2 + 2);
+       if (ret)
+               return ret;
+
+       intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(w->count));
+       for (i = 0; i < w->count; i++) {
+               intel_logical_ring_emit(ringbuf, w->reg[i].addr);
+               intel_logical_ring_emit(ringbuf, w->reg[i].value);
+       }
+       intel_logical_ring_emit(ringbuf, MI_NOOP);
+
+       intel_logical_ring_advance(ringbuf);
+
+       ring->gpu_caches_dirty = true;
+       ret = logical_ring_flush_all_caches(ringbuf);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static int gen8_init_common_ring(struct intel_engine_cs *ring)
 {
        struct drm_device *dev = ring->dev;
@@ -1032,7 +1070,7 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring)
 
        I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
 
-       return ret;
+       return init_workarounds_ring(ring);
 }
 
 static int gen8_emit_bb_start(struct intel_ringbuffer *ringbuf,
@@ -1282,6 +1320,7 @@ static int logical_render_ring_init(struct drm_device *dev)
                ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
 
        ring->init = gen8_init_render_ring;
+       ring->init_context = intel_logical_ring_workarounds_emit;
        ring->cleanup = intel_fini_pipe_control;
        ring->get_seqno = gen8_get_seqno;
        ring->set_seqno = gen8_set_seqno;
@@ -1763,6 +1802,12 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
        }
 
        if (ring->id == RCS && !ctx->rcs_initialized) {
+               if (ring->init_context) {
+                       ret = ring->init_context(ring, ctx);
+                       if (ret)
+                               DRM_ERROR("ring init context: %d\n", ret);
+               }
+
                ret = intel_lr_context_render_state_init(ring, ctx);
                if (ret) {
                        DRM_ERROR("Init render state failed: %d\n", ret);
index a09aae70e579da2e42c0ce1d496b344ac8b5cd23..ae092589ea0ce61daabe4c262fc46ef30e551f49 100644 (file)
@@ -665,7 +665,8 @@ err:
        return ret;
 }
 
-static int intel_ring_workarounds_emit(struct intel_engine_cs *ring)
+static int intel_ring_workarounds_emit(struct intel_engine_cs *ring,
+                                      struct intel_context *ctx)
 {
        int ret, i;
        struct drm_device *dev = ring->dev;
@@ -806,7 +807,7 @@ static int chv_init_workarounds(struct intel_engine_cs *ring)
        return 0;
 }
 
-static int init_workarounds_ring(struct intel_engine_cs *ring)
+int init_workarounds_ring(struct intel_engine_cs *ring)
 {
        struct drm_device *dev = ring->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
index 96479c89f4bda9c2e6af0084e75b6785eee6ccfa..aab2e2f90a74b262f5c4a7baf0d92b7fbc221292 100644 (file)
@@ -148,7 +148,8 @@ struct  intel_engine_cs {
 
        int             (*init)(struct intel_engine_cs *ring);
 
-       int             (*init_context)(struct intel_engine_cs *ring);
+       int             (*init_context)(struct intel_engine_cs *ring,
+                                       struct intel_context *ctx);
 
        void            (*write_tail)(struct intel_engine_cs *ring,
                                      u32 value);
@@ -424,6 +425,8 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev);
 u64 intel_ring_get_active_head(struct intel_engine_cs *ring);
 void intel_ring_setup_status_page(struct intel_engine_cs *ring);
 
+int init_workarounds_ring(struct intel_engine_cs *ring);
+
 static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf)
 {
        return ringbuf->tail;