From c8d733e402ffda45b55ae8ae5e2ea23fb3820f45 Mon Sep 17 00:00:00 2001 From: hebinglin Date: Wed, 12 Aug 2026 17:56:58 +0800 Subject: [PATCH] change(esp_hw_support): keep PLL across DFS/sleep on esp32h4/h21 --- .../port/esp32h21/include/soc/rtc.h | 8 +- .../esp_hw_support/port/esp32h21/rtc_clk.c | 117 +++++++++--------- .../port/esp32h4/include/soc/rtc.h | 8 +- .../esp_hw_support/port/esp32h4/rtc_clk.c | 117 +++++++++--------- .../esp_hw_support/port/esp32s31/rtc_clk.c | 4 +- 5 files changed, 131 insertions(+), 123 deletions(-) diff --git a/components/esp_hw_support/port/esp32h21/include/soc/rtc.h b/components/esp_hw_support/port/esp32h21/include/soc/rtc.h index 5da854b0e48..5499bd6508b 100644 --- a/components/esp_hw_support/port/esp32h21/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32h21/include/soc/rtc.h @@ -262,7 +262,9 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config); * * @param config CPU frequency configuration structure */ +#ifndef BOOTLOADER_BUILD void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config); +#endif /** * @brief Get the currently used CPU frequency configuration @@ -270,6 +272,7 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config); */ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config); +#ifndef BOOTLOADER_BUILD /** * @brief Switch CPU clock source to XTAL * @@ -277,11 +280,10 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config); * rtc_clk_cpu_freq_set_config when a switch to XTAL is needed. * Assumes that XTAL frequency has been determined — don't call in startup code. * - * @note This function always disables BBPLL after switching the CPU clock source to XTAL for power saving purpose. - * If this is unwanted, please use rtc_clk_cpu_freq_set_config. It helps to check whether USB Serial JTAG is in use, - * if so, then BBPLL will not be turned off. + * Releases the CPU clk_tree hold on the previous root clock (BBPLL / XTAL_X2). */ void rtc_clk_cpu_freq_set_xtal(void); +#endif /** * @brief Get the current APB frequency. diff --git a/components/esp_hw_support/port/esp32h21/rtc_clk.c b/components/esp_hw_support/port/esp32h21/rtc_clk.c index 3acace5c407..f06736a90dd 100644 --- a/components/esp_hw_support/port/esp32h21/rtc_clk.c +++ b/components/esp_hw_support/port/esp32h21/rtc_clk.c @@ -25,16 +25,19 @@ ESP_HW_LOG_ATTR_TAG(TAG, "rtc_clk"); -// Current PLL frequency, in 96MHz. Zero if PLL is not enabled. -static int s_cur_pll_freq; +#ifndef BOOTLOADER_BUILD +// BBPLL frequency option, in 96MHz. Zero if BBPLL is not enabled / needs recalibration. +static int s_cur_pll_freq = 0; 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) +/** + * Whether CPU currently holds a clk_tree ref on BBPLL / XTAL_X2. + * Survives DFS set_config_fast(XTAL) (keep-hot) and light-sleep (PMU restores ACTIVE XPD on wake). + * Cleared only on real leave via set_config / set_xtal. + */ 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) { @@ -45,6 +48,7 @@ void rtc_clk_bbpll_remove_consumer(void) { s_bbpll_digi_consumers_ref_count -= 1; } +#endif void rtc_clk_32k_enable(bool enable) { @@ -137,19 +141,6 @@ soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void) return clk_ll_rtc_fast_get_src(); } -#if BOOTLOADER_BUILD -static void rtc_clk_bbpll_disable(void) -{ - clk_ll_bbpll_disable(); - s_cur_pll_freq = 0; -} - -static void rtc_clk_bbpll_enable(void) -{ - clk_ll_bbpll_enable(); -} -#endif - static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) { /* Digital part */ @@ -167,7 +158,9 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) clk_ll_bbpll_calibration_stop(); ANALOG_CLOCK_DISABLE(); +#ifndef BOOTLOADER_BUILD s_cur_pll_freq = pll_freq; +#endif } /** @@ -281,64 +274,62 @@ __attribute__((weak)) void rtc_clk_set_cpu_switch_to_pll(int event_id) { } -static void rtc_clk_cpu_src_clk_enable(soc_cpu_clk_src_t new_src, uint32_t new_src_freq_mhz) +static void rtc_clk_update_pll_state_on_cpu_src_switching_start(soc_cpu_clk_src_t new_src, uint32_t new_src_freq_mhz) { +#ifdef BOOTLOADER_BUILD if (new_src == SOC_CPU_CLK_SRC_PLL) { - bool truly_enabled = false; -#if BOOTLOADER_BUILD - rtc_clk_bbpll_enable(); - truly_enabled = true; + clk_ll_bbpll_enable(); + rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), new_src_freq_mhz); + } else if (new_src == SOC_CPU_CLK_SRC_XTAL_X2) { + clk_ll_xtal_x2_enable(); + } #else + if (new_src == SOC_CPU_CLK_SRC_PLL) { + bool need_configure = false; if (!s_is_pll_acquired) { - truly_enabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, true); + need_configure = !esp_clk_tree_is_power_on(SOC_ROOT_CIRCUIT_CLK_BBPLL); + esp_clk_tree_enable_src(SOC_MOD_CLK_BBPLL, true); s_is_pll_acquired = true; } -#endif - if (truly_enabled || (s_cur_pll_freq != new_src_freq_mhz)) { + if (need_configure || (s_cur_pll_freq != (int)new_src_freq_mhz)) { rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), new_src_freq_mhz); } } else if (new_src == SOC_CPU_CLK_SRC_XTAL_X2) { -#if BOOTLOADER_BUILD - clk_ll_xtal_x2_enable(); -#else if (!s_is_xtal_x2_acquired) { - esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, true); + esp_clk_tree_enable_src(SOC_MOD_CLK_XTAL_X2, true); s_is_xtal_x2_acquired = true; } -#endif } +#endif } -static void rtc_clk_cpu_src_clk_disable(soc_cpu_clk_src_t old_src) +#ifndef BOOTLOADER_BUILD +static void rtc_clk_update_pll_state_on_cpu_src_switching_end(soc_cpu_clk_src_t old_src) { if ((old_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { -#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); + esp_clk_tree_enable_src(SOC_MOD_CLK_BBPLL, false); s_is_pll_acquired = false; - if (truly_disabled) { + if (!esp_clk_tree_is_power_on(SOC_ROOT_CIRCUIT_CLK_BBPLL)) { s_cur_pll_freq = 0; } -#endif } else if (old_src == SOC_CPU_CLK_SRC_XTAL_X2) { -#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); + esp_clk_tree_enable_src(SOC_MOD_CLK_XTAL_X2, false); s_is_xtal_x2_acquired = false; -#endif } } +#endif void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) { - soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src(); - - if (old_cpu_clk_src != config->source) { - rtc_clk_cpu_src_clk_enable(config->source, config->source_freq_mhz); + __attribute__((unused)) soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src(); +#ifndef BOOTLOADER_BUILD + bool src_changed = (old_cpu_clk_src != config->source); + if (src_changed) +#endif + { + rtc_clk_update_pll_state_on_cpu_src_switching_start(config->source, config->source_freq_mhz); } if (config->source == SOC_CPU_CLK_SRC_XTAL) { @@ -353,9 +344,11 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div); } - if (old_cpu_clk_src != config->source) { - rtc_clk_cpu_src_clk_disable(old_cpu_clk_src); +#ifndef BOOTLOADER_BUILD + if (src_changed) { + rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src); } +#endif } void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) @@ -391,20 +384,21 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) }; } +#ifndef BOOTLOADER_BUILD void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config) { + /* Mux only — Fall back to set_config when PLL/XTALx2 must be reacquired or recalibrated + * (s_cur_pll_freq == 0 after sleep). */ if (config->source == SOC_CPU_CLK_SRC_XTAL) { rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); } else if (config->source == SOC_CPU_CLK_SRC_PLL && - s_cur_pll_freq == config->source_freq_mhz) { + s_is_pll_acquired && + s_cur_pll_freq == (int)config->source_freq_mhz) { rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); } 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 -#if !BOOTLOADER_BUILD - && s_is_xtal_x2_acquired -#endif - ) { + } else if (config->source == SOC_CPU_CLK_SRC_XTAL_X2 && + s_is_xtal_x2_acquired) { rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div); } else { /* fallback */ @@ -419,22 +413,29 @@ void rtc_clk_cpu_freq_set_xtal(void) 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); + rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src); } } +#endif FORCE_IRAM_ATTR void rtc_clk_cpu_set_to_default_config(void) { int freq_mhz = (int)rtc_clk_xtal_freq_get(); rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); - s_cur_pll_freq = 0; // no disable PLL, but set freq to 0 to trigger a PLL calibration after wake-up from sleep } +#ifndef BOOTLOADER_BUILD void rtc_clk_cpu_freq_set_xtal_for_sleep(void) { - rtc_clk_cpu_set_to_default_config(); + int freq_mhz = (int)rtc_clk_xtal_freq_get(); + + /* Mux only — do not release CPU clk_tree hold. PMU restores ACTIVE XPD on + * wake; clearing s_cur_pll_freq forces recalibration via set_config fallback. */ + rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); + s_cur_pll_freq = 0; } +#endif FORCE_IRAM_ATTR soc_xtal_freq_t rtc_clk_xtal_freq_get(void) { diff --git a/components/esp_hw_support/port/esp32h4/include/soc/rtc.h b/components/esp_hw_support/port/esp32h4/include/soc/rtc.h index fd1ac2f3b37..1d3bbeca0e0 100644 --- a/components/esp_hw_support/port/esp32h4/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32h4/include/soc/rtc.h @@ -261,7 +261,9 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config); * * @param config CPU frequency configuration structure */ +#ifndef BOOTLOADER_BUILD void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config); +#endif /** * @brief Get the currently used CPU frequency configuration @@ -269,6 +271,7 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config); */ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config); +#ifndef BOOTLOADER_BUILD /** * @brief Switch CPU clock source to XTAL * @@ -276,11 +279,10 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config); * rtc_clk_cpu_freq_set_config when a switch to XTAL is needed. * Assumes that XTAL frequency has been determined — don't call in startup code. * - * @note This function always disables BBPLL after switching the CPU clock source to XTAL for power saving purpose. - * If this is unwanted, please use rtc_clk_cpu_freq_set_config. It helps to check whether USB Serial JTAG is in use, - * if so, then BBPLL will not be turned off. + * Releases the CPU clk_tree hold on the previous root clock (BBPLL / XTAL_X2). */ void rtc_clk_cpu_freq_set_xtal(void); +#endif /** * @brief Switch root clock source to PLL (only used by sleep) release root clock source locked by PMU diff --git a/components/esp_hw_support/port/esp32h4/rtc_clk.c b/components/esp_hw_support/port/esp32h4/rtc_clk.c index cd6083e4eb5..efae5d5728e 100644 --- a/components/esp_hw_support/port/esp32h4/rtc_clk.c +++ b/components/esp_hw_support/port/esp32h4/rtc_clk.c @@ -25,16 +25,19 @@ ESP_HW_LOG_ATTR_TAG(TAG, "rtc_clk"); -// Current PLL frequency, in 96MHz. Zero if PLL is not enabled. -static int s_cur_pll_freq; +#ifndef BOOTLOADER_BUILD +// BBPLL frequency option, in 96MHz. Zero if BBPLL is not enabled / needs recalibration. +static int s_cur_pll_freq = 0; 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) +/** + * Whether CPU currently holds a clk_tree ref on BBPLL / XTAL_X2. + * Survives DFS set_config_fast(XTAL) (keep-hot) and light-sleep (PMU restores ACTIVE XPD on wake). + * Cleared only on real leave via set_config / set_xtal. + */ 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) { @@ -45,6 +48,7 @@ void rtc_clk_bbpll_remove_consumer(void) { s_bbpll_digi_consumers_ref_count -= 1; } +#endif void rtc_clk_32k_enable(bool enable) { @@ -137,19 +141,6 @@ soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void) return clk_ll_rtc_fast_get_src(); } -#if BOOTLOADER_BUILD -static void rtc_clk_bbpll_disable(void) -{ - clk_ll_bbpll_disable(); - s_cur_pll_freq = 0; -} - -static void rtc_clk_bbpll_enable(void) -{ - clk_ll_bbpll_enable(); -} -#endif - static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) { /* Digital part */ @@ -167,7 +158,9 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) clk_ll_bbpll_calibration_stop(); ANALOG_CLOCK_DISABLE(); +#ifndef BOOTLOADER_BUILD s_cur_pll_freq = pll_freq; +#endif } /** @@ -281,64 +274,62 @@ __attribute__((weak)) void rtc_clk_set_cpu_switch_to_bbpll(int event_id) { } -static void rtc_clk_cpu_src_clk_enable(soc_cpu_clk_src_t new_src, uint32_t new_src_freq_mhz) +static void rtc_clk_update_pll_state_on_cpu_src_switching_start(soc_cpu_clk_src_t new_src, uint32_t new_src_freq_mhz) { +#ifdef BOOTLOADER_BUILD if (new_src == SOC_CPU_CLK_SRC_PLL) { - bool truly_enabled = false; -#if BOOTLOADER_BUILD - rtc_clk_bbpll_enable(); - truly_enabled = true; + clk_ll_bbpll_enable(); + rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), new_src_freq_mhz); + } else if (new_src == SOC_CPU_CLK_SRC_XTAL_X2) { + clk_ll_xtal_x2_enable(); + } #else + if (new_src == SOC_CPU_CLK_SRC_PLL) { + bool need_configure = false; if (!s_is_pll_acquired) { - truly_enabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, true); + need_configure = !esp_clk_tree_is_power_on(SOC_ROOT_CIRCUIT_CLK_BBPLL); + esp_clk_tree_enable_src(SOC_MOD_CLK_BBPLL, true); s_is_pll_acquired = true; } -#endif - if (truly_enabled || (s_cur_pll_freq != new_src_freq_mhz)) { + if (need_configure || (s_cur_pll_freq != (int)new_src_freq_mhz)) { rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), new_src_freq_mhz); } } else if (new_src == SOC_CPU_CLK_SRC_XTAL_X2) { -#if BOOTLOADER_BUILD - clk_ll_xtal_x2_enable(); -#else if (!s_is_xtal_x2_acquired) { - esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, true); + esp_clk_tree_enable_src(SOC_MOD_CLK_XTAL_X2, true); s_is_xtal_x2_acquired = true; } -#endif } +#endif } -static void rtc_clk_cpu_src_clk_disable(soc_cpu_clk_src_t old_src) +#ifndef BOOTLOADER_BUILD +static void rtc_clk_update_pll_state_on_cpu_src_switching_end(soc_cpu_clk_src_t old_src) { if ((old_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { -#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); + esp_clk_tree_enable_src(SOC_MOD_CLK_BBPLL, false); s_is_pll_acquired = false; - if (truly_disabled) { + if (!esp_clk_tree_is_power_on(SOC_ROOT_CIRCUIT_CLK_BBPLL)) { s_cur_pll_freq = 0; } -#endif } else if (old_src == SOC_CPU_CLK_SRC_XTAL_X2) { -#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); + esp_clk_tree_enable_src(SOC_MOD_CLK_XTAL_X2, false); s_is_xtal_x2_acquired = false; -#endif } } +#endif void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) { - soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src(); - - if (old_cpu_clk_src != config->source) { - rtc_clk_cpu_src_clk_enable(config->source, config->source_freq_mhz); + __attribute__((unused)) soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src(); +#ifndef BOOTLOADER_BUILD + bool src_changed = (old_cpu_clk_src != config->source); + if (src_changed) +#endif + { + rtc_clk_update_pll_state_on_cpu_src_switching_start(config->source, config->source_freq_mhz); } if (config->source == SOC_CPU_CLK_SRC_XTAL) { @@ -353,9 +344,11 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div); } - if (old_cpu_clk_src != config->source) { - rtc_clk_cpu_src_clk_disable(old_cpu_clk_src); +#ifndef BOOTLOADER_BUILD + if (src_changed) { + rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src); } +#endif } void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) @@ -391,20 +384,21 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) }; } +#ifndef BOOTLOADER_BUILD void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config) { + /* Mux only — Fall back to set_config when PLL/XTALx2 must be reacquired or recalibrated + * (s_cur_pll_freq == 0 after sleep). */ if (config->source == SOC_CPU_CLK_SRC_XTAL) { rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); } else if (config->source == SOC_CPU_CLK_SRC_PLL && - s_cur_pll_freq == config->source_freq_mhz) { + s_is_pll_acquired && + s_cur_pll_freq == (int)config->source_freq_mhz) { rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); } 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 -#if !BOOTLOADER_BUILD - && s_is_xtal_x2_acquired -#endif - ) { + } else if (config->source == SOC_CPU_CLK_SRC_XTAL_X2 && + s_is_xtal_x2_acquired) { rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div); } else { /* fallback */ @@ -419,22 +413,29 @@ void rtc_clk_cpu_freq_set_xtal(void) 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); + rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src); } } +#endif FORCE_IRAM_ATTR void rtc_clk_cpu_set_to_default_config(void) { int freq_mhz = (int)rtc_clk_xtal_freq_get(); rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); - s_cur_pll_freq = 0; // no disable PLL, but set freq to 0 to trigger a PLL calibration after wake-up from sleep } +#ifndef BOOTLOADER_BUILD void rtc_clk_cpu_freq_set_xtal_for_sleep(void) { - rtc_clk_cpu_set_to_default_config(); + int freq_mhz = (int)rtc_clk_xtal_freq_get(); + + /* Mux only — do not release CPU clk_tree hold. PMU restores ACTIVE XPD on + * wake; clearing s_cur_pll_freq forces recalibration via set_config fallback. */ + rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); + s_cur_pll_freq = 0; } +#endif void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz) { diff --git a/components/esp_hw_support/port/esp32s31/rtc_clk.c b/components/esp_hw_support/port/esp32s31/rtc_clk.c index 80421b6d386..f39f3a15946 100644 --- a/components/esp_hw_support/port/esp32s31/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s31/rtc_clk.c @@ -516,7 +516,9 @@ void rtc_clk_cpu_freq_set_xtal(void) int freq_mhz = (int)rtc_clk_xtal_freq_get(); rtc_clk_cpu_freq_to_xtal(freq_mhz, 1, false); - rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src); + if (old_cpu_clk_src != SOC_CPU_CLK_SRC_XTAL) { + rtc_clk_update_pll_state_on_cpu_src_switching_end(old_cpu_clk_src); + } } FORCE_IRAM_ATTR void rtc_clk_cpu_set_to_default_config(void)