diff options
author | Denis Brockus <dbrockus@google.com> | 2020-05-29 20:23:37 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-06-04 18:29:17 +0000 |
commit | e38fa2719bdb9cd732b9ecd319fe29644104859a (patch) | |
tree | 94123a4fd6d607a01334714f3fbd459c085338e5 /common | |
parent | e802de1376c9733b49bcf18e5194392a55cdccbf (diff) | |
download | chrome-ec-e38fa2719bdb9cd732b9ecd319fe29644104859a.tar.gz |
TCPMv2: Wait for Safe0V on PR Swap SNK to SRC before PS_RDY
We were out of spec for PR Swap transitioning from
SNK to SRC by sending PS_RDY before we were Safe0V.
We only waited for the TC state machine to go from
attached.snk to attached.src, which happened on the
first state machine tick after
pe_prs_src_snk_transition_to_off_entry was called
and this does not guarantee Safe0V as is needed.
Added an extra state to reflect what the PD spec
requests and now waiting for Safe0V before
indicating we are powered off.
BUG=b:157755939
BRANCH=none
TEST=ThinkPad Dock G2 should attach
Signed-off-by: Denis Brockus <dbrockus@google.com>
Change-Id: I93eb36acc64f273e8b30ca0a0bb76d6fa96b64ba
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2223723
Tested-by: Denis Brockus <dbrockus@chromium.org>
Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Auto-Submit: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index c4e0fa0a58..751fd1a167 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -216,6 +216,7 @@ enum usb_pe_state { PE_DRS_SEND_SWAP, PE_PRS_SRC_SNK_EVALUATE_SWAP, PE_PRS_SRC_SNK_TRANSITION_TO_OFF, + PE_PRS_SRC_SNK_ASSERT_RD, PE_PRS_SRC_SNK_WAIT_SOURCE_ON, PE_PRS_SRC_SNK_SEND_SWAP, PE_PRS_SNK_SRC_EVALUATE_SWAP, @@ -306,6 +307,7 @@ static const char * const pe_state_names[] = { [PE_DRS_SEND_SWAP] = "PE_DRS_Send_Swap", [PE_PRS_SRC_SNK_EVALUATE_SWAP] = "PE_PRS_SRC_SNK_Evaluate_Swap", [PE_PRS_SRC_SNK_TRANSITION_TO_OFF] = "PE_PRS_SRC_SNK_Transition_To_Off", + [PE_PRS_SRC_SNK_ASSERT_RD] = "PE_PRS_SRC_SNK_Assert_Rd", [PE_PRS_SRC_SNK_WAIT_SOURCE_ON] = "PE_PRS_SRC_SNK_Wait_Source_On", [PE_PRS_SRC_SNK_SEND_SWAP] = "PE_PRS_SRC_SNK_Send_Swap", [PE_PRS_SNK_SRC_EVALUATE_SWAP] = "PE_PRS_SNK_SRC_Evaluate_Swap", @@ -3484,8 +3486,9 @@ static void pe_prs_src_snk_transition_to_off_entry(int port) { print_current_state(port); - /* Tell TypeC to swap from Attached.SRC to Attached.SNK */ - tc_prs_src_snk_assert_rd(port); + /* Tell TypeC to power off the source */ + tc_src_power_off(port); + pe[port].ps_source_timer = get_time().val + PD_POWER_SUPPLY_TURN_OFF_DELAY; } @@ -3493,9 +3496,24 @@ static void pe_prs_src_snk_transition_to_off_entry(int port) static void pe_prs_src_snk_transition_to_off_run(int port) { /* Give time for supply to power off */ - if (get_time().val < pe[port].ps_source_timer) - return; + if (get_time().val > pe[port].ps_source_timer && + tcpm_check_vbus_level(port, VBUS_SAFE0V)) + set_state_pe(port, PE_PRS_SRC_SNK_ASSERT_RD); +} + +/** + * PE_PRS_SRC_SNK_Assert_Rd + */ +static void pe_prs_src_snk_assert_rd_entry(int port) +{ + print_current_state(port); + + /* Tell TypeC to swap from Attached.SRC to Attached.SNK */ + tc_prs_src_snk_assert_rd(port); +} +static void pe_prs_src_snk_assert_rd_run(int port) +{ /* Wait until Rd is asserted */ if (tc_is_attached_snk(port)) { /* Contract is invalid */ @@ -5813,6 +5831,10 @@ static const struct usb_state pe_states[] = { .entry = pe_prs_src_snk_transition_to_off_entry, .run = pe_prs_src_snk_transition_to_off_run, }, + [PE_PRS_SRC_SNK_ASSERT_RD] = { + .entry = pe_prs_src_snk_assert_rd_entry, + .run = pe_prs_src_snk_assert_rd_run, + }, [PE_PRS_SRC_SNK_WAIT_SOURCE_ON] = { .entry = pe_prs_src_snk_wait_source_on_entry, .run = pe_prs_src_snk_wait_source_on_run, |