Skip to content

Commit

Permalink
Merge branch 'refactor/rtc_init_before_mspi_tuning' into 'master'
Browse files Browse the repository at this point in the history
fix(startup): move rtc initialization before MSPI timing tuning to improve stability

See merge request espressif/esp-idf!31200
  • Loading branch information
ginkgm committed Jun 19, 2024
2 parents f791c6e + 5b71b94 commit e57c686
Show file tree
Hide file tree
Showing 19 changed files with 174 additions and 120 deletions.
6 changes: 0 additions & 6 deletions components/esp_hw_support/include/esp_private/rtc_clk.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 0 additions & 18 deletions components/esp_hw_support/port/esp32c2/rtc_clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
19 changes: 0 additions & 19 deletions components/esp_hw_support/port/esp32c6/rtc_clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
19 changes: 0 additions & 19 deletions components/esp_hw_support/port/esp32c61/rtc_clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
20 changes: 1 addition & 19 deletions components/esp_hw_support/port/esp32h2/rtc_clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}
}
21 changes: 1 addition & 20 deletions components/esp_hw_support/port/esp32s3/rtc_clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
*
Expand Down Expand Up @@ -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
*/
Expand Down
8 changes: 6 additions & 2 deletions components/esp_system/fpga_overrides_clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}
Expand Down
13 changes: 6 additions & 7 deletions components/esp_system/port/cpu_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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

Expand Down
9 changes: 9 additions & 0 deletions components/esp_system/port/include/esp_clk_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
5 changes: 4 additions & 1 deletion components/esp_system/port/soc/esp32/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
32 changes: 31 additions & 1 deletion components/esp_system/port/soc/esp32c2/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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);
}
}
5 changes: 4 additions & 1 deletion components/esp_system/port/soc/esp32c3/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down
8 changes: 7 additions & 1 deletion components/esp_system/port/soc/esp32c5/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
32 changes: 31 additions & 1 deletion components/esp_system/port/soc/esp32c6/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}
Loading

0 comments on commit e57c686

Please sign in to comment.