From 4888f1e8c4fce5b82ba06096fcce6c86c3365095 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 18 Apr 2017 13:39:58 +0300 Subject: [PATCH] drm/i915: Work around for underrun when enabling pipe scaler in GLK The first time the pipe scaler is enabled on Geminilake, an underrun happens on the first frame. Disabling DPF clock gating in the respective CLKGATE_DIS_PSL register makes it go away. Signed-off-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/i915_reg.h | 8 ++++++++ drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++++ drivers/gpu/drm/i915/intel_pm.c | 1 - 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 4c72ada..36efe72 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3430,6 +3430,14 @@ 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 CLKGATE_DIS_PSL(pipe) \ + _MMIO_PIPE(pipe, _CLKGATE_DIS_PSL_A, _CLKGATE_DIS_PSL_B) + /* * Display engine regs */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 85b9e2f5..c24acdd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3176,6 +3176,7 @@ static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id) static void skl_detach_scalers(struct intel_crtc *intel_crtc) { struct intel_crtc_scaler_state *scaler_state; + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); int i; scaler_state = &intel_crtc->config->scaler_state; @@ -3185,6 +3186,14 @@ static void skl_detach_scalers(struct intel_crtc *intel_crtc) if (!scaler_state->scalers[i].in_use) skl_detach_scaler(intel_crtc, i); } + + if (IS_GEMINILAKE(dev_priv)) { + u32 tmp; + + tmp = I915_READ(CLKGATE_DIS_PSL(intel_crtc->pipe)); + tmp &= ~DPF_GATING_DIS; + I915_WRITE(CLKGATE_DIS_PSL(intel_crtc->pipe), tmp); + } } u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, @@ -4763,6 +4772,14 @@ static void skylake_pfit_enable(struct intel_crtc *crtc) if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) return; + if (IS_GEMINILAKE(dev_priv)) { + u32 tmp; + + tmp = I915_READ(CLKGATE_DIS_PSL(crtc->pipe)); + tmp |= DPF_GATING_DIS; + I915_WRITE(CLKGATE_DIS_PSL(crtc->pipe), tmp); + } + id = scaler_state->scaler_id; I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN | PS_FILTER_MEDIUM | scaler_state->scalers[id].mode); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index cacb65f..1effc32 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -123,7 +123,6 @@ static void glk_init_clock_gating(struct drm_i915_private *dev_priv) GLK_CL2_PWR_DOWN); I915_WRITE(CHICKEN_MISC_2, val); } - } static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv) -- 2.9.3