From 9e20a2b27fc108f2f35b0dd129e40fa0ac8d36a6 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 3 Sep 2026 19:59:27 +0800 Subject: [PATCH 1/2] fix(pm): dslp will also isolate reserved dig pads to reduce leakage on S31 --- .../include/esp_private/esp_sleep_internal.h | 10 +++++----- components/esp_hw_support/sleep_gpio.c | 14 ++++++++------ components/esp_hw_support/sleep_modes.c | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/esp_sleep_internal.h b/components/esp_hw_support/include/esp_private/esp_sleep_internal.h index 0736cba5231..4529854faff 100644 --- a/components/esp_hw_support/include/esp_private/esp_sleep_internal.h +++ b/components/esp_hw_support/include/esp_private/esp_sleep_internal.h @@ -109,14 +109,14 @@ esp_err_t esp_sleep_release_lp_use_xtal(void); /** * @brief Soft-isolate valid digital IO pads (SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK) for leakage control * - * Skips pads that are digitally held and pads reserved by the driver. + * Skips pads that are digitally held and pads reserved by the driver (only for light sleep). * MSPI signal pads are not in this pass; use esp_sleep_isolate_mspi_gpio() after cache/MSPI idle. * - * @param do_backup If true, back up each pad's pu/pd/ie/oe/fun_sel before isolating so that - * esp_sleep_restore_isolated_digital_gpio() can restore them later. - * Pass false when restore is not needed (e.g. deep sleep). + * @param dslp If false, back up each pad's pu/pd/ie/oe/fun_sel before isolating so that + * esp_sleep_restore_isolated_digital_gpio() can restore them later after wakeup. + * Pass true indicating that backup/restore is not needed, just isolate the pads (i.e. deep sleep). */ -void esp_sleep_isolate_digital_gpio(bool do_backup); +void esp_sleep_isolate_digital_gpio(bool dslp); /** * @brief Backup and isolate (or pull up) the five base MSPI lines (CLK/Q/D/HD/WP) diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index d67bb74a8c2..825ed888cd7 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -283,7 +283,7 @@ IRAM_ATTR void esp_sleep_restore_isolated_digital_gpio(void) } #endif // SOC_GPIO_NEED_SOFT_ISOLATE_DURING_PD -IRAM_ATTR void esp_sleep_isolate_digital_gpio(bool do_backup) +IRAM_ATTR void esp_sleep_isolate_digital_gpio(bool dslp) { gpio_hal_context_t gpio_hal = { .dev = GPIO_HAL_GET_HW(GPIO_PORT_0) }; #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP @@ -306,7 +306,7 @@ IRAM_ATTR void esp_sleep_isolate_digital_gpio(bool do_backup) DRAM_ATTR static volatile uint64_t s_pad_mask = SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK; uint64_t pad_mask = s_pad_mask; #if SOC_GPIO_NEED_SOFT_ISOLATE_DURING_PD - if (do_backup) { + if (!dslp) { s_gpio_isolate_backup.backuped = 0; s_gpio_isolate_backup.pu = 0; s_gpio_isolate_backup.pd = 0; @@ -320,8 +320,10 @@ IRAM_ATTR void esp_sleep_isolate_digital_gpio(bool do_backup) while (pad_mask) { gpio_num_t gpio_num = (gpio_num_t)__builtin_ctzll(pad_mask); if (!(hold_mask & (1ULL << gpio_num)) && - !esp_gpio_is_reserved(BIT64(gpio_num))) { - if (do_backup) { + // for light sleep, we will skip the reserved GPIOs + // for deep sleep, since it does not return and reset the entire digital domain, it should be fine to isolate all digital IOs to minimize the leakage + (dslp || !esp_gpio_is_reserved(BIT64(gpio_num)))) { + if (!dslp) { gpio_io_config_t io_config; gpio_ll_backup_pad_config_for_sleep_isolate(gpio_num, &io_config); if (io_config.pu) { @@ -343,8 +345,8 @@ IRAM_ATTR void esp_sleep_isolate_digital_gpio(bool do_backup) } pad_mask &= pad_mask - 1; } -#else - (void)do_backup; +#else // !SOC_GPIO_NEED_SOFT_ISOLATE_DURING_PD + (void)dslp; while (pad_mask) { gpio_num_t gpio_num = (gpio_num_t)__builtin_ctzll(pad_mask); if (!gpio_hal_is_digital_io_hold(&gpio_hal, gpio_num) && diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 1568bd73024..17379f5fe57 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -873,7 +873,7 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint #endif if (deep_sleep) { #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP || SOC_GPIO_NEED_SOFT_ISOLATE_DURING_PD - esp_sleep_isolate_digital_gpio(false); + esp_sleep_isolate_digital_gpio(true); #endif #if CONFIG_IDF_TARGET_ESP32P4 && CONFIG_ESP_SLEEP_SET_FLASH_DPD @@ -915,7 +915,7 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint } else { #if SOC_GPIO_NEED_SOFT_ISOLATE_DURING_PD if (sleep_flags & RTC_SLEEP_PD_DIG) { - esp_sleep_isolate_digital_gpio(true); + esp_sleep_isolate_digital_gpio(false); } #endif /* Cache Suspend 1: will wait cache idle in cache suspend */ From 34c39159387235e827190dc18a74b7dbfb5aee4b Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 3 Sep 2026 21:17:08 +0800 Subject: [PATCH 2/2] fix(sdmmc): corrected the control of dedicated sdmmc pads - only slot1 takes dedicated pads - remove slot1 should clear the control of dedicated pads - fix the current leakage in deep sleep caused by the sdmmc pads --- .../esp_driver_sdmmc/src/sd_host_sdmmc.c | 12 +++-- .../esp32c61/include/hal/clk_gate_ll.h | 19 ++++++++ .../esp_hal_gpio/esp32/include/hal/gpio_ll.h | 9 ++++ .../esp32c2/include/hal/gpio_ll.h | 9 ++++ .../esp32c3/include/hal/gpio_ll.h | 9 ++++ .../esp32c5/include/hal/gpio_ll.h | 9 ++++ .../esp32c6/include/hal/gpio_ll.h | 9 ++++ .../esp32c61/include/hal/gpio_ll.h | 9 ++++ .../esp32h2/include/hal/gpio_ll.h | 9 ++++ .../esp32h21/include/hal/gpio_ll.h | 9 ++++ .../esp32h4/include/hal/gpio_ll.h | 9 ++++ .../esp32p4/include/hal/gpio_ll.h | 9 ++++ .../esp32s2/include/hal/gpio_ll.h | 9 ++++ .../esp32s3/include/hal/gpio_ll.h | 9 ++++ .../esp32s31/include/hal/gpio_ll.h | 12 +++++ .../esp_hal_sd/esp32/include/hal/sdmmc_ll.h | 4 +- .../esp_hal_sd/esp32p4/include/hal/sdmmc_ll.h | 4 +- .../esp_hal_sd/esp32s3/include/hal/sdmmc_ll.h | 4 +- .../esp32s31/include/hal/sdmmc_ll.h | 12 +++-- .../include/esp_private/sleep_gpio.h | 11 +++++ components/esp_hw_support/sleep_gpio.c | 2 +- components/esp_hw_support/sleep_modes.c | 47 ++----------------- 22 files changed, 182 insertions(+), 53 deletions(-) create mode 100644 components/esp_hal_clock/esp32c61/include/hal/clk_gate_ll.h diff --git a/components/esp_driver_sdmmc/src/sd_host_sdmmc.c b/components/esp_driver_sdmmc/src/sd_host_sdmmc.c index 8429f300be9..dfb4825518a 100644 --- a/components/esp_driver_sdmmc/src/sd_host_sdmmc.c +++ b/components/esp_driver_sdmmc/src/sd_host_sdmmc.c @@ -108,9 +108,6 @@ esp_err_t sd_host_create_sdmmc_controller(const sd_host_sdmmc_cfg_t *config, sd_ #endif //CONFIG_PM_ENABLE sdmmc_hal_init(&ctlr->hal); - PERIPH_RCC_ATOMIC() { - sdmmc_ll_pad_set_pin_dedicated_ctrl(ctlr->hal.dev, true); - } ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src(SDMMC_CLK_SRC_DEFAULT, true), err, TAG, "failed to acquire clk"); uint32_t src_freq_hz = 0; esp_clk_tree_src_get_freq_hz(SDMMC_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_freq_hz); @@ -398,6 +395,11 @@ static esp_err_t sd_host_controller_remove_sdmmc_slot(sd_host_slot_handle_t slot gpio_output_disable(slot_ctx->io_config.d7_io); } + // release the pads so that they can be used as normal GPIOs + PERIPH_RCC_ATOMIC() { + sdmmc_ll_pad_set_pin_dedicated_ctrl(ctlr->hal.dev, slot_ctx->slot_id, false); + } + xSemaphoreGive(ctlr->mutex); free(slot); @@ -1394,6 +1396,10 @@ static esp_err_t sdmmc_slot_io_config(sd_host_sdmmc_slot_t *slot, const sd_host_ GPIO_NUM_CHECK(slot_gpio->d7_io); } + PERIPH_RCC_ATOMIC() { + sdmmc_ll_pad_set_pin_dedicated_ctrl(slot->ctlr->hal.dev, slot_id, true); + } + configure_pin(slot_gpio->clk_io, sdmmc_slot_gpio_sig[slot_id].clk, GPIO_MODE_OUTPUT, "clk", use_gpio_matrix); configure_pin(slot_gpio->cmd_io, sdmmc_slot_gpio_sig[slot_id].cmd, GPIO_MODE_INPUT_OUTPUT, "cmd", use_gpio_matrix); configure_pin(slot_gpio->d0_io, sdmmc_slot_gpio_sig[slot_id].d0, GPIO_MODE_INPUT_OUTPUT, "d0", use_gpio_matrix); diff --git a/components/esp_hal_clock/esp32c61/include/hal/clk_gate_ll.h b/components/esp_hal_clock/esp32c61/include/hal/clk_gate_ll.h new file mode 100644 index 00000000000..3ed987f8346 --- /dev/null +++ b/components/esp_hal_clock/esp32c61/include/hal/clk_gate_ll.h @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_gpio/esp32/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32/include/hal/gpio_ll.h index 19c64d9433d..d89e0a0d944 100644 --- a/components/esp_hal_gpio/esp32/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32/include/hal/gpio_ll.h @@ -762,6 +762,15 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3 hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv; } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32c2/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32c2/include/hal/gpio_ll.h index a7a77719287..980599f575d 100644 --- a/components/esp_hal_gpio/esp32c2/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32c2/include/hal/gpio_ll.h @@ -769,6 +769,15 @@ static inline bool gpio_ll_hp_periph_powerdown_sleep_wakeup_is_enabled(gpio_dev_ return GET_PERI_REG_MASK(RTC_CNTL_GPIO_WAKEUP_REG, 1 << (RTC_CNTL_GPIO_PIN0_WAKEUP_ENABLE_S - gpio_num)); } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32c3/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32c3/include/hal/gpio_ll.h index f12998e91d1..b78f7aa0476 100644 --- a/components/esp_hal_gpio/esp32c3/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32c3/include/hal/gpio_ll.h @@ -790,6 +790,15 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32c5/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32c5/include/hal/gpio_ll.h index c6e8a896408..c5b5dcf1e66 100644 --- a/components/esp_hal_gpio/esp32c5/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32c5/include/hal/gpio_ll.h @@ -735,6 +735,15 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num IO_MUX.gpio[gpio_num].mcu_oe = 1; } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32c6/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32c6/include/hal/gpio_ll.h index 458ce292192..047a698820f 100644 --- a/components/esp_hal_gpio/esp32c6/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32c6/include/hal/gpio_ll.h @@ -696,6 +696,15 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num PIN_SLP_OUTPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4)); } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32c61/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32c61/include/hal/gpio_ll.h index af3d35a6beb..a5fa78cec4f 100644 --- a/components/esp_hal_gpio/esp32c61/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32c61/include/hal/gpio_ll.h @@ -735,6 +735,15 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num IO_MUX.gpion[gpio_num].gpion_mcu_oe = 1; } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32h2/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32h2/include/hal/gpio_ll.h index 4e3a78afb05..a98719e0589 100644 --- a/components/esp_hal_gpio/esp32h2/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32h2/include/hal/gpio_ll.h @@ -804,6 +804,15 @@ static inline bool gpio_ll_hp_periph_powerdown_sleep_wakeup_is_enabled(gpio_dev_ return wakeup_sel_mask & BIT(gpio_num - 7); } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32h21/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32h21/include/hal/gpio_ll.h index b7e159f8832..59e0b43d79d 100644 --- a/components/esp_hal_gpio/esp32h21/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32h21/include/hal/gpio_ll.h @@ -788,6 +788,15 @@ static inline bool gpio_ll_hp_periph_powerdown_sleep_wakeup_is_enabled(gpio_dev_ return wakeup_sel_mask & BIT(gpio_num - 5); } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32h4/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32h4/include/hal/gpio_ll.h index 817b6a73f93..ca2d6b7d9e0 100644 --- a/components/esp_hal_gpio/esp32h4/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32h4/include/hal/gpio_ll.h @@ -778,6 +778,15 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num IO_MUX.gpio[gpio_num].mcu_oe = 1; } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32p4/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32p4/include/hal/gpio_ll.h index 5d9a8d3907b..636ade669d0 100644 --- a/components/esp_hal_gpio/esp32p4/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32p4/include/hal/gpio_ll.h @@ -872,6 +872,15 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num IO_MUX.gpio[gpio_num].mcu_oe = 1; } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32s2/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32s2/include/hal/gpio_ll.h index d33ffad972e..555d75b50df 100644 --- a/components/esp_hal_gpio/esp32s2/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32s2/include/hal/gpio_ll.h @@ -734,6 +734,15 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num PIN_SLP_OUTPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32s3/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32s3/include/hal/gpio_ll.h index 33d508ad564..b89ea03bcc5 100644 --- a/components/esp_hal_gpio/esp32s3/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32s3/include/hal/gpio_ll.h @@ -761,6 +761,15 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; } +/** + * @brief Clear all GPIO dedicated control signals + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + // no dedicated ctrl pad +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_gpio/esp32s31/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32s31/include/hal/gpio_ll.h index d151fa5f0ae..affc9a7a77f 100644 --- a/components/esp_hal_gpio/esp32s31/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32s31/include/hal/gpio_ll.h @@ -28,6 +28,7 @@ #include "soc/lp_system_reg.h" #include "soc/pmu_struct.h" #include "soc/usb_serial_jtag_struct.h" +#include "soc/cnnt_io_mux_struct.h" #include "soc/clk_tree_defs.h" #include "soc/interrupts.h" #include "hal/gpio_types.h" @@ -881,6 +882,17 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num IO_MUX.gpio[gpio_num].mcu_oe = 1; } +/** + * @brief Clear all GPIO dedicated control signals (e.g. sdmmc, emac) + * + * Set is done in each peripheral's own LL layer. + */ +__attribute__((always_inline)) +static inline void gpio_ll_clear_dedicated_ctrl(void) +{ + CNNT_PAD_CTRL.ctrl.val = 0; +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_sd/esp32/include/hal/sdmmc_ll.h b/components/esp_hal_sd/esp32/include/hal/sdmmc_ll.h index 495fc65c8e1..6cd184ec45e 100644 --- a/components/esp_hal_sd/esp32/include/hal/sdmmc_ll.h +++ b/components/esp_hal_sd/esp32/include/hal/sdmmc_ll.h @@ -201,11 +201,13 @@ static inline void sdmmc_ll_mem_set_low_power_mode(sdmmc_dev_t *dev, sdmmc_ll_me * @brief Set SDMMC pad pin dedicated ctrl * * @param dev Peripheral instance address + * @param slot Slot index * @param enable True to enable, False to disable */ -static inline void sdmmc_ll_pad_set_pin_dedicated_ctrl(sdmmc_dev_t *dev, bool enable) +static inline void sdmmc_ll_pad_set_pin_dedicated_ctrl(sdmmc_dev_t *dev, uint32_t slot, bool enable) { (void)dev; + (void)slot; (void)enable; } diff --git a/components/esp_hal_sd/esp32p4/include/hal/sdmmc_ll.h b/components/esp_hal_sd/esp32p4/include/hal/sdmmc_ll.h index 5f59858923c..aa89c90085f 100644 --- a/components/esp_hal_sd/esp32p4/include/hal/sdmmc_ll.h +++ b/components/esp_hal_sd/esp32p4/include/hal/sdmmc_ll.h @@ -234,11 +234,13 @@ static inline void sdmmc_ll_mem_set_low_power_mode(sdmmc_dev_t *dev, sdmmc_ll_me * @brief Set SDMMC pad pin dedicated ctrl * * @param dev Peripheral instance address + * @param slot Slot index * @param enable True to enable, False to disable */ -static inline void sdmmc_ll_pad_set_pin_dedicated_ctrl(sdmmc_dev_t *dev, bool enable) +static inline void sdmmc_ll_pad_set_pin_dedicated_ctrl(sdmmc_dev_t *dev, uint32_t slot, bool enable) { (void)dev; + (void)slot; (void)enable; } diff --git a/components/esp_hal_sd/esp32s3/include/hal/sdmmc_ll.h b/components/esp_hal_sd/esp32s3/include/hal/sdmmc_ll.h index 87e63af3aa7..2a0bc10b169 100644 --- a/components/esp_hal_sd/esp32s3/include/hal/sdmmc_ll.h +++ b/components/esp_hal_sd/esp32s3/include/hal/sdmmc_ll.h @@ -210,11 +210,13 @@ static inline void sdmmc_ll_mem_set_low_power_mode(sdmmc_dev_t *dev, sdmmc_ll_me * @brief Set SDMMC pad pin dedicated ctrl * * @param dev Peripheral instance address + * @param slot Slot index * @param enable True to enable, False to disable */ -static inline void sdmmc_ll_pad_set_pin_dedicated_ctrl(sdmmc_dev_t *dev, bool enable) +static inline void sdmmc_ll_pad_set_pin_dedicated_ctrl(sdmmc_dev_t *dev, uint32_t slot, bool enable) { (void)dev; + (void)slot; (void)enable; } diff --git a/components/esp_hal_sd/esp32s31/include/hal/sdmmc_ll.h b/components/esp_hal_sd/esp32s31/include/hal/sdmmc_ll.h index 0f7d38a1957..9b4c4fed6c9 100644 --- a/components/esp_hal_sd/esp32s31/include/hal/sdmmc_ll.h +++ b/components/esp_hal_sd/esp32s31/include/hal/sdmmc_ll.h @@ -233,14 +233,20 @@ static inline void sdmmc_ll_mem_set_low_power_mode(sdmmc_dev_t *dev, sdmmc_ll_me /** * @brief Set SDMMC pad pin dedicated ctrl * + * Enable it when the slot is in use, disable it when the slot is released, so + * that the pads can be used as normal GPIOs again. + * * @param dev Peripheral instance address + * @param slot Slot index * @param enable True to enable, False to disable */ -static inline void sdmmc_ll_pad_set_pin_dedicated_ctrl(sdmmc_dev_t *dev, bool enable) +static inline void sdmmc_ll_pad_set_pin_dedicated_ctrl(sdmmc_dev_t *dev, uint32_t slot, bool enable) { - CNNT_PAD_CTRL.ctrl.sdio_pad_pin_ctrl_ded_sel = enable; + // only slot 0 is routed to the dedicated SDIO pads, slot 1 doesn't rely on this bit + if (slot == 0) { + CNNT_PAD_CTRL.ctrl.sdio_pad_pin_ctrl_ded_sel = enable; + } } - /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance #define sdmmc_ll_pad_set_pin_dedicated_ctrl(...) do { \ diff --git a/components/esp_hw_support/include/esp_private/sleep_gpio.h b/components/esp_hw_support/include/esp_private/sleep_gpio.h index 7f292b57389..0cf969eabd8 100644 --- a/components/esp_hw_support/include/esp_private/sleep_gpio.h +++ b/components/esp_hw_support/include/esp_private/sleep_gpio.h @@ -7,6 +7,8 @@ #pragma once #include #include "sdkconfig.h" +#include "esp_attr.h" +#include "hal/gpio_ll.h" #ifdef __cplusplus extern "C" { @@ -39,6 +41,15 @@ void esp_sleep_gpio_pupd_config_workaround_apply(void); void esp_sleep_gpio_pupd_config_workaround_unapply(void); #endif // CONFIG_IDF_TARGET_ESP32 + +/** + * @brief Clear all GPIO dedicated control signals + */ +FORCE_INLINE_ATTR void esp_sleep_gpio_clear_dedicated_ctrl(void) +{ + gpio_ll_clear_dedicated_ctrl(); +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index 825ed888cd7..42af74f1523 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -116,7 +116,7 @@ void esp_sleep_gpio_pupd_config_workaround_unapply(void) } } } -#endif +#endif // CONFIG_IDF_TARGET_ESP32 #if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO void esp_sleep_config_gpio_isolate(void) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 17379f5fe57..15b2914e442 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -41,6 +41,7 @@ #include "hal/efuse_hal.h" #include "hal/rtc_io_hal.h" #include "hal/clk_tree_hal.h" +#include "rom/rtc.h" #if RNG_LL_NEEDS_RESET_WHEN_WAKEUP #include "hal/rng_ll.h" @@ -66,6 +67,7 @@ #include "soc/rtc.h" +#include "hal/clk_gate_ll.h" #include "hal/clk_tree_ll.h" #if SOC_WDT_SUPPORTED || SOC_RTC_WDT_SUPPORTED || SOC_SLEEP_TGWDT_STOP_WORKAROUND #include "hal/wdt_hal.h" @@ -80,6 +82,7 @@ #endif #include "hal/temperature_sensor_hal.h" #include "hal/mspi_ll.h" +#include "hal/gpio_ll.h" #if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE #include "hal/lp_aon_hal.h" #endif @@ -99,62 +102,19 @@ #include "esp_private/esp_task_wdt.h" #include "esp_private/sar_periph_ctrl.h" -#if SOC_PM_SUPPORT_EXT1_WAKEUP && SOC_RTCIO_PIN_COUNT > 0 #include "esp_private/sleep_gpio.h" -#endif #ifdef CONFIG_IDF_TARGET_ESP32 -#include "esp32/rom/rtc.h" #include "esp_private/gpio.h" #elif CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/rom/rtc.h" #include "soc/extmem_reg.h" #include "esp_private/gpio.h" -#elif CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/rom/rtc.h" -#elif CONFIG_IDF_TARGET_ESP32C3 -#include "esp32c3/rom/rtc.h" -#elif CONFIG_IDF_TARGET_ESP32C2 -#include "esp32c2/rom/rtc.h" -#elif CONFIG_IDF_TARGET_ESP32C6 -#include "esp32c6/rom/rtc.h" -#include "hal/gpio_ll.h" -#include "hal/clk_gate_ll.h" -#elif CONFIG_IDF_TARGET_ESP32C5 -#include "esp32c5/rom/rtc.h" -#include "hal/gpio_ll.h" -#include "hal/clk_gate_ll.h" -#elif CONFIG_IDF_TARGET_ESP32C61 -#include "esp32c61/rom/rtc.h" -#include "hal/gpio_ll.h" -#elif CONFIG_IDF_TARGET_ESP32H2 -#include "esp32h2/rom/rtc.h" -#include "soc/extmem_reg.h" -#include "hal/gpio_ll.h" -#elif CONFIG_IDF_TARGET_ESP32H21 -#include "esp32h21/rom/rtc.h" -#include "hal/gpio_ll.h" -#elif CONFIG_IDF_TARGET_ESP32H4 -#include "esp32h4/rom/rtc.h" -#include "hal/gpio_ll.h" -#elif CONFIG_IDF_TARGET_ESP32P4 -#include "esp32p4/rom/rtc.h" -#include "hal/gpio_ll.h" -#include "hal/clk_gate_ll.h" -#elif CONFIG_IDF_TARGET_ESP32S31 -#include "esp32s31/rom/rtc.h" -#include "hal/gpio_ll.h" -#include "hal/clk_gate_ll.h" #endif #if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX #include "esp_private/eco3_livelock_workaround.h" #endif -#if SOC_MSPI_HAS_INDEPENT_IOMUX -#include "hal/mspi_ll.h" -#endif - #include "hal/rtc_timer_hal.h" #if SOC_VBAT_SUPPORTED @@ -872,6 +832,7 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint } #endif if (deep_sleep) { + esp_sleep_gpio_clear_dedicated_ctrl(); #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP || SOC_GPIO_NEED_SOFT_ISOLATE_DURING_PD esp_sleep_isolate_digital_gpio(true); #endif