File Index
Files and directories
Sign in
FILE

link_edp_panel_control.c

File preview with syntax highlighting.

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