[Intel-gfx] [PATCH 3/6] drm/i915: Fix and improve MCR selection logic
Summers, Stuart
stuart.summers at intel.com
Wed Jul 17 21:24:14 UTC 2019
On Wed, 2019-07-17 at 19:06 +0100, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>
> A couple issues were present in this code:
>
> 1.
> fls() usage was incorrect causing off by one in subslice mask lookup,
> which in other words means subslice mask of all zeroes is always used
> (subslice mask of a slice which is not present, or even out of bounds
> array access), rendering the checks in wa_init_mcr either futile or
> random.
>
> 2.
> Condition in WARN_ON was not correct. It is doing a bitwise and
> operation
> between a positive (present subslices) and negative mask (disabled L3
> banks).
>
> This means that with corrected fls() usage the assert would always
> incorrectly fail.
>
> We could fix this by inverting the fuse bits in the check, but
> instead do
> one better and improve the code so it not only asserts, but finds the
> first common index between the two masks and only warns if no such
> index
> can be found.
>
> v2:
> * Simplify check for logic and redability.
> * Improve commentary explaining what is really happening ie. what
> the
> assert is really trying to check and why.
>
> v3:
> * Find first common index instead of just asserting.
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> Fixes: fe864b76c2ab ("drm/i915: Implement
> WaProgramMgsrForL3BankSpecificMmioReads")
> Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk> # v1
> Cc: MichaĆ Winiarski <michal.winiarski at intel.com>
> Cc: Stuart Summers <stuart.summers at intel.com>
Reviewed-by: Stuart Summers <stuart.summers at intel.com>
> ---
> drivers/gpu/drm/i915/gt/intel_engine_cs.c | 24 ------
> drivers/gpu/drm/i915/gt/intel_workarounds.c | 90 +++++++++++------
> ----
> drivers/gpu/drm/i915/i915_drv.h | 2 -
> 3 files changed, 49 insertions(+), 67 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> index cc4d1826173d..65cbf1d9118d 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> @@ -959,30 +959,6 @@ const char *i915_cache_level_str(struct
> drm_i915_private *i915, int type)
> }
> }
>
> -u32 intel_calculate_mcr_s_ss_select(struct drm_i915_private
> *dev_priv)
> -{
> - const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)-
> >sseu;
> - unsigned int slice = fls(sseu->slice_mask) - 1;
> - unsigned int subslice;
> - u32 mcr_s_ss_select;
> -
> - GEM_BUG_ON(slice >= ARRAY_SIZE(sseu->subslice_mask));
> - subslice = fls(sseu->subslice_mask[slice]);
> - GEM_BUG_ON(!subslice);
> - subslice--;
> -
> - if (IS_GEN(dev_priv, 10))
> - mcr_s_ss_select = GEN8_MCR_SLICE(slice) |
> - GEN8_MCR_SUBSLICE(subslice);
> - else if (INTEL_GEN(dev_priv) >= 11)
> - mcr_s_ss_select = GEN11_MCR_SLICE(slice) |
> - GEN11_MCR_SUBSLICE(subslice);
> - else
> - mcr_s_ss_select = 0;
> -
> - return mcr_s_ss_select;
> -}
> -
> static u32
> read_subslice_reg(struct intel_engine_cs *engine, int slice, int
> subslice,
> i915_reg_t reg)
> diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c
> b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> index 3b1fc7c8faa8..c2325b7ecf8d 100644
> --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
> +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> @@ -762,7 +762,10 @@ static void
> wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal)
> {
> const struct sseu_dev_info *sseu = &RUNTIME_INFO(i915)->sseu;
> - u32 mcr_slice_subslice_mask;
> + unsigned int slice, subslice;
> + u32 l3_en, mcr, mcr_mask;
> +
> + GEM_BUG_ON(INTEL_GEN(i915) < 10);
>
> /*
> * WaProgramMgsrForL3BankSpecificMmioReads: cnl,icl
> @@ -770,42 +773,7 @@ wa_init_mcr(struct drm_i915_private *i915,
> struct i915_wa_list *wal)
> * 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(i915) >= 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 =
> - intel_uncore_read(&i915->uncore,
> 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);
> - }
> -
> - if (INTEL_GEN(i915) >= 11)
> - mcr_slice_subslice_mask = GEN11_MCR_SLICE_MASK |
> - GEN11_MCR_SUBSLICE_MASK;
> - else
> - mcr_slice_subslice_mask = GEN8_MCR_SLICE_MASK |
> - GEN8_MCR_SUBSLICE_MASK;
> - /*
> + *
> * WaProgramMgsrForCorrectSliceSpecificMmioReads:cnl,icl
> * Before any MMIO read into slice/subslice specific registers,
> MCR
> * packet control register needs to be programmed to point to
> any
> @@ -815,11 +783,51 @@ wa_init_mcr(struct drm_i915_private *i915,
> struct i915_wa_list *wal)
> * are consistent across s/ss in almost all cases. In the rare
> * occasions, such as INSTDONE, where this value is dependent
> * on s/ss combo, the read should be done with
> read_subslice_reg.
> + *
> + * Since GEN8_MCR_SELECTOR contains dual-purpose bits which
> select both
> + * to which subslice, or to which L3 bank, the respective mmio
> reads
> + * will go, we have to find a common index which works for both
> + * accesses.
> + *
> + * Case where we cannot find a common index fortunately should
> not
> + * happen in production hardware, so we only emit a warning
> instead of
> + * implementing something more complex that requires checking
> the range
> + * of every MMIO read.
> */
> - wa_write_masked_or(wal,
> - GEN8_MCR_SELECTOR,
> - mcr_slice_subslice_mask,
> - intel_calculate_mcr_s_ss_select(i915));
> +
> + if (INTEL_GEN(i915) >= 10 && is_power_of_2(sseu->slice_mask)) {
> + u32 l3_fuse =
> + intel_uncore_read(&i915->uncore,
> GEN10_MIRROR_FUSE3) &
> + GEN10_L3BANK_MASK;
> +
> + DRM_DEBUG_DRIVER("L3 fuse = %x\n", l3_fuse);
> + l3_en = ~(l3_fuse << GEN10_L3BANK_PAIR_COUNT |
> l3_fuse);
> + } else {
> + l3_en = ~0;
> + }
> +
> + slice = fls(sseu->slice_mask) - 1;
> + GEM_BUG_ON(slice >= ARRAY_SIZE(sseu->subslice_mask));
> + subslice = fls(l3_en & sseu->subslice_mask[slice]);
> + if (!subslice) {
> + DRM_WARN("No common index found between subslice mask
> %x and L3 bank mask %x!\n",
> + sseu->subslice_mask[slice], l3_en);
> + subslice = fls(l3_en);
> + WARN_ON(!subslice);
> + }
> + subslice--;
> +
> + if (INTEL_GEN(i915) >= 11) {
> + mcr = GEN11_MCR_SLICE(slice) |
> GEN11_MCR_SUBSLICE(subslice);
> + mcr_mask = GEN11_MCR_SLICE_MASK |
> GEN11_MCR_SUBSLICE_MASK;
> + } else {
> + mcr = GEN8_MCR_SLICE(slice) |
> GEN8_MCR_SUBSLICE(subslice);
> + mcr_mask = GEN8_MCR_SLICE_MASK |
> GEN8_MCR_SUBSLICE_MASK;
> + }
> +
> + DRM_DEBUG_DRIVER("MCR slice/subslice = %x\n", mcr);
> +
> + wa_write_masked_or(wal, GEN8_MCR_SELECTOR, mcr_mask, mcr);
> }
>
> static void
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 78c1ed6e17b2..0e44cc4b2ca1 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2389,8 +2389,6 @@ void i915_driver_remove(struct drm_device
> *dev);
> void intel_engine_init_hangcheck(struct intel_engine_cs *engine);
> int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on);
>
> -u32 intel_calculate_mcr_s_ss_select(struct drm_i915_private
> *dev_priv);
> -
> static inline bool intel_gvt_active(struct drm_i915_private
> *dev_priv)
> {
> return dev_priv->gvt;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3270 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/intel-gfx/attachments/20190717/56eb31d7/attachment.bin>
More information about the Intel-gfx
mailing list