diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-09-06 16:15:42 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-09-20 08:23:03 -0400 |
commit | 0767935e8682157dc98bee03f821faa08b944fe8 (patch) | |
tree | 7eab8aec8fced72170a0c70098e1d266bcac7f3c /drivers/gpu/drm/i915 | |
parent | 2bd2ad643def79b843e5ff3a88d42d505db158ad (diff) |
drm/i915: robustify edp_pll_on/off
With the previous patch to clean up where exactly these two functions
are getting called, this patch can tackle the enable/disable code
itself:
- WARN if the port enable bit is in the wrong state or if the edp pll
bit is in the wrong state, just for paranoia's sake.
- Don't disable the edp pll harder in the modeset functions just for
fun.
- Don't set the edp pll enable flag in intel_dp->DP in modeset, do
that while changing the actual hw state. We do the same with the
actual port enable bit, so this is a bit more consistent.
- Track the current DP register value when setting things up and add
some comments how intel_dp->DP is used in the disable code.
v2: Be more careful with resetting intel_dp->DP - otherwise dpms
off->on will fail spectacularly, becuase we enable the eDP port when
we should only enable the eDP pll.
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index fccc82970ae0..0f8480037cf0 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -887,7 +887,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
887 | intel_dp->DP |= intel_crtc->pipe << 29; | 887 | intel_dp->DP |= intel_crtc->pipe << 29; |
888 | 888 | ||
889 | /* don't miss out required setting for eDP */ | 889 | /* don't miss out required setting for eDP */ |
890 | intel_dp->DP |= DP_PLL_ENABLE; | ||
891 | if (adjusted_mode->clock < 200000) | 890 | if (adjusted_mode->clock < 200000) |
892 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; | 891 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; |
893 | else | 892 | else |
@@ -909,7 +908,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
909 | 908 | ||
910 | if (is_cpu_edp(intel_dp)) { | 909 | if (is_cpu_edp(intel_dp)) { |
911 | /* don't miss out required setting for eDP */ | 910 | /* don't miss out required setting for eDP */ |
912 | intel_dp->DP |= DP_PLL_ENABLE; | ||
913 | if (adjusted_mode->clock < 200000) | 911 | if (adjusted_mode->clock < 200000) |
914 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; | 912 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; |
915 | else | 913 | else |
@@ -1192,8 +1190,15 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp) | |||
1192 | 1190 | ||
1193 | DRM_DEBUG_KMS("\n"); | 1191 | DRM_DEBUG_KMS("\n"); |
1194 | dpa_ctl = I915_READ(DP_A); | 1192 | dpa_ctl = I915_READ(DP_A); |
1195 | dpa_ctl |= DP_PLL_ENABLE; | 1193 | WARN(dpa_ctl & DP_PLL_ENABLE, "dp pll on, should be off\n"); |
1196 | I915_WRITE(DP_A, dpa_ctl); | 1194 | WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n"); |
1195 | |||
1196 | /* We don't adjust intel_dp->DP while tearing down the link, to | ||
1197 | * facilitate link retraining (e.g. after hotplug). Hence clear all | ||
1198 | * enable bits here to ensure that we don't enable too much. */ | ||
1199 | intel_dp->DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE); | ||
1200 | intel_dp->DP |= DP_PLL_ENABLE; | ||
1201 | I915_WRITE(DP_A, intel_dp->DP); | ||
1197 | POSTING_READ(DP_A); | 1202 | POSTING_READ(DP_A); |
1198 | udelay(200); | 1203 | udelay(200); |
1199 | } | 1204 | } |
@@ -1209,6 +1214,13 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp) | |||
1209 | to_intel_crtc(crtc)->pipe); | 1214 | to_intel_crtc(crtc)->pipe); |
1210 | 1215 | ||
1211 | dpa_ctl = I915_READ(DP_A); | 1216 | dpa_ctl = I915_READ(DP_A); |
1217 | WARN((dpa_ctl & DP_PLL_ENABLE) == 0, | ||
1218 | "dp pll off, should be on\n"); | ||
1219 | WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n"); | ||
1220 | |||
1221 | /* We can't rely on the value tracked for the DP register in | ||
1222 | * intel_dp->DP because link_down must not change that (otherwise link | ||
1223 | * re-training will fail. */ | ||
1212 | dpa_ctl &= ~DP_PLL_ENABLE; | 1224 | dpa_ctl &= ~DP_PLL_ENABLE; |
1213 | I915_WRITE(DP_A, dpa_ctl); | 1225 | I915_WRITE(DP_A, dpa_ctl); |
1214 | POSTING_READ(DP_A); | 1226 | POSTING_READ(DP_A); |
@@ -1893,13 +1905,6 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1893 | 1905 | ||
1894 | DRM_DEBUG_KMS("\n"); | 1906 | DRM_DEBUG_KMS("\n"); |
1895 | 1907 | ||
1896 | if (is_edp(intel_dp)) { | ||
1897 | DP &= ~DP_PLL_ENABLE; | ||
1898 | I915_WRITE(intel_dp->output_reg, DP); | ||
1899 | POSTING_READ(intel_dp->output_reg); | ||
1900 | udelay(100); | ||
1901 | } | ||
1902 | |||
1903 | if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) { | 1908 | if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) { |
1904 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1909 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1905 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); | 1910 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); |
@@ -2443,6 +2448,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) | |||
2443 | 2448 | ||
2444 | intel_dp->output_reg = output_reg; | 2449 | intel_dp->output_reg = output_reg; |
2445 | intel_dp->port = port; | 2450 | intel_dp->port = port; |
2451 | /* Preserve the current hw state. */ | ||
2452 | intel_dp->DP = I915_READ(intel_dp->output_reg); | ||
2446 | 2453 | ||
2447 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 2454 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
2448 | if (!intel_connector) { | 2455 | if (!intel_connector) { |