diff --git a/components/esp_hw_support/include/esp_private/rtc_clk.h b/components/esp_hw_support/include/esp_private/rtc_clk.h index 5c143b8396..52610fa0d1 100644 --- a/components/esp_hw_support/include/esp_private/rtc_clk.h +++ b/components/esp_hw_support/include/esp_private/rtc_clk.h @@ -74,12 +74,6 @@ uint32_t rtc_clk_mpll_get_freq(void); #endif //#if SOC_CLK_MPLL_SUPPORTED -/** - * @brief Workaround for C2, S3, C6, H2. Trigger the calibration of PLL. Should be called when the bootloader doesn't provide a good enough PLL accuracy. -*/ -void rtc_clk_recalib_bbpll(void); - - #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/port/esp32c2/rtc_clk.c b/components/esp_hw_support/port/esp32c2/rtc_clk.c index 20ef6d1d56..425b72b17f 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c2/rtc_clk.c @@ -356,24 +356,6 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} - /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk.c b/components/esp_hw_support/port/esp32c6/rtc_clk.c index 3beac67c3c..6ac075923b 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk.c @@ -422,25 +422,6 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} - - /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32c61/rtc_clk.c b/components/esp_hw_support/port/esp32c61/rtc_clk.c index 4644e1df39..3a20ede1b9 100644 --- a/components/esp_hw_support/port/esp32c61/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c61/rtc_clk.c @@ -427,25 +427,6 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} - - /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32h2/rtc_clk.c b/components/esp_hw_support/port/esp32h2/rtc_clk.c index f2ca1ca3ff..27898a95b4 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32h2/rtc_clk.c @@ -238,7 +238,7 @@ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) /** * Switch to FLASH_PLL as cpu clock source. * On ESP32H2, FLASH_PLL frequency is 64MHz. - * PLL must alreay be enabled. + * PLL must already be enabled. */ static void rtc_clk_cpu_freq_to_flash_pll(uint32_t cpu_freq_mhz, uint32_t cpu_divider) { @@ -474,21 +474,3 @@ bool rtc_dig_8m_enabled(void) { return clk_ll_rc_fast_digi_is_enabled(); } - -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. Flash_PLL comes from the same source as PLL. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL || old_config.source == SOC_CPU_CLK_SRC_FLASH_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} diff --git a/components/esp_hw_support/port/esp32s3/rtc_clk.c b/components/esp_hw_support/port/esp32s3/rtc_clk.c index a795619b99..1416b2862c 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s3/rtc_clk.c @@ -187,7 +187,7 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) { - /* There are totally 6 LDO slaves(all on by default). At the moment of swithing LDO slave, LDO voltage will also change instantaneously. + /* There are totally 6 LDO slaves(all on by default). At the moment of switching LDO slave, LDO voltage will also change instantaneously. * LDO slave can reduce the voltage change caused by switching frequency. * CPU frequency <= 40M : just open 3 LDO slaves; CPU frequency = 80M : open 4 LDO slaves; CPU frequency = 160M : open 5 LDO slaves; CPU frequency = 240M : open 6 LDO slaves; * @@ -460,25 +460,6 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } -// Workaround for bootloader not calibrated well issue. -// Placed in IRAM because disabling BBPLL may influence the cache -void rtc_clk_recalib_bbpll(void) -{ - rtc_cpu_freq_config_t old_config; - rtc_clk_cpu_freq_get_config(&old_config); - - // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. - // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. - // Turn off the BBPLL and do calibration again to fix the issue. - // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's - // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. - if (old_config.source == SOC_CPU_CLK_SRC_PLL) { - rtc_clk_cpu_freq_set_xtal(); - rtc_clk_cpu_freq_set_config(&old_config); - } -} - - /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_system/fpga_overrides_clk.c b/components/esp_system/fpga_overrides_clk.c index a3b4b43de5..1b1f9efad2 100644 --- a/components/esp_system/fpga_overrides_clk.c +++ b/components/esp_system/fpga_overrides_clk.c @@ -62,14 +62,18 @@ void bootloader_clock_configure(void) REG_WRITE(RTC_XTAL_FREQ_REG, (xtal_freq_mhz) | ((xtal_freq_mhz) << 16)); } -void esp_clk_init(void) +void esp_rtc_init(void) { - s_warn(); #if SOC_PMU_SUPPORTED pmu_init(); #endif } +void esp_clk_init(void) +{ + s_warn(); +} + void esp_perip_clk_init(void) { } diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 2469b31506..798cd5e97d 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -541,6 +541,10 @@ void IRAM_ATTR call_start_cpu0(void) // For Octal flash, it's hard to implement a read_id function in OPI mode for all vendors. // So we have to read it here in SPI mode, before entering the OPI mode. bootloader_flash_update_id(); + + // Configure the power related stuff. After this the MSPI timing tuning can be done. + esp_rtc_init(); + /** * This function initialise the Flash chip to the user-defined settings. * @@ -549,14 +553,9 @@ void IRAM_ATTR call_start_cpu0(void) * In this stage, we re-configure the Flash (and MSPI) to required configuration */ spi_flash_init_chip_state(); - - // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. - // Do calibration again here so that we can use better clock for the timing tuning. -#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB - rtc_clk_recalib_bbpll(); -#endif #if SOC_MEMSPI_SRC_FREQ_120M - // This function needs to be called when PLL is enabled + // This function needs to be called when PLL is enabled. Needs to be called after spi_flash_init_chip_state in case + // some state of flash is modified. mspi_timing_flash_tuning(); #endif diff --git a/components/esp_system/port/include/esp_clk_internal.h b/components/esp_system/port/include/esp_clk_internal.h index 358002e2a1..a3829368b3 100644 --- a/components/esp_system/port/include/esp_clk_internal.h +++ b/components/esp_system/port/include/esp_clk_internal.h @@ -18,6 +18,15 @@ extern "C" { * Private clock-related functions */ +/** + * @brief Initialize rtc-related settings + * + * Called from cpu_start.c, not intended to be called from other places. + * This function configures the power related stuff. + * After this the MSPI timing tuning can be done. + */ +void esp_rtc_init(void); + /** * @brief Initialize clock-related settings * diff --git a/components/esp_system/port/soc/esp32/clk.c b/components/esp_system/port/soc/esp32/clk.c index 0de819e687..88f72ff947 100644 --- a/components/esp_system/port/soc/esp32/clk.c +++ b/components/esp_system/port/soc/esp32/clk.c @@ -106,11 +106,14 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk) esp_clk_slowclk_cal_set(cal_val); } -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { rtc_config_t cfg = RTC_CONFIG_DEFAULT(); rtc_init(cfg); +} +__attribute__((weak)) void esp_clk_init(void) +{ #if (CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS || CONFIG_APP_INIT_CLK) /* Check the bootloader set the XTAL frequency. diff --git a/components/esp_system/port/soc/esp32c2/clk.c b/components/esp_system/port/soc/esp32c2/clk.c index ef75764dac..6cc267ea6c 100644 --- a/components/esp_system/port/soc/esp32c2/clk.c +++ b/components/esp_system/port/soc/esp32c2/clk.c @@ -51,11 +51,18 @@ typedef enum { } slow_clk_sel_t; static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); +static __attribute__((unused)) void recalib_bbpll(void); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { +#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB + // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. + // Do calibration again here so that we can use better clock for the timing tuning. + recalib_bbpll(); +#endif + #if !CONFIG_IDF_ENV_FPGA rtc_config_t cfg = RTC_CONFIG_DEFAULT(); soc_reset_reason_t rst_reas; @@ -64,7 +71,12 @@ __attribute__((weak)) void esp_clk_init(void) cfg.cali_ocode = 1; } rtc_init(cfg); +#endif +} +__attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA #ifndef CONFIG_XTAL_FREQ_AUTO assert(rtc_clk_xtal_freq_get() == CONFIG_XTAL_FREQ); #endif @@ -265,3 +277,21 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); } + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +static void IRAM_ATTR NOINLINE_ATTR recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index 972dc75d1b..ece3d4c732 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -56,7 +56,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { #if !CONFIG_IDF_ENV_FPGA rtc_config_t cfg = RTC_CONFIG_DEFAULT(); @@ -70,7 +70,10 @@ __attribute__((weak)) void esp_clk_init(void) cfg.cali_ocode = 1; } rtc_init(cfg); +} +__attribute__((weak)) void esp_clk_init(void) +{ assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); diff --git a/components/esp_system/port/soc/esp32c5/clk.c b/components/esp_system/port/soc/esp32c5/clk.c index c1dab5b041..7242255e4d 100644 --- a/components/esp_system/port/soc/esp32c5/clk.c +++ b/components/esp_system/port/soc/esp32c5/clk.c @@ -45,7 +45,7 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; // TODO: [ESP32C5] IDF-8642 -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { #if !CONFIG_IDF_ENV_FPGA #if SOC_PMU_SUPPORTED @@ -54,7 +54,13 @@ __attribute__((weak)) void esp_clk_init(void) if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { esp_ocode_calib_init(); } +#endif +} +// TODO: [ESP32C5] IDF-8642 +__attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA assert((rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_48M) || (rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M)); rtc_clk_8m_enable(true); diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index e2b1e8d20e..42a2f8f00a 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -58,17 +58,29 @@ #define MHZ (1000000) static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); +static __attribute__((unused)) void recalib_bbpll(void); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { +#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB + // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. + // Do calibration again here so that we can use better clock for the timing tuning. + recalib_bbpll(); +#endif + #if !CONFIG_IDF_ENV_FPGA pmu_init(); if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { esp_ocode_calib_init(); } +#endif +} +__attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); rtc_clk_8m_enable(true); @@ -302,3 +314,21 @@ __attribute__((weak)) void esp_perip_clk_init(void) WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); } } + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +static void IRAM_ATTR NOINLINE_ATTR recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} diff --git a/components/esp_system/port/soc/esp32c61/clk.c b/components/esp_system/port/soc/esp32c61/clk.c index 9eabae2593..9a82793f6f 100644 --- a/components/esp_system/port/soc/esp32c61/clk.c +++ b/components/esp_system/port/soc/esp32c61/clk.c @@ -41,14 +41,19 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { #if !CONFIG_IDF_ENV_FPGA pmu_init(); if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { esp_ocode_calib_init(); } +#endif +} +__attribute__((weak)) void esp_clk_init(void) +{ +#if !CONFIG_IDF_ENV_FPGA assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); rtc_clk_8m_enable(true); diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 0523bd8c92..87e2140cf3 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -58,14 +58,26 @@ #define MHZ (1000000) static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); +static __attribute__((unused)) void recalib_bbpll(void); static const char *TAG = "clk"; +void esp_rtc_init(void) +{ +#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB + // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. + // Do calibration again here so that we can use better clock for the timing tuning. + recalib_bbpll(); +#endif + +#if !CONFIG_IDF_ENV_FPGA + pmu_init(); +#endif +} + __attribute__((weak)) void esp_clk_init(void) { #if !CONFIG_IDF_ENV_FPGA - pmu_init(); - assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_32M); rtc_clk_8m_enable(true); @@ -290,3 +302,21 @@ __attribute__((weak)) void esp_perip_clk_init(void) WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); } } + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +static void IRAM_ATTR NOINLINE_ATTR recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. Flash_PLL comes from the same source as PLL. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL || old_config.source == SOC_CPU_CLK_SRC_FLASH_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} diff --git a/components/esp_system/port/soc/esp32p4/clk.c b/components/esp_system/port/soc/esp32p4/clk.c index c00287e5a1..85332e67ae 100644 --- a/components/esp_system/port/soc/esp32p4/clk.c +++ b/components/esp_system/port/soc/esp32p4/clk.c @@ -41,12 +41,15 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { #if SOC_PMU_SUPPORTED pmu_init(); #endif //SOC_PMU_SUPPORTED +} +__attribute__((weak)) void esp_clk_init(void) +{ assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); rtc_clk_8m_enable(true); diff --git a/components/esp_system/port/soc/esp32s2/clk.c b/components/esp_system/port/soc/esp32s2/clk.c index 7da508fde7..45d932ba52 100644 --- a/components/esp_system/port/soc/esp32s2/clk.c +++ b/components/esp_system/port/soc/esp32s2/clk.c @@ -59,7 +59,7 @@ typedef enum { static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { rtc_config_t cfg = RTC_CONFIG_DEFAULT(); soc_reset_reason_t rst_reas = esp_rom_get_reset_reason(0); @@ -73,7 +73,10 @@ __attribute__((weak)) void esp_clk_init(void) } } rtc_init(cfg); +} +__attribute__((weak)) void esp_clk_init(void) +{ bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); rtc_clk_8m_enable(true, rc_fast_d256_is_enabled); rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); diff --git a/components/esp_system/port/soc/esp32s3/clk.c b/components/esp_system/port/soc/esp32s3/clk.c index 4589d5e4f9..fac148fb41 100644 --- a/components/esp_system/port/soc/esp32s3/clk.c +++ b/components/esp_system/port/soc/esp32s3/clk.c @@ -54,9 +54,16 @@ typedef enum { } slow_clk_sel_t; static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); +static __attribute__((unused)) void recalib_bbpll(void); -__attribute__((weak)) void esp_clk_init(void) +void esp_rtc_init(void) { +#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB + // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. + // Do calibration again here so that we can use better clock for the timing tuning. + recalib_bbpll(); +#endif + rtc_config_t cfg = RTC_CONFIG_DEFAULT(); soc_reset_reason_t rst_reas; rst_reas = esp_rom_get_reset_reason(0); @@ -65,7 +72,10 @@ __attribute__((weak)) void esp_clk_init(void) cfg.cali_ocode = 1; } rtc_init(cfg); +} +__attribute__((weak)) void esp_clk_init(void) +{ assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M); bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); @@ -325,3 +335,21 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); } + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +static void IRAM_ATTR NOINLINE_ATTR recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +}