summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2018-06-13 16:26:30 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-08-23 13:20:48 -0700
commitfa2d1dd956c0235b46be93361890485b1e3acc32 (patch)
treefb94d1629e4c19d23275f97f2b56995ca0972077 /common
parent18307f177db0c517e4734d61e3fd1655ea72b512 (diff)
downloadchrome-ec-fa2d1dd956c0235b46be93361890485b1e3acc32.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/1100165 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Tested-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/usb_pd_protocol.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 1de3a4a696..79f66aa57b 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -2054,6 +2054,22 @@ void pd_set_dual_role(int port, enum pd_dual_role_states state)
PD_EVENT_UPDATE_DUAL_ROLE, 0);
}
+static void exit_dp_mode(int port)
+{
+#ifdef CONFIG_USB_PD_ALT_MODE_DFP
+ 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 */
+#endif
+}
+
void pd_update_dual_role_config(int port)
{
/*
@@ -2508,6 +2524,8 @@ void pd_task(void *u)
#endif
#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
@@ -3873,8 +3891,11 @@ static void pd_chipset_shutdown(void)
{
int i;
- for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; 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(i, PD_DRP_FORCE_SINK);
+ }
CPRINTS("PD:S3->S5");
}
DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pd_chipset_shutdown, HOOK_PRIO_DEFAULT);