Procházet zdrojové kódy

refactor(apll): move the apll soc caps to clk_tree_ll

laokaiyao před 2 roky
rodič
revize
72a0746e62
30 změnil soubory, kde provedl 374 přidání a 256 odebrání
  1. 1 1
      components/driver/dac/esp32/dac_dma.c
  2. 4 3
      components/driver/dac/esp32s2/dac_dma.c
  3. 22 13
      components/driver/deprecated/i2s_legacy.c
  4. 10 6
      components/driver/i2s/i2s_common.c
  5. 2 4
      components/driver/i2s/i2s_pdm.c
  6. 7 3
      components/driver/i2s/i2s_private.h
  7. 1 2
      components/driver/i2s/i2s_std.c
  8. 1 2
      components/driver/i2s/i2s_tdm.c
  9. 8 5
      components/driver/i2s/include/driver/i2s_pdm.h
  10. 1 1
      components/esp_hw_support/include/clk_ctrl_os.h
  11. 2 2
      components/esp_hw_support/port/esp32/rtc_clk.c
  12. 2 2
      components/esp_hw_support/port/esp32s2/rtc_clk.c
  13. 10 1
      components/hal/esp32/include/hal/clk_tree_ll.h
  14. 44 23
      components/hal/esp32/include/hal/i2s_ll.h
  15. 29 22
      components/hal/esp32c3/include/hal/i2s_ll.h
  16. 22 8
      components/hal/esp32c6/include/hal/i2s_ll.h
  17. 22 8
      components/hal/esp32h2/include/hal/i2s_ll.h
  18. 10 0
      components/hal/esp32p4/include/hal/clk_tree_ll.h
  19. 40 33
      components/hal/esp32p4/include/hal/i2s_ll.h
  20. 10 1
      components/hal/esp32s2/include/hal/clk_tree_ll.h
  21. 43 23
      components/hal/esp32s2/include/hal/i2s_ll.h
  22. 33 30
      components/hal/esp32s3/include/hal/i2s_ll.h
  23. 24 16
      components/hal/i2s_hal.c
  24. 19 4
      components/hal/include/hal/i2s_hal.h
  25. 0 16
      components/soc/esp32/include/soc/Kconfig.soc_caps.in
  26. 1 6
      components/soc/esp32/include/soc/soc_caps.h
  27. 4 0
      components/soc/esp32p4/include/soc/Kconfig.soc_caps.in
  28. 2 0
      components/soc/esp32p4/include/soc/soc_caps.h
  29. 0 16
      components/soc/esp32s2/include/soc/Kconfig.soc_caps.in
  30. 0 5
      components/soc/esp32s2/include/soc/soc_caps.h

+ 1 - 1
components/driver/dac/esp32/dac_dma.c

