Depending on the transcoder enum values to translate from transcoder to EDP PSR flags can easily break if we add a new transcoder. So remove the dependency by using an explicit mapping. While at it also add a WARN for unexpected trancoders. Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Cc: Lucas De Marchi <lucas.demarchi@xxxxxxxxx> Cc: Mika Kahola <mika.kahola@xxxxxxxxx> Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_reg.h | 10 ++++-- drivers/gpu/drm/i915/intel_psr.c | 70 +++++++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index edb58af1e903..25b069175c2a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4150,9 +4150,13 @@ 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(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)) +#define _EDP_PSR_ERROR(idx) (1 << ((idx) * 8 + 2)) +#define _EDP_PSR_POST_EXIT(idx) (1 << ((idx) * 8 + 1)) +#define _EDP_PSR_PRE_ENTRY(idx) (1 << ((idx) * 8)) +#define _EDP_PSR_TRANSCODER_A_IDX 1 +#define _EDP_PSR_TRANSCODER_B_IDX 2 +#define _EDP_PSR_TRANSCODER_C_IDX 3 +#define _EDP_PSR_TRANSCODER_EDP_IDX 0 #define EDP_PSR_AUX_CTL _MMIO(dev_priv->psr_mmio_base + 0x10) #define EDP_PSR_AUX_CTL_TIME_OUT_MASK (3 << 26) diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 48df16a02fac..5fdc2f196045 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -83,25 +83,59 @@ static bool intel_psr2_enabled(struct drm_i915_private *dev_priv, } } +static int edp_psr_transcoder_idx(enum transcoder trans) +{ + int trans_to_idx[] = { + [TRANSCODER_A] = _EDP_PSR_TRANSCODER_A_IDX, + [TRANSCODER_B] = _EDP_PSR_TRANSCODER_B_IDX, + [TRANSCODER_C] = _EDP_PSR_TRANSCODER_C_IDX, + [TRANSCODER_EDP] = _EDP_PSR_TRANSCODER_EDP_IDX, + }; + + switch (trans) { + case TRANSCODER_A: + case TRANSCODER_B: + case TRANSCODER_C: + case TRANSCODER_EDP: + return trans_to_idx[trans]; + default: + MISSING_CASE(trans); + return trans_to_idx[TRANSCODER_EDP]; + } +} + +static u32 edp_psr_error(enum transcoder trans) +{ + return _EDP_PSR_ERROR(edp_psr_transcoder_idx(trans)); +} + +static u32 edp_psr_post_exit(enum transcoder trans) +{ + return _EDP_PSR_POST_EXIT(edp_psr_transcoder_idx(trans)); +} + +static u32 edp_psr_pre_entry(enum transcoder trans) +{ + return _EDP_PSR_PRE_ENTRY(edp_psr_transcoder_idx(trans)); +} + void intel_psr_irq_control(struct drm_i915_private *dev_priv, u32 debug) { u32 debug_mask, mask; + enum transcoder cpu_transcoder; + u32 transcoders = BIT(TRANSCODER_EDP); - mask = EDP_PSR_ERROR(TRANSCODER_EDP); - debug_mask = EDP_PSR_POST_EXIT(TRANSCODER_EDP) | - EDP_PSR_PRE_ENTRY(TRANSCODER_EDP); - - if (INTEL_GEN(dev_priv) >= 8) { - mask |= EDP_PSR_ERROR(TRANSCODER_A) | - EDP_PSR_ERROR(TRANSCODER_B) | - EDP_PSR_ERROR(TRANSCODER_C); - - debug_mask |= EDP_PSR_POST_EXIT(TRANSCODER_A) | - EDP_PSR_PRE_ENTRY(TRANSCODER_A) | - EDP_PSR_POST_EXIT(TRANSCODER_B) | - EDP_PSR_PRE_ENTRY(TRANSCODER_B) | - EDP_PSR_POST_EXIT(TRANSCODER_C) | - EDP_PSR_PRE_ENTRY(TRANSCODER_C); + if (INTEL_GEN(dev_priv) >= 8) + transcoders |= BIT(TRANSCODER_A) | + BIT(TRANSCODER_B) | + BIT(TRANSCODER_C); + + debug_mask = 0; + mask = 0; + for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) { + mask |= edp_psr_error(cpu_transcoder); + debug_mask |= edp_psr_post_exit(cpu_transcoder) | + edp_psr_pre_entry(cpu_transcoder); } if (debug & I915_PSR_DEBUG_IRQ) @@ -160,17 +194,17 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) { /* FIXME: Exit PSR and link train manually when this happens. */ - if (psr_iir & EDP_PSR_ERROR(cpu_transcoder)) + if (psr_iir & edp_psr_error(cpu_transcoder)) DRM_DEBUG_KMS("[transcoder %s] PSR aux error\n", transcoder_name(cpu_transcoder)); - if (psr_iir & EDP_PSR_PRE_ENTRY(cpu_transcoder)) { + if (psr_iir & edp_psr_pre_entry(cpu_transcoder)) { dev_priv->psr.last_entry_attempt = time_ns; DRM_DEBUG_KMS("[transcoder %s] PSR entry attempt in 2 vblanks\n", transcoder_name(cpu_transcoder)); } - if (psr_iir & EDP_PSR_POST_EXIT(cpu_transcoder)) { + if (psr_iir & edp_psr_post_exit(cpu_transcoder)) { dev_priv->psr.last_exit = time_ns; DRM_DEBUG_KMS("[transcoder %s] PSR exit completed\n", transcoder_name(cpu_transcoder)); -- 2.13.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx