drm/i915/xehpsdv/dg1/tgl: Fix issue with LRI relative addressing
authorAkeem G Abodunrin <akeem.g.abodunrin@intel.com>
Mon, 25 Apr 2022 15:23:15 +0000 (20:53 +0530)
committerRamalingam C <ramalingam.c@intel.com>
Mon, 2 May 2022 09:48:07 +0000 (15:18 +0530)
When bit 19 of MI_LOAD_REGISTER_IMM instruction opcode is set on tgl+
devices, HW does not care about certain register address offsets, but
instead check the following for valid address ranges on specific engines:
RCS && CCS: BITS(0 - 10)
BCS: BITS(0 - 11)
VECS && VCS: BITS(0 - 13)
Also, tgl+ now support relative addressing for BCS engine - So, this
patch fixes issue with live_gt_lrc selftest that is failing where there is
mismatch between LRC register layout generated during init and HW
default register offsets.

Signed-off-by: Akeem G Abodunrin <akeem.g.abodunrin@intel.com>
cc: Prathap Kumar Valsan <prathap.kumar.valsan@intel.com>
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220425152317.4275-2-ramalingam.c@intel.com
drivers/gpu/drm/i915/gt/selftest_lrc.c

index 6ba52ef1acb8e085ca205898bb68137755e8c1ea..8dc7b88cdca00468c8ba6756b4f8a08e5f65da99 100644 (file)
@@ -128,6 +128,27 @@ static int context_flush(struct intel_context *ce, long timeout)
        return err;
 }
 
+static int get_lri_mask(struct intel_engine_cs *engine, u32 lri)
+{
+       if ((lri & MI_LRI_LRM_CS_MMIO) == 0)
+               return ~0u;
+
+       if (GRAPHICS_VER(engine->i915) < 12)
+               return 0xfff;
+
+       switch (engine->class) {
+       default:
+       case RENDER_CLASS:
+       case COMPUTE_CLASS:
+               return 0x07ff;
+       case COPY_ENGINE_CLASS:
+               return 0x0fff;
+       case VIDEO_DECODE_CLASS:
+       case VIDEO_ENHANCEMENT_CLASS:
+               return 0x3fff;
+       }
+}
+
 static int live_lrc_layout(void *arg)
 {
        struct intel_gt *gt = arg;
@@ -167,6 +188,7 @@ static int live_lrc_layout(void *arg)
                dw = 0;
                do {
                        u32 lri = READ_ONCE(hw[dw]);
+                       u32 lri_mask;
 
                        if (lri == 0) {
                                dw++;
@@ -194,6 +216,18 @@ static int live_lrc_layout(void *arg)
                                break;
                        }
 
+                       /*
+                        * When bit 19 of MI_LOAD_REGISTER_IMM instruction
+                        * opcode is set on Gen12+ devices, HW does not
+                        * care about certain register address offsets, and
+                        * instead check the following for valid address
+                        * ranges on specific engines:
+                        * RCS && CCS: BITS(0 - 10)
+                        * BCS: BITS(0 - 11)
+                        * VECS && VCS: BITS(0 - 13)
+                        */
+                       lri_mask = get_lri_mask(engine, lri);
+
                        lri &= 0x7f;
                        lri++;
                        dw++;
@@ -201,7 +235,7 @@ static int live_lrc_layout(void *arg)
                        while (lri) {
                                u32 offset = READ_ONCE(hw[dw]);
 
-                               if (offset != lrc[dw]) {
+                               if ((offset ^ lrc[dw]) & lri_mask) {
                                        pr_err("%s: Different registers found at dword %d, expected %x, found %x\n",
                                               engine->name, dw, offset, lrc[dw]);
                                        err = -EINVAL;