diff options
author | Denis Brockus <dbrockus@google.com> | 2020-03-23 11:47:54 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-03-30 23:29:11 +0000 |
commit | 967a74dc60d6f1eb76c62e4c8736dd1b1372f522 (patch) | |
tree | 0c1fd3119f7f91640dbb0b70a3bda2adcc6d3f88 | |
parent | 0e423969f1ebfb627aad04810802e414c92a4c6e (diff) | |
download | chrome-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.c | 37 |
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); } |