feat(esp_hw_support): support DCDC always on

This commit is contained in:
wuzhenghui
2024-04-23 21:11:37 +08:00
parent 79c48b4707
commit dd5a5f1cf2
13 changed files with 77 additions and 39 deletions

View File

@ -270,7 +270,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
@ -302,9 +302,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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,5 +25,6 @@ menu "DCDC Regulator Configurations"
For the DCDC chip model recommended by ESP, the recommended configuration
values are listed below:
- TI-TLV62569/TLV62569P: 14
endmenu

View File

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

View File

@ -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(&param_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(&param_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,12 +312,18 @@ 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 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.
@ -314,6 +331,7 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(void)
esp_rom_delay_us(950);
}
pmu_sleep_shutdown_ldo();
}
unsigned chip_version = efuse_hal_chip_revision();
if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) {

View File

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

View File

@ -896,8 +896,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
#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;
@ -982,11 +989,18 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif
#if SOC_DCDC_SUPPORTED
#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();
}
#endif
#if SOC_PMU_SUPPORTED