diff mbox

[04/11] drm/i915: Move workarounds from init_clock_gating

Message ID 1507745721-4094-5-git-send-email-oscar.mateo@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

oscar.mateo@intel.com Oct. 11, 2017, 6:15 p.m. UTC
I'm not sure why some WAs have historically been applied in init_clock_gating
and some others in the engine setup (GT vs. display? context vs. global
registers?) but it does not look like the best place to apply workarounds:
the name is confusing, it's a display function (even though some GT WAs
also go here) and it isn't necessarily called on a GPU reset. This patch
moves these WAs to their rightful place inside i915_workarounds.c.

TODO: Do we want to keep display WAs separated from GT ones? In that case,
I would propose another category inside i915_workarounds.c (but I would need
help deciding what goes where).

v2:
  - Also move bdw and chv WAs from init_clock_gating that do not seem to be
    actually related to clock gating.
  - Rebased.

Signed-off-by: Oscar Mateo <oscar.mateo@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c          | 243 +------------------------------
 drivers/gpu/drm/i915/intel_workarounds.c | 195 ++++++++++++++++++++++++-
 2 files changed, 202 insertions(+), 236 deletions(-)

Comments

Chris Wilson Oct. 11, 2017, 6:26 p.m. UTC | #1
Quoting Oscar Mateo (2017-10-11 19:15:14)
> I'm not sure why some WAs have historically been applied in init_clock_gating
> and some others in the engine setup (GT vs. display? context vs. global
> registers?) but it does not look like the best place to apply workarounds:
> the name is confusing, it's a display function (even though some GT WAs
> also go here) and it isn't necessarily called on a GPU reset. This patch
> moves these WAs to their rightful place inside i915_workarounds.c.

How dare you answer my question before I ask it!

s/i915_workarounds/intel_workarounds/
-Chris
Chris Wilson Oct. 11, 2017, 6:29 p.m. UTC | #2
Quoting Oscar Mateo (2017-10-11 19:15:14)
> I'm not sure why some WAs have historically been applied in init_clock_gating
> and some others in the engine setup (GT vs. display? context vs. global
> registers?) but it does not look like the best place to apply workarounds:
> the name is confusing, it's a display function (even though some GT WAs
> also go here) and it isn't necessarily called on a GPU reset. This patch
> moves these WAs to their rightful place inside i915_workarounds.c.
> 
> TODO: Do we want to keep display WAs separated from GT ones? In that case,
> I would propose another category inside i915_workarounds.c (but I would need
> help deciding what goes where).
> 
> v2:
>   - Also move bdw and chv WAs from init_clock_gating that do not seem to be
>     actually related to clock gating.
>   - Rebased.

Too much in one patch. Start with copy'n'paste, and then we can see
which w/a you select to move from init_clock_gating.
-Chris
Ville Syrjälä Oct. 11, 2017, 6:35 p.m. UTC | #3
On Wed, Oct 11, 2017 at 11:15:14AM -0700, Oscar Mateo wrote:
> I'm not sure why some WAs have historically been applied in init_clock_gating
> and some others in the engine setup (GT vs. display? context vs. global
> registers?) but it does not look like the best place to apply workarounds:
> the name is confusing, it's a display function (even though some GT WAs
> also go here) and it isn't necessarily called on a GPU reset. This patch
> moves these WAs to their rightful place inside i915_workarounds.c.
> 
> TODO: Do we want to keep display WAs separated from GT ones? In that case,
> I would propose another category inside i915_workarounds.c (but I would need
> help deciding what goes where).

The current situation isn't very good. But neither really is moving
display stuff into something called gem_init_hw(). It also gets called
during GPU reset which is at the very least wasted effort when it comes
to display w/as, and could even be actively harmful in case we end up
clobbering something the current display configuration depends on.

> 
> v2:
>   - Also move bdw and chv WAs from init_clock_gating that do not seem to be
>     actually related to clock gating.
>   - Rebased.
> 
> Signed-off-by: Oscar Mateo <oscar.mateo@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c          | 243 +------------------------------
>  drivers/gpu/drm/i915/intel_workarounds.c | 195 ++++++++++++++++++++++++-
>  2 files changed, 202 insertions(+), 236 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 2fcff97..024ee94 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -56,101 +56,6 @@
>  #define INTEL_RC6p_ENABLE			(1<<1)
>  #define INTEL_RC6pp_ENABLE			(1<<2)
>  
> -static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
> -{
> -	if (HAS_LLC(dev_priv)) {
> -		/*
> -		 * WaCompressedResourceDisplayNewHashMode:skl,kbl
> -		 * Display WA#0390: skl,kbl
> -		 *
> -		 * Must match Sampler, Pixel Back End, and Media. See
> -		 * WaCompressedResourceSamplerPbeMediaNewHashMode.
> -		 */
> -		I915_WRITE(CHICKEN_PAR1_1,
> -			   I915_READ(CHICKEN_PAR1_1) |
> -			   SKL_DE_COMPRESSED_HASH_MODE);
> -	}
> -
> -	/* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
> -	I915_WRITE(CHICKEN_PAR1_1,
> -		   I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
> -
> -	I915_WRITE(GEN8_CONFIG0,
> -		   I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);
> -
> -	/* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */
> -	I915_WRITE(GEN8_CHICKEN_DCPR_1,
> -		   I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
> -
> -	/* WaFbcTurnOffFbcWatermark:skl,bxt,kbl,cfl */
> -	/* WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl */
> -	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
> -		   DISP_FBC_WM_DIS |
> -		   DISP_FBC_MEMORY_WAKE);
> -
> -	/* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */
> -	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
> -		   ILK_DPFC_DISABLE_DUMMY0);
> -
> -	if (IS_SKYLAKE(dev_priv)) {
> -		/* WaDisableDopClockGating */
> -		I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL)
> -			   & ~GEN7_DOP_CLOCK_GATE_ENABLE);
> -	}
> -}
> -
> -static void bxt_init_clock_gating(struct drm_i915_private *dev_priv)
> -{
> -	gen9_init_clock_gating(dev_priv);
> -
> -	/* WaDisableSDEUnitClockGating:bxt */
> -	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
> -		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
> -
> -	/*
> -	 * FIXME:
> -	 * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
> -	 */
> -	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
> -		   GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
> -
> -	/*
> -	 * Wa: Backlight PWM may stop in the asserted state, causing backlight
> -	 * to stay fully on.
> -	 */
> -	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
> -		   PWM1_GATING_DIS | PWM2_GATING_DIS);
> -}
> -
> -static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
> -{
> -	u32 val;
> -	gen9_init_clock_gating(dev_priv);
> -
> -	/*
> -	 * WaDisablePWMClockGating:glk
> -	 * Backlight PWM may stop in the asserted state, causing backlight
> -	 * to stay fully on.
> -	 */
> -	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
> -		   PWM1_GATING_DIS | PWM2_GATING_DIS);
> -
> -	/* WaDDIIOTimeout:glk */
> -	if (IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1)) {
> -		u32 val = I915_READ(CHICKEN_MISC_2);
> -		val &= ~(GLK_CL0_PWR_DOWN |
> -			 GLK_CL1_PWR_DOWN |
> -			 GLK_CL2_PWR_DOWN);
> -		I915_WRITE(CHICKEN_MISC_2, val);
> -	}
> -
> -	/* Display WA #1133: WaFbcSkipSegments:glk */
> -	val = I915_READ(ILK_DPFC_CHICKEN);
> -	val &= ~GLK_SKIP_SEG_COUNT_MASK;
> -	val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
> -	I915_WRITE(ILK_DPFC_CHICKEN, val);
> -}
> -
>  static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv)
>  {
>  	u32 tmp;
> @@ -8505,110 +8410,10 @@ static void cnp_init_clock_gating(struct drm_i915_private *dev_priv)
>  		   CNP_PWM_CGE_GATING_DISABLE);
>  }
>  
> -static void cnl_init_clock_gating(struct drm_i915_private *dev_priv)
> -{
> -	u32 val;
> -	cnp_init_clock_gating(dev_priv);
> -
> -	/* This is not an Wa. Enable for better image quality */
> -	I915_WRITE(_3D_CHICKEN3,
> -		   _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE));
> -
> -	/* WaEnableChickenDCPR:cnl */
> -	I915_WRITE(GEN8_CHICKEN_DCPR_1,
> -		   I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
> -
> -	/* WaFbcWakeMemOn:cnl */
> -	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
> -		   DISP_FBC_MEMORY_WAKE);
> -
> -	/* WaSarbUnitClockGatingDisable:cnl (pre-prod) */
> -	if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))
> -		I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE,
> -			   I915_READ(SLICE_UNIT_LEVEL_CLKGATE) |
> -			   SARBUNIT_CLKGATE_DIS);
> -
> -	/* Display WA #1133: WaFbcSkipSegments:cnl */
> -	val = I915_READ(ILK_DPFC_CHICKEN);
> -	val &= ~GLK_SKIP_SEG_COUNT_MASK;
> -	val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
> -	I915_WRITE(ILK_DPFC_CHICKEN, val);
> -}
> -
> -static void cfl_init_clock_gating(struct drm_i915_private *dev_priv)
> -{
> -	cnp_init_clock_gating(dev_priv);
> -	gen9_init_clock_gating(dev_priv);
> -
> -	/* WaFbcNukeOnHostModify:cfl */
> -	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
> -		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
> -}
> -
> -static void kbl_init_clock_gating(struct drm_i915_private *dev_priv)
> -{
> -	gen9_init_clock_gating(dev_priv);
> -
> -	/* WaDisableSDEUnitClockGating:kbl */
> -	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
> -		I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
> -			   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
> -
> -	/* WaDisableGamClockGating:kbl */
> -	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
> -		I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
> -			   GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
> -
> -	/* WaFbcNukeOnHostModify:kbl */
> -	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
> -		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
> -}
> -
> -static void skl_init_clock_gating(struct drm_i915_private *dev_priv)
> -{
> -	gen9_init_clock_gating(dev_priv);
> -
> -	/* WAC6entrylatency:skl */
> -	I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) |
> -		   FBC_LLC_FULLY_OPEN);
> -
> -	/* WaFbcNukeOnHostModify:skl */
> -	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
> -		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
> -}
> -
>  static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
>  {
> -	/* The GTT cache must be disabled if the system is using 2M pages. */
> -	bool can_use_gtt_cache = !HAS_PAGE_SIZES(dev_priv,
> -						 I915_GTT_PAGE_SIZE_2M);
> -	enum pipe pipe;
> -
>  	ilk_init_lp_watermarks(dev_priv);
>  
> -	/* WaSwitchSolVfFArbitrationPriority:bdw */
> -	I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
> -
> -	/* WaPsrDPAMaskVBlankInSRD:bdw */
> -	I915_WRITE(CHICKEN_PAR1_1,
> -		   I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD);
> -
> -	/* WaPsrDPRSUnmaskVBlankInSRD:bdw */
> -	for_each_pipe(dev_priv, pipe) {
> -		I915_WRITE(CHICKEN_PIPESL_1(pipe),
> -			   I915_READ(CHICKEN_PIPESL_1(pipe)) |
> -			   BDW_DPRS_MASK_VBLANK_SRD);
> -	}
> -
> -	/* WaVSRefCountFullforceMissDisable:bdw */
> -	/* WaDSRefCountFullforceMissDisable:bdw */
> -	I915_WRITE(GEN7_FF_THREAD_MODE,
> -		   I915_READ(GEN7_FF_THREAD_MODE) &
> -		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
> -
> -	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
> -		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
> -
>  	/* WaDisableSDEUnitClockGating:bdw */
>  	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
>  		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
> @@ -8616,19 +8421,12 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
>  	/* WaProgramL3SqcReg1Default:bdw */
>  	gen8_set_l3sqc_credits(dev_priv, 30, 2);
>  
> -	/* WaGttCachingOffByDefault:bdw */
> -	I915_WRITE(HSW_GTT_CACHE_EN, can_use_gtt_cache ? GTT_CACHE_EN_ALL : 0);
> -
> -	/* WaKVMNotificationOnConfigChange:bdw */
> -	I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1)
> -		   | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT);
> -
>  	lpt_init_clock_gating(dev_priv);
>  
>  	/* WaDisableDopClockGating:bdw
>  	 *
> -	 * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP
> -	 * clock gating.
> +	 * Also see the CHICKEN2 write in bdw_ctx_workarounds_init() to disable
> +	 * DOP clock gating.
>  	 */
>  	I915_WRITE(GEN6_UCGCTL1,
>  		   I915_READ(GEN6_UCGCTL1) | GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE);
> @@ -8867,16 +8665,6 @@ static void vlv_init_clock_gating(struct drm_i915_private *dev_priv)
>  
>  static void chv_init_clock_gating(struct drm_i915_private *dev_priv)
>  {
> -	/* WaVSRefCountFullforceMissDisable:chv */
> -	/* WaDSRefCountFullforceMissDisable:chv */
> -	I915_WRITE(GEN7_FF_THREAD_MODE,
> -		   I915_READ(GEN7_FF_THREAD_MODE) &
> -		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
> -
> -	/* WaDisableSemaphoreAndSyncFlipWait:chv */
> -	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
> -		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
> -
>  	/* WaDisableCSUnitClockGating:chv */
>  	I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
>  		   GEN6_CSUNIT_CLOCK_GATE_DISABLE);
> @@ -8891,12 +8679,6 @@ static void chv_init_clock_gating(struct drm_i915_private *dev_priv)
>  	 * LSQC Setting Recommendations.
>  	 */
>  	gen8_set_l3sqc_credits(dev_priv, 38, 2);
> -
> -	/*
> -	 * GTT cache may not work with big pages, so if those
> -	 * are ever enabled GTT cache may need to be disabled.
> -	 */
> -	I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
>  }
>  
>  static void g4x_init_clock_gating(struct drm_i915_private *dev_priv)
> @@ -9018,24 +8800,15 @@ static void nop_init_clock_gating(struct drm_i915_private *dev_priv)
>   * @dev_priv: device private
>   *
>   * Setup the hooks that configure which clocks of a given platform can be
> - * gated and also apply various GT and display specific workarounds for these
> - * platforms. Note that some GT specific workarounds are applied separately
> - * when GPU contexts or batchbuffers start their execution.
> + * gated.
>   */
>  void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
>  {
> -	if (IS_CANNONLAKE(dev_priv))
> -		dev_priv->display.init_clock_gating = cnl_init_clock_gating;
> -	else if (IS_COFFEELAKE(dev_priv))
> -		dev_priv->display.init_clock_gating = cfl_init_clock_gating;
> -	else if (IS_SKYLAKE(dev_priv))
> -		dev_priv->display.init_clock_gating = skl_init_clock_gating;
> -	else if (IS_KABYLAKE(dev_priv))
> -		dev_priv->display.init_clock_gating = kbl_init_clock_gating;
> -	else if (IS_BROXTON(dev_priv))
> -		dev_priv->display.init_clock_gating = bxt_init_clock_gating;
> -	else if (IS_GEMINILAKE(dev_priv))
> -		dev_priv->display.init_clock_gating = glk_init_clock_gating;
> +	if (IS_CANNONLAKE(dev_priv) || IS_COFFEELAKE(dev_priv))
> +		dev_priv->display.init_clock_gating = cnp_init_clock_gating;
> +	else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) ||
> +		 IS_BROXTON(dev_priv) || IS_GEMINILAKE(dev_priv))
> +		dev_priv->display.init_clock_gating = nop_init_clock_gating;
>  	else if (IS_BROADWELL(dev_priv))
>  		dev_priv->display.init_clock_gating = bdw_init_clock_gating;
>  	else if (IS_CHERRYVIEW(dev_priv))
> diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
> index ae66084..bc144c2 100644
> --- a/drivers/gpu/drm/i915/intel_workarounds.c
> +++ b/drivers/gpu/drm/i915/intel_workarounds.c
> @@ -513,6 +513,63 @@ int intel_ctx_workarounds_emit(struct drm_i915_gem_request *req)
>  	return 0;
>  }
>  
> +static void bdw_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
> +{
> +	/* The GTT cache must be disabled if the system is using 2M pages. */
> +	bool can_use_gtt_cache = !HAS_PAGE_SIZES(dev_priv,
> +						 I915_GTT_PAGE_SIZE_2M);
> +	enum pipe pipe;
> +
> +	/* WaSwitchSolVfFArbitrationPriority:bdw */
> +	I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
> +
> +	/* WaPsrDPAMaskVBlankInSRD:bdw */
> +	I915_WRITE(CHICKEN_PAR1_1,
> +		   I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD);
> +
> +	/* WaPsrDPRSUnmaskVBlankInSRD:bdw */
> +	for_each_pipe(dev_priv, pipe) {
> +		I915_WRITE(CHICKEN_PIPESL_1(pipe),
> +			   I915_READ(CHICKEN_PIPESL_1(pipe)) |
> +			   BDW_DPRS_MASK_VBLANK_SRD);
> +	}
> +
> +	/* WaVSRefCountFullforceMissDisable:bdw */
> +	/* WaDSRefCountFullforceMissDisable:bdw */
> +	I915_WRITE(GEN7_FF_THREAD_MODE,
> +		   I915_READ(GEN7_FF_THREAD_MODE) &
> +		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
> +
> +	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
> +		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
> +
> +	/* WaGttCachingOffByDefault:bdw */
> +	I915_WRITE(HSW_GTT_CACHE_EN, can_use_gtt_cache ? GTT_CACHE_EN_ALL : 0);
> +
> +	/* WaKVMNotificationOnConfigChange:bdw */
> +	I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1)
> +		   | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT);
> +}
> +
> +static void chv_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
> +{
> +	/* WaVSRefCountFullforceMissDisable:chv */
> +	/* WaDSRefCountFullforceMissDisable:chv */
> +	I915_WRITE(GEN7_FF_THREAD_MODE,
> +		   I915_READ(GEN7_FF_THREAD_MODE) &
> +		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
> +
> +	/* WaDisableSemaphoreAndSyncFlipWait:chv */
> +	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
> +		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
> +
> +	/*
> +	 * GTT cache may not work with big pages, so if those
> +	 * are ever enabled GTT cache may need to be disabled.
> +	 */
> +	I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
> +}
> +
>  static void gen9_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  {
>  	if (HAS_LLC(dev_priv)) {
> @@ -525,8 +582,40 @@ static void gen9_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  			   I915_READ(MMCD_MISC_CTRL) |
>  			   MMCD_PCLA |
>  			   MMCD_HOTSPOT_EN);
> +
> +		/*
> +		 * WaCompressedResourceDisplayNewHashMode:skl,kbl
> +		 * Display WA#0390: skl,kbl
> +		 *
> +		 * Must match Sampler, Pixel Back End, and Media. See
> +		 * WaCompressedResourceSamplerPbeMediaNewHashMode.
> +		 */
> +		I915_WRITE(CHICKEN_PAR1_1,
> +			   I915_READ(CHICKEN_PAR1_1) |
> +			   SKL_DE_COMPRESSED_HASH_MODE);
>  	}
>  
> +	/* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
> +	I915_WRITE(CHICKEN_PAR1_1,
> +		   I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
> +
> +	I915_WRITE(GEN8_CONFIG0,
> +		   I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);
> +
> +	/* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */
> +	I915_WRITE(GEN8_CHICKEN_DCPR_1,
> +		   I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
> +
> +	/* WaFbcTurnOffFbcWatermark:skl,bxt,kbl,cfl */
> +	/* WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl */
> +	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
> +		   DISP_FBC_WM_DIS |
> +		   DISP_FBC_MEMORY_WAKE);
> +
> +	/* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */
> +	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
> +		   ILK_DPFC_DISABLE_DUMMY0);
> +
>  	/* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
>  	I915_WRITE(GEN9_CSFE_CHICKEN1_RCS,
>  		   _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
> @@ -557,6 +646,18 @@ static void skl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  {
>  	gen9_mmio_workarounds_apply(dev_priv);
>  
> +	/* WaDisableDopClockGating */
> +	I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL)
> +		   & ~GEN7_DOP_CLOCK_GATE_ENABLE);
> +
> +	/* WAC6entrylatency:skl */
> +	I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) |
> +		   FBC_LLC_FULLY_OPEN);
> +
> +	/* WaFbcNukeOnHostModify:skl */
> +	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
> +		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
> +
>  	/* WaEnableGapsTsvCreditFix:skl */
>  	I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
>  				   GEN9_GAPS_TSV_CREDIT_DISABLE));
> @@ -576,6 +677,24 @@ static void bxt_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  {
>  	gen9_mmio_workarounds_apply(dev_priv);
>  
> +	/* WaDisableSDEUnitClockGating:bxt */
> +	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
> +		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
> +
> +	/*
> +	 * FIXME:
> +	 * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
> +	 */
> +	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
> +		   GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
> +
> +	/*
> +	 * Wa: Backlight PWM may stop in the asserted state, causing backlight
> +	 * to stay fully on.
> +	 */
> +	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
> +		   PWM1_GATING_DIS | PWM2_GATING_DIS);
> +
>  	/* WaStoreMultiplePTEenable:bxt */
>  	/* This is a requirement according to Hardware specification */
>  	if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
> @@ -609,6 +728,20 @@ static void kbl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  {
>  	gen9_mmio_workarounds_apply(dev_priv);
>  
> +	/* WaDisableSDEUnitClockGating:kbl */
> +	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
> +		I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
> +			   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
> +
> +	/* WaDisableGamClockGating:kbl */
> +	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
> +		I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
> +			   GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
> +
> +	/* WaFbcNukeOnHostModify:kbl */
> +	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
> +		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
> +
>  	/* WaEnableGapsTsvCreditFix:kbl */
>  	I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
>  				   GEN9_GAPS_TSV_CREDIT_DISABLE));
> @@ -631,13 +764,43 @@ static void kbl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  
>  static void glk_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  {
> +	u32 val;
> +
>  	gen9_mmio_workarounds_apply(dev_priv);
> +
> +	/*
> +	 * WaDisablePWMClockGating:glk
> +	 * Backlight PWM may stop in the asserted state, causing backlight
> +	 * to stay fully on.
> +	 */
> +	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
> +		   PWM1_GATING_DIS | PWM2_GATING_DIS);
> +
> +	/* WaDDIIOTimeout:glk */
> +	if (IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1)) {
> +		u32 val = I915_READ(CHICKEN_MISC_2);
> +		val &= ~(GLK_CL0_PWR_DOWN |
> +			 GLK_CL1_PWR_DOWN |
> +			 GLK_CL2_PWR_DOWN);
> +		I915_WRITE(CHICKEN_MISC_2, val);
> +	}
> +
> +	/* Display WA #1133: WaFbcSkipSegments:glk */
> +	val = I915_READ(ILK_DPFC_CHICKEN);
> +	val &= ~GLK_SKIP_SEG_COUNT_MASK;
> +	val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
> +	I915_WRITE(ILK_DPFC_CHICKEN, val);
>  }
>  
>  static void cfl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  {
>  	gen9_mmio_workarounds_apply(dev_priv);
>  
> +	/* WaFbcNukeOnHostModify:cfl */
> +	I915_WRITE(ILK_DPFC_CHICKEN,
> +		   I915_READ(ILK_DPFC_CHICKEN) |
> +			     ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
> +
>  	/* WaEnableGapsTsvCreditFix:cfl */
>  	I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
>  				   GEN9_GAPS_TSV_CREDIT_DISABLE));
> @@ -654,6 +817,32 @@ static void cfl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  
>  static void cnl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  {
> +	u32 val;
> +
> +	/* This is not an Wa. Enable for better image quality */
> +	I915_WRITE(_3D_CHICKEN3,
> +		   _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE));
> +
> +	/* WaEnableChickenDCPR:cnl */
> +	I915_WRITE(GEN8_CHICKEN_DCPR_1,
> +		   I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
> +
> +	/* WaFbcWakeMemOn:cnl */
> +	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
> +		   DISP_FBC_MEMORY_WAKE);
> +
> +	/* WaSarbUnitClockGatingDisable:cnl (pre-prod) */
> +	if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))
> +		I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE,
> +			   I915_READ(SLICE_UNIT_LEVEL_CLKGATE) |
> +			   SARBUNIT_CLKGATE_DIS);
> +
> +	/* Display WA #1133: WaFbcSkipSegments:cnl */
> +	val = I915_READ(ILK_DPFC_CHICKEN);
> +	val &= ~GLK_SKIP_SEG_COUNT_MASK;
> +	val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
> +	I915_WRITE(ILK_DPFC_CHICKEN, val);
> +
>  	/* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
>  	if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
>  		I915_WRITE(GAMT_CHKN_BIT_REG,
> @@ -672,8 +861,12 @@ static void cnl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  
>  void intel_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
>  {
> -	if (INTEL_GEN(dev_priv) < 9)
> +	if (INTEL_GEN(dev_priv) < 8)
>  		return;
> +	else if (IS_BROADWELL(dev_priv))
> +		bdw_mmio_workarounds_apply(dev_priv);
> +	else if (IS_CHERRYVIEW(dev_priv))
> +		chv_mmio_workarounds_apply(dev_priv);
>  	else if (IS_SKYLAKE(dev_priv))
>  		skl_mmio_workarounds_apply(dev_priv);
>  	else if (IS_BROXTON(dev_priv))
> -- 
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
oscar.mateo@intel.com Oct. 13, 2017, 8:34 p.m. UTC | #4
<SNIP>


On 10/11/2017 11:35 AM, Ville Syrjälä wrote:
> On Wed, Oct 11, 2017 at 11:15:14AM -0700, Oscar Mateo wrote:
>> I'm not sure why some WAs have historically been applied in init_clock_gating
>> and some others in the engine setup (GT vs. display? context vs. global
>> registers?) but it does not look like the best place to apply workarounds:
>> the name is confusing, it's a display function (even though some GT WAs
>> also go here) and it isn't necessarily called on a GPU reset. This patch
>> moves these WAs to their rightful place inside i915_workarounds.c.
>>
>> TODO: Do we want to keep display WAs separated from GT ones? In that case,
>> I would propose another category inside i915_workarounds.c (but I would need
>> help deciding what goes where).
> The current situation isn't very good. But neither really is moving
> display stuff into something called gem_init_hw(). It also gets called
> during GPU reset which is at the very least wasted effort when it comes
> to display w/as, and could even be actively harmful in case we end up
> clobbering something the current display configuration depends on.


Ok, fully agree. I'm sending a new version with separate GT and Display 
workarounds.

Thanks!
Oscar
oscar.mateo@intel.com Oct. 13, 2017, 8:52 p.m. UTC | #5
On 10/11/2017 11:29 AM, Chris Wilson wrote:
> Quoting Oscar Mateo (2017-10-11 19:15:14)
>> I'm not sure why some WAs have historically been applied in init_clock_gating
>> and some others in the engine setup (GT vs. display? context vs. global
>> registers?) but it does not look like the best place to apply workarounds:
>> the name is confusing, it's a display function (even though some GT WAs
>> also go here) and it isn't necessarily called on a GPU reset. This patch
>> moves these WAs to their rightful place inside i915_workarounds.c.
>>
>> TODO: Do we want to keep display WAs separated from GT ones? In that case,
>> I would propose another category inside i915_workarounds.c (but I would need
>> help deciding what goes where).
>>
>> v2:
>>    - Also move bdw and chv WAs from init_clock_gating that do not seem to be
>>      actually related to clock gating.
>>    - Rebased.
> Too much in one patch. Start with copy'n'paste, and then we can see
> which w/a you select to move from init_clock_gating.
> -Chris

Even better: I'll make the movement from init_clock_gating in small 
chunks, one per GEN/platform.
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 2fcff97..024ee94 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -56,101 +56,6 @@ 
 #define INTEL_RC6p_ENABLE			(1<<1)
 #define INTEL_RC6pp_ENABLE			(1<<2)
 
-static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-	if (HAS_LLC(dev_priv)) {
-		/*
-		 * WaCompressedResourceDisplayNewHashMode:skl,kbl
-		 * Display WA#0390: skl,kbl
-		 *
-		 * Must match Sampler, Pixel Back End, and Media. See
-		 * WaCompressedResourceSamplerPbeMediaNewHashMode.
-		 */
-		I915_WRITE(CHICKEN_PAR1_1,
-			   I915_READ(CHICKEN_PAR1_1) |
-			   SKL_DE_COMPRESSED_HASH_MODE);
-	}
-
-	/* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
-	I915_WRITE(CHICKEN_PAR1_1,
-		   I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
-
-	I915_WRITE(GEN8_CONFIG0,
-		   I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);
-
-	/* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */
-	I915_WRITE(GEN8_CHICKEN_DCPR_1,
-		   I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
-
-	/* WaFbcTurnOffFbcWatermark:skl,bxt,kbl,cfl */
-	/* WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl */
-	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
-		   DISP_FBC_WM_DIS |
-		   DISP_FBC_MEMORY_WAKE);
-
-	/* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */
-	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
-		   ILK_DPFC_DISABLE_DUMMY0);
-
-	if (IS_SKYLAKE(dev_priv)) {
-		/* WaDisableDopClockGating */
-		I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL)
-			   & ~GEN7_DOP_CLOCK_GATE_ENABLE);
-	}
-}
-
-static void bxt_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-	gen9_init_clock_gating(dev_priv);
-
-	/* WaDisableSDEUnitClockGating:bxt */
-	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
-		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
-
-	/*
-	 * FIXME:
-	 * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
-	 */
-	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
-		   GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
-
-	/*
-	 * Wa: Backlight PWM may stop in the asserted state, causing backlight
-	 * to stay fully on.
-	 */
-	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
-		   PWM1_GATING_DIS | PWM2_GATING_DIS);
-}
-
-static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-	u32 val;
-	gen9_init_clock_gating(dev_priv);
-
-	/*
-	 * WaDisablePWMClockGating:glk
-	 * Backlight PWM may stop in the asserted state, causing backlight
-	 * to stay fully on.
-	 */
-	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
-		   PWM1_GATING_DIS | PWM2_GATING_DIS);
-
-	/* WaDDIIOTimeout:glk */
-	if (IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1)) {
-		u32 val = I915_READ(CHICKEN_MISC_2);
-		val &= ~(GLK_CL0_PWR_DOWN |
-			 GLK_CL1_PWR_DOWN |
-			 GLK_CL2_PWR_DOWN);
-		I915_WRITE(CHICKEN_MISC_2, val);
-	}
-
-	/* Display WA #1133: WaFbcSkipSegments:glk */
-	val = I915_READ(ILK_DPFC_CHICKEN);
-	val &= ~GLK_SKIP_SEG_COUNT_MASK;
-	val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
-	I915_WRITE(ILK_DPFC_CHICKEN, val);
-}
-
 static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv)
 {
 	u32 tmp;
@@ -8505,110 +8410,10 @@  static void cnp_init_clock_gating(struct drm_i915_private *dev_priv)
 		   CNP_PWM_CGE_GATING_DISABLE);
 }
 
