feat(gdma): support lp ahb dma on esp32s31

This commit is contained in:
Chen Jichang
2026-01-19 11:30:49 +08:00
committed by morris
parent 1535ac2b0a
commit 7656e0935e
18 changed files with 400 additions and 54 deletions

View File

@@ -47,6 +47,18 @@ const gdma_signal_conn_t gdma_periph_signals = {
.tx_irq_id = ETS_AXI_PDMA_OUT_CH2_INTR_SOURCE,
}
}
},
[2] = {
.pairs = {
[0] = {
.rx_irq_id = ETS_LP_AHB_PDMA_IN_CH0_INTR_SOURCE,
.tx_irq_id = ETS_LP_AHB_PDMA_OUT_CH0_INTR_SOURCE,
},
[1] = {
.rx_irq_id = ETS_LP_AHB_PDMA_IN_CH1_INTR_SOURCE,
.tx_irq_id = ETS_LP_AHB_PDMA_OUT_CH1_INTR_SOURCE,
}
}
}
}
};

View File

@@ -18,10 +18,11 @@
extern "C" {
#endif
#define AHB_DMA_LL_GET_HW(id) (((id) == 0) ? (&AHB_DMA) : NULL)
#define AHB_DMA_LL_GET_HW(id) (((id) == 0) ? (&AHB_DMA) : (((id) == 2) ? ((ahb_dma_dev_t *)&LP_AHB_DMA) : NULL))
// any "dummy" peripheral ID can be used for M2M mode
#define AHB_DMA_LL_M2M_FREE_PERIPH_ID_MASK (0x8200)
#define LP_AHB_DMA_LL_M2M_FREE_PERIPH_ID_MASK (0xFFFC)
///////////////////////////////////// Common /////////////////////////////////////////
@@ -67,6 +68,17 @@ static inline void ahb_dma_ll_set_default_memory_range(ahb_dma_dev_t *dev)
dev->intr_mem_end_addr.val = 0x53FFFFFF;
}
/**
* @brief Preset valid memory range for LP_AHB-DMA
* @param dev DMA register base address
*/
static inline void lp_ahb_dma_ll_set_default_memory_range(ahb_dma_dev_t *dev)
{
// LP_AHB-DMA can access LPMEM, SRAM, ROM, MSPI Flash, MSPI PSRAM
dev->intr_mem_start_addr.val = 0x2E000000;
dev->intr_mem_end_addr.val = 0x53FFFFFF;
}
///////////////////////////////////// RX /////////////////////////////////////////
/**
* @brief Get DMA RX channel interrupt status word

View File

@@ -9,20 +9,21 @@
#include <stdbool.h>
#include <sys/param.h>
#include "soc/hp_sys_clkrst_struct.h"
#include "soc/lp_peri_clkrst_struct.h"
#include "soc/soc_etm_source.h"
#define GDMA_LL_GET(_attr) GDMA_LL_ ## _attr
#define GDMA_LL_INST_NUM 2
#define GDMA_LL_INST_NUM 3
#define GDMA_LL_PAIRS_PER_INST MAX(GDMA_LL_AHB_PAIRS_PER_GROUP, GDMA_LL_AXI_PAIRS_PER_GROUP)
#define GDMA_LL_PAIRS_PER_INST MAX(MAX(GDMA_LL_AHB_PAIRS_PER_GROUP, GDMA_LL_AXI_PAIRS_PER_GROUP), GDMA_LL_LP_AHB_PAIRS_PER_GROUP)
#define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5]
#define GDMA_LL_RX_EVENT_MASK (0x7F)
#define GDMA_LL_TX_EVENT_MASK (0x3F)
// the following event bits are identical for ahb-dma and axi-dma
// the following event bits are identical for ahb-dma, axi-dma and lp-ahb-dma
#define GDMA_LL_EVENT_TX_FIFO_UDF (1<<5)
#define GDMA_LL_EVENT_TX_FIFO_OVF (1<<4)
#define GDMA_LL_EVENT_TX_TOTAL_EOF (1<<3)
@@ -45,8 +46,13 @@
#define GDMA_LL_AXI_NUM_GROUPS 1 // Number of AXI GDMA groups
#define GDMA_LL_AXI_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AXI group
#define GDMA_LL_LP_AHB_GROUP_START_ID 2 // LP AHB GDMA group ID starts from 2
#define GDMA_LL_LP_AHB_NUM_GROUPS 1 // Number of LP AHB GDMA groups
#define GDMA_LL_LP_AHB_PAIRS_PER_GROUP 2 // Number of GDMA pairs in each LP AHB group
#define GDMA_LL_AHB_PSRAM_CAPABLE 1
#define GDMA_LL_AXI_PSRAM_CAPABLE 1
#define GDMA_LL_LP_AHB_PSRAM_CAPABLE 1
#define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size
#define GDMA_LL_AHB_DESC_ALIGNMENT 4
@@ -56,45 +62,58 @@
#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x1F // pair 0,1,2,3,4 are M2M capable
#define GDMA_LL_AXI_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable
#define GDMA_LL_LP_AHB_M2M_CAPABLE_PAIR_MASK 0x03 // pair 0,1 are M2M capable
#define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \
(uint32_t[2][GDMA_ETM_EVENT_MAX]){ \
{ \
[GDMA_ETM_EVENT_EOF] = PDMA_AHB_EVT_OUT_EOF_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_EVENT_EOF] = PDMA_AXI_EVT_OUT_EOF_CH0 + (chan), \
}, \
}[group][event]
#define GDMA_LL_RX_ETM_EVENT_TABLE(group, chan, event) \
(uint32_t[2][GDMA_ETM_EVENT_MAX]){ \
#define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \
(uint32_t[GDMA_LL_INST_NUM][GDMA_ETM_EVENT_MAX]){ \
{ \
[GDMA_ETM_EVENT_EOF] = PDMA_AHB_EVT_IN_SUC_EOF_CH0 + (chan), \
[GDMA_ETM_EVENT_EOF] = PDMA_AHB_EVT_OUT_EOF_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_EVENT_EOF] = PDMA_AXI_EVT_IN_SUC_EOF_CH0 + (chan), \
[GDMA_ETM_EVENT_EOF] = PDMA_AXI_EVT_OUT_EOF_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_EVENT_EOF] = LP_PDMA_AHB_EVT_OUT_EOF_CH0 + (chan), \
}, \
}[group][event]
#define GDMA_LL_TX_ETM_TASK_TABLE(group, chan, task) \
(uint32_t[2][GDMA_ETM_TASK_MAX]){ \
{ \
[GDMA_ETM_TASK_START] = PDMA_AHB_TASK_OUT_START_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_TASK_START] = PDMA_AXI_TASK_OUT_START_CH0 + (chan), \
}, \
#define GDMA_LL_RX_ETM_EVENT_TABLE(group, chan, event) \
(uint32_t[GDMA_LL_INST_NUM][GDMA_ETM_EVENT_MAX]){ \
{ \
[GDMA_ETM_EVENT_EOF] = PDMA_AHB_EVT_IN_SUC_EOF_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_EVENT_EOF] = PDMA_AXI_EVT_IN_SUC_EOF_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_EVENT_EOF] = LP_PDMA_AHB_EVT_IN_SUC_EOF_CH0 + (chan), \
}, \
}[group][event]
#define GDMA_LL_TX_ETM_TASK_TABLE(group, chan, task) \
(uint32_t[GDMA_LL_INST_NUM][GDMA_ETM_TASK_MAX]){ \
{ \
[GDMA_ETM_TASK_START] = PDMA_AHB_TASK_OUT_START_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_TASK_START] = PDMA_AXI_TASK_OUT_START_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_TASK_START] = LP_PDMA_AHB_TASK_OUT_START_CH0 + (chan), \
}, \
}[group][task]
#define GDMA_LL_RX_ETM_TASK_TABLE(group, chan, task) \
(uint32_t[2][GDMA_ETM_TASK_MAX]){ \
{ \
[GDMA_ETM_TASK_START] = PDMA_AHB_TASK_IN_START_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_TASK_START] = PDMA_AXI_TASK_IN_START_CH0 + (chan), \
}, \
#define GDMA_LL_RX_ETM_TASK_TABLE(group, chan, task) \
(uint32_t[GDMA_LL_INST_NUM][GDMA_ETM_TASK_MAX]){ \
{ \
[GDMA_ETM_TASK_START] = PDMA_AHB_TASK_IN_START_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_TASK_START] = PDMA_AXI_TASK_IN_START_CH0 + (chan), \
}, \
{ \
[GDMA_ETM_TASK_START] = LP_PDMA_AHB_TASK_IN_START_CH0 + (chan), \
}, \
}[group][task]
#ifdef __cplusplus
@@ -108,8 +127,10 @@ static inline void gdma_ll_enable_bus_clock(int group_id, bool enable)
{
if (group_id == 0) {
HP_SYS_CLKRST.ahb_pdma_ctrl0.reg_ahb_pdma_sys_clk_en = enable;
} else {
} else if (group_id == 1) {
HP_SYS_CLKRST.axi_pdma_ctrl0.reg_axi_pdma_sys_clk_en = enable;
} else { // group_id == 2, LP AHB GDMA
LP_PERI_CLKRST.ahb_dma_ctrl.lp_ahb_dma_clk_en = enable;
}
}
@@ -121,9 +142,12 @@ static inline void _gdma_ll_reset_register(int group_id)
if (group_id == 0) {
HP_SYS_CLKRST.ahb_pdma_ctrl0.reg_ahb_pdma_rst_en = 1;
HP_SYS_CLKRST.ahb_pdma_ctrl0.reg_ahb_pdma_rst_en = 0;
} else {
} else if (group_id == 1) {
HP_SYS_CLKRST.axi_pdma_ctrl0.reg_axi_pdma_rst_en = 1;
HP_SYS_CLKRST.axi_pdma_ctrl0.reg_axi_pdma_rst_en = 0;
} else {
LP_PERI_CLKRST.ahb_dma_ctrl.lp_ahb_dma_rst_en = 1;
LP_PERI_CLKRST.ahb_dma_ctrl.lp_ahb_dma_rst_en = 0;
}
}