@@ -47,7 +47,7 @@ static const char *TAG = "DAC_DMA";
 static uint32_t s_dac_set_apll_freq(uint32_t mclk)
 {
     /* Calculate the expected APLL  */
-    int div = (int)((SOC_APLL_MIN_HZ / mclk) + 1);
+    int div = (int)((CLK_LL_APLL_MIN_HZ / mclk) + 1);
     /* apll_freq = mclk * div
      * when div = 1, hardware will still divide 2
      * when div = 0, hardware will divide 255

+ 4 - 3
components/driver/dac/esp32s2/dac_dma.c

@@ -19,6 +19,7 @@
 #include "hal/dac_ll.h"
 #include "hal/adc_ll.h"
 #include "hal/hal_utils.h"
+#include "hal/clk_tree_ll.h"
 #include "soc/lldesc.h"
 #include "soc/soc.h"
 #include "soc/soc_caps.h"
@@ -75,9 +76,9 @@ static esp_err_t s_dac_dma_periph_set_clock(uint32_t freq_hz, bool is_apll){
     uint32_t digi_ctrl_freq; // Digital controller clock
     if (is_apll) {
         /* Theoretical frequency range (due to the limitation of DAC, the maximum frequency may not reach):
-         * SOC_APLL_MAX_HZ: 119.24 Hz ~ 67.5 MHz
-         * SOC_APLL_MIN_HZ: 5.06 Hz ~ 2.65 MHz */
-        digi_ctrl_freq = s_dac_set_apll_freq(freq_hz < 120 ? SOC_APLL_MIN_HZ :SOC_APLL_MAX_HZ);
+         * CLK_LL_APLL_MAX_HZ: 119.24 Hz ~ 67.5 MHz
+         * CLK_LL_APLL_MIN_HZ: 5.06 Hz ~ 2.65 MHz */
+        digi_ctrl_freq = s_dac_set_apll_freq(freq_hz < 120 ? CLK_LL_APLL_MIN_HZ :CLK_LL_APLL_MAX_HZ);
         ESP_RETURN_ON_FALSE(digi_ctrl_freq, ESP_ERR_INVALID_ARG, TAG, "set APLL coefficients failed");
     } else {
         digi_ctrl_freq = APB_CLK_FREQ;

+ 22 - 13
components/driver/deprecated/i2s_legacy.c

@@ -25,6 +25,10 @@
 #include "hal/gpio_hal.h"
 #include "driver/i2s_types_legacy.h"
 #include "hal/i2s_hal.h"
+#if SOC_I2S_SUPPORTS_APLL
+#include "hal/clk_tree_ll.h"
+#endif
+
 #if SOC_I2S_SUPPORTS_DAC
 #include "hal/dac_ll.h"
 #include "hal/dac_types.h"
@@ -58,12 +62,16 @@ static const char *TAG = "i2s(legacy)";
 #define I2S_ENTER_CRITICAL(i2s_num)              portENTER_CRITICAL(&i2s_spinlock[i2s_num])
 #define I2S_EXIT_CRITICAL(i2s_num)               portEXIT_CRITICAL(&i2s_spinlock[i2s_num])
 
+#if SOC_SYS_DIGI_CLKRST_REG_SHARED
+#define I2S_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
+#else
+#define I2S_CLOCK_SRC_ATOMIC()
+#endif
+
 #if !SOC_RCC_IS_INDEPENDENT
-#define I2S_RCC_ATOMIC()        PERIPH_RCC_ATOMIC()
-#define I2S_RCC_ENV_DECLARE     (void)__DECLARE_RCC_ATOMIC_ENV
+#define I2S_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
 #else
 #define I2S_RCC_ATOMIC()
-#define I2S_RCC_ENV_DECLARE
 #endif
 
 #define I2S_DMA_BUFFER_MAX_SIZE     4092
@@ -641,7 +649,7 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3
 #if SOC_I2S_SUPPORTS_APLL
     if (use_apll) {
         /* Calculate the expected APLL  */
-        int div = (int)((SOC_APLL_MIN_HZ / mclk) + 1);
+        int div = (int)((CLK_LL_APLL_MIN_HZ / mclk) + 1);
         /* apll_freq = mclk * div
          * when div = 1, hardware will still divide 2
          * when div = 0, the final mclk will be unpredictable
@@ -1029,8 +1037,7 @@ static void i2s_set_clock_legacy(i2s_port_t i2s_num)
     i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg;
     i2s_hal_clock_info_t clk_info;
     i2s_calculate_clock(i2s_num, &clk_info);
-    I2S_RCC_ATOMIC() {
-        I2S_RCC_ENV_DECLARE;
+    I2S_CLOCK_SRC_ATOMIC() {
         if (p_i2s[i2s_num]->dir & I2S_DIR_TX) {
             i2s_hal_set_tx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src);
         }
@@ -1538,14 +1545,13 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)
 
 #if SOC_I2S_SUPPORTS_APLL
     if (obj->use_apll) {
-        I2S_RCC_ATOMIC() {
-            I2S_RCC_ENV_DECLARE;
+        I2S_CLOCK_SRC_ATOMIC() {
             // switch back to PLL clock source
             if (obj->dir & I2S_DIR_TX) {
-                i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_SRC_DEFAULT);
+                i2s_hal_set_tx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT);
             }
             if (obj->dir & I2S_DIR_RX) {
-                i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_SRC_DEFAULT);
+                i2s_hal_set_rx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT);
             }
         }
         periph_rtc_apll_release();
@@ -1559,7 +1565,7 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)
     }
 #endif
 #if SOC_I2S_HW_VERSION_2
-    I2S_RCC_ATOMIC() {
+    I2S_CLOCK_SRC_ATOMIC() {
         if (obj->dir & I2S_DIR_TX) {
             i2s_ll_tx_disable_clock(obj->hal.dev);
         }
@@ -1910,7 +1916,9 @@ esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name)
         ret = ESP_OK;
         comp_using_i2s[id] = comp_name;
         I2S_RCC_ATOMIC() {
-            i2s_ll_enable_clock(I2S_LL_GET_HW(id));
+            i2s_ll_enable_bus_clock(id, true);
+            i2s_ll_reset_register(id);
+            i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), true);
         }
     }
     portEXIT_CRITICAL(&i2s_spinlock[id]);
@@ -1927,7 +1935,8 @@ esp_err_t i2s_platform_release_occupation(int id)
         comp_using_i2s[id] = NULL;
         /* Disable module clock */
         I2S_RCC_ATOMIC() {
-            i2s_ll_disable_clock(I2S_LL_GET_HW(id));
+            i2s_ll_enable_bus_clock(id, false);
+            i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), false);
         }
     }
     portEXIT_CRITICAL(&i2s_spinlock[id]);

+ 10 - 6
components/driver/i2s/i2s_common.c

@@ -36,6 +36,7 @@
 #include "driver/adc_i2s_legacy.h"
 #endif
 #if SOC_I2S_SUPPORTS_APLL
+#include "hal/clk_tree_ll.h"
 #include "clk_ctrl_os.h"
 #endif
 
@@ -401,7 +402,7 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu
     handle->dma.buf_size = bufsize;
 
 #if SOC_GDMA_TRIG_PERIPH_I2S0_BUS == SOC_GDMA_BUS_AHB
-    uint32_t alignment = 32;
+    uint32_t alignment = 64;
     uint32_t desc_size = alignment;
 #else
     uint32_t alignment = 4;
