Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   1/*
   2 * Copyright 2023 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 owns the programming sequence of stream's dpms state associated
  28 * with the link and link's enable/disable sequences as result of the stream's
  29 * dpms state change.
  30 *
  31 * TODO - The reason link owns stream's dpms programming sequence is
  32 * because dpms programming sequence is highly dependent on underlying signal
  33 * specific link protocols. This unfortunately causes link to own a portion of
  34 * stream state programming sequence. This creates a gray area where the
  35 * boundary between link and stream is not clearly defined.
  36 */
  37
  38#include "link_dpms.h"
  39#include "link_hwss.h"
  40#include "link_validation.h"
  41#include "accessories/link_dp_trace.h"
  42#include "protocols/link_dpcd.h"
  43#include "protocols/link_ddc.h"
  44#include "protocols/link_hpd.h"
  45#include "protocols/link_dp_phy.h"
  46#include "protocols/link_dp_capability.h"
  47#include "protocols/link_dp_training.h"
  48#include "protocols/link_edp_panel_control.h"
  49#include "protocols/link_dp_dpia_bw.h"
  50
  51#include "dm_helpers.h"
  52#include "link_enc_cfg.h"
  53#include "resource.h"
  54#include "dsc.h"
  55#include "dccg.h"
  56#include "clk_mgr.h"
  57#include "atomfirmware.h"
  58#define DC_LOGGER \
  59	dc_logger
  60#define DC_LOGGER_INIT(logger) \
  61	struct dal_logger *dc_logger = logger
  62
  63#define LINK_INFO(...) \
  64	DC_LOG_HW_HOTPLUG(  \
  65		__VA_ARGS__)
  66
  67#define RETIMER_REDRIVER_INFO(...) \
  68	DC_LOG_RETIMER_REDRIVER(  \
  69		__VA_ARGS__)
  70#include "dc/dcn30/dcn30_vpg.h"
  71
  72#define MAX_MTP_SLOT_COUNT 64
  73#define LINK_TRAINING_ATTEMPTS 4
  74#define PEAK_FACTOR_X1000 1006
  75
  76void link_blank_all_dp_displays(struct dc *dc)
  77{
  78	unsigned int i;
  79	uint8_t dpcd_power_state = '\0';
  80	enum dc_status status = DC_ERROR_UNEXPECTED;
  81
  82	for (i = 0; i < dc->link_count; i++) {
  83		if ((dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) ||
  84			(dc->links[i]->priv == NULL) || (dc->links[i]->local_sink == NULL))
  85			continue;
  86
  87		/* DP 2.0 spec requires that we read LTTPR caps first */
  88		dp_retrieve_lttpr_cap(dc->links[i]);
  89		/* if any of the displays are lit up turn them off */
  90		status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
  91							&dpcd_power_state, sizeof(dpcd_power_state));
  92
  93		if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0)
  94			link_blank_dp_stream(dc->links[i], true);
  95	}
  96
  97}
  98
  99void link_blank_all_edp_displays(struct dc *dc)
 100{
 101	unsigned int i;
 102	uint8_t dpcd_power_state = '\0';
 103	enum dc_status status = DC_ERROR_UNEXPECTED;
 104
 105	for (i = 0; i < dc->link_count; i++) {
 106		if ((dc->links[i]->connector_signal != SIGNAL_TYPE_EDP) ||
 107			(!dc->links[i]->edp_sink_present))
 108			continue;
 109
 110		/* if any of the displays are lit up turn them off */
 111		status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
 112							&dpcd_power_state, sizeof(dpcd_power_state));
 113
 114		if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0)
 115			link_blank_dp_stream(dc->links[i], true);
 116	}
 117}
 118
 119void link_blank_dp_stream(struct dc_link *link, bool hw_init)
 120{
 121	unsigned int j;
 122	struct dc  *dc = link->ctx->dc;
 123	enum signal_type signal = link->connector_signal;
 124
 125	if ((signal == SIGNAL_TYPE_EDP) ||
 126		(signal == SIGNAL_TYPE_DISPLAY_PORT)) {
 127		if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
 128			link->link_enc->funcs->get_dig_frontend &&
 129			link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
 130			unsigned int fe = link->link_enc->funcs->get_dig_frontend(link->link_enc);
 131
 132			if (fe != ENGINE_ID_UNKNOWN)
 133				for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
 134					if (fe == dc->res_pool->stream_enc[j]->id) {
 135						dc->res_pool->stream_enc[j]->funcs->dp_blank(link,
 136									dc->res_pool->stream_enc[j]);
 137						break;
 138					}
 139				}
 140		}
 141
 142		if ((!link->wa_flags.dp_keep_receiver_powered) || hw_init)
 143			dpcd_write_rx_power_ctrl(link, false);
 144	}
 145}
 146
 147void link_set_all_streams_dpms_off_for_link(struct dc_link *link)
 148{
 149	struct pipe_ctx *pipes[MAX_PIPES];
 150	struct dc_state *state = link->dc->current_state;
 151	uint8_t count;
 152	int i;
 153	struct dc_stream_update stream_update;
 154	bool dpms_off = true;
 155	struct link_resource link_res = {0};
 156
 157	memset(&stream_update, 0, sizeof(stream_update));
 158	stream_update.dpms_off = &dpms_off;
 159
 160	link_get_master_pipes_with_dpms_on(link, state, &count, pipes);
 161
 162	for (i = 0; i < count; i++) {
 163		stream_update.stream = pipes[i]->stream;
 164		dc_commit_updates_for_stream(link->ctx->dc, NULL, 0,
 165				pipes[i]->stream, &stream_update,
 166				state);
 167	}
 168
 169	/* link can be also enabled by vbios. In this case it is not recorded
 170	 * in pipe_ctx. Disable link phy here to make sure it is completely off
 171	 */
 172	dp_disable_link_phy(link, &link_res, link->connector_signal);
 173}
 174
 175void link_resume(struct dc_link *link)
 176{
 177	if (link->connector_signal != SIGNAL_TYPE_VIRTUAL)
 178		program_hpd_filter(link);
 179}
 180
 181/* This function returns true if the pipe is used to feed video signal directly
 182 * to the link.
 183 */
 184static bool is_master_pipe_for_link(const struct dc_link *link,
 185		const struct pipe_ctx *pipe)
 186{
 187	return resource_is_pipe_type(pipe, OTG_MASTER) &&
 188			pipe->stream->link == link;
 189}
 190
 191/*
 192 * This function finds all master pipes feeding to a given link with dpms set to
 193 * on in given dc state.
 194 */
 195void link_get_master_pipes_with_dpms_on(const struct dc_link *link,
 196		struct dc_state *state,
 197		uint8_t *count,
 198		struct pipe_ctx *pipes[MAX_PIPES])
 199{
 200	int i;
 201	struct pipe_ctx *pipe = NULL;
 202
 203	*count = 0;
 204	for (i = 0; i < MAX_PIPES; i++) {
 205		pipe = &state->res_ctx.pipe_ctx[i];
 206
 207		if (is_master_pipe_for_link(link, pipe) &&
 208				pipe->stream->dpms_off == false) {
 209			pipes[(*count)++] = pipe;
 210		}
 211	}
 212}
 213
 214static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
 215		enum engine_id eng_id,
 216		struct ext_hdmi_settings *settings)
 217{
 218	bool result = false;
 219	int i = 0;
 220	struct integrated_info *integrated_info =
 221			pipe_ctx->stream->ctx->dc_bios->integrated_info;
 222
 223	if (integrated_info == NULL)
 224		return false;
 225
 226	/*
 227	 * Get retimer settings from sbios for passing SI eye test for DCE11
 228	 * The setting values are varied based on board revision and port id
 229	 * Therefore the setting values of each ports is passed by sbios.
 230	 */
 231
 232	// Check if current bios contains ext Hdmi settings
 233	if (integrated_info->gpu_cap_info & 0x20) {
 234		switch (eng_id) {
 235		case ENGINE_ID_DIGA:
 236			settings->slv_addr = integrated_info->dp0_ext_hdmi_slv_addr;
 237			settings->reg_num = integrated_info->dp0_ext_hdmi_6g_reg_num;
 238			settings->reg_num_6g = integrated_info->dp0_ext_hdmi_6g_reg_num;
 239			memmove(settings->reg_settings,
 240					integrated_info->dp0_ext_hdmi_reg_settings,
 241					sizeof(integrated_info->dp0_ext_hdmi_reg_settings));
 242			memmove(settings->reg_settings_6g,
 243					integrated_info->dp0_ext_hdmi_6g_reg_settings,
 244					sizeof(integrated_info->dp0_ext_hdmi_6g_reg_settings));
 245			result = true;
 246			break;
 247		case ENGINE_ID_DIGB:
 248			settings->slv_addr = integrated_info->dp1_ext_hdmi_slv_addr;
 249			settings->reg_num = integrated_info->dp1_ext_hdmi_6g_reg_num;
 250			settings->reg_num_6g = integrated_info->dp1_ext_hdmi_6g_reg_num;
 251			memmove(settings->reg_settings,
 252					integrated_info->dp1_ext_hdmi_reg_settings,
 253					sizeof(integrated_info->dp1_ext_hdmi_reg_settings));
 254			memmove(settings->reg_settings_6g,
 255					integrated_info->dp1_ext_hdmi_6g_reg_settings,
 256					sizeof(integrated_info->dp1_ext_hdmi_6g_reg_settings));
 257			result = true;
 258			break;
 259		case ENGINE_ID_DIGC:
 260			settings->slv_addr = integrated_info->dp2_ext_hdmi_slv_addr;
 261			settings->reg_num = integrated_info->dp2_ext_hdmi_6g_reg_num;
 262			settings->reg_num_6g = integrated_info->dp2_ext_hdmi_6g_reg_num;
 263			memmove(settings->reg_settings,
 264					integrated_info->dp2_ext_hdmi_reg_settings,
 265					sizeof(integrated_info->dp2_ext_hdmi_reg_settings));
 266			memmove(settings->reg_settings_6g,
 267					integrated_info->dp2_ext_hdmi_6g_reg_settings,
 268					sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings));
 269			result = true;
 270			break;
 271		case ENGINE_ID_DIGD:
 272			settings->slv_addr = integrated_info->dp3_ext_hdmi_slv_addr;
 273			settings->reg_num = integrated_info->dp3_ext_hdmi_6g_reg_num;
 274			settings->reg_num_6g = integrated_info->dp3_ext_hdmi_6g_reg_num;
 275			memmove(settings->reg_settings,
 276					integrated_info->dp3_ext_hdmi_reg_settings,
 277					sizeof(integrated_info->dp3_ext_hdmi_reg_settings));
 278			memmove(settings->reg_settings_6g,
 279					integrated_info->dp3_ext_hdmi_6g_reg_settings,
 280					sizeof(integrated_info->dp3_ext_hdmi_6g_reg_settings));
 281			result = true;
 282			break;
 283		default:
 284			break;
 285		}
 286
 287		if (result == true) {
 288			// Validate settings from bios integrated info table
 289			if (settings->slv_addr == 0)
 290				return false;
 291			if (settings->reg_num > 9)
 292				return false;
 293			if (settings->reg_num_6g > 3)
 294				return false;
 295
 296			for (i = 0; i < settings->reg_num; i++) {
 297				if (settings->reg_settings[i].i2c_reg_index > 0x20)
 298					return false;
 299			}
 300
 301			for (i = 0; i < settings->reg_num_6g; i++) {
 302				if (settings->reg_settings_6g[i].i2c_reg_index > 0x20)
 303					return false;
 304			}
 305		}
 306	}
 307
 308	return result;
 309}
 310
 311static bool write_i2c(struct pipe_ctx *pipe_ctx,
 312		uint8_t address, uint8_t *buffer, uint32_t length)
 313{
 314	struct i2c_command cmd = {0};
 315	struct i2c_payload payload = {0};
 316
 317	memset(&payload, 0, sizeof(payload));
 318	memset(&cmd, 0, sizeof(cmd));
 319
 320	cmd.number_of_payloads = 1;
 321	cmd.engine = I2C_COMMAND_ENGINE_DEFAULT;
 322	cmd.speed = pipe_ctx->stream->ctx->dc->caps.i2c_speed_in_khz;
 323
 324	payload.address = address;
 325	payload.data = buffer;
 326	payload.length = length;
 327	payload.write = true;
 328	cmd.payloads = &payload;
 329
 330	if (dm_helpers_submit_i2c(pipe_ctx->stream->ctx,
 331			pipe_ctx->stream->link, &cmd))
 332		return true;
 333
 334	return false;
 335}
 336
 337static void write_i2c_retimer_setting(
 338		struct pipe_ctx *pipe_ctx,
 339		bool is_vga_mode,
 340		bool is_over_340mhz,
 341		struct ext_hdmi_settings *settings)
 342{
 343	uint8_t slave_address = (settings->slv_addr >> 1);
 344	uint8_t buffer[2];
 345	const uint8_t apply_rx_tx_change = 0x4;
 346	uint8_t offset = 0xA;
 347	uint8_t value = 0;
 348	int i = 0;
 349	bool i2c_success = false;
 350	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
 351
 352	memset(&buffer, 0, sizeof(buffer));
 353
 354	/* Start Ext-Hdmi programming*/
 355
 356	for (i = 0; i < settings->reg_num; i++) {
 357		/* Apply 3G settings */
 358		if (settings->reg_settings[i].i2c_reg_index <= 0x20) {
 359
 360			buffer[0] = settings->reg_settings[i].i2c_reg_index;
 361			buffer[1] = settings->reg_settings[i].i2c_reg_val;
 362			i2c_success = write_i2c(pipe_ctx, slave_address,
 363						buffer, sizeof(buffer));
 364			RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
 365				offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
 366				slave_address, buffer[0], buffer[1], i2c_success?1:0);
 367
 368			if (!i2c_success)
 369				goto i2c_write_fail;
 370
 371			/* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
 372			 * needs to be set to 1 on every 0xA-0xC write.
 373			 */
 374			if (settings->reg_settings[i].i2c_reg_index == 0xA ||
 375				settings->reg_settings[i].i2c_reg_index == 0xB ||
 376				settings->reg_settings[i].i2c_reg_index == 0xC) {
 377
 378				/* Query current value from offset 0xA */
 379				if (settings->reg_settings[i].i2c_reg_index == 0xA)
 380					value = settings->reg_settings[i].i2c_reg_val;
 381				else {
 382					i2c_success =
 383						link_query_ddc_data(
 384						pipe_ctx->stream->link->ddc,
 385						slave_address, &offset, 1, &value, 1);
 386					if (!i2c_success)
 387						goto i2c_write_fail;
 388				}
 389
 390				buffer[0] = offset;
 391				/* Set APPLY_RX_TX_CHANGE bit to 1 */
 392				buffer[1] = value | apply_rx_tx_change;
 393				i2c_success = write_i2c(pipe_ctx, slave_address,
 394						buffer, sizeof(buffer));
 395				RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
 396					offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 397					slave_address, buffer[0], buffer[1], i2c_success?1:0);
 398				if (!i2c_success)
 399					goto i2c_write_fail;
 400			}
 401		}
 402	}
 403
 404	/* Apply 3G settings */
 405	if (is_over_340mhz) {
 406		for (i = 0; i < settings->reg_num_6g; i++) {
 407			/* Apply 3G settings */
 408			if (settings->reg_settings[i].i2c_reg_index <= 0x20) {
 409
 410				buffer[0] = settings->reg_settings_6g[i].i2c_reg_index;
 411				buffer[1] = settings->reg_settings_6g[i].i2c_reg_val;
 412				i2c_success = write_i2c(pipe_ctx, slave_address,
 413							buffer, sizeof(buffer));
 414				RETIMER_REDRIVER_INFO("above 340Mhz: retimer write to slave_address = 0x%x,\
 415					offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 416					slave_address, buffer[0], buffer[1], i2c_success?1:0);
 417
 418				if (!i2c_success)
 419					goto i2c_write_fail;
 420
 421				/* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
 422				 * needs to be set to 1 on every 0xA-0xC write.
 423				 */
 424				if (settings->reg_settings_6g[i].i2c_reg_index == 0xA ||
 425					settings->reg_settings_6g[i].i2c_reg_index == 0xB ||
 426					settings->reg_settings_6g[i].i2c_reg_index == 0xC) {
 427
 428					/* Query current value from offset 0xA */
 429					if (settings->reg_settings_6g[i].i2c_reg_index == 0xA)
 430						value = settings->reg_settings_6g[i].i2c_reg_val;
 431					else {
 432						i2c_success =
 433								link_query_ddc_data(
 434								pipe_ctx->stream->link->ddc,
 435								slave_address, &offset, 1, &value, 1);
 436						if (!i2c_success)
 437							goto i2c_write_fail;
 438					}
 439
 440					buffer[0] = offset;
 441					/* Set APPLY_RX_TX_CHANGE bit to 1 */
 442					buffer[1] = value | apply_rx_tx_change;
 443					i2c_success = write_i2c(pipe_ctx, slave_address,
 444							buffer, sizeof(buffer));
 445					RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
 446						offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 447						slave_address, buffer[0], buffer[1], i2c_success?1:0);
 448					if (!i2c_success)
 449						goto i2c_write_fail;
 450				}
 451			}
 452		}
 453	}
 454
 455	if (is_vga_mode) {
 456		/* Program additional settings if using 640x480 resolution */
 457
 458		/* Write offset 0xFF to 0x01 */
 459		buffer[0] = 0xff;
 460		buffer[1] = 0x01;
 461		i2c_success = write_i2c(pipe_ctx, slave_address,
 462				buffer, sizeof(buffer));
 463		RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
 464				offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 465				slave_address, buffer[0], buffer[1], i2c_success?1:0);
 466		if (!i2c_success)
 467			goto i2c_write_fail;
 468
 469		/* Write offset 0x00 to 0x23 */
 470		buffer[0] = 0x00;
 471		buffer[1] = 0x23;
 472		i2c_success = write_i2c(pipe_ctx, slave_address,
 473				buffer, sizeof(buffer));
 474		RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
 475			offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 476			slave_address, buffer[0], buffer[1], i2c_success?1:0);
 477		if (!i2c_success)
 478			goto i2c_write_fail;
 479
 480		/* Write offset 0xff to 0x00 */
 481		buffer[0] = 0xff;
 482		buffer[1] = 0x00;
 483		i2c_success = write_i2c(pipe_ctx, slave_address,
 484				buffer, sizeof(buffer));
 485		RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
 486			offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 487			slave_address, buffer[0], buffer[1], i2c_success?1:0);
 488		if (!i2c_success)
 489			goto i2c_write_fail;
 490
 491	}
 492
 493	return;
 494
 495i2c_write_fail:
 496	DC_LOG_DEBUG("Set retimer failed");
 497}
 498
 499static void write_i2c_default_retimer_setting(
 500		struct pipe_ctx *pipe_ctx,
 501		bool is_vga_mode,
 502		bool is_over_340mhz)
 503{
 504	uint8_t slave_address = (0xBA >> 1);
 505	uint8_t buffer[2];
 506	bool i2c_success = false;
 507	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
 508
 509	memset(&buffer, 0, sizeof(buffer));
 510
 511	/* Program Slave Address for tuning single integrity */
 512	/* Write offset 0x0A to 0x13 */
 513	buffer[0] = 0x0A;
 514	buffer[1] = 0x13;
 515	i2c_success = write_i2c(pipe_ctx, slave_address,
 516			buffer, sizeof(buffer));
 517	RETIMER_REDRIVER_INFO("retimer writes default setting to slave_address = 0x%x,\
 518		offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 519		slave_address, buffer[0], buffer[1], i2c_success?1:0);
 520	if (!i2c_success)
 521		goto i2c_write_fail;
 522
 523	/* Write offset 0x0A to 0x17 */
 524	buffer[0] = 0x0A;
 525	buffer[1] = 0x17;
 526	i2c_success = write_i2c(pipe_ctx, slave_address,
 527			buffer, sizeof(buffer));
 528	RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
 529		offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 530		slave_address, buffer[0], buffer[1], i2c_success?1:0);
 531	if (!i2c_success)
 532		goto i2c_write_fail;
 533
 534	/* Write offset 0x0B to 0xDA or 0xD8 */
 535	buffer[0] = 0x0B;
 536	buffer[1] = is_over_340mhz ? 0xDA : 0xD8;
 537	i2c_success = write_i2c(pipe_ctx, slave_address,
 538			buffer, sizeof(buffer));
 539	RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
 540		offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 541		slave_address, buffer[0], buffer[1], i2c_success?1:0);
 542	if (!i2c_success)
 543		goto i2c_write_fail;
 544
 545	/* Write offset 0x0A to 0x17 */
 546	buffer[0] = 0x0A;
 547	buffer[1] = 0x17;
 548	i2c_success = write_i2c(pipe_ctx, slave_address,
 549			buffer, sizeof(buffer));
 550	RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
 551		offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
 552		slave_address, buffer[0], buffer[1], i2c_success?1:0);
 553	if (!i2c_success)
 554		goto i2c_write_fail;
 555
 556	/* Write offset 0x0C to 0x1D or 0x91 */
 557	buffer[0] = 0x0C;
 558	buffer[1] = is_over_340mhz ? 0x1D : 0x91;
 559	i2c_success = write_i2c(pipe_ctx, slave_address,
 560			buffer, sizeof(buffer));
 561	RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
 562		offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 563		slave_address, buffer[0], buffer[1], i2c_success?1:0);
 564	if (!i2c_success)
 565		goto i2c_write_fail;
 566
 567	/* Write offset 0x0A to 0x17 */
 568	buffer[0] = 0x0A;
 569	buffer[1] = 0x17;
 570	i2c_success = write_i2c(pipe_ctx, slave_address,
 571			buffer, sizeof(buffer));
 572	RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
 573		offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 574		slave_address, buffer[0], buffer[1], i2c_success?1:0);
 575	if (!i2c_success)
 576		goto i2c_write_fail;
 577
 578
 579	if (is_vga_mode) {
 580		/* Program additional settings if using 640x480 resolution */
 581
 582		/* Write offset 0xFF to 0x01 */
 583		buffer[0] = 0xff;
 584		buffer[1] = 0x01;
 585		i2c_success = write_i2c(pipe_ctx, slave_address,
 586				buffer, sizeof(buffer));
 587		RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
 588			offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
 589			slave_address, buffer[0], buffer[1], i2c_success?1:0);
 590		if (!i2c_success)
 591			goto i2c_write_fail;
 592
 593		/* Write offset 0x00 to 0x23 */
 594		buffer[0] = 0x00;
 595		buffer[1] = 0x23;
 596		i2c_success = write_i2c(pipe_ctx, slave_address,
 597				buffer, sizeof(buffer));
 598		RETIMER_REDRIVER_INFO("retimer write to slave_addr = 0x%x,\
 599			offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n",
 600			slave_address, buffer[0], buffer[1], i2c_success?1:0);
 601		if (!i2c_success)
 602			goto i2c_write_fail;
 603
 604		/* Write offset 0xff to 0x00 */
 605		buffer[0] = 0xff;
 606		buffer[1] = 0x00;
 607		i2c_success = write_i2c(pipe_ctx, slave_address,
 608				buffer, sizeof(buffer));
 609		RETIMER_REDRIVER_INFO("retimer write default setting to slave_addr = 0x%x,\
 610			offset = 0x%x, reg_val= 0x%x, i2c_success = %d end here\n",
 611			slave_address, buffer[0], buffer[1], i2c_success?1:0);
 612		if (!i2c_success)
 613			goto i2c_write_fail;
 614	}
 615
 616	return;
 617
 618i2c_write_fail:
 619	DC_LOG_DEBUG("Set default retimer failed");
 620}
 621
 622static void write_i2c_redriver_setting(
 623		struct pipe_ctx *pipe_ctx,
 624		bool is_over_340mhz)
 625{
 626	uint8_t slave_address = (0xF0 >> 1);
 627	uint8_t buffer[16];
 628	bool i2c_success = false;
 629	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
 630
 631	memset(&buffer, 0, sizeof(buffer));
 632
 633	// Program Slave Address for tuning single integrity
 634	buffer[3] = 0x4E;
 635	buffer[4] = 0x4E;
 636	buffer[5] = 0x4E;
 637	buffer[6] = is_over_340mhz ? 0x4E : 0x4A;
 638
 639	i2c_success = write_i2c(pipe_ctx, slave_address,
 640					buffer, sizeof(buffer));
 641	RETIMER_REDRIVER_INFO("redriver write 0 to all 16 reg offset expect following:\n\
 642		\t slave_addr = 0x%x, offset[3] = 0x%x, offset[4] = 0x%x,\
 643		offset[5] = 0x%x,offset[6] is_over_340mhz = 0x%x,\
 644		i2c_success = %d\n",
 645		slave_address, buffer[3], buffer[4], buffer[5], buffer[6], i2c_success?1:0);
 646
 647	if (!i2c_success)
 648		DC_LOG_DEBUG("Set redriver failed");
 649}
 650
 651static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 652{
 653	struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp;
 654	struct link_encoder *link_enc = NULL;
 655	struct cp_psp_stream_config config = {0};
 656	enum dp_panel_mode panel_mode =
 657			dp_get_panel_mode(pipe_ctx->stream->link);
 658
 659	if (cp_psp == NULL || cp_psp->funcs.update_stream_config == NULL)
 660		return;
 661
 662	link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
 663	ASSERT(link_enc);
 664	if (link_enc == NULL)
 665		return;
 666
 667	/* otg instance */
 668	config.otg_inst = (uint8_t) pipe_ctx->stream_res.tg->inst;
 669
 670	/* dig front end */
 671	config.dig_fe = (uint8_t) pipe_ctx->stream_res.stream_enc->stream_enc_inst;
 672
 673	/* stream encoder index */
 674	config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA;
 675	if (dp_is_128b_132b_signal(pipe_ctx))
 676		config.stream_enc_idx =
 677				pipe_ctx->stream_res.hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0;
 678
 679	/* dig back end */
 680	config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst;
 681
 682	/* link encoder index */
 683	config.link_enc_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
 684	if (dp_is_128b_132b_signal(pipe_ctx))
 685		config.link_enc_idx = pipe_ctx->link_res.hpo_dp_link_enc->inst;
 686
 687	/* dio output index is dpia index for DPIA endpoint & dcio index by default */
 688	if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
 689		config.dio_output_idx = pipe_ctx->stream->link->link_id.enum_id - ENUM_ID_1;
 690	else
 691		config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
 692
 693
 694	/* phy index */
 695	config.phy_idx = resource_transmitter_to_phy_idx(
 696			pipe_ctx->stream->link->dc, link_enc->transmitter);
 697	if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
 698		/* USB4 DPIA doesn't use PHY in our soc, initialize it to 0 */
 699		config.phy_idx = 0;
 700
 701	/* stream properties */
 702	config.assr_enabled = (panel_mode == DP_PANEL_MODE_EDP) ? 1 : 0;
 703	config.mst_enabled = (pipe_ctx->stream->signal ==
 704			SIGNAL_TYPE_DISPLAY_PORT_MST) ? 1 : 0;
 705	config.dp2_enabled = dp_is_128b_132b_signal(pipe_ctx) ? 1 : 0;
 706	config.usb4_enabled = (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) ?
 707			1 : 0;
 708	config.dpms_off = dpms_off;
 709
 710	/* dm stream context */
 711	config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context;
 712
 713	cp_psp->funcs.update_stream_config(cp_psp->handle, &config);
 714}
 715
 716static void set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
 717{
 718	struct dc  *dc = pipe_ctx->stream->ctx->dc;
 719
 720	if (!dc_is_hdmi_signal(pipe_ctx->stream->signal))
 721		return;
 722
 723	dc->hwss.set_avmute(pipe_ctx, enable);
 724}
 725
 726static void enable_mst_on_sink(struct dc_link *link, bool enable)
 727{
 728	unsigned char mstmCntl;
 729
 730	core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
 731	if (enable)
 732		mstmCntl |= DP_MST_EN;
 733	else
 734		mstmCntl &= (~DP_MST_EN);
 735
 736	core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
 737}
 738
 739static void dsc_optc_config_log(struct display_stream_compressor *dsc,
 740		struct dsc_optc_config *config)
 741{
 742	uint32_t precision = 1 << 28;
 743	uint32_t bytes_per_pixel_int = config->bytes_per_pixel / precision;
 744	uint32_t bytes_per_pixel_mod = config->bytes_per_pixel % precision;
 745	uint64_t ll_bytes_per_pix_fraq = bytes_per_pixel_mod;
 746	DC_LOGGER_INIT(dsc->ctx->logger);
 747
 748	/* 7 fractional digits decimal precision for bytes per pixel is enough because DSC
 749	 * bits per pixel precision is 1/16th of a pixel, which means bytes per pixel precision is
 750	 * 1/16/8 = 1/128 of a byte, or 0.0078125 decimal
 751	 */
 752	ll_bytes_per_pix_fraq *= 10000000;
 753	ll_bytes_per_pix_fraq /= precision;
 754
 755	DC_LOG_DSC("\tbytes_per_pixel 0x%08x (%d.%07d)",
 756			config->bytes_per_pixel, bytes_per_pixel_int, (uint32_t)ll_bytes_per_pix_fraq);
 757	DC_LOG_DSC("\tis_pixel_format_444 %d", config->is_pixel_format_444);
 758	DC_LOG_DSC("\tslice_width %d", config->slice_width);
 759}
 760
 761static bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
 762{
 763	struct dc *dc = pipe_ctx->stream->ctx->dc;
 764	struct dc_stream_state *stream = pipe_ctx->stream;
 765	bool result = false;
 766
 767	if (dc_is_virtual_signal(stream->signal))
 768		result = true;
 769	else
 770		result = dm_helpers_dp_write_dsc_enable(dc->ctx, stream, enable);
 771	return result;
 772}
 773
 774/* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
 775 * i.e. after dp_enable_dsc_on_rx() had been called
 776 */
 777void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 778{
 779	/* TODO: Move this to HWSS as this is hardware programming sequence not a
 780	 * link layer sequence
 781	 */
 782	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 783	struct dc *dc = pipe_ctx->stream->ctx->dc;
 784	struct dc_stream_state *stream = pipe_ctx->stream;
 785	struct pipe_ctx *odm_pipe;
 786	int opp_cnt = 1;
 787	struct dccg *dccg = dc->res_pool->dccg;
 788	/* It has been found that when DSCCLK is lower than 16Mhz, we will get DCN
 789	 * register access hung. When DSCCLk is based on refclk, DSCCLk is always a
 790	 * fixed value higher than 16Mhz so the issue doesn't occur. When DSCCLK is
 791	 * generated by DTO, DSCCLK would be based on 1/3 dispclk. For small timings
 792	 * with DSC such as 480p60Hz, the dispclk could be low enough to trigger
 793	 * this problem. We are implementing a workaround here to keep using dscclk
 794	 * based on fixed value refclk when timing is smaller than 3x16Mhz (i.e
 795	 * 48Mhz) pixel clock to avoid hitting this problem.
 796	 */
 797	bool should_use_dto_dscclk = (dccg->funcs->set_dto_dscclk != NULL) &&
 798			stream->timing.pix_clk_100hz > 480000;
 799	DC_LOGGER_INIT(dsc->ctx->logger);
 800
 801	for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
 802		opp_cnt++;
 803
 804	if (enable) {
 805		struct dsc_config dsc_cfg;
 806		struct dsc_optc_config dsc_optc_cfg;
 807		enum optc_dsc_mode optc_dsc_mode;
 808
 809		/* Enable DSC hw block */
 810		dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
 811		dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
 812		dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
 813		dsc_cfg.color_depth = stream->timing.display_color_depth;
 814		dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
 815		dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
 816		ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
 817		dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
 818
 819		dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
 820		dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
 821		if (should_use_dto_dscclk)
 822			dccg->funcs->set_dto_dscclk(dccg, dsc->inst);
 823		for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
 824			struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
 825
 826			odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
 827			odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
 828			if (should_use_dto_dscclk)
 829				dccg->funcs->set_dto_dscclk(dccg, odm_dsc->inst);
 830		}
 831		dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
 832		dsc_cfg.pic_width *= opp_cnt;
 833
 834		optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
 835
 836		/* Enable DSC in encoder */
 837		if (dc_is_dp_signal(stream->signal) && !dp_is_128b_132b_signal(pipe_ctx)) {
 838			DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
 839			dsc_optc_config_log(dsc, &dsc_optc_cfg);
 840			pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
 841									optc_dsc_mode,
 842									dsc_optc_cfg.bytes_per_pixel,
 843									dsc_optc_cfg.slice_width);
 844
 845			/* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
 846		}
 847
 848		/* Enable DSC in OPTC */
 849		DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
 850		dsc_optc_config_log(dsc, &dsc_optc_cfg);
 851		pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
 852							optc_dsc_mode,
 853							dsc_optc_cfg.bytes_per_pixel,
 854							dsc_optc_cfg.slice_width);
 855	} else {
 856		/* disable DSC in OPTC */
 857		pipe_ctx->stream_res.tg->funcs->set_dsc_config(
 858				pipe_ctx->stream_res.tg,
 859				OPTC_DSC_DISABLED, 0, 0);
 860
 861		/* disable DSC in stream encoder */
 862		if (dc_is_dp_signal(stream->signal)) {
 863			if (dp_is_128b_132b_signal(pipe_ctx))
 864				pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
 865										pipe_ctx->stream_res.hpo_dp_stream_enc,
 866										false,
 867										NULL,
 868										true);
 869			else {
 870				pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
 871						pipe_ctx->stream_res.stream_enc,
 872						OPTC_DSC_DISABLED, 0, 0);
 873				pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
 874							pipe_ctx->stream_res.stream_enc, false, NULL, true);
 875			}
 876		}
 877
 878		/* disable DSC block */
 879		if (dccg->funcs->set_ref_dscclk)
 880			dccg->funcs->set_ref_dscclk(dccg, pipe_ctx->stream_res.dsc->inst);
 881		pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
 882		for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
 883			if (dccg->funcs->set_ref_dscclk)
 884				dccg->funcs->set_ref_dscclk(dccg, odm_pipe->stream_res.dsc->inst);
 885			odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
 886		}
 887	}
 888}
 889
 890/*
 891 * For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled;
 892 * hence PPS info packet update need to use frame update instead of immediate update.
 893 * Added parameter immediate_update for this purpose.
 894 * The decision to use frame update is hard-coded in function dp_update_dsc_config(),
 895 * which is the only place where a "false" would be passed in for param immediate_update.
 896 *
 897 * immediate_update is only applicable when DSC is enabled.
 898 */
 899bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update)
 900{
 901	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 902	struct dc_stream_state *stream = pipe_ctx->stream;
 903
 904	if (!pipe_ctx->stream->timing.flags.DSC)
 905		return false;
 906
 907	if (!dsc)
 908		return false;
 909
 910	DC_LOGGER_INIT(dsc->ctx->logger);
 911
 912	if (enable) {
 913		struct dsc_config dsc_cfg;
 914		uint8_t dsc_packed_pps[128];
 915
 916		memset(&dsc_cfg, 0, sizeof(dsc_cfg));
 917		memset(dsc_packed_pps, 0, 128);
 918
 919		/* Enable DSC hw block */
 920		dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
 921		dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
 922		dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
 923		dsc_cfg.color_depth = stream->timing.display_color_depth;
 924		dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
 925		dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
 926
 927		dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
 928		memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps));
 929		if (dc_is_dp_signal(stream->signal)) {
 930			DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
 931			if (dp_is_128b_132b_signal(pipe_ctx))
 932				pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
 933										pipe_ctx->stream_res.hpo_dp_stream_enc,
 934										true,
 935										&dsc_packed_pps[0],
 936										immediate_update);
 937			else
 938				pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
 939						pipe_ctx->stream_res.stream_enc,
 940						true,
 941						&dsc_packed_pps[0],
 942						immediate_update);
 943		}
 944	} else {
 945		/* disable DSC PPS in stream encoder */
 946		memset(&stream->dsc_packed_pps[0], 0, sizeof(stream->dsc_packed_pps));
 947		if (dc_is_dp_signal(stream->signal)) {
 948			if (dp_is_128b_132b_signal(pipe_ctx))
 949				pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
 950										pipe_ctx->stream_res.hpo_dp_stream_enc,
 951										false,
 952										NULL,
 953										true);
 954			else
 955				pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
 956						pipe_ctx->stream_res.stream_enc, false, NULL, true);
 957		}
 958	}
 959
 960	return true;
 961}
 962
 963bool link_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
 964{
 965	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 966	bool result = false;
 967
 968	if (!pipe_ctx->stream->timing.flags.DSC)
 969		goto out;
 970	if (!dsc)
 971		goto out;
 972
 973	if (enable) {
 974		{
 975			link_set_dsc_on_stream(pipe_ctx, true);
 976			result = true;
 977		}
 978	} else {
 979		dp_set_dsc_on_rx(pipe_ctx, false);
 980		link_set_dsc_on_stream(pipe_ctx, false);
 981		result = true;
 982	}
 983out:
 984	return result;
 985}
 986
 987bool link_update_dsc_config(struct pipe_ctx *pipe_ctx)
 988{
 989	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 990
 991	if (!pipe_ctx->stream->timing.flags.DSC)
 992		return false;
 993	if (!dsc)
 994		return false;
 995
 996	link_set_dsc_on_stream(pipe_ctx, true);
 997	link_set_dsc_pps_packet(pipe_ctx, true, false);
 998	return true;
 999}
