From 1cc485a4cd8435f8d9f0b48977ac217c3e5899de Mon Sep 17 00:00:00 2001 From: Sankeerth Billakanti Date: Wed, 4 Sep 2019 14:26:05 +0530 Subject: [PATCH] disp: msm: dp: fix for dp link layer cts failures The DP link layer CTS tests issue continuous DP plug/unplug. When that happens, sometimes the DP sw state machine is going into a bad state causing DP blankout. This is happening when the post_enable call fails and the hpd handling logic in the DP driver skips sending the disconnect and next subsequent connect notifications. This change will fix the conditions to correctly notify the userspace about the DP connection status. Change-Id: I41310c8c465901eb5e5bd8fdec2038fe3c01e50a Signed-off-by: Sankeerth Billakanti --- msm/dp/dp_display.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index dfc1fbabe2c7..0693c0208f35 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -45,10 +45,12 @@ enum dp_display_states { DP_STATE_INITIALIZED = BIT(1), DP_STATE_READY = BIT(2), DP_STATE_CONNECTED = BIT(3), - DP_STATE_ENABLED = BIT(4), - DP_STATE_SUSPENDED = BIT(5), - DP_STATE_ABORTED = BIT(6), - DP_STATE_HDCP_ABORTED = BIT(7), + DP_STATE_CONNECT_NOTIFIED = BIT(4), + DP_STATE_DISCONNECT_NOTIFIED = BIT(5), + DP_STATE_ENABLED = BIT(6), + DP_STATE_SUSPENDED = BIT(7), + DP_STATE_ABORTED = BIT(8), + DP_STATE_HDCP_ABORTED = BIT(9), }; static char *dp_display_state_name(enum dp_display_states state) @@ -74,6 +76,14 @@ static char *dp_display_state_name(enum dp_display_states state) len += scnprintf(buf + len, sizeof(buf) - len, "|%s|", "CONNECTED"); + if (state & DP_STATE_CONNECT_NOTIFIED) + len += scnprintf(buf + len, sizeof(buf) - len, "|%s|", + "CONNECT_NOTIFIED"); + + if (state & DP_STATE_DISCONNECT_NOTIFIED) + len += scnprintf(buf + len, sizeof(buf) - len, "|%s|", + "DISCONNECT_NOTIFIED"); + if (state & DP_STATE_ENABLED) len += scnprintf(buf + len, sizeof(buf) - len, "|%s|", "ENABLED"); @@ -653,6 +663,14 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp) envp[4] = NULL; kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); + + if (connector->status == connector_status_connected) { + dp_display_state_add(DP_STATE_CONNECT_NOTIFIED); + dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED); + } else { + dp_display_state_add(DP_STATE_DISCONNECT_NOTIFIED); + dp_display_state_remove(DP_STATE_CONNECT_NOTIFIED); + } } static int dp_display_send_hpd_notification(struct dp_display_private *dp) @@ -911,7 +929,8 @@ static int dp_display_process_hpd_low(struct dp_display_private *dp) dp_display_process_mst_hpd_low(dp); - if (dp_display_state_is(DP_STATE_ENABLED) && !dp->mst.mst_active) + if (dp_display_state_is(DP_STATE_CONNECT_NOTIFIED) && + !dp->mst.mst_active) rc = dp_display_send_hpd_notification(dp); mutex_lock(&dp->session_lock);