drm/i915: Make wa list per-gt
authorVenkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com>
Fri, 17 Sep 2021 17:08:45 +0000 (10:08 -0700)
committerMatt Roper <matthew.d.roper@intel.com>
Mon, 20 Sep 2021 15:06:36 +0000 (08:06 -0700)
Support for multiple GT's within a single i915 device will be arriving
soon.  Since each GT may have its own fusing and require different
workarounds, we need to make the GT workaround functions and multicast
steering setup per-gt.

Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210917170845.836358-1-matthew.d.roper@intel.com
drivers/gpu/drm/i915/gt/intel_gt.c
drivers/gpu/drm/i915/gt/intel_gt_types.h
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/i915/gt/intel_workarounds.h
drivers/gpu/drm/i915/gt/selftest_workarounds.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c

index 985922c03297348b9034d809984b23f19b4fd39f..0c99424bf8109d92836baf015dc40183f581e9c1 100644 (file)
@@ -660,6 +660,8 @@ int intel_gt_init(struct intel_gt *gt)
        if (err)
                return err;
 
+       intel_gt_init_workarounds(gt);
+
        /*
         * This is just a security blanket to placate dragons.
         * On some systems, we very sporadically observe that the first TLBs
@@ -767,6 +769,7 @@ void intel_gt_driver_release(struct intel_gt *gt)
        if (vm) /* FIXME being called twice on error paths :( */
                i915_vm_put(vm);
 
+       intel_wa_list_free(&gt->wa_list);
        intel_gt_pm_fini(gt);
        intel_gt_fini_scratch(gt);
        intel_gt_fini_buffer_pool(gt);
index 6fdcde64c180012707fba2efcc2d2e29dc2fbb95..ce127cae9e4922773b697cf96705eb49dd8e7375 100644 (file)
@@ -72,6 +72,8 @@ struct intel_gt {
 
        struct intel_uc uc;
 
+       struct i915_wa_list wa_list;
+
        struct intel_gt_timelines {
                spinlock_t lock; /* protects active_list */
                struct list_head active_list;
index c314d4917b6b498ec78a467e50eb3635e54f3778..e1f36253088918c9bedc0805e3bb9a7f80235c7b 100644 (file)
@@ -804,7 +804,7 @@ int intel_engine_emit_ctx_wa(struct i915_request *rq)
 }
 
 static void
-gen4_gt_workarounds_init(struct drm_i915_private *i915,
+gen4_gt_workarounds_init(struct intel_gt *gt,
                         struct i915_wa_list *wal)
 {
        /* WaDisable_RenderCache_OperationalFlush:gen4,ilk */
@@ -812,29 +812,29 @@ gen4_gt_workarounds_init(struct drm_i915_private *i915,
 }
 
 static void
-g4x_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+g4x_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       gen4_gt_workarounds_init(i915, wal);
+       gen4_gt_workarounds_init(gt, wal);
 
        /* WaDisableRenderCachePipelinedFlush:g4x,ilk */
        wa_masked_en(wal, CACHE_MODE_0, CM0_PIPELINED_RENDER_FLUSH_DISABLE);
 }
 
 static void
-ilk_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+ilk_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       g4x_gt_workarounds_init(i915, wal);
+       g4x_gt_workarounds_init(gt, wal);
 
        wa_masked_en(wal, _3D_CHICKEN2, _3D_CHICKEN2_WM_READ_PIPELINED);
 }
 
 static void
-snb_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+snb_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
 }
 
 static void
-ivb_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+ivb_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
        /* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */
        wa_masked_dis(wal,
@@ -850,7 +850,7 @@ ivb_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
 }
 
 static void
-vlv_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+vlv_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
        /* WaForceL3Serialization:vlv */
        wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE);
@@ -863,7 +863,7 @@ vlv_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
 }
 
 static void
-hsw_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+hsw_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
        /* L3 caching of data atomics doesn't work -- disable it. */
        wa_write(wal, HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE);
@@ -878,8 +878,10 @@ hsw_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
 }
 
 static void
-gen9_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+gen9_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
+       struct drm_i915_private *i915 = gt->i915;
+
        /* WaDisableKillLogic:bxt,skl,kbl */
        if (!IS_COFFEELAKE(i915) && !IS_COMETLAKE(i915))
                wa_write_or(wal,
@@ -904,9 +906,9 @@ gen9_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal
 }
 
 static void
