[Intel-gfx] [PATCH v2 3/7] drm/i915/gen8: Enable WA batch buffers during ctx save/restore
Arun Siluvery
arun.siluvery at linux.intel.com
Fri May 29 11:03:21 PDT 2015
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 at intel.com>
Signed-off-by: Arun Siluvery <arun.siluvery at 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
More information about the Intel-gfx
mailing list