summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2023-02-23 15:04:48 -0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-04-17 18:19:39 +0000
commit74108a6ab365a110d70b4064ec2d99fa7ea9b73e (patch)
tree6195364b58322e9241c2868d09e5f4f98e2dc936
parent230aa1bc412c8c40137d8980873be9eedc986d74 (diff)
downloadchrome-ec-74108a6ab365a110d70b4064ec2d99fa7ea9b73e.tar.gz
USB-PD: Make sink automatically enter EPR mode
Currently, EPR mode is entered only by 'pd' console command. This CL makes sink ports enter EPR mode automatically. PE_FLAGS_EPR_EXPLICIT_EXIT is cleared when soft reset is sent, a source is disconnected, or EPR is entered again. BUG=b:257320026,b:274929940 BRANCH=None TEST=On Agah, plug AC, observe automatic entry to EPR. Then type 'pd 1 epr exit' and observe EPR mode is not re-entered. Then replug AC and observe the port enters EPR automatically. TEST=make run-usb_pd_console Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Change-Id: Ie2b94323ba404d44ee70756e1893c065c34911fd Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4421425 Reviewed-by: Eric Yilun Lin <yllin@google.com>
-rw-r--r--common/usbc/usb_pd_console.c2
-rw-r--r--common/usbc/usb_pe_drp_sm.c16
-rw-r--r--common/usbc/usb_pe_private.h5
-rw-r--r--include/usb_pe_sm.h7
-rw-r--r--test/usb_pd_console.c10
5 files changed, 37 insertions, 3 deletions
diff --git a/common/usbc/usb_pd_console.c b/common/usbc/usb_pd_console.c
index d1c82bafda..ae6527b601 100644
--- a/common/usbc/usb_pd_console.c
+++ b/common/usbc/usb_pd_console.c
@@ -226,6 +226,8 @@ static
req = DPM_REQUEST_EPR_MODE_ENTRY;
} else if (!strcasecmp(argv[3], "exit")) {
req = DPM_REQUEST_EPR_MODE_EXIT;
+ /* Prevent snk_ready from repeatedly entering EPR. */
+ pe_snk_epr_explicit_exit(port);
} else {
return EC_ERROR_PARAM3;
}
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index 767fed302b..dba06dfbfb 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -1159,6 +1159,11 @@ bool pe_snk_in_epr_mode(int port)
return PE_CHK_FLAG(port, PE_FLAGS_IN_EPR);
}
+void pe_snk_epr_explicit_exit(int port)
+{
+ PE_SET_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT);
+}
+
bool pe_snk_can_enter_epr_mode(int port)
{
/*
@@ -3749,9 +3754,12 @@ static void pe_snk_ready_entry(int port)
*/
pe_update_wait_and_add_jitter_timer(port);
- if (IS_ENABLED(CONFIG_USB_PD_EPR) && pe_snk_in_epr_mode(port)) {
- pd_timer_enable(port, PE_TIMER_SINK_EPR_KEEP_ALIVE,
- PD_T_SINK_EPR_KEEP_ALIVE);
+ if (IS_ENABLED(CONFIG_USB_PD_EPR)) {
+ if (pe_snk_in_epr_mode(port))
+ pd_timer_enable(port, PE_TIMER_SINK_EPR_KEEP_ALIVE,
+ PD_T_SINK_EPR_KEEP_ALIVE);
+ else if (!PE_CHK_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT))
+ pd_dpm_request(port, DPM_REQUEST_EPR_MODE_ENTRY);
}
}
@@ -4138,6 +4146,7 @@ static void pe_send_soft_reset_entry(int port)
print_current_state(port);
PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR);
+ PE_CLR_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT);
/* Reset Protocol Layer (softly) */
prl_reset_soft(port);
@@ -7913,6 +7922,7 @@ static void pe_ddr_perform_data_reset_exit(int port)
static void pe_enter_epr_mode(int port)
{
PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR);
+ PE_CLR_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT);
PE_SET_FLAG(port, PE_FLAGS_IN_EPR);
CPRINTS("C%d: Entered EPR", port);
}
diff --git a/common/usbc/usb_pe_private.h b/common/usbc/usb_pe_private.h
index 5eafb7befd..b71cfced86 100644
--- a/common/usbc/usb_pe_private.h
+++ b/common/usbc/usb_pe_private.h
@@ -92,6 +92,11 @@ enum {
PE_FLAGS_ENTERING_EPR_FN,
/* In EPR mode */
PE_FLAGS_IN_EPR_FN,
+ /*
+ * Indicate the port exited EPR mode explicitly. If this is set, the
+ * port wouldn't enter EPR mode automatically.
+ */
+ PE_FLAGS_EPR_EXPLICIT_EXIT_FN,
/* Discovery disabled due to UFP/PD 2.0 constraint. */
PE_FLAGS_DISCOVERY_DISABLED_FN,
/* Last element */
diff --git a/include/usb_pe_sm.h b/include/usb_pe_sm.h
index 9672c6b26b..21cc65d43d 100644
--- a/include/usb_pe_sm.h
+++ b/include/usb_pe_sm.h
@@ -210,6 +210,13 @@ void pe_clear_port_data(int port);
bool pe_snk_in_epr_mode(int port);
/**
+ * Make a sink exit EPR mode explicitly.
+ *
+ * @param port USB-C port number
+ */
+void pe_snk_epr_explicit_exit(int port);
+
+/**
* Checks whether the port is ready for EPR entry.
*
* @param port USB-C port number
diff --git a/test/usb_pd_console.c b/test/usb_pd_console.c
index a835a643f8..119fe7131d 100644
--- a/test/usb_pd_console.c
+++ b/test/usb_pd_console.c
@@ -35,6 +35,7 @@ static bool pe_get_current_state_called;
static bool pe_get_flags_called;
static bool pe_is_explicit_contract_called;
static bool pe_snk_in_epr_mode_called;
+static bool pe_snk_epr_explicit_exit_called;
static bool pd_get_dual_role_called;
static bool board_get_usb_pd_port_count_called;
static bool pd_srccaps_dump_called;
@@ -86,6 +87,11 @@ bool pe_snk_in_epr_mode(int port)
return true;
}
+void pe_snk_epr_explicit_exit(int port)
+{
+ pe_snk_epr_explicit_exit_called = true;
+}
+
const char *pe_get_current_state(int port)
{
pe_get_current_state_called = true;
@@ -726,18 +732,22 @@ static int test_command_pd_epr(void)
request = 0;
pd_get_power_role_called = false;
pd_get_power_role_return = PD_ROLE_SINK;
+ pe_snk_epr_explicit_exit_called = false;
TEST_ASSERT(command_pd(argc, argv) == EC_SUCCESS);
TEST_ASSERT(pd_get_power_role_called);
TEST_ASSERT(request == DPM_REQUEST_EPR_MODE_ENTRY);
+ TEST_ASSERT(!pe_snk_epr_explicit_exit_called);
/* Return SUCCESS with request==DPM_REQUEST_EPR_MODE_EXIT. */
argv[3] = "exit";
request = 0;
pd_get_power_role_called = false;
pd_get_power_role_return = PD_ROLE_SINK;
+ pe_snk_epr_explicit_exit_called = false;
TEST_ASSERT(command_pd(argc, argv) == EC_SUCCESS);
TEST_ASSERT(pd_get_power_role_called);
TEST_ASSERT(request == DPM_REQUEST_EPR_MODE_EXIT);
+ TEST_ASSERT(pe_snk_epr_explicit_exit_called);
/* Return EC_ERROR_PARAM3 for invalid sub-command. */
argv[3] = "start";