summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSankeerth Billakanti <sbillaka@codeaurora.org>2020-02-10 16:26:02 +0530
committerSankeerth Billakanti <sbillaka@codeaurora.org>2020-02-18 15:08:53 +0530
commit3d076a474cc99e7ac6d687078bc3306729595103 (patch)
treee0f324b4afa5b58aa9b3cac279edd3d17ad15124
parent174e74c85c2e168a4b9d30ac0bcd41a0e74eb9a1 (diff)
downloaddisplay-drivers-3d076a474cc99e7ac6d687078bc3306729595103.tar.gz
disp: msm: dp: execute host_init on restoring session teardown
Ensure host_init is executed when the DP display driver is resuming form a video session teardown. The host_deinit is executed when DP video session teardown is initiated by the userspace while DP cable is connected. If the DP display is disconnected from dongle while the video session is in teardown, the host_init is not executed when the session is restored. All subsequent display connections will fail because the core clocks are not on and aux abort is not reset. This change will ensure host_init is executed whenever the host_deinit is executed during DP video session teardown by userspace. Change-Id: If1ae3eb731a96bd929cd023733c098b513436a1c Signed-off-by: Sankeerth Billakanti <sbillaka@codeaurora.org>
-rw-r--r--msm/dp/dp_display.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c
index 33ba7b0b..ad30e03b 100644
--- a/msm/dp/dp_display.c
+++ b/msm/dp/dp_display.c
@@ -62,6 +62,7 @@ enum dp_display_states {
DP_STATE_SUSPENDED = BIT(7),
DP_STATE_ABORTED = BIT(8),
DP_STATE_HDCP_ABORTED = BIT(9),
+ DP_STATE_SRC_PWRDN = BIT(10),
};
static char *dp_display_state_name(enum dp_display_states state)
@@ -111,6 +112,10 @@ static char *dp_display_state_name(enum dp_display_states state)
len += scnprintf(buf + len, sizeof(buf) - len, "|%s|",
"HDCP_ABORTED");
+ if (state & DP_STATE_SRC_PWRDN)
+ len += scnprintf(buf + len, sizeof(buf) - len, "|%s|",
+ "SRC_PWRDN");
+
if (!strlen(buf))
return "DISCONNECTED";
@@ -952,6 +957,26 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
dp->dp_display.max_pclk_khz = min(dp->parser->max_pclk_khz,
dp->debug->max_pclk_khz);
+
+ /*
+ * If dp video session is not restored from a previous session teardown
+ * by userspace, ensure the host_init is executed, in such a scenario,
+ * so that all the required DP resources are enabled.
+ *
+ * Below is one of the sequences of events which describe the above
+ * scenario:
+ * a. Source initiated power down resulting in host_deinit.
+ * b. Sink issues hpd low attention without physical cable disconnect.
+ * c. Source initiated power up sequence returns early because hpd is
+ * not high.
+ * d. Sink issues a hpd high attention event.
+ */
+ if (dp_display_state_is(DP_STATE_SRC_PWRDN) &&
+ dp_display_state_is(DP_STATE_CONFIGURED)) {
+ dp_display_host_init(dp);
+ dp_display_state_remove(DP_STATE_SRC_PWRDN);
+ }
+
dp_display_host_ready(dp);
dp->link->psm_config(dp->link, &dp->panel->link_info, false);
@@ -1227,7 +1252,6 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, dp->state,
dp->debug->psm_enabled);
- dp_display_state_remove(DP_STATE_CONFIGURED);
if (dp->debug->psm_enabled && dp_display_state_is(DP_STATE_READY))
dp->link->psm_config(dp->link, &dp->panel->link_info, true);
@@ -1236,6 +1260,7 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
mutex_lock(&dp->session_lock);
dp_display_host_deinit(dp);
+ dp_display_state_remove(DP_STATE_CONFIGURED);
mutex_unlock(&dp->session_lock);
if (!dp->debug->sim_mode && !dp->parser->no_aux_switch
@@ -1784,6 +1809,20 @@ static int dp_display_prepare(struct dp_display *dp_display, void *panel)
mutex_lock(&dp->session_lock);
/*
+ * If DP video session is restored by the userspace after display
+ * disconnect notification from dongle i.e. typeC cable connected to
+ * source but disconnected at the display side, the DP controller is
+ * not restored to the desired configured state. So, ensure host_init
+ * is executed in such a scenario so that all the DP controller
+ * resources are enabled for the next connection event.
+ */
+ if (dp_display_state_is(DP_STATE_SRC_PWRDN) &&
+ dp_display_state_is(DP_STATE_CONFIGURED)) {
+ dp_display_host_init(dp);
+ dp_display_state_remove(DP_STATE_SRC_PWRDN);
+ }
+
+ /*
* If the physical connection to the sink is already lost by the time
* we try to set up the connection, we can just skip all the steps
* here safely.
@@ -1808,7 +1847,6 @@ static int dp_display_prepare(struct dp_display *dp_display, void *panel)
}
/* For supporting DP_PANEL_SRC_INITIATED_POWER_DOWN case */
- dp_display_host_init(dp);
dp_display_host_ready(dp);
if (dp->debug->psm_enabled) {
@@ -2223,6 +2261,7 @@ static int dp_display_unprepare(struct dp_display *dp_display, void *panel)
dp->ctrl->off(dp->ctrl);
dp_display_host_unready(dp);
dp_display_host_deinit(dp);
+ dp_display_state_add(DP_STATE_SRC_PWRDN);
}
dp_display_state_remove(DP_STATE_ENABLED);