-skl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+skl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       gen9_gt_workarounds_init(i915, wal);
+       gen9_gt_workarounds_init(gt, wal);
 
        /* WaDisableGafsUnitClkGating:skl */
        wa_write_or(wal,
@@ -914,19 +916,19 @@ skl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
                    GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
 
        /* WaInPlaceDecompressionHang:skl */
-       if (IS_SKL_GT_STEP(i915, STEP_A0, STEP_H0))
+       if (IS_SKL_GT_STEP(gt->i915, STEP_A0, STEP_H0))
                wa_write_or(wal,
                            GEN9_GAMT_ECO_REG_RW_IA,
                            GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
 }
 
 static void
-kbl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+kbl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       gen9_gt_workarounds_init(i915, wal);
+       gen9_gt_workarounds_init(gt, wal);
 
        /* WaDisableDynamicCreditSharing:kbl */
-       if (IS_KBL_GT_STEP(i915, 0, STEP_C0))
+       if (IS_KBL_GT_STEP(gt->i915, 0, STEP_C0))
                wa_write_or(wal,
                            GAMT_CHKN_BIT_REG,
                            GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);
@@ -943,15 +945,15 @@ kbl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
 }
 
 static void
-glk_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+glk_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       gen9_gt_workarounds_init(i915, wal);
+       gen9_gt_workarounds_init(gt, wal);
 }
 
 static void
-cfl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+cfl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       gen9_gt_workarounds_init(i915, wal);
+       gen9_gt_workarounds_init(gt, wal);
 
        /* WaDisableGafsUnitClkGating:cfl */
        wa_write_or(wal,
@@ -976,21 +978,21 @@ static void __set_mcr_steering(struct i915_wa_list *wal,
        wa_write_clr_set(wal, steering_reg, mcr_mask, mcr);
 }
 
-static void __add_mcr_wa(struct drm_i915_private *i915, struct i915_wa_list *wal,
+static void __add_mcr_wa(struct intel_gt *gt, struct i915_wa_list *wal,
                         unsigned int slice, unsigned int subslice)
 {
-       drm_dbg(&i915->drm, "MCR slice=0x%x, subslice=0x%x\n", slice, subslice);
+       drm_dbg(&gt->i915->drm, "MCR slice=0x%x, subslice=0x%x\n", slice, subslice);
 
        __set_mcr_steering(wal, GEN8_MCR_SELECTOR, slice, subslice);
 }
 
 static void
-icl_wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal)
+icl_wa_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       const struct sseu_dev_info *sseu = &i915->gt.info.sseu;
+       const struct sseu_dev_info *sseu = &gt->info.sseu;
        unsigned int slice, subslice;
 
-       GEM_BUG_ON(GRAPHICS_VER(i915) < 11);
+       GEM_BUG_ON(GRAPHICS_VER(gt->i915) < 11);
        GEM_BUG_ON(hweight8(sseu->slice_mask) > 1);
        slice = 0;
 
@@ -1010,16 +1012,15 @@ icl_wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal)
         * then we can just rely on the default steering and won't need to
         * worry about explicitly re-steering L3BANK reads later.
         */
-       if (i915->gt.info.l3bank_mask & BIT(subslice))
-               i915->gt.steering_table[L3BANK] = NULL;
+       if (gt->info.l3bank_mask & BIT(subslice))
+               gt->steering_table[L3BANK] = NULL;
 
-       __add_mcr_wa(i915, wal, slice, subslice);
+       __add_mcr_wa(gt, wal, slice, subslice);
 }
 
 static void
 xehp_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       struct drm_i915_private *i915 = gt->i915;
        const struct sseu_dev_info *sseu = &gt->info.sseu;
        unsigned long slice, subslice = 0, slice_mask = 0;
        u64 dss_mask = 0;
@@ -1083,7 +1084,7 @@ xehp_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)
        WARN_ON(subslice > GEN_DSS_PER_GSLICE);
        WARN_ON(dss_mask >> (slice * GEN_DSS_PER_GSLICE) == 0);
 
