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.c112
1 files changed, 25 insertions, 87 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index 257ef52a65..8e2581348b 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -1124,48 +1124,6 @@ uint32_t pd_get_requested_current(int port)
}
/*
- * Evaluate a sink PDO for reported FRS support on the given port.
- *
- * If the requirements in the PDO are compatible with what we can supply,
- * FRS will be enabled on the port. If the provided PDO does not specify
- * FRS requirements (because it is not a fixed PDO) or PD 3.0 and FRS support
- * are not enabled, do nothing.
- */
-__maybe_unused static void pe_evaluate_frs_snk_pdo(int port, uint32_t pdo)
-{
- if (!(IS_ENABLED(CONFIG_USB_PD_REV30) && IS_ENABLED(CONFIG_USB_PD_FRS)))
- return;
-
- if ((pdo & PDO_TYPE_MASK) != PDO_TYPE_FIXED) {
- /*
- * PDO must be a fixed supply: either the caller chose the
- * wrong PDO or the partner is not compliant.
- */
- CPRINTS("C%d: Sink PDO %x is not a fixed supply,"
- " cannot support FRS", port, pdo);
- return;
- }
- /*
- * TODO(b/14191267): Make sure we can handle the required current
- * before we enable FRS.
- */
- if ((pdo & PDO_FIXED_DUAL_ROLE)) {
- switch (pdo & PDO_FIXED_FRS_CURR_MASK) {
- case PDO_FIXED_FRS_CURR_NOT_SUPPORTED:
- break;
- case PDO_FIXED_FRS_CURR_DFLT_USB_POWER:
- case PDO_FIXED_FRS_CURR_1A5_AT_5V:
- case PDO_FIXED_FRS_CURR_3A0_AT_5V:
- CPRINTS("C%d: Partner FRS is OK: enabling PE support",
- port);
- typec_set_source_current_limit(port, TYPEC_RP_3A0);
- pe_set_frs_enable(port, 1);
- break;
- }
- }
-}
-
-/*
* Determine if this port may communicate with the cable plug.
*
* In both PD 2.0 and 3.0 (2.5.4 SOP'/SOP'' Communication with Cable Plugs):
@@ -1493,6 +1451,7 @@ static void pe_handle_detach(void)
pe_set_snk_caps(port, 0, NULL);
dpm_remove_sink(port);
+ dpm_remove_source(port);
/* Exit BIST Test mode, in case the TCPC entered it. */
tcpc_set_bist_test_mode(port, false);
@@ -2196,6 +2155,21 @@ static void pe_src_startup_entry(int port)
/* Start SwapSourceStartTimer */
pe[port].swap_source_start_timer = get_time().val +
PD_T_SWAP_SOURCE_START;
+
+ /*
+ * Evaluate port's sink caps for preferred current, if
+ * already available
+ */
+ if (pd_get_snk_cap_cnt(port) > 0)
+ dpm_evaluate_sink_fixed_pdo(port,
+ *pd_get_snk_caps(port));
+
+ /*
+ * Remove prior FRS claims to 3.0 A now that sink current has
+ * been claimed, to avoid issues with lower priority ports
+ * potentially receiving a 3.0 A claim between calls.
+ */
+ dpm_remove_source(port);
} else {
/*
* SwapSourceStartTimer delay is not needed, so trigger now.
@@ -2580,14 +2554,6 @@ static void pe_src_transition_supply_run(int port)
if (pd_get_src_cap_cnt(port) == 0)
pd_dpm_request(port, DPM_REQUEST_GET_SRC_CAPS);
- /*
- * Evaluate port's sink caps for preferred current, if
- * already available
- */
- if (pd_get_snk_cap_cnt(port) > 0)
- dpm_evaluate_sink_fixed_pdo(port,
- *pd_get_snk_caps(port));
-
set_state_pe(port, PE_SRC_READY);
} else {
/* NOTE: First pass through this code block */
@@ -3344,6 +3310,14 @@ static void pe_snk_transition_sink_run(int port)
if (tc_is_vconn_src(port))
tcpm_sop_prime_enable(port, true);
+ /*
+ * Evaluate port's sink caps for FRS current, if
+ * already available
+ */
+ if (pd_get_snk_cap_cnt(port) > 0)
+ dpm_evaluate_sink_fixed_pdo(port,
+ *pd_get_snk_caps(port));
+
set_state_pe(port, PE_SNK_READY);
return;
}
@@ -3405,40 +3379,6 @@ static void pe_snk_ready_entry(int port)
}
/*
- * If port partner sink capabilities are known (because we requested
- * and got them earlier), evaluate them for FRS support and enable
- * if appropriate. If not known, request that we get them through DPM
- * which will eventually come back here with known capabilities. Don't
- * do anything if FRS is already enabled.
- */
- if (IS_ENABLED(CONFIG_USB_PD_FRS) &&
- !PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_ENABLED)) {
- if (pd_get_snk_cap_cnt(port) > 0) {
- /*
- * Have partner sink caps. FRS support is only specified
- * in fixed PDOs, and "the vSafe5V Fixed Supply Object
- * Shall always be the first object" in a capabilities
- * message so take the first one.
- */
- const uint32_t *snk_caps = pd_get_snk_caps(port);
-
- pe_evaluate_frs_snk_pdo(port, snk_caps[0]);
- } else {
- /*
- * Don't have caps; request them. A sink port "shall
- * minimally offer one Power Data Object," so a
- * compliant partner that supports sink operation will
- * never fail to return sink capabilities in a way which
- * would cause us to endlessly request them. Non-DRPs
- * will never support FRS and may not support sink
- * operation, so avoid requesting caps from them.
- */
- if (pd_is_port_partner_dualrole(port))
- pd_dpm_request(port, DPM_REQUEST_GET_SNK_CAPS);
- }
- }
-
- /*
* Wait and add jitter if we are operating in PD2.0 mode and no messages
* have been sent since enter this state.
*/
@@ -6570,9 +6510,7 @@ static void pe_dr_get_sink_cap_run(int port)
pe_set_snk_caps(port, cap_cnt, payload);
- if (pe[port].power_role == PD_ROLE_SOURCE)
- dpm_evaluate_sink_fixed_pdo(port,
- payload[0]);
+ dpm_evaluate_sink_fixed_pdo(port, payload[0]);
pe_set_ready_state(port);
return;
} else if (cnt == 0 && (type == PD_CTRL_REJECT ||