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