-static void cnl_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-	u32 val;
-	cnp_init_clock_gating(dev_priv);
-
-	/* This is not an Wa. Enable for better image quality */
-	I915_WRITE(_3D_CHICKEN3,
-		   _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE));
-
-	/* WaEnableChickenDCPR:cnl */
-	I915_WRITE(GEN8_CHICKEN_DCPR_1,
-		   I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
-
-	/* WaFbcWakeMemOn:cnl */
-	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
-		   DISP_FBC_MEMORY_WAKE);
-
-	/* WaSarbUnitClockGatingDisable:cnl (pre-prod) */
-	if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))
-		I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE,
-			   I915_READ(SLICE_UNIT_LEVEL_CLKGATE) |
-			   SARBUNIT_CLKGATE_DIS);
-
-	/* Display WA #1133: WaFbcSkipSegments:cnl */
-	val = I915_READ(ILK_DPFC_CHICKEN);
-	val &= ~GLK_SKIP_SEG_COUNT_MASK;
-	val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
-	I915_WRITE(ILK_DPFC_CHICKEN, val);
-}
-
-static void cfl_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-	cnp_init_clock_gating(dev_priv);
-	gen9_init_clock_gating(dev_priv);
-
-	/* WaFbcNukeOnHostModify:cfl */
-	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
-		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
-}
-
-static void kbl_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-	gen9_init_clock_gating(dev_priv);
-
-	/* WaDisableSDEUnitClockGating:kbl */
-	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
-		I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
-			   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
-
-	/* WaDisableGamClockGating:kbl */
-	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
-		I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
-			   GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
-
-	/* WaFbcNukeOnHostModify:kbl */
-	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
-		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
-}
-
-static void skl_init_clock_gating(struct drm_i915_private *dev_priv)
-{
-	gen9_init_clock_gating(dev_priv);
-
-	/* WAC6entrylatency:skl */
-	I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) |
-		   FBC_LLC_FULLY_OPEN);
-
-	/* WaFbcNukeOnHostModify:skl */
-	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
-		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
-}
-
 static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
 {
-	/* The GTT cache must be disabled if the system is using 2M pages. */
-	bool can_use_gtt_cache = !HAS_PAGE_SIZES(dev_priv,
-						 I915_GTT_PAGE_SIZE_2M);
-	enum pipe pipe;
-
 	ilk_init_lp_watermarks(dev_priv);
 
-	/* WaSwitchSolVfFArbitrationPriority:bdw */
-	I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
-
-	/* WaPsrDPAMaskVBlankInSRD:bdw */
-	I915_WRITE(CHICKEN_PAR1_1,
-		   I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD);
-
-	/* WaPsrDPRSUnmaskVBlankInSRD:bdw */
-	for_each_pipe(dev_priv, pipe) {
-		I915_WRITE(CHICKEN_PIPESL_1(pipe),
-			   I915_READ(CHICKEN_PIPESL_1(pipe)) |
-			   BDW_DPRS_MASK_VBLANK_SRD);
-	}
-
-	/* WaVSRefCountFullforceMissDisable:bdw */
-	/* WaDSRefCountFullforceMissDisable:bdw */
-	I915_WRITE(GEN7_FF_THREAD_MODE,
-		   I915_READ(GEN7_FF_THREAD_MODE) &
-		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
-
-	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
-		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
-
 	/* WaDisableSDEUnitClockGating:bdw */
 	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
 		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
@@ -8616,19 +8421,12 @@  static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
 	/* WaProgramL3SqcReg1Default:bdw */
 	gen8_set_l3sqc_credits(dev_priv, 30, 2);
 
-	/* WaGttCachingOffByDefault:bdw */
-	I915_WRITE(HSW_GTT_CACHE_EN, can_use_gtt_cache ? GTT_CACHE_EN_ALL : 0);
-
-	/* WaKVMNotificationOnConfigChange:bdw */
-	I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1)
-		   | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT);
-
 	lpt_init_clock_gating(dev_priv);
 
 	/* WaDisableDopClockGating:bdw
 	 *
-	 * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP
-	 * clock gating.
+	 * Also see the CHICKEN2 write in bdw_ctx_workarounds_init() to disable
+	 * DOP clock gating.
 	 */
 	I915_WRITE(GEN6_UCGCTL1,
 		   I915_READ(GEN6_UCGCTL1) | GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE);
