diff options
author | Diana Z <dzigterman@chromium.org> | 2021-01-31 13:35:29 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-02-02 19:51:24 +0000 |
commit | 88438ce32109f651eb9e8424048edefd893a01c7 (patch) | |
tree | b69428c0975e48560b3d7725f6c6d458a8594870 | |
parent | babc0ea2dc00f53cac08e18a407b8f9921305d7c (diff) | |
download | chrome-ec-88438ce32109f651eb9e8424048edefd893a01c7.tar.gz |
TCPMv2: Exit modes consistently on detach
Currently, the TC can miss exiting modes during a power transition to S5
with a sinking DP dongle. Correct this and simplify the number of call
locations needed by putting any mode exit on detach in the existing
detach handler.
BRANCH=None
BUG=b:176213187
TEST=on drawcia, verify HPD is de-asserted when:
- unplugging sinking DP dongle in S0
- unplugging sourcing DP dongle in S0
- powering off to S5 with sinking DP dongle
Signed-off-by: Diana Z <dzigterman@chromium.org>
Change-Id: I2f7f3b09c4fd875e26d6c5e71de1b3250526dbe3
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2662212
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 44 |
1 files changed, 16 insertions, 28 deletions
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 5b442b37a1..7d14231d97 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -687,12 +687,28 @@ __maybe_unused static void tc_enable_try_src(int en) atomic_clear_bits(&pd_try_src, 1); } +/* + * Exit all modes due to a detach event + * Note: this skips the ExitMode VDM steps in the PE because it is assumed the + * partner is not present to receive them, and the PE will no longer be running. + */ +static void tc_set_modes_exit(int port) +{ + if (IS_ENABLED(CONFIG_USB_PE_SM) && + IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { + pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, 0, 0); + } +} + static void tc_detached(int port) { TC_CLR_FLAG(port, TC_FLAGS_TS_DTS_PARTNER); hook_notify(HOOK_USB_PD_DISCONNECT); tc_pd_connection(port, 0); tcpm_debug_accessory(port, 0); + tc_set_modes_exit(port); } static inline void pd_set_dual_role_and_event(int port, @@ -2226,13 +2242,6 @@ static void tc_attach_wait_snk_run(const int port) */ if (new_cc_state == PD_CC_NONE && get_time().val > tc[port].pd_debounce) { - if (IS_ENABLED(CONFIG_USB_PE_SM) && - IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { - pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); - pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); - pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, 0, 0); - } - /* We are detached */ if (drp_state[port] == PD_DRP_TOGGLE_OFF || drp_state[port] == PD_DRP_FREEZE @@ -2425,13 +2434,6 @@ static void tc_attached_snk_run(const int port) * Detach detection */ if (pd_check_vbus_level(port, VBUS_REMOVED)) { - if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { - pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); - pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); - pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, - 0, 0); - } - set_state_tc(port, TC_UNATTACHED_SNK); return; } @@ -2915,13 +2917,6 @@ static void tc_attached_src_run(const int port) tryWait = is_try_src_enabled(port) && !TC_CHK_FLAG(port, TC_FLAGS_TS_DTS_PARTNER); - if (IS_ENABLED(CONFIG_USB_PE_SM) && - IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { - pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); - pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); - pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, 0, 0); - } - if (IS_ENABLED(CONFIG_USB_PD_TRY_SRC)) set_state_tc(port, tryWait ? TC_TRY_WAIT_SNK : TC_UNATTACHED_SNK); @@ -3431,13 +3426,6 @@ __maybe_unused static void tc_ct_unattached_snk_run(int port) if (get_time().val > tc[port].cc_debounce) { if (new_cc_state == PD_CC_NONE && pd_check_vbus_level(port, VBUS_SAFE0V)) { - if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { - pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); - pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); - pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, - 0, 0); - } - set_state_tc(port, TC_UNATTACHED_SNK); return; } |