@@ -448,14 +449,14 @@ err:
 static uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq_hz)
 {
     /* Calculate the expected APLL  */
-    int mclk_div = (int)((SOC_APLL_MIN_HZ / mclk_freq_hz) + 1);
+    int mclk_div = (int)((CLK_LL_APLL_MIN_HZ / mclk_freq_hz) + 1);
     /* apll_freq = mclk * div
         * when div = 1, hardware will still divide 2
         * when div = 0, the final mclk will be unpredictable
         * So the div here should be at least 2 */
     mclk_div = mclk_div < 2 ? 2 : mclk_div;
     uint32_t expt_freq = mclk_freq_hz * mclk_div;
-    if (expt_freq > SOC_APLL_MAX_HZ) {
+    if (expt_freq > CLK_LL_APLL_MAX_HZ) {
         ESP_LOGE(TAG, "The required APLL frequency exceed its maximum value");
         return 0;
     }
@@ -867,7 +868,7 @@ esp_err_t i2s_del_channel(i2s_chan_handle_t handle)
     bool is_bound = true;
 
 #if SOC_I2S_HW_VERSION_2
-    I2S_RCC_ATOMIC() {
+    I2S_CLOCK_SRC_ATOMIC() {
         if (dir == I2S_DIR_TX) {
             i2s_ll_tx_disable_clock(handle->controller->hal.dev);
         } else {
@@ -1202,7 +1203,9 @@ esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name)
         g_i2s.comp_name[id] = comp_name;
         /* Enable module clock */
         I2S_RCC_ATOMIC() {
-            i2s_ll_enable_clock(I2S_LL_GET_HW(id));
+            i2s_ll_enable_bus_clock(id, true);
+            i2s_ll_reset_register(id);
+            i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), true);
         }
     } else {
         occupied_comp =  g_i2s.comp_name[id];
@@ -1224,7 +1227,8 @@ esp_err_t i2s_platform_release_occupation(int id)
         g_i2s.comp_name[id] = NULL;
         /* Disable module clock */
         I2S_RCC_ATOMIC() {
-            i2s_ll_disable_clock(I2S_LL_GET_HW(id));
+            i2s_ll_enable_bus_clock(id, false);
+            i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), false);
         }
     } else {
         ret = ESP_ERR_INVALID_STATE;

+ 2 - 4
components/driver/i2s/i2s_pdm.c

@@ -70,8 +70,7 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx
 
     portENTER_CRITICAL(&g_i2s.spinlock);
     /* Set clock configurations in HAL*/
-    I2S_RCC_ATOMIC() {
-        I2S_RCC_ENV_DECLARE;
+    I2S_CLOCK_SRC_ATOMIC() {
         i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
     }
 #if SOC_I2S_HW_VERSION_2
@@ -357,8 +356,7 @@ static esp_err_t i2s_pdm_rx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_rx
 
     portENTER_CRITICAL(&g_i2s.spinlock);
     /* Set clock configurations in HAL*/
-    I2S_RCC_ATOMIC() {
-        I2S_RCC_ENV_DECLARE;
+    I2S_CLOCK_SRC_ATOMIC() {
         i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
     }
     portEXIT_CRITICAL(&g_i2s.spinlock);

+ 7 - 3
components/driver/i2s/i2s_private.h

@@ -36,12 +36,16 @@ extern "C" {
 #endif //CONFIG_I2S_ISR_IRAM_SAFE
 #define I2S_DMA_ALLOC_CAPS      (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA)
 
+#if SOC_SYS_DIGI_CLKRST_REG_SHARED
+#define I2S_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
+#else
+#define I2S_CLOCK_SRC_ATOMIC()
+#endif
+
 #if !SOC_RCC_IS_INDEPENDENT
-#define I2S_RCC_ATOMIC()        PERIPH_RCC_ATOMIC()
-#define I2S_RCC_ENV_DECLARE     (void)__DECLARE_RCC_ATOMIC_ENV
+#define I2S_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
 #else
 #define I2S_RCC_ATOMIC()
-#define I2S_RCC_ENV_DECLARE
 #endif
 
 #define I2S_NULL_POINTER_CHECK(tag, p)          ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, tag, "input parameter '"#p"' is NULL")

+ 1 - 2
components/driver/i2s/i2s_std.c

@@ -77,8 +77,7 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c
 
     portENTER_CRITICAL(&g_i2s.spinlock);
     /* Set clock configurations in HAL*/
-    I2S_RCC_ATOMIC() {
-        I2S_RCC_ENV_DECLARE;
+    I2S_CLOCK_SRC_ATOMIC() {
         if (handle->dir == I2S_DIR_TX) {
             i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
         } else {

+ 1 - 2
components/driver/i2s/i2s_tdm.c

@@ -79,8 +79,7 @@ static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_c
 
     portENTER_CRITICAL(&g_i2s.spinlock);
     /* Set clock configurations in HAL*/
-    I2S_RCC_ATOMIC() {
-        I2S_RCC_ENV_DECLARE;
+    I2S_CLOCK_SRC_ATOMIC() {
         if (handle->dir == I2S_DIR_TX) {
             i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
         } else {

+ 8 - 5
components/driver/i2s/include/driver/i2s_pdm.h

@@ -35,8 +35,8 @@ extern "C" {
     .slot_mode = mono_or_stereo, \
     .slot_mask = (mono_or_stereo  == I2S_SLOT_MODE_MONO) ? \
                  I2S_PDM_SLOT_LEFT : I2S_PDM_SLOT_BOTH, \
-    .hpf_en = true, \
-    .hpf_cut_off_freq_hz = 35.5, \
+    .hp_en = true, \
+    .hp_cut_off_freq_hz = 35.5, \
     .amplify_num = 1, \
 }
 #else
@@ -81,7 +81,10 @@ typedef struct {
 #if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER
     bool                    hp_en;              /*!< High pass filter enable */
     float                   hp_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */
-    uint32_t                amplify_num;        /*!< The amplification number of the final conversion result, range 1~15, default 1 */
+    uint32_t                amplify_num;        /*!< The amplification number of the final conversion result.
+                                                 *   The data that have converted from PDM to PCM module, will time 'amplify_num' additionally to amplify the final result.
+                                                 *   Note that it's only a multiplier of the digital PCM data, not the gain of the analog signal
+                                                 *   range 1~15, default 1 */
 #endif  // SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER
 
 } i2s_pdm_rx_slot_config_t;
@@ -331,8 +334,8 @@ typedef struct {
     i2s_pdm_sig_scale_t     sinc_scale;         /*!< Sinc filter scaling value */
 #if SOC_I2S_HW_VERSION_2
     i2s_pdm_tx_line_mode_t  line_mode;          /*!< PDM TX line mode, one-line codec, one-line dac, two-line dac mode can be selected */
-    bool                    hpf_en;              /*!< High pass filter enable */
-    float                   hpf_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */
+    bool                    hp_en;              /*!< High pass filter enable */
+    float                   hp_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */
     uint32_t                sd_dither;          /*!< Sigma-delta filter dither */
     uint32_t                sd_dither2;         /*!< Sigma-delta filter dither2 */
 #endif // SOC_I2S_HW_VERSION_2

+ 1 - 1
components/esp_hw_support/include/clk_ctrl_os.h

@@ -54,7 +54,7 @@ void periph_rtc_apll_release(void);
  * @brief Calculate and set APLL coefficients by given frequency
  * @note  Have to call 'periph_rtc_apll_acquire' to enable APLL power before setting frequency
  * @note  This calculation is based on the inequality:
- *        xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= SOC_APLL_MULTIPLIER_OUT_MIN_HZ(350 MHz)
+ *        xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= CLK_LL_APLL_MULTIPLIER_MIN_HZ(350 MHz)
  *        It will always calculate the minimum coefficients that can satisfy the inequality above, instead of loop them one by one.
  *        which means more appropriate coefficients are likely to exist.
  *        But this algorithm can meet almost all the cases and the accuracy can be guaranteed as well.

+ 2 - 2
components/esp_hw_support/port/esp32/rtc_clk.c

@@ -217,7 +217,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
      * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= 350 MHz, '+1' in the following code is to get the ceil value.
      * With this condition, as we know the 'o_div' can't be greater than 31, then we can calculate the APLL minimum support frequency is
      * 350 MHz / ((31 + 2) * 2) = 5303031 Hz (for ceil) */
-    o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MIN_HZ / (float)(freq * 2) + 1) - 2;
+    o_div = (int)(CLK_LL_APLL_MULTIPLIER_MIN_HZ / (float)(freq * 2) + 1) - 2;
     if (o_div > 31) {
         ESP_HW_LOGE(TAG, "Expected frequency is too small");
         return 0;
@@ -227,7 +227,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
          * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) <= 500 MHz, we need to get the floor value in the following code.
          * With this condition, as we know the 'o_div' can't be smaller than 0, then we can calculate the APLL maximum support frequency is
          * 500 MHz / ((0 + 2) * 2) = 125000000 Hz */
-        o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MAX_HZ / (float)(freq * 2)) - 2;
+        o_div = (int)(CLK_LL_APLL_MULTIPLIER_MAX_HZ / (float)(freq * 2)) - 2;
         if (o_div < 0) {
             ESP_HW_LOGE(TAG, "Expected frequency is too big");
             return 0;

+ 2 - 2
components/esp_hw_support/port/esp32s2/rtc_clk.c

@@ -119,7 +119,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
      * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= 350 MHz, '+1' in the following code is to get the ceil value.
      * With this condition, as we know the 'o_div' can't be greater than 31, then we can calculate the APLL minimum support frequency is
      * 350 MHz / ((31 + 2) * 2) = 5303031 Hz (for ceil) */
-    o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MIN_HZ / (float)(freq * 2) + 1) - 2;
+    o_div = (int)(CLK_LL_APLL_MULTIPLIER_MIN_HZ / (float)(freq * 2) + 1) - 2;
     if (o_div > 31) {
         ESP_HW_LOGE(TAG, "Expected frequency is too small");
         return 0;
@@ -129,7 +129,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
          * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) <= 500 MHz, we need to get the floor value in the following code.
          * With this condition, as we know the 'o_div' can't be smaller than 0, then we can calculate the APLL maximum support frequency is
          * 500 MHz / ((0 + 2) * 2) = 125000000 Hz */
-        o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MAX_HZ / (float)(freq * 2)) - 2;
+        o_div = (int)(CLK_LL_APLL_MULTIPLIER_MAX_HZ / (float)(freq * 2)) - 2;
         if (o_div < 0) {
             ESP_HW_LOGE(TAG, "Expected frequency is too big");
             return 0;

+ 10 - 1
components/hal/esp32/include/hal/clk_tree_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -73,6 +73,15 @@ extern "C" {
 #define CLK_LL_XTAL_32K_BOOTSTRAP_DRES_VAL     3
 #define CLK_LL_XTAL_32K_BOOTSTRAP_DBIAS_VAL    0
 
+/* APLL multiplier output frequency range */
+// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)
+#define CLK_LL_APLL_MULTIPLIER_MIN_HZ (350000000) // 350 MHz
+#define CLK_LL_APLL_MULTIPLIER_MAX_HZ (500000000) // 500 MHz
+
+/* APLL output frequency range */
+#define CLK_LL_APLL_MIN_HZ    (5303031)   // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
+#define CLK_LL_APLL_MAX_HZ    (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
+
 /**
  * @brief XTAL32K_CLK enable modes
  */

+ 44 - 23
components/hal/esp32/include/hal/i2s_ll.h

@@ -85,51 +85,72 @@ static inline void i2s_ll_dma_enable_eof_on_fifo_empty(i2s_dev_t *hw, bool en)
 }
 
 /**
- * @brief I2S module general init, enable I2S clock.
+ * @brief Enable the bus clock for I2S module
  *
- * @param hw Peripheral I2S hardware instance address.
+ * @param i2s_id The port id of I2S
+ * @param enable Set true to enable the buf clock
+ */
+static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable)
+{
+    if (enable) {
+        if (i2s_id == 0) {
+            DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
+        } else {
+            DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
+        }
+    } else if (i2s_id == 1) {
+        if (i2s_id == 0) {
+            DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
+        } else {
+            DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
+        }
+    }
+}
+
+/// use a macro to wrap the function, force the caller to use it in a critical section
+/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
+#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__)
+
+
+/**
+ * @brief Reset the I2S module
+ *
+ * @param i2s_id The port id of I2S
  */
-static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_reset_register(int i2s_id)
 {
-    if (hw == &I2S0) {
-        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
+    if (i2s_id == 0) {
+        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
-    } else {
-        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
+    } else if (i2s_id == 1) {
+        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST);
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST);
     }
-    if (hw->clkm_conf.clk_en == 0) {
-        hw->clkm_conf.clk_en = 1;
-        hw->conf2.val = 0;
-    }
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__)
+#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__)
 
 /**
- * @brief I2S module disable clock.
+ * @brief I2S module general init, enable I2S clock.
  *
  * @param hw Peripheral I2S hardware instance address.
+ * @param enable set true to enable the core clock
  */
-static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable)
 {
-    if (hw->clkm_conf.clk_en == 1) {
+    if (enable && !hw->clkm_conf.clk_en) {
+        hw->clkm_conf.clk_en = 1;
+        hw->conf2.val = 0;
+    } else if (!enable && hw->clkm_conf.clk_en) {
         hw->clkm_conf.clk_en = 0;
     }
-    if (hw == &I2S0) {
-        DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
-        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
-    } else {
-        DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
-        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST);
-    }
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__)
+#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__)
 
 /**
  * @brief I2S tx msb right enable

+ 29 - 22
components/hal/esp32c3/include/hal/i2s_ll.h

@@ -37,37 +37,54 @@ extern "C" {
 #define I2S_LL_PLL_F160M_CLK_FREQ      (160 * 1000000) // PLL_F160M_CLK: 160MHz
 #define I2S_LL_DEFAULT_CLK_FREQ     I2S_LL_PLL_F160M_CLK_FREQ    // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
 
+
 /**
- * @brief I2S module general init, enable I2S clock.
+ * @brief Enable the bus clock for I2S module
  *
- * @param hw Peripheral I2S hardware instance address.
+ * @param i2s_id The port id of I2S
+ * @param enable Set true to enable the buf clock
+ */
+static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable)
+{
+    (void)i2s_id;
+    SYSTEM.perip_clk_en0.reg_i2s1_clk_en = enable;
+}
+
+/// use a macro to wrap the function, force the caller to use it in a critical section
+/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
+#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__)
+
+
+/**
+ * @brief Reset the I2S module
+ *
+ * @param i2s_id The port id of I2S
  */
-static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_reset_register(int i2s_id)
 {
-    SYSTEM.perip_clk_en0.reg_i2s1_clk_en = 1;
+    (void)i2s_id;
+    SYSTEM.perip_rst_en0.reg_i2s1_rst = 1;
     SYSTEM.perip_rst_en0.reg_i2s1_rst = 0;
-    hw->tx_clkm_conf.clk_en = 1;
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__)
+#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__)
 
 /**
- * @brief I2S module disable I2S clock.
+ * @brief I2S module general init, enable I2S clock.
  *
  * @param hw Peripheral I2S hardware instance address.
+ * @param enable set true to enable the core clock
  */
-static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable)
 {
-    hw->tx_clkm_conf.clk_en = 0;
-    SYSTEM.perip_clk_en0.reg_i2s1_clk_en = 0;
-    SYSTEM.perip_rst_en0.reg_i2s1_rst = 1;
+    hw->tx_clkm_conf.clk_en = enable;
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__)
+#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__)
 
 /**
  * @brief Enable I2S tx module clock
@@ -99,11 +116,6 @@ static inline void i2s_ll_tx_disable_clock(i2s_dev_t *hw)
     hw->tx_clkm_conf.tx_clk_active = 0;
 }
 
-/// use a macro to wrap the function, force the caller to use it in a critical section
-/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-// i2s_ll_tx_disable_clock don't need RCC ENV actually, but still defined here for compatiblity
-#define i2s_ll_tx_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_tx_disable_clock(__VA_ARGS__)
-
 /**
  * @brief Disable I2S rx module clock
  *
@@ -114,11 +126,6 @@ static inline void i2s_ll_rx_disable_clock(i2s_dev_t *hw)
     hw->rx_clkm_conf.rx_clk_active = 0;
 }
 
-/// use a macro to wrap the function, force the caller to use it in a critical section
-/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-// i2s_ll_rx_disable_clock don't need RCC ENV actually, but still defined here for compatiblity
-#define i2s_ll_rx_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_rx_disable_clock(__VA_ARGS__)
-
 /**
  * @brief I2S mclk use tx module clock
  *

+ 22 - 8
components/hal/esp32c6/include/hal/i2s_ll.h

@@ -38,25 +38,39 @@ extern "C" {
 #define I2S_LL_DEFAULT_CLK_FREQ     I2S_LL_PLL_F160M_CLK_FREQ    // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
 
 /**
- * @brief I2S module general init, enable I2S clock.
  *
- * @param hw Peripheral I2S hardware instance address.
+ * @param i2s_id The port id of I2S
+ * @param enable Set true to enable the buf clock
+ */
+static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable)
+{
+    (void)i2s_id;
+    PCR.i2s_conf.i2s_clk_en = enable;
+}
+
+/**
+ * @brief Reset the I2S module
+ *
+ * @param i2s_id The port id of I2S
  */
-static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_reset_register(int i2s_id)
 {
-    PCR.i2s_conf.i2s_clk_en = 1;
+    (void)i2s_id;
+    PCR.i2s_conf.i2s_rst_en = 1;
     PCR.i2s_conf.i2s_rst_en = 0;
 }
 
 /**
- * @brief I2S module disable I2S clock.
+ * @brief I2S module general init, enable I2S clock.
  *
  * @param hw Peripheral I2S hardware instance address.
+ * @param enable set true to enable the core clock
  */
-static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable)
 {
-    PCR.i2s_conf.i2s_clk_en = 0;
-    PCR.i2s_conf.i2s_rst_en = 1;
+    (void)hw;
+    (void)enable;
+    // No need to do anything
 }
 
 /**

+ 22 - 8
components/hal/esp32h2/include/hal/i2s_ll.h

@@ -39,25 +39,39 @@ extern "C" {
 #define I2S_LL_DEFAULT_CLK_FREQ   I2S_LL_PLL_F96M_CLK_FREQ  // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
 
 /**
- * @brief I2S module general init, enable I2S clock.
  *
- * @param hw Peripheral I2S hardware instance address.
+ * @param i2s_id The port id of I2S
+ * @param enable Set true to enable the buf clock
+ */
+static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable)
+{
+    (void)i2s_id;
+    PCR.i2s_conf.i2s_clk_en = enable;
+}
+
+/**
+ * @brief Reset the I2S module
+ *
+ * @param i2s_id The port id of I2S
  */
-static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_reset_register(int i2s_id)
 {
-    PCR.i2s_conf.i2s_clk_en = 1;
+    (void)i2s_id;
+    PCR.i2s_conf.i2s_rst_en = 1;
     PCR.i2s_conf.i2s_rst_en = 0;
 }
 
 /**
- * @brief I2S module disable I2S clock.
+ * @brief I2S module general init, enable I2S clock.
  *
  * @param hw Peripheral I2S hardware instance address.
+ * @param enable set true to enable the core clock
  */
-static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable)
 {
-    PCR.i2s_conf.i2s_clk_en = 0;
-    PCR.i2s_conf.i2s_rst_en = 1;
+    (void)hw;
+    (void)enable;
+    // No need to do anything
 }
 
 /**

+ 10 - 0
components/hal/esp32p4/include/hal/clk_tree_ll.h

@@ -30,6 +30,16 @@ extern "C" {
 
 #define CLK_LL_PLL_480M_FREQ_MHZ   (480)
 
+/* APLL multiplier output frequency range */
+// TODO: IDF-7526 check if the APLL frequency range is same as before
+// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)
+#define CLK_LL_APLL_MULTIPLIER_MIN_HZ (350000000) // 350 MHz
+#define CLK_LL_APLL_MULTIPLIER_MAX_HZ (500000000) // 500 MHz
+
+/* APLL output frequency range */
+#define CLK_LL_APLL_MIN_HZ    (5303031)   // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
+#define CLK_LL_APLL_MAX_HZ    (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
+
 #define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
     .dac = 3, \
     .dres = 3, \

+ 40 - 33
components/hal/esp32p4/include/hal/i2s_ll.h

@@ -48,66 +48,73 @@ typedef struct {
 } i2s_ll_mclk_div_t;
 
 /**
- * @brief I2S module general init, enable I2S clock.
+ * @brief Enable the bus clock for I2S module
  *
- * @param hw Peripheral I2S hardware instance address.
+ * @param i2s_id The port id of I2S
+ * @param enable Set true to enable the buf clock
  */
-static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable)
 {
-    // Note: this function involves HP_SYS_CLKRST register which is shared with other peripherals, need lock in upper layer
-    switch (I2S_LL_GET_ID(hw)) {
+    switch (i2s_id) {
         case 0:
-            HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s0_apb_clk_en = 1;
-            HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s0_apb = 0;
-            break;
+            HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s0_apb_clk_en = enable;
+            return;
         case 1:
-            HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s1_apb_clk_en = 1;
-            HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s1_apb = 0;
-            break;
+            HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s1_apb_clk_en = enable;
+            return;
         case 2:
-            HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s2_apb_clk_en = 1;
-            HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s2_apb = 0;
-            break;
-        default:
-            // Never reach
-            HAL_ASSERT(false);
+            HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s2_apb_clk_en = enable;
+            return;
     }
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__)
+#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__)
 
 /**
- * @brief I2S module disable I2S clock.
+ * @brief Reset the I2S module
  *
- * @param hw Peripheral I2S hardware instance address.
+ * @param i2s_id The port id of I2S
  */
-static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_reset_register(int i2s_id)
 {
-    // Note: this function involves HP_SYS_CLKRST register which is shared with other peripherals, need lock in upper layer
-    switch (I2S_LL_GET_ID(hw)) {
+    switch (i2s_id) {
         case 0:
-            HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s0_apb_clk_en = 0;
             HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s0_apb = 1;
-            break;
+            HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s0_apb = 0;
+            return;
         case 1:
-            HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s1_apb_clk_en = 0;
             HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s1_apb = 1;
-            break;
+            HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s1_apb = 0;
+            return;
         case 2:
-            HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s2_apb_clk_en = 0;
             HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s2_apb = 1;
-            break;
-        default:
-            // Never reach
-            HAL_ASSERT(false);
+            HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s2_apb = 0;
+            return;
     }
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__)
+#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__)
+
+/**
+ * @brief I2S module general init, enable I2S clock.
+ *
+ * @param hw Peripheral I2S hardware instance address.
+ * @param enable set true to enable the core clock
+ */
+static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable)
+{
+    (void)hw;
+    (void)enable;
+    // No need to do anything
+}
+
+/// use a macro to wrap the function, force the caller to use it in a critical section
+/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
+#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__)
 
 /**
  * @brief Enable I2S tx module clock

+ 10 - 1
components/hal/esp32s2/include/hal/clk_tree_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -47,6 +47,15 @@ extern "C" {
 #define CLK_LL_APLL_CAL_DELAY_2            0x3f
 #define CLK_LL_APLL_CAL_DELAY_3            0x1f
 
+/* APLL multiplier output frequency range */
+// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)
+#define CLK_LL_APLL_MULTIPLIER_MIN_HZ (350000000) // 350 MHz
+#define CLK_LL_APLL_MULTIPLIER_MAX_HZ (500000000) // 500 MHz
+
+/* APLL output frequency range */
+#define CLK_LL_APLL_MIN_HZ    (5303031)   // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
+#define CLK_LL_APLL_MAX_HZ    (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
+
 #define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
     .dac = 3, \
     .dres = 3, \

+ 43 - 23
components/hal/esp32s2/include/hal/i2s_ll.h

@@ -83,52 +83,72 @@ static inline void i2s_ll_dma_enable_eof_on_fifo_empty(i2s_dev_t *hw, bool en)
 }
 
 /**
- * @brief I2S module general init, enable I2S clock.
+ * @brief Enable the bus clock for I2S module
  *
- * @param hw Peripheral I2S hardware instance address.
+ * @param i2s_id The port id of I2S
+ * @param enable Set true to enable the buf clock
+ */
+static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable)
+{
+    if (enable) {
+        if (i2s_id == 0) {
+            DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
+        } else {
+            DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
+        }
+    } else {
+        if (i2s_id == 0) {
+            DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
+        } else {
+            DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
+        }
+    }
+}
+
+/// use a macro to wrap the function, force the caller to use it in a critical section
+/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
+#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__)
+
+/**
+ * @brief Reset the I2S module
+ *
+ * @param i2s_id The port id of I2S
  */
