summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew McRae <amcrae@google.com>2022-09-15 13:54:58 +1000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-10-06 23:06:09 +0000
commit29de97bc3b0a822eb80ddbdf5b6908544925b106 (patch)
tree4af8baae04f6fbf057754720326b914c61048d59
parent2edcba5b5ea17c3c3ffa2e0334ab28644d6345dc (diff)
downloadchrome-ec-29de97bc3b0a822eb80ddbdf5b6908544925b106.tar.gz
typec: Clear stale hard reset event when ready
When entering PE_SNK_Ready or PE_SRC_Ready, clear the PD_STATUS_EVENT_HARD_RESET flag so that the kernel does not receive stale events (which can disable the USB port). The hard reset can be triggered if the EC cannot distinguish between a reset and a power-on reboot (such as occurs with the IT81302), and so is flagged as a power-on. A power-on reset flag will reset the PD connection. The hard reset PD status event flag is set, and then PD negotiation may proceed and complete. Eventually the kernel starts, and will read the PD status, and see the (now stale) hard reset event flag, and take action to disable the USB port. BUG=b:231401624 TEST=zmake build nereid; Enter recovery via keyboard BRANCH=none Signed-off-by: Andrew McRae <amcrae@google.com> Change-Id: Icc179d19e0a0b6fce215021e464516471cdd47cd Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3897917 Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com> Reviewed-by: Diana Z <dzigterman@chromium.org>
-rw-r--r--common/usbc/usb_pe_drp_sm.c8
-rw-r--r--zephyr/Kconfig.usbc23
-rw-r--r--zephyr/shim/include/config_chip.h5
-rw-r--r--zephyr/test/drivers/prj.conf1
-rw-r--r--zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c2
5 files changed, 39 insertions, 0 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index 365eb5aa1a..2e3bffbf68 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -2732,6 +2732,10 @@ static void pe_src_ready_entry(int port)
/* Ensure any message send flags are cleaned up */
PE_CLR_MASK(port, PE_MASK_READY_CLR);
+ /* If configured, clear any stale hard reset events */
+ if (IS_ENABLED(CONFIG_USB_PD_CLEAR_HARD_RESET_STATUS))
+ pd_clear_events(port, PD_STATUS_EVENT_HARD_RESET);
+
/* Clear DPM Current Request */
pe[port].dpm_curr_request = 0;
@@ -3575,6 +3579,10 @@ static void pe_snk_ready_entry(int port)
/* Ensure any message send flags are cleaned up */
PE_CLR_MASK(port, PE_MASK_READY_CLR);
+ /* If configured, clear any stale hard reset events */
+ if (IS_ENABLED(CONFIG_USB_PD_CLEAR_HARD_RESET_STATUS))
+ pd_clear_events(port, PD_STATUS_EVENT_HARD_RESET);
+
/* Clear DPM Current Request */
pe[port].dpm_curr_request = 0;
diff --git a/zephyr/Kconfig.usbc b/zephyr/Kconfig.usbc
index 37c57bcdd2..903cf575c6 100644
--- a/zephyr/Kconfig.usbc
+++ b/zephyr/Kconfig.usbc
@@ -123,6 +123,29 @@ config PLATFORM_EC_USB_PD_TCPC_VCONN
present. Some TCPC/PPC can't handle 5V on its host-side CC pins, so
disable this config in those cases.
+config PLATFORM_EC_USB_PD_CLEAR_HARD_RESET_STATUS
+ bool "Clear PD hard reset status when PD setup completes"
+ default y if SOC_SERIES_RISCV32_IT8XXX2
+ help
+ Enabling this config will clear the Hard Reset event status
+ after the PD connection is finished initialization,
+ to avoid the AP getting a stale event notification.
+
+ The detection of a PD Hard Reset sets an status flag that
+ is then read by the AP in order to reset the USB muxes.
+ However by the time this is read, the connection may
+ have been re-initialized and is ready, but the AP may
+ process the hard reset as if it were still current,
+ causing the USB port to be incorrectly disabled.
+ The hard reset of the PD connection can be triggered
+ when the EC is detected as being initially powered on
+ (as opposed to being reset), to force clearing the connection.
+
+ This config is set by default for the IT8XXX2 EC, which
+ cannot distinguish between a reset and power-on, so a power-on
+ is assumed, which leads to the PD hard reset when the EC
+ undergoes a reset (such as when entering recovery mode).
+
config PLATFORM_EC_CONSOLE_CMD_PPC_DUMP
bool "Console command: ppc_dump"
depends on PLATFORM_EC_USBC_PPC
diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h
index 3e8c588643..87764a00fd 100644
--- a/zephyr/shim/include/config_chip.h
+++ b/zephyr/shim/include/config_chip.h
@@ -2637,6 +2637,11 @@ extern char mock_jump_data[sizeof(struct jump_data) + 256];
#define CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY
#endif
+#undef CONFIG_USB_PD_CLEAR_HARD_RESET_STATUS
+#ifdef CONFIG_PLATFORM_EC_USB_PD_CLEAR_HARD_RESET_STATUS
+#define CONFIG_USB_PD_CLEAR_HARD_RESET_STATUS
+#endif
+
#undef CONFIG_DEDICATED_CHARGE_PORT_COUNT
#ifdef CONFIG_PLATFORM_EC_DEDICATED_CHARGE_PORT
#define CONFIG_DEDICATED_CHARGE_PORT_COUNT 1
diff --git a/zephyr/test/drivers/prj.conf b/zephyr/test/drivers/prj.conf
index c212b11bb7..a106c568dd 100644
--- a/zephyr/test/drivers/prj.conf
+++ b/zephyr/test/drivers/prj.conf
@@ -122,6 +122,7 @@ CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8815_FORCE_DID=y
CONFIG_PLATFORM_EC_USB_PD_TCPM_MULTI_PS8XXX=y
CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_TCPC=y
CONFIG_PLATFORM_EC_USB_PD_REQUIRE_AP_MODE_ENTRY=y
+CONFIG_PLATFORM_EC_USB_PD_CLEAR_HARD_RESET_STATUS=y
CONFIG_PLATFORM_EC_CONSOLE_CMD_WAITMS=y
CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y
CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK=y
diff --git a/zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c b/zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c
index 38ce979594..977d8cceb2 100644
--- a/zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c
+++ b/zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c
@@ -234,6 +234,8 @@ ZTEST_F(usb_malfunction_sink, test_hard_reset_disconnect)
zassert_equal(typec_status.vconn_role, PD_ROLE_VCONN_OFF,
"Vconn should be disabled at power sequence (%d)",
try_count);
+ zassert_true(typec_status.events & PD_STATUS_EVENT_HARD_RESET,
+ "Hard reset status should be set (%d)", try_count);
/* Disconnect partner at the middle of power sequence */
disconnect_sink_from_port(fixture->tcpci_emul);