aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dp_link_training.c
diff options
context:
space:
mode:
authorNavare, Manasi D <manasi.d.navare@intel.com>2016-09-01 18:08:15 -0400
committerRodrigo Vivi <rodrigo.vivi@intel.com>2016-09-09 17:53:18 -0400
commitc92bd2fa33038d18858beca3cc65d53c99ce95f6 (patch)
tree46e0371e8bc405b628b934123728ddcd3191b0ef /drivers/gpu/drm/i915/intel_dp_link_training.c
parent13b1996e842aa4164c4d838908bc6dd76c3bd2b2 (diff)
drm/i915: Make DP link training channel equalization DP 1.2 Spec compliant
Fix the number of tries in channel euqalization link training sequence according to DP 1.2 Spec. It returns a boolean depending on channel equalization pass or failure. Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com> Reviewed-by: Mika Kahola <mika.kahola@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp_link_training.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dp_link_training.c57
1 files changed, 21 insertions, 36 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 80b932664743..c438b02184cb 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -244,12 +244,12 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
244 return training_pattern; 244 return training_pattern;
245} 245}
246 246
247static void 247static bool
248intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) 248intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
249{ 249{
250 bool channel_eq = false; 250 int tries;
251 int tries, cr_tries;
252 u32 training_pattern; 251 u32 training_pattern;
252 uint8_t link_status[DP_LINK_STATUS_SIZE];
253 253
254 training_pattern = intel_dp_training_pattern(intel_dp); 254 training_pattern = intel_dp_training_pattern(intel_dp);
255 255
@@ -258,20 +258,11 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
258 training_pattern | 258 training_pattern |
259 DP_LINK_SCRAMBLING_DISABLE)) { 259 DP_LINK_SCRAMBLING_DISABLE)) {
260 DRM_ERROR("failed to start channel equalization\n"); 260 DRM_ERROR("failed to start channel equalization\n");
261 return; 261 return false;
262 } 262 }
263 263
264 tries = 0; 264 intel_dp->channel_eq_status = false;
265 cr_tries = 0; 265 for (tries = 0; tries < 5; tries++) {
266 channel_eq = false;
267 for (;;) {
268 uint8_t link_status[DP_LINK_STATUS_SIZE];
269
270 if (cr_tries > 5) {
271 DRM_ERROR("failed to train DP, aborting\n");
272 intel_dp_dump_link_status(link_status);
273 break;
274 }
275 266
276 drm_dp_link_train_channel_eq_delay(intel_dp->dpcd); 267 drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
277 if (!intel_dp_get_link_status(intel_dp, link_status)) { 268 if (!intel_dp_get_link_status(intel_dp, link_status)) {
@@ -282,44 +273,38 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
282 /* Make sure clock is still ok */ 273 /* Make sure clock is still ok */
283 if (!drm_dp_clock_recovery_ok(link_status, 274 if (!drm_dp_clock_recovery_ok(link_status,
284 intel_dp->lane_count)) { 275 intel_dp->lane_count)) {
285 intel_dp_link_training_clock_recovery(intel_dp); 276 intel_dp_dump_link_status(link_status);
286 intel_dp_set_link_train(intel_dp, 277 DRM_DEBUG_KMS("Clock recovery check failed, cannot "
287 training_pattern | 278 "continue channel equalization\n");
288 DP_LINK_SCRAMBLING_DISABLE); 279 break;
289 cr_tries++;
290 continue;
291 } 280 }
292 281
293 if (drm_dp_channel_eq_ok(link_status, 282 if (drm_dp_channel_eq_ok(link_status,
294 intel_dp->lane_count)) { 283 intel_dp->lane_count)) {
295 channel_eq = true; 284 intel_dp->channel_eq_status = true;
285 DRM_DEBUG_KMS("Channel EQ done. DP Training "
286 "successful\n");
296 break; 287 break;
297 } 288 }
298 289
299 /* Try 5 times, then try clock recovery if that fails */
300 if (tries > 5) {
301 intel_dp_link_training_clock_recovery(intel_dp);
302 intel_dp_set_link_train(intel_dp,
303 training_pattern |
304 DP_LINK_SCRAMBLING_DISABLE);
305 tries = 0;
306 cr_tries++;
307 continue;
308 }
309
310 /* Update training set as requested by target */ 290 /* Update training set as requested by target */
311 intel_get_adjust_train(intel_dp, link_status); 291 intel_get_adjust_train(intel_dp, link_status);
312 if (!intel_dp_update_link_train(intel_dp)) { 292 if (!intel_dp_update_link_train(intel_dp)) {
313 DRM_ERROR("failed to update link training\n"); 293 DRM_ERROR("failed to update link training\n");
314 break; 294 break;
315 } 295 }
316 ++tries; 296 }
297
298 /* Try 5 times, else fail and try at lower BW */
299 if (tries == 5) {
300 intel_dp_dump_link_status(link_status);
301 DRM_DEBUG_KMS("Channel equalization failed 5 times\n");
317 } 302 }
318 303
319 intel_dp_set_idle_link_train(intel_dp); 304 intel_dp_set_idle_link_train(intel_dp);
320 305
321 if (channel_eq) 306 return intel_dp->channel_eq_status;
322 DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n"); 307
323} 308}
324 309
325void intel_dp_stop_link_train(struct intel_dp *intel_dp) 310void intel_dp_stop_link_train(struct intel_dp *intel_dp)