Linux Audio

Check our new training course

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