]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/video/exynos_dp.c
pcm051: use ti_am335x_common.h config
[karo-tx-uboot.git] / drivers / video / 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/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>
17 #include <fdtdec.h>
18 #include <libfdt.h>
19
20 #include "exynos_dp_lowlevel.h"
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 static struct exynos_dp_platform_data *dp_pd;
25
26 void __exynos_set_dp_phy(unsigned int onoff)
27 {
28 }
29 void exynos_set_dp_phy(unsigned int onoff)
30         __attribute__((weak, alias("__exynos_set_dp_phy")));
31
32 static void exynos_dp_disp_info(struct edp_disp_info *disp_info)
33 {
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;
38
39         return;
40 }
41
42 static int exynos_dp_init_dp(void)
43 {
44         int ret;
45         exynos_dp_reset();
46
47         /* SW defined function Normal operation */
48         exynos_dp_enable_sw_func(DP_ENABLE);
49
50         ret = exynos_dp_init_analog_func();
51         if (ret != EXYNOS_DP_SUCCESS)
52                 return ret;
53
54         exynos_dp_init_hpd();
55         exynos_dp_init_aux();
56
57         return ret;
58 }
59
60 static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
61 {
62         int i;
63         unsigned char sum = 0;
64
65         for (i = 0; i < EDID_BLOCK_LENGTH; i++)
66                 sum = sum + edid_data[i];
67
68         return sum;
69 }
70
71 static unsigned int exynos_dp_read_edid(void)
72 {
73         unsigned char edid[EDID_BLOCK_LENGTH * 2];
74         unsigned int extend_block = 0;
75         unsigned char sum;
76         unsigned char test_vector;
77         int retval;
78
79         /*
80          * EDID device address is 0x50.
81          * However, if necessary, you must have set upper address
82          * into E-EDID in I2C device, 0x30.
83          */
84
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,
87                         &extend_block);
88
89         if (extend_block > 0) {
90                 printf("DP EDID data includes a single extension!\n");
91
92                 /* Read EDID data */
93                 retval = exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR,
94                                                 EDID_HEADER_PATTERN,
95                                                 EDID_BLOCK_LENGTH,
96                                                 &edid[EDID_HEADER_PATTERN]);
97                 if (retval != 0) {
98                         printf("DP EDID Read failed!\n");
99                         return -1;
100                 }
101                 sum = exynos_dp_calc_edid_check_sum(edid);
102                 if (sum != 0) {
103                         printf("DP EDID bad checksum!\n");
104                         return -1;
105                 }
106
107                 /* Read additional EDID data */
108                 retval = exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR,
109                                 EDID_BLOCK_LENGTH,
110                                 EDID_BLOCK_LENGTH,
111                                 &edid[EDID_BLOCK_LENGTH]);
112                 if (retval != 0) {
113                         printf("DP EDID Read failed!\n");
114                         return -1;
115                 }
116                 sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
117                 if (sum != 0) {
118                         printf("DP EDID bad checksum!\n");
119                         return -1;
120                 }
121
122                 exynos_dp_read_byte_from_dpcd(DPCD_TEST_REQUEST,
123                                         &test_vector);
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);
129                 }
130         } else {
131                 debug("DP EDID data does not include any extensions.\n");
132
133                 /* Read EDID data */
134                 retval = exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR,
135                                 EDID_HEADER_PATTERN,
136                                 EDID_BLOCK_LENGTH,
137                                 &edid[EDID_HEADER_PATTERN]);
138
139                 if (retval != 0) {
140                         printf("DP EDID Read failed!\n");
141                         return -1;
142                 }
143                 sum = exynos_dp_calc_edid_check_sum(edid);
144                 if (sum != 0) {
145                         printf("DP EDID bad checksum!\n");
146                         return -1;
147                 }
148
149                 exynos_dp_read_byte_from_dpcd(DPCD_TEST_REQUEST,
150                         &test_vector);
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);
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 edp_device_info *edp_info)
165 {
166         unsigned char buf[12];
167         unsigned int ret;
168         unsigned char temp;
169         unsigned char retry_cnt;
170         unsigned char dpcd_rev[16];
171         unsigned char lane_bw[16];
172         unsigned char lane_cnt[16];
173
174         memset(dpcd_rev, 0, 16);
175         memset(lane_bw, 0, 16);
176         memset(lane_cnt, 0, 16);
177         memset(buf, 0, 12);
178
179         retry_cnt = 5;
180         while (retry_cnt) {
181                 /* Read DPCD 0x0000-0x000b */
182                 ret = exynos_dp_read_bytes_from_dpcd(DPCD_DPCD_REV, 12,
183                                 buf);
184                 if (ret != EXYNOS_DP_SUCCESS) {
185                         if (retry_cnt == 0) {
186                                 printf("DP read_byte_from_dpcd() failed\n");
187                                 return ret;
188                         }
189                         retry_cnt--;
190                 } else
191                         break;
192         }
193
194         /* */
195         temp = buf[DPCD_DPCD_REV];
196         if (temp == DP_DPCD_REV_10 || temp == DP_DPCD_REV_11)
197                 edp_info->dpcd_rev = temp;
198         else {
199                 printf("DP Wrong DPCD Rev : %x\n", temp);
200                 return -ENODEV;
201         }
202
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;
206         else {
207                 printf("DP Wrong MAX LINK RATE : %x\n", temp);
208                 return -EINVAL;
209         }
210
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;
216                 else
217                         edp_info->dpcd_efc = 0;
218         } else {
219                 temp = buf[DPCD_MAX_LANE_COUNT];
220                 edp_info->dpcd_efc = 0;
221         }
222
223         if (temp == DP_LANE_CNT_1 || temp == DP_LANE_CNT_2 ||
224                         temp == DP_LANE_CNT_4) {
225                 edp_info->lane_cnt = temp;
226         } else {
227                 printf("DP Wrong MAX LANE COUNT : %x\n", temp);
228                 return -EINVAL;
229         }
230
231         ret = exynos_dp_read_edid();
232         if (ret != EXYNOS_DP_SUCCESS) {
233                 printf("DP exynos_dp_read_edid() failed\n");
234                 return -EINVAL;
235         }
236
237         return ret;
238 }
239
240 static void exynos_dp_init_training(void)
241 {
242         /*
243          * MACRO_RST must be applied after the PLL_LOCK to avoid
244          * the DP inter pair skew issue for at least 10 us
245          */
246         exynos_dp_reset_macro();
247
248         /* All DP analog module power up */
249         exynos_dp_set_analog_power_down(POWER_ALL, 0);
250 }
251
252 static unsigned int exynos_dp_link_start(struct edp_device_info *edp_info)
253 {
254         unsigned char buf[5];
255         unsigned int ret = 0;
256
257         debug("DP: %s was called\n", __func__);
258
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;
265
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");
271                 return ret;
272         }
273
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);
277
278         /* Setup RX configuration */
279         buf[0] = edp_info->lane_bw;
280         buf[1] = edp_info->lane_cnt;
281
282         ret = exynos_dp_write_bytes_to_dpcd(DPCD_LINK_BW_SET, 2,
283                         buf);
284         if (ret != EXYNOS_DP_SUCCESS) {
285                 printf("DP write_dpcd_byte failed\n");
286                 return ret;
287         }
288
289         exynos_dp_set_lane_pre_emphasis(PRE_EMPHASIS_LEVEL_0,
290                         edp_info->lane_cnt);
291
292         /* Set training pattern 1 */
293         exynos_dp_set_training_pattern(TRAINING_PTN1);
294
295         /* Set RX training pattern */
296         buf[0] = DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1;
297
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;
306
307         ret = exynos_dp_write_bytes_to_dpcd(DPCD_TRAINING_PATTERN_SET,
308                         5, buf);
309         if (ret != EXYNOS_DP_SUCCESS) {
310                 printf("DP write_dpcd_byte failed\n");
311                 return ret;
312         }
313
314         return ret;
315 }
316
317 static unsigned int exynos_dp_training_pattern_dis(void)
318 {
319         unsigned int ret = EXYNOS_DP_SUCCESS;
320
321         exynos_dp_set_training_pattern(DP_NONE);
322
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");
327                 return -EAGAIN;
328         }
329
330         return ret;
331 }
332
333 static unsigned int exynos_dp_enable_rx_to_enhanced_mode(unsigned char enable)
334 {
335         unsigned char data;
336         unsigned int ret = EXYNOS_DP_SUCCESS;
337
338         ret = exynos_dp_read_byte_from_dpcd(DPCD_LANE_COUNT_SET,
339                         &data);
340         if (ret != EXYNOS_DP_SUCCESS) {
341                 printf("DP read_from_dpcd failed\n");
342                 return -EAGAIN;
343         }
344
345         if (enable)
346                 data = DPCD_ENHANCED_FRAME_EN | DPCD_LN_COUNT_SET(data);
347         else
348                 data = DPCD_LN_COUNT_SET(data);
349
350         ret = exynos_dp_write_byte_to_dpcd(DPCD_LANE_COUNT_SET,
351                         data);
352         if (ret != EXYNOS_DP_SUCCESS) {
353                         printf("DP write_to_dpcd failed\n");
354                         return -EAGAIN;
355
356         }
357
358         return ret;
359 }
360
361 static unsigned int exynos_dp_set_enhanced_mode(unsigned char enhance_mode)
362 {
363         unsigned int ret = EXYNOS_DP_SUCCESS;
364
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");
368                 return -EAGAIN;
369         }
370
371         exynos_dp_enable_enhanced_mode(enhance_mode);
372
373         return ret;
374 }
375
376 static int exynos_dp_read_dpcd_lane_stat(struct edp_device_info *edp_info,
377                 unsigned char *status)
378 {
379         unsigned int ret, i;
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,};
383
384         shift_val[0] = 0;
385         shift_val[1] = 4;
386         shift_val[2] = 0;
387         shift_val[3] = 4;
388
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");
392                 return ret;
393         }
394
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");
399                         return -EINVAL;
400                 }
401         }
402
403         *status = lane_stat[0];
404
405         return ret;
406 }
407
408 static unsigned int exynos_dp_read_dpcd_adj_req(unsigned char lane_num,
409                 unsigned char *sw, unsigned char *em)
410 {
411         unsigned int ret = EXYNOS_DP_SUCCESS;
412         unsigned char buf;
413         unsigned int dpcd_addr;
414         unsigned char shift_val[DP_LANE_CNT_4] = {0, 4, 0, 4};
415
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);
418
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");
422                 return -EAGAIN;
423         }
424
425         *sw = ((buf >> shift_val[lane_num]) & 0x03);
426         *em = ((buf >> shift_val[lane_num]) & 0x0c) >> 2;
427
428         return ret;
429 }
430
431 static int exynos_dp_equalizer_err_link(struct edp_device_info *edp_info)
432 {
433         int ret;
434
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;
439         }
440
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;
445         }
446
447         return ret;
448 }
449
450 static int exynos_dp_reduce_link_rate(struct edp_device_info *edp_info)
451 {
452         int ret;
453
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;
459         } else {
460                 ret = exynos_dp_training_pattern_dis();
461                 if (ret != EXYNOS_DP_SUCCESS)
462                         printf("DP training_patter_disable() failed\n");
463
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");
467
468                 edp_info->lt_info.lt_status = DP_LT_FAIL;
469         }
470
471         return ret;
472 }
473
474 static unsigned int exynos_dp_process_clock_recovery(struct edp_device_info
475                                                         *edp_info)
476 {
477         unsigned int ret = EXYNOS_DP_SUCCESS;
478         unsigned char lane_stat;
479         unsigned char lt_ctl_val[DP_LANE_CNT_4] = {0, };
480         unsigned int i;
481         unsigned char adj_req_sw;
482         unsigned char adj_req_em;
483         unsigned char buf[5];
484
485         debug("DP: %s was called\n", __func__);
486         mdelay(1);
487
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;
492                         return ret;
493         }
494
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);
498
499                 for (i = 0; i < edp_info->lane_cnt; i++) {
500                         ret = exynos_dp_read_dpcd_adj_req(i, &adj_req_sw,
501                                         &adj_req_em);
502                         if (ret != EXYNOS_DP_SUCCESS) {
503                                 edp_info->lt_info.lt_status = DP_LT_FAIL;
504                                 return ret;
505                         }
506
507                         lt_ctl_val[i] = 0;
508                         lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw;
509
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;
514                         }
515                         exynos_dp_set_lanex_pre_emphasis(lt_ctl_val[i], i);
516                 }
517
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];
523
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;
529                         return ret;
530                 } else
531                         edp_info->lt_info.lt_status = DP_LT_ET;
532         } else {
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;
540                                 return ret;
541                         }
542
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);
546
547                         if ((DRIVE_CURRENT_SET_0_GET(lt_ctl_val[i]) ==
548                                                 adj_req_sw) &&
549                                 (PRE_EMPHASIS_SET_0_GET(lt_ctl_val[i]) ==
550                                                 adj_req_em)) {
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(
554                                                         edp_info);
555                         }
556
557                         lt_ctl_val[i] = 0;
558                         lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw;
559
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;
564                         }
565                         exynos_dp_set_lanex_pre_emphasis(lt_ctl_val[i], i);
566                 }
567
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;
573                         return ret;
574                 }
575         }
576
577         return ret;
578 }
579
580 static unsigned int exynos_dp_process_equalizer_training(struct edp_device_info
581                 *edp_info)
582 {
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;
587         unsigned char f_bw;
588         unsigned char f_lane_cnt;
589         unsigned char sink_stat;
590
591         mdelay(1);
592
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;
597                 return ret;
598         }
599
600         debug("DP lane stat : %x\n", lane_stat);
601
602         if (lane_stat & DP_LANE_STAT_CR_DONE) {
603                 ret = exynos_dp_read_byte_from_dpcd(DPCD_LN_ALIGN_UPDATED,
604                                 &sink_stat);
605                 if (ret != EXYNOS_DP_SUCCESS) {
606                         edp_info->lt_info.lt_status = DP_LT_FAIL;
607
608                         return ret;
609                 }
610
611                 interlane_aligned = (sink_stat & DPCD_INTERLANE_ALIGN_DONE);
612
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;
619
620                                 return ret;
621                         }
622
623                         lt_ctl_val[i] = 0;
624                         lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw;
625
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;
630                         }
631                 }
632
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");
637
638                         f_bw = exynos_dp_get_link_bandwidth();
639                         f_lane_cnt = exynos_dp_get_lane_count();
640
641                         debug("DP final BandWidth : %x\n", f_bw);
642                         debug("DP final Lane Count : %x\n", f_lane_cnt);
643
644                         edp_info->lt_info.lt_status = DP_LT_FINISHED;
645
646                         exynos_dp_equalizer_err_link(edp_info);
647
648                 } else {
649                         edp_info->lt_info.ep_loop++;
650
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(
654                                                         edp_info);
655                                 } else {
656                                         edp_info->lt_info.lt_status =
657                                                                 DP_LT_FAIL;
658                                         exynos_dp_equalizer_err_link(edp_info);
659                                 }
660                         } else {
661                                 for (i = 0; i < edp_info->lane_cnt; i++)
662                                         exynos_dp_set_lanex_pre_emphasis(
663                                                         lt_ctl_val[i], i);
664
665                                 ret = exynos_dp_write_bytes_to_dpcd(
666                                         DPCD_TRAINING_LANE0_SET,
667                                         4, lt_ctl_val);
668                                 if (ret != EXYNOS_DP_SUCCESS) {
669                                         printf("DP set lt pattern failed\n");
670                                         edp_info->lt_info.lt_status =
671                                                                 DP_LT_FAIL;
672                                         exynos_dp_equalizer_err_link(edp_info);
673                                 }
674                         }
675                 }
676         } else if (edp_info->lane_bw == DP_LANE_BW_2_70) {
677                 ret = exynos_dp_reduce_link_rate(edp_info);
678         } else {
679                 edp_info->lt_info.lt_status = DP_LT_FAIL;
680                 exynos_dp_equalizer_err_link(edp_info);
681         }
682
683         return ret;
684 }
685
686 static unsigned int exynos_dp_sw_link_training(struct edp_device_info *edp_info)
687 {
688         unsigned int ret = 0;
689         int training_finished;
690
691         /* Turn off unnecessary lane */
692         if (edp_info->lane_cnt == 1)
693                 exynos_dp_set_analog_power_down(CH1_BLOCK, 1);
694
695         training_finished = 0;
696
697         edp_info->lt_info.lt_status = DP_LT_START;
698
699         /* Process here */
700         while (!training_finished) {
701                 switch (edp_info->lt_info.lt_status) {
702                 case DP_LT_START:
703                         ret = exynos_dp_link_start(edp_info);
704                         if (ret != EXYNOS_DP_SUCCESS) {
705                                 printf("DP LT:link start failed\n");
706                                 return ret;
707                         }
708                         break;
709                 case DP_LT_CR:
710                         ret = exynos_dp_process_clock_recovery(edp_info);
711                         if (ret != EXYNOS_DP_SUCCESS) {
712                                 printf("DP LT:clock recovery failed\n");
713                                 return ret;
714                         }
715                         break;
716                 case DP_LT_ET:
717                         ret = exynos_dp_process_equalizer_training(edp_info);
718                         if (ret != EXYNOS_DP_SUCCESS) {
719                                 printf("DP LT:equalizer training failed\n");
720                                 return ret;
721                         }
722                         break;
723                 case DP_LT_FINISHED:
724                         training_finished = 1;
725                         break;
726                 case DP_LT_FAIL:
727                         return -1;
728                 }
729         }
730
731         return ret;
732 }
733
734 static unsigned int exynos_dp_set_link_train(struct edp_device_info *edp_info)
735 {
736         unsigned int ret;
737
738         exynos_dp_init_training();
739
740         ret = exynos_dp_sw_link_training(edp_info);
741         if (ret != EXYNOS_DP_SUCCESS)
742                 printf("DP dp_sw_link_traning() failed\n");
743
744         return ret;
745 }
746
747 static void exynos_dp_enable_scramble(unsigned int enable)
748 {
749         unsigned char data;
750
751         if (enable) {
752                 exynos_dp_enable_scrambling(DP_ENABLE);
753
754                 exynos_dp_read_byte_from_dpcd(DPCD_TRAINING_PATTERN_SET,
755                                 &data);
756                 exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET,
757                         (u8)(data & ~DPCD_SCRAMBLING_DISABLED));
758         } else {
759                 exynos_dp_enable_scrambling(DP_DISABLE);
760                 exynos_dp_read_byte_from_dpcd(DPCD_TRAINING_PATTERN_SET,
761                                 &data);
762                 exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET,
763                         (u8)(data | DPCD_SCRAMBLING_DISABLED));
764         }
765 }
766
767 static unsigned int exynos_dp_config_video(struct edp_device_info *edp_info)
768 {
769         unsigned int ret = 0;
770         unsigned int retry_cnt;
771
772         mdelay(1);
773
774         if (edp_info->video_info.master_mode) {
775                 printf("DP does not support master mode\n");
776                 return -ENODEV;
777         } else {
778                 /* debug slave */
779                 exynos_dp_config_video_slave_mode(&edp_info->video_info);
780         }
781
782         exynos_dp_set_video_color_format(&edp_info->video_info);
783
784         if (edp_info->video_info.bist_mode) {
785                 if (exynos_dp_config_video_bist(edp_info) != 0)
786                         return -1;
787         }
788
789         ret = exynos_dp_get_pll_lock_status();
790         if (ret != PLL_LOCKED) {
791                 printf("DP PLL is not locked yet\n");
792                 return -EIO;
793         }
794
795         if (edp_info->video_info.master_mode == 0) {
796                 retry_cnt = 10;
797                 while (retry_cnt) {
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");
802                                         return ret;
803                                 }
804                                 retry_cnt--;
805                                 mdelay(1);
806                         } else
807                                 break;
808                 }
809         }
810
811         /* Set to use the register calculated M/N video */
812         exynos_dp_set_video_cr_mn(CALCULATED_M, 0, 0);
813
814         /* For video bist, Video timing must be generated by register */
815         exynos_dp_set_video_timing_mode(VIDEO_TIMING_FROM_CAPTURE);
816
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);
822         else
823                 exynos_dp_enable_video_bist(DP_DISABLE);
824
825         /* Disable video mute */
826         exynos_dp_enable_video_mute(DP_DISABLE);
827
828         /* Configure video Master or Slave mode */
829         exynos_dp_enable_video_master(edp_info->video_info.master_mode);
830
831         /* Enable video */
832         exynos_dp_start_video();
833
834         if (edp_info->video_info.master_mode == 0) {
835                 retry_cnt = 100;
836                 while (retry_cnt) {
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");
841                                         return ret;
842                                 }
843                                 retry_cnt--;
844                                 mdelay(5);
845                         } else
846                                 break;
847                 }
848         }
849
850         return ret;
851 }
852
853 #ifdef CONFIG_OF_CONTROL
854 int exynos_dp_parse_dt(const void *blob, struct edp_device_info *edp_info)
855 {
856         unsigned int node = fdtdec_next_compatible(blob, 0,
857                                                 COMPAT_SAMSUNG_EXYNOS5_DP);
858         if (node <= 0) {
859                 debug("exynos_dp: Can't get device node for dp\n");
860                 return -ENODEV;
861         }
862
863         edp_info->disp_info.h_res = fdtdec_get_int(blob, node,
864                                                         "samsung,h-res", 0);
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,
872                                                 "samsung,v-res", 0);
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);
881
882         edp_info->lt_info.lt_status = fdtdec_get_int(blob, node,
883                                                 "samsung,lt-status", 0);
884
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);
905         return 0;
906 }
907 #endif
908
909 unsigned int exynos_init_dp(void)
910 {
911         unsigned int ret;
912         struct edp_device_info *edp_info;
913
914         edp_info = kzalloc(sizeof(struct edp_device_info), GFP_KERNEL);
915         if (!edp_info) {
916                 debug("failed to allocate edp device object.\n");
917                 return -EFAULT;
918         }
919
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");
923 #else
924         edp_info = dp_pd->edp_dev_info;
925         if (edp_info == NULL) {
926                 debug("failed to get edp_info data.\n");
927                 return -EFAULT;
928         }
929 #endif
930
931         exynos_dp_set_base_addr();
932
933         exynos_dp_disp_info(&edp_info->disp_info);
934
935         exynos_set_dp_phy(1);
936
937         ret = exynos_dp_init_dp();
938         if (ret != EXYNOS_DP_SUCCESS) {
939                 printf("DP exynos_dp_init_dp() failed\n");
940                 return ret;
941         }
942
943         ret = exynos_dp_handle_edid(edp_info);
944         if (ret != EXYNOS_DP_SUCCESS) {
945                 printf("EDP handle_edid fail\n");
946                 return ret;
947         }
948
949         ret = exynos_dp_set_link_train(edp_info);
950         if (ret != EXYNOS_DP_SUCCESS) {
951                 printf("DP link training fail\n");
952                 return ret;
953         }
954
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);
958
959         exynos_dp_set_link_bandwidth(edp_info->lane_bw);
960         exynos_dp_set_lane_count(edp_info->lane_cnt);
961
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");
966                 return ret;
967         }
968
969         printf("Exynos DP init done\n");
970
971         return ret;
972 }
973
974 void exynos_set_dp_platform_data(struct exynos_dp_platform_data *pd)
975 {
976         if (pd == NULL) {
977                 debug("pd is NULL\n");
978                 return;
979         }
980
981         dp_pd = pd;
982 }