Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: dp mst detection code refactor

[why]
Move mst start top mgr in dc_link_detect layer.
Remove unused same_dpcd variable.
Move PEAK_FACTOR_X1000 and LINK_TRAINING_MAX_VERIFY_RETRY
to the proper header for defining dc link internal constant.

Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Reviewed-by: George Shen <George.Shen@amd.com>
Acked-by: Anson Jacob <Anson.Jacob@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Wenjing Liu and committed by
Alex Deucher
8a58e25b a161f8cb

+73 -99
+64 -98
drivers/gpu/drm/amd/display/dc/core/dc_link.c
··· 59 59 #define RETIMER_REDRIVER_INFO(...) \ 60 60 DC_LOG_RETIMER_REDRIVER( \ 61 61 __VA_ARGS__) 62 - /******************************************************************************* 63 - * Private structures 64 - ******************************************************************************/ 65 - 66 - enum { 67 - PEAK_FACTOR_X1000 = 1006, 68 - /* 69 - * Some receivers fail to train on first try and are good 70 - * on subsequent tries. 2 retries should be plenty. If we 71 - * don't have a successful training then we don't expect to 72 - * ever get one. 73 - */ 74 - LINK_TRAINING_MAX_VERIFY_RETRY = 2 75 - }; 76 62 77 63 /******************************************************************************* 78 64 * Private functions ··· 704 718 705 719 static bool detect_dp(struct dc_link *link, 706 720 struct display_sink_capability *sink_caps, 707 - bool *converter_disable_audio, 708 - struct audio_support *audio_support, 709 721 enum dc_detect_reason reason) 710 722 { 711 - bool boot = false; 723 + struct audio_support *audio_support = &link->dc->res_pool->audio_support; 712 724 713 725 sink_caps->signal = link_detect_sink(link, reason); 714 726 sink_caps->transaction_type = ··· 729 745 * of this function). */ 730 746 query_hdcp_capability(SIGNAL_TYPE_DISPLAY_PORT_MST, link); 731 747 #endif 732 - /* 733 - * This call will initiate MST topology discovery. Which 734 - * will detect MST ports and add new DRM connector DRM 735 - * framework. Then read EDID via remote i2c over aux. In 736 - * the end, will notify DRM detect result and save EDID 737 - * into DRM framework. 738 - * 739 - * .detect is called by .fill_modes. 740 - * .fill_modes is called by user mode ioctl 741 - * DRM_IOCTL_MODE_GETCONNECTOR. 742 - * 743 - * .get_modes is called by .fill_modes. 744 - * 745 - * call .get_modes, AMDGPU DM implementation will create 746 - * new dc_sink and add to dc_link. For long HPD plug 747 - * in/out, MST has its own handle. 748 - * 749 - * Therefore, just after dc_create, link->sink is not 750 - * created for MST until user mode app calls 751 - * DRM_IOCTL_MODE_GETCONNECTOR. 752 - * 753 - * Need check ->sink usages in case ->sink = NULL 754 - * TODO: s3 resume check 755 - */ 756 - if (reason == DETECT_REASON_BOOT) 757 - boot = true; 758 - 759 - dm_helpers_dp_update_branch_info(link->ctx, link); 760 - 761 - if (!dm_helpers_dp_mst_start_top_mgr(link->ctx, 762 - link, boot)) { 763 - /* MST not supported */ 764 - link->type = dc_connection_single; 765 - sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT; 766 - } 767 748 } 768 749 769 750 if (link->type != dc_connection_mst_branch && 770 - is_dp_branch_device(link)) { 751 + is_dp_branch_device(link)) 771 752 /* DP SST branch */ 772 753 link->type = dc_connection_sst_branch; 773 - if (!link->dpcd_caps.sink_count.bits.SINK_COUNT) { 774 - /* 775 - * SST branch unplug processing for short irq 776 - */ 777 - link_disconnect_sink(link); 778 - return true; 779 - } 780 - 781 - if (is_dp_active_dongle(link) && 782 - (link->dpcd_caps.dongle_type != 783 - DISPLAY_DONGLE_DP_HDMI_CONVERTER)) 784 - *converter_disable_audio = true; 785 - } 786 754 } else { 787 755 /* DP passive dongles */ 788 756 sink_caps->signal = dp_passive_dongle_detection(link->ddc, ··· 829 893 struct dc_sink *sink = NULL; 830 894 struct dc_sink *prev_sink = NULL; 831 895 struct dpcd_caps prev_dpcd_caps; 832 - bool same_dpcd = true; 833 896 enum dc_connection_type new_connection_type = dc_connection_none; 834 897 enum dc_connection_type pre_connection_type = dc_connection_none; 835 898 bool perform_dp_seamless_boot = false; ··· 919 984 return false; 920 985 } 921 986 922 - if (!detect_dp(link, &sink_caps, 923 - &converter_disable_audio, 924 - aud_support, reason)) { 987 + if (!detect_dp(link, &sink_caps, reason)) { 925 988 if (prev_sink) 926 989 dc_sink_release(prev_sink); 927 990 return false; 928 - } 929 - 930 - // Check if dpcp block is the same 931 - if (prev_sink) { 932 - if (memcmp(&link->dpcd_caps, &prev_dpcd_caps, 933 - sizeof(struct dpcd_caps))) 934 - same_dpcd = false; 935 - } 936 - /* Active SST downstream branch device unplug*/ 937 - if (link->type == dc_connection_sst_branch && 938 - link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) { 939 - if (prev_sink) 940 - /* Downstream unplug */ 941 - dc_sink_release(prev_sink); 942 - return true; 943 - } 944 - 945 - // link switch from MST to non-MST stop topology manager 946 - if (pre_connection_type == dc_connection_mst_branch && 947 - link->type != dc_connection_mst_branch) { 948 - dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); 949 991 } 950 992 951 993 if (link->type == dc_connection_mst_branch) { ··· 935 1023 */ 936 1024 dp_verify_mst_link_cap(link); 937 1025 938 - if (prev_sink) 939 - dc_sink_release(prev_sink); 940 - return false; 1026 + /* 1027 + * This call will initiate MST topology discovery. Which 1028 + * will detect MST ports and add new DRM connector DRM 1029 + * framework. Then read EDID via remote i2c over aux. In 1030 + * the end, will notify DRM detect result and save EDID 1031 + * into DRM framework. 1032 + * 1033 + * .detect is called by .fill_modes. 1034 + * .fill_modes is called by user mode ioctl 1035 + * DRM_IOCTL_MODE_GETCONNECTOR. 1036 + * 1037 + * .get_modes is called by .fill_modes. 1038 + * 1039 + * call .get_modes, AMDGPU DM implementation will create 1040 + * new dc_sink and add to dc_link. For long HPD plug 1041 + * in/out, MST has its own handle. 1042 + * 1043 + * Therefore, just after dc_create, link->sink is not 1044 + * created for MST until user mode app calls 1045 + * DRM_IOCTL_MODE_GETCONNECTOR. 1046 + * 1047 + * Need check ->sink usages in case ->sink = NULL 1048 + * TODO: s3 resume check 1049 + */ 1050 + 1051 + dm_helpers_dp_update_branch_info(link->ctx, link); 1052 + if (dm_helpers_dp_mst_start_top_mgr(link->ctx, 1053 + link, reason == DETECT_REASON_BOOT)) { 1054 + if (prev_sink) 1055 + dc_sink_release(prev_sink); 1056 + return false; 1057 + } else { 1058 + link->type = dc_connection_sst_branch; 1059 + sink_caps.signal = SIGNAL_TYPE_DISPLAY_PORT; 1060 + } 941 1061 } 1062 + 1063 + /* Active SST downstream branch device unplug*/ 1064 + if (link->type == dc_connection_sst_branch && 1065 + link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) { 1066 + if (prev_sink) 1067 + /* Downstream unplug */ 1068 + dc_sink_release(prev_sink); 1069 + return true; 1070 + } 1071 + 1072 + /* disable audio for non DP to HDMI active sst converter */ 1073 + if (link->type == dc_connection_sst_branch && 1074 + is_dp_active_dongle(link) && 1075 + (link->dpcd_caps.dongle_type != 1076 + DISPLAY_DONGLE_DP_HDMI_CONVERTER)) 1077 + converter_disable_audio = true; 1078 + 1079 + // link switch from MST to non-MST stop topology manager 1080 + if (pre_connection_type == dc_connection_mst_branch && 1081 + link->type != dc_connection_mst_branch) 1082 + dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); 1083 + 942 1084 943 1085 // For seamless boot, to skip verify link cap, we read UEFI settings and set them as verified. 944 1086 if (reason == DETECT_REASON_BOOT && 945 - !dc_ctx->dc->config.power_down_display_on_boot && 946 - link->link_status.link_active) 1087 + !dc_ctx->dc->config.power_down_display_on_boot && 1088 + link->link_status.link_active) 947 1089 perform_dp_seamless_boot = true; 948 1090 949 1091 if (perform_dp_seamless_boot) { ··· 1180 1214 link->dongle_max_pix_clk = 0; 1181 1215 } 1182 1216 1183 - LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p dpcd same=%d edid same=%d\n", 1217 + LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p edid same=%d\n", 1184 1218 link->link_index, sink, 1185 1219 (sink_caps.signal == 1186 1220 SIGNAL_TYPE_NONE ? "Disconnected" : "Connected"), 1187 - prev_sink, same_dpcd, same_edid); 1221 + prev_sink, same_edid); 1188 1222 1189 1223 if (prev_sink) 1190 1224 dc_sink_release(prev_sink);