Răsfoiți Sursa

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 <[email protected]>
Sankeerth Billakanti 5 ani în urmă
părinte
comite
1cc485a4cd
1 a modificat fișierele cu 24 adăugiri și 5 ștergeri
  1. 24 5
      msm/dp/dp_display.c

+ 24 - 5
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);