aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ddi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 852012b6fc5b..4bad0f724019 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
141static 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
@@ -167,6 +180,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
167 /* Enable the PCH Receiver FDI PLL */ 180 /* Enable the PCH Receiver FDI PLL */
168 rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE | 181 rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE |
169 ((intel_crtc->fdi_lanes - 1) << 19); 182 ((intel_crtc->fdi_lanes - 1) << 19);
183 if (dev_priv->fdi_rx_polarity_reversed)
184 rx_ctl_val |= FDI_RX_POLARITY_REVERSED_LPT;
170 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); 185 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
171 POSTING_READ(_FDI_RXA_CTL); 186 POSTING_READ(_FDI_RXA_CTL);
172 udelay(220); 187 udelay(220);
@@ -231,18 +246,30 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
231 return; 246 return;
232 } 247 }
233 248
249 temp = I915_READ(DDI_BUF_CTL(PORT_E));
250 temp &= ~DDI_BUF_CTL_ENABLE;
251 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
252 POSTING_READ(DDI_BUF_CTL(PORT_E));
253
234 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ 254 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
235 I915_WRITE(DP_TP_CTL(PORT_E), 255 temp = I915_READ(DP_TP_CTL(PORT_E));
236 I915_READ(DP_TP_CTL(PORT_E)) & ~DP_TP_CTL_ENABLE); 256 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
257 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
258 I915_WRITE(DP_TP_CTL(PORT_E), temp);
259 POSTING_READ(DP_TP_CTL(PORT_E));
260
261 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
237 262
238 rx_ctl_val &= ~FDI_RX_ENABLE; 263 rx_ctl_val &= ~FDI_RX_ENABLE;
239 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); 264 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
265 POSTING_READ(_FDI_RXA_CTL);
240 266
241 /* Reset FDI_RX_MISC pwrdn lanes */ 267 /* Reset FDI_RX_MISC pwrdn lanes */
242 temp = I915_READ(_FDI_RXA_MISC); 268 temp = I915_READ(_FDI_RXA_MISC);
243 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); 269 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); 270 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
245 I915_WRITE(_FDI_RXA_MISC, temp); 271 I915_WRITE(_FDI_RXA_MISC, temp);
272 POSTING_READ(_FDI_RXA_MISC);
246 } 273 }
247 274
248 DRM_ERROR("FDI link training failed!\n"); 275 DRM_ERROR("FDI link training failed!\n");
@@ -1222,20 +1249,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
1222 } 1249 }
1223} 1250}
1224 1251
1225static 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
1239static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) 1252static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
1240{ 1253{
1241 struct drm_encoder *encoder = &intel_encoder->base; 1254 struct drm_encoder *encoder = &intel_encoder->base;