xref: /linux/drivers/gpu/drm/amd/display/modules/power/power_psr.c (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
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 						   &params);
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