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