-static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_reset_register(int i2s_id)
 {
-    if (hw == &I2S0) {
-        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
+    if (i2s_id == 0) {
+        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
     } else {
-        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
+        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST);
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST);
     }
-    if (hw->clkm_conf.clk_en == 0) {
-        hw->clkm_conf.clk_sel = 2;
-        hw->clkm_conf.clk_en = 1;
-        hw->conf2.val = 0;
-    }
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__)
+#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__)
 
 /**
- * @brief I2S module disable clock.
+ * @brief I2S module general init, enable I2S clock.
  *
  * @param hw Peripheral I2S hardware instance address.
+ * @param enable set true to enable the core clock
  */
-static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable)
 {
-    if (hw->clkm_conf.clk_en == 1) {
+    if (enable && !hw->clkm_conf.clk_en) {
+        hw->clkm_conf.clk_sel = 2;
+        hw->clkm_conf.clk_en = 1;
+        hw->conf2.val = 0;
+    } else if (!enable && hw->clkm_conf.clk_en) {
         hw->clkm_conf.clk_en = 0;
     }
-    if (hw == &I2S0) {
-        DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
-        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
-    } else {
-        DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
-        DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST);
-    }
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__)
+#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__)
 
 /**
  * @brief I2S tx msb right enable

+ 33 - 30
components/hal/esp32s3/include/hal/i2s_ll.h

@@ -38,47 +38,60 @@ extern "C" {
 #define I2S_LL_PLL_F160M_CLK_FREQ      (160 * 1000000) // PLL_F160M_CLK: 160MHz
 #define I2S_LL_DEFAULT_CLK_FREQ     I2S_LL_PLL_F160M_CLK_FREQ    // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
 
+
 /**
- * @brief I2S module general init, enable I2S clock.
+ * @brief Enable the bus clock for I2S module
  *
- * @param hw Peripheral I2S hardware instance address.
+ * @param i2s_id The port id of I2S
+ * @param enable Set true to enable the buf clock
  */
