From 2ba98dfa4229ee9e87222513892fbd03fe46c512 Mon Sep 17 00:00:00 2001 From: hebinglin Date: Wed, 12 Aug 2026 16:14:58 +0800 Subject: [PATCH] change(esp_hw_support): use clk_tree manage active clk power --- .../esp32h21/include/hal/clk_tree_ll.h | 5 +++++ .../esp32h4/include/hal/clk_tree_ll.h | 5 +++++ .../esp_hal_pmu/esp32h21/include/hal/pmu_ll.h | 18 ++++++++++++++++++ .../esp_hal_pmu/esp32h4/include/hal/pmu_ll.h | 18 ++++++++++++++++++ .../esp_hw_support/port/esp32h21/pmu_init.c | 10 ++++++++-- .../esp_hw_support/port/esp32h4/pmu_init.c | 10 ++++++++-- 6 files changed, 62 insertions(+), 4 deletions(-) diff --git a/components/esp_hal_clock/esp32h21/include/hal/clk_tree_ll.h b/components/esp_hal_clock/esp32h21/include/hal/clk_tree_ll.h index 76bcab352b4..83e6249797d 100644 --- a/components/esp_hal_clock/esp32h21/include/hal/clk_tree_ll.h +++ b/components/esp_hal_clock/esp32h21/include/hal/clk_tree_ll.h @@ -68,6 +68,8 @@ typedef struct { static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void) { SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C); + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG); + SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_BBPLL_I2C | PMU_HP_ACTIVE_XPD_BBPLL); } /** @@ -77,6 +79,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void) { SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_BBPLL_ICG) ; SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_BBPLL | PMU_TIE_LOW_XPD_BBPLL_I2C); + CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_BBPLL_I2C | PMU_HP_ACTIVE_XPD_BBPLL); } /** @@ -88,6 +91,7 @@ static inline __attribute__((always_inline)) void clk_ll_xtal_x2_enable(void) CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_XTALX2_ICG); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XTALX2); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_XTALX2_ICG); + SET_PERI_REG_MASK(PMU_HP_ACTIVE_XTAL_REG, PMU_HP_ACTIVE_XPD_XTALX2); } /** @@ -98,6 +102,7 @@ static inline __attribute__((always_inline)) void clk_ll_xtal_x2_disable(void) CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XTALX2 | PMU_TIE_HIGH_GLOBAL_XTALX2_ICG); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_XTALX2); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_XTALX2_ICG); + CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_XTAL_REG, PMU_HP_ACTIVE_XPD_XTALX2); } /** diff --git a/components/esp_hal_clock/esp32h4/include/hal/clk_tree_ll.h b/components/esp_hal_clock/esp32h4/include/hal/clk_tree_ll.h index f89b1bd89bb..b12ec8afcfc 100644 --- a/components/esp_hal_clock/esp32h4/include/hal/clk_tree_ll.h +++ b/components/esp_hal_clock/esp32h4/include/hal/clk_tree_ll.h @@ -66,6 +66,8 @@ typedef struct { static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void) { SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C); + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG); + SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_BBPLL_I2C | PMU_HP_ACTIVE_XPD_BBPLL); } /** @@ -75,6 +77,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void) { SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_BBPLL_ICG) ; SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_BBPLL | PMU_TIE_LOW_XPD_BBPLL_I2C); + CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_CK_POWER_REG, PMU_HP_ACTIVE_XPD_BBPLL_I2C | PMU_HP_ACTIVE_XPD_BBPLL); } /** @@ -94,6 +97,7 @@ static inline __attribute__((always_inline)) void clk_ll_xtal_x2_enable(void) CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_XTALX2_ICG); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XTALX2); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_XTALX2_ICG); + SET_PERI_REG_MASK(PMU_HP_ACTIVE_XTAL_REG, PMU_HP_ACTIVE_XPD_XTALX2); } /** @@ -104,6 +108,7 @@ static inline __attribute__((always_inline)) void clk_ll_xtal_x2_disable(void) CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XTALX2 | PMU_TIE_HIGH_GLOBAL_XTALX2_ICG); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_XTALX2); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_XTALX2_ICG); + CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_XTAL_REG, PMU_HP_ACTIVE_XPD_XTALX2); } /** 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 e2b65687321..507f7a3f8b5 100644 --- a/components/esp_hal_pmu/esp32h21/include/hal/pmu_ll.h +++ b/components/esp_hal_pmu/esp32h21/include/hal/pmu_ll.h @@ -94,6 +94,24 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_clk_power(pmu_dev_t *hw, pmu_hp_mode_t mode hw->hp_sys[mode].clk_power.val = xpd_flag; } +/** + * @brief Set the power and isolation of the analog i2c master shared by all the PLLs + * + * @param hw Beginning address of the peripheral registers. + * @param mode The pmu mode + * @param xpd_bb_i2c Power up the analog i2c master + * @param iso_en Isolate the analog i2c master interface + * @param retention Retain the analog i2c master registers + * + * @return None + */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_ana_i2c_power(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_bb_i2c, bool iso_en, bool retention) +{ + hw->hp_sys[mode].clk_power.xpd_bb_i2c = xpd_bb_i2c; + hw->hp_sys[mode].clk_power.i2c_iso_en = iso_en; + hw->hp_sys[mode].clk_power.i2c_retention = retention; +} + FORCE_INLINE_ATTR void pmu_ll_hp_set_dcdc_ccm_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool enable) { hw->hp_sys[mode].bias.dcdc_ccm_enb = enable; 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 aa72e0b6579..4668db72eb3 100644 --- a/components/esp_hal_pmu/esp32h4/include/hal/pmu_ll.h +++ b/components/esp_hal_pmu/esp32h4/include/hal/pmu_ll.h @@ -94,6 +94,24 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_clk_power(pmu_dev_t *hw, pmu_hp_mode_t mode hw->hp_sys[mode].clk_power.val = xpd_flag; } +/** + * @brief Set the power and isolation of the analog i2c master shared by all the PLLs + * + * @param hw Beginning address of the peripheral registers. + * @param mode The pmu mode + * @param xpd_bb_i2c Power up the analog i2c master + * @param iso_en Isolate the analog i2c master interface + * @param retention Retain the analog i2c master registers + * + * @return None + */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_ana_i2c_power(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_bb_i2c, bool iso_en, bool retention) +{ + hw->hp_sys[mode].clk_power.xpd_bb_i2c = xpd_bb_i2c; + hw->hp_sys[mode].clk_power.i2c_iso_en = iso_en; + hw->hp_sys[mode].clk_power.i2c_retention = retention; +} + FORCE_INLINE_ATTR void pmu_ll_hp_set_xtal_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_xtal) { hw->hp_sys[mode].xtal.xpd_xtal = xpd_xtal; diff --git a/components/esp_hw_support/port/esp32h21/pmu_init.c b/components/esp_hw_support/port/esp32h21/pmu_init.c index 4108e24cd05..02748dcaea5 100644 --- a/components/esp_hw_support/port/esp32h21/pmu_init.c +++ b/components/esp_hw_support/port/esp32h21/pmu_init.c @@ -64,9 +64,15 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys assert(ctx->hal); /* Default configuration of hp-system power in active, modem and sleep modes */ 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); + if (mode == PMU_MODE_HP_ACTIVE) { + // In active mode the root clock circuit power (BBPLL/CPLL/MPLL/APLL/XTALx2, etc.) is owned by esp_clk_tree. + // The analog i2c master is shared by all the PLLs and is not refcounted there, so it is still configured here. + pmu_ll_hp_set_ana_i2c_power(ctx->hal->dev, mode, power->clk_power.xpd_bb_i2c, power->clk_power.i2c_iso_en, power->clk_power.i2c_retention); + } else { + pmu_ll_hp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val); + pmu_ll_hp_set_xtalx2_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtalx2); + } 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); diff --git a/components/esp_hw_support/port/esp32h4/pmu_init.c b/components/esp_hw_support/port/esp32h4/pmu_init.c index 625b549c00b..9180baa9c3c 100644 --- a/components/esp_hw_support/port/esp32h4/pmu_init.c +++ b/components/esp_hw_support/port/esp32h4/pmu_init.c @@ -68,9 +68,15 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys assert(ctx->hal); /* Default configuration of hp-system power in active, modem and sleep modes */ 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); + if (mode == PMU_MODE_HP_ACTIVE) { + // In active mode the root clock circuit power (BBPLL/CPLL/MPLL/APLL/XTALx2, etc.) is owned by esp_clk_tree. + // The analog i2c master is shared by all the PLLs and is not refcounted there, so it is still configured here. + pmu_ll_hp_set_ana_i2c_power(ctx->hal->dev, mode, power->clk_power.xpd_bb_i2c, power->clk_power.i2c_iso_en, power->clk_power.i2c_retention); + } else { + pmu_ll_hp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val); + pmu_ll_hp_set_xtalx2_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtalx2); + } 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);