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