summaryrefslogtreecommitdiff
path: root/common/usbc/usb_pe_drp_sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/usbc/usb_pe_drp_sm.c')
-rw-r--r--common/usbc/usb_pe_drp_sm.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index ab481bffe5..9a764cb716 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -182,11 +182,23 @@
#define N_DISCOVER_IDENTITY_COUNT 6
/*
- * tDiscoverIdentity is only defined while an explicit contract is in place.
- * To support captive cable devices that power the SOP' responder from VBUS
- * instead of VCONN stretch out the SOP' Discover Identity messages when
- * no contract is present. 200 ms provides about 1 second for the cable
- * to power up (200 * 5 retries).
+ * It is permitted to send SOP' Discover Identity messages before a PD contract
+ * is in place. However, this is only beneficial if the cable powers up quickly
+ * solely from VCONN. Limit the number of retries without a contract to
+ * ensure we attempt some cable discovery after a contract is in place.
+ */
+#define N_DISCOVER_IDENTITY_PRECONTRACT_LIMIT 2
+
+/*
+ * Once this limit of SOP' Discover Identity messages has been set, downgrade
+ * to PD 2.0 in case the cable is non-compliant about GoodCRC-ing higher
+ * revisions. This limit should be higher than the precontract limit.
+ */
+#define N_DISCOVER_IDENTITY_PD3_0_LIMIT 4
+
+/*
+ * tDiscoverIdentity is only defined while an explicit contract is in place, so
+ * extend the interval between retries pre-contract.
*/
#define PE_T_DISCOVER_IDENTITY_NO_CONTRACT (200*MSEC)
@@ -1946,7 +1958,9 @@ static void pe_src_discovery_run(int port)
*/
if (pd_get_identity_discovery(port, TCPC_TX_SOP_PRIME) == PD_DISC_NEEDED
&& get_time().val > pe[port].discover_identity_timer
- && pe_can_send_sop_prime(port)) {
+ && pe_can_send_sop_prime(port)
+ && (pe[port].discover_identity_counter <
+ N_DISCOVER_IDENTITY_PRECONTRACT_LIMIT)) {
pe[port].tx_type = TCPC_TX_SOP_PRIME;
set_state_pe(port, PE_VDM_IDENTITY_REQUEST_CBL);
return;
@@ -2209,7 +2223,6 @@ static void pe_src_transition_supply_run(int port)
if (PE_CHK_FLAG(port, PE_FLAGS_PS_READY)) {
PE_CLR_FLAG(port, PE_FLAGS_PS_READY);
- /* NOTE: Second pass through this code block */
/*
* Set first message flag to trigger a wait and add
@@ -2219,6 +2232,7 @@ static void pe_src_transition_supply_run(int port)
if (!pe_is_explicit_contract(port))
PE_SET_FLAG(port, PE_FLAGS_FIRST_MSG);
+ /* NOTE: Second pass through this code block */
/* Explicit Contract is now in place */
pe_set_explicit_contract(port);
@@ -5068,10 +5082,10 @@ static void pe_vdm_identity_request_cbl_exit(int port)
pd_set_identity_discovery(port, pe[port].tx_type,
PD_DISC_FAIL);
else if (pe[port].discover_identity_counter ==
- (N_DISCOVER_IDENTITY_COUNT / 2))
+ N_DISCOVER_IDENTITY_PD3_0_LIMIT)
/*
- * Downgrade to PD 2.0 if the partner hasn't replied halfway
- * through discovery as well, in case the cable is
+ * Downgrade to PD 2.0 if the partner hasn't replied before
+ * all retries are exhausted in case the cable is
* non-compliant about GoodCRC-ing higher revisions
*/
prl_set_rev(port, TCPC_TX_SOP_PRIME, PD_REV20);