fix(clk): update H4 to use 64MHz clock for mspi

And add pll clock ref count
This commit is contained in:
Song Ruo Jing
2025-12-16 19:27:56 +08:00
committed by Chen Jichang
parent 8702d5c986
commit 215c9993bf
22 changed files with 129 additions and 69 deletions
+2 -1
View File
@@ -41,7 +41,8 @@ menu "Bootloader config"
config BOOTLOADER_CPU_CLK_FREQ_MHZ
int
default 64 if IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32H21 || IDF_TARGET_ESP32H4
default 48 if IDF_TARGET_ESP32H21
default 64 if IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32H4
default 90 if IDF_TARGET_ESP32P4 && ESP32P4_SELECTS_REV_LESS_V3
default 100 if IDF_TARGET_ESP32P4 && !ESP32P4_SELECTS_REV_LESS_V3
default 80
@@ -27,6 +27,7 @@
#include "hal/cache_hal.h"
#include "hal/cache_ll.h"
#include "hal/mspi_ll.h"
#include "hal/clk_tree_ll.h"
ESP_LOG_ATTR_TAG(TAG, "boot.esp32h4");
@@ -88,12 +89,13 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
static void IRAM_ATTR bootloader_mspi_clock_init(void)
{
// // To raise the MSPI clock to 64MHz, needs to enable the 64MHz clock source, which is XTAL_X2_CLK
// // (FPGA image fixed MSPI0/1 clock to 64MHz)
// clk_ll_xtal_x2_enable();
// _mspi_timing_ll_set_flash_clk_src(0, FLASH_CLK_SRC_PLL_F64M);
// IDF-13632
_mspi_timing_ll_set_flash_clk_src(0, FLASH_CLK_SRC_PLL_F48M);
// To raise the MSPI clock to 64MHz, needs to enable the 64MHz clock source, which is XTAL_X2_CLK
// (FPGA image fixed MSPI0/1 clock to 64MHz)
clk_ll_xtal_x2_enable();
_mspi_timing_ll_set_flash_clk_src(0, FLASH_CLK_SRC_REF_F64M);
// Note: MSPI clock source cannot be set to 48MHz in bootloader
// 48MHz is derived from SPLL, and SPLL is not ready to be used in bootloader for H4
// (calibration not done since bootloader CPU clock source is also set to 64MHz, which does not rely on SPLL)
}
static void update_flash_config(const esp_image_header_t *bootloader_hdr)
@@ -68,10 +68,9 @@ static inline void _mspi_timing_ll_set_flash_clk_src(uint32_t mspi_id, soc_perip
case FLASH_CLK_SRC_RC_FAST:
PCR.mspi_clk_conf.mspi_func_clk_sel = 1;
break;
// case FLASH_CLK_SRC_PLL_F64M:
// PCR.mspi_clk_conf.mspi_func_clk_sel = 2;
// break;
// TODO: [ESP32H4] IDF-13632, support 64M
case FLASH_CLK_SRC_REF_F64M:
PCR.mspi_clk_conf.mspi_func_clk_sel = 2;
break;
case FLASH_CLK_SRC_PLL_F48M:
PCR.mspi_clk_conf.mspi_func_clk_sel = 3;
break;
@@ -101,13 +101,14 @@ void esp_clk_tree_initialize(void);
/**
* @brief Enable / Disable the power of the clock circuit
*
* This function is only used in rtc_clk.c for now.
*
* @param[in] clk_circuit Clock circuits, in soc_root_clk_circuit_t
* @param[in] enable Enable / Disable the power of the clock circuit
*
* @return
* - ESP_OK Success
* @return True if power control is truly toggled, false otherwise
*/
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable);
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable);
/**
* @brief Get the power status of the clock circuit
@@ -80,10 +80,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -74,10 +74,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -74,10 +74,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -111,10 +111,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -74,10 +74,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -74,10 +74,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -71,10 +71,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -82,7 +82,7 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
switch (clk_circuit) {
// case SOC_ROOT_CIRCUIT_CLK_XTAL_X2:
@@ -103,7 +103,7 @@ esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool ena
default:
break;
}
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -116,5 +116,5 @@ esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
default:
break;
}
return ESP_OK; // TODO: PM-354
return ESP_OK; // TODO: PM-653
}
@@ -64,15 +64,22 @@ uint32_t *freq_value)
}
static int16_t s_xtal_x2_ref_cnt = 0;
static int16_t s_bbpll_ref_cnt = 0;
void esp_clk_tree_initialize(void)
{
// TODO: IDF-14962
// // In bootloader, flash clock source will always be switched to use XTAL_X2 clock
// s_xtal_x2_ref_cnt++;
if (clk_ll_cpu_get_src() == SOC_CPU_CLK_SRC_XTAL_X2) {
// Power
// In bootloader, flash clock source will always be switched to use XTAL_X2 clock
s_xtal_x2_ref_cnt++;
soc_cpu_clk_src_t cpu_clk_src_btld = clk_ll_cpu_get_src();
if (cpu_clk_src_btld == SOC_CPU_CLK_SRC_XTAL_X2) {
s_xtal_x2_ref_cnt++;
} else if (cpu_clk_src_btld == SOC_CPU_CLK_SRC_PLL) {
s_bbpll_ref_cnt++;
}
// Gating
// PLL_F64M ++ for MSPI
}
bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
@@ -80,14 +87,17 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
switch (clk_circuit) {
case SOC_ROOT_CIRCUIT_CLK_XTAL_X2:
return s_xtal_x2_ref_cnt > 0;
case SOC_ROOT_CIRCUIT_CLK_BBPLL:
return s_bbpll_ref_cnt > 0;
default:
break;
}
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
bool toggled = false;
switch (clk_circuit) {
case SOC_ROOT_CIRCUIT_CLK_XTAL_X2:
if (enable) {
@@ -98,31 +108,58 @@ esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool ena
if (s_xtal_x2_ref_cnt == 1) {
clk_ll_xtal_x2_enable();
toggled = true;
} else if (s_xtal_x2_ref_cnt == 0) {
clk_ll_xtal_x2_disable();
toggled = true;
}
assert(s_xtal_x2_ref_cnt >= 0);
break;
case SOC_ROOT_CIRCUIT_CLK_BBPLL:
if (enable) {
s_bbpll_ref_cnt++;
} else {
s_bbpll_ref_cnt--;
}
// Note that a calibration is usually needed after enabling BBPLL
if (s_bbpll_ref_cnt == 1) {
clk_ll_bbpll_enable();
toggled = true;
} else if (s_bbpll_ref_cnt == 0) {
clk_ll_bbpll_disable();
toggled = true;
}
assert(s_bbpll_ref_cnt >= 0);
break;
default:
break;
}
return ESP_OK; // TODO: PM-456
return toggled;
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
{
switch (clk_src) {
case SOC_MOD_CLK_XTAL_X2_F32M:
// later, here should handle ref count for XTAL_X2_F32M clock gating, then also handle XTAL_X2 circuit enable/disable
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, enable);
break;
case SOC_MOD_CLK_XTAL_X2_F64M:
// later, here should handle ref count for XTAL_X2_F64M clock gating, then also handle XTAL_X2 circuit enable/disable
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, enable);
break;
default:
break;
PERIPH_RCC_ATOMIC() {
switch (clk_src) {
case SOC_MOD_CLK_XTAL_X2_F32M:
// later, here should handle ref count for XTAL_X2_F32M clock gating, then also handle XTAL_X2 circuit enable/disable
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, enable);
break;
case SOC_MOD_CLK_XTAL_X2_F64M:
// later, here should handle ref count for XTAL_X2_F64M clock gating, then also handle XTAL_X2 circuit enable/disable
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, enable);
break;
// case SOC_MOD_CLK_PLL_FxxM:
// bool truly_toggled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, enable);
// if (enable && truly_toggled) {
// ESP_LOGW(TAG, "BBPLL enabled, a calibration may be needed");
// }
default:
break;
}
}
return ESP_OK; // TODO: PM-456
}
@@ -131,6 +131,7 @@ soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
return clk_ll_rtc_fast_get_src();
}
#if BOOTLOADER_BUILD
static void rtc_clk_bbpll_disable(void)
{
clk_ll_bbpll_disable();
@@ -141,6 +142,7 @@ static void rtc_clk_bbpll_enable(void)
{
clk_ll_bbpll_enable();
}
#endif
static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq)
{
@@ -276,8 +278,16 @@ __attribute__((weak)) void rtc_clk_set_cpu_switch_to_bbpll(int event_id)
static void rtc_clk_cpu_src_clk_enable(soc_cpu_clk_src_t new_src, uint32_t new_src_freq_mhz)
{
if (new_src == SOC_CPU_CLK_SRC_PLL) {
bool truly_enabled = false;
#if BOOTLOADER_BUILD
rtc_clk_bbpll_enable();
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), new_src_freq_mhz);
truly_enabled = true;
#else
truly_enabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, true);
#endif
if (truly_enabled || (s_cur_pll_freq != new_src_freq_mhz)) {
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), new_src_freq_mhz);
}
} else if (new_src == SOC_CPU_CLK_SRC_XTAL_X2) {
#if BOOTLOADER_BUILD
clk_ll_xtal_x2_enable();
@@ -290,7 +300,14 @@ static void rtc_clk_cpu_src_clk_enable(soc_cpu_clk_src_t new_src, uint32_t new_s
static void rtc_clk_cpu_src_clk_disable(soc_cpu_clk_src_t old_src)
{
if ((old_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) {
#if BOOTLOADER_BUILD
rtc_clk_bbpll_disable();
#else
bool truly_disabled = esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, false);
if (truly_disabled) {
s_cur_pll_freq = 0;
}
#endif
} else if (old_src == SOC_CPU_CLK_SRC_XTAL_X2) {
#if BOOTLOADER_BUILD
clk_ll_xtal_x2_disable();
@@ -379,7 +396,11 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
void rtc_clk_cpu_freq_set_xtal(void)
{
rtc_clk_cpu_set_to_default_config();
#if BOOTLOADER_BUILD
rtc_clk_bbpll_disable();
#else
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_BBPLL, false);
#endif
}
void rtc_clk_cpu_set_to_default_config(void)
@@ -109,10 +109,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -78,10 +78,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -78,10 +78,10 @@ bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
return false; // TODO: PM-653
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
@@ -291,10 +291,9 @@ static void s_config_psram_clock(bool init_state)
} else {
// This function can be extended if we have other psram frequency
#if (CONFIG_SPIRAM_SPEED == 80) || (CONFIG_SPIRAM_SPEED == 48)
// IDF-13632, update 48M to 64M
#if (CONFIG_SPIRAM_SPEED == 80) || (CONFIG_SPIRAM_SPEED == 64)
clock_conf = psram_ctrlr_ll_calculate_clock_reg(1);
#elif (CONFIG_SPIRAM_SPEED == 40)
#elif (CONFIG_SPIRAM_SPEED == 40) || (CONFIG_SPIRAM_SPEED == 32)
clock_conf = psram_ctrlr_ll_calculate_clock_reg(2);
#endif
psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_0, clock_conf);
+6 -4
View File
@@ -19,17 +19,19 @@ menu "SPI RAM config"
choice SPIRAM_SPEED
prompt "Set RAM clock speed"
default SPIRAM_SPEED_48M
default SPIRAM_SPEED_64M
help
Select the speed for the SPI RAM chip.
config SPIRAM_SPEED_48M
bool "48Mhz clock speed"
config SPIRAM_SPEED_64M
bool "64Mhz clock speed"
config SPIRAM_SPEED_32M
bool "32Mhz clock speed"
endchoice
config SPIRAM_SPEED
int
default 48 if SPIRAM_SPEED_48M
default 32 if SPIRAM_SPEED_32M
default 64 if SPIRAM_SPEED_64M
config SPIRAM_FETCH_INSTRUCTIONS
@@ -13,4 +13,5 @@ static inline void esp_crypto_clk_init(void)
{
// Set crypto clock (`clk_sec`) to use 96M PLL clock
REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x3);
// TODO: IDF-12266 need to call esp_clk_tree_enable_src() to acquire PLL 96M clock gating
}
@@ -287,7 +287,7 @@ typedef enum {
FLASH_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
FLASH_CLK_SRC_REF_F64M = SOC_MOD_CLK_XTAL_X2_F64M, /*!< Select XTAL_X2_F64M as the source clock */
FLASH_CLK_SRC_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_F48M as the source clock */
FLASH_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
FLASH_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL_X2_F64M, /*!< Select XTAL_X2_F64M as the default clock choice */
FLASH_CLK_SRC_ROM_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as ROM default clock source */
} soc_periph_flash_clk_src_t;
@@ -1,12 +1,9 @@
choice ESPTOOLPY_FLASHFREQ
prompt "Flash SPI speed"
default ESPTOOLPY_FLASHFREQ_32M if IDF_ENV_FPGA
default ESPTOOLPY_FLASHFREQ_48M
config ESPTOOLPY_FLASHFREQ_48M
bool "48 MHz"
default ESPTOOLPY_FLASHFREQ_64M
config ESPTOOLPY_FLASHFREQ_64M
bool "64 MHz"
config ESPTOOLPY_FLASHFREQ_32M
bool "32 MHz"
depends on IDF_ENV_FPGA
config ESPTOOLPY_FLASHFREQ_24M
bool "24 MHz"
endchoice