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