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 * @brief DCDC has taken over power supply, shut down LDO to save power consumption
*/ */
void pmu_sleep_shutdown_ldo(void); void pmu_sleep_shutdown_ldo(void);
#endif #endif // SOC_DCDC_SUPPORTED
/** /**
* @brief Enter deep or light sleep mode * @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 * @brief Finish sleep process settings and get sleep reject status
* @param dslp True if sleep requests id deep-sleep
* @return return sleep reject status * @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 * @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 #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), 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 #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), 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 #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), 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 #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), 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); 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); 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); 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 For the DCDC chip model recommended by ESP, the recommended configuration
values are listed below: values are listed below:
- TI-TLV62569/TLV62569P: 14 - TI-TLV62569/TLV62569P: 14
endmenu 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_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_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_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_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_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); 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_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_G2) ? BIT(2) : 0;
iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G3) ? BIT(3) : 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) { 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); 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); pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags);
config->analog = analog_default; config->analog = analog_default;
} else { } else {
// Get light sleep digital_default
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags); pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags);
config->digital = digital_default; config->digital = digital_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
analog_default.hp_sys.analog.pd_cur = 1; analog_default.hp_sys.analog.pd_cur = 1;
analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 1; analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 1;
#endif #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->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; 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) static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp)
{ {
assert(ctx->hal); 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_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_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); 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) { void pmu_sleep_increase_ldo_volt(void) {
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 30); pmu_ll_hp_set_regulator_dbias(&PMU, PMU_MODE_HP_ACTIVE, 30);
REG_SET_BIT(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD); 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. // 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) { 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 (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) {
// If sleep is rejected, the hardware wake-up process that turns on DCDC // If sleep is rejected, the hardware wake-up process that turns on DCDC
// is skipped, and software is used to enable DCDC here. // 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); esp_rom_delay_us(950);
} }
pmu_sleep_shutdown_ldo(); pmu_sleep_shutdown_ldo();
}
unsigned chip_version = efuse_hal_chip_revision(); unsigned chip_version = efuse_hal_chip_revision();
if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) { if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) {

View File

@@ -153,7 +153,9 @@ typedef union {
typedef struct { typedef struct {
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 xpd_bias : 1;
uint32_t dbg_atten : 4; uint32_t dbg_atten : 4;
uint32_t pd_cur : 1; 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_PMU_SUPPORTED
#if SOC_DCDC_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(); s_config.rtc_ticks_at_ldo_prepare = rtc_time_get();
pmu_sleep_increase_ldo_volt(); pmu_sleep_increase_ldo_volt();
}
#endif #endif
pmu_sleep_config_t config; 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 #endif
#if SOC_DCDC_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
{
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); 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) { if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us); esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us);
} }
pmu_sleep_shutdown_dcdc(); pmu_sleep_shutdown_dcdc();
}
#endif #endif
#if SOC_PMU_SUPPORTED #if SOC_PMU_SUPPORTED