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