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