From 5b879a8f583e73e7fb4ef555a0779598e93eda3d Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 29 Dec 2025 21:58:28 +0800 Subject: [PATCH 1/3] 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 From aaeec3228de31ff4a81e02bca1c3795666f7c155 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 9 Jan 2026 17:58:51 +0800 Subject: [PATCH 2/3] fix(bootloader): fix bootloader bad spi pin drv config and clear all wpu/wpd by default --- .../src/bootloader_flash_config_esp32p4.c | 28 +++--- .../esp32p4/include/hal/mspi_ll.h | 98 ++++++++++++++++++- .../hw_ver1/soc/iomux_mspi_pin_struct.h | 45 +++++++-- .../hw_ver3/soc/iomux_mspi_pin_struct.h | 45 +++++++-- 4 files changed, 188 insertions(+), 28 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c index b4cd6f98c0..a176d2aeb3 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,7 @@ #include "hal/cache_hal.h" #include "hal/cache_ll.h" #include "esp_private/bootloader_flash_internal.h" +#include "hal/mspi_iomux_ll.h" void IRAM_ATTR bootloader_flash_update_id(void) { @@ -77,18 +78,19 @@ ESP_LOG_ATTR_TAG(TAG, "boot.esp32p4"); void IRAM_ATTR bootloader_configure_spi_pins(int drv) { - uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK; - uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO; - uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI; - uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0; - uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD; - uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP; - esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); - esp_rom_gpio_pad_set_drv(q_gpio_num, drv); - esp_rom_gpio_pad_set_drv(d_gpio_num, drv); - esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); - esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); - esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); + // Configure all Flash pins: clear pull-up/pull-down, set drive strength + // SPI CS is external pull-uped so there no need to set internal pull-up + mspi_iomux_flash_pin_cfg_t flash_cfg = { + .hys = 0, + .ie = 0, + .wpu = 0, + .wpd = 0, + .drv = drv, + .reserved = 0 + }; + for (mspi_iomux_flash_pin_id_t pin_id = MSPI_IOMUX_FLASH_PIN_ID_CS; pin_id < MSPI_IOMUX_FLASH_PIN_ID_MAX; pin_id++) { + mspi_iomux_ll_set_flash_pin_cfg(pin_id, &flash_cfg); + } } static void update_flash_config(const esp_image_header_t *bootloader_hdr) diff --git a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h index 7d5a5d0c74..3dee57e309 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,6 +38,8 @@ #include "soc/clk_tree_defs.h" #include "soc/spi_mem_struct.h" #include "soc/spi_mem_s_struct.h" +#include "hal/config.h" +#include "soc/lp_system_struct.h" #ifdef __cplusplus extern "C" { @@ -724,6 +726,100 @@ static inline void mspi_ll_psram_enable_axi_access(uint8_t spi_num, bool enable) SPIMEM2.mem_cache_fctrl.close_axi_inf_en = !enable; } +/*--------------------------------------------------------------- + MSPI IOMUX pin configuration +---------------------------------------------------------------*/ +/** + * @brief MSPI IOMUX pin ID enumeration for Flash pins + * ID ranges: + * 0-5: Flash pins (CS, Q, WP, HOLD, CK, D) - maps to flash_pin_regs[] array index + */ +typedef enum { + MSPI_LL_PIN_ID_FLASH_CS = 0, /**< Flash CS pin */ + MSPI_LL_PIN_ID_FLASH_Q, /**< Flash Q pin */ + MSPI_LL_PIN_ID_FLASH_WP, /**< Flash WP pin */ + MSPI_LL_PIN_ID_FLASH_HOLD, /**< Flash HOLD pin */ + MSPI_LL_PIN_ID_FLASH_CK, /**< Flash CLK pin */ + MSPI_LL_PIN_ID_FLASH_D, /**< Flash D pin */ +} mspi_ll_flash_pin_id_t; + +/** + * @brief MSPI IOMUX Flash pin configuration structure + * Register layout: hys(0), ie(1), wpu(2), wpd(3), drv(5:4) + */ +typedef union { + struct { + uint32_t hys: 1; /**< Hysteresis enable */ + uint32_t ie: 1; /**< Input enable */ + uint32_t wpu: 1; /**< Weak pull-up enable */ + uint32_t wpd: 1; /**< Weak pull-down enable */ + uint32_t drv: 2; /**< Drive strength (0-3) */ + uint32_t reserved: 26; /**< Reserved bits */ + }; + uint32_t val; /**< Raw register value for atomic write */ +} mspi_ll_flash_pin_cfg_t; + +/** + * @brief Set configuration for Flash pin + * + * @param pin_id Pin ID (MSPI_LL_PIN_ID_FLASH_CS to MSPI_LL_PIN_ID_FLASH_D, i.e., 0-5) + * @param cfg Pin configuration structure + */ +__attribute__((always_inline)) +static inline void mspi_ll_set_flash_pin_cfg(mspi_ll_flash_pin_id_t pin_id, const mspi_ll_flash_pin_cfg_t *cfg) +{ + HAL_ASSERT(pin_id <= MSPI_LL_PIN_ID_FLASH_D); + MSPI_IOMUX.flash_pin_regs[pin_id].val = cfg->val; +} + +/** + * @brief Hold all Flash pins + * Sets all Flash pins (CS, Q, WP, HOLD, CK, D) to hold status + */ +__attribute__((always_inline)) +static inline void mspi_ll_hold_all_flash_pins(void) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 // Only rev3+ chips support mspi pad holding. + LP_SYS.ded_pad_rtc_hold_ctrl.ded_pad_rtc_hold_ctrl |= 0x3F; +#endif +} + +/** + * @brief Unhold all Flash pins + * Releases hold status for all Flash pins (CS, Q, WP, HOLD, CK, D) + */ +__attribute__((always_inline)) +static inline void mspi_ll_unhold_all_flash_pins(void) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 // Only rev3+ chips support mspi pad holding. + LP_SYS.ded_pad_rtc_hold_ctrl.ded_pad_rtc_hold_ctrl &= ~0x3F; +#endif +} + +/** + * @brief Hold all PSRAM pins + * Sets all PSRAM pins (pin_group0, dqs0, pin_group1, dqs1) to hold status + */ +__attribute__((always_inline)) +static inline void mspi_ll_hold_all_psram_pins(void) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 // Only rev3+ chips support mspi pad holding. + LP_SYS.ded_pad_rtc_hold_ctrl.ded_pad_rtc_hold_ctrl |= 0x3FFFFC0; +#endif +} + +/** + * @brief Unhold all PSRAM pins + * Releases hold status for all PSRAM pins (pin_group0, dqs0, pin_group1, dqs1) + */ +__attribute__((always_inline)) +static inline void mspi_ll_unhold_all_psram_pins(void) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 // Only rev3+ chips support mspi pad holding. + LP_SYS.ded_pad_rtc_hold_ctrl.ded_pad_rtc_hold_ctrl &= ~0x3FFFFC0; +#endif +} + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32p4/register/hw_ver1/soc/iomux_mspi_pin_struct.h b/components/soc/esp32p4/register/hw_ver1/soc/iomux_mspi_pin_struct.h index f6f8e7e779..e9793d710e 100644 --- a/components/soc/esp32p4/register/hw_ver1/soc/iomux_mspi_pin_struct.h +++ b/components/soc/esp32p4/register/hw_ver1/soc/iomux_mspi_pin_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -311,14 +311,45 @@ typedef struct { volatile iomux_mspi_pin_psram_dqs_pin_reg_t dqs1; } iomux_mspi_pin_psram_pin_grp_reg_t; +/** + * @brief Union type for Flash MSPI IOMUX pin registers + * All Flash register types share the same size (uint32_t) and have a 'val' member for atomic access + */ +typedef union { + iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs; + iomux_mspi_pin_flash_q_pin0_reg_t flash_q; + iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp; + iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold; + iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck; + iomux_mspi_pin_flash_d_pin0_reg_t flash_d; + uint32_t val; +} iomux_mspi_pin_reg_union_t; + typedef struct { volatile iomux_mspi_pin_clk_en0_reg_t clk_en0; - volatile iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs_pin0; - volatile iomux_mspi_pin_flash_q_pin0_reg_t flash_q_pin0; - volatile iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp_pin0; - volatile iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold_pin0; - volatile iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck_pin0; - volatile iomux_mspi_pin_flash_d_pin0_reg_t flash_d_pin0; + union { + struct { + volatile iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs_pin0; + volatile iomux_mspi_pin_flash_q_pin0_reg_t flash_q_pin0; + volatile iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp_pin0; + volatile iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold_pin0; + volatile iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck_pin0; + volatile iomux_mspi_pin_flash_d_pin0_reg_t flash_d_pin0; + }; + /** + * @brief Flash pin register array for direct access by pin ID + * Array layout matches Flash pins in mspi_iomux_pin_t enumeration: + * [0]: Flash CS pin + * [1]: Flash Q pin + * [2]: Flash WP pin + * [3]: Flash HOLD pin + * [4]: Flash CK pin + * [5]: Flash D pin + */ + struct { + volatile iomux_mspi_pin_reg_union_t flash_pin_regs[6]; + }; + }; volatile iomux_mspi_pin_psram_pin_grp_reg_t psram_pin_group; } iomux_mspi_pin_dev_t; diff --git a/components/soc/esp32p4/register/hw_ver3/soc/iomux_mspi_pin_struct.h b/components/soc/esp32p4/register/hw_ver3/soc/iomux_mspi_pin_struct.h index f6f8e7e779..e9793d710e 100644 --- a/components/soc/esp32p4/register/hw_ver3/soc/iomux_mspi_pin_struct.h +++ b/components/soc/esp32p4/register/hw_ver3/soc/iomux_mspi_pin_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -311,14 +311,45 @@ typedef struct { volatile iomux_mspi_pin_psram_dqs_pin_reg_t dqs1; } iomux_mspi_pin_psram_pin_grp_reg_t; +/** + * @brief Union type for Flash MSPI IOMUX pin registers + * All Flash register types share the same size (uint32_t) and have a 'val' member for atomic access + */ +typedef union { + iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs; + iomux_mspi_pin_flash_q_pin0_reg_t flash_q; + iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp; + iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold; + iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck; + iomux_mspi_pin_flash_d_pin0_reg_t flash_d; + uint32_t val; +} iomux_mspi_pin_reg_union_t; + typedef struct { volatile iomux_mspi_pin_clk_en0_reg_t clk_en0; - volatile iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs_pin0; - volatile iomux_mspi_pin_flash_q_pin0_reg_t flash_q_pin0; - volatile iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp_pin0; - volatile iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold_pin0; - volatile iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck_pin0; - volatile iomux_mspi_pin_flash_d_pin0_reg_t flash_d_pin0; + union { + struct { + volatile iomux_mspi_pin_flash_cs_pin0_reg_t flash_cs_pin0; + volatile iomux_mspi_pin_flash_q_pin0_reg_t flash_q_pin0; + volatile iomux_mspi_pin_flash_wp_pin0_reg_t flash_wp_pin0; + volatile iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold_pin0; + volatile iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck_pin0; + volatile iomux_mspi_pin_flash_d_pin0_reg_t flash_d_pin0; + }; + /** + * @brief Flash pin register array for direct access by pin ID + * Array layout matches Flash pins in mspi_iomux_pin_t enumeration: + * [0]: Flash CS pin + * [1]: Flash Q pin + * [2]: Flash WP pin + * [3]: Flash HOLD pin + * [4]: Flash CK pin + * [5]: Flash D pin + */ + struct { + volatile iomux_mspi_pin_reg_union_t flash_pin_regs[6]; + }; + }; volatile iomux_mspi_pin_psram_pin_grp_reg_t psram_pin_group; } iomux_mspi_pin_dev_t; From cf3c8cb77c31b45cc1c1cffc0e3e80c97e90236d Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 14 Jan 2026 19:04:41 +0800 Subject: [PATCH 3/3] feat(esp_hw_support): hold MSPI pins in pd_top lightsleep --- .../src/bootloader_flash_config_esp32p4.c | 7 +++---- components/esp_hw_support/port/esp32p4/pmu_sleep.c | 4 +++- components/esp_hw_support/sleep_modes.c | 12 ++++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c index a176d2aeb3..0eb51fd271 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c @@ -24,7 +24,6 @@ #include "hal/cache_hal.h" #include "hal/cache_ll.h" #include "esp_private/bootloader_flash_internal.h" -#include "hal/mspi_iomux_ll.h" void IRAM_ATTR bootloader_flash_update_id(void) { @@ -80,7 +79,7 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv) { // Configure all Flash pins: clear pull-up/pull-down, set drive strength // SPI CS is external pull-uped so there no need to set internal pull-up - mspi_iomux_flash_pin_cfg_t flash_cfg = { + mspi_ll_flash_pin_cfg_t flash_cfg = { .hys = 0, .ie = 0, .wpu = 0, @@ -88,8 +87,8 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv) .drv = drv, .reserved = 0 }; - for (mspi_iomux_flash_pin_id_t pin_id = MSPI_IOMUX_FLASH_PIN_ID_CS; pin_id < MSPI_IOMUX_FLASH_PIN_ID_MAX; pin_id++) { - mspi_iomux_ll_set_flash_pin_cfg(pin_id, &flash_cfg); + for (mspi_ll_flash_pin_id_t pin_id = MSPI_LL_PIN_ID_FLASH_CS; pin_id <= MSPI_LL_PIN_ID_FLASH_D; pin_id++) { + mspi_ll_set_flash_pin_cfg(pin_id, &flash_cfg); } } diff --git a/components/esp_hw_support/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index 9357437a4e..ddf451f4e8 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -38,12 +38,12 @@ #include "hal/efuse_hal.h" #if CONFIG_SPIRAM #include "hal/ldo_ll.h" +#include "hal/mspi_ll.h" #endif #if (CONFIG_ESP_REV_MIN_FULL == 300) #include "soc/hp_system_reg.h" #include "hal/mmu_ll.h" -#include "hal/mspi_ll.h" #endif #define HP(state) (PMU_MODE_HP_ ## state) @@ -426,6 +426,7 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, _psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, false); _psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, false); } + mspi_ll_hold_all_psram_pins(); #endif rtc_clk_mpll_disable(); } @@ -504,6 +505,7 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp) } _psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_MPLL); _psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_MPLL); + mspi_ll_unhold_all_psram_pins(); #endif } diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index e5afada515..32e747a26c 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -136,6 +136,10 @@ #include "hal/clk_gate_ll.h" #endif +#if SOC_MSPI_HAS_INDEPENT_IOMUX +#include "hal/mspi_ll.h" +#endif + #if SOC_PM_SUPPORT_PMU_CLK_ICG #include "soc/pmu_icg_mapping.h" #endif @@ -907,6 +911,9 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode. In order to avoid the leakage of the SPI cs pin, hold it here */ if(sleep_flags & PMU_SLEEP_PD_TOP) { +#if SOC_MSPI_HAS_INDEPENT_IOMUX + mspi_ll_hold_all_flash_pins(); +#else // !SOC_MSPI_HAS_INDEPENT_IOMUX #if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND /* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */ gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS0); @@ -915,6 +922,7 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint /* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */ gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS1); #endif +#endif // !SOC_MSPI_HAS_INDEPENT_IOMUX } #endif } @@ -961,12 +969,16 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP /* Unhold the SPI CS pin */ if(!(sleep_flags & RTC_SLEEP_PD_VDDSDIO) && (sleep_flags & PMU_SLEEP_PD_TOP)) { +#if SOC_MSPI_HAS_INDEPENT_IOMUX + mspi_ll_unhold_all_flash_pins(); +#else // !SOC_MSPI_HAS_INDEPENT_IOMUX #if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND gpio_ll_hold_dis(&GPIO, MSPI_IOMUX_PIN_NUM_CS0); #endif #if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM gpio_ll_hold_dis(&GPIO, MSPI_IOMUX_PIN_NUM_CS1); #endif +#endif // !SOC_MSPI_HAS_INDEPENT_IOMUX } #endif /* Cache Resume 1: Resume cache for continue running*/