OSDN Git Service

drm/i915/tgl: Adjust the location of RING_MI_MODE in the context image
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 26 Oct 2019 08:22:20 +0000 (09:22 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Sat, 26 Oct 2019 08:48:34 +0000 (09:48 +0100)
The location of RING_MI_MODE (used to stop the ring across resets) moved
for Tigerlake. Fixup the new location and include a selftest to verify
the location in the default context image.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Acked-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191026082220.32632-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/gt/intel_lrc.c
drivers/gpu/drm/i915/gt/selftest_lrc.c

index 523de1f..1634074 100644 (file)
@@ -2935,14 +2935,28 @@ static void reset_csb_pointers(struct intel_engine_cs *engine)
                               &execlists->csb_status[reset_value]);
 }
 
+static int lrc_ring_mi_mode(const struct intel_engine_cs *engine)
+{
+       if (INTEL_GEN(engine->i915) >= 12)
+               return 0x60;
+       else if (INTEL_GEN(engine->i915) >= 9)
+               return 0x54;
+       else if (engine->class == RENDER_CLASS)
+               return 0x58;
+       else
+               return -1;
+}
+
 static void __execlists_reset_reg_state(const struct intel_context *ce,
                                        const struct intel_engine_cs *engine)
 {
        u32 *regs = ce->lrc_reg_state;
+       int x;
 
-       if (INTEL_GEN(engine->i915) >= 9) {
-               regs[GEN9_CTX_RING_MI_MODE + 1] &= ~STOP_RING;
-               regs[GEN9_CTX_RING_MI_MODE + 1] |= STOP_RING << 16;
+       x = lrc_ring_mi_mode(engine);
+       if (x != -1) {
+               regs[x + 1] &= ~STOP_RING;
+               regs[x + 1] |= STOP_RING << 16;
        }
 }
 
index d5d268b..ba7fc43 100644 (file)
@@ -3165,6 +3165,75 @@ static int live_lrc_layout(void *arg)
        return err;
 }
 
+static int find_offset(const u32 *lri, u32 offset)
+{
+       int i;
+
+       for (i = 0; i < PAGE_SIZE / sizeof(u32); i++)
+               if (lri[i] == offset)
+                       return i;
+
+       return -1;
+}
+
+static int live_lrc_fixed(void *arg)
+{
+       struct intel_gt *gt = arg;
+       struct intel_engine_cs *engine;
+       enum intel_engine_id id;
+       int err = 0;
+
+       /*
+        * Check the assumed register offsets match the actual locations in
+        * the context image.
+        */
+
+       for_each_engine(engine, gt, id) {
+               const struct {
+                       u32 reg;
+                       u32 offset;
+                       const char *name;
+               } tbl[] = {
+                       {
+                               i915_mmio_reg_offset(RING_MI_MODE(engine->mmio_base)),
+                               lrc_ring_mi_mode(engine),
+                               "RING_MI_MODE",
+                       },
+                       { },
+               }, *t;
+               u32 *hw;
+
+               if (!engine->default_state)
+                       continue;
+
+               hw = i915_gem_object_pin_map(engine->default_state,
+                                            I915_MAP_WB);
+               if (IS_ERR(hw)) {
+                       err = PTR_ERR(hw);
+                       break;
+               }
+               hw += LRC_STATE_PN * PAGE_SIZE / sizeof(*hw);
+
+               for (t = tbl; t->name; t++) {
+                       int dw = find_offset(hw, t->reg);
+
+                       if (dw != t->offset) {
+                               pr_err("%s: Offset for %s [0x%x] mismatch, found %x, expected %x\n",
+                                      engine->name,
+                                      t->name,
+                                      t->reg,
+                                      dw,
+                                      t->offset);
+                               err = -EINVAL;
+                       }
+               }
+
+               i915_gem_object_unpin_map(engine->default_state);
+       }
+
+       return err;
+}
+
 static int __live_lrc_state(struct i915_gem_context *fixme,
                            struct intel_engine_cs *engine,
                            struct i915_vma *scratch)
@@ -3437,6 +3506,7 @@ int intel_lrc_live_selftests(struct drm_i915_private *i915)
 {
        static const struct i915_subtest tests[] = {
                SUBTEST(live_lrc_layout),
+               SUBTEST(live_lrc_fixed),
                SUBTEST(live_lrc_state),
                SUBTEST(live_gpr_clear),
        };