]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
drm/i915: Implement WaProgramMgsrForL3BankSpecificMmioReads
authorYunwei Zhang <yunwei.zhang@intel.com>
Fri, 18 May 2018 22:41:25 +0000 (15:41 -0700)
committerMika Kuoppala <mika.kuoppala@linux.intel.com>
Thu, 24 May 2018 09:52:53 +0000 (12:52 +0300)
L3Bank could be fused off in hardware for debug purpose, and it
is possible that subslice is enabled while its corresponding L3Bank pairs
are disabled. In such case, if MCR packet control register(0xFDC) is
programed to point to a disabled bank pair, a MMIO read into L3Bank range
will return 0 instead of correct values.

However, this is not going to be the case in any production silicon.
Therefore, we only check at initialization and issue a warning should
this really happen.

References: HSDES#1405586840

v2:
 - use fls instead of find_last_bit (Chris)
 - use is_power_of_2() instead of counting bit set (Chris)
v3:
 - rebase on latest tip
v5:
 - Added references (Mika)
 - Move local variable into scope where they are used (Ursulin)
 - use a new local variable to reduce long line of code (Ursulin)
v6:
 - Some coding style and use more local variables for clearer
   logic (Ursulin)

Cc: Oscar Mateo <oscar.mateo@intel.com>
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Signed-off-by: Yunwei Zhang <yunwei.zhang@intel.com>
Reviewed-by: Oscar Mateo <oscar.mateo@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1526683285-24861-1-git-send-email-yunwei.zhang@intel.com
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_workarounds.c

index b888da96caf78bbf8604ef90dda6704ea30b3619..d52a11c2c73cbc23b66f3e202f011328d5b8905b 100644 (file)
@@ -2709,6 +2709,10 @@ enum i915_power_well_id {
 #define   GEN10_F2_SS_DIS_SHIFT                18
 #define   GEN10_F2_SS_DIS_MASK         (0xf << GEN10_F2_SS_DIS_SHIFT)
 
+#define        GEN10_MIRROR_FUSE3              _MMIO(0x9118)
+#define GEN10_L3BANK_PAIR_COUNT     4
+#define GEN10_L3BANK_MASK   0x0F
+
 #define GEN8_EU_DISABLE0               _MMIO(0x9134)
 #define   GEN8_EU_DIS0_S0_MASK         0xffffff
 #define   GEN8_EU_DIS0_S1_SHIFT                24
index 2deec58e97dde1844f48240558d8e831c02279ec..cea57104de13460bad06d58b6425e5f681f89361 100644 (file)
@@ -674,9 +674,44 @@ static void cfl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
 
 static void wa_init_mcr(struct drm_i915_private *dev_priv)
 {
+       const struct sseu_dev_info *sseu = &(INTEL_INFO(dev_priv)->sseu);
        u32 mcr;
        u32 mcr_slice_subslice_mask;
 
+       /*
+        * WaProgramMgsrForL3BankSpecificMmioReads: cnl,icl
+        * L3Banks could be fused off in single slice scenario. If that is
+        * the case, we might need to program MCR select to a valid L3Bank
+        * by default, to make sure we correctly read certain registers
+        * later on (in the range 0xB100 - 0xB3FF).
+        * This might be incompatible with
+        * WaProgramMgsrForCorrectSliceSpecificMmioReads.
+        * Fortunately, this should not happen in production hardware, so
+        * we only assert that this is the case (instead of implementing
+        * something more complex that requires checking the range of every
+        * MMIO read).
+        */
+       if (INTEL_GEN(dev_priv) >= 10 &&
+           is_power_of_2(sseu->slice_mask)) {
+               /*
+                * read FUSE3 for enabled L3 Bank IDs, if L3 Bank matches
+                * enabled subslice, no need to redirect MCR packet
+                */
+               u32 slice = fls(sseu->slice_mask);
+               u32 fuse3 = I915_READ(GEN10_MIRROR_FUSE3);
+               u8 ss_mask = sseu->subslice_mask[slice];
+
+               u8 enabled_mask = (ss_mask | ss_mask >>
+                                  GEN10_L3BANK_PAIR_COUNT) & GEN10_L3BANK_MASK;
+               u8 disabled_mask = fuse3 & GEN10_L3BANK_MASK;
+
+               /*
+                * Production silicon should have matched L3Bank and
+                * subslice enabled
+                */
+               WARN_ON((enabled_mask & disabled_mask) != enabled_mask);
+       }
+
        mcr = I915_READ(GEN8_MCR_SELECTOR);
 
        if (INTEL_GEN(dev_priv) >= 11)