@@ -8867,16 +8665,6 @@  static void vlv_init_clock_gating(struct drm_i915_private *dev_priv)
 
 static void chv_init_clock_gating(struct drm_i915_private *dev_priv)
 {
-	/* WaVSRefCountFullforceMissDisable:chv */
-	/* WaDSRefCountFullforceMissDisable:chv */
-	I915_WRITE(GEN7_FF_THREAD_MODE,
-		   I915_READ(GEN7_FF_THREAD_MODE) &
-		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
-
-	/* WaDisableSemaphoreAndSyncFlipWait:chv */
-	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
-		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
-
 	/* WaDisableCSUnitClockGating:chv */
 	I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
 		   GEN6_CSUNIT_CLOCK_GATE_DISABLE);
@@ -8891,12 +8679,6 @@  static void chv_init_clock_gating(struct drm_i915_private *dev_priv)
 	 * LSQC Setting Recommendations.
 	 */
 	gen8_set_l3sqc_credits(dev_priv, 38, 2);
-
-	/*
-	 * GTT cache may not work with big pages, so if those
-	 * are ever enabled GTT cache may need to be disabled.
-	 */
-	I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
 }
 
 static void g4x_init_clock_gating(struct drm_i915_private *dev_priv)
@@ -9018,24 +8800,15 @@  static void nop_init_clock_gating(struct drm_i915_private *dev_priv)
  * @dev_priv: device private
  *
  * Setup the hooks that configure which clocks of a given platform can be
