dp_link.c (31788B)
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_link.h" 11#include "dp_panel.h" 12 13#define DP_TEST_REQUEST_MASK 0x7F 14 15enum audio_sample_rate { 16 AUDIO_SAMPLE_RATE_32_KHZ = 0x00, 17 AUDIO_SAMPLE_RATE_44_1_KHZ = 0x01, 18 AUDIO_SAMPLE_RATE_48_KHZ = 0x02, 19 AUDIO_SAMPLE_RATE_88_2_KHZ = 0x03, 20 AUDIO_SAMPLE_RATE_96_KHZ = 0x04, 21 AUDIO_SAMPLE_RATE_176_4_KHZ = 0x05, 22 AUDIO_SAMPLE_RATE_192_KHZ = 0x06, 23}; 24 25enum audio_pattern_type { 26 AUDIO_TEST_PATTERN_OPERATOR_DEFINED = 0x00, 27 AUDIO_TEST_PATTERN_SAWTOOTH = 0x01, 28}; 29 30struct dp_link_request { 31 u32 test_requested; 32 u32 test_link_rate; 33 u32 test_lane_count; 34}; 35 36struct dp_link_private { 37 u32 prev_sink_count; 38 struct device *dev; 39 struct drm_device *drm_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_dbg_dp(link->drm_dev, "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_dbg_dp(link->drm_dev, "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_dbg_dp(link->drm_dev, "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_dbg_dp(link->drm_dev, "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_dbg_dp(link->drm_dev, "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_dbg_dp(link->drm_dev, "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_dbg_dp(link->drm_dev, "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_dbg_dp(link->drm_dev, "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_dbg_dp(link->drm_dev, "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_dbg_dp(link->drm_dev, 251 "sampling_rate = 0x%x, channel_count = 0x%x\n", 252 sampling_rate, channel_count); 253exit: 254 return ret; 255} 256 257static int dp_link_parse_audio_pattern_params(struct dp_link_private *link) 258{ 259 int ret = 0; 260 261 ret = dp_link_parse_audio_mode(link); 262 if (ret) 263 goto exit; 264 265 ret = dp_link_parse_audio_pattern_type(link); 266 if (ret) 267 goto exit; 268 269 ret = dp_link_parse_audio_channel_period(link); 270 271exit: 272 return ret; 273} 274 275static bool dp_link_is_video_pattern_valid(u32 pattern) 276{ 277 switch (pattern) { 278 case DP_NO_TEST_PATTERN: 279 case DP_COLOR_RAMP: 280 case DP_BLACK_AND_WHITE_VERTICAL_LINES: 281 case DP_COLOR_SQUARE: 282 return true; 283 default: 284 return false; 285 } 286} 287 288/** 289 * dp_link_is_bit_depth_valid() - validates the bit depth requested 290 * @tbd: bit depth requested by the sink 291 * 292 * Returns true if the requested bit depth is supported. 293 */ 294static bool dp_link_is_bit_depth_valid(u32 tbd) 295{ 296 /* DP_TEST_VIDEO_PATTERN_NONE is treated as invalid */ 297 switch (tbd) { 298 case DP_TEST_BIT_DEPTH_6: 299 case DP_TEST_BIT_DEPTH_8: 300 case DP_TEST_BIT_DEPTH_10: 301 return true; 302 default: 303 return false; 304 } 305} 306 307static int dp_link_parse_timing_params1(struct dp_link_private *link, 308 int addr, int len, u32 *val) 309{ 310 u8 bp[2]; 311 int rlen; 312 313 if (len != 2) 314 return -EINVAL; 315 316 /* Read the requested video link pattern (Byte 0x221). */ 317 rlen = drm_dp_dpcd_read(link->aux, addr, bp, len); 318 if (rlen < len) { 319 DRM_ERROR("failed to read 0x%x\n", addr); 320 return -EINVAL; 321 } 322 323 *val = bp[1] | (bp[0] << 8); 324 325 return 0; 326} 327 328static int dp_link_parse_timing_params2(struct dp_link_private *link, 329 int addr, int len, 330 u32 *val1, u32 *val2) 331{ 332 u8 bp[2]; 333 int rlen; 334 335 if (len != 2) 336 return -EINVAL; 337 338 /* Read the requested video link pattern (Byte 0x221). */ 339 rlen = drm_dp_dpcd_read(link->aux, addr, bp, len); 340 if (rlen < len) { 341 DRM_ERROR("failed to read 0x%x\n", addr); 342 return -EINVAL; 343 } 344 345 *val1 = (bp[0] & BIT(7)) >> 7; 346 *val2 = bp[1] | ((bp[0] & 0x7F) << 8); 347 348 return 0; 349} 350 351static int dp_link_parse_timing_params3(struct dp_link_private *link, 352 int addr, u32 *val) 353{ 354 u8 bp; 355 u32 len = 1; 356 int rlen; 357 358 rlen = drm_dp_dpcd_read(link->aux, addr, &bp, len); 359 if (rlen < 1) { 360 DRM_ERROR("failed to read 0x%x\n", addr); 361 return -EINVAL; 362 } 363 *val = bp; 364 365 return 0; 366} 367 368/** 369 * dp_link_parse_video_pattern_params() - parses video pattern parameters from DPCD 370 * @link: Display Port Driver data 371 * 372 * Returns 0 if it successfully parses the video link pattern and the link 373 * bit depth requested by the sink and, and if the values parsed are valid. 374 */ 375static int dp_link_parse_video_pattern_params(struct dp_link_private *link) 376{ 377 int ret = 0; 378 ssize_t rlen; 379 u8 bp; 380 381 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_PATTERN, &bp); 382 if (rlen < 0) { 383 DRM_ERROR("failed to read link video pattern. rlen=%zd\n", 384 rlen); 385 return rlen; 386 } 387 388 if (!dp_link_is_video_pattern_valid(bp)) { 389 DRM_ERROR("invalid link video pattern = 0x%x\n", bp); 390 ret = -EINVAL; 391 return ret; 392 } 393 394 link->dp_link.test_video.test_video_pattern = bp; 395 396 /* Read the requested color bit depth and dynamic range (Byte 0x232) */ 397 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_MISC0, &bp); 398 if (rlen < 0) { 399 DRM_ERROR("failed to read link bit depth. rlen=%zd\n", rlen); 400 return rlen; 401 } 402 403 /* Dynamic Range */ 404 link->dp_link.test_video.test_dyn_range = 405 (bp & DP_TEST_DYNAMIC_RANGE_CEA); 406 407 /* Color bit depth */ 408 bp &= DP_TEST_BIT_DEPTH_MASK; 409 if (!dp_link_is_bit_depth_valid(bp)) { 410 DRM_ERROR("invalid link bit depth = 0x%x\n", bp); 411 ret = -EINVAL; 412 return ret; 413 } 414 415 link->dp_link.test_video.test_bit_depth = bp; 416 417 /* resolution timing params */ 418 ret = dp_link_parse_timing_params1(link, DP_TEST_H_TOTAL_HI, 2, 419 &link->dp_link.test_video.test_h_total); 420 if (ret) { 421 DRM_ERROR("failed to parse test_htotal(DP_TEST_H_TOTAL_HI)\n"); 422 return ret; 423 } 424 425 ret = dp_link_parse_timing_params1(link, DP_TEST_V_TOTAL_HI, 2, 426 &link->dp_link.test_video.test_v_total); 427 if (ret) { 428 DRM_ERROR("failed to parse test_v_total(DP_TEST_V_TOTAL_HI)\n"); 429 return ret; 430 } 431 432 ret = dp_link_parse_timing_params1(link, DP_TEST_H_START_HI, 2, 433 &link->dp_link.test_video.test_h_start); 434 if (ret) { 435 DRM_ERROR("failed to parse test_h_start(DP_TEST_H_START_HI)\n"); 436 return ret; 437 } 438 439 ret = dp_link_parse_timing_params1(link, DP_TEST_V_START_HI, 2, 440 &link->dp_link.test_video.test_v_start); 441 if (ret) { 442 DRM_ERROR("failed to parse test_v_start(DP_TEST_V_START_HI)\n"); 443 return ret; 444 } 445 446 ret = dp_link_parse_timing_params2(link, DP_TEST_HSYNC_HI, 2, 447 &link->dp_link.test_video.test_hsync_pol, 448 &link->dp_link.test_video.test_hsync_width); 449 if (ret) { 450 DRM_ERROR("failed to parse (DP_TEST_HSYNC_HI)\n"); 451 return ret; 452 } 453 454 ret = dp_link_parse_timing_params2(link, DP_TEST_VSYNC_HI, 2, 455 &link->dp_link.test_video.test_vsync_pol, 456 &link->dp_link.test_video.test_vsync_width); 457 if (ret) { 458 DRM_ERROR("failed to parse (DP_TEST_VSYNC_HI)\n"); 459 return ret; 460 } 461 462 ret = dp_link_parse_timing_params1(link, DP_TEST_H_WIDTH_HI, 2, 463 &link->dp_link.test_video.test_h_width); 464 if (ret) { 465 DRM_ERROR("failed to parse test_h_width(DP_TEST_H_WIDTH_HI)\n"); 466 return ret; 467 } 468 469 ret = dp_link_parse_timing_params1(link, DP_TEST_V_HEIGHT_HI, 2, 470 &link->dp_link.test_video.test_v_height); 471 if (ret) { 472 DRM_ERROR("failed to parse test_v_height\n"); 473 return ret; 474 } 475 476 ret = dp_link_parse_timing_params3(link, DP_TEST_MISC1, 477 &link->dp_link.test_video.test_rr_d); 478 link->dp_link.test_video.test_rr_d &= DP_TEST_REFRESH_DENOMINATOR; 479 if (ret) { 480 DRM_ERROR("failed to parse test_rr_d (DP_TEST_MISC1)\n"); 481 return ret; 482 } 483 484 ret = dp_link_parse_timing_params3(link, DP_TEST_REFRESH_RATE_NUMERATOR, 485 &link->dp_link.test_video.test_rr_n); 486 if (ret) { 487 DRM_ERROR("failed to parse test_rr_n\n"); 488 return ret; 489 } 490 491 drm_dbg_dp(link->drm_dev, 492 "link video pattern = 0x%x\n" 493 "link dynamic range = 0x%x\n" 494 "link bit depth = 0x%x\n" 495 "TEST_H_TOTAL = %d, TEST_V_TOTAL = %d\n" 496 "TEST_H_START = %d, TEST_V_START = %d\n" 497 "TEST_HSYNC_POL = %d\n" 498 "TEST_HSYNC_WIDTH = %d\n" 499 "TEST_VSYNC_POL = %d\n" 500 "TEST_VSYNC_WIDTH = %d\n" 501 "TEST_H_WIDTH = %d\n" 502 "TEST_V_HEIGHT = %d\n" 503 "TEST_REFRESH_DENOMINATOR = %d\n" 504 "TEST_REFRESH_NUMERATOR = %d\n", 505 link->dp_link.test_video.test_video_pattern, 506 link->dp_link.test_video.test_dyn_range, 507 link->dp_link.test_video.test_bit_depth, 508 link->dp_link.test_video.test_h_total, 509 link->dp_link.test_video.test_v_total, 510 link->dp_link.test_video.test_h_start, 511 link->dp_link.test_video.test_v_start, 512 link->dp_link.test_video.test_hsync_pol, 513 link->dp_link.test_video.test_hsync_width, 514 link->dp_link.test_video.test_vsync_pol, 515 link->dp_link.test_video.test_vsync_width, 516 link->dp_link.test_video.test_h_width, 517 link->dp_link.test_video.test_v_height, 518 link->dp_link.test_video.test_rr_d, 519 link->dp_link.test_video.test_rr_n); 520 521 return ret; 522} 523 524/** 525 * dp_link_parse_link_training_params() - parses link training parameters from 526 * DPCD 527 * @link: Display Port Driver data 528 * 529 * Returns 0 if it successfully parses the link rate (Byte 0x219) and lane 530 * count (Byte 0x220), and if these values parse are valid. 531 */ 532static int dp_link_parse_link_training_params(struct dp_link_private *link) 533{ 534 u8 bp; 535 ssize_t rlen; 536 537 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LINK_RATE, &bp); 538 if (rlen < 0) { 539 DRM_ERROR("failed to read link rate. rlen=%zd\n", rlen); 540 return rlen; 541 } 542 543 if (!is_link_rate_valid(bp)) { 544 DRM_ERROR("invalid link rate = 0x%x\n", bp); 545 return -EINVAL; 546 } 547 548 link->request.test_link_rate = bp; 549 drm_dbg_dp(link->drm_dev, "link rate = 0x%x\n", 550 link->request.test_link_rate); 551 552 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LANE_COUNT, &bp); 553 if (rlen < 0) { 554 DRM_ERROR("failed to read lane count. rlen=%zd\n", rlen); 555 return rlen; 556 } 557 bp &= DP_MAX_LANE_COUNT_MASK; 558 559 if (!is_lane_count_valid(bp)) { 560 DRM_ERROR("invalid lane count = 0x%x\n", bp); 561 return -EINVAL; 562 } 563 564 link->request.test_lane_count = bp; 565 drm_dbg_dp(link->drm_dev, "lane count = 0x%x\n", 566 link->request.test_lane_count); 567 return 0; 568} 569 570/** 571 * dp_link_parse_phy_test_params() - parses the phy link parameters 572 * @link: Display Port Driver data 573 * 574 * Parses the DPCD (Byte 0x248) for the DP PHY link pattern that is being 575 * requested. 576 */ 577static int dp_link_parse_phy_test_params(struct dp_link_private *link) 578{ 579 u8 data; 580 ssize_t rlen; 581 582 rlen = drm_dp_dpcd_readb(link->aux, DP_PHY_TEST_PATTERN, 583 &data); 584 if (rlen < 0) { 585 DRM_ERROR("failed to read phy link pattern. rlen=%zd\n", rlen); 586 return rlen; 587 } 588 589 link->dp_link.phy_params.phy_test_pattern_sel = data & 0x07; 590 591 drm_dbg_dp(link->drm_dev, "phy_test_pattern_sel = 0x%x\n", data); 592 593 switch (data) { 594 case DP_PHY_TEST_PATTERN_SEL_MASK: 595 case DP_PHY_TEST_PATTERN_NONE: 596 case DP_PHY_TEST_PATTERN_D10_2: 597 case DP_PHY_TEST_PATTERN_ERROR_COUNT: 598 case DP_PHY_TEST_PATTERN_PRBS7: 599 case DP_PHY_TEST_PATTERN_80BIT_CUSTOM: 600 case DP_PHY_TEST_PATTERN_CP2520: 601 return 0; 602 default: 603 return -EINVAL; 604 } 605} 606 607/** 608 * dp_link_is_video_audio_test_requested() - checks for audio/video link request 609 * @link: link requested by the sink 610 * 611 * Returns true if the requested link is a permitted audio/video link. 612 */ 613static bool dp_link_is_video_audio_test_requested(u32 link) 614{ 615 u8 video_audio_test = (DP_TEST_LINK_VIDEO_PATTERN | 616 DP_TEST_LINK_AUDIO_PATTERN | 617 DP_TEST_LINK_AUDIO_DISABLED_VIDEO); 618 619 return ((link & video_audio_test) && 620 !(link & ~video_audio_test)); 621} 622 623/** 624 * dp_link_parse_request() - parses link request parameters from sink 625 * @link: Display Port Driver data 626 * 627 * Parses the DPCD to check if an automated link is requested (Byte 0x201), 628 * and what type of link automation is being requested (Byte 0x218). 629 */ 630static int dp_link_parse_request(struct dp_link_private *link) 631{ 632 int ret = 0; 633 u8 data; 634 ssize_t rlen; 635 636 /** 637 * Read the device service IRQ vector (Byte 0x201) to determine 638 * whether an automated link has been requested by the sink. 639 */ 640 rlen = drm_dp_dpcd_readb(link->aux, 641 DP_DEVICE_SERVICE_IRQ_VECTOR, &data); 642 if (rlen < 0) { 643 DRM_ERROR("aux read failed. rlen=%zd\n", rlen); 644 return rlen; 645 } 646 647 drm_dbg_dp(link->drm_dev, "device service irq vector = 0x%x\n", data); 648 649 if (!(data & DP_AUTOMATED_TEST_REQUEST)) { 650 drm_dbg_dp(link->drm_dev, "no test requested\n"); 651 return 0; 652 } 653 654 /** 655 * Read the link request byte (Byte 0x218) to determine what type 656 * of automated link has been requested by the sink. 657 */ 658 rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_REQUEST, &data); 659 if (rlen < 0) { 660 DRM_ERROR("aux read failed. rlen=%zd\n", rlen); 661 return rlen; 662 } 663 664 if (!data || (data == DP_TEST_LINK_FAUX_PATTERN)) { 665 drm_dbg_dp(link->drm_dev, "link 0x%x not supported\n", data); 666 goto end; 667 } 668 669 drm_dbg_dp(link->drm_dev, "Test:(0x%x) requested\n", data); 670 link->request.test_requested = data; 671 if (link->request.test_requested == DP_TEST_LINK_PHY_TEST_PATTERN) { 672 ret = dp_link_parse_phy_test_params(link); 673 if (ret) 674 goto end; 675 ret = dp_link_parse_link_training_params(link); 676 if (ret) 677 goto end; 678 } 679 680 if (link->request.test_requested == DP_TEST_LINK_TRAINING) { 681 ret = dp_link_parse_link_training_params(link); 682 if (ret) 683 goto end; 684 } 685 686 if (dp_link_is_video_audio_test_requested( 687 link->request.test_requested)) { 688 ret = dp_link_parse_video_pattern_params(link); 689 if (ret) 690 goto end; 691 692 ret = dp_link_parse_audio_pattern_params(link); 693 } 694end: 695 /* 696 * Send a DP_TEST_ACK if all link parameters are valid, otherwise send 697 * a DP_TEST_NAK. 698 */ 699 if (ret) { 700 link->dp_link.test_response = DP_TEST_NAK; 701 } else { 702 if (link->request.test_requested != DP_TEST_LINK_EDID_READ) 703 link->dp_link.test_response = DP_TEST_ACK; 704 else 705 link->dp_link.test_response = 706 DP_TEST_EDID_CHECKSUM_WRITE; 707 } 708 709 return ret; 710} 711 712/** 713 * dp_link_parse_sink_count() - parses the sink count 714 * @dp_link: pointer to link module data 715 * 716 * Parses the DPCD to check if there is an update to the sink count 717 * (Byte 0x200), and whether all the sink devices connected have Content 718 * Protection enabled. 719 */ 720static int dp_link_parse_sink_count(struct dp_link *dp_link) 721{ 722 ssize_t rlen; 723 bool cp_ready; 724 725 struct dp_link_private *link = container_of(dp_link, 726 struct dp_link_private, dp_link); 727 728 rlen = drm_dp_dpcd_readb(link->aux, DP_SINK_COUNT, 729 &link->dp_link.sink_count); 730 if (rlen < 0) { 731 DRM_ERROR("sink count read failed. rlen=%zd\n", rlen); 732 return rlen; 733 } 734 735 cp_ready = link->dp_link.sink_count & DP_SINK_CP_READY; 736 737 link->dp_link.sink_count = 738 DP_GET_SINK_COUNT(link->dp_link.sink_count); 739 740 drm_dbg_dp(link->drm_dev, "sink_count = 0x%x, cp_ready = 0x%x\n", 741 link->dp_link.sink_count, cp_ready); 742 return 0; 743} 744 745static int dp_link_parse_sink_status_field(struct dp_link_private *link) 746{ 747 int len = 0; 748 749 link->prev_sink_count = link->dp_link.sink_count; 750 len = dp_link_parse_sink_count(&link->dp_link); 751 if (len < 0) { 752 DRM_ERROR("DP parse sink count failed\n"); 753 return len; 754 } 755 756 len = drm_dp_dpcd_read_link_status(link->aux, 757 link->link_status); 758 if (len < DP_LINK_STATUS_SIZE) { 759 DRM_ERROR("DP link status read failed\n"); 760 return len; 761 } 762 763 return dp_link_parse_request(link); 764} 765 766/** 767 * dp_link_process_link_training_request() - processes new training requests 768 * @link: Display Port link data 769 * 770 * This function will handle new link training requests that are initiated by 771 * the sink. In particular, it will update the requested lane count and link 772 * rate, and then trigger the link retraining procedure. 773 * 774 * The function will return 0 if a link training request has been processed, 775 * otherwise it will return -EINVAL. 776 */ 777static int dp_link_process_link_training_request(struct dp_link_private *link) 778{ 779 if (link->request.test_requested != DP_TEST_LINK_TRAINING) 780 return -EINVAL; 781 782 drm_dbg_dp(link->drm_dev, 783 "Test:0x%x link rate = 0x%x, lane count = 0x%x\n", 784 DP_TEST_LINK_TRAINING, 785 link->request.test_link_rate, 786 link->request.test_lane_count); 787 788 link->dp_link.link_params.num_lanes = link->request.test_lane_count; 789 link->dp_link.link_params.rate = 790 drm_dp_bw_code_to_link_rate(link->request.test_link_rate); 791 792 return 0; 793} 794 795bool dp_link_send_test_response(struct dp_link *dp_link) 796{ 797 struct dp_link_private *link = NULL; 798 int ret = 0; 799 800 if (!dp_link) { 801 DRM_ERROR("invalid input\n"); 802 return false; 803 } 804 805 link = container_of(dp_link, struct dp_link_private, dp_link); 806 807 ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_RESPONSE, 808 dp_link->test_response); 809 810 return ret == 1; 811} 812 813int dp_link_psm_config(struct dp_link *dp_link, 814 struct dp_link_info *link_info, bool enable) 815{ 816 struct dp_link_private *link = NULL; 817 int ret = 0; 818 819 if (!dp_link) { 820 DRM_ERROR("invalid params\n"); 821 return -EINVAL; 822 } 823 824 link = container_of(dp_link, struct dp_link_private, dp_link); 825 826 mutex_lock(&link->psm_mutex); 827 if (enable) 828 ret = dp_aux_link_power_down(link->aux, link_info); 829 else 830 ret = dp_aux_link_power_up(link->aux, link_info); 831 832 if (ret) 833 DRM_ERROR("Failed to %s low power mode\n", enable ? 834 "enter" : "exit"); 835 else 836 dp_link->psm_enabled = enable; 837 838 mutex_unlock(&link->psm_mutex); 839 return ret; 840} 841 842bool dp_link_send_edid_checksum(struct dp_link *dp_link, u8 checksum) 843{ 844 struct dp_link_private *link = NULL; 845 int ret = 0; 846 847 if (!dp_link) { 848 DRM_ERROR("invalid input\n"); 849 return false; 850 } 851 852 link = container_of(dp_link, struct dp_link_private, dp_link); 853 854 ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_EDID_CHECKSUM, 855 checksum); 856 return ret == 1; 857} 858 859static void dp_link_parse_vx_px(struct dp_link_private *link) 860{ 861 drm_dbg_dp(link->drm_dev, "vx: 0=%d, 1=%d, 2=%d, 3=%d\n", 862 drm_dp_get_adjust_request_voltage(link->link_status, 0), 863 drm_dp_get_adjust_request_voltage(link->link_status, 1), 864 drm_dp_get_adjust_request_voltage(link->link_status, 2), 865 drm_dp_get_adjust_request_voltage(link->link_status, 3)); 866 867 drm_dbg_dp(link->drm_dev, "px: 0=%d, 1=%d, 2=%d, 3=%d\n", 868 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0), 869 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 1), 870 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 2), 871 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 3)); 872 873 /** 874 * Update the voltage and pre-emphasis levels as per DPCD request 875 * vector. 876 */ 877 drm_dbg_dp(link->drm_dev, 878 "Current: v_level = 0x%x, p_level = 0x%x\n", 879 link->dp_link.phy_params.v_level, 880 link->dp_link.phy_params.p_level); 881 link->dp_link.phy_params.v_level = 882 drm_dp_get_adjust_request_voltage(link->link_status, 0); 883 link->dp_link.phy_params.p_level = 884 drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0); 885 886 link->dp_link.phy_params.p_level >>= DP_TRAIN_PRE_EMPHASIS_SHIFT; 887 888 drm_dbg_dp(link->drm_dev, 889 "Requested: v_level = 0x%x, p_level = 0x%x\n", 890 link->dp_link.phy_params.v_level, 891 link->dp_link.phy_params.p_level); 892} 893 894/** 895 * dp_link_process_phy_test_pattern_request() - process new phy link requests 896 * @link: Display Port Driver data 897 * 898 * This function will handle new phy link pattern requests that are initiated 899 * by the sink. The function will return 0 if a phy link pattern has been 900 * processed, otherwise it will return -EINVAL. 901 */ 902static int dp_link_process_phy_test_pattern_request( 903 struct dp_link_private *link) 904{ 905 if (!(link->request.test_requested & DP_TEST_LINK_PHY_TEST_PATTERN)) { 906 drm_dbg_dp(link->drm_dev, "no phy test\n"); 907 return -EINVAL; 908 } 909 910 if (!is_link_rate_valid(link->request.test_link_rate) || 911 !is_lane_count_valid(link->request.test_lane_count)) { 912 DRM_ERROR("Invalid: link rate = 0x%x,lane count = 0x%x\n", 913 link->request.test_link_rate, 914 link->request.test_lane_count); 915 return -EINVAL; 916 } 917 918 drm_dbg_dp(link->drm_dev, 919 "Current: rate = 0x%x, lane count = 0x%x\n", 920 link->dp_link.link_params.rate, 921 link->dp_link.link_params.num_lanes); 922 923 drm_dbg_dp(link->drm_dev, 924 "Requested: rate = 0x%x, lane count = 0x%x\n", 925 link->request.test_link_rate, 926 link->request.test_lane_count); 927 928 link->dp_link.link_params.num_lanes = link->request.test_lane_count; 929 link->dp_link.link_params.rate = 930 drm_dp_bw_code_to_link_rate(link->request.test_link_rate); 931 932 dp_link_parse_vx_px(link); 933 934 return 0; 935} 936 937static u8 get_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r) 938{ 939 return link_status[r - DP_LANE0_1_STATUS]; 940} 941 942/** 943 * dp_link_process_link_status_update() - processes link status updates 944 * @link: Display Port link module data 945 * 946 * This function will check for changes in the link status, e.g. clock 947 * recovery done on all lanes, and trigger link training if there is a 948 * failure/error on the link. 949 * 950 * The function will return 0 if the a link status update has been processed, 951 * otherwise it will return -EINVAL. 952 */ 953static int dp_link_process_link_status_update(struct dp_link_private *link) 954{ 955 bool channel_eq_done = drm_dp_channel_eq_ok(link->link_status, 956 link->dp_link.link_params.num_lanes); 957 958 bool clock_recovery_done = drm_dp_clock_recovery_ok(link->link_status, 959 link->dp_link.link_params.num_lanes); 960 961 drm_dbg_dp(link->drm_dev, 962 "channel_eq_done = %d, clock_recovery_done = %d\n", 963 channel_eq_done, clock_recovery_done); 964 965 if (channel_eq_done && clock_recovery_done) 966 return -EINVAL; 967 968 969 return 0; 970} 971 972/** 973 * 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 */ 983static int dp_link_process_ds_port_status_change(struct 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->dp_link.sink_count) 990 return -EINVAL; 991 992reset: 993 /* reset prev_sink_count */ 994 link->prev_sink_count = link->dp_link.sink_count; 995 996 return 0; 997} 998 999static bool dp_link_is_video_pattern_requested(struct 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 1006static bool dp_link_is_audio_pattern_requested(struct dp_link_private *link) 1007{ 1008 return (link->request.test_requested & DP_TEST_LINK_AUDIO_PATTERN); 1009} 1010 1011static void dp_link_reset_data(struct dp_link_private *link) 1012{ 1013 link->request = (const struct dp_link_request){ 0 }; 1014 link->dp_link.test_video = (const struct dp_link_test_video){ 0 }; 1015 link->dp_link.test_video.test_bit_depth = DP_TEST_BIT_DEPTH_UNKNOWN; 1016 link->dp_link.test_audio = (const struct dp_link_test_audio){ 0 }; 1017 link->dp_link.phy_params.phy_test_pattern_sel = 0; 1018 link->dp_link.sink_request = 0; 1019 link->dp_link.test_response = 0; 1020} 1021 1022/** 1023 * dp_link_process_request() - handle HPD IRQ transition to HIGH 1024 * @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 */ 1030int dp_link_process_request(struct dp_link *dp_link) 1031{ 1032 int ret = 0; 1033 struct dp_link_private *link; 1034 1035 if (!dp_link) { 1036 DRM_ERROR("invalid input\n"); 1037 return -EINVAL; 1038 } 1039 1040 link = container_of(dp_link, struct dp_link_private, dp_link); 1041 1042 dp_link_reset_data(link); 1043 1044 ret = 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 dp_link->sink_request |= DP_TEST_LINK_EDID_READ; 1050 } else if (!dp_link_process_ds_port_status_change(link)) { 1051 dp_link->sink_request |= DS_PORT_STATUS_CHANGED; 1052 } else if (!dp_link_process_link_training_request(link)) { 1053 dp_link->sink_request |= DP_TEST_LINK_TRAINING; 1054 } else if (!dp_link_process_phy_test_pattern_request(link)) { 1055 dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN; 1056 } else { 1057 ret = dp_link_process_link_status_update(link); 1058 if (!ret) { 1059 dp_link->sink_request |= DP_LINK_STATUS_UPDATED; 1060 } else { 1061 if (dp_link_is_video_pattern_requested(link)) { 1062 ret = 0; 1063 dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN; 1064 } 1065 if (dp_link_is_audio_pattern_requested(link)) { 1066 dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN; 1067 ret = -EINVAL; 1068 } 1069 } 1070 } 1071 1072 drm_dbg_dp(link->drm_dev, "sink request=%#x", 1073 dp_link->sink_request); 1074 return ret; 1075} 1076 1077int dp_link_get_colorimetry_config(struct dp_link *dp_link) 1078{ 1079 u32 cc; 1080 struct dp_link_private *link; 1081 1082 if (!dp_link) { 1083 DRM_ERROR("invalid input\n"); 1084 return -EINVAL; 1085 } 1086 1087 link = container_of(dp_link, struct dp_link_private, dp_link); 1088 1089 /* 1090 * Unless a video pattern CTS test is ongoing, use RGB_VESA 1091 * Only RGB_VESA and RGB_CEA supported for now 1092 */ 1093 if (dp_link_is_video_pattern_requested(link)) 1094 cc = link->dp_link.test_video.test_dyn_range; 1095 else 1096 cc = DP_TEST_DYNAMIC_RANGE_VESA; 1097 1098 return cc; 1099} 1100 1101int dp_link_adjust_levels(struct dp_link *dp_link, u8 *link_status) 1102{ 1103 int i; 1104 int v_max = 0, p_max = 0; 1105 struct dp_link_private *link; 1106 1107 if (!dp_link) { 1108 DRM_ERROR("invalid input\n"); 1109 return -EINVAL; 1110 } 1111 1112 link = container_of(dp_link, struct dp_link_private, dp_link); 1113 1114 /* use the max level across lanes */ 1115 for (i = 0; i < dp_link->link_params.num_lanes; i++) { 1116 u8 data_v = drm_dp_get_adjust_request_voltage(link_status, i); 1117 u8 data_p = drm_dp_get_adjust_request_pre_emphasis(link_status, 1118 i); 1119 drm_dbg_dp(link->drm_dev, 1120 "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_dbg_dp(link->drm_dev, 1137 "Requested vSwingLevel=%d, change to %d\n", 1138 dp_link->phy_params.v_level, 1139 DP_TRAIN_VOLTAGE_SWING_MAX); 1140 dp_link->phy_params.v_level = DP_TRAIN_VOLTAGE_SWING_MAX; 1141 } 1142 1143 if (dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_MAX) { 1144 drm_dbg_dp(link->drm_dev, 1145 "Requested preEmphasisLevel=%d, change to %d\n", 1146 dp_link->phy_params.p_level, 1147 DP_TRAIN_PRE_EMPHASIS_MAX); 1148 dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_MAX; 1149 } 1150 1151 if ((dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_LVL_1) 1152 && (dp_link->phy_params.v_level == 1153 DP_TRAIN_VOLTAGE_SWING_LVL_2)) { 1154 drm_dbg_dp(link->drm_dev, 1155 "Requested preEmphasisLevel=%d, change to %d\n", 1156 dp_link->phy_params.p_level, 1157 DP_TRAIN_PRE_EMPHASIS_LVL_1); 1158 dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_LVL_1; 1159 } 1160 1161 drm_dbg_dp(link->drm_dev, "adjusted: v_level=%d, p_level=%d\n", 1162 dp_link->phy_params.v_level, dp_link->phy_params.p_level); 1163 1164 return 0; 1165} 1166 1167void dp_link_reset_phy_params_vx_px(struct dp_link *dp_link) 1168{ 1169 dp_link->phy_params.v_level = 0; 1170 dp_link->phy_params.p_level = 0; 1171} 1172 1173u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp) 1174{ 1175 u32 tbd; 1176 1177 /* 1178 * Few simplistic rules and assumptions made here: 1179 * 1. Test bit depth is bit depth per color component 1180 * 2. Assume 3 color components 1181 */ 1182 switch (bpp) { 1183 case 18: 1184 tbd = DP_TEST_BIT_DEPTH_6; 1185 break; 1186 case 24: 1187 tbd = DP_TEST_BIT_DEPTH_8; 1188 break; 1189 case 30: 1190 tbd = DP_TEST_BIT_DEPTH_10; 1191 break; 1192 default: 1193 tbd = DP_TEST_BIT_DEPTH_UNKNOWN; 1194 break; 1195 } 1196 1197 if (tbd != DP_TEST_BIT_DEPTH_UNKNOWN) 1198 tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT); 1199 1200 return tbd; 1201} 1202 1203struct dp_link *dp_link_get(struct device *dev, struct drm_dp_aux *aux) 1204{ 1205 struct dp_link_private *link; 1206 struct dp_link *dp_link; 1207 1208 if (!dev || !aux) { 1209 DRM_ERROR("invalid input\n"); 1210 return ERR_PTR(-EINVAL); 1211 } 1212 1213 link = devm_kzalloc(dev, sizeof(*link), GFP_KERNEL); 1214 if (!link) 1215 return ERR_PTR(-ENOMEM); 1216 1217 link->dev = dev; 1218 link->aux = aux; 1219 1220 mutex_init(&link->psm_mutex); 1221 dp_link = &link->dp_link; 1222 1223 return dp_link; 1224}