summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2018-06-13 16:26:30 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-08-28 00:40:24 +0000
commit0b0694dbc8d44c6c02cbfba1e7623f9ae9e0ad57 (patch)
tree72137e6d1e4d3e0878cf5fbaa36f8c0603fa4e7b
parentf9dc2e4852c67893a1893bb8eb49d113f171580c (diff)
downloadchrome-ec-0b0694dbc8d44c6c02cbfba1e7623f9ae9e0ad57.tar.gz
usb-pd: Exit DP mode before shutdown
On start-up, the tcpm tries to discover identity and enter amodes. When system reboots, this makes already entered modes re-entered. This causes some devices to malfunction. This patch makes the tcpm exit DP mode if it's already entered. Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> BUG=chromium:799535,b:79185392 BRANCH=none TEST=Verify picture is displayed on external monitor after suspend/resume, shutdown/power-on via D6000, Hoho, Aplle HDMI adapter, StarTech DP adapter, Dingdong with Vayne. Change-Id: I1fd577e12eaa5a81a0ae0242d38863dc211ac8bc Reviewed-on: https://chromium-review.googlesource.com/1185495 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org> (cherry picked from commit a1fa5af5da8f5209ce64428481d6916ca226a340) Reviewed-on: https://chromium-review.googlesource.com/1189783 Reviewed-by: Casper Chang <casper_chang@wistron.corp-partner.google.com> Tested-by: Casper Chang <casper_chang@wistron.corp-partner.google.com> Commit-Queue: Casper Chang <casper_chang@wistron.corp-partner.google.com>
-rw-r--r--common/usb_pd_protocol.c20
-rw-r--r--include/usb_pd.h1
2 files changed, 21 insertions, 0 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index ccf08b823f..5d8b902233 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -1758,6 +1758,20 @@ void pd_set_dual_role(enum pd_dual_role_states state)
PD_EVENT_UPDATE_DUAL_ROLE, 0);
}
+static void exit_dp_mode(int port)
+{
+ int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT);
+ if (opos <= 0)
+ return;
+ CPRINTS("C%d Exiting DP mode", port);
+ if (!pd_dfp_exit_mode(port, USB_SID_DISPLAYPORT, opos))
+ return;
+ pd_send_vdm(port, USB_SID_DISPLAYPORT,
+ CMD_EXIT_MODE | VDO_OPOS(opos), NULL, 0);
+ pd_vdm_send_state_machine(port);
+ /* Have to wait for ACK */
+}
+
void pd_update_dual_role_config(int port)
{
/*
@@ -2137,6 +2151,8 @@ void pd_task(void *u)
evt = task_wait_event(timeout);
#ifdef CONFIG_USB_PD_DUAL_ROLE
+ if (evt & PD_EVENT_DP_DISCONNECT)
+ exit_dp_mode(port);
if (evt & PD_EVENT_UPDATE_DUAL_ROLE)
pd_update_dual_role_config(port);
#endif
@@ -3443,6 +3459,10 @@ DECLARE_HOOK(HOOK_CHIPSET_STARTUP, pd_chipset_startup, HOOK_PRIO_DEFAULT);
static void pd_chipset_shutdown(void)
{
+ int i;
+ for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
+ task_set_event(PD_PORT_TO_TASK_ID(i),
+ PD_EVENT_DP_DISCONNECT, 0);
pd_set_dual_role(PD_DRP_FORCE_SINK);
CPRINTS("PD:S3->S5");
}
diff --git a/include/usb_pd.h b/include/usb_pd.h
index d068e2e4ce..035234e977 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -43,6 +43,7 @@ enum pd_rx_errors {
#define PD_EVENT_CC (1<<4) /* CC line change event */
#define PD_EVENT_TCPC_RESET (1<<5) /* TCPC has reset */
#define PD_EVENT_UPDATE_DUAL_ROLE (1<<6) /* DRP state has changed */
+#define PD_EVENT_DP_DISCONNECT (1<<7) /* DisplayPort disconnect requested */
/* --- PD data message helpers --- */
#define PDO_MAX_OBJECTS 7