diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2018-04-04 00:24:18 +0300 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2018-04-21 00:28:15 +0300 |
commit | e04f7ece1c4530b4f0db182b5596fadf48628f22 (patch) | |
tree | cded2ab405c72ed7cc747c19d78a9aa59a319049 /drivers/gpu/drm/i915/i915_irq.c | |
parent | fc34044248b611ea3f8b6e55b4ed404192a4f295 (diff) | |
download | linux-e04f7ece1c4530b4f0db182b5596fadf48628f22.tar.xz |
drm/i915: Enable edp psr error interrupts on bdw+
Plug in the bdw+ irq handling for PSR interrupts. bdw+ supports psr on
any transcoder in theory, though the we don't currenty enable PSR except
on the EDP transcoder.
v2: From DK
* Rebased on drm-tip
v3: Switched author to Ville based on IRC discussion.
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Reviewed-by: Jose Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180403212420.25007-2-dhinakaran.pandiyan@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 630fc6f514d8..ab9aac88a00b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2455,20 +2455,34 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv, static void hsw_edp_psr_irq_handler(struct drm_i915_private *dev_priv) { u32 edp_psr_iir = I915_READ(EDP_PSR_IIR); + u32 edp_psr_imr = I915_READ(EDP_PSR_IMR); + u32 mask = BIT(TRANSCODER_EDP); + enum transcoder cpu_transcoder; - if (edp_psr_iir & EDP_PSR_ERROR) - DRM_DEBUG_KMS("PSR error\n"); - - if (edp_psr_iir & EDP_PSR_PRE_ENTRY) { - DRM_DEBUG_KMS("PSR prepare entry in 2 vblanks\n"); - I915_WRITE(EDP_PSR_IMR, EDP_PSR_PRE_ENTRY); - } + if (INTEL_GEN(dev_priv) >= 8) + mask |= BIT(TRANSCODER_A) | + BIT(TRANSCODER_B) | + BIT(TRANSCODER_C); + + for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, mask) { + if (edp_psr_iir & EDP_PSR_ERROR(cpu_transcoder)) + DRM_DEBUG_KMS("Transcoder %s PSR error\n", + transcoder_name(cpu_transcoder)); + + if (edp_psr_iir & EDP_PSR_PRE_ENTRY(cpu_transcoder)) { + DRM_DEBUG_KMS("Transcoder %s PSR prepare entry in 2 vblanks\n", + transcoder_name(cpu_transcoder)); + edp_psr_imr |= EDP_PSR_PRE_ENTRY(cpu_transcoder); + } - if (edp_psr_iir & EDP_PSR_POST_EXIT) { - DRM_DEBUG_KMS("PSR exit completed\n"); - I915_WRITE(EDP_PSR_IMR, 0); + if (edp_psr_iir & EDP_PSR_POST_EXIT(cpu_transcoder)) { + DRM_DEBUG_KMS("Transcoder %s PSR exit completed\n", + transcoder_name(cpu_transcoder)); + edp_psr_imr &= ~EDP_PSR_PRE_ENTRY(cpu_transcoder); + } } + I915_WRITE(EDP_PSR_IMR, edp_psr_imr); I915_WRITE(EDP_PSR_IIR, edp_psr_iir); } @@ -2616,11 +2630,22 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) if (master_ctl & GEN8_DE_MISC_IRQ) { iir = I915_READ(GEN8_DE_MISC_IIR); if (iir) { + bool found = false; + I915_WRITE(GEN8_DE_MISC_IIR, iir); ret = IRQ_HANDLED; - if (iir & GEN8_DE_MISC_GSE) + + if (iir & GEN8_DE_MISC_GSE) { intel_opregion_asle_intr(dev_priv); - else + found = true; + } + + if (iir & GEN8_DE_EDP_PSR) { + hsw_edp_psr_irq_handler(dev_priv); + found = true; + } + + if (!found) DRM_ERROR("Unexpected DE Misc interrupt\n"); } else @@ -3414,6 +3439,9 @@ static void gen8_irq_reset(struct drm_device *dev) gen8_gt_irq_reset(dev_priv); + I915_WRITE(EDP_PSR_IMR, 0xffffffff); + I915_WRITE(EDP_PSR_IIR, 0xffffffff); + for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) @@ -3906,7 +3934,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) uint32_t de_pipe_enables; u32 de_port_masked = GEN8_AUX_CHANNEL_A; u32 de_port_enables; - u32 de_misc_masked = GEN8_DE_MISC_GSE; + u32 de_misc_masked = GEN8_DE_MISC_GSE | GEN8_DE_EDP_PSR; enum pipe pipe; if (INTEL_GEN(dev_priv) >= 9) { @@ -3931,6 +3959,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) else if (IS_BROADWELL(dev_priv)) de_port_enables |= GEN8_PORT_DP_A_HOTPLUG; + gen3_assert_iir_is_zero(dev_priv, EDP_PSR_IIR); + I915_WRITE(EDP_PSR_IMR, 0); + for_each_pipe(dev_priv, pipe) { dev_priv->de_irq_mask[pipe] = ~de_pipe_masked; |