mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/support_esp32p4_dcdc_always_on' into 'master'
feat(esp_hw_support): support esp32p4 dcdc always on during lightsleep Closes PM-104 and PM-131 See merge request espressif/esp-idf!30449
This commit is contained in:
commit
e254647b0a
@ -281,6 +281,8 @@ menu "Hardware Settings"
|
||||
|
||||
endmenu
|
||||
|
||||
orsource "./port/$IDF_TARGET/Kconfig.dcdc"
|
||||
|
||||
orsource "./port/$IDF_TARGET/Kconfig.ldo"
|
||||
|
||||
# Invisible bringup bypass options for esp_hw_support component
|
||||
|
@ -277,7 +277,7 @@ void pmu_sleep_shutdown_dcdc(void);
|
||||
* @brief DCDC has taken over power supply, shut down LDO to save power consumption
|
||||
*/
|
||||
void pmu_sleep_shutdown_ldo(void);
|
||||
#endif
|
||||
#endif // SOC_DCDC_SUPPORTED
|
||||
|
||||
/**
|
||||
* @brief Enter deep or light sleep mode
|
||||
@ -309,9 +309,10 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
|
||||
|
||||
/**
|
||||
* @brief Finish sleep process settings and get sleep reject status
|
||||
* @param dslp True if sleep requests id deep-sleep
|
||||
* @return return sleep reject status
|
||||
*/
|
||||
bool pmu_sleep_finish(void);
|
||||
bool pmu_sleep_finish(bool dslp);
|
||||
|
||||
/**
|
||||
* @brief Initialize PMU related power/clock/digital parameters and functions
|
||||
|
@ -435,7 +435,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
|
||||
}
|
||||
#endif
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
|
||||
|
@ -475,7 +475,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
|
||||
}
|
||||
#endif
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
|
||||
|
@ -475,7 +475,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
|
||||
}
|
||||
#endif
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
|
||||
|
@ -429,7 +429,7 @@ static TCM_IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
|
||||
}
|
||||
#endif
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
esp_err_t TCM_IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
|
||||
|
@ -274,11 +274,12 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
|
||||
;
|
||||
}
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
bool pmu_sleep_finish(void)
|
||||
bool pmu_sleep_finish(bool dslp)
|
||||
{
|
||||
(void)dslp;
|
||||
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
|
||||
}
|
||||
|
||||
|
@ -341,11 +341,12 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
|
||||
;
|
||||
}
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
bool pmu_sleep_finish(void)
|
||||
bool pmu_sleep_finish(bool dslp)
|
||||
{
|
||||
(void)dslp;
|
||||
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
|
||||
}
|
||||
|
||||
|
@ -258,11 +258,12 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
|
||||
;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
bool pmu_sleep_finish(void)
|
||||
bool pmu_sleep_finish(bool dslp)
|
||||
{
|
||||
(void)dslp;
|
||||
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
|
||||
}
|
||||
|
||||
|
30
components/esp_hw_support/port/esp32p4/Kconfig.dcdc
Normal file
30
components/esp_hw_support/port/esp32p4/Kconfig.dcdc
Normal file
@ -0,0 +1,30 @@
|
||||
menu "DCDC Regulator Configurations"
|
||||
depends on SOC_GP_LDO_SUPPORTED
|
||||
|
||||
config ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
bool "Keep DC-DC power always on during light-sleep"
|
||||
default y
|
||||
help
|
||||
ESP32P4 will switch the power supply to LDO before sleeping, and switch to DCDC after waking up.
|
||||
These two processes take a long time and may bring some risks for some short duration
|
||||
light sleep. (DCDC -> LDO: 2.5ms (max), LDO -> DCDC: 1.2 ms)
|
||||
Enabling this option will make chip powered by DCDC during light sleep to reduce some power switch
|
||||
risks, this will also increase the power consumption during the light sleep.
|
||||
|
||||
DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING.
|
||||
|
||||
config ESP_SLEEP_DCM_VSET_VAL_IN_SLEEP
|
||||
int "DCDC voltage parameter during sleep"
|
||||
default 14
|
||||
range 0 31
|
||||
depends on ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
help
|
||||
This value determines the voltage of the DCDC chip during sleep. The same parameter value may
|
||||
correspond to different voltage values on different models of DCDC chips. Please update this
|
||||
value according to the model of external DCDC selected in your hardware solution.
|
||||
|
||||
For the DCDC chip model recommended by ESP, the recommended configuration
|
||||
values are listed below:
|
||||
|
||||
- TI-TLV62569/TLV62569P: 14
|
||||
endmenu
|
@ -79,7 +79,6 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa
|
||||
pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
|
||||
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, mode, anlg->bias.dcm_mode);
|
||||
pmu_ll_hp_set_dcm_vset (ctx->hal->dev, mode, anlg->bias.dcm_vset);
|
||||
pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
|
||||
pmu_ll_hp_set_dbg_atten (ctx->hal->dev, mode, anlg->bias.dbg_atten);
|
||||
pmu_ll_hp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur);
|
||||
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
|
||||
|
@ -149,26 +149,35 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
|
||||
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G1) ? BIT(1) : 0;
|
||||
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G2) ? BIT(2) : 0;
|
||||
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G3) ? BIT(3) : 0;
|
||||
config->power = power_default;
|
||||
|
||||
pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags);
|
||||
config->param = *pmu_sleep_param_config_default(¶m_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period);
|
||||
|
||||
if (dslp) {
|
||||
config->param.lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US, slowclk_period);
|
||||
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags);
|
||||
config->analog = analog_default;
|
||||
} else {
|
||||
// Get light sleep digital_default
|
||||
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags);
|
||||
config->digital = digital_default;
|
||||
|
||||
// Get light sleep analog default
|
||||
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags);
|
||||
#if CONFIG_SPIRAM
|
||||
analog_default.hp_sys.analog.pd_cur = 1;
|
||||
analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 1;
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
power_default.hp_sys.dig_power.dcdc_switch_pd_en = 0;
|
||||
analog_default.hp_sys.analog.dcm_vset = CONFIG_ESP_SLEEP_DCM_VSET_VAL_IN_SLEEP;
|
||||
analog_default.hp_sys.analog.dcm_mode = 1;
|
||||
#endif
|
||||
config->analog = analog_default;
|
||||
}
|
||||
|
||||
config->power = power_default;
|
||||
pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags);
|
||||
config->param = *pmu_sleep_param_config_default(¶m_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@ -194,6 +203,8 @@ static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_c
|
||||
static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp)
|
||||
{
|
||||
assert(ctx->hal);
|
||||
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dcm_mode);
|
||||
pmu_ll_hp_set_dcm_vset (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dcm_vset);
|
||||
pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur);
|
||||
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep);
|
||||
pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_xpd);
|
||||
@ -250,10 +261,10 @@ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp)
|
||||
}
|
||||
|
||||
void pmu_sleep_increase_ldo_volt(void) {
|
||||
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 30);
|
||||
REG_SET_BIT(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD);
|
||||
pmu_ll_hp_set_regulator_dbias(&PMU, PMU_MODE_HP_ACTIVE, 30);
|
||||
pmu_ll_hp_set_regulator_xpd(&PMU, PMU_MODE_HP_ACTIVE, 1);
|
||||
// Decrease the DCDC voltage to reduce the voltage difference between the DCDC and the LDO to avoid overshooting the DCDC voltage during wake-up.
|
||||
REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 24);
|
||||
pmu_ll_hp_set_dcm_vset(&PMU, PMU_MODE_HP_ACTIVE, 24);
|
||||
}
|
||||
|
||||
void pmu_sleep_shutdown_dcdc(void) {
|
||||
@ -301,19 +312,26 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt,
|
||||
;
|
||||
}
|
||||
|
||||
return pmu_sleep_finish();
|
||||
return pmu_sleep_finish(dslp);
|
||||
}
|
||||
|
||||
TCM_IRAM_ATTR bool pmu_sleep_finish(void)
|
||||
TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp)
|
||||
{
|
||||
REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 27);
|
||||
if (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) {
|
||||
// If sleep is rejected, the hardware wake-up process that turns on DCDC
|
||||
// is skipped, and software is used to enable DCDC here.
|
||||
pmu_sleep_enable_dcdc();
|
||||
esp_rom_delay_us(950);
|
||||
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
if (!dslp) {
|
||||
// Keep DCDC always on during light sleep, no need to adjust LDO.
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
pmu_ll_hp_set_dcm_vset(&PMU, PMU_MODE_HP_ACTIVE, 27);
|
||||
if (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) {
|
||||
// If sleep is rejected, the hardware wake-up process that turns on DCDC
|
||||
// is skipped, and software is used to enable DCDC here.
|
||||
pmu_sleep_enable_dcdc();
|
||||
esp_rom_delay_us(950);
|
||||
}
|
||||
pmu_sleep_shutdown_ldo();
|
||||
}
|
||||
pmu_sleep_shutdown_ldo();
|
||||
|
||||
unsigned chip_version = efuse_hal_chip_revision();
|
||||
if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) {
|
||||
|
@ -105,7 +105,7 @@ const pmu_lp_system_analog_param_t* pmu_lp_system_analog_param_default(pmu_lp_mo
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t reserved0 : 21;
|
||||
uint32_t dcdc_switch_pd_en: 1;
|
||||
uint32_t dcdc_switch_pd_en: 1;
|
||||
uint32_t mem_dslp : 1;
|
||||
uint32_t mem_pd_en : 1;
|
||||
uint32_t reserved1 : 6;
|
||||
@ -153,7 +153,9 @@ typedef union {
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
uint32_t reserved0 : 25;
|
||||
uint32_t reserved0 : 18;
|
||||
uint32_t dcm_vset : 5;
|
||||
uint32_t dcm_mode : 2;
|
||||
uint32_t xpd_bias : 1;
|
||||
uint32_t dbg_atten : 4;
|
||||
uint32_t pd_cur : 1;
|
||||
|
@ -905,8 +905,15 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
#if SOC_PMU_SUPPORTED
|
||||
|
||||
#if SOC_DCDC_SUPPORTED
|
||||
s_config.rtc_ticks_at_ldo_prepare = rtc_time_get();
|
||||
pmu_sleep_increase_ldo_volt();
|
||||
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
if (!deep_sleep) {
|
||||
// Keep DCDC always on during light sleep, no need to adjust LDO voltage.
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
s_config.rtc_ticks_at_ldo_prepare = rtc_time_get();
|
||||
pmu_sleep_increase_ldo_volt();
|
||||
}
|
||||
#endif
|
||||
|
||||
pmu_sleep_config_t config;
|
||||
@ -991,11 +998,18 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
#endif
|
||||
|
||||
#if SOC_DCDC_SUPPORTED
|
||||
uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period);
|
||||
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
|
||||
esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us);
|
||||
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
|
||||
if (!deep_sleep) {
|
||||
// Keep DCDC always on during light sleep, no need to adjust LDO voltage.
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period);
|
||||
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
|
||||
esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us);
|
||||
}
|
||||
pmu_sleep_shutdown_dcdc();
|
||||
}
|
||||
pmu_sleep_shutdown_dcdc();
|
||||
#endif
|
||||
|
||||
#if SOC_PMU_SUPPORTED
|
||||
|
Loading…
x
Reference in New Issue
Block a user