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

@@ -24,6 +24,7 @@ menu "DCDC Regulator Configurations"
value according to the model of external DCDC selected in your hardware solution. value according to the model of external DCDC selected in your hardware solution.
For the DCDC chip model recommended by ESP, the recommended configuration For the DCDC chip model recommended by ESP, the recommended configuration
valuesare 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,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 CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
if (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) { if (!dslp) {
// If sleep is rejected, the hardware wake-up process that turns on DCDC // Keep DCDC always on during light sleep, no need to adjust LDO.
// is skipped, and software is used to enable DCDC here. } else
pmu_sleep_enable_dcdc(); #endif
esp_rom_delay_us(950); {
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(); 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

@@ -105,7 +105,7 @@ const pmu_lp_system_analog_param_t* pmu_lp_system_analog_param_default(pmu_lp_mo
typedef union { typedef union {
struct { struct {
uint32_t reserved0 : 21; 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_dslp : 1;
uint32_t mem_pd_en : 1; uint32_t mem_pd_en : 1;
uint32_t reserved1 : 6; uint32_t reserved1 : 6;
@@ -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
s_config.rtc_ticks_at_ldo_prepare = rtc_time_get(); #if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
pmu_sleep_increase_ldo_volt(); 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 #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
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 CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) { if (!deep_sleep) {
esp_rom_delay_us(LDO_POWER_TAKEOVER_PREPARATION_TIME_US - ldo_increased_us); // 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 #endif
#if SOC_PMU_SUPPORTED #if SOC_PMU_SUPPORTED