1 // SPDX-License-Identifier: MIT 2 // 3 // Copyright 2026 Advanced Micro Devices, Inc. 4 5 #include "dm_services.h" 6 #include "dc.h" 7 #include "mod_power.h" 8 #include "core_types.h" 9 #include "dmcu.h" 10 #include "abm.h" 11 #include "power_helpers.h" 12 #include "dce/dmub_psr.h" 13 #include "dal_asic_id.h" 14 #include "link_service.h" 15 #include <linux/math.h> 16 17 #define DC_TRACE_LEVEL_MESSAGE(...) /* do nothing */ 18 #define DC_TRACE_LEVEL_MESSAGEP(...) /* do nothing */ 19 #include "dc/inc/hw/dmcu.h" 20 #include "dc/inc/hw/abm.h" 21 #include "dmub_cmd.h" 22 23 #define MOD_POWER_TO_CORE(mod_power)\ 24 container_of(mod_power, struct core_power, mod_public) 25 26 static unsigned int calc_psr_num_static_frames(unsigned int vsync_rate_hz) 27 { 28 /* Initialize fail-safe to 2 static frames. */ 29 unsigned int num_frames_static = 2; 30 31 /* Calculate number of frames such that at least 30 ms has passed. 32 * Round up to ensure the static period is not shorter than 30 ms. 33 */ 34 if (vsync_rate_hz != 0) 35 num_frames_static = DIV_ROUND_UP(30000 * vsync_rate_hz, 1000000); 36 37 return num_frames_static; 38 } 39 40 bool mod_power_psr_notify_mode_change(struct mod_power *mod_power, 41 const struct dc_stream_state *stream, 42 struct dc_link *link, 43 unsigned int stream_index) 44 { 45 struct core_power *core_power = NULL; 46 struct dc *dc = NULL; 47 struct psr_config psr_config = {0}; 48 struct psr_context psr_context = {0}; 49 int active_psr_events = 0; 50 51 if ((mod_power == NULL) || (stream == NULL) || (link == NULL)) 52 return false; 53 54 core_power = MOD_POWER_TO_CORE(mod_power); 55 dc = core_power->dc; 56 57 // NO num_entities check here - already validated by caller 58 // stream_index is passed as validated parameter 59 active_psr_events = core_power->map[stream_index].psr_events; 60 61 /* forced psr is active for seamless switch. 62 * Re-running edp_setup_psr would disturb the freeze, 63 * so skip the PSR re-setup until forced psr releases the override. 64 */ 65 if (active_psr_events & psr_event_os_override_hold) 66 return false; 67 68 /* Calculate PSR configurations */ 69 mod_power_calc_psr_configs(&psr_config, link, stream); 70 71 psr_config.psr_exit_link_training_required = 72 core_power->map[stream_index].caps->psr_exit_link_training_required; 73 if (dc->ctx->asic_id.chip_family >= AMDGPU_FAMILY_GC_11_0_1) 74 psr_config.allow_smu_optimizations = 75 core_power->psr_smu_optimizations_support && dc_is_embedded_signal(stream->signal); 76 else 77 psr_config.allow_smu_optimizations = 78 core_power->psr_smu_optimizations_support && 79 mod_power_only_edp(dc->current_state, stream); 80 81 psr_config.allow_multi_disp_optimizations = core_power->multi_disp_optimizations_support; 82 83 psr_config.rate_control_caps = core_power->map[stream_index].caps->rate_control_caps; 84 85 if (active_psr_events & psr_event_os_request_force_ffu) 86 psr_config.os_request_force_ffu = true; 87 88 /* 89 * DSC support: 90 * DSC slice height value must be 'mod' by su_y_granularity. 91 * According to Panel Vendor, there might be varied conditions to fulfill. 92 * Right now, DSC slice height value must be multiple of su_y_granularity. 93 * 94 * The value of DSC slice height is determined in DSC Driver but it does not 95 * propagated out here, so we need to calculate it as below 'slice_height'. 96 */ 97 psr_su_set_dsc_slice_height(dc, link, 98 (struct dc_stream_state *) stream, 99 &psr_config); 100 101 dc_link_setup_psr(link, stream, &psr_config, &psr_context); 102 103 return true; 104 } 105 106 static void mod_power_psr_set_power_opt(struct mod_power *mod_power, 107 struct dc_stream_state *stream, 108 unsigned int active_psr_events, 109 bool psr_enable_request) 110 { 111 (void)psr_enable_request; 112 struct core_power *core_power = NULL; 113 struct dc_link *link = NULL; 114 unsigned int stream_index = 0; 115 unsigned int power_opt = 0; 116 117 if (!stream) 118 return; 119 120 core_power = MOD_POWER_TO_CORE(mod_power); 121 stream_index = map_index_from_stream(core_power, stream); 122 if (!core_power->map[stream_index].caps->psr_version) 123 return; 124 125 link = dc_stream_get_link(stream); 126 127 if (active_psr_events == 0) { 128 /* Static Screen */ 129 power_opt |= (psr_power_opt_smu_opt_static_screen | psr_power_opt_z10_static_screen | 130 psr_power_opt_ds_disable_allow); 131 } 132 133 /* psr_power_opt_flag is a configuration parameter into the module that determines 134 * which optimizations to enable during psr 135 */ 136 power_opt &= core_power->map[stream_index].caps->psr_power_opt_flag; 137 if (core_power->map[stream_index].psr_power_opt != power_opt) { 138 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE, 139 WPP_BIT_FLAG_Firmware_PsrState, 140 "mod_power set_power_opt: psr_power_opt=0x%04x, power_opt=0x%04x active_psr_events=0x%04x, psr_power_opt_flag=0x%04x", 141 core_power->map[stream_index].psr_power_opt, 142 power_opt, 143 active_psr_events, 144 core_power->map[stream_index].caps->psr_power_opt_flag); 145 dc_link_set_psr_allow_active(link, NULL, false, false, &power_opt); 146 core_power->map[stream_index].psr_power_opt = power_opt; 147 } 148 } 149 150 static bool set_psr_enable(struct mod_power *mod_power, 151 struct dc_stream_state *stream, 152 bool psr_enable, 153 bool wait, 154 bool force_static) 155 { 156 struct core_power *core_power = NULL; 157 enum dc_psr_state state = PSR_STATE0; 158 unsigned int retry_count; 159 const unsigned int max_retry = 1000; 160 struct dc_link *link = NULL; 161 162 if (mod_power == NULL) 163 return false; 164 165 core_power = MOD_POWER_TO_CORE(mod_power); 166 167 if (core_power->num_entities == 0) { 168 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 169 WPP_BIT_FLAG_Firmware_PsrState, 170 "set psr enable: ERROR: stream=%p num_entities=%u", 171 stream, 172 core_power->num_entities); 173 return false; 174 } 175 176 if (psr_enable) { 177 unsigned int vsync_rate_hz; 178 struct dc_static_screen_params params = {0}; 179 180 vsync_rate_hz = (unsigned int)div_u64(div_u64(( 181 stream->timing.pix_clk_100hz * 100), 182 stream->timing.v_total), 183 stream->timing.h_total); 184 185 params.triggers.cursor_update = true; 186 params.triggers.overlay_update = true; 187 params.triggers.surface_update = true; 188 params.num_frames = calc_psr_num_static_frames(vsync_rate_hz); 189 190 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 191 WPP_BIT_FLAG_Firmware_PsrState, 192 "set psr enable: CALCS: pix_clk_100hz=%u v_total=%u h_total=%u vsync_rate_hz=%u num_frames=%u", 193 stream->timing.pix_clk_100hz, 194 stream->timing.v_total, 195 stream->timing.h_total, 196 vsync_rate_hz, 197 params.num_frames); 198 199 dc_stream_set_static_screen_params(core_power->dc, 200 &stream, 1, 201 ¶ms); 202 } 203 204 link = dc_stream_get_link(stream); 205 206 if (!dc_link_set_psr_allow_active(link, &psr_enable, false, force_static, NULL)) { 207 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 208 WPP_BIT_FLAG_Firmware_PsrState, 209 "set psr enable: ERROR: stream=%p link=%p psr_enable=%d", 210 stream, 211 link, 212 psr_enable); 213 return false; 214 } 215 216 if (wait == true) { 217 218 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 219 WPP_BIT_FLAG_Firmware_PsrState, 220 "set psr enable: BEGIN WAIT: psr_enable=%d", 221 (int)psr_enable); 222 223 for (retry_count = 0; retry_count <= max_retry; retry_count++) { 224 dc_link_get_psr_state(link, &state); 225 if (psr_enable) { 226 if (state != PSR_STATE0 && 227 (!force_static || state == PSR_STATE3)) 228 break; 229 } else { 230 if (state == PSR_STATE0) 231 break; 232 } 233 udelay(500); 234 } 235 236 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 237 WPP_BIT_FLAG_Firmware_PsrState, 238 "set psr enable: END WAIT: psr_enable=%d", 239 (int)psr_enable); 240 241 /* assert if max retry hit */ 242 if (retry_count >= max_retry) { 243 ASSERT(0); 244 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 245 WPP_BIT_FLAG_Firmware_PsrState, 246 "set psr enable: ERROR: retry_count=%u: Unexpectedly long wait for PSR state change.", 247 retry_count); 248 } 249 } else { 250 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 251 WPP_BIT_FLAG_Firmware_PsrState, 252 "set psr enable: PSR state change initiated (wait=false): psr_enable=%d", 253 (int)psr_enable); 254 } 255 256 return true; 257 } 258 259 bool mod_power_get_psr_event(struct mod_power *mod_power, 260 struct dc_stream_state *stream, 261 unsigned int *active_psr_events) 262 { 263 struct core_power *core_power = NULL; 264 unsigned int stream_index = 0; 265 266 if (mod_power == NULL) 267 return false; 268 269 core_power = MOD_POWER_TO_CORE(mod_power); 270 271 if (core_power->num_entities == 0) 272 return false; 273 274 stream_index = map_index_from_stream(core_power, stream); 275 276 if (!core_power->map[stream_index].caps->psr_version) 277 return false; 278 279 *active_psr_events = core_power->map[stream_index].psr_events; 280 281 return true; 282 } 283 284 bool mod_power_set_psr_event(struct mod_power *mod_power, 285 struct dc_stream_state *stream, bool set_event, 286 enum psr_event event, bool wait) 287 { 288 struct core_power *core_power = NULL; 289 unsigned int stream_index = 0; 290 unsigned int active_psr_events = 0; 291 bool psr_enable_request = false; 292 bool force_static = false; 293 294 if (mod_power == NULL || stream == NULL) 295 return false; 296 297 core_power = MOD_POWER_TO_CORE(mod_power); 298 stream_index = map_index_from_stream(core_power, stream); 299 300 if (core_power->num_entities == 0) { 301 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 302 WPP_BIT_FLAG_Firmware_PsrState, 303 "mod_power set_psr_event: ERROR: stream=%p event=%d num_entities=%u", 304 stream, 305 (int)event, 306 core_power->num_entities); 307 return false; 308 } 309 310 if (!core_power->map[stream_index].caps->psr_version) 311 return false; 312 313 if (set_event) 314 core_power->map[stream_index].psr_events |= event; 315 else 316 core_power->map[stream_index].psr_events &= ~event; 317 318 active_psr_events = core_power->map[stream_index].psr_events; 319 320 // ignore other events when we're in forced psr enabled state 321 if (active_psr_events & psr_event_dynamic_display_switch && 322 event != psr_event_dynamic_display_switch) 323 return false; 324 325 // ignore other events when we're in forced psr enabled state 326 if (active_psr_events & psr_event_os_override_hold && 327 event != psr_event_os_override_hold) 328 return false; 329 330 // ignore other events when we're in forced psr enabled state 331 // dds events need to be processed while in dynamic_link_rate_control 332 if (active_psr_events & psr_event_dynamic_link_rate_control && 333 event != psr_event_dynamic_link_rate_control && 334 event != psr_event_dds_defer_stream_enable && 335 event != psr_event_dynamic_display_switch) 336 return false; 337 338 if (active_psr_events & (psr_event_test_harness_disable_psr | psr_event_os_request_disable)) 339 psr_enable_request = false; 340 else if (active_psr_events & psr_event_pause) 341 psr_enable_request = false; 342 else if (active_psr_events & psr_event_test_harness_enable_psr) 343 psr_enable_request = true; 344 else if (active_psr_events & psr_event_dynamic_display_switch) { 345 psr_enable_request = true; 346 force_static = true; 347 } else if (active_psr_events & psr_event_dynamic_link_rate_control) { 348 psr_enable_request = true; 349 force_static = true; 350 } else if (active_psr_events & psr_event_edp_panel_off_disable_psr) 351 psr_enable_request = false; 352 else if (active_psr_events & (psr_event_hw_programming | 353 psr_event_defer_enable | 354 psr_event_dds_defer_stream_enable | 355 psr_event_vrr_transition | 356 psr_event_immediate_flip)) 357 psr_enable_request = false; 358 else if (active_psr_events & psr_event_big_screen_video) 359 psr_enable_request = true; 360 else if (active_psr_events & psr_event_full_screen) 361 psr_enable_request = false; 362 else if (active_psr_events & psr_event_mpo_video_selective_update) 363 psr_enable_request = true; 364 else if (active_psr_events & psr_event_vsync) 365 psr_enable_request = false; 366 else if (active_psr_events & psr_event_crc_window_active) 367 psr_enable_request = false; 368 else 369 psr_enable_request = true; 370 371 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE, 372 WPP_BIT_FLAG_Firmware_PsrState, 373 "mod_power set_psr_event: before: psr_enabled=%d -> request: set_event=%d event=0x%04x -> result: psr_events=0x%04x psr_enable_request=%d", 374 (int)core_power->map[stream_index].psr_enabled, 375 (int)set_event, 376 (unsigned int)event, 377 (unsigned int)core_power->map[stream_index].psr_events, 378 (int)psr_enable_request); 379 mod_power_psr_set_power_opt(mod_power, stream, active_psr_events, psr_enable_request); 380 381 if (core_power->map[stream_index].psr_enabled != psr_enable_request || force_static) { 382 if (set_psr_enable(mod_power, stream, psr_enable_request, wait, force_static)) 383 core_power->map[stream_index].psr_enabled = psr_enable_request; 384 } 385 386 return true; 387 } 388 389 bool mod_power_get_psr_state(struct mod_power *mod_power, 390 const struct dc_stream_state *stream, 391 enum dc_psr_state *state) 392 { 393 struct core_power *core_power = NULL; 394 const struct dc_link *link = NULL; 395 396 if (!stream) 397 return false; 398 399 if (mod_power == NULL) 400 return false; 401 402 core_power = MOD_POWER_TO_CORE(mod_power); 403 404 if (core_power->num_entities == 0) 405 return false; 406 407 link = dc_stream_get_link(stream); 408 return dc_link_get_psr_state(link, state); 409 } 410 411 bool mod_power_get_psr_enabled_status(struct mod_power *mod_power, 412 const struct dc_stream_state *stream, 413 bool *psr_enabled) 414 { 415 struct core_power *core_power = NULL; 416 unsigned int stream_index = 0; 417 418 if (mod_power == NULL) 419 return false; 420 421 core_power = MOD_POWER_TO_CORE(mod_power); 422 423 if (core_power->num_entities == 0) 424 return false; 425 426 stream_index = map_index_from_stream(core_power, stream); 427 428 if (!core_power->map[stream_index].caps->psr_version) 429 return false; 430 431 *psr_enabled = core_power->map[stream_index].psr_enabled; 432 433 return true; 434 } 435 436 void mod_power_psr_residency(struct mod_power *mod_power, 437 const struct dc_stream_state *stream, 438 unsigned int *residency, 439 const uint8_t mode) 440 { 441 struct core_power *core_power = NULL; 442 const struct dc_link *link = NULL; 443 444 if (!stream) 445 return; 446 447 if (mod_power == NULL) 448 return; 449 450 core_power = MOD_POWER_TO_CORE(mod_power); 451 452 if (core_power->num_entities == 0) 453 return; 454 455 link = dc_stream_get_link(stream); 456 457 if (link != NULL) 458 link->dc->link_srv->edp_get_psr_residency(link, residency, mode); 459 } 460 bool mod_power_psr_get_active_psr_events(struct mod_power *mod_power, 461 const struct dc_stream_state *stream, unsigned int *active_psr_events) 462 { 463 struct core_power *core_power = NULL; 464 unsigned int stream_index = 0; 465 466 if (!stream) 467 return false; 468 469 if (mod_power == NULL) 470 return false; 471 472 if (active_psr_events == NULL) 473 return false; 474 475 core_power = MOD_POWER_TO_CORE(mod_power); 476 477 if (core_power->num_entities == 0) 478 return false; 479 480 stream_index = map_index_from_stream(core_power, stream); 481 482 *active_psr_events = core_power->map[stream_index].psr_events; 483 return true; 484 } 485 486 bool mod_power_psr_set_sink_vtotal_in_psr_active(struct mod_power *mod_power, 487 const struct dc_stream_state *stream, 488 uint16_t psr_vtotal_idle, 489 uint16_t psr_vtotal_su) 490 { 491 struct core_power *core_power = NULL; 492 unsigned int stream_index = 0; 493 const struct dc_link *link = NULL; 494 495 if (!stream) 496 return false; 497 498 if (mod_power == NULL) 499 return false; 500 501 core_power = MOD_POWER_TO_CORE(mod_power); 502 503 if (core_power->num_entities == 0) 504 return false; 505 506 stream_index = map_index_from_stream(core_power, stream); 507 508 if (!core_power->map[stream_index].caps->psr_version) 509 return false; 510 511 link = dc_stream_get_link(stream); 512 513 return link->dc->link_srv->edp_set_sink_vtotal_in_psr_active( 514 link, psr_vtotal_idle, psr_vtotal_su); 515 } 516 /* 517 * is_psr_su_specific_panel() - check if sink is AMD vendor-specific PSR-SU 518 * supported eDP device. 519 * 520 * @link: dc link pointer 521 * 522 * Return: true if AMDGPU vendor specific PSR-SU eDP panel 523 */ 524 bool is_psr_su_specific_panel(struct dc_link *link) 525 { 526 bool isPSRSUSupported = false; 527 struct dpcd_caps *dpcd_caps = &link->dpcd_caps; 528 529 if (dpcd_caps->edp_rev >= DP_EDP_14) { 530 if (dpcd_caps->psr_info.psr_version >= DP_PSR2_WITH_Y_COORD_ET_SUPPORTED) 531 isPSRSUSupported = true; 532 /* 533 * Some panels will report PSR capabilities over additional DPCD bits. 534 * Such panels are approved despite reporting only PSR v3, as long as 535 * the additional bits are reported. 536 */ 537 if (dpcd_caps->sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8) { 538 /* 539 * This is the temporary workaround to disable PSRSU when system turned on 540 * DSC function on the sepcific sink. 541 */ 542 if (dpcd_caps->psr_info.psr_version < DP_PSR2_WITH_Y_COORD_IS_SUPPORTED) 543 isPSRSUSupported = false; 544 else if (dpcd_caps->dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT && 545 ((dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x08) || 546 (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x07))) 547 isPSRSUSupported = false; 548 else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03) 549 isPSRSUSupported = false; 550 else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x01) 551 isPSRSUSupported = false; 552 else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1) 553 isPSRSUSupported = true; 554 } 555 } 556 557 return isPSRSUSupported; 558 } 559 560 /** 561 * mod_power_calc_psr_configs() - calculate/update generic psr configuration fields. 562 * @psr_config: [output], psr configuration structure to be updated 563 * @link: [input] dc link pointer 564 * @stream: [input] dc stream state pointer 565 * 566 * calculate and update the psr configuration fields that are not DM specific, i.e. such 567 * fields which are based on DPCD caps or timing information. To setup PSR in DMUB FW, 568 * this helper is assumed to be called before the call of the DC helper dc_link_setup_psr(). 569 * 570 * PSR config fields to be updated within the helper: 571 * - psr_rfb_setup_time 572 * - psr_sdp_transmit_line_num_deadline 573 * - line_time_in_us 574 * - su_y_granularity 575 * - su_granularity_required 576 * - psr_frame_capture_indication_req 577 * - psr_exit_link_training_required 578 * 579 * PSR config fields that are DM specific and NOT updated within the helper: 580 * - allow_smu_optimizations 581 * - allow_multi_disp_optimizations 582 */ 583 void mod_power_calc_psr_configs(struct psr_config *psr_config, 584 struct dc_link *link, 585 const struct dc_stream_state *stream) 586 { 587 unsigned int num_vblank_lines = 0; 588 unsigned int vblank_time_in_us = 0; 589 unsigned int sdp_tx_deadline_in_us = 0; 590 unsigned int line_time_in_us = 0; 591 struct dpcd_caps *dpcd_caps = &link->dpcd_caps; 592 const int psr_setup_time_step_in_us = 55; /* refer to eDP spec DPCD 0x071h */ 593 594 /* timing parameters */ 595 num_vblank_lines = stream->timing.v_total - 596 stream->timing.v_addressable - 597 stream->timing.v_border_top - 598 stream->timing.v_border_bottom; 599 600 vblank_time_in_us = (stream->timing.h_total * num_vblank_lines * 1000) / (stream->timing.pix_clk_100hz / 10); 601 602 line_time_in_us = ((stream->timing.h_total * 1000) / (stream->timing.pix_clk_100hz / 10)) + 1; 603 604 /** 605 * psr configuration fields 606 * 607 * as per eDP 1.5 pg. 377 of 459, DPCD 0x071h bits [3:1], psr setup time bits interpreted as below 608 * 000b <--> 330 us (default) 609 * 001b <--> 275 us 610 * 010b <--> 220 us 611 * 011b <--> 165 us 612 * 100b <--> 110 us 613 * 101b <--> 055 us 614 * 110b <--> 000 us 615 */ 616 psr_config->psr_rfb_setup_time = 617 (6 - dpcd_caps->psr_info.psr_dpcd_caps.bits.PSR_SETUP_TIME) * psr_setup_time_step_in_us; 618 619 if (psr_config->psr_rfb_setup_time > vblank_time_in_us) { 620 link->psr_settings.psr_frame_capture_indication_req = true; 621 link->psr_settings.psr_sdp_transmit_line_num_deadline = num_vblank_lines; 622 } else { 623 sdp_tx_deadline_in_us = vblank_time_in_us - psr_config->psr_rfb_setup_time; 624 625 /* Set the last possible line SDP may be transmitted without violating the RFB setup time */ 626 link->psr_settings.psr_frame_capture_indication_req = false; 627 link->psr_settings.psr_sdp_transmit_line_num_deadline = sdp_tx_deadline_in_us / line_time_in_us; 628 } 629 630 psr_config->psr_sdp_transmit_line_num_deadline = link->psr_settings.psr_sdp_transmit_line_num_deadline; 631 psr_config->line_time_in_us = line_time_in_us; 632 psr_config->su_y_granularity = dpcd_caps->psr_info.psr2_su_y_granularity_cap; 633 psr_config->su_granularity_required = dpcd_caps->psr_info.psr_dpcd_caps.bits.SU_GRANULARITY_REQUIRED; 634 psr_config->psr_frame_capture_indication_req = link->psr_settings.psr_frame_capture_indication_req; 635 psr_config->psr_exit_link_training_required = 636 !link->dpcd_caps.psr_info.psr_dpcd_caps.bits.LINK_TRAINING_ON_EXIT_NOT_REQUIRED; 637 } 638 639 bool psr_su_set_dsc_slice_height(struct dc *dc, struct dc_link *link, 640 struct dc_stream_state *stream, 641 struct psr_config *config) 642 { 643 uint32_t pic_height; 644 uint32_t slice_height; 645 646 config->dsc_slice_height = 0; 647 if (!(link->connector_signal & SIGNAL_TYPE_EDP) || 648 !dc->caps.edp_dsc_support || 649 link->panel_config.dsc.disable_dsc_edp || 650 !link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT || 651 !stream->timing.dsc_cfg.num_slices_v) 652 return true; 653 654 pic_height = stream->timing.v_addressable + 655 stream->timing.v_border_top + stream->timing.v_border_bottom; 656 657 if (stream->timing.dsc_cfg.num_slices_v == 0) 658 return false; 659 660 slice_height = pic_height / stream->timing.dsc_cfg.num_slices_v; 661 config->dsc_slice_height = (uint16_t)slice_height; 662 663 if (slice_height) { 664 if (config->su_y_granularity && 665 (slice_height % config->su_y_granularity)) { 666 ASSERT(0); 667 return false; 668 } 669 } 670 671 return true; 672 } 673