- * gated and also apply various GT and display specific workarounds for these
- * platforms. Note that some GT specific workarounds are applied separately
- * when GPU contexts or batchbuffers start their execution.
+ * gated.
  */
 void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
 {
-	if (IS_CANNONLAKE(dev_priv))
-		dev_priv->display.init_clock_gating = cnl_init_clock_gating;
-	else if (IS_COFFEELAKE(dev_priv))
-		dev_priv->display.init_clock_gating = cfl_init_clock_gating;
-	else if (IS_SKYLAKE(dev_priv))
-		dev_priv->display.init_clock_gating = skl_init_clock_gating;
-	else if (IS_KABYLAKE(dev_priv))
-		dev_priv->display.init_clock_gating = kbl_init_clock_gating;
-	else if (IS_BROXTON(dev_priv))
-		dev_priv->display.init_clock_gating = bxt_init_clock_gating;
-	else if (IS_GEMINILAKE(dev_priv))
-		dev_priv->display.init_clock_gating = glk_init_clock_gating;
+	if (IS_CANNONLAKE(dev_priv) || IS_COFFEELAKE(dev_priv))
+		dev_priv->display.init_clock_gating = cnp_init_clock_gating;
+	else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) ||
+		 IS_BROXTON(dev_priv) || IS_GEMINILAKE(dev_priv))
+		dev_priv->display.init_clock_gating = nop_init_clock_gating;
 	else if (IS_BROADWELL(dev_priv))
 		dev_priv->display.init_clock_gating = bdw_init_clock_gating;
 	else if (IS_CHERRYVIEW(dev_priv))
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
index ae66084..bc144c2 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -513,6 +513,63 @@  int intel_ctx_workarounds_emit(struct drm_i915_gem_request *req)
 	return 0;
 }
 
