diff options
author | Navare, Manasi D <manasi.d.navare@intel.com> | 2016-09-01 18:08:15 -0400 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2016-09-09 17:53:18 -0400 |
commit | c92bd2fa33038d18858beca3cc65d53c99ce95f6 (patch) | |
tree | 46e0371e8bc405b628b934123728ddcd3191b0ef /drivers/gpu/drm/i915/intel_dp_link_training.c | |
parent | 13b1996e842aa4164c4d838908bc6dd76c3bd2b2 (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.c | 57 |
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 | ||
247 | static void | 247 | static bool |
248 | intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) | 248 | intel_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 | ||
325 | void intel_dp_stop_link_train(struct intel_dp *intel_dp) | 310 | void intel_dp_stop_link_train(struct intel_dp *intel_dp) |