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