summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@google.com>2020-08-19 16:31:22 -0600
committerCommit Bot <commit-bot@chromium.org>2020-08-21 00:55:22 +0000
commit95ef179b4776aabbef0ff438849aa99537889f52 (patch)
tree523c27fef6e7c360e2ff81b181e3c528b6b24fe2
parent78e85a45ea8ce24041bce74bcc2f80422531eca5 (diff)
downloadchrome-ec-95ef179b4776aabbef0ff438849aa99537889f52.tar.gz
TCPMv2: SRC->SNK PR Swap enable AutoDischarge after Vbus
A debounce was added to allow for the TCPC to get a valid Vbus but AutoDischargeDisconnect was enabled as soon as we set for the debounce. Since Vbus had a good chance of not being valid, we would get a FAULT from the TCPC indicating an Auto Discharge Disconnect failure. BUG=b:165797061 BRANCH=none TEST=DUT-DUT PR_Swap Signed-off-by: Denis Brockus <dbrockus@google.com> Change-Id: I897d682e405d7f2fcda4b4a36a3c1b333e8f7913 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2365253 Tested-by: Denis Brockus <dbrockus@chromium.org> Commit-Queue: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org>
-rw-r--r--common/usbc/usb_tc_drp_acc_trysrc_sm.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
index 47a3f0fc63..da3ff85fd7 100644
--- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c
+++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
@@ -559,9 +559,13 @@ void tc_request_power_swap(int port)
/*
* Must be in Attached.SRC or Attached.SNK
*/
- if (IS_ATTACHED_SRC(port) || IS_ATTACHED_SNK(port))
+ if (IS_ATTACHED_SRC(port) || IS_ATTACHED_SNK(port)) {
TC_SET_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS);
+ /* Let tc_pr_swap_complete start the Vbus debounce */
+ tc[port].vbus_debounce_time = TIMER_DISABLED;
+ }
+
/*
* TCPCI Rev2 V1.1 4.4.5.4.4
* Disconnect Detection by the Sink TCPC during a Connection
@@ -808,25 +812,28 @@ int tc_check_vconn_swap(int port)
void tc_pr_swap_complete(int port, bool success)
{
- TC_CLR_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS);
-
if (IS_ATTACHED_SNK(port)) {
/*
* Give the ADCs in the TCPC or PPC time to react following
* a PS_RDY message received during a SRC to SNK swap.
* Note: This is empirically determined, not strictly
* part of the USB PD spec.
+ * Note: Swap in progress should not be cleared until the
+ * debounce is completed.
*/
tc[port].vbus_debounce_time = get_time().val + PD_T_DEBOUNCE;
- }
+ } else {
+ /* PR Swap is no longer in progress */
+ TC_CLR_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS);
- /*
- * AutoDischargeDisconnect was either turned off near the SNK->SRC
- * PR-Swap message or when we hit Safe0V on SRC->SNK PR-Swap.
- * Either case, we need to re-enable if we finished the swap.
- */
- if (success)
- tcpm_enable_auto_discharge_disconnect(port, 1);
+ /*
+ * AutoDischargeDisconnect was turned off near the SNK->SRC
+ * PR-Swap message. If the swap was a success, Vbus should be
+ * valid, so re-enable AutoDischargeDisconnect
+ */
+ if (success)
+ tcpm_enable_auto_discharge_disconnect(port, 1);
+ }
}
void tc_prs_src_snk_assert_rd(int port)
@@ -2202,17 +2209,32 @@ static void tc_attached_snk_run(const int port)
}
/*
+ * Debounce Vbus before we drop that we are doing a PR_Swap
+ */
+ if (TC_CHK_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS) &&
+ tc[port].vbus_debounce_time < get_time().val) {
+ /* PR Swap is no longer in progress */
+ TC_CLR_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS);
+
+ /*
+ * AutoDischargeDisconnect was turned off when we
+ * hit Safe0V on SRC->SNK PR-Swap. We now are done
+ * with the swap and should have Vbus, so re-enable
+ * AutoDischargeDisconnect.
+ */
+ tcpm_enable_auto_discharge_disconnect(port, 1);
+ }
+
+ /*
* The sink will be powered off during a power role swap but we don't
* want to trigger a disconnect.
*/
if (!TC_CHK_FLAG(port, TC_FLAGS_POWER_OFF_SNK) &&
!TC_CHK_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS)) {
/*
- * Detach detection, but only after allowing for a debounce
- * of the VBUS state.
+ * Detach detection
*/
- if ((tc[port].vbus_debounce_time < get_time().val) &&
- !pd_is_vbus_present(port)) {
+ if (!pd_is_vbus_present(port)) {
if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) {
pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0);
pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0);