-static inline void i2s_ll_enable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable)
 {
-    if (hw == &I2S0) {
-        SYSTEM.perip_clk_en0.i2s0_clk_en = 1;
-        SYSTEM.perip_rst_en0.i2s0_rst = 0;
-    } else {
-        SYSTEM.perip_clk_en0.i2s1_clk_en = 1;
-        SYSTEM.perip_rst_en0.i2s1_rst = 0;
+    if (i2s_id == 0) {
+        SYSTEM.perip_clk_en0.i2s0_clk_en = enable;
+    } else if (i2s_id == 1) {
+        SYSTEM.perip_clk_en0.i2s1_clk_en = enable;
     }
-    hw->tx_clkm_conf.clk_en = 1;
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__)
+#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__)
 
 /**
- * @brief I2S module disable I2S clock.
+ * @brief Reset the I2S module
  *
- * @param hw Peripheral I2S hardware instance address.
+ * @param i2s_id The port id of I2S
  */
-static inline void i2s_ll_disable_clock(i2s_dev_t *hw)
+static inline void i2s_ll_reset_register(int i2s_id)
 {
-    hw->tx_clkm_conf.clk_en = 0;
-    if (hw == &I2S0) {
-        SYSTEM.perip_clk_en0.i2s0_clk_en = 0;
+    if (i2s_id == 0) {
         SYSTEM.perip_rst_en0.i2s0_rst = 1;
-    } else {
-        SYSTEM.perip_clk_en0.i2s1_clk_en = 0;
+        SYSTEM.perip_rst_en0.i2s0_rst = 0;
+    } else if (i2s_id == 1) {
         SYSTEM.perip_rst_en0.i2s1_rst = 1;
+        SYSTEM.perip_rst_en0.i2s1_rst = 0;
     }
 }
 
 /// use a macro to wrap the function, force the caller to use it in a critical section
 /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__)
+#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__)
+
+/**
+ * @brief I2S module general init, enable I2S clock.
+ *
+ * @param hw Peripheral I2S hardware instance address.
+ * @param enable set true to enable the core clock
+ */
+static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable)
+{
+    hw->tx_clkm_conf.clk_en = enable;
+}
+
+/// use a macro to wrap the function, force the caller to use it in a critical section
+/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
+#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__)
 
 /**
  * @brief Enable I2S tx module clock
@@ -110,11 +123,6 @@ static inline void i2s_ll_tx_disable_clock(i2s_dev_t *hw)
     hw->tx_clkm_conf.tx_clk_active = 0;
 }
 
-/// use a macro to wrap the function, force the caller to use it in a critical section
-/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-// i2s_ll_tx_disable_clock don't need RCC ENV actually, but still defined here for compatiblity
-#define i2s_ll_tx_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_tx_disable_clock(__VA_ARGS__)
-
 /**
  * @brief Disable I2S rx module clock
  *
@@ -125,11 +133,6 @@ static inline void i2s_ll_rx_disable_clock(i2s_dev_t *hw)
     hw->rx_clkm_conf.rx_clk_active = 0;
 }
 
-/// use a macro to wrap the function, force the caller to use it in a critical section
-/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
-// i2s_ll_rx_disable_clock don't need RCC ENV actually, but still defined here for compatiblity
-#define i2s_ll_rx_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_rx_disable_clock(__VA_ARGS__)
-
 /**
  * @brief I2S mclk use tx module clock
  *

+ 24 - 16
components/hal/i2s_hal.c

@@ -65,30 +65,38 @@ void i2s_hal_init(i2s_hal_context_t *hal, int port_id)
     hal->dev = I2S_LL_GET_HW(port_id);
 }
 
-void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src)
+void _i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src)
 {
-    hal_utils_clk_div_t mclk_div = {};
+    if (clk_info) {
+        hal_utils_clk_div_t mclk_div = {};
 #if SOC_I2S_HW_VERSION_2
-    i2s_ll_tx_enable_clock(hal->dev);
-    i2s_ll_mclk_bind_to_tx_clk(hal->dev);
+        i2s_ll_tx_enable_clock(hal->dev);
+        i2s_ll_mclk_bind_to_tx_clk(hal->dev);
 #endif
-    i2s_ll_tx_clk_set_src(hal->dev, clk_src);
-    i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div);
-    i2s_ll_tx_set_mclk(hal->dev, &mclk_div);
-    i2s_ll_tx_set_bck_div_num(hal->dev, clk_info->bclk_div);
+        i2s_ll_tx_clk_set_src(hal->dev, clk_src);
+        i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div);
+        i2s_ll_tx_set_mclk(hal->dev, &mclk_div);
+        i2s_ll_tx_set_bck_div_num(hal->dev, clk_info->bclk_div);
+    } else {
+        i2s_ll_tx_clk_set_src(hal->dev, clk_src);
+    }
 }
 
-void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src)
+void _i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src)
 {
-    hal_utils_clk_div_t mclk_div = {};
+    if (clk_info) {
+        hal_utils_clk_div_t mclk_div = {};
 #if SOC_I2S_HW_VERSION_2
-    i2s_ll_rx_enable_clock(hal->dev);
-    i2s_ll_mclk_bind_to_rx_clk(hal->dev);
+        i2s_ll_rx_enable_clock(hal->dev);
+        i2s_ll_mclk_bind_to_rx_clk(hal->dev);
 #endif
-    i2s_ll_rx_clk_set_src(hal->dev, clk_src);
-    i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div);
-    i2s_ll_rx_set_mclk(hal->dev, &mclk_div);
-    i2s_ll_rx_set_bck_div_num(hal->dev, clk_info->bclk_div);
+        i2s_ll_rx_clk_set_src(hal->dev, clk_src);
+        i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div);
+        i2s_ll_rx_set_mclk(hal->dev, &mclk_div);
+        i2s_ll_rx_set_bck_div_num(hal->dev, clk_info->bclk_div);
+    } else {
+        i2s_ll_rx_clk_set_src(hal->dev, clk_src);
+    }
 }
 
 /*-------------------------------------------------------------------------

+ 19 - 4
components/hal/include/hal/i2s_hal.h

@@ -142,20 +142,35 @@ void i2s_hal_calc_mclk_precise_division(uint32_t sclk, uint32_t mclk, hal_utils_
  * @brief Set tx channel clock
  *
  * @param hal Context of the HAL layer
- * @param clk_info clock information
+ * @param clk_info clock information, if it is NULL, only set the clock source
  * @param clk_src clock source
  */