-       __add_mcr_wa(i915, wal, slice, subslice);
+       __add_mcr_wa(gt, wal, slice, subslice);
 
        /*
         * SQIDI ranges are special because they use different steering
@@ -1099,9 +1100,11 @@ xehp_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)
 }
 
 static void
-icl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+icl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       icl_wa_init_mcr(i915, wal);
+       struct drm_i915_private *i915 = gt->i915;
+
+       icl_wa_init_mcr(gt, wal);
 
        /* WaModifyGamTlbPartitioning:icl */
        wa_write_clr_set(wal,
@@ -1152,10 +1155,9 @@ icl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
  * the engine-specific workaround list.
  */
 static void
-wa_14011060649(struct drm_i915_private *i915, struct i915_wa_list *wal)
+wa_14011060649(struct intel_gt *gt, struct i915_wa_list *wal)
 {
        struct intel_engine_cs *engine;
-       struct intel_gt *gt = &i915->gt;
        int id;
 
        for_each_engine(engine, gt, id) {
@@ -1169,22 +1171,23 @@ wa_14011060649(struct drm_i915_private *i915, struct i915_wa_list *wal)
 }
 
 static void
-gen12_gt_workarounds_init(struct drm_i915_private *i915,
-                         struct i915_wa_list *wal)
+gen12_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       icl_wa_init_mcr(i915, wal);
+       icl_wa_init_mcr(gt, wal);
 
        /* Wa_14011060649:tgl,rkl,dg1,adl-s,adl-p */
-       wa_14011060649(i915, wal);
+       wa_14011060649(gt, wal);
 
        /* Wa_14011059788:tgl,rkl,adl-s,dg1,adl-p */
        wa_write_or(wal, GEN10_DFR_RATIO_EN_AND_CHICKEN, DFR_DISABLE);
 }
 
 static void
-tgl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+tgl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       gen12_gt_workarounds_init(i915, wal);
+       struct drm_i915_private *i915 = gt->i915;
+
+       gen12_gt_workarounds_init(gt, wal);
 
        /* Wa_1409420604:tgl */
        if (IS_TGL_UY_GT_STEP(i915, STEP_A0, STEP_B0))
@@ -1205,9 +1208,11 @@ tgl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
 }
 
 static void
-dg1_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+dg1_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       gen12_gt_workarounds_init(i915, wal);
+       struct drm_i915_private *i915 = gt->i915;
+
+       gen12_gt_workarounds_init(gt, wal);
 
        /* Wa_1607087056:dg1 */
        if (IS_DG1_GT_STEP(i915, STEP_A0, STEP_B0))
@@ -1229,60 +1234,62 @@ dg1_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
 }
 
 static void
-xehpsdv_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+xehpsdv_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-       xehp_init_mcr(&i915->gt, wal);
+       xehp_init_mcr(gt, wal);
 }
 
 static void
-gt_init_workarounds(struct drm_i915_private *i915, struct i915_wa_list *wal)
+gt_init_workarounds(struct intel_gt *gt, struct i915_wa_list *wal)
 {
+       struct drm_i915_private *i915 = gt->i915;
+
        if (IS_XEHPSDV(i915))
-               xehpsdv_gt_workarounds_init(i915, wal);
+               xehpsdv_gt_workarounds_init(gt, wal);
        else if (IS_DG1(i915))
-               dg1_gt_workarounds_init(i915, wal);
+               dg1_gt_workarounds_init(gt, wal);
        else if (IS_TIGERLAKE(i915))
-               tgl_gt_workarounds_init(i915, wal);
+               tgl_gt_workarounds_init(gt, wal);
        else if (GRAPHICS_VER(i915) == 12)
-               gen12_gt_workarounds_init(i915, wal);
+               gen12_gt_workarounds_init(gt, wal);
        else if (GRAPHICS_VER(i915) == 11)
-               icl_gt_workarounds_init(i915, wal);
+               icl_gt_workarounds_init(gt, wal);
        else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))
-               cfl_gt_workarounds_init(i915, wal);
+               cfl_gt_workarounds_init(gt, wal);
        else if (IS_GEMINILAKE(i915))
-               glk_gt_workarounds_init(i915, wal);
+               glk_gt_workarounds_init(gt, wal);
        else if (IS_KABYLAKE(i915))
-               kbl_gt_workarounds_init(i915, wal);
+               kbl_gt_workarounds_init(gt, wal);
        else if (IS_BROXTON(i915))
-               gen9_gt_workarounds_init(i915, wal);
+               gen9_gt_workarounds_init(gt, wal);
        else if (IS_SKYLAKE(i915))
-               skl_gt_workarounds_init(i915, wal);
+               skl_gt_workarounds_init(gt, wal);
        else if (IS_HASWELL(i915))
-               hsw_gt_workarounds_init(i915, wal);
+               hsw_gt_workarounds_init(gt, wal);
        else if (IS_VALLEYVIEW(i915))
-               vlv_gt_workarounds_init(i915, wal);
+               vlv_gt_workarounds_init(gt, wal);
        else if (IS_IVYBRIDGE(i915))
-               ivb_gt_workarounds_init(i915, wal);
+               ivb_gt_workarounds_init(gt, wal);
        else if (GRAPHICS_VER(i915) == 6)
-               snb_gt_workarounds_init(i915, wal);
+               snb_gt_workarounds_init(gt, wal);
        else if (GRAPHICS_VER(i915) == 5)
