aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2012-10-31 19:21:00 -0400
committerJingoo Han <jg1.han@samsung.com>2012-11-28 20:33:27 -0500
commitace2d7f2b537a072e39ddb4f51467d32b4900f8c (patch)
tree9a11b68cefb2768790c820a06f2ad96ed77e1c62 /drivers/video
parent825e90d0a138738657509d7460d77edb28fcfdc0 (diff)
video: exynos_dp: Check DPCD return codes
Add return code checks to the DPCD transactions in the SW link training Signed-off-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/exynos/exynos_dp_core.c86
1 files changed, 56 insertions, 30 deletions
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index 9a9ecc16269a..e007906694fa 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -262,11 +262,10 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
262 } 262 }
263} 263}
264 264
265static void exynos_dp_link_start(struct exynos_dp_device *dp) 265static int exynos_dp_link_start(struct exynos_dp_device *dp)
266{ 266{
267 u8 buf[4]; 267 u8 buf[4];
268 int lane; 268 int lane, lane_count, retval;
269 int lane_count;
270 269
271 lane_count = dp->link_train.lane_count; 270 lane_count = dp->link_train.lane_count;
272 271
@@ -277,8 +276,10 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
277 dp->link_train.cr_loop[lane] = 0; 276 dp->link_train.cr_loop[lane] = 0;
278 277
279 /* Set sink to D0 (Sink Not Ready) mode. */ 278 /* Set sink to D0 (Sink Not Ready) mode. */
280 exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE, 279 retval = exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
281 DPCD_SET_POWER_STATE_D0); 280 DPCD_SET_POWER_STATE_D0);
281 if (retval)
282 return retval;
282 283
283 /* Set link rate and count as you want to establish*/ 284 /* Set link rate and count as you want to establish*/
284 exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate); 285 exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
@@ -287,8 +288,10 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
287 /* Setup RX configuration */ 288 /* Setup RX configuration */
288 buf[0] = dp->link_train.link_rate; 289 buf[0] = dp->link_train.link_rate;
289 buf[1] = dp->link_train.lane_count; 290 buf[1] = dp->link_train.lane_count;
290 exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET, 291 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
291 2, buf); 292 2, buf);
293 if (retval)
294 return retval;
292 295
293 /* Set TX pre-emphasis to minimum */ 296 /* Set TX pre-emphasis to minimum */
294 for (lane = 0; lane < lane_count; lane++) 297 for (lane = 0; lane < lane_count; lane++)
@@ -307,9 +310,11 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
307 for (lane = 0; lane < lane_count; lane++) 310 for (lane = 0; lane < lane_count; lane++)
308 buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 | 311 buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
309 DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0; 312 DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
310 exynos_dp_write_bytes_to_dpcd(dp, 313 retval = exynos_dp_write_bytes_to_dpcd(dp,
311 DPCD_ADDR_TRAINING_LANE0_SET, 314 DPCD_ADDR_TRAINING_LANE0_SET,
312 lane_count, buf); 315 lane_count, buf);
316
317 return retval;
313} 318}
314 319
315static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane) 320static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
@@ -431,8 +436,7 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
431static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp) 436static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
432{ 437{
433 u8 link_status[2]; 438 u8 link_status[2];
434 int lane; 439 int lane, lane_count, retval;
435 int lane_count;
436 440
437 u8 adjust_request[2]; 441 u8 adjust_request[2];
438 u8 voltage_swing; 442 u8 voltage_swing;
@@ -443,17 +447,22 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
443 447
444 lane_count = dp->link_train.lane_count; 448 lane_count = dp->link_train.lane_count;
445 449
446 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, 450 retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
447 2, link_status); 451 2, link_status);
452 if (retval)
453 return retval;
448 454
449 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { 455 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
450 /* set training pattern 2 for EQ */ 456 /* set training pattern 2 for EQ */
451 exynos_dp_set_training_pattern(dp, TRAINING_PTN2); 457 exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
452 458
453 for (lane = 0; lane < lane_count; lane++) { 459 for (lane = 0; lane < lane_count; lane++) {
454 exynos_dp_read_bytes_from_dpcd(dp, 460 retval = exynos_dp_read_bytes_from_dpcd(dp,
455 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 461 DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
456 2, adjust_request); 462 2, adjust_request);
463 if (retval)
464 return retval;
465
457 voltage_swing = exynos_dp_get_adjust_request_voltage( 466 voltage_swing = exynos_dp_get_adjust_request_voltage(
458 adjust_request, lane); 467 adjust_request, lane);
459 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( 468 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
@@ -473,15 +482,19 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
473 lane); 482 lane);
474 } 483 }
475 484
476 exynos_dp_write_byte_to_dpcd(dp, 485 retval = exynos_dp_write_byte_to_dpcd(dp,
477 DPCD_ADDR_TRAINING_PATTERN_SET, 486 DPCD_ADDR_TRAINING_PATTERN_SET,
478 DPCD_SCRAMBLING_DISABLED | 487 DPCD_SCRAMBLING_DISABLED |
479 DPCD_TRAINING_PATTERN_2); 488 DPCD_TRAINING_PATTERN_2);
489 if (retval)
490 return retval;
480 491
481 exynos_dp_write_bytes_to_dpcd(dp, 492 retval = exynos_dp_write_bytes_to_dpcd(dp,
482 DPCD_ADDR_TRAINING_LANE0_SET, 493 DPCD_ADDR_TRAINING_LANE0_SET,
483 lane_count, 494 lane_count,
484 dp->link_train.training_lane); 495 dp->link_train.training_lane);
496 if (retval)
497 return retval;
485 498
486 dev_info(dp->dev, "Link Training Clock Recovery success\n"); 499 dev_info(dp->dev, "Link Training Clock Recovery success\n");
487 dp->link_train.lt_state = EQUALIZER_TRAINING; 500 dp->link_train.lt_state = EQUALIZER_TRAINING;
@@ -489,9 +502,12 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
489 for (lane = 0; lane < lane_count; lane++) { 502 for (lane = 0; lane < lane_count; lane++) {
490 training_lane = exynos_dp_get_lane_link_training( 503 training_lane = exynos_dp_get_lane_link_training(
491 dp, lane); 504 dp, lane);
492 exynos_dp_read_bytes_from_dpcd(dp, 505 retval = exynos_dp_read_bytes_from_dpcd(dp,
493 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 506 DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
494 2, adjust_request); 507 2, adjust_request);
508 if (retval)
509 return retval;
510
495 voltage_swing = exynos_dp_get_adjust_request_voltage( 511 voltage_swing = exynos_dp_get_adjust_request_voltage(
496 adjust_request, lane); 512 adjust_request, lane);
497 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( 513 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
@@ -528,13 +544,14 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
528 dp->link_train.training_lane[lane], lane); 544 dp->link_train.training_lane[lane], lane);
529 } 545 }
530 546
531 exynos_dp_write_bytes_to_dpcd(dp, 547 retval = exynos_dp_write_bytes_to_dpcd(dp,
532 DPCD_ADDR_TRAINING_LANE0_SET, 548 DPCD_ADDR_TRAINING_LANE0_SET, lane_count,
533 lane_count, 549 dp->link_train.training_lane);
534 dp->link_train.training_lane); 550 if (retval)
551 return retval;
535 } 552 }
536 553
537 return 0; 554 return retval;
538 555
539reduce_link_rate: 556reduce_link_rate:
540 exynos_dp_reduce_link_rate(dp); 557 exynos_dp_reduce_link_rate(dp);
@@ -545,8 +562,7 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
545{ 562{
546 u8 link_status[2]; 563 u8 link_status[2];
547 u8 link_align[3]; 564 u8 link_align[3];
548 int lane; 565 int lane, lane_count, retval;
549 int lane_count;
550 u32 reg; 566 u32 reg;
551 567
552 u8 adjust_request[2]; 568 u8 adjust_request[2];
@@ -558,8 +574,10 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
558 574
559 lane_count = dp->link_train.lane_count; 575 lane_count = dp->link_train.lane_count;
560 576
561 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, 577 retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
562 2, link_status); 578 2, link_status);
579 if (retval)
580 return retval;
563 581
564 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { 582 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
565 link_align[0] = link_status[0]; 583 link_align[0] = link_status[0];
@@ -570,9 +588,12 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
570 &link_align[2]); 588 &link_align[2]);
571 589
572 for (lane = 0; lane < lane_count; lane++) { 590 for (lane = 0; lane < lane_count; lane++) {
573 exynos_dp_read_bytes_from_dpcd(dp, 591 retval = exynos_dp_read_bytes_from_dpcd(dp,
574 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 592 DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
575 2, adjust_request); 593 2, adjust_request);
594 if (retval)
595 return retval;
596
576 voltage_swing = exynos_dp_get_adjust_request_voltage( 597 voltage_swing = exynos_dp_get_adjust_request_voltage(
577 adjust_request, lane); 598 adjust_request, lane);
578 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( 599 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
@@ -621,10 +642,12 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
621 dp->link_train.training_lane[lane], 642 dp->link_train.training_lane[lane],
622 lane); 643 lane);
623 644
624 exynos_dp_write_bytes_to_dpcd(dp, 645 retval = exynos_dp_write_bytes_to_dpcd(dp,
625 DPCD_ADDR_TRAINING_LANE0_SET, 646 DPCD_ADDR_TRAINING_LANE0_SET,
626 lane_count, 647 lane_count,
627 dp->link_train.training_lane); 648 dp->link_train.training_lane);
649 if (retval)
650 return retval;
628 } 651 }
629 } else { 652 } else {
630 goto reduce_link_rate; 653 goto reduce_link_rate;
@@ -702,16 +725,17 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
702 725
703static int exynos_dp_sw_link_training(struct exynos_dp_device *dp) 726static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
704{ 727{
705 int retval = 0; 728 int retval = 0, training_finished = 0;
706 int training_finished = 0;
707 729
708 dp->link_train.lt_state = START; 730 dp->link_train.lt_state = START;
709 731
710 /* Process here */ 732 /* Process here */
711 while (!training_finished) { 733 while (!retval && !training_finished) {
712 switch (dp->link_train.lt_state) { 734 switch (dp->link_train.lt_state) {
713 case START: 735 case START:
714 exynos_dp_link_start(dp); 736 retval = exynos_dp_link_start(dp);
737 if (retval)
738 dev_err(dp->dev, "LT link start failed!\n");
715 break; 739 break;
716 case CLOCK_RECOVERY: 740 case CLOCK_RECOVERY:
717 retval = exynos_dp_process_clock_recovery(dp); 741 retval = exynos_dp_process_clock_recovery(dp);
@@ -730,6 +754,8 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
730 return -EREMOTEIO; 754 return -EREMOTEIO;
731 } 755 }
732 } 756 }
757 if (retval)
758 dev_err(dp->dev, "eDP link training failed (%d)\n", retval);
733 759
734 return retval; 760 return retval;
735} 761}