diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2018-06-13 16:26:30 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-08-23 13:20:48 -0700 |
commit | fa2d1dd956c0235b46be93361890485b1e3acc32 (patch) | |
tree | fb94d1629e4c19d23275f97f2b56995ca0972077 /common | |
parent | 18307f177db0c517e4734d61e3fd1655ea72b512 (diff) | |
download | chrome-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.c | 23 |
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); |