提交 cdb39798 编写于 作者: Y Yongqiang Sun 提交者: Alex Deucher

drm/amd/display: Add return value for detect dp.

System soft hang when hotplug specific 4K DP panel
due to link caps read error and incorrect link setting
parmas to enable dp.
Add status check for DPCD read and add return value
for detect dp, in case of false, return from caller,
avoid further false operation.
Signed-off-by: NYongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: NTony Cheng <Tony.Cheng@amd.com>
Acked-by: NHarry Wentland <harry.wentland@amd.com>
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
上级 dc75dd70
...@@ -465,7 +465,7 @@ static void link_disconnect_sink(struct dc_link *link) ...@@ -465,7 +465,7 @@ static void link_disconnect_sink(struct dc_link *link)
link->dpcd_sink_count = 0; link->dpcd_sink_count = 0;
} }
static void detect_dp( static bool detect_dp(
struct dc_link *link, struct dc_link *link,
struct display_sink_capability *sink_caps, struct display_sink_capability *sink_caps,
bool *converter_disable_audio, bool *converter_disable_audio,
...@@ -479,7 +479,8 @@ static void detect_dp( ...@@ -479,7 +479,8 @@ static void detect_dp(
if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) { if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT; sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
detect_dp_sink_caps(link); if (!detect_dp_sink_caps(link))
return false;
if (is_mst_supported(link)) { if (is_mst_supported(link)) {
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST; sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
...@@ -530,7 +531,7 @@ static void detect_dp( ...@@ -530,7 +531,7 @@ static void detect_dp(
* active dongle unplug processing for short irq * active dongle unplug processing for short irq
*/ */
link_disconnect_sink(link); link_disconnect_sink(link);
return; return true;
} }
if (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER) if (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER)
...@@ -542,6 +543,8 @@ static void detect_dp( ...@@ -542,6 +543,8 @@ static void detect_dp(
sink_caps, sink_caps,
audio_support); audio_support);
} }
return true;
} }
bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
...@@ -605,11 +608,12 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) ...@@ -605,11 +608,12 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
} }
case SIGNAL_TYPE_DISPLAY_PORT: { case SIGNAL_TYPE_DISPLAY_PORT: {
detect_dp( if (!detect_dp(
link, link,
&sink_caps, &sink_caps,
&converter_disable_audio, &converter_disable_audio,
aud_support, reason); aud_support, reason))
return false;
/* Active dongle downstream unplug */ /* Active dongle downstream unplug */
if (link->type == dc_connection_active_dongle if (link->type == dc_connection_active_dongle
......
...@@ -2235,13 +2235,14 @@ static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data, ...@@ -2235,13 +2235,14 @@ static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
link->wa_flags.dp_keep_receiver_powered = false; link->wa_flags.dp_keep_receiver_powered = false;
} }
static void retrieve_link_cap(struct dc_link *link) static bool retrieve_link_cap(struct dc_link *link)
{ {
uint8_t dpcd_data[DP_TRAINING_AUX_RD_INTERVAL - DP_DPCD_REV + 1]; uint8_t dpcd_data[DP_TRAINING_AUX_RD_INTERVAL - DP_DPCD_REV + 1];
union down_stream_port_count down_strm_port_count; union down_stream_port_count down_strm_port_count;
union edp_configuration_cap edp_config_cap; union edp_configuration_cap edp_config_cap;
union dp_downstream_port_present ds_port = { 0 }; union dp_downstream_port_present ds_port = { 0 };
enum dc_status status = DC_ERROR_UNEXPECTED;
memset(dpcd_data, '\0', sizeof(dpcd_data)); memset(dpcd_data, '\0', sizeof(dpcd_data));
memset(&down_strm_port_count, memset(&down_strm_port_count,
...@@ -2249,11 +2250,16 @@ static void retrieve_link_cap(struct dc_link *link) ...@@ -2249,11 +2250,16 @@ static void retrieve_link_cap(struct dc_link *link)
memset(&edp_config_cap, '\0', memset(&edp_config_cap, '\0',
sizeof(union edp_configuration_cap)); sizeof(union edp_configuration_cap));
core_link_read_dpcd( status = core_link_read_dpcd(
link, link,
DP_DPCD_REV, DP_DPCD_REV,
dpcd_data, dpcd_data,
sizeof(dpcd_data)); sizeof(dpcd_data));
if (status != DC_OK) {
dm_error("%s: Read dpcd data failed.\n", __func__);
return false;
}
{ {
union training_aux_rd_interval aux_rd_interval; union training_aux_rd_interval aux_rd_interval;
...@@ -2315,11 +2321,13 @@ static void retrieve_link_cap(struct dc_link *link) ...@@ -2315,11 +2321,13 @@ static void retrieve_link_cap(struct dc_link *link)
/* Connectivity log: detection */ /* Connectivity log: detection */
CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: "); CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
return true;
} }
void detect_dp_sink_caps(struct dc_link *link) bool detect_dp_sink_caps(struct dc_link *link)
{ {
retrieve_link_cap(link); return retrieve_link_cap(link);
/* dc init_hw has power encoder using default /* dc init_hw has power encoder using default
* signal for connector. For native DP, no * signal for connector. For native DP, no
......
...@@ -53,7 +53,7 @@ bool perform_link_training_with_retries( ...@@ -53,7 +53,7 @@ bool perform_link_training_with_retries(
bool is_mst_supported(struct dc_link *link); bool is_mst_supported(struct dc_link *link);
void detect_dp_sink_caps(struct dc_link *link); bool detect_dp_sink_caps(struct dc_link *link);
void detect_edp_sink_caps(struct dc_link *link); void detect_edp_sink_caps(struct dc_link *link);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册