xref: /linux/drivers/gpu/drm/amd/display/modules/power/power.c (revision 254a47ce0c8a52ff78a60f92a13b56db69f69096)
1 /*
2  * Copyright 2016 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include "dm_services.h"
27 #include "dc.h"
28 #include "mod_power.h"
29 #include "core_types.h"
30 #include "dmcu.h"
31 #include "abm.h"
32 #include "power_helpers.h"
33 #include "dce/dmub_psr.h"
34 #include "dal_asic_id.h"
35 #include "link_service.h"
36 #include <linux/math.h>
37 
38 #define DC_TRACE_LEVEL_MESSAGE(...) /* do nothing */
39 #define DC_TRACE_LEVEL_MESSAGEP(...) /* do nothing */
40 
41 #define MOD_POWER_MAX_CONCURRENT_STREAMS 32
42 #define SMOOTH_BRIGHTNESS_ADJUSTMENT_TIME_IN_MS 500
43 #define LOW_REFRESH_RATE_DURATION_US_UPPER_BOUND 25000
44 
45 
46 struct backlight_state {
47 	/* HW uses u16.16 format for backlight PWM */
48 	unsigned int backlight_pwm;
49 	/* DM may call power module to set backlight
50 	 * targeting percent brightness
51 	 */
52 	unsigned int backlight_millipercent;
53 	/* DM may call power module to set backlight based on an explicit
54 	 * nits value.
55 	 */
56 	unsigned int backlight_millinit;
57 	unsigned int frame_ramp;
58 	bool smooth_brightness_enabled;
59 	bool isHDR;
60 };
61 struct power_entity {
62 	struct dc_stream_state *stream;
63 	struct psr_caps *caps;
64 	struct mod_power_psr_context *psr_context;
65 
66 	/*PSR cached properties*/
67 	bool psr_enabled;
68 	unsigned int psr_events;
69 	unsigned int psr_power_opt;
70 	unsigned int replay_events;
71 };
72 
73 struct pwr_backlight_properties {
74 	bool use_nits_based_brightness;
75 	bool disable_fractional_pwm;
76 
77 	unsigned int min_abm_backlight;
78 	unsigned int num_backlight_levels;
79 
80 	bool backlight_ramping_override;
81 	unsigned int backlight_ramping_reduction;
82 	unsigned int backlight_ramping_start;
83 
84 	/* Backlight cached properties */
85 	unsigned int ac_backlight_percent;
86 	unsigned int dc_backlight_percent;
87 
88 	/* backlight LUT stored in HW u16.16 format*/
89 	unsigned int *backlight_lut;
90 	unsigned int min_backlight_pwm;
91 	unsigned int max_backlight_pwm;
92 	unsigned int backlight_range;
93 
94 	/* Describes the panel's min and max luminance in millinits measured
95 	 * on full white screen, in min and max backlight settings.
96 	 */
97 	unsigned int min_brightness_millinits;
98 	unsigned int max_brightness_millinits;
99 	unsigned int nits_range;
100 
101 	bool backlight_caps_valid;
102 	bool use_custom_backlight_caps;
103 	unsigned int custom_backlight_caps_config_no;
104 	bool use_linear_backlight_curve;
105 };
106 
107 struct dmcu_varibright_cached_properties {
108 	unsigned int varibright_config_setting;
109 	unsigned int varibright_level;
110 	unsigned int varibright_hw_level;
111 	unsigned int def_varibright_level;
112 	bool varibright_user_enable;
113 	bool varibright_active;
114 };
115 
116 struct core_power {
117 	struct mod_power mod_public;
118 	struct dc *dc;
119 	struct power_entity *map;
120 	struct dmcu_varibright_cached_properties varibright_prop;
121 	struct pwr_backlight_properties bl_prop[MAX_NUM_EDP];
122 	struct backlight_state bl_state[MAX_NUM_EDP];
123 	unsigned int edp_num;
124 
125 	bool psr_smu_optimizations_support;
126 	bool multi_disp_optimizations_support;
127 
128 	unsigned int num_entities;
129 };
130 
131 union dmcu_abm_set_bl_params {
132 	struct {
133 		unsigned int gradual_change : 1; /* [0:0] */
134 		unsigned int reserved : 15; /* [15:1] */
135 		unsigned int frame_ramp : 16; /* [31:16] */
136 	} bits;
137 	unsigned int u32All;
138 };
139 
140 /* If system or panel does not report some sort of brightness percent to nits
141  * mapping, we will use following default values so backlight control using
142  * nits based interfaces will still work, but might not describe panel
143  * correctly. In this case percentage based backlight control should ideally
144  * be used.
145  * Min = 5 nits
146  * Max = 300 nits
147  */
148 
149 static const unsigned int pwr_default_min_brightness_millinits = 1000;
150 static const unsigned int pwr_default_sdr_brightness_millinits = 270000;
151 
152 static const unsigned int default_ac_backlight_percent   = 100;
153 static const unsigned int default_dc_backlight_percent   = 70;
154 
155 #define MOD_POWER_TO_CORE(mod_power)\
156 		container_of(mod_power, struct core_power, mod_public)
157 
158 static unsigned int calc_psr_num_static_frames(unsigned int vsync_rate_hz)
159 {
160 	/* Initialize fail-safe to 2 static frames. */
161 	unsigned int num_frames_static = 2;
162 
163 	/* Calculate number of frames such that at least 30 ms has passed.
164 	 * Round up to ensure the static period is not shorter than 30 ms.
165 	 */
166 	if (vsync_rate_hz != 0)
167 		num_frames_static = DIV_ROUND_UP(30000 * vsync_rate_hz, 1000000);
168 
169 	return num_frames_static;
170 }
171 
172 /* Given a specific dc_stream* this function finds its equivalent
173  * on the core_freesync->map and returns the corresponding index
174  */
175 static unsigned int map_index_from_stream(struct core_power *core_power,
176 		const struct dc_stream_state *stream)
177 {
178 	unsigned int index = 0;
179 
180 	for (index = 0; index < core_power->num_entities; index++) {
181 		if (core_power->map[index].stream == stream)
182 			return index;
183 	}
184 	/* Could not find stream requested, this is not trivial, fix when hit*/
185 	DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
186 						WPP_BIT_FLAG_Firmware_PsrState,
187 						"map index from stream: ERROR: core_power=%p stream=%p",
188 						core_power,
189 						stream);
190 	ASSERT(false);
191 	/* We come here only when we can't map stream index.
192 	 * In good cases, this would happen when we attempt to change
193 	 * brightness before stream creation, in which case we create a
194 	 * dummy stream with index 0.
195 	 * With external monitor connected, the index passed from this return
196 	 * is 1. Passing anything greater than 0 from here would always point
197 	 * to bad memory.
198 	 */
199 	return 0;
200 }
201 
202 bool mod_power_hw_init(struct mod_power *mod_power)
203 {
204 	/* Call backlight initialization */
205 	return mod_power_hw_init_backlight(mod_power);
206 
207 	/* Future: Add other HW init here */
208 }
209 
210 struct mod_power *mod_power_create(struct dc *dc,
211 		struct mod_power_init_params *init_params,
212 		unsigned int edp_num)
213 {
214 	struct core_power *core_power = NULL;
215 	int i = 0;
216 	unsigned int abm_max_config = 0;
217 	unsigned int inst = 0;
218 	bool is_brightness_range_valid = false;
219 
220 	if (dc == NULL)
221 		goto fail_dc_null;
222 
223 	core_power = kzalloc(sizeof(struct core_power), GFP_KERNEL);
224 
225 	if (core_power == NULL)
226 		goto fail_alloc_context;
227 
228 	core_power->edp_num = edp_num;
229 	core_power->map = kzalloc(sizeof(struct power_entity) * MOD_POWER_MAX_CONCURRENT_STREAMS,
230 				  GFP_KERNEL);
231 
232 	if (core_power->map == NULL)
233 		goto fail_alloc_map;
234 
235 	for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) {
236 		core_power->map[i].stream = NULL;
237 	}
238 
239 	for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) {
240 		core_power->map[i].psr_context =
241 				kzalloc(sizeof(struct mod_power_psr_context),
242 					GFP_KERNEL);
243 		if (core_power->map[i].psr_context == NULL)
244 			goto fail_construct;
245 	}
246 
247 	core_power->psr_smu_optimizations_support = init_params->allow_psr_smu_optimizations;
248 	core_power->multi_disp_optimizations_support = init_params->allow_psr_multi_disp_optimizations;
249 
250 	for (inst = 0; inst < edp_num; inst++) {
251 		core_power->bl_prop[inst].min_abm_backlight =
252 				init_params[inst].min_abm_backlight;
253 		core_power->bl_prop[inst].disable_fractional_pwm =
254 				init_params[inst].disable_fractional_pwm;
255 		core_power->bl_prop[inst].use_linear_backlight_curve =
256 				init_params[inst].use_linear_backlight_curve;
257 		core_power->bl_prop[inst].use_nits_based_brightness =
258 				init_params[inst].use_nits_based_brightness;
259 		core_power->bl_prop[inst].backlight_ramping_override =
260 				init_params[inst].backlight_ramping_override;
261 		core_power->bl_prop[inst].backlight_ramping_reduction =
262 				init_params[inst].backlight_ramping_reduction;
263 		core_power->bl_prop[inst].backlight_ramping_start =
264 				init_params[inst].backlight_ramping_start;
265 		core_power->bl_prop[inst].use_custom_backlight_caps =
266 				init_params[inst].use_custom_backlight_caps;
267 		core_power->bl_prop[inst].custom_backlight_caps_config_no =
268 				init_params[inst].custom_backlight_caps_config_no;
269 
270 		// Do not allow less than 101 backlight levels
271 		if (init_params[inst].num_backlight_levels < 101)
272 			core_power->bl_prop[inst].num_backlight_levels = 101;
273 		else
274 			core_power->bl_prop[inst].num_backlight_levels =
275 				init_params[inst].num_backlight_levels;
276 
277 		core_power->bl_prop[inst].backlight_lut = (unsigned int *)
278 				(kzalloc(sizeof(unsigned int) *
279 				core_power->bl_prop[inst].num_backlight_levels, GFP_KERNEL));
280 		if (core_power->bl_prop[inst].backlight_lut == NULL)
281 			goto fail_alloc_backlight_array;
282 	}
283 
284 	core_power->varibright_prop.varibright_active = false;
285 
286 	core_power->varibright_prop.varibright_user_enable =
287 			init_params->def_varibright_enable;
288 
289 	// Table of ABM levels here is 1-4, but level 0 also exists as 'off'
290 	if (init_params->varibright_level <= abm_defines_max_level) {
291 		core_power->varibright_prop.varibright_level =
292 			init_params->varibright_level;
293 
294 	} else {
295 		core_power->varibright_prop.varibright_level = 3;
296 	}
297 	if (init_params->def_varibright_level <= abm_defines_max_level) {
298 		core_power->varibright_prop.def_varibright_level =
299 			init_params->def_varibright_level;
300 	} else {
301 		core_power->varibright_prop.def_varibright_level = 3;
302 	}
303 
304 	// ABM used to contain 4 different configs. There is only 3 since ABM 2.3.
305 	if ((dc->res_pool->dmcu != NULL) && (dc->res_pool->dmcu->dmcu_version.abm_version < 0x23))
306 		abm_max_config = 4;
307 	else
308 		abm_max_config = 3;
309 
310 	if (init_params->abm_config_setting < abm_max_config)
311 		core_power->varibright_prop.varibright_config_setting =
312 			init_params->abm_config_setting;
313 	else
314 		core_power->varibright_prop.varibright_config_setting = 0;
315 
316 	for (inst = 0; inst < edp_num; inst++) {
317 		core_power->bl_prop[inst].backlight_lut[0] = init_params[inst].min_backlight_pwm;
318 		core_power->bl_prop[inst].backlight_lut[
319 			core_power->bl_prop[inst].num_backlight_levels-1] =
320 				init_params[inst].max_backlight_pwm;
321 		core_power->bl_prop[inst].min_backlight_pwm = init_params[inst].min_backlight_pwm;
322 		core_power->bl_prop[inst].max_backlight_pwm = init_params[inst].max_backlight_pwm;
323 		core_power->bl_prop[inst].ac_backlight_percent =
324 				default_ac_backlight_percent;
325 		core_power->bl_prop[inst].dc_backlight_percent =
326 				default_dc_backlight_percent;
327 		core_power->bl_prop[inst].backlight_caps_valid = false;
328 
329 		if (core_power->bl_prop[inst].use_nits_based_brightness) {
330 			core_power->bl_prop[inst].min_brightness_millinits =
331 					init_params[inst].panel_min_millinits;
332 			core_power->bl_prop[inst].max_brightness_millinits =
333 					init_params[inst].panel_max_millinits;
334 		} else {
335 
336 			core_power->bl_prop[inst].min_brightness_millinits =
337 					pwr_default_min_brightness_millinits;
338 			core_power->bl_prop[inst].max_brightness_millinits =
339 					pwr_default_sdr_brightness_millinits;
340 		}
341 
342 		core_power->bl_prop[inst].backlight_range =
343 				core_power->bl_prop[inst].max_backlight_pwm-
344 				core_power->bl_prop[inst].min_backlight_pwm;
345 
346 		core_power->bl_prop[inst].nits_range =
347 				core_power->bl_prop[inst].max_brightness_millinits -
348 				core_power->bl_prop[inst].min_brightness_millinits;
349 
350 		core_power->bl_state[inst].smooth_brightness_enabled = true;
351 	}
352 
353 	/* Check if at least 1 instance in core_power is populated before failing */
354 	for (inst = 0; inst < edp_num; inst++) {
355 		if (core_power->bl_prop[inst].nits_range != 0 && core_power->bl_prop[inst].backlight_range != 0) {
356 			is_brightness_range_valid = true;
357 			break;
358 		}
359 
360 	}
361 	if (!is_brightness_range_valid)
362 		goto fail_bad_brightness_range;
363 
364 	core_power->num_entities = 0;
365 
366 	core_power->dc = dc;
367 	for (inst = 0; inst < edp_num; inst++) {
368 		initialize_backlight_caps(core_power, inst);
369 		core_power->bl_state[inst].backlight_millipercent =
370 			core_power->bl_prop[inst].dc_backlight_percent * 1000;
371 		core_power->bl_state[inst].backlight_pwm = backlight_millipercent_to_pwm(core_power,
372 		core_power->bl_state[inst].backlight_millipercent, inst);
373 		core_power->bl_state[inst].backlight_millinit = backlight_millipercent_to_millinit(core_power,
374 		core_power->bl_state[inst].backlight_millipercent, inst);
375 	}
376 
377 	return &core_power->mod_public;
378 
379 fail_bad_brightness_range:
380 fail_alloc_backlight_array:
381 	for (inst = 0; inst < edp_num; inst++)
382 		if (core_power->bl_prop[inst].backlight_lut)
383 			kfree(core_power->bl_prop[inst].backlight_lut);
384 fail_construct:
385 	for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) {
386 		if (core_power->map[i].psr_context)
387 			kfree(core_power->map[i].psr_context);
388 	}
389 	kfree(core_power->map);
390 
391 fail_alloc_map:
392 	kfree(core_power);
393 
394 fail_alloc_context:
395 fail_dc_null:
396 	return NULL;
397 }
398 
399 void mod_power_destroy(struct mod_power *mod_power)
400 {
401 	if (mod_power != NULL) {
402 		unsigned int i;
403 		struct core_power *core_power =
404 				MOD_POWER_TO_CORE(mod_power);
405 
406 		for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++)
407 			if (core_power->map[i].psr_context)
408 				kfree(core_power->map[i].psr_context);
409 
410 		for (i = 0; i < core_power->num_entities; i++)
411 			if (core_power->map[i].stream)
412 				dc_stream_release(core_power->map[i].stream);
413 
414 		kfree(core_power->map);
415 
416 		for (i = 0; i < MAX_NUM_EDP; i++)
417 			if (core_power->bl_prop[i].backlight_lut)
418 				kfree(core_power->bl_prop[i].backlight_lut);
419 
420 		kfree(core_power);
421 	}
422 }
423 
424 bool mod_power_add_stream(struct mod_power *mod_power,
425 		struct dc_stream_state *stream, struct psr_caps *caps)
426 {
427 	struct core_power *core_power = NULL;
428 
429 	if (mod_power == NULL)
430 		return false;
431 
432 	core_power = MOD_POWER_TO_CORE(mod_power);
433 
434 	if (core_power->num_entities < MOD_POWER_MAX_CONCURRENT_STREAMS) {
435 		dc_stream_retain(stream);
436 
437 		core_power->map[core_power->num_entities].stream = stream;
438 		core_power->map[core_power->num_entities].caps = caps;
439 
440 		// initialize cached PSR params to something "safe" (something that is
441 		// consistent with disabled PSR state)
442 		core_power->map[core_power->num_entities].psr_enabled = 0;
443 		core_power->map[core_power->num_entities].psr_events = psr_event_vsync;
444 		core_power->map[core_power->num_entities].psr_power_opt = 0;
445 		core_power->num_entities++;
446 		return true;
447 	}
448 
449 	DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
450 						WPP_BIT_FLAG_Firmware_PsrState,
451 						"mod_power: add_stream: ERROR: stream=%p num_entities=%u >= MOD_POWER_MAX_CONCURRENT_STREAMS",
452 						stream,
453 						core_power->num_entities);
454 
455 	return false;
456 }
457 
458 bool mod_power_remove_stream(struct mod_power *mod_power,
459 		const struct dc_stream_state *stream)
460 {
461 	unsigned int i = 0;
462 	struct core_power *core_power = NULL;
463 	unsigned int index = 0;
464 
465 	if (mod_power == NULL)
466 		return false;
467 
468 	core_power = MOD_POWER_TO_CORE(mod_power);
469 	if (core_power->num_entities == 0) {
470 		/* trying to remove a stream a second time or have not added yet */
471 		BREAK_TO_DEBUGGER();
472 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
473 							WPP_BIT_FLAG_Firmware_PsrState,
474 							"mod_power: remove_stream: ERROR: num_entities=0 stream=%p",
475 							stream);
476 		return false;
477 	}
478 
479 	index = map_index_from_stream(core_power, stream);
480 
481 	if (index >= core_power->num_entities) {
482 		/* trying to remove a stream a second time or have not added yet */
483 		BREAK_TO_DEBUGGER();
484 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
485 							WPP_BIT_FLAG_Firmware_PsrState,
486 							"mod_power: remove_stream: ERROR: index=%u >= num_entities=%u stream=%p",
487 							index,
488 							core_power->num_entities,
489 							stream);
490 		return false;
491 	}
492 
493 	dc_stream_release(core_power->map[index].stream);
494 	core_power->map[index].stream = NULL;
495 	/* To remove this entity, shift everything after down */
496 	for (i = index; i < core_power->num_entities - 1; i++) {
497 		core_power->map[i].stream = core_power->map[i + 1].stream;
498 		core_power->map[i].caps = core_power->map[i + 1].caps;
499 
500 		// copy over cached parameters in case they map to PSR capable display
501 		core_power->map[i].psr_enabled = core_power->map[i + 1].psr_enabled;
502 		core_power->map[i].psr_events = core_power->map[i + 1].psr_events;
503 		core_power->map[i].psr_power_opt = core_power->map[i + 1].psr_power_opt;
504 
505 		memcpy(core_power->map[i].psr_context, core_power->map[i + 1].psr_context, sizeof(struct mod_power_psr_context));
506 		memset(core_power->map[i + 1].psr_context, 0, sizeof(struct mod_power_psr_context));
507 	}
508 	core_power->num_entities--;
509 
510 	return true;
511 }
512 
513 /*
514  * Replace_stream should be used when there is a mode set for existing
515  * display target with a valid stream. In this case might need to retain
516  * cached PSR state (events, power opt, en/dis) if we are dealing with PSR
517  * capable display. If mod_power_remove and mod_power_add are used instead,
518  * then stream may be assigned to a different slot and may end up with
519  * wrong cached PSR state. It is hard to tell which PSR events should
520  * persist through mode set or what psr_events should be initialized to, so
521  * it might be better just to retain them all.
522  */
523 bool mod_power_replace_stream(struct mod_power *mod_power,
524 		const struct dc_stream_state *current_stream,
525 		struct dc_stream_state *new_stream,
526 		struct psr_caps *new_caps)
527 {
528 	struct core_power *core_power = NULL;
529 	unsigned int index = 0;
530 
531 	if (mod_power == NULL)
532 		return false;
533 
534 	core_power = MOD_POWER_TO_CORE(mod_power);
535 	if (core_power->num_entities == 0) {
536 		/* no streams exist in the table yet */
537 		BREAK_TO_DEBUGGER();
538 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
539 							WPP_BIT_FLAG_Firmware_PsrState,
540 							"mod_power: replace_stream: ERROR: num_entities=0 stream=%p",
541 							current_stream);
542 		return false;
543 	}
544 
545 	index = map_index_from_stream(core_power, current_stream);
546 
547 	if (index >= core_power->num_entities) {
548 		/* trying to replace a non-existent stream */
549 		BREAK_TO_DEBUGGER();
550 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
551 							WPP_BIT_FLAG_Firmware_PsrState,
552 							"mod_power: replace_stream: ERROR: index=%u >= num_entities=%u stream=%p",
553 							index,
554 							core_power->num_entities,
555 							current_stream);
556 		return false;
557 	}
558 
559 	dc_stream_release(core_power->map[index].stream);
560 	dc_stream_retain(new_stream);
561 	core_power->map[index].stream = new_stream;
562 	core_power->map[index].caps = new_caps;
563 	memset(core_power->map[index].psr_context, 0, sizeof(struct mod_power_psr_context));
564 
565 	return true;
566 }
567 
568 bool mod_power_notify_mode_change(struct mod_power *mod_power,
569 		const struct dc_stream_state *stream,
570 		bool is_hdr)
571 {
572 	unsigned int stream_index = 0;
573 	struct core_power *core_power = NULL;
574 	struct dc_link *link = NULL;
575 	struct psr_config psr_config = {0};
576 	struct psr_context psr_context = {0};
577 	struct dc *dc = NULL;
578 	unsigned int panel_inst = 0;
579 	int active_psr_events = 0;
580 	int active_replay_events = 0;
581 
582 	if ((mod_power == NULL) || (stream == NULL))
583 		return false;
584 
585 	core_power = MOD_POWER_TO_CORE(mod_power);
586 
587 	if (core_power->num_entities == 0)
588 		return false;
589 
590 	stream_index = map_index_from_stream(core_power, stream);
591 
592 	if (stream_index >= core_power->num_entities)
593 		return false;
594 
595 	dc = core_power->dc;
596 	link = dc_stream_get_link(stream);
597 	active_psr_events = core_power->map[stream_index].psr_events;
598 	active_replay_events = core_power->map[stream_index].replay_events;
599 	if (link != NULL && dc_get_edp_link_panel_inst(dc, link, &panel_inst)) {
600 		ASSERT(link->ddc->ddc_pin->hw_info.ddc_channel <= 0xFF);
601 		uint8_t aux_inst = (uint8_t)link->ddc->ddc_pin->hw_info.ddc_channel;
602 
603 		mod_power_update_backlight_on_mode_change(core_power, link, panel_inst, aux_inst, is_hdr);
604 
605 		mod_power_calc_psr_configs(&psr_config, link, stream);
606 
607 		psr_config.psr_exit_link_training_required = core_power->map[stream_index].caps->psr_exit_link_training_required;
608 
609 		if (dc->ctx->asic_id.chip_family >= AMDGPU_FAMILY_GC_11_0_1)
610 			psr_config.allow_smu_optimizations =
611 					core_power->psr_smu_optimizations_support && dc_is_embedded_signal(stream->signal);
612 		else
613 			psr_config.allow_smu_optimizations =
614 					core_power->psr_smu_optimizations_support && mod_power_only_edp(dc->current_state, stream);
615 
616 		psr_config.allow_multi_disp_optimizations = core_power->multi_disp_optimizations_support;
617 
618 		psr_config.rate_control_caps = core_power->map[stream_index].caps->rate_control_caps;
619 
620 		if (active_psr_events & psr_event_os_request_force_ffu) {
621 			psr_config.os_request_force_ffu = true;
622 		}
623 		/*
624 		* DSC support:
625 		* DSC slice height value must be 'mod' by su_y_granularity.
626 		* According to Panel Vendor, there might be varied conditions to fulfill.
627 		* Right now, DSC slice height value must be multiple of su_y_granularity.
628 		*
629 		* The value of DSC slice height is determined in DSC Driver but it does not
630 		* propagated out here, so we need to calculate it as below 'slice_height'.
631 		*/
632 		psr_su_set_dsc_slice_height(dc, link,
633 					(struct dc_stream_state *) stream,
634 					&psr_config);
635 
636 		dc_link_setup_psr(link, stream, &psr_config, &psr_context);
637 
638 		link->replay_settings.replay_smu_opt_enable =
639 			(link->replay_settings.config.replay_smu_opt_supported &&
640 			mod_power_only_edp(dc->current_state, stream));
641 
642 		if (active_replay_events & replay_event_os_request_force_ffu) {
643 			link->replay_settings.config.os_request_force_ffu = true;
644 		}
645 
646 		if (dc_is_embedded_signal(stream->signal))
647 			dc->link_srv->dp_setup_replay(link, stream);
648 	}
649 
650 	return true;
651 }
652 
653 static void mod_power_psr_set_power_opt(struct mod_power *mod_power,
654 	struct dc_stream_state *stream,
655 	unsigned int active_psr_events,
656 	bool psr_enable_request)
657 {
658 	(void)psr_enable_request;
659 	struct core_power *core_power = NULL;
660 	struct dc_link *link = NULL;
661 	unsigned int stream_index = 0;
662 	unsigned int power_opt = 0;
663 
664 	if (!stream)
665 		return;
666 
667 	core_power = MOD_POWER_TO_CORE(mod_power);
668 	stream_index = map_index_from_stream(core_power, stream);
669 	if (!core_power->map[stream_index].caps->psr_version)
670 		return;
671 
672 	link = dc_stream_get_link(stream);
673 
674 	if (active_psr_events == 0) {
675 		/* Static Screen */
676 		power_opt |= (psr_power_opt_smu_opt_static_screen | psr_power_opt_z10_static_screen |
677 					psr_power_opt_ds_disable_allow);
678 	}
679 
680 	/* psr_power_opt_flag is a configuration parameter into the module that determines
681 	 * which optimizations to enable during psr
682 	 */
683 	power_opt &= core_power->map[stream_index].caps->psr_power_opt_flag;
684 	if (core_power->map[stream_index].psr_power_opt != power_opt) {
685 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE,
686 				WPP_BIT_FLAG_Firmware_PsrState,
687 				"mod_power set_power_opt: psr_power_opt=0x%04x, power_opt=0x%04x"
688 				"active_psr_events=0x%04x, psr_power_opt_flag=0x%04x",
689 				core_power->map[stream_index].psr_power_opt,
690 				power_opt,
691 				active_psr_events,
692 				core_power->map[stream_index].caps->psr_power_opt_flag);
693 		dc_link_set_psr_allow_active(link, NULL, false, false, &power_opt);
694 		core_power->map[stream_index].psr_power_opt = power_opt;
695 	}
696 }
697 
698 static bool set_psr_enable(struct mod_power *mod_power,
699 		struct dc_stream_state *stream,
700 		bool psr_enable,
701 		bool wait,
702 		bool force_static)
703 {
704 	struct core_power *core_power = NULL;
705 	enum dc_psr_state state = PSR_STATE0;
706 	unsigned int retry_count;
707 	const unsigned int max_retry = 1000;
708 	struct dc_link *link = NULL;
709 
710 	if (mod_power == NULL)
711 		return false;
712 
713 	core_power = MOD_POWER_TO_CORE(mod_power);
714 
715 	if (core_power->num_entities == 0) {
716 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
717 							WPP_BIT_FLAG_Firmware_PsrState,
718 							"set psr enable: ERROR: stream=%p num_entities=%u",
719 							stream,
720 							core_power->num_entities);
721 		return false;
722 	}
723 
724 	if (psr_enable)	{
725 		unsigned int vsync_rate_hz;
726 		struct dc_static_screen_params params = {0};
727 
728 		vsync_rate_hz = (unsigned int)div_u64(div_u64((
729 				stream->timing.pix_clk_100hz * 100),
730 				stream->timing.v_total),
731 				stream->timing.h_total);
732 
733 		params.triggers.cursor_update = true;
734 		params.triggers.overlay_update = true;
735 		params.triggers.surface_update = true;
736 		params.num_frames = calc_psr_num_static_frames(vsync_rate_hz);
737 
738 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
739 							WPP_BIT_FLAG_Firmware_PsrState,
740 							"set psr enable: CALCS: pix_clk_100hz=%u v_total=%u h_total=%u vsync_rate_hz=%u num_frames=%u",
741 							stream->timing.pix_clk_100hz,
742 							stream->timing.v_total,
743 							stream->timing.h_total,
744 							vsync_rate_hz,
745 							params.num_frames);
746 
747 		dc_stream_set_static_screen_params(core_power->dc,
748 						   &stream, 1,
749 						   &params);
750 	}
751 
752 	link = dc_stream_get_link(stream);
753 
754 	if (!dc_link_set_psr_allow_active(link, &psr_enable, false, force_static, NULL)) {
755 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
756 							WPP_BIT_FLAG_Firmware_PsrState,
757 							"set psr enable: ERROR: stream=%p link=%p psr_enable=%d",
758 							stream,
759 							link,
760 							psr_enable);
761 		return false;
762 	}
763 
764 	if (wait == true) {
765 
766 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
767 							WPP_BIT_FLAG_Firmware_PsrState,
768 							"set psr enable: BEGIN WAIT: psr_enable=%d",
769 							(int)psr_enable);
770 
771 		for (retry_count = 0; retry_count <= max_retry; retry_count++) {
772 			dc_link_get_psr_state(link, &state);
773 			if (psr_enable) {
774 				if (state != PSR_STATE0 &&
775 						(!force_static || state == PSR_STATE3))
776 					break;
777 			} else {
778 				if (state == PSR_STATE0)
779 					break;
780 			}
781 			udelay(500);
782 		}
783 
784 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
785 							WPP_BIT_FLAG_Firmware_PsrState,
786 							"set psr enable: END WAIT: psr_enable=%d",
787 							(int)psr_enable);
788 
789 		/* assert if max retry hit */
790 		if (retry_count >= max_retry) {
791 			ASSERT(0);
792 			DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
793 								WPP_BIT_FLAG_Firmware_PsrState,
794 								"set psr enable: ERROR: retry_count=%u: Unexpectedly long wait for PSR state change.",
795 								retry_count);
796 		}
797 	} else {
798 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
799 							WPP_BIT_FLAG_Firmware_PsrState,
800 							"set psr enable: PSR state change initiated (wait=false): psr_enable=%d",
801 							(int)psr_enable);
802 	}
803 
804 	return true;
805 }
806 
807 bool mod_power_get_psr_event(struct mod_power *mod_power,
808 			struct dc_stream_state *stream,
809 			unsigned int *active_psr_events)
810 {
811 	struct core_power *core_power = NULL;
812 	unsigned int stream_index = 0;
813 
814 	if (mod_power == NULL)
815 		return false;
816 
817 	core_power = MOD_POWER_TO_CORE(mod_power);
818 
819 	if (core_power->num_entities == 0)
820 		return false;
821 
822 	stream_index = map_index_from_stream(core_power, stream);
823 
824 	if (!core_power->map[stream_index].caps->psr_version)
825 		return false;
826 
827 	*active_psr_events = core_power->map[stream_index].psr_events;
828 
829 	return true;
830 }
831 
832 bool mod_power_set_psr_event(struct mod_power *mod_power,
833 		struct dc_stream_state *stream, bool set_event,
834 		enum psr_event event, bool wait)
835 {
836 	struct core_power *core_power = NULL;
837 	unsigned int stream_index = 0;
838 	unsigned int active_psr_events = 0;
839 	bool psr_enable_request = false;
840 	bool force_static = false;
841 
842 	if (mod_power == NULL || stream == NULL)
843 		return false;
844 
845 	core_power = MOD_POWER_TO_CORE(mod_power);
846 	stream_index = map_index_from_stream(core_power, stream);
847 
848 	if (core_power->num_entities == 0) {
849 		DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
850 							WPP_BIT_FLAG_Firmware_PsrState,
851 							"mod_power set_psr_event: ERROR: stream=%p event=%d num_entities=%u",
852 							stream,
853 							(int)event,
854 							core_power->num_entities);
855 		return false;
856 	}
857 
858 	if (!core_power->map[stream_index].caps->psr_version)
859 		return false;
860 
861 	if (set_event)
862 		core_power->map[stream_index].psr_events |= event;
863 	else
864 		core_power->map[stream_index].psr_events &= ~event;
865 
866 	active_psr_events = core_power->map[stream_index].psr_events;
867 
868 	// ignore other events when we're in forced psr enabled state
869 	if (active_psr_events & psr_event_dynamic_display_switch &&
870 			event != psr_event_dynamic_display_switch)
871 		return false;
872 
873 	// ignore other events when we're in forced psr enabled state
874 	if (active_psr_events & psr_event_os_override_hold &&
875 			event != psr_event_os_override_hold)
876 		return false;
877 
878 	// ignore other events when we're in forced psr enabled state
879 	// dds events need to be processed while in dynamic_link_rate_control
880 	if (active_psr_events & psr_event_dynamic_link_rate_control &&
881 			event != psr_event_dynamic_link_rate_control &&
882 			event != psr_event_dds_defer_stream_enable &&
883 			event != psr_event_dynamic_display_switch)
884 		return false;
885 
886 	if (active_psr_events & (psr_event_test_harness_disable_psr | psr_event_os_request_disable))
887 		psr_enable_request = false;
888 	else if (active_psr_events & psr_event_pause)
889 		psr_enable_request = false;
890 	else if (active_psr_events & psr_event_test_harness_enable_psr)
891 		psr_enable_request = true;
892 	else if (active_psr_events & psr_event_dynamic_display_switch) {
893 		psr_enable_request = true;
894 		force_static = true;
895 	} else if (active_psr_events & psr_event_dynamic_link_rate_control) {
896 		psr_enable_request = true;
897 		force_static = true;
898 	} else if (active_psr_events & psr_event_edp_panel_off_disable_psr)
899 		psr_enable_request = false;
900 	else if (active_psr_events & (psr_event_hw_programming |
901 			psr_event_defer_enable |
902 			psr_event_dds_defer_stream_enable |
903 			psr_event_vrr_transition |
904 			psr_event_immediate_flip))
905 		psr_enable_request = false;
906 	else if (active_psr_events & psr_event_big_screen_video)
907 		psr_enable_request = true;
908 	else if (active_psr_events & psr_event_full_screen)
909 		psr_enable_request = false;
910 	else if (active_psr_events & psr_event_mpo_video_selective_update)
911 		psr_enable_request = true;
912 	else if (active_psr_events & psr_event_vsync)
913 		psr_enable_request = false;
914 	else if (active_psr_events & psr_event_crc_window_active)
915 		psr_enable_request = false;
916 	else
917 		psr_enable_request = true;
918 
919 	DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE,
920 						WPP_BIT_FLAG_Firmware_PsrState,
921 						"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",
922 						(int)core_power->map[stream_index].psr_enabled,
923 						(int)set_event,
924 						(unsigned int)event,
925 						(unsigned int)core_power->map[stream_index].psr_events,
926 						(int)psr_enable_request);
927 	mod_power_psr_set_power_opt(mod_power, stream, active_psr_events, psr_enable_request);
928 
929 	if (core_power->map[stream_index].psr_enabled != psr_enable_request || force_static) {
930 		if (set_psr_enable(mod_power, stream, psr_enable_request, wait, force_static)) {
931 			core_power->map[stream_index].psr_enabled = psr_enable_request;
932 		}
933 	}
934 
935 	return true;
936 }
937 
938 bool mod_power_get_psr_state(struct mod_power *mod_power,
939 		const struct dc_stream_state *stream,
940 		enum dc_psr_state *state)
941 {
942 	struct core_power *core_power = NULL;
943 	const struct dc_link *link = NULL;
944 
945 	if (!stream)
946 		return false;
947 
948 	if (mod_power == NULL)
949 		return false;
950 
951 	core_power = MOD_POWER_TO_CORE(mod_power);
952 
953 	if (core_power->num_entities == 0)
954 		return false;
955 
956 	link = dc_stream_get_link(stream);
957 	return dc_link_get_psr_state(link, state);
958 }
959 
960 bool mod_power_get_psr_enabled_status(struct mod_power *mod_power,
961 		const struct dc_stream_state *stream,
962 		bool *psr_enabled)
963 {
964 	struct core_power *core_power = NULL;
965 	unsigned int stream_index = 0;
966 
967 	if (mod_power == NULL)
968 		return false;
969 
970 	core_power = MOD_POWER_TO_CORE(mod_power);
971 
972 	if (core_power->num_entities == 0)
973 		return false;
974 
975 	stream_index = map_index_from_stream(core_power, stream);
976 
977 	if (!core_power->map[stream_index].caps->psr_version)
978 		return false;
979 
980 	*psr_enabled = core_power->map[stream_index].psr_enabled;
981 
982 	return true;
983 }
984 
985 void mod_power_psr_residency(struct mod_power *mod_power,
986 		const struct dc_stream_state *stream,
987 		unsigned int *residency,
988 		const uint8_t mode)
989 {
990 	struct core_power *core_power = NULL;
991 	const struct dc_link *link = NULL;
992 
993 	if (!stream)
994 		return;
995 
996 	if (mod_power == NULL)
997 		return;
998 
999 	core_power = MOD_POWER_TO_CORE(mod_power);
1000 
1001 	if (core_power->num_entities == 0)
1002 		return;
1003 
1004 	link = dc_stream_get_link(stream);
1005 
1006 	if (link != NULL)
1007 		link->dc->link_srv->edp_get_psr_residency(link, residency, mode);
1008 }
1009 bool mod_power_psr_get_active_psr_events(struct mod_power *mod_power,
1010 		const struct dc_stream_state *stream, unsigned int *active_psr_events)
1011 {
1012 	struct core_power *core_power = NULL;
1013 	unsigned int stream_index = 0;
1014 
1015 	if (!stream)
1016 		return false;
1017 
1018 	if (mod_power == NULL)
1019 		return false;
1020 
1021 	if (active_psr_events == NULL)
1022 		return false;
1023 
1024 	core_power = MOD_POWER_TO_CORE(mod_power);
1025 
1026 	if (core_power->num_entities == 0)
1027 		return false;
1028 
1029 	stream_index = map_index_from_stream(core_power, stream);
1030 
1031 	*active_psr_events = core_power->map[stream_index].psr_events;
1032 	return true;
1033 }
1034 
1035 bool mod_power_psr_set_sink_vtotal_in_psr_active(struct mod_power *mod_power,
1036 		const struct dc_stream_state *stream,
1037 		uint16_t psr_vtotal_idle,
1038 		uint16_t psr_vtotal_su)
1039 {
1040 	struct core_power *core_power = NULL;
1041 	unsigned int stream_index = 0;
1042 	const struct dc_link *link = NULL;
1043 
1044 	if (!stream)
1045 		return false;
1046 
1047 	if (mod_power == NULL)
1048 		return false;
1049 
1050 	core_power = MOD_POWER_TO_CORE(mod_power);
1051 
1052 	if (core_power->num_entities == 0)
1053 		return false;
1054 
1055 	stream_index = map_index_from_stream(core_power, stream);
1056 
1057 	if (!core_power->map[stream_index].caps->psr_version)
1058 		return false;
1059 
1060 	link = dc_stream_get_link(stream);
1061 
1062 	return link->dc->link_srv->edp_set_sink_vtotal_in_psr_active(
1063 			link, psr_vtotal_idle, psr_vtotal_su);
1064 }
1065 
1066 static bool mod_power_set_replay_active(struct dc_stream_state *stream,
1067 	bool replay_active,
1068 	bool wait,
1069 	bool force_static)
1070 {
1071 	uint64_t state;
1072 	unsigned int retry_count;
1073 	const unsigned int max_retry = 1000;
1074 	struct dc_link *link = NULL;
1075 
1076 	if (!stream)
1077 		return false;
1078 
1079 	link = dc_stream_get_link(stream);
1080 
1081 	if (!link)
1082 		return false;
1083 
1084 	if (!dc_link_set_replay_allow_active(link, &replay_active, false, force_static, NULL))
1085 		return false;
1086 
1087 	if (wait == true) {
1088 
1089 		for (retry_count = 0; retry_count <= max_retry; retry_count++) {
1090 			dc_link_get_replay_state(link, &state);
1091 			if (replay_active) {
1092 				if (state != REPLAY_STATE_0 &&
1093 					(!force_static || state == REPLAY_STATE_3))
1094 					break;
1095 			} else {
1096 				if (state == REPLAY_STATE_0)
1097 					break;
1098 			}
1099 			udelay(500);
1100 		}
1101 
1102 		/* assert if max retry hit */
1103 		if (retry_count >= max_retry)
1104 			ASSERT(0);
1105 	} else {
1106 		/* To-do: Add trace log */
1107 	}
1108 
1109 	return true;
1110 }
1111 
1112 static unsigned int mod_power_replay_setup_power_opt(struct dc_link *link,
1113 	unsigned int active_replay_events, bool is_ultra_sleep_mode)
1114 {
1115 	unsigned int power_opt = 0;
1116 
1117 	if (is_ultra_sleep_mode) {
1118 		/* Static Screen */
1119 		power_opt |= (replay_power_opt_smu_opt_static_screen | replay_power_opt_z10_static_screen);
1120 	} else if (active_replay_events & replay_event_test_harness_ultra_sleep) {
1121 		power_opt |= replay_power_opt_z10_static_screen;
1122 	}
1123 
1124 	/* replay_power_opt_flag is a configuration parameter into the module that determines
1125 	 * which optimizations to enable during replay
1126 	 */
1127 	power_opt &= link->replay_settings.config.replay_power_opt_supported;
1128 
1129 	return power_opt;
1130 }
1131 
1132 static bool mod_power_replay_set_power_opt(struct mod_power *mod_power,
1133 	struct dc_stream_state *stream,
1134 	unsigned int active_replay_events,
1135 	bool is_ultra_sleep_mode)
1136 {
1137 	(void)mod_power;
1138 	struct dc_link *link = NULL;
1139 	unsigned int power_opt = 0;
1140 
1141 	if (!stream)
1142 		return false;
1143 
1144 	link = dc_stream_get_link(stream);
1145 
1146 	if (!link || !link->replay_settings.replay_feature_enabled)
1147 		return false;
1148 
1149 	power_opt = mod_power_replay_setup_power_opt(link, active_replay_events, is_ultra_sleep_mode);
1150 
1151 	if (!dc_link_set_replay_allow_active(link, NULL, false, false, &power_opt))
1152 		return false;
1153 
1154 	return true;
1155 }
1156 
1157 bool mod_power_get_replay_event(struct mod_power *mod_power,
1158 	struct dc_stream_state *stream,
1159 	unsigned int *active_replay_events)
1160 {
1161 	struct core_power *core_power = NULL;
1162 	unsigned int stream_index = 0;
1163 
1164 	if (mod_power == NULL)
1165 		return false;
1166 
1167 	core_power = MOD_POWER_TO_CORE(mod_power);
1168 
1169 	if (core_power->num_entities == 0)
1170 		return false;
1171 
1172 	stream_index = map_index_from_stream(core_power, stream);
1173 
1174 	*active_replay_events = core_power->map[stream_index].replay_events;
1175 
1176 	return true;
1177 }
1178 
1179 static bool mod_power_update_replay_active_status(unsigned int active_replay_events,
1180 	struct dc_link *link, uint32_t *coasting_vtotal, bool *is_full_screen_video, bool *is_ultra_sleep_mode, uint16_t *frame_skip_number, bool *is_video_playback)
1181 {
1182 	if (!link || !coasting_vtotal || !is_full_screen_video || !is_video_playback)
1183 		return false;
1184 
1185 	// Check coasting_vtotal_table has been updated.
1186 	if (!link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_STATIC]
1187 		|| !link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM])
1188 		return false;
1189 
1190 	unsigned int replay_enable_option =
1191 		link->replay_settings.config.replay_enable_option;
1192 
1193 	/* TODO: To support test harness and DDS event */
1194 
1195 	*coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM];
1196 	ASSERT(link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM] <= 0xFFFF);
1197 	*frame_skip_number = (uint16_t)link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM];
1198 
1199 	link->replay_settings.config.replay_timing_sync_supported = false;
1200 
1201 	*is_full_screen_video = false;
1202 
1203 	*is_ultra_sleep_mode = false;
1204 
1205 	*is_video_playback = false;
1206 
1207 	/* DSAT test scenario */
1208 	if (active_replay_events & replay_event_test_harness_mode) {
1209 		if (link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS])
1210 			*coasting_vtotal =
1211 				link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS];
1212 		if (link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]) {
1213 			ASSERT(link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS] <= 0xFFFF);
1214 			*frame_skip_number =
1215 				(uint16_t)link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS];
1216 		}
1217 
1218 		/* During the ultra sleep mode testing, disable the timing sync in short vblank mode */
1219 		if (active_replay_events & (replay_event_test_harness_enable_replay)) {
1220 			if ((active_replay_events & replay_event_test_harness_ultra_sleep) &&
1221 				  !link->replay_settings.config.replay_support_fast_resync_in_ultra_sleep_mode)
1222 				link->replay_settings.config.replay_timing_sync_supported = false;
1223 			return true;
1224 		} else
1225 			return false;
1226 	} else if (active_replay_events & (replay_event_test_harness_enable_replay)) {
1227 		if (link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS])
1228 			*coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS];
1229 		if (link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]) {
1230 			uint32_t frame_skip_val =
1231 				link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS];
1232 
1233 			ASSERT(frame_skip_val <= 0xFFFF);
1234 			*frame_skip_number = (uint16_t)frame_skip_val;
1235 		}
1236 
1237 		/* During the ultra sleep mode testing, disable the timing sync in short vblank mode */
1238 		if ((active_replay_events & replay_event_test_harness_ultra_sleep) &&
1239 			  !link->replay_settings.config.replay_support_fast_resync_in_ultra_sleep_mode)
1240 			link->replay_settings.config.replay_timing_sync_supported = false;
1241 		return true;
1242 	} else if (active_replay_events & (replay_event_test_harness_disable_replay | replay_event_os_request_disable)) {
1243 		// set last set coasting vtotal
1244 		if (link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS])
1245 			*coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS];
1246 		if (link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]) {
1247 			uint32_t frame_skip_val =
1248 				link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS];
1249 
1250 			ASSERT(frame_skip_val <= 0xFFFF);
1251 			*frame_skip_number = (uint16_t)frame_skip_val;
1252 		}
1253 		return false;
1254 	}
1255 
1256 	/* Inactive conditions */
1257 	if (active_replay_events & (replay_event_edp_panel_off_disable_psr |
1258 			replay_event_hw_programming |
1259 			replay_event_vrr |
1260 			replay_event_immediate_flip |
1261 			replay_event_prepare_vtotal |
1262 			replay_event_vrr_transition |
1263 			replay_event_pause |
1264 			replay_event_disable_replay_while_DPMS |
1265 			replay_event_sleep_resume |
1266 			replay_event_disable_in_AC |
1267 			replay_event_disable_replay_while_detect_display |
1268 			replay_event_infopacket |
1269 			replay_event_crc_window_active))
1270 		return false;
1271 
1272 	// Full screen scenario
1273 	if (active_replay_events & replay_event_full_screen) {
1274 		if (!(replay_enable_option & pr_enable_option_full_screen))
1275 			return false;
1276 	}
1277 
1278 	/* Full screen video scenario */
1279 	if (active_replay_events & replay_event_big_screen_video) {
1280 
1281 		link->replay_settings.config.replay_timing_sync_supported = false;
1282 
1283 		if (replay_enable_option & pr_enable_option_full_screen_video_coasting) {
1284 			unsigned int fsn_vid =
1285 				link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_FULL_SCREEN_VIDEO];
1286 
1287 			*coasting_vtotal =
1288 				link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_FULL_SCREEN_VIDEO];
1289 			ASSERT(fsn_vid <= 0xFFFF);
1290 			*frame_skip_number = (uint16_t)fsn_vid;
1291 		}
1292 
1293 		*is_video_playback = true;
1294 
1295 		if ((replay_enable_option & pr_enable_option_full_screen_video) &&
1296 			(replay_enable_option & pr_enable_option_full_screen_video_coasting)) {
1297 			*is_full_screen_video = true;
1298 			return true;
1299 		} else
1300 			return false;
1301 	}
1302 
1303 	/* MPO video scenario
1304 	 * Some of the cases may contain a full screen UI layer in MPO video scenario which is
1305 	 * not the expected case to enable Replay.
1306 	 */
1307 	if ((active_replay_events & replay_event_mpo_video_selective_update) &&
1308 		!(active_replay_events & replay_event_full_screen)) {
1309 
1310 		link->replay_settings.config.replay_timing_sync_supported = false;
1311 
1312 		if (replay_enable_option & pr_enable_option_mpo_video_coasting) {
1313 			*coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM];
1314 			{
1315 				uint32_t frame_skip_val =
1316 					link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM];
1317 
1318 				ASSERT(frame_skip_val <= 0xFFFF);
1319 				*frame_skip_number = (uint16_t)frame_skip_val;
1320 			}
1321 		}
1322 
1323 		*is_video_playback = true;
1324 
1325 		if (replay_enable_option & pr_enable_option_mpo_video)
1326 			return true;
1327 		else
1328 			return false;
1329 	}
1330 
1331 	/* Static screen scenario */
1332 	if (!(active_replay_events & replay_event_vsync)) {
1333 
1334 		if (replay_enable_option & pr_enable_option_static_screen_coasting) {
1335 			// Do not adjust eDP refresh rate if static screen + normal sleep mode
1336 			if ((!(link->replay_settings.config.replay_power_opt_supported &
1337 				replay_power_opt_z10_static_screen)) ||
1338 				(active_replay_events & replay_event_cursor_updating)) {
1339 				// normal sleep mode
1340 				*coasting_vtotal =
1341 					link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM];
1342 				{
1343 					uint32_t frame_skip_val =
1344 						link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM];
1345 
1346 					ASSERT(frame_skip_val <= 0xFFFF);
1347 					*frame_skip_number = (uint16_t)frame_skip_val;
1348 				}
1349 			} else {
1350 				// ultra sleep mode
1351 				*coasting_vtotal =
1352 					link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_STATIC];
1353 				{
1354 					uint32_t frame_skip_val =
1355 						link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_STATIC];
1356 
1357 					ASSERT(frame_skip_val <= 0xFFFF);
1358 					*frame_skip_number = (uint16_t)frame_skip_val;
1359 				}
1360 				*is_ultra_sleep_mode = true;
1361 			}
1362 		}
1363 
1364 		if (replay_enable_option & pr_enable_option_static_screen) {
1365 			if (!link->replay_settings.config.replay_support_fast_resync_in_ultra_sleep_mode)
1366 				link->replay_settings.config.replay_timing_sync_supported = false;
1367 			return true;
1368 		} else
1369 			return false;
1370 	}
1371 
1372 	/* General UI scenario */
1373 	if (active_replay_events & replay_event_general_ui) {
1374 		if (replay_enable_option & pr_enable_option_general_ui)
1375 			return true;
1376 		else
1377 			return false;
1378 	}
1379 
1380 	return false;
1381 }
1382 
1383 bool mod_power_replay_set_coasting_vtotal(struct mod_power *mod_power,
1384 	const struct dc_stream_state *stream,
1385 	uint32_t coasting_vtotal,
1386 	uint16_t frame_skip_number)
1387 {
1388 	struct core_power *core_power = NULL;
1389 	struct dc_link *link = NULL;
1390 
1391 	if (!stream)
1392 		return false;
1393 
1394 	link = dc_stream_get_link(stream);
1395 	if (!link || !link->replay_settings.replay_feature_enabled)
1396 		return false;
1397 
1398 	if (mod_power == NULL)
1399 		return false;
1400 
1401 	core_power = MOD_POWER_TO_CORE(mod_power);
1402 
1403 	if (core_power->num_entities == 0)
1404 		return false;
1405 
1406 	return link->dc->link_srv->edp_set_coasting_vtotal(link, coasting_vtotal, frame_skip_number);
1407 }
1408 
1409 void mod_power_replay_set_timing_sync_supported(struct mod_power *mod_power,
1410 	const struct dc_stream_state *stream)
1411 {
1412 	struct core_power *core_power = NULL;
1413 	struct dc_link *link = NULL;
1414 	unsigned int stream_index = 0;
1415 	union dmub_replay_cmd_set cmd_data = { 0 };
1416 
1417 	if (!stream || mod_power == NULL)
1418 		return;
1419 
1420 	core_power = MOD_POWER_TO_CORE(mod_power);
1421 	if (core_power->num_entities == 0)
1422 		return;
1423 
1424 	stream_index = map_index_from_stream(core_power, stream);
1425 	if (stream_index > core_power->num_entities) //invalid index
1426 		return;
1427 
1428 	link = dc_stream_get_link(stream);
1429 	if (!link || !link->replay_settings.replay_feature_enabled)
1430 		return;
1431 
1432 	cmd_data.sync_data.timing_sync_supported = link->replay_settings.config.replay_timing_sync_supported;
1433 
1434 	link->dc->link_srv->edp_send_replay_cmd(link, Replay_Set_Timing_Sync_Supported,
1435 		&cmd_data);
1436 }
1437 
1438 void mod_power_replay_disabled_adaptive_sync_sdp(struct mod_power *mod_power,
1439 	const struct dc_stream_state *stream, bool force_disabled)
1440 {
1441 	struct core_power *core_power = NULL;
1442 	struct dc_link *link = NULL;
1443 	unsigned int stream_index = 0;
1444 	union dmub_replay_cmd_set cmd_data = { 0 };
1445 
1446 	if (!stream || mod_power == NULL)
1447 		return;
1448 
1449 	core_power = MOD_POWER_TO_CORE(mod_power);
1450 	if (core_power->num_entities == 0)
1451 		return;
1452 
1453 	stream_index = map_index_from_stream(core_power, stream);
1454 	if (stream_index > core_power->num_entities) //invalid index
1455 		return;
1456 
1457 	link = dc_stream_get_link(stream);
1458 	if (!link || !link->replay_settings.replay_feature_enabled)
1459 		return;
1460 
1461 	cmd_data.disabled_adaptive_sync_sdp_data.force_disabled = force_disabled;
1462 
1463 	link->dc->link_srv->edp_send_replay_cmd(link, Replay_Disabled_Adaptive_Sync_SDP,
1464 		&cmd_data);
1465 }
1466 
1467 static void mod_power_replay_set_general_cmd(struct mod_power *mod_power,
1468 	const struct dc_stream_state *stream,
1469 	const enum dmub_cmd_replay_general_subtype general_cmd_type,
1470 	const uint32_t param1, const uint32_t param2)
1471 {
1472 	struct core_power *core_power = NULL;
1473 	struct dc_link *link = NULL;
1474 	unsigned int stream_index = 0;
1475 	union dmub_replay_cmd_set cmd_data = { 0 };
1476 
1477 	if (!stream || mod_power == NULL)
1478 		return;
1479 
1480 	core_power = MOD_POWER_TO_CORE(mod_power);
1481 	if (core_power->num_entities == 0)
1482 		return;
1483 
1484 	stream_index = map_index_from_stream(core_power, stream);
1485 	if (stream_index > core_power->num_entities) //invalid index
1486 		return;
1487 
1488 	link = dc_stream_get_link(stream);
1489 	if (!link || !link->replay_settings.replay_feature_enabled)
1490 		return;
1491 
1492 	cmd_data.set_general_cmd_data.subtype = general_cmd_type;
1493 	cmd_data.set_general_cmd_data.param1 = param1;
1494 	cmd_data.set_general_cmd_data.param2 = param2;
1495 	link->dc->link_srv->edp_send_replay_cmd(link, Replay_Set_General_Cmd,
1496 		&cmd_data);
1497 }
1498 
1499 void mod_power_replay_disabled_desync_error_detection(struct mod_power *mod_power,
1500 	const struct dc_stream_state *stream,  bool force_disabled)
1501 {
1502 	mod_power_replay_set_general_cmd(mod_power, stream,
1503 			REPLAY_GENERAL_CMD_DISABLED_DESYNC_ERROR_DETECTION,
1504 			force_disabled, 0);
1505 }
1506 
1507 static void mod_power_replay_set_pseudo_vtotal(struct mod_power *mod_power,
1508 	const struct dc_stream_state *stream, uint16_t vtotal)
1509 {
1510 	struct core_power *core_power = NULL;
1511 	struct dc_link *link = NULL;
1512 	unsigned int stream_index = 0;
1513 	union dmub_replay_cmd_set cmd_data = { 0 };
1514 
1515 	if (!stream || mod_power == NULL)
1516 		return;
1517 
1518 	core_power = MOD_POWER_TO_CORE(mod_power);
1519 	if (core_power->num_entities == 0)
1520 		return;
1521 
1522 	stream_index = map_index_from_stream(core_power, stream);
1523 	if (stream_index > core_power->num_entities) //invalid index
1524 		return;
1525 
1526 	link = dc_stream_get_link(stream);
1527 	if (!link || !link->replay_settings.replay_feature_enabled)
1528 		return;
1529 
1530 	cmd_data.pseudo_vtotal_data.vtotal = vtotal;
1531 
1532 	if (link->replay_settings.last_pseudo_vtotal != vtotal) {
1533 		link->replay_settings.last_pseudo_vtotal = vtotal;
1534 		link->dc->link_srv->edp_send_replay_cmd(link, Replay_Set_Pseudo_VTotal, &cmd_data);
1535 	}
1536 }
1537 
1538 static void mod_power_update_error_status(struct mod_power *mod_power,
1539 	const struct dc_stream_state *stream)
1540 {
1541 	struct dc_link *link = NULL;
1542 	union replay_debug_flags *pDebug = NULL;
1543 
1544 	if (mod_power == NULL || stream == NULL)
1545 		return;
1546 
1547 	link = dc_stream_get_link(stream);
1548 
1549 	if (!link)
1550 		return;
1551 
1552 	pDebug = (union replay_debug_flags *)&link->replay_settings.config.debug_flags;
1553 
1554 	if (0 == pDebug->bitfields.enable_visual_confirm_debug)
1555 		return;
1556 
1557 	mod_power_replay_set_general_cmd(mod_power, stream,
1558 		REPLAY_GENERAL_CMD_UPDATE_ERROR_STATUS,
1559 		link->replay_settings.config.replay_error_status.raw, 0);
1560 }
1561 
1562 void mod_power_set_low_rr_activate(struct mod_power *mod_power,
1563 	const struct dc_stream_state *stream, bool low_rr_supported)
1564 {
1565 	struct dc_link *link = NULL;
1566 
1567 	if (mod_power == NULL || stream == NULL)
1568 		return;
1569 
1570 	link = dc_stream_get_link(stream);
1571 
1572 	if (!link)
1573 		return;
1574 
1575 	mod_power_replay_set_general_cmd(mod_power, stream,
1576 		REPLAY_GENERAL_CMD_SET_LOW_RR_ACTIVATE,
1577 		low_rr_supported, 0);
1578 }
1579 
1580 void mod_power_set_video_conferencing_activate(struct mod_power *mod_power,
1581 	const struct dc_stream_state *stream, bool video_conferencing_activate)
1582 {
1583 	struct dc_link *link = NULL;
1584 
1585 	if (mod_power == NULL || stream == NULL)
1586 		return;
1587 
1588 	link = dc_stream_get_link(stream);
1589 	if (!link || !link->replay_settings.replay_feature_enabled)
1590 		return;
1591 
1592 	mod_power_replay_set_general_cmd(mod_power, stream,
1593 		REPLAY_GENERAL_CMD_VIDEO_CONFERENCING,
1594 		video_conferencing_activate, 0);
1595 }
1596 
1597 void mod_power_set_coasting_vtotal_without_frame_update(struct mod_power *mod_power,
1598 	const struct dc_stream_state *stream, uint32_t coasting_vtotal)
1599 {
1600 	struct dc_link *link = NULL;
1601 
1602 	if (mod_power == NULL || stream == NULL)
1603 		return;
1604 
1605 	link = dc_stream_get_link(stream);
1606 	if (!link || !link->replay_settings.replay_feature_enabled)
1607 		return;
1608 
1609 	mod_power_replay_set_general_cmd(mod_power, stream,
1610 		REPLAY_GENERAL_CMD_SET_COASTING_VTOTAL_WITHOUT_FRAME_UPDATE,
1611 		coasting_vtotal, 0);
1612 }
1613 
1614 void mod_power_set_replay_continuously_resync(struct mod_power *mod_power,
1615 	const struct dc_stream_state *stream, bool enable)
1616 {
1617 	struct dc_link *link = NULL;
1618 
1619 	if (mod_power == NULL || stream == NULL)
1620 		return;
1621 
1622 	link = dc_stream_get_link(stream);
1623 	if (!link || !link->replay_settings.replay_feature_enabled)
1624 		return;
1625 
1626 	mod_power_replay_set_general_cmd(mod_power, stream,
1627 		REPLAY_GENERAL_CMD_SET_CONTINUOUSLY_RESYNC,
1628 		enable, 0);
1629 }
1630 
1631 void mod_power_set_live_capture_with_cvt_activate(struct mod_power *mod_power,
1632 	const struct dc_stream_state *stream, bool live_capture_with_cvt_activate)
1633 {
1634 	struct dc_link *link = NULL;
1635 
1636 	if (mod_power == NULL || stream == NULL)
1637 		return;
1638 
1639 	link = dc_stream_get_link(stream);
1640 	if (!link || !link->replay_settings.replay_feature_enabled)
1641 		return;
1642 
1643 	// Check if LIVE_CAPTURE_WITH_CVT bit is enabled in DalRegKey_ReplayOptimization
1644 	if (!link->replay_settings.config.replay_optimization.bits.LIVE_CAPTURE_WITH_CVT)
1645 		return;
1646 
1647 	if (link->replay_settings.config.live_capture_with_cvt_activated != live_capture_with_cvt_activate) {
1648 		link->replay_settings.config.live_capture_with_cvt_activated = live_capture_with_cvt_activate;
1649 		mod_power_replay_set_general_cmd(mod_power, stream,
1650 			REPLAY_GENERAL_CMD_LIVE_CAPTURE_WITH_CVT,
1651 			live_capture_with_cvt_activate, 0);
1652 	}
1653 }
1654 
1655 bool mod_power_set_replay_event(struct mod_power *mod_power,
1656 	struct dc_stream_state *stream, bool set_event,
1657 	enum replay_event event, bool wait_for_disable)
1658 {
1659 	struct core_power *core_power = NULL;
1660 	struct dc_link *link = NULL;
1661 	unsigned int stream_index = 0;
1662 	unsigned int active_replay_events = 0;
1663 	bool replay_active_request = false;
1664 	bool force_static = false;
1665 	uint32_t coasting_vtotal = 0;
1666 	bool current_timing_sync_status = false;
1667 	bool is_full_screen_video = false;
1668 	bool is_ultra_sleep_mode = false;
1669 	unsigned int sink_duration_us = 0;
1670 	bool low_rr_active = false;
1671 	uint16_t frame_skip_number = 0;
1672 	bool is_video_playback = false;
1673 
1674 	if (!stream)
1675 		return false;
1676 
1677 	if (mod_power == NULL)
1678 		return false;
1679 
1680 	core_power = MOD_POWER_TO_CORE(mod_power);
1681 
1682 	if (core_power->num_entities == 0)
1683 		return false;
1684 
1685 	stream_index = map_index_from_stream(core_power, stream);
1686 
1687 	if (set_event)
1688 		core_power->map[stream_index].replay_events |= event;
1689 	else
1690 		core_power->map[stream_index].replay_events &= ~event;
1691 
1692 	link = dc_stream_get_link(stream);
1693 	if (!link || !link->replay_settings.replay_feature_enabled)
1694 		return false;
1695 
1696 	if ((core_power->map[stream_index].replay_events & replay_event_disable_replay_while_switching_mux) != 0)
1697 		return false;
1698 
1699 	if ((core_power->map[stream_index].replay_events & replay_event_os_override_hold) != 0)
1700 		return false;
1701 
1702 	active_replay_events = core_power->map[stream_index].replay_events;
1703 
1704 	current_timing_sync_status =
1705 		link->replay_settings.config.replay_timing_sync_supported;
1706 
1707 	replay_active_request = mod_power_update_replay_active_status(active_replay_events,
1708 		link, &coasting_vtotal, &is_full_screen_video, &is_ultra_sleep_mode, &frame_skip_number, &is_video_playback);
1709 
1710 	if (is_full_screen_video)
1711 		mod_power_replay_set_pseudo_vtotal(mod_power, stream,
1712 			link->replay_settings.low_rr_full_screen_video_pseudo_vtotal);
1713 	else
1714 		mod_power_replay_set_pseudo_vtotal(mod_power, stream, 0);
1715 
1716 	//If timing_sync_status change, then re-enabled set timing_sync_supported value and re-enabled replay
1717 	if (current_timing_sync_status != link->replay_settings.config.replay_timing_sync_supported)
1718 		mod_power_replay_set_timing_sync_supported(mod_power, stream);
1719 
1720 	if (link->replay_settings.config.low_rr_supported) {
1721 		sink_duration_us =
1722 			(unsigned int)(div_u64(((unsigned long long)(coasting_vtotal)
1723 				* 10000) * stream->timing.h_total,
1724 					stream->timing.pix_clk_100hz));
1725 		low_rr_active = sink_duration_us < LOW_REFRESH_RATE_DURATION_US_UPPER_BOUND ? false : true;
1726 		if (low_rr_active != link->replay_settings.config.low_rr_activated) {
1727 			mod_power_set_low_rr_activate(mod_power, stream, low_rr_active);
1728 			link->replay_settings.config.low_rr_activated = low_rr_active;
1729 		}
1730 	}
1731 
1732 	// The function return fail when
1733 	// 1. DMUB function is not support (for backward compatible).
1734 	// 2. active_replay_events or coasting_vtotal is not updated in the same time
1735 	if (!mod_power_replay_set_power_opt_and_coasting_vtotal(mod_power,
1736 		stream, active_replay_events, coasting_vtotal, is_ultra_sleep_mode, frame_skip_number)) {
1737 		if (!mod_power_replay_set_power_opt(mod_power, stream, active_replay_events, is_ultra_sleep_mode))
1738 			return false;
1739 
1740 		if (!mod_power_replay_set_coasting_vtotal(mod_power, stream, coasting_vtotal, frame_skip_number))
1741 			return false;
1742 	}
1743 
1744 	mod_power_set_live_capture_with_cvt_activate(mod_power, stream, is_video_playback);
1745 
1746 	mod_power_update_error_status(mod_power, stream);
1747 
1748 	// If Replay is going to be enable (No matter is disable -> enable or enable -> enable), we don't need to wait.
1749 	// If Replay is going to be disable
1750 	//     if disable -> disable
1751 	//         -> Replay DMUB state should be state 0.
1752 	//            So no matter wait_for_disable is true or not, it should makes no difference.
1753 	//     if enable -> disable -> We should wait if wait_for_disable is true.
1754 	if (replay_active_request)
1755 		wait_for_disable = false;
1756 
1757 	if (!mod_power_set_replay_active(stream, replay_active_request, wait_for_disable, force_static))
1758 		return false;
1759 
1760 	return true;
1761 }
1762 
1763 bool mod_power_get_replay_active_status(const struct dc_stream_state *stream,
1764 	bool *replay_active)
1765 {
1766 	const struct dc_link *link = NULL;
1767 
1768 	if (!stream)
1769 		return false;
1770 
1771 	link = dc_stream_get_link(stream);
1772 	*replay_active = link->replay_settings.replay_allow_active;
1773 
1774 	return true;
1775 }
1776 
1777 void mod_power_replay_residency(const struct dc_stream_state *stream,
1778 	unsigned int *residency, const bool is_start, const bool is_alpm)
1779 {
1780 	const struct dc_link *link = NULL;
1781 	enum pr_residency_mode mode;
1782 
1783 	if (!stream)
1784 		return;
1785 
1786 	link = dc_stream_get_link(stream);
1787 
1788 	if (is_alpm)
1789 		mode = PR_RESIDENCY_MODE_ALPM;
1790 	else
1791 		mode = PR_RESIDENCY_MODE_PHY;
1792 
1793 	if (link && link->dc && link->dc->link_srv)
1794 		link->dc->link_srv->edp_replay_residency(link, residency, is_start, mode);
1795 }
1796 
1797 bool mod_power_replay_set_power_opt_and_coasting_vtotal(struct mod_power *mod_power,
1798 	const struct dc_stream_state *stream, unsigned int active_replay_events, uint32_t coasting_vtotal,
1799 	bool is_ultra_sleep_mode, uint16_t frame_skip_number)
1800 {
1801 	struct core_power *core_power = NULL;
1802 	struct dc_link *link = NULL;
1803 	unsigned int power_opt = 0;
1804 
1805 	if (!stream)
1806 		return false;
1807 
1808 	if (mod_power == NULL)
1809 		return false;
1810 
1811 	core_power = MOD_POWER_TO_CORE(mod_power);
1812 
1813 	if (core_power->num_entities == 0)
1814 		return false;
1815 
1816 	link = dc_stream_get_link(stream);
1817 
1818 	if (!link || !link->replay_settings.replay_feature_enabled)
1819 		return false;
1820 
1821 	power_opt = mod_power_replay_setup_power_opt(link, active_replay_events, is_ultra_sleep_mode);
1822 
1823 	return link->dc->link_srv->edp_set_replay_power_opt_and_coasting_vtotal(link, &power_opt, coasting_vtotal, frame_skip_number);
1824 }
1825 
1826 
1827 
1828 
1829 
1830