aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorPaulo Zanoni <paulo.r.zanoni@intel.com>2018-07-24 20:28:13 -0400
committerPaulo Zanoni <paulo.r.zanoni@intel.com>2018-07-25 16:45:26 -0400
commitbc334d914eeee02eddefd7be533acafd9a042ade (patch)
tree7c97e1333ee1caed6129c34c9ebb2d935fac9e4c /drivers/gpu/drm/i915
parent340a44bef2342b0ff7334017e9e821645fa8ae43 (diff)
drm/i915/icl: toggle PHY clock gating around link training
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. v2: Simple rebase. Cc: Animesh Manna <animesh.manna@intel.com> Cc: Manasi Navare <manasi.d.navare@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> (v1) Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180725002813.6938-6-paulo.r.zanoni@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h20
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c3
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c66
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
4 files changed, 91 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index cf1d2bbb0613..5530c470f30d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2106,6 +2106,26 @@ enum i915_power_well_id {
2106 MG_DP_MODE_LN1_ACU_PORT1) 2106 MG_DP_MODE_LN1_ACU_PORT1)
2107#define MG_DP_MODE_CFG_DP_X2_MODE (1 << 7) 2107#define MG_DP_MODE_CFG_DP_X2_MODE (1 << 7)
2108#define MG_DP_MODE_CFG_DP_X1_MODE (1 << 6) 2108#define MG_DP_MODE_CFG_DP_X1_MODE (1 << 6)
2109#define MG_DP_MODE_CFG_TR2PWR_GATING (1 << 5)
2110#define MG_DP_MODE_CFG_TRPWR_GATING (1 << 4)
2111#define MG_DP_MODE_CFG_CLNPWR_GATING (1 << 3)
2112#define MG_DP_MODE_CFG_DIGPWR_GATING (1 << 2)
2113#define MG_DP_MODE_CFG_GAONPWR_GATING (1 << 1)
2114
2115#define MG_MISC_SUS0_PORT1 0x168814
2116#define MG_MISC_SUS0_PORT2 0x169814
2117#define MG_MISC_SUS0_PORT3 0x16A814
2118#define MG_MISC_SUS0_PORT4 0x16B814
2119#define MG_MISC_SUS0(tc_port) \
2120 _MMIO(_PORT(tc_port, MG_MISC_SUS0_PORT1, MG_MISC_SUS0_PORT2))
2121#define MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE_MASK (3 << 14)
2122#define MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE(x) ((x) << 14)
2123#define MG_MISC_SUS0_CFG_TR2PWR_GATING (1 << 12)
2124#define MG_MISC_SUS0_CFG_CL2PWR_GATING (1 << 11)
2125#define MG_MISC_SUS0_CFG_GAONPWR_GATING (1 << 10)
2126#define MG_MISC_SUS0_CFG_TRPWR_GATING (1 << 7)
2127#define MG_MISC_SUS0_CFG_CL1PWR_GATING (1 << 6)
2128#define MG_MISC_SUS0_CFG_DGPWR_GATING (1 << 5)
2109 2129
2110/* The spec defines this only for BXT PHY0, but lets assume that this 2130/* The spec defines this only for BXT PHY0, but lets assume that this
2111 * would exist for PHY1 too if it had a second channel. 2131 * 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 399c438bd210..0adc043529f2 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2810,6 +2810,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
2810 intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); 2810 intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
2811 2811
2812 icl_program_mg_dp_mode(intel_dp); 2812 icl_program_mg_dp_mode(intel_dp);
2813 icl_disable_phy_clock_gating(dig_port);
2813 2814
2814 if (IS_ICELAKE(dev_priv)) 2815 if (IS_ICELAKE(dev_priv))
2815 icl_ddi_vswing_sequence(encoder, crtc_state->port_clock, 2816 icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
@@ -2828,6 +2829,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
2828 if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) 2829 if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
2829 intel_dp_stop_link_train(intel_dp); 2830 intel_dp_stop_link_train(intel_dp);
2830 2831
2832 icl_enable_phy_clock_gating(dig_port);
2833
2831 intel_ddi_enable_pipe_clock(crtc_state); 2834 intel_ddi_enable_pipe_clock(crtc_state);
2832} 2835}
2833 2836
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 28de73be4507..cc33d7c6ba19 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)
295 I915_WRITE(MG_DP_MODE(port, 1), ln1); 295 I915_WRITE(MG_DP_MODE(port, 1), ln1);
296} 296}
297 297
298void icl_enable_phy_clock_gating(struct intel_digital_port *dig_port)
299{
300 struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
301 enum port port = dig_port->base.port;
302 enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
303 i915_reg_t mg_regs[2] = { MG_DP_MODE(port, 0), MG_DP_MODE(port, 1) };
304 u32 val;
305 int i;
306
307 if (tc_port == PORT_TC_NONE)
308 return;
309
310 for (i = 0; i < ARRAY_SIZE(mg_regs); i++) {
311 val = I915_READ(mg_regs[i]);
312 val |= MG_DP_MODE_CFG_TR2PWR_GATING |
313 MG_DP_MODE_CFG_TRPWR_GATING |
314 MG_DP_MODE_CFG_CLNPWR_GATING |
315 MG_DP_MODE_CFG_DIGPWR_GATING |
316 MG_DP_MODE_CFG_GAONPWR_GATING;
317 I915_WRITE(mg_regs[i], val);
318 }
319
320 val = I915_READ(MG_MISC_SUS0(tc_port));
321 val |= MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE(3) |
322 MG_MISC_SUS0_CFG_TR2PWR_GATING |
323 MG_MISC_SUS0_CFG_CL2PWR_GATING |
324 MG_MISC_SUS0_CFG_GAONPWR_GATING |
325 MG_MISC_SUS0_CFG_TRPWR_GATING |
326 MG_MISC_SUS0_CFG_CL1PWR_GATING |
327 MG_MISC_SUS0_CFG_DGPWR_GATING;
328 I915_WRITE(MG_MISC_SUS0(tc_port), val);
329}
330
331void icl_disable_phy_clock_gating(struct intel_digital_port *dig_port)
332{
333 struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
334 enum port port = dig_port->base.port;
335 enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
336 i915_reg_t mg_regs[2] = { MG_DP_MODE(port, 0), MG_DP_MODE(port, 1) };
337 u32 val;
338 int i;
339
340 if (tc_port == PORT_TC_NONE)
341 return;
342
343 for (i = 0; i < ARRAY_SIZE(mg_regs); i++) {
344 val = I915_READ(mg_regs[i]);
345 val &= ~(MG_DP_MODE_CFG_TR2PWR_GATING |
346 MG_DP_MODE_CFG_TRPWR_GATING |
347 MG_DP_MODE_CFG_CLNPWR_GATING |
348 MG_DP_MODE_CFG_DIGPWR_GATING |
349 MG_DP_MODE_CFG_GAONPWR_GATING);
350 I915_WRITE(mg_regs[i], val);
351 }
352
353 val = I915_READ(MG_MISC_SUS0(tc_port));
354 val &= ~(MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE_MASK |
355 MG_MISC_SUS0_CFG_TR2PWR_GATING |
356 MG_MISC_SUS0_CFG_CL2PWR_GATING |
357 MG_MISC_SUS0_CFG_GAONPWR_GATING |
358 MG_MISC_SUS0_CFG_TRPWR_GATING |
359 MG_MISC_SUS0_CFG_CL1PWR_GATING |
360 MG_MISC_SUS0_CFG_DGPWR_GATING);
361 I915_WRITE(MG_MISC_SUS0(tc_port), val);
362}
363
298int 364int
299intel_dp_max_data_rate(int max_link_clock, int max_lanes) 365intel_dp_max_data_rate(int max_link_clock, int max_lanes)
300{ 366{
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4e5b00052b5b..99a5f5be5b82 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1715,6 +1715,8 @@ void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv,
1715void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, 1715void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
1716 unsigned int frontbuffer_bits); 1716 unsigned int frontbuffer_bits);
1717void icl_program_mg_dp_mode(struct intel_dp *intel_dp); 1717void icl_program_mg_dp_mode(struct intel_dp *intel_dp);
1718void icl_enable_phy_clock_gating(struct intel_digital_port *dig_port);
1719void icl_disable_phy_clock_gating(struct intel_digital_port *dig_port);
1718 1720
1719void 1721void
1720intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, 1722intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,