fix(pm): dslp will also isolate reserved dig pads to reduce leakage on S31

This commit is contained in:
Song Ruo Jing
2026-09-03 19:59:27 +08:00
parent 1b3dc2d75b
commit 9e20a2b27f
3 changed files with 15 additions and 13 deletions

View File

@@ -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)

View File

@@ -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) &&

View File

@@ -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 */