From be88f84bcc897e703be2663b7935a59c893e631f Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 15 Aug 2025 14:42:44 +0800 Subject: [PATCH] change(esp_hw_support): control DCDC switch by PMU FSM while control DCDC_EN by software --- .../esp_hw_support/port/esp32p4/pmu_sleep.c | 31 ++++++++++++++++--- .../port/esp32p4/private_include/pmu_param.h | 4 ++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/components/esp_hw_support/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index b1090b088c..32944e87ad 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -43,6 +43,7 @@ #define HP(state) (PMU_MODE_HP_ ## state) #define LP(state) (PMU_MODE_LP_ ## state) +#define DCDC_STARTUP_TIME_US (950) static bool s_pmu_sleep_regdma_backup_enabled; @@ -296,6 +297,24 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias); pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b); +#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON + if (dslp) +#endif + { +/** + DCDC_EN will be controlled by software to avoid DCDC working in a non-feedback state, which may + cause input glitch voltage when waking up and switching to LDO. + 1. Lightsleep: + CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON = y: DCDC will not shutdown during sleep. + CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON = n: + PD_TOP: DCDC_EN DCDC_EN enabled by regdma after wake up. + PU_TOP: DCDC_EN DCDC_EN enabled by pmu_sleep_finish after wakeup. + 2. Deepsleep + After chip wake up from deepsleep, set DCDC_EN in rtc_clk_init. +**/ + pmu_ll_hp_set_dcm_mode(ctx->hal->dev, HP(ACTIVE), 0); + } + pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_dbias); pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.dbias); pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.drv_b); @@ -346,7 +365,7 @@ void pmu_sleep_increase_ldo_volt(void) { } void pmu_sleep_shutdown_dcdc(void) { - pmu_ll_set_dcdc_switch_force_power_down(&PMU, true); + // Keep dcdc_switch on, will be disabled by PMU when entered sleep. pmu_ll_set_dcdc_en(&PMU, false); // Decrease hp_ldo voltage. pmu_ll_hp_set_regulator_dbias(&PMU, PMU_MODE_HP_ACTIVE, HP_CALI_ACTIVE_DBIAS_DEFAULT); @@ -456,10 +475,12 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp) { pmu_ll_hp_set_dcm_vset(&PMU, PMU_MODE_HP_ACTIVE, HP_CALI_ACTIVE_DCM_VSET_DEFAULT); pmu_sleep_enable_dcdc(); - if (pmu_ll_hp_is_sleep_reject(&PMU)) { - // If sleep is rejected, the hardware wake-up process that turns on DCDC - // is skipped, and wait DCDC volt rise up by software here. - esp_rom_delay_us(950); + if (pmu_ll_hp_is_sleep_reject(&PMU) || !s_pmu_sleep_regdma_backup_enabled) { + // If sleep is rejected or regdma restore is skipped, the hardware wake-up process that + // turns on DCDC is skipped, and wait DCDC volt rise up by software here. + esp_rom_delay_us(DCDC_STARTUP_TIME_US); + } else if (s_pmu_sleep_regdma_backup_enabled) { + esp_rom_delay_us(DCDC_STARTUP_TIME_US - PMU_REGDMA_S2A_WORK_TIME_US); } pmu_sleep_shutdown_ldo(); } diff --git a/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h b/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h index d4b53eebaa..93d231ad07 100644 --- a/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h @@ -351,6 +351,7 @@ typedef struct { #define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(sleep_flags) { \ .hp_sys = { \ .analog = { \ + .dcm_mode = 0, \ .drv_b = PMU_HP_DRVB_LIGHTSLEEP, \ .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ @@ -385,6 +386,7 @@ typedef struct { #define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(sleep_flags) { \ .hp_sys = { \ .analog = { \ + .dcm_mode = 0, \ .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ .xpd = PMU_HP_XPD_DEEPSLEEP, \ @@ -503,7 +505,7 @@ typedef struct pmu_sleep_machine_constant { .system_dfs_up_work_time_us = 124, \ .analog_wait_time_us = PMU_HP_ANA_WAIT_TIME_PD_TOP_US, \ .power_supply_wait_time_us = 2, \ - .power_up_wait_time_us = 2, \ + .power_up_wait_time_us = 26, \ .regdma_s2m_work_time_us = 172, \ .regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \ .regdma_m2a_work_time_us = 278, \