blob: d72fa565a7d0d479d5d3dc176506e1f3c999e10e [file] [log] [blame]
Donghwa Leeb73a88b2012-07-02 01:16:02 +00001/*
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
33static struct exynos_dp_platform_data *dp_pd;
34
35static 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
45static 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
63static 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
74static 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
167static 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
243static 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
255static 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
320static 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
336static 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
364static 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
379static 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
411static 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
434static 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
453static 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
477static 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
583static 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
689static 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
737static 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
750static 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
770static 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
856unsigned int exynos_init_dp(void)
857{
858 unsigned int ret;
859 struct edp_device_info *edp_info;
Donghwa Leeb73a88b2012-07-02 01:16:02 +0000860
861 edp_info = kzalloc(sizeof(struct edp_device_info), GFP_KERNEL);
862 if (!edp_info) {
863 debug("failed to allocate edp device object.\n");
864 return -EFAULT;
865 }
866
867 edp_info = dp_pd->edp_dev_info;
868 if (edp_info == NULL) {
869 debug("failed to get edp_info data.\n");
870 return -EFAULT;
871 }
Donghwa Leeb73a88b2012-07-02 01:16:02 +0000872
873 exynos_dp_disp_info(&edp_info->disp_info);
874
875 if (dp_pd->phy_enable)
876 dp_pd->phy_enable(1);
877
878 ret = exynos_dp_init_dp();
879 if (ret != EXYNOS_DP_SUCCESS) {
880 printf("DP exynos_dp_init_dp() failed\n");
881 return ret;
882 }
883
884 ret = exynos_dp_handle_edid(edp_info);
885 if (ret != EXYNOS_DP_SUCCESS) {
886 printf("EDP handle_edid fail\n");
887 return ret;
888 }
889
890 ret = exynos_dp_set_link_train(edp_info);
891 if (ret != EXYNOS_DP_SUCCESS) {
892 printf("DP link training fail\n");
893 return ret;
894 }
895
896 exynos_dp_enable_scramble(DP_ENABLE);
897 exynos_dp_enable_rx_to_enhanced_mode(DP_ENABLE);
898 exynos_dp_enable_enhanced_mode(DP_ENABLE);
899
900 exynos_dp_set_link_bandwidth(edp_info->lane_bw);
901 exynos_dp_set_lane_count(edp_info->lane_cnt);
902
903 exynos_dp_init_video();
904 ret = exynos_dp_config_video(edp_info);
905 if (ret != EXYNOS_DP_SUCCESS) {
906 printf("Exynos DP init failed\n");
907 return ret;
908 }
909
910 printf("Exynos DP init done\n");
911
912 return ret;
913}
914
915void exynos_set_dp_platform_data(struct exynos_dp_platform_data *pd)
916{
917 if (pd == NULL) {
918 debug("pd is NULL\n");
919 return;
920 }
921
922 dp_pd = pd;
923}