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