summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorAyushee <ayushee.shah@intel.com>2020-05-08 03:09:41 -0700
committerCommit Bot <commit-bot@chromium.org>2020-06-09 19:28:05 +0000
commit6b90174eb1dd461ed336aa88b9f35a73767d0dd6 (patch)
tree197c98c87d8c524d3a33daae81395b1b8ef69267 /common
parent94492ef4046034935a1f8c6ac0887f2453c70151 (diff)
downloadchrome-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.c2
-rw-r--r--common/usb_pd_policy.c150
-rw-r--r--common/usb_pd_protocol.c52
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;