diff options
author | Wai-Hong Tam <waihong@google.com> | 2021-01-08 18:43:35 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-01-11 22:54:07 +0000 |
commit | 9fa7c906c2322413d5f8ee132ffcdf3654715b2f (patch) | |
tree | 6b5b325be07f034475bb54e4a89b3c0e453f0838 | |
parent | 986c00a9c68821c7b6b2ba1935760b87c8382858 (diff) | |
download | chrome-ec-9fa7c906c2322413d5f8ee132ffcdf3654715b2f.tar.gz |
TCPMv2: Defer initializing type-C supplier current limit
Initializing all of the suppliers seeds the charge manger and a
supplier is then selected (a corresponding charger input current
is configured).
Originally, both PD and type-C suppliers are unconditionally
initialized in the restart_tc_sm() that seeds the charge manger.
A lower current supplier (the default VBUS supplier) is selected
first before the type-C current detection.
A issue happens on the first boot from battery cutoff, the EC
RO detects 5V 3A and boots AP. When sysjump to RW, the default
VBUS supplier (5V 0.5A) is used first and limits the charger input
current to some lower value. It makes AP out of power.
This change defers the type-C supplier initialization to either
Unattached.SNK (new) or Attached.SNK.
In Unattached.SNK, we debounce the CC open status to make sure
CC open and then initialize the type-C supplier. As some TCPC
needs time to get the CC status valid. Before that, CC open is
reported by default. It misleads the decision.
We reuse the existing role toggle timer to debounce. And also
align the transitions to DRPAutoToggle and LowPowerState to
simplify the logic.
BRANCH=Trogdor
BUG=b:174105232, b:175663604
TEST=Verified the first boot from cutoff, AP still ON after sysjump
to RW.
TEST=Verified type-C detection, PD detection, and BC 1.2 detection
still work correctly.
Change-Id: Ia5d714a15d3f556463cf38e11130151e1f1477cb
Signed-off-by: Wai-Hong Tam <waihong@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2619338
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 1df7710301..d9b3b1cd20 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -1392,9 +1392,12 @@ static void restart_tc_sm(int port, enum usb_tc_state start_state) } if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) { - /* Initialize PD and type-C supplier current limits to 0 */ + /* + * Only initialize PD supplier current limit to 0. + * Defer initializing type-C supplier current limit + * to Unattached.SNK or Attached.SNK. + */ pd_set_input_current_limit(port, 0, 0); - typec_set_input_current_limit(port, 0, 0); charge_manager_update_dualrole(port, CAP_UNKNOWN); } @@ -2095,17 +2098,6 @@ static void tc_unattached_snk_run(const int port) tcpm_get_cc(port, &cc1, &cc2); /* - * Attempt TCPC auto DRP toggle if it is - * not already auto toggling. - */ - if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) && - drp_state[port] == PD_DRP_TOGGLE_ON && - tcpm_auto_toggle_supported(port) && cc_is_open(cc1, cc2)) { - set_state_tc(port, TC_DRP_AUTO_TOGGLE); - return; - } - - /* * The port shall transition to AttachWait.SNK when a Source * connection is detected, as indicated by the SNK.Rp state * on at least one of its CC pins. @@ -2117,9 +2109,34 @@ static void tc_unattached_snk_run(const int port) if (cc_is_rp(cc1) || cc_is_rp(cc2)) { /* Connection Detected */ set_state_tc(port, TC_ATTACH_WAIT_SNK); - } else if (get_time().val > tc[port].next_role_swap && - drp_state[port] == PD_DRP_TOGGLE_ON) { - /* DRP Toggle */ + return; + } + + /* + * Debounce the CC open status. Some TCPC needs time to get the CC + * status valid. Before that, CC open is reported by default. Wait + * to make sure the CC is really open. Reuse the role toggle timer. + */ + if (get_time().val < tc[port].next_role_swap) + return; + + /* + * Initialize type-C supplier current limits to 0. The charge + * manage is now seeded if it was not. + */ + if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) + typec_set_input_current_limit(port, 0, 0); + + /* + * Attempt TCPC auto DRP toggle if it is + * not already auto toggling. + */ + if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) && + drp_state[port] == PD_DRP_TOGGLE_ON && + tcpm_auto_toggle_supported(port)) { + set_state_tc(port, TC_DRP_AUTO_TOGGLE); + } else if (drp_state[port] == PD_DRP_TOGGLE_ON) { + /* DRP Toggle. The timer was checked above. */ set_state_tc(port, TC_UNATTACHED_SRC); } else if (IS_ENABLED(CONFIG_USB_PD_TCPC_LOW_POWER) && (drp_state[port] == PD_DRP_FORCE_SINK || |