From 28df79aee8673c5fed4e78de7f1b0870f65ec595 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Wed, 25 Jun 2025 17:30:46 +0800 Subject: [PATCH] feat(clk): Add basic clock support for esp32h4 --- Kconfig | 1 - components/bootloader/Kconfig.projbuild | 8 + .../src/bootloader_clock_init.c | 4 +- .../src/bootloader_random.c | 10 +- .../src/esp32h4/bootloader_esp32h4.c | 37 +- .../port/esp32/include/soc/rtc.h | 2 +- .../port/esp32c2/include/soc/rtc.h | 2 +- .../port/esp32c3/include/soc/rtc.h | 2 +- .../port/esp32c5/include/soc/rtc.h | 2 +- .../port/esp32c6/include/soc/rtc.h | 2 +- .../port/esp32c61/include/soc/rtc.h | 2 +- .../port/esp32h2/include/soc/rtc.h | 2 +- .../port/esp32h21/esp_clk_tree.c | 3 +- .../port/esp32h21/include/soc/rtc.h | 14 +- .../esp_hw_support/port/esp32h21/rtc_clk.c | 8 +- .../port/esp32h21/rtc_clk_init.c | 1 - .../esp_hw_support/port/esp32h21/rtc_time.c | 2 +- .../port/esp32h4/CMakeLists.txt | 2 +- .../esp_hw_support/port/esp32h4/Kconfig.rtc | 18 +- .../port/esp32h4/esp_clk_tree.c | 76 ++- .../port/esp32h4/include/soc/rtc.h | 103 ++-- .../esp_hw_support/port/esp32h4/pmu_init.c | 29 +- .../port/esp32h4/private_include/pmu_param.h | 4 +- .../esp_hw_support/port/esp32h4/rtc_clk.c | 192 ++++--- .../port/esp32h4/rtc_clk_init.c | 23 +- .../esp_hw_support/port/esp32h4/rtc_time.c | 152 ++--- .../port/esp32p4/include/soc/rtc.h | 2 +- .../port/esp32s2/include/soc/rtc.h | 2 +- .../port/esp32s3/include/soc/rtc.h | 2 +- .../test_apps/rtc_clk/README.md | 4 +- .../test_apps/rtc_clk/main/test_rtc_clk.c | 4 +- .../esp_rom/esp32h4/include/esp32h4/rom/rtc.h | 24 +- .../esp_rom/patches/esp_rom_regi2c_esp32h4.c | 3 + .../esp_system/port/soc/esp32h4/Kconfig.cpu | 14 +- components/esp_system/port/soc/esp32h4/clk.c | 32 +- components/hal/esp32h4/clk_tree_hal.c | 28 +- .../hal/esp32h4/include/hal/clk_tree_ll.h | 520 ++++++------------ .../hal/esp32h4/include/hal/lp_aon_ll.h | 4 +- .../soc/esp32/include/soc/clk_tree_defs.h | 2 + components/soc/esp32/include/soc/soc.h | 10 +- .../soc/esp32c2/include/soc/clk_tree_defs.h | 2 + components/soc/esp32c2/include/soc/soc.h | 10 +- .../soc/esp32c3/include/soc/clk_tree_defs.h | 2 + components/soc/esp32c3/include/soc/soc.h | 11 +- .../soc/esp32c5/include/soc/clk_tree_defs.h | 2 + components/soc/esp32c5/include/soc/soc.h | 1 - .../soc/esp32c6/include/soc/clk_tree_defs.h | 2 + components/soc/esp32c6/include/soc/soc.h | 4 - .../soc/esp32c61/include/soc/clk_tree_defs.h | 2 + components/soc/esp32c61/include/soc/soc.h | 1 - .../soc/esp32h2/include/soc/clk_tree_defs.h | 2 + components/soc/esp32h2/include/soc/soc.h | 4 - .../soc/esp32h21/include/soc/clk_tree_defs.h | 4 +- components/soc/esp32h21/include/soc/soc.h | 1 - .../esp32h4/include/soc/Kconfig.soc_caps.in | 10 +- .../soc/esp32h4/include/soc/clk_tree_defs.h | 87 +-- .../soc/esp32h4/include/soc/gpio_sig_map.h | 2 +- .../soc/esp32h4/include/soc/regi2c_dcdc.h | 4 + components/soc/esp32h4/include/soc/soc.h | 6 +- components/soc/esp32h4/include/soc/soc_caps.h | 8 +- components/soc/esp32h4/register/soc/pcr_reg.h | 35 +- .../soc/esp32h4/register/soc/pcr_struct.h | 30 +- .../soc/esp32p4/include/soc/clk_tree_defs.h | 2 + components/soc/esp32p4/include/soc/soc.h | 4 - .../soc/esp32s2/include/soc/clk_tree_defs.h | 2 + components/soc/esp32s2/include/soc/soc.h | 10 +- .../soc/esp32s3/include/soc/clk_tree_defs.h | 2 + components/soc/esp32s3/include/soc/soc.h | 11 +- docs/docs_not_updated/esp32h4.txt | 1 - .../en/api-reference/peripherals/clk_tree.rst | 10 +- .../api-reference/peripherals/clk_tree.rst | 10 +- 71 files changed, 697 insertions(+), 937 deletions(-) diff --git a/Kconfig b/Kconfig index dd690c14b3..2d4bffd397 100644 --- a/Kconfig +++ b/Kconfig @@ -147,7 +147,6 @@ mainmenu "Espressif IoT Development Framework Configuration" bool default "y" if IDF_TARGET="esp32h4" select IDF_TARGET_ARCH_RISCV - select IDF_ENV_FPGA select IDF_ENV_BRINGUP config IDF_TARGET_LINUX diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index f8ff0f146f..3af3987487 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -39,6 +39,14 @@ menu "Bootloader config" orsource "Kconfig.log" + config BOOTLOADER_CPU_CLK_FREQ_MHZ + int + default 64 if IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32H21 || IDF_TARGET_ESP32H4 + default 90 if IDF_TARGET_ESP32P4 + default 80 + help + The CPU clock frequency to be at least raised to in 2nd bootloader. Invisible for users. + menu "Serial Flash Configurations" config BOOTLOADER_SPI_CUSTOM_WP_PIN bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)" diff --git a/components/bootloader_support/src/bootloader_clock_init.c b/components/bootloader_support/src/bootloader_clock_init.c index 4598eb6333..161d58e07c 100644 --- a/components/bootloader_support/src/bootloader_clock_init.c +++ b/components/bootloader_support/src/bootloader_clock_init.c @@ -34,7 +34,7 @@ __attribute__((weak)) void bootloader_clock_configure(void) esp_rom_output_tx_wait_idle(0); /* Set CPU to a higher certain frequency. Keep other clocks unmodified. */ - int cpu_freq_mhz = CPU_CLK_FREQ_MHZ_BTLD; + int cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ; #if CONFIG_IDF_TARGET_ESP32 /* On ESP32 rev 0, switching to 80/160 MHz if clock was previously set to @@ -57,7 +57,7 @@ __attribute__((weak)) void bootloader_clock_configure(void) // RTC_SLOW clock source will be switched according to Kconfig selection at application startup clk_cfg.slow_clk_src = rtc_clk_slow_src_get(); if (clk_cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_INVALID) { - clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW; + clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_DEFAULT; } // Use RTC_FAST clock source sel register field's default value, XTAL_DIV, for 2nd stage bootloader diff --git a/components/bootloader_support/src/bootloader_random.c b/components/bootloader_support/src/bootloader_random.c index abab981e44..6c6ce5b048 100644 --- a/components/bootloader_support/src/bootloader_random.c +++ b/components/bootloader_support/src/bootloader_random.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,16 +26,16 @@ #if !defined CONFIG_IDF_TARGET_ESP32S3 #if (defined CONFIG_IDF_TARGET_ESP32C6 || defined CONFIG_IDF_TARGET_ESP32H2) - #define RNG_CPU_WAIT_CYCLE_NUM (80 * 16) // Keep the byte sampling frequency in the ~62KHz range which has been + #define RNG_CPU_WAIT_CYCLE_NUM (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ * 16) // Keep the byte sampling frequency in the ~62KHz range which has been // tested. #elif CONFIG_IDF_TARGET_ESP32P4 // bootloader tested with around 63 KHz bytes reading frequency - #define RNG_CPU_WAIT_CYCLE_NUM (CPU_CLK_FREQ_MHZ_BTLD * 16) + #define RNG_CPU_WAIT_CYCLE_NUM (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ * 16) #else - #define RNG_CPU_WAIT_CYCLE_NUM (80 * 32 * 2) /* extra factor of 2 is precautionary */ + #define RNG_CPU_WAIT_CYCLE_NUM (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ * 32 * 2) /* extra factor of 2 is precautionary */ #endif #else - #define RNG_CPU_WAIT_CYCLE_NUM (80 * 23) /* 45 KHz reading frequency is the maximum we have tested so far on S3 */ + #define RNG_CPU_WAIT_CYCLE_NUM (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ * 23) /* 45 KHz reading frequency is the maximum we have tested so far on S3 */ #endif __attribute__((weak)) void bootloader_fill_random(void *buffer, size_t length) diff --git a/components/bootloader_support/src/esp32h4/bootloader_esp32h4.c b/components/bootloader_support/src/esp32h4/bootloader_esp32h4.c index b287226712..55dff805dc 100644 --- a/components/bootloader_support/src/esp32h4/bootloader_esp32h4.c +++ b/components/bootloader_support/src/esp32h4/bootloader_esp32h4.c @@ -13,11 +13,9 @@ #include "esp_rom_efuse.h" #include "esp_rom_serial_output.h" #include "esp_rom_sys.h" -#include "esp_rom_spiflash.h" #include "soc/gpio_sig_map.h" #include "esp_cpu.h" #include "soc/rtc.h" -#include "soc/spi_periph.h" #include "soc/cache_reg.h" #include "soc/io_mux_reg.h" #include "soc/pcr_reg.h" @@ -28,8 +26,6 @@ #include "bootloader_flash_config.h" #include "bootloader_mem.h" #include "esp_private/regi2c_ctrl.h" -// #include "soc/regi2c_lp_bias.h" -// #include "soc/regi2c_bias.h" #include "soc/hp_system_reg.h" #include "bootloader_console.h" #include "bootloader_flash_priv.h" @@ -83,39 +79,18 @@ static void bootloader_super_wdt_auto_feed(void) REG_WRITE(LP_WDT_SWD_WPROTECT_REG, 0); } -void spi_flash_din_num_set(uint8_t spi_num, uint8_t din_num) -{ - uint32_t reg_val = (REG_READ(SPI_MEM_DIN_NUM_REG(spi_num)) & (~(SPI_MEM_DIN0_NUM_M | SPI_MEM_DIN1_NUM_M | SPI_MEM_DIN2_NUM_M | SPI_MEM_DIN3_NUM_M | SPI_MEM_DIN4_NUM_M | SPI_MEM_DIN5_NUM_M | SPI_MEM_DIN6_NUM_M | SPI_MEM_DIN7_NUM_M | SPI_MEM_DINS_NUM_M))) - | (din_num << SPI_MEM_DIN0_NUM_S) | (din_num << SPI_MEM_DIN1_NUM_S) | (din_num << SPI_MEM_DIN2_NUM_S) | (din_num << SPI_MEM_DIN3_NUM_S) - | (din_num << SPI_MEM_DIN4_NUM_S) | (din_num << SPI_MEM_DIN5_NUM_S) | (din_num << SPI_MEM_DIN6_NUM_S) | (din_num << SPI_MEM_DIN7_NUM_S) | (din_num << SPI_MEM_DINS_NUM_S); - REG_WRITE(SPI_MEM_DIN_NUM_REG(spi_num), reg_val); - REG_SET_BIT(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_UPDATE); -} - -void spi_flash_extra_dummy_set(uint8_t spi_num, uint8_t extra_dummy) -{ - rom_spiflash_legacy_data->dummy_len_plus[spi_num] = extra_dummy; -} - -/* - * din mode din_num dummy - 1 0 1 - 0 0 0 - 1 0 2 - 0 0 1 - 1 0 3 - 0 0 2 - 1 0 4 - 0 0 3 - */ static inline void bootloader_hardware_init(void) { - // TODO: IDF-12285 RF disable? + /* Disable RF pll by default */ + CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFPLL); + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_FORCE_RFPLL); +#if !CONFIG_IDF_ENV_FPGA /* Enable analog i2c master clock */ _regi2c_ctrl_ll_master_enable_clock(true); // keep ana i2c mst clock always enabled in bootloader - regi2c_ctrl_ll_master_force_enable_clock(true); // TODO: IDF-12285 Remove this? + regi2c_ctrl_ll_master_force_enable_clock(true); // TODO: IDF-12313 Remove this? regi2c_ctrl_ll_master_configure_clock(); +#endif } static inline void bootloader_ana_reset_config(void) diff --git a/components/esp_hw_support/port/esp32/include/soc/rtc.h b/components/esp_hw_support/port/esp32/include/soc/rtc.h index d3a453e4d6..3eaa3ded15 100644 --- a/components/esp_hw_support/port/esp32/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32/include/soc/rtc.h @@ -116,7 +116,7 @@ typedef struct rtc_clk_config_s { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 80, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_8m_div = 0, \ diff --git a/components/esp_hw_support/port/esp32c2/include/soc/rtc.h b/components/esp_hw_support/port/esp32c2/include/soc/rtc.h index 25605abcda..87ae0f7ba3 100644 --- a/components/esp_hw_support/port/esp32c2/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c2/include/soc/rtc.h @@ -186,7 +186,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 80, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/port/esp32c3/include/soc/rtc.h b/components/esp_hw_support/port/esp32c3/include/soc/rtc.h index 7173c76815..e756a7b286 100644 --- a/components/esp_hw_support/port/esp32c3/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c3/include/soc/rtc.h @@ -186,7 +186,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 80, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/port/esp32c5/include/soc/rtc.h b/components/esp_hw_support/port/esp32c5/include/soc/rtc.h index 76109b9980..d0c32e4ef7 100644 --- a/components/esp_hw_support/port/esp32c5/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c5/include/soc/rtc.h @@ -147,7 +147,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 80, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/port/esp32c6/include/soc/rtc.h b/components/esp_hw_support/port/esp32c6/include/soc/rtc.h index 307702a3c1..042dc494fe 100644 --- a/components/esp_hw_support/port/esp32c6/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c6/include/soc/rtc.h @@ -157,7 +157,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 80, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/port/esp32c61/include/soc/rtc.h b/components/esp_hw_support/port/esp32c61/include/soc/rtc.h index 72d5c0033a..b8179abc38 100644 --- a/components/esp_hw_support/port/esp32c61/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c61/include/soc/rtc.h @@ -147,7 +147,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 80, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/port/esp32h2/include/soc/rtc.h b/components/esp_hw_support/port/esp32h2/include/soc/rtc.h index d3811d23d3..ce8d783584 100644 --- a/components/esp_hw_support/port/esp32h2/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32h2/include/soc/rtc.h @@ -159,7 +159,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 96, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/port/esp32h21/esp_clk_tree.c b/components/esp_hw_support/port/esp32h21/esp_clk_tree.c index 71ad12c5e8..2b541ff061 100644 --- a/components/esp_hw_support/port/esp32h21/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32h21/esp_clk_tree.c @@ -110,8 +110,9 @@ 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_F64M: - // later, here should handle ref count for PLL_F64M clock gating, then also handle XTAL_X2 circuit enable/disable + // 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; } diff --git a/components/esp_hw_support/port/esp32h21/include/soc/rtc.h b/components/esp_hw_support/port/esp32h21/include/soc/rtc.h index 55c42f60e0..9556ea23a5 100644 --- a/components/esp_hw_support/port/esp32h21/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32h21/include/soc/rtc.h @@ -93,15 +93,6 @@ extern "C" { // #define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1 // #define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254 -// /* -// The follow value is used to get a reasonable rtc voltage dbias value according to digital dbias & some other value -// storing in efuse -// */ -// #define K_RTC_MID_MUL10000 215 -// #define K_DIG_MID_MUL10000 213 -// #define V_RTC_MID_MUL10000 10800 -// #define V_DIG_MID_MUL10000 10860 - /** * @brief CPU clock configuration structure */ @@ -114,9 +105,6 @@ typedef struct rtc_cpu_freq_config_s { #define RTC_CLK_CAL_FRACT 19 //!< Number of fractional bits in values returned by rtc_clk_cal -#define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO -#define RTC_VDDSDIO_TIEH_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO - /** * @brief Clock source to be calibrated using rtc_clk_cal function * @@ -151,7 +139,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 64, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/port/esp32h21/rtc_clk.c b/components/esp_hw_support/port/esp32h21/rtc_clk.c index 10f0ca990e..740c6c7c96 100644 --- a/components/esp_hw_support/port/esp32h21/rtc_clk.c +++ b/components/esp_hw_support/port/esp32h21/rtc_clk.c @@ -322,31 +322,27 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) { soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); uint32_t source_freq_mhz; - uint32_t div = clk_ll_cpu_get_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK - uint32_t freq_mhz; switch (source) { case SOC_CPU_CLK_SRC_XTAL: { source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get(); - freq_mhz = source_freq_mhz / div; break; } case SOC_CPU_CLK_SRC_PLL: { source_freq_mhz = clk_ll_bbpll_get_freq_mhz(); - freq_mhz = source_freq_mhz / div; break; } case SOC_CPU_CLK_SRC_RC_FAST: source_freq_mhz = 20; - freq_mhz = source_freq_mhz / div; break; case SOC_CPU_CLK_SRC_XTAL_X2: source_freq_mhz = clk_ll_xtal_x2_get_freq_mhz(); - freq_mhz = source_freq_mhz / div; break; default: ESP_HW_LOGE(TAG, "unsupported frequency configuration"); abort(); } + uint32_t div = clk_ll_cpu_get_divider(); + uint32_t freq_mhz = source_freq_mhz / div; // freq of CPU_CLK = freq of SOC_ROOT_CLK / cpu_div *out_config = (rtc_cpu_freq_config_t) { .source = source, .source_freq_mhz = source_freq_mhz, diff --git a/components/esp_hw_support/port/esp32h21/rtc_clk_init.c b/components/esp_hw_support/port/esp32h21/rtc_clk_init.c index c10a4af66c..19df616b6b 100644 --- a/components/esp_hw_support/port/esp32h21/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32h21/rtc_clk_init.c @@ -16,7 +16,6 @@ #include "soc/lp_clkrst_reg.h" #include "soc/regi2c_pmu.h" #include "esp_hw_log.h" -#include "sdkconfig.h" #include "hal/clk_tree_ll.h" #include "soc/pmu_reg.h" #include "pmu_param.h" diff --git a/components/esp_hw_support/port/esp32h21/rtc_time.c b/components/esp_hw_support/port/esp32h21/rtc_time.c index 0c588a894f..da5fb309ae 100644 --- a/components/esp_hw_support/port/esp32h21/rtc_time.c +++ b/components/esp_hw_support/port/esp32h21/rtc_time.c @@ -56,7 +56,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } - /* Enable requested clock (150k clock is always on) */ + /* Enable requested clock (rc_slow clock is always on) */ // All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock // Only enable if originally was disabled, and set back to the disable state after calibration is done // If the clock is already on, then do nothing diff --git a/components/esp_hw_support/port/esp32h4/CMakeLists.txt b/components/esp_hw_support/port/esp32h4/CMakeLists.txt index 5a4c189940..e0bf022482 100644 --- a/components/esp_hw_support/port/esp32h4/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32h4/CMakeLists.txt @@ -1,11 +1,11 @@ set(srcs "rtc_clk.c" "rtc_time.c" "chip_info.c" + "rtc_clk_init.c" ) if(CONFIG_SOC_PMU_SUPPORTED) list(APPEND srcs - # "rtc_clk_init.c" //TODO: IDF-12313 "pmu_param.c" "pmu_init.c" "pmu_sleep.c" diff --git a/components/esp_hw_support/port/esp32h4/Kconfig.rtc b/components/esp_hw_support/port/esp32h4/Kconfig.rtc index 297ffc1c4a..59123410a1 100644 --- a/components/esp_hw_support/port/esp32h4/Kconfig.rtc +++ b/components/esp_hw_support/port/esp32h4/Kconfig.rtc @@ -1,27 +1,25 @@ choice RTC_CLK_SRC prompt "RTC clock source" - default RTC_CLK_SRC_INT_RC + default RTC_CLK_SRC_INT_RC_D4 help Choose which clock is used as RTC clock source. - config RTC_CLK_SRC_INT_RC - bool "Internal 136kHz RC oscillator" + config RTC_CLK_SRC_INT_RC_D4 + bool "Internal 600kHz RC oscillator, divide by 4" config RTC_CLK_SRC_EXT_CRYS bool "External 32kHz crystal" select ESP_SYSTEM_RTC_EXT_XTAL config RTC_CLK_SRC_EXT_OSC bool "External 32kHz oscillator at 32K_XP pin" select ESP_SYSTEM_RTC_EXT_OSC - config RTC_CLK_SRC_INT_RC32K - bool "Internal 32kHz RC oscillator" endchoice config RTC_CLK_CAL_CYCLES int "Number of cycles for RTC_SLOW_CLK calibration" - default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K - default 1024 if RTC_CLK_SRC_INT_RC - range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K - range 0 32766 if RTC_CLK_SRC_INT_RC + default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC + default 1024 if RTC_CLK_SRC_INT_RC_D4 + range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC + range 0 32766 if RTC_CLK_SRC_INT_RC_D4 help When the startup code initializes RTC_SLOW_CLK, it can perform calibration by comparing the RTC_SLOW_CLK frequency with main XTAL @@ -33,7 +31,7 @@ config RTC_CLK_CAL_CYCLES When this option is set to 0, clock calibration will not be performed at startup, and approximate clock frequencies will be assumed: - - 136000 Hz if internal RC oscillator is used as clock source. For this use value 1024. + - 150000 Hz if internal RC oscillator is used as clock source. For this use value 1024. - 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more. In case more value will help improve the definition of the launch of the crystal. If the crystal could not start, it will be switched to internal RC. diff --git a/components/esp_hw_support/port/esp32h4/esp_clk_tree.c b/components/esp_hw_support/port/esp32h4/esp_clk_tree.c index 7c8cb8b577..8847f54abd 100644 --- a/components/esp_hw_support/port/esp32h4/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32h4/esp_clk_tree.c @@ -13,8 +13,6 @@ #include "hal/clk_tree_ll.h" #include "esp_private/esp_clk_tree_common.h" -//TODO: [ESP32H4] IDF-12285 - static const char *TAG = "esp_clk_tree"; esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision, @@ -26,18 +24,36 @@ uint32_t *freq_value) uint32_t clk_src_freq = 0; switch (clk_src) { + case SOC_MOD_CLK_CPU: + clk_src_freq = clk_hal_cpu_get_freq_hz(); + break; case SOC_MOD_CLK_XTAL: - clk_src_freq = SOC_XTAL_FREQ_32M * MHZ; + clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ; + break; + case SOC_MOD_CLK_XTAL_X2_F32M: + clk_src_freq = CLK_LL_PLL_32M_FREQ_MHZ * MHZ; break; case SOC_MOD_CLK_PLL_F48M: clk_src_freq = CLK_LL_PLL_48M_FREQ_MHZ * MHZ; break; - case SOC_MOD_CLK_PLL_F64M: + case SOC_MOD_CLK_XTAL_X2_F64M: clk_src_freq = CLK_LL_PLL_64M_FREQ_MHZ * MHZ; break; case SOC_MOD_CLK_PLL_F96M: clk_src_freq = CLK_LL_PLL_96M_FREQ_MHZ * MHZ; break; + case SOC_MOD_CLK_RTC_SLOW: + clk_src_freq = esp_clk_tree_lp_slow_get_freq_hz(precision); + break; + case SOC_MOD_CLK_RTC_FAST: + clk_src_freq = esp_clk_tree_lp_fast_get_freq_hz(precision); + break; + case SOC_MOD_CLK_RC_FAST: + clk_src_freq = esp_clk_tree_rc_fast_get_freq_hz(precision); + break; + case SOC_MOD_CLK_XTAL32K: + clk_src_freq = esp_clk_tree_xtal32k_get_freq_hz(precision); + break; default: break; } @@ -47,24 +63,66 @@ uint32_t *freq_value) return ESP_OK; } +static int16_t s_xtal_x2_ref_cnt = 0; + void esp_clk_tree_initialize(void) { + // TODO: IDF-12388 + // // 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) { + s_xtal_x2_ref_cnt++; + } } bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit) { - (void)clk_circuit; + switch (clk_circuit) { + case SOC_ROOT_CIRCUIT_CLK_XTAL_X2: + return s_xtal_x2_ref_cnt > 0; + default: + break; + } return false; } esp_err_t 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 + switch (clk_circuit) { + case SOC_ROOT_CIRCUIT_CLK_XTAL_X2: + if (enable) { + s_xtal_x2_ref_cnt++; + } else { + s_xtal_x2_ref_cnt--; + } + + if (s_xtal_x2_ref_cnt == 1) { + clk_ll_xtal_x2_enable(); + } else if (s_xtal_x2_ref_cnt == 0) { + clk_ll_xtal_x2_disable(); + } + + assert(s_xtal_x2_ref_cnt >= 0); + break; + default: + break; + } + return ESP_OK; // TODO: PM-456 } esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) { - (void)clk_src; (void)enable; - return ESP_ERR_NOT_SUPPORTED; + 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; + } + return ESP_OK; // TODO: PM-456 } diff --git a/components/esp_hw_support/port/esp32h4/include/soc/rtc.h b/components/esp_hw_support/port/esp32h4/include/soc/rtc.h index c71106a645..29588c1d9d 100644 --- a/components/esp_hw_support/port/esp32h4/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32h4/include/soc/rtc.h @@ -50,10 +50,6 @@ extern "C" { #define MHZ (1000000) -#define RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(cycles) (cycles << 10) -#define RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12) -#define RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(cycles) (TIMG_RTC_CALI_TIMEOUT_THRES_V) // Just use the max timeout thres value - #define OTHER_BLOCKS_POWERUP 1 #define OTHER_BLOCKS_WAIT 1 @@ -64,16 +60,14 @@ extern "C" { #define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300 #define SOC_DELAY_RC_FAST_ENABLE 50 #define SOC_DELAY_RC_FAST_DIGI_SWITCH 5 -#define SOC_DELAY_RC32K_ENABLE 300 #define RTC_CNTL_PLL_BUF_WAIT_DEFAULT 20 #define RTC_CNTL_XTL_BUF_WAIT_DEFAULT 100 -#define RTC_CNTL_CK8M_WAIT_DEFAULT 20 -#define RTC_CK8M_ENABLE_WAIT_DEFAULT 5 + +// TODO: IDF-12313 check all following values! #define RTC_CNTL_CK8M_DFREQ_DEFAULT 100 -#define RTC_CNTL_SCK_DCAP_DEFAULT 128 -#define RTC_CNTL_RC32K_DFREQ_DEFAULT 700 +#define RTC_CNTL_SCK_DCAP_DEFAULT 28 /* Various delays to be programmed into power control state machines */ #define RTC_CNTL_XTL_BUF_WAIT_SLP_US (250) @@ -84,29 +78,20 @@ extern "C" { #define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES (1) #define RTC_CNTL_MIN_SLP_VAL_MIN (2) -/* -set sleep_init default param -*/ -#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 5 -#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP 0 -#define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT 15 -#define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0 -#define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0 -#define RTC_CNTL_BIASSLP_SLEEP_ON 0 -#define RTC_CNTL_BIASSLP_SLEEP_DEFAULT 1 -#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0 -#define RTC_CNTL_PD_CUR_SLEEP_ON 0 -#define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1 -#define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254 - -/* -The follow value is used to get a reasonable rtc voltage dbias value according to digital dbias & some other value -storing in efuse (based on ATE 5k ECO3 chips) -*/ -#define K_RTC_MID_MUL10000 215 -#define K_DIG_MID_MUL10000 213 -#define V_RTC_MID_MUL10000 10800 -#define V_DIG_MID_MUL10000 10860 +// /* +// set sleep_init default param +// */ +// #define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 5 +// #define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP 0 +// #define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT 15 +// #define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0 +// #define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0 +// #define RTC_CNTL_BIASSLP_SLEEP_ON 0 +// #define RTC_CNTL_BIASSLP_SLEEP_DEFAULT 1 +// #define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0 +// #define RTC_CNTL_PD_CUR_SLEEP_ON 0 +// #define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1 +// #define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254 /** * @brief CPU clock configuration structure @@ -120,23 +105,18 @@ typedef struct rtc_cpu_freq_config_s { #define RTC_CLK_CAL_FRACT 19 //!< Number of fractional bits in values returned by rtc_clk_cal -#define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO -#define RTC_VDDSDIO_TIEH_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO - /** * @brief Clock source to be calibrated using rtc_clk_cal function * * @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL - * However, this is not true on ESP32H4. The conversion to register field values is explicitly done in - * rtc_clk_cal_internal + * However, this is not true on ESP32H4. The conversion to register field values is explicitly done internally */ typedef enum { RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK - RTC_CAL_RC_SLOW = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150kHz RC oscillator - RTC_CAL_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock - RTC_CAL_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32kHz XTAL, as one type of 32k clock - RTC_CAL_32K_OSC_SLOW = SOC_RTC_SLOW_CLK_SRC_OSC_SLOW, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock - RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator + RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 600kHz RC oscillator + RTC_CAL_32K_XTAL = CLK_CAL_32K_XTAL, //!< External 32kHz XTAL, as one type of 32k clock + RTC_CAL_32K_OSC_SLOW = CLK_CAL_32K_OSC_SLOW, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock + RTC_CAL_RC_FAST = CLK_CAL_RC_FAST, //!< Internal 20MHz RC oscillator } rtc_cal_sel_t; /** @@ -150,8 +130,7 @@ typedef struct { uint32_t clk_rtc_clk_div : 8; uint32_t clk_8m_clk_div : 3; //!< RC_FAST clock divider (division is by clk_8m_div+1, i.e. 0 means ~20MHz frequency) uint32_t slow_clk_dcap : 8; //!< RC_SLOW clock adjustment parameter (higher value leads to lower frequency) - uint32_t clk_8m_dfreq : 10; //!< RC_FAST clock adjustment parameter (higher value leads to higher frequency) - uint32_t rc32k_dfreq : 10; //!< Internal RC32K clock adjustment parameter (higher value leads to higher frequency) + uint32_t clk_8m_dfreq : 10; //!< RC_FAST clock adjustment parameter (higher value leads to higher frequency) } rtc_clk_config_t; /** @@ -159,18 +138,17 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 96, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ - .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ - .clk_rtc_clk_div = 0, \ + .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4, \ + .clk_rtc_clk_div = 3, \ .clk_8m_clk_div = 0, \ .slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \ .clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \ - .rc32k_dfreq = RTC_CNTL_RC32K_DFREQ_DEFAULT, \ } /** - * Initialize clocks and set CPU frequency + * @brief Initialize clocks and set CPU frequency * * @param cfg clock configuration as rtc_clk_config_t */ @@ -179,23 +157,10 @@ void rtc_clk_init(rtc_clk_config_t cfg); /** * @brief Get main XTAL frequency * - * This is the value stored in RTC register RTC_XTAL_FREQ_REG by the bootloader. As passed to - * rtc_clk_init function - * * @return XTAL frequency, one of soc_xtal_freq_t */ soc_xtal_freq_t rtc_clk_xtal_freq_get(void); -/** - * @brief Update XTAL frequency - * - * Updates the XTAL value stored in RTC_XTAL_FREQ_REG. Usually this value is ignored - * after startup. - * - * @param xtal_freq New frequency value - */ -void rtc_clk_xtal_freq_update(soc_xtal_freq_t xtal_freq); - /** * @brief Enable or disable 32 kHz XTAL oscillator * @param en true to enable, false to disable @@ -230,12 +195,6 @@ bool rtc_clk_32k_enabled(void); */ void rtc_clk_32k_bootstrap(uint32_t cycle); -/** - * @brief Enable or disable 32 kHz internal rc oscillator - * @param en true to enable, false to disable - */ -void rtc_clk_rc32k_enable(bool enable); - /** * @brief Enable or disable 8 MHz internal oscillator * @@ -264,9 +223,8 @@ soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void); /** * @brief Get the approximate frequency of RTC_SLOW_CLK, in Hz * - * - if SOC_RTC_SLOW_CLK_SRC_RC_SLOW is selected, returns 136000 + * - if SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4 is selected, returns 150000 * - if SOC_RTC_SLOW_CLK_SRC_XTAL32K is selected, returns 32768 - * - if SOC_RTC_SLOW_CLK_SRC_RC32K is selected, returns 32768 * - if SOC_RTC_SLOW_CLK_SRC_OSC_SLOW is selected, returns 32768 * * rtc_clk_cal function can be used to get more precise value by comparing @@ -345,8 +303,9 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config); * rtc_clk_cpu_freq_set_config when a switch to XTAL is needed. * Assumes that XTAL frequency has been determined — don't call in startup code. * - * @note On ESP32H4, this function will check whether BBPLL can be disabled. If there is no consumer, then BBPLL will be - * turned off. The behaviour is the same as using rtc_clk_cpu_freq_set_config to switch cpu clock source to XTAL. + * @note This function always disables BBPLL after switching the CPU clock source to XTAL for power saving purpose. + * If this is unwanted, please use rtc_clk_cpu_freq_set_config. It helps to check whether USB Serial JTAG is in use, + * if so, then BBPLL will not be turned off. */ void rtc_clk_cpu_freq_set_xtal(void); diff --git a/components/esp_hw_support/port/esp32h4/pmu_init.c b/components/esp_hw_support/port/esp32h4/pmu_init.c index 0fcd066edb..a6c8b4627b 100644 --- a/components/esp_hw_support/port/esp32h4/pmu_init.c +++ b/components/esp_hw_support/port/esp32h4/pmu_init.c @@ -14,6 +14,8 @@ #include "hal/pmu_hal.h" #include "pmu_param.h" #include "esp_private/esp_pmu.h" +#include "soc/regi2c_dcdc.h" +#include "regi2c_ctrl.h" static __attribute__((unused)) const char *TAG = "pmu_init"; @@ -227,21 +229,24 @@ static void pmu_lp_system_init_default(pmu_context_t *ctx) void pmu_init(void) { -#if 0 // TODO: IDF-12313 - /* Peripheral reg i2c power up */ - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFTX_I2C); - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFRX_I2C); - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFPLL); - - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0); -#endif + /* No peripheral reg i2c power up required on the target */ pmu_hp_system_init_default(PMU_instance()); pmu_lp_system_init_default(PMU_instance()); pmu_power_domain_force_default(PMU_instance()); + + // default ccm mode + REG_SET_FIELD(PMU_DCM_CTRL_REG, PMU_DCDC_CCM_SW_EN, 1); + REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCDC_CCM_ENB, 0); +#if !CONFIG_IDF_ENV_FPGA + REGI2C_WRITE_MASK(I2C_DCDC, I2C_DCDC_CCM_DREG0, 24); + REGI2C_WRITE_MASK(I2C_DCDC, I2C_DCDC_CCM_PCUR_LIMIT0, 4); + REGI2C_WRITE_MASK(I2C_DCDC, I2C_DCDC_VCM_PCUR_LIMIT0, 1); + REGI2C_WRITE_MASK(I2C_DCDC, I2C_DCDC_XPD_TRX, 0); +#endif + + // close rfpll to decrease mslp_cur + REG_SET_FIELD(PMU_RF_PWC_REG, PMU_XPD_FORCE_RFPLL, 1); + REG_SET_FIELD(PMU_RF_PWC_REG, PMU_XPD_RFPLL, 0); } diff --git a/components/esp_hw_support/port/esp32h4/private_include/pmu_param.h b/components/esp_hw_support/port/esp32h4/private_include/pmu_param.h index 2633725ff7..d50037c7c4 100644 --- a/components/esp_hw_support/port/esp32h4/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32h4/private_include/pmu_param.h @@ -16,8 +16,8 @@ extern "C" { #endif -#define HP_CALI_DBIAS_DEFAULT 25 -#define LP_CALI_DBIAS_DEFAULT 26 +#define HP_CALI_DBIAS_DEFAULT 0 +#define LP_CALI_DBIAS_DEFAULT 0 // FOR XTAL FORCE PU IN SLEEP #define PMU_PD_CUR_SLEEP_ON 0 diff --git a/components/esp_hw_support/port/esp32h4/rtc_clk.c b/components/esp_hw_support/port/esp32h4/rtc_clk.c index 9da7371ae4..8222658e2e 100644 --- a/components/esp_hw_support/port/esp32h4/rtc_clk.c +++ b/components/esp_hw_support/port/esp32h4/rtc_clk.c @@ -10,7 +10,7 @@ #include #include #include "sdkconfig.h" -#include "rom/rtc.h" +#include "esp32h4/rom/rtc.h" #include "soc/rtc.h" #include "esp_private/rtc_clk.h" #include "esp_hw_log.h" @@ -18,9 +18,9 @@ #include "hal/clk_tree_ll.h" #include "hal/gpio_ll.h" #include "hal/regi2c_ctrl_ll.h" -#include "hal/gpio_ll.h" #include "soc/lp_aon_reg.h" #include "esp_private/sleep_event.h" +#include "esp_private/esp_clk_tree_common.h" static const char *TAG = "rtc_clk"; @@ -76,16 +76,6 @@ bool rtc_clk_32k_enabled(void) return clk_ll_xtal32k_is_enabled(); } -void rtc_clk_rc32k_enable(bool enable) -{ - if (enable) { - clk_ll_rc32k_enable(); - esp_rom_delay_us(SOC_DELAY_RC32K_ENABLE); - } else { - clk_ll_rc32k_disable(); - } -} - void rtc_clk_8m_enable(bool clk_8m_en) { if (clk_8m_en) { @@ -115,9 +105,8 @@ soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void) uint32_t rtc_clk_slow_freq_get_hz(void) { switch (rtc_clk_slow_src_get()) { - case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4: return SOC_CLK_RC_SLOW_FREQ_APPROX / 4; case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX; - case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX; case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX; default: return 0; } @@ -149,15 +138,18 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) { /* Digital part */ clk_ll_bbpll_set_freq_mhz(pll_freq); - /* Analog part */ + /* Analog part */ + ANALOG_CLOCK_ENABLE(); /* BBPLL CALIBRATION START */ regi2c_ctrl_ll_bbpll_calibration_start(); 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); // wait for true stop /* BBPLL CALIBRATION STOP */ regi2c_ctrl_ll_bbpll_calibration_stop(); + ANALOG_CLOCK_DISABLE(); s_cur_pll_freq = pll_freq; } @@ -169,18 +161,22 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) */ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div) { - clk_ll_ahb_set_ls_divider(div); - clk_ll_cpu_set_ls_divider(div); + // let f_cpu = f_ahb + clk_ll_ahb_set_divider(1); + clk_ll_cpu_set_divider(div); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL); + clk_ll_bus_update(); esp_rom_set_cpu_ticks_per_us(cpu_freq); } static void rtc_clk_cpu_freq_to_rc_fast(void) { - clk_ll_ahb_set_ls_divider(1); - clk_ll_cpu_set_ls_divider(1); + // let f_cpu = f_ahb + clk_ll_ahb_set_divider(1); + clk_ll_cpu_set_divider(1); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST); - esp_rom_set_cpu_ticks_per_us(20); + clk_ll_bus_update(); + esp_rom_set_cpu_ticks_per_us(8); } /** @@ -190,8 +186,32 @@ static void rtc_clk_cpu_freq_to_rc_fast(void) */ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) { - clk_ll_cpu_set_hs_divider(CLK_LL_PLL_96M_FREQ_MHZ / cpu_freq_mhz); + // f_hp_root = 96MHz + uint32_t cpu_divider = CLK_LL_PLL_96M_FREQ_MHZ / cpu_freq_mhz; // must be a power of 2 + clk_ll_cpu_set_divider(cpu_divider); + // Constraint: f_ahb <= 32MHz + uint32_t ahb_divider = (cpu_divider == 1) ? 3 : + (cpu_divider == 2) ? 2 : 1; + clk_ll_ahb_set_divider(ahb_divider); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); + clk_ll_bus_update(); + esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); +} + +/** + * Switch to XTAL_X2 as cpu clock source. + * On ESP32H4, XTAL_X2 frequency is 64MHz. + * XTAL_X2 circuit must already been enabled. + */ +static void rtc_clk_cpu_freq_to_xtal_x2(uint32_t cpu_freq_mhz, uint32_t cpu_divider) +{ + // f_hp_root = 64MHz + clk_ll_cpu_set_divider(cpu_divider); + // Constraint: f_ahb <= 32MHz + uint32_t ahb_divider = (cpu_divider == 1) ? 2 : 1; + clk_ll_ahb_set_divider(ahb_divider); + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL_X2); + clk_ll_bus_update(); esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); } @@ -213,21 +233,21 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou source_freq_mhz = xtal_freq; source = SOC_CPU_CLK_SRC_XTAL; - } else if (freq_mhz == 16) { + } else if (freq_mhz == 96) { real_freq_mhz = freq_mhz; source = SOC_CPU_CLK_SRC_PLL; source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ; - divider = 6; - } else if (freq_mhz == 24) { + divider = 1; + } else if (freq_mhz == 64) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_XTAL_X2; + source_freq_mhz = CLK_LL_PLL_64M_FREQ_MHZ; + divider = 1; + } else if (freq_mhz == 48) { real_freq_mhz = freq_mhz; source = SOC_CPU_CLK_SRC_PLL; source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ; - divider = 4; - } else if (freq_mhz == 32) { - real_freq_mhz = freq_mhz; - source = SOC_CPU_CLK_SRC_PLL; - source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ; - divider = 3; + divider = 2; } else { // unsupported frequency return false; @@ -245,29 +265,55 @@ __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) { + rtc_clk_bbpll_enable(); + 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(); +#else + esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, true); +#endif + } +} + +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) { + rtc_clk_bbpll_disable(); + } else if (old_src == SOC_CPU_CLK_SRC_XTAL_X2) { +#if BOOTLOADER_BUILD + clk_ll_xtal_x2_disable(); +#else + esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, false); +#endif + } +} + void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) { soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src(); + + if (old_cpu_clk_src != config->source) { + rtc_clk_cpu_src_clk_enable(config->source, config->source_freq_mhz); + } + if (config->source == SOC_CPU_CLK_SRC_XTAL) { rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); - if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { - // We don't turn off the bbpll if some consumers depend on bbpll - rtc_clk_bbpll_disable(); - } } else if (config->source == SOC_CPU_CLK_SRC_PLL) { - if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) { - rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_PLL_EN_START); - rtc_clk_bbpll_enable(); - rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz); - } + rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_PLL_EN_START); rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_PLL_EN_STOP); } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { rtc_clk_cpu_freq_to_rc_fast(); - if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { - // We don't turn off the bbpll if some consumers depend on bbpll - rtc_clk_bbpll_disable(); - } + } else if (config->source == SOC_CPU_CLK_SRC_XTAL_X2) { + rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div); + } + + if (old_cpu_clk_src != config->source) { + rtc_clk_cpu_src_clk_disable(old_cpu_clk_src); } } @@ -275,30 +321,27 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) { soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); uint32_t source_freq_mhz; - uint32_t div; // div = freq of SOC_ROOT_CLK / freq of CPU_CLK - uint32_t freq_mhz; switch (source) { case SOC_CPU_CLK_SRC_XTAL: { - div = clk_ll_cpu_get_ls_divider(); source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get(); - freq_mhz = source_freq_mhz / div; break; } case SOC_CPU_CLK_SRC_PLL: { - div = clk_ll_cpu_get_hs_divider(); source_freq_mhz = clk_ll_bbpll_get_freq_mhz(); - freq_mhz = source_freq_mhz / div; break; } case SOC_CPU_CLK_SRC_RC_FAST: - div = clk_ll_cpu_get_ls_divider(); - source_freq_mhz = 20; - freq_mhz = source_freq_mhz / div; + source_freq_mhz = 8; + break; + case SOC_CPU_CLK_SRC_XTAL_X2: + source_freq_mhz = clk_ll_xtal_x2_get_freq_mhz(); break; default: ESP_HW_LOGE(TAG, "unsupported frequency configuration"); abort(); } + uint32_t div = clk_ll_cpu_get_divider(); + uint32_t freq_mhz = source_freq_mhz / div; // freq of CPU_CLK = freq of SOC_ROOT_CLK / cpu_div *out_config = (rtc_cpu_freq_config_t) { .source = source, .source_freq_mhz = source_freq_mhz, @@ -316,6 +359,9 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config) rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { rtc_clk_cpu_freq_to_rc_fast(); + } else if (config->source == SOC_CPU_CLK_SRC_XTAL_X2 + && esp_clk_tree_is_power_on(SOC_ROOT_CIRCUIT_CLK_XTAL_X2)) { + rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div); } else { /* fallback */ rtc_clk_cpu_freq_set_config(config); @@ -325,10 +371,7 @@ 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(); - // We don't turn off the bbpll if some consumers depend on bbpll - if (!s_bbpll_digi_consumers_ref_count) { - rtc_clk_bbpll_disable(); - } + rtc_clk_bbpll_disable(); } void rtc_clk_cpu_set_to_default_config(void) @@ -336,6 +379,7 @@ void rtc_clk_cpu_set_to_default_config(void) int freq_mhz = (int)rtc_clk_xtal_freq_get(); rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); + s_cur_pll_freq = 0; // no disable PLL, but set freq to 0 to trigger a PLL calibration after wake-up from sleep } void rtc_clk_cpu_freq_set_xtal_for_sleep(void) @@ -345,55 +389,47 @@ void rtc_clk_cpu_freq_set_xtal_for_sleep(void) void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz) { - rtc_clk_cpu_freq_to_pll_mhz(cpu_freq_mhz); + if (cpu_freq_mhz == 96 || cpu_freq_mhz == 48) { + rtc_clk_cpu_freq_to_pll_mhz(cpu_freq_mhz); + } else { // cpu_freq_mhz == 64 + rtc_clk_cpu_freq_to_xtal_x2(cpu_freq_mhz, 1); + } clk_ll_cpu_clk_src_lock_release(); } soc_xtal_freq_t rtc_clk_xtal_freq_get(void) { -#if !CONFIG_IDF_ENV_FPGA - uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz(); - if (xtal_freq_mhz == 0) { - ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 32MHz"); - return SOC_XTAL_FREQ_32M; - } + uint32_t xtal_freq_mhz = clk_ll_xtal_get_freq_mhz(); + assert(xtal_freq_mhz == SOC_XTAL_FREQ_32M); return (soc_xtal_freq_t)xtal_freq_mhz; -#else - return SOC_XTAL_FREQ_32M; -#endif -} - -void rtc_clk_xtal_freq_update(soc_xtal_freq_t xtal_freq) -{ - clk_ll_xtal_store_freq_mhz(xtal_freq); } static uint32_t rtc_clk_ahb_freq_get(void) { soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); uint32_t soc_root_freq_mhz; - uint32_t divider; + uint32_t cpu_divider = clk_ll_cpu_get_divider(); + uint32_t ahb_divider = clk_ll_ahb_get_divider(); switch (source) { case SOC_CPU_CLK_SRC_XTAL: soc_root_freq_mhz = rtc_clk_xtal_freq_get(); - divider = clk_ll_ahb_get_ls_divider(); break; case SOC_CPU_CLK_SRC_PLL: soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz(); - divider = clk_ll_ahb_get_hs_divider(); break; case SOC_CPU_CLK_SRC_RC_FAST: - soc_root_freq_mhz = 20; - divider = clk_ll_ahb_get_ls_divider(); + soc_root_freq_mhz = 8; + break; + case SOC_CPU_CLK_SRC_XTAL_X2: + soc_root_freq_mhz = clk_ll_xtal_x2_get_freq_mhz(); break; default: // Unknown SOC_ROOT clock source soc_root_freq_mhz = 0; - divider = 1; ESP_HW_LOGE(TAG, "Invalid SOC_ROOT_CLK"); break; } - return soc_root_freq_mhz / divider; + return soc_root_freq_mhz / cpu_divider / ahb_divider; } uint32_t rtc_clk_apb_freq_get(void) diff --git a/components/esp_hw_support/port/esp32h4/rtc_clk_init.c b/components/esp_hw_support/port/esp32h4/rtc_clk_init.c index ce04b33c9a..c391e8593c 100644 --- a/components/esp_hw_support/port/esp32h4/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32h4/rtc_clk_init.c @@ -9,16 +9,12 @@ #include #include #include "rom/ets_sys.h" -#include "rom/rtc.h" -#include "rom/uart.h" +#include "esp32h4/rom/rtc.h" #include "soc/rtc.h" #include "esp_cpu.h" #include "regi2c_ctrl.h" #include "soc/lp_clkrst_reg.h" -#include "soc/regi2c_dig_reg.h" #include "esp_hw_log.h" -#include "sdkconfig.h" -#include "esp_rom_serial_output.h" #include "esp_private/esp_pmu.h" #include "hal/clk_tree_ll.h" #include "hal/pmu_ll.h" @@ -31,30 +27,25 @@ void rtc_clk_init(rtc_clk_config_t cfg) { rtc_cpu_freq_config_t old_config, new_config; - /* Set tuning parameters for RC_FAST, RC_SLOW, and RC32K clocks. + /* Set tuning parameters for RC_FAST and RC_SLOW clocks. * Note: this doesn't attempt to set the clocks to precise frequencies. * Instead, we calibrate these clocks against XTAL frequency later, when necessary. * - SCK_DCAP value controls tuning of RC_SLOW clock. * The higher the value of DCAP is, the lower is the frequency. * - CK8M_DFREQ value controls tuning of RC_FAST clock. * CLK_8M_DFREQ constant gives the best temperature characteristics. - * - RC32K_DFREQ value controls tuning of RC32K clock. */ REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, cfg.slow_clk_dcap); - REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); + REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.slow_clk_dcap); // h4 specific workaround (RC32K_DFREQ is used for RC_SLOW clock tuning) TODO: IDF-12313 + uint32_t hp_cali_dbias = get_act_hp_dbias(); uint32_t lp_cali_dbias = get_act_lp_dbias(); REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias); REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias); - clk_ll_rc_fast_tick_conf(); + // XTAL freq can be directly informed from register field PCR_CLK_XTAL_FREQ - soc_xtal_freq_t xtal_freq = cfg.xtal_freq; - esp_rom_output_tx_wait_idle(0); - rtc_clk_xtal_freq_update(xtal_freq); + // No need to wait UART0 TX idle since its default clock source is XTAL, should not be affected by system clock configuration /* Set CPU frequency */ rtc_clk_cpu_freq_get_config(&old_config); @@ -77,8 +68,6 @@ void rtc_clk_init(rtc_clk_config_t cfg) rtc_clk_32k_enable(true); } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { rtc_clk_32k_enable_external(); - } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { - rtc_clk_rc32k_enable(true); } rtc_clk_8m_enable(need_rc_fast_en); rtc_clk_fast_src_set(cfg.fast_clk_src); diff --git a/components/esp_hw_support/port/esp32h4/rtc_time.c b/components/esp_hw_support/port/esp32h4/rtc_time.c index f36b58d847..7a6805da9a 100644 --- a/components/esp_hw_support/port/esp32h4/rtc_time.c +++ b/components/esp_hw_support/port/esp32h4/rtc_time.c @@ -5,81 +5,51 @@ */ #include -#include "rom/ets_sys.h" +#include "esp32h4/rom/ets_sys.h" #include "soc/rtc.h" -#include "soc/lp_timer_reg.h" #include "hal/lp_timer_hal.h" #include "hal/clk_tree_ll.h" #include "hal/timer_ll.h" #include "soc/timer_group_reg.h" #include "esp_rom_sys.h" #include "assert.h" -#include "hal/efuse_hal.h" -#include "soc/chip_revision.h" #include "esp_private/periph_ctrl.h" static const char *TAG = "rtc_time"; -/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. - * This feature counts the number of XTAL clock cycles within a given number of - * RTC_SLOW_CLK cycles. - * - * Slow clock calibration feature has two modes of operation: one-off and cycling. - * In cycling mode (which is enabled by default on SoC reset), counting of XTAL - * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled - * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed - * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is - * enabled using TIMG_RTC_CALI_START bit. - */ +#define RTC_SLOW_CLK_600K_CAL_TIMEOUT_THRES(cycles) (cycles << 10) +#define RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12) +#define RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(cycles) (TIMG_RTC_CALI_TIMEOUT_THRES_V) // Just use the max timeout thres value -/* On ESP32H4, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2 - * 0: calibrate RC_SLOW clock - * 1: calibrate RC_FAST clock - * 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0 - */ -#define TIMG_RTC_CALI_CLK_SEL_RC_SLOW 0 -#define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1 -#define TIMG_RTC_CALI_CLK_SEL_32K 2 +// Calibration can only be performed on relatively slow speed clock signal. Therefore, for high-speed clocks, +// calibration is performed on their DIV_CLKs. The divider is configurable. We set: +#define CLK_CAL_DIV_VAL(cal_clk) \ + ((cal_clk == RTC_CAL_RC_FAST) ? 32 : 1) -/** - * @brief Clock calibration function used by rtc_clk_cal - * - * Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. - * This feature counts the number of XTAL clock cycles within a given number of - * RTC_SLOW_CLK cycles. - * - * Slow clock calibration feature has two modes of operation: one-off and cycling. - * In cycling mode (which is enabled by default on SoC reset), counting of XTAL - * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled - * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed - * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is - * enabled using TIMG_RTC_CALI_START bit. - * - * @param cal_clk which clock to calibrate - * @param slowclk_cycles number of slow clock cycles to count - * @return number of XTAL clock cycles within the given number of slow clock cycles - */ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V); - uint32_t cali_clk_sel = 0; soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get(); - soc_rtc_slow_clk_src_t old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target(); + soc_clk_calibration_clk_src_t cali_clk_sel = (soc_clk_calibration_clk_src_t)cal_clk; if (cal_clk == RTC_CAL_RTC_MUX) { - cal_clk = (rtc_cal_sel_t)slow_clk_src; - } - if (cal_clk == RTC_CAL_RC_FAST) { - cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_FAST; - } else if (cal_clk == RTC_CAL_RC_SLOW) { - cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_SLOW; - } else { - cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_32K; - clk_ll_32k_calibration_set_target((soc_rtc_slow_clk_src_t)cal_clk); + switch (slow_clk_src) { + case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4: + cali_clk_sel = CLK_CAL_RC_SLOW; + break; + case SOC_RTC_SLOW_CLK_SRC_XTAL32K: + cali_clk_sel = CLK_CAL_32K_XTAL; + break; + case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: + cali_clk_sel = CLK_CAL_32K_OSC_SLOW; + break; + default: + ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated"); + return 0; // Invalid RTC_SLOW_CLK source + } } - - /* Enable requested clock (150k clock is always on) */ + /* Enable requested clock (rc_slow clock is always on) */ // All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock // Only enable if originally was disabled, and set back to the disable state after calibration is done // If the clock is already on, then do nothing @@ -99,17 +69,6 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } } - bool rc32k_enabled = clk_ll_rc32k_is_enabled(); - bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled(); - if (cal_clk == RTC_CAL_RC32K) { - if (!rc32k_enabled) { - rtc_clk_rc32k_enable(true); - } - if (!dig_rc32k_enabled) { - clk_ll_rc32k_digi_enable(); - } - } - /* There may be another calibration process already running during we call this function, * so we should wait the last process is done. */ @@ -124,23 +83,26 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } /* Prepare calibration */ - REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel); + clk_ll_calibration_set_target(cali_clk_sel); + uint32_t clk_cal_divider = CLK_CAL_DIV_VAL(cal_clk); + clk_ll_calibration_set_divider(clk_cal_divider); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); /* Figure out how long to wait for calibration to finish */ /* Set timeout reg and expect time delay*/ uint32_t expected_freq; - if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) { + if (cali_clk_sel == CLK_CAL_32K_XTAL || cali_clk_sel == CLK_CAL_32K_OSC_SLOW) { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; - } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { + } else if (cali_clk_sel == CLK_CAL_RC_FAST) { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX; } else { - REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles)); + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_600K_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; } + expected_freq /= clk_cal_divider; uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq); /* Start calibration */ CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); @@ -152,15 +114,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc while (true) { if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) { cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE); - - /*The Fosc CLK of calibration circuit is divided by 32 for ECO1. - So we need to multiply the frequency of the Fosc for ECO1 and above chips by 32 times. - And ensure that this modification will not affect ECO0.*/ - if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { - if (cal_clk == RTC_CAL_RC_FAST) { - cal_val = cal_val >> 5; - } - } + cal_val /= clk_cal_divider; break; } if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) { @@ -169,6 +123,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } } CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); + clk_ll_calibration_set_divider(1); /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { @@ -184,18 +139,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } } - if (cal_clk == RTC_CAL_RC32K) { - if (!dig_rc32k_enabled) { - clk_ll_rc32k_digi_disable(); - } - if (!rc32k_enabled) { - rtc_clk_rc32k_enable(false); - } - } - - // Always set back the calibration 32kHz clock selection - if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) { - clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel); + if (cal_clk == RTC_CAL_RTC_MUX && slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4) { + // calibration was done on RC_SLOW clock, but rtc_slow_clk src is RC_SLOW_D4, so we need to multiply the cal_val by 4 + cal_val *= 4; } return cal_val; @@ -210,20 +156,12 @@ static bool rtc_clk_cal_32k_valid(soc_xtal_freq_t xtal_freq, uint32_t slowclk_cy uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + slowclk_cycles /= (cal_clk == RTC_CAL_RTC_MUX) ? 1 : CLK_CAL_DIV_VAL(cal_clk); + assert(slowclk_cycles); soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); - - /*The Fosc CLK of calibration circuit is divided by 32 for ECO1. - So we need to divide the calibrate cycles of the FOSC for ECO1 and above chips by 32 to - avoid excessive calibration time.*/ - if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { - if (cal_clk == RTC_CAL_RC_FAST) { - slowclk_cycles = slowclk_cycles >> 5; - } - } - uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); - if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) { + if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid((uint32_t)xtal_freq, slowclk_cycles, xtal_cycles)) { return 0; } @@ -235,9 +173,10 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) { - /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. - * TODO: fix overflow. - */ + assert(period); + if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) { + return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period; + } return (time_in_us << RTC_CLK_CAL_FRACT) / period; } @@ -248,10 +187,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period) uint64_t rtc_time_get(void) { - ESP_EARLY_LOGW(TAG, "rtc_timer has not been implemented yet"); - return 0; - //TODO: [ESP32H4] IDF-11548 - // return lp_timer_hal_get_cycle_count(); + return lp_timer_hal_get_cycle_count(); } uint32_t rtc_clk_freq_cal(uint32_t cal_val) diff --git a/components/esp_hw_support/port/esp32p4/include/soc/rtc.h b/components/esp_hw_support/port/esp32p4/include/soc/rtc.h index 20875057b1..3bc8b96167 100644 --- a/components/esp_hw_support/port/esp32p4/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32p4/include/soc/rtc.h @@ -191,7 +191,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 90, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/port/esp32s2/include/soc/rtc.h b/components/esp_hw_support/port/esp32s2/include/soc/rtc.h index bee133f725..0bd7d49d0d 100644 --- a/components/esp_hw_support/port/esp32s2/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32s2/include/soc/rtc.h @@ -188,7 +188,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 80, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/port/esp32s3/include/soc/rtc.h b/components/esp_hw_support/port/esp32s3/include/soc/rtc.h index db2e178f82..9bf17221f6 100644 --- a/components/esp_hw_support/port/esp32s3/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32s3/include/soc/rtc.h @@ -190,7 +190,7 @@ typedef struct { */ #define RTC_CLK_CONFIG_DEFAULT() { \ .xtal_freq = CONFIG_XTAL_FREQ, \ - .cpu_freq_mhz = 80, \ + .cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ diff --git a/components/esp_hw_support/test_apps/rtc_clk/README.md b/components/esp_hw_support/test_apps/rtc_clk/README.md index 15bfc62bf3..44f3780f1d 100644 --- a/components/esp_hw_support/test_apps/rtc_clk/README.md +++ b/components/esp_hw_support/test_apps/rtc_clk/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c b/components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c index b7e1bcff4f..60eafcf3fa 100644 --- a/components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c +++ b/components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c @@ -327,8 +327,8 @@ TEST_CASE("Test starting 'External 32kHz XTAL' on the board without it.", "[rtc_ "will switch to the internal RC circuit. If the switch to the internal RC circuit " "was successful then the test succeeded.\n"); - start_freq(SOC_RTC_SLOW_CLK_SRC_RC_SLOW, 200); - start_freq(SOC_RTC_SLOW_CLK_SRC_RC_SLOW, 0); + start_freq(SOC_RTC_SLOW_CLK_SRC_DEFAULT, 200); + start_freq(SOC_RTC_SLOW_CLK_SRC_DEFAULT, 0); } #endif // !defined(CONFIG_IDF_CI_BUILD) || !CONFIG_SPIRAM_BANKSWITCH_ENABLE diff --git a/components/esp_rom/esp32h4/include/esp32h4/rom/rtc.h b/components/esp_rom/esp32h4/include/esp32h4/rom/rtc.h index d27c73a695..159d7dd660 100644 --- a/components/esp_rom/esp32h4/include/esp32h4/rom/rtc.h +++ b/components/esp_rom/esp32h4/include/esp32h4/rom/rtc.h @@ -8,8 +8,8 @@ #include #include +#include #include "esp_assert.h" - #include "soc/soc.h" #include "soc/lp_aon_reg.h" #include "soc/reset_reasons.h" @@ -18,8 +18,6 @@ extern "C" { #endif -//TODO: [ESP32H4] IDF-12313 inherit from verification branch, need check - /** \defgroup rtc_apis, rtc registers and memory related apis * @brief rtc apis */ @@ -44,29 +42,35 @@ extern "C" { * ************************************************************************************* * RTC store registers usage - * LP_AON_STORE0_REG Reserved + * LP_AON_STORE0_REG RTC fix us, high 32 bits * LP_AON_STORE1_REG RTC_SLOW_CLK calibration value * LP_AON_STORE2_REG Boot time, low word * LP_AON_STORE3_REG Boot time, high word - * LP_AON_STORE4_REG External XTAL frequency + * LP_AON_STORE4_REG Status of whether to disable LOG from ROM at bit[0] * LP_AON_STORE5_REG FAST_RTC_MEMORY_LENGTH * LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY - * LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC + * LP_AON_STORE7_REG RTC fix us, low 32 bits * LP_AON_STORE8_REG Store light sleep wake stub addr * LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep) ************************************************************************************* + * + * Since esp32h4 does not support RTC mem, so use LP_AON store regs to record rtc time: + * + * |------------------------|----------------------------------------| + * | LP_AON_STORE0_REG | LP_AON_STORE7_REG | + * | rtc_fix_us(MSB) | rtc_fix_us(LSB) | + * |------------------------|----------------------------------------| */ #define RTC_FIX_US_HIGH_REG LP_AON_STORE0_REG #define RTC_SLOW_CLK_CAL_REG LP_AON_STORE1_REG #define RTC_BOOT_TIME_LOW_REG LP_AON_STORE2_REG #define RTC_BOOT_TIME_HIGH_REG LP_AON_STORE3_REG -#define RTC_XTAL_FREQ_REG LP_AON_STORE4_REG #define RTC_ENTRY_LENGTH_REG LP_AON_STORE5_REG #define RTC_ENTRY_ADDR_REG LP_AON_STORE6_REG #define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG #define RTC_FIX_US_LOW_REG LP_AON_STORE7_REG -#define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG -#define SLEEP_MODE_REG LP_AON_STORE9_REG +#define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG +#define RTC_SLEEP_MODE_REG LP_AON_STORE9_REG #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. @@ -215,7 +219,7 @@ void esp_rom_set_rtc_wake_addr(esp_rom_wake_func_t entry_addr, size_t length); static inline void rtc_suppress_rom_log(void) { /* To disable logging in the ROM, only the least significant bit of the register is used, - * but since this register is also used to store the frequency of the main crystal (RTC_XTAL_FREQ_REG), + * but this register was also used to store the frequency of the main crystal (RTC_XTAL_FREQ_REG) on old targets, * you need to write to this register in the same format. * Namely, the upper 16 bits and lower should be the same. */ diff --git a/components/esp_rom/patches/esp_rom_regi2c_esp32h4.c b/components/esp_rom/patches/esp_rom_regi2c_esp32h4.c index ebc179de4f..288080994c 100644 --- a/components/esp_rom/patches/esp_rom_regi2c_esp32h4.c +++ b/components/esp_rom/patches/esp_rom_regi2c_esp32h4.c @@ -7,6 +7,7 @@ #include "esp_attr.h" #include "soc/i2c_ana_mst_reg.h" #include "hal/regi2c_ctrl_ll.h" +#include "sdkconfig.h" /* SLAVE */ #define REGI2C_BBPLL (0x66) @@ -26,7 +27,9 @@ void esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block) { uint32_t i2c_sel = 0; +#if !CONFIG_IDF_ENV_FPGA // on FPGA, unable to manipulate modem registers, skip the check assert(regi2c_ctrl_ll_master_is_clock_enabled()); +#endif /* Before config I2C register, enable corresponding slave. */ switch (block) { diff --git a/components/esp_system/port/soc/esp32h4/Kconfig.cpu b/components/esp_system/port/soc/esp32h4/Kconfig.cpu index bec29f8ca5..50e396a100 100644 --- a/components/esp_system/port/soc/esp32h4/Kconfig.cpu +++ b/components/esp_system/port/soc/esp32h4/Kconfig.cpu @@ -1,17 +1,27 @@ choice ESP_DEFAULT_CPU_FREQ_MHZ prompt "CPU frequency" - default ESP_DEFAULT_CPU_FREQ_MHZ_32 if IDF_ENV_FPGA + default ESP_DEFAULT_CPU_FREQ_MHZ_32 if IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING + default ESP_DEFAULT_CPU_FREQ_MHZ_96 help CPU frequency to be set on application startup. config ESP_DEFAULT_CPU_FREQ_MHZ_32 bool "32 MHz" - depends on IDF_ENV_FPGA + depends on IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING + config ESP_DEFAULT_CPU_FREQ_MHZ_48 + bool "48 MHz" + depends on !IDF_ENV_FPGA config ESP_DEFAULT_CPU_FREQ_MHZ_64 bool "64 MHz" + depends on !IDF_ENV_FPGA + config ESP_DEFAULT_CPU_FREQ_MHZ_96 + bool "96 MHz" + depends on !IDF_ENV_FPGA endchoice config ESP_DEFAULT_CPU_FREQ_MHZ int default 32 if ESP_DEFAULT_CPU_FREQ_MHZ_32 + default 48 if ESP_DEFAULT_CPU_FREQ_MHZ_48 default 64 if ESP_DEFAULT_CPU_FREQ_MHZ_64 + default 96 if ESP_DEFAULT_CPU_FREQ_MHZ_96 diff --git a/components/esp_system/port/soc/esp32h4/clk.c b/components/esp_system/port/soc/esp32h4/clk.c index 2320f5b2d9..b603deeb3b 100644 --- a/components/esp_system/port/soc/esp32h4/clk.c +++ b/components/esp_system/port/soc/esp32h4/clk.c @@ -17,7 +17,6 @@ #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_periph.h" -#include "soc/i2s_reg.h" #include "esp_cpu.h" #include "hal/wdt_hal.h" #include "esp_private/periph_ctrl.h" @@ -26,8 +25,6 @@ #include "esp_rom_serial_output.h" #include "esp_rom_sys.h" -//TODO: [ESP32H4] IDF-12285 inherited from verification branch, need check - /* Number of cycles to wait from the 32k XTAL oscillator to consider it running. * Larger values increase startup delay. Smaller values may cause false positive * detection (i.e. oscillator runs for a few cycles and then stops). @@ -40,11 +37,18 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; +void esp_rtc_init(void) +{ +#if SOC_PMU_SUPPORTED && !CONFIG_IDF_ENV_FPGA + pmu_init(); +#endif +} + __attribute__((weak)) void esp_clk_init(void) { #if !CONFIG_IDF_ENV_FPGA pmu_init(); - assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); + assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_32M); rtc_clk_8m_enable(true); rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); @@ -57,7 +61,7 @@ __attribute__((weak)) void esp_clk_init(void) // This prevents excessive delay before resetting in case the supply voltage is drawdown. // (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 1.6sec * 150/32 = 7.5 sec). wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT(); - uint32_t stage_timeout_ticks = (uint32_t)(1600ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); + uint32_t stage_timeout_ticks = (uint32_t)(2000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); wdt_hal_write_protect_disable(&rtc_wdt_ctx); wdt_hal_feed(&rtc_wdt_ctx); //Bootloader has enabled RTC WDT until now. We're only modifying timeout, so keep the stage and timeout action the same @@ -69,10 +73,8 @@ __attribute__((weak)) void esp_clk_init(void) select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K); #elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC) select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_OSC_SLOW); -#elif defined(CONFIG_RTC_CLK_SRC_INT_RC32K) - select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC32K); #else - select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW); + select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4); #endif #ifdef CONFIG_BOOTLOADER_WDT_ENABLE @@ -94,9 +96,11 @@ __attribute__((weak)) void esp_clk_init(void) // Wait for UART TX to finish, otherwise some UART output will be lost // when switching APB frequency - esp_rom_output_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); + if (CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM != -1) { + esp_rom_output_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); + } - if (res) { + if (res) { rtc_clk_cpu_freq_set_config(&new_config); } @@ -138,17 +142,18 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src) continue; } ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 150 kHz oscillator"); - rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW; + rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4; } } - } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { - rtc_clk_rc32k_enable(true); } rtc_clk_slow_src_set(rtc_slow_clk_src); + // Disable unused clock sources after clock source switching is complete. + // Regardless of the clock source selection, the internal 600k clock source will always keep on. if ((rtc_slow_clk_src != SOC_RTC_SLOW_CLK_SRC_XTAL32K) && (rtc_slow_clk_src != SOC_RTC_SLOW_CLK_SRC_OSC_SLOW)) { rtc_clk_32k_enable(false); rtc_clk_32k_disable_external(); } + if (SLOW_CLK_CAL_CYCLES > 0) { /* TODO: 32k XTAL oscillator has some frequency drift at startup. * Improve calibration routine to wait until the frequency is stable. @@ -176,6 +181,5 @@ void rtc_clk_select_rtc_slow_clk(void) */ __attribute__((weak)) void esp_perip_clk_init(void) { - ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); } diff --git a/components/hal/esp32h4/clk_tree_hal.c b/components/hal/esp32h4/clk_tree_hal.c index 9e29aed9cb..63e85df95c 100644 --- a/components/hal/esp32h4/clk_tree_hal.c +++ b/components/hal/esp32h4/clk_tree_hal.c @@ -6,13 +6,7 @@ #include "hal/clk_tree_hal.h" #include "hal/clk_tree_ll.h" -#include "soc/rtc.h" #include "hal/assert.h" -#include "hal/log.h" - -//TODO: [ESP32H4] IDF-12285 inherited from verification branch, need check - -static const char *CLK_HAL_TAG = "clk_hal"; uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) { @@ -23,6 +17,8 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) return clk_ll_bbpll_get_freq_mhz(); case SOC_CPU_CLK_SRC_RC_FAST: return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ; + case SOC_CPU_CLK_SRC_XTAL_X2: + return clk_ll_xtal_x2_get_freq_mhz(); default: // Unknown CPU_CLK mux input HAL_ASSERT(false); @@ -33,15 +29,12 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) uint32_t clk_hal_cpu_get_freq_hz(void) { soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); - uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_cpu_get_hs_divider() : clk_ll_cpu_get_ls_divider(); - return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider; + return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider(); } uint32_t clk_hal_ahb_get_freq_hz(void) { - soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); - uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_ahb_get_hs_divider() : clk_ll_ahb_get_ls_divider(); - return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider; + return clk_hal_cpu_get_freq_hz() / clk_ll_ahb_get_divider(); } uint32_t clk_hal_apb_get_freq_hz(void) @@ -52,14 +45,12 @@ uint32_t clk_hal_apb_get_freq_hz(void) uint32_t clk_hal_lp_slow_get_freq_hz(void) { switch (clk_ll_rtc_slow_get_src()) { - case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: - return SOC_CLK_RC_SLOW_FREQ_APPROX; + case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4: + return SOC_CLK_RC_SLOW_FREQ_APPROX / 4; case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX; case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX; - case SOC_RTC_SLOW_CLK_SRC_RC32K: - return SOC_CLK_RC32K_FREQ_APPROX; default: // Unknown RTC_SLOW_CLK mux input HAL_ASSERT(false); @@ -69,10 +60,7 @@ uint32_t clk_hal_lp_slow_get_freq_hz(void) uint32_t clk_hal_xtal_get_freq_mhz(void) { - uint32_t freq = clk_ll_xtal_load_freq_mhz(); - if (freq == 0) { - HAL_LOGW(CLK_HAL_TAG, "invalid SOC_XTAL_FREQ_32M value, assume 32MHz"); - return (uint32_t)SOC_XTAL_FREQ_32M; - } + uint32_t freq = clk_ll_xtal_get_freq_mhz(); + HAL_ASSERT(freq == SOC_XTAL_FREQ_32M); return freq; } diff --git a/components/hal/esp32h4/include/hal/clk_tree_ll.h b/components/hal/esp32h4/include/hal/clk_tree_ll.h index c7d378cf94..9163ac58d1 100644 --- a/components/hal/esp32h4/include/hal/clk_tree_ll.h +++ b/components/hal/esp32h4/include/hal/clk_tree_ll.h @@ -9,18 +9,16 @@ #include #include "soc/soc.h" #include "soc/clk_tree_defs.h" -#include "rom/rtc.h" #include "soc/pcr_struct.h" #include "soc/lp_clkrst_struct.h" #include "soc/pmu_reg.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_bbpll.h" +#include "esp32h4/rom/rtc.h" #include "hal/assert.h" #include "hal/log.h" #include "hal/misc.h" -//TODO: [ESP32H4] IDF-12285 inherited from verification branch, need check - #ifdef __cplusplus extern "C" { #endif @@ -28,6 +26,7 @@ extern "C" { #define MHZ (1000000) #define CLK_LL_PLL_8M_FREQ_MHZ (8) +#define CLK_LL_PLL_32M_FREQ_MHZ (32) #define CLK_LL_PLL_48M_FREQ_MHZ (48) #define CLK_LL_PLL_64M_FREQ_MHZ (64) #define CLK_LL_PLL_96M_FREQ_MHZ (96) @@ -39,13 +38,6 @@ extern "C" { .dbuf = 1, \ } -/* -Set the frequency division factor of ref_tick -The FOSC of rtc calibration uses the 32 frequency division clock for ECO1, -So the frequency division factor of ref_tick must be greater than or equal to 32 -*/ -#define REG_FOSC_TICK_NUM 255 - /** * @brief XTAL32K_CLK enable modes */ @@ -70,8 +62,7 @@ typedef struct { */ static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void) { - SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C | - PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C); + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C | PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C); SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG); } @@ -92,6 +83,27 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_clk_src_lock_releas SET_PERI_REG_MASK(PMU_IMM_SLEEP_SYSCLK_REG, PMU_UPDATE_DIG_SYS_CLK_SEL); } +/** + * @brief Power up XTAL_X2 circuit + */ +static inline __attribute__((always_inline)) void clk_ll_xtal_x2_enable(void) +{ + CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_XTALX2); + CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_XTALX2_ICG); + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XTALX2); + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_XTALX2_ICG); +} + +/** + * @brief Power down XTAL_X2 circuit + */ +static inline __attribute__((always_inline)) void clk_ll_xtal_x2_disable(void) +{ + CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XTALX2 | PMU_TIE_HIGH_GLOBAL_XTALX2_ICG); + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_XTALX2); + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_XTALX2_ICG); +} + /** * @brief Enable the 32kHz crystal oscillator * @@ -132,34 +144,6 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K) == 1; } -/** - * @brief Enable the internal oscillator output for RC32K_CLK - */ -static inline __attribute__((always_inline)) void clk_ll_rc32k_enable(void) -{ - // Enable rc32k xpd status - SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K); -} - -/** - * @brief Disable the internal oscillator output for RC32K_CLK - */ -static inline __attribute__((always_inline)) void clk_ll_rc32k_disable(void) -{ - // Disable rc32k xpd status - CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K); -} - -/** - * @brief Get the state of the internal oscillator for RC32K_CLK - * - * @return True if the oscillator is enabled - */ -static inline __attribute__((always_inline)) bool clk_ll_rc32k_is_enabled(void) -{ - return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K) == 1; -} - /** * @brief Enable the internal oscillator output for RC_FAST_CLK */ @@ -239,29 +223,13 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_digi_is_enabled } /** - * @brief Enable the digital RC32K_CLK, which is used to support peripherals. - */ -static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_enable(void) -{ - LP_CLKRST.clk_to_hp.icg_hp_osc32k = 1; -} - -/** - * @brief Disable the digital RC32K_CLK, which is used to support peripherals. - */ -static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_disable(void) -{ - LP_CLKRST.clk_to_hp.icg_hp_osc32k = 0; -} - -/** - * @brief Get the state of the digital RC32K_CLK + * @brief Get XTAL_CLK frequency * - * @return True if the digital RC32K_CLK is enabled + * @return Main XTAL clock frequency, in MHz. */ -static inline __attribute__((always_inline)) bool clk_ll_rc32k_digi_is_enabled(void) +static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_get_freq_mhz(void) { - return LP_CLKRST.clk_to_hp.icg_hp_osc32k; + return PCR.sysclk_conf.clk_xtal_freq; } /** @@ -295,37 +263,43 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint */ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz) { - // HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_96M_FREQ_MHZ); - // uint8_t div_ref; - // uint8_t div7_0; - // uint8_t dr1; - // uint8_t dr3; - // uint8_t dchgp; - // uint8_t dcur; - // uint8_t dbias; + HAL_ASSERT(xtal_freq_mhz == SOC_XTAL_FREQ_32M); + HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_96M_FREQ_MHZ); + uint8_t oc_ref_div; + uint8_t oc_div; + uint8_t oc_dhref_sel; + uint8_t oc_dlref_sel; - // /* Configure 480M PLL */ - // switch (xtal_freq_mhz) { - // case SOC_XTAL_FREQ_32M: - // default: - // div_ref = 0; - // div7_0 = 8; - // dr1 = 0; - // dr3 = 0; - // dchgp = 5; - // dcur = 3; - // dbias = 2; - // break; - // } - // uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); - // uint8_t i2c_bbpll_div_7_0 = div7_0; - // uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; - // REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); - // REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); - // REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); - // REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3); - // REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur); - // REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias); + oc_ref_div = 8; + oc_div = 24; + oc_dhref_sel = 3; + oc_dlref_sel = 1; + + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, oc_ref_div); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DIV, oc_div); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, oc_dhref_sel); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, oc_dlref_sel); +} + +/** + * @brief Get XTAL_X2_CLK frequency + * + * @return XTAL_X2 clock frequency, in MHz + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_x2_get_freq_mhz(void) +{ + return SOC_XTAL_FREQ_32M * 2; +} + +/** + * @brief To enable the change of soc_clk_sel, cpu_div_num, ahb_div_num, apb_div_num + * + * If the group of the parameters are invalid, the bus may get stuck. + */ +static inline __attribute__((always_inline)) void clk_ll_bus_update(void) +{ + PCR.bus_clk_update.bus_clock_update = 1; + while (PCR.bus_clk_update.bus_clock_update); } /** @@ -339,12 +313,15 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk case SOC_CPU_CLK_SRC_XTAL: PCR.sysclk_conf.soc_clk_sel = 0; break; - case SOC_CPU_CLK_SRC_PLL: + case SOC_CPU_CLK_SRC_RC_FAST: PCR.sysclk_conf.soc_clk_sel = 1; break; - case SOC_CPU_CLK_SRC_RC_FAST: + case SOC_CPU_CLK_SRC_XTAL_X2: PCR.sysclk_conf.soc_clk_sel = 2; break; + case SOC_CPU_CLK_SRC_PLL: + PCR.sysclk_conf.soc_clk_sel = 3; + break; default: // Unsupported SOC_CLK mux input sel abort(); @@ -363,9 +340,11 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr case 0: return SOC_CPU_CLK_SRC_XTAL; case 1: - return SOC_CPU_CLK_SRC_PLL; - case 2: return SOC_CPU_CLK_SRC_RC_FAST; + case 2: + return SOC_CPU_CLK_SRC_XTAL_X2; + case 3: + return SOC_CPU_CLK_SRC_PLL; default: // Invalid SOC_CLK_SEL value return SOC_CPU_CLK_SRC_INVALID; @@ -373,129 +352,48 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr } /** - * @brief Set CPU_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) + * @brief Set CPU_CLK divider * - * @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider. + * @param divider Divider. PRE_DIV_CNT = divider - 1. */ -static inline __attribute__((always_inline)) void clk_ll_cpu_set_hs_divider(uint32_t divider) +static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider) { - // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK - // (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM) - // Fixed at 3 for HS clock source - // Corresponding register field value is PCR_HS_DIV_NUM=2 - // (2) configurable - // HS divider option: 1, 2, 4 (PCR_CPU_HS_DIV_NUM=0, 1, 3) - - HAL_ASSERT(divider == 3 || divider == 4 || divider == 6 || divider == 12); - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, (divider / 3) - 1); - - // 120MHz CPU freq cannot be achieved through divider, need to set force_120m - // This field is only valid if PCR_CPU_HS_DIV_NUM=0 and PCR_SOC_CLK_SEL=SOC_CPU_CLK_SRC_PLL - // bool force_120m = (divider == 4) ? 1 : 0; - // PCR.cpu_freq_conf.cpu_hs_120m_force = force_120m; -} - -/** - * @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) - * - * @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider. - */ -static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider) -{ - // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK - // (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM) - // Fixed at 1 for LS clock source - // Corresponding register field value is PCR_LS_DIV_NUM=0 - // (2) configurable - // LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31) - HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0)); + // HP_ROOT_CLK ------> CPU_CLK + // f_hp_root = 2 ^ n * f_cpu + HAL_ASSERT(divider >= 1 && ((divider & (divider - 1)) == 0)); HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, divider - 1); } /** - * @brief Get CPU_CLK's high-speed divider + * @brief Get CPU_CLK divider * - * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1). + * @return Divider. Divider = (PRE_DIV_CNT + 1). */ -static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_divider(void) +static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void) { - // uint32_t force_120m = PCR.cpu_freq_conf.cpu_hs_120m_force; - uint32_t cpu_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num); - if (cpu_hs_div == 0) { - return 4; - } - uint32_t hp_root_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, hs_div_num); - return (hp_root_hs_div + 1) * (cpu_hs_div + 1); + return HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num) + 1; } /** - * @brief Get CPU_CLK's low-speed divider + * @brief Set AHB_CLK divider * - * @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1). + * @param divider Divider. PRE_DIV_CNT = divider - 1. */ -static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_ls_divider(void) +static inline __attribute__((always_inline)) void clk_ll_ahb_set_divider(uint32_t divider) { - uint32_t cpu_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num); - uint32_t hp_root_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, ls_div_num); - return (hp_root_ls_div + 1) * (cpu_ls_div + 1); -} - -/** - * @brief Set AHB_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) - * - * @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1) = divider. - */ -static inline __attribute__((always_inline)) void clk_ll_ahb_set_hs_divider(uint32_t divider) -{ - // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK - // (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM) - // Fixed at 3 for HS clock source - // Corresponding register field value is PCR_HS_DIV_NUM=2 - // (2) configurable - // HS divider option: 4, 8, 16 (PCR_AHB_HS_DIV_NUM=3, 7, 15) - HAL_ASSERT(divider == 12 || divider == 24 || divider == 48); - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num, (divider / 3) - 1); -} - -/** - * @brief Set AHB_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) - * - * @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1) = divider. - */ -static inline __attribute__((always_inline)) void clk_ll_ahb_set_ls_divider(uint32_t divider) -{ - // SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK - // (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM) - // Fixed at 1 for LS clock source - // Corresponding register field value is PCR_LS_DIV_NUM=0 - // (2) configurable - // LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31) - HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0)); + // CPU_CLK ------> AHB_CLK + HAL_ASSERT(divider >= 1); HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num, divider - 1); } /** - * @brief Get AHB_CLK's high-speed divider + * @brief Get AHB_CLK divider * - * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1). + * @return Divider. Divider = (PRE_DIV_CNT + 1). */ -static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_hs_divider(void) +static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_divider(void) { - uint32_t ahb_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num); - uint32_t hp_root_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, hs_div_num); - return (hp_root_hs_div + 1) * (ahb_hs_div + 1); -} - -/** - * @brief Get AHB_CLK's low-speed divider - * - * @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1). - */ -static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_ls_divider(void) -{ - uint32_t ahb_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num); - uint32_t hp_root_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, ls_div_num); - return (hp_root_ls_div + 1) * (ahb_ls_div + 1); + return HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num) + 1; } /** @@ -522,100 +420,95 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi } /** - * @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) + * @brief Select the calibration clock source for timergroup0 * - * @param divider Divider. + * @param clk_sel One of the clock sources in soc_clk_calibration_clk_src_t */ -static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divider(uint32_t divider) +static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_clk_calibration_clk_src_t clk_sel) { - // SOC_ROOT_CLK ------> MSPI_FAST_CLK - // HS divider option: 4, 5, 6 (PCR_MSPI_FAST_HS_DIV_NUM=3, 4, 5) - uint32_t div_num = 0; - switch (divider) { - case 4: - div_num = 3; - break; - case 5: - div_num = 4; - break; - case 6: - div_num = 5; - break; - default: - // Unsupported HS MSPI_FAST divider - abort(); - } - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_div_num, div_num); -} + int timg_cali_clk_sel = -1; + int timg_secure_clk_sel = -1; -/** - * @brief Set MSPI_FAST_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) - * - * @param divider Divider. - */ -static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_ls_divider(uint32_t divider) -{ - // SOC_ROOT_CLK ------> MSPI_FAST_CLK - // LS divider option: 1, 2, 4 (PCR_MSPI_FAST_LS_DIV_NUM=0, 1, 2) - uint32_t div_num = 0; - switch (divider) { - case 1: - div_num = 0; - break; - case 2: - div_num = 1; - break; - case 4: - div_num = 2; - break; - default: - // Unsupported LS MSPI_FAST divider - abort(); - } - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_div_num, div_num); -} - -/** - * @brief Select the calibration 32kHz clock source for timergroup0 - * - * @param in_sel One of the 32kHz clock sources (RC32K_CLK, XTAL32K_CLK, OSC_SLOW_CLK) - */ -static inline __attribute__((always_inline)) void clk_ll_32k_calibration_set_target(soc_rtc_slow_clk_src_t in_sel) -{ - switch (in_sel) { - case SOC_RTC_SLOW_CLK_SRC_RC32K: - PCR.timg_cali_clk_conf.timg_cali_clk_sel = 0; - break; - case SOC_RTC_SLOW_CLK_SRC_XTAL32K: - PCR.timg_cali_clk_conf.timg_cali_clk_sel = 1; - break; - case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: - PCR.timg_cali_clk_conf.timg_cali_clk_sel = 2; - break; - default: - // Unsupported 32K_SEL mux input - abort(); - } -} - -/** - * @brief Get the calibration 32kHz clock source for timergroup0 - * - * @return soc_rtc_slow_clk_src_t Currently selected calibration 32kHz clock (one of the 32kHz clocks) - */ -static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_calibration_get_target(void) -{ - uint32_t clk_sel = PCR.timg_cali_clk_conf.timg_cali_clk_sel; switch (clk_sel) { - case 0: - return SOC_RTC_SLOW_CLK_SRC_RC32K; - case 1: - return SOC_RTC_SLOW_CLK_SRC_XTAL32K; - case 2: - return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW; + case CLK_CAL_32K_XTAL: + timg_cali_clk_sel = 1; + break; + case CLK_CAL_32K_OSC_SLOW: + timg_cali_clk_sel = 2; + break; + case CLK_CAL_RC_SLOW: + timg_cali_clk_sel = 3; + break; + case CLK_CAL_EXT_IO: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 0; + break; + case CLK_CAL_CPU: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 1; + break; + case CLK_CAL_AHB: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 2; + break; + case CLK_CAL_APB: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 3; + break; + case CLK_CAL_SEC: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 4; + break; + case CLK_CAL_MSPI: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 5; + break; + case CLK_CAL_IOMUX: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 6; + break; + case CLK_CAL_PARLIO_RX: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 7; + break; + case CLK_CAL_PARLIO_TX: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 8; + break; + case CLK_CAL_GPSPI3_MST: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 9; + break; + case CLK_CAL_GPSPI2_MST: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 10; + break; + case CLK_CAL_RC_FAST: + timg_cali_clk_sel = 4; + timg_secure_clk_sel = 11; + break; default: - return SOC_RTC_SLOW_CLK_SRC_INVALID; + // Unsupported CLK_CAL mux input + abort(); } + + if (timg_cali_clk_sel >= 0) { + PCR.timg_cali_clk_conf.timg_cali_clk_sel = timg_cali_clk_sel; + } + if (timg_secure_clk_sel >= 0) { + PCR.timg_cali_clk_conf.timg_secure_clk_sel = timg_secure_clk_sel; + } +} + +/** + * @brief Set a divider for the clock to be calibrated by timergroup0 + * + * @param divider Divider. PRE_DIV_CNT = divider - 1. + */ +static inline __attribute__((always_inline)) void clk_ll_calibration_set_divider(uint32_t divider) +{ + HAL_ASSERT(divider >= 1); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.timg_cali_clk_conf, timg_secure_clk_div_num, divider - 1); } /** @@ -626,15 +519,12 @@ static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_c static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel) { switch (in_sel) { - case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: + case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4: LP_CLKRST.lp_clk_conf.slow_clk_sel = 0; break; case SOC_RTC_SLOW_CLK_SRC_XTAL32K: LP_CLKRST.lp_clk_conf.slow_clk_sel = 1; break; - case SOC_RTC_SLOW_CLK_SRC_RC32K: - LP_CLKRST.lp_clk_conf.slow_clk_sel = 2; - break; case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: LP_CLKRST.lp_clk_conf.slow_clk_sel = 3; break; @@ -654,11 +544,9 @@ static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_s uint32_t clk_sel = LP_CLKRST.lp_clk_conf.slow_clk_sel; switch (clk_sel) { case 0: - return SOC_RTC_SLOW_CLK_SRC_RC_SLOW; + return SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4; case 1: return SOC_RTC_SLOW_CLK_SRC_XTAL32K; - case 2: - return SOC_RTC_SLOW_CLK_SRC_RC32K; case 3: return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW; default: @@ -729,56 +617,15 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider /** * @brief Set RC_SLOW_CLK divider * - * @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage. + * @param divider Divider of RC_SLOW_CLK. Fixed the divider to 4 on the target. */ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uint32_t divider) { - // No divider on the target - HAL_ASSERT(divider == 1); + // Register not exposed + HAL_ASSERT(divider == 4); } /************************** LP STORAGE REGISTER STORE/LOAD **************************/ -/** - * @brief Store XTAL_CLK frequency in RTC storage register - * - * Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit - * halves. These are the routines to work with that representation. - * - * @param xtal_freq_mhz XTAL frequency, in MHz. The frequency must necessarily be even, - * otherwise there will be a conflict with the low bit, which is used to disable logs - * in the ROM code. - */ -static inline __attribute__((always_inline)) void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz) -{ - // Read the status of whether disabling logging from ROM code - uint32_t reg = READ_PERI_REG(RTC_XTAL_FREQ_REG) & RTC_DISABLE_ROM_LOG; - // If so, need to write back this setting - if (reg == RTC_DISABLE_ROM_LOG) { - xtal_freq_mhz |= 1; - } - WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16)); -} - -/** - * @brief Load XTAL_CLK frequency from RTC storage register - * - * Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit - * halves. These are the routines to work with that representation. - * - * @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid. - */ -static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void) -{ - // Read from RTC storage register - uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); - if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) && - xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) { - return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX; - } - // If the format in reg is invalid - return 0; -} - /** * @brief Store RTC_SLOW_CLK calibration value in RTC storage register * @@ -804,15 +651,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v return REG_READ(RTC_SLOW_CLK_CAL_REG); } - -/* -Set the frequency division factor of ref_tick -*/ -static inline void clk_ll_rc_fast_tick_conf(void) -{ - PCR.timg_cali_clk_conf.timg_secure_clk_div_num = REG_FOSC_TICK_NUM; -} - /** * @brief Store rtc_fix_us in RTC storage register * diff --git a/components/hal/esp32h4/include/hal/lp_aon_ll.h b/components/hal/esp32h4/include/hal/lp_aon_ll.h index f31234fc70..d034ec8a77 100644 --- a/components/hal/esp32h4/include/hal/lp_aon_ll.h +++ b/components/hal/esp32h4/include/hal/lp_aon_ll.h @@ -85,10 +85,10 @@ static inline uint32_t lp_aon_ll_ext1_get_wakeup_pins(void) static inline void lp_aon_ll_inform_wakeup_type(bool dslp) { if (dslp) { - REG_SET_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */ + REG_SET_BIT(RTC_SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */ } else { - REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */ + REG_CLR_BIT(RTC_SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */ } } #ifdef __cplusplus diff --git a/components/soc/esp32/include/soc/clk_tree_defs.h b/components/soc/esp32/include/soc/clk_tree_defs.h index 48668299f1..2516908ec7 100644 --- a/components/soc/esp32/include/soc/clk_tree_defs.h +++ b/components/soc/esp32/include/soc/clk_tree_defs.h @@ -86,6 +86,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index 340a2a4623..6fe8afa731 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -153,17 +153,9 @@ //}} //Periheral Clock {{ -#define APB_CLK_FREQ_ROM ( 26*1000000 ) -#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM -#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) -#define UART_CLK_FREQ APB_CLK_FREQ -#define WDT_CLK_FREQ APB_CLK_FREQ -#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16 -#define SPI_CLK_DIV 4 -#define TICKS_PER_US_ROM 26 // CPU is 80MHz //}} /* Overall memory map */ diff --git a/components/soc/esp32c2/include/soc/clk_tree_defs.h b/components/soc/esp32c2/include/soc/clk_tree_defs.h index 2fda76d4b9..15d1c7f009 100644 --- a/components/soc/esp32c2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c2/include/soc/clk_tree_defs.h @@ -84,6 +84,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 1, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32c2/include/soc/soc.h b/components/soc/esp32c2/include/soc/soc.h index a1d7b8fa47..8f3945dac9 100644 --- a/components/soc/esp32c2/include/soc/soc.h +++ b/components/soc/esp32c2/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -140,17 +140,9 @@ //}} //Periheral Clock {{ -#define APB_CLK_FREQ_ROM ( 40*1000000 ) -#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM -#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ (SOC_XTAL_FREQ_MHZ * 1000000 ) #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) -#define UART_CLK_FREQ APB_CLK_FREQ -#define WDT_CLK_FREQ APB_CLK_FREQ -#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 4 -#define SPI_CLK_DIV 4 -#define TICKS_PER_US_ROM 40 // CPU is 40MHz //}} /* Overall memory map */ diff --git a/components/soc/esp32c3/include/soc/clk_tree_defs.h b/components/soc/esp32c3/include/soc/clk_tree_defs.h index 287ffe305a..8914f1ab0c 100644 --- a/components/soc/esp32c3/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c3/include/soc/clk_tree_defs.h @@ -82,6 +82,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32c3/include/soc/soc.h b/components/soc/esp32c3/include/soc/soc.h index 1b47dd70fb..da0dbb8a84 100644 --- a/components/soc/esp32c3/include/soc/soc.h +++ b/components/soc/esp32c3/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -134,18 +134,9 @@ //}} //Periheral Clock {{ -#define APB_CLK_FREQ_ROM ( 40*1000000 ) -#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM -#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ ( 80*1000000 ) #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) -#define XTAL_CLK_FREQ (40*1000000) -#define UART_CLK_FREQ APB_CLK_FREQ -#define WDT_CLK_FREQ APB_CLK_FREQ -#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16 -#define SPI_CLK_DIV 4 -#define TICKS_PER_US_ROM 40 // CPU is 80MHz //}} /* Overall memory map */ diff --git a/components/soc/esp32c5/include/soc/clk_tree_defs.h b/components/soc/esp32c5/include/soc/clk_tree_defs.h index fd45772ac7..ff69d5eec9 100644 --- a/components/soc/esp32c5/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c5/include/soc/clk_tree_defs.h @@ -127,6 +127,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32c5/include/soc/soc.h b/components/soc/esp32c5/include/soc/soc.h index b69113df54..3413beeeba 100644 --- a/components/soc/esp32c5/include/soc/soc.h +++ b/components/soc/esp32c5/include/soc/soc.h @@ -133,7 +133,6 @@ //}} //Periheral Clock {{ -#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ ( 40*1000000 ) #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) diff --git a/components/soc/esp32c6/include/soc/clk_tree_defs.h b/components/soc/esp32c6/include/soc/clk_tree_defs.h index c785df80d4..5ebb9ff942 100644 --- a/components/soc/esp32c6/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c6/include/soc/clk_tree_defs.h @@ -97,6 +97,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32c6/include/soc/soc.h b/components/soc/esp32c6/include/soc/soc.h index afd44da86c..af3ed6c919 100644 --- a/components/soc/esp32c6/include/soc/soc.h +++ b/components/soc/esp32c6/include/soc/soc.h @@ -136,13 +136,9 @@ //}} //Periheral Clock {{ -#define APB_CLK_FREQ_ROM ( 40*1000000 ) -#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM -#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ ( 40*1000000 ) #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) -#define XTAL_CLK_FREQ (40*1000000) //}} /* Overall memory map */ diff --git a/components/soc/esp32c61/include/soc/clk_tree_defs.h b/components/soc/esp32c61/include/soc/clk_tree_defs.h index b61dc05f43..c10a6e5067 100644 --- a/components/soc/esp32c61/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c61/include/soc/clk_tree_defs.h @@ -90,6 +90,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32c61/include/soc/soc.h b/components/soc/esp32c61/include/soc/soc.h index a961fc8ff5..838fd98a68 100644 --- a/components/soc/esp32c61/include/soc/soc.h +++ b/components/soc/esp32c61/include/soc/soc.h @@ -132,7 +132,6 @@ //}} //Periheral Clock {{ -#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ ( 40*1000000 ) #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) diff --git a/components/soc/esp32h2/include/soc/clk_tree_defs.h b/components/soc/esp32h2/include/soc/clk_tree_defs.h index 749573cf5a..779815aa4f 100644 --- a/components/soc/esp32h2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h2/include/soc/clk_tree_defs.h @@ -98,6 +98,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32h2/include/soc/soc.h b/components/soc/esp32h2/include/soc/soc.h index 35441cfe23..df2b8f2a01 100644 --- a/components/soc/esp32h2/include/soc/soc.h +++ b/components/soc/esp32h2/include/soc/soc.h @@ -134,13 +134,9 @@ //}} //Periheral Clock {{ -#define APB_CLK_FREQ_ROM ( 32*1000000 ) -#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM -#define CPU_CLK_FREQ_MHZ_BTLD (64) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ ( 32*1000000 ) #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 32*1000000 ) #define REF_CLK_FREQ ( 1000000 ) -#define XTAL_CLK_FREQ (32*1000000) //}} /* Overall memory map */ diff --git a/components/soc/esp32h21/include/soc/clk_tree_defs.h b/components/soc/esp32h21/include/soc/clk_tree_defs.h index 4876e38b26..77fed0c4bc 100644 --- a/components/soc/esp32h21/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h21/include/soc/clk_tree_defs.h @@ -92,6 +92,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** @@ -132,7 +134,7 @@ typedef enum { SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, OSC_SLOW, or RC32K by configuring soc_rtc_slow_clk_src_t */ // For digital domain: peripherals, BLE SOC_MOD_CLK_PLL_F48M, /*!< PLL_F48M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 48MHz */ - SOC_MOD_CLK_XTAL_X2_F64M, /*!< PLL_F64M_CLK is derived from XTAL_X2 (clock gating), it has a fixed frequency of 64MHz */ + SOC_MOD_CLK_XTAL_X2_F64M, /*!< XTAL_X2_F64M_CLK is derived from XTAL_X2 (clock gating), it has a fixed frequency of 64MHz */ SOC_MOD_CLK_PLL_F96M, /*!< PLL_F96M_CLK is derived from PLL (clock gating), it has a fixed frequency of 96MHz */ SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */ SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */ diff --git a/components/soc/esp32h21/include/soc/soc.h b/components/soc/esp32h21/include/soc/soc.h index 76e914f339..2eebc3ff98 100644 --- a/components/soc/esp32h21/include/soc/soc.h +++ b/components/soc/esp32h21/include/soc/soc.h @@ -135,7 +135,6 @@ //}} //Periheral Clock {{ -#define CPU_CLK_FREQ_MHZ_BTLD (64) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ ( 32*1000000 ) #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 32*1000000 ) #define REF_CLK_FREQ ( 1000000 ) diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index d4d29f94f7..a9b7daa8a7 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -59,6 +59,10 @@ config SOC_REG_I2C_SUPPORTED bool default y +config SOC_CLK_TREE_SUPPORTED + bool + default y + config SOC_WDT_SUPPORTED bool default y @@ -547,6 +551,10 @@ config SOC_PM_RETENTION_MODULE_NUM int default 32 +config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION + bool + default y + config SOC_MODEM_CLOCK_IS_INDEPENDENT bool default y @@ -559,7 +567,7 @@ config SOC_CLK_OSC_SLOW_SUPPORTED bool default y -config SOC_CLK_RC32K_SUPPORTED +config SOC_CLK_LP_FAST_SUPPORT_XTAL_D2 bool default y diff --git a/components/soc/esp32h4/include/soc/clk_tree_defs.h b/components/soc/esp32h4/include/soc/clk_tree_defs.h index f2cfc83d84..894a6acf4f 100644 --- a/components/soc/esp32h4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h4/include/soc/clk_tree_defs.h @@ -9,37 +9,31 @@ extern "C" { #endif -// TODO: [ESP32H4] IDF-12285 inherit from verify code, need check - /* ************************* ESP32H4 Root Clock Source **************************** - * 1) Internal 17.5MHz RC Oscillator: RC_FAST (may also referred as FOSC in TRM and reg. description) + * 1) Internal 20MHz RC Oscillator: RC_FAST (may also referred as FOSC in TRM and reg. description) * - * This RC oscillator generates a ~17.5MHz clock signal output as the RC_FAST_CLK. + * This RC oscillator generates a ~20MHz clock signal output as the RC_FAST_CLK. * * The exact frequency of RC_FAST_CLK can be computed in runtime through calibration. * * 2) External 32MHz Crystal Clock: XTAL * - * 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description) + * 3) Internal 600kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description) * - * This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock + * This RC oscillator generates a ~600kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock * can be computed in runtime through calibration. * - * 4) Internal 32kHz RC Oscillator: RC32K - * - * The exact frequency of this clock can be computed in runtime through calibration. - * - * 5) External 32kHz Crystal Clock (optional): XTAL32K + * 4) External 32kHz Crystal Clock (optional): XTAL32K * * The clock source for this XTAL32K_CLK should be a 32kHz crystal connecting to the XTAL_32K_P and XTAL_32K_N * pins. * * XTAL32K_CLK can also be calibrated to get its exact frequency. * - * 6) External Slow Clock (optional): OSC_SLOW + * 5) External Slow Clock (optional): OSC_SLOW * - * A slow clock signal generated by an external circuit can be connected to GPIO0 to be the clock source for the + * A slow clock signal generated by an external circuit can be connected to GPIO5 to be the clock source for the * RTC_SLOW_CLK. * * OSC_SLOW_CLK can also be calibrated to get its exact frequency. @@ -48,10 +42,9 @@ extern "C" { /* The pin number to connect the external slow clock (OSC_SLOW_CLK), XTAL_32K_P */ #define SOC_EXT_OSC_SLOW_GPIO_NUM 5 -/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */ -#define SOC_CLK_RC_FAST_FREQ_APPROX 17500000 /*!< Approximate RC_FAST_CLK frequency in Hz */ -#define SOC_CLK_RC_SLOW_FREQ_APPROX 136000 /*!< Approximate RC_SLOW_CLK frequency in Hz */ -#define SOC_CLK_RC32K_FREQ_APPROX 32768 /*!< Approximate RC32K_CLK frequency in Hz */ +/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 20 MHz +/- 7% */ +#define SOC_CLK_RC_FAST_FREQ_APPROX 20000000 /*!< Approximate RC_FAST_CLK frequency in Hz */ +#define SOC_CLK_RC_SLOW_FREQ_APPROX 600000 /*!< Approximate RC_SLOW_CLK frequency in Hz */ #define SOC_CLK_XTAL32K_FREQ_APPROX 32768 /*!< Approximate XTAL32K_CLK frequency in Hz */ #define SOC_CLK_OSC_SLOW_FREQ_APPROX 32768 /*!< Approximate OSC_SLOW_CLK (external slow clock) frequency in Hz */ @@ -63,12 +56,11 @@ extern "C" { * @brief Root clock */ typedef enum { - SOC_ROOT_CLK_INT_RC_FAST, /*!< Internal 17.5MHz RC oscillator */ - SOC_ROOT_CLK_INT_RC_SLOW, /*!< Internal 136kHz RC oscillator */ + SOC_ROOT_CLK_INT_RC_FAST, /*!< Internal 20MHz RC oscillator */ + SOC_ROOT_CLK_INT_RC_SLOW, /*!< Internal 600kHz RC oscillator */ SOC_ROOT_CLK_EXT_XTAL, /*!< External 32MHz crystal */ SOC_ROOT_CLK_EXT_XTAL32K, /*!< External 32kHz crystal */ - SOC_ROOT_CLK_INT_RC32K, /*!< Internal 32kHz RC oscillator */ - SOC_ROOT_CLK_EXT_OSC_SLOW, /*!< External slow clock signal at pin0 */ + SOC_ROOT_CLK_EXT_OSC_SLOW, /*!< External slow clock signal at pin5 */ } soc_root_clk_t; /** @@ -76,6 +68,7 @@ typedef enum { */ typedef enum { SOC_ROOT_CIRCUIT_CLK_BBPLL, /*!< BBPLL_CLK is the output of the PLL generator circuit */ + SOC_ROOT_CIRCUIT_CLK_XTAL_X2, /*!< XTAL_X2_CLK is the output of the XTAL_X2 generator circuit */ } soc_root_clk_circuit_t; /** @@ -84,8 +77,9 @@ typedef enum { */ typedef enum { SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */ - SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 32MHz crystal oscillator frequency multiplier, 96MHz) */ - SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */ + SOC_CPU_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as CPU_CLK source */ + SOC_CPU_CLK_SRC_XTAL_X2 = 2, /*!< Select XTAL_X2_CLK as CPU_CLK source (XTAL_X2_CLK is the other output of 32MHz crystal oscillator frequency multiplier, 64MHz) */ + SOC_CPU_CLK_SRC_PLL = 3, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 32MHz crystal oscillator frequency multiplier, 96MHz) */ SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */ } soc_cpu_clk_src_t; @@ -94,11 +88,12 @@ typedef enum { * @note Enum values are matched with the register field values on purpose */ typedef enum { - SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */ + SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4 = 0, /*!< Select RC_SLOW_D4_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ - SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4, /*!< RC_SLOW_D4_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** @@ -134,19 +129,18 @@ typedef enum { */ typedef enum { // For CPU domain - SOC_MOD_CLK_CPU = 1, /*!< CPU_CLK can be sourced from XTAL, PLL, or RC_FAST by configuring soc_cpu_clk_src_t */ + SOC_MOD_CLK_CPU = 1, /*!< CPU_CLK can be sourced from XTAL, PLL, RC_FAST, or XTAL_X2 by configuring soc_cpu_clk_src_t */ // For RTC domain SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */ - SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, RC32K, or OSC_SLOW by configuring soc_rtc_slow_clk_src_t */ + SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW_D4, XTAL32K, or OSC_SLOW by configuring soc_rtc_slow_clk_src_t */ // For digital domain: peripherals, BLE + SOC_MOD_CLK_XTAL_X2_F32M, /*!< XTAL_X2_F32M_CLK is derived from XTAL_X2 (clock gating + fixed divider of 2), it has a fixed frequency of 32MHz */ SOC_MOD_CLK_PLL_F48M, /*!< PLL_F48M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 48MHz */ - SOC_MOD_CLK_PLL_F64M, /*!< PLL_F64M_CLK is derived from FLASH_PLL (clock gating), it has a fixed frequency of 64MHz */ + SOC_MOD_CLK_XTAL_X2_F64M, /*!< XTAL_X2_F64M_CLK is derived from XTAL_X2 (clock gating), it has a fixed frequency of 64MHz */ SOC_MOD_CLK_PLL_F96M, /*!< PLL_F96M_CLK is derived from PLL (clock gating), it has a fixed frequency of 96MHz */ SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */ SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */ SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 32MHz crystal */ - // For LP peripherals - SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 32MHz crystal, passing a div of 2 to the LP peripherals */ SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */ } soc_module_clk_t; @@ -217,15 +211,6 @@ typedef enum { UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< UART source clock default choice is PLL_F48M */ } soc_periph_uart_clk_src_legacy_t; -/** - * @brief Type of LP_UART clock source - */ -typedef enum { - LP_UART_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock is LP(RTC)_FAST */ - LP_UART_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock is XTAL_D2 */ - LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock default choice is LP(RTC)_FAST */ -} soc_periph_lp_uart_clk_src_t; - /////////////////////////////////////////////////SPI//////////////////////////////////////////////////////////////////// /** @@ -271,10 +256,34 @@ typedef enum { typedef enum { FLASH_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ 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_REF_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_ROM_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as ROM default clock source */ } soc_periph_flash_clk_src_t; +////////////////////////////////////////////RTC CALIBRATION/////////////////////////////////////////////////////////// +/** + * @brief Clock frequency calibration source selection + */ +typedef enum { + CLK_CAL_RC_SLOW = 0, /*!< Select to calibrate RC_SLOW_CLK */ + CLK_CAL_32K_XTAL, /*!< Select to calibrate XTAL32K_CLK */ + CLK_CAL_32K_OSC_SLOW, /*!< Select to calibrate OSC_SLOW_CLK (external slow clock) */ + CLK_CAL_RC_FAST, /*!< Select to calibrate RC_FAST_CLK */ + CLK_CAL_CPU, /*!< Select to calibrate CPU_CLK */ + CLK_CAL_AHB, /*!< Select to calibrate AHB_CLK */ + CLK_CAL_APB, /*!< Select to calibrate APB_CLK */ + CLK_CAL_SEC, /*!< Select to calibrate SEC_CLK */ + CLK_CAL_MSPI, /*!< Select to calibrate MSPI_CLK */ + CLK_CAL_IOMUX, /*!< Select to calibrate IOMUX_CLK */ + CLK_CAL_PARLIO_RX, /*!< Select to calibrate PARLIO_RX_CLK */ + CLK_CAL_PARLIO_TX, /*!< Select to calibrate PARLIO_TX_CLK */ + CLK_CAL_GPSPI3_MST, /*!< Select to calibrate GPSPI3_MST_CLK */ + CLK_CAL_GPSPI2_MST, /*!< Select to calibrate GPSPI2_MST_CLK */ + CLK_CAL_EXT_IO, /*!< Select to calibrate an external clock from an IO */ +} soc_clk_calibration_clk_src_t; + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32h4/include/soc/gpio_sig_map.h b/components/soc/esp32h4/include/soc/gpio_sig_map.h index fb9c494778..f1602efa5d 100644 --- a/components/soc/esp32h4/include/soc/gpio_sig_map.h +++ b/components/soc/esp32h4/include/soc/gpio_sig_map.h @@ -6,7 +6,7 @@ #pragma once -#define TIMER_IN_IDX 0 // TODO: [ESP32H4] IDF-12499 need check +#define TIMER_IN_IDX 0 #define LEDC_LS_SIG_OUT0_IDX 0 #define LEDC_LS_SIG_OUT1_IDX 1 #define LEDC_LS_SIG_OUT2_IDX 2 diff --git a/components/soc/esp32h4/include/soc/regi2c_dcdc.h b/components/soc/esp32h4/include/soc/regi2c_dcdc.h index 361f9c867e..c2cb7db659 100644 --- a/components/soc/esp32h4/include/soc/regi2c_dcdc.h +++ b/components/soc/esp32h4/include/soc/regi2c_dcdc.h @@ -15,6 +15,10 @@ #define I2C_DCDC 0x6D #define I2C_DCDC_HOSTID 0 +#define I2C_DCDC_XPD_TRX 1 +#define I2C_DCDC_XPD_TRX_MSB 7 +#define I2C_DCDC_XPD_TRX_LSB 7 + #define I2C_DCDC_CCM_DREG0 7 #define I2C_DCDC_CCM_DREG0_MSB 4 #define I2C_DCDC_CCM_DREG0_LSB 0 diff --git a/components/soc/esp32h4/include/soc/soc.h b/components/soc/esp32h4/include/soc/soc.h index b8baa9a391..459430162a 100644 --- a/components/soc/esp32h4/include/soc/soc.h +++ b/components/soc/esp32h4/include/soc/soc.h @@ -124,11 +124,9 @@ //}} //Periheral Clock {{ -#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration -#define APB_CLK_FREQ ( 40*1000000 ) -#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) +#define APB_CLK_FREQ ( 32*1000000 ) +#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 32*1000000 ) #define REF_CLK_FREQ ( 1000000 ) -#define XTAL_CLK_FREQ (40*1000000) //}} /* Overall memory map */ diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index 3d2c3f6955..ffdfd236ff 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -76,7 +76,7 @@ // #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32H4] IDF-12449 // #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32H4] IDF-12445 IDF-12451 #define SOC_REG_I2C_SUPPORTED 1 -// #define SOC_CLK_TREE_SUPPORTED 1 // TODO: [ESP32H4] IDF-12285 +#define SOC_CLK_TREE_SUPPORTED 1 // #define SOC_ASSIST_DEBUG_SUPPORTED 1 // TODO: [ESP32H4] IDF-12310 #define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 // TODO: [ESP32H4] IDF-12388 @@ -536,12 +536,14 @@ #define SOC_PM_RETENTION_MODULE_NUM (32) /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ -// #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) // TODO: [ESP32H4] IDF-12285 +#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) + #define SOC_MODEM_CLOCK_IS_INDEPENDENT (1) #define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */ #define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */ -#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */ + +#define SOC_CLK_LP_FAST_SUPPORT_XTAL_D2 (1) /*!< Support XTAL_D2 clock as the LP_FAST clock source */ #define SOC_RCC_IS_INDEPENDENT 1 /*!< Reset and Clock Control is independent, thanks to the PCR registers */ diff --git a/components/soc/esp32h4/register/soc/pcr_reg.h b/components/soc/esp32h4/register/soc/pcr_reg.h index 7651143928..8e75c6c525 100644 --- a/components/soc/esp32h4/register/soc/pcr_reg.h +++ b/components/soc/esp32h4/register/soc/pcr_reg.h @@ -1992,21 +1992,6 @@ extern "C" { * SYSCLK configuration register */ #define PCR_SYSCLK_CONF_REG (DR_REG_PCR_BASE + 0x114) -/** PCR_LS_DIV_NUM : HRO; bitpos: [7:0]; default: 0; - * clk_hproot is div1 of low-speed clock-source if clck-source is a low-speed - * clock-source such as XTAL/FOSC. - */ -#define PCR_LS_DIV_NUM 0x000000FFU -#define PCR_LS_DIV_NUM_M (PCR_LS_DIV_NUM_V << PCR_LS_DIV_NUM_S) -#define PCR_LS_DIV_NUM_V 0x000000FFU -#define PCR_LS_DIV_NUM_S 0 -/** PCR_HS_DIV_NUM : HRO; bitpos: [15:8]; default: 2; - * clk_hproot is div3 of SPLL if the clock-source is high-speed clock SPLL. - */ -#define PCR_HS_DIV_NUM 0x000000FFU -#define PCR_HS_DIV_NUM_M (PCR_HS_DIV_NUM_V << PCR_HS_DIV_NUM_S) -#define PCR_HS_DIV_NUM_V 0x000000FFU -#define PCR_HS_DIV_NUM_S 8 /** PCR_SOC_CLK_SEL : R/W; bitpos: [17:16]; default: 0; * Configures to select the clock source of HP_ROOT_CLK. * 0 (default): XTAL_CLK @@ -2267,16 +2252,18 @@ extern "C" { #define PCR_TIMG_CALI_CLK_SEL_S 0 /** PCR_TIMG_SECURE_CLK_SEL : R/W; bitpos: [7:4]; default: 7; * Configures the clock source for the TIMG_SECURE_CLK. - * 0 (default):CPU_CLK - * 1: AHB_CLK - * 2: APB_CLK - * 3: sec function clock - * 4: mspi function clock - * 5: iomux function clock - * 6: parl io rx function clock - * 7: parl io tx function clock - * 8: spi2 function clock + * 0: EXT_IO_CLK + * 1: CPU_CLK + * 2: AHB_CLK + * 3: APB_CLK + * 4: sec function clock + * 5: mspi function clock + * 6: iomux function clock + * 7: parl io rx function clock + * 8: parl io tx function clock * 9: spi3 function clock + * 10: spi2 function clock + * 11: RC_FAST_CLK */ #define PCR_TIMG_SECURE_CLK_SEL 0x0000000FU #define PCR_TIMG_SECURE_CLK_SEL_M (PCR_TIMG_SECURE_CLK_SEL_V << PCR_TIMG_SECURE_CLK_SEL_S) diff --git a/components/soc/esp32h4/register/soc/pcr_struct.h b/components/soc/esp32h4/register/soc/pcr_struct.h index 62854ce6c7..7f01570130 100644 --- a/components/soc/esp32h4/register/soc/pcr_struct.h +++ b/components/soc/esp32h4/register/soc/pcr_struct.h @@ -1679,15 +1679,7 @@ typedef union { */ typedef union { struct { - /** ls_div_num : HRO; bitpos: [7:0]; default: 0; - * clk_hproot is div1 of low-speed clock-source if clck-source is a low-speed - * clock-source such as XTAL/FOSC. - */ - uint32_t ls_div_num:8; - /** hs_div_num : HRO; bitpos: [15:8]; default: 2; - * clk_hproot is div3 of SPLL if the clock-source is high-speed clock SPLL. - */ - uint32_t hs_div_num:8; + uint32_t reserved_0:16; /** soc_clk_sel : R/W; bitpos: [17:16]; default: 0; * Configures to select the clock source of HP_ROOT_CLK. * 0 (default): XTAL_CLK @@ -1891,16 +1883,18 @@ typedef union { uint32_t reserved_3:1; /** timg_secure_clk_sel : R/W; bitpos: [7:4]; default: 7; * Configures the clock source for the TIMG_SECURE_CLK. - * 0 (default):CPU_CLK - * 1: AHB_CLK - * 2: APB_CLK - * 3: sec function clock - * 4: mspi function clock - * 5: iomux function clock - * 6: parl io rx function clock - * 7: parl io tx function clock - * 8: spi2 function clock + * 0: EXT_IO_CLK + * 1: CPU_CLK + * 2: AHB_CLK + * 3: APB_CLK + * 4: sec function clock + * 5: mspi function clock + * 6: iomux function clock + * 7: parl io rx function clock + * 8: parl io tx function clock * 9: spi3 function clock + * 10: spi2 function clock + * 11: RC_FAST_CLK */ uint32_t timg_secure_clk_sel:4; /** timg_secure_clk_div_num : R/W; bitpos: [15:8]; default: 7; diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index d3cdf3b1d0..1e8a692376 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -106,6 +106,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32p4/include/soc/soc.h b/components/soc/esp32p4/include/soc/soc.h index e8e79a9d07..07d55f12d2 100644 --- a/components/soc/esp32p4/include/soc/soc.h +++ b/components/soc/esp32p4/include/soc/soc.h @@ -136,12 +136,8 @@ //}} //Periheral Clock {{ -#define APB_CLK_FREQ_ROM ( 10*1000000 ) -#define CPU_CLK_FREQ_ROM ( 40*1000000 ) -#define CPU_CLK_FREQ_MHZ_BTLD (90) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ ( 90*1000000 ) #define REF_CLK_FREQ ( 1000000 ) -#define XTAL_CLK_FREQ (40*1000000) //}} /* Overall memory map */ diff --git a/components/soc/esp32s2/include/soc/clk_tree_defs.h b/components/soc/esp32s2/include/soc/clk_tree_defs.h index 7d4e063dbd..b3ede80582 100644 --- a/components/soc/esp32s2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32s2/include/soc/clk_tree_defs.h @@ -84,6 +84,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32s2/include/soc/soc.h b/components/soc/esp32s2/include/soc/soc.h index 1c2a5becaf..08601b2574 100644 --- a/components/soc/esp32s2/include/soc/soc.h +++ b/components/soc/esp32s2/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -141,17 +141,9 @@ #endif /* !ULP_RISCV_REGISTER_OPS */ //Periheral Clock {{ -#define APB_CLK_FREQ_ROM ( 40*1000000 ) -#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM -#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) -#define UART_CLK_FREQ APB_CLK_FREQ -#define WDT_CLK_FREQ APB_CLK_FREQ -#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16 -#define SPI_CLK_DIV 4 -#define TICKS_PER_US_ROM 40 // CPU is 80MHz //}} /* Overall memory map */ diff --git a/components/soc/esp32s3/include/soc/clk_tree_defs.h b/components/soc/esp32s3/include/soc/clk_tree_defs.h index a2a5afae2c..fa36f5b8a1 100644 --- a/components/soc/esp32s3/include/soc/clk_tree_defs.h +++ b/components/soc/esp32s3/include/soc/clk_tree_defs.h @@ -82,6 +82,8 @@ typedef enum { SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */ + + SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */ } soc_rtc_slow_clk_src_t; /** diff --git a/components/soc/esp32s3/include/soc/soc.h b/components/soc/esp32s3/include/soc/soc.h index 1955df7db0..b9468b90fb 100644 --- a/components/soc/esp32s3/include/soc/soc.h +++ b/components/soc/esp32s3/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -149,18 +149,9 @@ #endif /* !ULP_RISCV_REGISTER_OPS */ //Periheral Clock {{ -#define APB_CLK_FREQ_ROM (40*1000000) -#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM -#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define APB_CLK_FREQ (80*1000000) #define MODEM_REQUIRED_MIN_APB_CLK_FREQ (80*1000000) #define REF_CLK_FREQ (1000000) -#define XTAL_CLK_FREQ (40*1000000) -#define UART_CLK_FREQ APB_CLK_FREQ -#define WDT_CLK_FREQ APB_CLK_FREQ -#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16 -#define SPI_CLK_DIV 4 -#define TICKS_PER_US_ROM 40 // CPU is 80MHz //}} /* Overall memory map */ diff --git a/docs/docs_not_updated/esp32h4.txt b/docs/docs_not_updated/esp32h4.txt index 261c699deb..acd9f38c22 100644 --- a/docs/docs_not_updated/esp32h4.txt +++ b/docs/docs_not_updated/esp32h4.txt @@ -146,7 +146,6 @@ api-reference/peripherals/i2c.rst api-reference/peripherals/jpeg.rst api-reference/peripherals/mcpwm.rst api-reference/peripherals/usb_host.rst -api-reference/peripherals/clk_tree.rst api-reference/peripherals/camera_driver.rst api-reference/peripherals/spi_master.rst api-reference/peripherals/adc_oneshot.rst diff --git a/docs/en/api-reference/peripherals/clk_tree.rst b/docs/en/api-reference/peripherals/clk_tree.rst index efb05a47d8..8201eede15 100644 --- a/docs/en/api-reference/peripherals/clk_tree.rst +++ b/docs/en/api-reference/peripherals/clk_tree.rst @@ -3,15 +3,15 @@ Clock Tree :link_to_translation:`zh_CN:[中文]` -{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8", esp32h21="20"} +{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8", esp32h21="20", esp32h4="20"} -{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5", esp32h21="20"} +{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5", esp32h21="20", esp32h4="20"} -{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48", esp32h21="32"} +{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48", esp32h21="32", esp32h4="32"} -{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90", esp32h21="600"} +{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90", esp32h21="600", esp32h4="600"} -{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0 (when its frequency is no more than 136 kHz)", "esp32c6="GPIO0", esp32h2="GPIO13", esp32h21="GPIO11"} +{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0 (when its frequency is no more than 136 kHz)", "esp32c6="GPIO0", esp32h2="GPIO13", esp32h21="GPIO11", esp32h4="GPIO5"} The clock subsystem of {IDF_TARGET_NAME} is used to source and distribute system/module clocks from a range of root clocks. The clock tree driver maintains the basic functionality of the system clock and the intricate relationship among module clocks. diff --git a/docs/zh_CN/api-reference/peripherals/clk_tree.rst b/docs/zh_CN/api-reference/peripherals/clk_tree.rst index 4f019a67b8..3e41295906 100644 --- a/docs/zh_CN/api-reference/peripherals/clk_tree.rst +++ b/docs/zh_CN/api-reference/peripherals/clk_tree.rst @@ -3,15 +3,15 @@ :link_to_translation:`en:[English]` -{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8", esp32h21="20"} +{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8", esp32h21="20", esp32h4="20"} -{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5", esp32h21="20"} +{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5", esp32h21="20", esp32h4="20"} -{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48", esp32h21="32"} +{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48", esp32h21="32", esp32h4="32"} -{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90", esp32h21="600"} +{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90", esp32h21="600", esp32h4="600"} -{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0(时钟信号频率不超过 136 kHz 时)", "esp32c6="GPIO0", esp32h2="GPIO13", esp32h21="GPIO11"} +{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0(时钟信号频率不超过 136 kHz 时)", "esp32c6="GPIO0", esp32h2="GPIO13", esp32h21="GPIO11", esp32h4="GPIO5"} {IDF_TARGET_NAME} 的时钟子系统用于从一系列根时钟中提取并分配系统/模块时钟。时钟树驱动程序负责维护系统时钟的基本功能,并管理模块时钟间的复杂关系。