1 // SPDX-License-Identifier: MIT 2 /* Copyright © 2024 Intel Corporation */ 3 4 #include <drm/display/drm_dp.h> 5 #include <drm/display/drm_dp_helper.h> 6 #include <drm/drm_edid.h> 7 8 #include "i915_drv.h" 9 #include "i915_reg.h" 10 #include "intel_ddi.h" 11 #include "intel_de.h" 12 #include "intel_display_types.h" 13 #include "intel_dp.h" 14 #include "intel_dp_link_training.h" 15 #include "intel_dp_mst.h" 16 #include "intel_dp_test.h" 17 18 /* Adjust link config limits based on compliance test requests. */ 19 void 20 intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, 21 struct intel_crtc_state *pipe_config, 22 struct link_config_limits *limits) 23 { 24 struct intel_display *display = to_intel_display(intel_dp); 25 26 /* For DP Compliance we override the computed bpp for the pipe */ 27 if (intel_dp->compliance.test_data.bpc != 0) { 28 int bpp = 3 * intel_dp->compliance.test_data.bpc; 29 30 limits->pipe.min_bpp = bpp; 31 limits->pipe.max_bpp = bpp; 32 pipe_config->dither_force_disable = bpp == 6 * 3; 33 34 drm_dbg_kms(display->drm, "Setting pipe_bpp to %d\n", bpp); 35 } 36 37 /* Use values requested by Compliance Test Request */ 38 if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { 39 int index; 40 41 /* Validate the compliance test data since max values 42 * might have changed due to link train fallback. 43 */ 44 if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate, 45 intel_dp->compliance.test_lane_count)) { 46 index = intel_dp_rate_index(intel_dp->common_rates, 47 intel_dp->num_common_rates, 48 intel_dp->compliance.test_link_rate); 49 if (index >= 0) { 50 limits->min_rate = intel_dp->compliance.test_link_rate; 51 limits->max_rate = intel_dp->compliance.test_link_rate; 52 } 53 limits->min_lane_count = intel_dp->compliance.test_lane_count; 54 limits->max_lane_count = intel_dp->compliance.test_lane_count; 55 } 56 } 57 } 58 59 /* Compliance test status bits */ 60 #define INTEL_DP_RESOLUTION_PREFERRED 1 61 #define INTEL_DP_RESOLUTION_STANDARD 2 62 #define INTEL_DP_RESOLUTION_FAILSAFE 3 63 64 static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) 65 { 66 struct intel_display *display = to_intel_display(intel_dp); 67 int status = 0; 68 int test_link_rate; 69 u8 test_lane_count, test_link_bw; 70 /* (DP CTS 1.2) 71 * 4.3.1.11 72 */ 73 /* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */ 74 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT, 75 &test_lane_count); 76 77 if (status <= 0) { 78 drm_dbg_kms(display->drm, "Lane count read failed\n"); 79 return DP_TEST_NAK; 80 } 81 test_lane_count &= DP_MAX_LANE_COUNT_MASK; 82 83 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE, 84 &test_link_bw); 85 if (status <= 0) { 86 drm_dbg_kms(display->drm, "Link Rate read failed\n"); 87 return DP_TEST_NAK; 88 } 89 test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw); 90 91 /* Validate the requested link rate and lane count */ 92 if (!intel_dp_link_params_valid(intel_dp, test_link_rate, 93 test_lane_count)) 94 return DP_TEST_NAK; 95 96 intel_dp->compliance.test_lane_count = test_lane_count; 97 intel_dp->compliance.test_link_rate = test_link_rate; 98 99 return DP_TEST_ACK; 100 } 101 102 static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp) 103 { 104 struct intel_display *display = to_intel_display(intel_dp); 105 u8 test_pattern; 106 u8 test_misc; 107 __be16 h_width, v_height; 108 int status = 0; 109 110 /* Read the TEST_PATTERN (DP CTS 3.1.5) */ 111 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN, 112 &test_pattern); 113 if (status <= 0) { 114 drm_dbg_kms(display->drm, "Test pattern read failed\n"); 115 return DP_TEST_NAK; 116 } 117 if (test_pattern != DP_COLOR_RAMP) 118 return DP_TEST_NAK; 119 120 status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI, 121 &h_width, 2); 122 if (status <= 0) { 123 drm_dbg_kms(display->drm, "H Width read failed\n"); 124 return DP_TEST_NAK; 125 } 126 127 status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI, 128 &v_height, 2); 129 if (status <= 0) { 130 drm_dbg_kms(display->drm, "V Height read failed\n"); 131 return DP_TEST_NAK; 132 } 133 134 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0, 135 &test_misc); 136 if (status <= 0) { 137 drm_dbg_kms(display->drm, "TEST MISC read failed\n"); 138 return DP_TEST_NAK; 139 } 140 if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB) 141 return DP_TEST_NAK; 142 if (test_misc & DP_TEST_DYNAMIC_RANGE_CEA) 143 return DP_TEST_NAK; 144 switch (test_misc & DP_TEST_BIT_DEPTH_MASK) { 145 case DP_TEST_BIT_DEPTH_6: 146 intel_dp->compliance.test_data.bpc = 6; 147 break; 148 case DP_TEST_BIT_DEPTH_8: 149 intel_dp->compliance.test_data.bpc = 8; 150 break; 151 default: 152 return DP_TEST_NAK; 153 } 154 155 intel_dp->compliance.test_data.video_pattern = test_pattern; 156 intel_dp->compliance.test_data.hdisplay = be16_to_cpu(h_width); 157 intel_dp->compliance.test_data.vdisplay = be16_to_cpu(v_height); 158 /* Set test active flag here so userspace doesn't interrupt things */ 159 intel_dp->compliance.test_active = true; 160 161 return DP_TEST_ACK; 162 } 163 164 static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) 165 { 166 struct intel_display *display = to_intel_display(intel_dp); 167 u8 test_result = DP_TEST_ACK; 168 struct intel_connector *intel_connector = intel_dp->attached_connector; 169 struct drm_connector *connector = &intel_connector->base; 170 171 if (!intel_connector->detect_edid || connector->edid_corrupt || 172 intel_dp->aux.i2c_defer_count > 6) { 173 /* Check EDID read for NACKs, DEFERs and corruption 174 * (DP CTS 1.2 Core r1.1) 175 * 4.2.2.4 : Failed EDID read, I2C_NAK 176 * 4.2.2.5 : Failed EDID read, I2C_DEFER 177 * 4.2.2.6 : EDID corruption detected 178 * Use failsafe mode for all cases 179 */ 180 if (intel_dp->aux.i2c_nack_count > 0 || 181 intel_dp->aux.i2c_defer_count > 0) 182 drm_dbg_kms(display->drm, 183 "EDID read had %d NACKs, %d DEFERs\n", 184 intel_dp->aux.i2c_nack_count, 185 intel_dp->aux.i2c_defer_count); 186 intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE; 187 } else { 188 /* FIXME: Get rid of drm_edid_raw() */ 189 const struct edid *block = drm_edid_raw(intel_connector->detect_edid); 190 191 /* We have to write the checksum of the last block read */ 192 block += block->extensions; 193 194 if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM, 195 block->checksum) <= 0) 196 drm_dbg_kms(display->drm, 197 "Failed to write EDID checksum\n"); 198 199 test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE; 200 intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED; 201 } 202 203 /* Set test active flag here so userspace doesn't interrupt things */ 204 intel_dp->compliance.test_active = true; 205 206 return test_result; 207 } 208 209 static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, 210 const struct intel_crtc_state *crtc_state) 211 { 212 struct intel_display *display = to_intel_display(intel_dp); 213 struct drm_dp_phy_test_params *data = 214 &intel_dp->compliance.test_data.phytest; 215 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 216 struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 217 enum pipe pipe = crtc->pipe; 218 u32 pattern_val; 219 220 switch (data->phy_pattern) { 221 case DP_LINK_QUAL_PATTERN_DISABLE: 222 drm_dbg_kms(display->drm, "Disable Phy Test Pattern\n"); 223 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0); 224 if (DISPLAY_VER(display) >= 10) 225 intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), 226 DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, 227 DP_TP_CTL_LINK_TRAIN_NORMAL); 228 break; 229 case DP_LINK_QUAL_PATTERN_D10_2: 230 drm_dbg_kms(display->drm, "Set D10.2 Phy Test Pattern\n"); 231 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 232 DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2); 233 break; 234 case DP_LINK_QUAL_PATTERN_ERROR_RATE: 235 drm_dbg_kms(display->drm, 236 "Set Error Count Phy Test Pattern\n"); 237 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 238 DDI_DP_COMP_CTL_ENABLE | 239 DDI_DP_COMP_CTL_SCRAMBLED_0); 240 break; 241 case DP_LINK_QUAL_PATTERN_PRBS7: 242 drm_dbg_kms(display->drm, "Set PRBS7 Phy Test Pattern\n"); 243 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 244 DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7); 245 break; 246 case DP_LINK_QUAL_PATTERN_80BIT_CUSTOM: 247 /* 248 * FIXME: Ideally pattern should come from DPCD 0x250. As 249 * current firmware of DPR-100 could not set it, so hardcoding 250 * now for complaince test. 251 */ 252 drm_dbg_kms(display->drm, 253 "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); 254 pattern_val = 0x3e0f83e0; 255 intel_de_write(display, DDI_DP_COMP_PAT(pipe, 0), pattern_val); 256 pattern_val = 0x0f83e0f8; 257 intel_de_write(display, DDI_DP_COMP_PAT(pipe, 1), pattern_val); 258 pattern_val = 0x0000f83e; 259 intel_de_write(display, DDI_DP_COMP_PAT(pipe, 2), pattern_val); 260 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 261 DDI_DP_COMP_CTL_ENABLE | 262 DDI_DP_COMP_CTL_CUSTOM80); 263 break; 264 case DP_LINK_QUAL_PATTERN_CP2520_PAT_1: 265 /* 266 * FIXME: Ideally pattern should come from DPCD 0x24A. As 267 * current firmware of DPR-100 could not set it, so hardcoding 268 * now for complaince test. 269 */ 270 drm_dbg_kms(display->drm, 271 "Set HBR2 compliance Phy Test Pattern\n"); 272 pattern_val = 0xFB; 273 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 274 DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 | 275 pattern_val); 276 break; 277 case DP_LINK_QUAL_PATTERN_CP2520_PAT_3: 278 if (DISPLAY_VER(display) < 10) { 279 drm_warn(display->drm, 280 "Platform does not support TPS4\n"); 281 break; 282 } 283 drm_dbg_kms(display->drm, 284 "Set TPS4 compliance Phy Test Pattern\n"); 285 intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0); 286 intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), 287 DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, 288 DP_TP_CTL_TRAIN_PAT4_SEL_TP4A | DP_TP_CTL_LINK_TRAIN_PAT4); 289 break; 290 default: 291 drm_warn(display->drm, "Invalid Phy Test Pattern\n"); 292 } 293 } 294 295 static void intel_dp_process_phy_request(struct intel_dp *intel_dp, 296 const struct intel_crtc_state *crtc_state) 297 { 298 struct intel_display *display = to_intel_display(intel_dp); 299 struct drm_dp_phy_test_params *data = 300 &intel_dp->compliance.test_data.phytest; 301 u8 link_status[DP_LINK_STATUS_SIZE]; 302 303 if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, 304 link_status) < 0) { 305 drm_dbg_kms(display->drm, "failed to get link status\n"); 306 return; 307 } 308 309 /* retrieve vswing & pre-emphasis setting */ 310 intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, 311 link_status); 312 313 intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX); 314 315 intel_dp_phy_pattern_update(intel_dp, crtc_state); 316 317 drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET, 318 intel_dp->train_set, crtc_state->lane_count); 319 320 drm_dp_set_phy_test_pattern(&intel_dp->aux, data, 321 intel_dp->dpcd[DP_DPCD_REV]); 322 } 323 324 static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) 325 { 326 struct intel_display *display = to_intel_display(intel_dp); 327 struct drm_dp_phy_test_params *data = 328 &intel_dp->compliance.test_data.phytest; 329 330 if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { 331 drm_dbg_kms(display->drm, 332 "DP Phy Test pattern AUX read failure\n"); 333 return DP_TEST_NAK; 334 } 335 336 /* Set test active flag here so userspace doesn't interrupt things */ 337 intel_dp->compliance.test_active = true; 338 339 return DP_TEST_ACK; 340 } 341 342 void intel_dp_handle_test_request(struct intel_dp *intel_dp) 343 { 344 struct intel_display *display = to_intel_display(intel_dp); 345 u8 response = DP_TEST_NAK; 346 u8 request = 0; 347 int status; 348 349 status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request); 350 if (status <= 0) { 351 drm_dbg_kms(display->drm, 352 "Could not read test request from sink\n"); 353 goto update_status; 354 } 355 356 switch (request) { 357 case DP_TEST_LINK_TRAINING: 358 drm_dbg_kms(display->drm, "LINK_TRAINING test requested\n"); 359 response = intel_dp_autotest_link_training(intel_dp); 360 break; 361 case DP_TEST_LINK_VIDEO_PATTERN: 362 drm_dbg_kms(display->drm, "TEST_PATTERN test requested\n"); 363 response = intel_dp_autotest_video_pattern(intel_dp); 364 break; 365 case DP_TEST_LINK_EDID_READ: 366 drm_dbg_kms(display->drm, "EDID test requested\n"); 367 response = intel_dp_autotest_edid(intel_dp); 368 break; 369 case DP_TEST_LINK_PHY_TEST_PATTERN: 370 drm_dbg_kms(display->drm, "PHY_PATTERN test requested\n"); 371 response = intel_dp_autotest_phy_pattern(intel_dp); 372 break; 373 default: 374 drm_dbg_kms(display->drm, "Invalid test request '%02x'\n", 375 request); 376 break; 377 } 378 379 if (response & DP_TEST_ACK) 380 intel_dp->compliance.test_type = request; 381 382 update_status: 383 status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response); 384 if (status <= 0) 385 drm_dbg_kms(display->drm, 386 "Could not write test response to sink\n"); 387 } 388 389 /* phy test */ 390 391 static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, 392 struct drm_modeset_acquire_ctx *ctx, 393 u8 *pipe_mask) 394 { 395 struct intel_display *display = to_intel_display(intel_dp); 396 struct drm_connector_list_iter conn_iter; 397 struct intel_connector *connector; 398 int ret = 0; 399 400 *pipe_mask = 0; 401 402 drm_connector_list_iter_begin(display->drm, &conn_iter); 403 for_each_intel_connector_iter(connector, &conn_iter) { 404 struct drm_connector_state *conn_state = 405 connector->base.state; 406 struct intel_crtc_state *crtc_state; 407 struct intel_crtc *crtc; 408 409 if (!intel_dp_has_connector(intel_dp, conn_state)) 410 continue; 411 412 crtc = to_intel_crtc(conn_state->crtc); 413 if (!crtc) 414 continue; 415 416 ret = drm_modeset_lock(&crtc->base.mutex, ctx); 417 if (ret) 418 break; 419 420 crtc_state = to_intel_crtc_state(crtc->base.state); 421 422 drm_WARN_ON(display->drm, 423 !intel_crtc_has_dp_encoder(crtc_state)); 424 425 if (!crtc_state->hw.active) 426 continue; 427 428 if (conn_state->commit && 429 !try_wait_for_completion(&conn_state->commit->hw_done)) 430 continue; 431 432 *pipe_mask |= BIT(crtc->pipe); 433 } 434 drm_connector_list_iter_end(&conn_iter); 435 436 return ret; 437 } 438 439 static int intel_dp_do_phy_test(struct intel_encoder *encoder, 440 struct drm_modeset_acquire_ctx *ctx) 441 { 442 struct intel_display *display = to_intel_display(encoder); 443 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 444 struct intel_crtc *crtc; 445 u8 pipe_mask; 446 int ret; 447 448 ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex, 449 ctx); 450 if (ret) 451 return ret; 452 453 ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask); 454 if (ret) 455 return ret; 456 457 if (pipe_mask == 0) 458 return 0; 459 460 drm_dbg_kms(display->drm, "[ENCODER:%d:%s] PHY test\n", 461 encoder->base.base.id, encoder->base.name); 462 463 for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { 464 const struct intel_crtc_state *crtc_state = 465 to_intel_crtc_state(crtc->base.state); 466 467 /* test on the MST master transcoder */ 468 if (DISPLAY_VER(display) >= 12 && 469 intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && 470 !intel_dp_mst_is_master_trans(crtc_state)) 471 continue; 472 473 intel_dp_process_phy_request(intel_dp, crtc_state); 474 break; 475 } 476 477 return 0; 478 } 479 480 void intel_dp_phy_test(struct intel_encoder *encoder) 481 { 482 struct drm_modeset_acquire_ctx ctx; 483 int ret; 484 485 drm_modeset_acquire_init(&ctx, 0); 486 487 for (;;) { 488 ret = intel_dp_do_phy_test(encoder, &ctx); 489 490 if (ret == -EDEADLK) { 491 drm_modeset_backoff(&ctx); 492 continue; 493 } 494 495 break; 496 } 497 498 drm_modeset_drop_locks(&ctx); 499 drm_modeset_acquire_fini(&ctx); 500 drm_WARN(encoder->base.dev, ret, 501 "Acquiring modeset locks failed with %i\n", ret); 502 } 503