diff options
author | Diana Z <dzigterman@chromium.org> | 2021-02-24 17:02:52 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-03-16 21:36:15 +0000 |
commit | 91ad865eaf32295240b62b5fbbd402c2023c187c (patch) | |
tree | 8356a43777aa5384ff60e9e894206e17c041b6be | |
parent | 657c9f952da217d18e55fb139e5e59f3cd58c670 (diff) | |
download | chrome-ec-91ad865eaf32295240b62b5fbbd402c2023c187c.tar.gz |
TCPMv2: Debounce Vbus loss when FRS is enabled
A hub may send a Fast Role Swap signal when Vbus is less than vSafe5V,
so allow a 5ms debounce after Vbus loss for the signal to come in before
we declare the connection detached.
BRANCH=None
BUG=b:180453483
TEST=on voxel, confirm FRS behaves normally
Signed-off-by: Diana Z <dzigterman@chromium.org>
Change-Id: If56106660c0a2bf82e28b91129bc9dd367ebc8fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2718838
Tested-by: Eric Herrmann <eherrmann@chromium.org>
Reviewed-by: Eric Herrmann <eherrmann@chromium.org>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 49 | ||||
-rw-r--r-- | include/usb_pd.h | 7 |
2 files changed, 50 insertions, 6 deletions
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 58fc085a61..50211feacf 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -2427,6 +2427,46 @@ static void tc_attached_snk_entry(const int port) tcpm_debug_accessory(port, 1); } +/* + * Check whether Vbus has been removed on this port, accounting for some Vbus + * debounce if FRS is enabled. + * + * Returns true if a new state was set and the calling run should exit. + */ +static bool tc_snk_check_vbus_removed(const int port) +{ + if (IS_ENABLED(CONFIG_USB_PD_FRS)) { + /* + * Debounce Vbus presence when FRS is enabled. Note that we may + * lose Vbus before the FRS signal comes in to let us know + * we're PR swapping, but we must still transition to unattached + * within tSinkDisconnect. + * + * We may safely re-use the Vbus debounce timer here + * since a PR swap would no longer be in progress when Vbus + * removal is checked. + */ + if (pd_check_vbus_level(port, VBUS_REMOVED)) { + if (pd_timer_is_disabled(port, + TC_TIMER_VBUS_DEBOUNCE)) { + pd_timer_enable(port, TC_TIMER_VBUS_DEBOUNCE, + PD_T_FRS_VBUS_DEBOUNCE); + } else if (pd_timer_is_expired(port, + TC_TIMER_VBUS_DEBOUNCE)) { + set_state_tc(port, TC_UNATTACHED_SNK); + return true; + } + } else { + pd_timer_disable(port, TC_TIMER_VBUS_DEBOUNCE); + } + } else if (pd_check_vbus_level(port, VBUS_REMOVED)) { + set_state_tc(port, TC_UNATTACHED_SNK); + return true; + } + + return false; +} + static void tc_attached_snk_run(const int port) { #ifdef CONFIG_USB_PE_SM @@ -2465,6 +2505,7 @@ static void tc_attached_snk_run(const int port) pd_timer_is_expired(port, TC_TIMER_VBUS_DEBOUNCE)) { /* PR Swap is no longer in progress */ TC_CLR_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS); + pd_timer_disable(port, TC_TIMER_VBUS_DEBOUNCE); /* * AutoDischargeDisconnect was turned off when we @@ -2485,10 +2526,8 @@ static void tc_attached_snk_run(const int port) /* * Detach detection */ - if (pd_check_vbus_level(port, VBUS_REMOVED)) { - set_state_tc(port, TC_UNATTACHED_SNK); + if (tc_snk_check_vbus_removed(port)) return; - } if (!pe_is_explicit_contract(port)) sink_power_sub_states(port); @@ -2577,10 +2616,8 @@ static void tc_attached_snk_run(const int port) #else /* CONFIG_USB_PE_SM */ /* Detach detection */ - if (pd_check_vbus_level(port, VBUS_REMOVED)) { - set_state_tc(port, TC_UNATTACHED_SNK); + if (tc_snk_check_vbus_removed(port)) return; - } /* Run Sink Power Sub-State */ sink_power_sub_states(port); diff --git a/include/usb_pd.h b/include/usb_pd.h index 81dbc3220a..ed15149441 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -246,6 +246,13 @@ enum pd_rx_errors { #define PD_T_SYSJUMP (1000*MSEC) /* 1s */ #define PD_T_PR_SWAP_WAIT (100*MSEC) /* tPRSwapWait 100ms */ +/* + * Non-spec timer to prevent going Unattached if Vbus drops before a partner FRS + * signal comes through. This timer should be shorter than tSinkDisconnect + * (40ms) to ensure we still transition out of Attached.SNK in time. + */ +#define PD_T_FRS_VBUS_DEBOUNCE (5*MSEC) + /* number of edges and time window to detect CC line is not idle */ #define PD_RX_TRANSITION_COUNT 3 #define PD_RX_TRANSITION_WINDOW 20 /* between 12us and 20us */ |