diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 852012b6fc5b..3264cb4564b0 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -138,6 +138,19 @@ static const long hsw_ddi_buf_ctl_values[] = { | |||
138 | DDI_BUF_EMP_800MV_3_5DB_HSW | 138 | DDI_BUF_EMP_800MV_3_5DB_HSW |
139 | }; | 139 | }; |
140 | 140 | ||
141 | static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, | ||
142 | enum port port) | ||
143 | { | ||
144 | uint32_t reg = DDI_BUF_CTL(port); | ||
145 | int i; | ||
146 | |||
147 | for (i = 0; i < 8; i++) { | ||
148 | udelay(1); | ||
149 | if (I915_READ(reg) & DDI_BUF_IS_IDLE) | ||
150 | return; | ||
151 | } | ||
152 | DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port)); | ||
153 | } | ||
141 | 154 | ||
142 | /* Starting with Haswell, different DDI ports can work in FDI mode for | 155 | /* Starting with Haswell, different DDI ports can work in FDI mode for |
143 | * connection to the PCH-located connectors. For this, it is necessary to train | 156 | * connection to the PCH-located connectors. For this, it is necessary to train |
@@ -231,18 +244,30 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) | |||
231 | return; | 244 | return; |
232 | } | 245 | } |
233 | 246 | ||
247 | temp = I915_READ(DDI_BUF_CTL(PORT_E)); | ||
248 | temp &= ~DDI_BUF_CTL_ENABLE; | ||
249 | I915_WRITE(DDI_BUF_CTL(PORT_E), temp); | ||
250 | POSTING_READ(DDI_BUF_CTL(PORT_E)); | ||
251 | |||
234 | /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ | 252 | /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ |
235 | I915_WRITE(DP_TP_CTL(PORT_E), | 253 | temp = I915_READ(DP_TP_CTL(PORT_E)); |
236 | I915_READ(DP_TP_CTL(PORT_E)) & ~DP_TP_CTL_ENABLE); | 254 | temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
255 | temp |= DP_TP_CTL_LINK_TRAIN_PAT1; | ||
256 | I915_WRITE(DP_TP_CTL(PORT_E), temp); | ||
257 | POSTING_READ(DP_TP_CTL(PORT_E)); | ||
258 | |||
259 | intel_wait_ddi_buf_idle(dev_priv, PORT_E); | ||
237 | 260 | ||
238 | rx_ctl_val &= ~FDI_RX_ENABLE; | 261 | rx_ctl_val &= ~FDI_RX_ENABLE; |
239 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); | 262 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
263 | POSTING_READ(_FDI_RXA_CTL); | ||
240 | 264 | ||
241 | /* Reset FDI_RX_MISC pwrdn lanes */ | 265 | /* Reset FDI_RX_MISC pwrdn lanes */ |
242 | temp = I915_READ(_FDI_RXA_MISC); | 266 | temp = I915_READ(_FDI_RXA_MISC); |
243 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); | 267 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
244 | temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); | 268 | temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
245 | I915_WRITE(_FDI_RXA_MISC, temp); | 269 | I915_WRITE(_FDI_RXA_MISC, temp); |
270 | POSTING_READ(_FDI_RXA_MISC); | ||
246 | } | 271 | } |
247 | 272 | ||
248 | DRM_ERROR("FDI link training failed!\n"); | 273 | DRM_ERROR("FDI link training failed!\n"); |
@@ -1222,20 +1247,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) | |||
1222 | } | 1247 | } |
1223 | } | 1248 | } |
1224 | 1249 | ||
1225 | static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, | ||
1226 | enum port port) | ||
1227 | { | ||
1228 | uint32_t reg = DDI_BUF_CTL(port); | ||
1229 | int i; | ||
1230 | |||
1231 | for (i = 0; i < 8; i++) { | ||
1232 | udelay(1); | ||
1233 | if (I915_READ(reg) & DDI_BUF_IS_IDLE) | ||
1234 | return; | ||
1235 | } | ||
1236 | DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port)); | ||
1237 | } | ||
1238 | |||
1239 | static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) | 1250 | static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) |
1240 | { | 1251 | { |
1241 | struct drm_encoder *encoder = &intel_encoder->base; | 1252 | struct drm_encoder *encoder = &intel_encoder->base; |