Bladeren bron

Merge branch 'feature/esp32c6_clock_basic_support' into 'master'

clk: Add basic clock support for esp32c6

Closes IDF-5630, IDF-5973, IDF-5346, and IDF-6050

See merge request espressif/esp-idf!21149
Song Ruo Jing 3 jaren geleden
bovenliggende
commit
edd815af2e
59 gewijzigde bestanden met toevoegingen van 1206 en 658 verwijderingen
  1. 0 1
      Kconfig
  2. 17 4
      components/bootloader_support/src/bootloader_clock_init.c
  3. 1 1
      components/bootloader_support/src/esp32c6/bootloader_esp32c6.c
  4. 5 0
      components/driver/deprecated/timer_legacy.c
  5. 12 0
      components/driver/gptimer/gptimer.c
  6. 13 2
      components/driver/i2s/i2s_common.c
  7. 0 2
      components/driver/test/test_ledc.c
  8. 8 0
      components/driver/test_apps/gpio/main/test_gpio_filter.c
  9. 5 0
      components/esp_hw_support/esp_clk.c
  10. 1 1
      components/esp_hw_support/port/esp32c2/rtc_init.c
  11. 5 5
      components/esp_hw_support/port/esp32c2/rtc_time.c
  12. 1 1
      components/esp_hw_support/port/esp32c3/rtc_clk.c
  13. 1 1
      components/esp_hw_support/port/esp32c6/CMakeLists.txt
  14. 2 3
      components/esp_hw_support/port/esp32c6/Kconfig.rtc
  15. 230 88
      components/esp_hw_support/port/esp32c6/rtc_clk.c
  16. 21 25
      components/esp_hw_support/port/esp32c6/rtc_clk_init.c
  17. 18 1
      components/esp_hw_support/port/esp32c6/rtc_init.c
  18. 173 34
      components/esp_hw_support/port/esp32c6/rtc_time.c
  19. 2 2
      components/esp_hw_support/rtc_module.c
  20. 3 3
      components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c
  21. 0 138
      components/esp_rom/esp32c6/ld/esp32c6.rom.eco3.ld
  22. 1 1
      components/esp_system/port/soc/esp32c2/clk.c
  23. 3 0
      components/esp_system/port/soc/esp32c6/Kconfig.cpu
  24. 20 46
      components/esp_system/port/soc/esp32c6/clk.c
  25. 7 1
      components/esptool_py/Kconfig.projbuild
  26. 2 0
      components/hal/esp32/include/hal/i2s_ll.h
  27. 2 0
      components/hal/esp32c3/include/hal/i2s_ll.h
  28. 395 132
      components/hal/esp32c6/include/hal/clk_tree_ll.h
  29. 2 0
      components/hal/esp32c6/include/hal/i2s_ll.h
  30. 29 10
      components/hal/esp32c6/include/hal/regi2c_ctrl_ll.h
  31. 1 2
      components/hal/esp32c6/include/hal/spimem_flash_ll.h
  32. 1 1
      components/hal/esp32c6/include/hal/timer_ll.h
  33. 2 0
      components/hal/esp32h4/include/hal/i2s_ll.h
  34. 2 0
      components/hal/esp32s2/include/hal/i2s_ll.h
  35. 2 0
      components/hal/esp32s3/include/hal/i2s_ll.h
  36. 4 0
      components/soc/esp32/include/soc/Kconfig.soc_caps.in
  37. 3 3
      components/soc/esp32/include/soc/clk_tree_defs.h
  38. 1 0
      components/soc/esp32/include/soc/soc_caps.h
  39. 4 1
      components/soc/esp32c2/include/soc/rtc.h
  40. 4 0
      components/soc/esp32c3/include/soc/Kconfig.soc_caps.in
  41. 1 0
      components/soc/esp32c3/include/soc/soc_caps.h
  42. 1 1
      components/soc/esp32c6/include/modem/modem_lpcon_reg.h
  43. 3 2
      components/soc/esp32c6/include/modem/modem_lpcon_struct.h
  44. 5 1
      components/soc/esp32c6/include/soc/Kconfig.soc_caps.in
  45. 40 68
      components/soc/esp32c6/include/soc/clk_tree_defs.h
  46. 2 0
      components/soc/esp32c6/include/soc/io_mux_reg.h
  47. 1 1
      components/soc/esp32c6/include/soc/regi2c_bias.h
  48. 7 4
      components/soc/esp32c6/include/soc/regi2c_defs.h
  49. 64 0
      components/soc/esp32c6/include/soc/regi2c_dig_reg.h
  50. 57 61
      components/soc/esp32c6/include/soc/rtc.h
  51. 1 10
      components/soc/esp32c6/include/soc/soc.h
  52. 2 1
      components/soc/esp32c6/include/soc/soc_caps.h
  53. 4 0
      components/soc/esp32h4/include/soc/Kconfig.soc_caps.in
  54. 4 0
      components/soc/esp32h4/include/soc/regi2c_dig_reg.h
  55. 1 0
      components/soc/esp32h4/include/soc/soc_caps.h
  56. 4 0
      components/soc/esp32s2/include/soc/Kconfig.soc_caps.in
  57. 1 0
      components/soc/esp32s2/include/soc/soc_caps.h
  58. 4 0
      components/soc/esp32s3/include/soc/Kconfig.soc_caps.in
  59. 1 0
      components/soc/esp32s3/include/soc/soc_caps.h

+ 0 - 1
Kconfig

@@ -13,7 +13,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
     config IDF_ENV_FPGA
         # This option is for internal use only
         bool
-        default "y" if IDF_TARGET_ESP32C6 # TODO: IDF-5630
         option env="IDF_ENV_FPGA"
 
     config IDF_CI_BUILD

+ 17 - 4
components/bootloader_support/src/bootloader_clock_init.c

@@ -52,15 +52,28 @@ __attribute__((weak)) void bootloader_clock_configure(void)
 
     if (esp_rom_get_reset_reason(0) != RESET_REASON_CPU0_SW || rtc_clk_apb_freq_get() < APB_CLK_FREQ) {
         rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
+
         clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
+
+        // 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;
         }
+
+#if CONFIG_IDF_TARGET_ESP32C6
+        // TODO: IDF-5781 Some of esp32c6 SOC_RTC_FAST_CLK_SRC_XTAL_D2 rtc_fast clock has timing issue
+        // Force to use SOC_RTC_FAST_CLK_SRC_RC_FAST since 2nd stage bootloader
+        clk_cfg.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST;
+#else
+        // 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
         clk_cfg.fast_clk_src = rtc_clk_fast_src_get();
         if (clk_cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_INVALID) {
             clk_cfg.fast_clk_src = SOC_RTC_FAST_CLK_SRC_XTAL_DIV;
         }
+#endif
         rtc_clk_init(clk_cfg);
     }
 
@@ -82,15 +95,15 @@ __attribute__((weak)) void bootloader_clock_configure(void)
     CLEAR_PERI_REG_MASK(LP_TIMER_LP_INT_ENA_REG, LP_TIMER_MAIN_TIMER_LP_INT_ENA);                           /* MAIN_TIMER */
     CLEAR_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_ENA_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_ENA);  /* BROWN_OUT */
     CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_LP_WDT_INT_ENA);                                         /* WDT */
-    CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA);                                        /* SLP_REJECT */
-    CLEAR_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_ENA, PMU_SOC_SLEEP_REJECT_INT_ENA);                        /* SLP_WAKEUP */
+    // CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA);  // TODO: IDF-5348                                    /* SLP_REJECT */
+    // CLEAR_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_ENA, PMU_SOC_SLEEP_REJECT_INT_ENA);                        /* SLP_WAKEUP */
     // SET CLR
     SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR);                                        /* SWD */
     SET_PERI_REG_MASK(LP_TIMER_LP_INT_CLR_REG, LP_TIMER_MAIN_TIMER_LP_INT_CLR);                             /* MAIN_TIMER */
     SET_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_CLR_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_CLR);    /* BROWN_OUT */
     SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_LP_WDT_INT_CLR);                                           /* WDT */
-    SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR);                                          /* SLP_REJECT */
-    SET_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_CLR, PMU_SOC_SLEEP_REJECT_INT_CLR);                          /* SLP_WAKEUP */
+    // SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR);  // TODO: IDF-5348                                          /* SLP_REJECT */
+    // SET_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_CLR, PMU_SOC_SLEEP_REJECT_INT_CLR);                          /* SLP_WAKEUP */
 #else
     REG_WRITE(RTC_CNTL_INT_ENA_REG, 0);
     REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX);

+ 1 - 1
components/bootloader_support/src/esp32c6/bootloader_esp32c6.c

@@ -227,7 +227,7 @@ static void bootloader_super_wdt_auto_feed(void)
 static inline void bootloader_hardware_init(void)
 {
     // TODO: IDF-5990 need update, enable i2c mst clk by force on temporarily
-    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);
     SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M);
 }
 

+ 5 - 0
components/driver/deprecated/timer_legacy.c

@@ -97,6 +97,11 @@ esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_
     case TIMER_SRC_CLK_PLL_F40M:
         *time = (double)timer_val * div / (40 * 1000 * 1000);
         break;
+#endif
+#if SOC_TIMER_GROUP_SUPPORT_PLL_F80M
+    case TIMER_SRC_CLK_PLL_F80M:
+        *time = (double)timer_val * div / (80 * 1000 * 1000);
+        break;
 #endif
     default:
         ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_ARG, TIMER_TAG, "invalid clock source");

+ 12 - 0
components/driver/gptimer/gptimer.c

@@ -411,6 +411,18 @@ static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_sou
 #endif
         break;
 #endif // SOC_TIMER_GROUP_SUPPORT_PLL_F40M
+#if SOC_TIMER_GROUP_SUPPORT_PLL_F80M
+    case GPTIMER_CLK_SRC_PLL_F80M:
+        counter_src_hz = 80 * 1000 * 1000;
+#if CONFIG_PM_ENABLE
+        sprintf(timer->pm_lock_name, "gptimer_%d_%d", timer->group->group_id, timer_id); // e.g. gptimer_0_0
+        // ESP32C6 PLL_F80M is available when SOC_ROOT_CLK switchs to XTAL
+        ret  = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, timer->pm_lock_name, &timer->pm_lock);
+        ESP_RETURN_ON_ERROR(ret, TAG, "create NO_LIGHT_SLEEP lock failed");
+        ESP_LOGD(TAG, "install NO_LIGHT_SLEEP lock for timer (%d,%d)", timer->group->group_id, timer_id);
+#endif
+        break;
+#endif // SOC_TIMER_GROUP_SUPPORT_PLL_F80M
 #if SOC_TIMER_GROUP_SUPPORT_AHB
     case GPTIMER_CLK_SRC_AHB:
         // TODO: decide which kind of PM lock we should use for such clock

+ 13 - 2
components/driver/i2s/i2s_common.c

@@ -488,8 +488,19 @@ uint32_t i2s_get_source_clk_freq(i2s_clock_src_t clk_src, uint32_t mclk_freq_hz)
         (void)mclk_freq_hz;
         return esp_clk_xtal_freq();
 #endif
-    default: // I2S_CLK_SRC_PLL_160M
-        return esp_clk_apb_freq() * 2;
+#if SOC_I2S_SUPPORTS_PLL_F160M
+    case I2S_CLK_SRC_PLL_160M:
+        (void)mclk_freq_hz;
+        return I2S_LL_PLL_F160M_CLK_FREQ;
+#endif
+#if SOC_I2S_SUPPORTS_PLL_F96M
+    case I2S_CLK_SRC_PLL_96M:
+        (void)mclk_freq_hz;
+        return I2S_LL_PLL_F96M_CLK_FREQ;
+#endif
+    default:
+        // Invalid clock source
+        return 0;
     }
 }
 

+ 0 - 2
components/driver/test/test_ledc.c

@@ -535,10 +535,8 @@ TEST_CASE("LEDC timer select specific clock source", "[ledc]")
     TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
 
     if (test_speed_mode == LEDC_LOW_SPEED_MODE) {
-#if !CONFIG_IDF_TARGET_ESP32C6 // Temporary. RC_FAST not able to calibrate currently. Can be removed once IDF-5346 done.
         printf("Check LEDC_USE_RTC8M_CLK for a 100Hz signal\n");
         timer_set_clk_src_and_freq_test(test_speed_mode, LEDC_USE_RTC8M_CLK, 10, 100);
-#endif
 #if SOC_LEDC_SUPPORT_XTAL_CLOCK
         printf("Check LEDC_USE_XTAL_CLK for a 400Hz signal\n");
         timer_set_clk_src_and_freq_test(test_speed_mode, LEDC_USE_XTAL_CLK, 13, 400);

+ 8 - 0
components/driver/test_apps/gpio/main/test_gpio_filter.c

@@ -123,6 +123,10 @@ TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]")
 
     printf("generate rising edge glitch signal\r\n");
     asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
+    asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
+    asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
+    asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
+
     asm volatile("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
 
     // should timeout, because the glitch is filtered out
@@ -133,6 +137,10 @@ TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]")
 
     printf("generate rising edge glitch signal again\r\n");
     asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
+    asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
+    asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
+    asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
+
     asm volatile("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
 
     // this time we should see the GPIO interrupt fired up

+ 5 - 0
components/esp_hw_support/esp_clk.c

@@ -71,7 +71,12 @@ 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
+    return rtc_clk_apb_freq_get();
+#else
     return MIN(s_get_cpu_freq_mhz() * MHZ, APB_CLK_FREQ);
+#endif
 }
 
 int IRAM_ATTR esp_clk_xtal_freq(void)

+ 1 - 1
components/esp_hw_support/port/esp32c2/rtc_init.c

@@ -167,7 +167,7 @@ static void calibrate_ocode(void)
     soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
     rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
     if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
-        cal_clk = RTC_CAL_EXT_32K;
+        cal_clk = RTC_CAL_32K_OSC_SLOW;
     } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
         cal_clk  = RTC_CAL_8MD256;
     }

+ 5 - 5
components/esp_hw_support/port/esp32c2/rtc_time.c

@@ -40,14 +40,14 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
     if (cal_clk == RTC_CAL_RTC_MUX) {
         soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
         if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
-            cal_clk = RTC_CAL_EXT_32K;
+            cal_clk = RTC_CAL_32K_OSC_SLOW;
         } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
             cal_clk = RTC_CAL_8MD256;
         }
     }
     /* Enable requested clock (150k clock is always on) */
     bool dig_ext_clk_enabled = clk_ll_xtal32k_digi_is_enabled();
