summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2021-01-08 18:43:35 -0800
committerCommit Bot <commit-bot@chromium.org>2021-01-11 22:54:07 +0000
commit9fa7c906c2322413d5f8ee132ffcdf3654715b2f (patch)
tree6b5b325be07f034475bb54e4a89b3c0e453f0838
parent986c00a9c68821c7b6b2ba1935760b87c8382858 (diff)
downloadchrome-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.c49
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 ||