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