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@xxxxxxxxx> > Cc: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100302 > Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> > --- > 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 > _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx