summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@google.com>2020-03-23 11:47:54 -0600
committerCommit Bot <commit-bot@chromium.org>2020-03-30 23:29:11 +0000
commit967a74dc60d6f1eb76c62e4c8736dd1b1372f522 (patch)
tree0c1fd3119f7f91640dbb0b70a3bda2adcc6d3f88
parent0e423969f1ebfb627aad04810802e414c92a4c6e (diff)
downloadchrome-ec-967a74dc60d6f1eb76c62e4c8736dd1b1372f522.tar.gz
tcpci: zork: battery-less AP boot needs to set DRP on unattached ports
The timing on the AP boot takes the PD stack into TOGGLE_OFF and then immediately to TOGGLE_ON. The TOGGLE_ON is getting lost due to being in execution past where we set the DRP and before we go back to LOW_POWER, so it gets lost. Then when we get back to LOW_POWER it requires a SOURCE attach to wake up and allow the port to detect a SINK. This CL tracks TOGGLE_x to see if we should have set DRP and didn't and reroute back if needed so we don't lose the port. BUG=b:152028728 BRANCH=none TEST=verify trembyle will see unattached port after boot to AP Signed-off-by: Denis Brockus <dbrockus@google.com> Change-Id: Ifaf0e01e4816fdf2c569d21aba7968d8538768c3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2118430 Tested-by: Denis Brockus <dbrockus@chromium.org> Auto-Submit: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Edward Hill <ecgh@chromium.org> Commit-Queue: Denis Brockus <dbrockus@chromium.org>
-rw-r--r--common/usbc/usb_tc_drp_acc_trysrc_sm.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
index 9800dd3486..82504919c1 100644
--- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c
+++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
@@ -82,6 +82,8 @@
#define TC_FLAGS_WAKE_FROM_LPM BIT(22)
/* Flag to note the TCPM supports auto toggle */
#define TC_FLAGS_AUTO_TOGGLE_SUPPORTED BIT(23)
+/* Flag to note TCPM was requested to DRP auto toggle */
+#define TC_FLAGS_AUTO_TOGGLE_REQUESTED BIT(24)
/*
* Clear all flags except TC_FLAGS_AUTO_TOGGLE_SUPPORTED,
@@ -2795,13 +2797,20 @@ static void tc_drp_auto_toggle_entry(const int port)
atomic_clear(task_get_event_bitmap(task_get_current()),
PD_EXIT_LOW_POWER_EVENT_MASK);
- if (drp_state[port] == PD_DRP_TOGGLE_ON)
+ /*
+ * Enable DRP Toggle based on the current drp_state.
+ * Keep a flag showing if DRP Toggle is enabled.
+ */
+ if (drp_state[port] == PD_DRP_TOGGLE_ON) {
tcpm_enable_drp_toggle(port);
+ TC_SET_FLAG(port, TC_FLAGS_AUTO_TOGGLE_REQUESTED);
+ }
}
static void tc_drp_auto_toggle_run(const int port)
{
enum pd_drp_next_states next_state;
+ enum pd_dual_role_states entry_drp_state;
enum tcpc_cc_voltage_status cc1, cc2;
/*
@@ -2821,9 +2830,22 @@ static void tc_drp_auto_toggle_run(const int port)
/* Check for connection */
tcpm_get_cc(port, &cc1, &cc2);
+ /*
+ * Make sure the drp_state didn't change since we went
+ * through tc_drp_auto_toggle_entry from not toggling to
+ * toggling. This will make getting the next state
+ * different if we have an open connection
+ */
+ if (!TC_CHK_FLAG(port, TC_FLAGS_AUTO_TOGGLE_REQUESTED) &&
+ drp_state[port] == PD_DRP_TOGGLE_ON)
+ entry_drp_state = PD_DRP_TOGGLE_OFF;
+ else
+ entry_drp_state = drp_state[port];
+
+ /* Determine the next state to attempt */
tc[port].drp_sink_time = get_time().val;
next_state = drp_auto_toggle_next_state(&tc[port].drp_sink_time,
- tc[port].power_role, drp_state[port], cc1, cc2);
+ tc[port].power_role, entry_drp_state, cc1, cc2);
/*
* The next state is not determined just by what is
@@ -2884,7 +2906,14 @@ static void tc_low_power_mode_entry(const int port)
static void tc_low_power_mode_run(const int port)
{
#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
- if (TC_CHK_FLAG(port, TC_FLAGS_WAKE_FROM_LPM)) {
+ /*
+ * If we were tagged to wake up immediately instead of
+ * going into LOW_POWER or we should have DRP enabled and
+ * it didn't happen, then go back to TC_DRP_AUTO_TOGGLE.
+ */
+ if ((TC_CHK_FLAG(port, TC_FLAGS_WAKE_FROM_LPM)) ||
+ (!TC_CHK_FLAG(port, TC_FLAGS_AUTO_TOGGLE_REQUESTED) &&
+ drp_state[port] == PD_DRP_TOGGLE_ON)) {
set_state_tc(port, TC_DRP_AUTO_TOGGLE);
return;
}
@@ -2896,7 +2925,7 @@ static void tc_low_power_mode_exit(const int port)
{
CPRINTS("TCPC p%d Exit Low Power Mode", port);
TC_CLR_FLAG(port, TC_FLAGS_LPM_REQUESTED | TC_FLAGS_LPM_ENGAGED |
- TC_FLAGS_WAKE_FROM_LPM);
+ TC_FLAGS_WAKE_FROM_LPM | TC_FLAGS_AUTO_TOGGLE_REQUESTED);
reset_device_and_notify(port);
tc_start_event_loop(port);
}