diff options
Diffstat (limited to 'common/usbc/tbt_alt_mode.c')
-rw-r--r-- | common/usbc/tbt_alt_mode.c | 28 |
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); |