From 5b879a8f583e73e7fb4ef555a0779598e93eda3d Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 29 Dec 2025 21:58:28 +0800 Subject: [PATCH] feat(esp_hw_support): set USB2.0 phy to suspend mode at startup for active power saving --- .../esp32p4/include/hal/clk_gate_ll.h | 15 +++++++++++---- components/esp_hal_usb/usb_dwc_hal.c | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/components/esp_hal_clock/esp32p4/include/hal/clk_gate_ll.h b/components/esp_hal_clock/esp32p4/include/hal/clk_gate_ll.h index ba85360765..3e5d68f2bb 100644 --- a/components/esp_hal_clock/esp32p4/include/hal/clk_gate_ll.h +++ b/components/esp_hal_clock/esp32p4/include/hal/clk_gate_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,6 +27,7 @@ #include "soc/lp_gpio_reg.h" #include "soc/lpperi_reg.h" #include "soc/uart_reg.h" +#include "soc/usb_dwc_struct.h" #ifdef __cplusplus extern "C" { @@ -307,17 +308,23 @@ static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason, HP_SYS_CLKRST_REG_CRYPTO_RSA_CLK_EN | HP_SYS_CLKRST_REG_CRYPTO_SHA_CLK_EN); - // USB1.1 + /*** USB sys & phy & pad & clock initialization for power saving ***/ + // Force the USB 2.0 PHY to enter suspend mode before disabling the clock. + REG_SET_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_USB_OTG20_SYS_CLK_EN); + REG_SET_BIT(LP_CLKRST_HP_USB_CLKRST_CTRL1_REG, LP_CLKRST_USB_OTG20_PHYREF_CLK_EN); + USB_DWC_HS.gotgctl_reg.bvalidoven = 1; + USB_DWC_HS.pcgcctl_reg.stoppclk = 1; + // USB1.1 & USB OTG2.0 sys clock gating REG_CLR_BIT(LP_CLKRST_HP_USB_CLKRST_CTRL0_REG, LP_CLKRST_USB_OTG11_BK_SYS_CLK_EN | LP_CLKRST_USB_OTG11_48M_CLK_EN | LP_CLKRST_USB_OTG20_BK_SYS_CLK_EN); REG_CLR_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_USB_OTG11_SYS_CLK_EN | HP_SYS_CLKRST_REG_USB_OTG20_SYS_CLK_EN | HP_SYS_CLKRST_REG_UHCI_SYS_CLK_EN); - // USB2.0 + // USB2.0 phy & ULPI clock gating REG_CLR_BIT(LP_CLKRST_HP_USB_CLKRST_CTRL1_REG, LP_CLKRST_USB_OTG20_PHYREF_CLK_EN | LP_CLKRST_USB_OTG20_ULPI_CLK_EN); - // UHCI + // UHCI clock gating REG_CLR_BIT(HP_SYS_CLKRST_SOC_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_UHCI_APB_CLK_EN); if (config->disable_usb_serial_jtag) { diff --git a/components/esp_hal_usb/usb_dwc_hal.c b/components/esp_hal_usb/usb_dwc_hal.c index 51fabde0d6..64ac930483 100644 --- a/components/esp_hal_usb/usb_dwc_hal.c +++ b/components/esp_hal_usb/usb_dwc_hal.c @@ -109,6 +109,21 @@ static void set_defaults(usb_dwc_hal_context_t *hal) hbstlen = 1; //Set AHB burst to INCR to workaround hardware errata } #endif // SOC_IS(ESP32S2) +#if SOC_IS(ESP32P4) + /* + * ESP32P4-specific initialization: Clear USB PHY suspend state set during system boot. + * + * During system initialization (see clk_gate_ll.h:periph_ll_clk_gate_set_default), the USB PHY + * is forced into suspend mode before disabling clocks to prevent USB leakage current and ensure + * proper power management. + * + * When initializing the USB DWC HAL, we need to restore the USB PHY to normal operation by: + * 1. Clearing GOTGCTL.BvalidOvEn (disable override, allow hardware to detect session validity) + * 2. Clearing PCGCCTL.StopPclk (resume PHY clock for normal operation) + */ + usb_dwc_ll_enable_bvalid_override(hal->dev, false); + usb_dwc_ll_set_stoppclk(hal->dev, false); +#endif // SOC_IS(ESP32P4) usb_dwc_ll_gahbcfg_set_hbstlen(hal->dev, hbstlen); //Set AHB burst mode //GUSBCFG register usb_dwc_ll_gusbcfg_dis_hnp_cap(hal->dev); //Disable HNP