aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-11-29 03:34:41 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-11-29 03:34:41 -0500
commit473af20f705b690342af1bfb36462c0c5190d289 (patch)
tree1f48932284bf30bb9d83bbedba8caa84aca51341 /drivers/video
parentfa1f94979883aeef231fa023e5b9be971d459952 (diff)
parent3fcb6eb4063ab4eef05601c266afa2af667c8e1f (diff)
Merge branch 'exynos-dp-next' of git://github.com/jingoo/linux into for-linus
Exynos DP changes for the 3.8 merge window. - Device Tree support for Samsung Exynos DP - SW Link training is cleaned up. - HPD interrupt is supported. * 'exynos-dp-next' of git://github.com/jingoo/linux: video: exynos_dp: remove redundant parameters video: exynos_dp: Fix incorrect setting for INT_CTL video: exynos_dp: Reset and initialize DP before requesting irq video: exynos_dp: Enable hotplug interrupts video: exynos_dp: Move hotplug into a workqueue video: exynos_dp: Remove sink control to D0 video: exynos_dp: Fix bug when checking dp->irq video: exynos_dp: Improve EDID error handling video: exynos_dp: Get pll lock before pattern set video: exynos_dp: Clean up SW link training video: exynos_dp: Check DPCD return codes video: exynos_dp: device tree documentation video: exynos_dp: Add device tree support to DP driver
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/exynos/exynos_dp_core.c697
-rw-r--r--drivers/video/exynos/exynos_dp_core.h21
-rw-r--r--drivers/video/exynos/exynos_dp_reg.c77
-rw-r--r--drivers/video/exynos/exynos_dp_reg.h3
4 files changed, 503 insertions, 295 deletions
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e75412..28fd686c6b81 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/of.h>
21 22
22#include <video/exynos_dp.h> 23#include <video/exynos_dp.h>
23 24
@@ -48,10 +49,6 @@ static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
48{ 49{
49 int timeout_loop = 0; 50 int timeout_loop = 0;
50 51
51 exynos_dp_init_hpd(dp);
52
53 usleep_range(200, 210);
54
55 while (exynos_dp_get_plug_in_status(dp) != 0) { 52 while (exynos_dp_get_plug_in_status(dp) != 0) {
56 timeout_loop++; 53 timeout_loop++;
57 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 54 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
@@ -90,9 +87,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
90 */ 87 */
91 88
92 /* Read Extension Flag, Number of 128-byte EDID extension blocks */ 89 /* Read Extension Flag, Number of 128-byte EDID extension blocks */
93 exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, 90 retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
94 EDID_EXTENSION_FLAG, 91 EDID_EXTENSION_FLAG,
95 &extend_block); 92 &extend_block);
93 if (retval)
94 return retval;
96 95
97 if (extend_block > 0) { 96 if (extend_block > 0) {
98 dev_dbg(dp->dev, "EDID data includes a single extension!\n"); 97 dev_dbg(dp->dev, "EDID data includes a single extension!\n");
@@ -181,14 +180,15 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
181 int retval; 180 int retval;
182 181
183 /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */ 182 /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */
184 exynos_dp_read_bytes_from_dpcd(dp, 183 retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV,
185 DPCD_ADDR_DPCD_REV, 184 12, buf);
186 12, buf); 185 if (retval)
186 return retval;
187 187
188 /* Read EDID */ 188 /* Read EDID */
189 for (i = 0; i < 3; i++) { 189 for (i = 0; i < 3; i++) {
190 retval = exynos_dp_read_edid(dp); 190 retval = exynos_dp_read_edid(dp);
191 if (retval == 0) 191 if (!retval)
192 break; 192 break;
193 } 193 }
194 194
@@ -261,11 +261,10 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
261 } 261 }
262} 262}
263 263
264static void exynos_dp_link_start(struct exynos_dp_device *dp) 264static int exynos_dp_link_start(struct exynos_dp_device *dp)
265{ 265{
266 u8 buf[4]; 266 u8 buf[4];
267 int lane; 267 int lane, lane_count, pll_tries, retval;
268 int lane_count;
269 268
270 lane_count = dp->link_train.lane_count; 269 lane_count = dp->link_train.lane_count;
271 270
@@ -275,10 +274,6 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
275 for (lane = 0; lane < lane_count; lane++) 274 for (lane = 0; lane < lane_count; lane++)
276 dp->link_train.cr_loop[lane] = 0; 275 dp->link_train.cr_loop[lane] = 0;
277 276
278 /* Set sink to D0 (Sink Not Ready) mode. */
279 exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
280 DPCD_SET_POWER_STATE_D0);
281
282 /* Set link rate and count as you want to establish*/ 277 /* Set link rate and count as you want to establish*/
283 exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate); 278 exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
284 exynos_dp_set_lane_count(dp, dp->link_train.lane_count); 279 exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
@@ -286,29 +281,46 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
286 /* Setup RX configuration */ 281 /* Setup RX configuration */
287 buf[0] = dp->link_train.link_rate; 282 buf[0] = dp->link_train.link_rate;
288 buf[1] = dp->link_train.lane_count; 283 buf[1] = dp->link_train.lane_count;
289 exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET, 284 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
290 2, buf); 285 2, buf);
286 if (retval)
287 return retval;
291 288
292 /* Set TX pre-emphasis to minimum */ 289 /* Set TX pre-emphasis to minimum */
293 for (lane = 0; lane < lane_count; lane++) 290 for (lane = 0; lane < lane_count; lane++)
294 exynos_dp_set_lane_lane_pre_emphasis(dp, 291 exynos_dp_set_lane_lane_pre_emphasis(dp,
295 PRE_EMPHASIS_LEVEL_0, lane); 292 PRE_EMPHASIS_LEVEL_0, lane);
296 293
294 /* Wait for PLL lock */
295 pll_tries = 0;
296 while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
297 if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
298 dev_err(dp->dev, "Wait for PLL lock timed out\n");
299 return -ETIMEDOUT;
300 }
301
302 pll_tries++;
303 usleep_range(90, 120);
304 }
305
297 /* Set training pattern 1 */ 306 /* Set training pattern 1 */
298 exynos_dp_set_training_pattern(dp, TRAINING_PTN1); 307 exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
299 308
300 /* Set RX training pattern */ 309 /* Set RX training pattern */
301 exynos_dp_write_byte_to_dpcd(dp, 310 retval = exynos_dp_write_byte_to_dpcd(dp,
302 DPCD_ADDR_TRAINING_PATTERN_SET, 311 DPCD_ADDR_TRAINING_PATTERN_SET,
303 DPCD_SCRAMBLING_DISABLED | 312 DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1);
304 DPCD_TRAINING_PATTERN_1); 313 if (retval)
314 return retval;
305 315
306 for (lane = 0; lane < lane_count; lane++) 316 for (lane = 0; lane < lane_count; lane++)
307 buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 | 317 buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
308 DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0; 318 DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
309 exynos_dp_write_bytes_to_dpcd(dp, 319
310 DPCD_ADDR_TRAINING_LANE0_SET, 320 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET,
311 lane_count, buf); 321 lane_count, buf);
322
323 return retval;
312} 324}
313 325
314static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane) 326static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
@@ -332,18 +344,17 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
332 return 0; 344 return 0;
333} 345}
334 346
335static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count) 347static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
348 int lane_count)
336{ 349{
337 int lane; 350 int lane;
338 u8 lane_align;
339 u8 lane_status; 351 u8 lane_status;
340 352
341 lane_align = link_align[2]; 353 if ((link_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
342 if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
343 return -EINVAL; 354 return -EINVAL;
344 355
345 for (lane = 0; lane < lane_count; lane++) { 356 for (lane = 0; lane < lane_count; lane++) {
346 lane_status = exynos_dp_get_lane_status(link_align, lane); 357 lane_status = exynos_dp_get_lane_status(link_status, lane);
347 lane_status &= DPCD_CHANNEL_EQ_BITS; 358 lane_status &= DPCD_CHANNEL_EQ_BITS;
348 if (lane_status != DPCD_CHANNEL_EQ_BITS) 359 if (lane_status != DPCD_CHANNEL_EQ_BITS)
349 return -EINVAL; 360 return -EINVAL;
@@ -427,60 +438,60 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
427 dp->link_train.lt_state = FAILED; 438 dp->link_train.lt_state = FAILED;
428} 439}
429 440
430static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp) 441static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
442 u8 adjust_request[2])
431{ 443{
432 u8 link_status[2]; 444 int lane, lane_count;
433 int lane; 445 u8 voltage_swing, pre_emphasis, training_lane;
434 int lane_count;
435 446
436 u8 adjust_request[2]; 447 lane_count = dp->link_train.lane_count;
437 u8 voltage_swing; 448 for (lane = 0; lane < lane_count; lane++) {
438 u8 pre_emphasis; 449 voltage_swing = exynos_dp_get_adjust_request_voltage(
439 u8 training_lane; 450 adjust_request, lane);
451 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
452 adjust_request, lane);
453 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
454 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
455
456 if (voltage_swing == VOLTAGE_LEVEL_3)
457 training_lane |= DPCD_MAX_SWING_REACHED;
458 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
459 training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
460
461 dp->link_train.training_lane[lane] = training_lane;
462 }
463}
464
465static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
466{
467 int lane, lane_count, retval;
468 u8 voltage_swing, pre_emphasis, training_lane;
469 u8 link_status[2], adjust_request[2];
440 470
441 usleep_range(100, 101); 471 usleep_range(100, 101);
442 472
443 lane_count = dp->link_train.lane_count; 473 lane_count = dp->link_train.lane_count;
444 474
445 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, 475 retval = exynos_dp_read_bytes_from_dpcd(dp,
446 2, link_status); 476 DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
477 if (retval)
478 return retval;
479
480 retval = exynos_dp_read_bytes_from_dpcd(dp,
481 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
482 if (retval)
483 return retval;
447 484
448 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { 485 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
449 /* set training pattern 2 for EQ */ 486 /* set training pattern 2 for EQ */
450 exynos_dp_set_training_pattern(dp, TRAINING_PTN2); 487 exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
451 488
452 for (lane = 0; lane < lane_count; lane++) { 489 retval = exynos_dp_write_byte_to_dpcd(dp,
453 exynos_dp_read_bytes_from_dpcd(dp, 490 DPCD_ADDR_TRAINING_PATTERN_SET,
454 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 491 DPCD_SCRAMBLING_DISABLED |
455 2, adjust_request); 492 DPCD_TRAINING_PATTERN_2);
456 voltage_swing = exynos_dp_get_adjust_request_voltage( 493 if (retval)
457 adjust_request, lane); 494 return retval;
458 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
459 adjust_request, lane);
460 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
461 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
462
463 if (voltage_swing == VOLTAGE_LEVEL_3)
464 training_lane |= DPCD_MAX_SWING_REACHED;
465 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
466 training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
467
468 dp->link_train.training_lane[lane] = training_lane;
469
470 exynos_dp_set_lane_link_training(dp,
471 dp->link_train.training_lane[lane],
472 lane);
473 }
474
475 exynos_dp_write_byte_to_dpcd(dp,
476 DPCD_ADDR_TRAINING_PATTERN_SET,
477 DPCD_SCRAMBLING_DISABLED |
478 DPCD_TRAINING_PATTERN_2);
479
480 exynos_dp_write_bytes_to_dpcd(dp,
481 DPCD_ADDR_TRAINING_LANE0_SET,
482 lane_count,
483 dp->link_train.training_lane);
484 495
485 dev_info(dp->dev, "Link Training Clock Recovery success\n"); 496 dev_info(dp->dev, "Link Training Clock Recovery success\n");
486 dp->link_train.lt_state = EQUALIZER_TRAINING; 497 dp->link_train.lt_state = EQUALIZER_TRAINING;
@@ -488,152 +499,116 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
488 for (lane = 0; lane < lane_count; lane++) { 499 for (lane = 0; lane < lane_count; lane++) {
489 training_lane = exynos_dp_get_lane_link_training( 500 training_lane = exynos_dp_get_lane_link_training(
490 dp, lane); 501 dp, lane);
491 exynos_dp_read_bytes_from_dpcd(dp,
492 DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
493 2, adjust_request);
494 voltage_swing = exynos_dp_get_adjust_request_voltage( 502 voltage_swing = exynos_dp_get_adjust_request_voltage(
495 adjust_request, lane); 503 adjust_request, lane);
496 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( 504 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
497 adjust_request, lane); 505 adjust_request, lane);
498 506
499 if (voltage_swing == VOLTAGE_LEVEL_3 || 507 if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
500 pre_emphasis == PRE_EMPHASIS_LEVEL_3) { 508 voltage_swing &&
501 dev_err(dp->dev, "voltage or pre emphasis reached max level\n"); 509 DPCD_PRE_EMPHASIS_GET(training_lane) ==
502 goto reduce_link_rate; 510 pre_emphasis)
503 }
504
505 if ((DPCD_VOLTAGE_SWING_GET(training_lane) ==
506 voltage_swing) &&
507 (DPCD_PRE_EMPHASIS_GET(training_lane) ==
508 pre_emphasis)) {
509 dp->link_train.cr_loop[lane]++; 511 dp->link_train.cr_loop[lane]++;
510 if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP) {
511 dev_err(dp->dev, "CR Max loop\n");
512 goto reduce_link_rate;
513 }
514 }
515
516 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
517 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
518 512
519 if (voltage_swing == VOLTAGE_LEVEL_3) 513 if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
520 training_lane |= DPCD_MAX_SWING_REACHED; 514 voltage_swing == VOLTAGE_LEVEL_3 ||
521 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) 515 pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
522 training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED; 516 dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
517 dp->link_train.cr_loop[lane],
518 voltage_swing, pre_emphasis);
519 exynos_dp_reduce_link_rate(dp);
520 return -EIO;
521 }
522 }
523 }
523 524
524 dp->link_train.training_lane[lane] = training_lane; 525 exynos_dp_get_adjust_training_lane(dp, adjust_request);
525 526
526 exynos_dp_set_lane_link_training(dp, 527 for (lane = 0; lane < lane_count; lane++)
527 dp->link_train.training_lane[lane], lane); 528 exynos_dp_set_lane_link_training(dp,
528 } 529 dp->link_train.training_lane[lane], lane);
529 530
530 exynos_dp_write_bytes_to_dpcd(dp, 531 retval = exynos_dp_write_bytes_to_dpcd(dp,
531 DPCD_ADDR_TRAINING_LANE0_SET, 532 DPCD_ADDR_TRAINING_LANE0_SET, lane_count,
532 lane_count,
533 dp->link_train.training_lane); 533 dp->link_train.training_lane);
534 } 534 if (retval)
535 535 return retval;
536 return 0;
537 536
538reduce_link_rate: 537 return retval;
539 exynos_dp_reduce_link_rate(dp);
540 return -EIO;
541} 538}
542 539
543static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp) 540static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
544{ 541{
545 u8 link_status[2]; 542 int lane, lane_count, retval;
546 u8 link_align[3];
547 int lane;
548 int lane_count;
549 u32 reg; 543 u32 reg;
550 544 u8 link_align, link_status[2], adjust_request[2];
551 u8 adjust_request[2];
552 u8 voltage_swing;
553 u8 pre_emphasis;
554 u8 training_lane;
555 545
556 usleep_range(400, 401); 546 usleep_range(400, 401);
557 547
558 lane_count = dp->link_train.lane_count; 548 lane_count = dp->link_train.lane_count;
559 549
560 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, 550 retval = exynos_dp_read_bytes_from_dpcd(dp,
561 2, link_status); 551 DPCD_ADDR_LANE0_1_STATUS, 2, link_status);
552 if (retval)
553 return retval;
562 554
563 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { 555 if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
564 link_align[0] = link_status[0]; 556 exynos_dp_reduce_link_rate(dp);
565 link_align[1] = link_status[1]; 557 return -EIO;
558 }
566 559
567 exynos_dp_read_byte_from_dpcd(dp, 560 retval = exynos_dp_read_bytes_from_dpcd(dp,
568 DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, 561 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
569 &link_align[2]); 562 if (retval)
563 return retval;
570 564
571 for (lane = 0; lane < lane_count; lane++) { 565 retval = exynos_dp_read_byte_from_dpcd(dp,
572 exynos_dp_read_bytes_from_dpcd(dp, 566 DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &link_align);
573 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 567 if (retval)
574 2, adjust_request); 568 return retval;
575 voltage_swing = exynos_dp_get_adjust_request_voltage(
576 adjust_request, lane);
577 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
578 adjust_request, lane);
579 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
580 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
581 569
582 if (voltage_swing == VOLTAGE_LEVEL_3) 570 exynos_dp_get_adjust_training_lane(dp, adjust_request);
583 training_lane |= DPCD_MAX_SWING_REACHED;
584 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
585 training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
586 571
587 dp->link_train.training_lane[lane] = training_lane; 572 if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) {
588 } 573 /* traing pattern Set to Normal */
574 exynos_dp_training_pattern_dis(dp);
589 575
590 if (exynos_dp_channel_eq_ok(link_align, lane_count) == 0) { 576 dev_info(dp->dev, "Link Training success!\n");
591 /* traing pattern Set to Normal */
592 exynos_dp_training_pattern_dis(dp);
593 577
594 dev_info(dp->dev, "Link Training success!\n"); 578 exynos_dp_get_link_bandwidth(dp, &reg);
595 579 dp->link_train.link_rate = reg;
596 exynos_dp_get_link_bandwidth(dp, &reg); 580 dev_dbg(dp->dev, "final bandwidth = %.2x\n",
597 dp->link_train.link_rate = reg; 581 dp->link_train.link_rate);
598 dev_dbg(dp->dev, "final bandwidth = %.2x\n",
599 dp->link_train.link_rate);
600 582
601 exynos_dp_get_lane_count(dp, &reg); 583 exynos_dp_get_lane_count(dp, &reg);
602 dp->link_train.lane_count = reg; 584 dp->link_train.lane_count = reg;
603 dev_dbg(dp->dev, "final lane count = %.2x\n", 585 dev_dbg(dp->dev, "final lane count = %.2x\n",
604 dp->link_train.lane_count); 586 dp->link_train.lane_count);
605 587
606 /* set enhanced mode if available */ 588 /* set enhanced mode if available */
607 exynos_dp_set_enhanced_mode(dp); 589 exynos_dp_set_enhanced_mode(dp);
608 dp->link_train.lt_state = FINISHED; 590 dp->link_train.lt_state = FINISHED;
609 } else {
610 /* not all locked */
611 dp->link_train.eq_loop++;
612 591
613 if (dp->link_train.eq_loop > MAX_EQ_LOOP) { 592 return 0;
614 dev_err(dp->dev, "EQ Max loop\n"); 593 }
615 goto reduce_link_rate;
616 }
617 594
618 for (lane = 0; lane < lane_count; lane++) 595 /* not all locked */
619 exynos_dp_set_lane_link_training(dp, 596 dp->link_train.eq_loop++;
620 dp->link_train.training_lane[lane],
621 lane);
622 597
623 exynos_dp_write_bytes_to_dpcd(dp, 598 if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
624 DPCD_ADDR_TRAINING_LANE0_SET, 599 dev_err(dp->dev, "EQ Max loop\n");
625 lane_count, 600 exynos_dp_reduce_link_rate(dp);
626 dp->link_train.training_lane); 601 return -EIO;
627 }
628 } else {
629 goto reduce_link_rate;
630 } 602 }
631 603
632 return 0; 604 for (lane = 0; lane < lane_count; lane++)
605 exynos_dp_set_lane_link_training(dp,
606 dp->link_train.training_lane[lane], lane);
607
608 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET,
609 lane_count, dp->link_train.training_lane);
633 610
634reduce_link_rate: 611 return retval;
635 exynos_dp_reduce_link_rate(dp);
636 return -EIO;
637} 612}
638 613
639static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp, 614static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
@@ -701,16 +676,17 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
701 676
702static int exynos_dp_sw_link_training(struct exynos_dp_device *dp) 677static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
703{ 678{
704 int retval = 0; 679 int retval = 0, training_finished = 0;
705 int training_finished = 0;
706 680
707 dp->link_train.lt_state = START; 681 dp->link_train.lt_state = START;
708 682
709 /* Process here */ 683 /* Process here */
710 while (!training_finished) { 684 while (!retval && !training_finished) {
711 switch (dp->link_train.lt_state) { 685 switch (dp->link_train.lt_state) {
712 case START: 686 case START:
713 exynos_dp_link_start(dp); 687 retval = exynos_dp_link_start(dp);
688 if (retval)
689 dev_err(dp->dev, "LT link start failed!\n");
714 break; 690 break;
715 case CLOCK_RECOVERY: 691 case CLOCK_RECOVERY:
716 retval = exynos_dp_process_clock_recovery(dp); 692 retval = exynos_dp_process_clock_recovery(dp);
@@ -729,6 +705,8 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
729 return -EREMOTEIO; 705 return -EREMOTEIO;
730 } 706 }
731 } 707 }
708 if (retval)
709 dev_err(dp->dev, "eDP link training failed (%d)\n", retval);
732 710
733 return retval; 711 return retval;
734} 712}
@@ -752,19 +730,15 @@ static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
752 return retval; 730 return retval;
753} 731}
754 732
755static int exynos_dp_config_video(struct exynos_dp_device *dp, 733static int exynos_dp_config_video(struct exynos_dp_device *dp)
756 struct video_info *video_info)
757{ 734{
758 int retval = 0; 735 int retval = 0;
759 int timeout_loop = 0; 736 int timeout_loop = 0;
760 int done_count = 0; 737 int done_count = 0;
761 738
762 exynos_dp_config_video_slave_mode(dp, video_info); 739 exynos_dp_config_video_slave_mode(dp);
763 740
764 exynos_dp_set_video_color_format(dp, video_info->color_depth, 741 exynos_dp_set_video_color_format(dp);
765 video_info->color_space,
766 video_info->dynamic_range,
767 video_info->ycbcr_coeff);
768 742
769 if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 743 if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
770 dev_err(dp->dev, "PLL is not locked yet.\n"); 744 dev_err(dp->dev, "PLL is not locked yet.\n");
@@ -852,10 +826,213 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
852{ 826{
853 struct exynos_dp_device *dp = arg; 827 struct exynos_dp_device *dp = arg;
854 828
855 dev_err(dp->dev, "exynos_dp_irq_handler\n"); 829 enum dp_irq_type irq_type;
830
831 irq_type = exynos_dp_get_irq_type(dp);
832 switch (irq_type) {
833 case DP_IRQ_TYPE_HP_CABLE_IN:
834 dev_dbg(dp->dev, "Received irq - cable in\n");
835 schedule_work(&dp->hotplug_work);
836 exynos_dp_clear_hotplug_interrupts(dp);
837 break;
838 case DP_IRQ_TYPE_HP_CABLE_OUT:
839 dev_dbg(dp->dev, "Received irq - cable out\n");
840 exynos_dp_clear_hotplug_interrupts(dp);
841 break;
842 case DP_IRQ_TYPE_HP_CHANGE:
843 /*
844 * We get these change notifications once in a while, but there
845 * is nothing we can do with them. Just ignore it for now and
846 * only handle cable changes.
847 */
848 dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n");
849 exynos_dp_clear_hotplug_interrupts(dp);
850 break;
851 default:
852 dev_err(dp->dev, "Received irq - unknown type!\n");
853 break;
854 }
856 return IRQ_HANDLED; 855 return IRQ_HANDLED;
857} 856}
858 857
858static void exynos_dp_hotplug(struct work_struct *work)
859{
860 struct exynos_dp_device *dp;
861 int ret;
862
863 dp = container_of(work, struct exynos_dp_device, hotplug_work);
864
865 ret = exynos_dp_detect_hpd(dp);
866 if (ret) {
867 /* Cable has been disconnected, we're done */
868 return;
869 }
870
871 ret = exynos_dp_handle_edid(dp);
872 if (ret) {
873 dev_err(dp->dev, "unable to handle edid\n");
874 return;
875 }
876
877 ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
878 dp->video_info->link_rate);
879 if (ret) {
880 dev_err(dp->dev, "unable to do link train\n");
881 return;
882 }
883
884 exynos_dp_enable_scramble(dp, 1);
885 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
886 exynos_dp_enable_enhanced_mode(dp, 1);
887
888 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
889 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
890
891 exynos_dp_init_video(dp);
892 ret = exynos_dp_config_video(dp);
893 if (ret)
894 dev_err(dp->dev, "unable to config video\n");
895}
896
897#ifdef CONFIG_OF
898static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
899{
900 struct device_node *dp_node = dev->of_node;
901 struct exynos_dp_platdata *pd;
902 struct video_info *dp_video_config;
903
904 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
905 if (!pd) {
906 dev_err(dev, "memory allocation for pdata failed\n");
907 return ERR_PTR(-ENOMEM);
908 }
909 dp_video_config = devm_kzalloc(dev,
910 sizeof(*dp_video_config), GFP_KERNEL);
911
912 if (!dp_video_config) {
913 dev_err(dev, "memory allocation for video config failed\n");
914 return ERR_PTR(-ENOMEM);
915 }
916 pd->video_info = dp_video_config;
917
918 dp_video_config->h_sync_polarity =
919 of_property_read_bool(dp_node, "hsync-active-high");
920
921 dp_video_config->v_sync_polarity =
922 of_property_read_bool(dp_node, "vsync-active-high");
923
924 dp_video_config->interlaced =
925 of_property_read_bool(dp_node, "interlaced");
926
927 if (of_property_read_u32(dp_node, "samsung,color-space",
928 &dp_video_config->color_space)) {
929 dev_err(dev, "failed to get color-space\n");
930 return ERR_PTR(-EINVAL);
931 }
932
933 if (of_property_read_u32(dp_node, "samsung,dynamic-range",
934 &dp_video_config->dynamic_range)) {
935 dev_err(dev, "failed to get dynamic-range\n");
936 return ERR_PTR(-EINVAL);
937 }
938
939 if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
940 &dp_video_config->ycbcr_coeff)) {
941 dev_err(dev, "failed to get ycbcr-coeff\n");
942 return ERR_PTR(-EINVAL);
943 }
944
945 if (of_property_read_u32(dp_node, "samsung,color-depth",
946 &dp_video_config->color_depth)) {
947 dev_err(dev, "failed to get color-depth\n");
948 return ERR_PTR(-EINVAL);
949 }
950
951 if (of_property_read_u32(dp_node, "samsung,link-rate",
952 &dp_video_config->link_rate)) {
953 dev_err(dev, "failed to get link-rate\n");
954 return ERR_PTR(-EINVAL);
955 }
956
957 if (of_property_read_u32(dp_node, "samsung,lane-count",
958 &dp_video_config->lane_count)) {
959 dev_err(dev, "failed to get lane-count\n");
960 return ERR_PTR(-EINVAL);
961 }
962
963 return pd;
964}
965
966static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
967{
968 struct device_node *dp_phy_node;
969 u32 phy_base;
970
971 dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
972 if (!dp_phy_node) {
973 dev_err(dp->dev, "could not find dptx-phy node\n");
974 return -ENODEV;
975 }
976
977 if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
978 dev_err(dp->dev, "faild to get reg for dptx-phy\n");
979 return -EINVAL;
980 }
981
982 if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
983 &dp->enable_mask)) {
984 dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
985 return -EINVAL;
986 }
987
988 dp->phy_addr = ioremap(phy_base, SZ_4);
989 if (!dp->phy_addr) {
990 dev_err(dp->dev, "failed to ioremap dp-phy\n");
991 return -ENOMEM;
992 }
993
994 return 0;
995}
996
997static void exynos_dp_phy_init(struct exynos_dp_device *dp)
998{
999 u32 reg;
1000
1001 reg = __raw_readl(dp->phy_addr);
1002 reg |= dp->enable_mask;
1003 __raw_writel(reg, dp->phy_addr);
1004}
1005
1006static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
1007{
1008 u32 reg;
1009
1010 reg = __raw_readl(dp->phy_addr);
1011 reg &= ~(dp->enable_mask);
1012 __raw_writel(reg, dp->phy_addr);
1013}
1014#else
1015static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
1016{
1017 return NULL;
1018}
1019
1020static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
1021{
1022 return -EINVAL;
1023}
1024
1025static void exynos_dp_phy_init(struct exynos_dp_device *dp)
1026{
1027 return;
1028}
1029
1030static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
1031{
1032 return;
1033}
1034#endif /* CONFIG_OF */
1035
859static int __devinit exynos_dp_probe(struct platform_device *pdev) 1036static int __devinit exynos_dp_probe(struct platform_device *pdev)
860{ 1037{
861 struct resource *res; 1038 struct resource *res;
@@ -864,12 +1041,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
864 1041
865 int ret = 0; 1042 int ret = 0;
866 1043
867 pdata = pdev->dev.platform_data;
868 if (!pdata) {
869 dev_err(&pdev->dev, "no platform data\n");
870 return -EINVAL;
871 }
872
873 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), 1044 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
874 GFP_KERNEL); 1045 GFP_KERNEL);
875 if (!dp) { 1046 if (!dp) {
@@ -879,6 +1050,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
879 1050
880 dp->dev = &pdev->dev; 1051 dp->dev = &pdev->dev;
881 1052
1053 if (pdev->dev.of_node) {
1054 pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
1055 if (IS_ERR(pdata))
1056 return PTR_ERR(pdata);
1057
1058 ret = exynos_dp_dt_parse_phydata(dp);
1059 if (ret)
1060 return ret;
1061 } else {
1062 pdata = pdev->dev.platform_data;
1063 if (!pdata) {
1064 dev_err(&pdev->dev, "no platform data\n");
1065 return -EINVAL;
1066 }
1067 }
1068
882 dp->clock = devm_clk_get(&pdev->dev, "dp"); 1069 dp->clock = devm_clk_get(&pdev->dev, "dp");
883 if (IS_ERR(dp->clock)) { 1070 if (IS_ERR(dp->clock)) {
884 dev_err(&pdev->dev, "failed to get clock\n"); 1071 dev_err(&pdev->dev, "failed to get clock\n");
@@ -896,50 +1083,29 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
896 } 1083 }
897 1084
898 dp->irq = platform_get_irq(pdev, 0); 1085 dp->irq = platform_get_irq(pdev, 0);
899 if (!dp->irq) { 1086 if (dp->irq == -ENXIO) {
900 dev_err(&pdev->dev, "failed to get irq\n"); 1087 dev_err(&pdev->dev, "failed to get irq\n");
901 return -ENODEV; 1088 return -ENODEV;
902 } 1089 }
903 1090
904 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0, 1091 INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
905 "exynos-dp", dp);
906 if (ret) {
907 dev_err(&pdev->dev, "failed to request irq\n");
908 return ret;
909 }
910 1092
911 dp->video_info = pdata->video_info; 1093 dp->video_info = pdata->video_info;
912 if (pdata->phy_init)
913 pdata->phy_init();
914
915 exynos_dp_init_dp(dp);
916
917 ret = exynos_dp_detect_hpd(dp);
918 if (ret) {
919 dev_err(&pdev->dev, "unable to detect hpd\n");
920 return ret;
921 }
922 1094
923 exynos_dp_handle_edid(dp); 1095 if (pdev->dev.of_node) {
924 1096 if (dp->phy_addr)
925 ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count, 1097 exynos_dp_phy_init(dp);
926 dp->video_info->link_rate); 1098 } else {
927 if (ret) { 1099 if (pdata->phy_init)
928 dev_err(&pdev->dev, "unable to do link train\n"); 1100 pdata->phy_init();
929 return ret;
930 } 1101 }
931 1102
932 exynos_dp_enable_scramble(dp, 1); 1103 exynos_dp_init_dp(dp);
933 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
934 exynos_dp_enable_enhanced_mode(dp, 1);
935
936 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
937 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
938 1104
939 exynos_dp_init_video(dp); 1105 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
940 ret = exynos_dp_config_video(dp, dp->video_info); 1106 "exynos-dp", dp);
941 if (ret) { 1107 if (ret) {
942 dev_err(&pdev->dev, "unable to config video\n"); 1108 dev_err(&pdev->dev, "failed to request irq\n");
943 return ret; 1109 return ret;
944 } 1110 }
945 1111
@@ -953,23 +1119,41 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
953 struct exynos_dp_platdata *pdata = pdev->dev.platform_data; 1119 struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
954 struct exynos_dp_device *dp = platform_get_drvdata(pdev); 1120 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
955 1121
956 if (pdata && pdata->phy_exit) 1122 disable_irq(dp->irq);
957 pdata->phy_exit(); 1123
1124 if (work_pending(&dp->hotplug_work))
1125 flush_work(&dp->hotplug_work);
1126
1127 if (pdev->dev.of_node) {
1128 if (dp->phy_addr)
1129 exynos_dp_phy_exit(dp);
1130 } else {
1131 if (pdata->phy_exit)
1132 pdata->phy_exit();
1133 }
958 1134
959 clk_disable_unprepare(dp->clock); 1135 clk_disable_unprepare(dp->clock);
960 1136
1137
961 return 0; 1138 return 0;
962} 1139}
963 1140
964#ifdef CONFIG_PM_SLEEP 1141#ifdef CONFIG_PM_SLEEP
965static int exynos_dp_suspend(struct device *dev) 1142static int exynos_dp_suspend(struct device *dev)
966{ 1143{
967 struct platform_device *pdev = to_platform_device(dev); 1144 struct exynos_dp_platdata *pdata = dev->platform_data;
968 struct exynos_dp_platdata *pdata = pdev->dev.platform_data; 1145 struct exynos_dp_device *dp = dev_get_drvdata(dev);
969 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
970 1146
971 if (pdata && pdata->phy_exit) 1147 if (work_pending(&dp->hotplug_work))
972 pdata->phy_exit(); 1148 flush_work(&dp->hotplug_work);
1149
1150 if (dev->of_node) {
1151 if (dp->phy_addr)
1152 exynos_dp_phy_exit(dp);
1153 } else {
1154 if (pdata->phy_exit)
1155 pdata->phy_exit();
1156 }
973 1157
974 clk_disable_unprepare(dp->clock); 1158 clk_disable_unprepare(dp->clock);
975 1159
@@ -978,32 +1162,22 @@ static int exynos_dp_suspend(struct device *dev)
978 1162
979static int exynos_dp_resume(struct device *dev) 1163static int exynos_dp_resume(struct device *dev)
980{ 1164{
981 struct platform_device *pdev = to_platform_device(dev); 1165 struct exynos_dp_platdata *pdata = dev->platform_data;
982 struct exynos_dp_platdata *pdata = pdev->dev.platform_data; 1166 struct exynos_dp_device *dp = dev_get_drvdata(dev);
983 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
984 1167
985 if (pdata && pdata->phy_init) 1168 if (dev->of_node) {
986 pdata->phy_init(); 1169 if (dp->phy_addr)
1170 exynos_dp_phy_init(dp);
1171 } else {
1172 if (pdata->phy_init)
1173 pdata->phy_init();
1174 }
987 1175
988 clk_prepare_enable(dp->clock); 1176 clk_prepare_enable(dp->clock);
989 1177
990 exynos_dp_init_dp(dp); 1178 exynos_dp_init_dp(dp);
991 1179
992 exynos_dp_detect_hpd(dp); 1180 enable_irq(dp->irq);
993 exynos_dp_handle_edid(dp);
994
995 exynos_dp_set_link_train(dp, dp->video_info->lane_count,
996 dp->video_info->link_rate);
997
998 exynos_dp_enable_scramble(dp, 1);
999 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
1000 exynos_dp_enable_enhanced_mode(dp, 1);
1001
1002 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
1003 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
1004
1005 exynos_dp_init_video(dp);
1006 exynos_dp_config_video(dp, dp->video_info);
1007 1181
1008 return 0; 1182 return 0;
1009} 1183}
@@ -1013,6 +1187,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
1013 SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume) 1187 SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
1014}; 1188};
1015 1189
1190static const struct of_device_id exynos_dp_match[] = {
1191 { .compatible = "samsung,exynos5-dp" },
1192 {},
1193};
1194MODULE_DEVICE_TABLE(of, exynos_dp_match);
1195
1016static struct platform_driver exynos_dp_driver = { 1196static struct platform_driver exynos_dp_driver = {
1017 .probe = exynos_dp_probe, 1197 .probe = exynos_dp_probe,
1018 .remove = __devexit_p(exynos_dp_remove), 1198 .remove = __devexit_p(exynos_dp_remove),
@@ -1020,6 +1200,7 @@ static struct platform_driver exynos_dp_driver = {
1020 .name = "exynos-dp", 1200 .name = "exynos-dp",
1021 .owner = THIS_MODULE, 1201 .owner = THIS_MODULE,
1022 .pm = &exynos_dp_pm_ops, 1202 .pm = &exynos_dp_pm_ops,
1203 .of_match_table = of_match_ptr(exynos_dp_match),
1023 }, 1204 },
1024}; 1205};
1025 1206
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a6531c0e..6c567bbf2fb8 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -13,6 +13,13 @@
13#ifndef _EXYNOS_DP_CORE_H 13#ifndef _EXYNOS_DP_CORE_H
14#define _EXYNOS_DP_CORE_H 14#define _EXYNOS_DP_CORE_H
15 15
16enum dp_irq_type {
17 DP_IRQ_TYPE_HP_CABLE_IN,
18 DP_IRQ_TYPE_HP_CABLE_OUT,
19 DP_IRQ_TYPE_HP_CHANGE,
20 DP_IRQ_TYPE_UNKNOWN,
21};
22
16struct link_train { 23struct link_train {
17 int eq_loop; 24 int eq_loop;
18 int cr_loop[4]; 25 int cr_loop[4];
@@ -29,9 +36,12 @@ struct exynos_dp_device {
29 struct clk *clock; 36 struct clk *clock;
30 unsigned int irq; 37 unsigned int irq;
31 void __iomem *reg_base; 38 void __iomem *reg_base;
39 void __iomem *phy_addr;
40 unsigned int enable_mask;
32 41
33 struct video_info *video_info; 42 struct video_info *video_info;
34 struct link_train link_train; 43 struct link_train link_train;
44 struct work_struct hotplug_work;
35}; 45};
36 46
37/* exynos_dp_reg.c */ 47/* exynos_dp_reg.c */
@@ -50,6 +60,8 @@ void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
50 bool enable); 60 bool enable);
51void exynos_dp_init_analog_func(struct exynos_dp_device *dp); 61void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
52void exynos_dp_init_hpd(struct exynos_dp_device *dp); 62void exynos_dp_init_hpd(struct exynos_dp_device *dp);
63enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
64void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp);
53void exynos_dp_reset_aux(struct exynos_dp_device *dp); 65void exynos_dp_reset_aux(struct exynos_dp_device *dp);
54void exynos_dp_init_aux(struct exynos_dp_device *dp); 66void exynos_dp_init_aux(struct exynos_dp_device *dp);
55int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp); 67int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
@@ -107,11 +119,7 @@ u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
107void exynos_dp_reset_macro(struct exynos_dp_device *dp); 119void exynos_dp_reset_macro(struct exynos_dp_device *dp);
108void exynos_dp_init_video(struct exynos_dp_device *dp); 120void exynos_dp_init_video(struct exynos_dp_device *dp);
109 121
110void exynos_dp_set_video_color_format(struct exynos_dp_device *dp, 122void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
111 u32 color_depth,
112 u32 color_space,
113 u32 dynamic_range,
114 u32 ycbcr_coeff);
115int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp); 123int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
116void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, 124void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
117 enum clock_recovery_m_value_type type, 125 enum clock_recovery_m_value_type type,
@@ -121,8 +129,7 @@ void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
121void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable); 129void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
122void exynos_dp_start_video(struct exynos_dp_device *dp); 130void exynos_dp_start_video(struct exynos_dp_device *dp);
123int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp); 131int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp);
124void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp, 132void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp);
125 struct video_info *video_info);
126void exynos_dp_enable_scrambling(struct exynos_dp_device *dp); 133void exynos_dp_enable_scrambling(struct exynos_dp_device *dp);
127void exynos_dp_disable_scrambling(struct exynos_dp_device *dp); 134void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
128 135
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 3f5ca8a0d5ea..29d9d035c73a 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -19,11 +19,11 @@
19#include "exynos_dp_core.h" 19#include "exynos_dp_core.h"
20#include "exynos_dp_reg.h" 20#include "exynos_dp_reg.h"
21 21
22#define COMMON_INT_MASK_1 (0) 22#define COMMON_INT_MASK_1 0
23#define COMMON_INT_MASK_2 (0) 23#define COMMON_INT_MASK_2 0
24#define COMMON_INT_MASK_3 (0) 24#define COMMON_INT_MASK_3 0
25#define COMMON_INT_MASK_4 (0) 25#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
26#define INT_STA_MASK (0) 26#define INT_STA_MASK INT_HPD
27 27
28void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable) 28void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
29{ 29{
@@ -88,7 +88,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
88void exynos_dp_init_interrupt(struct exynos_dp_device *dp) 88void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
89{ 89{
90 /* Set interrupt pin assertion polarity as high */ 90 /* Set interrupt pin assertion polarity as high */
91 writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL); 91 writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
92 92
93 /* Clear pending regisers */ 93 /* Clear pending regisers */
94 writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 94 writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
@@ -324,7 +324,7 @@ void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
324 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 324 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
325} 325}
326 326
327void exynos_dp_init_hpd(struct exynos_dp_device *dp) 327void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
328{ 328{
329 u32 reg; 329 u32 reg;
330 330
@@ -333,12 +333,38 @@ void exynos_dp_init_hpd(struct exynos_dp_device *dp)
333 333
334 reg = INT_HPD; 334 reg = INT_HPD;
335 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); 335 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
336}
337
338void exynos_dp_init_hpd(struct exynos_dp_device *dp)
339{
340 u32 reg;
341
342 exynos_dp_clear_hotplug_interrupts(dp);
336 343
337 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 344 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
338 reg &= ~(F_HPD | HPD_CTRL); 345 reg &= ~(F_HPD | HPD_CTRL);
339 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 346 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
340} 347}
341 348
349enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
350{
351 u32 reg;
352
353 /* Parse hotplug interrupt status register */
354 reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
355
356 if (reg & PLUG)
357 return DP_IRQ_TYPE_HP_CABLE_IN;
358
359 if (reg & HPD_LOST)
360 return DP_IRQ_TYPE_HP_CABLE_OUT;
361
362 if (reg & HOTPLUG_CHG)
363 return DP_IRQ_TYPE_HP_CHANGE;
364
365 return DP_IRQ_TYPE_UNKNOWN;
366}
367
342void exynos_dp_reset_aux(struct exynos_dp_device *dp) 368void exynos_dp_reset_aux(struct exynos_dp_device *dp)
343{ 369{
344 u32 reg; 370 u32 reg;
@@ -491,7 +517,7 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
491 int i; 517 int i;
492 int retval; 518 int retval;
493 519
494 for (i = 0; i < 10; i++) { 520 for (i = 0; i < 3; i++) {
495 /* Clear AUX CH data buffer */ 521 /* Clear AUX CH data buffer */
496 reg = BUF_CLR; 522 reg = BUF_CLR;
497 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 523 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
@@ -552,7 +578,7 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
552 else 578 else
553 cur_data_count = count - start_offset; 579 cur_data_count = count - start_offset;
554 580
555 for (i = 0; i < 10; i++) { 581 for (i = 0; i < 3; i++) {
556 /* Select DPCD device address */ 582 /* Select DPCD device address */
557 reg = AUX_ADDR_7_0(reg_addr + start_offset); 583 reg = AUX_ADDR_7_0(reg_addr + start_offset);
558 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 584 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
@@ -617,7 +643,7 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
617 cur_data_count = count - start_offset; 643 cur_data_count = count - start_offset;
618 644
619 /* AUX CH Request Transaction process */ 645 /* AUX CH Request Transaction process */
620 for (i = 0; i < 10; i++) { 646 for (i = 0; i < 3; i++) {
621 /* Select DPCD device address */ 647 /* Select DPCD device address */
622 reg = AUX_ADDR_7_0(reg_addr + start_offset); 648 reg = AUX_ADDR_7_0(reg_addr + start_offset);
623 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 649 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
@@ -700,17 +726,15 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
700 int i; 726 int i;
701 int retval; 727 int retval;
702 728
703 for (i = 0; i < 10; i++) { 729 for (i = 0; i < 3; i++) {
704 /* Clear AUX CH data buffer */ 730 /* Clear AUX CH data buffer */
705 reg = BUF_CLR; 731 reg = BUF_CLR;
706 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 732 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
707 733
708 /* Select EDID device */ 734 /* Select EDID device */
709 retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); 735 retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
710 if (retval != 0) { 736 if (retval != 0)
711 dev_err(dp->dev, "Select EDID device fail!\n");
712 continue; 737 continue;
713 }
714 738
715 /* 739 /*
716 * Set I2C transaction and read data 740 * Set I2C transaction and read data
@@ -750,7 +774,7 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
750 int retval = 0; 774 int retval = 0;
751 775
752 for (i = 0; i < count; i += 16) { 776 for (i = 0; i < count; i += 16) {
753 for (j = 0; j < 100; j++) { 777 for (j = 0; j < 3; j++) {
754 /* Clear AUX CH data buffer */ 778 /* Clear AUX CH data buffer */
755 reg = BUF_CLR; 779 reg = BUF_CLR;
756 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 780 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
@@ -1034,24 +1058,20 @@ void exynos_dp_init_video(struct exynos_dp_device *dp)
1034 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); 1058 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
1035} 1059}
1036 1060
1037void exynos_dp_set_video_color_format(struct exynos_dp_device *dp, 1061void exynos_dp_set_video_color_format(struct exynos_dp_device *dp)
1038 u32 color_depth,
1039 u32 color_space,
1040 u32 dynamic_range,
1041 u32 ycbcr_coeff)
1042{ 1062{
1043 u32 reg; 1063 u32 reg;
1044 1064
1045 /* Configure the input color depth, color space, dynamic range */ 1065 /* Configure the input color depth, color space, dynamic range */
1046 reg = (dynamic_range << IN_D_RANGE_SHIFT) | 1066 reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
1047 (color_depth << IN_BPC_SHIFT) | 1067 (dp->video_info->color_depth << IN_BPC_SHIFT) |
1048 (color_space << IN_COLOR_F_SHIFT); 1068 (dp->video_info->color_space << IN_COLOR_F_SHIFT);
1049 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2); 1069 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
1050 1070
1051 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ 1071 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
1052 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); 1072 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
1053 reg &= ~IN_YC_COEFFI_MASK; 1073 reg &= ~IN_YC_COEFFI_MASK;
1054 if (ycbcr_coeff) 1074 if (dp->video_info->ycbcr_coeff)
1055 reg |= IN_YC_COEFFI_ITU709; 1075 reg |= IN_YC_COEFFI_ITU709;
1056 else 1076 else
1057 reg |= IN_YC_COEFFI_ITU601; 1077 reg |= IN_YC_COEFFI_ITU601;
@@ -1178,8 +1198,7 @@ int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
1178 return 0; 1198 return 0;
1179} 1199}
1180 1200
1181void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp, 1201void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
1182 struct video_info *video_info)
1183{ 1202{
1184 u32 reg; 1203 u32 reg;
1185 1204
@@ -1190,17 +1209,17 @@ void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
1190 1209
1191 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1210 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1192 reg &= ~INTERACE_SCAN_CFG; 1211 reg &= ~INTERACE_SCAN_CFG;
1193 reg |= (video_info->interlaced << 2); 1212 reg |= (dp->video_info->interlaced << 2);
1194 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1213 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1195 1214
1196 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1215 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1197 reg &= ~VSYNC_POLARITY_CFG; 1216 reg &= ~VSYNC_POLARITY_CFG;
1198 reg |= (video_info->v_sync_polarity << 1); 1217 reg |= (dp->video_info->v_sync_polarity << 1);
1199 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1218 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1200 1219
1201 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1220 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1202 reg &= ~HSYNC_POLARITY_CFG; 1221 reg &= ~HSYNC_POLARITY_CFG;
1203 reg |= (video_info->h_sync_polarity << 0); 1222 reg |= (dp->video_info->h_sync_polarity << 0);
1204 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1223 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1205 1224
1206 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; 1225 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 1f2f014cfe88..2e9bd0e0b9f2 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -242,7 +242,8 @@
242 242
243/* EXYNOS_DP_INT_CTL */ 243/* EXYNOS_DP_INT_CTL */
244#define SOFT_INT_CTRL (0x1 << 2) 244#define SOFT_INT_CTRL (0x1 << 2)
245#define INT_POL (0x1 << 0) 245#define INT_POL1 (0x1 << 1)
246#define INT_POL0 (0x1 << 0)
246 247
247/* EXYNOS_DP_SYS_CTL_1 */ 248/* EXYNOS_DP_SYS_CTL_1 */
248#define DET_STA (0x1 << 2) 249#define DET_STA (0x1 << 2)