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