-void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src);
+void _i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src);
+
+#if SOC_SYS_DIGI_CLKRST_REG_SHARED
+/// use a macro to wrap the function, force the caller to use it in a critical section
+/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
+#define i2s_hal_set_tx_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _i2s_hal_set_tx_clock(__VA_ARGS__)
+#else
+#define i2s_hal_set_tx_clock(...)   _i2s_hal_set_tx_clock(__VA_ARGS__)
+#endif
 
 /**
  * @brief Set rx channel clock
  *
  * @param hal Context of the HAL layer
- * @param clk_info clock information
+ * @param clk_info clock information, if it is NULL, only set the clock source
  * @param clk_src clock source
  */
-void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src);
+void _i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src);
 
+#if SOC_SYS_DIGI_CLKRST_REG_SHARED
+/// use a macro to wrap the function, force the caller to use it in a critical section
+/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
+#define i2s_hal_set_rx_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _i2s_hal_set_rx_clock(__VA_ARGS__)
+#else
+#define i2s_hal_set_rx_clock(...)   _i2s_hal_set_rx_clock(__VA_ARGS__)
+#endif
 
 /*-------------------------------------------------------------------------
  |                           STD configuration                            |

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

@@ -811,22 +811,6 @@ config SOC_CLK_APLL_SUPPORTED
     bool
     default y
 
-config SOC_APLL_MULTIPLIER_OUT_MIN_HZ
-    int
-    default 350000000
-
-config SOC_APLL_MULTIPLIER_OUT_MAX_HZ
-    int
-    default 500000000
-
-config SOC_APLL_MIN_HZ
-    int
-    default 5303031
-
-config SOC_APLL_MAX_HZ
-    int
-    default 125000000
-
 config SOC_CLK_RC_FAST_D256_SUPPORTED
     bool
     default y

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

@@ -1,6 +1,6 @@
 
 /*
- * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -399,11 +399,6 @@
 
 /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
 #define SOC_CLK_APLL_SUPPORTED                    (1)
-// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)
-#define SOC_APLL_MULTIPLIER_OUT_MIN_HZ (350000000) // 350 MHz
-#define SOC_APLL_MULTIPLIER_OUT_MAX_HZ (500000000) // 500 MHz
-#define SOC_APLL_MIN_HZ    (5303031)   // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
-#define SOC_APLL_MAX_HZ    (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
 
 #define SOC_CLK_RC_FAST_D256_SUPPORTED            (1)
 #define SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256     (1)

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

@@ -1123,6 +1123,10 @@ config SOC_PM_PAU_LINK_NUM
     int
     default 4
 
+config SOC_SYS_DIGI_CLKRST_REG_SHARED
+    bool
+    default y
+
 config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
     bool
     default n

+ 2 - 0
components/soc/esp32p4/include/soc/soc_caps.h

@@ -154,6 +154,7 @@
 #define SOC_CPU_HAS_PMA                 1
 #define SOC_CPU_IDRAM_SPLIT_USING_PMP   1
 
+// TODO: IDF-5360 (Copy from esp32c3, need check)
 /*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/
 /** The maximum length of a Digital Signature in bits. */
 #define SOC_DS_SIGNATURE_MAX_BIT_LEN (4096)