1000
1001static void enable_stream_features(struct pipe_ctx *pipe_ctx)
1002{
1003	struct dc_stream_state *stream = pipe_ctx->stream;
1004
1005	if (pipe_ctx->stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST) {
1006		struct dc_link *link = stream->link;
1007		union down_spread_ctrl old_downspread;
1008		union down_spread_ctrl new_downspread;
1009
1010		memset(&old_downspread, 0, sizeof(old_downspread));
1011
1012		core_link_read_dpcd(link, DP_DOWNSPREAD_CTRL,
1013				&old_downspread.raw, sizeof(old_downspread));
1014
1015		new_downspread.raw = old_downspread.raw;
1016
1017		new_downspread.bits.IGNORE_MSA_TIMING_PARAM =
1018				(stream->ignore_msa_timing_param) ? 1 : 0;
1019
1020		if (new_downspread.raw != old_downspread.raw) {
1021			core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
1022				&new_downspread.raw, sizeof(new_downspread));
1023		}
1024
1025	} else {
1026		dm_helpers_mst_enable_stream_features(stream);
1027	}
1028}
1029
1030static void log_vcp_x_y(const struct dc_link *link, struct fixed31_32 avg_time_slots_per_mtp)
1031{
1032	const uint32_t VCP_Y_PRECISION = 1000;
1033	uint64_t vcp_x, vcp_y;
1034	DC_LOGGER_INIT(link->ctx->logger);
1035
1036	// Add 0.5*(1/VCP_Y_PRECISION) to round up to decimal precision
1037	avg_time_slots_per_mtp = dc_fixpt_add(
1038			avg_time_slots_per_mtp,
1039			dc_fixpt_from_fraction(
1040				1,
1041				2*VCP_Y_PRECISION));
1042
1043	vcp_x = dc_fixpt_floor(
1044			avg_time_slots_per_mtp);
1045	vcp_y = dc_fixpt_floor(
1046			dc_fixpt_mul_int(
1047				dc_fixpt_sub_int(
1048					avg_time_slots_per_mtp,
1049					dc_fixpt_floor(
1050							avg_time_slots_per_mtp)),
1051				VCP_Y_PRECISION));
1052
1053
1054	if (link->type == dc_connection_mst_branch)
1055		DC_LOG_DP2("MST Update Payload: set_throttled_vcp_size slot X.Y for MST stream "
1056				"X: %llu "
1057				"Y: %llu/%d",
1058				vcp_x,
1059				vcp_y,
1060				VCP_Y_PRECISION);
1061	else
1062		DC_LOG_DP2("SST Update Payload: set_throttled_vcp_size slot X.Y for SST stream "
1063				"X: %llu "
1064				"Y: %llu/%d",
1065				vcp_x,
1066				vcp_y,
1067				VCP_Y_PRECISION);
1068}
1069
1070static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream)
1071{
1072	struct fixed31_32 mbytes_per_sec;
1073	uint32_t link_rate_in_mbytes_per_sec = dp_link_bandwidth_kbps(stream->link,
1074			&stream->link->cur_link_settings);
1075	link_rate_in_mbytes_per_sec /= 8000; /* Kbits to MBytes */
1076
1077	mbytes_per_sec = dc_fixpt_from_int(link_rate_in_mbytes_per_sec);
1078
1079	return dc_fixpt_div_int(mbytes_per_sec, 54);
1080}
1081
1082static struct fixed31_32 get_pbn_from_bw_in_kbps(uint64_t kbps)
1083{
1084	struct fixed31_32 peak_kbps;
1085	uint32_t numerator = 0;
1086	uint32_t denominator = 1;
1087
1088	/*
1089	 * The 1.006 factor (margin 5300ppm + 300ppm ~ 0.6% as per spec) is not
1090	 * required when determining PBN/time slot utilization on the link between
1091	 * us and the branch, since that overhead is already accounted for in
1092	 * the get_pbn_per_slot function.
1093	 *
1094	 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
1095	 * common multiplier to render an integer PBN for all link rate/lane
1096	 * counts combinations
1097	 * calculate
1098	 * peak_kbps *= (64/54)
1099	 * peak_kbps /= (8 * 1000) convert to bytes
1100	 */
1101
1102	numerator = 64;
1103	denominator = 54 * 8 * 1000;
1104	kbps *= numerator;
1105	peak_kbps = dc_fixpt_from_fraction(kbps, denominator);
1106
1107	return peak_kbps;
1108}
1109
1110static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
1111{
1112	uint64_t kbps;
1113	enum dc_link_encoding_format link_encoding;
1114
1115	if (dp_is_128b_132b_signal(pipe_ctx))
1116		link_encoding = DC_LINK_ENCODING_DP_128b_132b;
1117	else
1118		link_encoding = DC_LINK_ENCODING_DP_8b_10b;
1119
1120	kbps = dc_bandwidth_in_kbps_from_timing(&pipe_ctx->stream->timing, link_encoding);
1121	return get_pbn_from_bw_in_kbps(kbps);
1122}
1123
1124
1125// TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
1126static void get_lane_status(
1127	struct dc_link *link,
1128	uint32_t lane_count,
1129	union lane_status *status,
1130	union lane_align_status_updated *status_updated)
1131{
1132	unsigned int lane;
1133	uint8_t dpcd_buf[3] = {0};
1134
1135	if (status == NULL || status_updated == NULL) {
1136		return;
1137	}
1138
1139	core_link_read_dpcd(
1140			link,
1141			DP_LANE0_1_STATUS,
1142			dpcd_buf,
1143			sizeof(dpcd_buf));
1144
1145	for (lane = 0; lane < lane_count; lane++) {
1146		status[lane].raw = dp_get_nibble_at_index(&dpcd_buf[0], lane);
1147	}
1148
1149	status_updated->raw = dpcd_buf[2];
1150}
1151
1152static bool poll_for_allocation_change_trigger(struct dc_link *link)
1153{
1154	/*
1155	 * wait for ACT handled
1156	 */
1157	int i;
1158	const int act_retries = 30;
1159	enum act_return_status result = ACT_FAILED;
1160	union payload_table_update_status update_status = {0};
1161	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
1162	union lane_align_status_updated lane_status_updated;
1163	DC_LOGGER_INIT(link->ctx->logger);
1164
1165	if (link->aux_access_disabled)
1166		return true;
1167	for (i = 0; i < act_retries; i++) {
1168		get_lane_status(link, link->cur_link_settings.lane_count, dpcd_lane_status, &lane_status_updated);
1169
1170		if (!dp_is_cr_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
1171				!dp_is_ch_eq_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
1172				!dp_is_symbol_locked(link->cur_link_settings.lane_count, dpcd_lane_status) ||
1173				!dp_is_interlane_aligned(lane_status_updated)) {
1174			DC_LOG_ERROR("SST Update Payload: Link loss occurred while "
1175					"polling for ACT handled.");
1176			result = ACT_LINK_LOST;
1177			break;
1178		}
1179		core_link_read_dpcd(
1180				link,
1181				DP_PAYLOAD_TABLE_UPDATE_STATUS,
1182				&update_status.raw,
1183				1);
1184
1185		if (update_status.bits.ACT_HANDLED == 1) {
1186			DC_LOG_DP2("SST Update Payload: ACT handled by downstream.");
1187			result = ACT_SUCCESS;
1188			break;
1189		}
1190
1191		fsleep(5000);
1192	}
1193
1194	if (result == ACT_FAILED) {
1195		DC_LOG_ERROR("SST Update Payload: ACT still not handled after retries, "
1196				"continue on. Something is wrong with the branch.");
1197	}
1198
1199	return (result == ACT_SUCCESS);
1200}
1201
1202static void update_mst_stream_alloc_table(
1203	struct dc_link *link,
1204	struct stream_encoder *stream_enc,
1205	struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
1206	const struct dc_dp_mst_stream_allocation_table *proposed_table)
1207{
1208	struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
1209	struct link_mst_stream_allocation *dc_alloc;
1210
1211	int i;
1212	int j;
1213
1214	/* if DRM proposed_table has more than one new payload */
1215	ASSERT(proposed_table->stream_count -
1216			link->mst_stream_alloc_table.stream_count < 2);
1217
1218	/* copy proposed_table to link, add stream encoder */
1219	for (i = 0; i < proposed_table->stream_count; i++) {
1220
1221		for (j = 0; j < link->mst_stream_alloc_table.stream_count; j++) {
1222			dc_alloc =
1223			&link->mst_stream_alloc_table.stream_allocations[j];
1224
1225			if (dc_alloc->vcp_id ==
1226				proposed_table->stream_allocations[i].vcp_id) {
1227
1228				work_table[i] = *dc_alloc;
1229				work_table[i].slot_count = proposed_table->stream_allocations[i].slot_count;
1230				break; /* exit j loop */
1231			}
1232		}
1233
1234		/* new vcp_id */
1235		if (j == link->mst_stream_alloc_table.stream_count) {
1236			work_table[i].vcp_id =
1237				proposed_table->stream_allocations[i].vcp_id;
1238			work_table[i].slot_count =
1239				proposed_table->stream_allocations[i].slot_count;
1240			work_table[i].stream_enc = stream_enc;
1241			work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
1242		}
1243	}
1244
1245	/* update link->mst_stream_alloc_table with work_table */
1246	link->mst_stream_alloc_table.stream_count =
1247			proposed_table->stream_count;
1248	for (i = 0; i < MAX_CONTROLLER_NUM; i++)
1249		link->mst_stream_alloc_table.stream_allocations[i] =
1250				work_table[i];
1251}
1252
1253static void remove_stream_from_alloc_table(
1254		struct dc_link *link,
1255		struct stream_encoder *dio_stream_enc,
1256		struct hpo_dp_stream_encoder *hpo_dp_stream_enc)
1257{
1258	int i = 0;
1259	struct link_mst_stream_allocation_table *table =
1260			&link->mst_stream_alloc_table;
1261
1262	if (hpo_dp_stream_enc) {
1263		for (; i < table->stream_count; i++)
1264			if (hpo_dp_stream_enc == table->stream_allocations[i].hpo_dp_stream_enc)
1265				break;
1266	} else {
1267		for (; i < table->stream_count; i++)
1268			if (dio_stream_enc == table->stream_allocations[i].stream_enc)
1269				break;
1270	}
1271
1272	if (i < table->stream_count) {
1273		i++;
1274		for (; i < table->stream_count; i++)
1275			table->stream_allocations[i-1] = table->stream_allocations[i];
1276		memset(&table->stream_allocations[table->stream_count-1], 0,
1277				sizeof(struct link_mst_stream_allocation));
1278		table->stream_count--;
1279	}
1280}
1281
1282static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
1283{
1284	struct dc_stream_state *stream = pipe_ctx->stream;
1285	struct dc_link *link = stream->link;
1286	struct dc_dp_mst_stream_allocation_table proposed_table = {0};
1287	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
1288	int i;
1289	bool mst_mode = (link->type == dc_connection_mst_branch);
1290	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
1291	const struct dc_link_settings empty_link_settings = {0};
1292	DC_LOGGER_INIT(link->ctx->logger);
1293
1294	/* deallocate_mst_payload is called before disable link. When mode or
1295	 * disable/enable monitor, new stream is created which is not in link
1296	 * stream[] yet. For this, payload is not allocated yet, so de-alloc
1297	 * should not done. For new mode set, map_resources will get engine
1298	 * for new stream, so stream_enc->id should be validated until here.
1299	 */
1300
1301	/* slot X.Y */
1302	if (link_hwss->ext.set_throttled_vcp_size)
1303		link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
1304	if (link_hwss->ext.set_hblank_min_symbol_width)
1305		link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
1306				&empty_link_settings,
1307				avg_time_slots_per_mtp);
1308
1309	if (mst_mode) {
1310		/* when link is in mst mode, reply on mst manager to remove
1311		 * payload
1312		 */
1313		if (dm_helpers_dp_mst_write_payload_allocation_table(
1314				stream->ctx,
1315				stream,
1316				&proposed_table,
1317				false))
1318			update_mst_stream_alloc_table(
1319					link,
1320					pipe_ctx->stream_res.stream_enc,
1321					pipe_ctx->stream_res.hpo_dp_stream_enc,
1322					&proposed_table);
1323		else
1324			DC_LOG_WARNING("Failed to update"
1325					"MST allocation table for"
1326					"pipe idx:%d\n",
1327					pipe_ctx->pipe_idx);
1328	} else {
1329		/* when link is no longer in mst mode (mst hub unplugged),
1330		 * remove payload with default dc logic
1331		 */
1332		remove_stream_from_alloc_table(link, pipe_ctx->stream_res.stream_enc,
1333				pipe_ctx->stream_res.hpo_dp_stream_enc);
1334	}
1335
1336	DC_LOG_MST("%s"
1337			"stream_count: %d: ",
1338			__func__,
1339			link->mst_stream_alloc_table.stream_count);
1340
1341	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
1342		DC_LOG_MST("stream_enc[%d]: %p      "
1343		"stream[%d].hpo_dp_stream_enc: %p      "
1344		"stream[%d].vcp_id: %d      "
1345		"stream[%d].slot_count: %d\n",
1346		i,
1347		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
1348		i,
1349		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
1350		i,
1351		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
1352		i,
1353		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
1354	}
1355
1356	/* update mst stream allocation table hardware state */
1357	if (link_hwss->ext.update_stream_allocation_table == NULL ||
1358			link_dp_get_encoding_format(&link->cur_link_settings) == DP_UNKNOWN_ENCODING) {
1359		DC_LOG_DEBUG("Unknown encoding format\n");
1360		return DC_ERROR_UNEXPECTED;
1361	}
1362
1363	link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
1364			&link->mst_stream_alloc_table);
1365
1366	if (mst_mode)
1367		dm_helpers_dp_mst_poll_for_allocation_change_trigger(
1368			stream->ctx,
1369			stream);
1370
1371	dm_helpers_dp_mst_update_mst_mgr_for_deallocation(
1372			stream->ctx,
1373			stream);
1374
1375	return DC_OK;
1376}
1377
1378/* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table
1379 * because stream_encoder is not exposed to dm
1380 */
1381static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx)
1382{
1383	struct dc_stream_state *stream = pipe_ctx->stream;
1384	struct dc_link *link = stream->link;
1385	struct dc_dp_mst_stream_allocation_table proposed_table = {0};
1386	struct fixed31_32 avg_time_slots_per_mtp;
1387	struct fixed31_32 pbn;
1388	struct fixed31_32 pbn_per_slot;
1389	int i;
1390	enum act_return_status ret;
1391	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
1392	DC_LOGGER_INIT(link->ctx->logger);
1393
1394	/* enable_link_dp_mst already check link->enabled_stream_count
1395	 * and stream is in link->stream[]. This is called during set mode,
1396	 * stream_enc is available.
1397	 */
1398
1399	/* get calculate VC payload for stream: stream_alloc */
1400	if (dm_helpers_dp_mst_write_payload_allocation_table(
1401		stream->ctx,
1402		stream,
1403		&proposed_table,
1404		true))
1405		update_mst_stream_alloc_table(
1406					link,
1407					pipe_ctx->stream_res.stream_enc,
1408					pipe_ctx->stream_res.hpo_dp_stream_enc,
1409					&proposed_table);
1410	else
1411		DC_LOG_WARNING("Failed to update"
1412				"MST allocation table for"
1413				"pipe idx:%d\n",
1414				pipe_ctx->pipe_idx);
1415
1416	DC_LOG_MST("%s  "
1417			"stream_count: %d: \n ",
1418			__func__,
1419			link->mst_stream_alloc_table.stream_count);
1420
1421	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
1422		DC_LOG_MST("stream_enc[%d]: %p      "
1423		"stream[%d].hpo_dp_stream_enc: %p      "
1424		"stream[%d].vcp_id: %d      "
1425		"stream[%d].slot_count: %d\n",
1426		i,
1427		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
1428		i,
1429		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
1430		i,
1431		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
1432		i,
1433		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
1434	}
1435
1436	ASSERT(proposed_table.stream_count > 0);
1437
1438	/* program DP source TX for payload */
1439	if (link_hwss->ext.update_stream_allocation_table == NULL ||
1440			link_dp_get_encoding_format(&link->cur_link_settings) == DP_UNKNOWN_ENCODING) {
1441		DC_LOG_ERROR("Failure: unknown encoding format\n");
1442		return DC_ERROR_UNEXPECTED;
1443	}
1444
1445	link_hwss->ext.update_stream_allocation_table(link,
1446			&pipe_ctx->link_res,
1447			&link->mst_stream_alloc_table);
1448
1449	/* send down message */
1450	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
1451			stream->ctx,
1452			stream);
1453
1454	if (ret != ACT_LINK_LOST)
1455		dm_helpers_dp_mst_send_payload_allocation(
1456				stream->ctx,
1457				stream);
1458
1459	/* slot X.Y for only current stream */
1460	pbn_per_slot = get_pbn_per_slot(stream);
1461	if (pbn_per_slot.value == 0) {
1462		DC_LOG_ERROR("Failure: pbn_per_slot==0 not allowed. Cannot continue, returning DC_UNSUPPORTED_VALUE.\n");
1463		return DC_UNSUPPORTED_VALUE;
1464	}
1465	pbn = get_pbn_from_timing(pipe_ctx);
1466	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
1467
1468	log_vcp_x_y(link, avg_time_slots_per_mtp);
1469
1470	if (link_hwss->ext.set_throttled_vcp_size)
1471		link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
1472	if (link_hwss->ext.set_hblank_min_symbol_width)
1473		link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
1474				&link->cur_link_settings,
1475				avg_time_slots_per_mtp);
1476
1477	return DC_OK;
1478}
1479
1480struct fixed31_32 link_calculate_sst_avg_time_slots_per_mtp(
1481		const struct dc_stream_state *stream,
1482		const struct dc_link *link)
1483{
1484	struct fixed31_32 link_bw_effective =
1485			dc_fixpt_from_int(
1486					dp_link_bandwidth_kbps(link, &link->cur_link_settings));
1487	struct fixed31_32 timeslot_bw_effective =
1488			dc_fixpt_div_int(link_bw_effective, MAX_MTP_SLOT_COUNT);
1489	struct fixed31_32 timing_bw =
1490			dc_fixpt_from_int(
1491					dc_bandwidth_in_kbps_from_timing(&stream->timing,
1492							dc_link_get_highest_encoding_format(link)));
1493	struct fixed31_32 avg_time_slots_per_mtp =
1494			dc_fixpt_div(timing_bw, timeslot_bw_effective);
1495
1496	return avg_time_slots_per_mtp;
1497}
1498
1499
1500static bool write_128b_132b_sst_payload_allocation_table(
1501		const struct dc_stream_state *stream,
1502		struct dc_link *link,
1503		struct link_mst_stream_allocation_table *proposed_table,
1504		bool allocate)
1505{
1506	const uint8_t vc_id = 1; /// VC ID always 1 for SST
1507	const uint8_t start_time_slot = 0; /// Always start at time slot 0 for SST
1508	bool result = false;
1509	uint8_t req_slot_count = 0;
1510	struct fixed31_32 avg_time_slots_per_mtp = { 0 };
1511	union payload_table_update_status update_status = { 0 };
1512	const uint32_t max_retries = 30;
1513	uint32_t retries = 0;
1514	DC_LOGGER_INIT(link->ctx->logger);
1515
1516	if (allocate)	{
1517		avg_time_slots_per_mtp = link_calculate_sst_avg_time_slots_per_mtp(stream, link);
1518		req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
1519		/// Validation should filter out modes that exceed link BW
1520		ASSERT(req_slot_count <= MAX_MTP_SLOT_COUNT);
1521		if (req_slot_count > MAX_MTP_SLOT_COUNT)
1522			return false;
1523	} else {
1524		/// Leave req_slot_count = 0 if allocate is false.
1525	}
1526
1527	proposed_table->stream_count = 1; /// Always 1 stream for SST
1528	proposed_table->stream_allocations[0].slot_count = req_slot_count;
1529	proposed_table->stream_allocations[0].vcp_id = vc_id;
1530
1531	if (link->aux_access_disabled)
1532		return true;
1533
1534	/// Write DPCD 2C0 = 1 to start updating
1535	update_status.bits.VC_PAYLOAD_TABLE_UPDATED = 1;
1536	core_link_write_dpcd(
1537			link,
1538			DP_PAYLOAD_TABLE_UPDATE_STATUS,
1539			&update_status.raw,
1540			1);
1541
1542	/// Program the changes in DPCD 1C0 - 1C2
1543	ASSERT(vc_id == 1);
1544	core_link_write_dpcd(
1545			link,
1546			DP_PAYLOAD_ALLOCATE_SET,
1547			&vc_id,
1548			1);
1549
1550	ASSERT(start_time_slot == 0);
1551	core_link_write_dpcd(
1552			link,
1553			DP_PAYLOAD_ALLOCATE_START_TIME_SLOT,
1554			&start_time_slot,
1555			1);
1556
1557	core_link_write_dpcd(
1558			link,
1559			DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT,
1560			&req_slot_count,
1561			1);
1562
1563	/// Poll till DPCD 2C0 read 1
1564	/// Try for at least 150ms (30 retries, with 5ms delay after each attempt)
1565
1566	while (retries < max_retries) {
1567		if (core_link_read_dpcd(
1568				link,
1569				DP_PAYLOAD_TABLE_UPDATE_STATUS,
1570				&update_status.raw,
1571				1) == DC_OK) {
1572			if (update_status.bits.VC_PAYLOAD_TABLE_UPDATED == 1) {
1573				DC_LOG_DP2("SST Update Payload: downstream payload table updated.");
1574				result = true;
1575				break;
1576			}
1577		} else {
1578			union dpcd_rev dpcdRev;
1579
1580			if (core_link_read_dpcd(
1581					link,
1582					DP_DPCD_REV,
1583					&dpcdRev.raw,
1584					1) != DC_OK) {
1585				DC_LOG_ERROR("SST Update Payload: Unable to read DPCD revision "
1586						"of sink while polling payload table "
1587						"updated status bit.");
1588				break;
1589			}
1590		}
1591		retries++;
1592		fsleep(5000);
1593	}
1594
1595	if (!result && retries == max_retries) {
1596		DC_LOG_ERROR("SST Update Payload: Payload table not updated after retries, "
1597				"continue on. Something is wrong with the branch.");
1598		// TODO - DP2.0 Payload: Read and log the payload table from downstream branch
1599	}
1600
1601	return result;
1602}
1603
1604/*
1605 * Payload allocation/deallocation for SST introduced in DP2.0
1606 */
1607static enum dc_status update_sst_payload(struct pipe_ctx *pipe_ctx,
1608						 bool allocate)
1609{
1610	struct dc_stream_state *stream = pipe_ctx->stream;
1611	struct dc_link *link = stream->link;
1612	struct link_mst_stream_allocation_table proposed_table = {0};
1613	struct fixed31_32 avg_time_slots_per_mtp;
1614	const struct dc_link_settings empty_link_settings = {0};
1615	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
1616	DC_LOGGER_INIT(link->ctx->logger);
1617
1618	/* slot X.Y for SST payload deallocate */
1619	if (!allocate) {
1620		avg_time_slots_per_mtp = dc_fixpt_from_int(0);
1621
1622		log_vcp_x_y(link, avg_time_slots_per_mtp);
1623
1624		if (link_hwss->ext.set_throttled_vcp_size)
1625			link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
1626					avg_time_slots_per_mtp);
1627		if (link_hwss->ext.set_hblank_min_symbol_width)
1628			link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
1629					&empty_link_settings,
1630					avg_time_slots_per_mtp);
1631	}
1632
1633	/* calculate VC payload and update branch with new payload allocation table*/
1634	if (!write_128b_132b_sst_payload_allocation_table(
1635			stream,
1636			link,
1637			&proposed_table,
1638			allocate)) {
1639		DC_LOG_ERROR("SST Update Payload: Failed to update "
1640						"allocation table for "
1641						"pipe idx: %d\n",
1642						pipe_ctx->pipe_idx);
1643		return DC_FAIL_DP_PAYLOAD_ALLOCATION;
1644	}
1645
1646	proposed_table.stream_allocations[0].hpo_dp_stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
1647
1648	ASSERT(proposed_table.stream_count == 1);
1649
1650	//TODO - DP2.0 Logging: Instead of hpo_dp_stream_enc pointer, log instance id
1651	DC_LOG_DP2("SST Update Payload: hpo_dp_stream_enc: %p      "
1652		"vcp_id: %d      "
1653		"slot_count: %d\n",
1654		(void *) proposed_table.stream_allocations[0].hpo_dp_stream_enc,
1655		proposed_table.stream_allocations[0].vcp_id,
1656		proposed_table.stream_allocations[0].slot_count);
1657
1658	/* program DP source TX for payload */
1659	link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
1660			&proposed_table);
1661
1662	/* poll for ACT handled */
1663	if (!poll_for_allocation_change_trigger(link)) {
1664		// Failures will result in blackscreen and errors logged
1665		BREAK_TO_DEBUGGER();
1666	}
1667
1668	/* slot X.Y for SST payload allocate */
1669	if (allocate && link_dp_get_encoding_format(&link->cur_link_settings) ==
1670			DP_128b_132b_ENCODING) {
1671		avg_time_slots_per_mtp = link_calculate_sst_avg_time_slots_per_mtp(stream, link);
1672
1673		log_vcp_x_y(link, avg_time_slots_per_mtp);
1674
1675		if (link_hwss->ext.set_throttled_vcp_size)
1676			link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
1677					avg_time_slots_per_mtp);
1678		if (link_hwss->ext.set_hblank_min_symbol_width)
1679			link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
1680					&link->cur_link_settings,
1681					avg_time_slots_per_mtp);
1682	}
1683
1684	/* Always return DC_OK.
1685	 * If part of sequence fails, log failure(s) and show blackscreen
1686	 */
1687	return DC_OK;
1688}
1689
1690enum dc_status link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
1691{
1692	struct dc_stream_state *stream = pipe_ctx->stream;
1693	struct dc_link *link = stream->link;
1694	struct fixed31_32 avg_time_slots_per_mtp;
1695	struct fixed31_32 pbn;
1696	struct fixed31_32 pbn_per_slot;
1697	struct dc_dp_mst_stream_allocation_table proposed_table = {0};
1698	uint8_t i;
1699	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
1700	DC_LOGGER_INIT(link->ctx->logger);
1701
1702	/* decrease throttled vcp size */
1703	pbn_per_slot = get_pbn_per_slot(stream);
1704	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
1705	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
1706
1707	if (link_hwss->ext.set_throttled_vcp_size)
1708		link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
1709	if (link_hwss->ext.set_hblank_min_symbol_width)
1710		link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
1711				&link->cur_link_settings,
1712				avg_time_slots_per_mtp);
1713
1714	/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
1715	dm_helpers_dp_mst_send_payload_allocation(
1716			stream->ctx,
1717			stream);
1718
1719	/* notify immediate branch device table update */
1720	if (dm_helpers_dp_mst_write_payload_allocation_table(
1721			stream->ctx,
1722			stream,
1723			&proposed_table,
1724			true)) {
1725		/* update mst stream allocation table software state */
1726		update_mst_stream_alloc_table(
1727				link,
1728				pipe_ctx->stream_res.stream_enc,
1729				pipe_ctx->stream_res.hpo_dp_stream_enc,
1730				&proposed_table);
1731	} else {
1732		DC_LOG_WARNING("Failed to update"
1733				"MST allocation table for"
1734				"pipe idx:%d\n",
1735				pipe_ctx->pipe_idx);
1736	}
1737
1738	DC_LOG_MST("%s  "
1739			"stream_count: %d: \n ",
1740			__func__,
1741			link->mst_stream_alloc_table.stream_count);
1742
1743	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
1744		DC_LOG_MST("stream_enc[%d]: %p      "
1745		"stream[%d].hpo_dp_stream_enc: %p      "
1746		"stream[%d].vcp_id: %d      "
1747		"stream[%d].slot_count: %d\n",
1748		i,
1749		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
1750		i,
1751		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
1752		i,
1753		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
1754		i,
1755		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
1756	}
1757
1758	ASSERT(proposed_table.stream_count > 0);
1759
1760	/* update mst stream allocation table hardware state */
1761	if (link_hwss->ext.update_stream_allocation_table == NULL ||
1762			link_dp_get_encoding_format(&link->cur_link_settings) == DP_UNKNOWN_ENCODING) {
1763		DC_LOG_ERROR("Failure: unknown encoding format\n");
1764		return DC_ERROR_UNEXPECTED;
1765	}
1766
1767	link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
1768			&link->mst_stream_alloc_table);
1769
1770	/* poll for immediate branch device ACT handled */
1771	dm_helpers_dp_mst_poll_for_allocation_change_trigger(
1772			stream->ctx,
1773			stream);
1774
1775	return DC_OK;
1776}
1777
1778enum dc_status link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
1779{
1780	struct dc_stream_state *stream = pipe_ctx->stream;
1781	struct dc_link *link = stream->link;
1782	struct fixed31_32 avg_time_slots_per_mtp;
1783	struct fixed31_32 pbn;
1784	struct fixed31_32 pbn_per_slot;
1785	struct dc_dp_mst_stream_allocation_table proposed_table = {0};
1786	uint8_t i;
1787	enum act_return_status ret;
1788	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
1789	DC_LOGGER_INIT(link->ctx->logger);
1790
1791	/* notify immediate branch device table update */
1792	if (dm_helpers_dp_mst_write_payload_allocation_table(
1793				stream->ctx,
1794				stream,
1795				&proposed_table,
1796				true)) {
1797		/* update mst stream allocation table software state */
1798		update_mst_stream_alloc_table(
1799				link,
1800				pipe_ctx->stream_res.stream_enc,
1801				pipe_ctx->stream_res.hpo_dp_stream_enc,
1802				&proposed_table);
1803	}
1804
1805	DC_LOG_MST("%s  "
1806			"stream_count: %d: \n ",
1807			__func__,
1808			link->mst_stream_alloc_table.stream_count);
1809
1810	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
1811		DC_LOG_MST("stream_enc[%d]: %p      "
1812		"stream[%d].hpo_dp_stream_enc: %p      "
1813		"stream[%d].vcp_id: %d      "
1814		"stream[%d].slot_count: %d\n",
1815		i,
1816		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
1817		i,
1818		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
1819		i,
1820		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
1821		i,
1822		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
1823	}
1824
1825	ASSERT(proposed_table.stream_count > 0);
1826
1827	/* update mst stream allocation table hardware state */
1828	if (link_hwss->ext.update_stream_allocation_table == NULL ||
1829			link_dp_get_encoding_format(&link->cur_link_settings) == DP_UNKNOWN_ENCODING) {
1830		DC_LOG_ERROR("Failure: unknown encoding format\n");
1831		return DC_ERROR_UNEXPECTED;
1832	}
1833
1834	link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
1835			&link->mst_stream_alloc_table);
1836
1837	/* poll for immediate branch device ACT handled */
1838	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
1839			stream->ctx,
1840			stream);
1841
1842	if (ret != ACT_LINK_LOST) {
1843		/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
1844		dm_helpers_dp_mst_send_payload_allocation(
1845				stream->ctx,
1846				stream);
1847	}
1848
1849	/* increase throttled vcp size */
1850	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
1851	pbn_per_slot = get_pbn_per_slot(stream);
1852	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
1853
1854	if (link_hwss->ext.set_throttled_vcp_size)
1855		link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
1856	if (link_hwss->ext.set_hblank_min_symbol_width)
1857		link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
1858				&link->cur_link_settings,
1859				avg_time_slots_per_mtp);
1860
1861	return DC_OK;
1862}
1863
1864static void disable_link_dp(struct dc_link *link,
1865		const struct link_resource *link_res,
1866		enum signal_type signal)
1867{
1868	struct dc_link_settings link_settings = link->cur_link_settings;
1869
1870	if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST &&
1871			link->mst_stream_alloc_table.stream_count > 0)
1872		/* disable MST link only when last vc payload is deallocated */
1873		return;
1874
1875	dp_disable_link_phy(link, link_res, signal);
1876
1877	if (link->connector_signal == SIGNAL_TYPE_EDP) {
1878		if (!link->skip_implict_edp_power_control)
1879			link->dc->hwss.edp_power_control(link, false);
1880	}
1881
1882	if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
1883		/* set the sink to SST mode after disabling the link */
1884		enable_mst_on_sink(link, false);
1885
1886	if (link_dp_get_encoding_format(&link_settings) ==
1887			DP_8b_10b_ENCODING) {
1888		dp_set_fec_enable(link, false);
1889		dp_set_fec_ready(link, link_res, false);
1890	}
1891}
1892
1893static void disable_link(struct dc_link *link,
1894		const struct link_resource *link_res,
1895		enum signal_type signal)
1896{
1897	if (dc_is_dp_signal(signal)) {
1898		disable_link_dp(link, link_res, signal);
1899	} else if (signal != SIGNAL_TYPE_VIRTUAL) {
1900		link->dc->hwss.disable_link_output(link, link_res, signal);
1901	}
1902
1903	if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
1904		/* MST disable link only when no stream use the link */
1905		if (link->mst_stream_alloc_table.stream_count <= 0)
1906			link->link_status.link_active = false;
1907	} else {
1908		link->link_status.link_active = false;
1909	}
1910}
1911
1912static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
1913{
1914	struct dc_stream_state *stream = pipe_ctx->stream;
1915	struct dc_link *link = stream->link;
1916	enum dc_color_depth display_color_depth;
1917	enum engine_id eng_id;
1918	struct ext_hdmi_settings settings = {0};
1919	bool is_over_340mhz = false;
1920	bool is_vga_mode = (stream->timing.h_addressable == 640)
1921			&& (stream->timing.v_addressable == 480);
1922	struct dc *dc = pipe_ctx->stream->ctx->dc;
1923	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
1924
1925	if (stream->phy_pix_clk == 0)
1926		stream->phy_pix_clk = stream->timing.pix_clk_100hz / 10;
1927	if (stream->phy_pix_clk > 340000)
1928		is_over_340mhz = true;
1929
1930	if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
1931		unsigned short masked_chip_caps = pipe_ctx->stream->link->chip_caps &
1932				EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
1933		if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_TISN65DP159RSBT) {
1934			/* DP159, Retimer settings */
1935			eng_id = pipe_ctx->stream_res.stream_enc->id;
1936
1937			if (get_ext_hdmi_settings(pipe_ctx, eng_id, &settings)) {
1938				write_i2c_retimer_setting(pipe_ctx,
1939						is_vga_mode, is_over_340mhz, &settings);
1940			} else {
1941				write_i2c_default_retimer_setting(pipe_ctx,
1942						is_vga_mode, is_over_340mhz);
1943			}
1944		} else if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_PI3EQX1204) {
1945			/* PI3EQX1204, Redriver settings */
1946			write_i2c_redriver_setting(pipe_ctx, is_over_340mhz);
1947		}
1948	}
1949
1950	if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
1951		write_scdc_data(
1952			stream->link->ddc,
1953			stream->phy_pix_clk,
1954			stream->timing.flags.LTE_340MCSC_SCRAMBLE);
1955
1956	memset(&stream->link->cur_link_settings, 0,
1957			sizeof(struct dc_link_settings));
1958
1959	display_color_depth = stream->timing.display_color_depth;
1960	if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)
1961		display_color_depth = COLOR_DEPTH_888;
1962
1963	/* We need to enable stream encoder for TMDS first to apply 1/4 TMDS
1964	 * character clock in case that beyond 340MHz.
1965	 */
1966	if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal))
1967		link_hwss->setup_stream_encoder(pipe_ctx);
1968
1969	dc->hwss.enable_tmds_link_output(
1970			link,
1971			&pipe_ctx->link_res,
1972			pipe_ctx->stream->signal,
1973			pipe_ctx->clock_source->id,
1974			display_color_depth,
1975			stream->phy_pix_clk);
1976
1977	if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
1978		read_scdc_data(link->ddc);
1979}
1980
1981static enum dc_status enable_link_dp(struct dc_state *state,
1982				     struct pipe_ctx *pipe_ctx)
1983{
1984	struct dc_stream_state *stream = pipe_ctx->stream;
1985	enum dc_status status;
1986	bool skip_video_pattern;
1987	struct dc_link *link = stream->link;
1988	const struct dc_link_settings *link_settings =
1989			&pipe_ctx->link_config.dp_link_settings;
1990	bool fec_enable;
1991	int i;
1992	bool apply_seamless_boot_optimization = false;
1993	uint32_t bl_oled_enable_delay = 50; // in ms
1994	uint32_t post_oui_delay = 30; // 30ms
1995	/* Reduce link bandwidth between failed link training attempts. */
1996	bool do_fallback = false;
1997	int lt_attempts = LINK_TRAINING_ATTEMPTS;
1998
1999	// Increase retry count if attempting DP1.x on FIXED_VS link
2000	if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
2001			link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING)
2002		lt_attempts = 10;
2003
2004	// check for seamless boot
2005	for (i = 0; i < state->stream_count; i++) {
2006		if (state->streams[i]->apply_seamless_boot_optimization) {
2007			apply_seamless_boot_optimization = true;
2008			break;
2009		}
2010	}
2011
2012	/* Train with fallback when enabling DPIA link. Conventional links are
2013	 * trained with fallback during sink detection.
2014	 */
2015	if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
2016		do_fallback = true;
2017
2018	/*
2019	 * Temporary w/a to get DP2.0 link rates to work with SST.
2020	 * TODO DP2.0 - Workaround: Remove w/a if and when the issue is resolved.
2021	 */
2022	if (link_dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING &&
2023			pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
2024			link->dc->debug.set_mst_en_for_sst) {
2025		enable_mst_on_sink(link, true);
2026	}
2027	if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
2028		/*in case it is not on*/
2029		if (!link->dc->config.edp_no_power_sequencing)
2030			link->dc->hwss.edp_power_control(link, true);
2031		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
2032	}
2033
2034	if (link_dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
2035		/* TODO - DP2.0 HW: calculate 32 symbol clock for HPO encoder */
2036	} else {
2037		pipe_ctx->stream_res.pix_clk_params.requested_sym_clk =
2038				link_settings->link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
2039		if (state->clk_mgr && !apply_seamless_boot_optimization)
2040			state->clk_mgr->funcs->update_clocks(state->clk_mgr,
2041					state, false);
2042	}
2043
2044	// during mode switch we do DP_SET_POWER off then on, and OUI is lost
2045	dpcd_set_source_specific_data(link);
2046	if (link->dpcd_sink_ext_caps.raw != 0) {
2047		post_oui_delay += link->panel_config.pps.extra_post_OUI_ms;
2048		msleep(post_oui_delay);
2049	}
2050
2051	// similarly, mode switch can cause loss of cable ID
2052	dpcd_write_cable_id_to_dprx(link);
2053
2054	skip_video_pattern = true;
2055
2056	if (link_settings->link_rate == LINK_RATE_LOW)
2057		skip_video_pattern = false;
2058
2059	if (perform_link_training_with_retries(link_settings,
2060					       skip_video_pattern,
2061					       lt_attempts,
2062					       pipe_ctx,
2063					       pipe_ctx->stream->signal,
2064					       do_fallback)) {
2065		status = DC_OK;
2066	} else {
2067		status = DC_FAIL_DP_LINK_TRAINING;
2068	}
2069
2070	if (link->preferred_training_settings.fec_enable)
2071		fec_enable = *link->preferred_training_settings.fec_enable;
2072	else
2073		fec_enable = true;
2074
2075	if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING)
2076		dp_set_fec_enable(link, fec_enable);
2077
2078	// during mode set we do DP_SET_POWER off then on, aux writes are lost
2079	if (link->dpcd_sink_ext_caps.bits.oled == 1 ||
2080		link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1 ||
2081		link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1) {
2082		set_default_brightness_aux(link);
2083		if (link->dpcd_sink_ext_caps.bits.oled == 1)
2084			msleep(bl_oled_enable_delay);
2085		edp_backlight_enable_aux(link, true);
2086	}
2087
2088	return status;
2089}
2090
2091static enum dc_status enable_link_edp(
2092		struct dc_state *state,
2093		struct pipe_ctx *pipe_ctx)
2094{
2095	return enable_link_dp(state, pipe_ctx);
2096}
2097
2098static void enable_link_lvds(struct pipe_ctx *pipe_ctx)
2099{
2100	struct dc_stream_state *stream = pipe_ctx->stream;
2101	struct dc_link *link = stream->link;
2102	struct dc *dc = stream->ctx->dc;
2103
2104	if (stream->phy_pix_clk == 0)
2105		stream->phy_pix_clk = stream->timing.pix_clk_100hz / 10;
2106
2107	memset(&stream->link->cur_link_settings, 0,
2108			sizeof(struct dc_link_settings));
2109	dc->hwss.enable_lvds_link_output(
2110			link,
2111			&pipe_ctx->link_res,
2112			pipe_ctx->clock_source->id,
2113			stream->phy_pix_clk);
2114
2115}
2116
2117static enum dc_status enable_link_dp_mst(
2118		struct dc_state *state,
2119		struct pipe_ctx *pipe_ctx)
2120{
2121	struct dc_link *link = pipe_ctx->stream->link;
2122	unsigned char mstm_cntl;
2123
2124	/* sink signal type after MST branch is MST. Multiple MST sinks
2125	 * share one link. Link DP PHY is enable or training only once.
2126	 */
2127	if (link->link_status.link_active)
2128		return DC_OK;
2129
2130	/* clear payload table */
2131	core_link_read_dpcd(link, DP_MSTM_CTRL, &mstm_cntl, 1);
2132	if (mstm_cntl & DP_MST_EN)
2133		dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link);
2134
2135	/* to make sure the pending down rep can be processed
2136	 * before enabling the link
2137	 */
2138	dm_helpers_dp_mst_poll_pending_down_reply(link->ctx, link);
2139
2140	/* set the sink to MST mode before enabling the link */
2141	enable_mst_on_sink(link, true);
2142
2143	return enable_link_dp(state, pipe_ctx);
2144}
2145
2146static enum dc_status enable_link(
2147		struct dc_state *state,
2148		struct pipe_ctx *pipe_ctx)
2149{
2150	enum dc_status status = DC_ERROR_UNEXPECTED;
2151	struct dc_stream_state *stream = pipe_ctx->stream;
2152	struct dc_link *link = stream->link;
2153
2154	/* There's some scenarios where driver is unloaded with display
2155	 * still enabled. When driver is reloaded, it may cause a display
2156	 * to not light up if there is a mismatch between old and new
2157	 * link settings. Need to call disable first before enabling at
2158	 * new link settings.
2159	 */
2160	if (link->link_status.link_active)
2161		disable_link(link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
2162
2163	switch (pipe_ctx->stream->signal) {
2164	case SIGNAL_TYPE_DISPLAY_PORT:
2165		status = enable_link_dp(state, pipe_ctx);
2166		break;
2167	case SIGNAL_TYPE_EDP:
2168		status = enable_link_edp(state, pipe_ctx);
2169		break;
2170	case SIGNAL_TYPE_DISPLAY_PORT_MST:
2171		status = enable_link_dp_mst(state, pipe_ctx);
2172		msleep(200);
2173		break;
2174	case SIGNAL_TYPE_DVI_SINGLE_LINK:
2175	case SIGNAL_TYPE_DVI_DUAL_LINK:
2176	case SIGNAL_TYPE_HDMI_TYPE_A:
2177		enable_link_hdmi(pipe_ctx);
2178		status = DC_OK;
2179		break;
2180	case SIGNAL_TYPE_LVDS:
2181		enable_link_lvds(pipe_ctx);
2182		status = DC_OK;
2183		break;
2184	case SIGNAL_TYPE_VIRTUAL:
2185		status = DC_OK;
2186		break;
2187	default:
2188		break;
2189	}
2190
2191	if (status == DC_OK) {
2192		pipe_ctx->stream->link->link_status.link_active = true;
2193	}
2194
2195	return status;
2196}
2197
2198static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, int bw)
2199{
2200	struct dc_link *link = stream->sink->link;
2201	int req_bw = bw;
2202
2203	DC_LOGGER_INIT(link->ctx->logger);
2204
2205	if (!link->dpia_bw_alloc_config.bw_alloc_enabled)
2206		return false;
2207
2208	if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
2209		int sink_index = 0;
2210		int i = 0;
2211
2212		for (i = 0; i < link->sink_count; i++) {
2213			if (link->remote_sinks[i] == NULL)
2214				continue;
2215
2216			if (stream->sink->sink_id != link->remote_sinks[i]->sink_id)
2217				req_bw += link->dpia_bw_alloc_config.remote_sink_req_bw[i];
2218			else
2219				sink_index = i;
2220		}
2221
2222		link->dpia_bw_alloc_config.remote_sink_req_bw[sink_index] = bw;
2223	}
2224
2225	/* get dp overhead for dp tunneling */
2226	link->dpia_bw_alloc_config.dp_overhead = link_dp_dpia_get_dp_overhead_in_dp_tunneling(link);
2227	req_bw += link->dpia_bw_alloc_config.dp_overhead;
2228
2229	if (link_dp_dpia_allocate_usb4_bandwidth_for_stream(link, req_bw)) {
2230		if (req_bw <= link->dpia_bw_alloc_config.allocated_bw) {
2231			DC_LOG_DEBUG("%s, Success in allocate bw for link(%d), allocated_bw(%d), dp_overhead(%d)\n",
2232					__func__, link->link_index, link->dpia_bw_alloc_config.allocated_bw,
2233					link->dpia_bw_alloc_config.dp_overhead);
2234		} else {
2235			// Cannot get the required bandwidth.
2236			DC_LOG_ERROR("%s, Failed to allocate bw for link(%d), allocated_bw(%d), dp_overhead(%d)\n",
2237					__func__, link->link_index, link->dpia_bw_alloc_config.allocated_bw,
2238					link->dpia_bw_alloc_config.dp_overhead);
2239			return false;
2240		}
2241	} else {
2242		DC_LOG_DEBUG("%s, usb4 request bw timeout\n", __func__);
2243		return false;
2244	}
2245
2246	if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
2247		int i = 0;
2248
2249		for (i = 0; i < link->sink_count; i++) {
2250			if (link->remote_sinks[i] == NULL)
2251				continue;
2252			DC_LOG_DEBUG("%s, remote_sink=%s, request_bw=%d\n", __func__,
2253					(const char *)(&link->remote_sinks[i]->edid_caps.display_name[0]),
2254					link->dpia_bw_alloc_config.remote_sink_req_bw[i]);
2255		}
2256	}
2257
2258	return true;
2259}
2260
2261static bool allocate_usb4_bandwidth(struct dc_stream_state *stream)
2262{
2263	bool ret;
2264
2265	int bw = dc_bandwidth_in_kbps_from_timing(&stream->timing,
2266			dc_link_get_highest_encoding_format(stream->sink->link));
2267
2268	ret = allocate_usb4_bandwidth_for_stream(stream, bw);
2269
2270	return ret;
2271}
2272
2273static bool deallocate_usb4_bandwidth(struct dc_stream_state *stream)
2274{
2275	bool ret;
2276
2277	ret = allocate_usb4_bandwidth_for_stream(stream, 0);
2278
2279	return ret;
2280}
2281
2282void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
2283{
2284	struct dc  *dc = pipe_ctx->stream->ctx->dc;
2285	struct dc_stream_state *stream = pipe_ctx->stream;
2286	struct dc_link *link = stream->sink->link;
2287	struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
2288
2289	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
2290
2291	ASSERT(is_master_pipe_for_link(link, pipe_ctx));
2292
2293	if (dp_is_128b_132b_signal(pipe_ctx))
2294		vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
2295	if (dc_is_virtual_signal(pipe_ctx->stream->signal))
2296		return;
2297
2298	if (pipe_ctx->stream->sink) {
2299		if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
2300			pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
2301			DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x\n", __func__,
2302			pipe_ctx->stream->sink->edid_caps.display_name,
2303			pipe_ctx->stream->signal);
2304		}
2305	}
2306
2307	if (!pipe_ctx->stream->sink->edid_caps.panel_patch.skip_avmute) {
2308		if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
2309			set_avmute(pipe_ctx, true);
2310	}
2311
2312	dc->hwss.disable_audio_stream(pipe_ctx);
2313
2314	update_psp_stream_config(pipe_ctx, true);
2315	dc->hwss.blank_stream(pipe_ctx);
2316
2317	if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
2318		deallocate_usb4_bandwidth(pipe_ctx->stream);
2319
2320	if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
2321		deallocate_mst_payload(pipe_ctx);
2322	else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
2323			dp_is_128b_132b_signal(pipe_ctx))
2324		update_sst_payload(pipe_ctx, false);
2325
2326	if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
2327		struct ext_hdmi_settings settings = {0};
2328		enum engine_id eng_id = pipe_ctx->stream_res.stream_enc->id;
2329
2330		unsigned short masked_chip_caps = link->chip_caps &
2331				EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
2332		//Need to inform that sink is going to use legacy HDMI mode.
2333		write_scdc_data(
2334			link->ddc,
2335			165000,//vbios only handles 165Mhz.
2336			false);
2337		if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_TISN65DP159RSBT) {
2338			/* DP159, Retimer settings */
2339			if (get_ext_hdmi_settings(pipe_ctx, eng_id, &settings))
2340				write_i2c_retimer_setting(pipe_ctx,
2341						false, false, &settings);
2342			else
2343				write_i2c_default_retimer_setting(pipe_ctx,
2344						false, false);
2345		} else if (masked_chip_caps == EXT_DISPLAY_PATH_CAPS__HDMI20_PI3EQX1204) {
2346			/* PI3EQX1204, Redriver settings */
2347			write_i2c_redriver_setting(pipe_ctx, false);
2348		}
2349	}
2350
2351	if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
2352			!dp_is_128b_132b_signal(pipe_ctx)) {
2353
2354		/* In DP1.x SST mode, our encoder will go to TPS1
2355		 * when link is on but stream is off.
2356		 * Disabling link before stream will avoid exposing TPS1 pattern
2357		 * during the disable sequence as it will confuse some receivers
2358		 * state machine.
2359		 * In DP2 or MST mode, our encoder will stay video active
2360		 */
2361		disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
2362		dc->hwss.disable_stream(pipe_ctx);
2363	} else {
2364		dc->hwss.disable_stream(pipe_ctx);
2365		disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
2366	}
2367
2368	if (pipe_ctx->stream->timing.flags.DSC) {
2369		if (dc_is_dp_signal(pipe_ctx->stream->signal))
2370			link_set_dsc_enable(pipe_ctx, false);
2371	}
2372	if (dp_is_128b_132b_signal(pipe_ctx)) {
2373		if (pipe_ctx->stream_res.tg->funcs->set_out_mux)
2374			pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO);
2375	}
2376
2377	if (vpg && vpg->funcs->vpg_powerdown)
2378		vpg->funcs->vpg_powerdown(vpg);
2379
2380	/* for psp not exist case */
2381	if (link->connector_signal == SIGNAL_TYPE_EDP && dc->debug.psp_disabled_wa) {
2382		/* reset internal save state to default since eDP is  off */
2383		enum dp_panel_mode panel_mode = dp_get_panel_mode(pipe_ctx->stream->link);
2384		/* since current psp not loaded, we need to reset it to default*/
2385		link->panel_mode = panel_mode;
2386	}
2387}
2388
2389void link_set_dpms_on(
2390		struct dc_state *state,
2391		struct pipe_ctx *pipe_ctx)
2392{
2393	struct dc *dc = pipe_ctx->stream->ctx->dc;
2394	struct dc_stream_state *stream = pipe_ctx->stream;
2395	struct dc_link *link = stream->sink->link;
2396	enum dc_status status;
2397	struct link_encoder *link_enc;
2398	enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
2399	struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
2400	const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
2401	bool apply_edp_fast_boot_optimization =
2402		pipe_ctx->stream->apply_edp_fast_boot_optimization;
2403
2404	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
2405
2406	ASSERT(is_master_pipe_for_link(link, pipe_ctx));
2407
2408	if (dp_is_128b_132b_signal(pipe_ctx))
2409		vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
2410	if (dc_is_virtual_signal(pipe_ctx->stream->signal))
2411		return;
2412
2413	if (pipe_ctx->stream->sink) {
2414		if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
2415			pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
2416			DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x\n", __func__,
2417			pipe_ctx->stream->sink->edid_caps.display_name,
2418			pipe_ctx->stream->signal);
2419		}
2420	}
2421
2422	link_enc = link_enc_cfg_get_link_enc(link);
2423	ASSERT(link_enc);
2424
2425	if (!dc_is_virtual_signal(pipe_ctx->stream->signal)
2426			&& !dp_is_128b_132b_signal(pipe_ctx)) {
2427		struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
2428
2429		if (link_enc)
2430			link_enc->funcs->setup(
2431				link_enc,
2432				pipe_ctx->stream->signal);
2433
2434		if (stream_enc && stream_enc->funcs->dig_stream_enable)
2435			stream_enc->funcs->dig_stream_enable(
2436				stream_enc,
2437				pipe_ctx->stream->signal, 1);
2438	}
2439
2440	pipe_ctx->stream->link->link_state_valid = true;
2441
2442	if (pipe_ctx->stream_res.tg->funcs->set_out_mux) {
2443		if (dp_is_128b_132b_signal(pipe_ctx))
2444			otg_out_dest = OUT_MUX_HPO_DP;
2445		else
2446			otg_out_dest = OUT_MUX_DIO;
2447		pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, otg_out_dest);
2448	}
2449
2450	link_hwss->setup_stream_attribute(pipe_ctx);
2451
2452	pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
2453
2454	// Enable VPG before building infoframe
2455	if (vpg && vpg->funcs->vpg_poweron)
2456		vpg->funcs->vpg_poweron(vpg);
2457
2458	resource_build_info_frame(pipe_ctx);
2459	dc->hwss.update_info_frame(pipe_ctx);
2460
2461	if (dc_is_dp_signal(pipe_ctx->stream->signal))
2462		dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
2463
2464	/* Do not touch link on seamless boot optimization. */
2465	if (pipe_ctx->stream->apply_seamless_boot_optimization) {
2466		pipe_ctx->stream->dpms_off = false;
2467
2468		/* Still enable stream features & audio on seamless boot for DP external displays */
2469		if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
2470			enable_stream_features(pipe_ctx);
2471			dc->hwss.enable_audio_stream(pipe_ctx);
2472		}
2473
2474		update_psp_stream_config(pipe_ctx, false);
2475		return;
2476	}
2477
2478	/* eDP lit up by bios already, no need to enable again. */
2479	if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
2480				apply_edp_fast_boot_optimization &&
2481				!pipe_ctx->stream->timing.flags.DSC &&
2482				!pipe_ctx->next_odm_pipe) {
2483		pipe_ctx->stream->dpms_off = false;
2484		update_psp_stream_config(pipe_ctx, false);
2485		return;
2486	}
2487
2488	if (pipe_ctx->stream->dpms_off)
2489		return;
2490
2491	/* Have to setup DSC before DIG FE and BE are connected (which happens before the
2492	 * link training). This is to make sure the bandwidth sent to DIG BE won't be
2493	 * bigger than what the link and/or DIG BE can handle. VBID[6]/CompressedStream_flag
2494	 * will be automatically set at a later time when the video is enabled
2495	 * (DP_VID_STREAM_EN = 1).
2496	 */
2497	if (pipe_ctx->stream->timing.flags.DSC) {
2498		if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
2499		    dc_is_virtual_signal(pipe_ctx->stream->signal))
2500			link_set_dsc_enable(pipe_ctx, true);
2501	}
2502
2503	status = enable_link(state, pipe_ctx);
2504
2505	if (status != DC_OK) {
2506		DC_LOG_WARNING("enabling link %u failed: %d\n",
2507		pipe_ctx->stream->link->link_index,
2508		status);
2509
2510		/* Abort stream enable *unless* the failure was due to
2511		 * DP link training - some DP monitors will recover and
2512		 * show the stream anyway. But MST displays can't proceed
2513		 * without link training.
2514		 */
2515		if (status != DC_FAIL_DP_LINK_TRAINING ||
2516				pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
2517			if (false == stream->link->link_status.link_active)
2518				disable_link(stream->link, &pipe_ctx->link_res,
2519						pipe_ctx->stream->signal);
2520			BREAK_TO_DEBUGGER();
2521			return;
2522		}
2523	}
2524
2525	/* turn off otg test pattern if enable */
2526	if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
2527		pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
2528				CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
2529				COLOR_DEPTH_UNDEFINED);
2530
2531	/* This second call is needed to reconfigure the DIG
2532	 * as a workaround for the incorrect value being applied
2533	 * from transmitter control.
2534	 */
2535	if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) ||
2536			dp_is_128b_132b_signal(pipe_ctx))) {
2537			struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
2538
2539			if (link_enc)
2540				link_enc->funcs->setup(
2541					link_enc,
2542					pipe_ctx->stream->signal);
2543
2544			if (stream_enc && stream_enc->funcs->dig_stream_enable)
2545				stream_enc->funcs->dig_stream_enable(
2546					stream_enc,
2547					pipe_ctx->stream->signal, 1);
2548
2549		}
2550
2551	dc->hwss.enable_stream(pipe_ctx);
2552
2553	/* Set DPS PPS SDP (AKA "info frames") */
2554	if (pipe_ctx->stream->timing.flags.DSC) {
2555		if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
2556				dc_is_virtual_signal(pipe_ctx->stream->signal)) {
2557			dp_set_dsc_on_rx(pipe_ctx, true);
2558			link_set_dsc_pps_packet(pipe_ctx, true, true);
2559		}
2560	}
2561
2562	if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
2563		allocate_usb4_bandwidth(pipe_ctx->stream);
2564
2565	if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
2566		allocate_mst_payload(pipe_ctx);
2567	else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
2568			dp_is_128b_132b_signal(pipe_ctx))
2569		update_sst_payload(pipe_ctx, true);
2570
2571	dc->hwss.unblank_stream(pipe_ctx,
2572		&pipe_ctx->stream->link->cur_link_settings);
2573
2574	if (stream->sink_patches.delay_ignore_msa > 0)
2575		msleep(stream->sink_patches.delay_ignore_msa);
2576
2577	if (dc_is_dp_signal(pipe_ctx->stream->signal))
2578		enable_stream_features(pipe_ctx);
2579	update_psp_stream_config(pipe_ctx, false);
2580
2581	dc->hwss.enable_audio_stream(pipe_ctx);
2582
2583	if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
2584		set_avmute(pipe_ctx, false);
2585	}
2586}