aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Zanoni <paulo.r.zanoni@intel.com>2012-11-29 08:29:31 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-12-08 07:59:09 -0500
commit248138b59880a3cc69e9b7f0e06fb0caedd58305 (patch)
tree63693f6411677ec63ac33e9aea5cfd30578184cc
parente7d841ca03b7ab668620045cd7b428eda9f41601 (diff)
drm/i915: fix hsw_fdi_link_train "retry" code
We were previously doing exactly what the "mode set sequence for CRT" document mandates, but whenever we failed to train the link in the first tentative, all the other subsequent retries always failed. In one of my monitors that has 47 modes, I was usually getting around 3 failures when running "testdisplay -a". After this patch, even if we fail in the first tentative, we can succeed in the next ones. So now when running "testdisplay -a" I see around 3 times the message "FDI link training done on step 1" and no failures. Notice that now the "retry" code looks a lot like the DP retry code. Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c43
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
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
@@ -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
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) 1250static 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;