Merge branch 'refactor/rtc_init_before_mspi_tuning_v5.0' into 'release/v5.0'

fix(startup): move rtc initialization before MSPI timing tuning to improve stability (v5.0)

See merge request espressif/esp-idf!33627
This commit is contained in:
Jiang Jiang Jian 2024-09-21 14:59:55 +08:00
commit f8a3ba1400
13 changed files with 94 additions and 61 deletions

View File

@ -434,14 +434,6 @@ build_examples_cmake_esp32c3:
IDF_TARGET: esp32c3
TEST_DIR: examples
build_examples_cmake_esp32h2:
extends:
- .build_cmake_template
- .rules:build:example_test-esp32h2
variables:
IDF_TARGET: esp32h2
TEST_DIR: examples
build_test_apps_esp32:
extends:
- .build_cmake_template

View File

@ -351,24 +351,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
*/

View File

@ -176,7 +176,7 @@ static void rtc_clk_bbpll_configure(rtc_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;
*
@ -459,25 +459,6 @@ static bool rtc_clk_set_bbpll_always_on(void)
return is_bbpll_on;
}
// 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

@ -60,6 +60,10 @@ void IRAM_ATTR bootloader_fill_random(void *buffer, size_t length)
}
}
void esp_rtc_init(void)
{
}
void esp_clk_init(void)
{
s_warn();

View File

@ -420,6 +420,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.
*
@ -428,15 +432,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
extern void rtc_clk_recalib_bbpll(void);
rtc_clk_recalib_bbpll();
#endif
#if CONFIG_IDF_TARGET_ESP32S3
// 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.
// On other chips, this feature is not provided by HW, or hasn't been tested yet.
spi_timing_flash_tuning();
#endif

View File

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

View File

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

View File

@ -51,12 +51,19 @@ 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;
@ -65,7 +72,12 @@ static const char *TAG = "clk";
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
@ -266,3 +278,21 @@ __attribute__((weak)) void esp_perip_clk_init(void)
*/
periph_module_enable(PERIPH_TIMG0_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);
}
}

View File

@ -57,7 +57,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();
@ -71,7 +71,10 @@ static const char *TAG = "clk";
cfg.cali_ocode = 1;
}
rtc_init(cfg);
}
__attribute__((weak)) void esp_clk_init(void)
{
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled();

View File

@ -60,7 +60,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);
@ -74,7 +74,10 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk);
}
}
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);

View File

@ -53,9 +53,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);
@ -64,7 +71,10 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk);
cfg.cali_ocode = 1;
}
rtc_init(cfg);
}
__attribute__((weak)) void esp_clk_init(void)
{
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled();
@ -324,3 +334,21 @@ __attribute__((weak)) void esp_perip_clk_init(void)
*/
periph_module_enable(PERIPH_TIMG0_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);
}
}

View File

@ -77,7 +77,7 @@ build_stage1() {
--build-log ${BUILD_LOG_CMAKE} \
--size-file size.json \
--collect-size-info size_info.txt \
--default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32h2
--default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3
}
# Default arguments

View File

@ -513,7 +513,7 @@ function run_tests()
print_status "Test build ESP-IDF as a library to a custom CMake projects for all targets"
IDF_AS_LIB=$IDF_PATH/examples/build_system/cmake/idf_as_lib
# note: we just need to run cmake
for TARGET in "esp32" "esp32s2" "esp32s3" "esp32c3" "esp32h2" "esp32c2"
for TARGET in "esp32" "esp32s2" "esp32s3" "esp32c3" "esp32c2"
do
echo "Build idf_as_lib for $TARGET target"
rm -rf build