Skip to content

Commit

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

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

See merge request espressif/esp-idf!28284
  • Loading branch information
ginkgm committed Jan 17, 2024
2 parents 6769179 + ea45c22 commit e1dfdf2
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,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 @@ -355,6 +356,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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,15 @@ menu "ESP System Settings"
This config allows to trigger a panic interrupt when Stack Pointer register goes out of allocated stack
memory bounds.

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
Original file line number Diff line number Diff line change
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 @@ -527,7 +529,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 e1dfdf2

Please sign in to comment.