-    if (cal_clk == RTC_CAL_EXT_32K && !dig_ext_clk_enabled) {
+    if (cal_clk == RTC_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) {
         clk_ll_xtal32k_digi_enable();
     }
 
@@ -78,7 +78,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
 
     /* Set timeout reg and expect time delay*/
     uint32_t expected_freq;
-    if (cal_clk == RTC_CAL_EXT_32K) {
+    if (cal_clk == RTC_CAL_32K_OSC_SLOW) {
         REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
         expected_freq = SOC_CLK_OSC_SLOW_FREQ_APPROX;
     } else if (cal_clk == RTC_CAL_8MD256) {
@@ -109,7 +109,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
     CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
 
     /* if dig_ext_clk was originally off and enabled due to calibration, then set back to off state */
-    if (cal_clk == RTC_CAL_EXT_32K && !dig_ext_clk_enabled) {
+    if (cal_clk == RTC_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) {
         clk_ll_xtal32k_digi_disable();
     }
 
@@ -141,7 +141,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
     rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
     uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
 
-    if ((cal_clk == RTC_CAL_EXT_32K) && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
+    if ((cal_clk == RTC_CAL_32K_OSC_SLOW) && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
         return 0;
     }
 

+ 1 - 1
components/esp_hw_support/port/esp32c3/rtc_clk.c

@@ -238,8 +238,8 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
         div = clk_ll_cpu_get_divider();
         source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
         freq_mhz = source_freq_mhz / div;
+        break;
     }
-    break;
     case SOC_CPU_CLK_SRC_PLL: {
         freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
         source_freq_mhz = clk_ll_bbpll_get_freq_mhz();

+ 1 - 1
components/esp_hw_support/port/esp32c6/CMakeLists.txt

@@ -1,6 +1,6 @@
 set(srcs "rtc_clk_init.c"
          "rtc_clk.c"
-        #  "rtc_init.c" // TODO: IDF-5645
+         "rtc_init.c"
         #  "rtc_pm.c" // TODO: IDF-5645
         #  "rtc_sleep.c" // TODO: IDF-5645
          "rtc_time.c"

+ 2 - 3
components/esp_hw_support/port/esp32c6/Kconfig.rtc

@@ -1,5 +1,4 @@
 choice RTC_CLK_SRC
-    # TODO: IDF-5346
     prompt "RTC clock source"
     default RTC_CLK_SRC_INT_RC
     help
@@ -13,8 +12,8 @@ choice RTC_CLK_SRC
     config RTC_CLK_SRC_EXT_OSC
         bool "External 32kHz oscillator at 32K_XP pin"
         select ESP_SYSTEM_RTC_EXT_OSC
-    config RTC_CLK_SRC_INT_8MD256
-        bool "Internal 17.5MHz oscillator, divided by 256"
+    config RTC_CLK_SRC_INT_RC32K
+        bool "Internal 32kHz RC oscillator"
 endchoice
 
 config RTC_CLK_CAL_CYCLES

+ 230 - 88
components/esp_hw_support/port/esp32c6/rtc_clk.c

@@ -15,98 +15,147 @@
 #include "soc/rtc.h"
 #include "esp_hw_log.h"
 #include "esp_rom_sys.h"
-#include "hal/usb_serial_jtag_ll.h"
 #include "hal/clk_tree_ll.h"
 #include "hal/regi2c_ctrl_ll.h"
-#include "soc/lp_clkrst_reg.h"
+#include "soc/io_mux_reg.h"
+#include "soc/lp_aon_reg.h"
 
 static const char *TAG = "rtc_clk";
 
+// Current PLL frequency, in 480MHz. Zero if PLL is not enabled.
+static int s_cur_pll_freq;
+
 void rtc_clk_32k_enable(bool enable)
 {
-    // TODO: IDF-5645
+    if (enable) {
+        clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL);
+    } else {
+        clk_ll_xtal32k_disable();
+    }
 }
 
 void rtc_clk_32k_enable_external(void)
 {
-    // TODO: IDF-5645
+    // EXT_OSC_SLOW_GPIO_NUM == GPIO_NUM_0
+    PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG);
+    REG_SET_BIT(LP_AON_GPIO_HOLD0_REG, BIT(EXT_OSC_SLOW_GPIO_NUM));
+    clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
 }
 
 void rtc_clk_32k_bootstrap(uint32_t cycle)
 {
-    // TODO: IDF-5645
+    /* No special bootstrapping needed for ESP32-C6, 'cycle' argument is to keep the signature
+     * same as for the ESP32. Just enable the XTAL here.
+     */
+    (void)cycle;
+    rtc_clk_32k_enable(true);
 }
 
 bool rtc_clk_32k_enabled(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    return clk_ll_xtal32k_is_enabled();
 }
 
-void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
+void rtc_clk_rc32k_enable(bool enable)
 {
-    // TODO: IDF-5645
+    if (enable) {
+        clk_ll_rc32k_enable();
+        esp_rom_delay_us(SOC_DELAY_RC32K_ENABLE);
+    } else {
+        clk_ll_rc32k_disable();
+    }
 }
 
-bool rtc_clk_8m_enabled(void)
+void rtc_clk_8m_enable(bool clk_8m_en)
 {
-    // TODO: IDF-5645
-    return 0;
+    if (clk_8m_en) {
+        clk_ll_rc_fast_enable();
+        esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
+    } else {
+        clk_ll_rc_fast_disable();
+    }
 }
 
-bool rtc_clk_8md256_enabled(void)
+bool rtc_clk_8m_enabled(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    return clk_ll_rc_fast_is_enabled();
 }
 
 void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
 {
-    // TODO: IDF-5645
+    clk_ll_rtc_slow_set_src(clk_src);
+    esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
 }
 
 soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
 {
-    // TODO: IDF-5645
-    return REG_GET_FIELD(LP_CLKRST_LP_CLK_CONF_REG, LP_CLKRST_SLOW_CLK_SEL);
+    return clk_ll_rtc_slow_get_src();
 }
 
 uint32_t rtc_clk_slow_freq_get_hz(void)
 {
-    // TODO: IDF-5645
-    switch (rtc_clk_slow_freq_get()) {
-        case RTC_SLOW_FREQ_RTC: return RTC_SLOW_CLK_FREQ_150K;
-        case RTC_SLOW_FREQ_32K_XTAL: return RTC_SLOW_CLK_FREQ_32K;
-        case RTC_SLOW_FREQ_8MD256: return RTC_SLOW_CLK_FREQ_8MD256;
-        default: return 0;
+    switch (rtc_clk_slow_src_get()) {
+    case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
+    case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
+    case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX;
+    case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX;
+    default: return 0;
     }
 }
 
 void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
 {
-    // TODO: IDF-5645
+    clk_ll_rtc_fast_set_src(clk_src);
+    esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
 }
 
 soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    return clk_ll_rtc_fast_get_src();
 }
 
-#if 0
 static void rtc_clk_bbpll_disable(void)
 {
-    // TODO: IDF-5645
+    clk_ll_bbpll_disable();
+    s_cur_pll_freq = 0;
 }
 
 static void rtc_clk_bbpll_enable(void)
 {
-    // TODO: IDF-5645
+    clk_ll_bbpll_enable();
 }
 
 static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
 {
-    // TODO: IDF-5645
+    /* Digital part */
+    clk_ll_bbpll_set_freq_mhz(pll_freq);
+    /* Analog part */
+    /* BBPLL CALIBRATION START */
+    regi2c_ctrl_ll_bbpll_calibration_start();
+    clk_ll_bbpll_set_config(pll_freq, xtal_freq);
+    /* WAIT CALIBRATION DONE */
+    while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
+    /* BBPLL CALIBRATION STOP */
+    regi2c_ctrl_ll_bbpll_calibration_stop();
+
+    s_cur_pll_freq = pll_freq;
+}
+
+/**
+ * Switch to XTAL frequency. Does not disable the PLL.
+ */
+static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
+{
+    clk_ll_cpu_set_ls_divider(div);
+    clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
+    ets_update_cpu_frequency(freq);
+}
+
+static void rtc_clk_cpu_freq_to_8m(void)
+{
+    clk_ll_cpu_set_ls_divider(1);
+    clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
+    ets_update_cpu_frequency(20);
 }
 
 /**
@@ -116,109 +165,202 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
  */
 static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
 {
-    // TODO: IDF-5645
+    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);
+    ets_update_cpu_frequency(cpu_freq_mhz);
 }
-#endif
 
 bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
 {
-    // TODO: IDF-5645
-    return 0;
+    uint32_t source_freq_mhz;
+    soc_cpu_clk_src_t source;
+    uint32_t divider; // divider = freq of SOC_ROOT_CLK / freq of CPU_CLK
+    uint32_t real_freq_mhz;
+
+    uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
+    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) {
+            // no suitable divider
+            return false;
+        }
+
+        source_freq_mhz = xtal_freq;
+        source = SOC_CPU_CLK_SRC_XTAL;
+    } else if (freq_mhz == 80) {
+        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;
+    } 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;
+    } else {
+        // unsupported frequency
+        return false;
+    }
+    *out_config = (rtc_cpu_freq_config_t) {
+        .source = source,
+        .div = divider,
+        .source_freq_mhz = source_freq_mhz,
+        .freq_mhz = real_freq_mhz
+    };
+    return true;
 }
 
 void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
 {
-    // TODO: IDF-5645
+    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) {
+            rtc_clk_bbpll_disable();
+        }
+    } else if (config->source == SOC_CPU_CLK_SRC_PLL) {
+        if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) {
+            rtc_clk_bbpll_enable();
+            rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
+        }
+        rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
+    } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
+        rtc_clk_cpu_freq_to_8m();
+        if (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) {
+            rtc_clk_bbpll_disable();
+        }
+    }
 }
 
 void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
 {
-    // TODO: IDF-5645
+    soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
+    uint32_t source_freq_mhz;
+    uint32_t div; // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
+    uint32_t freq_mhz;
+    switch (source) {
+    case SOC_CPU_CLK_SRC_XTAL: {
+        div = clk_ll_cpu_get_ls_divider();
+        source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
+        freq_mhz = source_freq_mhz / div;
+        break;
+    }
+    case SOC_CPU_CLK_SRC_PLL: {
+        div = clk_ll_cpu_get_hs_divider();
+        source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
+        freq_mhz = source_freq_mhz / div;
+        break;
+    }
+    case SOC_CPU_CLK_SRC_RC_FAST:
+        div = clk_ll_cpu_get_ls_divider();
+        source_freq_mhz = 20;
+        freq_mhz = source_freq_mhz / div;
+        break;
+    default:
+        ESP_HW_LOGE(TAG, "unsupported frequency configuration");
+        abort();
+    }
+    *out_config = (rtc_cpu_freq_config_t) {
+        .source = source,
+        .source_freq_mhz = source_freq_mhz,
+        .div = div,
+        .freq_mhz = freq_mhz
+    };
 }
 
 void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
 {
-    // TODO: IDF-5645
+    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_RC_FAST) {
+        rtc_clk_cpu_freq_to_8m();
+    } else {
+        /* fallback */
+        rtc_clk_cpu_freq_set_config(config);
+    }
 }
 
 void rtc_clk_cpu_freq_set_xtal(void)
 {
-    ESP_EARLY_LOGW(TAG, "rtc_clk_cpu_freq_set_xtal() has not been implemented yet");
-    // TODO: IDF-5645
-}
-
-#if 0
-/**
- * Switch to XTAL frequency. Does not disable the PLL.
- */
-static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
-{
-    // TODO: IDF-5645
-}
+    int freq_mhz = (int)rtc_clk_xtal_freq_get();
 
-static void rtc_clk_cpu_freq_to_8m(void)
-{
-    // TODO: IDF-5645
+    rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
+    rtc_clk_bbpll_disable();
 }
-#endif
 
 rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
 {
-    ESP_EARLY_LOGW(TAG, "rtc_clk_xtal_freq_get() has not been implemented yet");
-    // TODO: IDF-5645
-    return 40;
+    uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
+    if (xtal_freq_mhz == 0) {
+        ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
+        return RTC_XTAL_FREQ_40M;
+    }
+    return (rtc_xtal_freq_t)xtal_freq_mhz;
 }
 
 void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
 {
-    // TODO: IDF-5645
-}
-
-void rtc_clk_apb_freq_update(uint32_t apb_freq)
-{
-    // TODO: IDF-5645
+    clk_ll_xtal_store_freq_mhz(xtal_freq);
+}
+
+static uint32_t rtc_clk_ahb_freq_get(void)
+{
+    soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
+    uint32_t soc_root_freq_mhz;
+    uint32_t divider;
+    switch (source) {
+    case SOC_CPU_CLK_SRC_XTAL:
+        soc_root_freq_mhz = rtc_clk_xtal_freq_get();
+        divider = clk_ll_ahb_get_ls_divider();
+        break;
+    case SOC_CPU_CLK_SRC_PLL:
+        soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz();
+        divider = clk_ll_ahb_get_hs_divider();
+        break;
+    case SOC_CPU_CLK_SRC_RC_FAST:
+        soc_root_freq_mhz = 20;
+        divider = clk_ll_ahb_get_ls_divider();
+        break;
+    default:
+        // Unknown SOC_ROOT clock source
+        soc_root_freq_mhz = 0;
+        divider = 1;
+        ESP_HW_LOGE(TAG, "Invalid SOC_ROOT_CLK");
+        break;
+    }
+    return soc_root_freq_mhz / divider;
 }
 
 uint32_t rtc_clk_apb_freq_get(void)
 {
-    ESP_EARLY_LOGW(TAG, "rtc_clk_apb_freq_get() has not been implemented yet");
-    // TODO: IDF-5645
-    return 0;
-}
-
-void rtc_clk_divider_set(uint32_t div)
-{
-    // TODO: IDF-5645
-}
-
-void rtc_clk_8m_divider_set(uint32_t div)
-{
-    // TODO: IDF-5645
+    return rtc_clk_ahb_freq_get() / clk_ll_apb_get_divider() * MHZ;
 }
 
 void rtc_dig_clk8m_enable(void)
 {
-    // TODO: IDF-5645
+    clk_ll_rc_fast_digi_enable();
+    esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
 }
 
 void rtc_dig_clk8m_disable(void)
 {
-    // TODO: IDF-5645
+    clk_ll_rc_fast_digi_disable();
+    esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
 }
 
 bool rtc_dig_8m_enabled(void)
 {
-    // TODO: IDF-5645
-    return 0;
-}
-
-#if 0
-static bool rtc_clk_set_bbpll_always_on(void)
-{
-    // TODO: IDF-5645
-    return 0;
+    return clk_ll_rc_fast_digi_is_enabled();
 }
-#endif
 
 /* Name used in libphy.a:phy_chip_v7.o
  * TODO: update the library to use rtc_clk_xtal_freq_get

+ 21 - 25
components/esp_hw_support/port/esp32c6/rtc_clk_init.c

@@ -13,45 +13,41 @@
 #include "esp32c6/rom/uart.h"
 #include "soc/rtc.h"
 #include "esp_cpu.h"
-#include "hal/regi2c_ctrl_ll.h"
+#include "regi2c_ctrl.h"
+#include "soc/lp_clkrst_reg.h"
+#include "soc/regi2c_dig_reg.h"
 #include "esp_hw_log.h"
 #include "sdkconfig.h"
 #include "esp_rom_uart.h"
+#include "hal/clk_tree_ll.h"
 
 static const char *TAG = "rtc_clk_init";
 
 void rtc_clk_init(rtc_clk_config_t cfg)
 {
-    ESP_HW_LOGW(TAG, "rtc_clk_init() has not been implemented yet");
-#if 0 // TODO: IDF-5645
     rtc_cpu_freq_config_t old_config, new_config;
 
-    /* Set tuning parameters for 8M and 150k clocks.
+    /* Set tuning parameters for RC_FAST, RC_SLOW, and RC32K clocks.
      * Note: this doesn't attempt to set the clocks to precise frequencies.
      * Instead, we calibrate these clocks against XTAL frequency later, when necessary.
-     * - SCK_DCAP value controls tuning of 150k clock.
+     * - SCK_DCAP value controls tuning of RC_SLOW clock.
      *   The higher the value of DCAP is, the lower is the frequency.
-     * - CK8M_DFREQ value controls tuning of 8M clock.
+     * - CK8M_DFREQ value controls tuning of RC_FAST clock.
      *   CLK_8M_DFREQ constant gives the best temperature characteristics.
+     * - RC32K_DFREQ value controls tuning of RC32K clock.
      */