+static void bdw_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+	/* The GTT cache must be disabled if the system is using 2M pages. */
+	bool can_use_gtt_cache = !HAS_PAGE_SIZES(dev_priv,
+						 I915_GTT_PAGE_SIZE_2M);
+	enum pipe pipe;
+
+	/* WaSwitchSolVfFArbitrationPriority:bdw */
+	I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
+
+	/* WaPsrDPAMaskVBlankInSRD:bdw */
+	I915_WRITE(CHICKEN_PAR1_1,
+		   I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD);
+
+	/* WaPsrDPRSUnmaskVBlankInSRD:bdw */
+	for_each_pipe(dev_priv, pipe) {
+		I915_WRITE(CHICKEN_PIPESL_1(pipe),
+			   I915_READ(CHICKEN_PIPESL_1(pipe)) |
+			   BDW_DPRS_MASK_VBLANK_SRD);
+	}
+
+	/* WaVSRefCountFullforceMissDisable:bdw */
+	/* WaDSRefCountFullforceMissDisable:bdw */
+	I915_WRITE(GEN7_FF_THREAD_MODE,
+		   I915_READ(GEN7_FF_THREAD_MODE) &
+		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
+
+	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
+		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
+
+	/* WaGttCachingOffByDefault:bdw */
+	I915_WRITE(HSW_GTT_CACHE_EN, can_use_gtt_cache ? GTT_CACHE_EN_ALL : 0);
+
+	/* WaKVMNotificationOnConfigChange:bdw */
+	I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1)
+		   | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT);
+}
+
+static void chv_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
+{
+	/* WaVSRefCountFullforceMissDisable:chv */
+	/* WaDSRefCountFullforceMissDisable:chv */
+	I915_WRITE(GEN7_FF_THREAD_MODE,
+		   I915_READ(GEN7_FF_THREAD_MODE) &
+		   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
+
+	/* WaDisableSemaphoreAndSyncFlipWait:chv */
+	I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
+		   _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
+
+	/*
+	 * GTT cache may not work with big pages, so if those
+	 * are ever enabled GTT cache may need to be disabled.
+	 */
+	I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
+}
+
 static void gen9_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	if (HAS_LLC(dev_priv)) {
@@ -525,8 +582,40 @@  static void gen9_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 			   I915_READ(MMCD_MISC_CTRL) |
 			   MMCD_PCLA |
 			   MMCD_HOTSPOT_EN);
+
+		/*
+		 * WaCompressedResourceDisplayNewHashMode:skl,kbl
+		 * Display WA#0390: skl,kbl
+		 *
+		 * Must match Sampler, Pixel Back End, and Media. See
+		 * WaCompressedResourceSamplerPbeMediaNewHashMode.
+		 */
+		I915_WRITE(CHICKEN_PAR1_1,
+			   I915_READ(CHICKEN_PAR1_1) |
+			   SKL_DE_COMPRESSED_HASH_MODE);
 	}
 
