mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 11:03:11 +00:00
Merge branch 'feat/esp_idfesp32h4_eco1_sleep_support' into 'master'
Feat/ESP32H4 ECO1 Sleep Support Closes PM-633 See merge request espressif/esp-idf!47023
This commit is contained in:
@@ -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
|
||||
*/
|
||||
@@ -10,6 +10,11 @@
|
||||
#include <stdbool.h>
|
||||
#include "esp_attr.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/reset_reasons.h"
|
||||
#include "soc/usb_serial_jtag_struct.h"
|
||||
#include "soc/lpperi_struct.h"
|
||||
#include "soc/lp_clkrst_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -87,6 +92,124 @@ FORCE_INLINE_ATTR void _clk_gate_ll_ref_96m_clk_en(bool enable)
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define clk_gate_ll_ref_96m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_96m_clk_en(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Configuration structure for peripheral clock gate settings
|
||||
*/
|
||||
typedef struct {
|
||||
bool disable_uart0_clk; ///< Disable UART0 clock (when UART0 is not console)
|
||||
bool disable_uart1_clk; ///< Disable UART1 clock (when UART1 is not console)
|
||||
bool disable_mspi_flash_clk; ///< Disable MSPI flash clock (for PURE_RAM_APP)
|
||||
bool disable_assist_clk; ///< Disable ASSIST Debug module clock
|
||||
bool disable_crypto_periph_clk; ///< Disable crypto peripherals clock when TEE is not enabled
|
||||
bool disable_usb_serial_jtag; ///< Disable USB-Serial-JTAG clock and pad (when not enabled)
|
||||
bool disable_pvt_clk; ///< Disable PVT monitor clocks when PVT is not used
|
||||
} periph_ll_clk_gate_config_t;
|
||||
|
||||
/**
|
||||
* @brief Set default clock gates: turn off unused peripheral root clocks at CPU start.
|
||||
*
|
||||
* @note LP_PERI clocks are gated on cold boot paths; efuse clock stays enabled.
|
||||
*/
|
||||
static inline void periph_ll_clk_gate_set_default(soc_reset_reason_t rst_reason, const periph_ll_clk_gate_config_t *config)
|
||||
{
|
||||
if ((rst_reason != RESET_REASON_CPU0_MWDT0) && (rst_reason != RESET_REASON_CPU0_MWDT1) \
|
||||
&& (rst_reason != RESET_REASON_CPU0_SW) && (rst_reason != RESET_REASON_CPU0_RTC_WDT) \
|
||||
&& (rst_reason != RESET_REASON_CPU0_JTAG)) {
|
||||
/* Use independent ifs: console may be neither UART0 nor UART1 (e.g. USB), both need gating. */
|
||||
if (config->disable_uart0_clk) {
|
||||
PCR.uart0_conf.uart0_clk_en = 0;
|
||||
PCR.uart0_sclk_conf.uart0_sclk_en = 0;
|
||||
}
|
||||
if (config->disable_uart1_clk) {
|
||||
PCR.uart1_conf.uart1_clk_en = 0;
|
||||
PCR.uart1_sclk_conf.uart1_sclk_en = 0;
|
||||
}
|
||||
|
||||
PCR.i2c0_conf.i2c0_clk_en = 0;
|
||||
PCR.i2c1_conf.i2c1_clk_en = 0;
|
||||
PCR.i2c0_sclk_conf.i2c0_sclk_en = 0;
|
||||
PCR.i2c1_sclk_conf.i2c1_sclk_en = 0;
|
||||
PCR.rmt_conf.rmt_clk_en = 0;
|
||||
PCR.rmt_sclk_conf.rmt_sclk_en = 0;
|
||||
PCR.ledc_sclk_conf.ledc_sclk_en = 0;
|
||||
PCR.ledc_conf.ledc_clk_en = 0;
|
||||
PCR.timergroup0_timer_clk_conf.tg0_timer_clk_en = 0;
|
||||
PCR.timergroup1_timer_clk_conf.tg1_timer_clk_en = 0;
|
||||
PCR.timergroup0_conf.tg0_clk_en = 0;
|
||||
PCR.timergroup1_conf.tg1_clk_en = 0;
|
||||
PCR.twai0_func_clk_conf.twai0_func_clk_en = 0;
|
||||
PCR.twai0_conf.twai0_clk_en = 0;
|
||||
PCR.i2s_conf.i2s_clk_en = 0;
|
||||
PCR.i2s_tx_clkm_conf.i2s_tx_clkm_en = 0;
|
||||
PCR.i2s_rx_clkm_conf.i2s_rx_clkm_en = 0;
|
||||
PCR.pcnt_conf.pcnt_clk_en = 0;
|
||||
PCR.etm_conf.etm_clk_en = 0;
|
||||
PCR.pwm0_conf.pwm0_clk_en = 0;
|
||||
PCR.pwm0_clk_conf.pwm0_clkm_en = 0;
|
||||
PCR.pwm1_conf.pwm1_clk_en = 0;
|
||||
PCR.pwm1_clk_conf.pwm1_clkm_en = 0;
|
||||
PCR.parl_clk_rx_conf.parl_clk_rx_en = 0;
|
||||
PCR.parl_clk_tx_conf.parl_clk_tx_en = 0;
|
||||
PCR.parl_io_conf.parl_clk_en = 0;
|
||||
PCR.gdma_conf.gdma_clk_en = 0;
|
||||
|
||||
if (config->disable_mspi_flash_clk) {
|
||||
PCR.mspi_conf.mspi_clk_en = 0;
|
||||
}
|
||||
|
||||
PCR.spi2_conf.spi2_clk_en = 0;
|
||||
PCR.spi3_conf.spi3_clk_en = 0;
|
||||
PCR.tsens_clk_conf.tsens_clk_en = 0;
|
||||
|
||||
PCR.uhci_conf.uhci_clk_en = 0;
|
||||
PCR.saradc_conf.saradc_clk_en = 0;
|
||||
PCR.asrc_func_clk_conf.asrc_func_clk_en = 0;
|
||||
PCR.asrc_func_clk_conf.asrc_apb_clk_en = 0;
|
||||
PCR.zero_det_conf.zero_det_clk_en = 0;
|
||||
PCR.zero_det_clk_conf.zero_det_func_clk_en = 0;
|
||||
|
||||
if (config->disable_assist_clk) {
|
||||
/* Disable ASSIST Debug module clock if PC recording is not used;
|
||||
* stack guard may re-enable in esp_hw_stack_guard_init */
|
||||
PCR.assist_conf.assist_clk_en = 0;
|
||||
}
|
||||
|
||||
if (config->disable_crypto_periph_clk) {
|
||||
// NOTE: [ESP-TEE] The TEE is responsible for the AES and SHA peripherals
|
||||
PCR.aes_conf.aes_clk_en = 0;
|
||||
PCR.sha_conf.sha_clk_en = 0;
|
||||
PCR.ecc_conf.ecc_clk_en = 0;
|
||||
PCR.hmac_conf.hmac_clk_en = 0;
|
||||
PCR.km_conf.km_clk_en = 0;
|
||||
PCR.ecdsa_conf.ecdsa_clk_en = 0;
|
||||
}
|
||||
|
||||
PCR.trace_conf.trace_clk_en = 0;
|
||||
PCR.tcm_mem_monitor_conf.tcm_mem_monitor_clk_en = 0;
|
||||
PCR.psram_mem_monitor_conf.psram_mem_monitor_clk_en = 0;
|
||||
if (config->disable_pvt_clk) {
|
||||
PCR.pvt_monitor_conf.pvt_monitor_clk_en = 0;
|
||||
PCR.pvt_monitor_func_clk_conf.pvt_monitor_func_clk_en = 0;
|
||||
}
|
||||
PCR.ctrl_clk_out_en.val = 0;
|
||||
|
||||
if (config->disable_usb_serial_jtag) {
|
||||
// Disable USB-Serial-JTAG clock and its pad if not used
|
||||
USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_usb_pad_enable = 0;
|
||||
PCR.usb_device_conf.usb_device_clk_en = 0;
|
||||
PCR.usb_otg11_conf.usb_otg11_clk_en = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CHIP_BROWN_OUT) \
|
||||
|| (rst_reason == RESET_REASON_SYS_RTC_WDT) || (rst_reason == RESET_REASON_SYS_SUPER_WDT)) {
|
||||
LPPERI.clk_en.val = 0;
|
||||
LPPERI.clk_en.lp_io_ck_en = 1; // TODO: PM-699
|
||||
LPPERI.clk_en.efuse_ck_en = 1; // keep efuse clock enabled
|
||||
LP_CLKRST.lp_clk_po_en.val = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -578,13 +578,6 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_on_mask(pmu_dev_t *hw, uint32_
|
||||
hw->power.mem_mask.mem2_mask = (mem_mask & BIT(2)) ? 1 : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_off_mask(pmu_dev_t *hw, uint32_t mem0_pd_mask, uint32_t mem1_pd_mask, uint32_t mem2_pd_mask)
|
||||
{
|
||||
hw->power.mem_mask.mem0_pd_mask = mem0_pd_mask;
|
||||
hw->power.mem_mask.mem1_pd_mask = mem1_pd_mask;
|
||||
hw->power.mem_mask.mem2_pd_mask = mem2_pd_mask;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void pmu_ll_hp_set_vdd_flash_tiel_enable(pmu_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->power.vdd_flash.ldo_tiel_en = enable;
|
||||
|
||||
@@ -178,6 +178,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON;
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON;
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias();
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.dcm_vset = 20;
|
||||
} else if (!(sleep_flags & PMU_SLEEP_PD_RC_FAST)) {
|
||||
analog_default.hp_sys.analog.drv_b = get_act_hp_drvb();
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias();
|
||||
|
||||
@@ -30,6 +30,12 @@ static int s_cur_pll_freq;
|
||||
|
||||
static uint32_t s_bbpll_digi_consumers_ref_count = 0; // Currently, it only tracks whether the 48MHz PHY clock is in-use by USB Serial/JTAG
|
||||
|
||||
#if !BOOTLOADER_BUILD
|
||||
// Indicate whether the specific cpu clock source is acquired by the hp root clock (i.e. whether ref_cnt in esp_clk_tree.c is incremented by the hp root clock)
|
||||
static bool s_is_pll_acquired = (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ == 96 || CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ == 48);
|
||||
static bool s_is_xtal_x2_acquired = (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ == 64);
|
||||
#endif
|
||||
|
||||
void rtc_clk_bbpll_add_consumer(void)
|
||||
{
|
||||
s_bbpll_digi_consumers_ref_count += 1;
|
||||
@@ -283,7 +289,10 @@ static void rtc_clk_cpu_src_clk_enable(soc_cpu_clk_src_t new_src, uint32_t new_s
|
||||
rtc_clk_bbpll_enable();
|
||||
truly_enabled = true;
|
||||
#else
|
||||
truly_enabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, true);
|
||||
if (!s_is_pll_acquired) {
|
||||
truly_enabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, true);
|
||||
s_is_pll_acquired = true;
|
||||
}
|
||||
#endif
|
||||
if (truly_enabled || (s_cur_pll_freq != new_src_freq_mhz)) {
|
||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), new_src_freq_mhz);
|
||||
@@ -292,7 +301,10 @@ static void rtc_clk_cpu_src_clk_enable(soc_cpu_clk_src_t new_src, uint32_t new_s
|
||||
#if BOOTLOADER_BUILD
|
||||
clk_ll_xtal_x2_enable();
|
||||
#else
|
||||
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, true);
|
||||
if (!s_is_xtal_x2_acquired) {
|
||||
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, true);
|
||||
s_is_xtal_x2_acquired = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -303,7 +315,9 @@ static void rtc_clk_cpu_src_clk_disable(soc_cpu_clk_src_t old_src)
|
||||
#if BOOTLOADER_BUILD
|
||||
rtc_clk_bbpll_disable();
|
||||
#else
|
||||
assert(s_is_pll_acquired);
|
||||
bool truly_disabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, false);
|
||||
s_is_pll_acquired = false;
|
||||
if (truly_disabled) {
|
||||
s_cur_pll_freq = 0;
|
||||
}
|
||||
@@ -312,7 +326,9 @@ static void rtc_clk_cpu_src_clk_disable(soc_cpu_clk_src_t old_src)
|
||||
#if BOOTLOADER_BUILD
|
||||
clk_ll_xtal_x2_disable();
|
||||
#else
|
||||
assert(s_is_xtal_x2_acquired);
|
||||
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, false);
|
||||
s_is_xtal_x2_acquired = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -385,7 +401,10 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||
rtc_clk_cpu_freq_to_rc_fast();
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_XTAL_X2
|
||||
&& esp_clk_tree_is_power_on(SOC_ROOT_CIRCUIT_CLK_XTAL_X2)) {
|
||||
#if !BOOTLOADER_BUILD
|
||||
&& s_is_xtal_x2_acquired
|
||||
#endif
|
||||
) {
|
||||
rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div);
|
||||
} else {
|
||||
/* fallback */
|
||||
@@ -395,12 +414,13 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
||||
|
||||
void rtc_clk_cpu_freq_set_xtal(void)
|
||||
{
|
||||
rtc_clk_cpu_set_to_default_config();
|
||||
#if BOOTLOADER_BUILD
|
||||
rtc_clk_bbpll_disable();
|
||||
#else
|
||||
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, false);
|
||||
#endif
|
||||
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||
int freq_mhz = (int)rtc_clk_xtal_freq_get();
|
||||
|
||||
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
||||
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_src_clk_disable(old_cpu_clk_src);
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_IRAM_ATTR void rtc_clk_cpu_set_to_default_config(void)
|
||||
|
||||
@@ -161,5 +161,5 @@ esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ESP_OK; // TODO: PM-456
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,9 @@ 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.drv_b = PMU_HP_DRVB_LIGHTSLEEP;
|
||||
if (sleep_flags & PMU_SLEEP_PD_TOP) {
|
||||
analog_default.hp_sys.analog.drv_b = PMU_HP_DRVB_LIGHTSLEEP_TOP_PD;
|
||||
}
|
||||
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;
|
||||
@@ -164,6 +166,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON;
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON;
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias();
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.dcm_vset = 20;
|
||||
} else if (!(sleep_flags & PMU_SLEEP_PD_RC_FAST)) {
|
||||
analog_default.hp_sys.analog.drv_b = get_act_hp_drvb();
|
||||
analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias();
|
||||
@@ -214,6 +217,7 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con
|
||||
pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd);
|
||||
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_hp_set_discnnt_dig_rtc (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.discnnt_dig_rtc);
|
||||
|
||||
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);
|
||||
@@ -222,6 +226,7 @@ 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_lp_set_discnnt_dig_rtc (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.discnnt_dig_rtc);
|
||||
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -27,18 +27,19 @@ extern "C" {
|
||||
// FOR BOTH LIGHTSLEEP & DEEPSLEEP
|
||||
#define PMU_PD_CUR_SLEEP_DEFAULT 1
|
||||
#define PMU_BIASSLP_SLEEP_DEFAULT 1
|
||||
#define PMU_LP_XPD_SLEEP_DEFAULT 1
|
||||
#define PMU_LP_SLP_XPD_SLEEP_DEFAULT 0
|
||||
#define PMU_LP_SLP_DBIAS_SLEEP_DEFAULT 0
|
||||
|
||||
// FOR LIGHTSLEEP
|
||||
#define PMU_HP_DRVB_LIGHTSLEEP 0
|
||||
#define PMU_HP_DRVB_LIGHTSLEEP_TOP_PU 25
|
||||
#define PMU_HP_DRVB_LIGHTSLEEP_TOP_PD 23
|
||||
#define PMU_LP_DRVB_LIGHTSLEEP 0
|
||||
#define PMU_HP_XPD_LIGHTSLEEP 1
|
||||
#define PMU_LP_XPD_LIGHTSLEEP_DEFAULT 1
|
||||
|
||||
#define PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT 0
|
||||
#define PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT 1
|
||||
#define PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT 12
|
||||
#define PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT 0
|
||||
#define PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT 3
|
||||
|
||||
#define PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US 0
|
||||
// The current value of this depends on the restoration time overhead of the longest chain in regdma
|
||||
@@ -48,9 +49,9 @@ extern "C" {
|
||||
#define PMU_DBG_HP_DEEPSLEEP 0
|
||||
#define PMU_HP_XPD_DEEPSLEEP 0
|
||||
#define PMU_LP_DRVB_DEEPSLEEP 0
|
||||
|
||||
#define PMU_LP_XPD_DEEPSLEEP_DEFAULT 0
|
||||
#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12
|
||||
#define PMU_LP_DBIAS_SLEEP_0V7_DEFAULT 23
|
||||
#define PMU_LP_DBIAS_SLEEP_0V7_DEFAULT 3
|
||||
|
||||
uint32_t get_act_hp_drvb(void);
|
||||
uint32_t get_act_lp_dbias(void);
|
||||
@@ -330,8 +331,7 @@ typedef struct {
|
||||
}, \
|
||||
.lp_sys[PMU_MODE_LP_SLEEP] = { \
|
||||
.dig_power = { \
|
||||
/* TODO: PM-638 */\
|
||||
.vdd_io_mode = 0, \
|
||||
.vdd_io_mode = 3, \
|
||||
.bod_source_sel = 0, \
|
||||
.vddbat_mode = 0, \
|
||||
.peri_pd_en = ((sleep_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0,\
|
||||
@@ -391,8 +391,9 @@ typedef struct {
|
||||
.dcm_mode = 3, \
|
||||
.discnnt_dig_rtc = 0, \
|
||||
.xpd_trx = 0, \
|
||||
.xpd_bias = 0, \
|
||||
.power_det_bypass = 0, \
|
||||
.drv_b = PMU_HP_DRVB_LIGHTSLEEP, \
|
||||
.drv_b = PMU_HP_DRVB_LIGHTSLEEP_TOP_PU, \
|
||||
.pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \
|
||||
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
|
||||
.xpd = PMU_HP_XPD_LIGHTSLEEP, \
|
||||
@@ -405,7 +406,7 @@ typedef struct {
|
||||
.dcdc_clear_rdy = 0, \
|
||||
.dig_reg_dpcur_bias = 1, \
|
||||
.dig_reg_dsfmos = 4, \
|
||||
.dcm_vset = 20, \
|
||||
.dcm_vset = 0, \
|
||||
.dcm_mode = 3, \
|
||||
.discnnt_dig_rtc = 0, \
|
||||
.drv_b = PMU_LP_DRVB_DEEPSLEEP, \
|
||||
@@ -413,7 +414,7 @@ typedef struct {
|
||||
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
|
||||
.slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \
|
||||
.slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT, \
|
||||
.xpd = PMU_LP_XPD_SLEEP_DEFAULT, \
|
||||
.xpd = PMU_LP_XPD_LIGHTSLEEP_DEFAULT, \
|
||||
.dbias = PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT \
|
||||
} \
|
||||
} \
|
||||
@@ -426,7 +427,7 @@ typedef struct {
|
||||
.dcdc_clear_rdy = 0, \
|
||||
.dig_reg_dpcur_bias = 1, \
|
||||
.dig_reg_dsfmos = 4, \
|
||||
.dcm_vset = 23, \
|
||||
.dcm_vset = 20, \
|
||||
.dcm_mode = 3, \
|
||||
.discnnt_dig_rtc = 0, \
|
||||
.xpd_trx = 0, \
|
||||
@@ -450,7 +451,7 @@ typedef struct {
|
||||
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
|
||||
.slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \
|
||||
.slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT, \
|
||||
.xpd = PMU_LP_XPD_SLEEP_DEFAULT, \
|
||||
.xpd = PMU_LP_XPD_DEEPSLEEP_DEFAULT, \
|
||||
.dbias = PMU_LP_DBIAS_SLEEP_0V7_DEFAULT \
|
||||
} \
|
||||
} \
|
||||
|
||||
@@ -30,6 +30,12 @@ static int s_cur_pll_freq;
|
||||
|
||||
static uint32_t s_bbpll_digi_consumers_ref_count = 0; // Currently, it only tracks whether the 48MHz PHY clock is in-use by USB Serial/JTAG
|
||||
|
||||
#if !BOOTLOADER_BUILD
|
||||
// Indicate whether the specific cpu clock source is acquired by the hp root clock (i.e. whether ref_cnt in esp_clk_tree.c is incremented by the hp root clock)
|
||||
static bool s_is_pll_acquired = (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ == 96 || CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ == 48);
|
||||
static bool s_is_xtal_x2_acquired = (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ == 64);
|
||||
#endif
|
||||
|
||||
void rtc_clk_bbpll_add_consumer(void)
|
||||
{
|
||||
s_bbpll_digi_consumers_ref_count += 1;
|
||||
@@ -283,7 +289,10 @@ static void rtc_clk_cpu_src_clk_enable(soc_cpu_clk_src_t new_src, uint32_t new_s
|
||||
rtc_clk_bbpll_enable();
|
||||
truly_enabled = true;
|
||||
#else
|
||||
truly_enabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, true);
|
||||
if (!s_is_pll_acquired) {
|
||||
truly_enabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, true);
|
||||
s_is_pll_acquired = true;
|
||||
}
|
||||
#endif
|
||||
if (truly_enabled || (s_cur_pll_freq != new_src_freq_mhz)) {
|
||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), new_src_freq_mhz);
|
||||
@@ -292,7 +301,10 @@ static void rtc_clk_cpu_src_clk_enable(soc_cpu_clk_src_t new_src, uint32_t new_s
|
||||
#if BOOTLOADER_BUILD
|
||||
clk_ll_xtal_x2_enable();
|
||||
#else
|
||||
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, true);
|
||||
if (!s_is_xtal_x2_acquired) {
|
||||
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, true);
|
||||
s_is_xtal_x2_acquired = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -303,7 +315,9 @@ static void rtc_clk_cpu_src_clk_disable(soc_cpu_clk_src_t old_src)
|
||||
#if BOOTLOADER_BUILD
|
||||
rtc_clk_bbpll_disable();
|
||||
#else
|
||||
assert(s_is_pll_acquired);
|
||||
bool truly_disabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, false);
|
||||
s_is_pll_acquired = false;
|
||||
if (truly_disabled) {
|
||||
s_cur_pll_freq = 0;
|
||||
}
|
||||
@@ -312,7 +326,9 @@ static void rtc_clk_cpu_src_clk_disable(soc_cpu_clk_src_t old_src)
|
||||
#if BOOTLOADER_BUILD
|
||||
clk_ll_xtal_x2_disable();
|
||||
#else
|
||||
assert(s_is_xtal_x2_acquired);
|
||||
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, false);
|
||||
s_is_xtal_x2_acquired = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -385,7 +401,10 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||
rtc_clk_cpu_freq_to_rc_fast();
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_XTAL_X2
|
||||
&& esp_clk_tree_is_power_on(SOC_ROOT_CIRCUIT_CLK_XTAL_X2)) {
|
||||
#if !BOOTLOADER_BUILD
|
||||
&& s_is_xtal_x2_acquired
|
||||
#endif
|
||||
) {
|
||||
rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div);
|
||||
} else {
|
||||
/* fallback */
|
||||
@@ -395,12 +414,13 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
||||
|
||||
void rtc_clk_cpu_freq_set_xtal(void)
|
||||
{
|
||||
rtc_clk_cpu_set_to_default_config();
|
||||
#if BOOTLOADER_BUILD
|
||||
rtc_clk_bbpll_disable();
|
||||
#else
|
||||
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, false);
|
||||
#endif
|
||||
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||
int freq_mhz = (int)rtc_clk_xtal_freq_get();
|
||||
|
||||
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
|
||||
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_src_clk_disable(old_cpu_clk_src);
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_IRAM_ATTR void rtc_clk_cpu_set_to_default_config(void)
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -28,47 +28,10 @@
|
||||
|
||||
ESP_HW_LOG_ATTR_TAG(TAG, "rtc_clk_init");
|
||||
|
||||
/**
|
||||
* Initialize the ICG map of some modem clock domains in the PMU_ACTIVE state
|
||||
*
|
||||
* A pre-initialization interface is used to initialize the ICG map of the
|
||||
* MODEM_APB, I2C_MST and LP_APB clock domains in the PMU_ACTIVE state, and
|
||||
* disable the clock gating of these clock domains in the PMU_ACTIVE state,
|
||||
* because the system clock source (PLL) in the system boot up process needs
|
||||
* to use the i2c master peripheral.
|
||||
*
|
||||
* ICG map of all modem clock domains under different power states (PMU_ACTIVE,
|
||||
* PMU_MODEM and PMU_SLEEP) will be initialized in esp_perip_clk_init().
|
||||
*/
|
||||
static void rtc_clk_modem_clock_domain_active_state_icg_map_preinit(void)
|
||||
{
|
||||
/* Configure modem ICG code in PMU_ACTIVE state */
|
||||
pmu_ll_hp_set_icg_modem(&PMU, PMU_MODE_HP_ACTIVE, PMU_HP_ICG_MODEM_CODE_ACTIVE);
|
||||
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
/* Disable clock gating for MODEM_APB, I2C_MST and LP_APB clock domains in PMU_ACTIVE state */
|
||||
modem_syscon_ll_set_modem_apb_icg_bitmap(&MODEM_SYSCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
modem_syscon_ll_set_ieee802154_icg_bitmap(&MODEM_SYSCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
modem_syscon_ll_set_fe_icg_bitmap(&MODEM_SYSCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
modem_syscon_ll_set_bt_icg_bitmap(&MODEM_SYSCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
|
||||
modem_lpcon_ll_set_i2c_master_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
modem_lpcon_ll_set_lp_apb_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
modem_lpcon_ll_set_coex_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
|
||||
#endif
|
||||
|
||||
/* Software trigger force update modem ICG code and ICG switch */
|
||||
pmu_ll_imm_update_dig_icg_modem_code(&PMU, true);
|
||||
pmu_ll_imm_update_dig_icg_switch(&PMU, true);
|
||||
}
|
||||
|
||||
void rtc_clk_init(rtc_clk_config_t cfg)
|
||||
{
|
||||
rtc_cpu_freq_config_t old_config, new_config;
|
||||
|
||||
rtc_clk_modem_clock_domain_active_state_icg_map_preinit();
|
||||
|
||||
/* Set tuning parameters for RC_FAST and RC_SLOW clocks.
|
||||
* Note: this doesn't attempt to set the clocks to precise frequencies.
|
||||
* Instead, we calibrate these clocks against XTAL frequency later, when necessary.
|
||||
|
||||
@@ -2962,9 +2962,9 @@ static SLEEP_FN_ATTR uint32_t get_power_down_flags(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C6
|
||||
#if SOC_PM_TOP_DEPENDS_ON_RTC_PERIPH
|
||||
if (!(pd_flags & PMU_SLEEP_PD_TOP)) {
|
||||
// TOP power domain depends on the RTC_PERIPH power domain on ESP32C6, RTC_PERIPH should only be disabled when the TOP domain is down.
|
||||
// TOP power domain depends on the RTC_PERIPH power domain on ESP32C6 and ESP32H4, RTC_PERIPH should only be disabled when the TOP domain is down.
|
||||
pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#if SOC_WDT_SUPPORTED || SOC_RTC_WDT_SUPPORTED
|
||||
#include "hal/wdt_hal.h"
|
||||
#endif
|
||||
#include "hal/clk_gate_ll.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
@@ -196,5 +197,30 @@ void rtc_clk_select_rtc_slow_clk(void)
|
||||
*/
|
||||
__attribute__((weak)) void esp_perip_clk_init(void)
|
||||
{
|
||||
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
|
||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
periph_ll_clk_gate_config_t clk_gate_config = {0};
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_UART_NUM != 0
|
||||
clk_gate_config.disable_uart0_clk = true;
|
||||
#endif
|
||||
#if CONFIG_ESP_CONSOLE_UART_NUM != 1
|
||||
clk_gate_config.disable_uart1_clk = true;
|
||||
#endif
|
||||
#if CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
clk_gate_config.disable_mspi_flash_clk = true;
|
||||
#endif
|
||||
#if !CONFIG_ESP_SYSTEM_HW_PC_RECORD
|
||||
clk_gate_config.disable_assist_clk = true;
|
||||
#endif
|
||||
#if !CONFIG_SECURE_ENABLE_TEE
|
||||
clk_gate_config.disable_crypto_periph_clk = true;
|
||||
#endif
|
||||
#if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED
|
||||
clk_gate_config.disable_usb_serial_jtag = true;
|
||||
#endif
|
||||
#if !CONFIG_ESP_ENABLE_PVT
|
||||
clk_gate_config.disable_pvt_clk = true;
|
||||
#endif
|
||||
|
||||
periph_ll_clk_gate_set_default(rst_reason, &clk_gate_config);
|
||||
}
|
||||
|
||||
@@ -1203,6 +1203,10 @@ config SOC_PM_RETENTION_MODULE_NUM
|
||||
int
|
||||
default 32
|
||||
|
||||
config SOC_PM_TOP_DEPENDS_ON_RTC_PERIPH
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -494,6 +494,8 @@
|
||||
|
||||
#define SOC_PM_RETENTION_MODULE_NUM (32)
|
||||
|
||||
#define SOC_PM_TOP_DEPENDS_ON_RTC_PERIPH (1)
|
||||
|
||||
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
|
||||
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
|
||||
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (1)
|
||||
|
||||
@@ -1099,6 +1099,10 @@ config SOC_PM_SUPPORT_MAC_BB_PD
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_SUPPORT_RTC_PERIPH_PD
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_SUPPORT_PMU_CLK_ICG
|
||||
bool
|
||||
default y
|
||||
@@ -1139,6 +1143,10 @@ config SOC_PM_RETENTION_MODULE_NUM
|
||||
int
|
||||
default 64
|
||||
|
||||
config SOC_PM_TOP_DEPENDS_ON_RTC_PERIPH
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -476,7 +476,7 @@
|
||||
#define SOC_PM_SUPPORT_TOP_PD (1)
|
||||
#define SOC_PM_SUPPORT_HP_AON_PD (1)
|
||||
#define SOC_PM_SUPPORT_MAC_BB_PD (1)
|
||||
// #define SOC_PM_SUPPORT_RTC_PERIPH_PD (1) // TODO: [ESP32H4] PM-484
|
||||
#define SOC_PM_SUPPORT_RTC_PERIPH_PD (1)
|
||||
|
||||
// #define SOC_PM_SUPPORT_PMU_MODEM_STATE (1)
|
||||
// /* macro redefine for pass esp_wifi headers md5sum check */
|
||||
@@ -495,6 +495,8 @@
|
||||
#define SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE (1)
|
||||
#define SOC_PM_RETENTION_MODULE_NUM (64)
|
||||
|
||||
#define SOC_PM_TOP_DEPENDS_ON_RTC_PERIPH (1) // In ESP32H4, RTC_PERIPH should be pd only together with TOP, otherwise there is some current leak.
|
||||
|
||||
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
|
||||
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user