From 40f3bc2e57616da672a0031cda17cd5bb36d88ef Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 14 Jun 2024 16:46:48 +0800 Subject: [PATCH] feat(clk): Add basic clock support for esp32c5 mp - Support SOC ROOT clock source switch - Support CPU frequency change - Support RTC SLOW clock source switch - Support RTC SLOW clock + RC FAST calibration - Remove FPGA build --- Kconfig | 1 - .../src/bootloader_flash_config_esp32c5.c | 6 - .../src/bootloader_clock_init.c | 6 - .../src/esp32c5/bootloader_esp32c5.c | 4 - components/esp_hw_support/CMakeLists.txt | 1 - components/esp_hw_support/Kconfig | 5 +- components/esp_hw_support/esp_clk.c | 2 +- components/esp_hw_support/linker.lf | 2 +- .../port/esp32c5/CMakeLists.txt | 3 +- .../port/esp32c5/esp_clk_tree.c | 19 +- .../port/esp32c5/include/soc/rtc.h | 24 +- .../esp_hw_support/port/esp32c5/pmu_init.c | 36 +- .../esp_hw_support/port/esp32c5/pmu_param.c | 56 ++- .../esp_hw_support/port/esp32c5/pmu_sleep.c | 4 +- .../port/esp32c5/private_include/ocode_init.h | 21 -- .../port/esp32c5/private_include/pmu_param.h | 12 +- .../esp_hw_support/port/esp32c5/rtc_clk.c | 143 ++++--- .../port/esp32c5/rtc_clk_init.c | 10 +- .../esp_hw_support/port/esp32c5/rtc_time.c | 147 +++----- .../port/esp32c6/rtc_clk_init.c | 2 - .../esp_hw_support/port/esp32c6/rtc_time.c | 10 +- .../port/esp32h2/rtc_clk_init.c | 2 - .../esp_hw_support/port/esp32h2/rtc_time.c | 10 +- .../esp_hw_support/port/esp_clk_tree_common.c | 7 + .../patches/esp_rom_hp_regi2c_esp32c5.c | 3 - components/esp_system/port/soc/esp32c5/clk.c | 14 +- components/esptool_py/Kconfig.projbuild | 5 +- components/hal/CMakeLists.txt | 2 +- components/hal/esp32c5/clk_tree_hal.c | 12 +- .../hal/esp32c5/include/hal/clk_tree_ll.h | 348 ++++-------------- .../hal/esp32c6/include/hal/clk_tree_ll.h | 5 +- .../hal/esp32c61/include/hal/clk_tree_ll.h | 2 +- .../hal/esp32h2/include/hal/clk_tree_ll.h | 5 +- .../esp32c5/include/soc/Kconfig.soc_caps.in | 24 ++ .../soc/esp32c5/include/soc/clk_tree_defs.h | 22 +- components/soc/esp32c5/include/soc/pcr_reg.h | 15 - .../soc/esp32c5/include/soc/pcr_struct.h | 34 +- components/soc/esp32c5/include/soc/soc_caps.h | 11 +- docs/docs_not_updated/esp32c5.txt | 1 - .../en/api-reference/peripherals/clk_tree.rst | 2 +- docs/en/api-reference/peripherals/ledc.rst | 2 +- .../api-reference/peripherals/clk_tree.rst | 2 +- docs/zh_CN/api-reference/peripherals/ledc.rst | 2 +- 43 files changed, 449 insertions(+), 595 deletions(-) delete mode 100644 components/esp_hw_support/port/esp32c5/private_include/ocode_init.h diff --git a/Kconfig b/Kconfig index d7240e6329..b5c529cbeb 100644 --- a/Kconfig +++ b/Kconfig @@ -122,7 +122,6 @@ mainmenu "Espressif IoT Development Framework Configuration" default "y" if IDF_TARGET="esp32c5" select FREERTOS_UNICORE select IDF_TARGET_ARCH_RISCV - select IDF_ENV_FPGA config IDF_TARGET_ESP32P4 bool diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c5.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c5.c index d1cf55eddf..3f04c45b7c 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c5.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c5.c @@ -28,7 +28,6 @@ #include "hal/mmu_ll.h" #include "hal/cache_hal.h" #include "hal/cache_ll.h" -#include "hal/clk_tree_ll.h" void bootloader_flash_update_id() { @@ -204,11 +203,6 @@ static void bootloader_spi_flash_resume(void) esp_err_t bootloader_init_spi_flash(void) { - // On ESP32C5, MSPI source clock's default HS divider leads to 120MHz, which is unusable before calibration - // Therefore, before switching SOC_ROOT_CLK to HS, we need to set MSPI source clock HS divider to make it run at - // 80MHz after the switch. PLL = 480MHz, so divider is 6. - clk_ll_mspi_fast_set_hs_divider(6); - bootloader_init_flash_configure(); bootloader_spi_flash_resume(); bootloader_flash_unlock(); diff --git a/components/bootloader_support/src/bootloader_clock_init.c b/components/bootloader_support/src/bootloader_clock_init.c index a3654ec3dd..8099aa4955 100644 --- a/components/bootloader_support/src/bootloader_clock_init.c +++ b/components/bootloader_support/src/bootloader_clock_init.c @@ -53,18 +53,12 @@ __attribute__((weak)) void bootloader_clock_configure(void) clk_cfg.cpu_freq_mhz = cpu_freq_mhz; -#if CONFIG_IDF_TARGET_ESP32C5 - // TODO: [ESP32C5] IDF-9009 Check whether SOC_RTC_SLOW_CLK_SRC_RC_SLOW can be used on C5 MP - // RC150K can't do calibrate on ESP32C5MPW so not use it - clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC32K; -#else // Use RTC_SLOW clock source sel register field's default value, RC_SLOW, for 2nd stage bootloader // 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; } -#endif // Use RTC_FAST clock source sel register field's default value, XTAL_DIV, for 2nd stage bootloader // RTC_FAST clock source will be switched to RC_FAST at application startup diff --git a/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c b/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c index 3a11e2c29e..7009b9afae 100644 --- a/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c +++ b/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c @@ -89,11 +89,7 @@ static inline void bootloader_hardware_init(void) /* Enable analog i2c master clock */ SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_FORCE_ON_REG, MODEM_LPCON_CLK_I2C_MST_FO); // TODO: IDF-8667 Remove this? -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M); -#else // CONFIG_IDF_TARGET_ESP32C5_MP_VERSION SET_PERI_REG_MASK(MODEM_SYSCON_CLK_CONF_REG, MODEM_SYSCON_CLK_I2C_MST_SEL_160M); -#endif } static inline void bootloader_ana_reset_config(void) diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 45eb393269..0807483723 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -159,7 +159,6 @@ if(NOT BOOTLOADER_BUILD) "sleep_modem.c" # TODO: [ESP32C5] IDF-8638 "sleep_wake_stub.c" # TODO: [ESP32C5] IDF-8638 "sleep_gpio.c" # TODO: [ESP32C5] IDF-8638 - "port/esp_clk_tree_common.c" # TODO: [ESP32C5] IDF-8638 ) endif() diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 8561d769b0..6f61db5402 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -288,10 +288,7 @@ menu "Hardware Settings" # Invisible bringup bypass options for esp_hw_support component config ESP_BRINGUP_BYPASS_CPU_CLK_SETTING bool - # TODO: [ESP32C5] IDF-8642 IDF_TARGET_ESP32C5 is added because clock - # is required when bringup on C5 beta3, remove it when clock tree is - # supported - default y if !SOC_CLK_TREE_SUPPORTED && !IDF_TARGET_ESP32C5 + default y if !SOC_CLK_TREE_SUPPORTED default n help This option is only used for new chip bringup, when diff --git a/components/esp_hw_support/esp_clk.c b/components/esp_hw_support/esp_clk.c index d777543eac..c4a2c0c207 100644 --- a/components/esp_hw_support/esp_clk.c +++ b/components/esp_hw_support/esp_clk.c @@ -96,7 +96,7 @@ int IRAM_ATTR esp_clk_cpu_freq(void) int IRAM_ATTR esp_clk_apb_freq(void) { // TODO: IDF-5173 Require cleanup, implementation should be unified -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C61 +#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 return rtc_clk_apb_freq_get(); #else return MIN(s_get_cpu_freq_mhz() * MHZ, APB_CLK_FREQ); diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 0ad8003c56..b4b1518e6f 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -19,7 +19,7 @@ entries: if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y || IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C2 = y || IDF_TARGET_ESP32C3 = y: rtc_sleep (noflash_text) rtc_time (noflash_text) - if SOC_PMU_SUPPORTED = y: + if SOC_PMU_SUPPORTED = y && SOC_LIGHT_SLEEP_SUPPORTED = y: pmu_sleep (noflash) if SOC_USB_SERIAL_JTAG_SUPPORTED = y: sleep_console (noflash) diff --git a/components/esp_hw_support/port/esp32c5/CMakeLists.txt b/components/esp_hw_support/port/esp32c5/CMakeLists.txt index b7e789dd26..6a32d8aec1 100644 --- a/components/esp_hw_support/port/esp32c5/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c5/CMakeLists.txt @@ -1,10 +1,11 @@ set(srcs "rtc_clk_init.c" "rtc_time.c" "rtc_clk.c" + "pmu_init.c" + "pmu_param.c" "chip_info.c" ) - if(NOT BOOTLOADER_BUILD) list(APPEND srcs "sar_periph_ctrl.c" "esp_crypto_lock.c") diff --git a/components/esp_hw_support/port/esp32c5/esp_clk_tree.c b/components/esp_hw_support/port/esp32c5/esp_clk_tree.c index 77a61ea8f2..62dfe1eddd 100644 --- a/components/esp_hw_support/port/esp32c5/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32c5/esp_clk_tree.c @@ -11,21 +11,22 @@ #include "soc/rtc.h" #include "hal/clk_tree_hal.h" #include "hal/clk_tree_ll.h" -// #include "esp_private/esp_clk_tree_common.h" -#include "sdkconfig.h" +#include "esp_private/esp_clk_tree_common.h" 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, uint32_t *freq_value) { - // TODO: [ESP32C5] IDF-8642 check again for MP version ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src"); ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision"); ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer"); 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 = clk_hal_xtal_get_freq_mhz() * MHZ; break; @@ -41,9 +42,17 @@ uint32_t *freq_value) case SOC_MOD_CLK_SPLL: clk_src_freq = CLK_LL_PLL_480M_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: - // C5-beta3 unable to calibrate to get exact RC_FAST frequency - clk_src_freq = SOC_CLK_RC_FAST_FREQ_APPROX; + 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; case SOC_MOD_CLK_XTAL_D2: clk_src_freq = (clk_hal_xtal_get_freq_mhz() * MHZ) >> 1; 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 8aeb061173..b449d37414 100644 --- a/components/esp_hw_support/port/esp32c5/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c5/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 @@ -121,21 +117,19 @@ typedef struct rtc_cpu_freq_config_s { #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 ESP32C5. The conversion to register field values is explicitly done in - * rtc_clk_cal_internal + * @note On ESP32C5, the enum values somehow reflects the register field values of PCR_32K_SEL. */ 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_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK + RTC_CAL_RC32K = 0, //!< Internal 32kHz RC oscillator, as one type of 32k clock + RTC_CAL_32K_XTAL = 1, //!< External 32kHz XTAL, as one type of 32k clock + RTC_CAL_32K_OSC_SLOW = 2, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock + RTC_CAL_RC_SLOW = 3, //!< Internal 150kHz RC oscillator + RTC_CAL_RC_FAST = 4, //!< Internal 20MHz RC oscillator + RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate } rtc_cal_sel_t; /** @@ -160,7 +154,7 @@ typedef struct { .xtal_freq = CONFIG_XTAL_FREQ, \ .cpu_freq_mhz = 80, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ - .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC32K, \ + .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \ .clk_rtc_clk_div = 0, \ .clk_8m_clk_div = 0, \ .slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \ diff --git a/components/esp_hw_support/port/esp32c5/pmu_init.c b/components/esp_hw_support/port/esp32c5/pmu_init.c index 345efa32ca..e280fc36dc 100644 --- a/components/esp_hw_support/port/esp32c5/pmu_init.c +++ b/components/esp_hw_support/port/esp32c5/pmu_init.c @@ -23,13 +23,13 @@ typedef struct { const pmu_hp_system_power_param_t *power; const pmu_hp_system_clock_param_t *clock; const pmu_hp_system_digital_param_t *digital; - const pmu_hp_system_analog_param_t *analog; + pmu_hp_system_analog_param_t *analog; //param determined at runtime const pmu_hp_system_retention_param_t *retent; } pmu_hp_system_param_t; typedef struct { const pmu_lp_system_power_param_t *power; - const pmu_lp_system_analog_param_t *analog; + pmu_lp_system_analog_param_t *analog; //param determined at runtime } pmu_lp_system_param_t; pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) @@ -42,7 +42,7 @@ pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) return &pmu_context; } -void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_param_t *param) +void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_system_param_t *param) { const pmu_hp_system_power_param_t *power = param->power; const pmu_hp_system_clock_param_t *clock = param->clock; @@ -101,7 +101,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP); } -void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, pmu_lp_system_param_t *param) +void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param) { const pmu_lp_system_power_param_t *power = param->power; const pmu_lp_system_analog_param_t *anlg = param->analog; @@ -157,18 +157,26 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx) static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param) { + assert (param->analog); + param->power = pmu_hp_system_power_param_default(mode); param->clock = pmu_hp_system_clock_param_default(mode); param->digital = pmu_hp_system_digital_param_default(mode); - param->analog = pmu_hp_system_analog_param_default(mode); + *param->analog = *pmu_hp_system_analog_param_default(mode); //copy default value param->retent = pmu_hp_system_retention_param_default(mode); + + if (mode == PMU_MODE_HP_ACTIVE || mode == PMU_MODE_HP_MODEM) { + param->analog->regulator0.dbias = get_act_hp_dbias(); + } } static void pmu_hp_system_init_default(pmu_context_t *ctx) { assert(ctx); - pmu_hp_system_param_t param = { 0 }; for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) { + pmu_hp_system_analog_param_t analog = {}; + pmu_hp_system_param_t param = {.analog = &analog}; + pmu_hp_system_param_default(mode, ¶m); pmu_hp_system_init(ctx, mode, ¶m); } @@ -176,15 +184,23 @@ static void pmu_hp_system_init_default(pmu_context_t *ctx) static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param) { + assert (param->analog); + param->power = pmu_lp_system_power_param_default(mode); - param->analog = pmu_lp_system_analog_param_default(mode); + *param->analog = *pmu_lp_system_analog_param_default(mode); //copy default value + + if (mode == PMU_MODE_LP_ACTIVE) { + param->analog->regulator0.dbias = get_act_lp_dbias(); + } } static void pmu_lp_system_init_default(pmu_context_t *ctx) { assert(ctx); - pmu_lp_system_param_t param; for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) { + pmu_lp_system_analog_param_t analog = {}; + pmu_lp_system_param_t param = {.analog = &analog}; + pmu_lp_system_param_default(mode, ¶m); pmu_lp_system_init(ctx, mode, ¶m); } @@ -195,10 +211,6 @@ void pmu_init(void) /* Peripheral reg i2c power up */ SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); - 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); pmu_hp_system_init_default(PMU_instance()); pmu_lp_system_init_default(PMU_instance()); diff --git a/components/esp_hw_support/port/esp32c5/pmu_param.c b/components/esp_hw_support/port/esp32c5/pmu_param.c index 262bfe9fcf..cdcc639ad5 100644 --- a/components/esp_hw_support/port/esp32c5/pmu_param.c +++ b/components/esp_hw_support/port/esp32c5/pmu_param.c @@ -211,7 +211,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .xpd = 1, \ .slp_mem_dbias = 0, \ .slp_logic_dbias = 0, \ - .dbias = HP_CALI_DBIAS \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -231,7 +231,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .xpd = 1, \ .slp_mem_dbias = 0, \ .slp_logic_dbias = 0, \ - .dbias = HP_CALI_DBIAS \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -413,7 +413,7 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod .slp_xpd = 0, \ .xpd = 1, \ .slp_dbias = 0, \ - .dbias = LP_CALI_DBIAS \ + .dbias = LP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -447,3 +447,53 @@ const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_m assert(mode < ARRAY_SIZE(lp_analog)); return &lp_analog[mode]; } + +uint32_t get_act_hp_dbias(void) +{ + /* hp_cali_dbias is read from efuse to ensure that the hp_active_voltage is close to 1.15V + */ + uint32_t hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + // uint32_t blk_version = efuse_hal_blk_version(); + // if (blk_version >= 3) { + // hp_cali_dbias = efuse_ll_get_active_hp_dbias(); + // if (hp_cali_dbias != 0) { + // //efuse dbias need to add 2 to meet the CPU frequency switching + // if (hp_cali_dbias + 2 > 31) { + // hp_cali_dbias = 31; + // } else { + // hp_cali_dbias += 2; + // } + // } else { + // hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + // ESP_HW_LOGD(TAG, "hp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %" PRIu32 "\n", blk_version); + // } + // } + + return hp_cali_dbias; +} + +uint32_t get_act_lp_dbias(void) +{ + /* lp_cali_dbias is read from efuse to ensure that the lp_active_voltage is close to 1.15V + */ + uint32_t lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + // uint32_t blk_version = efuse_hal_blk_version(); + // if (blk_version >= 3) { + // lp_cali_dbias = efuse_ll_get_active_lp_dbias(); + // if (lp_cali_dbias != 0) { + // //efuse dbias need to add 2 to meet the CPU frequency switching + // if (lp_cali_dbias + 2 > 31) { + // lp_cali_dbias = 31; + // } else { + // lp_cali_dbias += 2; + // } + // } else { + // lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + // ESP_HW_LOGD(TAG, "lp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %" PRIu32 "\n", blk_version); + // } + // } else { + // ESP_HW_LOGD(TAG, "blk_version is less than 3, act dbias not burnt in efuse\n"); + // } + + return lp_cali_dbias; +} diff --git a/components/esp_hw_support/port/esp32c5/pmu_sleep.c b/components/esp_hw_support/port/esp32c5/pmu_sleep.c index 262ce0086e..f7f8185c13 100644 --- a/components/esp_hw_support/port/esp32c5/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32c5/pmu_sleep.c @@ -168,11 +168,11 @@ const pmu_sleep_config_t* pmu_sleep_config_default( if (!(pd_flags & PMU_SLEEP_PD_XTAL)){ analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON; analog_default.hp_sys.analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; - analog_default.hp_sys.analog.dbias = HP_CALI_DBIAS; + analog_default.hp_sys.analog.dbias = HP_CALI_DBIAS_DEFAULT; analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON; analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; - analog_default.lp_sys[LP(SLEEP)].analog.dbias = LP_CALI_DBIAS; + analog_default.lp_sys[LP(SLEEP)].analog.dbias = LP_CALI_DBIAS_DEFAULT; } config->analog = analog_default; diff --git a/components/esp_hw_support/port/esp32c5/private_include/ocode_init.h b/components/esp_hw_support/port/esp32c5/private_include/ocode_init.h deleted file mode 100644 index 524f286194..0000000000 --- a/components/esp_hw_support/port/esp32c5/private_include/ocode_init.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialize OCode - * - */ -void esp_ocode_calib_init(void); - -#ifdef __cplusplus -} -#endif diff --git a/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h b/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h index 909a583215..7153ef4846 100644 --- a/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32c5/private_include/pmu_param.h @@ -19,9 +19,8 @@ extern "C" { #endif - -#define HP_CALI_DBIAS 25 -#define LP_CALI_DBIAS 26 +#define HP_CALI_DBIAS_DEFAULT 28 +#define LP_CALI_DBIAS_DEFAULT 28 // FOR XTAL FORCE PU IN SLEEP #define PMU_PD_CUR_SLEEP_ON 0 @@ -51,6 +50,9 @@ extern "C" { #define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12 #define PMU_LP_DBIAS_DEEPSLEEP_0V7 23 +uint32_t get_act_hp_dbias(void); +uint32_t get_act_lp_dbias(void); + typedef struct { pmu_hp_dig_power_reg_t dig_power; pmu_hp_clk_power_reg_t clk_power; @@ -412,7 +414,7 @@ typedef struct { typedef struct pmu_sleep_machine_constant { struct { - uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */ uint8_t wakeup_wait_cycle; /* Modem wakeup signal (WiFi MAC and BEACON wakeup) waits for the slow & fast clock domain synchronization and the wakeup signal triggers the PMU FSM switching wait cycle (unit: slow clock cycle) */ uint8_t reserved0; uint16_t reserved1; @@ -424,7 +426,7 @@ typedef struct pmu_sleep_machine_constant { uint16_t power_up_wait_time_us; /* (unit: microsecond) */ } lp; struct { - uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */ uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */ uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */ uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */ diff --git a/components/esp_hw_support/port/esp32c5/rtc_clk.c b/components/esp_hw_support/port/esp32c5/rtc_clk.c index e244ebe18d..c550c44d0c 100644 --- a/components/esp_hw_support/port/esp32c5/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c5/rtc_clk.c @@ -172,6 +172,7 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq) 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(); rtc_clk_enable_i2c_ana_master_clock(false); @@ -185,29 +186,60 @@ 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_cpu_set_divider(div); + clk_ll_ahb_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_8m(void) { - clk_ll_ahb_set_ls_divider(1); - clk_ll_cpu_set_ls_divider(1); + clk_ll_cpu_set_divider(1); + clk_ll_ahb_set_divider(1); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST); + clk_ll_bus_update(); esp_rom_set_cpu_ticks_per_us(20); } /** - * Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL. + * Switch to PLL_F240M as cpu clock source. * PLL must already be enabled. * @param cpu_freq new CPU frequency */ -static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) +static void rtc_clk_cpu_freq_to_pll_240_mhz(int cpu_freq_mhz) { - clk_ll_cpu_set_hs_divider(CLK_LL_PLL_480M_FREQ_MHZ / cpu_freq_mhz); - clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); + // f_hp_root = 240MHz + uint32_t cpu_divider = CLK_LL_PLL_240M_FREQ_MHZ / cpu_freq_mhz; + clk_ll_cpu_set_divider(cpu_divider); + // Constraint: f_ahb <= 48MHz; f_cpu = N * f_ahb (N = 1, 2, 3...) + // let f_ahb = 40MHz + const uint32_t ahb_divider = 6; + assert((cpu_divider <= ahb_divider) && (ahb_divider % cpu_divider == 0)); + clk_ll_ahb_set_divider(ahb_divider); + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL_F240M); + clk_ll_bus_update(); + esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); +} + +/** + * Switch to PLL_F160M as cpu clock source. + * PLL must already be enabled. + * @param cpu_freq new CPU frequency + */ +static void rtc_clk_cpu_freq_to_pll_160_mhz(int cpu_freq_mhz) +{ + // f_hp_root = 160MHz + uint32_t cpu_divider = CLK_LL_PLL_160M_FREQ_MHZ / cpu_freq_mhz; + clk_ll_cpu_set_divider(cpu_divider); + // Constraint: f_ahb <= 48MHz; f_cpu = N * f_ahb (N = 1, 2, 3...) + // let f_ahb = 40MHz + const uint32_t ahb_divider = 4; + assert((cpu_divider <= ahb_divider) && (ahb_divider % cpu_divider == 0)); + clk_ll_ahb_set_divider(ahb_divider); + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL_F160M); + clk_ll_bus_update(); esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); } @@ -219,7 +251,14 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou uint32_t real_freq_mhz; uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get(); - if (freq_mhz <= xtal_freq && freq_mhz != 0) { + // To maintain APB_MAX (40MHz) while lowering CPU frequency when using a 48MHz XTAL, have to let CPU frequnecy be + // 40MHz with PLL_F160M or PLL_F240M clock source. This is a special case, has to handle separately. + if (xtal_freq == SOC_XTAL_FREQ_48M && freq_mhz == 40) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_PLL_F160M; + source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + divider = 4; + } else if (freq_mhz <= xtal_freq && freq_mhz != 0) { divider = xtal_freq / freq_mhz; real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */ if (real_freq_mhz != freq_mhz) { @@ -229,21 +268,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 == 80) { + } else if (freq_mhz == 240) { real_freq_mhz = freq_mhz; - source = SOC_CPU_CLK_SRC_PLL; - source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; - divider = 6; - } else if (freq_mhz == 120) { - real_freq_mhz = freq_mhz; - source = SOC_CPU_CLK_SRC_PLL; - source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; - divider = 4; + source = SOC_CPU_CLK_SRC_PLL_F240M; + source_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ; + divider = 1; } else if (freq_mhz == 160) { real_freq_mhz = freq_mhz; - source = SOC_CPU_CLK_SRC_PLL; - source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; - divider = 3; + source = SOC_CPU_CLK_SRC_PLL_F160M; + source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + divider = 1; + } else if (freq_mhz == 80) { + real_freq_mhz = freq_mhz; + source = SOC_CPU_CLK_SRC_PLL_F160M; + source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + divider = 2; } else { // unsupported frequency return false; @@ -266,21 +305,29 @@ 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 (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) { + if (((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) || (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M)) && !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) { + } else if (config->source == SOC_CPU_CLK_SRC_PLL_F240M) { + if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F240M && old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F160M) { rtc_clk_set_cpu_switch_to_pll(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_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_480M_FREQ_MHZ); } - rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); + rtc_clk_cpu_freq_to_pll_240_mhz(config->freq_mhz); + rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP); + } else if (config->source == SOC_CPU_CLK_SRC_PLL_F160M) { + if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F240M && old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F160M) { + rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START); + rtc_clk_bbpll_enable(); + rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_480M_FREQ_MHZ); + } + rtc_clk_cpu_freq_to_pll_160_mhz(config->freq_mhz); rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP); } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { rtc_clk_cpu_freq_to_8m(); - if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { + if (((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) || (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M)) && !s_bbpll_digi_consumers_ref_count) { // We don't turn off the bbpll if some consumers depend on bbpll rtc_clk_bbpll_disable(); } @@ -292,17 +339,21 @@ 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 freq_mhz; - uint32_t div = clk_ll_cpu_get_ls_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK - uint32_t hs_div = clk_ll_cpu_get_hs_divider(); + uint32_t div = clk_ll_cpu_get_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK 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 / hs_div; + case SOC_CPU_CLK_SRC_PLL_F160M: { + source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + freq_mhz = source_freq_mhz / div; + break; + } + case SOC_CPU_CLK_SRC_PLL_F240M: { + source_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ; + freq_mhz = source_freq_mhz / div; break; } case SOC_CPU_CLK_SRC_RC_FAST: @@ -325,11 +376,12 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config) { if (config->source == SOC_CPU_CLK_SRC_XTAL) { rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); - } else if ( - config->source == SOC_CPU_CLK_SRC_PLL && - s_cur_pll_freq == config->source_freq_mhz - ) { - rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); + } else if (config->source == SOC_CPU_CLK_SRC_PLL_F160M && + s_cur_pll_freq == CLK_LL_PLL_480M_FREQ_MHZ) { + rtc_clk_cpu_freq_to_pll_160_mhz(config->freq_mhz); + } else if (config->source == SOC_CPU_CLK_SRC_PLL_F240M && + s_cur_pll_freq == CLK_LL_PLL_480M_FREQ_MHZ) { + rtc_clk_cpu_freq_to_pll_240_mhz(config->freq_mhz); } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { rtc_clk_cpu_freq_to_8m(); } else { @@ -356,7 +408,8 @@ void rtc_clk_cpu_set_to_default_config(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); + // TODO: IDF-8641 CPU_MAX_FREQ don't know what to do... pll_240 or pll_160... + rtc_clk_cpu_freq_to_pll_240_mhz(cpu_freq_mhz); clk_ll_cpu_clk_src_lock_release(); } @@ -375,15 +428,19 @@ static uint32_t rtc_clk_ahb_freq_get(void) switch (source) { case SOC_CPU_CLK_SRC_XTAL: soc_root_freq_mhz = rtc_clk_xtal_freq_get(); - divider = clk_ll_ahb_get_ls_divider(); + divider = clk_ll_ahb_get_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(); + case SOC_CPU_CLK_SRC_PLL_F160M: + soc_root_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ; + divider = clk_ll_ahb_get_divider(); + break; + case SOC_CPU_CLK_SRC_PLL_F240M: + soc_root_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ; + divider = clk_ll_ahb_get_divider(); break; case SOC_CPU_CLK_SRC_RC_FAST: soc_root_freq_mhz = 20; - divider = clk_ll_ahb_get_ls_divider(); + divider = clk_ll_ahb_get_divider(); break; default: // Unknown SOC_ROOT clock source diff --git a/components/esp_hw_support/port/esp32c5/rtc_clk_init.c b/components/esp_hw_support/port/esp32c5/rtc_clk_init.c index f8c61cda81..81e452e71a 100644 --- a/components/esp_hw_support/port/esp32c5/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32c5/rtc_clk_init.c @@ -79,10 +79,14 @@ void rtc_clk_init(rtc_clk_config_t cfg) 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(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); + 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); + uint32_t hp_cali_dbias = get_act_hp_dbias(); + uint32_t lp_cali_dbias = get_act_lp_dbias(); - clk_ll_rc_fast_tick_conf(); // TODO: IDF-8642 Unnecessary or not? + SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); // XTAL freq determined by efuse, and can be directly informed from register field PCR_CLK_XTAL_FREQ diff --git a/components/esp_hw_support/port/esp32c5/rtc_time.c b/components/esp_hw_support/port/esp32c5/rtc_time.c index ec157f07d1..76e77e06f5 100644 --- a/components/esp_hw_support/port/esp32c5/rtc_time.c +++ b/components/esp_hw_support/port/esp32c5/rtc_time.c @@ -12,6 +12,7 @@ #include "hal/clk_tree_ll.h" #include "hal/timer_ll.h" #include "soc/timer_group_reg.h" +#include "soc/pcr_reg.h" #include "esp_rom_sys.h" #include "assert.h" #include "hal/efuse_hal.h" @@ -23,64 +24,31 @@ __attribute__((unused)) 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. */ -/* On ESP32C5, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3 - * 0 or 3: 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 +#define CLK_CAL_TIMEOUT_THRES(cal_clk, cycles) ((cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) ? (cycles << 12) : (cycles << 10)) -/** - * @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(); if (cal_clk == RTC_CAL_RTC_MUX) { - cal_clk = (rtc_cal_sel_t)slow_clk_src; + soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get(); + if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) { + cal_clk = RTC_CAL_RC_SLOW; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + cal_clk = RTC_CAL_32K_XTAL; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) { + cal_clk = RTC_CAL_RC32K; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + cal_clk = RTC_CAL_32K_OSC_SLOW; + } } - // TODO: [ESP32C5] IDF-8642 Seems RC_SLOW, RC_FAST can't be calibrated on beta3 - // 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); + if (cal_clk < 0 || cal_clk >= RTC_CAL_INVALID_CLK) { + ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated"); + return 0; } - /* Enable requested clock (150k 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 @@ -90,16 +58,16 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc clk_ll_xtal32k_digi_enable(); } - // bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); - // bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); - // if (cal_clk == RTC_CAL_RC_FAST) { - // if (!rc_fast_enabled) { - // rtc_clk_8m_enable(true); - // } - // if (!dig_rc_fast_enabled) { - // rtc_dig_clk8m_enable(); - // } - // } + bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); + bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); + if (cal_clk == RTC_CAL_RC_FAST) { + if (!rc_fast_enabled) { + rtc_clk_8m_enable(true); + } + if (!dig_rc_fast_enabled) { + rtc_dig_clk8m_enable(); + } + } bool rc32k_enabled = clk_ll_rc32k_is_enabled(); bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled(); @@ -126,22 +94,22 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } /* Prepare calibration */ - // calibration clock source is set by PCR register: PCR_32K_SEL - // REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel); + REG_SET_FIELD(PCR_CTRL_32K_CONF_REG, PCR_32K_SEL, cal_clk); + if (cal_clk == RTC_CAL_RC_FAST) { + clk_ll_rc_fast_tick_conf(); + } 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*/ + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cal_clk, slowclk_cycles)); uint32_t expected_freq; - if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) { - REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles)); + if (cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) { expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; - } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_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 if (cal_clk == RTC_CAL_RC_FAST) { + expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX >> CLK_LL_RC_FAST_TICK_DIV_BITS; } else { - REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; } uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq); @@ -156,12 +124,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc 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); - // TODO: IDF-8642 Check whether this workaround still need for C5 - // /*The Fosc CLK of calibration circuit is divided by 32. - // So we need to multiply the frequency of the FOSC by 32 times.*/ - // if (cal_clk == RTC_CAL_RC_FAST) { - // cal_val = cal_val >> 5; - // } + /*The Fosc CLK of calibration circuit is divided by a factor, k. + So we need to multiply the frequency of the FOSC by k times.*/ + if (cal_clk == RTC_CAL_RC_FAST) { + cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS; + } break; } if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) { @@ -176,14 +143,14 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc clk_ll_xtal32k_digi_disable(); } - // if (cal_clk == RTC_CAL_RC_FAST) { - // if (!dig_rc_fast_enabled) { - // rtc_dig_clk8m_disable(); - // } - // if (!rc_fast_enabled) { - // rtc_clk_8m_enable(false); - // } - // } + if (cal_clk == RTC_CAL_RC_FAST) { + if (!dig_rc_fast_enabled) { + rtc_dig_clk8m_disable(); + } + if (!rc_fast_enabled) { + rtc_clk_8m_enable(false); + } + } if (cal_clk == RTC_CAL_RC32K) { if (!dig_rc32k_enabled) { @@ -194,11 +161,6 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } } - // 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); - } - return cal_val; } @@ -212,13 +174,13 @@ static bool rtc_clk_cal_32k_valid(uint32_t xtal_freq, uint32_t slowclk_cycles, u uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); - // TODO: IDF-8642 Check whether this workaround still need for C5 - // /*The Fosc CLK of calibration circuit is divided by 32. - // So we need to divide the calibrate cycles of the FOSC by 32 to - // avoid excessive calibration time.*/ - // if (cal_clk == RTC_CAL_RC_FAST) { - // slowclk_cycles = slowclk_cycles >> 5; - // } + + /*The Fosc CLK of calibration circuit is divided by a factor, k. + So we need to divide the calibrate cycles of the FOSC by k to + avoid excessive calibration time.*/ + if (cal_clk == RTC_CAL_RC_FAST) { + slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS; + } uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid((uint32_t)xtal_freq, slowclk_cycles, xtal_cycles)) { @@ -246,8 +208,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; + 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/esp32c6/rtc_clk_init.c b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c index 70c275a1f9..9ab938f02a 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c @@ -84,8 +84,6 @@ void rtc_clk_init(rtc_clk_config_t cfg) SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); - clk_ll_rc_fast_tick_conf(); - soc_xtal_freq_t xtal_freq = cfg.xtal_freq; esp_rom_output_tx_wait_idle(0); rtc_clk_xtal_freq_update(xtal_freq); diff --git a/components/esp_hw_support/port/esp32c6/rtc_time.c b/components/esp_hw_support/port/esp32c6/rtc_time.c index 40b535eefd..8e31485e1d 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_time.c +++ b/components/esp_hw_support/port/esp32c6/rtc_time.c @@ -125,6 +125,9 @@ 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); + if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { + clk_ll_rc_fast_tick_conf(); + } 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 */ @@ -137,6 +140,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_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; + if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { + expected_freq = expected_freq >> CLK_LL_RC_FAST_TICK_DIV_BITS; + } } else { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; @@ -160,7 +166,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc calibration. */ if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { if (cal_clk == RTC_CAL_RC_FAST) { - cal_val = cal_val >> 5; + cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS; CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } @@ -221,7 +227,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) 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; + slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS; SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } diff --git a/components/esp_hw_support/port/esp32h2/rtc_clk_init.c b/components/esp_hw_support/port/esp32h2/rtc_clk_init.c index d456aee764..fcac148c6a 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32h2/rtc_clk_init.c @@ -52,8 +52,6 @@ void rtc_clk_init(rtc_clk_config_t cfg) SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); - clk_ll_rc_fast_tick_conf(); - soc_xtal_freq_t xtal_freq = cfg.xtal_freq; esp_rom_output_tx_wait_idle(0); rtc_clk_xtal_freq_update(xtal_freq); diff --git a/components/esp_hw_support/port/esp32h2/rtc_time.c b/components/esp_hw_support/port/esp32h2/rtc_time.c index 395be4dc4a..7db712d7a6 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_time.c +++ b/components/esp_hw_support/port/esp32h2/rtc_time.c @@ -125,6 +125,9 @@ 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); + if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { + clk_ll_rc_fast_tick_conf(); + } 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 */ @@ -137,6 +140,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_8M_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX; + if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { + expected_freq = expected_freq >> CLK_LL_RC_FAST_TICK_DIV_BITS; + } } else { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; @@ -160,7 +166,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc calibration. */ if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (cal_clk == RTC_CAL_RC_FAST) { - cal_val = cal_val >> 5; + cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS; CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } @@ -221,7 +227,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) avoid excessive calibration time.*/ if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (cal_clk == RTC_CAL_RC_FAST) { - slowclk_cycles = slowclk_cycles >> 5; + slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS; SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); } } diff --git a/components/esp_hw_support/port/esp_clk_tree_common.c b/components/esp_hw_support/port/esp_clk_tree_common.c index 0bc2bfe531..cf5a2eece1 100644 --- a/components/esp_hw_support/port/esp_clk_tree_common.c +++ b/components/esp_hw_support/port/esp_clk_tree_common.c @@ -41,6 +41,9 @@ static esp_clk_tree_calibrated_freq_t s_calibrated_freq = {}; #define DEFAULT_32K_CLK_CAL_CYCLES 100 /* Number of cycles for RC_FAST calibration */ #define DEFAULT_RC_FAST_CAL_CYCLES 10000 // RC_FAST has a higher frequency, therefore, requires more cycles to get an accurate value + // Usually we calibrate on the divider of the RC_FAST clock, the cal_cycles is divided by + // the divider factor internally in rtc_clk_cal, so the time to spend on calibrating RC_FAST + // is always (10000 / f_rc_fast) /** @@ -187,6 +190,10 @@ uint32_t esp_clk_tree_lp_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t prec #if SOC_CLK_LP_FAST_SUPPORT_LP_PLL case SOC_RTC_FAST_CLK_SRC_LP_PLL: return clk_ll_lp_pll_get_freq_mhz() * MHZ; +#endif +#if SOC_CLK_LP_FAST_SUPPORT_XTAL + case SOC_RTC_FAST_CLK_SRC_XTAL: + return clk_hal_xtal_get_freq_mhz() * MHZ; #endif default: // Invalid clock source diff --git a/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c index f1de569127..dedebaee47 100644 --- a/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c +++ b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c @@ -7,7 +7,6 @@ #include "esp_attr.h" #include "soc/i2c_ana_mst_reg.h" #include "modem/modem_lpcon_reg.h" -#include "soc/pmu_reg.h" #define REGI2C_BIAS_MST_SEL (BIT(8)) #define REGI2C_BBPLL_MST_SEL (BIT(9)) @@ -77,8 +76,6 @@ static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block) uint32_t i2c_sel = 0; REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); - REG_SET_BIT(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); // TODO: IDF-8642 Move to pmu_init() - REG_SET_BIT(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); // TODO: IDF-8642 Move to pmu_init() /* Before config I2C register, enable corresponding slave. */ switch (block) { diff --git a/components/esp_system/port/soc/esp32c5/clk.c b/components/esp_system/port/soc/esp32c5/clk.c index 7242255e4d..674b92920e 100644 --- a/components/esp_system/port/soc/esp32c5/clk.c +++ b/components/esp_system/port/soc/esp32c5/clk.c @@ -30,7 +30,6 @@ #include "esp_private/esp_pmu.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" -#include "ocode_init.h" /* 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 @@ -44,20 +43,13 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src); static const char *TAG = "clk"; -// TODO: [ESP32C5] IDF-8642 void esp_rtc_init(void) { #if !CONFIG_IDF_ENV_FPGA -#if SOC_PMU_SUPPORTED pmu_init(); -#endif - if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { - esp_ocode_calib_init(); - } #endif } -// TODO: [ESP32C5] IDF-8642 __attribute__((weak)) void esp_clk_init(void) { #if !CONFIG_IDF_ENV_FPGA @@ -122,7 +114,7 @@ __attribute__((weak)) void esp_clk_init(void) // Re calculate the ccount to make time calculation correct. esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz); - // Set crypto clock (`clk_sec`) to use 160M SPLL clock + // Set crypto clock (`clk_sec`) to use 480M SPLL clock REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x2); } @@ -195,7 +187,8 @@ void rtc_clk_select_rtc_slow_clk(void) */ __attribute__((weak)) void esp_perip_clk_init(void) { - // TODO: [ESP32C5] IDF-8844 +// TODO: [ESP32C5] IDF-8844 +#if SOC_MODEM_CLOCK_SUPPORTED // modem_clock_domain_pmu_state_icg_map_init(); /* During system initialization, the low-power clock source of the modem * (WiFi, BLE or Coexist) follows the configuration of the slow clock source @@ -211,6 +204,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_EXT32K : MODEM_CLOCK_LPCLK_SRC_RC32K); modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0); +#endif ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); #if 0 // TODO: [ESP32C5] IDF-8844 diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 0351cc16fb..49661e1b79 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -3,8 +3,9 @@ menu "Serial flasher config" config ESPTOOLPY_NO_STUB bool "Disable download stub" - default "y" if IDF_ENV_FPGA || IDF_ENV_BRINGUP - default "n" + default y if IDF_ENV_FPGA || IDF_ENV_BRINGUP + default y if IDF_TARGET_ESP32C5 # TODO: IDF-8631 to be removed + default n help The flasher tool sends a precompiled download stub first by default. That stub allows things diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 6cc4319dc2..0e9e12a6fc 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -56,7 +56,7 @@ if(NOT BOOTLOADER_BUILD) endif() endif() - if(CONFIG_SOC_CLK_TREE_SUPPORTED OR CONFIG_IDF_TARGET_ESP32C5) # TODO: IDF-8642 + if(CONFIG_SOC_CLK_TREE_SUPPORTED) list(APPEND srcs "${target}/clk_tree_hal.c") endif() diff --git a/components/hal/esp32c5/clk_tree_hal.c b/components/hal/esp32c5/clk_tree_hal.c index de3b62e9fc..b7ac7939f2 100644 --- a/components/hal/esp32c5/clk_tree_hal.c +++ b/components/hal/esp32c5/clk_tree_hal.c @@ -17,8 +17,10 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src) switch (cpu_clk_src) { case SOC_CPU_CLK_SRC_XTAL: return clk_hal_xtal_get_freq_mhz(); - case SOC_CPU_CLK_SRC_PLL: - return clk_ll_bbpll_get_freq_mhz(); + case SOC_CPU_CLK_SRC_PLL_F160M: + return CLK_LL_PLL_160M_FREQ_MHZ; + case SOC_CPU_CLK_SRC_PLL_F240M: + return CLK_LL_PLL_240M_FREQ_MHZ; case SOC_CPU_CLK_SRC_RC_FAST: return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ; default: @@ -31,16 +33,14 @@ 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(); - + uint32_t divider = clk_ll_cpu_get_divider(); return clk_hal_soc_root_get_freq_mhz(source) * MHZ / 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(); - + uint32_t divider = clk_ll_ahb_get_divider(); return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider; } diff --git a/components/hal/esp32c5/include/hal/clk_tree_ll.h b/components/hal/esp32c5/include/hal/clk_tree_ll.h index f1a9793efe..08eaa2747e 100644 --- a/components/hal/esp32c5/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c5/include/hal/clk_tree_ll.h @@ -40,12 +40,8 @@ extern "C" { .dbuf = 1, \ } -/* -Set the frequency division factor of ref_tick -The FOSC of rtc calibration uses the 32 frequency division clock, -So the frequency division factor of ref_tick must be greater than or equal to 32 -*/ -#define REG_FOSC_TICK_NUM 255 // TODO: IDF-8642 No need? Can calibrate on RC_FAST directly? +// Fix default division factor for the RC_FAST clock for calibration to be 32 +#define CLK_LL_RC_FAST_TICK_DIV_BITS 5 /** * @brief XTAL32K_CLK enable modes @@ -289,7 +285,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz( } /** - * @brief Set BBPLL frequency from XTAL source (Digital part) + * @brief Set SPLL frequency from XTAL source (Digital part) * * @param pll_freq_mhz PLL frequency, in MHz */ @@ -301,7 +297,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint } /** - * @brief Set BBPLL frequency from XTAL source (Analog part) + * @brief Set SPLL frequency from XTAL source (Analog part) * * @param pll_freq_mhz PLL frequency, in MHz * @param xtal_freq_mhz XTAL frequency, in MHz @@ -313,36 +309,52 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32 uint8_t div7_0; uint8_t dr1; uint8_t dr3; - uint8_t dchgp; - uint8_t dbias; - uint8_t dcur; + uint8_t dchgp = 5; + uint8_t dbias = 3; + uint8_t href = 3; + uint8_t lref = 1; /* Configure 480M PLL */ switch (xtal_freq_mhz) { + case SOC_XTAL_FREQ_48M: + div_ref = 1; + div7_0 = 10; + dr1 = 1; + dr3 = 1; + break; case SOC_XTAL_FREQ_40M: - default: - div_ref = 0; - div7_0 = 8; + div_ref = 1; + div7_0 = 12; + dr1 = 0; + dr3 = 0; + break; + default: + div_ref = 1; + div7_0 = 12; 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_DLREF_SEL, lref); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, href); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias); } +/** + * @brief To enable the change of soc_clk_sel, cpu_div_num, and ahb_div_num + */ +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); +} + /** * @brief Select the clock source for CPU_CLK (SOC Clock Root) * @@ -354,12 +366,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_PLL_F160M: PCR.sysclk_conf.soc_clk_sel = 2; break; + case SOC_CPU_CLK_SRC_PLL_F240M: + PCR.sysclk_conf.soc_clk_sel = 3; + break; default: // Unsupported SOC_CLK mux input sel abort(); @@ -378,9 +393,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_PLL_F160M; + case 3: + return SOC_CPU_CLK_SRC_PLL_F240M; default: // Invalid SOC_CLK_SEL value return SOC_CPU_CLK_SRC_INVALID; @@ -388,129 +405,47 @@ 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's divider * - * @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider. + * @param divider Divider. (PCR_CPU_DIV_NUM + 1) = divider. */ -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; + HAL_ASSERT(divider >= 1); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, (divider) - 1); } /** - * @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST) + * @brief Get CPU_CLK's divider * - * @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider. + * @return Divider. Divider = (PCR_CPU_DIV_NUM + 1). */ -static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider) +static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void) { - // 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)); - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, divider - 1); + return HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num) + 1; } /** - * @brief Get CPU_CLK's high-speed divider + * @brief Set AHB_CLK's divider * - * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1). - */ -static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_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); -} - -/** - * @brief Get CPU_CLK's low-speed divider + * Constraint: f_ahb <= 48 MHz, f_cpu = n * f_ahb * - * @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1). + * @param divider Divider. (PCR_AHB_DIV_NUM + 1) = divider. */ -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)); + 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's divider * - * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1). + * @return Divider. Divider = (PCR_AHB_DIV_NUM + 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; } /** @@ -536,103 +471,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi return HAL_FORCE_READ_U32_REG_FIELD(PCR.apb_freq_conf, apb_div_num) + 1; } -/** - * @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) - * - * @param divider Divider. - */ -static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divider(uint32_t divider) -{ - // 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); -} - -/** - * @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.ctrl_32k_conf.clk_32k_sel = 0; - break; - case SOC_RTC_SLOW_CLK_SRC_XTAL32K: - PCR.ctrl_32k_conf.clk_32k_sel = 1; - break; - case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: - PCR.ctrl_32k_conf.clk_32k_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.ctrl_32k_conf.clk_32k_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; - default: - return SOC_RTC_SLOW_CLK_SRC_INVALID; - } -} - /** * @brief Select the clock source for RTC_SLOW_CLK * @@ -695,6 +533,9 @@ static inline __attribute__((always_inline)) void clk_ll_rtc_fast_set_src(soc_rt case SOC_RTC_FAST_CLK_SRC_XTAL_D2: LP_CLKRST.lp_clk_conf.fast_clk_sel = 1; break; + case SOC_RTC_FAST_CLK_SRC_XTAL: + LP_CLKRST.lp_clk_conf.fast_clk_sel = 2; + break; default: // Unsupported RTC_FAST_CLK mux input sel abort(); @@ -714,6 +555,8 @@ static inline __attribute__((always_inline)) soc_rtc_fast_clk_src_t clk_ll_rtc_f return SOC_RTC_FAST_CLK_SRC_RC_FAST; case 1: return SOC_RTC_FAST_CLK_SRC_XTAL_D2; + case 2: + return SOC_RTC_FAST_CLK_SRC_XTAL; default: return SOC_RTC_FAST_CLK_SRC_INVALID; } @@ -741,6 +584,14 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider return 1; } +/** + * @brief Set the frequency division factor of RC_FAST clock + */ +static inline void clk_ll_rc_fast_tick_conf(void) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, (1 << CLK_LL_RC_FAST_TICK_DIV_BITS) - 1); // divider = 1 << CLK_LL_RC_FAST_TICK_DIV_BITS +} + /** * @brief Set RC_SLOW_CLK divider * @@ -753,49 +604,6 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin } /************************** LP STORAGE REGISTER STORE/LOAD **************************/ -#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION -/** - * @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; -} -#endif - /** * @brief Store RTC_SLOW_CLK calibration value in RTC storage register * @@ -821,16 +629,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.ctrl_32k_conf.fosc_tick_num = REG_FOSC_TICK_NUM; -} - - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/clk_tree_ll.h b/components/hal/esp32c6/include/hal/clk_tree_ll.h index 9fe36292ac..30aa05e1ad 100644 --- a/components/hal/esp32c6/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c6/include/hal/clk_tree_ll.h @@ -44,7 +44,8 @@ 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 +#define CLK_LL_RC_FAST_TICK_DIV_BITS 5 +#define REG_FOSC_TICK_NUM 255 /** * @brief XTAL32K_CLK enable modes @@ -810,7 +811,7 @@ Set the frequency division factor of ref_tick */ static inline void clk_ll_rc_fast_tick_conf(void) { - PCR.ctrl_tick_conf.fosc_tick_num = REG_FOSC_TICK_NUM; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock } diff --git a/components/hal/esp32c61/include/hal/clk_tree_ll.h b/components/hal/esp32c61/include/hal/clk_tree_ll.h index 4ad88dccbb..8ed04659a1 100644 --- a/components/hal/esp32c61/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c61/include/hal/clk_tree_ll.h @@ -808,7 +808,7 @@ Set the frequency division factor of ref_tick */ static inline void clk_ll_rc_fast_tick_conf(void) { - PCR.ctrl_32k_conf.fosc_tick_num = REG_FOSC_TICK_NUM; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // divider = (REG_FOSC_TICK_NUM + 1) = 256 } diff --git a/components/hal/esp32h2/include/hal/clk_tree_ll.h b/components/hal/esp32h2/include/hal/clk_tree_ll.h index f862b5a128..f594607728 100644 --- a/components/hal/esp32h2/include/hal/clk_tree_ll.h +++ b/components/hal/esp32h2/include/hal/clk_tree_ll.h @@ -43,7 +43,8 @@ Set the frequency division factor of ref_tick The FOSC of rtc calibration uses the 32 frequency division clock for ECO2, So the frequency division factor of ref_tick must be greater than or equal to 32 */ -#define REG_FOSC_TICK_NUM 255 +#define CLK_LL_RC_FAST_TICK_DIV_BITS 5 +#define REG_FOSC_TICK_NUM 255 /** * @brief XTAL32K_CLK enable modes @@ -746,7 +747,7 @@ Set the frequency division factor of ref_tick */ static inline void clk_ll_rc_fast_tick_conf(void) { - PCR.ctrl_tick_conf.fosc_tick_num = REG_FOSC_TICK_NUM; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock } /* diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index a9d6abc8e6..100ca95028 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -131,6 +131,10 @@ config SOC_SECURE_BOOT_SUPPORTED bool default y +config SOC_PMU_SUPPORTED + bool + default y + config SOC_LP_TIMER_SUPPORTED bool default y @@ -139,6 +143,10 @@ config SOC_LP_PERIPHERALS_SUPPORTED bool default y +config SOC_CLK_TREE_SUPPORTED + bool + default y + config SOC_SPI_FLASH_SUPPORTED bool default y @@ -847,6 +855,14 @@ config SOC_UART_BITRATE_MAX int default 5000000 +config SOC_UART_SUPPORT_PLL_F80M_CLK + bool + default y + +config SOC_UART_SUPPORT_RTC_CLK + bool + default y + config SOC_UART_SUPPORT_XTAL_CLK bool default y @@ -895,6 +911,10 @@ config SOC_PM_SUPPORT_RTC_PERIPH_PD bool default y +config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION + bool + default y + config SOC_MODEM_CLOCK_IS_INDEPENDENT bool default y @@ -911,6 +931,10 @@ config SOC_CLK_RC32K_SUPPORTED bool default y +config SOC_CLK_LP_FAST_SUPPORT_XTAL + bool + default y + config SOC_RCC_IS_INDEPENDENT bool default y diff --git a/components/soc/esp32c5/include/soc/clk_tree_defs.h b/components/soc/esp32c5/include/soc/clk_tree_defs.h index ee7437c0e5..05cb03e456 100644 --- a/components/soc/esp32c5/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c5/include/soc/clk_tree_defs.h @@ -19,7 +19,7 @@ extern "C" { * * The exact frequency of RC_FAST_CLK can be computed in runtime through calibration. * - * 2) External 40/48MHz Crystal Clock: XTAL + * 2) External 48MHz Crystal Clock: XTAL * * 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description) * @@ -45,7 +45,6 @@ extern "C" { * OSC_SLOW_CLK can also be calibrated to get its exact frequency. */ -// TODO: [ESP32C5] IDF-8642 (inherit from C6) /* 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 */ @@ -60,10 +59,10 @@ extern "C" { /** * @brief Root clock */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +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_EXT_XTAL, /*!< External 40MHz crystal */ + SOC_ROOT_CLK_EXT_XTAL, /*!< External 48MHz 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 */ @@ -73,12 +72,11 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) * @brief CPU_CLK mux inputs, which are the supported clock sources for the CPU_CLK * @note Enum values are matched with the register field values on purpose */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */ SOC_CPU_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as CPU_CLK source */ SOC_CPU_CLK_SRC_PLL_F160M = 2, /*!< Select PLL_F160M_CLK as CPU_CLK source (PLL_F160M_CLK is derived from SPLL (480MHz), which is the output of the main crystal oscillator frequency multiplier) */ SOC_CPU_CLK_SRC_PLL_F240M = 3, /*!< Select PLL_F240M_CLK as CPU_CLK source (PLL_F240M_CLK is derived from SPLL (480MHz), which is the output of the main crystal oscillator frequency multiplier) */ - SOC_CPU_CLK_SRC_PLL = SOC_CPU_CLK_SRC_PLL_F240M, // TODO: [IDF-8642] remove this alias SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */ } soc_cpu_clk_src_t; @@ -86,7 +84,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) * @brief RTC_SLOW_CLK mux inputs, which are the supported clock sources for the RTC_SLOW_CLK * @note Enum values are matched with the register field values on purpose */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_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 */ @@ -98,7 +96,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) * @brief RTC_FAST_CLK mux inputs, which are the supported clock sources for the RTC_FAST_CLK * @note Enum values are matched with the register field values on purpose */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { SOC_RTC_FAST_CLK_SRC_RC_FAST = 0, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */ SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 1, /*!< Select XTAL_D2_CLK as RTC_FAST_CLK source */ SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */ @@ -125,7 +123,7 @@ typedef enum { * * @note enum starts from 1, to save 0 for special purpose */ -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +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 */ // For RTC domain @@ -138,9 +136,9 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) SOC_MOD_CLK_SPLL, /*!< SPLL is from the main XTAL oscillator frequency multipliers, it has a "fixed" frequency of 480MHz */ 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 40MHz crystal */ + SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 48MHz crystal */ // For LP peripherals - SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 40MHz crystal, passing a div of 2 to the LP peripherals */ + SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 48MHz 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; @@ -548,7 +546,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8649 } soc_periph_mspi_clk_src_t; //////////////////////////////////////////////CLOCK OUTPUT/////////////////////////////////////////////////////////// -typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) +typedef enum { // TODO CLKOUT_SIG_PLL = 1, /*!< PLL_CLK is the output of crystal oscillator frequency multiplier */ CLKOUT_SIG_XTAL = 5, /*!< Main crystal oscillator clock */ CLKOUT_SIG_PLL_F80M = 13, /*!< From PLL, usually be 80MHz */ diff --git a/components/soc/esp32c5/include/soc/pcr_reg.h b/components/soc/esp32c5/include/soc/pcr_reg.h index b8e084f1a7..e9e7316b2a 100644 --- a/components/soc/esp32c5/include/soc/pcr_reg.h +++ b/components/soc/esp32c5/include/soc/pcr_reg.h @@ -1902,21 +1902,6 @@ extern "C" { * SYSCLK configuration register */ #define PCR_SYSCLK_CONF_REG (DR_REG_PCR_BASE + 0x110) -/** 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\\ diff --git a/components/soc/esp32c5/include/soc/pcr_struct.h b/components/soc/esp32c5/include/soc/pcr_struct.h index db621a0671..15acd48aad 100644 --- a/components/soc/esp32c5/include/soc/pcr_struct.h +++ b/components/soc/esp32c5/include/soc/pcr_struct.h @@ -1642,15 +1642,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\\ @@ -1706,7 +1698,7 @@ typedef union { typedef union { struct { /** cpu_div_num : R/W; bitpos: [7:0]; default: 0; - * Set this field to generate clk_cpu driven by clk_hproot. The clk_cpu is + * Set this field to generate clk_cpu derived by clk_hproot. The clk_cpu is * div1(default)/div2/div4 of clk_hproot. This field is only available for low-speed * clock-source such as XTAL/FOSC, and should be used together with PCR_AHB_DIV_NUM. */ @@ -1722,7 +1714,7 @@ typedef union { typedef union { struct { /** ahb_div_num : R/W; bitpos: [7:0]; default: 0; - * Set this field to generate clk_ahb driven by clk_hproot. The clk_ahb is + * Set this field to generate clk_ahb derived by clk_hproot. The clk_ahb is * div1(default)/div2/div4/div8 of clk_hproot. This field is only available for * low-speed clock-source such as XTAL/FOSC, and should be used together with * PCR_CPU_DIV_NUM. @@ -1749,7 +1741,7 @@ typedef union { */ uint32_t apb_decrease_div_num:8; /** apb_div_num : R/W; bitpos: [15:8]; default: 0; - * Set as one within (0,1,3) to generate clk_apb driven by clk_ahb. The clk_apb is + * Set as one within (0,1,3) to generate clk_apb derived by clk_ahb. The clk_apb is * div1(default)/div2/div4 of clk_ahb. */ uint32_t apb_div_num:8; @@ -1764,47 +1756,47 @@ typedef union { typedef union { struct { /** pll_240m_clk_en : R/W; bitpos: [0]; default: 1; - * This field is used to open 240 MHz clock (div2 of SPLL) driven from SPLL. 0: close, + * This field is used to open 240 MHz clock (div2 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_240m_clk_en:1; /** pll_160m_clk_en : R/W; bitpos: [1]; default: 1; - * This field is used to open 160 MHz clock (div3 of SPLL) driven from SPLL. 0: close, + * This field is used to open 160 MHz clock (div3 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_160m_clk_en:1; /** pll_120m_clk_en : R/W; bitpos: [2]; default: 1; - * This field is used to open 120 MHz clock (div4 of SPLL) driven from SPLL. 0: close, + * This field is used to open 120 MHz clock (div4 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_120m_clk_en:1; /** pll_80m_clk_en : R/W; bitpos: [3]; default: 1; - * This field is used to open 80 MHz clock (div6 of SPLL) driven from SPLL. 0: close, + * This field is used to open 80 MHz clock (div6 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_80m_clk_en:1; /** pll_60m_clk_en : R/W; bitpos: [4]; default: 1; - * This field is used to open 60 MHz clock (div8 of SPLL) driven from SPLL. 0: close, + * This field is used to open 60 MHz clock (div8 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_60m_clk_en:1; /** pll_48m_clk_en : R/W; bitpos: [5]; default: 1; - * This field is used to open 48 MHz clock (div10 of SPLL) driven from SPLL. 0: close, + * This field is used to open 48 MHz clock (div10 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_48m_clk_en:1; /** pll_40m_clk_en : R/W; bitpos: [6]; default: 1; - * This field is used to open 40 MHz clock (div12 of SPLL) driven from SPLL. 0: close, + * This field is used to open 40 MHz clock (div12 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_40m_clk_en:1; /** pll_20m_clk_en : R/W; bitpos: [7]; default: 1; - * This field is used to open 20 MHz clock (div24 of SPLL) driven from SPLL. 0: close, + * This field is used to open 20 MHz clock (div24 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_20m_clk_en:1; /** pll_12m_clk_en : R/W; bitpos: [8]; default: 1; - * This field is used to open 12 MHz clock (div40 of SPLL) driven from SPLL. 0: close, + * This field is used to open 12 MHz clock (div40 of SPLL) derived from SPLL. 0: close, * 1: open(default). Only available when high-speed clock-source SPLL is active. */ uint32_t pll_12m_clk_en:1; diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index 155000b197..9870aaeeb7 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -58,14 +58,14 @@ #define SOC_SECURE_BOOT_SUPPORTED 1 // #define SOC_BOD_SUPPORTED 1 // TODO: [ESP32C5] IDF-8647 // #define SOC_APM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8614, IDF-8615 -// #define SOC_PMU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8667 +#define SOC_PMU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8667 // #define SOC_PAU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 #define SOC_LP_TIMER_SUPPORTED 1 // #define SOC_LP_AON_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 #define SOC_LP_PERIPHERALS_SUPPORTED 1 // #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32C5] IDF-8634 // #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32C5] IDF-8633 -// #define SOC_CLK_TREE_SUPPORTED 1 // TODO: [ESP32C5] IDF-8642 +#define SOC_CLK_TREE_SUPPORTED 1 // #define SOC_ASSIST_DEBUG_SUPPORTED 1 // TODO: [ESP32C5] IDF-8663 // #define SOC_WDT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8650 #define SOC_SPI_FLASH_SUPPORTED 1 // TODO: [ESP32C5] IDF-8715 @@ -493,8 +493,8 @@ #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #define SOC_LP_UART_FIFO_LEN (16) /*!< The LP UART hardware FIFO length */ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ -// #define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_F80M as the clock source */ -// #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ // TODO: [ESP32C5] IDF-8642 +#define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_F80M as the clock source */ +#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ #define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ #define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */ @@ -545,12 +545,13 @@ // #define SOC_PM_PAU_LINK_NUM (4) /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ -// #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) // TODO: IDF-8642 +#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 (1) /*!< Support XTAL 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/docs/docs_not_updated/esp32c5.txt b/docs/docs_not_updated/esp32c5.txt index bd92346df9..10d49479d1 100644 --- a/docs/docs_not_updated/esp32c5.txt +++ b/docs/docs_not_updated/esp32c5.txt @@ -97,7 +97,6 @@ api-reference/peripherals/lcd.rst api-reference/peripherals/ana_cmpr.rst api-reference/peripherals/temp_sensor.rst api-reference/peripherals/spi_features.rst -api-reference/peripherals/clk_tree.rst api-reference/peripherals/spi_flash/spi_flash_concurrency.rst api-reference/peripherals/spi_flash/spi_flash_override_driver.rst api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst diff --git a/docs/en/api-reference/peripherals/clk_tree.rst b/docs/en/api-reference/peripherals/clk_tree.rst index 1b43c0e7c4..d54b6bbbcc 100644 --- a/docs/en/api-reference/peripherals/clk_tree.rst +++ b/docs/en/api-reference/peripherals/clk_tree.rst @@ -7,7 +7,7 @@ Clock Tree {IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"} -{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32"} +{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48"} {IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"} diff --git a/docs/en/api-reference/peripherals/ledc.rst b/docs/en/api-reference/peripherals/ledc.rst index cce6b155cd..6595a5aa9c 100644 --- a/docs/en/api-reference/peripherals/ledc.rst +++ b/docs/en/api-reference/peripherals/ledc.rst @@ -166,7 +166,7 @@ The source clock can also limit the PWM frequency. The higher the source clock f - ~ 17.5 MHz - Dynamic Frequency Scaling compatible, Light sleep compatible * - XTAL_CLK - - 48/40 MHz + - 48 MHz - Dynamic Frequency Scaling compatible .. only:: esp32c6 diff --git a/docs/zh_CN/api-reference/peripherals/clk_tree.rst b/docs/zh_CN/api-reference/peripherals/clk_tree.rst index 46ab9c20c8..18705f495d 100644 --- a/docs/zh_CN/api-reference/peripherals/clk_tree.rst +++ b/docs/zh_CN/api-reference/peripherals/clk_tree.rst @@ -7,7 +7,7 @@ {IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"} -{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32"} +{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48"} {IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"} diff --git a/docs/zh_CN/api-reference/peripherals/ledc.rst b/docs/zh_CN/api-reference/peripherals/ledc.rst index 71dbdd9d36..5baae074a7 100644 --- a/docs/zh_CN/api-reference/peripherals/ledc.rst +++ b/docs/zh_CN/api-reference/peripherals/ledc.rst @@ -166,7 +166,7 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实 - ~ 17.5 MHz - 支持动态调频 (DFS) 功能,支持 Light-sleep 模式 * - XTAL_CLK - - 48/40 MHz + - 48 MHz - 支持动态调频 (DFS) 功能 .. only:: esp32c6