From 820475f0e7705ce0ee4860aaa6ac2bd8bb7479e6 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 24 Apr 2026 20:35:55 +0800 Subject: [PATCH] fix(esp_hw_support): 1v8 flash/psram dedicate ldo depends on pd_cur on --- .../esp_hw_support/include/esp_private/esp_pmu.h | 3 +++ .../esp_hw_support/port/esp32s31/pmu_init.c | 14 +++++++++++++- .../esp_hw_support/port/esp32s31/pmu_sleep.c | 8 ++++++++ .../port/esp32s31/private_include/pmu_param.h | 4 ++-- components/hal/esp32s31/include/hal/efuse_ll.h | 16 ++++++++++++++++ .../soc/esp32s31/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s31/include/soc/soc_caps.h | 1 + 7 files changed, 47 insertions(+), 3 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/esp_pmu.h b/components/esp_hw_support/include/esp_private/esp_pmu.h index af7cc9042cb..3383455878a 100644 --- a/components/esp_hw_support/include/esp_private/esp_pmu.h +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -199,6 +199,9 @@ typedef struct { #if SOC_PM_SLEEP_CLK_ICG_USE_REGDMA void *priv; #endif +#if SOC_SPI_FLASH_HAS_DEDICATED_LDO + bool flash_ldo_volt_1v8; +#endif } pmu_context_t; pmu_context_t * PMU_instance(void); diff --git a/components/esp_hw_support/port/esp32s31/pmu_init.c b/components/esp_hw_support/port/esp32s31/pmu_init.c index 508c01e666f..5cbaf821e74 100644 --- a/components/esp_hw_support/port/esp32s31/pmu_init.c +++ b/components/esp_hw_support/port/esp32s31/pmu_init.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include "sdkconfig.h" @@ -13,6 +14,9 @@ #include "soc/soc.h" #include "soc/pmu_struct.h" #include "hal/efuse_hal.h" +#include "hal/efuse_ll.h" +#include "hal/gpio_ll.h" +#include "hal/gpio_types.h" #include "hal/pmu_hal.h" #include "pmu_param.h" #include "esp_private/esp_pmu.h" @@ -38,9 +42,17 @@ pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) { /* It should be explicitly defined in the internal RAM, because this * instance will be used in pmu_sleep.c */ - static DRAM_ATTR pmu_hal_context_t pmu_hal = { .dev = &PMU }; + static DRAM_ATTR pmu_hal_context_t pmu_hal = { .dev = NULL }; static DRAM_ATTR pmu_sleep_machine_constant_t pmu_mc = PMU_SLEEP_MC_DEFAULT(); static DRAM_ATTR pmu_context_t pmu_context = { .hal = &pmu_hal, .mc = (void *)&pmu_mc }; + + if (pmu_hal.dev == NULL) { + pmu_hal.dev = &PMU; + const uint32_t sel = efuse_ll_get_flash_power_sel(); + const uint32_t en = efuse_ll_get_flash_power_sel_en(); + const int g36 = gpio_ll_get_level(GPIO_LL_GET_HW(0), (uint32_t)GPIO_NUM_36); + pmu_context.flash_ldo_volt_1v8 = (sel == 0 && g36 == 0) || (sel == 1 && en == 0); + } return &pmu_context; } diff --git a/components/esp_hw_support/port/esp32s31/pmu_sleep.c b/components/esp_hw_support/port/esp32s31/pmu_sleep.c index a13585a6bd7..3abb86e68c7 100644 --- a/components/esp_hw_support/port/esp32s31/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32s31/pmu_sleep.c @@ -212,6 +212,14 @@ const pmu_sleep_config_t* pmu_sleep_config_default( // Get light sleep analog default pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(sleep_flags); +#if !CONFIG_SPIRAM + if (PMU_instance()->flash_ldo_volt_1v8) +#endif + { + analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON; + analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON; + } + if (!(sleep_flags & PMU_SLEEP_PD_XTAL)) { // Analog parameters in HP_SLEEP diff --git a/components/esp_hw_support/port/esp32s31/private_include/pmu_param.h b/components/esp_hw_support/port/esp32s31/private_include/pmu_param.h index cb8f5c1f0e1..48b4555cd97 100644 --- a/components/esp_hw_support/port/esp32s31/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32s31/private_include/pmu_param.h @@ -360,7 +360,7 @@ typedef struct { .hp_sys = { \ .analog = { \ .drv_b = PMU_HP_DRVB_LIGHTSLEEP, \ - .pd_cur = PMU_PD_CUR_SLEEP_ON, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ .xpd = PMU_HP_XPD_LIGHTSLEEP, \ .dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT, \ @@ -370,7 +370,7 @@ typedef struct { .lp_sys[PMU_MODE_LP_SLEEP] = { \ .analog = { \ .drv_b = PMU_LP_DRVB_LIGHTSLEEP, \ - .pd_cur = PMU_PD_CUR_SLEEP_ON, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ .slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \ .slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT, \ diff --git a/components/hal/esp32s31/include/hal/efuse_ll.h b/components/hal/esp32s31/include/hal/efuse_ll.h index 4f3b0f7bf1f..c1e90442d8b 100644 --- a/components/hal/esp32s31/include/hal/efuse_ll.h +++ b/components/hal/esp32s31/include/hal/efuse_ll.h @@ -142,6 +142,22 @@ __attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_st return EFUSE.status.state; } +/** + * @brief Flash power select eFuse bit (see VDD_SPI voltage table; not the final rail by itself) + */ +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_flash_power_sel(void) +{ + return EFUSE.rd_repeat_data6.pmu_flash_power_sel; +} + +/** + * @brief Flash power select valid eFuse bit (1: `flash_power_sel` is valid, 0: not) + */ +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_flash_power_sel_en(void) +{ + return EFUSE.rd_repeat_data6.pmu_flash_power_sel_en; +} + /******************* eFuse control functions *************************/ #ifdef __cplusplus diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index ca45cf59db6..3ea2ff0aa3c 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -227,6 +227,10 @@ config SOC_SPI_FLASH_SUPPORTED bool default y +config SOC_SPI_FLASH_HAS_DEDICATED_LDO + bool + default y + config SOC_TOUCH_SENSOR_SUPPORTED bool default y diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index 988dfe2a0da..1abda0792cc 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -94,6 +94,7 @@ #define SOC_WDT_SUPPORTED 1 #define SOC_RTC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 // TODO: [ESP32S31] IDF-14777 +#define SOC_SPI_FLASH_HAS_DEDICATED_LDO 1 #define SOC_TOUCH_SENSOR_SUPPORTED 1 // #define SOC_RNG_SUPPORTED 1 // TODO: [ESP32S31] IDF-14632 #define SOC_PPA_SUPPORTED 1