Skip to content

Commit

Permalink
Merge branch 'bugfix/recalib_bbpll_before_tuning_v5.1' into 'release/…
Browse files Browse the repository at this point in the history
…v5.1'

fix(bbpll): fix bbpll may not lock or not stable bug for stop early (ESP32C2/S3/C6/H2) (v5.1)

See merge request espressif/esp-idf!28285
  • Loading branch information
ginkgm committed Jan 17, 2024
2 parents 9c4b89c + a055fcb commit 89cc908
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 0 deletions.
6 changes: 6 additions & 0 deletions components/esp_hw_support/include/esp_private/rtc_clk.h
Expand Up @@ -44,6 +44,12 @@ void rtc_clk_bbpll_add_consumer(void);
*/
void rtc_clk_bbpll_remove_consumer(void);

/**
* @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
19 changes: 19 additions & 0 deletions components/esp_hw_support/port/esp32c2/rtc_clk.c
Expand Up @@ -128,6 +128,7 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
/* WAIT CALIBRATION DONE */
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
esp_rom_delay_us(10);
/* BBPLL CALIBRATION STOP */
regi2c_ctrl_ll_bbpll_calibration_stop();

Expand Down Expand Up @@ -357,6 +358,24 @@ 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
*/
Expand Down
20 changes: 20 additions & 0 deletions components/esp_hw_support/port/esp32c6/rtc_clk.c
Expand Up @@ -168,6 +168,7 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
/* WAIT CALIBRATION DONE */
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
esp_rom_delay_us(10);
/* BBPLL CALIBRATION STOP */
regi2c_ctrl_ll_bbpll_calibration_stop();
rtc_clk_enable_i2c_ana_master_clock(false);
Expand Down Expand Up @@ -421,6 +422,25 @@ 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
*/
Expand Down
19 changes: 19 additions & 0 deletions components/esp_hw_support/port/esp32h2/rtc_clk.c
Expand Up @@ -185,6 +185,7 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
/* WAIT CALIBRATION DONE */
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
esp_rom_delay_us(10);
/* BBPLL CALIBRATION STOP */
regi2c_ctrl_ll_bbpll_calibration_stop();
rtc_clk_enable_i2c_ana_master_clock(false);
Expand Down Expand Up @@ -474,3 +475,21 @@ 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);
}
}
20 changes: 20 additions & 0 deletions components/esp_hw_support/port/esp32s3/rtc_clk.c
Expand Up @@ -172,6 +172,7 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
/* WAIT CALIBRATION DONE */
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
esp_rom_delay_us(10);
/* BBPLL CALIBRATION STOP */
regi2c_ctrl_ll_bbpll_calibration_stop();

Expand Down Expand Up @@ -459,6 +460,25 @@ 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
*/
Expand Down
9 changes: 9 additions & 0 deletions components/esp_system/Kconfig
Expand Up @@ -561,6 +561,15 @@ menu "ESP System Settings"
(2). For special workflow, the chip needs do more things instead of restarting directly. This part
needs to be done in callback function of interrupt.

config ESP_SYSTEM_BBPLL_RECALIB
bool "Re-calibration BBPLL at startup"
depends on IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2
default y
help
This configuration helps to address an BBPLL inaccurate issue when boot from certain bootloader version,
which may increase about the boot-up time by about 200 us. Disable this when your bootloader is built with
ESP-IDF version v5.2 and above.

endmenu # ESP System Settings

menu "IPC (Inter-Processor Call)"
Expand Down
9 changes: 9 additions & 0 deletions components/esp_system/port/cpu_start.c
Expand Up @@ -17,6 +17,8 @@
#include "esp_efuse.h"
#include "esp_private/cache_err_int.h"
#include "esp_clk_internal.h"
// For workaround `rtc_clk_recalib_bbpll()`
#include "esp_private/rtc_clk.h"

#include "esp_rom_efuse.h"
#include "esp_rom_uart.h"
Expand Down Expand Up @@ -454,7 +456,14 @@ 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
mspi_timing_flash_tuning();
#endif

Expand Down

0 comments on commit 89cc908

Please sign in to comment.