On Tue, 2018-04-03 at 14:24 -0700, Dhinakaran Pandiyan wrote:
> From: Ville Syrjälä
>
> 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
> Cc: Daniel Vetter
Reviewed-by: Jose Roberto de Souza
> Signed-off-by: Ville Syrjälä
> Signed-off-by: Dhinakaran Pandiyan
> ---
> drivers/gpu/drm/i915/i915_irq.c | 57
>
> drivers/gpu/drm/i915/i915_reg.h | 7 +++--
> drivers/gpu/drm/i915/intel_display.h | 4 +++
> 3 files changed, 52 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c
> b/drivers/gpu/drm/i915/i915_irq.c
> index c2d3f30778ee..8a894adf2ca1 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -2394,20 +2394,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)
nitpick: Like I said in the other patch I would like to have this
function renamed here.
> {
> 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);
> }
>
> @@ -2555,11 +2569,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
> @@ -3326,6 +3351,9 @@ static void gen8_irq_reset(struct drm_device
> *dev)
>
> gen8_gt_irq_reset(dev_priv);
>
> + I915_WRITE(EDP_PSR_IMR, 0x);
> + I915_WRITE(EDP_PSR_IIR, 0x);
> +
> for_each_pipe(dev_priv, pipe)
> if (intel_display_power_is_enabled(dev_priv,
> POWER_DOMAIN_PIPE
> (pipe)))
> @@ -3815,7 +3843,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) {
> @@ -3840,6 +3868,9 @@ static void gen8_de_irq_postinstall(struct
> drm_i915_private *dev_priv)
> else if (IS_BROADWELL(dev_priv))