Lines Matching refs:link
27 * This file manages link detection states and receiver states by using various
28 * link protocols. It also provides helper functions to interpret certain
55 link->ctx->logger
170 static enum signal_type link_detect_sink_signal_type(struct dc_link *link,
176 if (link->is_dig_mapping_flexible)
179 enc_id = link->link_enc->id;
180 result = get_basic_signal_type(enc_id, link->link_id);
182 /* Use basic signal type for link without physical connector. */
183 if (link->ep_type != DISPLAY_ENDPOINT_PHY)
199 if (link->link_id.id == CONNECTOR_ID_PCIE) {
203 switch (link->link_id.id) {
209 &link->dc->res_pool->audio_support;
212 if (link->link_id.id == CONNECTOR_ID_HDMI_TYPE_A)
226 if (!dm_helpers_is_dp_sink_present(link))
311 ddc->link,
331 struct dc_link *link = ddc->link;
356 CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
403 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
411 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
418 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
435 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
442 CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
463 static void link_disconnect_sink(struct dc_link *link)
465 if (link->local_sink) {
466 dc_sink_release(link->local_sink);
467 link->local_sink = NULL;
470 link->dpcd_sink_count = 0;
471 //link->dpcd_caps.dpcd_rev.raw = 0;
474 static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *link)
476 dc_sink_release(link->local_sink);
477 link->local_sink = prev_sink;
480 static void query_hdcp_capability(enum signal_type signal, struct dc_link *link)
487 memset(link->hdcp_caps.rx_caps.raw, 0,
488 sizeof(link->hdcp_caps.rx_caps.raw));
490 if ((link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
491 link->ddc->transaction_type ==
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);
498 msg22.data = &link->hdcp_caps.rx_caps.fields.version;
499 msg22.length = sizeof(link->hdcp_caps.rx_caps.fields.version);
503 msg22.link = HDCP_LINK_PRIMARY;
505 dc_process_hdcp_msg(signal, link, &msg22);
508 msg14.data = &link->hdcp_caps.bcaps.raw;
509 msg14.length = sizeof(link->hdcp_caps.bcaps.raw);
512 msg14.link = HDCP_LINK_PRIMARY;
515 dc_process_hdcp_msg(signal, link, &msg14);
519 static void read_current_link_settings_on_detect(struct dc_link *link)
531 status = core_link_read_dpcd(link,
541 link->cur_link_settings.lane_count =
549 // Read DPCD 00100h to find if standard link rates are set
550 core_link_read_dpcd(link, DP_LINK_BW_SET,
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
558 core_link_read_dpcd(link, DP_LINK_RATE_SET,
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;
573 link->cur_link_settings.link_rate = link_bw_set;
574 link->cur_link_settings.use_link_rate_set = false;
577 core_link_read_dpcd(link, DP_MAX_DOWNSPREAD,
579 link->cur_link_settings.link_spread =
584 static bool detect_dp(struct dc_link *link,
588 struct audio_support *audio_support = &link->dc->res_pool->audio_support;
590 sink_caps->signal = link_detect_sink_signal_type(link, reason);
596 if (!detect_dp_sink_caps(link)) {
600 if (is_dp_branch_device(link))
602 link->type = dc_connection_sst_branch;
604 if (link->dc->debug.disable_dp_plus_plus_wa &&
605 link->link_enc->features.flags.bits.IS_UHBR20_CAPABLE)
609 sink_caps->signal = dp_passive_dongle_detection(link->ddc,
612 link->dpcd_caps.dongle_type = sink_caps->dongle_type;
613 link->dpcd_caps.is_dongle_type_one = sink_caps->is_dongle_type_one;
614 link->dpcd_caps.dpcd_rev.raw = 0;
615 link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.raw = 0;
633 static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
648 DC_LOGGER_INIT(link->ctx->logger);
655 if (!link->link_enc->funcs->is_in_alt_mode)
658 is_in_alt_mode = link->link_enc->funcs->is_in_alt_mode(link->link_enc);
664 enter_timestamp = dm_get_timestamp(link->ctx);
668 /* ask the link if alt mode is enabled, if so return ok */
669 if (link->link_enc->funcs->is_in_alt_mode(link->link_enc)) {
670 finish_timestamp = dm_get_timestamp(link->ctx);
672 dm_get_elapse_time_in_ns(link->ctx,
680 finish_timestamp = dm_get_timestamp(link->ctx);
681 time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp,
688 static void apply_dpia_mst_dsc_always_on_wa(struct dc_link *link)
693 if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
694 link->type == dc_connection_mst_branch &&
695 link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
696 link->dpcd_caps.branch_hw_revision == DP_BRANCH_HW_REV_20 &&
697 link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
698 !link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around)
699 link->wa_flags.dpia_mst_dsc_always_on = true;
701 if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
702 link->type == dc_connection_mst_branch &&
703 link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
704 link->dpcd_caps.branch_vendor_specific_data[2] == MST_HUB_ID_0x5A &&
705 link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
706 !link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around) {
707 link->wa_flags.dpia_mst_dsc_always_on = true;
711 static void revert_dpia_mst_dsc_always_on_wa(struct dc_link *link)
714 if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
715 link->wa_flags.dpia_mst_dsc_always_on = false;
718 static bool discover_dp_mst_topology(struct dc_link *link, enum dc_detect_reason reason)
720 DC_LOGGER_INIT(link->ctx->logger);
722 LINK_INFO("link=%d, mst branch is now Connected\n",
723 link->link_index);
725 link->type = dc_connection_mst_branch;
726 apply_dpia_mst_dsc_always_on_wa(link);
728 dm_helpers_dp_update_branch_info(link->ctx, link);
729 if (dm_helpers_dp_mst_start_top_mgr(link->ctx,
730 link, (reason == DETECT_REASON_BOOT || reason == DETECT_REASON_RESUMEFROMS3S4))) {
731 link_disconnect_sink(link);
733 link->type = dc_connection_sst_branch;
736 return link->type == dc_connection_mst_branch;
739 bool link_reset_cur_dp_mst_topology(struct dc_link *link)
741 DC_LOGGER_INIT(link->ctx->logger);
743 LINK_INFO("link=%d, mst branch is now Disconnected\n",
744 link->link_index);
746 revert_dpia_mst_dsc_always_on_wa(link);
747 return dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
777 static void verify_link_capability_destructive(struct dc_link *link,
782 should_prepare_phy_clocks_for_link_verification(link->dc, reason);
785 prepare_phy_clocks_for_destructive_link_verification(link->dc);
787 if (dc_is_dp_signal(link->local_sink->sink_signal)) {
789 dp_get_max_link_cap(link);
790 link_set_all_streams_dpms_off_for_link(link);
792 link, &known_limit_link_setting,
799 restore_phy_clocks_for_destructive_link_verification(link->dc);
802 static void verify_link_capability_non_destructive(struct dc_link *link)
804 if (dc_is_dp_signal(link->local_sink->sink_signal)) {
805 if (dc_is_embedded_signal(link->local_sink->sink_signal) ||
806 link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
807 /* TODO - should we check link encoder's max link caps here?
808 * How do we know which link encoder to check from?
810 link->verified_link_cap = link->reported_link_cap;
812 link->verified_link_cap = dp_get_max_link_cap(link);
816 static bool should_verify_link_capability_destructively(struct dc_link *link,
823 if (!link->dc->config.unify_link_enc_assignment)
824 is_link_enc_unavailable = link->link_enc &&
825 link->dc->res_pool->funcs->link_encs_assign &&
827 link->ctx->dc,
828 link->link_enc->preferred_engine,
829 link);
831 if (dc_is_dp_signal(link->local_sink->sink_signal)) {
832 max_link_cap = dp_get_max_link_cap(link);
835 if (link->dc->debug.skip_detection_link_training ||
836 dc_is_embedded_signal(link->local_sink->sink_signal) ||
837 (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
838 !link->dc->config.enable_dpia_pre_training)) {
842 if (link->dpcd_caps.is_mst_capable ||
852 static void verify_link_capability(struct dc_link *link, struct dc_sink *sink,
855 if (should_verify_link_capability_destructively(link, reason))
856 verify_link_capability_destructive(link, sink, reason);
858 verify_link_capability_non_destructive(link);
862 * detect_link_and_local_sink() - Detect if a sink is attached to a given link
864 * link->local_sink is created or destroyed as needed.
868 static bool detect_link_and_local_sink(struct dc_link *link,
875 struct audio_support *aud_support = &link->dc->res_pool->audio_support;
878 struct dc_context *dc_ctx = link->ctx;
886 DC_LOGGER_INIT(link->ctx->logger);
888 if (dc_is_virtual_signal(link->connector_signal))
891 if (((link->connector_signal == SIGNAL_TYPE_LVDS ||
892 link->connector_signal == SIGNAL_TYPE_EDP) &&
893 (!link->dc->config.allow_edp_hotplug_detection)) &&
894 link->local_sink) {
896 if (link->connector_signal == SIGNAL_TYPE_EDP &&
897 (link->dpcd_sink_ext_caps.bits.oled == 1)) {
898 dpcd_set_source_specific_data(link);
900 set_default_brightness_aux(link);
906 if (!link_detect_connection_type(link, &new_connection_type)) {
911 prev_sink = link->local_sink;
914 memcpy(&prev_dpcd_caps, &link->dpcd_caps, sizeof(struct dpcd_caps));
917 link_disconnect_sink(link);
919 link->type = new_connection_type;
920 link->link_state_valid = false;
923 switch (link->connector_signal) {
952 detect_edp_sink_caps(link);
953 read_current_link_settings_on_detect(link);
959 link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_0022B9 &&
960 memcmp(&link->dpcd_caps.branch_dev_name, DP_SINK_BRANCH_DEV_NAME_7580,
961 sizeof(link->dpcd_caps.branch_dev_name)) == 0) {
964 if (!link->dpcd_caps.set_power_state_capable_edp)
965 link->wa_flags.dp_keep_receiver_powered = true;
976 if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
977 link->link_enc->features.flags.bits.DP_IS_USB_C == 1) {
980 if (!wait_for_entering_dp_alt_mode(link))
984 if (!detect_dp(link, &sink_caps, reason)) {
992 if (link->type == dc_connection_sst_branch &&
993 link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
1001 if (link->type == dc_connection_sst_branch &&
1002 is_dp_active_dongle(link) &&
1003 (link->dpcd_caps.dongle_type !=
1007 /* limited link rate to HBR3 for DPIA until we implement USB4 V2 */
1008 if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
1009 link->reported_link_cap.link_rate > LINK_RATE_HIGH3)
1010 link->reported_link_cap.link_rate = LINK_RATE_HIGH3;
1012 if (link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling
1013 && link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc
1014 && link->dpcd_caps.usb4_dp_tun_info.driver_bw_cap.bits.driver_bw_alloc_support) {
1015 if (link_dpia_enable_usb4_dp_bw_alloc_mode(link) == false)
1016 link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc = false;
1023 link->connector_signal);
1029 if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
1030 link->dpcd_sink_count =
1031 link->dpcd_caps.sink_count.bits.SINK_COUNT;
1033 link->dpcd_sink_count = 1;
1035 set_ddc_transaction_type(link->ddc,
1038 link->aux_mode =
1039 link_is_in_aux_transaction_mode(link->ddc);
1041 sink_init_data.link = link;
1052 sink->link->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
1056 link->local_sink = sink;
1058 edid_status = dm_helpers_read_local_edid(link->ctx,
1059 link, sink);
1078 if (dc_is_hdmi_signal(link->connector_signal) ||
1079 dc_is_dvi_signal(link->connector_signal)) {
1086 if (link->type == dc_connection_sst_branch &&
1087 link->dpcd_caps.dongle_type ==
1096 link_disconnect_sink(link);
1113 link->ctx->dc->debug.hdmi20_disable = true;
1116 link->dpcd_sink_ext_caps.raw = 0;
1118 if (dc_is_hdmi_signal(link->connector_signal))
1119 read_scdc_caps(link->ddc, link->local_sink);
1121 if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
1126 * two link trainings
1128 query_hdcp_capability(sink->sink_signal, link);
1132 link_disconnect_remap(prev_sink, link);
1136 query_hdcp_capability(sink->sink_signal, link);
1144 if (link->local_sink && dc_is_dp_signal(sink_caps.signal))
1145 dp_trace_init(link);
1149 CONN_DATA_DETECT(link,
1188 if (link->connector_signal == SIGNAL_TYPE_EDP) {
1191 dc_ctx->dc->res_pool->funcs->get_panel_config_defaults(&link->panel_config);
1193 dm_helpers_init_panel_settings(dc_ctx, &link->panel_config, sink);
1195 dm_helpers_override_panel_settings(dc_ctx, &link->panel_config);
1197 //sink only can use supported link rate table, we are foreced to enable it
1198 if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
1199 link->panel_config.ilr.optimize_edp_link_rate = true;
1200 link->reported_link_cap.link_rate = get_max_edp_link_rate(link);
1205 link->type = dc_connection_none;
1207 memset(&link->hdcp_caps, 0, sizeof(struct hdcp_caps));
1213 link->dongle_max_pix_clk = 0;
1215 dc_link_clear_dprx_states(link);
1216 dp_trace_reset(link);
1219 LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p edid same=%d\n",
1220 link->link_index, sink,
1238 bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type)
1242 if (link->connector_signal == SIGNAL_TYPE_LVDS) {
1247 if (link->connector_signal == SIGNAL_TYPE_EDP) {
1249 if (!link->dc->config.edp_no_power_sequencing)
1250 link->dc->hwss.edp_power_control(link, true);
1251 link->dc->hwss.edp_wait_for_hpd_ready(link, true);
1255 if (link->ep_type != DISPLAY_ENDPOINT_PHY) {
1256 if (link->is_hpd_pending || !dpia_query_hpd_status(link))
1265 if (!query_hpd_status(link, &is_hpd_high))
1273 if (link->connector_signal == SIGNAL_TYPE_EDP) {
1275 if (!link->dc->config.edp_no_power_sequencing)
1276 link->dc->hwss.edp_power_control(link, false);
1286 bool link_detect(struct dc_link *link, enum dc_detect_reason reason)
1290 enum dc_connection_type pre_link_type = link->type;
1292 DC_LOGGER_INIT(link->ctx->logger);
1294 is_local_sink_detect_success = detect_link_and_local_sink(link, reason);
1296 if (is_local_sink_detect_success && link->local_sink)
1297 verify_link_capability(link, link->local_sink, reason);
1300 link->link_index, is_local_sink_detect_success, pre_link_type, link->type);
1302 if (is_local_sink_detect_success && link->local_sink &&
1303 dc_is_dp_signal(link->local_sink->sink_signal) &&
1304 link->dpcd_caps.is_mst_capable)
1305 is_delegated_to_mst_top_mgr = discover_dp_mst_topology(link, reason);
1308 link->type != dc_connection_mst_branch)
1309 is_delegated_to_mst_top_mgr = link_reset_cur_dp_mst_topology(link);
1314 void link_clear_dprx_states(struct dc_link *link)
1316 memset(&link->dprx_states, 0, sizeof(link->dprx_states));
1319 bool link_is_hdcp14(struct dc_link *link, enum signal_type signal)
1326 ret = link->hdcp_caps.bcaps.bits.HDCP_CAPABLE;
1343 bool link_is_hdcp22(struct dc_link *link, enum signal_type signal)
1350 ret = (link->hdcp_caps.bcaps.bits.HDCP_CAPABLE &&
1351 link->hdcp_caps.rx_caps.fields.byte0.hdcp_capable &&
1352 (link->hdcp_caps.rx_caps.fields.version == 0x2)) ? 1 : 0;
1357 ret = (link->hdcp_caps.rx_caps.fields.version == 0x4) ? 1:0;
1366 const struct dc_link_status *link_get_status(const struct dc_link *link)
1368 return &link->link_status;
1388 struct dc_link *link,
1406 if (!init_data->link) {
1420 link,
1425 link,
1445 void link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
1449 if (!link->sink_count) {
1454 for (i = 0; i < link->sink_count; i++) {
1455 if (link->remote_sinks[i] == sink) {
1457 link->remote_sinks[i] = NULL;
1460 while (i < link->sink_count - 1) {
1461 link->remote_sinks[i] = link->remote_sinks[i+1];
1464 link->remote_sinks[i] = NULL;
1465 link->sink_count--;