Merge branch 'bugfix/recalib_bbpll_before_tuning_v5.1' into 'release/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
This commit is contained in:
Michael (XIAO Xufeng) 2024-01-17 21:24:10 +08:00
commit 89cc9084ab
7 changed files with 102 additions and 0 deletions

View File

@ -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

View File

@ -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();
@ -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
*/

View File

@ -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);
@ -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
*/

View File

@ -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);
@ -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);
}
}

View File

@ -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();
@ -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
*/

View File

@ -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)"

View File

@ -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"
@ -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