[v2,3/7] drm/i915/gen8: Enable WA batch buffers during ctx save/restore

Submitted by arun.siluvery@linux.intel.com on May 29, 2015, 6:03 p.m.

Details

Message ID 1432922605-5893-4-git-send-email-arun.siluvery@linux.intel.com
State New
Headers show

Not browsing as part of any series.

Commit Message

arun.siluvery@linux.intel.com May 29, 2015, 6:03 p.m.
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@intel.com>
Signed-off-by: Arun Siluvery <arun.siluvery@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(-)

Patch hide | download patch | download mbox

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,