Populate Ctx offset pointer registers with WA batch buffer address;
Let the HW know about these batch buffers so that it can execute them
during ctx save/restore.

Signed-off-by: Rafael Barbalho <rafael.barba...@intel.com>
Signed-off-by: Arun Siluvery <arun.siluv...@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c        | 74 +++++++++++++++++++++++++++++----
 drivers/gpu/drm/i915/intel_ringbuffer.h |  3 ++
 2 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index d124636..ee968e1 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -211,6 +211,7 @@ enum {
        FAULT_AND_CONTINUE /* Unsupported */
 };
 #define GEN8_CTX_ID_SHIFT 32
+#define CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT  0x17
 
 static int intel_lr_context_pin(struct intel_engine_cs *ring,
                struct intel_context *ctx);
@@ -1173,7 +1174,18 @@ static int intel_init_workaround_bb(struct 
intel_engine_cs *ring,
        if (WARN_ON(ring->id != RCS))
                return -EINVAL;
 
-       /* FIXME: Add Gen specific init functions */
+       if (IS_GEN8(dev)) {
+               ret = gen8_init_indirectctx_bb(ring, ctx);
+               if (ret)
+                       return ret;
+
+               ret = gen8_init_perctx_bb(ring, ctx);
+               if (ret)
+                       return ret;
+       } else {
+               WARN_ONCE(INTEL_INFO(dev)->gen > 8,
+                         "WA batch buffers are not initialized\n");
+       }
 
        return 0;
 }
@@ -1561,6 +1573,7 @@ static int logical_render_ring_init(struct drm_device 
*dev)
        else
                ring->init_hw = gen8_init_render_ring;
        ring->init_context = gen8_init_rcs_context;
+       ring->init_context_bb = intel_init_workaround_bb;
        ring->cleanup = intel_fini_pipe_control;
        ring->get_seqno = gen8_get_seqno;
        ring->set_seqno = gen8_set_seqno;
@@ -1860,15 +1873,29 @@ populate_lr_context(struct intel_context *ctx, struct 
drm_i915_gem_object *ctx_o
        reg_state[CTX_SECOND_BB_STATE] = ring->mmio_base + 0x118;
        reg_state[CTX_SECOND_BB_STATE+1] = 0;
        if (ring->id == RCS) {
-               /* TODO: according to BSpec, the register state context
-                * for CHV does not have these. OTOH, these registers do
-                * exist in CHV. I'm waiting for a clarification */
                reg_state[CTX_BB_PER_CTX_PTR] = ring->mmio_base + 0x1c0;
-               reg_state[CTX_BB_PER_CTX_PTR+1] = 0;
+
+               if (ctx->per_ctx_wa_bb)
+                       reg_state[CTX_BB_PER_CTX_PTR + 1] =
+                               i915_gem_obj_ggtt_offset(
+                                       ctx->per_ctx_wa_bb->obj) | 0x01;
+               else
+                       reg_state[CTX_BB_PER_CTX_PTR+1] = 0;
+
                reg_state[CTX_RCS_INDIRECT_CTX] = ring->mmio_base + 0x1c4;
-               reg_state[CTX_RCS_INDIRECT_CTX+1] = 0;
                reg_state[CTX_RCS_INDIRECT_CTX_OFFSET] = ring->mmio_base + 
0x1c8;
-               reg_state[CTX_RCS_INDIRECT_CTX_OFFSET+1] = 0;
+
+               if (ctx->indirect_ctx_wa_bb) {
+                       reg_state[CTX_RCS_INDIRECT_CTX + 1] =
+                               i915_gem_obj_ggtt_offset(
+                               ctx->indirect_ctx_wa_bb->obj) | 0x01;
+
+                       reg_state[CTX_RCS_INDIRECT_CTX_OFFSET + 1] =
+                               CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT << 6;
+               } else {
+                       reg_state[CTX_RCS_INDIRECT_CTX+1] = 0;
+                       reg_state[CTX_RCS_INDIRECT_CTX_OFFSET+1] = 0;
+               }
        }
        reg_state[CTX_LRI_HEADER_1] = MI_LOAD_REGISTER_IMM(9);
        reg_state[CTX_LRI_HEADER_1] |= MI_LRI_FORCE_POSTED;
@@ -1935,6 +1962,18 @@ void intel_lr_context_free(struct intel_context *ctx)
                        drm_gem_object_unreference(&ctx_obj->base);
                }
        }
+
+       if (ctx->indirect_ctx_wa_bb) {
+               intel_unpin_ringbuffer_obj(ctx->indirect_ctx_wa_bb);
+               intel_destroy_ringbuffer_obj(ctx->indirect_ctx_wa_bb);
+               kfree(ctx->indirect_ctx_wa_bb);
+       }
+
+       if (ctx->per_ctx_wa_bb) {
+               intel_unpin_ringbuffer_obj(ctx->per_ctx_wa_bb);
+               intel_destroy_ringbuffer_obj(ctx->per_ctx_wa_bb);
+               kfree(ctx->per_ctx_wa_bb);
+       }
 }
 
 static uint32_t get_lr_context_size(struct intel_engine_cs *ring)
@@ -2060,6 +2099,16 @@ int intel_lr_context_deferred_create(struct 
intel_context *ctx,
 
        }
 
+       if (ring->id == RCS && !ctx->rcs_initialized) {
+               if (ring->init_context_bb) {
+                       ret = ring->init_context_bb(ring, ctx);
+                       if (ret) {
+                               DRM_ERROR("ring init context bb: %d\n", ret);
+                               goto error;
+                       }
+               }
+       }
+
        ret = populate_lr_context(ctx, ctx_obj, ring, ringbuf);
        if (ret) {
                DRM_DEBUG_DRIVER("Failed to populate LRC: %d\n", ret);
@@ -2088,6 +2137,17 @@ int intel_lr_context_deferred_create(struct 
intel_context *ctx,
        return 0;
 
 error:
+       if (ctx->indirect_ctx_wa_bb) {
+               intel_unpin_ringbuffer_obj(ctx->indirect_ctx_wa_bb);
+               intel_destroy_ringbuffer_obj(ctx->indirect_ctx_wa_bb);
+               kfree(ctx->indirect_ctx_wa_bb);
+       }
+       if (ctx->per_ctx_wa_bb) {
+               intel_unpin_ringbuffer_obj(ctx->per_ctx_wa_bb);
+               intel_destroy_ringbuffer_obj(ctx->per_ctx_wa_bb);
+               kfree(ctx->per_ctx_wa_bb);
+       }
+
        if (is_global_default_ctx)
                intel_unpin_ringbuffer_obj(ringbuf);
 error_destroy_rbuf:
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h 
b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 39f6dfc..ddb8421 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -154,6 +154,9 @@ struct  intel_engine_cs {
        int             (*init_context)(struct intel_engine_cs *ring,
                                        struct intel_context *ctx);
 
+       int             (*init_context_bb)(struct intel_engine_cs *ring,
+                                          struct intel_context *ctx);
+
        void            (*write_tail)(struct intel_engine_cs *ring,
                                      u32 value);
        int __must_check (*flush)(struct intel_engine_cs *ring,
-- 
2.3.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to