mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 18:57:19 +02:00
Merge branch 'feat/support_esp32p4_flash_psram_sleep_pd_v5.3' into 'release/v5.3'
feat(esp_hw_support): support power down PSRAM or Flash during sleep for esp32p4 v1.0 (v5.3) See merge request espressif/esp-idf!34390
This commit is contained in:
@ -69,8 +69,9 @@ menu "Hardware Settings"
|
|||||||
# This is here since this option affect behavior of esp_light_sleep_start
|
# This is here since this option affect behavior of esp_light_sleep_start
|
||||||
# regardless of power management configuration.
|
# regardless of power management configuration.
|
||||||
config ESP_SLEEP_POWER_DOWN_FLASH
|
config ESP_SLEEP_POWER_DOWN_FLASH
|
||||||
bool "Power down flash in light sleep when there is no SPIRAM"
|
bool "Power down flash in light sleep when there is no SPIRAM or SPIRAM has independent power supply"
|
||||||
depends on !SPIRAM
|
depends on !SPIRAM || ESP_LDO_RESERVE_PSRAM
|
||||||
|
depends on !(IDF_TARGET_ESP32P4 && (ESP32P4_REV_MIN_FULL >= 100))
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
If enabled, chip will try to power down flash as part of esp_light_sleep_start(), which costs
|
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 <esp_types.h>
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
|
#include "soc/chip_revision.h"
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#include "soc/pmu_struct.h"
|
#include "soc/pmu_struct.h"
|
||||||
|
#include "hal/efuse_hal.h"
|
||||||
#include "hal/pmu_hal.h"
|
#include "hal/pmu_hal.h"
|
||||||
#include "pmu_param.h"
|
#include "pmu_param.h"
|
||||||
#include "esp_private/esp_pmu.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_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_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_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_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);
|
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, \
|
.dbias_init = 1, \
|
||||||
.slp_mem_xpd = 0, \
|
.slp_mem_xpd = 0, \
|
||||||
.slp_logic_xpd = 0, \
|
.slp_logic_xpd = 0, \
|
||||||
.slp_mem_dbias = 0, \
|
.slp_mem_dbias = 1, /* slp_mem_dbias bit[3] controls ext_ldo_1 xpd for rev1.0*/ \
|
||||||
.slp_logic_dbias = 0, \
|
.slp_logic_dbias = 0, \
|
||||||
}, \
|
}, \
|
||||||
.regulator1 = { \
|
.regulator1 = { \
|
||||||
.drv_b = 0x0 \
|
.drv_b = 0x0 \
|
||||||
@ -172,8 +172,8 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
|
|||||||
.regulator0 = { \
|
.regulator0 = { \
|
||||||
.slp_mem_xpd = 0, \
|
.slp_mem_xpd = 0, \
|
||||||
.slp_logic_xpd = 0, \
|
.slp_logic_xpd = 0, \
|
||||||
.slp_mem_dbias = 0, \
|
.slp_mem_dbias = 1, /* slp_mem_dbias bit[3] controls ext_ldo_1 xpd for rev1.0*/ \
|
||||||
.slp_logic_dbias = 0, \
|
.slp_logic_dbias = 0, \
|
||||||
}, \
|
}, \
|
||||||
.regulator1 = { \
|
.regulator1 = { \
|
||||||
.drv_b = 0x0 \
|
.drv_b = 0x0 \
|
||||||
|
@ -154,6 +154,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
|
|||||||
config->digital = digital_default;
|
config->digital = digital_default;
|
||||||
|
|
||||||
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags);
|
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;
|
config->analog = analog_default;
|
||||||
} else {
|
} else {
|
||||||
// Get light sleep digital_default
|
// Get light sleep digital_default
|
||||||
@ -163,6 +164,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
|
|||||||
// Get light sleep analog default
|
// Get light sleep analog default
|
||||||
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags);
|
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags);
|
||||||
#if CONFIG_SPIRAM
|
#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.hp_sys.analog.pd_cur = 0;
|
||||||
analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 0;
|
analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 0;
|
||||||
#endif
|
#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_vset = CONFIG_ESP_SLEEP_DCM_VSET_VAL_IN_SLEEP;
|
||||||
analog_default.hp_sys.analog.dcm_mode = 1;
|
analog_default.hp_sys.analog.dcm_mode = 1;
|
||||||
#endif
|
#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;
|
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_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_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_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_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_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);
|
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_mem_xpd : 1;
|
||||||
uint32_t slp_logic_xpd : 1;
|
uint32_t slp_logic_xpd : 1;
|
||||||
uint32_t 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 slp_logic_dbias: 4;
|
||||||
uint32_t dbias : 5;
|
uint32_t dbias : 5;
|
||||||
};
|
};
|
||||||
@ -325,7 +325,7 @@ typedef struct {
|
|||||||
#define PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(pd_flags) { \
|
#define PMU_SLEEP_DIGITAL_DSLP_CONFIG_DEFAULT(pd_flags) { \
|
||||||
.syscntl = { \
|
.syscntl = { \
|
||||||
.dig_pad_slp_sel = 0, \
|
.dig_pad_slp_sel = 0, \
|
||||||
.lp_pad_hold_all = (pd_flags & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \
|
.lp_pad_hold_all = 0, \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,10 @@
|
|||||||
#include "hal/touch_sensor_hal.h"
|
#include "hal/touch_sensor_hal.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_SPIRAM && CONFIG_ESP_LDO_RESERVE_PSRAM
|
||||||
|
#include "hal/ldo_ll.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_rom_uart.h"
|
#include "esp_rom_uart.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
@ -1110,6 +1114,10 @@ static esp_err_t IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
|
|||||||
portENTER_CRITICAL(&spinlock_rtc_deep_sleep);
|
portENTER_CRITICAL(&spinlock_rtc_deep_sleep);
|
||||||
esp_ipc_isr_stall_other_cpu();
|
esp_ipc_isr_stall_other_cpu();
|
||||||
esp_ipc_isr_stall_pause();
|
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
|
// record current RTC time
|
||||||
s_config.rtc_ticks_at_sleep_start = rtc_time_get();
|
s_config.rtc_ticks_at_sleep_start = rtc_time_get();
|
||||||
@ -1175,6 +1183,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.
|
// Never returns here, except that the sleep is rejected.
|
||||||
esp_ipc_isr_stall_resume();
|
esp_ipc_isr_stall_resume();
|
||||||
esp_ipc_isr_release_other_cpu();
|
esp_ipc_isr_release_other_cpu();
|
||||||
@ -2240,6 +2252,11 @@ static uint32_t get_power_down_flags(void)
|
|||||||
if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option == ESP_PD_OPTION_AUTO) {
|
if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option == ESP_PD_OPTION_AUTO) {
|
||||||
#ifndef CONFIG_ESP_SLEEP_POWER_DOWN_FLASH
|
#ifndef CONFIG_ESP_SLEEP_POWER_DOWN_FLASH
|
||||||
s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option = ESP_PD_OPTION_ON;
|
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
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2324,6 +2341,13 @@ static uint32_t get_power_down_flags(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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;
|
return pd_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,11 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "soc/chip_revision.h"
|
||||||
#include "esp_bit_defs.h"
|
#include "esp_bit_defs.h"
|
||||||
#include "hal/misc.h"
|
#include "hal/misc.h"
|
||||||
|
#include "hal/efuse_hal.h"
|
||||||
|
#include "hal/pmu_types.h"
|
||||||
#include "soc/pmu_struct.h"
|
#include "soc/pmu_struct.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -122,6 +125,10 @@ __attribute__((always_inline))
|
|||||||
static inline void ldo_ll_enable(int ldo_unit, bool enable)
|
static inline void ldo_ll_enable(int ldo_unit, bool enable)
|
||||||
{
|
{
|
||||||
uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4};
|
uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4};
|
||||||
|
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100) && (ldo_unit == 0)) {
|
||||||
|
// If chip_rev >= v1.0, slp_mem_dbias[3] is used to control the volt output of VO1.
|
||||||
|
PMU.hp_sys[PMU_MODE_HP_ACTIVE].regulator0.xpd_0p1a = (enable ? 8 : 0);
|
||||||
|
}
|
||||||
PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo.xpd = enable;
|
PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo.xpd = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,9 +216,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_logic_dbias(pmu_dev_t *hw,
|
|||||||
hw->hp_sys[mode].regulator0.slp_logic_dbias = slp_dbias;
|
hw->hp_sys[mode].regulator0.slp_logic_dbias = slp_dbias;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_memory_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t slp_dbias)
|
FORCE_INLINE_ATTR void pmu_ll_hp_enable_sleep_flash_ldo_channel(pmu_dev_t *hw, bool enable)
|
||||||
{
|
{
|
||||||
hw->hp_sys[mode].regulator0.slp_mem_dbias = slp_dbias;
|
// slp_mem_dbias[3] is used to control the volt output of VO1 for chip_revision >= 100,
|
||||||
|
// and this field is not used for chip_revision < 100.
|
||||||
|
hw->hp_sys[PMU_MODE_HP_SLEEP].regulator0.xpd_0p1a = (enable ? 8 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t dbias)
|
FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t dbias)
|
||||||
|
@ -121,6 +121,7 @@ typedef union {
|
|||||||
} pmu_hp_sysclk_reg_t;
|
} pmu_hp_sysclk_reg_t;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
// For chip_revsion < 1.0
|
||||||
struct {
|
struct {
|
||||||
uint32_t reserved0 : 4; /* Only HP_ACTIVE modem under hp system is valid */
|
uint32_t reserved0 : 4; /* Only HP_ACTIVE modem under hp system is valid */
|
||||||
uint32_t lp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */
|
uint32_t lp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */
|
||||||
@ -130,10 +131,16 @@ typedef union {
|
|||||||
uint32_t slp_mem_xpd : 1;
|
uint32_t slp_mem_xpd : 1;
|
||||||
uint32_t slp_logic_xpd : 1;
|
uint32_t slp_logic_xpd : 1;
|
||||||
uint32_t xpd : 1;
|
uint32_t xpd : 1;
|
||||||
uint32_t slp_mem_dbias : 4;
|
uint32_t slp_mem_dbias : 4; /* slp_mem_dbias is not used on chip_revision < 100 */
|
||||||
uint32_t slp_logic_dbias: 4;
|
uint32_t slp_logic_dbias: 4;
|
||||||
uint32_t dbias : 5;
|
uint32_t dbias : 5;
|
||||||
};
|
};
|
||||||
|
// For chip revision >= 100
|
||||||
|
struct {
|
||||||
|
uint32_t reserved1 : 19;
|
||||||
|
uint32_t xpd_0p1a : 4; /* slp_mem_dbias[3] is used to control the volt output of VO1 on chip_revision >= 1.0 */
|
||||||
|
uint32_t reserved2 : 9;
|
||||||
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} pmu_hp_regulator0_reg_t;
|
} pmu_hp_regulator0_reg_t;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user