Op 22-05-18 om 02:25 schreef Paulo Zanoni: > The Gen11 TypeC PHY DDI Buffer chapter, PHY Clock Gating Programming > section says that PHY clock gating should be disabled before starting > voltage swing programming, then enabled after any link training is > complete. > > Cc: Animesh Manna <animesh.manna@xxxxxxxxx> > Cc: Manasi Navare <manasi.d.navare@xxxxxxxxx> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_reg.h | 21 +++++++++++++ > drivers/gpu/drm/i915/intel_ddi.c | 3 ++ > drivers/gpu/drm/i915/intel_dp.c | 66 ++++++++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > 4 files changed, 92 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 2ccae6c3e905..9d2c022bc3a1 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -1957,6 +1957,27 @@ enum i915_power_well_id { > _MG_DP_MODE_LN1_ACU_PORT1) > #define MG_DP_MODE_CFG_DP_X2_MODE (1 << 7) > #define MG_DP_MODE_CFG_DP_X1_MODE (1 << 6) > +#define MG_DP_MODE_CFG_TR2PWR_GATING (1 << 5) > +#define MG_DP_MODE_CFG_TRPWR_GATING (1 << 4) > +#define MG_DP_MODE_CFG_CLNPWR_GATING (1 << 3) > +#define MG_DP_MODE_CFG_DIGPWR_GATING (1 << 2) > +#define MG_DP_MODE_CFG_GAONPWR_GATING (1 << 1) > + > +#define _MG_MISC_SUS0_PORT1 0x168814 > +#define _MG_MISC_SUS0_PORT2 0x169814 > +#define _MG_MISC_SUS0_PORT3 0x16A814 > +#define _MG_MISC_SUS0_PORT4 0x16B814 > +#define MG_MISC_SUS0(tc_port) \ > + _MMIO(_PORT(tc_port, _MG_MISC_SUS0_PORT1, _MG_MISC_SUS0_PORT2)) > +#define MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE_MASK (3 << 14) > +#define MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE(x) ((x) << 14) > +#define MG_MISC_SUS0_CFG_TR2PWR_GATING (1 << 12) > +#define MG_MISC_SUS0_CFG_CL2PWR_GATING (1 << 11) > +#define MG_MISC_SUS0_CFG_GAONPWR_GATING (1 << 10) > +#define MG_MISC_SUS0_CFG_TRPWR_GATING (1 << 7) > +#define MG_MISC_SUS0_CFG_CL1PWR_GATING (1 << 6) > +#define MG_MISC_SUS0_CFG_DGPWR_GATING (1 << 5) > + > > /* The spec defines this only for BXT PHY0, but lets assume that this > * would exist for PHY1 too if it had a second channel. > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > index c3c29565b863..6617950a28a9 100644 > --- a/drivers/gpu/drm/i915/intel_ddi.c > +++ b/drivers/gpu/drm/i915/intel_ddi.c > @@ -2668,6 +2668,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, > intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); > > icl_program_mg_dp_mode(intel_dp); > + icl_disable_phy_clock_gating(dig_port); > > if (IS_ICELAKE(dev_priv)) > icl_ddi_vswing_sequence(encoder, level, encoder->type); > @@ -2684,6 +2685,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, > intel_dp_start_link_train(intel_dp); > if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) > intel_dp_stop_link_train(intel_dp); > + > + icl_enable_phy_clock_gating(dig_port); > } > > static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 1228d6185f76..e898d61b5924 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -295,6 +295,72 @@ void icl_program_mg_dp_mode(struct intel_dp *intel_dp) > I915_WRITE(MG_DP_MODE(port, 1), ln1); > } > > +void icl_enable_phy_clock_gating(struct intel_digital_port *dig_port) > +{ > + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); > + enum port port = dig_port->base.port; > + enum tc_port tc_port = intel_port_to_tc(dev_priv, port); > + i915_reg_t mg_regs[2] = { MG_DP_MODE(port, 0), MG_DP_MODE(port, 1) }; > + u32 val; > + int i; > + > + if (tc_port == PORT_TC_NONE) > + return; > + > + for (i = 0; i < ARRAY_SIZE(mg_regs); i++) { > + val = I915_READ(mg_regs[i]); > + val |= MG_DP_MODE_CFG_TR2PWR_GATING | > + MG_DP_MODE_CFG_TRPWR_GATING | > + MG_DP_MODE_CFG_CLNPWR_GATING | > + MG_DP_MODE_CFG_DIGPWR_GATING | > + MG_DP_MODE_CFG_GAONPWR_GATING; > + I915_WRITE(mg_regs[i], val); > + } > + > + val = I915_READ(MG_MISC_SUS0(tc_port)); > + val |= MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE(3) | > + MG_MISC_SUS0_CFG_TR2PWR_GATING | > + MG_MISC_SUS0_CFG_CL2PWR_GATING | > + MG_MISC_SUS0_CFG_GAONPWR_GATING | > + MG_MISC_SUS0_CFG_TRPWR_GATING | > + MG_MISC_SUS0_CFG_CL1PWR_GATING | > + MG_MISC_SUS0_CFG_DGPWR_GATING; > + I915_WRITE(MG_MISC_SUS0(tc_port), val); > +} > + > +void icl_disable_phy_clock_gating(struct intel_digital_port *dig_port) > +{ > + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); > + enum port port = dig_port->base.port; > + enum tc_port tc_port = intel_port_to_tc(dev_priv, port); > + i915_reg_t mg_regs[2] = { MG_DP_MODE(port, 0), MG_DP_MODE(port, 1) }; > + u32 val; > + int i; > + > + if (tc_port == PORT_TC_NONE) > + return; > + > + for (i = 0; i < ARRAY_SIZE(mg_regs); i++) { > + val = I915_READ(mg_regs[i]); > + val &= ~(MG_DP_MODE_CFG_TR2PWR_GATING | > + MG_DP_MODE_CFG_TRPWR_GATING | > + MG_DP_MODE_CFG_CLNPWR_GATING | > + MG_DP_MODE_CFG_DIGPWR_GATING | > + MG_DP_MODE_CFG_GAONPWR_GATING); > + I915_WRITE(mg_regs[i], val); > + } > + > + val = I915_READ(MG_MISC_SUS0(tc_port)); > + val &= ~(MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE_MASK | > + MG_MISC_SUS0_CFG_TR2PWR_GATING | > + MG_MISC_SUS0_CFG_CL2PWR_GATING | > + MG_MISC_SUS0_CFG_GAONPWR_GATING | > + MG_MISC_SUS0_CFG_TRPWR_GATING | > + MG_MISC_SUS0_CFG_CL1PWR_GATING | > + MG_MISC_SUS0_CFG_DGPWR_GATING); > + I915_WRITE(MG_MISC_SUS0(tc_port), val); > +} > + > int > intel_dp_max_data_rate(int max_link_clock, int max_lanes) > { > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index d04be4c1f30e..8c77e0499b44 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -1703,6 +1703,8 @@ void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, > void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, > unsigned int frontbuffer_bits); > void icl_program_mg_dp_mode(struct intel_dp *intel_dp); > +void icl_enable_phy_clock_gating(struct intel_digital_port *dig_port); > +void icl_disable_phy_clock_gating(struct intel_digital_port *dig_port); > > void > intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, Reviewed-by: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx