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