drm/i195: Make the async flip VT-d workaround dynamic
Since the VT-d vs. async flip issues are plaguing a wider range of supported hw let's try to minimize the impact on normal operation by flipping the relevant chicken bits on and off as needed. I presume there is some power/perf impact on since this is reducing some prefetching I think. Cc: Karthik B S <karthik.b.s@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210930190943.17547-2-ville.syrjala@linux.intel.com Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
This commit is contained in:
parent
d08df3b0bd
commit
7d396cacae
2 changed files with 35 additions and 26 deletions
|
@ -2311,6 +2311,33 @@ static bool needs_cursorclk_wa(const struct intel_crtc_state *crtc_state)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void intel_async_flip_vtd_wa(struct drm_i915_private *i915,
|
||||||
|
enum pipe pipe, bool enable)
|
||||||
|
{
|
||||||
|
if (DISPLAY_VER(i915) == 9) {
|
||||||
|
/*
|
||||||
|
* "Plane N strech max must be programmed to 11b (x1)
|
||||||
|
* when Async flips are enabled on that plane."
|
||||||
|
*/
|
||||||
|
intel_de_rmw(i915, CHICKEN_PIPESL_1(pipe),
|
||||||
|
SKL_PLANE1_STRETCH_MAX_MASK,
|
||||||
|
enable ? SKL_PLANE1_STRETCH_MAX_X1 : SKL_PLANE1_STRETCH_MAX_X8);
|
||||||
|
} else {
|
||||||
|
/* Also needed on HSW/BDW albeit undocumented */
|
||||||
|
intel_de_rmw(i915, CHICKEN_PIPESL_1(pipe),
|
||||||
|
HSW_PRI_STRETCH_MAX_MASK,
|
||||||
|
enable ? HSW_PRI_STRETCH_MAX_X1 : HSW_PRI_STRETCH_MAX_X8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool needs_async_flip_vtd_wa(const struct intel_crtc_state *crtc_state)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||||
|
|
||||||
|
return crtc_state->uapi.async_flip && intel_vtd_active() &&
|
||||||
|
(DISPLAY_VER(i915) == 9 || IS_BROADWELL(i915) || IS_HASWELL(i915));
|
||||||
|
}
|
||||||
|
|
||||||
static bool planes_enabling(const struct intel_crtc_state *old_crtc_state,
|
static bool planes_enabling(const struct intel_crtc_state *old_crtc_state,
|
||||||
const struct intel_crtc_state *new_crtc_state)
|
const struct intel_crtc_state *new_crtc_state)
|
||||||
{
|
{
|
||||||
|
@ -2346,6 +2373,10 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
|
||||||
intel_fbc_post_update(state, crtc);
|
intel_fbc_post_update(state, crtc);
|
||||||
intel_drrs_page_flip(state, crtc);
|
intel_drrs_page_flip(state, crtc);
|
||||||
|
|
||||||
|
if (needs_async_flip_vtd_wa(old_crtc_state) &&
|
||||||
|
!needs_async_flip_vtd_wa(new_crtc_state))
|
||||||
|
intel_async_flip_vtd_wa(dev_priv, pipe, false);
|
||||||
|
|
||||||
if (needs_nv12_wa(old_crtc_state) &&
|
if (needs_nv12_wa(old_crtc_state) &&
|
||||||
!needs_nv12_wa(new_crtc_state))
|
!needs_nv12_wa(new_crtc_state))
|
||||||
skl_wa_827(dev_priv, pipe, false);
|
skl_wa_827(dev_priv, pipe, false);
|
||||||
|
@ -2444,6 +2475,10 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
|
||||||
if (intel_fbc_pre_update(state, crtc))
|
if (intel_fbc_pre_update(state, crtc))
|
||||||
intel_wait_for_vblank(dev_priv, pipe);
|
intel_wait_for_vblank(dev_priv, pipe);
|
||||||
|
|
||||||
|
if (!needs_async_flip_vtd_wa(old_crtc_state) &&
|
||||||
|
needs_async_flip_vtd_wa(new_crtc_state))
|
||||||
|
intel_async_flip_vtd_wa(dev_priv, pipe, true);
|
||||||
|
|
||||||
/* Display WA 827 */
|
/* Display WA 827 */
|
||||||
if (!needs_nv12_wa(old_crtc_state) &&
|
if (!needs_nv12_wa(old_crtc_state) &&
|
||||||
needs_nv12_wa(new_crtc_state))
|
needs_nv12_wa(new_crtc_state))
|
||||||
|
|
|
@ -76,8 +76,6 @@ struct intel_wm_config {
|
||||||
|
|
||||||
static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
|
static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
enum pipe pipe;
|
|
||||||
|
|
||||||
if (HAS_LLC(dev_priv)) {
|
if (HAS_LLC(dev_priv)) {
|
||||||
/*
|
/*
|
||||||
* WaCompressedResourceDisplayNewHashMode:skl,kbl
|
* WaCompressedResourceDisplayNewHashMode:skl,kbl
|
||||||
|
@ -91,16 +89,6 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
|
||||||
SKL_DE_COMPRESSED_HASH_MODE);
|
SKL_DE_COMPRESSED_HASH_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each_pipe(dev_priv, pipe) {
|
|
||||||
/*
|
|
||||||
* "Plane N strech max must be programmed to 11b (x1)
|
|
||||||
* when Async flips are enabled on that plane."
|
|
||||||
*/
|
|
||||||
if (!IS_GEMINILAKE(dev_priv) && intel_vtd_active())
|
|
||||||
intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe),
|
|
||||||
SKL_PLANE1_STRETCH_MAX_MASK, SKL_PLANE1_STRETCH_MAX_X1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
|
/* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
|
||||||
intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1,
|
intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1,
|
||||||
intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
|
intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
|
||||||
|
@ -7599,11 +7587,6 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
|
||||||
intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe),
|
intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe),
|
||||||
intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe)) |
|
intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe)) |
|
||||||
BDW_DPRS_MASK_VBLANK_SRD);
|
BDW_DPRS_MASK_VBLANK_SRD);
|
||||||
|
|
||||||
/* Undocumented but fixes async flip + VT-d corruption */
|
|
||||||
if (intel_vtd_active())
|
|
||||||
intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe),
|
|
||||||
HSW_PRI_STRETCH_MAX_MASK, HSW_PRI_STRETCH_MAX_X1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WaVSRefCountFullforceMissDisable:bdw */
|
/* WaVSRefCountFullforceMissDisable:bdw */
|
||||||
|
@ -7639,20 +7622,11 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
|
||||||
|
|
||||||
static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
|
static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
enum pipe pipe;
|
|
||||||
|
|
||||||
/* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */
|
/* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */
|
||||||
intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A),
|
intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A),
|
||||||
intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A)) |
|
intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A)) |
|
||||||
HSW_FBCQ_DIS);
|
HSW_FBCQ_DIS);
|
||||||
|
|
||||||
for_each_pipe(dev_priv, pipe) {
|
|
||||||
/* Undocumented but fixes async flip + VT-d corruption */
|
|
||||||
if (intel_vtd_active())
|
|
||||||
intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe),
|
|
||||||
HSW_PRI_STRETCH_MAX_MASK, HSW_PRI_STRETCH_MAX_X1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is required by WaCatErrorRejectionIssue:hsw */
|
/* This is required by WaCatErrorRejectionIssue:hsw */
|
||||||
intel_uncore_write(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
|
intel_uncore_write(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
|
||||||
intel_uncore_read(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
|
intel_uncore_read(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
|
||||||
|
|
Loading…
Add table
Reference in a new issue