From c09aaa64bfda2646e0c963f65a9df6f0cc9aedee Mon Sep 17 00:00:00 2001 From: hebinglin Date: Wed, 11 Mar 2026 15:38:23 +0800 Subject: [PATCH] change(esp_hw_support): support esp32h21eco1 sleep flow --- .../esp_hal_pmu/esp32h21/include/hal/pmu_ll.h | 20 +++- .../esp_hal_pmu/esp32h4/include/hal/pmu_ll.h | 23 ++++- .../esp_hal_pmu/include/hal/pmu_types.h | 1 + .../esp32h21/include/hal/regi2c_ctrl_ll.h | 32 +++++++ components/esp_hw_support/linker.lf | 2 +- .../lowpower/port/esp32h21/sleep_clock.c | 3 - .../esp_hw_support/port/esp32h21/pmu_init.c | 91 ++++++------------- .../esp_hw_support/port/esp32h21/pmu_param.c | 4 +- .../esp_hw_support/port/esp32h21/pmu_sleep.c | 12 ++- .../port/esp32h21/private_include/pmu_param.h | 12 +-- .../port/esp32h21/rtc_clk_init.c | 9 +- .../esp_hw_support/port/esp32h4/pmu_init.c | 21 +++-- .../hal/esp32h21/include/hal/lp_aon_ll.h | 8 +- 13 files changed, 143 insertions(+), 95 deletions(-) diff --git a/components/esp_hal_pmu/esp32h21/include/hal/pmu_ll.h b/components/esp_hal_pmu/esp32h21/include/hal/pmu_ll.h index 16f8c906e8..5feeb28a86 100644 --- a/components/esp_hal_pmu/esp32h21/include/hal/pmu_ll.h +++ b/components/esp_hal_pmu/esp32h21/include/hal/pmu_ll.h @@ -134,6 +134,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_xtal_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, hw->hp_sys[mode].xtal.xpd_xtal = xpd_xtal; } +FORCE_INLINE_ATTR void pmu_ll_hp_set_xtalx2_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_xtalx2) +{ + hw->hp_sys[mode].xtal.xpd_xtalx2 = xpd_xtalx2; +} + FORCE_INLINE_ATTR void pmu_ll_hp_set_discnnt_dig_rtc(pmu_dev_t *hw, pmu_hp_mode_t mode, bool discnnt) { hw->hp_sys[mode].bias.discnnt_dig_rtc = discnnt; @@ -299,6 +304,12 @@ FORCE_INLINE_ATTR void pmu_ll_lp_set_xtal_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, hw->lp_sys[mode].xtal.xpd_xtal = slp_xpd; } +FORCE_INLINE_ATTR void pmu_ll_lp_set_xtalx2_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd_xtalx2) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].xtal.xpd_xtalx2 = xpd_xtalx2; +} + FORCE_INLINE_ATTR void pmu_ll_lp_set_dig_power(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t flag) { hw->lp_sys[mode].dig_power.val = flag; @@ -320,6 +331,12 @@ FORCE_INLINE_ATTR void pmu_ll_lp_set_dcdc_ccm_enable(pmu_dev_t *hw, pmu_lp_mode_ hw->lp_sys[mode].bias.dcdc_ccm_enb = enable; } +FORCE_INLINE_ATTR void pmu_ll_lp_set_dcdc_clear_ready(pmu_dev_t *hw, pmu_lp_mode_t mode, bool clear_rdy) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].bias.dcdc_clear_rdy = clear_rdy; +} + FORCE_INLINE_ATTR void pmu_ll_lp_set_dig_reg_dpcur_bias(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t value) { HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); @@ -764,7 +781,8 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_get_dcdc_boost_dreg(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_set_ble_bandgap_ext_ocode(pmu_dev_t *hw, uint32_t ocode) { - hw->ble_bandgap_ctrl.ext_ocode = ocode; + /* Field is 8 bits (see PMU_EXT_OCODE); mask matches REG_SET_FIELD(..., PMU_EXT_OCODE, x). */ + hw->ble_bandgap_ctrl.ext_ocode = ocode & 0xFFU; } FORCE_INLINE_ATTR uint32_t pmu_ll_get_ble_bandgap_ext_ocode(pmu_dev_t *hw) diff --git a/components/esp_hal_pmu/esp32h4/include/hal/pmu_ll.h b/components/esp_hal_pmu/esp32h4/include/hal/pmu_ll.h index 8e5a68a902..3352c55d21 100644 --- a/components/esp_hal_pmu/esp32h4/include/hal/pmu_ll.h +++ b/components/esp_hal_pmu/esp32h4/include/hal/pmu_ll.h @@ -259,7 +259,7 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_power_detect_bypass(pmu_dev_t *hw hw->hp_sys[mode].regulator0.power_det_bypass = bypass; } -FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_dbias_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool dbias_sel) +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_dbias_select(pmu_dev_t *hw, pmu_hp_mode_t mode, bool dbias_sel) { HAL_ASSERT(mode == PMU_MODE_HP_ACTIVE); hw->hp_sys[mode].regulator0.dbias_sel = dbias_sel; @@ -843,6 +843,27 @@ FORCE_INLINE_ATTR void pmu_ll_set_dcdc_ccm_sw_en(pmu_dev_t *hw, bool en) hw->dcm_ctrl.dcdc_ccm_sw_en = en; } +FORCE_INLINE_ATTR void pmu_ll_set_ble_bandgap_ext_ocode(pmu_dev_t *hw, uint32_t ocode) +{ + /* Field is 8 bits (see PMU_EXT_OCODE); mask matches REG_SET_FIELD(..., PMU_EXT_OCODE, x). */ + hw->ble_bandgap_ctrl.ext_ocode = ocode & 0xFFU; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_get_ble_bandgap_ext_ocode(pmu_dev_t *hw) +{ + return hw->ble_bandgap_ctrl.ext_ocode; +} + +FORCE_INLINE_ATTR void pmu_ll_set_ble_bandgap_ext_force_ocode(pmu_dev_t *hw, bool force) +{ + hw->ble_bandgap_ctrl.ext_force_ocode = force; +} + +FORCE_INLINE_ATTR bool pmu_ll_get_ble_bandgap_ext_force_ocode(pmu_dev_t *hw) +{ + return hw->ble_bandgap_ctrl.ext_force_ocode; +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_pmu/include/hal/pmu_types.h b/components/esp_hal_pmu/include/hal/pmu_types.h index 2176be3e88..77767dd8f5 100644 --- a/components/esp_hal_pmu/include/hal/pmu_types.h +++ b/components/esp_hal_pmu/include/hal/pmu_types.h @@ -61,6 +61,7 @@ typedef enum { PMU_HP_PD_CPU = 2, /*!< Power domain of HP CPU */ PMU_HP_PD_RESERVED = 3, /*!< Reserved power domain */ PMU_HP_PD_WIFI = 4, /*!< Power domain of WIFI */ + PMU_HP_PD_BT_154 = PMU_HP_PD_WIFI, /*!< Power domain of BT 154 */ } pmu_hp_power_domain_t; #endif diff --git a/components/esp_hal_regi2c/esp32h21/include/hal/regi2c_ctrl_ll.h b/components/esp_hal_regi2c/esp32h21/include/hal/regi2c_ctrl_ll.h index 422f2e5215..31372d0882 100644 --- a/components/esp_hal_regi2c/esp32h21/include/hal/regi2c_ctrl_ll.h +++ b/components/esp_hal_regi2c/esp32h21/include/hal/regi2c_ctrl_ll.h @@ -84,6 +84,38 @@ static inline void regi2c_ctrl_ll_i2c_sar_periph_disable(void) CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); } +/** + * @brief Enable the RF TX I2C internal bus power domain + */ +static inline void regi2c_ctrl_ll_i2c_rftx_periph_enable(void) +{ + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFTX_I2C); +} + +/** + * @brief Disable the RF TX I2C internal bus power domain + */ +static inline void regi2c_ctrl_ll_i2c_rftx_periph_disable(void) +{ + CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFTX_I2C); +} + +/** + * @brief Enable the RF RX I2C internal bus power domain + */ +static inline void regi2c_ctrl_ll_i2c_rfrx_periph_enable(void) +{ + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFRX_I2C); +} + +/** + * @brief Disable the RF RX I2C internal bus power domain + */ +static inline void regi2c_ctrl_ll_i2c_rfrx_periph_disable(void) +{ + CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFRX_I2C); +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 528205e275..1527d7fd9b 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -47,7 +47,7 @@ entries: pmu_param (noflash) elif PM_SLP_IRAM_OPT = y && IDF_TARGET_ESP32P4 != y: pmu_param:get_act_lp_dbias (noflash) - if IDF_TARGET_ESP32H4 = y: + if IDF_TARGET_ESP32H4 || IDF_TARGET_ESP32H21 = y: pmu_param:get_act_hp_drvb (noflash) else: pmu_param:get_act_hp_dbias (noflash) diff --git a/components/esp_hw_support/lowpower/port/esp32h21/sleep_clock.c b/components/esp_hw_support/lowpower/port/esp32h21/sleep_clock.c index 71af05bc32..7c2b48457a 100644 --- a/components/esp_hw_support/lowpower/port/esp32h21/sleep_clock.c +++ b/components/esp_hw_support/lowpower/port/esp32h21/sleep_clock.c @@ -50,9 +50,6 @@ esp_err_t sleep_clock_modem_retention_init(void *arg) const static sleep_retention_entries_config_t modem_regs_retention[] = { [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */ -#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ -#endif }; esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM); diff --git a/components/esp_hw_support/port/esp32h21/pmu_init.c b/components/esp_hw_support/port/esp32h21/pmu_init.c index 7aef03a4dd..652bfc239f 100644 --- a/components/esp_hw_support/port/esp32h21/pmu_init.c +++ b/components/esp_hw_support/port/esp32h21/pmu_init.c @@ -14,11 +14,12 @@ #include "pmu_param.h" #include "esp_private/esp_pmu.h" #include "regi2c_ctrl.h" -#include "soc/rtc.h" +// #include "esp_private/ocode_init.h" +#include "esp_hw_log.h" #include "soc/regi2c_lp_bias.h" -#include "soc/lp_aon_reg.h" +#include "hal/lp_aon_ll.h" -static __attribute__((unused)) const char *TAG = "pmu_init"; +ESP_HW_LOG_ATTR_TAG(TAG, "pmu_init"); typedef struct { const pmu_hp_system_power_param_t *power; @@ -56,6 +57,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys pmu_ll_hp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val); pmu_ll_hp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val); pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtal); + pmu_ll_hp_set_xtalx2_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtalx2); /* Default configuration of hp-system clock in active, modem and sleep modes */ pmu_ll_hp_set_icg_func (ctx->hal->dev, mode, clock->icg_func); @@ -115,7 +117,23 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP); /* set dcdc ccm mode software enable */ - pmu_ll_set_dcdc_ccm_sw_en(&PMU, true); + pmu_ll_set_dcdc_ccm_sw_en(ctx->hal->dev, true); + + //For dcdc ldo mode when VDD is low than about a certion value, eg 2.6v + lp_aon_ll_set_ldo_sw(15); + + /* set ble bandgap ocode */ + uint32_t ulp_ocode = 0; +#if !CONFIG_IDF_ENV_FPGA + bool ulp_force_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE); + if (ulp_force_flag) { + ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_EXT_CODE); + } else { + ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_OCODE); + } +#endif + pmu_ll_set_ble_bandgap_ext_ocode(ctx->hal->dev, ulp_ocode); + pmu_ll_set_ble_bandgap_ext_force_ocode(ctx->hal->dev, true); } void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param) @@ -128,11 +146,13 @@ void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_sys pmu_ll_lp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val); pmu_ll_lp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val); pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtal); + pmu_ll_lp_set_xtalx2_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtalx2); /* Default configuration of lp-system analog sub-system in active and * sleep modes */ if (mode == PMU_MODE_LP_SLEEP) { pmu_ll_lp_set_dcdc_ccm_enable (ctx->hal->dev, mode, anlg->bias.dcdc_ccm_enb); + pmu_ll_lp_set_dcdc_clear_ready (ctx->hal->dev, mode, anlg->bias.dcdc_clear_rdy); pmu_ll_lp_set_dig_reg_dpcur_bias(ctx->hal->dev, mode, anlg->bias.dig_reg_dpcur_bias); pmu_ll_lp_set_dig_reg_dsfmos (ctx->hal->dev, mode, anlg->bias.dig_reg_dsfmos); pmu_ll_lp_set_dcm_vset (ctx->hal->dev, mode, anlg->bias.dcm_vset); @@ -156,7 +176,7 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx) const pmu_hp_power_domain_t pmu_hp_domains[] = { PMU_HP_PD_TOP, PMU_HP_PD_CPU, - PMU_HP_PD_WIFI + PMU_HP_PD_BT_154 }; for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) { @@ -191,7 +211,7 @@ static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system *param->analog = *pmu_hp_system_analog_param_default(mode); //copy default value param->retent = pmu_hp_system_retention_param_default(mode); - if (mode == PMU_MODE_HP_ACTIVE || mode == PMU_MODE_HP_MODEM) { + if (mode == PMU_MODE_HP_ACTIVE) { param->analog->regulator1.drv_b = get_act_hp_drvb(); } } @@ -229,31 +249,12 @@ static void pmu_lp_system_init_default(pmu_context_t *ctx) } } -uint32_t get_ulp_ocode() -{ - uint32_t ulp_ocode = 0; - bool ulp_force_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE); - if (ulp_force_flag) - ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_EXT_CODE); - else - ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_OCODE); - return ulp_ocode; -} - void pmu_init(void) { - WRITE_PERI_REG(PMU_POWER_PD_TOP_CNTL_REG, 0); - WRITE_PERI_REG(PMU_POWER_PD_HPAON_CNTL_REG, 0); - WRITE_PERI_REG(PMU_POWER_PD_HPCPU_CNTL_REG, 0); - WRITE_PERI_REG(PMU_POWER_PD_HPPERI_RESERVE_REG, 0); - WRITE_PERI_REG(PMU_POWER_PD_HPWIFI_CNTL_REG, 0); - WRITE_PERI_REG(PMU_POWER_PD_LPPERI_CNTL_REG, 0); - WRITE_PERI_REG(PMU_POWER_PD_MEM_CNTL_REG, 0); - /* Peripheral reg i2c power up */ - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFTX_I2C); - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFRX_I2C); + regi2c_ctrl_ll_i2c_sar_periph_enable(); + regi2c_ctrl_ll_i2c_rftx_periph_enable(); + regi2c_ctrl_ll_i2c_rfrx_periph_enable(); pmu_hp_system_init_default(PMU_instance()); pmu_lp_system_init_default(PMU_instance()); @@ -266,38 +267,4 @@ void pmu_init(void) // esp_ocode_calib_init(); // } // #endif - uint32_t ulp_ocode = get_ulp_ocode(); - REG_SET_FIELD(PMU_BLE_BANDGAP_CTRL_REG, PMU_EXT_OCODE, ulp_ocode); - SET_PERI_REG_MASK(PMU_BLE_BANDGAP_CTRL_REG, PMU_EXT_FORCE_OCODE); - - //For dcdc ldo mode when VDD is low than about a certion value, eg 2.6v - CLEAR_PERI_REG_MASK(LP_AON_DATE_REG, LP_AON_DREG_LDO_HW); - REG_SET_FIELD(LP_AON_DATE_REG, LP_AON_DREG_LDO_SW, 15); - - - // For sleep - bool hp_ana_wait_sel_sosc = 1; - uint32_t lp_wait_us = 154; - uint32_t hp_wait_us = 150; - uint32_t xtl_stable_wait = 200; - - uint32_t slowclk_period = rtc_clk_cal(0, 128) * 4; - uint32_t fosc_period = rtc_clk_cal(3, 5000); - - uint32_t lp_wait_cycle = rtc_time_us_to_slowclk(lp_wait_us, slowclk_period); - uint32_t xtl_wait_cycle = rtc_time_us_to_slowclk(xtl_stable_wait, fosc_period); - uint32_t hp_wait_cycle; - - if (hp_ana_wait_sel_sosc) - { - REG_SET_BIT(PMU_SLP_WAKEUP_CNTL7_REG, PMU_ANA_WAIT_CLK_SEL); // hp_ana_wait_clk sel sosc - hp_wait_cycle = rtc_time_us_to_slowclk(hp_wait_us, slowclk_period); - } else { - REG_CLR_BIT(PMU_SLP_WAKEUP_CNTL7_REG, PMU_ANA_WAIT_CLK_SEL); // hp_ana_wait_clk sel fosc - hp_wait_cycle = rtc_time_us_to_slowclk(lp_wait_us, fosc_period); - } - - REG_SET_FIELD(PMU_SLP_WAKEUP_CNTL5_REG, PMU_LP_ANA_WAIT_TARGET, lp_wait_cycle); - REG_SET_FIELD(PMU_SLP_WAKEUP_CNTL7_REG, PMU_ANA_WAIT_TARGET, hp_wait_cycle); - REG_SET_FIELD(PMU_POWER_CK_WAIT_CNTL_REG, PMU_WAIT_XTL_STABLE, xtl_wait_cycle); } diff --git a/components/esp_hw_support/port/esp32h21/pmu_param.c b/components/esp_hw_support/port/esp32h21/pmu_param.c index fe58c23e81..faf01161b9 100644 --- a/components/esp_hw_support/port/esp32h21/pmu_param.c +++ b/components/esp_hw_support/port/esp32h21/pmu_param.c @@ -50,7 +50,7 @@ ESP_HW_LOG_ATTR_TAG(TAG, "pmu_param"); .xpd_bbpll = 1 \ }, \ .xtal = { \ - .xpd_xtalx2 = 0, \ + .xpd_xtalx2 = 1, \ .xpd_xtal = 1 \ } \ } @@ -65,7 +65,7 @@ ESP_HW_LOG_ATTR_TAG(TAG, "pmu_param"); */ #define PMU_HP_SLEEP_POWER_CONFIG_DEFAULT() { \ .dig_power = { \ - .vdd_flash_mode = 0, \ + .vdd_flash_mode = 3, \ .mem_dslp = 0, \ .mem_pd_en = 0, \ .wifi_pd_en = 0, \ diff --git a/components/esp_hw_support/port/esp32h21/pmu_sleep.c b/components/esp_hw_support/port/esp32h21/pmu_sleep.c index 308eac7fd5..e5587c3725 100644 --- a/components/esp_hw_support/port/esp32h21/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32h21/pmu_sleep.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -167,7 +167,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default( config->digital = digital_default; pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(sleep_flags); - analog_default.hp_sys.analog.dbias = PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT; + analog_default.hp_sys.analog.drv_b = PMU_HP_DRVB_LIGHTSLEEP; analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_slp_lp_dbias(); if (!(sleep_flags & PMU_SLEEP_PD_XTAL)){ analog_default.hp_sys.analog.xpd_trx = PMU_XPD_TRX_SLEEP_ON; @@ -192,6 +192,7 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi pmu_ll_hp_set_dig_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.dig_power.val); pmu_ll_hp_set_clk_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.clk_power.val); pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, HP(SLEEP), power->hp_sys.xtal.xpd_xtal); + pmu_ll_hp_set_xtalx2_xpd (ctx->hal->dev, HP(SLEEP), power->hp_sys.xtal.xpd_xtalx2); if (dslp) { pmu_ll_hp_set_memory_power_on_mask(ctx->hal->dev, 0); @@ -205,6 +206,7 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].dig_power.val); pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].clk_power.val); pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtal); + pmu_ll_lp_set_xtalx2_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtalx2); } static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_config_t *dig, bool dslp) @@ -220,12 +222,13 @@ 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); + // Core power supply (include DCDC, HP LDO, LP LDO) configuration 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_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd); - 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); pmu_ll_hp_set_trx_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd_trx); + pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur); pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep); pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_xpd); @@ -233,6 +236,9 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con pmu_ll_lp_set_regulator_sleep_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias); pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias); pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b); + + 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_lp_set_dcm_vset (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dcm_vset); pmu_ll_lp_set_dcm_mode (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dcm_mode); } diff --git a/components/esp_hw_support/port/esp32h21/private_include/pmu_param.h b/components/esp_hw_support/port/esp32h21/private_include/pmu_param.h index fc2ce899f9..aa9624850c 100644 --- a/components/esp_hw_support/port/esp32h21/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32h21/private_include/pmu_param.h @@ -312,7 +312,7 @@ typedef struct { }, \ .lp_sys[PMU_MODE_LP_ACTIVE] = { \ .dig_power = { \ - .vdd_io_mode = 4, \ + .vdd_io_mode = 0, \ .bod_source_sel = 0, \ .vddbat_mode = 0, \ .peri_pd_en = 0, \ @@ -327,7 +327,7 @@ typedef struct { }, \ .lp_sys[PMU_MODE_LP_SLEEP] = { \ .dig_power = { \ - .vdd_io_mode = 4, \ + .vdd_io_mode = 3, \ .bod_source_sel = 0, \ .vddbat_mode = 1, \ .peri_pd_en = ((sleep_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0,\ @@ -548,8 +548,8 @@ typedef struct pmu_sleep_machine_constant { #define PMU_SLEEP_MC_DEFAULT() { \ .lp = { \ .min_slp_time_us = 450, \ - .analog_wait_time_us = 100, \ - .xtal_wait_stable_time_us = 250, \ + .analog_wait_time_us = 154, \ + .xtal_wait_stable_time_us = 200, \ .clk_switch_cycle = 1, \ .clk_power_on_wait_cycle = 1, \ .isolate_wait_time_us = 1, \ @@ -559,14 +559,14 @@ typedef struct pmu_sleep_machine_constant { }, \ .hp = { \ .min_slp_time_us = 450, \ - .analog_wait_time_us = 1600, \ + .analog_wait_time_us = 150, \ .isolate_wait_time_us = 1, \ .reset_wait_time_us = 1, \ .power_supply_wait_time_us = 2, \ .power_up_wait_time_us = 2, \ .regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \ .regdma_a2s_work_time_us = PMU_REGDMA_A2S_WORK_TIME_US, \ - .xtal_wait_stable_time_us = 250, \ + .xtal_wait_stable_time_us = 200, \ .pll_wait_stable_time_us = 1 \ } \ } diff --git a/components/esp_hw_support/port/esp32h21/rtc_clk_init.c b/components/esp_hw_support/port/esp32h21/rtc_clk_init.c index f95c0dce22..18e3dc89ec 100644 --- a/components/esp_hw_support/port/esp32h21/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32h21/rtc_clk_init.c @@ -20,7 +20,7 @@ #include "soc/pmu_reg.h" #include "pmu_param.h" -// ESP_HW_LOG_ATTR_TAG(TAG, "rtc_clk_init"); +ESP_HW_LOG_ATTR_TAG(TAG, "rtc_clk_init"); void rtc_clk_init(rtc_clk_config_t cfg) { @@ -35,7 +35,7 @@ void rtc_clk_init(rtc_clk_config_t cfg) * CLK_8M_DFREQ constant gives the best temperature characteristics. */ REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq); - REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.slow_clk_dcap); // h4 specific workaround (RC32K_DFREQ is used for RC_SLOW clock tuning) TODO: IDF-12313 + REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.slow_clk_dcap); // h21 specific workaround (RC32K_DFREQ is used for RC_SLOW clock tuning) TODO: IDF-12313 // switch to ccm mode @@ -90,8 +90,3 @@ void rtc_clk_init(rtc_clk_config_t cfg) rtc_clk_fast_src_set(cfg.fast_clk_src); rtc_clk_slow_src_set(cfg.slow_clk_src); } - -__attribute__((weak)) uint8_t i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add) {return 0;} -__attribute__((weak)) uint8_t i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) {return 0;} -__attribute__((weak)) void i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) {}; -__attribute__((weak)) void i2c_writeReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) {}; diff --git a/components/esp_hw_support/port/esp32h4/pmu_init.c b/components/esp_hw_support/port/esp32h4/pmu_init.c index 1c28630666..7061620c34 100644 --- a/components/esp_hw_support/port/esp32h4/pmu_init.c +++ b/components/esp_hw_support/port/esp32h4/pmu_init.c @@ -20,8 +20,9 @@ #include "esp_rom_sys.h" #include "soc/regi2c_ulp.h" #include "hal/lp_aon_ll.h" +#include "esp_hw_log.h" -static __attribute__((unused)) const char *TAG = "pmu_init"; +ESP_HW_LOG_ATTR_TAG(TAG, "pmu_init"); typedef struct { const pmu_hp_system_power_param_t *power; @@ -96,7 +97,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys if (mode == PMU_MODE_HP_ACTIVE) { pmu_ll_hp_set_regulator_lp_dbias_voltage(ctx->hal->dev, mode, anlg->regulator0.lp_dbias_vol); pmu_ll_hp_set_regulator_hp_dbias_voltage(ctx->hal->dev, mode, anlg->regulator0.hp_dbias_vol); - pmu_ll_hp_set_regulator_dbias_sel (ctx->hal->dev, mode, anlg->regulator0.dbias_sel); + pmu_ll_hp_set_regulator_dbias_select (ctx->hal->dev, mode, anlg->regulator0.dbias_sel); pmu_ll_hp_set_regulator_dbias_init (ctx->hal->dev, mode, anlg->regulator0.dbias_init); } pmu_ll_hp_set_regulator_power_detect_bypass(ctx->hal->dev, mode, anlg->regulator0.power_det_bypass); @@ -122,6 +123,9 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys /* set dcdc ccm mode software enable */ pmu_ll_set_dcdc_ccm_sw_en(ctx->hal->dev, true); + //For dcdc ldo mode when VDD is low than about a certion value, eg 2.6v + lp_aon_ll_set_ldo_sw(15); + /* set ble bandgap ocode */ uint32_t ulp_ocode = 0; #if !CONFIG_IDF_ENV_FPGA @@ -132,8 +136,8 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys ulp_ocode = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_OCODE); } #endif - REG_SET_FIELD(PMU_BLE_BANDGAP_CTRL_REG, PMU_EXT_OCODE, ulp_ocode); - SET_PERI_REG_MASK(PMU_BLE_BANDGAP_CTRL_REG, PMU_EXT_FORCE_OCODE); + pmu_ll_set_ble_bandgap_ext_ocode(ctx->hal->dev, ulp_ocode); + pmu_ll_set_ble_bandgap_ext_force_ocode(ctx->hal->dev, true); } void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param) @@ -147,6 +151,7 @@ void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_sys pmu_ll_lp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val); pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtal); pmu_ll_lp_set_xtalx2_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtalx2); + /* Default configuration of lp-system analog sub-system in active and * sleep modes */ if (mode == PMU_MODE_LP_SLEEP) { @@ -176,16 +181,16 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx) PMU_HP_PD_TOP, PMU_HP_PD_HP_AON, PMU_HP_PD_CPU, - PMU_HP_PD_WIFI + PMU_HP_PD_BT_154 }; for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) { pmu_ll_hp_set_power_force_power_up (ctx->hal->dev, pmu_hp_domains[idx], false); - pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false); - pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false); - pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_no_reset (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false); } /* Isolate all memory banks while sleeping, avoid memory leakage current */ pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0); diff --git a/components/hal/esp32h21/include/hal/lp_aon_ll.h b/components/hal/esp32h21/include/hal/lp_aon_ll.h index c92520178b..55d890825a 100644 --- a/components/hal/esp32h21/include/hal/lp_aon_ll.h +++ b/components/hal/esp32h21/include/hal/lp_aon_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -84,6 +84,12 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp) } } +static inline void lp_aon_ll_set_ldo_sw(uint32_t value) +{ + CLEAR_PERI_REG_MASK(LP_AON_DATE_REG, LP_AON_DREG_LDO_HW); + REG_SET_FIELD(LP_AON_DATE_REG, LP_AON_DREG_LDO_SW, value); +} + #ifdef __cplusplus } #endif