-    REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, cfg.slow_clk_dcap);
-    REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, cfg.clk_8m_dfreq);
-
-    /* Configure 150k clock division */
-    rtc_clk_divider_set(cfg.clk_rtc_clk_div);
-
-    /* Configure 8M clock division */
-    rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
-
-    /* Reset (disable) i2c internal bus for all regi2c registers */
-    regi2c_ctrl_ll_i2c_reset(); // TODO: This should be move out from rtc_clk_init
-    /* Enable the internal bus used to configure BBPLL */
-    regi2c_ctrl_ll_i2c_bbpll_enable(); // TODO: This should be moved to bbpll_set_config
+    REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq);
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, cfg.slow_clk_dcap);
+    REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq);
 
     rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
     esp_rom_uart_tx_wait_idle(0);
     rtc_clk_xtal_freq_update(xtal_freq);
-    rtc_clk_apb_freq_update(xtal_freq * MHZ);
+
+    // On ESP32C6, 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);
 
     /* Set CPU frequency */
     rtc_clk_cpu_freq_get_config(&old_config);
@@ -70,14 +66,14 @@ void rtc_clk_init(rtc_clk_config_t cfg)
     // We will not power off RC_FAST in bootloader stage even if it is not being used as any
     // cpu / rtc_fast / rtc_slow clock sources, this is because RNG always needs it in the bootloader stage.
     bool need_rc_fast_en = true;
-    bool need_rc_fast_d256_en = false;
     if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
         rtc_clk_32k_enable(true);
-    } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
-        need_rc_fast_d256_en = true;
+    } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
+        rtc_clk_32k_enable_external();
+    } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
+       rtc_clk_rc32k_enable(true);
     }
-    rtc_clk_8m_enable(need_rc_fast_en, need_rc_fast_d256_en);
+    rtc_clk_8m_enable(need_rc_fast_en);
     rtc_clk_fast_src_set(cfg.fast_clk_src);
     rtc_clk_slow_src_set(cfg.slow_clk_src);
-#endif
 }

+ 18 - 1
components/esp_hw_support/port/esp32c6/rtc_init.c

@@ -4,4 +4,21 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
-// TODO: IDF-5645
+#include "soc/rtc.h"
+#include "soc/pmu_reg.h"
+#include "soc/regi2c_dig_reg.h"
+#include "regi2c_ctrl.h"
+
+// TODO: IDF-5781
+
+void rtc_init(rtc_config_t cfg)
+{
+    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);
+    REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 25);
+    REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, 26);
+}

+ 173 - 34
components/esp_hw_support/port/esp32c6/rtc_time.c

@@ -7,10 +7,13 @@
 #include <stdint.h>
 #include "esp32c6/rom/ets_sys.h"
 #include "soc/rtc.h"
-// #include "soc/rtc_cntl_reg.h"
+#include "soc/lp_timer_reg.h"
 #include "hal/clk_tree_ll.h"
 #include "soc/timer_group_reg.h"
 #include "esp_rom_sys.h"
+#include "assert.h"
+
+static const char *TAG = "rtc_time";
 
 /* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
  * This feature counts the number of XTAL clock cycles within a given number of
@@ -24,55 +27,189 @@
  * enabled using TIMG_RTC_CALI_START bit.
  */
 
-/**
- * @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
- * @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
+/* On ESP32C6, 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
  */
-// TODO: IDF-5645
-static const char *TAG = "rtc_time";
+#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
 
 uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
 {
-    // TODO: IDF-5645
-    ESP_EARLY_LOGW(TAG, "rtc_clk_cal_internal() has not been implemented yet");
-    return 0;
+    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;
+    }
+    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);
+    }
+
+
+    /* 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 orignally was disabled, and set back to the disable state after calibration is done
+    // If the clock is already on, then do nothing
+    bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
+    if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
+            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 rc32k_enabled = clk_ll_rc32k_is_enabled();
+    bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
+    if (cal_clk == RTC_CAL_RC32K) {
+        if (!rc32k_enabled) {
+            rtc_clk_rc32k_enable(true);
+        }
+        if (!dig_rc32k_enabled) {
+            clk_ll_rc32k_digi_enable();
+        }
+    }
+
+    /* There may be another calibration process already running during we call this function,
+     * so we should wait the last process is done.
+     */
+    if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) {
+        /**
+         * Set a small timeout threshold to accelerate the generation of timeout.
+         * The internal circuit will be reset when the timeout occurs and will not affect the next calibration.
+         */
+        REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1);
+        while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)
+               && !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT));
+    }
+
+    /* Prepare calibration */
+    REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
+    CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
+    REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
+    /* Figure out how long to wait for calibration to finish */
+
+    /* Set timeout reg and expect time delay*/
+    uint32_t expected_freq;
+    if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) {
+        REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles));
+        expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
+    } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
+        REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles));
+        expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
+    } else {
+        REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
+        expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
+    }
+    uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
+    /* Start calibration */
+    CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
+    SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
+
+    /* Wait for calibration to finish up to another us_time_estimate */
+    esp_rom_delay_us(us_time_estimate);
+    uint32_t cal_val;
+    while (true) {
+        if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
+            cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
+            break;
+        }
+        if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
+            cal_val = 0;
+            break;
+        }
+    }
+    CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
+
+    /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
+    if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
+        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_RC32K) {
+        if (!dig_rc32k_enabled) {
+            clk_ll_rc32k_digi_disable();
+        }
+        if (!rc32k_enabled) {
+            rtc_clk_rc32k_enable(false);
+        }
+    }
+
+    // Always set back the calibration 32kHz clock selection
+    if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) {
+        clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel);
+    }
+
+    return cal_val;
 }
 
-uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
+static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles)
 {
-    // TODO: IDF-5645
-    ESP_EARLY_LOGW(TAG, "rtc_clk_cal_ratio() has not been implemented yet");
-    return 0;
+    uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768
+    uint64_t delta = expected_xtal_cycles / 2000;                                    // 5/10000 = 0.05% error range
+    return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta));
 }
 
 uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
 {
-    // TODO: IDF-5645
-    ESP_EARLY_LOGW(TAG, "rtc_clk_cal() has not been implemented yet");
-    return 0;
+    rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
+    uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
+
+    if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
+        return 0;
+    }
+
+    uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles;
+    uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider;
+    uint32_t period = (uint32_t)(period_64 & UINT32_MAX);
+    return period;
 }
 
 uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
 {
-    // TODO: IDF-5645
-    ESP_EARLY_LOGW(TAG, "rtc_time_us_to_slowclk() has not been implemented yet");
-    return 0;
+    /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
+     * TODO: fix overflow.
+     */
+    return (time_in_us << RTC_CLK_CAL_FRACT) / period;
 }
 
 uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
 {
-    // TODO: IDF-5645
-    ESP_EARLY_LOGW(TAG, "rtc_time_slowclk_to_us() has not been implemented yet");
-    return 0;
+    return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT;
 }
 
 uint64_t rtc_time_get(void)
 {
-    // TODO: IDF-5645
-    ESP_EARLY_LOGW(TAG, "rtc_time_get() has not been implemented yet");
-    return 0;
+    SET_PERI_REG_MASK(LP_TIMER_UPDATE_REG, LP_TIMER_MAIN_TIMER_UPDATE);
+    uint64_t t = READ_PERI_REG(LP_TIMER_MAIN_BUF0_LOW_REG);
+    t |= ((uint64_t) READ_PERI_REG(LP_TIMER_MAIN_BUF0_HIGH_REG)) << 32;
+    return t;
 }
 
 uint64_t rtc_light_slp_time_get(void)
@@ -84,20 +221,22 @@ uint64_t rtc_light_slp_time_get(void)
 
 uint64_t rtc_deep_slp_time_get(void)
 {
-    // TODO: IDF-5645
-    ESP_EARLY_LOGW(TAG, "rtc_deep_slp_time_get() has not been implemented yet");
-    return 0;
+    uint64_t t_slp = READ_PERI_REG(LP_TIMER_MAIN_BUF1_LOW_REG);
+    t_slp |= ((uint64_t) READ_PERI_REG(LP_TIMER_MAIN_BUF1_HIGH_REG)) << 32;
+    uint64_t t_wake = rtc_time_get();
+    return (t_wake - t_slp);
 }
 
 void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more
 {
-    // TODO: IDF-5645
+    // TODO: IDF-5781
     ESP_EARLY_LOGW(TAG, "rtc_clk_wait_for_slow_cycle() has not been implemented yet");
 }
 
 uint32_t rtc_clk_freq_cal(uint32_t cal_val)
 {
-    // TODO: IDF-5645
-    ESP_EARLY_LOGW(TAG, "rtc_clk_freq_cal() has not been implemented yet");
-    return 0;
+    if (cal_val == 0) {
+        return 0;   // cal_val will be denominator, return 0 as the symbol of failure.
+    }
+    return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
 }

+ 2 - 2
components/esp_hw_support/rtc_module.c

@@ -101,7 +101,7 @@ out:
 esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, uint32_t rtc_intr_mask, uint32_t flags)
 {
 #if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5645
-    ESP_LOGW(TAG, "rtc_isr_register() has not been implemented yet");
+    ESP_EARLY_LOGW(TAG, "rtc_isr_register() has not been implemented yet");
     return ESP_OK;
 #else
     esp_err_t err = rtc_isr_ensure_installed();
@@ -132,7 +132,7 @@ esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, uint32_t r
 esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg)
 {
 #if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5645
-    ESP_LOGW(TAG, "rtc_isr_deregister() has not been implemented yet");
+    ESP_EARLY_LOGW(TAG, "rtc_isr_deregister() has not been implemented yet");
     return ESP_OK;
 #else
     rtc_isr_handler_t* it;

+ 3 - 3
components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c

@@ -83,7 +83,7 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]")
     CALIBRATE_ONE(RTC_CAL_8MD256);
 
 #if CONFIG_IDF_TARGET_ESP32C2
-    uint32_t cal_ext_slow_clk = CALIBRATE_ONE(RTC_CAL_EXT_32K);
+    uint32_t cal_ext_slow_clk = CALIBRATE_ONE(RTC_CAL_32K_OSC_SLOW);
     if (cal_ext_slow_clk == 0) {
         printf("EXT CLOCK by PIN has not started up");
     } else {
@@ -93,7 +93,7 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]")
 
         CALIBRATE_ONE(RTC_CAL_RTC_MUX);
         CALIBRATE_ONE(RTC_CAL_8MD256);
-        CALIBRATE_ONE(RTC_CAL_EXT_32K);
+        CALIBRATE_ONE(RTC_CAL_32K_OSC_SLOW);
     }
 #else
     uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL);
@@ -116,7 +116,7 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]")
     CALIBRATE_ONE(RTC_CAL_RTC_MUX);
     CALIBRATE_ONE(RTC_CAL_8MD256);
 #if CONFIG_IDF_TARGET_ESP32C2
-    CALIBRATE_ONE(RTC_CAL_EXT_32K);
+    CALIBRATE_ONE(RTC_CAL_32K_OSC_SLOW);
 #else
     CALIBRATE_ONE(RTC_CAL_32K_XTAL);
 #endif

+ 0 - 138
components/esp_rom/esp32c6/ld/esp32c6.rom.eco3.ld

