diff options
author | Ayushee <ayushee.shah@intel.com> | 2020-05-08 03:09:41 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-06-09 19:28:05 +0000 |
commit | 6b90174eb1dd461ed336aa88b9f35a73767d0dd6 (patch) | |
tree | 197c98c87d8c524d3a33daae81395b1b8ef69267 /common | |
parent | 94492ef4046034935a1f8c6ac0887f2453c70151 (diff) | |
download | chrome-ec-6b90174eb1dd461ed336aa88b9f35a73767d0dd6.tar.gz |
usb_pd: Cleanup: Cable flags
Instead of using CABLE_FLAGS_SOP_PRIME_ENABLE and
CABLE_FLAGS_SOP_PRIME_PRIME_ENABLE cable flags, add the type of message
to be transmitted directly in the message header.
BUG=b:148528713
BRANCH=none
TEST=1. make buildall -j
2. Able to enter DP mode with Type-C dock and Type-C to DP
connector.
3. Able to enter Thunderbolt-Compatible mode with thunderbolt dock
with both Active and Passive cables.
4. Able to Enter USB4 mode with USB4 device with thunderbolt Gen2
cable.
Change-Id: Ib0cac818200e7ab8f73cace85ffee65203019709
Signed-off-by: Ayushee <ayushee.shah@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2159592
Reviewed-by: Keith Short <keithshort@chromium.org>
Commit-Queue: Keith Short <keithshort@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/usb_pd_alt_mode_dfp.c | 2 | ||||
-rw-r--r-- | common/usb_pd_policy.c | 150 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 52 |
3 files changed, 75 insertions, 129 deletions
diff --git a/common/usb_pd_alt_mode_dfp.c b/common/usb_pd_alt_mode_dfp.c index 9fc6dfc5aa..e4a7eb294a 100644 --- a/common/usb_pd_alt_mode_dfp.c +++ b/common/usb_pd_alt_mode_dfp.c @@ -661,7 +661,7 @@ bool is_active_cable_element_retimer(int port) * partner and cable identity discovery. */ void dfp_consume_cable_response(int port, int cnt, uint32_t *payload, - uint16_t head) + uint32_t head) { struct pd_cable *cable = pd_get_cable_attributes(port); struct pd_discovery *disc = diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index b8ca3d53ab..d4c59ba1ed 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -113,18 +113,6 @@ uint8_t pd_get_src_cap_cnt(int port) static struct pd_cable cable[CONFIG_USB_PD_PORT_MAX_COUNT]; -bool is_transmit_msg_sop_prime(int port) -{ - return (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP) && - (cable[port].flags & CABLE_FLAGS_SOP_PRIME_ENABLE)); -} - -bool is_transmit_msg_sop_prime_prime(int port) -{ - return (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP) && - (cable[port].flags & CABLE_FLAGS_SOP_PRIME_PRIME_ENABLE)); -} - bool consume_sop_prime_repeat_msg(int port, uint8_t msg_id) { @@ -147,18 +135,6 @@ bool consume_sop_prime_prime_repeat_msg(int port, uint8_t msg_id) return true; } -__maybe_unused static void disable_transmit_sop_prime(int port) -{ - if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) - cable[port].flags &= ~CABLE_FLAGS_SOP_PRIME_ENABLE; -} - -__maybe_unused static void disable_transmit_sop_prime_prime(int port) -{ - if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) - cable[port].flags &= ~CABLE_FLAGS_SOP_PRIME_PRIME_ENABLE; -} - __maybe_unused static uint8_t is_sop_prime_ready(int port) { /* @@ -176,16 +152,6 @@ __maybe_unused static uint8_t is_sop_prime_ready(int port) || (pd_get_data_role(port) == PD_ROLE_DFP))); } -enum pd_msg_type pd_msg_tx_type(int port) -{ - if (is_transmit_msg_sop_prime(port)) - return PD_MSG_SOP_PRIME; - if (is_transmit_msg_sop_prime_prime(port)) - return PD_MSG_SOP_PRIME_PRIME; - - return PD_MSG_SOP; -} - void reset_pd_cable(int port) { memset(&cable[port], 0, sizeof(cable[port])); @@ -241,18 +207,6 @@ void disable_enter_usb4_mode(int port) static struct pd_discovery discovery[CONFIG_USB_PD_PORT_MAX_COUNT]; -static void enable_transmit_sop_prime(int port) -{ - if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) - cable[port].flags |= CABLE_FLAGS_SOP_PRIME_ENABLE; -} - -static void enable_transmit_sop_prime_prime(int port) -{ - if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) - cable[port].flags |= CABLE_FLAGS_SOP_PRIME_PRIME_ENABLE; -} - static bool is_tbt_compat_enabled(int port) { return (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE) && @@ -410,18 +364,9 @@ struct pd_cable *pd_get_cable_attributes(int port) return &cable[port]; } -static enum tcpm_transmit_type get_tcpm_transmit_msg_type(int port) -{ - if (is_transmit_msg_sop_prime(port)) - return TCPC_TX_SOP_PRIME; - - if (is_transmit_msg_sop_prime_prime(port)) - return TCPC_TX_SOP_PRIME_PRIME; - - return TCPC_TX_SOP; -} - -static int process_am_discover_svids(int port, int cnt, uint32_t *payload) +static int process_am_discover_svids(int port, int cnt, uint32_t *payload, + enum tcpm_transmit_type sop, + enum tcpm_transmit_type *rtype) { int prev_svid_cnt = discovery[port].svid_cnt; @@ -456,47 +401,40 @@ static int process_am_discover_svids(int port, int cnt, uint32_t *payload) TBT_SS_U32_GEN1_GEN2; enable_enter_usb4_mode(port); usb_mux_set_safe_mode(port); - if (is_transmit_msg_sop_prime(port)) - disable_transmit_sop_prime(port); return 0; } - if (is_transmit_msg_sop_prime(port)) + if (sop == TCPC_TX_SOP_PRIME) limit_tbt_cable_speed(port); else disable_tbt_compat_mode(port); - } else if (!is_transmit_msg_sop_prime(port)) { - enable_transmit_sop_prime(port); + } else if (sop == TCPC_TX_SOP) { + *rtype = TCPC_TX_SOP_PRIME; return dfp_discover_svids(payload); } - - disable_transmit_sop_prime(port); } return dfp_discover_modes(port, payload); } static int process_tbt_compat_discover_modes(int port, - enum tcpm_transmit_type sop, uint32_t *payload) + enum tcpm_transmit_type sop, uint32_t *payload, + enum tcpm_transmit_type *rtype) { int rsize; + /* Initialize transmit type to SOP */ + *rtype = TCPC_TX_SOP; + /* * For active cables, Enter mode: SOP', SOP'', SOP * Ref: USB Type-C Cable and Connector Specification, figure F-1: TBT3 * Discovery Flow and Section F.2.7 TBT3 Cable Enter Mode Command. */ - if (is_transmit_msg_sop_prime(port)) { + if (sop == TCPC_TX_SOP_PRIME) { /* Store Discover Mode SOP' response */ cable[port].cable_mode_resp.raw_value = payload[1]; - /* - * Enter Mode SOP' (Cable Enter Mode) and Enter USB SOP' is - * skipped for passive cables. - */ - if (get_usb_pd_cable_type(port) == IDH_PTYPE_PCABLE) - disable_transmit_sop_prime(port); - if (is_usb4_mode_enabled(port)) { /* * If Cable is not Thunderbolt Gen 3 @@ -512,7 +450,15 @@ static int process_tbt_compat_discover_modes(int port, } disable_usb4_mode(port); } - rsize = enter_tbt_compat_mode(port, sop, payload); + + /* + * Send TBT3 Cable Enter Mode (SOP') for active cables, + * otherwise send TBT3 Device Enter Mode (SOP). + */ + if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE) + *rtype = TCPC_TX_SOP_PRIME; + + rsize = enter_tbt_compat_mode(port, *rtype, payload); } else { /* Store Discover Mode SOP response */ cable[port].dev_mode_resp.raw_value = payload[1]; @@ -531,35 +477,33 @@ static int process_tbt_compat_discover_modes(int port, TBT_SS_U32_GEN1_GEN2 : cable[port].attr.p_rev30.ss; - rsize = enter_tbt_compat_mode(port, sop, payload); + rsize = enter_tbt_compat_mode(port, *rtype, payload); } else { /* Discover modes for SOP' */ discovery[port].svid_idx--; rsize = dfp_discover_modes(port, payload); - enable_transmit_sop_prime(port); + *rtype = TCPC_TX_SOP_PRIME; } } return rsize; } -static int obj_cnt_enter_tbt_compat_mode(int port, enum tcpm_transmit_type sop, - uint32_t *payload) +static int obj_cnt_enter_tbt_compat_mode(int port, + enum tcpm_transmit_type sop, uint32_t *payload, + enum tcpm_transmit_type *rtype) { /* Enter mode SOP' for active cables */ - if (is_transmit_msg_sop_prime(port)) { - disable_transmit_sop_prime(port); + if (sop == TCPC_TX_SOP_PRIME) { /* Check if the cable has a SOP'' controller */ if (cable[port].attr.a_rev20.sop_p_p) - enable_transmit_sop_prime_prime(port); - return enter_tbt_compat_mode(port, sop, payload); + *rtype = TCPC_TX_SOP_PRIME_PRIME; + return enter_tbt_compat_mode(port, *rtype, payload); } /* Enter Mode SOP'' for active cables with SOP'' controller */ - if (is_transmit_msg_sop_prime_prime(port)) { - disable_transmit_sop_prime_prime(port); - return enter_tbt_compat_mode(port, sop, payload); - } + if (sop == TCPC_TX_SOP_PRIME_PRIME) + return enter_tbt_compat_mode(port, *rtype, payload); /* Update Mux state to Thunderbolt-compatible mode. */ set_tbt_compat_mode_ready(port); @@ -569,7 +513,7 @@ static int obj_cnt_enter_tbt_compat_mode(int port, enum tcpm_transmit_type sop, #endif /* CONFIG_USB_PD_ALT_MODE_DFP */ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, - uint16_t head) + uint32_t head, enum tcpm_transmit_type *rtype) { int cmd = PD_VDO_CMD(payload[0]); int cmd_type = PD_VDO_CMDT(payload[0]); @@ -577,6 +521,13 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, int rsize = 1; /* VDM header at a minimum */ +#ifdef CONFIG_USB_PD_ALT_MODE_DFP + enum tcpm_transmit_type sop = PD_HEADER_GET_SOP(head); +#endif + + /* Transmit SOP messages by default */ + *rtype = TCPC_TX_SOP; + payload[0] &= ~VDO_CMDT_MASK; *rpayload = payload; @@ -642,11 +593,10 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, #ifdef CONFIG_USB_PD_ALT_MODE_DFP case CMD_DISCOVER_IDENT: /* Received a SOP' Discover Ident msg */ - if (is_transmit_msg_sop_prime(port)) { + if (sop == TCPC_TX_SOP_PRIME) { /* Store cable type */ dfp_consume_cable_response(port, cnt, payload, head); - /* * Enter USB4 mode if the cable supports USB4 * operation and has USB4 VDO. @@ -655,7 +605,6 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, is_cable_ready_to_enter_usb4(port, cnt)) { enable_enter_usb4_mode(port); usb_mux_set_safe_mode(port); - disable_transmit_sop_prime(port); /* * To change the mode of operation from * USB4 the port needs to be @@ -679,8 +628,6 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, } rsize = dfp_discover_svids(payload); - - disable_transmit_sop_prime(port); /* Received a SOP Discover Ident Message */ } else if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP) && is_sop_prime_ready(port) && @@ -706,7 +653,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, if (is_modal(port, cnt, payload) || is_usb4_vdo(port, cnt, payload)) { rsize = dfp_discover_ident(payload); - enable_transmit_sop_prime(port); + *rtype = TCPC_TX_SOP_PRIME; } else { rsize = dfp_discover_svids(payload); } @@ -723,7 +670,8 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, #endif break; case CMD_DISCOVER_SVID: - rsize = process_am_discover_svids(port, cnt, payload); + rsize = process_am_discover_svids(port, cnt, payload, + sop, rtype); break; case CMD_DISCOVER_MODES: /* @@ -736,9 +684,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, if (is_tbt_compat_enabled(port) && is_tbt_compat_mode(port, cnt, payload)) { rsize = process_tbt_compat_discover_modes( - port, - get_tcpm_transmit_msg_type(port), - payload); + port, sop, payload, rtype); break; } @@ -759,8 +705,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, case CMD_ENTER_MODE: if (is_tbt_compat_enabled(port)) { rsize = obj_cnt_enter_tbt_compat_mode(port, - get_tcpm_transmit_msg_type(port), - payload); + sop, payload, rtype); /* * Continue with PD flow if Thunderbolt-compatible mode * is disabled. @@ -832,11 +777,10 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, } else if (cmd_type == CMDT_RSP_NAK) { /* Passive cable Nacked for Discover SVID */ if (cmd == CMD_DISCOVER_SVID && is_tbt_compat_enabled(port) && - is_transmit_msg_sop_prime(port) && + sop == TCPC_TX_SOP_PRIME && get_usb_pd_cable_type(port) == IDH_PTYPE_PCABLE) { limit_tbt_cable_speed(port); rsize = dfp_discover_modes(port, payload); - disable_transmit_sop_prime(port); } else { rsize = 0; } @@ -852,7 +796,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, #else int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, - uint16_t head) + uint32_t head, enum tcpm_transmit_type *rtype) { return 0; } diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index a82c2b79d0..526769a8e2 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -257,6 +257,8 @@ static struct pd_protocol { timestamp_t vdm_timeout; /* next Vendor Defined Message to send */ uint32_t vdo_data[VDO_MAX_SIZE]; + /* type of transmit message (SOP/SOP'/SOP'') */ + enum tcpm_transmit_type xmit_type; uint8_t vdo_count; /* VDO to retry if UFP responder replied busy. */ uint32_t vdo_retry; @@ -641,17 +643,18 @@ static bool consume_sop_repeat_message(int port, uint8_t msg_id) * using SOP* Packets Shall maintain copies of the last MessageID for * each type of SOP* it uses. */ -static bool consume_repeat_message(int port, uint16_t msg_header) +static bool consume_repeat_message(int port, uint32_t msg_header) { uint8_t msg_id = PD_HEADER_ID(msg_header); + enum tcpm_transmit_type sop = PD_HEADER_GET_SOP(msg_header); /* If repeat message ignore, except softreset control request. */ if (PD_HEADER_TYPE(msg_header) == PD_CTRL_SOFT_RESET && PD_HEADER_CNT(msg_header) == 0) { return false; - } else if (is_transmit_msg_sop_prime(port)) { + } else if (sop == TCPC_TX_SOP_PRIME) { return consume_sop_prime_repeat_msg(port, msg_id); - } else if (is_transmit_msg_sop_prime_prime(port)) { + } else if (sop == TCPC_TX_SOP_PRIME_PRIME) { return consume_sop_prime_prime_repeat_msg(port, msg_id); } else { return consume_sop_repeat_message(port, msg_id); @@ -1212,20 +1215,23 @@ static int send_bist_cmd(int port) #endif static void queue_vdm(int port, uint32_t *header, const uint32_t *data, - int data_cnt) + int data_cnt, enum tcpm_transmit_type type) { pd[port].vdo_count = data_cnt + 1; pd[port].vdo_data[0] = header[0]; - memcpy(&pd[port].vdo_data[1], data, sizeof(uint32_t) * data_cnt); + pd[port].xmit_type = type; + memcpy(&pd[port].vdo_data[1], data, + sizeof(uint32_t) * data_cnt); /* Set ready, pd task will actually send */ pd[port].vdm_state = VDM_STATE_READY; } static void handle_vdm_request(int port, int cnt, uint32_t *payload, - uint16_t head) + uint32_t head) { int rlen = 0; uint32_t *rdata; + enum tcpm_transmit_type rtype = TCPC_TX_SOP; if (pd[port].vdm_state == VDM_STATE_BUSY) { /* If UFP responded busy retry after timeout */ @@ -1248,14 +1254,15 @@ static void handle_vdm_request(int port, int cnt, uint32_t *payload, } if (PD_VDO_SVDM(payload[0])) - rlen = pd_svdm(port, cnt, payload, &rdata, head); + rlen = pd_svdm(port, cnt, payload, &rdata, head, &rtype); else rlen = pd_custom_vdm(port, cnt, payload, &rdata); if (rlen > 0) { - queue_vdm(port, rdata, &rdata[1], rlen - 1); + queue_vdm(port, rdata, &rdata[1], rlen - 1, rtype); return; } + if (debug_level >= 2) CPRINTF("C%d Unhandled VDM VID %04x CMD %04x\n", port, PD_VDO_VID(payload[0]), payload[0] & 0xFFFF); @@ -1503,7 +1510,7 @@ static void pd_update_pdo_flags(int port, uint32_t pdo) #endif } -static void handle_data_request(int port, uint16_t head, +static void handle_data_request(int port, uint32_t head, uint32_t *payload) { int type = PD_HEADER_TYPE(head); @@ -1672,7 +1679,7 @@ static void pd_dr_swap(int port) pd[port].flags |= PD_FLAGS_CHECK_IDENTITY; } -static void handle_ctrl_request(int port, uint16_t head, +static void handle_ctrl_request(int port, uint32_t head, uint32_t *payload) { int type = PD_HEADER_TYPE(head); @@ -1990,7 +1997,7 @@ static void handle_ext_request(int port, uint16_t head, uint32_t *payload) } #endif -static void handle_request(int port, uint16_t head, +static void handle_request(int port, uint32_t head, uint32_t *payload) { int cnt = PD_HEADER_CNT(head); @@ -2069,7 +2076,7 @@ void pd_send_vdm(int port, uint32_t vid, int cmd, const uint32_t *data, #ifdef CONFIG_USB_PD_REV30 pd[port].vdo_data[0] |= VDO_SVDM_VERS(vdo_ver[pd[port].rev]); #endif - queue_vdm(port, pd[port].vdo_data, data, count); + queue_vdm(port, pd[port].vdo_data, data, count, TCPC_TX_SOP); task_wake(PD_PORT_TO_TASK_ID(port)); } @@ -2149,7 +2156,7 @@ static void pd_vdm_send_state_machine(int port) { int res; uint16_t header; - enum pd_msg_type msg_type = pd_msg_tx_type(port); + enum tcpm_transmit_type msg_type = pd[port].xmit_type; switch (pd[port].vdm_state) { case VDM_STATE_READY: @@ -2177,8 +2184,8 @@ static void pd_vdm_send_state_machine(int port) * data role swap takes place during source and sink * negotiation and in case of failure, a soft reset is issued. */ - if ((msg_type == PD_MSG_SOP_PRIME) || - (msg_type == PD_MSG_SOP_PRIME_PRIME)) { + if ((msg_type == TCPC_TX_SOP_PRIME) || + (msg_type == TCPC_TX_SOP_PRIME_PRIME)) { /* Prepare SOP'/SOP'' header and send VDM */ header = PD_HEADER( PD_DATA_VENDOR_DEF, @@ -2188,13 +2195,8 @@ static void pd_vdm_send_state_machine(int port) (int)pd[port].vdo_count, pd_get_rev(port), 0); - res = pd_transmit(port, - (msg_type == PD_MSG_SOP_PRIME) ? - TCPC_TX_SOP_PRIME : - TCPC_TX_SOP_PRIME_PRIME, - header, - pd[port].vdo_data, - AMS_START); + res = pd_transmit(port, msg_type, header, + pd[port].vdo_data, AMS_START); /* * In the case of SOP', if there is no response from * the cable, it's a non-emark cable and therefore the @@ -2217,10 +2219,10 @@ static void pd_vdm_send_state_machine(int port) (int)pd[port].vdo_count, pd_get_rev(port), 0); - if ((msg_type == PD_MSG_SOP_PRIME_PRIME) && + if ((msg_type == TCPC_TX_SOP_PRIME_PRIME) && IS_ENABLED(CONFIG_USBC_SS_MUX)) { exit_tbt_mode_sop_prime(port); - } else if (msg_type == PD_MSG_SOP_PRIME) { + } else if (msg_type == TCPC_TX_SOP_PRIME) { pd[port].vdo_data[0] = VDO(USB_SID_PD, 1, CMD_DISCOVER_SVID); } @@ -2856,7 +2858,7 @@ static void pd_send_enter_usb(int port, int *timeout) void pd_task(void *u) { - int head; + uint32_t head; int port = TASK_ID_TO_PD_PORT(task_get_current()); uint32_t payload[7]; int timeout = 10*MSEC; |