1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. 4 */ 5 6 #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ 7 8 #include <drm/drm_device.h> 9 #include <drm/drm_print.h> 10 11 #include "dp_reg.h" 12 #include "dp_link.h" 13 #include "dp_panel.h" 14 15 #define DP_TEST_REQUEST_MASK 0x7F 16 17 enum audio_sample_rate { 18 AUDIO_SAMPLE_RATE_32_KHZ = 0x00, 19 AUDIO_SAMPLE_RATE_44_1_KHZ = 0x01, 20 AUDIO_SAMPLE_RATE_48_KHZ = 0x02, 21 AUDIO_SAMPLE_RATE_88_2_KHZ = 0x03, 22 AUDIO_SAMPLE_RATE_96_KHZ = 0x04, 23 AUDIO_SAMPLE_RATE_176_4_KHZ = 0x05, 24 AUDIO_SAMPLE_RATE_192_KHZ = 0x06, 25 }; 26 27 enum audio_pattern_type { 28 AUDIO_TEST_PATTERN_OPERATOR_DEFINED = 0x00, 29 AUDIO_TEST_PATTERN_SAWTOOTH = 0x01, 30 }; 31 32 struct msm_dp_link_request { 33 u32 test_requested; 34 u32 test_link_rate; 35 u32 test_lane_count; 36 }; 37 38 struct msm_dp_link_private { 39 u32 prev_sink_count; 40 struct drm_device *drm_dev; 41 struct drm_dp_aux *aux; 42 struct msm_dp_link msm_dp_link; 43 44 struct msm_dp_link_request request; 45 struct mutex psm_mutex; 46 u8 link_status[DP_LINK_STATUS_SIZE]; 47 }; 48 49 static int msm_dp_aux_link_power_up(struct drm_dp_aux *aux, 50 struct msm_dp_link_info *link) 51 { 52 u8 value; 53 ssize_t len; 54 int i; 55 56 if (link->revision < 0x11) 57 return 0; 58 59 len = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value); 60 if (len < 0) 61 return len; 62 63 value &= ~DP_SET_POWER_MASK; 64 value |= DP_SET_POWER_D0; 65 66 /* retry for 1ms to give the sink time to wake up */ 67 for (i = 0; i < 3; i++) { 68 len = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value); 69 usleep_range(1000, 2000); 70 if (len == 1) 71 break; 72 } 73 74 return 0; 75 } 76 77 static int msm_dp_aux_link_power_down(struct drm_dp_aux *aux, 78 struct msm_dp_link_info *link) 79 { 80 u8 value; 81 int err; 82 83 if (link->revision < 0x11) 84 return 0; 85 86 err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value); 87 if (err < 0) 88 return err; 89 90 value &= ~DP_SET_POWER_MASK; 91 value |= DP_SET_POWER_D3; 92 93 err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value); 94 if (err < 0) 95 return err; 96 97 return 0; 98 } 99 100 static int msm_dp_link_get_period(struct msm_dp_link_private *link, int const addr) 101 { 102 int ret = 0; 103 u8 data; 104 u32 const max_audio_period = 0xA; 105 106 /* TEST_AUDIO_PERIOD_CH_XX */ 107 if (drm_dp_dpcd_readb(link->aux, addr, &data) < 0) { 108 DRM_ERROR("failed to read test_audio_period (0x%x)\n", addr); 109 ret = -EINVAL; 110 goto exit; 111 } 112 113 /* Period - Bits 3:0 */ 114 data = data & 0xF; 115 if ((int)data > max_audio_period) { 116 DRM_ERROR("invalid test_audio_period_ch_1 = 0x%x\n", data); 117 ret = -EINVAL; 118 goto exit; 119 } 120 121 ret = data; 122 exit: 123 return ret; 124 } 125 126 static int msm_dp_link_parse_audio_channel_period(struct msm_dp_link_private *link) 127 { 128 int ret = 0; 129 struct msm_dp_link_test_audio *req = &link->msm_dp_link.test_audio; 130 131 ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH1); 132 if (ret == -EINVAL) 133 goto exit; 134 135 req->test_audio_period_ch_1 = ret; 136 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_1 = 0x%x\n", ret); 137 138 ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH2); 139 if (ret == -EINVAL) 140 goto exit; 141 142 req->test_audio_period_ch_2 = ret; 143 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_2 = 0x%x\n", ret); 144 145 /* TEST_AUDIO_PERIOD_CH_3 (Byte 0x275) */ 146 ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH3); 147 if (ret == -EINVAL) 148 goto exit; 149 150 req->test_audio_period_ch_3 = ret; 151 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_3 = 0x%x\n", ret); 152 153 ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH4); 154 if (ret == -EINVAL) 155 goto exit; 156 157 req->test_audio_period_ch_4 = ret; 158 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_4 = 0x%x\n", ret); 159 160 ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH5); 161 if (ret == -EINVAL) 162 goto exit; 163 164 req->test_audio_period_ch_5 = ret; 165 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_5 = 0x%x\n", ret); 166 167 ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH6); 168 if (ret == -EINVAL) 169 goto exit; 170 171 req->test_audio_period_ch_6 = ret; 172 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_6 = 0x%x\n", ret); 173 174 ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH7); 175 if (ret == -EINVAL) 176 goto exit; 177 178 req->test_audio_period_ch_7 = ret; 179 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_7 = 0x%x\n", ret); 180 181 ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH8); 182 if (ret == -EINVAL) 183 goto exit; 184 185 req->test_audio_period_ch_8 = ret; 186 drm_dbg_dp(link->drm_dev, "test_audio_period_ch_8 = 0x%x\n", ret); 187 exit: 188 return ret; 189 } 190 191 static int msm_dp_link_parse_audio_pattern_type(struct msm_dp_link_private *link) 192 { 193 int ret = 0; 194 u8 data; 195 ssize_t rlen; 196 int const max_audio_pattern_type = 0x1; 197 198 rlen = drm_dp_dpcd_readb(link->aux, 199 DP_TEST_AUDIO_PATTERN_TYPE, &data); 200 if (rlen < 0) { 201 DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen); 202 return rlen; 203 } 204 205 /* Audio Pattern Type - Bits 7:0 */ 206 if ((int)data > max_audio_pattern_type) { 207 DRM_ERROR("invalid audio pattern type = 0x%x\n", data); 208 ret = -EINVAL; 209 goto exit; 210 } 211 212 link->msm_dp_link.test_audio.test_audio_pattern_type = data; 213 drm_dbg_dp(link->drm_dev, "audio pattern type = 0x%x\n", data); 214 exit: 215 return ret; 216 } 217 218 static int msm_dp_link_parse_audio_mode(struct msm_dp_link_private *link) 219 { 220 int ret = 0; 221 u8 data; 222 ssize_t rlen; 223 int const max_audio_sampling_rate = 0x6; 224 int const max_audio_channel_count = 0x8; 225 int sampling_rate = 0x0; 226 int channel_count = 0x0; 227 228 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_AUDIO_MODE, &data); 229 if (rlen < 0) { 230 DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen); 231 return rlen; 232 } 233 234 /* Sampling Rate - Bits 3:0 */ 235 sampling_rate = data & 0xF; 236 if (sampling_rate > max_audio_sampling_rate) { 237 DRM_ERROR("sampling rate (0x%x) greater than max (0x%x)\n", 238 sampling_rate, max_audio_sampling_rate); 239 ret = -EINVAL; 240 goto exit; 241 } 242 243 /* Channel Count - Bits 7:4 */ 244 channel_count = ((data & 0xF0) >> 4) + 1; 245 if (channel_count > max_audio_channel_count) { 246 DRM_ERROR("channel_count (0x%x) greater than max (0x%x)\n", 247 channel_count, max_audio_channel_count); 248 ret = -EINVAL; 249 goto exit; 250 } 251 252 link->msm_dp_link.test_audio.test_audio_sampling_rate = sampling_rate; 253 link->msm_dp_link.test_audio.test_audio_channel_count = channel_count; 254 drm_dbg_dp(link->drm_dev, 255 "sampling_rate = 0x%x, channel_count = 0x%x\n", 256 sampling_rate, channel_count); 257 exit: 258 return ret; 259 } 260 261 static int msm_dp_link_parse_audio_pattern_params(struct msm_dp_link_private *link) 262 { 263 int ret = 0; 264 265 ret = msm_dp_link_parse_audio_mode(link); 266 if (ret) 267 goto exit; 268 269 ret = msm_dp_link_parse_audio_pattern_type(link); 270 if (ret) 271 goto exit; 272 273 ret = msm_dp_link_parse_audio_channel_period(link); 274 275 exit: 276 return ret; 277 } 278 279 static bool msm_dp_link_is_video_pattern_valid(u32 pattern) 280 { 281 switch (pattern) { 282 case DP_NO_TEST_PATTERN: 283 case DP_COLOR_RAMP: 284 case DP_BLACK_AND_WHITE_VERTICAL_LINES: 285 case DP_COLOR_SQUARE: 286 return true; 287 default: 288 return false; 289 } 290 } 291 292 /** 293 * msm_dp_link_is_bit_depth_valid() - validates the bit depth requested 294 * @tbd: bit depth requested by the sink 295 * 296 * Returns true if the requested bit depth is supported. 297 */ 298 static bool msm_dp_link_is_bit_depth_valid(u32 tbd) 299 { 300 /* DP_TEST_VIDEO_PATTERN_NONE is treated as invalid */ 301 switch (tbd) { 302 case DP_TEST_BIT_DEPTH_6: 303 case DP_TEST_BIT_DEPTH_8: 304 case DP_TEST_BIT_DEPTH_10: 305 return true; 306 default: 307 return false; 308 } 309 } 310 311 static int msm_dp_link_parse_timing_params1(struct msm_dp_link_private *link, 312 int addr, int len, u32 *val) 313 { 314 u8 bp[2]; 315 int rlen; 316 317 if (len != 2) 318 return -EINVAL; 319 320 /* Read the requested video link pattern (Byte 0x221). */ 321 rlen = drm_dp_dpcd_read(link->aux, addr, bp, len); 322 if (rlen < len) { 323 DRM_ERROR("failed to read 0x%x\n", addr); 324 return -EINVAL; 325 } 326 327 *val = bp[1] | (bp[0] << 8); 328 329 return 0; 330 } 331 332 static int msm_dp_link_parse_timing_params2(struct msm_dp_link_private *link, 333 int addr, int len, 334 u32 *val1, u32 *val2) 335 { 336 u8 bp[2]; 337 int rlen; 338 339 if (len != 2) 340 return -EINVAL; 341 342 /* Read the requested video link pattern (Byte 0x221). */ 343 rlen = drm_dp_dpcd_read(link->aux, addr, bp, len); 344 if (rlen < len) { 345 DRM_ERROR("failed to read 0x%x\n", addr); 346 return -EINVAL; 347 } 348 349 *val1 = (bp[0] & BIT(7)) >> 7; 350 *val2 = bp[1] | ((bp[0] & 0x7F) << 8); 351 352 return 0; 353 } 354 355 static int msm_dp_link_parse_timing_params3(struct msm_dp_link_private *link, 356 int addr, u32 *val) 357 { 358 u8 bp; 359 u32 len = 1; 360 int rlen; 361 362 rlen = drm_dp_dpcd_read(link->aux, addr, &bp, len); 363 if (rlen < 1) { 364 DRM_ERROR("failed to read 0x%x\n", addr); 365 return -EINVAL; 366 } 367 *val = bp; 368 369 return 0; 370 } 371 372 /** 373 * msm_dp_link_parse_video_pattern_params() - parses video pattern parameters from DPCD 374 * @link: Display Port Driver data 375 * 376 * Returns 0 if it successfully parses the video link pattern and the link 377 * bit depth requested by the sink and, and if the values parsed are valid. 378 */ 379 static int msm_dp_link_parse_video_pattern_params(struct msm_dp_link_private *link) 380 { 381 int ret = 0; 382 ssize_t rlen; 383 u8 bp; 384 385 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_PATTERN, &bp); 386 if (rlen < 0) { 387 DRM_ERROR("failed to read link video pattern. rlen=%zd\n", 388 rlen); 389 return rlen; 390 } 391 392 if (!msm_dp_link_is_video_pattern_valid(bp)) { 393 DRM_ERROR("invalid link video pattern = 0x%x\n", bp); 394 ret = -EINVAL; 395 return ret; 396 } 397 398 link->msm_dp_link.test_video.test_video_pattern = bp; 399 400 /* Read the requested color bit depth and dynamic range (Byte 0x232) */ 401 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_MISC0, &bp); 402 if (rlen < 0) { 403 DRM_ERROR("failed to read link bit depth. rlen=%zd\n", rlen); 404 return rlen; 405 } 406 407 /* Dynamic Range */ 408 link->msm_dp_link.test_video.test_dyn_range = 409 (bp & DP_TEST_DYNAMIC_RANGE_CEA); 410 411 /* Color bit depth */ 412 bp &= DP_TEST_BIT_DEPTH_MASK; 413 if (!msm_dp_link_is_bit_depth_valid(bp)) { 414 DRM_ERROR("invalid link bit depth = 0x%x\n", bp); 415 ret = -EINVAL; 416 return ret; 417 } 418 419 link->msm_dp_link.test_video.test_bit_depth = bp; 420 421 /* resolution timing params */ 422 ret = msm_dp_link_parse_timing_params1(link, DP_TEST_H_TOTAL_HI, 2, 423 &link->msm_dp_link.test_video.test_h_total); 424 if (ret) { 425 DRM_ERROR("failed to parse test_htotal(DP_TEST_H_TOTAL_HI)\n"); 426 return ret; 427 } 428 429 ret = msm_dp_link_parse_timing_params1(link, DP_TEST_V_TOTAL_HI, 2, 430 &link->msm_dp_link.test_video.test_v_total); 431 if (ret) { 432 DRM_ERROR("failed to parse test_v_total(DP_TEST_V_TOTAL_HI)\n"); 433 return ret; 434 } 435 436 ret = msm_dp_link_parse_timing_params1(link, DP_TEST_H_START_HI, 2, 437 &link->msm_dp_link.test_video.test_h_start); 438 if (ret) { 439 DRM_ERROR("failed to parse test_h_start(DP_TEST_H_START_HI)\n"); 440 return ret; 441 } 442 443 ret = msm_dp_link_parse_timing_params1(link, DP_TEST_V_START_HI, 2, 444 &link->msm_dp_link.test_video.test_v_start); 445 if (ret) { 446 DRM_ERROR("failed to parse test_v_start(DP_TEST_V_START_HI)\n"); 447 return ret; 448 } 449 450 ret = msm_dp_link_parse_timing_params2(link, DP_TEST_HSYNC_HI, 2, 451 &link->msm_dp_link.test_video.test_hsync_pol, 452 &link->msm_dp_link.test_video.test_hsync_width); 453 if (ret) { 454 DRM_ERROR("failed to parse (DP_TEST_HSYNC_HI)\n"); 455 return ret; 456 } 457 458 ret = msm_dp_link_parse_timing_params2(link, DP_TEST_VSYNC_HI, 2, 459 &link->msm_dp_link.test_video.test_vsync_pol, 460 &link->msm_dp_link.test_video.test_vsync_width); 461 if (ret) { 462 DRM_ERROR("failed to parse (DP_TEST_VSYNC_HI)\n"); 463 return ret; 464 } 465 466 ret = msm_dp_link_parse_timing_params1(link, DP_TEST_H_WIDTH_HI, 2, 467 &link->msm_dp_link.test_video.test_h_width); 468 if (ret) { 469 DRM_ERROR("failed to parse test_h_width(DP_TEST_H_WIDTH_HI)\n"); 470 return ret; 471 } 472 473 ret = msm_dp_link_parse_timing_params1(link, DP_TEST_V_HEIGHT_HI, 2, 474 &link->msm_dp_link.test_video.test_v_height); 475 if (ret) { 476 DRM_ERROR("failed to parse test_v_height\n"); 477 return ret; 478 } 479 480 ret = msm_dp_link_parse_timing_params3(link, DP_TEST_MISC1, 481 &link->msm_dp_link.test_video.test_rr_d); 482 link->msm_dp_link.test_video.test_rr_d &= DP_TEST_REFRESH_DENOMINATOR; 483 if (ret) { 484 DRM_ERROR("failed to parse test_rr_d (DP_TEST_MISC1)\n"); 485 return ret; 486 } 487 488 ret = msm_dp_link_parse_timing_params3(link, DP_TEST_REFRESH_RATE_NUMERATOR, 489 &link->msm_dp_link.test_video.test_rr_n); 490 if (ret) { 491 DRM_ERROR("failed to parse test_rr_n\n"); 492 return ret; 493 } 494 495 drm_dbg_dp(link->drm_dev, 496 "link video pattern = 0x%x\n" 497 "link dynamic range = 0x%x\n" 498 "link bit depth = 0x%x\n" 499 "TEST_H_TOTAL = %d, TEST_V_TOTAL = %d\n" 500 "TEST_H_START = %d, TEST_V_START = %d\n" 501 "TEST_HSYNC_POL = %d\n" 502 "TEST_HSYNC_WIDTH = %d\n" 503 "TEST_VSYNC_POL = %d\n" 504 "TEST_VSYNC_WIDTH = %d\n" 505 "TEST_H_WIDTH = %d\n" 506 "TEST_V_HEIGHT = %d\n" 507 "TEST_REFRESH_DENOMINATOR = %d\n" 508 "TEST_REFRESH_NUMERATOR = %d\n", 509 link->msm_dp_link.test_video.test_video_pattern, 510 link->msm_dp_link.test_video.test_dyn_range, 511 link->msm_dp_link.test_video.test_bit_depth, 512 link->msm_dp_link.test_video.test_h_total, 513 link->msm_dp_link.test_video.test_v_total, 514 link->msm_dp_link.test_video.test_h_start, 515 link->msm_dp_link.test_video.test_v_start, 516 link->msm_dp_link.test_video.test_hsync_pol, 517 link->msm_dp_link.test_video.test_hsync_width, 518 link->msm_dp_link.test_video.test_vsync_pol, 519 link->msm_dp_link.test_video.test_vsync_width, 520 link->msm_dp_link.test_video.test_h_width, 521 link->msm_dp_link.test_video.test_v_height, 522 link->msm_dp_link.test_video.test_rr_d, 523 link->msm_dp_link.test_video.test_rr_n); 524 525 return ret; 526 } 527 528 /** 529 * msm_dp_link_parse_link_training_params() - parses link training parameters from 530 * DPCD 531 * @link: Display Port Driver data 532 * 533 * Returns 0 if it successfully parses the link rate (Byte 0x219) and lane 534 * count (Byte 0x220), and if these values parse are valid. 535 */ 536 static int msm_dp_link_parse_link_training_params(struct msm_dp_link_private *link) 537 { 538 u8 bp; 539 ssize_t rlen; 540 541 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LINK_RATE, &bp); 542 if (rlen < 0) { 543 DRM_ERROR("failed to read link rate. rlen=%zd\n", rlen); 544 return rlen; 545 } 546 547 if (!is_link_rate_valid(bp)) { 548 DRM_ERROR("invalid link rate = 0x%x\n", bp); 549 return -EINVAL; 550 } 551 552 link->request.test_link_rate = bp; 553 drm_dbg_dp(link->drm_dev, "link rate = 0x%x\n", 554 link->request.test_link_rate); 555 556 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LANE_COUNT, &bp); 557 if (rlen < 0) { 558 DRM_ERROR("failed to read lane count. rlen=%zd\n", rlen); 559 return rlen; 560 } 561 bp &= DP_MAX_LANE_COUNT_MASK; 562 563 if (!is_lane_count_valid(bp)) { 564 DRM_ERROR("invalid lane count = 0x%x\n", bp); 565 return -EINVAL; 566 } 567 568 link->request.test_lane_count = bp; 569 drm_dbg_dp(link->drm_dev, "lane count = 0x%x\n", 570 link->request.test_lane_count); 571 return 0; 572 } 573 574 /** 575 * msm_dp_link_parse_phy_test_params() - parses the phy link parameters 576 * @link: Display Port Driver data 577 * 578 * Parses the DPCD (Byte 0x248) for the DP PHY link pattern that is being 579 * requested. 580 */ 581 static int msm_dp_link_parse_phy_test_params(struct msm_dp_link_private *link) 582 { 583 u8 data; 584 ssize_t rlen; 585 586 rlen = drm_dp_dpcd_readb(link->aux, DP_PHY_TEST_PATTERN, 587 &data); 588 if (rlen < 0) { 589 DRM_ERROR("failed to read phy link pattern. rlen=%zd\n", rlen); 590 return rlen; 591 } 592 593 link->msm_dp_link.phy_params.phy_test_pattern_sel = data & 0x07; 594 595 drm_dbg_dp(link->drm_dev, "phy_test_pattern_sel = 0x%x\n", data); 596 597 switch (data) { 598 case DP_PHY_TEST_PATTERN_SEL_MASK: 599 case DP_PHY_TEST_PATTERN_NONE: 600 case DP_PHY_TEST_PATTERN_D10_2: 601 case DP_PHY_TEST_PATTERN_ERROR_COUNT: 602 case DP_PHY_TEST_PATTERN_PRBS7: 603 case DP_PHY_TEST_PATTERN_80BIT_CUSTOM: 604 case DP_PHY_TEST_PATTERN_CP2520: 605 return 0; 606 default: 607 return -EINVAL; 608 } 609 } 610 611 /** 612 * msm_dp_link_is_video_audio_test_requested() - checks for audio/video link request 613 * @link: link requested by the sink 614 * 615 * Returns true if the requested link is a permitted audio/video link. 616 */ 617 static bool msm_dp_link_is_video_audio_test_requested(u32 link) 618 { 619 u8 video_audio_test = (DP_TEST_LINK_VIDEO_PATTERN | 620 DP_TEST_LINK_AUDIO_PATTERN | 621 DP_TEST_LINK_AUDIO_DISABLED_VIDEO); 622 623 return ((link & video_audio_test) && 624 !(link & ~video_audio_test)); 625 } 626 627 /** 628 * msm_dp_link_parse_request() - parses link request parameters from sink 629 * @link: Display Port Driver data 630 * 631 * Parses the DPCD to check if an automated link is requested (Byte 0x201), 632 * and what type of link automation is being requested (Byte 0x218). 633 */ 634 static int msm_dp_link_parse_request(struct msm_dp_link_private *link) 635 { 636 int ret = 0; 637 u8 data; 638 ssize_t rlen; 639 640 /** 641 * Read the device service IRQ vector (Byte 0x201) to determine 642 * whether an automated link has been requested by the sink. 643 */ 644 rlen = drm_dp_dpcd_readb(link->aux, 645 DP_DEVICE_SERVICE_IRQ_VECTOR, &data); 646 if (rlen < 0) { 647 DRM_ERROR("aux read failed. rlen=%zd\n", rlen); 648 return rlen; 649 } 650 651 drm_dbg_dp(link->drm_dev, "device service irq vector = 0x%x\n", data); 652 653 if (!(data & DP_AUTOMATED_TEST_REQUEST)) { 654 drm_dbg_dp(link->drm_dev, "no test requested\n"); 655 return 0; 656 } 657 658 /** 659 * Read the link request byte (Byte 0x218) to determine what type 660 * of automated link has been requested by the sink. 661 */ 662 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_REQUEST, &data); 663 if (rlen < 0) { 664 DRM_ERROR("aux read failed. rlen=%zd\n", rlen); 665 return rlen; 666 } 667 668 if (!data || (data == DP_TEST_LINK_FAUX_PATTERN)) { 669 drm_dbg_dp(link->drm_dev, "link 0x%x not supported\n", data); 670 goto end; 671 } 672 673 drm_dbg_dp(link->drm_dev, "Test:(0x%x) requested\n", data); 674 link->request.test_requested = data; 675 if (link->request.test_requested == DP_TEST_LINK_PHY_TEST_PATTERN) { 676 ret = msm_dp_link_parse_phy_test_params(link); 677 if (ret) 678 goto end; 679 ret = msm_dp_link_parse_link_training_params(link); 680 if (ret) 681 goto end; 682 } 683 684 if (link->request.test_requested == DP_TEST_LINK_TRAINING) { 685 ret = msm_dp_link_parse_link_training_params(link); 686 if (ret) 687 goto end; 688 } 689 690 if (msm_dp_link_is_video_audio_test_requested( 691 link->request.test_requested)) { 692 ret = msm_dp_link_parse_video_pattern_params(link); 693 if (ret) 694 goto end; 695 696 ret = msm_dp_link_parse_audio_pattern_params(link); 697 } 698 end: 699 /* 700 * Send a DP_TEST_ACK if all link parameters are valid, otherwise send 701 * a DP_TEST_NAK. 702 */ 703 if (ret) { 704 link->msm_dp_link.test_response = DP_TEST_NAK; 705 } else { 706 if (link->request.test_requested != DP_TEST_LINK_EDID_READ) 707 link->msm_dp_link.test_response = DP_TEST_ACK; 708 else 709 link->msm_dp_link.test_response = 710 DP_TEST_EDID_CHECKSUM_WRITE; 711 } 712 713 return ret; 714 } 715 716 static int msm_dp_link_parse_sink_status_field(struct msm_dp_link_private *link) 717 { 718 int ret; 719 720 link->prev_sink_count = link->msm_dp_link.sink_count; 721 ret = drm_dp_read_sink_count(link->aux); 722 if (ret < 0) { 723 DRM_ERROR("DP parse sink count failed\n"); 724 return ret; 725 } 726 link->msm_dp_link.sink_count = ret; 727 728 ret = drm_dp_dpcd_read_link_status(link->aux, 729 link->link_status); 730 if (ret < 0) { 731 DRM_ERROR("DP link status read failed\n"); 732 return ret; 733 } 734 735 return msm_dp_link_parse_request(link); 736 } 737 738 /** 739 * msm_dp_link_process_link_training_request() - processes new training requests 740 * @link: Display Port link data 741 * 742 * This function will handle new link training requests that are initiated by 743 * the sink. In particular, it will update the requested lane count and link 744 * rate, and then trigger the link retraining procedure. 745 * 746 * The function will return 0 if a link training request has been processed, 747 * otherwise it will return -EINVAL. 748 */ 749 static int msm_dp_link_process_link_training_request(struct msm_dp_link_private *link) 750 { 751 if (link->request.test_requested != DP_TEST_LINK_TRAINING) 752 return -EINVAL; 753 754 drm_dbg_dp(link->drm_dev, 755 "Test:0x%x link rate = 0x%x, lane count = 0x%x\n", 756 DP_TEST_LINK_TRAINING, 757 link->request.test_link_rate, 758 link->request.test_lane_count); 759 760 link->msm_dp_link.link_params.num_lanes = link->request.test_lane_count; 761 link->msm_dp_link.link_params.rate = 762 drm_dp_bw_code_to_link_rate(link->request.test_link_rate); 763 764 return 0; 765 } 766 767 bool msm_dp_link_send_test_response(struct msm_dp_link *msm_dp_link) 768 { 769 struct msm_dp_link_private *link = NULL; 770 int ret = 0; 771 772 if (!msm_dp_link) { 773 DRM_ERROR("invalid input\n"); 774 return false; 775 } 776 777 link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link); 778 779 ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_RESPONSE, 780 msm_dp_link->test_response); 781 782 return ret == 1; 783 } 784 785 int msm_dp_link_psm_config(struct msm_dp_link *msm_dp_link, 786 struct msm_dp_link_info *link_info, bool enable) 787 { 788 struct msm_dp_link_private *link = NULL; 789 int ret = 0; 790 791 if (!msm_dp_link) { 792 DRM_ERROR("invalid params\n"); 793 return -EINVAL; 794 } 795 796 link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link); 797 798 mutex_lock(&link->psm_mutex); 799 if (enable) 800 ret = msm_dp_aux_link_power_down(link->aux, link_info); 801 else 802 ret = msm_dp_aux_link_power_up(link->aux, link_info); 803 804 if (ret) 805 DRM_ERROR("Failed to %s low power mode\n", enable ? 806 "enter" : "exit"); 807 808 mutex_unlock(&link->psm_mutex); 809 return ret; 810 } 811 812 bool msm_dp_link_send_edid_checksum(struct msm_dp_link *msm_dp_link, u8 checksum) 813 { 814 struct msm_dp_link_private *link = NULL; 815 int ret = 0; 816 817 if (!msm_dp_link) { 818 DRM_ERROR("invalid input\n"); 819 return false; 820 } 821 822 link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link); 823 824 ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_EDID_CHECKSUM, 825 checksum); 826 return ret == 1; 827 } 828 829 static void msm_dp_link_parse_vx_px(struct msm_dp_link_private *link) 830 { 831 drm_dbg_dp(link->drm_dev, "vx: 0=%d, 1=%d, 2=%d, 3=%d\n", 832 drm_dp_get_adjust_request_voltage(link->link_status, 0), 833 drm_dp_get_adjust_request_voltage(link->link_status, 1), 834 drm_dp_get_adjust_request_voltage(link->link_status, 2), 835 drm_dp_get_adjust_request_voltage(link->link_status, 3)); 836 837 drm_dbg_dp(link->drm_dev, "px: 0=%d, 1=%d, 2=%d, 3=%d\n", 838 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0), 839 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 1), 840 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 2), 841 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 3)); 842 843 /** 844 * Update the voltage and pre-emphasis levels as per DPCD request 845 * vector. 846 */ 847 drm_dbg_dp(link->drm_dev, 848 "Current: v_level = 0x%x, p_level = 0x%x\n", 849 link->msm_dp_link.phy_params.v_level, 850 link->msm_dp_link.phy_params.p_level); 851 link->msm_dp_link.phy_params.v_level = 852 drm_dp_get_adjust_request_voltage(link->link_status, 0); 853 link->msm_dp_link.phy_params.p_level = 854 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0); 855 856 link->msm_dp_link.phy_params.p_level >>= DP_TRAIN_PRE_EMPHASIS_SHIFT; 857 858 drm_dbg_dp(link->drm_dev, 859 "Requested: v_level = 0x%x, p_level = 0x%x\n", 860 link->msm_dp_link.phy_params.v_level, 861 link->msm_dp_link.phy_params.p_level); 862 } 863 864 /** 865 * msm_dp_link_process_phy_test_pattern_request() - process new phy link requests 866 * @link: Display Port Driver data 867 * 868 * This function will handle new phy link pattern requests that are initiated 869 * by the sink. The function will return 0 if a phy link pattern has been 870 * processed, otherwise it will return -EINVAL. 871 */ 872 static int msm_dp_link_process_phy_test_pattern_request( 873 struct msm_dp_link_private *link) 874 { 875 if (!(link->request.test_requested & DP_TEST_LINK_PHY_TEST_PATTERN)) { 876 drm_dbg_dp(link->drm_dev, "no phy test\n"); 877 return -EINVAL; 878 } 879 880 if (!is_link_rate_valid(link->request.test_link_rate) || 881 !is_lane_count_valid(link->request.test_lane_count)) { 882 DRM_ERROR("Invalid: link rate = 0x%x,lane count = 0x%x\n", 883 link->request.test_link_rate, 884 link->request.test_lane_count); 885 return -EINVAL; 886 } 887 888 drm_dbg_dp(link->drm_dev, 889 "Current: rate = 0x%x, lane count = 0x%x\n", 890 link->msm_dp_link.link_params.rate, 891 link->msm_dp_link.link_params.num_lanes); 892 893 drm_dbg_dp(link->drm_dev, 894 "Requested: rate = 0x%x, lane count = 0x%x\n", 895 link->request.test_link_rate, 896 link->request.test_lane_count); 897 898 link->msm_dp_link.link_params.num_lanes = link->request.test_lane_count; 899 link->msm_dp_link.link_params.rate = 900 drm_dp_bw_code_to_link_rate(link->request.test_link_rate); 901 902 msm_dp_link_parse_vx_px(link); 903 904 return 0; 905 } 906 907 static bool msm_dp_link_read_psr_error_status(struct msm_dp_link_private *link) 908 { 909 u8 status; 910 911 drm_dp_dpcd_read(link->aux, DP_PSR_ERROR_STATUS, &status, 1); 912 913 if (status & DP_PSR_LINK_CRC_ERROR) 914 DRM_ERROR("PSR LINK CRC ERROR\n"); 915 else if (status & DP_PSR_RFB_STORAGE_ERROR) 916 DRM_ERROR("PSR RFB STORAGE ERROR\n"); 917 else if (status & DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR) 918 DRM_ERROR("PSR VSC SDP UNCORRECTABLE ERROR\n"); 919 else 920 return false; 921 922 return true; 923 } 924 925 static bool msm_dp_link_psr_capability_changed(struct msm_dp_link_private *link) 926 { 927 u8 status; 928 929 drm_dp_dpcd_read(link->aux, DP_PSR_ESI, &status, 1); 930 931 if (status & DP_PSR_CAPS_CHANGE) { 932 drm_dbg_dp(link->drm_dev, "PSR Capability Change\n"); 933 return true; 934 } 935 936 return false; 937 } 938 939 static u8 get_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r) 940 { 941 return link_status[r - DP_LANE0_1_STATUS]; 942 } 943 944 /** 945 * msm_dp_link_process_link_status_update() - processes link status updates 946 * @link: Display Port link module data 947 * 948 * This function will check for changes in the link status, e.g. clock 949 * recovery done on all lanes, and trigger link training if there is a 950 * failure/error on the link. 951 * 952 * The function will return 0 if the a link status update has been processed, 953 * otherwise it will return -EINVAL. 954 */ 955 static int msm_dp_link_process_link_status_update(struct msm_dp_link_private *link) 956 { 957 bool channel_eq_done = drm_dp_channel_eq_ok(link->link_status, 958 link->msm_dp_link.link_params.num_lanes); 959 960 bool clock_recovery_done = drm_dp_clock_recovery_ok(link->link_status, 961 link->msm_dp_link.link_params.num_lanes); 962 963 drm_dbg_dp(link->drm_dev, 964 "channel_eq_done = %d, clock_recovery_done = %d\n", 965 channel_eq_done, clock_recovery_done); 966 967 if (channel_eq_done && clock_recovery_done) 968 return -EINVAL; 969 970 return 0; 971 } 972 973 /** 974 * msm_dp_link_process_ds_port_status_change() - process port status changes 975 * @link: Display Port Driver data 976 * 977 * This function will handle downstream port updates that are initiated by 978 * the sink. If the downstream port status has changed, the EDID is read via 979 * AUX. 980 * 981 * The function will return 0 if a downstream port update has been 982 * processed, otherwise it will return -EINVAL. 983 */ 984 static int msm_dp_link_process_ds_port_status_change(struct msm_dp_link_private *link) 985 { 986 if (get_link_status(link->link_status, DP_LANE_ALIGN_STATUS_UPDATED) & 987 DP_DOWNSTREAM_PORT_STATUS_CHANGED) 988 goto reset; 989 990 if (link->prev_sink_count == link->msm_dp_link.sink_count) 991 return -EINVAL; 992 993 reset: 994 /* reset prev_sink_count */ 995 link->prev_sink_count = link->msm_dp_link.sink_count; 996 997 return 0; 998 } 999 1000 static bool msm_dp_link_is_video_pattern_requested(struct msm_dp_link_private *link) 1001 { 1002 return (link->request.test_requested & DP_TEST_LINK_VIDEO_PATTERN) 1003 && !(link->request.test_requested & 1004 DP_TEST_LINK_AUDIO_DISABLED_VIDEO); 1005 } 1006 1007 static bool msm_dp_link_is_audio_pattern_requested(struct msm_dp_link_private *link) 1008 { 1009 return (link->request.test_requested & DP_TEST_LINK_AUDIO_PATTERN); 1010 } 1011 1012 static void msm_dp_link_reset_data(struct msm_dp_link_private *link) 1013 { 1014 link->request = (const struct msm_dp_link_request){ 0 }; 1015 link->msm_dp_link.test_video = (const struct msm_dp_link_test_video){ 0 }; 1016 link->msm_dp_link.test_video.test_bit_depth = DP_TEST_BIT_DEPTH_UNKNOWN; 1017 link->msm_dp_link.test_audio = (const struct msm_dp_link_test_audio){ 0 }; 1018 link->msm_dp_link.phy_params.phy_test_pattern_sel = 0; 1019 link->msm_dp_link.sink_request = 0; 1020 link->msm_dp_link.test_response = 0; 1021 } 1022 1023 /** 1024 * msm_dp_link_process_request() - handle HPD IRQ transition to HIGH 1025 * @msm_dp_link: pointer to link module data 1026 * 1027 * This function will handle the HPD IRQ state transitions from LOW to HIGH 1028 * (including cases when there are back to back HPD IRQ HIGH) indicating 1029 * the start of a new link training request or sink status update. 1030 */ 1031 int msm_dp_link_process_request(struct msm_dp_link *msm_dp_link) 1032 { 1033 int ret = 0; 1034 struct msm_dp_link_private *link; 1035 1036 if (!msm_dp_link) { 1037 DRM_ERROR("invalid input\n"); 1038 return -EINVAL; 1039 } 1040 1041 link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link); 1042 1043 msm_dp_link_reset_data(link); 1044 1045 ret = msm_dp_link_parse_sink_status_field(link); 1046 if (ret) 1047 return ret; 1048 1049 if (link->request.test_requested == DP_TEST_LINK_EDID_READ) { 1050 msm_dp_link->sink_request |= DP_TEST_LINK_EDID_READ; 1051 } else if (!msm_dp_link_process_ds_port_status_change(link)) { 1052 msm_dp_link->sink_request |= DS_PORT_STATUS_CHANGED; 1053 } else if (!msm_dp_link_process_link_training_request(link)) { 1054 msm_dp_link->sink_request |= DP_TEST_LINK_TRAINING; 1055 } else if (!msm_dp_link_process_phy_test_pattern_request(link)) { 1056 msm_dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN; 1057 } else if (msm_dp_link_read_psr_error_status(link)) { 1058 DRM_ERROR("PSR IRQ_HPD received\n"); 1059 } else if (msm_dp_link_psr_capability_changed(link)) { 1060 drm_dbg_dp(link->drm_dev, "PSR Capability changed\n"); 1061 } else { 1062 ret = msm_dp_link_process_link_status_update(link); 1063 if (!ret) { 1064 msm_dp_link->sink_request |= DP_LINK_STATUS_UPDATED; 1065 } else { 1066 if (msm_dp_link_is_video_pattern_requested(link)) { 1067 ret = 0; 1068 msm_dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN; 1069 } 1070 if (msm_dp_link_is_audio_pattern_requested(link)) { 1071 msm_dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN; 1072 ret = -EINVAL; 1073 } 1074 } 1075 } 1076 1077 drm_dbg_dp(link->drm_dev, "sink request=%#x\n", 1078 msm_dp_link->sink_request); 1079 return ret; 1080 } 1081 1082 int msm_dp_link_get_colorimetry_config(struct msm_dp_link *msm_dp_link) 1083 { 1084 u32 cc = DP_MISC0_COLORIMERY_CFG_LEGACY_RGB; 1085 struct msm_dp_link_private *link; 1086 1087 if (!msm_dp_link) { 1088 DRM_ERROR("invalid input\n"); 1089 return -EINVAL; 1090 } 1091 1092 link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link); 1093 1094 /* 1095 * Unless a video pattern CTS test is ongoing, use RGB_VESA 1096 * Only RGB_VESA and RGB_CEA supported for now 1097 */ 1098 if (msm_dp_link_is_video_pattern_requested(link)) { 1099 if (link->msm_dp_link.test_video.test_dyn_range & 1100 DP_TEST_DYNAMIC_RANGE_CEA) 1101 cc = DP_MISC0_COLORIMERY_CFG_CEA_RGB; 1102 } 1103 1104 return cc; 1105 } 1106 1107 int msm_dp_link_adjust_levels(struct msm_dp_link *msm_dp_link, u8 *link_status) 1108 { 1109 int i; 1110 u8 max_p_level; 1111 int v_max = 0, p_max = 0; 1112 struct msm_dp_link_private *link; 1113 1114 if (!msm_dp_link) { 1115 DRM_ERROR("invalid input\n"); 1116 return -EINVAL; 1117 } 1118 1119 link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link); 1120 1121 /* use the max level across lanes */ 1122 for (i = 0; i < msm_dp_link->link_params.num_lanes; i++) { 1123 u8 data_v = drm_dp_get_adjust_request_voltage(link_status, i); 1124 u8 data_p = drm_dp_get_adjust_request_pre_emphasis(link_status, 1125 i); 1126 drm_dbg_dp(link->drm_dev, 1127 "lane=%d req_vol_swing=%d req_pre_emphasis=%d\n", 1128 i, data_v, data_p); 1129 if (v_max < data_v) 1130 v_max = data_v; 1131 if (p_max < data_p) 1132 p_max = data_p; 1133 } 1134 1135 msm_dp_link->phy_params.v_level = v_max >> DP_TRAIN_VOLTAGE_SWING_SHIFT; 1136 msm_dp_link->phy_params.p_level = p_max >> DP_TRAIN_PRE_EMPHASIS_SHIFT; 1137 1138 /** 1139 * Adjust the voltage swing and pre-emphasis level combination to within 1140 * the allowable range. 1141 */ 1142 if (msm_dp_link->phy_params.v_level > DP_TRAIN_LEVEL_MAX) { 1143 drm_dbg_dp(link->drm_dev, 1144 "Requested vSwingLevel=%d, change to %d\n", 1145 msm_dp_link->phy_params.v_level, 1146 DP_TRAIN_LEVEL_MAX); 1147 msm_dp_link->phy_params.v_level = DP_TRAIN_LEVEL_MAX; 1148 } 1149 1150 if (msm_dp_link->phy_params.p_level > DP_TRAIN_LEVEL_MAX) { 1151 drm_dbg_dp(link->drm_dev, 1152 "Requested preEmphasisLevel=%d, change to %d\n", 1153 msm_dp_link->phy_params.p_level, 1154 DP_TRAIN_LEVEL_MAX); 1155 msm_dp_link->phy_params.p_level = DP_TRAIN_LEVEL_MAX; 1156 } 1157 1158 max_p_level = DP_TRAIN_LEVEL_MAX - msm_dp_link->phy_params.v_level; 1159 if (msm_dp_link->phy_params.p_level > max_p_level) { 1160 drm_dbg_dp(link->drm_dev, 1161 "Requested preEmphasisLevel=%d, change to %d\n", 1162 msm_dp_link->phy_params.p_level, 1163 max_p_level); 1164 msm_dp_link->phy_params.p_level = max_p_level; 1165 } 1166 1167 drm_dbg_dp(link->drm_dev, "adjusted: v_level=%d, p_level=%d\n", 1168 msm_dp_link->phy_params.v_level, msm_dp_link->phy_params.p_level); 1169 1170 return 0; 1171 } 1172 1173 void msm_dp_link_reset_phy_params_vx_px(struct msm_dp_link *msm_dp_link) 1174 { 1175 msm_dp_link->phy_params.v_level = 0; 1176 msm_dp_link->phy_params.p_level = 0; 1177 } 1178 1179 u32 msm_dp_link_get_test_bits_depth(struct msm_dp_link *msm_dp_link, u32 bpp) 1180 { 1181 u32 tbd; 1182 struct msm_dp_link_private *link; 1183 1184 link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link); 1185 1186 /* 1187 * Few simplistic rules and assumptions made here: 1188 * 1. Test bit depth is bit depth per color component 1189 * 2. Assume 3 color components 1190 */ 1191 switch (bpp) { 1192 case 18: 1193 tbd = DP_TEST_BIT_DEPTH_6; 1194 break; 1195 case 24: 1196 tbd = DP_TEST_BIT_DEPTH_8; 1197 break; 1198 case 30: 1199 tbd = DP_TEST_BIT_DEPTH_10; 1200 break; 1201 default: 1202 drm_dbg_dp(link->drm_dev, "bpp=%d not supported, use bpc=8\n", 1203 bpp); 1204 tbd = DP_TEST_BIT_DEPTH_8; 1205 break; 1206 } 1207 1208 tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT); 1209 1210 return tbd; 1211 } 1212 1213 struct msm_dp_link *msm_dp_link_get(struct device *dev, struct drm_dp_aux *aux) 1214 { 1215 struct msm_dp_link_private *link; 1216 struct msm_dp_link *msm_dp_link; 1217 1218 if (!dev || !aux) { 1219 DRM_ERROR("invalid input\n"); 1220 return ERR_PTR(-EINVAL); 1221 } 1222 1223 link = devm_kzalloc(dev, sizeof(*link), GFP_KERNEL); 1224 if (!link) 1225 return ERR_PTR(-ENOMEM); 1226 1227 link->aux = aux; 1228 1229 mutex_init(&link->psm_mutex); 1230 msm_dp_link = &link->msm_dp_link; 1231 1232 return msm_dp_link; 1233 } 1234