-               ilk_gt_workarounds_init(i915, wal);
+               ilk_gt_workarounds_init(gt, wal);
        else if (IS_G4X(i915))
-               g4x_gt_workarounds_init(i915, wal);
+               g4x_gt_workarounds_init(gt, wal);
        else if (GRAPHICS_VER(i915) == 4)
-               gen4_gt_workarounds_init(i915, wal);
+               gen4_gt_workarounds_init(gt, wal);
        else if (GRAPHICS_VER(i915) <= 8)
                ;
        else
                MISSING_CASE(GRAPHICS_VER(i915));
 }
 
-void intel_gt_init_workarounds(struct drm_i915_private *i915)
+void intel_gt_init_workarounds(struct intel_gt *gt)
 {
-       struct i915_wa_list *wal = &i915->gt_wa_list;
+       struct i915_wa_list *wal = &gt->wa_list;
 
        wa_init_start(wal, "GT", "global");
-       gt_init_workarounds(i915, wal);
+       gt_init_workarounds(gt, wal);
        wa_init_finish(wal);
 }
 
@@ -1353,7 +1360,7 @@ wa_list_apply(struct intel_gt *gt, const struct i915_wa_list *wal)
 
 void intel_gt_apply_workarounds(struct intel_gt *gt)
 {
-       wa_list_apply(gt, &gt->i915->gt_wa_list);
+       wa_list_apply(gt, &gt->wa_list);
 }
 
 static bool wa_list_verify(struct intel_gt *gt,
@@ -1385,7 +1392,7 @@ static bool wa_list_verify(struct intel_gt *gt,
 
 bool intel_gt_verify_workarounds(struct intel_gt *gt, const char *from)
 {
-       return wa_list_verify(gt, &gt->i915->gt_wa_list, from);
+       return wa_list_verify(gt, &gt->wa_list, from);
 }
 
 __maybe_unused
index 15abb68b6c00b0ea71a59363618453e3c00c3e2f..9beaab77c7f0b8ecb736e4eda780fcfe97df018e 100644 (file)
@@ -24,7 +24,7 @@ static inline void intel_wa_list_free(struct i915_wa_list *wal)
 void intel_engine_init_ctx_wa(struct intel_engine_cs *engine);
 int intel_engine_emit_ctx_wa(struct i915_request *rq);
 
-void intel_gt_init_workarounds(struct drm_i915_private *i915);
+void intel_gt_init_workarounds(struct intel_gt *gt);
 void intel_gt_apply_workarounds(struct intel_gt *gt);
 bool intel_gt_verify_workarounds(struct intel_gt *gt, const char *from);
 
index e623ac45f4aa65e645a980151b20a31646d1f387..962e91ba3be4969a76e4e9191b291c6a45c48dc5 100644 (file)
@@ -66,7 +66,7 @@ reference_lists_init(struct intel_gt *gt, struct wa_lists *lists)
        memset(lists, 0, sizeof(*lists));
 
        wa_init_start(&lists->gt_wa_list, "GT_REF", "global");
-       gt_init_workarounds(gt->i915, &lists->gt_wa_list);
+       gt_init_workarounds(gt, &lists->gt_wa_list);
        wa_init_finish(&lists->gt_wa_list);
 
        for_each_engine(engine, gt, id) {
index 59fb4c710c8ca16c873ee5d4fb95de8a5701f37a..3cf61bead2f6196f5c1874093b88218ec894a86b 100644 (file)
@@ -588,8 +588,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
 
        pci_set_master(pdev);
 
-       intel_gt_init_workarounds(dev_priv);
-
        /* On the 945G/GM, the chipset reports the MSI capability on the
         * integrated graphics even though the support isn't actually there
         * according to the published specs.  It doesn't appear to function
index 74fd7038527393dd319c9e30f7004d97f9195164..93d13aba6a850d31080b8b0edc535809c5f29a3a 100644 (file)
@@ -1022,8 +1022,6 @@ struct drm_i915_private {
         */
        u8 active_pipes;
 
-       struct i915_wa_list gt_wa_list;
-
        struct i915_frontbuffer_tracking fb_tracking;
 
        struct intel_atomic_helper {
index 590efc8b0265b66a51ea6ac41db134de70249c1d..981e383d1a5db7fd406d9243409b80f4aefff177 100644 (file)
@@ -1139,8 +1139,6 @@ void i915_gem_driver_release(struct drm_i915_private *dev_priv)
 {
        intel_gt_driver_release(&dev_priv->gt);
 
-       intel_wa_list_free(&dev_priv->gt_wa_list);
-
        intel_uc_cleanup_firmwares(&dev_priv->gt.uc);
 
        i915_gem_drain_freed_objects(dev_priv);