@@ -1,138 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-/*
-ESP32C6 ECO3 ROM address table
-Version 3 API's imported from the ROM
-*/
-
-esf_buf_alloc_dynamic = 0x400015c0;
-esf_buf_recycle = 0x400015c4;
-/*lmacTxDone = 0x4000162c;*/
-/*ppMapTxQueue = 0x400016d8;*/
-rcGetSched = 0x40001764;
-wDevCheckBlockError = 0x400017b4;
-/*ppProcTxDone = 0x40001804;*/
-sta_input = rom_sta_input;
-
-/***************************************
- Group rom_phy
- ***************************************/
-
-/* Functions */
-rom_index_to_txbbgain = 0x40001964;
-rom_pbus_xpd_tx_on = 0x400019b0;
-rom_set_tx_dig_gain = 0x400019f0;
-rom_set_txcap_reg = 0x400019f4;
-rom_txbbgain_to_index = 0x40001a0c;
-rom_agc_reg_init = 0x40001a54;
-rom_bb_reg_init = 0x40001a58;
-rom_set_pbus_reg = 0x40001a70;
-rom_phy_xpd_rf = 0x40001a78;
-rom_write_txrate_power_offset = 0x40001a8c;
-rom_temp_to_power = 0x40001ab4;
-rom_open_i2c_xpd = 0x40001af8;
-rom_tsens_read_init = 0x40001b00;
-rom_tsens_code_read = 0x40001b04;
-rom_tsens_dac_cal = 0x40001b10;
-rom_pll_vol_cal = 0x40001b28;
-
-/***************************************
-   Group eco3_wifi
- ***************************************/
-
-/* Functions */
-wdev_is_data_in_rxlist = 0x40001b2c;
-ppProcTxCallback = 0x40001b30;
-ieee80211_gettid = 0x40001b34;
-
-
-/***************************************
-   Group eco3_bluetooth
- ***************************************/
-
-/* Functions */
-r_lld_legacy_adv_dynamic_pti_get = 0x40001b38;
-r_lld_legacy_adv_dynamic_pti_process = 0x40001b3c;
-r_lld_ext_adv_dynamic_pti_get = 0x40001b40;
-r_lld_ext_adv_dynamic_aux_pti_process = 0x40001b44;
-r_lld_ext_adv_dynamic_pti_process = 0x40001b48;
-r_lld_adv_ext_pkt_prepare_set = 0x40001b4c;
-r_lld_adv_ext_chain_none_construct = 0x40001b50;
-r_lld_adv_ext_chain_connectable_construct = 0x40001b54;
-r_lld_adv_ext_chain_scannable_construct = 0x40001b58;
-r_lld_adv_pkt_rx_connect_post = 0x40001b5c;
-r_lld_adv_start_init_evt_param = 0x40001b60;
-r_lld_adv_start_set_cs = 0x40001b64;
-r_lld_adv_start_update_filter_policy = 0x40001b68;
-r_lld_adv_start_schedule_asap = 0x40001b6c;
-r_lld_con_tx_prog_new_packet_coex = 0x40001b70;
-r_lld_con_tx_prog_new_packet = 0x40001b74;
-r_lld_per_adv_dynamic_pti_get = 0x40001b78;
-r_lld_per_adv_evt_start_chm_upd = 0x40001b7c;
-r_lld_ext_scan_dynamic_pti_get = 0x40001b80;
-r_lld_scan_try_sched = 0x40001b84;
-r_lld_sync_insert = 0x40001b88;
-r_sch_prog_ble_push = 0x40001b8c;
-r_sch_prog_bt_push = 0x40001b90;
-r_lld_init_evt_end_type_set = 0x40001b94;
-r_lld_init_evt_end_type_get = 0x40001b98;
-r_lld_adv_direct_adv_use_rpa_addr_state_set = 0x40001b9c;
-r_lld_adv_direct_adv_use_rpa_addr_state_get = 0x40001ba0;
-r_lld_init_evt_end_type_check_state_set = 0x40001ba4;
-r_lld_init_evt_end_type_check_state_get = 0x40001ba8;
-
-
-/***************************************
-   Group eco3_phy
- ***************************************/
-
-/* Functions */
-rom_wrtie_pll_cap = 0x40001bac;
-rom_set_tx_gain_mem = 0x40001bb0;
-rom_bt_tx_dig_gain = 0x40001bb4;
-rom_bt_get_tx_gain = 0x40001bb8;
-rom_get_chan_target_power = 0x40001bbc;
-rom_get_tx_gain_value = 0x40001bc0;
-rom_wifi_tx_dig_gain = 0x40001bc4;
-rom_wifi_get_tx_gain = 0x40001bc8;
-rom_fe_i2c_reg_renew = 0x40001bcc;
-rom_wifi_agc_sat_gain = 0x40001bd0;
-rom_i2c_master_reset = 0x40001bd4;
-rom_bt_filter_reg = 0x40001bd8;
-rom_phy_bbpll_cal = 0x40001bdc;
-rom_i2c_sar2_init_code = 0x40001be0;
-rom_phy_param_addr = 0x40001be4;
-rom_phy_reg_init = 0x40001be8;
-rom_set_chan_reg = 0x40001bec;
-rom_phy_wakeup_init = 0x40001bf0;
-rom_phy_i2c_init1 = 0x40001bf4;
-rom_tsens_temp_read = 0x40001bf8;
-rom_bt_track_pll_cap = 0x40001bfc;
-rom_wifi_track_pll_cap = 0x40001c00;
-rom_wifi_set_tx_gain = 0x40001c04;
-rom_txpwr_cal_track = 0x40001c08;
-rom_tx_pwctrl_background = 0x40001c0c;
-rom_bt_set_tx_gain = 0x40001c10;
-rom_noise_check_loop = 0x40001c14;
-rom_phy_close_rf = 0x40001c18;
-rom_phy_xpd_tsens = 0x40001c1c;
-rom_phy_freq_mem_backup = 0x40001c20;
-rom_phy_ant_init = 0x40001c24;
-rom_bt_track_tx_power = 0x40001c28;
-rom_wifi_track_tx_power = 0x40001c2c;
-rom_phy_dig_reg_backup = 0x40001c30;
-chip726_phyrom_version_num = 0x40001c34;
-/* Data (.data, .bss, .rodata) */
-phy_param_rom = 0x3fcdf830;
-
-/***************************************
-   Group eco3_esp_flash
- ***************************************/
-
-/* Functions */
-PROVIDE( esp_flash_read_chip_id = 0x40001c38 );
-PROVIDE( detect_spi_flash_chip = 0x40001c3c );
-PROVIDE( esp_rom_spiflash_write_disable = 0x40001c40 );

+ 1 - 1
components/esp_system/port/soc/esp32c2/clk.c

@@ -149,7 +149,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
 
             // When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
             if (SLOW_CLK_CAL_CYCLES > 0) {
-                cal_val = rtc_clk_cal(RTC_CAL_EXT_32K, SLOW_CLK_CAL_CYCLES);
+                cal_val = rtc_clk_cal(RTC_CAL_32K_OSC_SLOW, SLOW_CLK_CAL_CYCLES);
                 if (cal_val == 0) {
                     if (retry_ext_clk-- > 0) {
                         continue;

+ 3 - 0
components/esp_system/port/soc/esp32c6/Kconfig.cpu

@@ -10,6 +10,8 @@ choice ESP_DEFAULT_CPU_FREQ_MHZ
         depends on IDF_ENV_FPGA
     config ESP_DEFAULT_CPU_FREQ_MHZ_80
         bool "80 MHz"
+    config ESP_DEFAULT_CPU_FREQ_MHZ_120
+        bool "120 MHz"
     config ESP_DEFAULT_CPU_FREQ_MHZ_160
         bool "160 MHz"
 endchoice
@@ -18,4 +20,5 @@ config ESP_DEFAULT_CPU_FREQ_MHZ
     int
     default 40 if ESP_DEFAULT_CPU_FREQ_MHZ_40
     default 80 if ESP_DEFAULT_CPU_FREQ_MHZ_80
+    default 120 if ESP_DEFAULT_CPU_FREQ_MHZ_120
     default 160 if ESP_DEFAULT_CPU_FREQ_MHZ_160

+ 20 - 46
components/esp_system/port/soc/esp32c6/clk.c

@@ -14,7 +14,6 @@
 #include "esp_clk_internal.h"
 #include "esp32c6/rom/ets_sys.h"
 #include "esp32c6/rom/uart.h"
-// #include "soc/system_reg.h"
 #include "soc/soc.h"
 #include "soc/rtc.h"
 #include "soc/rtc_periph.h"
@@ -23,8 +22,6 @@
 #include "hal/wdt_hal.h"
 #include "esp_private/periph_ctrl.h"
 #include "esp_private/esp_clk.h"
-#include "bootloader_clock.h"
-// #include "soc/syscon_reg.h"
 #include "esp_rom_uart.h"
 #include "esp_rom_sys.h"
 
@@ -36,28 +33,7 @@
 
 #define MHZ (1000000)
 
-/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
- * The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6.
- */
-#define MIN_32K_XTAL_CAL_VAL  15000000L
-
-/* Indicates that this 32k oscillator gets input from external oscillator, rather
- * than a crystal.
- */
-#define EXT_OSC_FLAG    BIT(3)
-
-/* This is almost the same as soc_rtc_slow_clk_src_t, except that we define
- * an extra enum member for the external 32k oscillator.
- * For convenience, lower 2 bits should correspond to soc_rtc_slow_clk_src_t values.
- */
-typedef enum {
-    SLOW_CLK_RTC = SOC_RTC_SLOW_CLK_SRC_RC_SLOW,                       //!< Internal 150 kHz RC oscillator
-    SLOW_CLK_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K,                  //!< External 32 kHz XTAL
-    SLOW_CLK_8MD256 = SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256,               //!< Internal 8 MHz RC oscillator, divided by 256
-    SLOW_CLK_32K_EXT_OSC = SOC_RTC_SLOW_CLK_SRC_XTAL32K | EXT_OSC_FLAG //!< External 32k oscillator connected to 32K_XP pin
-} slow_clk_sel_t;
-
-static void select_rtc_slow_clk(slow_clk_sel_t slow_clk);
+static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src);
 
 static const char *TAG = "clk";
 
@@ -75,8 +51,7 @@ static const char *TAG = "clk";
 
     assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
 
-    bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled();
-    rtc_clk_8m_enable(true, rc_fast_d256_is_enabled);
+    rtc_clk_8m_enable(true);
     rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST);
 #endif
 
@@ -96,13 +71,13 @@ static const char *TAG = "clk";
 #endif
 
 #if defined(CONFIG_RTC_CLK_SRC_EXT_CRYS)
-    select_rtc_slow_clk(SLOW_CLK_32K_XTAL);
+    select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K);
 #elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC)
-    select_rtc_slow_clk(SLOW_CLK_32K_EXT_OSC);
-#elif defined(CONFIG_RTC_CLK_SRC_INT_8MD256)
-    select_rtc_slow_clk(SLOW_CLK_8MD256);
+    select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_OSC_SLOW);
+#elif defined(CONFIG_RTC_CLK_SRC_INT_RC32K)
+    select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC32K);
 #else
-    select_rtc_slow_clk(SLOW_CLK_RTC);
+    select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW);
 #endif
 
 #ifdef CONFIG_BOOTLOADER_WDT_ENABLE
@@ -134,11 +109,8 @@ static const char *TAG = "clk";
     esp_cpu_set_cycle_count( (uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz );
 }
 
-static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
+static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
 {
-    ESP_EARLY_LOGW(TAG, "select_rtc_slow_clk() has not been implemented yet");
-#if 0 // TODO: IDF-5645
-    soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk & RTC_CNTL_ANA_CLK_RTC_SEL_V;
     uint32_t cal_val = 0;
     /* number of times to repeat 32k XTAL calibration
      * before giving up and switching to the internal RC
@@ -146,7 +118,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
     int retry_32k_xtal = 3;
 
     do {
-        if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
+        if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K || rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
             /* 32k XTAL oscillator needs to be enabled and running before it can
              * be used. Hardware doesn't have a direct way of checking if the
              * oscillator is running. Here we use rtc_clk_cal function to count
@@ -155,24 +127,27 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
              * will time out, returning 0.
              */
             ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
-            if (slow_clk == SLOW_CLK_32K_XTAL) {
+            rtc_cal_sel_t cal_sel = 0;
+            if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
                 rtc_clk_32k_enable(true);
-            } else if (slow_clk == SLOW_CLK_32K_EXT_OSC) {
+                cal_sel = RTC_CAL_32K_XTAL;
+            } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
                 rtc_clk_32k_enable_external();
+                cal_sel = RTC_CAL_32K_OSC_SLOW;
             }
             // When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
             if (SLOW_CLK_CAL_CYCLES > 0) {
-                cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
-                if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) {
+                cal_val = rtc_clk_cal(cal_sel, SLOW_CLK_CAL_CYCLES);
+                if (cal_val == 0) {
                     if (retry_32k_xtal-- > 0) {
                         continue;
                     }
-                    ESP_EARLY_LOGW(TAG, "32 kHz XTAL not found, switching to internal 150 kHz oscillator");
+                    ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 150 kHz oscillator");
                     rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
                 }
             }
-        } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
-            rtc_clk_8m_enable(true, true);
+        } else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
+            rtc_clk_rc32k_enable(true);
         }
         rtc_clk_slow_src_set(rtc_slow_clk_src);
 
@@ -188,12 +163,11 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
     } while (cal_val == 0);
     ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %d", cal_val);
     esp_clk_slowclk_cal_set(cal_val);
-#endif
 }
 
 void rtc_clk_select_rtc_slow_clk(void)
 {
-    select_rtc_slow_clk(SLOW_CLK_32K_XTAL);
+    select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K);
 }
 
 /* This function is not exposed as an API at this point.

+ 7 - 1
components/esptool_py/Kconfig.projbuild

@@ -88,7 +88,7 @@ menu "Serial flasher config"
     choice ESPTOOLPY_FLASHFREQ
         prompt "Flash SPI speed"
         default ESPTOOLPY_FLASHFREQ_40M if IDF_TARGET_ESP32
-        default ESPTOOLPY_FLASHFREQ_80M if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3
+        default ESPTOOLPY_FLASHFREQ_80M if ESPTOOLPY_FLASHFREQ_80M_DEFAULT
         default ESPTOOLPY_FLASHFREQ_60M if IDF_TARGET_ESP32C2
         default ESPTOOLPY_FLASHFREQ_48M if IDF_TARGET_ESP32H4
         config ESPTOOLPY_FLASHFREQ_120M
@@ -124,6 +124,12 @@ menu "Serial flasher config"
             depends on SOC_MEMSPI_SRC_FREQ_15M_SUPPORTED
     endchoice
 
+    config ESPTOOLPY_FLASHFREQ_80M_DEFAULT
+        bool
+        default y if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C6
+        help
+            This is an invisible item, used to define the targets that defaults to use 80MHz Flash SPI speed.
+
     config ESPTOOLPY_FLASHFREQ
         string
         # On some of the ESP chips, max boot frequency would be equal to (or even lower than) 80m.

+ 2 - 0
components/hal/esp32/include/hal/i2s_ll.h

@@ -45,6 +45,8 @@ extern "C" {
 #define I2S_LL_TX_EVENT_MASK        I2S_LL_EVENT_TX_EOF
 #define I2S_LL_RX_EVENT_MASK        I2S_LL_EVENT_RX_EOF
 
+#define I2S_LL_PLL_F160M_CLK_FREQ   (160 * 1000000) // PLL_F160M_CLK: 160MHz
+
 /* I2S clock configuration structure */
 typedef struct {
     uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

+ 2 - 0
components/hal/esp32c3/include/hal/i2s_ll.h

@@ -32,6 +32,8 @@ extern "C" {
 #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH  (9)
 #define I2S_LL_MCLK_DIVIDER_MAX        ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
 
+#define I2S_LL_PLL_F160M_CLK_FREQ      (160 * 1000000) // PLL_F160M_CLK: 160MHz
+
 /* I2S clock configuration structure */
 typedef struct {
     uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

+ 395 - 132
components/hal/esp32c6/include/hal/clk_tree_ll.h

@@ -10,7 +10,9 @@
 #include "soc/soc.h"
 #include "soc/clk_tree_defs.h"
 #include "soc/rtc.h"
-#include "soc/pcr_reg.h"
+#include "soc/pcr_struct.h"
+#include "soc/lp_clkrst_struct.h"
+#include "soc/pmu_reg.h"
 #include "hal/regi2c_ctrl.h"
 #include "soc/regi2c_bbpll.h"
 #include "hal/assert.h"
@@ -24,9 +26,9 @@ extern "C" {
 #define MHZ                 (1000000)
 
 #define CLK_LL_PLL_80M_FREQ_MHZ    (80)
+#define CLK_LL_PLL_120M_FREQ_MHZ   (120)
 #define CLK_LL_PLL_160M_FREQ_MHZ   (160)
 
-#define CLK_LL_PLL_320M_FREQ_MHZ   (320)
 #define CLK_LL_PLL_480M_FREQ_MHZ   (480)
 
 #define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
@@ -41,7 +43,7 @@ extern "C" {
  */
 typedef enum {
     CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL,       //!< Enable the external 32kHz crystal for XTAL32K_CLK
-    CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL,      //!< Enable the external clock signal for XTAL32K_CLK
+    CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL,      //!< Enable the external clock signal for OSC_SLOW_CLK
     CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP,     //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
 } clk_ll_xtal32k_enable_mode_t;
 
@@ -60,7 +62,9 @@ typedef struct {
  */
 static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
 {
-    // TODO: IDF-5645
+    SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C |
+                        PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C);
+    SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG) ;
 }
 
 /**
@@ -68,7 +72,8 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
  */
 static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
 {
-    // TODO: IDF-5645
+    SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_BBPLL_ICG) ;
+    SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_BBPLL | PMU_TIE_LOW_XPD_BBPLL_I2C);
 }
 
 /**
@@ -78,7 +83,18 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
  */
 static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
 {
-    // TODO: IDF-5645
+    if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) {
+        // No need to configure anything for OSC_SLOW_CLK
+        return;
+    }
+    // Configure xtal32k
+    clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
+    LP_CLKRST.xtal32k.dac_xtal32k = cfg.dac;
+    LP_CLKRST.xtal32k.dres_xtal32k = cfg.dres;
+    LP_CLKRST.xtal32k.dgm_xtal32k = cfg.dgm;
+    LP_CLKRST.xtal32k.dbuf_xtal32k = cfg.dbuf;
+    // Enable xtal32k xpd
+    SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
 }
 
 /**
@@ -86,7 +102,8 @@ static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
  */
 static inline void clk_ll_xtal32k_disable(void)
 {
-    // TODO: IDF-5645
+    // Disable xtal32k xpd
+    CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
 }
 
 /**
@@ -96,70 +113,61 @@ static inline void clk_ll_xtal32k_disable(void)
  */
 static inline bool clk_ll_xtal32k_is_enabled(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K) == 1;
 }
 
 /**
- * @brief Enable the internal oscillator output for RC_FAST_CLK
+ * @brief Enable the internal oscillator output for RC32K_CLK
  */