@@ -513,6 +514,7 @@
 #define SOC_PM_PAU_LINK_NUM             (4)
 
 /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
+#define SOC_SYS_DIGI_CLKRST_REG_SHARED            (1)
 #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION       (0)
 #define SOC_MODEM_CLOCK_IS_INDEPENDENT            (0)
 

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

@@ -1035,22 +1035,6 @@ config SOC_CLK_APLL_SUPPORTED
     bool
     default y
 
-config SOC_APLL_MULTIPLIER_OUT_MIN_HZ
-    int
-    default 350000000
-
-config SOC_APLL_MULTIPLIER_OUT_MAX_HZ
-    int
-    default 500000000
-
-config SOC_APLL_MIN_HZ
-    int
-    default 5303031
-
-config SOC_APLL_MAX_HZ
-    int
-    default 125000000
-
 config SOC_CLK_RC_FAST_D256_SUPPORTED
     bool
     default y

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

@@ -446,11 +446,6 @@
 
 /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
 #define SOC_CLK_APLL_SUPPORTED                    (1)
-// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)
-#define SOC_APLL_MULTIPLIER_OUT_MIN_HZ (350000000) // 350 MHz
-#define SOC_APLL_MULTIPLIER_OUT_MAX_HZ (500000000) // 500 MHz
-#define SOC_APLL_MIN_HZ    (5303031)   // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
-#define SOC_APLL_MAX_HZ    (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation
 
 #define SOC_CLK_RC_FAST_D256_SUPPORTED            (1)
 #define SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256     (1)