Skip to content

Commit 03b5ba5

Browse files
Dat-NguyenDuydleach02
authored andcommitted
drivers: dma_mcux_edma: add support for multiple DMAMuxes
This adds support for platforms that have multiple DMAMUXes per DMA instance Signed-off-by: Dat Nguyen Duy <dat.nguyenduy@nxp.com>
1 parent f27815d commit 03b5ba5

File tree

1 file changed

+51
-28
lines changed

1 file changed

+51
-28
lines changed

drivers/dma/dma_mcux_edma.c

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ LOG_MODULE_REGISTER(dma_mcux_edma, CONFIG_DMA_LOG_LEVEL);
3030

3131
struct dma_mcux_edma_config {
3232
DMA_Type *base;
33-
DMAMUX_Type *dmamux_base;
33+
DMAMUX_Type **dmamux_base;
34+
uint8_t channels_per_mux;
3435
int dma_channels; /* number of channels */
3536
void (*irq_config_func)(const struct device *dev);
3637
};
@@ -102,14 +103,16 @@ struct dma_mcux_edma_data {
102103
#define DEV_DATA(dev) ((struct dma_mcux_edma_data *)dev->data)
103104
#define DEV_BASE(dev) ((DMA_Type *)DEV_CFG(dev)->base)
104105

105-
#define DEV_DMAMUX_BASE(dev) ((DMAMUX_Type *)DEV_CFG(dev)->dmamux_base)
106-
107106
#define DEV_CHANNEL_DATA(dev, ch) \
108107
((struct call_back *)(&(DEV_DATA(dev)->data_cb[ch])))
109108

110109
#define DEV_EDMA_HANDLE(dev, ch) \
111110
((edma_handle_t *)(&(DEV_CHANNEL_DATA(dev, ch)->edma_handle)))
112111

112+
#define DEV_DMAMUX_BASE(dev, idx) ((DMAMUX_Type *)DEV_CFG(dev)->dmamux_base[idx])
113+
#define DEV_DMAMUX_IDX(dev, ch) (ch / DEV_CFG(dev)->channels_per_mux)
114+
#define DEV_DMAMUX_CHANNEL(dev, ch) (ch % DEV_CFG(dev)->channels_per_mux)
115+
113116
static bool data_size_valid(const size_t data_size)
114117
{
115118
return (data_size == 4U || data_size == 2U ||
@@ -188,6 +191,7 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
188191
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
189192
struct dma_block_config *block_config = config->head_block;
190193
uint32_t slot = config->dma_slot;
194+
uint8_t dmamux_idx, dmamux_channel;
191195
edma_transfer_type_t transfer_type;
192196
unsigned int key;
193197
int ret = 0;
@@ -202,6 +206,8 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
202206
return -EINVAL;
203207
}
204208

209+
dmamux_idx = DEV_DMAMUX_IDX(dev, channel);
210+
dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel);
205211
data->transfer_settings.valid = false;
206212

207213
switch (config->channel_direction) {
@@ -256,16 +262,16 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
256262
transfer_type == kEDMA_MemoryToMemory) {
257263
/*software trigger make the channel always on*/
258264
LOG_DBG("ALWAYS ON");
259-
DMAMUX_EnableAlwaysOn(DEV_DMAMUX_BASE(dev), channel, true);
265+
DMAMUX_EnableAlwaysOn(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel, true);
260266
} else {
261-
DMAMUX_SetSource(DEV_DMAMUX_BASE(dev), channel, slot);
267+
DMAMUX_SetSource(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel, slot);
262268
}
263269
#else
264-
DMAMUX_SetSource(DEV_DMAMUX_BASE(dev), channel, slot);
270+
DMAMUX_SetSource(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel, slot);
265271
#endif
266272

267273
/* dam_imx_rt_set_channel_priority(dev, channel, config); */
268-
DMAMUX_EnableChannel(DEV_DMAMUX_BASE(dev), channel);
274+
DMAMUX_EnableChannel(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel);
269275

270276
if (data->busy) {
271277
EDMA_AbortTransfer(p_handle);
@@ -345,9 +351,11 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
345351
static int dma_mcux_edma_start(const struct device *dev, uint32_t channel)
346352
{
347353
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
354+
uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel);
355+
uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel);
348356

349357
LOG_DBG("START TRANSFER");
350-
LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev)->CHCFG[channel]);
358+
LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]);
351359
LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR);
352360
data->busy = true;
353361
EDMA_StartTransfer(DEV_EDMA_HANDLE(dev, channel));
@@ -444,6 +452,8 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel,
444452
struct dma_status *status)
445453
{
446454
edma_tcd_t *tcdRegs;
455+
uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel);
456+
uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel);
447457

