summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2021-03-12 15:21:16 -0700
committerCommit Bot <commit-bot@chromium.org>2021-03-19 17:39:40 +0000
commit7bc2599f6c803e6248b793d11300e2262e0908ed (patch)
treef91cdbcd9f55146e548fca5fedaced5866cbf375
parent015d9606b30299aff975db8b3096dbf57b3f065f (diff)
downloadchrome-ec-7bc2599f6c803e6248b793d11300e2262e0908ed.tar.gz
TCPMv2: Preserve selected source current in FRS
When executing a fast role swap, ensure that any 3.0 A selected current is preserved through the select_current_limit_rp in the TC layer. Additionally, use this selected current to set our current limit when first attaching as a source. If FRS is disabled on a port, restore the default Rp value for the board. BRANCH=None BUG=b:180434465 TEST=Check that a 3A FRS device loaded over 1.5 A is able to successfully complete FRS Signed-off-by: Diana Z <dzigterman@chromium.org> Change-Id: I6e6b2f95066a3f8972664c6ac62b450e179e408d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2757096 Reviewed-by: Abe Levkoy <alevkoy@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2774582 Tested-by: Abe Levkoy <alevkoy@chromium.org> Commit-Queue: Abe Levkoy <alevkoy@chromium.org>
-rw-r--r--common/mock/usb_tc_sm_mock.c4
-rw-r--r--common/usbc/usb_pd_dpm.c3
-rw-r--r--common/usbc/usb_pe_drp_sm.c11
-rw-r--r--common/usbc/usb_tc_drp_acc_trysrc_sm.c10
4 files changed, 23 insertions, 5 deletions
diff --git a/common/mock/usb_tc_sm_mock.c b/common/mock/usb_tc_sm_mock.c
index 07d861f4d4..259170d6bf 100644
--- a/common/mock/usb_tc_sm_mock.c
+++ b/common/mock/usb_tc_sm_mock.c
@@ -56,6 +56,10 @@ void typec_select_src_collision_rp(int port, enum tcpc_rp_value rp)
mock_tc_port[port].lcl_rp = rp;
}
+void typec_select_src_current_limit_rp(int port, enum tcpc_rp_value rp)
+{
+}
+
int tc_is_attached_src(int port)
{
return mock_tc_port[port].attached_src;
diff --git a/common/usbc/usb_pd_dpm.c b/common/usbc/usb_pd_dpm.c
index 32929d2b79..1c579d7630 100644
--- a/common/usbc/usb_pd_dpm.c
+++ b/common/usbc/usb_pd_dpm.c
@@ -584,6 +584,9 @@ void dpm_remove_sink(int port)
atomic_clear_bits(&sink_max_pdo_requested, BIT(port));
atomic_clear_bits(&non_pd_sink_max_requested, BIT(port));
+ /* Restore selected default Rp on the port */
+ typec_select_src_current_limit_rp(port, CONFIG_USB_PD_PULLUP);
+
balance_source_ports();
}
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index 79bdc3166e..85caf0473c 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -931,10 +931,10 @@ static void pe_set_frs_enable(int port, int enable)
int curr_limit = *pd_get_snk_caps(port)
& PDO_FIXED_FRS_CURR_MASK;
- typec_set_source_current_limit(port,
- curr_limit ==
- PDO_FIXED_FRS_CURR_3A0_AT_5V ?
- TYPEC_RP_3A0 : TYPEC_RP_1A5);
+ typec_select_src_current_limit_rp(port,
+ curr_limit ==
+ PDO_FIXED_FRS_CURR_3A0_AT_5V ?
+ TYPEC_RP_3A0 : TYPEC_RP_1A5);
PE_SET_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_ENABLED);
} else {
PE_CLR_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_ENABLED);
@@ -1622,6 +1622,9 @@ static bool sink_dpm_requests(int port)
} else if (PE_CHK_DPM_REQUEST(port,
DPM_REQUEST_FRS_DET_DISABLE)) {
pe_set_frs_enable(port, 0);
+ /* Restore a default port current limit */
+ typec_select_src_current_limit_rp(port,
+ CONFIG_USB_PD_PULLUP);
/* Requires no state change, fall through to false */
PE_CLR_DPM_REQUEST(port, DPM_REQUEST_FRS_DET_DISABLE);
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
index cb7f7866b9..981227f468 100644
--- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c
+++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
@@ -2150,10 +2150,14 @@ static void tc_unattached_snk_entry(const int port)
*
* Both CC1 and CC2 pins shall be independently terminated to
* ground through Rd.
+ *
+ * Restore default current limit Rp in case we swap to source
*/
typec_select_pull(port, TYPEC_CC_RD);
+ typec_select_src_current_limit_rp(port, CONFIG_USB_PD_PULLUP);
typec_update_cc(port);
+
prev_data_role = tc[port].data_role;
tc[port].data_role = PD_ROLE_DISCONNECTED;
/*
@@ -2696,6 +2700,8 @@ static void tc_unattached_src_entry(const int port)
*
* Both CC1 and CC2 pins shall be independently terminated to
* ground through Rp.
+ *
+ * Restore default current limit Rp.
*/
typec_select_pull(port, TYPEC_CC_RP);
typec_select_src_current_limit_rp(port, CONFIG_USB_PD_PULLUP);
@@ -2880,9 +2886,11 @@ static void tc_attached_src_entry(const int port)
*
* Both CC1 and CC2 pins shall be independently terminated to
* pulled up through Rp.
+ *
+ * Set selected current limit in the hardware.
*/
typec_select_pull(port, TYPEC_CC_RP);
- typec_select_src_current_limit_rp(port, CONFIG_USB_PD_PULLUP);
+ typec_set_source_current_limit(port, tc[port].select_current_limit_rp);
if (IS_ENABLED(CONFIG_USB_PE_SM)) {
if (TC_CHK_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS)) {