1 // SPDX-License-Identifier: MIT 2 /* Copyright © 2024 Intel Corporation */ 3 4 #include <linux/debugfs.h> 5 6 #include <drm/display/drm_dp.h> 7 #include <drm/display/drm_dp_helper.h> 8 #include <drm/drm_edid.h> 9 #include <drm/drm_print.h> 10 #include <drm/drm_probe_helper.h> 11 12 #include "intel_ddi.h" 13 #include "intel_de.h" 14 #include "intel_display_regs.h" 15 #include "intel_display_types.h" 16 #include "intel_dp.h" 17 #include "intel_dp_link_caps.h" 18 #include "intel_dp_link_training.h" 19 #include "intel_dp_mst.h" 20 #include "intel_dp_test.h" 21 22 void intel_dp_test_reset(struct intel_dp *intel_dp) 23 { 24 /* 25 * Clearing compliance test variables to allow capturing 26 * of values for next automated test request. 27 */ 28 memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance)); 29 } 30 31 static bool set_filter_for_lane_count(struct intel_connector *connector, 32 struct intel_dp_link_caps *link_caps, 33 int lane_count, 34 struct link_config_limits *limits) 35 { 36 struct intel_dp_link_config link_config; 37 struct intel_dp_link_caps_order order = 38 intel_dp_link_caps_connector_compute_order(connector); 39 struct intel_dp_link_caps_filter new_filter = INTEL_DP_LINK_CAPS_FILTER_NONE; 40 struct intel_dp_link_caps_iter iter; 41 bool found = false; 42 43 intel_dp_link_caps_iter_start(&iter, link_caps, order, limits->link_config_filter); 44 for_each_dp_link_config(&iter, &link_config) { 45 if (link_config.lane_count != lane_count) 46 continue; 47 48 intel_dp_link_caps_filter_add(link_caps, &new_filter, &link_config); 49 found = true; 50 } 51 intel_dp_link_caps_iter_end(&iter); 52 53 if (!found) 54 return false; 55 56 limits->link_config_filter = new_filter; 57 58 return true; 59 } 60 61 static bool set_filter_for_link_config(struct intel_connector *connector, 62 struct intel_dp_link_caps *link_caps, 63 const struct intel_dp_link_config *link_params, 64 struct link_config_limits *limits) 65 { 66 struct intel_dp_link_caps_filter new_filter = INTEL_DP_LINK_CAPS_FILTER_NONE; 67 68 if (!intel_dp_link_caps_filter_add(link_caps, &new_filter, link_params)) 69 return false; 70 71 limits->link_config_filter = new_filter; 72 73 return true; 74 } 75 76 static bool set_filter_for_link_params(struct intel_connector *connector, 77 int link_rate, int lane_count, 78 struct link_config_limits *limits) 79 { 80 struct intel_dp *intel_dp = intel_attached_dp(connector); 81 struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 82 struct intel_dp_link_caps *link_caps = intel_dp->link.caps; 83 struct intel_display *display = to_intel_display(intel_dp); 84 struct intel_dp_link_config requested_config; 85 86 requested_config.rate = link_rate; 87 requested_config.lane_count = lane_count; 88 89 if (set_filter_for_link_config(connector, link_caps, &requested_config, limits)) 90 return true; 91 92 /* 93 * Preserve the legacy behavior: if the requested (rate, lane_count) 94 * combination is not an allowed config, fall back to all configs 95 * matching the requested lane count. 96 * 97 * TODO: Recheck whether this behavior is actually correct. 98 */ 99 if (set_filter_for_lane_count(connector, link_caps, lane_count, limits)) 100 return true; 101 102 drm_dbg_kms(display->drm, 103 "[ENCODER:%d:%s] Invalid autotest link config parameters: %dx%d\n", 104 encoder->base.base.id, encoder->base.name, 105 requested_config.lane_count, 106 requested_config.rate); 107 108 return false; 109 } 110 111 /* Adjust link config limits based on compliance test requests. */ 112 bool intel_dp_test_compute_config(struct intel_connector *connector, 113 struct intel_crtc_state *pipe_config, 114 struct link_config_limits *limits) 115 { 116 struct intel_dp *intel_dp = intel_attached_dp(connector); 117 struct intel_display *display = to_intel_display(intel_dp); 118 119 /* For DP Compliance we override the computed bpp for the pipe */ 120 if (intel_dp->compliance.test_data.bpc != 0) { 121 int bpp = 3 * intel_dp->compliance.test_data.bpc; 122 123 limits->pipe.min_bpp = bpp; 124 limits->pipe.max_bpp = bpp; 125 pipe_config->dither_force_disable = bpp == 6 * 3; 126 127 drm_dbg_kms(display->drm, "Setting pipe_bpp to %d\n", bpp); 128 } 129 130 /* Use values requested by Compliance Test Request */ 131 if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { 132 if (!set_filter_for_link_params(connector, 133 intel_dp->compliance.test_link_rate, 134 intel_dp->compliance.test_lane_count, 135 limits)) 136 return false; 137 } 138 139 return true; 140 } 141 142 /* Compliance test status bits */ 143 #define INTEL_DP_RESOLUTION_PREFERRED 1 144 #define INTEL_DP_RESOLUTION_STANDARD 2 145 #define INTEL_DP_RESOLUTION_FAILSAFE 3 146 147 static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) 148 { 149 struct intel_display *display = to_intel_display(intel_dp); 150 int status = 0; 151 int test_link_rate; 152 u8 test_lane_count, test_link_bw; 153 /* (DP CTS 1.2) 154 * 4.3.1.11 155 */ 156 /* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */ 157 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT, 158 &test_lane_count); 159 160 if (status <= 0) { 161 drm_dbg_kms(display->drm, "Lane count read failed\n"); 162 return DP_TEST_NAK; 163 } 164 test_lane_count &= DP_MAX_LANE_COUNT_MASK; 165 166 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE, 167 &test_link_bw); 168 if (status <= 0) { 169 drm_dbg_kms(display->drm, "Link Rate read failed\n"); 170 return DP_TEST_NAK; 171 } 172 test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw); 173 174 /* Validate the requested link rate and lane count */ 175 if (!intel_dp_link_params_valid(intel_dp, test_link_rate, 176 test_lane_count)) 177 return DP_TEST_NAK; 178 179 intel_dp->compliance.test_lane_count = test_lane_count; 180 intel_dp->compliance.test_link_rate = test_link_rate; 181 182 return DP_TEST_ACK; 183 } 184 185 static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp) 186 { 187 struct intel_display *display = to_intel_display(intel_dp); 188 u8 test_pattern; 189 u8 test_misc; 190 __be16 h_width, v_height; 191 int status = 0; 192 193 /* Read the TEST_PATTERN (DP CTS 3.1.5) */ 194 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN, 195 &test_pattern); 196 if (status <= 0) { 197 drm_dbg_kms(display->drm, "Test pattern read failed\n"); 198 return DP_TEST_NAK; 199 } 200 if (test_pattern != DP_COLOR_RAMP) 201 return DP_TEST_NAK; 202 203 status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI, 204 &h_width, 2); 205 if (status <= 0) { 206 drm_dbg_kms(display->drm, "H Width read failed\n"); 207 return DP_TEST_NAK; 208 } 209 210 status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI, 211 &v_height, 2); 212 if (status <= 0) { 213 drm_dbg_kms(display->drm, "V Height read failed\n"); 214 return DP_TEST_NAK; 215 } 216 217 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0, 218 &test_misc); 219 if (status <= 0) { 220 drm_dbg_kms(display->drm, "TEST MISC read failed\n"); 221 return DP_TEST_NAK; 222 } 223 if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB) 224 return DP_TEST_NAK; 225 if (test_misc & DP_TEST_DYNAMIC_RANGE_CEA) 226 return DP_TEST_NAK; 227 switch (test_misc & DP_TEST_BIT_DEPTH_MASK) { 228 case DP_TEST_BIT_DEPTH_6: 229 intel_dp->compliance.test_data.bpc = 6; 230 break; 231 case DP_TEST_BIT_DEPTH_8: 232 intel_dp->compliance.test_data.bpc = 8; 233 break; 234 default: 235 return DP_TEST_NAK; 236 } 237 238 intel_dp->compliance.test_data.video_pattern = test_pattern; 239 intel_dp->compliance.test_data.hdisplay = be16_to_cpu(h_width); 240 intel_dp->compliance.test_data.vdisplay = be16_to_cpu(v_height); 241 /* Set test active flag here so userspace doesn't interrupt things */ 242 intel_dp->compliance.test_active = true; 243 244 return DP_TEST_ACK; 245 } 246 247 static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) 248 { 249 struct intel_display *display = to_intel_display(intel_dp); 250 u8 test_result = DP_TEST_ACK; 251 struct intel_connector *intel_connector = intel_dp->attached_connector; 252 struct drm_connector *connector = &intel_connector->base; 253 254 if (!intel_connector->detect_edid || connector->edid_corrupt || 255 intel_dp->aux.i2c_defer_count > 6) { 256 /* Check EDID read for NACKs, DEFERs and corruption 257 * (DP CTS 1.2 Core r1.1) 258 * 4.2.2.4 : Failed EDID read, I2C_NAK 259 * 4.2.2.5 : Failed EDID read, I2C_DEFER 260 * 4.2.2.6 : EDID corruption detected 261 * Use failsafe mode for all cases 262 */ 263 if (intel_dp->aux.i2c_nack_count > 0 || 264 intel_dp->aux.i2c_defer_count > 0) 265 drm_dbg_kms(display->drm, 266 "EDID read had %d NACKs, %d DEFERs\n", 267 intel_dp->aux.i2c_nack_count, 268 intel_dp->aux.i2c_defer_count); 269 intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE; 270 } else { 271 /* FIXME: Get rid of drm_edid_raw() */ 272 const struct edid *block = drm_edid_raw(intel_connector->detect_edid); 273 274 /* We have to write the checksum of the last block read */ 275 block += block->extensions; 276 277 if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM, 278 block->checksum) <= 0) 279 drm_dbg_kms(display->drm, 280 "Failed to write EDID checksum\n"); 281 282 test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE; 283 intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED; 284 } 285 286 /* Set test active flag here so userspace doesn't interrupt things */ 287 intel_dp->compliance.test_active = true; 288 289 return test_result; 290 } 291 292 static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, 293 const struct intel_crtc_state *crtc_state) 294 { 295 struct intel_display *display = to_intel_display(intel_dp); 296 struct drm_dp_phy_test_params *data = 297 &intel_dp->compliance.test_data.phytest; 298 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 299 struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 300 enum pipe pipe = crtc->pipe; 301 u32 pattern_val; 302 303 switch (data->phy_pattern) { 304 case DP_LINK_QUAL_PATTERN_DISABLE: 305 drm_dbg_kms(display->drm, "Disable Phy Test Pattern\n"); 306 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0); 307 if (DISPLAY_VER(display) >= 10) 308 intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), 309 DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, 310 DP_TP_CTL_LINK_TRAIN_NORMAL); 311 break; 312 case DP_LINK_QUAL_PATTERN_D10_2: 313 drm_dbg_kms(display->drm, "Set D10.2 Phy Test Pattern\n"); 314 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 315 DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2); 316 break; 317 case DP_LINK_QUAL_PATTERN_ERROR_RATE: 318 drm_dbg_kms(display->drm, 319 "Set Error Count Phy Test Pattern\n"); 320 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 321 DDI_DP_COMP_CTL_ENABLE | 322 DDI_DP_COMP_CTL_SCRAMBLED_0); 323 break; 324 case DP_LINK_QUAL_PATTERN_PRBS7: 325 drm_dbg_kms(display->drm, "Set PRBS7 Phy Test Pattern\n"); 326 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 327 DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7); 328 break; 329 case DP_LINK_QUAL_PATTERN_80BIT_CUSTOM: 330 /* 331 * FIXME: Ideally pattern should come from DPCD 0x250. As 332 * current firmware of DPR-100 could not set it, so hardcoding 333 * now for compliance test. 334 */ 335 drm_dbg_kms(display->drm, 336 "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); 337 pattern_val = 0x3e0f83e0; 338 intel_de_write(display, DDI_DP_COMP_PAT(pipe, 0), pattern_val); 339 pattern_val = 0x0f83e0f8; 340 intel_de_write(display, DDI_DP_COMP_PAT(pipe, 1), pattern_val); 341 pattern_val = 0x0000f83e; 342 intel_de_write(display, DDI_DP_COMP_PAT(pipe, 2), pattern_val); 343 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 344 DDI_DP_COMP_CTL_ENABLE | 345 DDI_DP_COMP_CTL_CUSTOM80); 346 break; 347 case DP_LINK_QUAL_PATTERN_CP2520_PAT_1: 348 /* 349 * FIXME: Ideally pattern should come from DPCD 0x24A. As 350 * current firmware of DPR-100 could not set it, so hardcoding 351 * now for compliance test. 352 */ 353 drm_dbg_kms(display->drm, 354 "Set HBR2 compliance Phy Test Pattern\n"); 355 pattern_val = 0xFB; 356 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 357 DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 | 358 pattern_val); 359 break; 360 case DP_LINK_QUAL_PATTERN_CP2520_PAT_3: 361 if (DISPLAY_VER(display) < 10) { 362 drm_warn(display->drm, 363 "Platform does not support TPS4\n"); 364 break; 365 } 366 drm_dbg_kms(display->drm, 367 "Set TPS4 compliance Phy Test Pattern\n"); 368 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0); 369 intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), 370 DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, 371 DP_TP_CTL_TRAIN_PAT4_SEL_TP4A | DP_TP_CTL_LINK_TRAIN_PAT4); 372 break; 373 default: 374 drm_warn(display->drm, "Invalid Phy Test Pattern\n"); 375 } 376 } 377 378 static void intel_dp_process_phy_request(struct intel_dp *intel_dp, 379 const struct intel_crtc_state *crtc_state) 380 { 381 struct intel_display *display = to_intel_display(intel_dp); 382 struct drm_dp_phy_test_params *data = 383 &intel_dp->compliance.test_data.phytest; 384 u8 link_status[DP_LINK_STATUS_SIZE]; 385 386 if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, 387 link_status) < 0) { 388 drm_dbg_kms(display->drm, "failed to get link status\n"); 389 return; 390 } 391 392 /* retrieve vswing & pre-emphasis setting */ 393 intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, 394 link_status); 395 396 intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX); 397 398 intel_dp_phy_pattern_update(intel_dp, crtc_state); 399 400 drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET, 401 intel_dp->train_set, crtc_state->lane_count); 402 403 drm_dp_set_phy_test_pattern(&intel_dp->aux, data, 404 intel_dp->dpcd[DP_DPCD_REV]); 405 } 406 407 static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) 408 { 409 struct intel_display *display = to_intel_display(intel_dp); 410 struct drm_dp_phy_test_params *data = 411 &intel_dp->compliance.test_data.phytest; 412 413 if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { 414 drm_dbg_kms(display->drm, 415 "DP Phy Test pattern AUX read failure\n"); 416 return DP_TEST_NAK; 417 } 418 419 /* Set test active flag here so userspace doesn't interrupt things */ 420 intel_dp->compliance.test_active = true; 421 422 return DP_TEST_ACK; 423 } 424 425 void intel_dp_test_request(struct intel_dp *intel_dp) 426 { 427 struct intel_display *display = to_intel_display(intel_dp); 428 u8 response = DP_TEST_NAK; 429 u8 request = 0; 430 int status; 431 432 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request); 433 if (status <= 0) { 434 drm_dbg_kms(display->drm, 435 "Could not read test request from sink\n"); 436 goto update_status; 437 } 438 439 switch (request) { 440 case DP_TEST_LINK_TRAINING: 441 drm_dbg_kms(display->drm, "LINK_TRAINING test requested\n"); 442 response = intel_dp_autotest_link_training(intel_dp); 443 break; 444 case DP_TEST_LINK_VIDEO_PATTERN: 445 drm_dbg_kms(display->drm, "TEST_PATTERN test requested\n"); 446 response = intel_dp_autotest_video_pattern(intel_dp); 447 break; 448 case DP_TEST_LINK_EDID_READ: 449 drm_dbg_kms(display->drm, "EDID test requested\n"); 450 response = intel_dp_autotest_edid(intel_dp); 451 break; 452 case DP_TEST_LINK_PHY_TEST_PATTERN: 453 drm_dbg_kms(display->drm, "PHY_PATTERN test requested\n"); 454 response = intel_dp_autotest_phy_pattern(intel_dp); 455 break; 456 default: 457 drm_dbg_kms(display->drm, "Invalid test request '%02x'\n", 458 request); 459 break; 460 } 461 462 if (response & DP_TEST_ACK) 463 intel_dp->compliance.test_type = request; 464 465 update_status: 466 status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response); 467 if (status <= 0) 468 drm_dbg_kms(display->drm, 469 "Could not write test response to sink\n"); 470 } 471 472 /* phy test */ 473 474 static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, 475 struct drm_modeset_acquire_ctx *ctx, 476 u8 *pipe_mask) 477 { 478 struct intel_display *display = to_intel_display(intel_dp); 479 struct drm_connector_list_iter conn_iter; 480 struct intel_connector *connector; 481 int ret = 0; 482 483 *pipe_mask = 0; 484 485 drm_connector_list_iter_begin(display->drm, &conn_iter); 486 for_each_intel_connector_iter(connector, &conn_iter) { 487 struct drm_connector_state *conn_state = 488 connector->base.state; 489 struct intel_crtc_state *crtc_state; 490 struct intel_crtc *crtc; 491 492 if (!intel_dp_has_connector(intel_dp, conn_state)) 493 continue; 494 495 crtc = to_intel_crtc(conn_state->crtc); 496 if (!crtc) 497 continue; 498 499 ret = drm_modeset_lock(&crtc->base.mutex, ctx); 500 if (ret) 501 break; 502 503 crtc_state = to_intel_crtc_state(crtc->base.state); 504 505 drm_WARN_ON(display->drm, 506 !intel_crtc_has_dp_encoder(crtc_state)); 507 508 if (!crtc_state->hw.active) 509 continue; 510 511 if (conn_state->commit && 512 !try_wait_for_completion(&conn_state->commit->hw_done)) 513 continue; 514 515 *pipe_mask |= BIT(crtc->pipe); 516 } 517 drm_connector_list_iter_end(&conn_iter); 518 519 return ret; 520 } 521 522 static int intel_dp_do_phy_test(struct intel_encoder *encoder, 523 struct drm_modeset_acquire_ctx *ctx) 524 { 525 struct intel_display *display = to_intel_display(encoder); 526 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 527 struct intel_crtc *crtc; 528 u8 pipe_mask; 529 int ret; 530 531 ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex, 532 ctx); 533 if (ret) 534 return ret; 535 536 ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask); 537 if (ret) 538 return ret; 539 540 if (pipe_mask == 0) 541 return 0; 542 543 drm_dbg_kms(display->drm, "[ENCODER:%d:%s] PHY test\n", 544 encoder->base.base.id, encoder->base.name); 545 546 for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) { 547 const struct intel_crtc_state *crtc_state = 548 to_intel_crtc_state(crtc->base.state); 549 550 /* test on the MST master transcoder */ 551 if (DISPLAY_VER(display) >= 12 && 552 intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && 553 !intel_dp_mst_is_master_trans(crtc_state)) 554 continue; 555 556 intel_dp_process_phy_request(intel_dp, crtc_state); 557 break; 558 } 559 560 return 0; 561 } 562 563 bool intel_dp_test_phy(struct intel_dp *intel_dp) 564 { 565 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 566 struct intel_encoder *encoder = &dig_port->base; 567 struct drm_modeset_acquire_ctx ctx; 568 int ret; 569 570 if (!intel_dp->compliance.test_active || 571 intel_dp->compliance.test_type != DP_TEST_LINK_PHY_TEST_PATTERN) 572 return false; 573 574 drm_modeset_acquire_init(&ctx, 0); 575 576 for (;;) { 577 ret = intel_dp_do_phy_test(encoder, &ctx); 578 579 if (ret == -EDEADLK) { 580 drm_modeset_backoff(&ctx); 581 continue; 582 } 583 584 break; 585 } 586 587 drm_modeset_drop_locks(&ctx); 588 drm_modeset_acquire_fini(&ctx); 589 drm_WARN(encoder->base.dev, ret, 590 "Acquiring modeset locks failed with %i\n", ret); 591 592 return true; 593 } 594 595 bool intel_dp_test_short_pulse(struct intel_dp *intel_dp) 596 { 597 struct intel_display *display = to_intel_display(intel_dp); 598 bool reprobe_needed = false; 599 600 switch (intel_dp->compliance.test_type) { 601 case DP_TEST_LINK_TRAINING: 602 drm_dbg_kms(display->drm, 603 "Link Training Compliance Test requested\n"); 604 /* Send a Hotplug Uevent to userspace to start modeset */ 605 drm_kms_helper_hotplug_event(display->drm); 606 break; 607 case DP_TEST_LINK_PHY_TEST_PATTERN: 608 drm_dbg_kms(display->drm, 609 "PHY test pattern Compliance Test requested\n"); 610 /* 611 * Schedule long hpd to do the test 612 * 613 * FIXME get rid of the ad-hoc phy test modeset code 614 * and properly incorporate it into the normal modeset. 615 */ 616 reprobe_needed = true; 617 } 618 619 return reprobe_needed; 620 } 621 622 static ssize_t i915_displayport_test_active_write(struct file *file, 623 const char __user *ubuf, 624 size_t len, loff_t *offp) 625 { 626 struct seq_file *m = file->private_data; 627 struct intel_display *display = m->private; 628 char *input_buffer; 629 int status = 0; 630 struct drm_connector *connector; 631 struct drm_connector_list_iter conn_iter; 632 struct intel_dp *intel_dp; 633 int val = 0; 634 635 if (len == 0) 636 return 0; 637 638 input_buffer = memdup_user_nul(ubuf, len); 639 if (IS_ERR(input_buffer)) 640 return PTR_ERR(input_buffer); 641 642 drm_dbg_kms(display->drm, "Copied %d bytes from user\n", (unsigned int)len); 643 644 drm_connector_list_iter_begin(display->drm, &conn_iter); 645 drm_for_each_connector_iter(connector, &conn_iter) { 646 struct intel_encoder *encoder; 647 648 if (connector->connector_type != 649 DRM_MODE_CONNECTOR_DisplayPort) 650 continue; 651 652 encoder = to_intel_encoder(connector->encoder); 653 if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) 654 continue; 655 656 if (encoder && connector->status == connector_status_connected) { 657 intel_dp = enc_to_intel_dp(encoder); 658 status = kstrtoint(input_buffer, 10, &val); 659 if (status < 0) 660 break; 661 drm_dbg_kms(display->drm, "Got %d for test active\n", val); 662 /* To prevent erroneous activation of the compliance 663 * testing code, only accept an actual value of 1 here 664 */ 665 if (val == 1) 666 intel_dp->compliance.test_active = true; 667 else 668 intel_dp->compliance.test_active = false; 669 } 670 } 671 drm_connector_list_iter_end(&conn_iter); 672 kfree(input_buffer); 673 if (status < 0) 674 return status; 675 676 *offp += len; 677 return len; 678 } 679 680 static int i915_displayport_test_active_show(struct seq_file *m, void *data) 681 { 682 struct intel_display *display = m->private; 683 struct drm_connector *connector; 684 struct drm_connector_list_iter conn_iter; 685 struct intel_dp *intel_dp; 686 687 drm_connector_list_iter_begin(display->drm, &conn_iter); 688 drm_for_each_connector_iter(connector, &conn_iter) { 689 struct intel_encoder *encoder; 690 691 if (connector->connector_type != 692 DRM_MODE_CONNECTOR_DisplayPort) 693 continue; 694 695 encoder = to_intel_encoder(connector->encoder); 696 if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) 697 continue; 698 699 if (encoder && connector->status == connector_status_connected) { 700 intel_dp = enc_to_intel_dp(encoder); 701 if (intel_dp->compliance.test_active) 702 seq_puts(m, "1"); 703 else 704 seq_puts(m, "0"); 705 } else { 706 seq_puts(m, "0"); 707 } 708 } 709 drm_connector_list_iter_end(&conn_iter); 710 711 return 0; 712 } 713 714 static int i915_displayport_test_active_open(struct inode *inode, 715 struct file *file) 716 { 717 return single_open(file, i915_displayport_test_active_show, 718 inode->i_private); 719 } 720 721 static const struct file_operations i915_displayport_test_active_fops = { 722 .owner = THIS_MODULE, 723 .open = i915_displayport_test_active_open, 724 .read = seq_read, 725 .llseek = seq_lseek, 726 .release = single_release, 727 .write = i915_displayport_test_active_write 728 }; 729 730 static int i915_displayport_test_data_show(struct seq_file *m, void *data) 731 { 732 struct intel_display *display = m->private; 733 struct drm_connector *connector; 734 struct drm_connector_list_iter conn_iter; 735 struct intel_dp *intel_dp; 736 737 drm_connector_list_iter_begin(display->drm, &conn_iter); 738 drm_for_each_connector_iter(connector, &conn_iter) { 739 struct intel_encoder *encoder; 740 741 if (connector->connector_type != 742 DRM_MODE_CONNECTOR_DisplayPort) 743 continue; 744 745 encoder = to_intel_encoder(connector->encoder); 746 if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) 747 continue; 748 749 if (encoder && connector->status == connector_status_connected) { 750 intel_dp = enc_to_intel_dp(encoder); 751 if (intel_dp->compliance.test_type == 752 DP_TEST_LINK_EDID_READ) 753 seq_printf(m, "%lx", 754 intel_dp->compliance.test_data.edid); 755 else if (intel_dp->compliance.test_type == 756 DP_TEST_LINK_VIDEO_PATTERN) { 757 seq_printf(m, "hdisplay: %d\n", 758 intel_dp->compliance.test_data.hdisplay); 759 seq_printf(m, "vdisplay: %d\n", 760 intel_dp->compliance.test_data.vdisplay); 761 seq_printf(m, "bpc: %u\n", 762 intel_dp->compliance.test_data.bpc); 763 } else if (intel_dp->compliance.test_type == 764 DP_TEST_LINK_PHY_TEST_PATTERN) { 765 seq_printf(m, "pattern: %d\n", 766 intel_dp->compliance.test_data.phytest.phy_pattern); 767 seq_printf(m, "Number of lanes: %d\n", 768 intel_dp->compliance.test_data.phytest.num_lanes); 769 seq_printf(m, "Link Rate: %d\n", 770 intel_dp->compliance.test_data.phytest.link_rate); 771 seq_printf(m, "level: %02x\n", 772 intel_dp->train_set[0]); 773 } 774 } else { 775 seq_puts(m, "0"); 776 } 777 } 778 drm_connector_list_iter_end(&conn_iter); 779 780 return 0; 781 } 782 DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data); 783 784 static int i915_displayport_test_type_show(struct seq_file *m, void *data) 785 { 786 struct intel_display *display = m->private; 787 struct drm_connector *connector; 788 struct drm_connector_list_iter conn_iter; 789 struct intel_dp *intel_dp; 790 791 drm_connector_list_iter_begin(display->drm, &conn_iter); 792 drm_for_each_connector_iter(connector, &conn_iter) { 793 struct intel_encoder *encoder; 794 795 if (connector->connector_type != 796 DRM_MODE_CONNECTOR_DisplayPort) 797 continue; 798 799 encoder = to_intel_encoder(connector->encoder); 800 if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) 801 continue; 802 803 if (encoder && connector->status == connector_status_connected) { 804 intel_dp = enc_to_intel_dp(encoder); 805 seq_printf(m, "%02lx\n", intel_dp->compliance.test_type); 806 } else { 807 seq_puts(m, "0"); 808 } 809 } 810 drm_connector_list_iter_end(&conn_iter); 811 812 return 0; 813 } 814 DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type); 815 816 static const struct { 817 const char *name; 818 const struct file_operations *fops; 819 } intel_display_debugfs_files[] = { 820 {"i915_dp_test_data", &i915_displayport_test_data_fops}, 821 {"i915_dp_test_type", &i915_displayport_test_type_fops}, 822 {"i915_dp_test_active", &i915_displayport_test_active_fops}, 823 }; 824 825 void intel_dp_test_debugfs_register(struct intel_display *display) 826 { 827 int i; 828 829 for (i = 0; i < ARRAY_SIZE(intel_display_debugfs_files); i++) { 830 debugfs_create_file(intel_display_debugfs_files[i].name, 831 0644, 832 display->drm->debugfs_root, 833 display, 834 intel_display_debugfs_files[i].fops); 835 } 836 } 837