summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJett Rink <jettrink@chromium.org>2020-08-07 09:50:11 -0600
committerCommit Bot <commit-bot@chromium.org>2020-08-13 22:32:15 +0000
commit39a526023e435a776639d68271eed593598e9106 (patch)
tree743fa4d30fa2ad4dfbdbcc8b8f52f0ae8ffa84fe /common
parent0212d4a3ce01452ddaba46f076f90e9a5e90e589 (diff)
downloadchrome-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.c10
-rw-r--r--common/usbc/usb_tc_drp_acc_trysrc_sm.c26
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);