summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKeith Short <keithshort@chromium.org>2020-08-27 14:51:41 -0600
committerCommit Bot <commit-bot@chromium.org>2020-09-02 03:20:23 +0000
commitc069177ccc29b4373d5587e1dcea966aeee0a856 (patch)
tree84f6a1b6e046b0c2aab859a992a7366c5fb29c8c /common
parent6b7a3e349d4d55c3a5a40bfa6094e415a5a4d8c3 (diff)
downloadchrome-ec-c069177ccc29b4373d5587e1dcea966aeee0a856.tar.gz
tcpmv2: disable receive of SOP' during VCONN swap
The USB PD specification indicates that the initial VCONN source shall cease source VCONN within tVCONNSourceOff (25 ms) after receiving PS_RDY. Not all partners wait after sending PS_RDY before trying to communicate with the cable. BUG=b:163478172, b:163143427 BRANCH=none TEST=make buildall TEST=Connect 2 Volteers together and force VCONN swaps confirming the sequence completes normally. Signed-off-by: Keith Short <keithshort@chromium.org> Change-Id: I14720f033c5f6e9caed9c4fe3bfa11e5c046116e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2381030 Reviewed-by: Denis Brockus <dbrockus@chromium.org> Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/usbc/usb_pe_drp_sm.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index c90d98a75c..7e76c15e1c 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -5269,6 +5269,23 @@ static void pe_vcs_evaluate_swap_entry(int port)
/* NOTE: PE_VCS_Accept_Swap State embedded here */
PE_SET_FLAG(port, PE_FLAGS_ACCEPT);
send_ctrl_msg(port, TCPC_TX_SOP, PD_CTRL_ACCEPT);
+
+ /*
+ * The USB PD 3.0 spec indicates that the initial VCONN source
+ * shall cease sourcing VCONN within tVCONNSourceOff (25ms)
+ * after receiving the PS_RDY message. However, some partners
+ * begin sending SOP' messages only 1 ms after sending PS_RDY
+ * during VCONN swap.
+ *
+ * Preemptively disable receipt of SOP' and SOP'' messages while
+ * we wait for PS_RDY so we don't attempt to process messages
+ * directed at the cable. If the partner fails to send PS_RDY we
+ * perform a hard reset so no need to re-enable SOP' messages.
+ *
+ * We continue to source VCONN while we wait as required by the
+ * spec.
+ */
+ tcpm_sop_prime_disable(port);
}
}
@@ -5333,12 +5350,18 @@ static void pe_vcs_send_swap_run(int port)
*/
if (type == PD_CTRL_ACCEPT) {
pe[port].vconn_swap_counter = 0;
- if (tc_is_vconn_src(port))
+ if (tc_is_vconn_src(port)) {
+ /*
+ * Prevent receiving any SOP' and SOP''
+ * messages while a swap is in progress.
+ */
+ tcpm_sop_prime_disable(port);
set_state_pe(port,
PE_VCS_WAIT_FOR_VCONN_SWAP);
- else
+ } else {
set_state_pe(port,
PE_VCS_TURN_ON_VCONN_SWAP);
+ }
return;
}
/*