From ad568190dde4b0ab1217d49b3e66b122a03afbde Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Fri, 24 Feb 2023 12:26:02 -0800 Subject: USB-PD: Support Vconn swap during EPR entry for Sink Currently, a sink port must not be a Vconn source before entering EPR. This CL makes TCPMv2 allow a sink port to swap Vconn during EPR mode entry. BUG=b:257320026 BRANCH=None TEST=Agah. Set the sink port as Vconn source. Trigger EPR enter. Signed-off-by: Daisuke Nojiri Change-Id: If569ec9fe9e0f4ffbb153db649c3f9c04b698eb2 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4295370 Reviewed-by: Diana Z Commit-Queue: Diana Z --- common/usbc/usb_pe_drp_sm.c | 17 ++++++++++++++++- common/usbc/usb_pe_private.h | 6 ++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 0264837057..767fed302b 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -4137,6 +4137,8 @@ static void pe_send_soft_reset_entry(int port) { print_current_state(port); + PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR); + /* Reset Protocol Layer (softly) */ prl_reset_soft(port); @@ -6965,7 +6967,11 @@ static void pe_vcs_turn_off_vconn_swap_run(int port) pe[port].discover_identity_counter = 0; pe[port].dr_swap_attempt_counter = 0; - pe_set_ready_state(port); + if (PE_CHK_FLAG(port, PE_FLAGS_ENTERING_EPR)) + set_state_pe(port, + PE_SNK_EPR_MODE_ENTRY_WAIT_FOR_RESPONSE); + else + pe_set_ready_state(port); return; } } @@ -7906,6 +7912,7 @@ static void pe_ddr_perform_data_reset_exit(int port) #ifdef CONFIG_USB_PD_EPR static void pe_enter_epr_mode(int port) { + PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR); PE_SET_FLAG(port, PE_FLAGS_IN_EPR); CPRINTS("C%d: Entered EPR", port); } @@ -7984,6 +7991,8 @@ static void pe_snk_send_epr_mode_entry_entry(int port) print_current_state(port); + PE_SET_FLAG(port, PE_FLAGS_ENTERING_EPR); + /* Send EPR mode entry message */ eprmdo->action = PD_EPRMDO_ACTION_ENTER; eprmdo->data = 0; /* EPR Sink Operational PDP */ @@ -8004,6 +8013,7 @@ static void pe_snk_send_epr_mode_entry_run(int port) msg_check = pe_sender_response_msg_run(port); if (msg_check & PE_MSG_DISCARDED) { + PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR); set_state_pe(port, PE_SNK_READY); return; } @@ -8072,11 +8082,16 @@ static void pe_snk_epr_mode_entry_wait_for_response_run(int port) return; } else if (eprmdo->action == PD_EPRMDO_ACTION_ENTER_FAILED) { + PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR); /* Table 6-50 EPR Mode Data Object */ CPRINTS("C%d: Failed to enter EPR for 0x%x", port, eprmdo->data); } /* Fall through to soft reset. */ + } else if ((ext == 0) && (cnt == 0) && + (type == PD_CTRL_VCONN_SWAP)) { + set_state_pe(port, PE_VCS_EVALUATE_SWAP); + return; } /* * 6.4.10.1 Process to enter EPR Mode diff --git a/common/usbc/usb_pe_private.h b/common/usbc/usb_pe_private.h index a3979c1821..5eafb7befd 100644 --- a/common/usbc/usb_pe_private.h +++ b/common/usbc/usb_pe_private.h @@ -84,6 +84,12 @@ enum { PE_FLAGS_DATA_RESET_COMPLETE_FN, /* Waiting for SRC to SNK settle time */ PE_FLAGS_SRC_SNK_SETTLE_FN, + /* + * Indicates the port is in the process of entering EPR mode. For a + * sink, the SM is in and after PE_SNK_EPR_Mode_Entry. For a source, + * the SM is in and after PE_SRC_EPR_Mode_Entery_ACK. + */ + PE_FLAGS_ENTERING_EPR_FN, /* In EPR mode */ PE_FLAGS_IN_EPR_FN, /* Discovery disabled due to UFP/PD 2.0 constraint. */ -- cgit v1.2.1