[PATCH 39/49] drm/i915/bdw: Swap the PPGTT PDPs, LRC style

oscar.mateo
2014-03-27T17:12:49Z

From: Oscar Mateo <oscar.mateo@intel.com>

Each logical ring context has the PDPs in the context object, so update
them before submission. This should work both for Aliasing PPGTT
(nothing will be changed) and Full PPGTT.

Also, don't write PDP in the legacy way when using logical ring contexts
(this is mostly for correctness so that we know we are running the
LR context correctly).

Signed-off-by: Oscar Mateo <oscar.mateo@intel.com>
---
drivers/gpu/drm/i915/i915_gem_gtt.c | 4 ++++
drivers/gpu/drm/i915/i915_lrc.c | 34 +++++++++++++++++++++++++++++++++-
2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e5911ec..9f39b7f 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -220,11 +220,15 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
struct intel_engine *ring,
bool synchronous)
{
+ struct drm_i915_private *dev_priv = ring->dev->dev_private;
int i, ret;

/* bit of a hack to find the actual last used pd */
int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE;

+ if (dev_priv->lrc_enabled)
+ return 0;
+
for (i = used_pd - 1; i >= 0; i--) {
dma_addr_t addr = ppgtt->pd_dma_addr[i];
ret = gen8_write_pdp(ring, i, addr, synchronous);
diff --git a/drivers/gpu/drm/i915/i915_lrc.c b/drivers/gpu/drm/i915/i915_lrc.c
index 6948df1..9984a54 100644
--- a/drivers/gpu/drm/i915/i915_lrc.c
+++ b/drivers/gpu/drm/i915/i915_lrc.c
@@ -172,15 +172,47 @@ static void submit_execlist(struct intel_engine *ring,
gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
}

+static int gen8_write_pdp_ctx(struct i915_hw_context *ctx,
+ struct i915_hw_ppgtt *ppgtt)
+{
+ struct page *page;
+ uint32_t *reg_state;
+
+ page = i915_gem_object_get_page(ctx->obj, 1);
+ reg_state = kmap_atomic(page);
+
+ reg_state[CTX_PDP3_UDW+1] = ppgtt->pd_dma_addr[3] >> 32;
+ reg_state[CTX_PDP3_LDW+1] = ppgtt->pd_dma_addr[3];
+ reg_state[CTX_PDP2_UDW+1] = ppgtt->pd_dma_addr[2] >> 32;
+ reg_state[CTX_PDP2_LDW+1] = ppgtt->pd_dma_addr[2];
+ reg_state[CTX_PDP1_UDW+1] = ppgtt->pd_dma_addr[1] >> 32;
+ reg_state[CTX_PDP1_LDW+1] = ppgtt->pd_dma_addr[1];
+ reg_state[CTX_PDP0_UDW+1] = ppgtt->pd_dma_addr[0] >> 32;
+ reg_state[CTX_PDP0_LDW+1] = ppgtt->pd_dma_addr[0];
+
+ kunmap_atomic(reg_state);
+
+ return 0;
+}
+
static int gen8_switch_context(struct intel_engine *ring,
struct i915_hw_context *to0, u32 tail0,
struct i915_hw_context *to1, u32 tail1)
{
+ struct i915_hw_ppgtt *ppgtt;
+
BUG_ON(!i915_gem_obj_is_pinned(to0->obj));

- if (to1)
+ ppgtt = ctx_to_ppgtt(to0);
+ gen8_write_pdp_ctx(to0, ppgtt);
+
+ if (to1) {
BUG_ON(!i915_gem_obj_is_pinned(to1->obj));

+ ppgtt = ctx_to_ppgtt(to1);
+ gen8_write_pdp_ctx(to1, ppgtt);
+ }
+
submit_execlist(ring, to0, to1);

return 0;
--
1.9.0