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