+	/* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
+	I915_WRITE(CHICKEN_PAR1_1,
+		   I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
+
+	I915_WRITE(GEN8_CONFIG0,
+		   I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);
+
+	/* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */
+	I915_WRITE(GEN8_CHICKEN_DCPR_1,
+		   I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
+
+	/* WaFbcTurnOffFbcWatermark:skl,bxt,kbl,cfl */
+	/* WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl */
+	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
+		   DISP_FBC_WM_DIS |
+		   DISP_FBC_MEMORY_WAKE);
+
+	/* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */
+	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+		   ILK_DPFC_DISABLE_DUMMY0);
+
 	/* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
 	I915_WRITE(GEN9_CSFE_CHICKEN1_RCS,
 		   _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
@@ -557,6 +646,18 @@  static void skl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	gen9_mmio_workarounds_apply(dev_priv);
 
+	/* WaDisableDopClockGating */
+	I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL)
+		   & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+
+	/* WAC6entrylatency:skl */
+	I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) |
+		   FBC_LLC_FULLY_OPEN);
+
+	/* WaFbcNukeOnHostModify:skl */
+	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
+
 	/* WaEnableGapsTsvCreditFix:skl */
 	I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
 				   GEN9_GAPS_TSV_CREDIT_DISABLE));