-static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
+static inline void clk_ll_rc32k_enable(void)
 {
-    // TODO: IDF-5645
+    // Enable rc32k xpd status
+    SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
 }
 
 /**
- * @brief Disable the internal oscillator output for RC_FAST_CLK
+ * @brief Disable the internal oscillator output for RC32K_CLK
  */
-static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
+static inline void clk_ll_rc32k_disable(void)
 {
-    // TODO: IDF-5645
+    // Disable rc32k xpd status
+    CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
 }
 
 /**
- * @brief Get the state of the internal oscillator for RC_FAST_CLK
+ * @brief Get the state of the internal oscillator for RC32K_CLK
  *
  * @return True if the oscillator is enabled
  */
-static inline bool clk_ll_rc_fast_is_enabled(void)
+static inline bool clk_ll_rc32k_is_enabled(void)
 {
-    // TODO: IDF-5645
-    return 1;
+    return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K) == 1;
 }
 
 /**
- * @brief Enable the output from the internal oscillator to be passed into a configurable divider,
- * which by default divides the input clock frequency by 256. i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
- *
- * Divider values other than 256 may be configured, but this facility is not currently needed,
- * so is not exposed in the code.
- * The output of the divider, RC_FAST_D256_CLK, is referred as 8md256 or simply d256 in reg. descriptions.
+ * @brief Enable the internal oscillator output for RC_FAST_CLK
  */
-static inline void clk_ll_rc_fast_d256_enable(void)
+static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
 {
-    // TODO: IDF-5645
+    SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
 }
 
 /**
- * @brief Disable the output from the internal oscillator to be passed into a configurable divider.
- * i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
- *
- * Disabling this divider could reduce power consumption.
+ * @brief Disable the internal oscillator output for RC_FAST_CLK
  */
-static inline void clk_ll_rc_fast_d256_disable(void)
+static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
 {
-    // TODO: IDF-5645
+    CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
 }
 
 /**
- * @brief Get the state of the divider which is applied to the output from the internal oscillator (RC_FAST_CLK)
+ * @brief Get the state of the internal oscillator for RC_FAST_CLK
  *
- * @return True if the divided output is enabled
+ * @return True if the oscillator is enabled
  */
-static inline bool clk_ll_rc_fast_d256_is_enabled(void)
+static inline bool clk_ll_rc_fast_is_enabled(void)
 {
-    // TODO: IDF-5645
-    return 1;
+    return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK) == 1;
 }
 
 /**
@@ -167,7 +175,7 @@ static inline bool clk_ll_rc_fast_d256_is_enabled(void)
  */
 static inline void clk_ll_rc_fast_digi_enable(void)
 {
-    // TODO: IDF-5645
+    LP_CLKRST.clk_to_hp.icg_hp_fosc = 1;
 }
 
 /**
@@ -175,7 +183,7 @@ static inline void clk_ll_rc_fast_digi_enable(void)
  */
 static inline void clk_ll_rc_fast_digi_disable(void)
 {
-    // TODO: IDF-5645
+    LP_CLKRST.clk_to_hp.icg_hp_fosc = 0;
 }
 
 /**
@@ -185,51 +193,59 @@ static inline void clk_ll_rc_fast_digi_disable(void)
  */
 static inline bool clk_ll_rc_fast_digi_is_enabled(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    return LP_CLKRST.clk_to_hp.icg_hp_fosc;
 }
 
 /**
- * @brief Enable the digital RC_FAST_D256_CLK, which is used to support peripherals.
+ * @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
  */
-static inline void clk_ll_rc_fast_d256_digi_enable(void)
+static inline void clk_ll_xtal32k_digi_enable(void)
 {
-    // TODO: IDF-5645
+    LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 1;
 }
 
 /**
- * @brief Disable the digital RC_FAST_D256_CLK, which is used to support peripherals.
+ * @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
  */
-static inline void clk_ll_rc_fast_d256_digi_disable(void)
+static inline void clk_ll_xtal32k_digi_disable(void)
 {
-    // TODO: IDF-5645
+    LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 0;
 }
 
 /**
- * @brief Enable the digital XTAL32K_CLK, which is used to support peripherals.
+ * @brief Get the state of the digital XTAL32K_CLK
+ *
+ * @return True if the digital XTAL32K_CLK is enabled
  */
-static inline void clk_ll_xtal32k_digi_enable(void)
+static inline bool clk_ll_xtal32k_digi_is_enabled(void)
 {
-    // TODO: IDF-5645
+    return LP_CLKRST.clk_to_hp.icg_hp_xtal32k;
 }
 
 /**
- * @brief Disable the digital XTAL32K_CLK, which is used to support peripherals.
+ * @brief Enable the digital RC32K_CLK, which is used to support peripherals.
  */
-static inline void clk_ll_xtal32k_digi_disable(void)
+static inline void clk_ll_rc32k_digi_enable(void)
 {
-    // TODO: IDF-5645
+    LP_CLKRST.clk_to_hp.icg_hp_osc32k = 1;
 }
 
 /**
- * @brief Get the state of the digital XTAL32K_CLK
+ * @brief Disable the digital RC32K_CLK, which is used to support peripherals.
+ */
+static inline void clk_ll_rc32k_digi_disable(void)
+{
+    LP_CLKRST.clk_to_hp.icg_hp_osc32k = 0;
+}
+
+/**
+ * @brief Get the state of the digital RC32K_CLK
  *
- * @return True if the digital XTAL32K_CLK is enabled
+ * @return True if the digital RC32K_CLK is enabled
  */
-static inline bool clk_ll_xtal32k_digi_is_enabled(void)
+static inline bool clk_ll_rc32k_digi_is_enabled(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    return LP_CLKRST.clk_to_hp.icg_hp_osc32k;
 }
 
 /**
@@ -239,8 +255,8 @@ static inline bool clk_ll_xtal32k_digi_is_enabled(void)
  */
 static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    // The target has a fixed 480MHz SPLL
+    return CLK_LL_PLL_480M_FREQ_MHZ;
 }
 
 /**
@@ -250,7 +266,9 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(
  */
 static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
 {
-    // TODO: IDF-5645
+    // The target SPLL is fixed to 480MHz
+    // Do nothing
+    HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ);
 }
 
 /**
@@ -261,42 +279,70 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint
  */
 static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
 {
-    // TODO: IDF-5645
+    HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ);
+    uint8_t div_ref;
+    uint8_t div7_0;
+    uint8_t dr1;
+    uint8_t dr3;
+    uint8_t dchgp;
+    uint8_t dcur;
+    uint8_t dbias;
+
+    /* Configure 480M PLL */
+    switch (xtal_freq_mhz) {
+    case RTC_XTAL_FREQ_40M:
+    default:
+        div_ref = 0;
+        div7_0 = 8;
+        dr1 = 0;
+        dr3 = 0;
+        dchgp = 5;
+        dcur = 3;
+        dbias = 2;
+        break;
+    }
+    uint8_t i2c_bbpll_lref  = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
+    uint8_t i2c_bbpll_div_7_0 = div7_0;
+    uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
+    REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
+    REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
+    REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
+    REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
+    REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
+    REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
 }
 
 /**
- * @brief Select the clock source for CPU_CLK
+ * @brief Select the clock source for CPU_CLK (SOC Clock Root)
  *
  * @param in_sel One of the clock sources in soc_cpu_clk_src_t
  */
 static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
 {
-    // TODO: IDF-5645
     switch (in_sel) {
     case SOC_CPU_CLK_SRC_XTAL:
-        REG_SET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL, 0);
+        PCR.sysclk_conf.soc_clk_sel = 0;
         break;
     case SOC_CPU_CLK_SRC_PLL:
-        REG_SET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL, 1);
+        PCR.sysclk_conf.soc_clk_sel = 1;
         break;
     case SOC_CPU_CLK_SRC_RC_FAST:
-        REG_SET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL, 2);
+        PCR.sysclk_conf.soc_clk_sel = 2;
         break;
     default:
-        // Unsupported CPU_CLK mux input sel
+        // Unsupported SOC_CLK mux input sel
         abort();
     }
 }
 
 /**
- * @brief Get the clock source for CPU_CLK
+ * @brief Get the clock source for CPU_CLK (SOC Clock Root)
  *
  * @return Currently selected clock source (one of soc_cpu_clk_src_t values)
  */
 static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
 {
-    // TODO: IDF-5645
-    uint32_t clk_sel = REG_GET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL);
+    uint32_t clk_sel = PCR.sysclk_conf.soc_clk_sel;
     switch (clk_sel) {
     case 0:
         return SOC_CPU_CLK_SRC_XTAL;
@@ -311,45 +357,238 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr
 }
 
 /**
- * @brief Set CPU frequency from PLL clock
+ * @brief Set CPU_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
  *
- * @param cpu_mhz CPU frequency value, in MHz
+ * @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider.
  */
-static inline __attribute__((always_inline)) void clk_ll_cpu_set_freq_mhz_from_pll(uint32_t cpu_mhz)
+static inline __attribute__((always_inline)) void clk_ll_cpu_set_hs_divider(uint32_t divider)
 {
-    // TODO: IDF-5645
+    // 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);
+    PCR.cpu_freq_conf.cpu_hs_div_num = (divider / 3) - 1;
+
+    // 120MHz CPU freq cannot be achieved through divider, need to set force_120m
+    // This field is only valid if PCR_CPU_HS_DIV_NUM=0 and PCR_SOC_CLK_SEL=SOC_CPU_CLK_SRC_PLL
+    bool force_120m = (divider == 4) ? 1 : 0;
+    PCR.cpu_freq_conf.cpu_hs_120m_force = force_120m;
 }
 
 /**
- * @brief Get CPU_CLK frequency from PLL_CLK source
+ * @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
  *
- * @return CPU clock frequency, in MHz. Returns 0 if register field value is invalid.
+ * @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider.
  */
-static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_freq_mhz_from_pll(void)
+static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider)
 {
-    // TODO: IDF-5645
-    return 0;
+    // 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));
+    PCR.cpu_freq_conf.cpu_ls_div_num = divider - 1;
 }
 
 /**
- * @brief Set CPU_CLK's XTAL/FAST_RC clock source path divider
+ * @brief Get CPU_CLK's high-speed divider
  *
- * @param divider Divider. Usually this divider is set to 1 in bootloader stage. PRE_DIV_CNT = divider - 1.
+ * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1).
  */
-static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
+static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_divider(void)
 {
-    // TODO: IDF-5645  not configurable for 761, fixed at 3 for HS, 1 for LS
+    uint32_t force_120m = PCR.cpu_freq_conf.cpu_hs_120m_force;
+    uint32_t cpu_hs_div = PCR.cpu_freq_conf.cpu_hs_div_num;
+    if (cpu_hs_div == 0 && force_120m) {
+        return 4;
+    }
+    return (PCR.sysclk_conf.hs_div_num + 1) * (cpu_hs_div + 1);
 }
 
 /**
- * @brief Get CPU_CLK's XTAL/FAST_RC clock source path divider
+ * @brief Get CPU_CLK's low-speed divider
  *
- * @return Divider. Divider = (PRE_DIV_CNT + 1).
+ * @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1).
  */
-static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
+static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_ls_divider(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    return (PCR.sysclk_conf.ls_div_num + 1) * (PCR.cpu_freq_conf.cpu_ls_div_num + 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);
+    PCR.ahb_freq_conf.ahb_hs_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));
+    PCR.ahb_freq_conf.ahb_ls_div_num = divider - 1;
+}
+
+/**
+ * @brief Get AHB_CLK's high-speed divider
+ *
+ * @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1).
+ */
+static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_hs_divider(void)
+{
+    return (PCR.sysclk_conf.hs_div_num + 1) * (PCR.ahb_freq_conf.ahb_hs_div_num + 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)
+{
+    return (PCR.sysclk_conf.ls_div_num + 1) * (PCR.ahb_freq_conf.ahb_ls_div_num + 1);
+}
+
+/**
+ * @brief Set APB_CLK divider. freq of APB_CLK = freq of AHB_CLK / divider
+ *
+ * @param divider Divider. PCR_APB_DIV_NUM = divider - 1.
+ */
+static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_t divider)
+{
+    // AHB ------> APB
+    // Divider option: 1, 2, 4 (PCR_APB_DIV_NUM=0, 1, 3)
+    HAL_ASSERT(divider == 1 || divider == 2 || divider == 4);
+    PCR.apb_freq_conf.apb_div_num = divider - 1;
+}
+
+/**
+ * @brief Get APB_CLK divider
+ *
+ * @return Divider. Divider = (PCR_APB_DIV_NUM + 1).
+ */
+static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(void)
+{
+    return 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)
+    switch (divider) {
+    case 4:
+        PCR.mspi_clk_conf.mspi_fast_hs_div_num = 3;
+        break;
+    case 5:
+        PCR.mspi_clk_conf.mspi_fast_hs_div_num = 4;
+        break;
+    case 6:
+        PCR.mspi_clk_conf.mspi_fast_hs_div_num = 5;
+        break;
+    default:
+        // Unsupported HS MSPI_FAST divider
+        abort();
+    }
+}
+
+/**
+ * @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)
+    switch (divider) {
+    case 1:
+        PCR.mspi_clk_conf.mspi_fast_ls_div_num = 0;
+        break;
+    case 2:
+        PCR.mspi_clk_conf.mspi_fast_ls_div_num = 1;
+        break;
+    case 4:
+        PCR.mspi_clk_conf.mspi_fast_ls_div_num = 2;
+        break;
+    default:
+        // Unsupported LS MSPI_FAST divider
+        abort();
+    }
+}
+
+/**
+ * @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 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 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;
+    }
 }
 
 /**
@@ -359,7 +598,23 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(voi
  */
 static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
 {
-    // TODO: IDF-5645
+    switch (in_sel) {
+    case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
+        LP_CLKRST.lp_clk_conf.slow_clk_sel = 0;
+        break;
+    case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
+        LP_CLKRST.lp_clk_conf.slow_clk_sel = 1;
+        break;
+    case SOC_RTC_SLOW_CLK_SRC_RC32K:
+        LP_CLKRST.lp_clk_conf.slow_clk_sel = 2;
+        break;
+    case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
+        LP_CLKRST.lp_clk_conf.slow_clk_sel = 3;
+        break;
+    default:
+        // Unsupported RTC_SLOW_CLK mux input sel
+        abort();
+    }
 }
 
 /**
@@ -369,8 +624,19 @@ static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
  */
 static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    uint32_t clk_sel = LP_CLKRST.lp_clk_conf.slow_clk_sel;