448458
if (DEV_CHANNEL_DATA(dev, channel)->busy) {
449459
status->busy = true;
@@ -454,7 +464,7 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel,
454464
status->pending_length = 0;
455465
}
456466
status->dir = DEV_CHANNEL_DATA(dev, channel)->transfer_settings.direction;
457-
LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev)->CHCFG[channel]);
467+
LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]);
458468
LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR);
459469
LOG_DBG("DMA INT 0x%x", DEV_BASE(dev)->INT);
460470
LOG_DBG("DMA ERQ 0x%x", DEV_BASE(dev)->ERQ);
@@ -496,9 +506,14 @@ static int dma_mcux_edma_init(const struct device *dev)
496506
struct dma_mcux_edma_data *data = dev->data;
497507

498508
edma_config_t userConfig = { 0 };
509+
uint8_t i;
499510

500511
LOG_DBG("INIT NXP EDMA");
501-
DMAMUX_Init(DEV_DMAMUX_BASE(dev));
512+
513+
for (i = 0; i < config->dma_channels / config->channels_per_mux; i++) {
514+
DMAMUX_Init(DEV_DMAMUX_BASE(dev, i));
515+
}
516+
502517
EDMA_GetDefaultConfig(&userConfig);
503518
EDMA_Init(DEV_BASE(dev), &userConfig);
504519
config->irq_config_func(dev);
@@ -546,27 +561,35 @@ static int dma_mcux_edma_init(const struct device *dev)
546561
LOG_DBG("install irq done"); \
547562
}
548563

564+
#define DMA_MCUX_EDMA_MUX(idx, n) \
565+
(DMAMUX_Type *)DT_INST_REG_ADDR_BY_IDX(n, UTIL_INC(idx))
566+
549567
/*
550568
* define the dma
551569
*/
552-
#define DMA_INIT(n) \
553-
static void dma_imx_config_func_##n(const struct device *dev); \
554-
static const struct dma_mcux_edma_config dma_config_##n = { \
555-
.base = (DMA_Type *)DT_INST_REG_ADDR(n), \
556-
.dmamux_base = \
557-
(DMAMUX_Type *)DT_INST_REG_ADDR_BY_IDX(n, 1), \
558-
.dma_channels = DT_INST_PROP(n, dma_channels), \
559-
.irq_config_func = dma_imx_config_func_##n, \
560-
}; \
561-
\
562-
struct dma_mcux_edma_data dma_data_##n; \
563-
\
564-
DEVICE_DT_INST_DEFINE(n, \
565-
&dma_mcux_edma_init, NULL, \
566-
&dma_data_##n, &dma_config_##n, \
567-
PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, \
568-
&dma_mcux_edma_api); \
569-
\
570+
#define DMA_INIT(n) \
571+
static void dma_imx_config_func_##n(const struct device *dev); \
572+
static DMAMUX_Type *dmamux_base_##n[] = { \
573+
LISTIFY(UTIL_DEC(DT_NUM_REGS(DT_DRV_INST(n))), \
574+
DMA_MCUX_EDMA_MUX, (,), n) \
575+
}; \
576+
static const struct dma_mcux_edma_config dma_config_##n = { \
577+
.base = (DMA_Type *)DT_INST_REG_ADDR(n), \
578+
.dmamux_base = &dmamux_base_##n[0], \
579+
.dma_channels = DT_INST_PROP(n, dma_channels), \
580+
.channels_per_mux = DT_INST_PROP(n, dma_channels) / \
581+
ARRAY_SIZE(dmamux_base_##n), \
582+
.irq_config_func = dma_imx_config_func_##n, \
583+
}; \
584+
\
585+
struct dma_mcux_edma_data dma_data_##n; \
586+
\
587+
DEVICE_DT_INST_DEFINE(n, \
588+
&dma_mcux_edma_init, NULL, \
589+
&dma_data_##n, &dma_config_##n, \
590+
PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, \
591+
&dma_mcux_edma_api); \
592+
\
570593
DMA_MCUX_EDMA_CONFIG_FUNC(n);
571594

572595
DT_INST_FOREACH_STATUS_OKAY(DMA_INIT)

0 commit comments

Comments
 (0)