2 * Copyright (C) 2012 Samsung Electronics
4 * Author: Donghwa Lee <dh09.lee@samsung.com>
6 * SPDX-License-Identifier: GPL-2.0+
12 #include <linux/err.h>
13 #include <asm/arch/clk.h>
14 #include <asm/arch/cpu.h>
15 #include <asm/arch/dp_info.h>
16 #include <asm/arch/dp.h>
20 #include "exynos_dp_lowlevel.h"
22 DECLARE_GLOBAL_DATA_PTR
;
24 static struct exynos_dp_platform_data
*dp_pd
;
26 void __exynos_set_dp_phy(unsigned int onoff
)
29 void exynos_set_dp_phy(unsigned int onoff
)
30 __attribute__((weak
, alias("__exynos_set_dp_phy")));
32 static void exynos_dp_disp_info(struct edp_disp_info
*disp_info
)
34 disp_info
->h_total
= disp_info
->h_res
+ disp_info
->h_sync_width
+
35 disp_info
->h_back_porch
+ disp_info
->h_front_porch
;
36 disp_info
->v_total
= disp_info
->v_res
+ disp_info
->v_sync_width
+
37 disp_info
->v_back_porch
+ disp_info
->v_front_porch
;
42 static int exynos_dp_init_dp(void)
47 /* SW defined function Normal operation */
48 exynos_dp_enable_sw_func(DP_ENABLE
);
50 ret
= exynos_dp_init_analog_func();
51 if (ret
!= EXYNOS_DP_SUCCESS
)
60 static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data
)
63 unsigned char sum
= 0;
65 for (i
= 0; i
< EDID_BLOCK_LENGTH
; i
++)
66 sum
= sum
+ edid_data
[i
];
71 static unsigned int exynos_dp_read_edid(void)
73 unsigned char edid
[EDID_BLOCK_LENGTH
* 2];
74 unsigned int extend_block
= 0;
76 unsigned char test_vector
;
80 * EDID device address is 0x50.
81 * However, if necessary, you must have set upper address
82 * into E-EDID in I2C device, 0x30.
85 /* Read Extension Flag, Number of 128-byte EDID extension blocks */
86 exynos_dp_read_byte_from_i2c(I2C_EDID_DEVICE_ADDR
, EDID_EXTENSION_FLAG
,
89 if (extend_block
> 0) {
90 printf("DP EDID data includes a single extension!\n");
93 retval
= exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR
,
96 &edid
[EDID_HEADER_PATTERN
]);
98 printf("DP EDID Read failed!\n");
101 sum
= exynos_dp_calc_edid_check_sum(edid
);
103 printf("DP EDID bad checksum!\n");
107 /* Read additional EDID data */
108 retval
= exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR
,
111 &edid
[EDID_BLOCK_LENGTH
]);
113 printf("DP EDID Read failed!\n");
116 sum
= exynos_dp_calc_edid_check_sum(&edid
[EDID_BLOCK_LENGTH
]);
118 printf("DP EDID bad checksum!\n");
122 exynos_dp_read_byte_from_dpcd(DPCD_TEST_REQUEST
,
124 if (test_vector
& DPCD_TEST_EDID_READ
) {
125 exynos_dp_write_byte_to_dpcd(DPCD_TEST_EDID_CHECKSUM
,
126 edid
[EDID_BLOCK_LENGTH
+ EDID_CHECKSUM
]);
127 exynos_dp_write_byte_to_dpcd(DPCD_TEST_RESPONSE
,
128 DPCD_TEST_EDID_CHECKSUM_WRITE
);
131 debug("DP EDID data does not include any extensions.\n");
134 retval
= exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR
,
137 &edid
[EDID_HEADER_PATTERN
]);
140 printf("DP EDID Read failed!\n");
143 sum
= exynos_dp_calc_edid_check_sum(edid
);
145 printf("DP EDID bad checksum!\n");
149 exynos_dp_read_byte_from_dpcd(DPCD_TEST_REQUEST
,
151 if (test_vector
& DPCD_TEST_EDID_READ
) {
152 exynos_dp_write_byte_to_dpcd(DPCD_TEST_EDID_CHECKSUM
,
153 edid
[EDID_CHECKSUM
]);
154 exynos_dp_write_byte_to_dpcd(DPCD_TEST_RESPONSE
,
155 DPCD_TEST_EDID_CHECKSUM_WRITE
);
159 debug("DP EDID Read success!\n");
164 static unsigned int exynos_dp_handle_edid(struct edp_device_info
*edp_info
)
166 unsigned char buf
[12];
169 unsigned char retry_cnt
;
170 unsigned char dpcd_rev
[16];
171 unsigned char lane_bw
[16];
172 unsigned char lane_cnt
[16];
174 memset(dpcd_rev
, 0, 16);
175 memset(lane_bw
, 0, 16);
176 memset(lane_cnt
, 0, 16);
181 /* Read DPCD 0x0000-0x000b */
182 ret
= exynos_dp_read_bytes_from_dpcd(DPCD_DPCD_REV
, 12,
184 if (ret
!= EXYNOS_DP_SUCCESS
) {
185 if (retry_cnt
== 0) {
186 printf("DP read_byte_from_dpcd() failed\n");
195 temp
= buf
[DPCD_DPCD_REV
];
196 if (temp
== DP_DPCD_REV_10
|| temp
== DP_DPCD_REV_11
)
197 edp_info
->dpcd_rev
= temp
;
199 printf("DP Wrong DPCD Rev : %x\n", temp
);
203 temp
= buf
[DPCD_MAX_LINK_RATE
];
204 if (temp
== DP_LANE_BW_1_62
|| temp
== DP_LANE_BW_2_70
)
205 edp_info
->lane_bw
= temp
;
207 printf("DP Wrong MAX LINK RATE : %x\n", temp
);
211 /*Refer VESA Display Port Stnadard Ver1.1a Page 120 */
212 if (edp_info
->dpcd_rev
== DP_DPCD_REV_11
) {
213 temp
= buf
[DPCD_MAX_LANE_COUNT
] & 0x1f;
214 if (buf
[DPCD_MAX_LANE_COUNT
] & 0x80)
215 edp_info
->dpcd_efc
= 1;
217 edp_info
->dpcd_efc
= 0;
219 temp
= buf
[DPCD_MAX_LANE_COUNT
];
220 edp_info
->dpcd_efc
= 0;
223 if (temp
== DP_LANE_CNT_1
|| temp
== DP_LANE_CNT_2
||
224 temp
== DP_LANE_CNT_4
) {
225 edp_info
->lane_cnt
= temp
;
227 printf("DP Wrong MAX LANE COUNT : %x\n", temp
);
231 ret
= exynos_dp_read_edid();
232 if (ret
!= EXYNOS_DP_SUCCESS
) {
233 printf("DP exynos_dp_read_edid() failed\n");
240 static void exynos_dp_init_training(void)
243 * MACRO_RST must be applied after the PLL_LOCK to avoid
244 * the DP inter pair skew issue for at least 10 us
246 exynos_dp_reset_macro();
248 /* All DP analog module power up */
249 exynos_dp_set_analog_power_down(POWER_ALL
, 0);
252 static unsigned int exynos_dp_link_start(struct edp_device_info
*edp_info
)
254 unsigned char buf
[5];
255 unsigned int ret
= 0;
257 debug("DP: %s was called\n", __func__
);
259 edp_info
->lt_info
.lt_status
= DP_LT_CR
;
260 edp_info
->lt_info
.ep_loop
= 0;
261 edp_info
->lt_info
.cr_loop
[0] = 0;
262 edp_info
->lt_info
.cr_loop
[1] = 0;
263 edp_info
->lt_info
.cr_loop
[2] = 0;
264 edp_info
->lt_info
.cr_loop
[3] = 0;
266 /* Set sink to D0 (Sink Not Ready) mode. */
267 ret
= exynos_dp_write_byte_to_dpcd(DPCD_SINK_POWER_STATE
,
268 DPCD_SET_POWER_STATE_D0
);
269 if (ret
!= EXYNOS_DP_SUCCESS
) {
270 printf("DP write_dpcd_byte failed\n");
274 /* Set link rate and count as you want to establish*/
275 exynos_dp_set_link_bandwidth(edp_info
->lane_bw
);
276 exynos_dp_set_lane_count(edp_info
->lane_cnt
);
278 /* Setup RX configuration */
279 buf
[0] = edp_info
->lane_bw
;
280 buf
[1] = edp_info
->lane_cnt
;
282 ret
= exynos_dp_write_bytes_to_dpcd(DPCD_LINK_BW_SET
, 2,
284 if (ret
!= EXYNOS_DP_SUCCESS
) {
285 printf("DP write_dpcd_byte failed\n");
289 exynos_dp_set_lane_pre_emphasis(PRE_EMPHASIS_LEVEL_0
,
292 /* Set training pattern 1 */
293 exynos_dp_set_training_pattern(TRAINING_PTN1
);
295 /* Set RX training pattern */
296 buf
[0] = DPCD_SCRAMBLING_DISABLED
| DPCD_TRAINING_PATTERN_1
;
298 buf
[1] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0
|
299 DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0
;
300 buf
[2] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0
|
301 DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0
;
302 buf
[3] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0
|
303 DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0
;
304 buf
[4] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0
|
305 DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0
;
307 ret
= exynos_dp_write_bytes_to_dpcd(DPCD_TRAINING_PATTERN_SET
,
309 if (ret
!= EXYNOS_DP_SUCCESS
) {
310 printf("DP write_dpcd_byte failed\n");
317 static unsigned int exynos_dp_training_pattern_dis(void)
319 unsigned int ret
= EXYNOS_DP_SUCCESS
;
321 exynos_dp_set_training_pattern(DP_NONE
);
323 ret
= exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET
,
324 DPCD_TRAINING_PATTERN_DISABLED
);
325 if (ret
!= EXYNOS_DP_SUCCESS
) {
326 printf("DP requst_link_traninig_req failed\n");
333 static unsigned int exynos_dp_enable_rx_to_enhanced_mode(unsigned char enable
)
336 unsigned int ret
= EXYNOS_DP_SUCCESS
;
338 ret
= exynos_dp_read_byte_from_dpcd(DPCD_LANE_COUNT_SET
,
340 if (ret
!= EXYNOS_DP_SUCCESS
) {
341 printf("DP read_from_dpcd failed\n");
346 data
= DPCD_ENHANCED_FRAME_EN
| DPCD_LN_COUNT_SET(data
);
348 data
= DPCD_LN_COUNT_SET(data
);
350 ret
= exynos_dp_write_byte_to_dpcd(DPCD_LANE_COUNT_SET
,
352 if (ret
!= EXYNOS_DP_SUCCESS
) {
353 printf("DP write_to_dpcd failed\n");
361 static unsigned int exynos_dp_set_enhanced_mode(unsigned char enhance_mode
)
363 unsigned int ret
= EXYNOS_DP_SUCCESS
;
365 ret
= exynos_dp_enable_rx_to_enhanced_mode(enhance_mode
);
366 if (ret
!= EXYNOS_DP_SUCCESS
) {
367 printf("DP rx_enhance_mode failed\n");
371 exynos_dp_enable_enhanced_mode(enhance_mode
);
376 static int exynos_dp_read_dpcd_lane_stat(struct edp_device_info
*edp_info
,
377 unsigned char *status
)
380 unsigned char buf
[2];
381 unsigned char lane_stat
[DP_LANE_CNT_4
] = {0,};
382 unsigned char shift_val
[DP_LANE_CNT_4
] = {0,};
389 ret
= exynos_dp_read_bytes_from_dpcd(DPCD_LANE0_1_STATUS
, 2, buf
);
390 if (ret
!= EXYNOS_DP_SUCCESS
) {
391 printf("DP read lane status failed\n");
395 for (i
= 0; i
< edp_info
->lane_cnt
; i
++) {
396 lane_stat
[i
] = (buf
[(i
/ 2)] >> shift_val
[i
]) & 0x0f;
397 if (lane_stat
[0] != lane_stat
[i
]) {
398 printf("Wrong lane status\n");
403 *status
= lane_stat
[0];
408 static unsigned int exynos_dp_read_dpcd_adj_req(unsigned char lane_num
,
409 unsigned char *sw
, unsigned char *em
)
411 unsigned int ret
= EXYNOS_DP_SUCCESS
;
413 unsigned int dpcd_addr
;
414 unsigned char shift_val
[DP_LANE_CNT_4
] = {0, 4, 0, 4};
416 /*lane_num value is used as arry index, so this range 0 ~ 3 */
417 dpcd_addr
= DPCD_ADJUST_REQUEST_LANE0_1
+ (lane_num
/ 2);
419 ret
= exynos_dp_read_byte_from_dpcd(dpcd_addr
, &buf
);
420 if (ret
!= EXYNOS_DP_SUCCESS
) {
421 printf("DP read adjust request failed\n");
425 *sw
= ((buf
>> shift_val
[lane_num
]) & 0x03);
426 *em
= ((buf
>> shift_val
[lane_num
]) & 0x0c) >> 2;
431 static int exynos_dp_equalizer_err_link(struct edp_device_info
*edp_info
)
435 ret
= exynos_dp_training_pattern_dis();
436 if (ret
!= EXYNOS_DP_SUCCESS
) {
437 printf("DP training_patter_disable() failed\n");
438 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
441 ret
= exynos_dp_set_enhanced_mode(edp_info
->dpcd_efc
);
442 if (ret
!= EXYNOS_DP_SUCCESS
) {
443 printf("DP set_enhanced_mode() failed\n");
444 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
450 static int exynos_dp_reduce_link_rate(struct edp_device_info
*edp_info
)
454 if (edp_info
->lane_bw
== DP_LANE_BW_2_70
) {
455 edp_info
->lane_bw
= DP_LANE_BW_1_62
;
456 printf("DP Change lane bw to 1.62Gbps\n");
457 edp_info
->lt_info
.lt_status
= DP_LT_START
;
458 ret
= EXYNOS_DP_SUCCESS
;
460 ret
= exynos_dp_training_pattern_dis();
461 if (ret
!= EXYNOS_DP_SUCCESS
)
462 printf("DP training_patter_disable() failed\n");
464 ret
= exynos_dp_set_enhanced_mode(edp_info
->dpcd_efc
);
465 if (ret
!= EXYNOS_DP_SUCCESS
)
466 printf("DP set_enhanced_mode() failed\n");
468 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
474 static unsigned int exynos_dp_process_clock_recovery(struct edp_device_info
477 unsigned int ret
= EXYNOS_DP_SUCCESS
;
478 unsigned char lane_stat
;
479 unsigned char lt_ctl_val
[DP_LANE_CNT_4
] = {0, };
481 unsigned char adj_req_sw
;
482 unsigned char adj_req_em
;
483 unsigned char buf
[5];
485 debug("DP: %s was called\n", __func__
);
488 ret
= exynos_dp_read_dpcd_lane_stat(edp_info
, &lane_stat
);
489 if (ret
!= EXYNOS_DP_SUCCESS
) {
490 printf("DP read lane status failed\n");
491 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
495 if (lane_stat
& DP_LANE_STAT_CR_DONE
) {
496 debug("DP clock Recovery training succeed\n");
497 exynos_dp_set_training_pattern(TRAINING_PTN2
);
499 for (i
= 0; i
< edp_info
->lane_cnt
; i
++) {
500 ret
= exynos_dp_read_dpcd_adj_req(i
, &adj_req_sw
,
502 if (ret
!= EXYNOS_DP_SUCCESS
) {
503 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
508 lt_ctl_val
[i
] = adj_req_em
<< 3 | adj_req_sw
;
510 if ((adj_req_sw
== VOLTAGE_LEVEL_3
)
511 || (adj_req_em
== PRE_EMPHASIS_LEVEL_3
)) {
512 lt_ctl_val
[i
] |= MAX_DRIVE_CURRENT_REACH_3
|
513 MAX_PRE_EMPHASIS_REACH_3
;
515 exynos_dp_set_lanex_pre_emphasis(lt_ctl_val
[i
], i
);
518 buf
[0] = DPCD_SCRAMBLING_DISABLED
| DPCD_TRAINING_PATTERN_2
;
519 buf
[1] = lt_ctl_val
[0];
520 buf
[2] = lt_ctl_val
[1];
521 buf
[3] = lt_ctl_val
[2];
522 buf
[4] = lt_ctl_val
[3];
524 ret
= exynos_dp_write_bytes_to_dpcd(
525 DPCD_TRAINING_PATTERN_SET
, 5, buf
);
526 if (ret
!= EXYNOS_DP_SUCCESS
) {
527 printf("DP write traning pattern1 failed\n");
528 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
531 edp_info
->lt_info
.lt_status
= DP_LT_ET
;
533 for (i
= 0; i
< edp_info
->lane_cnt
; i
++) {
534 lt_ctl_val
[i
] = exynos_dp_get_lanex_pre_emphasis(i
);
535 ret
= exynos_dp_read_dpcd_adj_req(i
,
536 &adj_req_sw
, &adj_req_em
);
537 if (ret
!= EXYNOS_DP_SUCCESS
) {
538 printf("DP read adj req failed\n");
539 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
543 if ((adj_req_sw
== VOLTAGE_LEVEL_3
) ||
544 (adj_req_em
== PRE_EMPHASIS_LEVEL_3
))
545 ret
= exynos_dp_reduce_link_rate(edp_info
);
547 if ((DRIVE_CURRENT_SET_0_GET(lt_ctl_val
[i
]) ==
549 (PRE_EMPHASIS_SET_0_GET(lt_ctl_val
[i
]) ==
551 edp_info
->lt_info
.cr_loop
[i
]++;
552 if (edp_info
->lt_info
.cr_loop
[i
] == MAX_CR_LOOP
)
553 ret
= exynos_dp_reduce_link_rate(
558 lt_ctl_val
[i
] = adj_req_em
<< 3 | adj_req_sw
;
560 if ((adj_req_sw
== VOLTAGE_LEVEL_3
) ||
561 (adj_req_em
== PRE_EMPHASIS_LEVEL_3
)) {
562 lt_ctl_val
[i
] |= MAX_DRIVE_CURRENT_REACH_3
|
563 MAX_PRE_EMPHASIS_REACH_3
;
565 exynos_dp_set_lanex_pre_emphasis(lt_ctl_val
[i
], i
);
568 ret
= exynos_dp_write_bytes_to_dpcd(
569 DPCD_TRAINING_LANE0_SET
, 4, lt_ctl_val
);
570 if (ret
!= EXYNOS_DP_SUCCESS
) {
571 printf("DP write traning pattern2 failed\n");
572 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
580 static unsigned int exynos_dp_process_equalizer_training(struct edp_device_info
583 unsigned int ret
= EXYNOS_DP_SUCCESS
;
584 unsigned char lane_stat
, adj_req_sw
, adj_req_em
, i
;
585 unsigned char lt_ctl_val
[DP_LANE_CNT_4
] = {0,};
586 unsigned char interlane_aligned
= 0;
588 unsigned char f_lane_cnt
;
589 unsigned char sink_stat
;
593 ret
= exynos_dp_read_dpcd_lane_stat(edp_info
, &lane_stat
);
594 if (ret
!= EXYNOS_DP_SUCCESS
) {
595 printf("DP read lane status failed\n");
596 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
600 debug("DP lane stat : %x\n", lane_stat
);
602 if (lane_stat
& DP_LANE_STAT_CR_DONE
) {
603 ret
= exynos_dp_read_byte_from_dpcd(DPCD_LN_ALIGN_UPDATED
,
605 if (ret
!= EXYNOS_DP_SUCCESS
) {
606 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
611 interlane_aligned
= (sink_stat
& DPCD_INTERLANE_ALIGN_DONE
);
613 for (i
= 0; i
< edp_info
->lane_cnt
; i
++) {
614 ret
= exynos_dp_read_dpcd_adj_req(i
,
615 &adj_req_sw
, &adj_req_em
);
616 if (ret
!= EXYNOS_DP_SUCCESS
) {
617 printf("DP read adj req 1 failed\n");
618 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
624 lt_ctl_val
[i
] = adj_req_em
<< 3 | adj_req_sw
;
626 if ((adj_req_sw
== VOLTAGE_LEVEL_3
) ||
627 (adj_req_em
== PRE_EMPHASIS_LEVEL_3
)) {
628 lt_ctl_val
[i
] |= MAX_DRIVE_CURRENT_REACH_3
;
629 lt_ctl_val
[i
] |= MAX_PRE_EMPHASIS_REACH_3
;
633 if (((lane_stat
&DP_LANE_STAT_CE_DONE
) &&
634 (lane_stat
&DP_LANE_STAT_SYM_LOCK
))
635 && (interlane_aligned
== DPCD_INTERLANE_ALIGN_DONE
)) {
636 debug("DP Equalizer training succeed\n");
638 f_bw
= exynos_dp_get_link_bandwidth();
639 f_lane_cnt
= exynos_dp_get_lane_count();
641 debug("DP final BandWidth : %x\n", f_bw
);
642 debug("DP final Lane Count : %x\n", f_lane_cnt
);
644 edp_info
->lt_info
.lt_status
= DP_LT_FINISHED
;
646 exynos_dp_equalizer_err_link(edp_info
);
649 edp_info
->lt_info
.ep_loop
++;
651 if (edp_info
->lt_info
.ep_loop
> MAX_EQ_LOOP
) {
652 if (edp_info
->lane_bw
== DP_LANE_BW_2_70
) {
653 ret
= exynos_dp_reduce_link_rate(
656 edp_info
->lt_info
.lt_status
=
658 exynos_dp_equalizer_err_link(edp_info
);
661 for (i
= 0; i
< edp_info
->lane_cnt
; i
++)
662 exynos_dp_set_lanex_pre_emphasis(
665 ret
= exynos_dp_write_bytes_to_dpcd(
666 DPCD_TRAINING_LANE0_SET
,
668 if (ret
!= EXYNOS_DP_SUCCESS
) {
669 printf("DP set lt pattern failed\n");
670 edp_info
->lt_info
.lt_status
=
672 exynos_dp_equalizer_err_link(edp_info
);
676 } else if (edp_info
->lane_bw
== DP_LANE_BW_2_70
) {
677 ret
= exynos_dp_reduce_link_rate(edp_info
);
679 edp_info
->lt_info
.lt_status
= DP_LT_FAIL
;
680 exynos_dp_equalizer_err_link(edp_info
);
686 static unsigned int exynos_dp_sw_link_training(struct edp_device_info
*edp_info
)
688 unsigned int ret
= 0;
689 int training_finished
;
691 /* Turn off unnecessary lane */
692 if (edp_info
->lane_cnt
== 1)
693 exynos_dp_set_analog_power_down(CH1_BLOCK
, 1);
695 training_finished
= 0;
697 edp_info
->lt_info
.lt_status
= DP_LT_START
;
700 while (!training_finished
) {
701 switch (edp_info
->lt_info
.lt_status
) {
703 ret
= exynos_dp_link_start(edp_info
);
704 if (ret
!= EXYNOS_DP_SUCCESS
) {
705 printf("DP LT:link start failed\n");
710 ret
= exynos_dp_process_clock_recovery(edp_info
);
711 if (ret
!= EXYNOS_DP_SUCCESS
) {
712 printf("DP LT:clock recovery failed\n");
717 ret
= exynos_dp_process_equalizer_training(edp_info
);
718 if (ret
!= EXYNOS_DP_SUCCESS
) {
719 printf("DP LT:equalizer training failed\n");
724 training_finished
= 1;
734 static unsigned int exynos_dp_set_link_train(struct edp_device_info
*edp_info
)
738 exynos_dp_init_training();
740 ret
= exynos_dp_sw_link_training(edp_info
);
741 if (ret
!= EXYNOS_DP_SUCCESS
)
742 printf("DP dp_sw_link_traning() failed\n");
747 static void exynos_dp_enable_scramble(unsigned int enable
)
752 exynos_dp_enable_scrambling(DP_ENABLE
);
754 exynos_dp_read_byte_from_dpcd(DPCD_TRAINING_PATTERN_SET
,
756 exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET
,
757 (u8
)(data
& ~DPCD_SCRAMBLING_DISABLED
));
759 exynos_dp_enable_scrambling(DP_DISABLE
);
760 exynos_dp_read_byte_from_dpcd(DPCD_TRAINING_PATTERN_SET
,
762 exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET
,
763 (u8
)(data
| DPCD_SCRAMBLING_DISABLED
));
767 static unsigned int exynos_dp_config_video(struct edp_device_info
*edp_info
)
769 unsigned int ret
= 0;
770 unsigned int retry_cnt
;
774 if (edp_info
->video_info
.master_mode
) {
775 printf("DP does not support master mode\n");
779 exynos_dp_config_video_slave_mode(&edp_info
->video_info
);
782 exynos_dp_set_video_color_format(&edp_info
->video_info
);
784 if (edp_info
->video_info
.bist_mode
) {
785 if (exynos_dp_config_video_bist(edp_info
) != 0)
789 ret
= exynos_dp_get_pll_lock_status();
790 if (ret
!= PLL_LOCKED
) {
791 printf("DP PLL is not locked yet\n");
795 if (edp_info
->video_info
.master_mode
== 0) {
798 ret
= exynos_dp_is_slave_video_stream_clock_on();
799 if (ret
!= EXYNOS_DP_SUCCESS
) {
800 if (retry_cnt
== 0) {
801 printf("DP stream_clock_on failed\n");
811 /* Set to use the register calculated M/N video */
812 exynos_dp_set_video_cr_mn(CALCULATED_M
, 0, 0);
814 /* For video bist, Video timing must be generated by register */
815 exynos_dp_set_video_timing_mode(VIDEO_TIMING_FROM_CAPTURE
);
817 /* Enable video bist */
818 if (edp_info
->video_info
.bist_pattern
!= COLOR_RAMP
&&
819 edp_info
->video_info
.bist_pattern
!= BALCK_WHITE_V_LINES
&&
820 edp_info
->video_info
.bist_pattern
!= COLOR_SQUARE
)
821 exynos_dp_enable_video_bist(edp_info
->video_info
.bist_mode
);
823 exynos_dp_enable_video_bist(DP_DISABLE
);
825 /* Disable video mute */
826 exynos_dp_enable_video_mute(DP_DISABLE
);
828 /* Configure video Master or Slave mode */
829 exynos_dp_enable_video_master(edp_info
->video_info
.master_mode
);
832 exynos_dp_start_video();
834 if (edp_info
->video_info
.master_mode
== 0) {
837 ret
= exynos_dp_is_video_stream_on();
838 if (ret
!= EXYNOS_DP_SUCCESS
) {
839 if (retry_cnt
== 0) {
840 printf("DP Timeout of video stream\n");
853 #ifdef CONFIG_OF_CONTROL
854 int exynos_dp_parse_dt(const void *blob
, struct edp_device_info
*edp_info
)
856 unsigned int node
= fdtdec_next_compatible(blob
, 0,
857 COMPAT_SAMSUNG_EXYNOS5_DP
);
859 debug("exynos_dp: Can't get device node for dp\n");
863 edp_info
->disp_info
.h_res
= fdtdec_get_int(blob
, node
,
865 edp_info
->disp_info
.h_sync_width
= fdtdec_get_int(blob
, node
,
866 "samsung,h-sync-width", 0);
867 edp_info
->disp_info
.h_back_porch
= fdtdec_get_int(blob
, node
,
868 "samsung,h-back-porch", 0);
869 edp_info
->disp_info
.h_front_porch
= fdtdec_get_int(blob
, node
,
870 "samsung,h-front-porch", 0);
871 edp_info
->disp_info
.v_res
= fdtdec_get_int(blob
, node
,
873 edp_info
->disp_info
.v_sync_width
= fdtdec_get_int(blob
, node
,
874 "samsung,v-sync-width", 0);
875 edp_info
->disp_info
.v_back_porch
= fdtdec_get_int(blob
, node
,
876 "samsung,v-back-porch", 0);
877 edp_info
->disp_info
.v_front_porch
= fdtdec_get_int(blob
, node
,
878 "samsung,v-front-porch", 0);
879 edp_info
->disp_info
.v_sync_rate
= fdtdec_get_int(blob
, node
,
880 "samsung,v-sync-rate", 0);
882 edp_info
->lt_info
.lt_status
= fdtdec_get_int(blob
, node
,
883 "samsung,lt-status", 0);
885 edp_info
->video_info
.master_mode
= fdtdec_get_int(blob
, node
,
886 "samsung,master-mode", 0);
887 edp_info
->video_info
.bist_mode
= fdtdec_get_int(blob
, node
,
888 "samsung,bist-mode", 0);
889 edp_info
->video_info
.bist_pattern
= fdtdec_get_int(blob
, node
,
890 "samsung,bist-pattern", 0);
891 edp_info
->video_info
.h_sync_polarity
= fdtdec_get_int(blob
, node
,
892 "samsung,h-sync-polarity", 0);
893 edp_info
->video_info
.v_sync_polarity
= fdtdec_get_int(blob
, node
,
894 "samsung,v-sync-polarity", 0);
895 edp_info
->video_info
.interlaced
= fdtdec_get_int(blob
, node
,
896 "samsung,interlaced", 0);
897 edp_info
->video_info
.color_space
= fdtdec_get_int(blob
, node
,
898 "samsung,color-space", 0);
899 edp_info
->video_info
.dynamic_range
= fdtdec_get_int(blob
, node
,
900 "samsung,dynamic-range", 0);
901 edp_info
->video_info
.ycbcr_coeff
= fdtdec_get_int(blob
, node
,
902 "samsung,ycbcr-coeff", 0);
903 edp_info
->video_info
.color_depth
= fdtdec_get_int(blob
, node
,
904 "samsung,color-depth", 0);
909 unsigned int exynos_init_dp(void)
912 struct edp_device_info
*edp_info
;
914 edp_info
= kzalloc(sizeof(struct edp_device_info
), GFP_KERNEL
);
916 debug("failed to allocate edp device object.\n");
920 #ifdef CONFIG_OF_CONTROL
921 if (exynos_dp_parse_dt(gd
->fdt_blob
, edp_info
))
922 debug("unable to parse DP DT node\n");
924 edp_info
= dp_pd
->edp_dev_info
;
925 if (edp_info
== NULL
) {
926 debug("failed to get edp_info data.\n");
931 exynos_dp_set_base_addr();
933 exynos_dp_disp_info(&edp_info
->disp_info
);
935 exynos_set_dp_phy(1);
937 ret
= exynos_dp_init_dp();
938 if (ret
!= EXYNOS_DP_SUCCESS
) {
939 printf("DP exynos_dp_init_dp() failed\n");
943 ret
= exynos_dp_handle_edid(edp_info
);
944 if (ret
!= EXYNOS_DP_SUCCESS
) {
945 printf("EDP handle_edid fail\n");
949 ret
= exynos_dp_set_link_train(edp_info
);
950 if (ret
!= EXYNOS_DP_SUCCESS
) {
951 printf("DP link training fail\n");
955 exynos_dp_enable_scramble(DP_ENABLE
);
956 exynos_dp_enable_rx_to_enhanced_mode(DP_ENABLE
);
957 exynos_dp_enable_enhanced_mode(DP_ENABLE
);
959 exynos_dp_set_link_bandwidth(edp_info
->lane_bw
);
960 exynos_dp_set_lane_count(edp_info
->lane_cnt
);
962 exynos_dp_init_video();
963 ret
= exynos_dp_config_video(edp_info
);
964 if (ret
!= EXYNOS_DP_SUCCESS
) {
965 printf("Exynos DP init failed\n");
969 printf("Exynos DP init done\n");
974 void exynos_set_dp_platform_data(struct exynos_dp_platform_data
*pd
)
977 debug("pd is NULL\n");