+    switch (clk_sel) {
+    case 0:
+        return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
+    case 1:
+        return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
+    case 2:
+        return SOC_RTC_SLOW_CLK_SRC_RC32K;
+    case 3:
+        return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW;
+    default:
+        return SOC_RTC_SLOW_CLK_SRC_INVALID;
+    }
 }
 
 /**
@@ -380,7 +646,17 @@ static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
  */
 static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
 {
-    // TODO: IDF-5645
+    switch (in_sel) {
+    case SOC_RTC_FAST_CLK_SRC_RC_FAST:
+        LP_CLKRST.lp_clk_conf.fast_clk_sel = 0;
+        break;
+    case SOC_RTC_FAST_CLK_SRC_XTAL_D2:
+        LP_CLKRST.lp_clk_conf.fast_clk_sel = 1;
+        break;
+    default:
+        // Unsupported RTC_FAST_CLK mux input sel
+        abort();
+    }
 }
 
 /**
@@ -390,8 +666,15 @@ static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
  */
 static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    uint32_t clk_sel = LP_CLKRST.lp_clk_conf.fast_clk_sel;
+    switch (clk_sel) {
+    case 0:
+        return SOC_RTC_FAST_CLK_SRC_RC_FAST;
+    case 1:
+        return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
+    default:
+        return SOC_RTC_FAST_CLK_SRC_INVALID;
+    }
 }
 
 /**
@@ -401,7 +684,8 @@ static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
  */
 static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
 {
-    // TODO: IDF-5645
+    // No divider on the target
+    HAL_ASSERT(divider == 1);
 }
 
 /**
@@ -411,8 +695,8 @@ static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
  */
 static inline uint32_t clk_ll_rc_fast_get_divider(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    // No divider on the target, always return divider = 1
+    return 1;
 }
 
 /**
@@ -422,7 +706,8 @@ static inline uint32_t clk_ll_rc_fast_get_divider(void)
  */
 static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
 {
-    // TODO: IDF-5645
+    // No divider on the target
+    HAL_ASSERT(divider == 1);
 }
 
 /************************* RTC STORAGE REGISTER STORE/LOAD **************************/
@@ -436,7 +721,7 @@ static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
  */
 static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
 {
-    // TODO: IDF-5645
+    WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
 }
 
 /**
@@ -449,34 +734,13 @@ static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
  */
 static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
 {
-    // TODO: IDF-5645
-    return 0;
-}
-
-/**
- * @brief Store APB_CLK frequency in RTC storage register
- *
- * Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
- * halves. These are the routines to work with that representation.
- *
- * @param apb_freq_hz APB frequency, in Hz
- */
-static inline __attribute__((always_inline)) void clk_ll_apb_store_freq_hz(uint32_t apb_freq_hz)
-{
-    // TODO: IDF-5645
-}
-
-/**
- * @brief Load APB_CLK frequency from RTC storage register
- *
- * Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
- * halves. These are the routines to work with that representation.
- *
- * @return The stored APB frequency, in Hz
- */
-static inline uint32_t clk_ll_apb_load_freq_hz(void)
-{
-    // TODO: IDF-5645
+    // 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 & UINT16_MAX;
+    }
+    // If the format in reg is invalid
     return 0;
 }
 
@@ -490,7 +754,7 @@ static inline uint32_t clk_ll_apb_load_freq_hz(void)
  */
 static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
 {
-    // TODO: IDF-5645
+    REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
 }
 
 /**
@@ -502,8 +766,7 @@ static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
  */
 static inline uint32_t clk_ll_rtc_slow_load_cal(void)
 {
-    // TODO: IDF-5645
-    return 0;
+    return REG_READ(RTC_SLOW_CLK_CAL_REG);
 }
 
 #ifdef __cplusplus

+ 2 - 0
components/hal/esp32c6/include/hal/i2s_ll.h

@@ -33,6 +33,8 @@ extern "C" {
 #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH  (9)
 #define I2S_LL_MCLK_DIVIDER_MAX        ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
 
+#define I2S_LL_PLL_F160M_CLK_FREQ      (160 * 1000000) // PLL_F160M_CLK: 160MHz
+
 /* I2S clock configuration structure */
 typedef struct {
     uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

+ 29 - 10
components/hal/esp32c6/include/hal/regi2c_ctrl_ll.h

@@ -14,29 +14,48 @@
 extern "C" {
 #endif
 
+// /**
+//  * @brief Reset (Disable) the I2C internal bus for all regi2c registers
+//  */
+// static inline void regi2c_ctrl_ll_i2c_reset(void)
+// {
+//     SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
+// }
+
+// /**
+//  * @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
+//  */
+// static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
+// {
+//     CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
+// }
+
 /**
- * @brief Reset (Disable) the I2C internal bus for all regi2c registers
+ * @brief Start BBPLL self-calibration
  */
-static inline void regi2c_ctrl_ll_i2c_reset(void)
+static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void)
 {
-    SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
+    REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
+    REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
 }
 
 /**
- * @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
+ * @brief Stop BBPLL self-calibration
  */
-static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
+static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_stop(void)
 {
-    CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
+    REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
+    REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
 }
 
 /**
- * @brief Start BBPLL self-calibration
+ * @brief Check whether BBPLL calibration is done
+ *
+ * @return True if calibration is done; otherwise false
  */
-static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void)
+static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_bbpll_calibration_is_done(void)
 {
-    REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
-    REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
+    return REG_GET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE);
 }
 
 /**

+ 1 - 2
components/hal/esp32c6/include/hal/spimem_flash_ll.h

@@ -550,6 +550,7 @@ static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_
  */
 static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void)
 {
+    // MAY CAN IMPROVE (ONLY rc_fast case is incorrect)!
     // TODO: Default is PLL480M, this is hard-coded.
     // In the future, we can get the CPU clock source by calling interface.
     uint8_t clock_val = 0;
@@ -584,8 +585,6 @@ static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void)
             HAL_ASSERT(false);
         }
     }
-    // Hard-coded line, will be removed when pll is enabled.
-    clock_val = 80;
 
     return clock_val;
 }

+ 1 - 1
components/hal/esp32c6/include/hal/timer_ll.h

@@ -65,7 +65,7 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
     case GPTIMER_CLK_SRC_XTAL:
         clk_id = 0;
         break;
-    case GPTIMER_CLK_SRC_APB:
+    case GPTIMER_CLK_SRC_PLL_F80M:
         clk_id = 1;
         break;
     default:

+ 2 - 0
components/hal/esp32h4/include/hal/i2s_ll.h

