[Intel-gfx] [PATCH v2] drm/i915/glk, cnl: Implement WaDisableScalarClockGating

Rodrigo Vivi rodrigo.vivi at intel.com
Mon Oct 2 19:08:07 UTC 2017


On Mon, Oct 02, 2017 at 07:55:57AM +0000, Imre Deak wrote:
> On GLK and CNL enabling a pipe with its pipe scaler enabled will result
> in a FIFO underrun. This happens only once after driver loading or
> system/runtime resume, more specifically after power well 1 gets
> enabled; subsequent modesets seem to be free of underruns. The BSpec
> workaround for this is to disable the pipe scaler clock gating for the
> duration of modeset. Based on my tests disabling clock gating must be
> done before enabling pipe scaling and we can re-enable it after the pipe
> is enabled and one vblank has passed.
> 
> For consistency I also checked if plane scaling would cause the same
> problem, but that doesn't seem to trigger this problem.
> 
> The patch is based on an earlier version from Ander.
> 
> v2 (Rodrigo):
> - Set also CLKGATE_DIS_PSL bits 8 and 9.
> - Add also the BSpec workaround ID.

Thanks for this and for the explanation around the places where
we need to protect.
They make sense.

> 
> Cc: Ander Conselvan de Oliveira <conselvan2 at gmail.com>
> Cc: Rodrigo Vivi <rodrigo.vivi at intel.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100302
> Signed-off-by: Imre Deak <imre.deak at intel.com>

Reviewed-by: Rodrigo Vivi <rodrigo.vivi at intel.com>

> ---
>  drivers/gpu/drm/i915/i915_reg.h      | 10 ++++++++++
>  drivers/gpu/drm/i915/intel_display.c | 26 ++++++++++++++++++++++++++
>  2 files changed, 36 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index ee0d4f14ac98..39ad9327e2a0 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3819,6 +3819,16 @@ enum {
>  #define   PWM2_GATING_DIS		(1 << 14)
>  #define   PWM1_GATING_DIS		(1 << 13)
>  
> +#define _CLKGATE_DIS_PSL_A		0x46520
> +#define _CLKGATE_DIS_PSL_B		0x46524
> +#define _CLKGATE_DIS_PSL_C		0x46528
> +#define   DPF_GATING_DIS		(1 << 10)
> +#define   DPF_RAM_GATING_DIS		(1 << 9)
> +#define   DPFR_GATING_DIS		(1 << 8)
> +
> +#define CLKGATE_DIS_PSL(pipe) \
> +	_MMIO_PIPE(pipe, _CLKGATE_DIS_PSL_A, _CLKGATE_DIS_PSL_B)
> +
>  /*
>   * GEN10 clock gating regs
>   */
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index c4b224a3a0ee..b7a6ddc6a66d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5459,6 +5459,20 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
>  	return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A;
>  }
>  
> +static void glk_pipe_scaler_clock_gating_wa(struct drm_i915_private *dev_priv,
> +					    enum pipe pipe, bool apply)
> +{
> +	u32 val = I915_READ(CLKGATE_DIS_PSL(pipe));
> +	u32 mask = DPF_GATING_DIS | DPF_RAM_GATING_DIS | DPFR_GATING_DIS;
> +
> +	if (apply)
> +		val |= mask;
> +	else
> +		val &= ~mask;
> +
> +	I915_WRITE(CLKGATE_DIS_PSL(pipe), val);
> +}
> +
>  static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  				struct drm_atomic_state *old_state)
>  {
> @@ -5469,6 +5483,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
>  	struct intel_atomic_state *old_intel_state =
>  		to_intel_atomic_state(old_state);
> +	bool psl_clkgate_wa;
>  
>  	if (WARN_ON(intel_crtc->active))
>  		return;
> @@ -5522,6 +5537,12 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  	if (!transcoder_is_dsi(cpu_transcoder))
>  		intel_ddi_enable_pipe_clock(pipe_config);
>  
> +	/* Display WA #1180: WaDisableScalarClockGating: glk, cnl */
> +	psl_clkgate_wa = (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
> +			 intel_crtc->config->pch_pfit.enabled;
> +	if (psl_clkgate_wa)
> +		glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, true);
> +
>  	if (INTEL_GEN(dev_priv) >= 9)
>  		skylake_pfit_enable(intel_crtc);
>  	else
> @@ -5555,6 +5576,11 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  
>  	intel_encoders_enable(crtc, pipe_config, old_state);
>  
> +	if (psl_clkgate_wa) {
> +		intel_wait_for_vblank(dev_priv, pipe);
> +		glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false);
> +	}
> +
>  	if (intel_crtc->config->has_pch_encoder) {
>  		intel_wait_for_vblank(dev_priv, pipe);
>  		intel_wait_for_vblank(dev_priv, pipe);
> -- 
> 2.13.2
> 


More information about the Intel-gfx mailing list