File Index
Files and directories
Sign in
FILE

link_detection.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/link/link_detection.c C
   1/*
   2 * Copyright 2022 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: AMD
  23 *
  24 */
  25
  26/* FILE POLICY AND INTENDED USAGE:
  27 * This file 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	if (ddc_service->link->local_sink &&
 274		!ddc_service->link->local_sink->edid_caps.scdc_present)
 275		return;
 276
 277	link_query_ddc_data(ddc_service, slave_address, &offset,
 278			sizeof(offset), sink->scdc_caps.manufacturer_OUI.byte,
 279			sizeof(sink->scdc_caps.manufacturer_OUI.byte));
 280
 281	offset = HDMI_SCDC_DEVICE_ID;
 282
 283	link_query_ddc_data(ddc_service, slave_address, &offset,
 284			sizeof(offset), &(sink->scdc_caps.device_id.byte),
 285			sizeof(sink->scdc_caps.device_id.byte));
 286}
 287
 288static bool i2c_read(
 289	struct ddc_service *ddc,
 290	uint32_t address,
 291	uint8_t *buffer,
 292	uint32_t len)
 293{
 294	uint8_t offs_data = 0;
 295	struct i2c_payload payloads[2] = {
 296		{
 297		.write = true,
 298		.address = address,
 299		.length = 1,
 300		.data = &offs_data },
 301		{
 302		.write = false,
 303		.address = address,
 304		.length = len,
 305		.data = buffer } };
 306
 307	struct i2c_command command = {
 308		.payloads = payloads,
 309		.number_of_payloads = 2,
 310		.engine = DDC_I2C_COMMAND_ENGINE,
 311		.speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
 312
 313	return dm_helpers_submit_i2c(
 314			ddc->ctx,
 315			ddc->link,
 316			&command);
 317}
 318
 319enum {
 320	DP_SINK_CAP_SIZE =
 321		DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV + 1
 322};
 323
 324static void query_dp_dual_mode_adaptor(
 325	struct ddc_service *ddc,
 326	struct display_sink_capability *sink_cap)
 327{
 328	uint8_t i;
 329	bool is_valid_hdmi_signature;
 330	enum display_dongle_type *dongle = &sink_cap->dongle_type;
 331	uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
 332	bool is_type2_dongle = false;
 333	int retry_count = 2;
 334	struct dp_hdmi_dongle_signature_data *dongle_signature;
 335	struct dc_link *link = ddc->link;
 336
 337	/* Assume we have no valid DP passive dongle connected */
 338	*dongle = DISPLAY_DONGLE_NONE;
 339	sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
 340
 341	/* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
 342	if (!i2c_read(
 343		ddc,
 344		DP_HDMI_DONGLE_ADDRESS,
 345		type2_dongle_buf,
 346		sizeof(type2_dongle_buf))) {
 347		/* Passive HDMI dongles can sometimes fail here without retrying*/
 348		while (retry_count > 0) {
 349			if (i2c_read(ddc,
 350				DP_HDMI_DONGLE_ADDRESS,
 351				type2_dongle_buf,
 352				sizeof(type2_dongle_buf)))
 353				break;
 354			retry_count--;
 355		}
 356		if (retry_count == 0) {
 357			*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
 358			sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
 359
 360			CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
 361					"DP-DVI passive dongle %dMhz: ",
 362					DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
 363			return;
 364		}
 365	}
 366
 367	/* Check if Type 2 dongle.*/
 368	if (type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_ID] == DP_ADAPTOR_TYPE2_ID)
 369		is_type2_dongle = true;
 370
 371	dongle_signature =
 372		(struct dp_hdmi_dongle_signature_data *)type2_dongle_buf;
 373
 374	is_valid_hdmi_signature = true;
 375
 376	/* Check EOT */
 377	if (dongle_signature->eot != DP_HDMI_DONGLE_SIGNATURE_EOT) {
 378		is_valid_hdmi_signature = false;
 379	}
 380
 381	/* Check signature */
 382	for (i = 0; i < sizeof(dongle_signature->id); ++i) {
 383		/* If its not the right signature,
 384		 * skip mismatch in subversion byte.*/
 385		if (dongle_signature->id[i] !=
 386			dp_hdmi_dongle_signature_str[i] && i != 3) {
 387
 388			if (is_type2_dongle) {
 389				is_valid_hdmi_signature = false;
 390				break;
 391			}
 392
 393		}
 394	}
 395	if (is_valid_hdmi_signature)
 396		sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
 397
 398	if (is_type2_dongle) {
 399		uint32_t max_tmds_clk =
 400			type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK];
 401
 402		max_tmds_clk = max_tmds_clk * 2 + max_tmds_clk / 2;
 403
 404		if (0 == max_tmds_clk ||
 405				max_tmds_clk < DP_ADAPTOR_TYPE2_MIN_TMDS_CLK ||
 406				max_tmds_clk > DP_ADAPTOR_TYPE2_MAX_TMDS_CLK) {
 407			*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
 408
 409			CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 410					sizeof(type2_dongle_buf),
 411					"DP-DVI passive dongle %dMhz: ",
 412					DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
 413		} else {
 414			if (is_valid_hdmi_signature == true) {
 415				*dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
 416
 417				CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 418						sizeof(type2_dongle_buf),
 419						"Type 2 DP-HDMI passive dongle %dMhz: ",
 420						max_tmds_clk);
 421			} else {
 422				*dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
 423
 424				CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 425						sizeof(type2_dongle_buf),
 426						"Type 2 DP-HDMI passive dongle (no signature) %dMhz: ",
 427						max_tmds_clk);
 428
 429			}
 430
 431			/* Multiply by 1000 to convert to kHz. */
 432			sink_cap->max_hdmi_pixel_clock =
 433				max_tmds_clk * 1000;
 434		}
 435		sink_cap->is_dongle_type_one = false;
 436
 437	} else {
 438		if (is_valid_hdmi_signature == true) {
 439			*dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
 440
 441			CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 442					sizeof(type2_dongle_buf),
 443					"Type 1 DP-HDMI passive dongle %dMhz: ",
 444					sink_cap->max_hdmi_pixel_clock / 1000);
 445		} else {
 446			*dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
 447
 448			CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
 449					sizeof(type2_dongle_buf),
 450					"Type 1 DP-HDMI passive dongle (no signature) %dMhz: ",
 451					sink_cap->max_hdmi_pixel_clock / 1000);
 452		}
 453		sink_cap->is_dongle_type_one = true;
 454	}
 455
 456	return;
 457}
 458
 459static enum signal_type dp_passive_dongle_detection(struct ddc_service *ddc,
 460						    struct display_sink_capability *sink_cap,
 461						    struct audio_support *audio_support)
 462{
 463	query_dp_dual_mode_adaptor(ddc, sink_cap);
 464
 465	return decide_signal_from_strap_and_dongle_type(sink_cap->dongle_type,
 466							audio_support);
 467}
 468
 469static void link_disconnect_sink(struct dc_link *link)
 470{
 471	if (link->local_sink) {
 472		dc_sink_release(link->local_sink);
 473		link->local_sink = NULL;
 474	}
 475
 476	link->dpcd_sink_count = 0;
 477	//link->dpcd_caps.dpcd_rev.raw = 0;
 478}
 479
 480static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *link)
 481{
 482	dc_sink_release(link->local_sink);
 483	link->local_sink = prev_sink;
 484}
 485
 486static void query_hdcp_capability(enum signal_type signal, struct dc_link *link)
 487{
 488	struct hdcp_protection_message msg22;
 489	struct hdcp_protection_message msg14;
 490
 491	memset(&msg22, 0, sizeof(struct hdcp_protection_message));
 492	memset(&msg14, 0, sizeof(struct hdcp_protection_message));
 493	memset(link->hdcp_caps.rx_caps.raw, 0,
 494		sizeof(link->hdcp_caps.rx_caps.raw));
 495
 496	if ((link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
 497			link->ddc->transaction_type ==
 498			DDC_TRANSACTION_TYPE_I2C_OVER_AUX) ||
 499			link->connector_signal == SIGNAL_TYPE_EDP) {
 500		msg22.data = link->hdcp_caps.rx_caps.raw;
 501		msg22.length = sizeof(link->hdcp_caps.rx_caps.raw);
 502		msg22.msg_id = HDCP_MESSAGE_ID_RX_CAPS;
 503	} else {
 504		msg22.data = &link->hdcp_caps.rx_caps.fields.version;
 505		msg22.length = sizeof(link->hdcp_caps.rx_caps.fields.version);
 506		msg22.msg_id = HDCP_MESSAGE_ID_HDCP2VERSION;
 507	}
 508	msg22.version = HDCP_VERSION_22;
 509	msg22.link = HDCP_LINK_PRIMARY;
 510	msg22.max_retries = 5;
 511	dc_process_hdcp_msg(signal, link, &msg22);
 512
 513	if (signal == SIGNAL_TYPE_DISPLAY_PORT || signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
 514		msg14.data = &link->hdcp_caps.bcaps.raw;
 515		msg14.length = sizeof(link->hdcp_caps.bcaps.raw);
 516		msg14.msg_id = HDCP_MESSAGE_ID_READ_BCAPS;
 517		msg14.version = HDCP_VERSION_14;
 518		msg14.link = HDCP_LINK_PRIMARY;
 519		msg14.max_retries = 5;
 520
 521		dc_process_hdcp_msg(signal, link, &msg14);
 522	}
 523
 524}
 525static void read_current_link_settings_on_detect(struct dc_link *link)
 526{
 527	union lane_count_set lane_count_set = {0};
 528	uint8_t link_bw_set = 0;
 529	uint8_t link_rate_set = 0;
 530	uint32_t read_dpcd_retry_cnt = 10;
 531	enum dc_status status = DC_ERROR_UNEXPECTED;
 532	int i;
 533	union max_down_spread max_down_spread = {0};
 534
 535	// Read DPCD 00101h to find out the number of lanes currently set
 536	for (i = 0; i < read_dpcd_retry_cnt; i++) {
 537		status = core_link_read_dpcd(link,
 538					     DP_LANE_COUNT_SET,
 539					     &lane_count_set.raw,
 540					     sizeof(lane_count_set));
 541		/* First DPCD read after VDD ON can fail if the particular board
 542		 * does not have HPD pin wired correctly. So if DPCD read fails,
 543		 * which it should never happen, retry a few times. Target worst
 544		 * case scenario of 80 ms.
 545		 */
 546		if (status == DC_OK) {
 547			link->cur_link_settings.lane_count =
 548					lane_count_set.bits.LANE_COUNT_SET;
 549			break;
 550		}
 551
 552		msleep(8);
 553	}
 554
 555	// Read DPCD 00100h to find if standard link rates are set
 556	core_link_read_dpcd(link, DP_LINK_BW_SET,
 557			    &link_bw_set, sizeof(link_bw_set));
 558
 559	if (link_bw_set == 0) {
 560		if (link->connector_signal == SIGNAL_TYPE_EDP) {
 561			/* If standard link rates are not being used,
 562			 * Read DPCD 00115h to find the edp link rate set used
 563			 */
 564			core_link_read_dpcd(link, DP_LINK_RATE_SET,
 565					    &link_rate_set, sizeof(link_rate_set));
 566
 567			// edp_supported_link_rates_count = 0 for DP
 568			if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
 569				link->cur_link_settings.link_rate =
 570					link->dpcd_caps.edp_supported_link_rates[link_rate_set];
 571				link->cur_link_settings.link_rate_set = link_rate_set;
 572				link->cur_link_settings.use_link_rate_set = true;
 573			}
 574		} else {
 575			// Link Rate not found. Seamless boot may not work.
 576			ASSERT(false);
 577		}
 578	} else {
 579		link->cur_link_settings.link_rate = link_bw_set;
 580		link->cur_link_settings.use_link_rate_set = false;
 581	}
 582	// Read DPCD 00003h to find the max down spread.
 583	core_link_read_dpcd(link, DP_MAX_DOWNSPREAD,
 584			    &max_down_spread.raw, sizeof(max_down_spread));
 585	link->cur_link_settings.link_spread =
 586		max_down_spread.bits.MAX_DOWN_SPREAD ?
 587		LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
 588}
 589
 590static bool detect_dp(struct dc_link *link,
 591		      struct display_sink_capability *sink_caps,
 592		      enum dc_detect_reason reason)
 593{
 594	struct audio_support *audio_support = &link->dc->res_pool->audio_support;
 595
 596	sink_caps->signal = link_detect_sink_signal_type(link, reason);
 597	sink_caps->transaction_type =
 598		get_ddc_transaction_type(sink_caps->signal);
 599
 600	if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
 601		sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
 602		if (!detect_dp_sink_caps(link)) {
 603			return false;
 604		}
 605
 606		if (is_dp_branch_device(link))
 607			/* DP SST branch */
 608			link->type = dc_connection_sst_branch;
 609	} else {
 610		if (link->dc->debug.disable_dp_plus_plus_wa &&
 611				link->link_enc->features.flags.bits.IS_UHBR20_CAPABLE)
 612			return false;
 613
 614		/* DP passive dongles */
 615		sink_caps->signal = dp_passive_dongle_detection(link->ddc,
 616								sink_caps,
 617								audio_support);
 618		link->dpcd_caps.dongle_type = sink_caps->dongle_type;
 619		link->dpcd_caps.is_dongle_type_one = sink_caps->is_dongle_type_one;
 620		link->dpcd_caps.dpcd_rev.raw = 0;
 621		link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.raw = 0;
 622	}
 623
 624	return true;
 625}
 626
 627static bool is_same_edid(struct dc_edid *old_edid, struct dc_edid *new_edid)
 628{
 629	if (old_edid->length != new_edid->length)
 630		return false;
 631
 632	if (new_edid->length == 0)
 633		return false;
 634
 635	return (memcmp(old_edid->raw_edid,
 636		       new_edid->raw_edid, new_edid->length) == 0);
 637}
 638
 639static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
 640{
 641
 642	/**
 643	 * something is terribly wrong if time out is > 200ms. (5Hz)
 644	 * 500 microseconds * 400 tries us 200 ms
 645	 **/
 646	unsigned int sleep_time_in_microseconds = 500;
 647	unsigned int tries_allowed = 400;
 648	bool is_in_alt_mode;
 649	unsigned long long enter_timestamp;
 650	unsigned long long finish_timestamp;
 651	unsigned long long time_taken_in_ns;
 652	int tries_taken;
 653
 654	DC_LOGGER_INIT(link->ctx->logger);
 655
 656	/**
 657	 * this function will only exist if we are on dcn21 (is_in_alt_mode is a
 658	 *  function pointer, so checking to see if it is equal to 0 is the same
 659	 *  as checking to see if it is null
 660	 **/
 661	if (!link->link_enc->funcs->is_in_alt_mode)
 662		return true;
 663
 664	is_in_alt_mode = link->link_enc->funcs->is_in_alt_mode(link->link_enc);
 665	DC_LOG_DC("DP Alt mode state on HPD: %d  Link=%d\n", is_in_alt_mode, link->link_index);
 666
 667	if (is_in_alt_mode)
 668		return true;
 669
 670	enter_timestamp = dm_get_timestamp(link->ctx);
 671
 672	for (tries_taken = 0; tries_taken < tries_allowed; tries_taken++) {
 673		udelay(sleep_time_in_microseconds);
 674		/* ask the link if alt mode is enabled, if so return ok */
 675		if (link->link_enc->funcs->is_in_alt_mode(link->link_enc)) {
 676			finish_timestamp = dm_get_timestamp(link->ctx);
 677			time_taken_in_ns =
 678				dm_get_elapse_time_in_ns(link->ctx,
 679							 finish_timestamp,
 680							 enter_timestamp);
 681			DC_LOG_WARNING("Alt mode entered finished after %llu ms\n",
 682				       div_u64(time_taken_in_ns, 1000000));
 683			return true;
 684		}
 685	}
 686	finish_timestamp = dm_get_timestamp(link->ctx);
 687	time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp,
 688						    enter_timestamp);
 689	DC_LOG_WARNING("Alt mode has timed out after %llu ms\n",
 690			div_u64(time_taken_in_ns, 1000000));
 691	return false;
 692}
 693
 694static void apply_dpia_mst_dsc_always_on_wa(struct dc_link *link)
 695{
 696	/* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock
 697	 * reports DSC support.
 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_hw_revision == DP_BRANCH_HW_REV_20 &&
 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	if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
 708		link->type == dc_connection_mst_branch &&
 709		link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
 710		link->dpcd_caps.branch_vendor_specific_data[2] == MST_HUB_ID_0x5A &&
 711		link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
 712		!link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around) {
 713			link->wa_flags.dpia_mst_dsc_always_on = true;
 714	}
 715}
 716
 717static void revert_dpia_mst_dsc_always_on_wa(struct dc_link *link)
 718{
 719	/* Disable work around which keeps DSC on for tunneled MST on certain USB4 docks. */
 720	if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
 721		link->wa_flags.dpia_mst_dsc_always_on = false;
 722}
 723
 724static bool discover_dp_mst_topology(struct dc_link *link, enum dc_detect_reason reason)
 725{
 726	DC_LOGGER_INIT(link->ctx->logger);
 727
 728	LINK_INFO("link=%d, mst branch is now Connected\n",
 729		  link->link_index);
 730
 731	link->type = dc_connection_mst_branch;
 732	apply_dpia_mst_dsc_always_on_wa(link);
 733
 734	dm_helpers_dp_update_branch_info(link->ctx, link);
 735	if (dm_helpers_dp_mst_start_top_mgr(link->ctx,
 736			link, (reason == DETECT_REASON_BOOT || reason == DETECT_REASON_RESUMEFROMS3S4))) {
 737		link_disconnect_sink(link);
 738	} else {
 739		link->type = dc_connection_sst_branch;
 740	}
 741
 742	return link->type == dc_connection_mst_branch;
 743}
 744
 745bool link_reset_cur_dp_mst_topology(struct dc_link *link)
 746{
 747	DC_LOGGER_INIT(link->ctx->logger);
 748
 749	LINK_INFO("link=%d, mst branch is now Disconnected\n",
 750		  link->link_index);
 751
 752	revert_dpia_mst_dsc_always_on_wa(link);
 753	return dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
 754}
 755
 756static bool should_prepare_phy_clocks_for_link_verification(const struct dc *dc,
 757		enum dc_detect_reason reason)
 758{
 759	int i;
 760	bool can_apply_seamless_boot = false;
 761
 762	for (i = 0; i < dc->current_state->stream_count; i++) {
 763		if (dc->current_state->streams[i]->apply_seamless_boot_optimization) {
 764			can_apply_seamless_boot = true;
 765			break;
 766		}
 767	}
 768
 769	return !can_apply_seamless_boot && reason != DETECT_REASON_BOOT;
 770}
 771
 772static void prepare_phy_clocks_for_destructive_link_verification(const struct dc *dc)
 773{
 774	dc_z10_restore(dc);
 775	clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
 776}
 777
 778static void restore_phy_clocks_for_destructive_link_verification(const struct dc *dc)
 779{
 780	clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
 781}
 782
 783static void verify_link_capability_destructive(struct dc_link *link,
 784		struct dc_sink *sink,
 785		enum dc_detect_reason reason)
 786{
 787	bool should_prepare_phy_clocks =
 788			should_prepare_phy_clocks_for_link_verification(link->dc, reason);
 789
 790	if (should_prepare_phy_clocks)
 791		prepare_phy_clocks_for_destructive_link_verification(link->dc);
 792
 793	if (dc_is_dp_signal(link->local_sink->sink_signal)) {
 794		struct dc_link_settings known_limit_link_setting =
 795				dp_get_max_link_cap(link);
 796		link_set_all_streams_dpms_off_for_link(link);
 797		dp_verify_link_cap_with_retries(
 798				link, &known_limit_link_setting,
 799				LINK_TRAINING_MAX_VERIFY_RETRY);
 800	} else {
 801		ASSERT(0);
 802	}
 803
 804	if (should_prepare_phy_clocks)
 805		restore_phy_clocks_for_destructive_link_verification(link->dc);
 806}
 807
 808static void verify_link_capability_non_destructive(struct dc_link *link)
 809{
 810	if (dc_is_dp_signal(link->local_sink->sink_signal)) {
 811		if (dc_is_embedded_signal(link->local_sink->sink_signal) ||
 812				link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
 813			/* TODO - should we check link encoder's max link caps here?
 814			 * How do we know which link encoder to check from?
 815			 */
 816			link->verified_link_cap = link->reported_link_cap;
 817		else
 818			link->verified_link_cap = dp_get_max_link_cap(link);
 819	}
 820}
 821
 822static bool should_verify_link_capability_destructively(struct dc_link *link,
 823		enum dc_detect_reason reason)
 824{
 825	bool destrictive = false;
 826	struct dc_link_settings max_link_cap;
 827	bool is_link_enc_unavailable = false;
 828
 829	if (!link->dc->config.unify_link_enc_assignment)
 830		is_link_enc_unavailable = link->link_enc &&
 831			link->dc->res_pool->funcs->link_encs_assign &&
 832			!link_enc_cfg_is_link_enc_avail(
 833					link->ctx->dc,
 834					link->link_enc->preferred_engine,
 835					link);
 836
 837	if (dc_is_dp_signal(link->local_sink->sink_signal)) {
 838		max_link_cap = dp_get_max_link_cap(link);
 839		destrictive = true;
 840
 841		if (link->dc->debug.skip_detection_link_training ||
 842				dc_is_embedded_signal(link->local_sink->sink_signal) ||
 843				(link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
 844				!link->dc->config.enable_dpia_pre_training)) {
 845			destrictive = false;
 846		} else if (link_dp_get_encoding_format(&max_link_cap) ==
 847				DP_8b_10b_ENCODING) {
 848			if (link->dpcd_caps.is_mst_capable ||
 849					is_link_enc_unavailable) {
 850				destrictive = false;
 851			}
 852		}
 853	}
 854
 855	return destrictive;
 856}
 857
 858static void verify_link_capability(struct dc_link *link, struct dc_sink *sink,
 859		enum dc_detect_reason reason)
 860{
 861	if (should_verify_link_capability_destructively(link, reason))
 862		verify_link_capability_destructive(link, sink, reason);
 863	else
 864		verify_link_capability_non_destructive(link);
 865}
 866
 867/**
 868 * link_detect_evaluate_edid_header() - Evaluate if an EDID header is acceptable.
 869 *
 870 * Evaluates an 8-byte EDID header to check if it's good enough
 871 * for the purpose of determining whether a display is connected
 872 * without reading the full EDID.
 873 *
 874 * @edid_header: The first 8 bytes of the EDID read from DDC.
 875 *
 876 * Return: true if the header looks valid (>= 6 of 8 bytes match the
 877 *         expected 00/FF pattern), false otherwise.
 878 */
 879static bool link_detect_evaluate_edid_header(uint8_t edid_header[8])
 880{
 881	int edid_header_score = 0;
 882	int i;
 883
 884	for (i = 0; i < 8; ++i)
 885		edid_header_score += edid_header[i] == ((i == 0 || i == 7) ? 0x00 : 0xff);
 886
 887	return edid_header_score >= 6;
 888}
 889
 890/**
 891 * link_detect_ddc_probe() - Probe the DDC to see if a display is connected.
 892 *
 893 * Detect whether a display is connected to DDC without reading full EDID.
 894 * Reads only the EDID header (the first 8 bytes of EDID) from DDC and
 895 * evaluates whether that matches.
 896 *
 897 * @link: DC link whose DDC/I2C is probed for the EDID header.
 898 *
 899 * Return: true if the EDID header was read and passes validation,
 900 *         false otherwise.
 901 */
 902static bool link_detect_ddc_probe(struct dc_link *link)
 903{
 904	if (!link->ddc)
 905		return false;
 906
 907	uint8_t edid_header[8] = {0};
 908	bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header, sizeof(edid_header));
 909
 910	if (!ddc_probed)
 911		return false;
 912
 913	if (!link_detect_evaluate_edid_header(edid_header))
 914		return false;
 915
 916	return true;
 917}
 918
 919/**
 920 * link_detect_dac_load_detect() - Performs DAC load detection.
 921 *
 922 * Load detection can be used to detect the presence of an
 923 * analog display when we can't read DDC. This causes a visible
 924 * visual glitch so it should be used sparingly.
 925 *
 926 * @link: DC link to test using the DAC load-detect path.
 927 *
 928 * Return: true if the VBIOS load-detect call reports OK, false
 929 *         otherwise.
 930 */
 931static bool link_detect_dac_load_detect(struct dc_link *link)
 932{
 933	struct dc_bios *bios = link->ctx->dc_bios;
 934	struct link_encoder *link_enc = link->link_enc;
 935	enum engine_id engine_id = link_enc->preferred_engine;
 936	enum dal_device_type device_type = DEVICE_TYPE_CRT;
 937	enum bp_result bp_result = BP_RESULT_UNSUPPORTED;
 938	uint32_t enum_id;
 939
 940	switch (engine_id) {
 941	case ENGINE_ID_DACB:
 942		enum_id = 2;
 943		break;
 944	case ENGINE_ID_DACA:
 945	default:
 946		engine_id = ENGINE_ID_DACA;
 947		enum_id = 1;
 948		break;
 949	}
 950
 951	if (bios->funcs->dac_load_detection)
 952		bp_result = bios->funcs->dac_load_detection(bios, engine_id, device_type, enum_id);
 953
 954	return bp_result == BP_RESULT_OK;
 955}
 956
 957/*
 958 * detect_link_and_local_sink() - Detect if a sink is attached to a given link
 959 *
 960 * link->local_sink is created or destroyed as needed.
 961 *
 962 * This does not create remote sinks.
 963 */
 964static bool detect_link_and_local_sink(struct dc_link *link,
 965				  enum dc_detect_reason reason)
 966{
 967	struct dc_sink_init_data sink_init_data = { 0 };
 968	struct display_sink_capability sink_caps = { 0 };
 969	uint32_t i;
 970	bool converter_disable_audio = false;
 971	struct audio_support *aud_support = &link->dc->res_pool->audio_support;
 972	bool same_edid = false;
 973	enum dc_edid_status edid_status;
 974	struct dc_context *dc_ctx = link->ctx;
 975	struct dc *dc = dc_ctx->dc;
 976	struct dc_sink *sink = NULL;
 977	struct dc_sink *prev_sink = NULL;
 978	struct dpcd_caps prev_dpcd_caps;
 979	enum dc_connection_type new_connection_type = dc_connection_none;
 980	const uint32_t post_oui_delay = 30; // 30ms
 981
 982	DC_LOGGER_INIT(link->ctx->logger);
 983
 984	if (dc_is_virtual_signal(link->connector_signal))
 985		return false;
 986
 987	if (((link->connector_signal == SIGNAL_TYPE_LVDS ||
 988		link->connector_signal == SIGNAL_TYPE_EDP) &&
 989		(!link->dc->config.allow_edp_hotplug_detection)) &&
 990		link->local_sink) {
 991		// need to re-write OUI and brightness in resume case
 992		if (link->connector_signal == SIGNAL_TYPE_EDP &&
 993			(link->dpcd_sink_ext_caps.bits.oled == 1)) {
 994			dpcd_set_source_specific_data(link);
 995			msleep(post_oui_delay);
 996			set_default_brightness_aux(link);
 997		}
 998
 999		return true;
1000	}
1001
1002	if (!link_detect_connection_type(link, &new_connection_type)) {
1003		BREAK_TO_DEBUGGER();
1004		return false;
1005	}
1006
1007	prev_sink = link->local_sink;
1008	if (prev_sink) {
1009		dc_sink_retain(prev_sink);
1010		memcpy(&prev_dpcd_caps, &link->dpcd_caps, sizeof(struct dpcd_caps));
1011	}
1012
1013	link_disconnect_sink(link);
1014	if (new_connection_type != dc_connection_none) {
1015		link->type = new_connection_type;
1016		link->link_state_valid = false;
1017
1018		/* From Disconnected-to-Connected. */
1019		switch (link->connector_signal) {
1020		case SIGNAL_TYPE_HDMI_TYPE_A: {
1021			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
1022			if (aud_support->hdmi_audio_native)
1023				sink_caps.signal = SIGNAL_TYPE_HDMI_TYPE_A;
1024			else
1025				sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
1026			break;
1027		}
1028
1029		case SIGNAL_TYPE_DVI_SINGLE_LINK: {
1030			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
1031			sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
1032			break;
1033		}
1034
1035		case SIGNAL_TYPE_DVI_DUAL_LINK: {
1036			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
1037			sink_caps.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
1038			break;
1039		}
1040
1041		case SIGNAL_TYPE_RGB: {
1042			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
1043			sink_caps.signal = SIGNAL_TYPE_RGB;
1044			break;
1045		}
1046
1047		case SIGNAL_TYPE_LVDS: {
1048			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
1049			sink_caps.signal = SIGNAL_TYPE_LVDS;
1050			break;
1051		}
1052
1053		case SIGNAL_TYPE_EDP: {
1054			detect_edp_sink_caps(link);
1055			read_current_link_settings_on_detect(link);
1056
1057			/* Disable power sequence on MIPI panel + converter
1058			 */
1059			if (dc->config.enable_mipi_converter_optimization &&
1060				dc_ctx->dce_version == DCN_VERSION_3_01 &&
1061				link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_0022B9 &&
1062				memcmp(&link->dpcd_caps.branch_dev_name, DP_SINK_BRANCH_DEV_NAME_7580,
1063					sizeof(link->dpcd_caps.branch_dev_name)) == 0) {
1064				dc->config.edp_no_power_sequencing = true;
1065
1066				if (!link->dpcd_caps.set_power_state_capable_edp)
1067					link->wa_flags.dp_keep_receiver_powered = true;
1068			}
1069
1070			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
1071			sink_caps.signal = SIGNAL_TYPE_EDP;
1072			break;
1073		}
1074
1075		case SIGNAL_TYPE_DISPLAY_PORT: {
1076
1077			/* wa HPD high coming too early*/
1078			if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
1079			    link->link_enc->features.flags.bits.DP_IS_USB_C == 1) {
1080
1081				/* if alt mode times out, return false */
1082				if (!wait_for_entering_dp_alt_mode(link))
1083					return false;
1084			}
1085
1086			if (!detect_dp(link, &sink_caps, reason)) {
1087
1088				if (prev_sink)
1089					dc_sink_release(prev_sink);
1090				return false;
1091			}
1092
1093			/* Active SST downstream branch device unplug*/
1094			if (link->type == dc_connection_sst_branch &&
1095			    link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
1096				if (prev_sink)
1097					/* Downstream unplug */
1098					dc_sink_release(prev_sink);
1099				return true;
1100			}
1101
1102			/* disable audio for non DP to HDMI active sst converter */
1103			if (link->type == dc_connection_sst_branch &&
1104					is_dp_active_dongle(link) &&
1105					(link->dpcd_caps.dongle_type !=
1106							DISPLAY_DONGLE_DP_HDMI_CONVERTER))
1107				converter_disable_audio = true;
1108
1109			/* limited link rate to HBR3 for DPIA until we implement USB4 V2 */
1110			if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
1111					link->reported_link_cap.link_rate > LINK_RATE_HIGH3)
1112				link->reported_link_cap.link_rate = LINK_RATE_HIGH3;
1113
1114			if (link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling
1115					&& link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc
1116					&& link->dpcd_caps.usb4_dp_tun_info.driver_bw_cap.bits.driver_bw_alloc_support) {
1117				if (link_dpia_enable_usb4_dp_bw_alloc_mode(link) == false)
1118					link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc = false;
1119			}
1120			break;
1121		}
1122
1123		default:
1124			DC_ERROR("Invalid connector type! signal:%d\n",
1125				 link->connector_signal);
1126			if (prev_sink)
1127				dc_sink_release(prev_sink);
1128			return false;
1129		} /* switch() */
1130
1131		if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
1132			link->dpcd_sink_count =
1133				link->dpcd_caps.sink_count.bits.SINK_COUNT;
1134		else
1135			link->dpcd_sink_count = 1;
1136
1137		set_ddc_transaction_type(link->ddc,
1138						     sink_caps.transaction_type);
1139
1140		link->aux_mode =
1141			link_is_in_aux_transaction_mode(link->ddc);
1142
1143		sink_init_data.link = link;
1144		sink_init_data.sink_signal = sink_caps.signal;
1145
1146		sink = dc_sink_create(&sink_init_data);
1147		if (!sink) {
1148			DC_ERROR("Failed to create sink!\n");
1149			if (prev_sink)
1150				dc_sink_release(prev_sink);
1151			return false;
1152		}
1153
1154		sink->link->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
1155		sink->converter_disable_audio = converter_disable_audio;
1156
1157		/* dc_sink_create returns a new reference */
1158		link->local_sink = sink;
1159
1160		edid_status = dm_helpers_read_local_edid(link->ctx,
1161							 link, sink);
1162
1163		switch (edid_status) {
1164		case EDID_BAD_CHECKSUM:
1165			DC_LOG_ERROR("EDID checksum invalid.\n");
1166			break;
1167		case EDID_PARTIAL_VALID:
1168			DC_LOG_ERROR("Partial EDID valid, abandon invalid blocks.\n");
1169			break;
1170		case EDID_NO_RESPONSE:
1171			/* Analog connectors without EDID:
1172			 * - old monitor that actually doesn't have EDID
1173			 * - cheap DVI-A cable or adapter that doesn't connect DDC
1174			 */
1175			if (dc_connector_supports_analog(link->link_id.id)) {
1176				/* If we didn't already detect a display using
1177				 * DAC load detection, we know it isn't connected.
1178				 */
1179				if (link->type != dc_connection_analog_load) {
1180					if (prev_sink)
1181						dc_sink_release(prev_sink);
1182					link_disconnect_sink(link);
1183					return false;
1184				}
1185
1186				DC_LOG_INFO("%s detected analog display without EDID\n", __func__);
1187				link->type = dc_connection_analog_load;
1188				sink->edid_caps.analog = true;
1189				break;
1190			}
1191
1192			DC_LOG_ERROR("No EDID read.\n");
1193
1194			/*
1195			 * Abort detection for non-DP connectors if we have
1196			 * no EDID
1197			 *
1198			 * DP needs to report as connected if HDP is high
1199			 * even if we have no EDID in order to go to
1200			 * fail-safe mode
1201			 */
1202			if (dc_is_hdmi_signal(link->connector_signal) ||
1203			    dc_is_dvi_signal(link->connector_signal)) {
1204				if (prev_sink)
1205					dc_sink_release(prev_sink);
1206
1207				return false;
1208			}
1209
1210			if (link->type == dc_connection_sst_branch &&
1211					link->dpcd_caps.dongle_type ==
1212						DISPLAY_DONGLE_DP_VGA_CONVERTER &&
1213					reason == DETECT_REASON_HPDRX) {
1214				/* Abort detection for DP-VGA adapters when EDID
1215				 * can't be read and detection reason is VGA-side
1216				 * hotplug
1217				 */
1218				if (prev_sink)
1219					dc_sink_release(prev_sink);
1220				link_disconnect_sink(link);
1221
1222				return true;
1223			}
1224
1225			break;
1226		default:
1227			break;
1228		}
1229
1230		// Check if edid is the same
1231		if ((prev_sink) &&
1232		    (edid_status == EDID_THE_SAME || edid_status == EDID_OK))
1233			same_edid = is_same_edid(&prev_sink->dc_edid,
1234						 &sink->dc_edid);
1235
1236		if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
1237			link->ctx->dc->debug.hdmi20_disable = true;
1238
1239		if (sink->edid_caps.panel_patch.remove_sink_ext_caps)
1240			link->dpcd_sink_ext_caps.raw = 0;
1241
1242		if (dc_is_hdmi_signal(link->connector_signal))
1243			read_scdc_caps(link->ddc, link->local_sink);
1244
1245		if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
1246		    sink_caps.transaction_type ==
1247		    DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
1248			/*
1249			 * TODO debug why certain monitors don't like
1250			 *  two link trainings
1251			 */
1252			query_hdcp_capability(sink->sink_signal, link);
1253		} else {
1254			// If edid is the same, then discard new sink and revert back to original sink
1255			if (same_edid) {
1256				link_disconnect_remap(prev_sink, link);
1257				sink = prev_sink;
1258				prev_sink = NULL;
1259			}
1260
1261			if (!sink->edid_caps.analog)
1262				query_hdcp_capability(sink->sink_signal, link);
1263		}
1264
1265		/* DVI-I connector connected to analog display. */
1266		if ((link->link_id.id == CONNECTOR_ID_DUAL_LINK_DVII ||
1267		     link->link_id.id == CONNECTOR_ID_SINGLE_LINK_DVII) &&
1268			sink->edid_caps.analog)
1269			sink->sink_signal = SIGNAL_TYPE_RGB;
1270
1271		/* HDMI-DVI Dongle */
1272		if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
1273		    !sink->edid_caps.edid_hdmi)
1274			sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
1275		else if (dc_is_dvi_signal(sink->sink_signal) &&
1276			 dc_is_dvi_signal(link->connector_signal) &&
1277			 aud_support->hdmi_audio_native &&
1278			 sink->edid_caps.edid_hdmi)
1279			sink->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
1280
1281		if (link->local_sink && dc_is_dp_signal(sink_caps.signal))
1282			dp_trace_init(link);
1283
1284		/* Connectivity log: detection */
1285		for (i = 0; i < sink->dc_edid.length / DC_EDID_BLOCK_SIZE; i++) {
1286			CONN_DATA_DETECT(link,
1287					 &sink->dc_edid.raw_edid[i * DC_EDID_BLOCK_SIZE],
1288					 DC_EDID_BLOCK_SIZE,
1289					 "%s: [Block %d] ", sink->edid_caps.display_name, i);
1290		}
1291
1292		DC_LOG_DETECTION_EDID_PARSER("%s: "
1293			"manufacturer_id = %X, "
1294			"product_id = %X, "
1295			"serial_number = %X, "
1296			"manufacture_week = %d, "
1297			"manufacture_year = %d, "
1298			"display_name = %s, "
1299			"speaker_flag = %d, "
1300			"audio_mode_count = %d\n",
1301			__func__,
1302			sink->edid_caps.manufacturer_id,
1303			sink->edid_caps.product_id,
1304			sink->edid_caps.serial_number,
1305			sink->edid_caps.manufacture_week,
1306			sink->edid_caps.manufacture_year,
1307			sink->edid_caps.display_name,
1308			sink->edid_caps.speaker_flags,
1309			sink->edid_caps.audio_mode_count);
1310
1311		for (i = 0; i < sink->edid_caps.audio_mode_count; i++) {
1312			DC_LOG_DETECTION_EDID_PARSER("%s: mode number = %d, "
1313				"format_code = %d, "
1314				"channel_count = %d, "
1315				"sample_rate = %d, "
1316				"sample_size = %d\n",
1317				__func__,
1318				i,
1319				sink->edid_caps.audio_modes[i].format_code,
1320				sink->edid_caps.audio_modes[i].channel_count,
1321				sink->edid_caps.audio_modes[i].sample_rate,
1322				sink->edid_caps.audio_modes[i].sample_size);
1323		}
1324
1325		if (link->connector_signal == SIGNAL_TYPE_EDP) {
1326			// Init dc_panel_config by HW config
1327			if (dc_ctx->dc->res_pool->funcs->get_panel_config_defaults)
1328				dc_ctx->dc->res_pool->funcs->get_panel_config_defaults(&link->panel_config);
1329			// Pickup base DM settings
1330			dm_helpers_init_panel_settings(dc_ctx, &link->panel_config, sink);
1331			// Override dc_panel_config if system has specific settings
1332			dm_helpers_override_panel_settings(dc_ctx, &link->panel_config);
1333
1334			//sink only can use supported link rate table, we are foreced to enable it
1335			if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
1336				link->panel_config.ilr.optimize_edp_link_rate = true;
1337			link->reported_link_cap.link_rate = get_max_edp_link_rate(link);
1338		}
1339
1340	} else {
1341		/* From Connected-to-Disconnected. */
1342		link->type = dc_connection_none;
1343		sink_caps.signal = SIGNAL_TYPE_NONE;
1344		memset(&link->hdcp_caps, 0, sizeof(struct hdcp_caps));
1345		/* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk
1346		 *  is not cleared. If we emulate a DP signal on this connection, it thinks
1347		 *  the dongle is still there and limits the number of modes we can emulate.
1348		 *  Clear dongle_max_pix_clk on disconnect to fix this
1349		 */
1350		link->dongle_max_pix_clk = 0;
1351
1352		dc_link_clear_dprx_states(link);
1353		dp_trace_reset(link);
1354	}
1355
1356	LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p edid same=%d\n",
1357		  link->link_index, sink,
1358		  (sink_caps.signal ==
1359		   SIGNAL_TYPE_NONE ? "Disconnected" : "Connected"),
1360		  prev_sink, same_edid);
1361
1362	if (prev_sink)
1363		dc_sink_release(prev_sink);
1364
1365	return true;
1366}
1367
1368/**
1369 * link_detect_analog() - Determines if an analog sink is connected.
1370 *
1371 * @link: DC link to evaluate (must support analog signalling).
1372 * @type: Updated with the detected connection type:
1373 *        dc_connection_single (analog via DDC),
1374 *        dc_connection_analog_load (via load-detect),
1375 *        or dc_connection_none.
1376 *
1377 * Return: true if detection completed.
1378 */
1379static bool link_detect_analog(struct dc_link *link, enum dc_connection_type *type)
1380{
1381	/* Don't care about connectors that don't support an analog signal. */
1382	ASSERT(dc_connector_supports_analog(link->link_id.id));
1383
1384	if (link_detect_ddc_probe(link)) {
1385		*type = dc_connection_single;
1386		return true;
1387	}
1388
1389	if (link_detect_dac_load_detect(link)) {
1390		*type = dc_connection_analog_load;
1391		return true;
1392	}
1393
1394	*type = dc_connection_none;
1395	return true;
1396}
1397
1398/*
1399 * link_detect_connection_type() - Determine if there is a sink connected
1400 *
1401 * @type: Returned connection type
1402 * Does not detect downstream devices, such as MST sinks
1403 * or display connected through active dongles
1404 */
1405bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type)
1406{
1407	uint32_t is_hpd_high = 0;
1408
1409	if (link->connector_signal == SIGNAL_TYPE_LVDS) {
1410		*type = dc_connection_single;
1411		return true;
1412	}
1413
1414	/* Ignore the HPD pin (if any) for analog connectors.
1415	 * Instead rely on DDC and DAC.
1416	 *
1417	 * - VGA connectors don't have any HPD at all.
1418	 * - Some DVI-A cables don't connect the HPD pin.
1419	 * - Some DVI-A cables pull up the HPD pin.
1420	 *   (So it's high even when no display is connected.)
1421	 */
1422	if (dc_connector_supports_analog(link->link_id.id))
1423		return link_detect_analog(link, type);
1424
1425	if (link->connector_signal == SIGNAL_TYPE_EDP) {
1426		/*in case it is not on*/
1427		if (!link->dc->config.edp_no_power_sequencing)
1428			link->dc->hwss.edp_power_control(link, true);
1429		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
1430	}
1431
1432	/* Link may not have physical HPD pin. */
1433	if (link->ep_type != DISPLAY_ENDPOINT_PHY) {
1434		if (link->is_hpd_pending || !dpia_query_hpd_status(link))
1435			*type = dc_connection_none;
1436		else
1437			*type = dc_connection_single;
1438
1439		return true;
1440	}
1441
1442
1443	if (!query_hpd_status(link, &is_hpd_high))
1444		goto hpd_gpio_failure;
1445
1446	if (is_hpd_high) {
1447		*type = dc_connection_single;
1448		/* TODO: need to do the actual detection */
1449	} else {
1450		*type = dc_connection_none;
1451		if (link->connector_signal == SIGNAL_TYPE_EDP) {
1452			/* eDP is not connected, power down it */
1453			if (!link->dc->config.edp_no_power_sequencing)
1454				link->dc->hwss.edp_power_control(link, false);
1455		}
1456	}
1457
1458	return true;
1459
1460hpd_gpio_failure:
1461	return false;
1462}
1463
1464bool link_detect(struct dc_link *link, enum dc_detect_reason reason)
1465{
1466	bool is_local_sink_detect_success;
1467	bool is_delegated_to_mst_top_mgr = false;
1468	enum dc_connection_type pre_link_type = link->type;
1469
1470	DC_LOGGER_INIT(link->ctx->logger);
1471
1472	is_local_sink_detect_success = detect_link_and_local_sink(link, reason);
1473
1474	if (is_local_sink_detect_success && link->local_sink)
1475		verify_link_capability(link, link->local_sink, reason);
1476
1477	DC_LOG_DC("%s: link_index=%d is_local_sink_detect_success=%d pre_link_type=%d link_type=%d\n", __func__,
1478				link->link_index, is_local_sink_detect_success, pre_link_type, link->type);
1479
1480	if (is_local_sink_detect_success && link->local_sink &&
1481			dc_is_dp_signal(link->local_sink->sink_signal) &&
1482			link->dpcd_caps.is_mst_capable)
1483		is_delegated_to_mst_top_mgr = discover_dp_mst_topology(link, reason);
1484
1485	if (pre_link_type == dc_connection_mst_branch &&
1486			link->type != dc_connection_mst_branch)
1487		is_delegated_to_mst_top_mgr = link_reset_cur_dp_mst_topology(link);
1488
1489	return is_local_sink_detect_success && !is_delegated_to_mst_top_mgr;
1490}
1491
1492void link_clear_dprx_states(struct dc_link *link)
1493{
1494	memset(&link->dprx_states, 0, sizeof(link->dprx_states));
1495}
1496
1497bool link_is_hdcp14(struct dc_link *link, enum signal_type signal)
1498{
1499	bool ret = false;
1500
1501	switch (signal)	{
1502	case SIGNAL_TYPE_DISPLAY_PORT:
1503	case SIGNAL_TYPE_DISPLAY_PORT_MST:
1504		ret = link->hdcp_caps.bcaps.bits.HDCP_CAPABLE;
1505		break;
1506	case SIGNAL_TYPE_DVI_SINGLE_LINK:
1507	case SIGNAL_TYPE_DVI_DUAL_LINK:
1508	case SIGNAL_TYPE_HDMI_TYPE_A:
1509	/* HDMI doesn't tell us its HDCP(1.4) capability, so assume to always be capable,
1510	 * we can poll for bksv but some displays have an issue with this. Since its so rare
1511	 * for a display to not be 1.4 capable, this assumtion is ok
1512	 */
1513		ret = true;
1514		break;
1515	default:
1516		break;
1517	}
1518	return ret;
1519}
1520
1521bool link_is_hdcp22(struct dc_link *link, enum signal_type signal)
1522{
1523	bool ret = false;
1524
1525	switch (signal)	{
1526	case SIGNAL_TYPE_DISPLAY_PORT:
1527	case SIGNAL_TYPE_DISPLAY_PORT_MST:
1528		ret = (link->hdcp_caps.bcaps.bits.HDCP_CAPABLE &&
1529				link->hdcp_caps.rx_caps.fields.byte0.hdcp_capable &&
1530				(link->hdcp_caps.rx_caps.fields.version == 0x2)) ? 1 : 0;
1531		break;
1532	case SIGNAL_TYPE_DVI_SINGLE_LINK:
1533	case SIGNAL_TYPE_DVI_DUAL_LINK:
1534	case SIGNAL_TYPE_HDMI_TYPE_A:
1535		ret = (link->hdcp_caps.rx_caps.fields.version == 0x4) ? 1:0;
1536		break;
1537	default:
1538		break;
1539	}
1540
1541	return ret;
1542}
1543
1544const struct dc_link_status *link_get_status(const struct dc_link *link)
1545{
1546	return &link->link_status;
1547}
1548
1549
1550static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
1551{
1552	if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
1553		BREAK_TO_DEBUGGER();
1554		return false;
1555	}
1556
1557	dc_sink_retain(sink);
1558
1559	dc_link->remote_sinks[dc_link->sink_count] = sink;
1560	dc_link->sink_count++;
1561
1562	return true;
1563}
1564
1565struct dc_sink *link_add_remote_sink(
1566		struct dc_link *link,
1567		const uint8_t *edid,
1568		int len,
1569		struct dc_sink_init_data *init_data)
1570{
1571	struct dc_sink *dc_sink;
1572	enum dc_edid_status edid_status;
1573
1574	if (len > DC_MAX_EDID_BUFFER_SIZE) {
1575		dm_error("Max EDID buffer size breached!\n");
1576		return NULL;
1577	}
1578
1579	if (!init_data) {
1580		BREAK_TO_DEBUGGER();
1581		return NULL;
1582	}
1583
1584	if (!init_data->link) {
1585		BREAK_TO_DEBUGGER();
1586		return NULL;
1587	}
1588
1589	dc_sink = dc_sink_create(init_data);
1590
1591	if (!dc_sink)
1592		return NULL;
1593
1594	memmove(dc_sink->dc_edid.raw_edid, edid, len);
1595	dc_sink->dc_edid.length = len;
1596
1597	if (!link_add_remote_sink_helper(
1598			link,
1599			dc_sink))
1600		goto fail_add_sink;
1601
1602	edid_status = dm_helpers_parse_edid_caps(
1603			link,
1604			&dc_sink->dc_edid,
1605			&dc_sink->edid_caps);
1606
1607	/*
1608	 * Treat device as no EDID device if EDID
1609	 * parsing fails
1610	 */
1611	if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) {
1612		dc_sink->dc_edid.length = 0;
1613		dm_error("Bad EDID, status%d!\n", edid_status);
1614	}
1615
1616	return dc_sink;
1617
1618fail_add_sink:
1619	dc_sink_release(dc_sink);
1620	return NULL;
1621}
1622
1623void link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
1624{
1625	int i;
1626
1627	if (!link->sink_count) {
1628		BREAK_TO_DEBUGGER();
1629		return;
1630	}
1631
1632	for (i = 0; i < link->sink_count; i++) {
1633		if (link->remote_sinks[i] == sink) {
1634			dc_sink_release(sink);
1635			link->remote_sinks[i] = NULL;
1636
1637			/* shrink array to remove empty place */
1638			while (i < link->sink_count - 1) {
1639				link->remote_sinks[i] = link->remote_sinks[i+1];
1640				i++;
1641			}
1642			link->remote_sinks[i] = NULL;
1643			link->sink_count--;
1644			return;
1645		}
1646	}
1647}
~/ Read-only file preview.