@@ -33,6 +33,8 @@ extern "C" {
 #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH  (9)
 #define I2S_LL_MCLK_DIVIDER_MAX        ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
 
+#define I2S_LL_PLL_F96M_CLK_FREQ       (96 * 1000000) // PLL_F96M_CLK: 96MHz
+
 /* I2S clock configuration structure */
 typedef struct {
     uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

+ 2 - 0
components/hal/esp32s2/include/hal/i2s_ll.h

@@ -42,6 +42,8 @@ extern "C" {
 #define I2S_LL_TX_EVENT_MASK        I2S_LL_EVENT_TX_EOF
 #define I2S_LL_RX_EVENT_MASK        I2S_LL_EVENT_RX_EOF
 
+#define I2S_LL_PLL_F160M_CLK_FREQ   (160 * 1000000) // PLL_F160M_CLK: 160MHz
+
 /* I2S clock configuration structure */
 typedef struct {
     uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

+ 2 - 0
components/hal/esp32s3/include/hal/i2s_ll.h

@@ -33,6 +33,8 @@ extern "C" {
 #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH  (9)
 #define I2S_LL_MCLK_DIVIDER_MAX        ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
 
+#define I2S_LL_PLL_F160M_CLK_FREQ      (160 * 1000000) // PLL_F160M_CLK: 160MHz
+
 /* I2S clock configuration structure */
 typedef struct {
     uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

+ 4 - 0
components/soc/esp32/include/soc/Kconfig.soc_caps.in

@@ -299,6 +299,10 @@ config SOC_I2S_SUPPORTS_APLL
     bool
     default y
 
+config SOC_I2S_SUPPORTS_PLL_F160M
+    bool
+    default y
+
 config SOC_I2S_SUPPORTS_PDM
     bool
     default y

+ 3 - 3
components/soc/esp32/include/soc/clk_tree_defs.h

@@ -244,15 +244,15 @@ typedef enum {
 /**
  * @brief Array initializer for all supported clock sources of I2S
  */
-#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_D2, SOC_MOD_CLK_APLL}
+#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_APLL}
 
 /**
  * @brief I2S clock source enum
  *
  */
 typedef enum {
-    I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_D2,                   /*!< Select PLL_D2 as the default source clock  */
-    I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_D2,                  /*!< Select PLL_D2 as the source clock */
+    I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M,                /*!< Select PLL_F160M as the default source clock  */
+    I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_F160M,               /*!< Select PLL_F160M as the source clock */
     I2S_CLK_SRC_APLL = SOC_MOD_CLK_APLL,                        /*!< Select APLL as the source clock */
 } soc_periph_i2s_clk_src_t;
 

+ 1 - 0
components/soc/esp32/include/soc/soc_caps.h

@@ -185,6 +185,7 @@
 #define SOC_I2S_NUM                 (2U)
 #define SOC_I2S_HW_VERSION_1        (1)
 #define SOC_I2S_SUPPORTS_APLL       (1)
+#define SOC_I2S_SUPPORTS_PLL_F160M  (1)
 #define SOC_I2S_SUPPORTS_PDM        (1)
 #define SOC_I2S_SUPPORTS_PDM_TX     (1)
 #define SOC_I2S_PDM_MAX_TX_LINES    (1U)

+ 4 - 1
components/soc/esp32c2/include/soc/rtc.h

@@ -154,7 +154,10 @@ typedef struct rtc_cpu_freq_config_s {
 typedef enum {
     RTC_CAL_RTC_MUX = 0,       //!< Currently selected RTC SLOW_CLK
     RTC_CAL_8MD256 = 1,        //!< Internal 8 MHz RC oscillator, divided by 256
-    RTC_CAL_EXT_32K = 2        //!< External 32.768 KHz CLK
+    RTC_CAL_32K_OSC_SLOW = 2,  //!< External 32.768 KHz CLK
+
+    // deprecated name
+    RTC_CAL_EXT_32K __attribute__((deprecated)) = RTC_CAL_32K_OSC_SLOW,
 } rtc_cal_sel_t;
 
 /**

+ 4 - 0
components/soc/esp32c3/include/soc/Kconfig.soc_caps.in

@@ -375,6 +375,10 @@ config SOC_I2S_SUPPORTS_XTAL
     bool
     default y
 
+config SOC_I2S_SUPPORTS_PLL_F160M
+    bool
+    default y
+
 config SOC_I2S_SUPPORTS_PCM
     bool
     default y

+ 1 - 0
components/soc/esp32c3/include/soc/soc_caps.h

@@ -184,6 +184,7 @@
 #define SOC_I2S_NUM                 (1)
 #define SOC_I2S_HW_VERSION_2        (1)
 #define SOC_I2S_SUPPORTS_XTAL       (1)
+#define SOC_I2S_SUPPORTS_PLL_F160M  (1)
 #define SOC_I2S_SUPPORTS_PCM        (1)
 #define SOC_I2S_SUPPORTS_PDM        (1)
 #define SOC_I2S_SUPPORTS_PDM_TX     (1)

+ 1 - 1
components/soc/esp32c6/include/modem/modem_lpcon_reg.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */

+ 3 - 2
components/soc/esp32c6/include/modem/modem_lpcon_struct.h

@@ -1,12 +1,11 @@
 /*
- * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
 #pragma once
 
 #include <stdint.h>
-#include "modem/reg_base.h"
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -228,7 +227,9 @@ typedef volatile struct {
         uint32_t val;
     } date;
 } modem_lpcon_dev_t;
+
 extern modem_lpcon_dev_t MODEM_LPCON;
+
 #ifdef __cplusplus
 }
 #endif

+ 5 - 1
components/soc/esp32c6/include/soc/Kconfig.soc_caps.in

@@ -367,6 +367,10 @@ config SOC_I2S_SUPPORTS_XTAL
     bool
     default y
 
+config SOC_I2S_SUPPORTS_PLL_F160M
+    bool
+    default y
+
 config SOC_I2S_SUPPORTS_PCM
     bool
     default y
@@ -751,7 +755,7 @@ config SOC_TIMER_GROUP_SUPPORT_XTAL
     bool
     default y
 
-config SOC_TIMER_GROUP_SUPPORT_APB
+config SOC_TIMER_GROUP_SUPPORT_PLL_F80M
     bool
     default y
 

+ 40 - 68
components/soc/esp32c6/include/soc/clk_tree_defs.h

@@ -5,44 +5,50 @@
  */
 #pragma once
 
-#include "sdkconfig.h" // TODO: IDF-5973
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-// TODO: IDF-5346 Copied from C3, need to update
 /*
  ************************* ESP32C6 Root Clock Source ****************************
- * 1) Internal 17.5MHz RC Oscillator: RC_FAST (usually referred as FOSC or CK8M/CLK8M in TRM and reg. description)
+ * 1) Internal 17.5MHz RC Oscillator: RC_FAST (may also referred as FOSC in TRM and reg. description)
  *
  *    This RC oscillator generates a ~17.5MHz clock signal output as the RC_FAST_CLK.
- *    The ~17.5MHz signal output is also passed into a configurable divider, which by default divides the input clock
- *    frequency by 256, to generate a RC_FAST_D256_CLK (usually referred as 8md256 or simply d256 in reg. description).
  *
- *    The exact frequency of RC_FAST_CLK can be computed in runtime through calibration on the RC_FAST_D256_CLK.
+ *    The exact frequency of RC_FAST_CLK can be computed in runtime through calibration.
  *
  * 2) External 40MHz Crystal Clock: XTAL
  *
- * 3) Internal 136kHz RC Oscillator: RC_SLOW (usually referrred as RTC in TRM or reg. description)
+ * 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referrred as SOSC in TRM or reg. description)
  *
  *    This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock
  *    can be computed in runtime through calibration.
  *
- * 4) External 32kHz Crystal Clock (optional): XTAL32K
+ * 4) Internal 32kHz RC Oscillator: RC32K
+ *
+ *    The exact frequency of this clock can be computed in runtime through calibration.
  *
- *    The clock source for this XTAL32K_CLK can be either a 32kHz crystal connecting to the XTAL_32K_P and XTAL_32K_N
- *    pins or a 32kHz clock signal generated by an external circuit. The external signal must be connected to the
- *    XTAL_32K_P pin.
+ * 5) External 32kHz Crystal Clock (optional): XTAL32K
+ *
+ *    The clock source for this XTAL32K_CLK should be a 32kHz crystal connecting to the XTAL_32K_P and XTAL_32K_N
+ *    pins.
  *
  *    XTAL32K_CLK can also be calibrated to get its exact frequency.
+ *
+ * 6) External Slow Clock (optional): OSC_SLOW
+ *
+ *    A clock signal generated by an external circuit with frequency ~32kHz can be connected to GPIO0
+ *    to be the clock source for the RTC_SLOW_CLK.
+ *
+ *    OSC_SLOW_CLK can also be calibrated to get its exact frequency.
  */
 
-/* With the default value of CK8M_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */
+/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */
 #define SOC_CLK_RC_FAST_FREQ_APPROX         17500000                            /*!< Approximate RC_FAST_CLK frequency in Hz */
 #define SOC_CLK_RC_SLOW_FREQ_APPROX         136000                              /*!< Approximate RC_SLOW_CLK frequency in Hz */
-#define SOC_CLK_RC_FAST_D256_FREQ_APPROX    (SOC_CLK_RC_FAST_FREQ_APPROX / 256) /*!< Approximate RC_FAST_D256_CLK frequency in Hz */
+#define SOC_CLK_RC32K_FREQ_APPROX           32768                               /*!< Approximate RC32K_CLK frequency in Hz */
 #define SOC_CLK_XTAL32K_FREQ_APPROX         32768                               /*!< Approximate XTAL32K_CLK frequency in Hz */
+#define SOC_CLK_OSC_SLOW_FREQ_APPROX        32768                               /*!< Approximate OSC_SLOW_CLK (external slow clock) frequency in Hz */
 
 // Naming convention: SOC_ROOT_CLK_{loc}_{type}_[attr]
 // {loc}: EXT, INT
@@ -55,7 +61,9 @@ 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_XTAL32K,          /*!< External 32kHz crystal/clock signal */
+    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, only support 32.768 kHz currently */
 } soc_root_clk_t;
 
 /**
@@ -64,7 +72,7 @@ typedef enum {
  */
 typedef enum {
     SOC_CPU_CLK_SRC_XTAL = 0,              /*!< Select XTAL_CLK as CPU_CLK source */
-    SOC_CPU_CLK_SRC_PLL = 1,               /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
+    SOC_CPU_CLK_SRC_PLL = 1,               /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, 480MHz) */
     SOC_CPU_CLK_SRC_RC_FAST = 2,           /*!< Select RC_FAST_CLK as CPU_CLK source */
     SOC_CPU_CLK_SRC_INVALID,               /*!< Invalid CPU_CLK source */
 } soc_cpu_clk_src_t;
@@ -74,10 +82,11 @@ typedef enum {
  * @note Enum values are matched with the register field values on purpose
  */
 typedef enum {
-    SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0,      /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
-    SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1,      /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
-    SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
-    SOC_RTC_SLOW_CLK_SRC_INVALID,          /*!< Invalid RTC_SLOW_CLK source */
+    SOC_RTC_SLOW_CLK_SRC_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 */
+    SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3,                /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
+    SOC_RTC_SLOW_CLK_SRC_INVALID,                     /*!< Invalid RTC_SLOW_CLK source */
 } soc_rtc_slow_clk_src_t;
 
 /**
@@ -85,9 +94,9 @@ typedef enum {
  * @note Enum values are matched with the register field values on purpose
  */
 typedef enum {
-    SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0,      /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
+    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 (may referred as XTAL_CLK_DIV_2) 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` */
-    SOC_RTC_FAST_CLK_SRC_RC_FAST = 1,      /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
     SOC_RTC_FAST_CLK_SRC_INVALID,          /*!< Invalid RTC_FAST_CLK source */
 } soc_rtc_fast_clk_src_t;
 
@@ -106,13 +115,12 @@ typedef enum {
     SOC_MOD_CLK_RTC_FAST,                      /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */
     SOC_MOD_CLK_RTC_SLOW,                      /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or RC_FAST_D256 by configuring soc_rtc_slow_clk_src_t */
     // For digital domain: peripherals, WIFI, BLE
-    SOC_MOD_CLK_APB,                           /*!< APB_CLK is highly dependent on the CPU_CLK source */
+    SOC_MOD_CLK_APB,                           /*!< APB_CLK is highly dependent on the CPU_CLK source */    // TODO: IDF-6343 This should be removed on ESP32C6! Impacts on all following peripheral drivers!
     SOC_MOD_CLK_PLL_F80M,                      /*!< PLL_F80M_CLK is derived from PLL, and has a fixed frequency of 80MHz */
     SOC_MOD_CLK_PLL_F160M,                     /*!< PLL_F160M_CLK is derived from PLL, and has a fixed frequency of 160MHz */
-    SOC_MOD_CLK_PLL_D2,                        /*!< PLL_D2_CLK is derived from PLL, it has a fixed divider of 2 */
+    SOC_MOD_CLK_PLL_F240M,                     /*!< PLL_F240M_CLK is derived from PLL, and has a fixed frequency of 240MHz */
     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_RC_FAST_D256,                  /*!< RC_FAST_D256_CLK comes from the internal 20MHz rc oscillator, divided by 256, and passing a clock gating to the peripherals */
     SOC_MOD_CLK_XTAL,                          /*!< XTAL_CLK comes from the external 40MHz crystal */
 } soc_module_clk_t;
 
@@ -141,32 +149,24 @@ typedef enum {
  * }
  * @endcode
  */
-#if CONFIG_IDF_ENV_FPGA
-#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_XTAL}
-#else
-#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL}
-#endif
+#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL}
 
 /**
  * @brief Type of GPTimer clock source
  */
 typedef enum {
-    GPTIMER_CLK_SRC_APB = SOC_MOD_CLK_APB,         /*!< Select APB as the source clock */
-    GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,       /*!< Select XTAL as the source clock */
-#if CONFIG_IDF_ENV_FPGA
-    GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,    /*!< Select XTAL as the default choice */
-#else
-    GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB,     /*!< Select APB as the default choice */
-#endif
+    GPTIMER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M,   /*!< Select PLL_F80M as the source clock */
+    GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,           /*!< Select XTAL as the source clock */
+    GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,    /*!< Select PLL_F80M as the default choice */
 } soc_periph_gptimer_clk_src_t;
 
 /**
  * @brief Type of Timer Group clock source, reserved for the legacy timer group driver
  */
 typedef enum {
-    TIMER_SRC_CLK_APB = SOC_MOD_CLK_APB,     /*!< Timer group clock source is APB */
-    TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL,   /*!< Timer group clock source is XTAL */
-    TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_APB, /*!< Timer group clock source default choice is APB */
+    TIMER_SRC_CLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M,     /*!< Timer group clock source is PLL_F80M */
+    TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL,             /*!< Timer group clock source is XTAL */
+    TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F80M,      /*!< Timer group clock source default choice is PLL_F80M */
 } soc_periph_tg_clk_src_legacy_t;
 
 //////////////////////////////////////////////////RMT///////////////////////////////////////////////////////////////////
@@ -174,11 +174,7 @@ typedef enum {
 /**
  * @brief Array initializer for all supported clock sources of RMT
  */
-#if CONFIG_IDF_ENV_FPGA
-#define SOC_RMT_CLKS {SOC_MOD_CLK_XTAL}
-#else
 #define SOC_RMT_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL}
-#endif
 
 /**
  * @brief Type of RMT clock source
@@ -186,11 +182,7 @@ typedef enum {
 typedef enum {
     RMT_CLK_SRC_APB = SOC_MOD_CLK_APB,         /*!< Select APB as the source clock */
     RMT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,       /*!< Select XTAL as the source clock */
-#if CONFIG_IDF_ENV_FPGA
-    RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,    /*!< Select XTAL as the default choice */
-#else
     RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB,     /*!< Select APB as the default choice */
-#endif
 } soc_periph_rmt_clk_src_t;
 
 /**
@@ -227,11 +219,7 @@ typedef enum {
     UART_SCLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M,           /*!< UART source clock is PLL_F80M */
     UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST,                /*!< UART source clock is RC_FAST */
     UART_SCLK_XTAL = SOC_MOD_CLK_XTAL,                  /*!< UART source clock is XTAL */
-#if CONFIG_IDF_ENV_FPGA
-    UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL,               /*!< UART source clock default choice is XTAL for FPGA environment */
-#else
     UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M,           /*!< UART source clock default choice is PLL_F80M */
-#endif
 } soc_periph_uart_clk_src_legacy_t;
 
 //////////////////////////////////////////////////MCPWM/////////////////////////////////////////////////////////////////
@@ -247,11 +235,7 @@ typedef enum {
 typedef enum {
     MCPWM_TIMER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
     MCPWM_TIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,         /*!< Select XTAL as the source clock */
-#if CONFIG_IDF_ENV_FPGA
-    MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,      /*!< Select XTAL as the default clock choice */
-#else
     MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
-#endif
 } soc_periph_mcpwm_timer_clk_src_t;
 
 /**
@@ -265,11 +249,7 @@ typedef enum {
 typedef enum {
     MCPWM_CAPTURE_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
     MCPWM_CAPTURE_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,         /*!< Select XTAL as the source clock */
-#if CONFIG_IDF_ENV_FPGA
-    MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,      /*!< Select XTAL as the default clock choice */
-#else
     MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
-#endif
 } soc_periph_mcpwm_capture_clk_src_t;
 
 ///////////////////////////////////////////////////// I2S //////////////////////////////////////////////////////////////
@@ -277,21 +257,13 @@ typedef enum {
 /**
  * @brief Array initializer for all supported clock sources of I2S
  */
-#if CONFIG_IDF_ENV_FPGA
-#define SOC_I2S_CLKS {SOC_MOD_CLK_XTAL}
-#else
 #define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
-#endif
 
 /**
  * @brief I2S clock source enum
  */
 typedef enum {
-#if CONFIG_IDF_ENV_FPGA
-    I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,
-#else
     I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M,                /*!< Select PLL_F160M as the default source clock  */
-#endif
     I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_F160M,               /*!< Select PLL_F160M as the source clock */
     I2S_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,                        /*!< Select XTAL as the source clock */
 } soc_periph_i2s_clk_src_t;

+ 2 - 0
components/soc/esp32c6/include/soc/io_mux_reg.h

@@ -146,6 +146,8 @@
 #define USB_DM_GPIO_NUM              12
 #define USB_DP_GPIO_NUM              13
 
+#define EXT_OSC_SLOW_GPIO_NUM        0
+
 #define MAX_RTC_GPIO_NUM              8
 #define MAX_PAD_GPIO_NUM             30
 #define MAX_GPIO_NUM                 34

+ 1 - 1
components/soc/esp32c6/include/soc/regi2c_bias.h

@@ -11,7 +11,7 @@
  * @brief Register definitions for bias
  *
  * This file lists register fields of BIAS. These definitions are used via macros defined in regi2c_ctrl.h, by
- * bootloader_hardware_init function in bootloader_esp32c3.c.
+ * bootloader_hardware_init function in bootloader_esp32c6.c.
  */
 
 #define I2C_BIAS            0X6A

+ 7 - 4
components/soc/esp32c6/include/soc/regi2c_defs.h

@@ -9,11 +9,13 @@
 #include "esp_bit_defs.h"
 
 /* Analog function control register */
-#define I2C_MST_ANA_CONF0_REG  0x6000E040
+#define I2C_MST_ANA_CONF0_REG          0x600AF818
 #define I2C_MST_BBPLL_STOP_FORCE_HIGH  (BIT(2))
-#define I2C_MST_BBPLL_STOP_FORCE_LOW  (BIT(3))
+#define I2C_MST_BBPLL_STOP_FORCE_LOW   (BIT(3))
+#define I2C_MST_BBPLL_CAL_DONE         (BIT(24))
 
-#define ANA_CONFIG_REG  0x6000E044
+
+#define ANA_CONFIG_REG  0x600AF81C
 #define ANA_CONFIG_S    (8)
 #define ANA_CONFIG_M    (0x3FF)
 
@@ -21,11 +23,12 @@
 #define ANA_I2C_BBPLL_M      BIT(17) /* Clear to enable BBPLL */
 
 
-#define ANA_CONFIG2_REG  0x6000E048
+#define ANA_CONFIG2_REG  0x600AF820
 #define ANA_CONFIG2_M    BIT(18)
 
 #define ANA_I2C_SAR_FORCE_PU BIT(16)
 
+
 /**
  * Restore regi2c analog calibration related configuration registers.
  * This is a workaround, and is fixed on later chips

+ 64 - 0
components/soc/esp32c6/include/soc/regi2c_dig_reg.h

@@ -0,0 +1,64 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+/**
+ * @file regi2c_dig_reg.h
+ * @brief Register definitions for digital to get rtc voltage & digital voltage
+ *        by setting rtc_dbias_Wak & dig_dbias_wak or by analog self-calibration.
+ */
+
+#define I2C_DIG_REG 0x6D
+#define I2C_DIG_REG_HOSTID 0
+
+#define I2C_DIG_REG_EXT_RTC_DREG    4
+#define I2C_DIG_REG_EXT_RTC_DREG_MSB    4
+#define I2C_DIG_REG_EXT_RTC_DREG_LSB    0
+
+#define I2C_DIG_REG_ENX_RTC_DREG    4
+#define I2C_DIG_REG_ENX_RTC_DREG_MSB    7
+#define I2C_DIG_REG_ENX_RTC_DREG_LSB    7
+
+#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP    5
+#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_MSB    4
+#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_LSB    0
+
+#define I2C_DIG_REG_ENIF_RTC_DREG    5
+#define I2C_DIG_REG_ENIF_RTC_DREG_MSB    7
+#define I2C_DIG_REG_ENIF_RTC_DREG_LSB    7
+
+#define I2C_DIG_REG_EXT_DIG_DREG    6
+#define I2C_DIG_REG_EXT_DIG_DREG_MSB    4
+#define I2C_DIG_REG_EXT_DIG_DREG_LSB    0
+
+#define I2C_DIG_REG_ENX_DIG_DREG    6
+#define I2C_DIG_REG_ENX_DIG_DREG_MSB    7
+#define I2C_DIG_REG_ENX_DIG_DREG_LSB    7
+
+#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP    7
+#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_MSB    4
+#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_LSB    0
+
+#define I2C_DIG_REG_ENIF_DIG_DREG    7
+#define I2C_DIG_REG_ENIF_DIG_DREG_MSB    7
+#define I2C_DIG_REG_ENIF_DIG_DREG_LSB    7
+
+#define I2C_DIG_REG_OR_EN_CONT_CAL 9
+#define I2C_DIG_REG_OR_EN_CONT_CAL_MSB 7
+#define I2C_DIG_REG_OR_EN_CONT_CAL_LSB 7
+
+#define I2C_DIG_REG_XPD_RTC_REG 13
+#define I2C_DIG_REG_XPD_RTC_REG_MSB 2
+#define I2C_DIG_REG_XPD_RTC_REG_LSB 2
+
+#define I2C_DIG_REG_XPD_DIG_REG 13
+#define I2C_DIG_REG_XPD_DIG_REG_MSB 3
+#define I2C_DIG_REG_XPD_DIG_REG_LSB 3
+
+#define I2C_DIG_REG_SCK_DCAP	14
+#define I2C_DIG_REG_SCK_DCAP_MSB	7
+#define I2C_DIG_REG_SCK_DCAP_LSB	0

+ 57 - 61
components/soc/esp32c6/include/soc/rtc.h

@@ -46,13 +46,14 @@ extern "C" {
 
 #define MHZ (1000000)
 
-#define RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(cycles)  (cycles << 12)
-#define RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(cycles)  (cycles << 12)
 #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
 
+// TODO: IDF-5781
 /* Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP,
  * RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values.
  */
@@ -74,9 +75,10 @@ extern "C" {
 #define SOC_DELAY_RTC_SLOW_CLK_SWITCH       300
 #define SOC_DELAY_RC_FAST_ENABLE            50
 #define SOC_DELAY_RC_FAST_DIGI_SWITCH       5
+#define SOC_DELAY_RC32K_ENABLE              300
 
-/* Core voltage:
- * Currently, ESP32C3 never adjust its wake voltage in runtime
+/* Core voltage: // TODO: IDF-5781
+ * Currently, ESP32C6 never adjust its wake voltage in runtime
  * Only sets dig/rtc voltage dbias at startup time
  */
 #define DIG_DBIAS_80M       RTC_CNTL_DBIAS_1V20
@@ -89,8 +91,9 @@ extern "C" {
 #define RTC_CNTL_CK8M_WAIT_DEFAULT  20
 #define RTC_CK8M_ENABLE_WAIT_DEFAULT 5
 
-#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100
-#define RTC_CNTL_SCK_DCAP_DEFAULT   255
+#define RTC_CNTL_CK8M_DFREQ_DEFAULT  100
+#define RTC_CNTL_SCK_DCAP_DEFAULT    128
+#define RTC_CNTL_RC32K_DFREQ_DEFAULT 700
 
 /* Various delays to be programmed into power control state machines */
 #define RTC_CNTL_XTL_BUF_WAIT_SLP_US            (250)
@@ -140,7 +143,7 @@ typedef enum {
 typedef struct rtc_cpu_freq_config_s {
     soc_cpu_clk_src_t source;       //!< The clock from which CPU clock is derived
     uint32_t source_freq_mhz;       //!< Source clock frequency
-    uint32_t div;                   //!< Divider, freq_mhz = source_freq_mhz / div
+    uint32_t div;                   //!< Divider, freq_mhz = SOC_ROOT_CLK freq_mhz / div
     uint32_t freq_mhz;              //!< CPU clock frequency
 } rtc_cpu_freq_config_t;
 
@@ -151,12 +154,18 @@ typedef struct rtc_cpu_freq_config_s {
 
 /**
  * @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 ESP32C6. The conversion to register field values is explicitly done in
+ *       rtc_clk_cal_internal
  */
 typedef enum {
-    RTC_CAL_RTC_MUX = 0,       //!< Currently selected RTC SLOW_CLK
-    RTC_CAL_32K_XTAL = 2,      //!< External 32 kHz XTAL
-    RTC_CAL_INTERNAL_OSC = 3,  //!< Internal 150 kHz oscillator
-    RTC_CAL_RC_FAST,           //!< Internal 20 MHz oscillator
+    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 32kHz clk signal input by lp_pad_gpio0, as one type of 32k clock
+    RTC_CAL_RC_FAST                                        //!< Internal 20MHz RC oscillator
 } rtc_cal_sel_t;
 
 /**
@@ -166,11 +175,12 @@ typedef struct {
     rtc_xtal_freq_t xtal_freq : 8;             //!< Main XTAL frequency
     uint32_t cpu_freq_mhz : 10;                //!< CPU frequency to set, in MHz
     soc_rtc_fast_clk_src_t fast_clk_src : 2;   //!< RTC_FAST_CLK clock source to choose
-    soc_rtc_slow_clk_src_t slow_clk_src : 2;   //!< RTC_SLOW_CLK clock source to choose
+    soc_rtc_slow_clk_src_t slow_clk_src : 3;   //!< RTC_SLOW_CLK clock source to choose
     uint32_t clk_rtc_clk_div : 8;
-    uint32_t clk_8m_clk_div : 3;               //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
-    uint32_t slow_clk_dcap : 8;                //!< RTC 150k clock adjustment parameter (higher value leads to lower frequency)
-    uint32_t clk_8m_dfreq : 8;                 //!< RTC 8m clock adjustment parameter (higher value leads to higher frequency)
+    uint32_t clk_8m_clk_div : 3;               //!< RC_FAST clock divider (division is by clk_8m_div+1, i.e. 0 means ~20MHz frequency)
+    uint32_t slow_clk_dcap : 8;                //!< RC_SLOW clock adjustment parameter (higher value leads to lower frequency)
+    uint32_t clk_8m_dfreq : 8;                 //!< RC_FAST clock adjustment parameter (higher value leads to higher frequency)
+    uint32_t rc32k_dfreq : 10;                 //!< Internal RC32K clock adjustment parameter (higher value leads to higher frequency)
 } rtc_clk_config_t;
 
 /**
@@ -185,6 +195,7 @@ typedef struct {
     .clk_8m_clk_div = 0, \
     .slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \
     .clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
+    .rc32k_dfreq = RTC_CNTL_RC32K_DFREQ_DEFAULT, \
 }
 
 typedef struct {
@@ -213,10 +224,6 @@ typedef struct {
     .dg_peri_wait_cycles = OTHER_BLOCKS_WAIT, \
 }
 
-void rtc_clk_divider_set(uint32_t div);
-
-void rtc_clk_8m_divider_set(uint32_t div);
-
 /**
  * Initialize clocks and set CPU frequency
  *
@@ -273,23 +280,18 @@ bool rtc_clk_32k_enabled(void);
  */
 void rtc_clk_32k_bootstrap(uint32_t cycle);
 
+/**
+ * @brief Enable or disable 32 kHz internal rc oscillator
+ * @param en  true to enable, false to disable
+ */
+void rtc_clk_rc32k_enable(bool enable);
+
 /**
  * @brief Enable or disable 8 MHz internal oscillator
  *
- * Output from 8 MHz internal oscillator is passed into a configurable
- * divider, which by default divides the input clock frequency by 256.
- * Output of the divider may be used as RTC_SLOW_CLK source.
- * Output of the divider is referred to in register descriptions and code as
- * 8md256 or simply d256. Divider values other than 256 may be configured, but
- * this facility is not currently needed, so is not exposed in the code.
- *
- * When 8MHz/256 divided output is not needed, the divider should be disabled
- * to reduce power consumption.
- *
  * @param clk_8m_en true to enable 8MHz generator
- * @param d256_en true to enable /256 divider
  */
-void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en);
+void rtc_clk_8m_enable(bool clk_8m_en);
 
 /**
  * @brief Get the state of 8 MHz internal oscillator
@@ -297,12 +299,6 @@ void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en);
  */
 bool rtc_clk_8m_enabled(void);
 
-/**
- * @brief Get the state of /256 divider which is applied to 8MHz clock
- * @return true if the divided output is enabled
- */
-bool rtc_clk_8md256_enabled(void);
-
 /**
  * @brief Select source for RTC_SLOW_CLK
  * @param clk_src clock source (one of soc_rtc_slow_clk_src_t values)
@@ -401,25 +397,29 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config);
 void rtc_clk_cpu_freq_set_xtal(void);
 
 /**
- * @brief Store new APB frequency value into RTC_APB_FREQ_REG
- *
- * This function doesn't change any hardware clocks.
- *
- * Functions which perform frequency switching and change APB frequency call
- * this function to update the value of APB frequency stored in RTC_APB_FREQ_REG
- * (one of RTC general purpose retention registers). This should not normally
- * be called from application code.
- *
- * @param apb_freq  new APB frequency, in Hz
+ * @brief Get the current APB frequency.
+ * @return The calculated APB frequency value, in Hz.
  */
-void rtc_clk_apb_freq_update(uint32_t apb_freq);
+uint32_t rtc_clk_apb_freq_get(void);
 
 /**
- * @brief Get the current stored APB frequency.
- * @return The APB frequency value as last set via rtc_clk_apb_freq_update(), in Hz.
+ * @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
  */
-uint32_t rtc_clk_apb_freq_get(void);
-
 uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
 
 /**
@@ -430,6 +430,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
  * 32k XTAL is being calibrated, but the oscillator has not started up (due to
  * incorrect loading capacitance, board design issue, or lack of 32 XTAL on board).
  *
+ * @note When 32k CLK is being calibrated, this function will check the accuracy
+ * of the clock. Since the xtal 32k or ext osc 32k is generally very stable, if
+ * the check fails, then consider this an invalid 32k clock and return 0. This
+ * check can filter some jamming signal.
+ *
  * @param cal_clk  clock to be measured
  * @param slow_clk_cycles  number of slow clock cycles to average
  * @return average slow clock period in microseconds, Q13.19 fixed point format,
@@ -437,15 +442,6 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
  */
 uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles);
 
-/**
- * @brief Measure ratio between XTAL frequency and RTC slow clock frequency
- * @param cal_clk slow clock to be measured
- * @param slow_clk_cycles number of slow clock cycles to average
- * @return average ratio between XTAL frequency and slow clock frequency,
- *         Q13.19 fixed point format, or 0 if calibration has timed out.
- */
-uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles);
-
 /**
  * @brief Convert time interval from microseconds to RTC_SLOW_CLK cycles
  * @param time_in_us Time interval in microseconds

+ 1 - 10
components/soc/esp32c6/include/soc/soc.h

@@ -140,19 +140,10 @@
 #define  CPU_CLK_FREQ_ROM                            APB_CLK_FREQ_ROM
 #define  EFUSE_CLK_FREQ_ROM                          ( 20*1000000)
 #define  CPU_CLK_FREQ                                APB_CLK_FREQ
-#if CONFIG_IDF_ENV_FPGA
-#define  APB_CLK_FREQ                                ( 40*1000000 )
-#else
-#define  APB_CLK_FREQ                                ( 80*1000000 )
-#endif
+#define  APB_CLK_FREQ                                ( 80*1000000 ) // TODO: IDF-6343 APB clock freq is 40MHz indeed
 #define  REF_CLK_FREQ                                ( 1000000 )
 #define  RTC_CLK_FREQ                                (20*1000000)
 #define  XTAL_CLK_FREQ                               (40*1000000)
-#define  UART_CLK_FREQ                               APB_CLK_FREQ
-#define  WDT_CLK_FREQ                                APB_CLK_FREQ
-#define  TIMER_CLK_FREQ                              (80000000>>4) //80MHz divided by 16
-#define  SPI_CLK_DIV                                 4
-#define  TICKS_PER_US_ROM                            40              // CPU is 80MHz
 #define  GPIO_MATRIX_DELAY_NS                        0
 //}}
 

+ 2 - 1
components/soc/esp32c6/include/soc/soc_caps.h

@@ -205,6 +205,7 @@
 #define SOC_I2S_NUM                 (1)
 #define SOC_I2S_HW_VERSION_2        (1)
 #define SOC_I2S_SUPPORTS_XTAL       (1)
+#define SOC_I2S_SUPPORTS_PLL_F160M  (1)
 #define SOC_I2S_SUPPORTS_PCM        (1)
 #define SOC_I2S_SUPPORTS_PDM        (1)
 #define SOC_I2S_SUPPORTS_PDM_TX     (1)
@@ -362,7 +363,7 @@
 #define SOC_TIMER_GROUP_TIMERS_PER_GROUP  (1U)
 #define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
 #define SOC_TIMER_GROUP_SUPPORT_XTAL      (1)
-#define SOC_TIMER_GROUP_SUPPORT_APB       (1)
+#define SOC_TIMER_GROUP_SUPPORT_PLL_F80M  (1)
 #define SOC_TIMER_GROUP_TOTAL_TIMERS      (2)
 #define SOC_TIMER_SUPPORT_ETM             (1)
 

+ 4 - 0
components/soc/esp32h4/include/soc/Kconfig.soc_caps.in

@@ -351,6 +351,10 @@ config SOC_I2S_SUPPORTS_XTAL
     bool
     default y
 
+config SOC_I2S_SUPPORTS_PLL_F96M
+    bool
+    default y
+
 config SOC_I2S_SUPPORTS_PCM
     bool
     default y

+ 4 - 0
components/soc/esp32h4/include/soc/regi2c_dig_reg.h

@@ -58,3 +58,7 @@
 #define I2C_DIG_REG_XPD_DIG_REG 13
 #define I2C_DIG_REG_XPD_DIG_REG_MSB 3
 #define I2C_DIG_REG_XPD_DIG_REG_LSB 3
+
+#define I2C_DIG_REG_SCK_DCAP	14
+#define I2C_DIG_REG_SCK_DCAP_MSB	7
+#define I2C_DIG_REG_SCK_DCAP_LSB	0

+ 1 - 0
components/soc/esp32h4/include/soc/soc_caps.h

@@ -191,6 +191,7 @@
 #define SOC_I2S_NUM                 (1)
 #define SOC_I2S_HW_VERSION_2        (1)
 #define SOC_I2S_SUPPORTS_XTAL       (1)
+#define SOC_I2S_SUPPORTS_PLL_F96M   (1)
 #define SOC_I2S_SUPPORTS_PCM        (1)
 #define SOC_I2S_SUPPORTS_PDM        (1)
 #define SOC_I2S_SUPPORTS_PDM_TX     (1)

+ 4 - 0
components/soc/esp32s2/include/soc/Kconfig.soc_caps.in

@@ -363,6 +363,10 @@ config SOC_I2S_SUPPORTS_APLL
     bool
     default y
 
+config SOC_I2S_SUPPORTS_PLL_F160M
+    bool
+    default y
+
 config SOC_I2S_SUPPORTS_DMA_EQUAL
     bool
     default y

+ 1 - 0
components/soc/esp32s2/include/soc/soc_caps.h

@@ -181,6 +181,7 @@
 #define SOC_I2S_NUM                 (1U)
 #define SOC_I2S_HW_VERSION_1        (1)
 #define SOC_I2S_SUPPORTS_APLL       (1)
+#define SOC_I2S_SUPPORTS_PLL_F160M  (1)
 #define SOC_I2S_SUPPORTS_DMA_EQUAL  (1)
 #define SOC_I2S_SUPPORTS_LCD_CAMERA (1)
 #define SOC_I2S_APLL_MIN_FREQ       (250000000)

+ 4 - 0
components/soc/esp32s3/include/soc/Kconfig.soc_caps.in

@@ -419,6 +419,10 @@ config SOC_I2S_SUPPORTS_XTAL
     bool
     default y
 
+config SOC_I2S_SUPPORTS_PLL_F160M
+    bool
+    default y
+
 config SOC_I2S_SUPPORTS_PCM
     bool
     default y

+ 1 - 0
components/soc/esp32s3/include/soc/soc_caps.h

@@ -185,6 +185,7 @@
 #define SOC_I2S_NUM                 (2)
 #define SOC_I2S_HW_VERSION_2        (1)
 #define SOC_I2S_SUPPORTS_XTAL       (1)
+#define SOC_I2S_SUPPORTS_PLL_F160M  (1)
 #define SOC_I2S_SUPPORTS_PCM        (1)
 #define SOC_I2S_SUPPORTS_PDM        (1)
 #define SOC_I2S_SUPPORTS_PDM_TX     (1)