@@ -576,6 +677,24 @@  static void bxt_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	gen9_mmio_workarounds_apply(dev_priv);
 
+	/* WaDisableSDEUnitClockGating:bxt */
+	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+	/*
+	 * FIXME:
+	 * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
+	 */
+	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+		   GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
+
+	/*
+	 * Wa: Backlight PWM may stop in the asserted state, causing backlight
+	 * to stay fully on.
+	 */
+	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
+		   PWM1_GATING_DIS | PWM2_GATING_DIS);
+
 	/* WaStoreMultiplePTEenable:bxt */
 	/* This is a requirement according to Hardware specification */
 	if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
@@ -609,6 +728,20 @@  static void kbl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	gen9_mmio_workarounds_apply(dev_priv);
 
+	/* WaDisableSDEUnitClockGating:kbl */
+	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
+		I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+			   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaDisableGamClockGating:kbl */
+	if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
+		I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
+			   GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
+
+	/* WaFbcNukeOnHostModify:kbl */
+	I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+		   ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
+
 	/* WaEnableGapsTsvCreditFix:kbl */
 	I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
 				   GEN9_GAPS_TSV_CREDIT_DISABLE));
@@ -631,13 +764,43 @@  static void kbl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 
 static void glk_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 {
+	u32 val;
+
 	gen9_mmio_workarounds_apply(dev_priv);
+
+	/*
+	 * WaDisablePWMClockGating:glk
+	 * Backlight PWM may stop in the asserted state, causing backlight
+	 * to stay fully on.
+	 */
+	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
+		   PWM1_GATING_DIS | PWM2_GATING_DIS);
+
+	/* WaDDIIOTimeout:glk */
+	if (IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1)) {
+		u32 val = I915_READ(CHICKEN_MISC_2);
+		val &= ~(GLK_CL0_PWR_DOWN |
+			 GLK_CL1_PWR_DOWN |
+			 GLK_CL2_PWR_DOWN);
+		I915_WRITE(CHICKEN_MISC_2, val);
+	}
+
+	/* Display WA #1133: WaFbcSkipSegments:glk */
+	val = I915_READ(ILK_DPFC_CHICKEN);
+	val &= ~GLK_SKIP_SEG_COUNT_MASK;
+	val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
+	I915_WRITE(ILK_DPFC_CHICKEN, val);
 }
 
 static void cfl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 {
 	gen9_mmio_workarounds_apply(dev_priv);
 
+	/* WaFbcNukeOnHostModify:cfl */
+	I915_WRITE(ILK_DPFC_CHICKEN,
+		   I915_READ(ILK_DPFC_CHICKEN) |
+			     ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
+
 	/* WaEnableGapsTsvCreditFix:cfl */
 	I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
 				   GEN9_GAPS_TSV_CREDIT_DISABLE));
@@ -654,6 +817,32 @@  static void cfl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 
 static void cnl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 {
+	u32 val;
+
+	/* This is not an Wa. Enable for better image quality */
+	I915_WRITE(_3D_CHICKEN3,
+		   _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE));
+
+	/* WaEnableChickenDCPR:cnl */
+	I915_WRITE(GEN8_CHICKEN_DCPR_1,
+		   I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
+
+	/* WaFbcWakeMemOn:cnl */
+	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
+		   DISP_FBC_MEMORY_WAKE);
+
+	/* WaSarbUnitClockGatingDisable:cnl (pre-prod) */
+	if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))
+		I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE,
+			   I915_READ(SLICE_UNIT_LEVEL_CLKGATE) |
+			   SARBUNIT_CLKGATE_DIS);
+
+	/* Display WA #1133: WaFbcSkipSegments:cnl */
+	val = I915_READ(ILK_DPFC_CHICKEN);
+	val &= ~GLK_SKIP_SEG_COUNT_MASK;
+	val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
+	I915_WRITE(ILK_DPFC_CHICKEN, val);
+
 	/* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
 	if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
 		I915_WRITE(GAMT_CHKN_BIT_REG,
@@ -672,8 +861,12 @@  static void cnl_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 
 void intel_mmio_workarounds_apply(struct drm_i915_private *dev_priv)
 {
-	if (INTEL_GEN(dev_priv) < 9)
+	if (INTEL_GEN(dev_priv) < 8)
 		return;
+	else if (IS_BROADWELL(dev_priv))
+		bdw_mmio_workarounds_apply(dev_priv);
+	else if (IS_CHERRYVIEW(dev_priv))
+		chv_mmio_workarounds_apply(dev_priv);
 	else if (IS_SKYLAKE(dev_priv))
 		skl_mmio_workarounds_apply(dev_priv);
 	else if (IS_BROXTON(dev_priv))