summaryrefslogtreecommitdiff
path: root/common/usbc/tbt_alt_mode.c
diff options
context:
space:
mode:
authorAyushee <ayushee.shah@intel.com>2020-09-24 15:40:07 -0700
committerCommit Bot <commit-bot@chromium.org>2020-11-05 04:11:47 +0000
commit1a265d194969d8778fdd759e1eed891f0638202b (patch)
tree9644b49b6c118bc0120c051530b16995d4bc5a78 /common/usbc/tbt_alt_mode.c
parente609f07eef8b851b19bf4b59b5263ac702d8b871 (diff)
downloadchrome-ec-1a265d194969d8778fdd759e1eed891f0638202b.tar.gz
TCPMv2: Add support for USB4 active cable
USB4 PD flow for active cables: Structured VDM version (cable revision)-- <2.0 -------->| | | >=2.0 | | | VDO version---- <1.3 -------> Modal op? -- N --| (B21:23 of | | Discover ID SOP'- y | Active cable VDO1) | | | TBT SVID? -- N --| >=1.3 | | | y | Cable USB4 support? - N | | | | Gen4 cable? - N - Skip USB4 mode entry y Skip USB4 | | mode entry | Enter USB4 y (SOP',SOP'',SOP) | | |<---- NAK ----- Enter mode TBT SOP'<---| | | | | ACK | | | | |<---- NAK ----- Enter mode TBT SOP'' | | | | Exit TBT mode SOP ACK | | | | ACK/NAK Enter USB4 mode | | SOP | Exit TBT mode SOP'' | | | ACK/NAK | | | Exit TBT mode SOP' | | | ACK/NAK | | | |--------Retry done? ---- N ------------| | y | Skip USB4 mode entry The CL also checks if the port is VCONN source before sending Enter USB SOP' and SOP'' messages and requests for a vconn swap is it isn't In case of reboot, the port sends exit Thunderbolt mode SOP' and SOP'' and skips sending exit Thunderbolt mode for SOP, since it didn't enter Thunderbolt mode SOP prior to reboot. Note: 1. This is only applicable when the port enters USB4 mode SOP and Thunderbolt mode with the cable plug. 2. It is a temporary behaviour until data reset feature is in place (b/141363146) BUG=b:156749387 BRANCH=None TEST=1.Able to enter into USB4 with active cable. 2.Able to exit Thunderbolt mode SOP' and SOP'' on reboot and re-enter into USB4 mode with active cable. Signed-off-by: Ayushee <ayushee.shah@intel.com> Change-Id: I828c7ca0fd9b7b1025f13bcc86c511692b9f9895 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2432868 Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
Diffstat (limited to 'common/usbc/tbt_alt_mode.c')
-rw-r--r--common/usbc/tbt_alt_mode.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/common/usbc/tbt_alt_mode.c b/common/usbc/tbt_alt_mode.c
index 1319263e74..0785376355 100644
--- a/common/usbc/tbt_alt_mode.c
+++ b/common/usbc/tbt_alt_mode.c
@@ -69,8 +69,9 @@
* with a partner. It may be fixed in b/159495742, in which case this
* logic is unneeded.
*/
-#define TBT_FLAG_RETRY_DONE BIT(0)
-#define TBT_FLAG_EXIT_DONE BIT(1)
+#define TBT_FLAG_RETRY_DONE BIT(0)
+#define TBT_FLAG_EXIT_DONE BIT(1)
+#define TBT_FLAG_CABLE_ENTRY_DONE BIT(2)
static uint8_t tbt_flags[CONFIG_USB_PD_PORT_MAX_COUNT];
@@ -115,6 +116,7 @@ void tbt_init(int port)
tbt_state[port] = TBT_START;
TBT_CLR_FLAG(port, TBT_FLAG_RETRY_DONE);
TBT_SET_FLAG(port, TBT_FLAG_EXIT_DONE);
+ TBT_CLR_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
}
bool tbt_is_active(int port)
@@ -129,10 +131,16 @@ bool tbt_entry_is_done(int port)
tbt_state[port] == TBT_INACTIVE;
}
+bool tbt_cable_entry_is_done(int port)
+{
+ return TBT_CHK_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
+}
+
static void tbt_exit_done(int port)
{
tbt_state[port] = TBT_INACTIVE;
TBT_CLR_FLAG(port, TBT_FLAG_RETRY_DONE);
+ TBT_CLR_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
if (!TBT_CHK_FLAG(port, TBT_FLAG_EXIT_DONE)) {
TBT_SET_FLAG(port, TBT_FLAG_EXIT_DONE);
@@ -147,6 +155,14 @@ void tbt_exit_mode_request(int port)
{
TBT_SET_FLAG(port, TBT_FLAG_RETRY_DONE);
TBT_CLR_FLAG(port, TBT_FLAG_EXIT_DONE);
+ /*
+ * If the port has entered USB4 mode with Thunderbolt mode for the
+ * cable, on request to exit, only exit Thunderbolt mode for the
+ * cable.
+ * TODO (b/156749387): Remove once data reset feature is in place.
+ */
+ if (tbt_state[port] == TBT_ENTER_SOP)
+ tbt_state[port] = TBT_EXIT_SOP_PRIME_PRIME;
}
static bool tbt_response_valid(int port, enum tcpm_transmit_type type,
@@ -203,12 +219,15 @@ void intel_vdm_acked(int port, enum tcpm_transmit_type type, int vdo_count,
switch (tbt_state[port]) {
case TBT_ENTER_SOP_PRIME:
- if (disc->identity.product_t1.a_rev20.sop_p_p)
+ if (disc->identity.product_t1.a_rev20.sop_p_p) {
tbt_state[port] = TBT_ENTER_SOP_PRIME_PRIME;
- else
+ } else {
+ TBT_SET_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
tbt_state[port] = TBT_ENTER_SOP;
+ }
break;
case TBT_ENTER_SOP_PRIME_PRIME:
+ TBT_SET_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE);
tbt_state[port] = TBT_ENTER_SOP;
break;
case TBT_ENTER_SOP:
@@ -315,6 +334,7 @@ void intel_vdm_naked(int port, enum tcpm_transmit_type type, uint8_t vdm_cmd)
break;
case TBT_EXIT_SOP:
/* Exit SOP got NAK'ed */
+ tbt_prints("exit mode SOP failed", port);
set_usb_mux_with_current_data_role(port);
if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE)
tbt_active_cable_exit_mode(port);