feat(esp_hw_support): support power down PSRAM or Flash during sleep for esp32p4 v1.0

This commit is contained in:
wuzhenghui
2024-10-23 16:03:39 +08:00
parent 8d472cf779
commit 855bba0582
9 changed files with 67 additions and 13 deletions
+3 -2
View File
@@ -69,8 +69,9 @@ menu "Hardware Settings"
# This is here since this option affect behavior of esp_light_sleep_start
# regardless of power management configuration.
config ESP_SLEEP_POWER_DOWN_FLASH
bool "Power down flash in light sleep when there is no SPIRAM"
depends on !SPIRAM
bool "Power down flash in light sleep when there is no SPIRAM or SPIRAM has independent power supply"
depends on !SPIRAM || ESP_LDO_RESERVE_PSRAM
depends on !(IDF_TARGET_ESP32P4 && (ESP32P4_REV_MIN_FULL >= 100))
default n
help
If enabled, chip will try to power down flash as part of esp_light_sleep_start(), which costs
@@ -9,8 +9,10 @@
#include <esp_types.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "soc/chip_revision.h"
#include "soc/soc.h"
#include "soc/pmu_struct.h"
#include "hal/efuse_hal.h"
#include "hal/pmu_hal.h"
#include "pmu_param.h"
#include "esp_private/esp_pmu.h"
@@ -84,7 +86,9 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_mem_xpd);
pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_logic_xpd);
pmu_ll_hp_set_regulator_sleep_memory_dbias(ctx->hal->dev, mode, anlg->regulator0.slp_mem_dbias);
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100) && (mode == PMU_MODE_HP_SLEEP)) {
pmu_ll_hp_enable_sleep_flash_ldo_channel(ctx->hal->dev, anlg->regulator0.xpd_0p1a);
}
pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, mode, anlg->regulator0.slp_logic_dbias);
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b);
@@ -152,8 +152,8 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
.dbias_init = 1, \
.slp_mem_xpd = 0, \
.slp_logic_xpd = 0, \
.slp_mem_dbias = 0, \
.slp_logic_dbias = 0, \
.slp_mem_dbias = 1, /* slp_mem_dbias bit[3] controls ext_ldo_1 xpd for rev1.0*/ \
.slp_logic_dbias = 0, \
}, \
.regulator1 = { \
.drv_b = 0x0 \
@@ -172,8 +172,8 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
.regulator0 = { \
.slp_mem_xpd = 0, \
.slp_logic_xpd = 0, \
.slp_mem_dbias = 0, \
.slp_logic_dbias = 0, \
.slp_mem_dbias = 1, /* slp_mem_dbias bit[3] controls ext_ldo_1 xpd for rev1.0*/ \
.slp_logic_dbias = 0, \
}, \
.regulator1 = { \
.drv_b = 0x0 \
@@ -154,6 +154,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
config->digital = digital_default;
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags);
analog_default.hp_sys.analog.xpd_0p1a = 0;
config->analog = analog_default;
} else {
// Get light sleep digital_default
@@ -163,6 +164,7 @@ 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(pd_flags);
#if CONFIG_SPIRAM
// Adjust analog parameters to keep EXT_LDO PSRAM channel volt outputting during light-sleep.
analog_default.hp_sys.analog.pd_cur = 0;
analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 0;
#endif
@@ -189,6 +191,11 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
analog_default.hp_sys.analog.dcm_vset = CONFIG_ESP_SLEEP_DCM_VSET_VAL_IN_SLEEP;
analog_default.hp_sys.analog.dcm_mode = 1;
#endif
if (pd_flags & PMU_SLEEP_PD_VDDSDIO) {
analog_default.hp_sys.analog.xpd_0p1a = 0;
} else {
analog_default.hp_sys.analog.xpd_0p1a = 1;
}
config->analog = analog_default;
}
@@ -229,7 +236,9 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con
pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_xpd);
pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_xpd);
pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd);
pmu_ll_hp_set_regulator_sleep_memory_dbias(ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_dbias);
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100)) {
pmu_ll_hp_enable_sleep_flash_ldo_channel(ctx->hal->dev, analog->hp_sys.analog.xpd_0p1a);
}
pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_dbias);
pmu_ll_hp_set_dbg_atten (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbg_atten);
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias);
@@ -173,7 +173,7 @@ typedef struct {
uint32_t slp_mem_xpd : 1;
uint32_t slp_logic_xpd : 1;
uint32_t xpd : 1;
uint32_t slp_mem_dbias : 4;
uint32_t xpd_0p1a : 1; // Should map to slp_mem_dbias bit[3] on hardware.
uint32_t slp_logic_dbias: 4;
uint32_t dbias : 5;
};
@@ -325,7 +325,7 @@ typedef struct {
#define PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(pd_flags) { \
.syscntl = { \
.dig_pad_slp_sel = 0, \
.lp_pad_hold_all = (pd_flags & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \
.lp_pad_hold_all = 0, \
} \
}
+24
View File
@@ -62,6 +62,10 @@
#include "hal/touch_sensor_hal.h"
#endif
#if CONFIG_SPIRAM && CONFIG_ESP_LDO_RESERVE_PSRAM
#include "hal/ldo_ll.h"
#endif
#include "sdkconfig.h"
#include "esp_rom_uart.h"
#include "esp_rom_sys.h"
@@ -1109,6 +1113,10 @@ static esp_err_t IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
portENTER_CRITICAL(&spinlock_rtc_deep_sleep);
esp_ipc_isr_stall_other_cpu();
esp_ipc_isr_stall_pause();
#if CONFIG_SPIRAM && CONFIG_ESP_LDO_RESERVE_PSRAM
// Disable PSRAM chip power supply
ldo_ll_enable(LDO_ID2UNIT(CONFIG_ESP_LDO_CHAN_PSRAM_DOMAIN), false);
#endif
// record current RTC time
s_config.rtc_ticks_at_sleep_start = rtc_time_get();
@@ -1174,6 +1182,10 @@ static esp_err_t IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
;
}
}
#if CONFIG_SPIRAM && CONFIG_ESP_LDO_RESERVE_PSRAM
// Enable PSRAM chip power supply
ldo_ll_enable(LDO_ID2UNIT(CONFIG_ESP_LDO_CHAN_PSRAM_DOMAIN), true);
#endif
// Never returns here, except that the sleep is rejected.
esp_ipc_isr_stall_resume();
esp_ipc_isr_release_other_cpu();
@@ -2233,6 +2245,11 @@ static uint32_t get_power_down_flags(void)
if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option == ESP_PD_OPTION_AUTO) {
#ifndef CONFIG_ESP_SLEEP_POWER_DOWN_FLASH
s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option = ESP_PD_OPTION_ON;
#endif
#if CONFIG_IDF_TARGET_ESP32P4
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100)) {
s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option = ESP_PD_OPTION_ON;
}
#endif
}
#endif
@@ -2317,6 +2334,13 @@ static uint32_t get_power_down_flags(void)
}
#endif
#if CONFIG_IDF_TARGET_ESP32P4
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100)) {
if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
ESP_LOGE(TAG, "ESP32P4 chips lower than v1.0 are not allowed to power down the Flash");
}
}
#endif
return pd_flags;
}