diff options
author | Jett Rink <jettrink@chromium.org> | 2020-08-07 09:50:11 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-08-13 22:32:15 +0000 |
commit | 39a526023e435a776639d68271eed593598e9106 (patch) | |
tree | 743fa4d30fa2ad4dfbdbcc8b8f52f0ae8ffa84fe /common | |
parent | 0212d4a3ce01452ddaba46f076f90e9a5e90e589 (diff) | |
download | chrome-ec-39a526023e435a776639d68271eed593598e9106.tar.gz |
tcpmv2: wait before enabling HW auto toggle
We need to ensure that the previous Rd or Rp has been held long enough
before we transition into hardware auto toggle otherwise the first
toggle might be too short and violate the DRP timing spec
BRANCH=none
BUG=b:163095971
TEST=Verify on scope
Signed-off-by: Jett Rink <jettrink@chromium.org>
Change-Id: I92e9f5ca7dbca2b347e438d774551cc11476195b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2343176
Reviewed-by: Edward Hill <ecgh@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/mock/tcpc_mock.c | 10 | ||||
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 26 |
2 files changed, 31 insertions, 5 deletions
diff --git a/common/mock/tcpc_mock.c b/common/mock/tcpc_mock.c index 71be5ca281..64a1ce01cf 100644 --- a/common/mock/tcpc_mock.c +++ b/common/mock/tcpc_mock.c @@ -9,6 +9,7 @@ #include "memory.h" #include "mock/tcpc_mock.h" #include "tests/enum_strings.h" +#include "timer.h" #include "usb_pd_tcpm.h" #ifndef CONFIG_COMMON_RUNTIME @@ -142,6 +143,15 @@ void mock_tcpc_discharge_vbus(int port, int enable) __maybe_unused static int mock_drp_toggle(int port) { + /* Only set the time the first time this is called. */ + if (mock_tcpc.first_call_to_enable_auto_toggle == 0) + mock_tcpc.first_call_to_enable_auto_toggle = get_time().val; + + if (!mock_tcpc.should_print_call) + return EC_SUCCESS; + + ccprints("[TCPC] Enabling Auto Toggle"); + return EC_SUCCESS; } diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 4be631bedf..864976da4c 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -152,6 +152,9 @@ */ #define PD_DISABLED_BY_POLICY BIT(1) +/* Unreachable time in future */ +#define TIMER_DISABLED 0xffffffffffffffff + enum ps_reset_sequence { PS_STATE0, PS_STATE1, @@ -2890,15 +2893,28 @@ static void tc_drp_auto_toggle_entry(const int port) { print_current_state(port); - tcpm_enable_drp_toggle(port); + /* + * We need to ensure that we are waiting in the previous Rd or Rp state + * for the minimum of DRP SNK or SRC so the first toggle cause by + * transition into auto toggle doesn't violate spec timing. + */ + tc[port].timeout = get_time().val + MAX(PD_T_DRP_SNK, PD_T_DRP_SRC); } static void tc_drp_auto_toggle_run(const int port) { -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER - set_state_tc(port, TC_LOW_POWER_MODE); - return; -#endif + if (tc[port].timeout != TIMER_DISABLED) { + if (tc[port].timeout > get_time().val) + return; + + tc[port].timeout = TIMER_DISABLED; + tcpm_enable_drp_toggle(port); + + if (IS_ENABLED(CONFIG_USB_PD_TCPC_LOW_POWER)) { + set_state_tc(port, TC_LOW_POWER_MODE); + return; + } + } if (TC_CHK_FLAG(port, TC_FLAGS_CHECK_CONNECTION)) check_drp_connection(port); |