From d4a821a03ea4f16fc01d19ab14563e716e060fb2 Mon Sep 17 00:00:00 2001 From: "yanzihan@espressif.com" Date: Tue, 19 Aug 2025 15:58:56 +0800 Subject: [PATCH] feat(clk): add 100m/200m/400m cpu freq & change clk cal & change blk version --- components/bootloader/Kconfig.projbuild | 3 +- .../esp_hw_support/port/esp32p4/pmu_param.c | 4 +- .../esp_hw_support/port/esp32p4/pmu_pvt.c | 6 +-- .../esp_hw_support/port/esp32p4/rtc_clk.c | 50 ++++++++++++++++++- .../esp_hw_support/port/esp32p4/rtc_time.c | 2 +- .../esp_system/port/soc/esp32p4/Kconfig.cpu | 7 ++- .../hal/esp32p4/include/hal/clk_tree_ll.h | 3 ++ .../soc/esp32p4/include/soc/clk_tree_defs.h | 1 + 8 files changed, 67 insertions(+), 9 deletions(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index e63a67da5b..4076357b2a 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -43,7 +43,8 @@ menu "Bootloader config" int default 64 if IDF_TARGET_ESP32H2 default 48 if IDF_TARGET_ESP32H21 || IDF_TARGET_ESP32H4 - default 90 if IDF_TARGET_ESP32P4 + default 90 if IDF_TARGET_ESP32P4 && ESP32P4_SELECTS_REV_LESS_V2 + default 100 if IDF_TARGET_ESP32P4 && !ESP32P4_SELECTS_REV_LESS_V2 default 80 help The CPU clock frequency to be at least raised to in 2nd bootloader. Invisible for users. diff --git a/components/esp_hw_support/port/esp32p4/pmu_param.c b/components/esp_hw_support/port/esp32p4/pmu_param.c index d49ed3a67b..f1dbecfb8b 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_param.c +++ b/components/esp_hw_support/port/esp32p4/pmu_param.c @@ -336,7 +336,7 @@ uint32_t get_act_hp_dbias(void) uint32_t hp_cali_dbias = HP_CALI_ACTIVE_DBIAS_DEFAULT; uint32_t blk_version = efuse_hal_blk_version(); uint32_t hp_cali_dbias_efuse = 0; - if (blk_version >= 2) { + if (blk_version >= 2 && blk_version < 100) { hp_cali_dbias_efuse = efuse_ll_get_active_hp_dbias(); } if (hp_cali_dbias_efuse > 0) { @@ -357,7 +357,7 @@ uint32_t get_act_lp_dbias(void) uint32_t lp_cali_dbias = LP_CALI_ACTIVE_DBIAS_DEFAULT; uint32_t blk_version = efuse_hal_blk_version(); uint32_t lp_cali_dbias_efuse = 0; - if (blk_version >= 2) { + if (blk_version >= 2 && blk_version < 100) { lp_cali_dbias_efuse = efuse_ll_get_active_lp_dbias(); } if (lp_cali_dbias_efuse > 0) { diff --git a/components/esp_hw_support/port/esp32p4/pmu_pvt.c b/components/esp_hw_support/port/esp32p4/pmu_pvt.c index 4c99b938c6..1eda49d0cc 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_pvt.c +++ b/components/esp_hw_support/port/esp32p4/pmu_pvt.c @@ -33,7 +33,7 @@ static uint8_t get_lp_hp_gap(void) int8_t lp_hp_gap = 0; uint32_t blk_version = efuse_hal_blk_version(); uint8_t lp_hp_gap_efuse = 0; - if (blk_version >= 2) { + if (blk_version >= 2 && blk_version < 100) { lp_hp_gap_efuse = efuse_ll_get_dbias_vol_gap(); bool gap_flag = lp_hp_gap_efuse >> 4; uint8_t gap_abs_value = lp_hp_gap_efuse & 0xf; @@ -77,7 +77,7 @@ static uint32_t pvt_get_lp_dbias(void) void pvt_auto_dbias_init(void) { uint32_t blk_version = efuse_hal_blk_version(); - if (blk_version >= 2) { + if (blk_version >= 2 && blk_version < 100) { SET_PERI_REG_MASK(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_160M_CLK_EN); SET_PERI_REG_MASK(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN); /*config for dbias func*/ @@ -120,7 +120,7 @@ void pvt_auto_dbias_init(void) void pvt_func_enable(bool enable) { uint32_t blk_version = efuse_hal_blk_version(); - if (blk_version >= 2){ + if (blk_version >= 2 && blk_version < 100){ if (enable) { SET_PERI_REG_MASK(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_160M_CLK_EN); diff --git a/components/esp_hw_support/port/esp32p4/rtc_clk.c b/components/esp_hw_support/port/esp32p4/rtc_clk.c index 86931160b9..4c3151f9bf 100644 --- a/components/esp_hw_support/port/esp32p4/rtc_clk.c +++ b/components/esp_hw_support/port/esp32p4/rtc_clk.c @@ -224,6 +224,7 @@ static void rtc_clk_cpu_freq_to_cpll_mhz(int cpu_freq_mhz, hal_utils_clk_div_t * uint32_t mem_divider = 1; uint32_t sys_divider = 1; // We are not going to change this uint32_t apb_divider = 1; +#if CONFIG_ESP32P4_SELECTS_REV_LESS_V2 switch (cpu_freq_mhz) { case 360: mem_divider = 2; @@ -244,6 +245,28 @@ static void rtc_clk_cpu_freq_to_cpll_mhz(int cpu_freq_mhz, hal_utils_clk_div_t * // To avoid such case, we will strictly do abort here. abort(); } +#else + switch (cpu_freq_mhz) { + case 400: + mem_divider = 2; + apb_divider = 2; + break; + case 200: + mem_divider = 1; + apb_divider = 2; + break; + case 100: + mem_divider = 1; + apb_divider = 1; + break; + default: + // Unsupported configuration + // This is dangerous to modify dividers. Hardware could automatically correct the divider, and it won't be + // reflected to the registers. Therefore, you won't even be able to calculate out the real mem_clk, apb_clk freq. + // To avoid such case, we will strictly do abort here. + abort(); + } +#endif // If it's upscaling, the divider of MEM/SYS/APB needs to be increased, to avoid illegal intermediate states, // the clock divider should be updated in the order from the APB_CLK to CPU_CLK. @@ -289,6 +312,7 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou // Keep default CPLL at 360MHz uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get(); +#if CONFIG_ESP32P4_SELECTS_REV_LESS_V2 if (freq_mhz <= xtal_freq && freq_mhz != 0) { divider.integer = xtal_freq / freq_mhz; real_freq_mhz = (xtal_freq + divider.integer / 2) / divider.integer; /* round */ @@ -296,7 +320,6 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou // no suitable divider return false; } - source_freq_mhz = xtal_freq; source = SOC_CPU_CLK_SRC_XTAL; } else if (freq_mhz == 90) { @@ -314,6 +337,30 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou source = SOC_CPU_CLK_SRC_CPLL; source_freq_mhz = CLK_LL_PLL_360M_FREQ_MHZ; divider.integer = 1; + } else { + // unsupported frequency + return false; + } +#else + if (freq_mhz <= xtal_freq && freq_mhz != 0) { + divider.integer = xtal_freq / freq_mhz; + real_freq_mhz = (xtal_freq + divider.integer / 2) / divider.integer; /* round */ + if (real_freq_mhz != freq_mhz) { + // no suitable divider + return false; + } + source_freq_mhz = xtal_freq; + source = SOC_CPU_CLK_SRC_XTAL; + } else if (freq_mhz == 100) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_CPLL; + source_freq_mhz = CLK_LL_PLL_400M_FREQ_MHZ; + divider.integer = 4; + } else if (freq_mhz == 200) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_CPLL; + source_freq_mhz = CLK_LL_PLL_400M_FREQ_MHZ; + divider.integer = 2; } else if (freq_mhz == 400) { // If CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ selects 400MHz, then at app startup stage will need a CPLL calibration to raise its freq from 360MHz to 400MHz real_freq_mhz = freq_mhz; @@ -324,6 +371,7 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou // unsupported frequency return false; } +#endif *out_config = (rtc_cpu_freq_config_t) { .source = source, .div = divider, diff --git a/components/esp_hw_support/port/esp32p4/rtc_time.c b/components/esp_hw_support/port/esp32p4/rtc_time.c index ffbd10ef39..159345ba83 100644 --- a/components/esp_hw_support/port/esp32p4/rtc_time.c +++ b/components/esp_hw_support/port/esp32p4/rtc_time.c @@ -182,7 +182,7 @@ static bool rtc_clk_cal_32k_valid(uint32_t xtal_freq, uint32_t slowclk_cycles, u uint32_t rtc_clk_cal(soc_clk_freq_calculation_src_t cal_clk_sel, uint32_t slowclk_cycles) { - slowclk_cycles /= (cal_clk_sel == CLK_CAL_RTC_SLOW) ? 1 : CLK_CAL_DIV_VAL(cal_clk_sel); + // slowclk_cycles /= (cal_clk_sel == CLK_CAL_RTC_SLOW) ? 1 : CLK_CAL_DIV_VAL(cal_clk_sel); assert(slowclk_cycles); soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk_sel, slowclk_cycles); diff --git a/components/esp_system/port/soc/esp32p4/Kconfig.cpu b/components/esp_system/port/soc/esp32p4/Kconfig.cpu index 18ad802598..9a9ab5c095 100644 --- a/components/esp_system/port/soc/esp32p4/Kconfig.cpu +++ b/components/esp_system/port/soc/esp32p4/Kconfig.cpu @@ -1,7 +1,8 @@ choice ESP_DEFAULT_CPU_FREQ_MHZ prompt "CPU frequency" default ESP_DEFAULT_CPU_FREQ_MHZ_40 if IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING - default ESP_DEFAULT_CPU_FREQ_MHZ_360 + default ESP_DEFAULT_CPU_FREQ_MHZ_360 if ESP32P4_SELECTS_REV_LESS_V2 + default ESP_DEFAULT_CPU_FREQ_MHZ_400 help CPU frequency to be set on application startup. @@ -10,9 +11,13 @@ choice ESP_DEFAULT_CPU_FREQ_MHZ depends on IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING config ESP_DEFAULT_CPU_FREQ_MHZ_360 bool "360 MHz" + depends on ESP32P4_SELECTS_REV_LESS_V2 + config ESP_DEFAULT_CPU_FREQ_MHZ_400 + bool "400 MHz" endchoice config ESP_DEFAULT_CPU_FREQ_MHZ int default 40 if ESP_DEFAULT_CPU_FREQ_MHZ_40 default 360 if ESP_DEFAULT_CPU_FREQ_MHZ_360 + default 400 if ESP_DEFAULT_CPU_FREQ_MHZ_400 diff --git a/components/hal/esp32p4/include/hal/clk_tree_ll.h b/components/hal/esp32p4/include/hal/clk_tree_ll.h index 6b56df44e7..a3ec789860 100644 --- a/components/hal/esp32p4/include/hal/clk_tree_ll.h +++ b/components/hal/esp32p4/include/hal/clk_tree_ll.h @@ -771,6 +771,9 @@ static inline __attribute__((always_inline)) void clk_ll_freq_calulation_set_tar case CLK_CAL_LP_PLL: timg_cali_clk_sel = 11; break; + case CLK_CAL_DSI_DPHY: + timg_cali_clk_sel = 12; + break; default: // Unsupported CLK_CAL mux input abort(); diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index c1a0edeb89..765b7032ad 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -801,6 +801,7 @@ typedef enum { CLK_CAL_RC32K, /*!< Select to calculate frequency of RC32K_CLK */ CLK_CAL_32K_XTAL, /*!< Select to calculate frequency of XTAL32K_CLK */ CLK_CAL_LP_PLL, /*!< Select to calculate frequency of LP_PLL_CLK */ + CLK_CAL_DSI_DPHY, /*!< Select to calculate frequency of DSI_DPHY_lanebyteclk */ } soc_clk_freq_calculation_src_t; #ifdef __cplusplus