aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_runtime_pm.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2015-07-08 16:46:01 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-09-01 05:44:57 -0400
commit30142273a3e83936fd7b45aa5339311a9295ca51 (patch)
tree3646156dd7cadb5d67b2ffa9ee9a0b70e122b22d /drivers/gpu/drm/i915/intel_runtime_pm.c
parent6669e39f95b5530ca8cb9137703ceb5e83e5d648 (diff)
drm/i915: Add CHV PHY LDO power sanity checks
At various points when changing the DPIO lane/phy power states, construct an expected value of the DISPLAY_PHY_STATUS register and compare it with the real thing. To construct the expected value we look at our shadow PHY_CONTROL register value (which should match what we've just written to the hardware), and we also need to look at the actual state of the cmn power wells as a disabled power well causes the relevant LDO status to be reported as 'on' in DISPLAY_PHY_STATUS. When initially powering up the PHY it performs various internal calibrations for which it fully powers up. That means that if we check for the expetected power state immediately upon releasing cmnreset we would get the occasional false positive. But we can of course poll until the expected value appears. It shouldn't be too long so this shouldn't make modesets substantially longer. One extra complication is introduced when we cross the streams, ie. drive port B with pipe B. In this case we trick CL2 (where the DPLL lives) into life by temporaily powering up the lanes in the second channel, and once the pipe is up and runnign we release the lane power override. At that point the power state of CL2 has somehow gotten entangled with the power state of the first channel. That means that constructing the expected DISPLAY_PHY_STATUS value is a bit tricky since based on the lane power states in the second channel, CL2 should also be powered down. But we can use the DPLL enable bit to determine when CL2 should be alive even if the lanes are powered down. However the power state of CL2 isn't actually tied in with the DPLL state, but to the state of the lanes in first channel, so we have to avoid checking the expected state between shutting down the DPLL and powering down the lanes in the first channel. So no calling assert_chv_phy_status() before the DISPLAY_PHY_CONTROL write in chv_phy_powergate_lanes(), but after the write is a safe time to check. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Deepak S <deepak.s@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c126
1 files changed, 109 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 7991eff01662..b1bd25e1e853 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -958,6 +958,107 @@ static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
958 vlv_set_power_well(dev_priv, power_well, false); 958 vlv_set_power_well(dev_priv, power_well, false);
959} 959}
960 960
961#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
962
963static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv,
964 int power_well_id)
965{
966 struct i915_power_domains *power_domains = &dev_priv->power_domains;
967 struct i915_power_well *power_well;
968 int i;
969
970 for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
971 if (power_well->data == power_well_id)
972 return power_well;
973 }
974
975 return NULL;
976}
977
978#define BITS_SET(val, bits) (((val) & (bits)) == (bits))
979
980static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
981{
982 struct i915_power_well *cmn_bc =
983 lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC);
984 struct i915_power_well *cmn_d =
985 lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_D);
986 u32 phy_control = dev_priv->chv_phy_control;
987 u32 phy_status = 0;
988 u32 tmp;
989
990 if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) {
991 phy_status |= PHY_POWERGOOD(DPIO_PHY0);
992
993 /* this assumes override is only used to enable lanes */
994 if ((phy_control & PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY0, DPIO_CH0)) == 0)
995 phy_control |= PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH0);
996
997 if ((phy_control & PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY0, DPIO_CH1)) == 0)
998 phy_control |= PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH1);
999
1000 /* CL1 is on whenever anything is on in either channel */
1001 if (BITS_SET(phy_control,
1002 PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH0) |
1003 PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH1)))
1004 phy_status |= PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH0);
1005
1006 /*
1007 * The DPLLB check accounts for the pipe B + port A usage
1008 * with CL2 powered up but all the lanes in the second channel
1009 * powered down.
1010 */
1011 if (BITS_SET(phy_control,
1012 PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH1)) &&
1013 (I915_READ(DPLL(PIPE_B)) & DPLL_VCO_ENABLE) == 0)
1014 phy_status |= PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH1);
1015
1016 if (BITS_SET(phy_control,
1017 PHY_CH_POWER_DOWN_OVRD(0x3, DPIO_PHY0, DPIO_CH0)))
1018 phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 0);
1019 if (BITS_SET(phy_control,
1020 PHY_CH_POWER_DOWN_OVRD(0xc, DPIO_PHY0, DPIO_CH0)))
1021 phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 1);
1022
1023 if (BITS_SET(phy_control,
1024 PHY_CH_POWER_DOWN_OVRD(0x3, DPIO_PHY0, DPIO_CH1)))
1025 phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 0);
1026 if (BITS_SET(phy_control,
1027 PHY_CH_POWER_DOWN_OVRD(0xc, DPIO_PHY0, DPIO_CH1)))
1028 phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1);
1029 }
1030
1031 if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) {
1032 phy_status |= PHY_POWERGOOD(DPIO_PHY1);
1033
1034 /* this assumes override is only used to enable lanes */
1035 if ((phy_control & PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY1, DPIO_CH0)) == 0)
1036 phy_control |= PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY1, DPIO_CH0);
1037
1038 if (BITS_SET(phy_control,
1039 PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY1, DPIO_CH0)))
1040 phy_status |= PHY_STATUS_CMN_LDO(DPIO_PHY1, DPIO_CH0);
1041
1042 if (BITS_SET(phy_control,
1043 PHY_CH_POWER_DOWN_OVRD(0x3, DPIO_PHY1, DPIO_CH0)))
1044 phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0);
1045 if (BITS_SET(phy_control,
1046 PHY_CH_POWER_DOWN_OVRD(0xc, DPIO_PHY1, DPIO_CH0)))
1047 phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1);
1048 }
1049
1050 /*
1051 * The PHY may be busy with some initial calibration and whatnot,
1052 * so the power state can take a while to actually change.
1053 */
1054 if (wait_for((tmp = I915_READ(DISPLAY_PHY_STATUS)) == phy_status, 10))
1055 WARN(phy_status != tmp,
1056 "Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n",
1057 tmp, phy_status, dev_priv->chv_phy_control);
1058}
1059
1060#undef BITS_SET
1061
961static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, 1062static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
962 struct i915_power_well *power_well) 1063 struct i915_power_well *power_well)
963{ 1064{
@@ -1014,6 +1115,8 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
1014 1115
1015 DRM_DEBUG_KMS("Enabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n", 1116 DRM_DEBUG_KMS("Enabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n",
1016 phy, dev_priv->chv_phy_control); 1117 phy, dev_priv->chv_phy_control);
1118
1119 assert_chv_phy_status(dev_priv);
1017} 1120}
1018 1121
1019static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, 1122static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
@@ -1040,6 +1143,8 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
1040 1143
1041 DRM_DEBUG_KMS("Disabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n", 1144 DRM_DEBUG_KMS("Disabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n",
1042 phy, dev_priv->chv_phy_control); 1145 phy, dev_priv->chv_phy_control);
1146
1147 assert_chv_phy_status(dev_priv);
1043} 1148}
1044 1149
1045static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpio_phy phy, 1150static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpio_phy phy,
@@ -1117,6 +1222,8 @@ bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
1117 DRM_DEBUG_KMS("Power gating DPIO PHY%d CH%d (DPIO_PHY_CONTROL=0x%08x)\n", 1222 DRM_DEBUG_KMS("Power gating DPIO PHY%d CH%d (DPIO_PHY_CONTROL=0x%08x)\n",
1118 phy, ch, dev_priv->chv_phy_control); 1223 phy, ch, dev_priv->chv_phy_control);
1119 1224
1225 assert_chv_phy_status(dev_priv);
1226
1120out: 1227out:
1121 mutex_unlock(&power_domains->lock); 1228 mutex_unlock(&power_domains->lock);
1122 1229
@@ -1146,6 +1253,8 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder,
1146 DRM_DEBUG_KMS("Power gating DPIO PHY%d CH%d lanes 0x%x (PHY_CONTROL=0x%08x)\n", 1253 DRM_DEBUG_KMS("Power gating DPIO PHY%d CH%d lanes 0x%x (PHY_CONTROL=0x%08x)\n",
1147 phy, ch, mask, dev_priv->chv_phy_control); 1254 phy, ch, mask, dev_priv->chv_phy_control);
1148 1255
1256 assert_chv_phy_status(dev_priv);
1257
1149 assert_chv_phy_powergate(dev_priv, phy, ch, override, mask); 1258 assert_chv_phy_powergate(dev_priv, phy, ch, override, mask);
1150 1259
1151 mutex_unlock(&power_domains->lock); 1260 mutex_unlock(&power_domains->lock);
@@ -1312,8 +1421,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
1312 intel_runtime_pm_put(dev_priv); 1421 intel_runtime_pm_put(dev_priv);
1313} 1422}
1314 1423
1315#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
1316
1317#define HSW_ALWAYS_ON_POWER_DOMAINS ( \ 1424#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
1318 BIT(POWER_DOMAIN_PIPE_A) | \ 1425 BIT(POWER_DOMAIN_PIPE_A) | \
1319 BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ 1426 BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
@@ -1575,21 +1682,6 @@ static struct i915_power_well chv_power_wells[] = {
1575 }, 1682 },
1576}; 1683};
1577 1684
1578static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv,
1579 int power_well_id)
1580{
1581 struct i915_power_domains *power_domains = &dev_priv->power_domains;
1582 struct i915_power_well *power_well;
1583 int i;
1584
1585 for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
1586 if (power_well->data == power_well_id)
1587 return power_well;
1588 }
1589
1590 return NULL;
1591}
1592
1593bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, 1685bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
1594 int power_well_id) 1686 int power_well_id)
1595{ 1687{