[Intel-gfx] [PATCH v3 2/4] drm/i915: Enable edp psr error interrupts on bdw+
Souza, Jose
jose.souza at intel.com
Thu Apr 5 20:38:02 UTC 2018
On Tue, 2018-04-03 at 14:24 -0700, Dhinakaran Pandiyan wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
> 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 at intel.com>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
Reviewed-by: Jose Roberto de Souza <jose.souza at intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
> ---
> 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, 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)))
> @@ -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))
> 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;
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index f5783d6db614..6eb351177a68 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4014,9 +4014,9 @@ enum {
> /* Bspec claims those aren't shifted but stay at 0x64800 */
> #define EDP_PSR_IMR _MMIO(0x64834)
> #define EDP_PSR_IIR _MMIO(0x64838)
> -#define EDP_PSR_ERROR (1<<2)
> -#define EDP_PSR_POST_EXIT (1<<1)
> -#define EDP_PSR_PRE_ENTRY (1<<0)
> +#define EDP_PSR_ERROR(trans) (1 <<
> (((trans) * 8 + 10) & 31))
> +#define EDP_PSR_POST_EXIT(trans) (1 << (((trans) *
> 8 + 9) & 31))
> +#define EDP_PSR_PRE_ENTRY(trans) (1 << (((trans) *
> 8 + 8) & 31))
>
Clever macros
> #define EDP_PSR_AUX_CTL _MMIO(dev_pri
> v->psr_mmio_base + 0x10)
> #define EDP_PSR_AUX_CTL_TIME_OUT_MASK (3 << 26)
> @@ -6952,6 +6952,7 @@ enum {
> #define GEN8_DE_MISC_IIR _MMIO(0x44468)
> #define GEN8_DE_MISC_IER _MMIO(0x4446c)
> #define GEN8_DE_MISC_GSE (1 << 27)
> +#define GEN8_DE_EDP_PSR (1 << 19)
>
> #define GEN8_PCU_ISR _MMIO(0x444e0)
> #define GEN8_PCU_IMR _MMIO(0x444e4)
> diff --git a/drivers/gpu/drm/i915/intel_display.h
> b/drivers/gpu/drm/i915/intel_display.h
> index 4e7418b345bc..2ef31617614a 100644
> --- a/drivers/gpu/drm/i915/intel_display.h
> +++ b/drivers/gpu/drm/i915/intel_display.h
> @@ -218,6 +218,10 @@ struct intel_link_m_n {
> for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes;
> (__p)++) \
> for_each_if((__mask) & BIT(__p))
>
> +#define for_each_cpu_transcoder_masked(__dev_priv, __t, __mask) \
> + for ((__t) = 0; (__t) < I915_MAX_TRANSCODERS; (__t)++)
> \
> + for_each_if ((__mask) & (1 << (__t)))
> +
> #define for_each_universal_plane(__dev_priv, __pipe, __p)
> \
> for ((__p) = 0;
> \
> (__p) < INTEL_INFO(__dev_priv)->num_sprites[(__pipe)] +
> 1; \
More information about the Intel-gfx
mailing list