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.barbalho@xxxxxxxxx> Signed-off-by: Arun Siluvery <arun.siluvery@xxxxxxxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx