Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
   1/*
   2 * Copyright 2022 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: AMD
  23 *
  24 */
  25
  26/* FILE POLICY AND INTENDED USAGE:
  27 * This file manages link detection states and receiver states by using various
  28 * link protocols. It also provides helper functions to interpret certain
  29 * capabilities or status based on the states it manages or retrieve them
  30 * directly from connected receivers.
  31 */
  32
  33#include "link_dpms.h"
  34#include "link_detection.h"
  35#include "link_hwss.h"
  36#include "protocols/link_edp_panel_control.h"
  37#include "protocols/link_ddc.h"
  38#include "protocols/link_hpd.h"
  39#include "protocols/link_dpcd.h"
  40#include "protocols/link_dp_capability.h"
  41#include "protocols/link_dp_dpia.h"
  42#include "protocols/link_dp_phy.h"
  43#include "protocols/link_dp_training.h"
  44#include "protocols/link_dp_dpia_bw.h"
  45#include "accessories/link_dp_trace.h"
  46
  47#include "link_enc_cfg.h"
  48#include "dm_helpers.h"
  49#include "clk_mgr.h"
  50
  51 // Offset DPCD 050Eh == 0x5A
  52#define MST_HUB_ID_0x5A  0x5A
  53
  54#define DC_LOGGER \
  55	link->ctx->logger
  56#define DC_LOGGER_INIT(logger)
  57
  58#define LINK_INFO(...) \
  59	DC_LOG_HW_HOTPLUG(  \
  60		__VA_ARGS__)
  61/*
  62 * Some receivers fail to train on first try and are good
  63 * on subsequent tries. 2 retries should be plenty. If we
  64 * don't have a successful training then we don't expect to
  65 * ever get one.
  66 */
  67#define LINK_TRAINING_MAX_VERIFY_RETRY 2
  68
  69static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u";
  70
  71static const u8 dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR";
  72
  73static enum ddc_transaction_type get_ddc_transaction_type(enum signal_type sink_signal)
  74{
  75	enum ddc_transaction_type transaction_type = DDC_TRANSACTION_TYPE_NONE;
  76
  77	switch (sink_signal) {
  78	case SIGNAL_TYPE_DVI_SINGLE_LINK:
  79	case SIGNAL_TYPE_DVI_DUAL_LINK:
  80	case SIGNAL_TYPE_HDMI_TYPE_A:
  81	case SIGNAL_TYPE_LVDS:
  82	case SIGNAL_TYPE_RGB:
  83		transaction_type = DDC_TRANSACTION_TYPE_I2C;
  84		break;
  85
  86	case SIGNAL_TYPE_DISPLAY_PORT:
  87	case SIGNAL_TYPE_EDP:
  88		transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
  89		break;
  90
  91	case SIGNAL_TYPE_DISPLAY_PORT_MST:
  92		/* MST does not use I2COverAux, but there is the
  93		 * SPECIAL use case for "immediate dwnstrm device
  94		 * access" (EPR#370830).
  95		 */
  96		transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
  97		break;
  98
  99	default:
 100		break;
 101	}
 102
 103	return transaction_type;
 104}
 105
 106static enum signal_type get_basic_signal_type(struct graphics_object_id encoder,
 107					      struct graphics_object_id downstream)
 108{
 109	if (downstream.type == OBJECT_TYPE_CONNECTOR) {
 110		switch (downstream.id) {
 111		case CONNECTOR_ID_SINGLE_LINK_DVII:
 112			switch (encoder.id) {
 113			case ENCODER_ID_INTERNAL_DAC1:
 114			case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
 115			case ENCODER_ID_INTERNAL_DAC2:
 116			case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
 117				return SIGNAL_TYPE_RGB;
 118			default:
 119				return SIGNAL_TYPE_DVI_SINGLE_LINK;
 120			}
 121		break;
 122		case CONNECTOR_ID_DUAL_LINK_DVII:
 123		{
 124			switch (encoder.id) {
 125			case ENCODER_ID_INTERNAL_DAC1:
 126			case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
 127			case ENCODER_ID_INTERNAL_DAC2:
 128			case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
 129				return SIGNAL_TYPE_RGB;
 130			default:
 131				return SIGNAL_TYPE_DVI_DUAL_LINK;
 132			}
 133		}
 134		break;
 135		case CONNECTOR_ID_SINGLE_LINK_DVID:
 136			return SIGNAL_TYPE_DVI_SINGLE_LINK;
 137		case CONNECTOR_ID_DUAL_LINK_DVID:
 138			return SIGNAL_TYPE_DVI_DUAL_LINK;
 139		case CONNECTOR_ID_VGA:
 140			return SIGNAL_TYPE_RGB;
 141		case CONNECTOR_ID_HDMI_TYPE_A:
 142			return SIGNAL_TYPE_HDMI_TYPE_A;
 143		case CONNECTOR_ID_LVDS:
 144			return SIGNAL_TYPE_LVDS;
 145		case CONNECTOR_ID_DISPLAY_PORT:
 146		case CONNECTOR_ID_USBC:
 147			return SIGNAL_TYPE_DISPLAY_PORT;
 148		case CONNECTOR_ID_EDP:
 149			return SIGNAL_TYPE_EDP;
 150		default:
 151			return SIGNAL_TYPE_NONE;
 152		}
 153	} else if (downstream.type == OBJECT_TYPE_ENCODER) {
 154		switch (downstream.id) {
 155		case ENCODER_ID_EXTERNAL_NUTMEG:
 156		case ENCODER_ID_EXTERNAL_TRAVIS:
 157			return SIGNAL_TYPE_DISPLAY_PORT;
 158		default:
 159			return SIGNAL_TYPE_NONE;
 160		}
 161	}
 162
 163	return SIGNAL_TYPE_NONE;
 164}
 165
 166/*
 167 * @brief
 168 * Detect output sink type
 169 */
 170static enum signal_type link_detect_sink_signal_type(struct dc_link *link,
 171					 enum dc_detect_reason reason)
 172{
 173	enum signal_type result;
 174	struct graphics_object_id enc_id;
 175
 176	if (link->is_dig_mapping_flexible)
 177		enc_id = (struct graphics_object_id){.id = ENCODER_ID_UNKNOWN};
 178	else
 179		enc_id = link->link_enc->id;
 180	result = get_basic_signal_type(enc_id, link->link_id);
 181
 182	/* Use basic signal type for link without physical connector. */
 183	if (link->ep_type != DISPLAY_ENDPOINT_PHY)
 184		return result;
 185
 186	/* Internal digital encoder will detect only dongles
 187	 * that require digital signal
 188	 */
 189
 190	/* Detection mechanism is different
 191	 * for different native connectors.
 192	 * LVDS connector supports only LVDS signal;
 193	 * PCIE is a bus slot, the actual connector needs to be detected first;
 194	 * eDP connector supports only eDP signal;
 195	 * HDMI should check straps for audio
 196	 */
 197
 198	/* PCIE detects the actual connector on add-on board */
 199	if (link->link_id.id == CONNECTOR_ID_PCIE) {
 200		/* ZAZTODO implement PCIE add-on card detection */
 201	}
 202
 203	switch (link->link_id.id) {
 204	case CONNECTOR_ID_HDMI_TYPE_A: {
 205		/* check audio support:
 206		 * if native HDMI is not supported, switch to DVI
 207		 */
 208		struct audio_support *aud_support =
 209					&link->dc->res_pool->audio_support;
 210
 211		if (!aud_support->hdmi_audio_native)
 212			if (link->link_id.id == CONNECTOR_ID_HDMI_TYPE_A)
 213				result = SIGNAL_TYPE_DVI_SINGLE_LINK;
 214	}
 215	break;
 216	case CONNECTOR_ID_DISPLAY_PORT:
 217	case CONNECTOR_ID_USBC: {
 218		/* DP HPD short pulse. Passive DP dongle will not
 219		 * have short pulse
 220		 */
 221		if (reason != DETECT_REASON_HPDRX) {
 222			/* Check whether DP signal detected: if not -
 223			 * we assume signal is DVI; it could be corrected
 224			 * to HDMI after dongle detection
 225			 */
 226			if (!dm_helpers_is_dp_sink_present(link))
 227				result = SIGNAL_TYPE_DVI_SINGLE_LINK;
 228		}
 229	}
 230	break;
 231	default:
 232	break;
 233	}
 234
 235	return result;
 236}
 237
 238static enum signal_type decide_signal_from_strap_and_dongle_type(enum display_dongle_type dongle_type,
 239								 struct audio_support *audio_support)
 240{
 241	enum signal_type signal = SIGNAL_TYPE_NONE;
 242
 243	switch (dongle_type) {
 244	case DISPLAY_DONGLE_DP_HDMI_DONGLE:
 245		if (audio_support->hdmi_audio_on_dongle)
 246			signal = SIGNAL_TYPE_HDMI_TYPE_A;
 247		else
 248			signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
 249		break;
 250	case DISPLAY_DONGLE_DP_DVI_DONGLE:
 251		signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
 252		break;
 253	case DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE:
 254		if (audio_support->hdmi_audio_native)
 255			signal =  SIGNAL_TYPE_HDMI_TYPE_A;
 256		else
 257			signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
 258		break;
 259	default:
 260		signal = SIGNAL_TYPE_NONE;
 261		break;
 262	}
 263
 264	return signal;
 265}
 266
 267static void read_scdc_caps(struct ddc_service *ddc_service,
 268		struct dc_sink *sink)
 269{
 270	uint8_t slave_address = HDMI_SCDC_ADDRESS;
 271	uint8_t offset = HDMI_SCDC_MANUFACTURER_OUI;
 272
 273	link_query_ddc_data(ddc_service, slave_address, &offset,
 274			sizeof(offset), sink->scdc_caps.manufacturer_OUI.byte,
 275			sizeof(sink->scdc_caps.manufacturer_OUI.byte));
 276
 277	offset = HDMI_SCDC_DEVICE_ID;
 278
 279	link_query_ddc_data(ddc_service, slave_address, &offset,
 280			sizeof(offset), &(sink->scdc_caps.device_id.byte),
 281			sizeof(sink->scdc_caps.device_id.byte));
 282}
 283
 284static bool i2c_read(
 285	struct ddc_service *ddc,
 286	uint32_t address,
 287	uint8_t *buffer,
 288	uint32_t len)
 289{
 290	uint8_t offs_data = 0;
 291	struct i2c_payload payloads[2] = {
 292		{
 293		.write = true,
 294		.address = address,
 295		.length = 1,
 296		.data = &offs_data },
 297		{
 298		.write = false,
 299		.address = address,
 300		.length = len,
 301		.data = buffer } };
 302
 303	struct i2c_command command = {
 304		.payloads = payloads,
 305		.number_of_payloads = 2,
 306		.engine = DDC_I2C_COMMAND_ENGINE,
 307		.speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
 308
 309	return dm_helpers_submit_i2c(
 310			ddc->ctx,
 311			ddc->link,
 312			&command);
 313}
 314
 315enum {
 316	DP_SINK_CAP_SIZE =
 317		DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV + 1
 318};
 319
 320static void query_dp_dual_mode_adaptor(
 321	struct ddc_service *ddc,
 322	struct display_sink_capability *sink_cap)
 323{
 324	uint8_t i;
 325	bool is_valid_hdmi_signature;
 326	enum display_dongle_type *dongle = &sink_cap->dongle_type;
 327	uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
 328	bool is_type2_dongle = false;
 329	int retry_count = 2;
 330	struct dp_hdmi_dongle_signature_data *dongle_signature;
 331	struct dc_link *link = ddc->link;
 332
 333	/* Assume we have no valid DP passive dongle connected */
 334	*dongle = DISPLAY_DONGLE_NONE;
 335	sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
 336
 337	/* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
 338	if (!i2c_read(
 339		ddc,
 340		DP_HDMI_DONGLE_ADDRESS,
 341		type2_dongle_buf,
 342		sizeof(type2_dongle_buf))) {
 343		/* Passive HDMI dongles can sometimes fail here without retrying*/
 344		while (retry_count > 0) {
 345			if (i2c_read(ddc,
 346				DP_HDMI_DONGLE_ADDRESS,
 347				type2_dongle_buf,
 348				sizeof(type2_dongle_buf)))
 349				break;
 350			retry_count--;
 351		}
 352		if (retry_count == 0) {
 353			*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
 354			sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
 355
 356			CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
 357					"DP-DVI passive dongle %dMhz: ",
 358					DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
 359			return;
 360		}
 361	}
 362
 363	/* Check if Type 2 dongle.*/
 364	if (type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_ID] == DP_ADAPTOR_TYPE2_ID)
 365		is_type2_dongle = true;
 366
 367	dongle_signature =
 368		(struct dp_hdmi_dongle_signature_data *)type2_dongle_buf;
 369
 370	is_valid_hdmi_signature = true;
 371
 372	/* Check EOT */
 373	if (dongle_signature->eot != DP_HDMI_DONGLE_SIGNATURE_EOT) {
 374		is_valid_hdmi_signature = false;
 375	}
 376
 377	/* Check signature */
 378	for (i = 0; i < sizeof(dongle_signature->id); ++i) {
 379		/* If its not the right signature,
 380		 * skip mismatch in subversion byte.*/
 381		if (dongle_signature->id[i] !=
 382			dp_hdmi_dongle_signature_str[i] && i != 3) {
 383
 384			if (is_type2_dongle) {
 385				is_valid_hdmi_signature = false;
 386				break;
 387			}
 388
 389		}
 390	}
 391
 392	if (is_type2_dongle) {
 393		uint32_t max_tmds_clk =
 394			type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK];
 395
 396		max_tmds_clk = max_tmds_clk * 2 + max_tmds_clk / 2;
 397
 398		if (0 == max_tmds_clk ||
 399				max_tmds_clk < DP_ADAPTOR_TYPE2_MIN_TMDS_CLK ||
 400				max_tmds_clk > DP_ADAPTOR_TYPE2_MAX_TMDS_CLK) {
 401			*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
 402
 403			CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 404					sizeof(type2_dongle_buf),
 405					"DP-DVI passive dongle %dMhz: ",
 406					DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
 407		} else {
 408			if (is_valid_hdmi_signature == true) {
 409				*dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
 410
 411				CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 412						sizeof(type2_dongle_buf),
 413						"Type 2 DP-HDMI passive dongle %dMhz: ",
 414						max_tmds_clk);
 415			} else {
 416				*dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
 417
 418				CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 419						sizeof(type2_dongle_buf),
 420						"Type 2 DP-HDMI passive dongle (no signature) %dMhz: ",
 421						max_tmds_clk);
 422
 423			}
 424
 425			/* Multiply by 1000 to convert to kHz. */
 426			sink_cap->max_hdmi_pixel_clock =
 427				max_tmds_clk * 1000;
 428		}
 429		sink_cap->is_dongle_type_one = false;
 430
 431	} else {
 432		if (is_valid_hdmi_signature == true) {
 433			*dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
 434
 435			CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 436					sizeof(type2_dongle_buf),
 437					"Type 1 DP-HDMI passive dongle %dMhz: ",
 438					sink_cap->max_hdmi_pixel_clock / 1000);
 439		} else {
 440			*dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
 441
 442			CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 443					sizeof(type2_dongle_buf),
 444					"Type 1 DP-HDMI passive dongle (no signature) %dMhz: ",
 445					sink_cap->max_hdmi_pixel_clock / 1000);
 446		}
 447		sink_cap->is_dongle_type_one = true;
 448	}
 449
 450	return;
 451}
 452
 453static enum signal_type dp_passive_dongle_detection(struct ddc_service *ddc,
 454						    struct display_sink_capability *sink_cap,
 455						    struct audio_support *audio_support)
 456{
 457	query_dp_dual_mode_adaptor(ddc, sink_cap);
 458
 459	return decide_signal_from_strap_and_dongle_type(sink_cap->dongle_type,
 460							audio_support);
 461}
 462
 463static void link_disconnect_sink(struct dc_link *link)
 464{
 465	if (link->local_sink) {
 466		dc_sink_release(link->local_sink);
 467		link->local_sink = NULL;
 468	}
 469
 470	link->dpcd_sink_count = 0;
 471	//link->dpcd_caps.dpcd_rev.raw = 0;
 472}
 473
 474static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *link)
 475{
 476	dc_sink_release(link->local_sink);
 477	link->local_sink = prev_sink;
 478}
 479
 480static void query_hdcp_capability(enum signal_type signal, struct dc_link *link)
 481{
 482	struct hdcp_protection_message msg22;
 483	struct hdcp_protection_message msg14;
 484
 485	memset(&msg22, 0, sizeof(struct hdcp_protection_message));
 486	memset(&msg14, 0, sizeof(struct hdcp_protection_message));
 487	memset(link->hdcp_caps.rx_caps.raw, 0,
 488		sizeof(link->hdcp_caps.rx_caps.raw));
 489
 490	if ((link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
 491			link->ddc->transaction_type ==
 492			DDC_TRANSACTION_TYPE_I2C_OVER_AUX) ||
 493			link->connector_signal == SIGNAL_TYPE_EDP) {
 494		msg22.data = link->hdcp_caps.rx_caps.raw;
 495		msg22.length = sizeof(link->hdcp_caps.rx_caps.raw);
 496		msg22.msg_id = HDCP_MESSAGE_ID_RX_CAPS;
 497	} else {
 498		msg22.data = &link->hdcp_caps.rx_caps.fields.version;
 499		msg22.length = sizeof(link->hdcp_caps.rx_caps.fields.version);
 500		msg22.msg_id = HDCP_MESSAGE_ID_HDCP2VERSION;
 501	}
 502	msg22.version = HDCP_VERSION_22;
 503	msg22.link = HDCP_LINK_PRIMARY;
 504	msg22.max_retries = 5;
 505	dc_process_hdcp_msg(signal, link, &msg22);
 506
 507	if (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
 508		msg14.data = &link->hdcp_caps.bcaps.raw;
 509		msg14.length = sizeof(link->hdcp_caps.bcaps.raw);
 510		msg14.msg_id = HDCP_MESSAGE_ID_READ_BCAPS;
 511		msg14.version = HDCP_VERSION_14;
 512		msg14.link = HDCP_LINK_PRIMARY;
 513		msg14.max_retries = 5;
 514
 515		dc_process_hdcp_msg(signal, link, &msg14);
 516	}
 517
 518}
 519static void read_current_link_settings_on_detect(struct dc_link *link)
 520{
 521	union lane_count_set lane_count_set = {0};
 522	uint8_t link_bw_set = 0;
 523	uint8_t link_rate_set = 0;
 524	uint32_t read_dpcd_retry_cnt = 10;
 525	enum dc_status status = DC_ERROR_UNEXPECTED;
 526	int i;
 527	union max_down_spread max_down_spread = {0};
 528
 529	// Read DPCD 00101h to find out the number of lanes currently set
 530	for (i = 0; i < read_dpcd_retry_cnt; i++) {
 531		status = core_link_read_dpcd(link,
 532					     DP_LANE_COUNT_SET,
 533					     &lane_count_set.raw,
 534					     sizeof(lane_count_set));
 535		/* First DPCD read after VDD ON can fail if the particular board
 536		 * does not have HPD pin wired correctly. So if DPCD read fails,
 537		 * which it should never happen, retry a few times. Target worst
 538		 * case scenario of 80 ms.
 539		 */
 540		if (status == DC_OK) {
 541			link->cur_link_settings.lane_count =
 542					lane_count_set.bits.LANE_COUNT_SET;
 543			break;
 544		}
 545
 546		msleep(8);
 547	}
 548
 549	// Read DPCD 00100h to find if standard link rates are set
 550	core_link_read_dpcd(link, DP_LINK_BW_SET,
 551			    &link_bw_set, sizeof(link_bw_set));
 552
 553	if (link_bw_set == 0) {
 554		if (link->connector_signal == SIGNAL_TYPE_EDP) {
 555			/* If standard link rates are not being used,
 556			 * Read DPCD 00115h to find the edp link rate set used
 557			 */
 558			core_link_read_dpcd(link, DP_LINK_RATE_SET,
 559					    &link_rate_set, sizeof(link_rate_set));
 560
 561			// edp_supported_link_rates_count = 0 for DP
 562			if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
 563				link->cur_link_settings.link_rate =
 564					link->dpcd_caps.edp_supported_link_rates[link_rate_set];
 565				link->cur_link_settings.link_rate_set = link_rate_set;
 566				link->cur_link_settings.use_link_rate_set = true;
 567			}
 568		} else {
 569			// Link Rate not found. Seamless boot may not work.
 570			ASSERT(false);
 571		}
 572	} else {
 573		link->cur_link_settings.link_rate = link_bw_set;
 574		link->cur_link_settings.use_link_rate_set = false;
 575	}
 576	// Read DPCD 00003h to find the max down spread.
 577	core_link_read_dpcd(link, DP_MAX_DOWNSPREAD,
 578			    &max_down_spread.raw, sizeof(max_down_spread));
 579	link->cur_link_settings.link_spread =
 580		max_down_spread.bits.MAX_DOWN_SPREAD ?
 581		LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
 582}
 583
 584static bool detect_dp(struct dc_link *link,
 585		      struct display_sink_capability *sink_caps,
 586		      enum dc_detect_reason reason)
 587{
 588	struct audio_support *audio_support = &link->dc->res_pool->audio_support;
 589
 590	sink_caps->signal = link_detect_sink_signal_type(link, reason);
 591	sink_caps->transaction_type =
 592		get_ddc_transaction_type(sink_caps->signal);
 593
 594	if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
 595		sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
 596		if (!detect_dp_sink_caps(link))
 597			return false;
 598
 599		if (is_dp_branch_device(link))
 600			/* DP SST branch */
 601			link->type = dc_connection_sst_branch;
 602	} else {
 603		if (link->dc->debug.disable_dp_plus_plus_wa &&
 604				link->link_enc->features.flags.bits.IS_UHBR20_CAPABLE)
 605			return false;
 606
 607		/* DP passive dongles */
 608		sink_caps->signal = dp_passive_dongle_detection(link->ddc,
 609								sink_caps,
 610								audio_support);
 611		link->dpcd_caps.dongle_type = sink_caps->dongle_type;
 612		link->dpcd_caps.is_dongle_type_one = sink_caps->is_dongle_type_one;
 613		link->dpcd_caps.dpcd_rev.raw = 0;
 614	}
 615
 616	return true;
 617}
 618
 619static bool is_same_edid(struct dc_edid *old_edid, struct dc_edid *new_edid)
 620{
 621	if (old_edid->length != new_edid->length)
 622		return false;
 623
 624	if (new_edid->length == 0)
 625		return false;
 626
 627	return (memcmp(old_edid->raw_edid,
 628		       new_edid->raw_edid, new_edid->length) == 0);
 629}
 630
 631static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
 632{
 633
 634	/**
 635	 * something is terribly wrong if time out is > 200ms. (5Hz)
 636	 * 500 microseconds * 400 tries us 200 ms
 637	 **/
 638	unsigned int sleep_time_in_microseconds = 500;
 639	unsigned int tries_allowed = 400;
 640	bool is_in_alt_mode;
 641	unsigned long long enter_timestamp;
 642	unsigned long long finish_timestamp;
 643	unsigned long long time_taken_in_ns;
 644	int tries_taken;
 645
 646	DC_LOGGER_INIT(link->ctx->logger);
 647
 648	/**
 649	 * this function will only exist if we are on dcn21 (is_in_alt_mode is a
 650	 *  function pointer, so checking to see if it is equal to 0 is the same
 651	 *  as checking to see if it is null
 652	 **/
 653	if (!link->link_enc->funcs->is_in_alt_mode)
 654		return true;
 655
 656	is_in_alt_mode = link->link_enc->funcs->is_in_alt_mode(link->link_enc);
 657	DC_LOG_DC("DP Alt mode state on HPD: %d\n", is_in_alt_mode);
 658
 659	if (is_in_alt_mode)
 660		return true;
 661
 662	enter_timestamp = dm_get_timestamp(link->ctx);
 663
 664	for (tries_taken = 0; tries_taken < tries_allowed; tries_taken++) {
 665		udelay(sleep_time_in_microseconds);
 666		/* ask the link if alt mode is enabled, if so return ok */
 667		if (link->link_enc->funcs->is_in_alt_mode(link->link_enc)) {
 668			finish_timestamp = dm_get_timestamp(link->ctx);
 669			time_taken_in_ns =
 670				dm_get_elapse_time_in_ns(link->ctx,
 671							 finish_timestamp,
 672							 enter_timestamp);
 673			DC_LOG_WARNING("Alt mode entered finished after %llu ms\n",
 674				       div_u64(time_taken_in_ns, 1000000));
 675			return true;
 676		}
 677	}
 678	finish_timestamp = dm_get_timestamp(link->ctx);
 679	time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp,
 680						    enter_timestamp);
 681	DC_LOG_WARNING("Alt mode has timed out after %llu ms\n",
 682			div_u64(time_taken_in_ns, 1000000));
 683	return false;
 684}
 685
 686static void apply_dpia_mst_dsc_always_on_wa(struct dc_link *link)
 687{
 688	/* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock
 689	 * reports DSC support.
 690	 */
 691	if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
 692			link->type == dc_connection_mst_branch &&
 693			link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
 694			link->dpcd_caps.branch_hw_revision == DP_BRANCH_HW_REV_20 &&
 695			link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
 696			!link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around)
 697		link->wa_flags.dpia_mst_dsc_always_on = true;
 698
 699	if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
 700		link->type == dc_connection_mst_branch &&
 701		link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
 702		link->dpcd_caps.branch_vendor_specific_data[2] == MST_HUB_ID_0x5A &&
 703		link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
 704		!link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around) {
 705			link->wa_flags.dpia_mst_dsc_always_on = true;
 706	}
 707}
 708
 709static void revert_dpia_mst_dsc_always_on_wa(struct dc_link *link)
 710{
 711	/* Disable work around which keeps DSC on for tunneled MST on certain USB4 docks. */
 712	if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
 713		link->wa_flags.dpia_mst_dsc_always_on = false;
 714}
 715
 716static bool discover_dp_mst_topology(struct dc_link *link, enum dc_detect_reason reason)
 717{
 718	DC_LOGGER_INIT(link->ctx->logger);
 719
 720	LINK_INFO("link=%d, mst branch is now Connected\n",
 721		  link->link_index);
 722
 723	link->type = dc_connection_mst_branch;
 724	apply_dpia_mst_dsc_always_on_wa(link);
 725
 726	dm_helpers_dp_update_branch_info(link->ctx, link);
 727	if (dm_helpers_dp_mst_start_top_mgr(link->ctx,
 728			link, (reason == DETECT_REASON_BOOT || reason == DETECT_REASON_RESUMEFROMS3S4))) {
 729		link_disconnect_sink(link);
 730	} else {
 731		link->type = dc_connection_sst_branch;
 732	}
 733
 734	return link->type == dc_connection_mst_branch;
 735}
 736
 737bool link_reset_cur_dp_mst_topology(struct dc_link *link)
 738{
 739	DC_LOGGER_INIT(link->ctx->logger);
 740
 741	LINK_INFO("link=%d, mst branch is now Disconnected\n",
 742		  link->link_index);
 743
 744	revert_dpia_mst_dsc_always_on_wa(link);
 745	return dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
 746}
 747
 748static bool should_prepare_phy_clocks_for_link_verification(const struct dc *dc,
 749		enum dc_detect_reason reason)
 750{
 751	int i;
 752	bool can_apply_seamless_boot = false;
 753
 754	for (i = 0; i < dc->current_state->stream_count; i++) {
 755		if (dc->current_state->streams[i]->apply_seamless_boot_optimization) {
 756			can_apply_seamless_boot = true;
 757			break;
 758		}
 759	}
 760
 761	return !can_apply_seamless_boot && reason != DETECT_REASON_BOOT;
 762}
 763
 764static void prepare_phy_clocks_for_destructive_link_verification(const struct dc *dc)
 765{
 766	dc_z10_restore(dc);
 767	clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
 768}
 769
 770static void restore_phy_clocks_for_destructive_link_verification(const struct dc *dc)
 771{
 772	clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
 773}
 774
 775static void verify_link_capability_destructive(struct dc_link *link,
 776		struct dc_sink *sink,
 777		enum dc_detect_reason reason)
 778{
 779	bool should_prepare_phy_clocks =
 780			should_prepare_phy_clocks_for_link_verification(link->dc, reason);
 781
 782	if (should_prepare_phy_clocks)
 783		prepare_phy_clocks_for_destructive_link_verification(link->dc);
 784
 785	if (dc_is_dp_signal(link->local_sink->sink_signal)) {
 786		struct dc_link_settings known_limit_link_setting =
 787				dp_get_max_link_cap(link);
 788		link_set_all_streams_dpms_off_for_link(link);
 789		dp_verify_link_cap_with_retries(
 790				link, &known_limit_link_setting,
 791				LINK_TRAINING_MAX_VERIFY_RETRY);
 792	} else {
 793		ASSERT(0);
 794	}
 795
 796	if (should_prepare_phy_clocks)
 797		restore_phy_clocks_for_destructive_link_verification(link->dc);
 798}
 799
 800static void verify_link_capability_non_destructive(struct dc_link *link)
 801{
 802	if (dc_is_dp_signal(link->local_sink->sink_signal)) {
 803		if (dc_is_embedded_signal(link->local_sink->sink_signal) ||
 804				link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
 805			/* TODO - should we check link encoder's max link caps here?
 806			 * How do we know which link encoder to check from?
 807			 */
 808			link->verified_link_cap = link->reported_link_cap;
 809		else
 810			link->verified_link_cap = dp_get_max_link_cap(link);
 811	}
 812}
 813
 814static bool should_verify_link_capability_destructively(struct dc_link *link,
 815		enum dc_detect_reason reason)
 816{
 817	bool destrictive = false;
 818	struct dc_link_settings max_link_cap;
 819	bool is_link_enc_unavailable = link->link_enc &&
 820			link->dc->res_pool->funcs->link_encs_assign &&
 821			!link_enc_cfg_is_link_enc_avail(
 822					link->ctx->dc,
 823					link->link_enc->preferred_engine,
 824					link);
 825
 826	if (dc_is_dp_signal(link->local_sink->sink_signal)) {
 827		max_link_cap = dp_get_max_link_cap(link);
 828		destrictive = true;
 829
 830		if (link->dc->debug.skip_detection_link_training ||
 831				dc_is_embedded_signal(link->local_sink->sink_signal) ||
 832				link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
 833			destrictive = false;
 834		} else if (link_dp_get_encoding_format(&max_link_cap) ==
 835				DP_8b_10b_ENCODING) {
 836			if (link->dpcd_caps.is_mst_capable ||
 837					is_link_enc_unavailable) {
 838				destrictive = false;
 839			}
 840		}
 841	}
 842
 843	return destrictive;
 844}
 845
 846static void verify_link_capability(struct dc_link *link, struct dc_sink *sink,
 847		enum dc_detect_reason reason)
 848{
 849	if (should_verify_link_capability_destructively(link, reason))
 850		verify_link_capability_destructive(link, sink, reason);
 851	else
 852		verify_link_capability_non_destructive(link);
 853}
 854
 855/*
 856 * detect_link_and_local_sink() - Detect if a sink is attached to a given link
 857 *
 858 * link->local_sink is created or destroyed as needed.
 859 *
 860 * This does not create remote sinks.
 861 */
 862static bool detect_link_and_local_sink(struct dc_link *link,
 863				  enum dc_detect_reason reason)
 864{
 865	struct dc_sink_init_data sink_init_data = { 0 };
 866	struct display_sink_capability sink_caps = { 0 };
 867	uint32_t i;
 868	bool converter_disable_audio = false;
 869	struct audio_support *aud_support = &link->dc->res_pool->audio_support;
 870	bool same_edid = false;
 871	enum dc_edid_status edid_status;
 872	struct dc_context *dc_ctx = link->ctx;
 873	struct dc *dc = dc_ctx->dc;
 874	struct dc_sink *sink = NULL;
 875	struct dc_sink *prev_sink = NULL;
 876	struct dpcd_caps prev_dpcd_caps;
 877	enum dc_connection_type new_connection_type = dc_connection_none;
 878	const uint32_t post_oui_delay = 30; // 30ms
 879
 880	DC_LOGGER_INIT(link->ctx->logger);
 881
 882	if (dc_is_virtual_signal(link->connector_signal))
 883		return false;
 884
 885	if (((link->connector_signal == SIGNAL_TYPE_LVDS ||
 886		link->connector_signal == SIGNAL_TYPE_EDP) &&
 887		(!link->dc->config.allow_edp_hotplug_detection)) &&
 888		link->local_sink) {
 889		// need to re-write OUI and brightness in resume case
 890		if (link->connector_signal == SIGNAL_TYPE_EDP &&
 891			(link->dpcd_sink_ext_caps.bits.oled == 1)) {
 892			dpcd_set_source_specific_data(link);
 893			msleep(post_oui_delay);
 894			set_default_brightness_aux(link);
 895		}
 896
 897		return true;
 898	}
 899
 900	if (!link_detect_connection_type(link, &new_connection_type)) {
 901		BREAK_TO_DEBUGGER();
 902		return false;
 903	}
 904
 905	prev_sink = link->local_sink;
 906	if (prev_sink) {
 907		dc_sink_retain(prev_sink);
 908		memcpy(&prev_dpcd_caps, &link->dpcd_caps, sizeof(struct dpcd_caps));
 909	}
 910
 911	link_disconnect_sink(link);
 912	if (new_connection_type != dc_connection_none) {
 913		link->type = new_connection_type;
 914		link->link_state_valid = false;
 915
 916		/* From Disconnected-to-Connected. */
 917		switch (link->connector_signal) {
 918		case SIGNAL_TYPE_HDMI_TYPE_A: {
 919			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
 920			if (aud_support->hdmi_audio_native)
 921				sink_caps.signal = SIGNAL_TYPE_HDMI_TYPE_A;
 922			else
 923				sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
 924			break;
 925		}
 926
 927		case SIGNAL_TYPE_DVI_SINGLE_LINK: {
 928			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
 929			sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
 930			break;
 931		}
 932
 933		case SIGNAL_TYPE_DVI_DUAL_LINK: {
 934			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
 935			sink_caps.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
 936			break;
 937		}
 938
 939		case SIGNAL_TYPE_LVDS: {
 940			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
 941			sink_caps.signal = SIGNAL_TYPE_LVDS;
 942			break;
 943		}
 944
 945		case SIGNAL_TYPE_EDP: {
 946			detect_edp_sink_caps(link);
 947			read_current_link_settings_on_detect(link);
 948
 949			/* Disable power sequence on MIPI panel + converter
 950			 */
 951			if (dc->config.enable_mipi_converter_optimization &&
 952				dc_ctx->dce_version == DCN_VERSION_3_01 &&
 953				link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_0022B9 &&
 954				memcmp(&link->dpcd_caps.branch_dev_name, DP_SINK_BRANCH_DEV_NAME_7580,
 955					sizeof(link->dpcd_caps.branch_dev_name)) == 0) {
 956				dc->config.edp_no_power_sequencing = true;
 957
 958				if (!link->dpcd_caps.set_power_state_capable_edp)
 959					link->wa_flags.dp_keep_receiver_powered = true;
 960			}
 961
 962			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
 963			sink_caps.signal = SIGNAL_TYPE_EDP;
 964			break;
 965		}
 966
 967		case SIGNAL_TYPE_DISPLAY_PORT: {
 968
 969			/* wa HPD high coming too early*/
 970			if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
 971			    link->link_enc->features.flags.bits.DP_IS_USB_C == 1) {
 972
 973				/* if alt mode times out, return false */
 974				if (!wait_for_entering_dp_alt_mode(link))
 975					return false;
 976			}
 977
 978			if (!detect_dp(link, &sink_caps, reason)) {
 979
 980				if (prev_sink)
 981					dc_sink_release(prev_sink);
 982				return false;
 983			}
 984
 985			/* Active SST downstream branch device unplug*/
 986			if (link->type == dc_connection_sst_branch &&
 987			    link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
 988				if (prev_sink)
 989					/* Downstream unplug */
 990					dc_sink_release(prev_sink);
 991				return true;
 992			}
 993
 994			/* disable audio for non DP to HDMI active sst converter */
 995			if (link->type == dc_connection_sst_branch &&
 996					is_dp_active_dongle(link) &&
 997					(link->dpcd_caps.dongle_type !=
 998							DISPLAY_DONGLE_DP_HDMI_CONVERTER))
 999				converter_disable_audio = true;
1000
1001			/* limited link rate to HBR3 for DPIA until we implement USB4 V2 */
1002			if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
1003					link->reported_link_cap.link_rate > LINK_RATE_HIGH3)
1004				link->reported_link_cap.link_rate = LINK_RATE_HIGH3;
1005
1006			/*
1007			 * If this is DP over USB4 link then we need to:
1008			 * - Enable BW ALLOC support on DPtx if applicable
1009			 */
1010			if (dc->config.usb4_bw_alloc_support) {
1011				if (link_dp_dpia_set_dptx_usb4_bw_alloc_support(link)) {
1012					/* update with non reduced link cap if bw allocation mode is supported */
1013					if (link->dpia_bw_alloc_config.nrd_max_link_rate &&
1014						link->dpia_bw_alloc_config.nrd_max_lane_count) {
1015						link->reported_link_cap.link_rate =
1016							link->dpia_bw_alloc_config.nrd_max_link_rate;
1017						link->reported_link_cap.lane_count =
1018							link->dpia_bw_alloc_config.nrd_max_lane_count;
1019					}
1020				}
1021			}
1022			break;
1023		}
1024
1025		default:
1026			DC_ERROR("Invalid connector type! signal:%d\n",
1027				 link->connector_signal);
1028			if (prev_sink)
1029				dc_sink_release(prev_sink);
1030			return false;
1031		} /* switch() */
1032
1033		if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
1034			link->dpcd_sink_count =
1035				link->dpcd_caps.sink_count.bits.SINK_COUNT;
1036		else
1037			link->dpcd_sink_count = 1;
1038
1039		set_ddc_transaction_type(link->ddc,
1040						     sink_caps.transaction_type);
1041
1042		link->aux_mode =
1043			link_is_in_aux_transaction_mode(link->ddc);
1044
1045		sink_init_data.link = link;
1046		sink_init_data.sink_signal = sink_caps.signal;
1047
1048		sink = dc_sink_create(&sink_init_data);
1049		if (!sink) {
1050			DC_ERROR("Failed to create sink!\n");
1051			if (prev_sink)
1052				dc_sink_release(prev_sink);
1053			return false;
1054		}
1055
1056		sink->link->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
1057		sink->converter_disable_audio = converter_disable_audio;
1058
1059		/* dc_sink_create returns a new reference */
1060		link->local_sink = sink;
1061
1062		edid_status = dm_helpers_read_local_edid(link->ctx,
1063							 link, sink);
1064
1065		switch (edid_status) {
1066		case EDID_BAD_CHECKSUM:
1067			DC_LOG_ERROR("EDID checksum invalid.\n");
1068			break;
1069		case EDID_PARTIAL_VALID:
1070			DC_LOG_ERROR("Partial EDID valid, abandon invalid blocks.\n");
1071			break;
1072		case EDID_NO_RESPONSE:
1073			DC_LOG_ERROR("No EDID read.\n");
1074			/*
1075			 * Abort detection for non-DP connectors if we have
1076			 * no EDID
1077			 *
1078			 * DP needs to report as connected if HDP is high
1079			 * even if we have no EDID in order to go to
1080			 * fail-safe mode
1081			 */
1082			if (dc_is_hdmi_signal(link->connector_signal) ||
1083			    dc_is_dvi_signal(link->connector_signal)) {
1084				if (prev_sink)
1085					dc_sink_release(prev_sink);
1086
1087				return false;
1088			}
1089
1090			if (link->type == dc_connection_sst_branch &&
1091					link->dpcd_caps.dongle_type ==
1092						DISPLAY_DONGLE_DP_VGA_CONVERTER &&
1093					reason == DETECT_REASON_HPDRX) {
1094				/* Abort detection for DP-VGA adapters when EDID
1095				 * can't be read and detection reason is VGA-side
1096				 * hotplug
1097				 */
1098				if (prev_sink)
1099					dc_sink_release(prev_sink);
1100				link_disconnect_sink(link);
1101
1102				return true;
1103			}
1104
1105			break;
1106		default:
1107			break;
1108		}
1109
1110		// Check if edid is the same
1111		if ((prev_sink) &&
1112		    (edid_status == EDID_THE_SAME || edid_status == EDID_OK))
1113			same_edid = is_same_edid(&prev_sink->dc_edid,
1114						 &sink->dc_edid);
1115
1116		if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
1117			link->ctx->dc->debug.hdmi20_disable = true;
1118
1119		if (sink->edid_caps.panel_patch.remove_sink_ext_caps)
1120			link->dpcd_sink_ext_caps.raw = 0;
1121
1122		if (dc_is_hdmi_signal(link->connector_signal))
1123			read_scdc_caps(link->ddc, link->local_sink);
1124
1125		if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
1126		    sink_caps.transaction_type ==
1127		    DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
1128			/*
1129			 * TODO debug why certain monitors don't like
1130			 *  two link trainings
1131			 */
1132			query_hdcp_capability(sink->sink_signal, link);
1133		} else {
1134			// If edid is the same, then discard new sink and revert back to original sink
1135			if (same_edid) {
1136				link_disconnect_remap(prev_sink, link);
1137				sink = prev_sink;
1138				prev_sink = NULL;
1139			}
1140			query_hdcp_capability(sink->sink_signal, link);
1141		}
1142
1143		/* HDMI-DVI Dongle */
1144		if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
1145		    !sink->edid_caps.edid_hdmi)
1146			sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
1147
1148		if (link->local_sink && dc_is_dp_signal(sink_caps.signal))
1149			dp_trace_init(link);
1150
1151		/* Connectivity log: detection */
1152		for (i = 0; i < sink->dc_edid.length / DC_EDID_BLOCK_SIZE; i++) {
1153			CONN_DATA_DETECT(link,
1154					 &sink->dc_edid.raw_edid[i * DC_EDID_BLOCK_SIZE],
1155					 DC_EDID_BLOCK_SIZE,
1156					 "%s: [Block %d] ", sink->edid_caps.display_name, i);
1157		}
1158
1159		DC_LOG_DETECTION_EDID_PARSER("%s: "
1160			"manufacturer_id = %X, "
1161			"product_id = %X, "
1162			"serial_number = %X, "
1163			"manufacture_week = %d, "
1164			"manufacture_year = %d, "
1165			"display_name = %s, "
1166			"speaker_flag = %d, "
1167			"audio_mode_count = %d\n",
1168			__func__,
1169			sink->edid_caps.manufacturer_id,
1170			sink->edid_caps.product_id,
1171			sink->edid_caps.serial_number,
1172			sink->edid_caps.manufacture_week,
1173			sink->edid_caps.manufacture_year,
1174			sink->edid_caps.display_name,
1175			sink->edid_caps.speaker_flags,
1176			sink->edid_caps.audio_mode_count);
1177
1178		for (i = 0; i < sink->edid_caps.audio_mode_count; i++) {
1179			DC_LOG_DETECTION_EDID_PARSER("%s: mode number = %d, "
1180				"format_code = %d, "
1181				"channel_count = %d, "
1182				"sample_rate = %d, "
1183				"sample_size = %d\n",
1184				__func__,
1185				i,
1186				sink->edid_caps.audio_modes[i].format_code,
1187				sink->edid_caps.audio_modes[i].channel_count,
1188				sink->edid_caps.audio_modes[i].sample_rate,
1189				sink->edid_caps.audio_modes[i].sample_size);
1190		}
1191
1192		if (link->connector_signal == SIGNAL_TYPE_EDP) {
1193			// Init dc_panel_config by HW config
1194			if (dc_ctx->dc->res_pool->funcs->get_panel_config_defaults)
1195				dc_ctx->dc->res_pool->funcs->get_panel_config_defaults(&link->panel_config);
1196			// Pickup base DM settings
1197			dm_helpers_init_panel_settings(dc_ctx, &link->panel_config, sink);
1198			// Override dc_panel_config if system has specific settings
1199			dm_helpers_override_panel_settings(dc_ctx, &link->panel_config);
1200
1201			//sink only can use supported link rate table, we are foreced to enable it
1202			if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
1203				link->panel_config.ilr.optimize_edp_link_rate = true;
1204			link->reported_link_cap.link_rate = get_max_edp_link_rate(link);
1205		}
1206
1207	} else {
1208		/* From Connected-to-Disconnected. */
1209		link->type = dc_connection_none;
1210		sink_caps.signal = SIGNAL_TYPE_NONE;
1211		memset(&link->hdcp_caps, 0, sizeof(struct hdcp_caps));
1212		/* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk
1213		 *  is not cleared. If we emulate a DP signal on this connection, it thinks
1214		 *  the dongle is still there and limits the number of modes we can emulate.
1215		 *  Clear dongle_max_pix_clk on disconnect to fix this
1216		 */
1217		link->dongle_max_pix_clk = 0;
1218
1219		dc_link_clear_dprx_states(link);
1220		dp_trace_reset(link);
1221	}
1222
1223	LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p edid same=%d\n",
1224		  link->link_index, sink,
1225		  (sink_caps.signal ==
1226		   SIGNAL_TYPE_NONE ? "Disconnected" : "Connected"),
1227		  prev_sink, same_edid);
1228
1229	if (prev_sink)
1230		dc_sink_release(prev_sink);
1231
1232	return true;
1233}
1234
1235/*
1236 * link_detect_connection_type() - Determine if there is a sink connected
1237 *
1238 * @type: Returned connection type
1239 * Does not detect downstream devices, such as MST sinks
1240 * or display connected through active dongles
1241 */
1242bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type)
1243{
1244	uint32_t is_hpd_high = 0;
1245
1246	if (link->connector_signal == SIGNAL_TYPE_LVDS) {
1247		*type = dc_connection_single;
1248		return true;
1249	}
1250
1251	if (link->connector_signal == SIGNAL_TYPE_EDP) {
1252		/*in case it is not on*/
1253		if (!link->dc->config.edp_no_power_sequencing)
1254			link->dc->hwss.edp_power_control(link, true);
1255		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
1256	}
1257
1258	/* Link may not have physical HPD pin. */
1259	if (link->ep_type != DISPLAY_ENDPOINT_PHY) {
1260		if (link->is_hpd_pending || !dpia_query_hpd_status(link))
1261			*type = dc_connection_none;
1262		else
1263			*type = dc_connection_single;
1264
1265		return true;
1266	}
1267
1268
1269	if (!query_hpd_status(link, &is_hpd_high))
1270		goto hpd_gpio_failure;
1271
1272	if (is_hpd_high) {
1273		*type = dc_connection_single;
1274		/* TODO: need to do the actual detection */
1275	} else {
1276		*type = dc_connection_none;
1277		if (link->connector_signal == SIGNAL_TYPE_EDP) {
1278			/* eDP is not connected, power down it */
1279			if (!link->dc->config.edp_no_power_sequencing)
1280				link->dc->hwss.edp_power_control(link, false);
1281		}
1282	}
1283
1284	return true;
1285
1286hpd_gpio_failure:
1287	return false;
1288}
1289
1290bool link_detect(struct dc_link *link, enum dc_detect_reason reason)
1291{
1292	bool is_local_sink_detect_success;
1293	bool is_delegated_to_mst_top_mgr = false;
1294	enum dc_connection_type pre_link_type = link->type;
1295
1296	DC_LOGGER_INIT(link->ctx->logger);
1297
1298	is_local_sink_detect_success = detect_link_and_local_sink(link, reason);
1299
1300	if (is_local_sink_detect_success && link->local_sink)
1301		verify_link_capability(link, link->local_sink, reason);
1302
1303	DC_LOG_DC("%s: link_index=%d is_local_sink_detect_success=%d pre_link_type=%d link_type=%d\n", __func__,
1304				link->link_index, is_local_sink_detect_success, pre_link_type, link->type);
1305
1306	if (is_local_sink_detect_success && link->local_sink &&
1307			dc_is_dp_signal(link->local_sink->sink_signal) &&
1308			link->dpcd_caps.is_mst_capable)
1309		is_delegated_to_mst_top_mgr = discover_dp_mst_topology(link, reason);
1310
1311	if (pre_link_type == dc_connection_mst_branch &&
1312			link->type != dc_connection_mst_branch)
1313		is_delegated_to_mst_top_mgr = link_reset_cur_dp_mst_topology(link);
1314
1315	return is_local_sink_detect_success && !is_delegated_to_mst_top_mgr;
1316}
1317
1318void link_clear_dprx_states(struct dc_link *link)
1319{
1320	memset(&link->dprx_states, 0, sizeof(link->dprx_states));
1321}
1322
1323bool link_is_hdcp14(struct dc_link *link, enum signal_type signal)
1324{
1325	bool ret = false;
1326
1327	switch (signal)	{
1328	case SIGNAL_TYPE_DISPLAY_PORT:
1329	case SIGNAL_TYPE_DISPLAY_PORT_MST:
1330		ret = link->hdcp_caps.bcaps.bits.HDCP_CAPABLE;
1331		break;
1332	case SIGNAL_TYPE_DVI_SINGLE_LINK:
1333	case SIGNAL_TYPE_DVI_DUAL_LINK:
1334	case SIGNAL_TYPE_HDMI_TYPE_A:
1335	/* HDMI doesn't tell us its HDCP(1.4) capability, so assume to always be capable,
1336	 * we can poll for bksv but some displays have an issue with this. Since its so rare
1337	 * for a display to not be 1.4 capable, this assumtion is ok
1338	 */
1339		ret = true;
1340		break;
1341	default:
1342		break;
1343	}
1344	return ret;
1345}
1346
1347bool link_is_hdcp22(struct dc_link *link, enum signal_type signal)
1348{
1349	bool ret = false;
1350
1351	switch (signal)	{
1352	case SIGNAL_TYPE_DISPLAY_PORT:
1353	case SIGNAL_TYPE_DISPLAY_PORT_MST:
1354		ret = (link->hdcp_caps.bcaps.bits.HDCP_CAPABLE &&
1355				link->hdcp_caps.rx_caps.fields.byte0.hdcp_capable &&
1356				(link->hdcp_caps.rx_caps.fields.version == 0x2)) ? 1 : 0;
1357		break;
1358	case SIGNAL_TYPE_DVI_SINGLE_LINK:
1359	case SIGNAL_TYPE_DVI_DUAL_LINK:
1360	case SIGNAL_TYPE_HDMI_TYPE_A:
1361		ret = (link->hdcp_caps.rx_caps.fields.version == 0x4) ? 1:0;
1362		break;
1363	default:
1364		break;
1365	}
1366
1367	return ret;
1368}
1369
1370const struct dc_link_status *link_get_status(const struct dc_link *link)
1371{
1372	return &link->link_status;
1373}
1374
1375
1376static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
1377{
1378	if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
1379		BREAK_TO_DEBUGGER();
1380		return false;
1381	}
1382
1383	dc_sink_retain(sink);
1384
1385	dc_link->remote_sinks[dc_link->sink_count] = sink;
1386	dc_link->sink_count++;
1387
1388	return true;
1389}
1390
1391struct dc_sink *link_add_remote_sink(
1392		struct dc_link *link,
1393		const uint8_t *edid,
1394		int len,
1395		struct dc_sink_init_data *init_data)
1396{
1397	struct dc_sink *dc_sink;
1398	enum dc_edid_status edid_status;
1399
1400	if (len > DC_MAX_EDID_BUFFER_SIZE) {
1401		dm_error("Max EDID buffer size breached!\n");
1402		return NULL;
1403	}
1404
1405	if (!init_data) {
1406		BREAK_TO_DEBUGGER();
1407		return NULL;
1408	}
1409
1410	if (!init_data->link) {
1411		BREAK_TO_DEBUGGER();
1412		return NULL;
1413	}
1414
1415	dc_sink = dc_sink_create(init_data);
1416
1417	if (!dc_sink)
1418		return NULL;
1419
1420	memmove(dc_sink->dc_edid.raw_edid, edid, len);
1421	dc_sink->dc_edid.length = len;
1422
1423	if (!link_add_remote_sink_helper(
1424			link,
1425			dc_sink))
1426		goto fail_add_sink;
1427
1428	edid_status = dm_helpers_parse_edid_caps(
1429			link,
1430			&dc_sink->dc_edid,
1431			&dc_sink->edid_caps);
1432
1433	/*
1434	 * Treat device as no EDID device if EDID
1435	 * parsing fails
1436	 */
1437	if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) {
1438		dc_sink->dc_edid.length = 0;
1439		dm_error("Bad EDID, status%d!\n", edid_status);
1440	}
1441
1442	return dc_sink;
1443
1444fail_add_sink:
1445	dc_sink_release(dc_sink);
1446	return NULL;
1447}
1448
1449void link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
1450{
1451	int i;
1452
1453	if (!link->sink_count) {
1454		BREAK_TO_DEBUGGER();
1455		return;
1456	}
1457
1458	for (i = 0; i < link->sink_count; i++) {
1459		if (link->remote_sinks[i] == sink) {
1460			dc_sink_release(sink);
1461			link->remote_sinks[i] = NULL;
1462
1463			/* shrink array to remove empty place */
1464			while (i < link->sink_count - 1) {
1465				link->remote_sinks[i] = link->remote_sinks[i+1];
1466				i++;
1467			}
1468			link->remote_sinks[i] = NULL;
1469			link->sink_count--;
1470			return;
1471		}
1472	}
1473}