1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright 2024, Intel Corporation. 4 */ 5 6 #include <linux/debugfs.h> 7 8 #include <drm/drm_print.h> 9 10 #include "intel_alpm.h" 11 #include "intel_crtc.h" 12 #include "intel_de.h" 13 #include "intel_display_types.h" 14 #include "intel_dp.h" 15 #include "intel_dp_aux.h" 16 #include "intel_psr.h" 17 #include "intel_psr_regs.h" 18 19 bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp) 20 { 21 return intel_dp->alpm_dpcd & DP_ALPM_CAP; 22 } 23 24 bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp) 25 { 26 return intel_dp->alpm_dpcd & DP_ALPM_AUX_LESS_CAP; 27 } 28 29 bool intel_alpm_is_alpm_aux_less(struct intel_dp *intel_dp, 30 const struct intel_crtc_state *crtc_state) 31 { 32 return intel_psr_needs_alpm_aux_less(intel_dp, crtc_state) || 33 (crtc_state->has_lobf && intel_alpm_aux_less_wake_supported(intel_dp)); 34 } 35 36 void intel_alpm_init(struct intel_dp *intel_dp) 37 { 38 u8 dpcd; 39 40 if (drm_dp_dpcd_readb(&intel_dp->aux, DP_RECEIVER_ALPM_CAP, &dpcd) < 0) 41 return; 42 43 intel_dp->alpm_dpcd = dpcd; 44 mutex_init(&intel_dp->alpm_parameters.lock); 45 } 46 47 /* 48 * See Bspec: 71632 for the table 49 * 50 * Silence_period = tSilence,Min + ((tSilence,Max - tSilence,Min) / 2) 51 * 52 * Half cycle duration: 53 * 54 * Link rates 1.62 - 4.32 and tLFPS_Cycle = 70 ns 55 * FLOOR( (Link Rate * tLFPS_Cycle) / (2 * 10) ) 56 * 57 * Link rates 5.4 - 8.1 58 * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ] = 10 59 * LFPS Period chosen is the mid-point of the min:max values from the table 60 * FLOOR( LFPS Period in Symbol clocks / 61 * (2 * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ]) ) 62 */ 63 static bool _lnl_get_silence_period_and_lfps_half_cycle(int link_rate, 64 int *silence_period, 65 int *lfps_half_cycle) 66 { 67 switch (link_rate) { 68 case 162000: 69 *silence_period = 20; 70 *lfps_half_cycle = 5; 71 break; 72 case 216000: 73 *silence_period = 27; 74 *lfps_half_cycle = 7; 75 break; 76 case 243000: 77 *silence_period = 31; 78 *lfps_half_cycle = 8; 79 break; 80 case 270000: 81 *silence_period = 34; 82 *lfps_half_cycle = 9; 83 break; 84 case 324000: 85 *silence_period = 41; 86 *lfps_half_cycle = 11; 87 break; 88 case 432000: 89 *silence_period = 56; 90 *lfps_half_cycle = 15; 91 break; 92 case 540000: 93 *silence_period = 69; 94 *lfps_half_cycle = 12; 95 break; 96 case 648000: 97 *silence_period = 84; 98 *lfps_half_cycle = 15; 99 break; 100 case 675000: 101 *silence_period = 87; 102 *lfps_half_cycle = 15; 103 break; 104 case 810000: 105 *silence_period = 104; 106 *lfps_half_cycle = 19; 107 break; 108 default: 109 *silence_period = *lfps_half_cycle = -1; 110 return false; 111 } 112 return true; 113 } 114 115 /* 116 * AUX-Less Wake Time = CEILING( ((PHY P2 to P0) + tLFPS_Period, Max+ 117 * tSilence, Max+ tPHY Establishment + tCDS) / tline) 118 * For the "PHY P2 to P0" latency see the PHY Power Control page 119 * (PHY P2 to P0) : https://gfxspecs.intel.com/Predator/Home/Index/68965 120 * : 12 us 121 * The tLFPS_Period, Max term is 800ns 122 * The tSilence, Max term is 180ns 123 * The tPHY Establishment (a.k.a. t1) term is 50us 124 * The tCDS term is 1 or 2 times t2 125 * t2 = Number ML_PHY_LOCK * tML_PHY_LOCK 126 * Number ML_PHY_LOCK = ( 7 + CEILING( 6.5us / tML_PHY_LOCK ) + 1) 127 * Rounding up the 6.5us padding to the next ML_PHY_LOCK boundary and 128 * adding the "+ 1" term ensures all ML_PHY_LOCK sequences that start 129 * within the CDS period complete within the CDS period regardless of 130 * entry into the period 131 * tML_PHY_LOCK = TPS4 Length * ( 10 / (Link Rate in MHz) ) 132 * TPS4 Length = 252 Symbols 133 */ 134 static int _lnl_compute_aux_less_wake_time(int port_clock) 135 { 136 int tphy2_p2_to_p0 = 12 * 1000; 137 int tlfps_period_max = 800; 138 int tsilence_max = 180; 139 int t1 = 50 * 1000; 140 int tps4 = 252; 141 /* port_clock is link rate in 10kbit/s units */ 142 int tml_phy_lock = 1000 * 1000 * tps4 / port_clock; 143 int num_ml_phy_lock = 7 + DIV_ROUND_UP(6500, tml_phy_lock) + 1; 144 int t2 = num_ml_phy_lock * tml_phy_lock; 145 int tcds = 1 * t2; 146 147 return DIV_ROUND_UP(tphy2_p2_to_p0 + tlfps_period_max + tsilence_max + 148 t1 + tcds, 1000); 149 } 150 151 static int 152 _lnl_compute_aux_less_alpm_params(struct intel_dp *intel_dp, 153 const struct intel_crtc_state *crtc_state) 154 { 155 struct intel_display *display = to_intel_display(intel_dp); 156 int aux_less_wake_time, aux_less_wake_lines, silence_period, 157 lfps_half_cycle; 158 159 aux_less_wake_time = 160 _lnl_compute_aux_less_wake_time(crtc_state->port_clock); 161 aux_less_wake_lines = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 162 aux_less_wake_time); 163 164 if (!_lnl_get_silence_period_and_lfps_half_cycle(crtc_state->port_clock, 165 &silence_period, 166 &lfps_half_cycle)) 167 return false; 168 169 if (aux_less_wake_lines > ALPM_CTL_AUX_LESS_WAKE_TIME_MASK || 170 silence_period > PORT_ALPM_CTL_SILENCE_PERIOD_MASK || 171 lfps_half_cycle > PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION_MASK) 172 return false; 173 174 if (display->params.psr_safest_params) 175 aux_less_wake_lines = ALPM_CTL_AUX_LESS_WAKE_TIME_MASK; 176 177 intel_dp->alpm_parameters.aux_less_wake_lines = aux_less_wake_lines; 178 intel_dp->alpm_parameters.silence_period_sym_clocks = silence_period; 179 intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms = lfps_half_cycle; 180 181 return true; 182 } 183 184 static bool _lnl_compute_alpm_params(struct intel_dp *intel_dp, 185 const struct intel_crtc_state *crtc_state) 186 { 187 struct intel_display *display = to_intel_display(intel_dp); 188 int check_entry_lines; 189 190 if (DISPLAY_VER(display) < 20) 191 return true; 192 193 /* ALPM Entry Check = 2 + CEILING( 5us /tline ) */ 194 check_entry_lines = 2 + 195 intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 5); 196 197 if (check_entry_lines > 15) 198 return false; 199 200 if (!_lnl_compute_aux_less_alpm_params(intel_dp, crtc_state)) 201 return false; 202 203 if (display->params.psr_safest_params) 204 check_entry_lines = 15; 205 206 intel_dp->alpm_parameters.check_entry_lines = check_entry_lines; 207 208 return true; 209 } 210 211 /* 212 * IO wake time for DISPLAY_VER < 12 is not directly mentioned in Bspec. There 213 * are 50 us io wake time and 32 us fast wake time. Clearly preharge pulses are 214 * not (improperly) included in 32 us fast wake time. 50 us - 32 us = 18 us. 215 */ 216 static int skl_io_buffer_wake_time(void) 217 { 218 return 18; 219 } 220 221 static int tgl_io_buffer_wake_time(void) 222 { 223 return 10; 224 } 225 226 static int io_buffer_wake_time(const struct intel_crtc_state *crtc_state) 227 { 228 struct intel_display *display = to_intel_display(crtc_state); 229 230 if (DISPLAY_VER(display) >= 12) 231 return tgl_io_buffer_wake_time(); 232 else 233 return skl_io_buffer_wake_time(); 234 } 235 236 bool intel_alpm_compute_params(struct intel_dp *intel_dp, 237 const struct intel_crtc_state *crtc_state) 238 { 239 struct intel_display *display = to_intel_display(intel_dp); 240 int io_wake_lines, io_wake_time, fast_wake_lines, fast_wake_time; 241 int tfw_exit_latency = 20; /* eDP spec */ 242 int phy_wake = 4; /* eDP spec */ 243 int preamble = 8; /* eDP spec */ 244 int precharge = intel_dp_aux_fw_sync_len(intel_dp) - preamble; 245 u8 max_wake_lines; 246 247 io_wake_time = max(precharge, io_buffer_wake_time(crtc_state)) + 248 preamble + phy_wake + tfw_exit_latency; 249 fast_wake_time = precharge + preamble + phy_wake + 250 tfw_exit_latency; 251 252 if (DISPLAY_VER(display) >= 20) 253 max_wake_lines = 68; 254 else if (DISPLAY_VER(display) >= 12) 255 max_wake_lines = 12; 256 else 257 max_wake_lines = 8; 258 259 io_wake_lines = intel_usecs_to_scanlines( 260 &crtc_state->hw.adjusted_mode, io_wake_time); 261 fast_wake_lines = intel_usecs_to_scanlines( 262 &crtc_state->hw.adjusted_mode, fast_wake_time); 263 264 if (io_wake_lines > max_wake_lines || 265 fast_wake_lines > max_wake_lines) 266 return false; 267 268 if (!_lnl_compute_alpm_params(intel_dp, crtc_state)) 269 return false; 270 271 if (display->params.psr_safest_params) 272 io_wake_lines = fast_wake_lines = max_wake_lines; 273 274 /* According to Bspec lower limit should be set as 7 lines. */ 275 intel_dp->alpm_parameters.io_wake_lines = max(io_wake_lines, 7); 276 intel_dp->alpm_parameters.fast_wake_lines = max(fast_wake_lines, 7); 277 278 return true; 279 } 280 281 void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp, 282 struct intel_crtc_state *crtc_state, 283 struct drm_connector_state *conn_state) 284 { 285 struct intel_display *display = to_intel_display(intel_dp); 286 struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; 287 int waketime_in_lines, first_sdp_position; 288 int context_latency, guardband; 289 290 if (intel_dp->alpm_parameters.lobf_disable_debug) { 291 drm_dbg_kms(display->drm, "LOBF is disabled by debug flag\n"); 292 return; 293 } 294 295 if (intel_dp->alpm_parameters.sink_alpm_error) 296 return; 297 298 if (!intel_dp_is_edp(intel_dp)) 299 return; 300 301 if (DISPLAY_VER(display) < 20) 302 return; 303 304 if (!intel_dp->as_sdp_supported) 305 return; 306 307 if (crtc_state->has_psr) 308 return; 309 310 if (crtc_state->vrr.vmin != crtc_state->vrr.vmax || 311 crtc_state->vrr.vmin != crtc_state->vrr.flipline) 312 return; 313 314 if (!(intel_alpm_aux_wake_supported(intel_dp) || 315 intel_alpm_aux_less_wake_supported(intel_dp))) 316 return; 317 318 if (!intel_alpm_compute_params(intel_dp, crtc_state)) 319 return; 320 321 context_latency = adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay; 322 guardband = adjusted_mode->crtc_vtotal - 323 adjusted_mode->crtc_vdisplay - context_latency; 324 first_sdp_position = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start; 325 if (intel_alpm_aux_less_wake_supported(intel_dp)) 326 waketime_in_lines = intel_dp->alpm_parameters.io_wake_lines; 327 else 328 waketime_in_lines = intel_dp->alpm_parameters.aux_less_wake_lines; 329 330 crtc_state->has_lobf = (context_latency + guardband) > 331 (first_sdp_position + waketime_in_lines); 332 } 333 334 static void lnl_alpm_configure(struct intel_dp *intel_dp, 335 const struct intel_crtc_state *crtc_state) 336 { 337 struct intel_display *display = to_intel_display(intel_dp); 338 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 339 u32 alpm_ctl; 340 341 if (DISPLAY_VER(display) < 20 || (!intel_psr_needs_alpm(intel_dp, crtc_state) && 342 !crtc_state->has_lobf)) 343 return; 344 345 mutex_lock(&intel_dp->alpm_parameters.lock); 346 /* 347 * Panel Replay on eDP is always using ALPM aux less. I.e. no need to 348 * check panel support at this point. 349 */ 350 if (intel_alpm_is_alpm_aux_less(intel_dp, crtc_state)) { 351 alpm_ctl = ALPM_CTL_ALPM_ENABLE | 352 ALPM_CTL_ALPM_AUX_LESS_ENABLE | 353 ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS | 354 ALPM_CTL_AUX_LESS_WAKE_TIME(intel_dp->alpm_parameters.aux_less_wake_lines); 355 356 if (intel_dp->as_sdp_supported) { 357 u32 pr_alpm_ctl = PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1; 358 359 if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] & 360 DP_PANEL_REPLAY_LINK_OFF_SUPPORTED_IN_PR_AFTER_ADAPTIVE_SYNC_SDP) 361 pr_alpm_ctl |= PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU; 362 if (!(intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] & 363 DP_PANEL_REPLAY_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR)) 364 pr_alpm_ctl |= PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE; 365 366 intel_de_write(display, PR_ALPM_CTL(display, cpu_transcoder), 367 pr_alpm_ctl); 368 } 369 370 } else { 371 alpm_ctl = ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE | 372 ALPM_CTL_EXTENDED_FAST_WAKE_TIME(intel_dp->alpm_parameters.fast_wake_lines); 373 } 374 375 if (crtc_state->has_lobf) { 376 alpm_ctl |= ALPM_CTL_LOBF_ENABLE; 377 drm_dbg_kms(display->drm, "Link off between frames (LOBF) enabled\n"); 378 } 379 380 alpm_ctl |= ALPM_CTL_ALPM_ENTRY_CHECK(intel_dp->alpm_parameters.check_entry_lines); 381 382 intel_de_write(display, ALPM_CTL(display, cpu_transcoder), alpm_ctl); 383 mutex_unlock(&intel_dp->alpm_parameters.lock); 384 } 385 386 void intel_alpm_configure(struct intel_dp *intel_dp, 387 const struct intel_crtc_state *crtc_state) 388 { 389 lnl_alpm_configure(intel_dp, crtc_state); 390 intel_dp->alpm_parameters.transcoder = crtc_state->cpu_transcoder; 391 } 392 393 void intel_alpm_port_configure(struct intel_dp *intel_dp, 394 const struct intel_crtc_state *crtc_state) 395 { 396 struct intel_display *display = to_intel_display(intel_dp); 397 enum port port = dp_to_dig_port(intel_dp)->base.port; 398 u32 alpm_ctl_val = 0, lfps_ctl_val = 0; 399 400 if (DISPLAY_VER(display) < 20) 401 return; 402 403 if (intel_alpm_is_alpm_aux_less(intel_dp, crtc_state)) { 404 alpm_ctl_val = PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE | 405 PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) | 406 PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) | 407 PORT_ALPM_CTL_SILENCE_PERIOD( 408 intel_dp->alpm_parameters.silence_period_sym_clocks); 409 lfps_ctl_val = PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT(10) | 410 PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION( 411 intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) | 412 PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION( 413 intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) | 414 PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION( 415 intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms); 416 } 417 418 intel_de_write(display, PORT_ALPM_CTL(port), alpm_ctl_val); 419 420 intel_de_write(display, PORT_ALPM_LFPS_CTL(port), lfps_ctl_val); 421 } 422 423 void intel_alpm_pre_plane_update(struct intel_atomic_state *state, 424 struct intel_crtc *crtc) 425 { 426 struct intel_display *display = to_intel_display(state); 427 const struct intel_crtc_state *crtc_state = 428 intel_atomic_get_new_crtc_state(state, crtc); 429 const struct intel_crtc_state *old_crtc_state = 430 intel_atomic_get_old_crtc_state(state, crtc); 431 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 432 struct intel_encoder *encoder; 433 434 if (DISPLAY_VER(display) < 20) 435 return; 436 437 if (crtc_state->has_lobf || crtc_state->has_lobf == old_crtc_state->has_lobf) 438 return; 439 440 for_each_intel_encoder_mask(display->drm, encoder, 441 crtc_state->uapi.encoder_mask) { 442 struct intel_dp *intel_dp; 443 444 if (!intel_encoder_is_dp(encoder)) 445 continue; 446 447 intel_dp = enc_to_intel_dp(encoder); 448 449 if (!intel_dp_is_edp(intel_dp)) 450 continue; 451 452 if (old_crtc_state->has_lobf) { 453 mutex_lock(&intel_dp->alpm_parameters.lock); 454 intel_de_write(display, ALPM_CTL(display, cpu_transcoder), 0); 455 drm_dbg_kms(display->drm, "Link off between frames (LOBF) disabled\n"); 456 mutex_unlock(&intel_dp->alpm_parameters.lock); 457 } 458 } 459 } 460 461 void intel_alpm_enable_sink(struct intel_dp *intel_dp, 462 const struct intel_crtc_state *crtc_state) 463 { 464 u8 val; 465 466 if (!intel_psr_needs_alpm(intel_dp, crtc_state) && !crtc_state->has_lobf) 467 return; 468 469 val = DP_ALPM_ENABLE | DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE; 470 471 if (crtc_state->has_panel_replay || (crtc_state->has_lobf && 472 intel_alpm_aux_less_wake_supported(intel_dp))) 473 val |= DP_ALPM_MODE_AUX_LESS; 474 475 drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val); 476 } 477 478 void intel_alpm_post_plane_update(struct intel_atomic_state *state, 479 struct intel_crtc *crtc) 480 { 481 struct intel_display *display = to_intel_display(state); 482 const struct intel_crtc_state *crtc_state = 483 intel_atomic_get_new_crtc_state(state, crtc); 484 const struct intel_crtc_state *old_crtc_state = 485 intel_atomic_get_old_crtc_state(state, crtc); 486 struct intel_encoder *encoder; 487 488 if (crtc_state->has_psr || !crtc_state->has_lobf || 489 crtc_state->has_lobf == old_crtc_state->has_lobf) 490 return; 491 492 for_each_intel_encoder_mask(display->drm, encoder, 493 crtc_state->uapi.encoder_mask) { 494 struct intel_dp *intel_dp; 495 496 if (!intel_encoder_is_dp(encoder)) 497 continue; 498 499 intel_dp = enc_to_intel_dp(encoder); 500 501 if (intel_dp_is_edp(intel_dp)) { 502 intel_alpm_enable_sink(intel_dp, crtc_state); 503 intel_alpm_configure(intel_dp, crtc_state); 504 } 505 } 506 } 507 508 static int i915_edp_lobf_info_show(struct seq_file *m, void *data) 509 { 510 struct intel_connector *connector = m->private; 511 struct intel_display *display = to_intel_display(connector); 512 struct drm_crtc *crtc; 513 struct intel_crtc_state *crtc_state; 514 enum transcoder cpu_transcoder; 515 u32 alpm_ctl; 516 int ret; 517 518 ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); 519 if (ret) 520 return ret; 521 522 crtc = connector->base.state->crtc; 523 if (connector->base.status != connector_status_connected || !crtc) { 524 ret = -ENODEV; 525 goto out; 526 } 527 528 crtc_state = to_intel_crtc_state(crtc->state); 529 cpu_transcoder = crtc_state->cpu_transcoder; 530 alpm_ctl = intel_de_read(display, ALPM_CTL(display, cpu_transcoder)); 531 seq_printf(m, "LOBF status: %s\n", str_enabled_disabled(alpm_ctl & ALPM_CTL_LOBF_ENABLE)); 532 seq_printf(m, "Aux-wake alpm status: %s\n", 533 str_enabled_disabled(!(alpm_ctl & ALPM_CTL_ALPM_AUX_LESS_ENABLE))); 534 seq_printf(m, "Aux-less alpm status: %s\n", 535 str_enabled_disabled(alpm_ctl & ALPM_CTL_ALPM_AUX_LESS_ENABLE)); 536 out: 537 drm_modeset_unlock(&display->drm->mode_config.connection_mutex); 538 539 return ret; 540 } 541 542 DEFINE_SHOW_ATTRIBUTE(i915_edp_lobf_info); 543 544 static int 545 i915_edp_lobf_debug_get(void *data, u64 *val) 546 { 547 struct intel_connector *connector = data; 548 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); 549 550 *val = intel_dp->alpm_parameters.lobf_disable_debug; 551 552 return 0; 553 } 554 555 static int 556 i915_edp_lobf_debug_set(void *data, u64 val) 557 { 558 struct intel_connector *connector = data; 559 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); 560 561 intel_dp->alpm_parameters.lobf_disable_debug = val; 562 563 return 0; 564 } 565 566 DEFINE_SIMPLE_ATTRIBUTE(i915_edp_lobf_debug_fops, 567 i915_edp_lobf_debug_get, i915_edp_lobf_debug_set, 568 "%llu\n"); 569 570 void intel_alpm_lobf_debugfs_add(struct intel_connector *connector) 571 { 572 struct intel_display *display = to_intel_display(connector); 573 struct dentry *root = connector->base.debugfs_entry; 574 575 if (DISPLAY_VER(display) < 20 || 576 connector->base.connector_type != DRM_MODE_CONNECTOR_eDP) 577 return; 578 579 debugfs_create_file("i915_edp_lobf_debug", 0644, root, 580 connector, &i915_edp_lobf_debug_fops); 581 582 debugfs_create_file("i915_edp_lobf_info", 0444, root, 583 connector, &i915_edp_lobf_info_fops); 584 } 585 586 void intel_alpm_disable(struct intel_dp *intel_dp) 587 { 588 struct intel_display *display = to_intel_display(intel_dp); 589 enum transcoder cpu_transcoder = intel_dp->alpm_parameters.transcoder; 590 591 if (DISPLAY_VER(display) < 20 || !intel_dp->alpm_dpcd) 592 return; 593 594 mutex_lock(&intel_dp->alpm_parameters.lock); 595 596 intel_de_rmw(display, ALPM_CTL(display, cpu_transcoder), 597 ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE | 598 ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); 599 600 intel_de_rmw(display, 601 PORT_ALPM_CTL(cpu_transcoder), 602 PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); 603 604 drm_dbg_kms(display->drm, "Disabling ALPM\n"); 605 mutex_unlock(&intel_dp->alpm_parameters.lock); 606 } 607 608 bool intel_alpm_get_error(struct intel_dp *intel_dp) 609 { 610 struct intel_display *display = to_intel_display(intel_dp); 611 struct drm_dp_aux *aux = &intel_dp->aux; 612 u8 val; 613 int r; 614 615 r = drm_dp_dpcd_readb(aux, DP_RECEIVER_ALPM_STATUS, &val); 616 if (r != 1) { 617 drm_err(display->drm, "Error reading ALPM status\n"); 618 return true; 619 } 620 621 if (val & DP_ALPM_LOCK_TIMEOUT_ERROR) { 622 drm_dbg_kms(display->drm, "ALPM lock timeout error\n"); 623 624 /* Clearing error */ 625 drm_dp_dpcd_writeb(aux, DP_RECEIVER_ALPM_STATUS, val); 626 return true; 627 } 628 629 return false; 630 } 631