]> git.sur5r.net Git - u-boot/blob - drivers/video/exynos/exynos_dp.c
d7bccc3708f3701b49ba22a66a5385496dc7b5d8
[u-boot] / drivers / video / exynos / exynos_dp.c
1 /*
2  * Copyright (C) 2012 Samsung Electronics
3  *
4  * Author: Donghwa Lee <dh09.lee@samsung.com>
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <config.h>
10 #include <common.h>
11 #include <malloc.h>
12 #include <linux/compat.h>
13 #include <linux/err.h>
14 #include <asm/arch/clk.h>
15 #include <asm/arch/cpu.h>
16 #include <asm/arch/dp_info.h>
17 #include <asm/arch/dp.h>
18 #include <asm/arch/power.h>
19 #include <fdtdec.h>
20 #include <libfdt.h>
21
22 #include "exynos_dp_lowlevel.h"
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 static void exynos_dp_disp_info(struct edp_disp_info *disp_info)
27 {
28         disp_info->h_total = disp_info->h_res + disp_info->h_sync_width +
29                 disp_info->h_back_porch + disp_info->h_front_porch;
30         disp_info->v_total = disp_info->v_res + disp_info->v_sync_width +
31                 disp_info->v_back_porch + disp_info->v_front_porch;
32
33         return;
34 }
35
36 static int exynos_dp_init_dp(struct exynos_dp *regs)
37 {
38         int ret;
39         exynos_dp_reset(regs);
40
41         /* SW defined function Normal operation */
42         exynos_dp_enable_sw_func(regs, DP_ENABLE);
43
44         ret = exynos_dp_init_analog_func(regs);
45         if (ret != EXYNOS_DP_SUCCESS)
46                 return ret;
47
48         exynos_dp_init_hpd(regs);
49         exynos_dp_init_aux(regs);
50
51         return ret;
52 }
53
54 static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
55 {
56         int i;
57         unsigned char sum = 0;
58
59         for (i = 0; i < EDID_BLOCK_LENGTH; i++)
60                 sum = sum + edid_data[i];
61
62         return sum;
63 }
64
65 static unsigned int exynos_dp_read_edid(struct exynos_dp *regs)
66 {
67         unsigned char edid[EDID_BLOCK_LENGTH * 2];
68         unsigned int extend_block = 0;
69         unsigned char sum;
70         unsigned char test_vector;
71         int retval;
72
73         /*
74          * EDID device address is 0x50.
75          * However, if necessary, you must have set upper address
76          * into E-EDID in I2C device, 0x30.
77          */
78
79         /* Read Extension Flag, Number of 128-byte EDID extension blocks */
80         exynos_dp_read_byte_from_i2c(regs, I2C_EDID_DEVICE_ADDR,
81                                      EDID_EXTENSION_FLAG, &extend_block);
82
83         if (extend_block > 0) {
84                 printf("DP EDID data includes a single extension!\n");
85
86                 /* Read EDID data */
87                 retval = exynos_dp_read_bytes_from_i2c(regs,
88                                                 I2C_EDID_DEVICE_ADDR,
89                                                 EDID_HEADER_PATTERN,
90                                                 EDID_BLOCK_LENGTH,
91                                                 &edid[EDID_HEADER_PATTERN]);
92                 if (retval != 0) {
93                         printf("DP EDID Read failed!\n");
94                         return -1;
95                 }
96                 sum = exynos_dp_calc_edid_check_sum(edid);
97                 if (sum != 0) {
98                         printf("DP EDID bad checksum!\n");
99                         return -1;
100                 }
101
102                 /* Read additional EDID data */
103                 retval = exynos_dp_read_bytes_from_i2c(regs,
104                                 I2C_EDID_DEVICE_ADDR,
105                                 EDID_BLOCK_LENGTH,
106                                 EDID_BLOCK_LENGTH,
107                                 &edid[EDID_BLOCK_LENGTH]);
108                 if (retval != 0) {
109                         printf("DP EDID Read failed!\n");
110                         return -1;
111                 }
112                 sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
113                 if (sum != 0) {
114                         printf("DP EDID bad checksum!\n");
115                         return -1;
116                 }
117
118                 exynos_dp_read_byte_from_dpcd(regs, DPCD_TEST_REQUEST,
119                                               &test_vector);
120                 if (test_vector & DPCD_TEST_EDID_READ) {
121                         exynos_dp_write_byte_to_dpcd(regs,
122                                 DPCD_TEST_EDID_CHECKSUM,
123                                 edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
124                         exynos_dp_write_byte_to_dpcd(regs,
125                                 DPCD_TEST_RESPONSE,
126                                 DPCD_TEST_EDID_CHECKSUM_WRITE);
127                 }
128         } else {
129                 debug("DP EDID data does not include any extensions.\n");
130
131                 /* Read EDID data */
132                 retval = exynos_dp_read_bytes_from_i2c(regs,
133                                 I2C_EDID_DEVICE_ADDR,
134                                 EDID_HEADER_PATTERN,
135                                 EDID_BLOCK_LENGTH,
136                                 &edid[EDID_HEADER_PATTERN]);
137
138                 if (retval != 0) {
139                         printf("DP EDID Read failed!\n");
140                         return -1;
141                 }
142                 sum = exynos_dp_calc_edid_check_sum(edid);
143                 if (sum != 0) {
144                         printf("DP EDID bad checksum!\n");
145                         return -1;
146                 }
147
148                 exynos_dp_read_byte_from_dpcd(regs, DPCD_TEST_REQUEST,
149                         &test_vector);
150                 if (test_vector & DPCD_TEST_EDID_READ) {
151                         exynos_dp_write_byte_to_dpcd(regs,
152                                 DPCD_TEST_EDID_CHECKSUM, edid[EDID_CHECKSUM]);
153                         exynos_dp_write_byte_to_dpcd(regs,
154                                 DPCD_TEST_RESPONSE,
155                                 DPCD_TEST_EDID_CHECKSUM_WRITE);
156                 }
157         }
158
159         debug("DP EDID Read success!\n");
160
161         return 0;
162 }
163
164 static unsigned int exynos_dp_handle_edid(struct exynos_dp *regs,
165                                           struct exynos_dp_priv *priv)
166 {
167         unsigned char buf[12];
168         unsigned int ret;
169         unsigned char temp;
170         unsigned char retry_cnt;
171         unsigned char dpcd_rev[16];
172         unsigned char lane_bw[16];
173         unsigned char lane_cnt[16];
174
175         memset(dpcd_rev, 0, 16);
176         memset(lane_bw, 0, 16);
177         memset(lane_cnt, 0, 16);
178         memset(buf, 0, 12);
179
180         retry_cnt = 5;
181         while (retry_cnt) {
182                 /* Read DPCD 0x0000-0x000b */
183                 ret = exynos_dp_read_bytes_from_dpcd(regs, DPCD_DPCD_REV, 12,
184                                                      buf);
185                 if (ret != EXYNOS_DP_SUCCESS) {
186                         if (retry_cnt == 0) {
187                                 printf("DP read_byte_from_dpcd() failed\n");
188                                 return ret;
189                         }
190                         retry_cnt--;
191                 } else
192                         break;
193         }
194
195         /* */
196         temp = buf[DPCD_DPCD_REV];
197         if (temp == DP_DPCD_REV_10 || temp == DP_DPCD_REV_11)
198                 priv->dpcd_rev = temp;
199         else {
200                 printf("DP Wrong DPCD Rev : %x\n", temp);
201                 return -ENODEV;
202         }
203
204         temp = buf[DPCD_MAX_LINK_RATE];
205         if (temp == DP_LANE_BW_1_62 || temp == DP_LANE_BW_2_70)
206                 priv->lane_bw = temp;
207         else {
208                 printf("DP Wrong MAX LINK RATE : %x\n", temp);
209                 return -EINVAL;
210         }
211
212         /* Refer VESA Display Port Standard Ver1.1a Page 120 */
213         if (priv->dpcd_rev == DP_DPCD_REV_11) {
214                 temp = buf[DPCD_MAX_LANE_COUNT] & 0x1f;
215                 if (buf[DPCD_MAX_LANE_COUNT] & 0x80)
216                         priv->dpcd_efc = 1;
217                 else
218                         priv->dpcd_efc = 0;
219         } else {
220                 temp = buf[DPCD_MAX_LANE_COUNT];
221                 priv->dpcd_efc = 0;
222         }
223
224         if (temp == DP_LANE_CNT_1 || temp == DP_LANE_CNT_2 ||
225                         temp == DP_LANE_CNT_4) {
226                 priv->lane_cnt = temp;
227         } else {
228                 printf("DP Wrong MAX LANE COUNT : %x\n", temp);
229                 return -EINVAL;
230         }
231
232         ret = exynos_dp_read_edid(regs);
233         if (ret != EXYNOS_DP_SUCCESS) {
234                 printf("DP exynos_dp_read_edid() failed\n");
235                 return -EINVAL;
236         }
237
238         return ret;
239 }
240
241 static void exynos_dp_init_training(struct exynos_dp *regs)
242 {
243         /*
244          * MACRO_RST must be applied after the PLL_LOCK to avoid
245          * the DP inter pair skew issue for at least 10 us
246          */
247         exynos_dp_reset_macro(regs);
248
249         /* All DP analog module power up */
250         exynos_dp_set_analog_power_down(regs, POWER_ALL, 0);
251 }
252
253 static unsigned int exynos_dp_link_start(struct exynos_dp *regs,
254                                          struct exynos_dp_priv *priv)
255 {
256         unsigned char buf[5];
257         unsigned int ret = 0;
258
259         debug("DP: %s was called\n", __func__);
260
261         priv->lt_info.lt_status = DP_LT_CR;
262         priv->lt_info.ep_loop = 0;
263         priv->lt_info.cr_loop[0] = 0;
264         priv->lt_info.cr_loop[1] = 0;
265         priv->lt_info.cr_loop[2] = 0;
266         priv->lt_info.cr_loop[3] = 0;
267
268                 /* Set sink to D0 (Sink Not Ready) mode. */
269         ret = exynos_dp_write_byte_to_dpcd(regs, DPCD_SINK_POWER_STATE,
270                                            DPCD_SET_POWER_STATE_D0);
271         if (ret != EXYNOS_DP_SUCCESS) {
272                 printf("DP write_dpcd_byte failed\n");
273                 return ret;
274         }
275
276         /* Set link rate and count as you want to establish */
277         exynos_dp_set_link_bandwidth(regs, priv->lane_bw);
278         exynos_dp_set_lane_count(regs, priv->lane_cnt);
279
280         /* Setup RX configuration */
281         buf[0] = priv->lane_bw;
282         buf[1] = priv->lane_cnt;
283
284         ret = exynos_dp_write_bytes_to_dpcd(regs, DPCD_LINK_BW_SET, 2, buf);
285         if (ret != EXYNOS_DP_SUCCESS) {
286                 printf("DP write_dpcd_byte failed\n");
287                 return ret;
288         }
289
290         exynos_dp_set_lane_pre_emphasis(regs, PRE_EMPHASIS_LEVEL_0,
291                         priv->lane_cnt);
292
293         /* Set training pattern 1 */
294         exynos_dp_set_training_pattern(regs, TRAINING_PTN1);
295
296         /* Set RX training pattern */
297         buf[0] = DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1;
298
299         buf[1] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 |
300                 DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0;
301         buf[2] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 |
302                 DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0;
303         buf[3] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 |
304                 DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0;
305         buf[4] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 |
306                 DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0;
307
308         ret = exynos_dp_write_bytes_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
309                                             5, buf);
310         if (ret != EXYNOS_DP_SUCCESS) {
311                 printf("DP write_dpcd_byte failed\n");
312                 return ret;
313         }
314
315         return ret;
316 }
317
318 static unsigned int exynos_dp_training_pattern_dis(struct exynos_dp *regs)
319 {
320         unsigned int ret = EXYNOS_DP_SUCCESS;
321
322         exynos_dp_set_training_pattern(regs, DP_NONE);
323
324         ret = exynos_dp_write_byte_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
325                                            DPCD_TRAINING_PATTERN_DISABLED);
326         if (ret != EXYNOS_DP_SUCCESS) {
327                 printf("DP request_link_training_req failed\n");
328                 return -EAGAIN;
329         }
330
331         return ret;
332 }
333
334 static unsigned int exynos_dp_enable_rx_to_enhanced_mode(
335                 struct exynos_dp *regs, unsigned char enable)
336 {
337         unsigned char data;
338         unsigned int ret = EXYNOS_DP_SUCCESS;
339
340         ret = exynos_dp_read_byte_from_dpcd(regs, DPCD_LANE_COUNT_SET,
341                                             &data);
342         if (ret != EXYNOS_DP_SUCCESS) {
343                 printf("DP read_from_dpcd failed\n");
344                 return -EAGAIN;
345         }
346
347         if (enable)
348                 data = DPCD_ENHANCED_FRAME_EN | DPCD_LN_COUNT_SET(data);
349         else
350                 data = DPCD_LN_COUNT_SET(data);
351
352         ret = exynos_dp_write_byte_to_dpcd(regs, DPCD_LANE_COUNT_SET, data);
353         if (ret != EXYNOS_DP_SUCCESS) {
354                         printf("DP write_to_dpcd failed\n");
355                         return -EAGAIN;
356
357         }
358
359         return ret;
360 }
361
362 static unsigned int exynos_dp_set_enhanced_mode(struct exynos_dp *regs,
363                                                 unsigned char enhance_mode)
364 {
365         unsigned int ret = EXYNOS_DP_SUCCESS;
366
367         ret = exynos_dp_enable_rx_to_enhanced_mode(regs, enhance_mode);
368         if (ret != EXYNOS_DP_SUCCESS) {
369                 printf("DP rx_enhance_mode failed\n");
370                 return -EAGAIN;
371         }
372
373         exynos_dp_enable_enhanced_mode(regs, enhance_mode);
374
375         return ret;
376 }
377
378 static int exynos_dp_read_dpcd_lane_stat(struct exynos_dp *regs,
379                                          struct exynos_dp_priv *priv,
380                                          unsigned char *status)
381 {
382         unsigned int ret, i;
383         unsigned char buf[2];
384         unsigned char lane_stat[DP_LANE_CNT_4] = {0,};
385         unsigned char shift_val[DP_LANE_CNT_4] = {0,};
386
387         shift_val[0] = 0;
388         shift_val[1] = 4;
389         shift_val[2] = 0;
390         shift_val[3] = 4;
391
392         ret = exynos_dp_read_bytes_from_dpcd(regs, DPCD_LANE0_1_STATUS, 2,
393                                              buf);
394         if (ret != EXYNOS_DP_SUCCESS) {
395                 printf("DP read lane status failed\n");
396                 return ret;
397         }
398
399         for (i = 0; i < priv->lane_cnt; i++) {
400                 lane_stat[i] = (buf[(i / 2)] >> shift_val[i]) & 0x0f;
401                 if (lane_stat[0] != lane_stat[i]) {
402                         printf("Wrong lane status\n");
403                         return -EINVAL;
404                 }
405         }
406
407         *status = lane_stat[0];
408
409         return ret;
410 }
411
412 static unsigned int exynos_dp_read_dpcd_adj_req(struct exynos_dp *regs,
413                 unsigned char lane_num, unsigned char *sw, unsigned char *em)
414 {
415         unsigned int ret = EXYNOS_DP_SUCCESS;
416         unsigned char buf;
417         unsigned int dpcd_addr;
418         unsigned char shift_val[DP_LANE_CNT_4] = {0, 4, 0, 4};
419
420         /* lane_num value is used as array index, so this range 0 ~ 3 */
421         dpcd_addr = DPCD_ADJUST_REQUEST_LANE0_1 + (lane_num / 2);
422
423         ret = exynos_dp_read_byte_from_dpcd(regs, dpcd_addr, &buf);
424         if (ret != EXYNOS_DP_SUCCESS) {
425                 printf("DP read adjust request failed\n");
426                 return -EAGAIN;
427         }
428
429         *sw = ((buf >> shift_val[lane_num]) & 0x03);
430         *em = ((buf >> shift_val[lane_num]) & 0x0c) >> 2;
431
432         return ret;
433 }
434
435 static int exynos_dp_equalizer_err_link(struct exynos_dp *regs,
436                                         struct exynos_dp_priv *priv)
437 {
438         int ret;
439
440         ret = exynos_dp_training_pattern_dis(regs);
441         if (ret != EXYNOS_DP_SUCCESS) {
442                 printf("DP training_pattern_disable() failed\n");
443                 priv->lt_info.lt_status = DP_LT_FAIL;
444         }
445
446         ret = exynos_dp_set_enhanced_mode(regs, priv->dpcd_efc);
447         if (ret != EXYNOS_DP_SUCCESS) {
448                 printf("DP set_enhanced_mode() failed\n");
449                 priv->lt_info.lt_status = DP_LT_FAIL;
450         }
451
452         return ret;
453 }
454
455 static int exynos_dp_reduce_link_rate(struct exynos_dp *regs,
456                                       struct exynos_dp_priv *priv)
457 {
458         int ret;
459
460         if (priv->lane_bw == DP_LANE_BW_2_70) {
461                 priv->lane_bw = DP_LANE_BW_1_62;
462                 printf("DP Change lane bw to 1.62Gbps\n");
463                 priv->lt_info.lt_status = DP_LT_START;
464                 ret = EXYNOS_DP_SUCCESS;
465         } else {
466                 ret = exynos_dp_training_pattern_dis(regs);
467                 if (ret != EXYNOS_DP_SUCCESS)
468                         printf("DP training_patter_disable() failed\n");
469
470                 ret = exynos_dp_set_enhanced_mode(regs, priv->dpcd_efc);
471                 if (ret != EXYNOS_DP_SUCCESS)
472                         printf("DP set_enhanced_mode() failed\n");
473
474                 priv->lt_info.lt_status = DP_LT_FAIL;
475         }
476
477         return ret;
478 }
479
480 static unsigned int exynos_dp_process_clock_recovery(struct exynos_dp *regs,
481                                         struct exynos_dp_priv *priv)
482 {
483         unsigned int ret = EXYNOS_DP_SUCCESS;
484         unsigned char lane_stat;
485         unsigned char lt_ctl_val[DP_LANE_CNT_4] = {0, };
486         unsigned int i;
487         unsigned char adj_req_sw;
488         unsigned char adj_req_em;
489         unsigned char buf[5];
490
491         debug("DP: %s was called\n", __func__);
492         mdelay(1);
493
494         ret = exynos_dp_read_dpcd_lane_stat(regs, priv, &lane_stat);
495         if (ret != EXYNOS_DP_SUCCESS) {
496                         printf("DP read lane status failed\n");
497                         priv->lt_info.lt_status = DP_LT_FAIL;
498                         return ret;
499         }
500
501         if (lane_stat & DP_LANE_STAT_CR_DONE) {
502                 debug("DP clock Recovery training succeed\n");
503                 exynos_dp_set_training_pattern(regs, TRAINING_PTN2);
504
505                 for (i = 0; i < priv->lane_cnt; i++) {
506                         ret = exynos_dp_read_dpcd_adj_req(regs, i,
507                                                 &adj_req_sw, &adj_req_em);
508                         if (ret != EXYNOS_DP_SUCCESS) {
509                                 priv->lt_info.lt_status = DP_LT_FAIL;
510                                 return ret;
511                         }
512
513                         lt_ctl_val[i] = 0;
514                         lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw;
515
516                         if ((adj_req_sw == VOLTAGE_LEVEL_3)
517                                 || (adj_req_em == PRE_EMPHASIS_LEVEL_3)) {
518                                 lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3 |
519                                         MAX_PRE_EMPHASIS_REACH_3;
520                         }
521                         exynos_dp_set_lanex_pre_emphasis(regs,
522                                                          lt_ctl_val[i], i);
523                 }
524
525                 buf[0] =  DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_2;
526                 buf[1] = lt_ctl_val[0];
527                 buf[2] = lt_ctl_val[1];
528                 buf[3] = lt_ctl_val[2];
529                 buf[4] = lt_ctl_val[3];
530
531                 ret = exynos_dp_write_bytes_to_dpcd(regs,
532                                 DPCD_TRAINING_PATTERN_SET, 5, buf);
533                 if (ret != EXYNOS_DP_SUCCESS) {
534                         printf("DP write training pattern1 failed\n");
535                         priv->lt_info.lt_status = DP_LT_FAIL;
536                         return ret;
537                 } else
538                         priv->lt_info.lt_status = DP_LT_ET;
539         } else {
540                 for (i = 0; i < priv->lane_cnt; i++) {
541                         lt_ctl_val[i] = exynos_dp_get_lanex_pre_emphasis(
542                                                 regs, i);
543                                 ret = exynos_dp_read_dpcd_adj_req(regs, i,
544                                                 &adj_req_sw, &adj_req_em);
545                         if (ret != EXYNOS_DP_SUCCESS) {
546                                 printf("DP read adj req failed\n");
547                                 priv->lt_info.lt_status = DP_LT_FAIL;
548                                 return ret;
549                         }
550
551                         if ((adj_req_sw == VOLTAGE_LEVEL_3) ||
552                                         (adj_req_em == PRE_EMPHASIS_LEVEL_3))
553                                 ret = exynos_dp_reduce_link_rate(regs,
554                                                                  priv);
555
556                         if ((DRIVE_CURRENT_SET_0_GET(lt_ctl_val[i]) ==
557                                                 adj_req_sw) &&
558                                 (PRE_EMPHASIS_SET_0_GET(lt_ctl_val[i]) ==
559                                                 adj_req_em)) {
560                                 priv->lt_info.cr_loop[i]++;
561                                 if (priv->lt_info.cr_loop[i] == MAX_CR_LOOP)
562                                         ret = exynos_dp_reduce_link_rate(
563                                                         regs, priv);
564                         }
565
566                         lt_ctl_val[i] = 0;
567                         lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw;
568
569                         if ((adj_req_sw == VOLTAGE_LEVEL_3) ||
570                                         (adj_req_em == PRE_EMPHASIS_LEVEL_3)) {
571                                 lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3 |
572                                         MAX_PRE_EMPHASIS_REACH_3;
573                         }
574                         exynos_dp_set_lanex_pre_emphasis(regs,
575                                                          lt_ctl_val[i], i);
576                 }
577
578                 ret = exynos_dp_write_bytes_to_dpcd(regs,
579                                 DPCD_TRAINING_LANE0_SET, 4, lt_ctl_val);
580                 if (ret != EXYNOS_DP_SUCCESS) {
581                         printf("DP write training pattern2 failed\n");
582                         priv->lt_info.lt_status = DP_LT_FAIL;
583                         return ret;
584                 }
585         }
586
587         return ret;
588 }
589
590 static unsigned int exynos_dp_process_equalizer_training(
591                 struct exynos_dp *regs, struct exynos_dp_priv *priv)
592 {
593         unsigned int ret = EXYNOS_DP_SUCCESS;
594         unsigned char lane_stat, adj_req_sw, adj_req_em, i;
595         unsigned char lt_ctl_val[DP_LANE_CNT_4] = {0,};
596         unsigned char interlane_aligned = 0;
597         unsigned char f_bw;
598         unsigned char f_lane_cnt;
599         unsigned char sink_stat;
600
601         mdelay(1);
602
603         ret = exynos_dp_read_dpcd_lane_stat(regs, priv, &lane_stat);
604         if (ret != EXYNOS_DP_SUCCESS) {
605                 printf("DP read lane status failed\n");
606                 priv->lt_info.lt_status = DP_LT_FAIL;
607                 return ret;
608         }
609
610         debug("DP lane stat : %x\n", lane_stat);
611
612         if (lane_stat & DP_LANE_STAT_CR_DONE) {
613                 ret = exynos_dp_read_byte_from_dpcd(regs,
614                                                     DPCD_LN_ALIGN_UPDATED,
615                                                     &sink_stat);
616                 if (ret != EXYNOS_DP_SUCCESS) {
617                         priv->lt_info.lt_status = DP_LT_FAIL;
618
619                         return ret;
620                 }
621
622                 interlane_aligned = (sink_stat & DPCD_INTERLANE_ALIGN_DONE);
623
624                 for (i = 0; i < priv->lane_cnt; i++) {
625                         ret = exynos_dp_read_dpcd_adj_req(regs, i,
626                                         &adj_req_sw, &adj_req_em);
627                         if (ret != EXYNOS_DP_SUCCESS) {
628                                 printf("DP read adj req 1 failed\n");
629                                 priv->lt_info.lt_status = DP_LT_FAIL;
630
631                                 return ret;
632                         }
633
634                         lt_ctl_val[i] = 0;
635                         lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw;
636
637                         if ((adj_req_sw == VOLTAGE_LEVEL_3) ||
638                                 (adj_req_em == PRE_EMPHASIS_LEVEL_3)) {
639                                 lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3;
640                                 lt_ctl_val[i] |= MAX_PRE_EMPHASIS_REACH_3;
641                         }
642                 }
643
644                 if (((lane_stat&DP_LANE_STAT_CE_DONE) &&
645                         (lane_stat&DP_LANE_STAT_SYM_LOCK))
646                         && (interlane_aligned == DPCD_INTERLANE_ALIGN_DONE)) {
647                         debug("DP Equalizer training succeed\n");
648
649                         f_bw = exynos_dp_get_link_bandwidth(regs);
650                         f_lane_cnt = exynos_dp_get_lane_count(regs);
651
652                         debug("DP final BandWidth : %x\n", f_bw);
653                         debug("DP final Lane Count : %x\n", f_lane_cnt);
654
655                         priv->lt_info.lt_status = DP_LT_FINISHED;
656
657                         exynos_dp_equalizer_err_link(regs, priv);
658
659                 } else {
660                         priv->lt_info.ep_loop++;
661
662                         if (priv->lt_info.ep_loop > MAX_EQ_LOOP) {
663                                 if (priv->lane_bw == DP_LANE_BW_2_70) {
664                                         ret = exynos_dp_reduce_link_rate(
665                                                         regs, priv);
666                                 } else {
667                                         priv->lt_info.lt_status =
668                                                                 DP_LT_FAIL;
669                                         exynos_dp_equalizer_err_link(regs,
670                                                                      priv);
671                                 }
672                         } else {
673                                 for (i = 0; i < priv->lane_cnt; i++)
674                                         exynos_dp_set_lanex_pre_emphasis(
675                                                 regs, lt_ctl_val[i], i);
676
677                                 ret = exynos_dp_write_bytes_to_dpcd(regs,
678                                                 DPCD_TRAINING_LANE0_SET,
679                                                 4, lt_ctl_val);
680                                 if (ret != EXYNOS_DP_SUCCESS) {
681                                         printf("DP set lt pattern failed\n");
682                                         priv->lt_info.lt_status =
683                                                                 DP_LT_FAIL;
684                                         exynos_dp_equalizer_err_link(regs,
685                                                                      priv);
686                                 }
687                         }
688                 }
689         } else if (priv->lane_bw == DP_LANE_BW_2_70) {
690                 ret = exynos_dp_reduce_link_rate(regs, priv);
691         } else {
692                 priv->lt_info.lt_status = DP_LT_FAIL;
693                 exynos_dp_equalizer_err_link(regs, priv);
694         }
695
696         return ret;
697 }
698
699 static unsigned int exynos_dp_sw_link_training(struct exynos_dp *regs,
700                                                struct exynos_dp_priv *priv)
701 {
702         unsigned int ret = 0;
703         int training_finished;
704
705         /* Turn off unnecessary lane */
706         if (priv->lane_cnt == 1)
707                 exynos_dp_set_analog_power_down(regs, CH1_BLOCK, 1);
708
709         training_finished = 0;
710
711         priv->lt_info.lt_status = DP_LT_START;
712
713         /* Process here */
714         while (!training_finished) {
715                 switch (priv->lt_info.lt_status) {
716                 case DP_LT_START:
717                         ret = exynos_dp_link_start(regs, priv);
718                         if (ret != EXYNOS_DP_SUCCESS) {
719                                 printf("DP LT:link start failed\n");
720                                 return ret;
721                         }
722                         break;
723                 case DP_LT_CR:
724                         ret = exynos_dp_process_clock_recovery(regs,
725                                                                priv);
726                         if (ret != EXYNOS_DP_SUCCESS) {
727                                 printf("DP LT:clock recovery failed\n");
728                                 return ret;
729                         }
730                         break;
731                 case DP_LT_ET:
732                         ret = exynos_dp_process_equalizer_training(regs,
733                                                                    priv);
734                         if (ret != EXYNOS_DP_SUCCESS) {
735                                 printf("DP LT:equalizer training failed\n");
736                                 return ret;
737                         }
738                         break;
739                 case DP_LT_FINISHED:
740                         training_finished = 1;
741                         break;
742                 case DP_LT_FAIL:
743                         return -1;
744                 }
745         }
746
747         return ret;
748 }
749
750 static unsigned int exynos_dp_set_link_train(struct exynos_dp *regs,
751                                              struct exynos_dp_priv *priv)
752 {
753         unsigned int ret;
754
755         exynos_dp_init_training(regs);
756
757         ret = exynos_dp_sw_link_training(regs, priv);
758         if (ret != EXYNOS_DP_SUCCESS)
759                 printf("DP dp_sw_link_training() failed\n");
760
761         return ret;
762 }
763
764 static void exynos_dp_enable_scramble(struct exynos_dp *regs,
765                                       unsigned int enable)
766 {
767         unsigned char data;
768
769         if (enable) {
770                 exynos_dp_enable_scrambling(regs, DP_ENABLE);
771
772                 exynos_dp_read_byte_from_dpcd(regs,
773                                               DPCD_TRAINING_PATTERN_SET, &data);
774                 exynos_dp_write_byte_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
775                         (u8)(data & ~DPCD_SCRAMBLING_DISABLED));
776         } else {
777                 exynos_dp_enable_scrambling(regs, DP_DISABLE);
778                 exynos_dp_read_byte_from_dpcd(regs,
779                                               DPCD_TRAINING_PATTERN_SET, &data);
780                 exynos_dp_write_byte_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
781                         (u8)(data | DPCD_SCRAMBLING_DISABLED));
782         }
783 }
784
785 static unsigned int exynos_dp_config_video(struct exynos_dp *regs,
786                                            struct exynos_dp_priv *priv)
787 {
788         unsigned int ret = 0;
789         unsigned int retry_cnt;
790
791         mdelay(1);
792
793         if (priv->video_info.master_mode) {
794                 printf("DP does not support master mode\n");
795                 return -ENODEV;
796         } else {
797                 /* debug slave */
798                 exynos_dp_config_video_slave_mode(regs,
799                                                   &priv->video_info);
800         }
801
802         exynos_dp_set_video_color_format(regs, &priv->video_info);
803
804         if (priv->video_info.bist_mode) {
805                 if (exynos_dp_config_video_bist(regs, priv) != 0)
806                         return -1;
807         }
808
809         ret = exynos_dp_get_pll_lock_status(regs);
810         if (ret != PLL_LOCKED) {
811                 printf("DP PLL is not locked yet\n");
812                 return -EIO;
813         }
814
815         if (priv->video_info.master_mode == 0) {
816                 retry_cnt = 10;
817                 while (retry_cnt) {
818                         ret = exynos_dp_is_slave_video_stream_clock_on(regs);
819                         if (ret != EXYNOS_DP_SUCCESS) {
820                                 if (retry_cnt == 0) {
821                                         printf("DP stream_clock_on failed\n");
822                                         return ret;
823                                 }
824                                 retry_cnt--;
825                                 mdelay(1);
826                         } else
827                                 break;
828                 }
829         }
830
831         /* Set to use the register calculated M/N video */
832         exynos_dp_set_video_cr_mn(regs, CALCULATED_M, 0, 0);
833
834         /* For video bist, Video timing must be generated by register */
835         exynos_dp_set_video_timing_mode(regs, VIDEO_TIMING_FROM_CAPTURE);
836
837         /* Enable video bist */
838         if (priv->video_info.bist_pattern != COLOR_RAMP &&
839                 priv->video_info.bist_pattern != BALCK_WHITE_V_LINES &&
840                 priv->video_info.bist_pattern != COLOR_SQUARE)
841                 exynos_dp_enable_video_bist(regs,
842                                             priv->video_info.bist_mode);
843         else
844                 exynos_dp_enable_video_bist(regs, DP_DISABLE);
845
846         /* Disable video mute */
847         exynos_dp_enable_video_mute(regs, DP_DISABLE);
848
849         /* Configure video Master or Slave mode */
850         exynos_dp_enable_video_master(regs,
851                                       priv->video_info.master_mode);
852
853         /* Enable video */
854         exynos_dp_start_video(regs);
855
856         if (priv->video_info.master_mode == 0) {
857                 retry_cnt = 100;
858                 while (retry_cnt) {
859                         ret = exynos_dp_is_video_stream_on(regs);
860                         if (ret != EXYNOS_DP_SUCCESS) {
861                                 if (retry_cnt == 0) {
862                                         printf("DP Timeout of video stream\n");
863                                         return ret;
864                                 }
865                                 retry_cnt--;
866                                 mdelay(5);
867                         } else
868                                 break;
869                 }
870         }
871
872         return ret;
873 }
874
875 int exynos_dp_parse_dt(const void *blob, struct exynos_dp_priv *priv)
876 {
877         unsigned int node = fdtdec_next_compatible(blob, 0,
878                                                 COMPAT_SAMSUNG_EXYNOS5_DP);
879         if (node <= 0) {
880                 debug("exynos_dp: Can't get device node for dp\n");
881                 return -ENODEV;
882         }
883
884         priv->disp_info.h_res = fdtdec_get_int(blob, node,
885                                                         "samsung,h-res", 0);
886         priv->disp_info.h_sync_width = fdtdec_get_int(blob, node,
887                                                 "samsung,h-sync-width", 0);
888         priv->disp_info.h_back_porch = fdtdec_get_int(blob, node,
889                                                 "samsung,h-back-porch", 0);
890         priv->disp_info.h_front_porch = fdtdec_get_int(blob, node,
891                                                 "samsung,h-front-porch", 0);
892         priv->disp_info.v_res = fdtdec_get_int(blob, node,
893                                                 "samsung,v-res", 0);
894         priv->disp_info.v_sync_width = fdtdec_get_int(blob, node,
895                                                 "samsung,v-sync-width", 0);
896         priv->disp_info.v_back_porch = fdtdec_get_int(blob, node,
897                                                 "samsung,v-back-porch", 0);
898         priv->disp_info.v_front_porch = fdtdec_get_int(blob, node,
899                                                 "samsung,v-front-porch", 0);
900         priv->disp_info.v_sync_rate = fdtdec_get_int(blob, node,
901                                                 "samsung,v-sync-rate", 0);
902
903         priv->lt_info.lt_status = fdtdec_get_int(blob, node,
904                                                 "samsung,lt-status", 0);
905
906         priv->video_info.master_mode = fdtdec_get_int(blob, node,
907                                                 "samsung,master-mode", 0);
908         priv->video_info.bist_mode = fdtdec_get_int(blob, node,
909                                                 "samsung,bist-mode", 0);
910         priv->video_info.bist_pattern = fdtdec_get_int(blob, node,
911                                                 "samsung,bist-pattern", 0);
912         priv->video_info.h_sync_polarity = fdtdec_get_int(blob, node,
913                                                 "samsung,h-sync-polarity", 0);
914         priv->video_info.v_sync_polarity = fdtdec_get_int(blob, node,
915                                                 "samsung,v-sync-polarity", 0);
916         priv->video_info.interlaced = fdtdec_get_int(blob, node,
917                                                 "samsung,interlaced", 0);
918         priv->video_info.color_space = fdtdec_get_int(blob, node,
919                                                 "samsung,color-space", 0);
920         priv->video_info.dynamic_range = fdtdec_get_int(blob, node,
921                                                 "samsung,dynamic-range", 0);
922         priv->video_info.ycbcr_coeff = fdtdec_get_int(blob, node,
923                                                 "samsung,ycbcr-coeff", 0);
924         priv->video_info.color_depth = fdtdec_get_int(blob, node,
925                                                 "samsung,color-depth", 0);
926         return 0;
927 }
928
929 unsigned int exynos_init_dp(void)
930 {
931         unsigned int ret;
932         struct exynos_dp_priv *priv;
933         struct exynos_dp *regs;
934         int node;
935
936         priv = kzalloc(sizeof(struct exynos_dp_priv), GFP_KERNEL);
937         if (!priv) {
938                 debug("failed to allocate edp device object.\n");
939                 return -EFAULT;
940         }
941
942         if (exynos_dp_parse_dt(gd->fdt_blob, priv))
943                 debug("unable to parse DP DT node\n");
944
945         node = fdtdec_next_compatible(gd->fdt_blob, 0,
946                                       COMPAT_SAMSUNG_EXYNOS5_DP);
947         if (node <= 0)
948                 debug("exynos_dp: Can't get device node for dp\n");
949
950         regs = (struct exynos_dp *)fdtdec_get_addr(gd->fdt_blob, node,
951                                                       "reg");
952         if (regs == NULL)
953                 debug("Can't get the DP base address\n");
954
955         exynos_dp_disp_info(&priv->disp_info);
956
957         exynos_dp_phy_ctrl(1);
958
959         ret = exynos_dp_init_dp(regs);
960         if (ret != EXYNOS_DP_SUCCESS) {
961                 printf("DP exynos_dp_init_dp() failed\n");
962                 return ret;
963         }
964
965         ret = exynos_dp_handle_edid(regs, priv);
966         if (ret != EXYNOS_DP_SUCCESS) {
967                 printf("EDP handle_edid fail\n");
968                 return ret;
969         }
970
971         ret = exynos_dp_set_link_train(regs, priv);
972         if (ret != EXYNOS_DP_SUCCESS) {
973                 printf("DP link training fail\n");
974                 return ret;
975         }
976
977         exynos_dp_enable_scramble(regs, DP_ENABLE);
978         exynos_dp_enable_rx_to_enhanced_mode(regs, DP_ENABLE);
979         exynos_dp_enable_enhanced_mode(regs, DP_ENABLE);
980
981         exynos_dp_set_link_bandwidth(regs, priv->lane_bw);
982         exynos_dp_set_lane_count(regs, priv->lane_cnt);
983
984         exynos_dp_init_video(regs);
985         ret = exynos_dp_config_video(regs, priv);
986         if (ret != EXYNOS_DP_SUCCESS) {
987                 printf("Exynos DP init failed\n");
988                 return ret;
989         }
990
991         debug("Exynos DP init done\n");
992
993         return ret;
994 }