1 /*
2  * Copyright 2022 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 /* FILE POLICY AND INTENDED USAGE:
27  * This file implements retrieval and configuration of eDP panel features such
28  * as PSR and ABM and it also manages specs defined eDP panel power sequences.
29  */
30 
31 #include "link_edp_panel_control.h"
32 #include "link_dpcd.h"
33 #include "link_dp_capability.h"
34 #include "dm_helpers.h"
35 #include "dal_asic_id.h"
36 #include "link_dp_phy.h"
37 #include "dce/dmub_psr.h"
38 #include "dc/dc_dmub_srv.h"
39 #include "dce/dmub_replay.h"
40 #include "abm.h"
41 #include "resource.h"
42 #define DC_LOGGER \
43 	link->ctx->logger
44 #define DC_LOGGER_INIT(logger)
45 
46 #define DP_SINK_PR_ENABLE_AND_CONFIGURATION		0x37B
47 
48 /* Travis */
49 static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT";
50 /* Nutmeg */
51 static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA";
52 
dp_set_panel_mode(struct dc_link * link,enum dp_panel_mode panel_mode)53 void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
54 {
55 	union dpcd_edp_config edp_config_set;
56 	bool panel_mode_edp = false;
57 	enum dc_status result;
58 
59 	memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
60 
61 	switch (panel_mode) {
62 	case DP_PANEL_MODE_EDP:
63 	case DP_PANEL_MODE_SPECIAL:
64 		panel_mode_edp = true;
65 		break;
66 
67 	default:
68 		break;
69 	}
70 
71 	/*set edp panel mode in receiver*/
72 	result = core_link_read_dpcd(
73 		link,
74 		DP_EDP_CONFIGURATION_SET,
75 		&edp_config_set.raw,
76 		sizeof(edp_config_set.raw));
77 
78 	if (result == DC_OK &&
79 		edp_config_set.bits.PANEL_MODE_EDP
80 		!= panel_mode_edp) {
81 
82 		edp_config_set.bits.PANEL_MODE_EDP =
83 		panel_mode_edp;
84 		result = core_link_write_dpcd(
85 			link,
86 			DP_EDP_CONFIGURATION_SET,
87 			&edp_config_set.raw,
88 			sizeof(edp_config_set.raw));
89 
90 		ASSERT(result == DC_OK);
91 	}
92 
93 	link->panel_mode = panel_mode;
94 	DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
95 		 "eDP panel mode enabled: %d \n",
96 		 link->link_index,
97 		 link->dpcd_caps.panel_mode_edp,
98 		 panel_mode_edp);
99 }
100 
dp_get_panel_mode(struct dc_link * link)101 enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
102 {
103 	/* We need to explicitly check that connector
104 	 * is not DP. Some Travis_VGA get reported
105 	 * by video bios as DP.
106 	 */
107 	if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
108 
109 		switch (link->dpcd_caps.branch_dev_id) {
110 		case DP_BRANCH_DEVICE_ID_0022B9:
111 			/* alternate scrambler reset is required for Travis
112 			 * for the case when external chip does not
113 			 * provide sink device id, alternate scrambler
114 			 * scheme will  be overriden later by querying
115 			 * Encoder features
116 			 */
117 			if (strncmp(
118 				link->dpcd_caps.branch_dev_name,
119 				DP_VGA_LVDS_CONVERTER_ID_2,
120 				sizeof(
121 				link->dpcd_caps.
122 				branch_dev_name)) == 0) {
123 					return DP_PANEL_MODE_SPECIAL;
124 			}
125 			break;
126 		case DP_BRANCH_DEVICE_ID_00001A:
127 			/* alternate scrambler reset is required for Travis
128 			 * for the case when external chip does not provide
129 			 * sink device id, alternate scrambler scheme will
130 			 * be overriden later by querying Encoder feature
131 			 */
132 			if (strncmp(link->dpcd_caps.branch_dev_name,
133 				DP_VGA_LVDS_CONVERTER_ID_3,
134 				sizeof(
135 				link->dpcd_caps.
136 				branch_dev_name)) == 0) {
137 					return DP_PANEL_MODE_SPECIAL;
138 			}
139 			break;
140 		default:
141 			break;
142 		}
143 	}
144 
145 	if (link->dpcd_caps.panel_mode_edp &&
146 		(link->connector_signal == SIGNAL_TYPE_EDP ||
147 		 (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
148 		  link->is_internal_display))) {
149 		return DP_PANEL_MODE_EDP;
150 	}
151 
152 	return DP_PANEL_MODE_DEFAULT;
153 }
154 
edp_set_backlight_level_nits(struct dc_link * link,bool isHDR,uint32_t backlight_millinits,uint32_t transition_time_in_ms)155 bool edp_set_backlight_level_nits(struct dc_link *link,
156 		bool isHDR,
157 		uint32_t backlight_millinits,
158 		uint32_t transition_time_in_ms)
159 {
160 	struct dpcd_source_backlight_set dpcd_backlight_set;
161 	uint8_t backlight_control = isHDR ? 1 : 0;
162 
163 	if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
164 			link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
165 		return false;
166 
167 	// OLEDs have no PWM, they can only use AUX
168 	if (link->dpcd_sink_ext_caps.bits.oled == 1)
169 		backlight_control = 1;
170 
171 	*(uint32_t *)&dpcd_backlight_set.backlight_level_millinits = backlight_millinits;
172 	*(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = (uint16_t)transition_time_in_ms;
173 
174 
175 	if (!link->dpcd_caps.panel_luminance_control) {
176 		if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
177 			(uint8_t *)(&dpcd_backlight_set),
178 			sizeof(dpcd_backlight_set)) != DC_OK)
179 			return false;
180 
181 		if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL,
182 			&backlight_control, 1) != DC_OK)
183 			return false;
184 	} else {
185 		uint8_t backlight_enable = 0;
186 		struct target_luminance_value *target_luminance = NULL;
187 
188 		//if target luminance value is greater than 24 bits, clip the value to 24 bits
189 		if (backlight_millinits > 0xFFFFFF)
190 			backlight_millinits = 0xFFFFFF;
191 
192 		target_luminance = (struct target_luminance_value *)&backlight_millinits;
193 
194 		core_link_read_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
195 			&backlight_enable, sizeof(uint8_t));
196 
197 		backlight_enable |= DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE;
198 
199 		if (core_link_write_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
200 			&backlight_enable,
201 			sizeof(backlight_enable)) != DC_OK)
202 			return false;
203 
204 		if (core_link_write_dpcd(link, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE,
205 			(uint8_t *)(target_luminance),
206 			sizeof(struct target_luminance_value)) != DC_OK)
207 			return false;
208 	}
209 
210 	return true;
211 }
212 
edp_get_backlight_level_nits(struct dc_link * link,uint32_t * backlight_millinits_avg,uint32_t * backlight_millinits_peak)213 bool edp_get_backlight_level_nits(struct dc_link *link,
214 		uint32_t *backlight_millinits_avg,
215 		uint32_t *backlight_millinits_peak)
216 {
217 	union dpcd_source_backlight_get dpcd_backlight_get;
218 
219 	memset(&dpcd_backlight_get, 0, sizeof(union dpcd_source_backlight_get));
220 
221 	if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
222 			link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
223 		return false;
224 
225 	if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK,
226 			dpcd_backlight_get.raw,
227 			sizeof(union dpcd_source_backlight_get)))
228 		return false;
229 
230 	*backlight_millinits_avg =
231 		dpcd_backlight_get.bytes.backlight_millinits_avg;
232 	*backlight_millinits_peak =
233 		dpcd_backlight_get.bytes.backlight_millinits_peak;
234 
235 	/* On non-supported panels dpcd_read usually succeeds with 0 returned */
236 	if (*backlight_millinits_avg == 0 ||
237 			*backlight_millinits_avg > *backlight_millinits_peak)
238 		return false;
239 
240 	return true;
241 }
242 
edp_backlight_enable_aux(struct dc_link * link,bool enable)243 bool edp_backlight_enable_aux(struct dc_link *link, bool enable)
244 {
245 	uint8_t backlight_enable = enable ? 1 : 0;
246 
247 	if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
248 		link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
249 		return false;
250 
251 	if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_ENABLE,
252 		&backlight_enable, 1) != DC_OK)
253 		return false;
254 
255 	return true;
256 }
257 
258 // we read default from 0x320 because we expect BIOS wrote it there
259 // regular get_backlight_nit reads from panel set at 0x326
read_default_bl_aux(struct dc_link * link,uint32_t * backlight_millinits)260 static bool read_default_bl_aux(struct dc_link *link, uint32_t *backlight_millinits)
261 {
262 	if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
263 		link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
264 		return false;
265 
266 	if (!link->dpcd_caps.panel_luminance_control) {
267 		if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
268 			(uint8_t *)backlight_millinits,
269 			sizeof(uint32_t)))
270 			return false;
271 	} else {
272 		//setting to 0 as a precaution, since target_luminance_value is 3 bytes
273 		memset(backlight_millinits, 0, sizeof(uint32_t));
274 
275 		if (!core_link_read_dpcd(link, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE,
276 			(uint8_t *)backlight_millinits,
277 			sizeof(struct target_luminance_value)))
278 			return false;
279 	}
280 
281 	return true;
282 }
283 
set_default_brightness_aux(struct dc_link * link)284 bool set_default_brightness_aux(struct dc_link *link)
285 {
286 	uint32_t default_backlight;
287 
288 	if (link && link->dpcd_sink_ext_caps.bits.oled == 1) {
289 		if (!read_default_bl_aux(link, &default_backlight))
290 			default_backlight = 150000;
291 		// if > 5000, it might be wrong readback. 0 nits is a valid default value for OLED panel.
292 		if (default_backlight < 1000 || default_backlight > 5000000)
293 			default_backlight = 150000;
294 
295 		return edp_set_backlight_level_nits(link, true,
296 				default_backlight, 0);
297 	}
298 	return false;
299 }
300 
edp_is_ilr_optimization_enabled(struct dc_link * link)301 bool edp_is_ilr_optimization_enabled(struct dc_link *link)
302 {
303 	if (link->dpcd_caps.edp_supported_link_rates_count == 0 || !link->panel_config.ilr.optimize_edp_link_rate)
304 		return false;
305 	return true;
306 }
307 
get_max_edp_link_rate(struct dc_link * link)308 enum dc_link_rate get_max_edp_link_rate(struct dc_link *link)
309 {
310 	enum dc_link_rate max_ilr_rate = LINK_RATE_UNKNOWN;
311 	enum dc_link_rate max_non_ilr_rate = dp_get_max_link_cap(link).link_rate;
312 
313 	for (int i = 0; i < link->dpcd_caps.edp_supported_link_rates_count; i++) {
314 		if (max_ilr_rate < link->dpcd_caps.edp_supported_link_rates[i])
315 			max_ilr_rate = link->dpcd_caps.edp_supported_link_rates[i];
316 	}
317 
318 	return (max_ilr_rate > max_non_ilr_rate ? max_ilr_rate : max_non_ilr_rate);
319 }
320 
edp_is_ilr_optimization_required(struct dc_link * link,struct dc_crtc_timing * crtc_timing)321 bool edp_is_ilr_optimization_required(struct dc_link *link,
322 		struct dc_crtc_timing *crtc_timing)
323 {
324 	struct dc_link_settings link_setting;
325 	uint8_t link_bw_set = 0;
326 	uint8_t link_rate_set = 0;
327 	uint32_t req_bw;
328 	union lane_count_set lane_count_set = {0};
329 
330 	ASSERT(link || crtc_timing); // invalid input
331 
332 	if (!edp_is_ilr_optimization_enabled(link))
333 		return false;
334 
335 
336 	// Read DPCD 00100h to find if standard link rates are set
337 	core_link_read_dpcd(link, DP_LINK_BW_SET,
338 				&link_bw_set, sizeof(link_bw_set));
339 
340 	if (link_bw_set) {
341 		DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS used link_bw_set\n");
342 		return true;
343 	}
344 
345 	// Read DPCD 00115h to find the edp link rate set used
346 	core_link_read_dpcd(link, DP_LINK_RATE_SET,
347 			    &link_rate_set, sizeof(link_rate_set));
348 
349 	// Read DPCD 00101h to find out the number of lanes currently set
350 	core_link_read_dpcd(link, DP_LANE_COUNT_SET,
351 				&lane_count_set.raw, sizeof(lane_count_set));
352 
353 	req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing, dc_link_get_highest_encoding_format(link));
354 
355 	if (!crtc_timing->flags.DSC)
356 		edp_decide_link_settings(link, &link_setting, req_bw);
357 	else
358 		decide_edp_link_settings_with_dsc(link, &link_setting, req_bw, LINK_RATE_UNKNOWN);
359 
360 	if (link->dpcd_caps.edp_supported_link_rates[link_rate_set] != link_setting.link_rate ||
361 			lane_count_set.bits.LANE_COUNT_SET != link_setting.lane_count) {
362 		DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS link_rate_set not optimal\n");
363 		return true;
364 	}
365 
366 	DC_LOG_EVENT_LINK_TRAINING("eDP ILR: No optimization required, VBIOS set optimal link_rate_set\n");
367 	return false;
368 }
369 
edp_panel_backlight_power_on(struct dc_link * link,bool wait_for_hpd)370 void edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd)
371 {
372 	if (link->connector_signal != SIGNAL_TYPE_EDP)
373 		return;
374 
375 	link->dc->hwss.edp_power_control(link, true);
376 	if (wait_for_hpd)
377 		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
378 	if (link->dc->hwss.edp_backlight_control)
379 		link->dc->hwss.edp_backlight_control(link, true);
380 }
381 
edp_set_panel_power(struct dc_link * link,bool powerOn)382 void edp_set_panel_power(struct dc_link *link, bool powerOn)
383 {
384 	if (powerOn) {
385 		// 1. panel VDD on
386 		if (!link->dc->config.edp_no_power_sequencing)
387 			link->dc->hwss.edp_power_control(link, true);
388 		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
389 
390 		// 2. panel BL on
391 		if (link->dc->hwss.edp_backlight_control)
392 			link->dc->hwss.edp_backlight_control(link, true);
393 
394 		// 3. Rx power on
395 		dpcd_write_rx_power_ctrl(link, true);
396 	} else {
397 		// 3. Rx power off
398 		dpcd_write_rx_power_ctrl(link, false);
399 
400 		// 2. panel BL off
401 		if (link->dc->hwss.edp_backlight_control)
402 			link->dc->hwss.edp_backlight_control(link, false);
403 
404 		// 1. panel VDD off
405 		if (!link->dc->config.edp_no_power_sequencing)
406 			link->dc->hwss.edp_power_control(link, false);
407 	}
408 }
409 
edp_wait_for_t12(struct dc_link * link)410 bool edp_wait_for_t12(struct dc_link *link)
411 {
412 	if (link->connector_signal == SIGNAL_TYPE_EDP && link->dc->hwss.edp_wait_for_T12) {
413 		link->dc->hwss.edp_wait_for_T12(link);
414 
415 		return true;
416 	}
417 
418 	return false;
419 }
420 
edp_add_delay_for_T9(struct dc_link * link)421 void edp_add_delay_for_T9(struct dc_link *link)
422 {
423 	if (link && link->panel_config.pps.extra_delay_backlight_off > 0)
424 		fsleep(link->panel_config.pps.extra_delay_backlight_off * 1000);
425 }
426 
edp_receiver_ready_T9(struct dc_link * link)427 bool edp_receiver_ready_T9(struct dc_link *link)
428 {
429 	unsigned int tries = 0;
430 	unsigned char sinkstatus = 0;
431 	unsigned char edpRev = 0;
432 	enum dc_status result = DC_OK;
433 
434 	result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
435 
436 	/* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
437 	if (result == DC_OK && edpRev >= DP_EDP_12) {
438 		do {
439 			sinkstatus = 1;
440 			result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
441 			if (sinkstatus == 0)
442 				break;
443 			if (result != DC_OK)
444 				break;
445 			udelay(100); //MAx T9
446 		} while (++tries < 50);
447 	}
448 
449 	return result;
450 }
451 
edp_receiver_ready_T7(struct dc_link * link)452 bool edp_receiver_ready_T7(struct dc_link *link)
453 {
454 	unsigned char sinkstatus = 0;
455 	unsigned char edpRev = 0;
456 	enum dc_status result = DC_OK;
457 
458 	/* use absolute time stamp to constrain max T7*/
459 	unsigned long long enter_timestamp = 0;
460 	unsigned long long finish_timestamp = 0;
461 	unsigned long long time_taken_in_ns = 0;
462 
463 	result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
464 
465 	if (result == DC_OK && edpRev >= DP_EDP_12) {
466 		/* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
467 		enter_timestamp = dm_get_timestamp(link->ctx);
468 		do {
469 			sinkstatus = 0;
470 			result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
471 			if (sinkstatus == 1)
472 				break;
473 			if (result != DC_OK)
474 				break;
475 			udelay(25);
476 			finish_timestamp = dm_get_timestamp(link->ctx);
477 			time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp, enter_timestamp);
478 		} while (time_taken_in_ns < 50 * 1000000); //MAx T7 is 50ms
479 	}
480 
481 	if (link && link->panel_config.pps.extra_t7_ms > 0)
482 		fsleep(link->panel_config.pps.extra_t7_ms * 1000);
483 
484 	return result;
485 }
486 
edp_power_alpm_dpcd_enable(struct dc_link * link,bool enable)487 bool edp_power_alpm_dpcd_enable(struct dc_link *link, bool enable)
488 {
489 	bool ret = false;
490 	union dpcd_alpm_configuration alpm_config;
491 
492 	if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
493 		memset(&alpm_config, 0, sizeof(alpm_config));
494 
495 		alpm_config.bits.ENABLE = (enable ? true : false);
496 		ret = dm_helpers_dp_write_dpcd(link->ctx, link,
497 				DP_RECEIVER_ALPM_CONFIG, &alpm_config.raw,
498 				sizeof(alpm_config.raw));
499 	}
500 	return ret;
501 }
502 
get_pipe_from_link(const struct dc_link * link)503 static struct pipe_ctx *get_pipe_from_link(const struct dc_link *link)
504 {
505 	int i;
506 	struct dc *dc = link->ctx->dc;
507 	struct pipe_ctx *pipe_ctx = NULL;
508 
509 	for (i = 0; i < MAX_PIPES; i++) {
510 		if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
511 			if (dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) {
512 				pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
513 				break;
514 			}
515 		}
516 	}
517 
518 	return pipe_ctx;
519 }
520 
edp_set_backlight_level(const struct dc_link * link,uint32_t backlight_pwm_u16_16,uint32_t frame_ramp)521 bool edp_set_backlight_level(const struct dc_link *link,
522 		uint32_t backlight_pwm_u16_16,
523 		uint32_t frame_ramp)
524 {
525 	struct dc  *dc = link->ctx->dc;
526 
527 	DC_LOGGER_INIT(link->ctx->logger);
528 	DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
529 			backlight_pwm_u16_16, backlight_pwm_u16_16);
530 
531 	if (dc_is_embedded_signal(link->connector_signal)) {
532 		struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);
533 
534 		if (link->panel_cntl)
535 			link->panel_cntl->stored_backlight_registers.USER_LEVEL = backlight_pwm_u16_16;
536 
537 		if (pipe_ctx) {
538 			/* Disable brightness ramping when the display is blanked
539 			 * as it can hang the DMCU
540 			 */
541 			if (pipe_ctx->plane_state == NULL)
542 				frame_ramp = 0;
543 		} else {
544 			return false;
545 		}
546 
547 		dc->hwss.set_backlight_level(
548 				pipe_ctx,
549 				backlight_pwm_u16_16,
550 				frame_ramp);
551 	}
552 	return true;
553 }
554 
edp_set_psr_allow_active(struct dc_link * link,const bool * allow_active,bool wait,bool force_static,const unsigned int * power_opts)555 bool edp_set_psr_allow_active(struct dc_link *link, const bool *allow_active,
556 		bool wait, bool force_static, const unsigned int *power_opts)
557 {
558 	struct dc  *dc = link->ctx->dc;
559 	struct dmcu *dmcu = dc->res_pool->dmcu;
560 	struct dmub_psr *psr = dc->res_pool->psr;
561 	unsigned int panel_inst;
562 
563 	if (psr == NULL && force_static)
564 		return false;
565 
566 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
567 		return false;
568 
569 	if ((allow_active != NULL) && (*allow_active == true) && (link->type == dc_connection_none)) {
570 		// Don't enter PSR if panel is not connected
571 		return false;
572 	}
573 
574 	/* Set power optimization flag */
575 	if (power_opts && link->psr_settings.psr_power_opt != *power_opts) {
576 		link->psr_settings.psr_power_opt = *power_opts;
577 
578 		if (psr != NULL && link->psr_settings.psr_feature_enabled && psr->funcs->psr_set_power_opt)
579 			psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt, panel_inst);
580 	}
581 
582 	if (psr != NULL && link->psr_settings.psr_feature_enabled &&
583 			force_static && psr->funcs->psr_force_static)
584 		psr->funcs->psr_force_static(psr, panel_inst);
585 
586 	/* Enable or Disable PSR */
587 	if (allow_active && link->psr_settings.psr_allow_active != *allow_active) {
588 		link->psr_settings.psr_allow_active = *allow_active;
589 
590 		if (!link->psr_settings.psr_allow_active)
591 			dc_z10_restore(dc);
592 
593 		if (psr != NULL && link->psr_settings.psr_feature_enabled) {
594 			psr->funcs->psr_enable(psr, link->psr_settings.psr_allow_active, wait, panel_inst);
595 		} else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) &&
596 			link->psr_settings.psr_feature_enabled)
597 			dmcu->funcs->set_psr_enable(dmcu, link->psr_settings.psr_allow_active, wait);
598 		else
599 			return false;
600 	}
601 	return true;
602 }
603 
edp_get_psr_state(const struct dc_link * link,enum dc_psr_state * state)604 bool edp_get_psr_state(const struct dc_link *link, enum dc_psr_state *state)
605 {
606 	struct dc  *dc = link->ctx->dc;
607 	struct dmcu *dmcu = dc->res_pool->dmcu;
608 	struct dmub_psr *psr = dc->res_pool->psr;
609 	unsigned int panel_inst;
610 
611 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
612 		return false;
613 
614 	if (psr != NULL && link->psr_settings.psr_feature_enabled)
615 		psr->funcs->psr_get_state(psr, state, panel_inst);
616 	else if (dmcu != NULL && link->psr_settings.psr_feature_enabled)
617 		dmcu->funcs->get_psr_state(dmcu, state);
618 
619 	return true;
620 }
621 
622 static inline enum physical_phy_id
transmitter_to_phy_id(struct dc_link * link)623 transmitter_to_phy_id(struct dc_link *link)
624 {
625 	struct dc_context *dc_ctx = link->ctx;
626 	enum transmitter transmitter_value = link->link_enc->transmitter;
627 
628 	switch (transmitter_value) {
629 	case TRANSMITTER_UNIPHY_A:
630 		return PHYLD_0;
631 	case TRANSMITTER_UNIPHY_B:
632 		return PHYLD_1;
633 	case TRANSMITTER_UNIPHY_C:
634 		return PHYLD_2;
635 	case TRANSMITTER_UNIPHY_D:
636 		return PHYLD_3;
637 	case TRANSMITTER_UNIPHY_E:
638 		return PHYLD_4;
639 	case TRANSMITTER_UNIPHY_F:
640 		return PHYLD_5;
641 	case TRANSMITTER_NUTMEG_CRT:
642 		return PHYLD_6;
643 	case TRANSMITTER_TRAVIS_CRT:
644 		return PHYLD_7;
645 	case TRANSMITTER_TRAVIS_LCD:
646 		return PHYLD_8;
647 	case TRANSMITTER_UNIPHY_G:
648 		return PHYLD_9;
649 	case TRANSMITTER_COUNT:
650 		return PHYLD_COUNT;
651 	case TRANSMITTER_UNKNOWN:
652 		return PHYLD_UNKNOWN;
653 	default:
654 		DC_ERROR("Unknown transmitter value %d\n", transmitter_value);
655 		return PHYLD_UNKNOWN;
656 	}
657 }
658 
edp_setup_psr(struct dc_link * link,const struct dc_stream_state * stream,struct psr_config * psr_config,struct psr_context * psr_context)659 bool edp_setup_psr(struct dc_link *link,
660 		const struct dc_stream_state *stream, struct psr_config *psr_config,
661 		struct psr_context *psr_context)
662 {
663 	struct dc *dc;
664 	struct dmcu *dmcu;
665 	struct dmub_psr *psr;
666 	int i;
667 	unsigned int panel_inst;
668 	/* updateSinkPsrDpcdConfig*/
669 	union dpcd_psr_configuration psr_configuration;
670 	union dpcd_sink_active_vtotal_control_mode vtotal_control = {0};
671 
672 	psr_context->controllerId = CONTROLLER_ID_UNDEFINED;
673 
674 	if (!link)
675 		return false;
676 
677 	dc = link->ctx->dc;
678 	dmcu = dc->res_pool->dmcu;
679 	psr = dc->res_pool->psr;
680 
681 	if (!dmcu && !psr)
682 		return false;
683 
684 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
685 		return false;
686 
687 
688 	memset(&psr_configuration, 0, sizeof(psr_configuration));
689 
690 	psr_configuration.bits.ENABLE                    = 1;
691 	psr_configuration.bits.CRC_VERIFICATION          = 1;
692 	psr_configuration.bits.FRAME_CAPTURE_INDICATION  =
693 			psr_config->psr_frame_capture_indication_req;
694 
695 	/* Check for PSR v2*/
696 	if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
697 		/* For PSR v2 selective update.
698 		 * Indicates whether sink should start capturing
699 		 * immediately following active scan line,
700 		 * or starting with the 2nd active scan line.
701 		 */
702 		psr_configuration.bits.LINE_CAPTURE_INDICATION = 0;
703 		/*For PSR v2, determines whether Sink should generate
704 		 * IRQ_HPD when CRC mismatch is detected.
705 		 */
706 		psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR    = 1;
707 		/* For PSR v2, set the bit when the Source device will
708 		 * be enabling PSR2 operation.
709 		 */
710 		psr_configuration.bits.ENABLE_PSR2    = 1;
711 		/* For PSR v2, the Sink device must be able to receive
712 		 * SU region updates early in the frame time.
713 		 */
714 		psr_configuration.bits.EARLY_TRANSPORT_ENABLE    = 1;
715 	}
716 
717 	dm_helpers_dp_write_dpcd(
718 		link->ctx,
719 		link,
720 		368,
721 		&psr_configuration.raw,
722 		sizeof(psr_configuration.raw));
723 
724 	if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
725 		edp_power_alpm_dpcd_enable(link, true);
726 		psr_context->su_granularity_required =
727 			psr_config->su_granularity_required;
728 		psr_context->su_y_granularity =
729 			psr_config->su_y_granularity;
730 		psr_context->line_time_in_us = psr_config->line_time_in_us;
731 
732 		/* linux must be able to expose AMD Source DPCD definition
733 		 * in order to support FreeSync PSR
734 		 */
735 		if (link->psr_settings.psr_vtotal_control_support) {
736 			psr_context->rate_control_caps = psr_config->rate_control_caps;
737 			vtotal_control.bits.ENABLE = true;
738 			core_link_write_dpcd(link, DP_SINK_PSR_ACTIVE_VTOTAL_CONTROL_MODE,
739 							&vtotal_control.raw, sizeof(vtotal_control.raw));
740 		}
741 	}
742 
743 	psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
744 	psr_context->transmitterId = link->link_enc->transmitter;
745 	psr_context->engineId = link->link_enc->preferred_engine;
746 
747 	for (i = 0; i < MAX_PIPES; i++) {
748 		if (dc->current_state->res_ctx.pipe_ctx[i].stream
749 				== stream) {
750 			/* dmcu -1 for all controller id values,
751 			 * therefore +1 here
752 			 */
753 			psr_context->controllerId =
754 				dc->current_state->res_ctx.
755 				pipe_ctx[i].stream_res.tg->inst + 1;
756 			break;
757 		}
758 	}
759 
760 	/* Hardcoded for now.  Can be Pcie or Uniphy (or Unknown)*/
761 	psr_context->phyType = PHY_TYPE_UNIPHY;
762 	/*PhyId is associated with the transmitter id*/
763 	psr_context->smuPhyId = transmitter_to_phy_id(link);
764 
765 	psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
766 	psr_context->vsync_rate_hz = div64_u64(div64_u64((stream->
767 					timing.pix_clk_100hz * (u64)100),
768 					stream->timing.v_total),
769 					stream->timing.h_total);
770 
771 	psr_context->psrSupportedDisplayConfig = true;
772 	psr_context->psrExitLinkTrainingRequired =
773 		psr_config->psr_exit_link_training_required;
774 	psr_context->sdpTransmitLineNumDeadline =
775 		psr_config->psr_sdp_transmit_line_num_deadline;
776 	psr_context->psrFrameCaptureIndicationReq =
777 		psr_config->psr_frame_capture_indication_req;
778 
779 	psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */
780 
781 	psr_context->numberOfControllers =
782 			link->dc->res_pool->timing_generator_count;
783 
784 	psr_context->rfb_update_auto_en = true;
785 
786 	/* 2 frames before enter PSR. */
787 	psr_context->timehyst_frames = 2;
788 	/* half a frame
789 	 * (units in 100 lines, i.e. a value of 1 represents 100 lines)
790 	 */
791 	psr_context->hyst_lines = stream->timing.v_total / 2 / 100;
792 	psr_context->aux_repeats = 10;
793 
794 	psr_context->psr_level.u32all = 0;
795 
796 	/*skip power down the single pipe since it blocks the cstate*/
797 	if (link->ctx->asic_id.chip_family >= FAMILY_RV) {
798 		switch (link->ctx->asic_id.chip_family) {
799 		case FAMILY_YELLOW_CARP:
800 		case AMDGPU_FAMILY_GC_10_3_6:
801 		case AMDGPU_FAMILY_GC_11_0_1:
802 			if (dc->debug.disable_z10 || dc->debug.psr_skip_crtc_disable)
803 				psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
804 			break;
805 		default:
806 			psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
807 			break;
808 		}
809 	}
810 
811 	/* SMU will perform additional powerdown sequence.
812 	 * For unsupported ASICs, set psr_level flag to skip PSR
813 	 *  static screen notification to SMU.
814 	 *  (Always set for DAL2, did not check ASIC)
815 	 */
816 	psr_context->allow_smu_optimizations = psr_config->allow_smu_optimizations;
817 	psr_context->allow_multi_disp_optimizations = psr_config->allow_multi_disp_optimizations;
818 
819 	/* Complete PSR entry before aborting to prevent intermittent
820 	 * freezes on certain eDPs
821 	 */
822 	psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1;
823 
824 	/* Disable ALPM first for compatible non-ALPM panel now */
825 	psr_context->psr_level.bits.DISABLE_ALPM = 0;
826 	psr_context->psr_level.bits.ALPM_DEFAULT_PD_MODE = 1;
827 
828 	/* Controls additional delay after remote frame capture before
829 	 * continuing power down, default = 0
830 	 */
831 	psr_context->frame_delay = 0;
832 
833 	psr_context->dsc_slice_height = psr_config->dsc_slice_height;
834 
835 	if (psr) {
836 		link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr,
837 			link, psr_context, panel_inst);
838 		link->psr_settings.psr_power_opt = 0;
839 		link->psr_settings.psr_allow_active = 0;
840 	} else {
841 		link->psr_settings.psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context);
842 	}
843 
844 	/* psr_enabled == 0 indicates setup_psr did not succeed, but this
845 	 * should not happen since firmware should be running at this point
846 	 */
847 	if (link->psr_settings.psr_feature_enabled == 0)
848 		ASSERT(0);
849 
850 	return true;
851 
852 }
853 
edp_get_psr_residency(const struct dc_link * link,uint32_t * residency,enum psr_residency_mode mode)854 void edp_get_psr_residency(const struct dc_link *link, uint32_t *residency, enum psr_residency_mode mode)
855 {
856 	struct dc  *dc = link->ctx->dc;
857 	struct dmub_psr *psr = dc->res_pool->psr;
858 	unsigned int panel_inst;
859 
860 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
861 		return;
862 
863 	// PSR residency measurements only supported on DMCUB
864 	if (psr != NULL && link->psr_settings.psr_feature_enabled)
865 		psr->funcs->psr_get_residency(psr, residency, panel_inst, mode);
866 	else
867 		*residency = 0;
868 }
edp_set_sink_vtotal_in_psr_active(const struct dc_link * link,uint16_t psr_vtotal_idle,uint16_t psr_vtotal_su)869 bool edp_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su)
870 {
871 	struct dc *dc = link->ctx->dc;
872 	struct dmub_psr *psr = dc->res_pool->psr;
873 
874 	if (psr == NULL || !link->psr_settings.psr_feature_enabled || !link->psr_settings.psr_vtotal_control_support)
875 		return false;
876 
877 	psr->funcs->psr_set_sink_vtotal_in_psr_active(psr, psr_vtotal_idle, psr_vtotal_su);
878 
879 	return true;
880 }
881 
edp_set_replay_allow_active(struct dc_link * link,const bool * allow_active,bool wait,bool force_static,const unsigned int * power_opts)882 bool edp_set_replay_allow_active(struct dc_link *link, const bool *allow_active,
883 	bool wait, bool force_static, const unsigned int *power_opts)
884 {
885 	struct dc  *dc = link->ctx->dc;
886 	struct dmub_replay *replay = dc->res_pool->replay;
887 	unsigned int panel_inst;
888 
889 	if (replay == NULL && force_static)
890 		return false;
891 
892 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
893 		return false;
894 
895 	/* Set power optimization flag */
896 	if (power_opts && link->replay_settings.replay_power_opt_active != *power_opts) {
897 		if (replay != NULL && link->replay_settings.replay_feature_enabled &&
898 		    replay->funcs->replay_set_power_opt) {
899 			replay->funcs->replay_set_power_opt(replay, *power_opts, panel_inst);
900 			link->replay_settings.replay_power_opt_active = *power_opts;
901 		}
902 	}
903 
904 	/* Activate or deactivate Replay */
905 	if (allow_active && link->replay_settings.replay_allow_active != *allow_active) {
906 		// TODO: Handle mux change case if force_static is set
907 		// If force_static is set, just change the replay_allow_active state directly
908 		if (replay != NULL && link->replay_settings.replay_feature_enabled)
909 			replay->funcs->replay_enable(replay, *allow_active, wait, panel_inst);
910 		link->replay_settings.replay_allow_active = *allow_active;
911 	}
912 
913 	return true;
914 }
915 
edp_get_replay_state(const struct dc_link * link,uint64_t * state)916 bool edp_get_replay_state(const struct dc_link *link, uint64_t *state)
917 {
918 	struct dc  *dc = link->ctx->dc;
919 	struct dmub_replay *replay = dc->res_pool->replay;
920 	unsigned int panel_inst;
921 	enum replay_state pr_state = REPLAY_STATE_0;
922 
923 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
924 		return false;
925 
926 	if (replay != NULL && link->replay_settings.replay_feature_enabled)
927 		replay->funcs->replay_get_state(replay, &pr_state, panel_inst);
928 	*state = pr_state;
929 
930 	return true;
931 }
932 
edp_setup_replay(struct dc_link * link,const struct dc_stream_state * stream)933 bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream)
934 {
935 	/* To-do: Setup Replay */
936 	struct dc *dc;
937 	struct dmub_replay *replay;
938 	int i;
939 	unsigned int panel_inst;
940 	struct replay_context replay_context = { 0 };
941 	unsigned int lineTimeInNs = 0;
942 
943 
944 	union replay_enable_and_configuration replay_config;
945 
946 	union dpcd_alpm_configuration alpm_config;
947 
948 	replay_context.controllerId = CONTROLLER_ID_UNDEFINED;
949 
950 	if (!link)
951 		return false;
952 
953 	dc = link->ctx->dc;
954 
955 	replay = dc->res_pool->replay;
956 
957 	if (!replay)
958 		return false;
959 
960 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
961 		return false;
962 
963 	replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel;
964 	replay_context.digbe_inst = link->link_enc->transmitter;
965 	replay_context.digfe_inst = link->link_enc->preferred_engine;
966 
967 	for (i = 0; i < MAX_PIPES; i++) {
968 		if (dc->current_state->res_ctx.pipe_ctx[i].stream
969 				== stream) {
970 			/* dmcu -1 for all controller id values,
971 			 * therefore +1 here
972 			 */
973 			replay_context.controllerId =
974 				dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg->inst + 1;
975 			break;
976 		}
977 	}
978 
979 	lineTimeInNs =
980 		((stream->timing.h_total * 1000000) /
981 			(stream->timing.pix_clk_100hz / 10)) + 1;
982 
983 	replay_context.line_time_in_ns = lineTimeInNs;
984 
985 	link->replay_settings.replay_feature_enabled =
986 			replay->funcs->replay_copy_settings(replay, link, &replay_context, panel_inst);
987 	if (link->replay_settings.replay_feature_enabled) {
988 
989 		replay_config.bits.FREESYNC_PANEL_REPLAY_MODE = 1;
990 		replay_config.bits.TIMING_DESYNC_ERROR_VERIFICATION =
991 			link->replay_settings.config.replay_timing_sync_supported;
992 		replay_config.bits.STATE_TRANSITION_ERROR_DETECTION = 1;
993 		dm_helpers_dp_write_dpcd(link->ctx, link,
994 			DP_SINK_PR_ENABLE_AND_CONFIGURATION,
995 			(uint8_t *)&(replay_config.raw), sizeof(uint8_t));
996 
997 		memset(&alpm_config, 0, sizeof(alpm_config));
998 		alpm_config.bits.ENABLE = 1;
999 		dm_helpers_dp_write_dpcd(
1000 			link->ctx,
1001 			link,
1002 			DP_RECEIVER_ALPM_CONFIG,
1003 			&alpm_config.raw,
1004 			sizeof(alpm_config.raw));
1005 	}
1006 	return true;
1007 }
1008 
1009 /*
1010  * This is general Interface for Replay to set an 32 bit variable to dmub
1011  * replay_FW_Message_type: Indicates which instruction or variable pass to DMUB
1012  * cmd_data: Value of the config.
1013  */
edp_send_replay_cmd(struct dc_link * link,enum replay_FW_Message_type msg,union dmub_replay_cmd_set * cmd_data)1014 bool edp_send_replay_cmd(struct dc_link *link,
1015 			enum replay_FW_Message_type msg,
1016 			union dmub_replay_cmd_set *cmd_data)
1017 {
1018 	struct dc *dc = link->ctx->dc;
1019 	struct dmub_replay *replay = dc->res_pool->replay;
1020 	unsigned int panel_inst;
1021 
1022 	if (!replay)
1023 		return false;
1024 
1025 	DC_LOGGER_INIT(link->ctx->logger);
1026 
1027 	if (dc_get_edp_link_panel_inst(dc, link, &panel_inst))
1028 		cmd_data->panel_inst = panel_inst;
1029 	else {
1030 		DC_LOG_DC("%s(): get edp panel inst fail ", __func__);
1031 		return false;
1032 	}
1033 
1034 	replay->funcs->replay_send_cmd(replay, msg, cmd_data);
1035 
1036 	return true;
1037 }
1038 
edp_set_coasting_vtotal(struct dc_link * link,uint32_t coasting_vtotal)1039 bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal)
1040 {
1041 	struct dc *dc = link->ctx->dc;
1042 	struct dmub_replay *replay = dc->res_pool->replay;
1043 	unsigned int panel_inst;
1044 
1045 	if (!replay)
1046 		return false;
1047 
1048 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
1049 		return false;
1050 
1051 	if (coasting_vtotal && link->replay_settings.coasting_vtotal != coasting_vtotal) {
1052 		replay->funcs->replay_set_coasting_vtotal(replay, coasting_vtotal, panel_inst);
1053 		link->replay_settings.coasting_vtotal = coasting_vtotal;
1054 	}
1055 
1056 	return true;
1057 }
1058 
edp_replay_residency(const struct dc_link * link,unsigned int * residency,const bool is_start,const enum pr_residency_mode mode)1059 bool edp_replay_residency(const struct dc_link *link,
1060 	unsigned int *residency, const bool is_start, const enum pr_residency_mode mode)
1061 {
1062 	struct dc  *dc = link->ctx->dc;
1063 	struct dmub_replay *replay = dc->res_pool->replay;
1064 	unsigned int panel_inst;
1065 
1066 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
1067 		return false;
1068 
1069 	if (!residency)
1070 		return false;
1071 
1072 	if (replay != NULL && link->replay_settings.replay_feature_enabled)
1073 		replay->funcs->replay_residency(replay, panel_inst, residency, is_start, mode);
1074 	else
1075 		*residency = 0;
1076 
1077 	return true;
1078 }
1079 
edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link * link,const unsigned int * power_opts,uint32_t coasting_vtotal)1080 bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link,
1081 	const unsigned int *power_opts, uint32_t coasting_vtotal)
1082 {
1083 	struct dc  *dc = link->ctx->dc;
1084 	struct dmub_replay *replay = dc->res_pool->replay;
1085 	unsigned int panel_inst;
1086 
1087 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
1088 		return false;
1089 
1090 	/* Only both power and coasting vtotal changed, this func could return true */
1091 	if (power_opts && link->replay_settings.replay_power_opt_active != *power_opts &&
1092 		coasting_vtotal && link->replay_settings.coasting_vtotal != coasting_vtotal) {
1093 		if (link->replay_settings.replay_feature_enabled &&
1094 			replay->funcs->replay_set_power_opt_and_coasting_vtotal) {
1095 			replay->funcs->replay_set_power_opt_and_coasting_vtotal(replay,
1096 				*power_opts, panel_inst, coasting_vtotal);
1097 			link->replay_settings.replay_power_opt_active = *power_opts;
1098 			link->replay_settings.coasting_vtotal = coasting_vtotal;
1099 		} else
1100 			return false;
1101 	} else
1102 		return false;
1103 
1104 	return true;
1105 }
1106 
get_abm_from_stream_res(const struct dc_link * link)1107 static struct abm *get_abm_from_stream_res(const struct dc_link *link)
1108 {
1109 	int i;
1110 	struct dc *dc = link->ctx->dc;
1111 	struct abm *abm = NULL;
1112 
1113 	for (i = 0; i < MAX_PIPES; i++) {
1114 		struct pipe_ctx pipe_ctx = dc->current_state->res_ctx.pipe_ctx[i];
1115 		struct dc_stream_state *stream = pipe_ctx.stream;
1116 
1117 		if (stream && stream->link == link) {
1118 			abm = pipe_ctx.stream_res.abm;
1119 			break;
1120 		}
1121 	}
1122 	return abm;
1123 }
1124 
edp_get_backlight_level(const struct dc_link * link)1125 int edp_get_backlight_level(const struct dc_link *link)
1126 {
1127 	struct abm *abm = get_abm_from_stream_res(link);
1128 	struct panel_cntl *panel_cntl = link->panel_cntl;
1129 	struct dc  *dc = link->ctx->dc;
1130 	struct dmcu *dmcu = dc->res_pool->dmcu;
1131 	bool fw_set_brightness = true;
1132 
1133 	if (dmcu)
1134 		fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
1135 
1136 	if (!fw_set_brightness && panel_cntl->funcs->get_current_backlight)
1137 		return panel_cntl->funcs->get_current_backlight(panel_cntl);
1138 	else if (abm != NULL && abm->funcs->get_current_backlight != NULL)
1139 		return (int) abm->funcs->get_current_backlight(abm);
1140 	else
1141 		return DC_ERROR_UNEXPECTED;
1142 }
1143 
edp_get_target_backlight_pwm(const struct dc_link * link)1144 int edp_get_target_backlight_pwm(const struct dc_link *link)
1145 {
1146 	struct abm *abm = get_abm_from_stream_res(link);
1147 
1148 	if (abm == NULL || abm->funcs->get_target_backlight == NULL)
1149 		return DC_ERROR_UNEXPECTED;
1150 
1151 	return (int) abm->funcs->get_target_backlight(abm);
1152 }
1153 
edp_set_assr_enable(const struct dc * pDC,struct dc_link * link,struct link_resource * link_res,bool enable)1154 static void edp_set_assr_enable(const struct dc *pDC, struct dc_link *link,
1155 		struct link_resource *link_res, bool enable)
1156 {
1157 	union dmub_rb_cmd cmd;
1158 	bool use_hpo_dp_link_enc = false;
1159 	uint8_t link_enc_index = 0;
1160 	uint8_t phy_type = 0;
1161 	uint8_t phy_id = 0;
1162 
1163 	if (!pDC->config.use_assr_psp_message)
1164 		return;
1165 
1166 	memset(&cmd, 0, sizeof(cmd));
1167 
1168 	link_enc_index = link->link_enc->transmitter - TRANSMITTER_UNIPHY_A;
1169 
1170 	if (link_res->hpo_dp_link_enc) {
1171 		if (link->wa_flags.disable_assr_for_uhbr)
1172 			return;
1173 
1174 		link_enc_index = link_res->hpo_dp_link_enc->inst;
1175 		use_hpo_dp_link_enc = true;
1176 	}
1177 
1178 	if (enable)
1179 		phy_type = ((dp_get_panel_mode(link) == DP_PANEL_MODE_EDP) ? 1 : 0);
1180 
1181 	phy_id = resource_transmitter_to_phy_idx(pDC, link->link_enc->transmitter);
1182 
1183 	cmd.assr_enable.header.type = DMUB_CMD__PSP;
1184 	cmd.assr_enable.header.sub_type = DMUB_CMD__PSP_ASSR_ENABLE;
1185 	cmd.assr_enable.assr_data.enable = enable;
1186 	cmd.assr_enable.assr_data.phy_port_type = phy_type;
1187 	cmd.assr_enable.assr_data.phy_port_id = phy_id;
1188 	cmd.assr_enable.assr_data.link_enc_index = link_enc_index;
1189 	cmd.assr_enable.assr_data.hpo_mode = use_hpo_dp_link_enc;
1190 
1191 	dc_wake_and_execute_dmub_cmd(pDC->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
1192 }
1193 
edp_set_panel_assr(struct dc_link * link,struct pipe_ctx * pipe_ctx,enum dp_panel_mode * panel_mode,bool enable)1194 void edp_set_panel_assr(struct dc_link *link, struct pipe_ctx *pipe_ctx,
1195 		enum dp_panel_mode *panel_mode, bool enable)
1196 {
1197 	struct link_resource *link_res = &pipe_ctx->link_res;
1198 	struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp;
1199 
1200 	if (*panel_mode != DP_PANEL_MODE_EDP)
1201 		return;
1202 
1203 	if (link->dc->config.use_assr_psp_message) {
1204 		edp_set_assr_enable(link->dc, link, link_res, enable);
1205 	} else if (cp_psp && cp_psp->funcs.enable_assr && enable) {
1206 		/* ASSR is bound to fail with unsigned PSP
1207 		 * verstage used during devlopment phase.
1208 		 * Report and continue with eDP panel mode to
1209 		 * perform eDP link training with right settings
1210 		 */
1211 		bool result;
1212 
1213 		result = cp_psp->funcs.enable_assr(cp_psp->handle, link);
1214 
1215 		if (!result && link->panel_mode != DP_PANEL_MODE_EDP)
1216 			*panel_mode = DP_PANEL_MODE_DEFAULT;
1217 	}
1218 }
1219