diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index 87ffa7e244..ac2b2a7934 100644 --- a/components/esp_hw_support/dma/gdma.c +++ b/components/esp_hw_support/dma/gdma.c @@ -48,6 +48,13 @@ static const char *TAG = "gdma"; +#if !SOC_RCC_IS_INDEPENDENT +// Reset and Clock Control registers are mixing with other peripherals, so we need to use a critical section +#define GDMA_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define GDMA_RCC_ATOMIC() +#endif + #define GDMA_INVALID_PERIPH_TRIG (0x3F) #define SEARCH_REQUEST_RX_CHANNEL (1 << 0) #define SEARCH_REQUEST_TX_CHANNEL (1 << 1) @@ -615,7 +622,9 @@ static void gdma_release_group_handle(gdma_group_t *group) if (do_deinitialize) { gdma_hal_deinit(&group->hal); - periph_module_disable(gdma_periph_signals.groups[group_id].module); + GDMA_RCC_ATOMIC() { + gdma_ll_enable_bus_clock(group_id, false); + } free(group); ESP_LOGD(TAG, "del group %d", group_id); } @@ -646,7 +655,10 @@ static gdma_group_t *gdma_acquire_group_handle(int group_id, void (*hal_init)(gd group->group_id = group_id; group->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; // enable APB to access GDMA registers - periph_module_enable(gdma_periph_signals.groups[group_id].module); + GDMA_RCC_ATOMIC() { + gdma_ll_enable_bus_clock(group_id, true); + gdma_ll_reset_register(group_id); + } gdma_hal_config_t config = { .group_id = group_id, }; diff --git a/components/hal/esp32c2/include/hal/gdma_ll.h b/components/hal/esp32c2/include/hal/gdma_ll.h index f9e474cdab..7747ca3378 100644 --- a/components/hal/esp32c2/include/hal/gdma_ll.h +++ b/components/hal/esp32c2/include/hal/gdma_ll.h @@ -11,6 +11,7 @@ #include "hal/gdma_types.h" #include "soc/gdma_struct.h" #include "soc/gdma_reg.h" +#include "soc/system_struct.h" #ifdef __cplusplus extern "C" { @@ -47,6 +48,34 @@ extern "C" { #define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number ///////////////////////////////////// Common ///////////////////////////////////////// + +/** + * @brief Enable the bus clock for the DMA module + */ +static inline void gdma_ll_enable_bus_clock(int group_id, bool enable) +{ + (void)group_id; + SYSTEM.perip_clk_en1.dma_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 gdma_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; gdma_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the DMA module + */ +static inline void gdma_ll_reset_register(int group_id) +{ + (void)group_id; + SYSTEM.perip_rst_en1.dma_rst = 1; + SYSTEM.perip_rst_en1.dma_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 gdma_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; gdma_ll_reset_register(__VA_ARGS__) + /** * @brief Force enable register clock */ diff --git a/components/hal/esp32c3/include/hal/gdma_ll.h b/components/hal/esp32c3/include/hal/gdma_ll.h index 4c15879756..d3deb43181 100644 --- a/components/hal/esp32c3/include/hal/gdma_ll.h +++ b/components/hal/esp32c3/include/hal/gdma_ll.h @@ -11,6 +11,7 @@ #include "hal/gdma_types.h" #include "soc/gdma_struct.h" #include "soc/gdma_reg.h" +#include "soc/system_struct.h" #ifdef __cplusplus extern "C" { @@ -47,6 +48,34 @@ extern "C" { #define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number ///////////////////////////////////// Common ///////////////////////////////////////// + +/** + * @brief Enable the bus clock for the DMA module + */ +static inline void gdma_ll_enable_bus_clock(int group_id, bool enable) +{ + (void)group_id; + SYSTEM.perip_clk_en1.reg_dma_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 gdma_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; gdma_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the DMA module + */ +static inline void gdma_ll_reset_register(int group_id) +{ + (void)group_id; + SYSTEM.perip_rst_en1.reg_dma_rst = 1; + SYSTEM.perip_rst_en1.reg_dma_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 gdma_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; gdma_ll_reset_register(__VA_ARGS__) + /** * @brief Force enable register clock */ diff --git a/components/hal/esp32c6/include/hal/gdma_ll.h b/components/hal/esp32c6/include/hal/gdma_ll.h index 15ebf4a08f..bdccf27035 100644 --- a/components/hal/esp32c6/include/hal/gdma_ll.h +++ b/components/hal/esp32c6/include/hal/gdma_ll.h @@ -12,6 +12,7 @@ #include "soc/gdma_struct.h" #include "soc/gdma_reg.h" #include "soc/soc_etm_source.h" +#include "soc/pcr_struct.h" #ifdef __cplusplus extern "C" { @@ -91,6 +92,26 @@ extern "C" { }}}[group][chan][task] ///////////////////////////////////// Common ///////////////////////////////////////// + +/** + * @brief Enable the bus clock for the DMA module + */ +static inline void gdma_ll_enable_bus_clock(int group_id, bool enable) +{ + (void)group_id; + PCR.gdma_conf.gdma_clk_en = enable; +} + +/** + * @brief Reset the DMA module + */ +static inline void gdma_ll_reset_register(int group_id) +{ + (void)group_id; + PCR.gdma_conf.gdma_rst_en = 1; + PCR.gdma_conf.gdma_rst_en = 0; +} + /** * @brief Force enable register clock */ diff --git a/components/hal/esp32h2/include/hal/gdma_ll.h b/components/hal/esp32h2/include/hal/gdma_ll.h index 15ebf4a08f..bdccf27035 100644 --- a/components/hal/esp32h2/include/hal/gdma_ll.h +++ b/components/hal/esp32h2/include/hal/gdma_ll.h @@ -12,6 +12,7 @@ #include "soc/gdma_struct.h" #include "soc/gdma_reg.h" #include "soc/soc_etm_source.h" +#include "soc/pcr_struct.h" #ifdef __cplusplus extern "C" { @@ -91,6 +92,26 @@ extern "C" { }}}[group][chan][task] ///////////////////////////////////// Common ///////////////////////////////////////// + +/** + * @brief Enable the bus clock for the DMA module + */ +static inline void gdma_ll_enable_bus_clock(int group_id, bool enable) +{ + (void)group_id; + PCR.gdma_conf.gdma_clk_en = enable; +} + +/** + * @brief Reset the DMA module + */ +static inline void gdma_ll_reset_register(int group_id) +{ + (void)group_id; + PCR.gdma_conf.gdma_rst_en = 1; + PCR.gdma_conf.gdma_rst_en = 0; +} + /** * @brief Force enable register clock */ diff --git a/components/hal/esp32p4/include/hal/clk_gate_ll.h b/components/hal/esp32p4/include/hal/clk_gate_ll.h index 2de987c382..1003eb81a8 100644 --- a/components/hal/esp32p4/include/hal/clk_gate_ll.h +++ b/components/hal/esp32p4/include/hal/clk_gate_ll.h @@ -60,10 +60,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return HP_SYS_CLKRST_REG_TWAI1_CLK_EN; case PERIPH_TWAI2_MODULE: return HP_SYS_CLKRST_REG_TWAI2_CLK_EN; - case PERIPH_AHB_PDMA_MODULE: - return HP_SYS_CLKRST_REG_AHB_PDMA_SYS_CLK_EN; - case PERIPH_AXI_PDMA_MODULE: - return HP_SYS_CLKRST_REG_AXI_PDMA_SYS_CLK_EN; case PERIPH_GPSPI_MODULE: return HP_SYS_CLKRST_REG_GPSPI2_HS_CLK_EN; case PERIPH_GPSPI2_MODULE: @@ -120,8 +116,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en switch (periph) { case PERIPH_PVT_MODULE: return HP_SYS_CLKRST_REG_RST_EN_PVT_TOP; - case PERIPH_GDMA_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_GDMA; case PERIPH_MSPI_FLASH_MODULE: return HP_SYS_CLKRST_REG_RST_EN_MSPI_AXI; case PERIPH_MSPI_PSRAM_MODULE: @@ -138,10 +132,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en return HP_SYS_CLKRST_REG_RST_EN_DMA2D; case PERIPH_PPA_MODULE: return HP_SYS_CLKRST_REG_RST_EN_PPA; - case PERIPH_AHB_PDMA_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_AHB_PDMA; - case PERIPH_AXI_PDMA_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_AXI_PDMA; case PERIPH_SYSTIMER_MODULE: return HP_SYS_CLKRST_REG_RST_EN_STIMER; case PERIPH_UART0_MODULE: @@ -222,9 +212,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) { switch (periph) { - case PERIPH_AHB_PDMA_MODULE: - case PERIPH_AXI_PDMA_MODULE: - return HP_SYS_CLKRST_SOC_CLK_CTRL1_REG; case PERIPH_MSPI_FLASH_MODULE: case PERIPH_MSPI_PSRAM_MODULE: return HP_SYS_CLKRST_PERI_CLK_CTRL00_REG; @@ -290,7 +277,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) { switch (periph) { case PERIPH_PVT_MODULE: - case PERIPH_GDMA_MODULE: case PERIPH_MSPI_FLASH_MODULE: case PERIPH_MSPI_PSRAM_MODULE: case PERIPH_ISP_MODULE: @@ -298,8 +284,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) case PERIPH_DMA2D_MODULE: return HP_SYS_CLKRST_HP_RST_EN0_REG; case PERIPH_PPA_MODULE: - case PERIPH_AHB_PDMA_MODULE: - case PERIPH_AXI_PDMA_MODULE: case PERIPH_SYSTIMER_MODULE: case PERIPH_UART0_MODULE: case PERIPH_UART1_MODULE: diff --git a/components/hal/esp32p4/include/hal/gdma_ll.h b/components/hal/esp32p4/include/hal/gdma_ll.h index f29f33feb1..f282a23a7d 100644 --- a/components/hal/esp32p4/include/hal/gdma_ll.h +++ b/components/hal/esp32p4/include/hal/gdma_ll.h @@ -11,10 +11,8 @@ #pragma once #include - -#ifdef __cplusplus -extern "C" { -#endif +#include +#include "soc/hp_sys_clkrst_struct.h" #define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5] @@ -46,6 +44,44 @@ extern "C" { #define GDMA_LL_AHB_MAX_CRC_BIT_WIDTH 32 // Max CRC bit width supported by AHB GDMA #define GDMA_LL_AXI_MAX_CRC_BIT_WIDTH 16 // Max CRC bit width supported by AXI GDMA +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable the bus clock for the DMA module + */ +static inline void gdma_ll_enable_bus_clock(int group_id, bool enable) +{ + if (group_id == 0) { + HP_SYS_CLKRST.soc_clk_ctrl1.reg_ahb_pdma_sys_clk_en = enable; + } else { + HP_SYS_CLKRST.soc_clk_ctrl1.reg_axi_pdma_sys_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 gdma_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; gdma_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the DMA module + */ +static inline void gdma_ll_reset_register(int group_id) +{ + if (group_id == 0) { + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_ahb_pdma = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_ahb_pdma = 0; + } else { + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_axi_pdma = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_axi_pdma = 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 gdma_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; gdma_ll_reset_register(__VA_ARGS__) + __attribute__((always_inline)) static inline uint8_t _bitwise_reverse(uint8_t n) { diff --git a/components/hal/esp32s3/include/hal/gdma_ll.h b/components/hal/esp32s3/include/hal/gdma_ll.h index 53bebb0fde..ff923dd82f 100644 --- a/components/hal/esp32s3/include/hal/gdma_ll.h +++ b/components/hal/esp32s3/include/hal/gdma_ll.h @@ -12,6 +12,7 @@ #include "hal/gdma_types.h" #include "soc/gdma_struct.h" #include "soc/gdma_reg.h" +#include "soc/system_struct.h" #ifdef __cplusplus extern "C" { @@ -60,6 +61,34 @@ extern "C" { #define GDMA_LL_AHB_PAIRS_PER_GROUP 5 // Number of GDMA pairs in each AHB group ///////////////////////////////////// Common ///////////////////////////////////////// + +/** + * @brief Enable the bus clock for the DMA module + */ +static inline void gdma_ll_enable_bus_clock(int group_id, bool enable) +{ + (void)group_id; + SYSTEM.perip_clk_en1.dma_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 gdma_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; gdma_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the DMA module + */ +static inline void gdma_ll_reset_register(int group_id) +{ + (void)group_id; + SYSTEM.perip_rst_en1.dma_rst = 1; + SYSTEM.perip_rst_en1.dma_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 gdma_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; gdma_ll_reset_register(__VA_ARGS__) + /** * @brief Force enable register clock */