Skip to content

Commit 6d89f1e

Browse files
committed
drivers: mcux_edma: refactor configure func more
Split this function up even more Signed-off-by: Declan Snyder <[email protected]>
1 parent 95e274b commit 6d89f1e

File tree

1 file changed

+124
-68
lines changed

1 file changed

+124
-68
lines changed

drivers/dma/dma_mcux_edma.c

Lines changed: 124 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,16 @@ static void dma_mcux_edma_multi_channels_irq_handler(const struct device *dev, u
280280

281281
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
282282
static void edma_configure_dmamux(const struct device *dev, uint32_t channel,
283-
struct dma_config *config, edma_transfer_type_t transfer_type)
283+
struct dma_config *config)
284284
{
285+
uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel);
286+
uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel);
285287
uint32_t slot = config->dma_slot;
286-
uint8_t dmamux_idx, dmamux_channel;
287-
288-
dmamux_idx = DEV_DMAMUX_IDX(dev, channel);
289-
dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel);
290288

291289
#if DT_INST_PROP(0, nxp_a_on)
290+
edma_transfer_type_t transfer_type = data->transfer_settings.transfer_type;
291+
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
292+
292293
if (config->source_handshake || config->dest_handshake ||
293294
transfer_type == kEDMA_MemoryToMemory) {
294295
/*software trigger make the channel always on*/
@@ -317,6 +318,22 @@ static void edma_log_dmamux(const struct device *dev, uint32_t channel)
317318
#define edma_log_dmamux(...)
318319
#endif /* FSL_FEATURE_SOC_DMA_MUX_COUNT */
319320

321+
static inline void dma_mcux_edma_configure_muxes(const struct device *dev, uint32_t channel,
322+
struct dma_config *config)
323+
{
324+
edma_configure_dmamux(dev, channel, config);
325+
326+
#if defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && FSL_FEATURE_EDMA_HAS_CHANNEL_MUX
327+
uint32_t slot = config->dma_slot;
328+
uint32_t hw_channel = dma_mcux_edma_add_channel_gap(dev, channel);
329+
330+
/* First release any peripheral previously associated with this channel */
331+
EDMA_SetChannelMux(DEV_BASE(dev), hw_channel, 0);
332+
EDMA_SetChannelMux(DEV_BASE(dev), hw_channel, slot);
333+
#endif
334+
}
335+
336+
320337
static int dma_mcux_edma_configure_sg_loop(const struct device *dev,
321338
uint32_t channel,
322339
struct dma_config *config,
@@ -471,24 +488,52 @@ static int dma_mcux_edma_configure_basic(const struct device *dev,
471488
return ret;
472489
}
473490

474-
/* Configure a channel */
475-
static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
476-
struct dma_config *config)
491+
static void dma_mcux_edma_configure_hardware(const struct device *dev, uint32_t channel,
492+
struct dma_config *config)
493+
{
494+
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
495+
edma_transfer_type_t transfer_type = data->transfer_settings.transfer_type;
496+
struct dma_block_config *block_config = config->head_block;
497+
bool sg_mode = block_config->source_gather_en || block_config->dest_scatter_en;
498+
uint32_t hw_channel = dma_mcux_edma_add_channel_gap(dev, channel);
499+
500+
dma_mcux_edma_configure_muxes(dev, channel, config);
501+
502+
if (sg_mode && config->cyclic) {
503+
dma_mcux_edma_configure_sg_loop(dev, channel, config, transfer_type);
504+
} else if (sg_mode) {
505+
dma_mcux_edma_configure_sg_dynamic(dev, channel, config, transfer_type);
506+
} else {
507+
dma_mcux_edma_configure_basic(dev, channel, config, transfer_type);
508+
}
509+
510+
if (config->dest_chaining_en) {
511+
LOG_DBG("link major channel %d", config->linked_channel);
512+
EDMA_SetChannelLink(DEV_BASE(dev), channel, kEDMA_MajorLink,
513+
config->linked_channel);
514+
}
515+
if (config->source_chaining_en) {
516+
LOG_DBG("link minor channel %d", config->linked_channel);
517+
EDMA_SetChannelLink(DEV_BASE(dev), channel, kEDMA_MinorLink,
518+
config->linked_channel);
519+
}
520+
521+
EDMA_EnableChannelInterrupts(DEV_BASE(dev), hw_channel, kEDMA_ErrorInterruptEnable);
522+
}
523+
524+
static inline int dma_mcux_edma_validate_cfg(const struct device *dev,
525+
uint32_t channel,
526+
struct dma_config *config)
477527
{
478528
/* Check for invalid parameters before dereferencing them. */
479529
if (NULL == dev || NULL == config) {
480530
return -EINVAL;
481531
}
482532

483-
uint32_t hw_channel = dma_mcux_edma_add_channel_gap(dev, channel);
484-
edma_handle_t *p_handle = DEV_EDMA_HANDLE(dev, channel);
485533
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
486534
struct dma_block_config *block_config = config->head_block;
487-
bool sg_mode = block_config->source_gather_en || block_config->dest_scatter_en;
488535
uint32_t slot = config->dma_slot;
489-
edma_transfer_type_t transfer_type;
490-
unsigned int key;
491-
int ret = 0;
536+
edma_transfer_type_t *type = &data->transfer_settings.transfer_type;
492537

493538
if (slot >= DEV_CFG(dev)->dma_requests) {
494539
LOG_ERR("source number is out of scope %d", slot);
@@ -499,27 +544,10 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
499544
LOG_ERR("out of DMA channel %d", channel);
500545
return -EINVAL;
501546
}
547+
LOG_DBG("channel is %d", channel);
502548

503549
data->transfer_settings.valid = false;
504550

505-
switch (config->channel_direction) {
506-
case MEMORY_TO_MEMORY:
507-
transfer_type = kEDMA_MemoryToMemory;
508-
break;
509-
case MEMORY_TO_PERIPHERAL:
510-
transfer_type = kEDMA_MemoryToPeripheral;
511-
break;
512-
case PERIPHERAL_TO_MEMORY:
513-
transfer_type = kEDMA_PeripheralToMemory;
514-
break;
515-
case PERIPHERAL_TO_PERIPHERAL:
516-
transfer_type = kEDMA_PeripheralToPeripheral;
517-
break;
518-
default:
519-
LOG_ERR("not support transfer direction");
520-
return -EINVAL;
521-
}
522-
523551
if (!data_size_valid(config->source_data_size)) {
524552
LOG_ERR("Source unit size error, %d", config->source_data_size);
525553
return -EINVAL;
@@ -537,60 +565,88 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
537565
}
538566
}
539567

540-
data->transfer_settings.source_data_size = config->source_data_size;
541-
data->transfer_settings.dest_data_size = config->dest_data_size;
542-
data->transfer_settings.source_burst_length = config->source_burst_length;
543-
data->transfer_settings.dest_burst_length = config->dest_burst_length;
544-
data->transfer_settings.direction = config->channel_direction;
545-
data->transfer_settings.transfer_type = transfer_type;
546-
data->transfer_settings.valid = true;
547-
data->transfer_settings.cyclic = config->cyclic;
568+
switch (config->channel_direction) {
569+
case MEMORY_TO_MEMORY:
570+
*type = kEDMA_MemoryToMemory;
571+
break;
572+
case MEMORY_TO_PERIPHERAL:
573+
*type = kEDMA_MemoryToPeripheral;
574+
break;
575+
case PERIPHERAL_TO_MEMORY:
576+
*type = kEDMA_PeripheralToMemory;
577+
break;
578+
case PERIPHERAL_TO_PERIPHERAL:
579+
*type = kEDMA_PeripheralToPeripheral;
580+
break;
581+
default:
582+
LOG_ERR("not support transfer direction");
583+
return -EINVAL;
584+
}
548585

549-
/* Lock and page in the channel configuration */
550-
key = irq_lock();
586+
return 0;
587+
}
588+
589+
/* fills out transfer settings struct based on api config */
590+
static inline void dma_mcux_edma_set_xfer_settings(const struct device *dev, uint32_t channel,
591+
struct dma_config *config)
592+
{
593+
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
594+
struct dma_mcux_channel_transfer_edma_settings *xfer_settings = &data->transfer_settings;
595+
596+
xfer_settings->source_burst_length = config->source_burst_length;
597+
xfer_settings->dest_burst_length = config->dest_burst_length;
598+
xfer_settings->source_data_size = config->source_data_size;
599+
xfer_settings->dest_data_size = config->dest_data_size;
600+
xfer_settings->direction = config->channel_direction;
601+
xfer_settings->valid = true;
602+
xfer_settings->cyclic = config->cyclic;
603+
}
551604

552-
edma_configure_dmamux(dev, channel, config, transfer_type);
605+
/* stops, resets, and creates new MCUX SDK handle for a channel */
606+
static inline void dma_mcux_edma_reset_channel(const struct device *dev, uint32_t channel)
607+
{
608+
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
609+
edma_handle_t *p_handle = DEV_EDMA_HANDLE(dev, channel);
610+
uint32_t hw_channel = dma_mcux_edma_add_channel_gap(dev, channel);
553611

554612
if (data->busy) {
555613
EDMA_AbortTransfer(p_handle);
556614
}
615+
557616
EDMA_ResetChannel(DEV_BASE(dev), hw_channel);
558617
EDMA_CreateHandle(p_handle, DEV_BASE(dev), hw_channel);
559618
EDMA_SetCallback(p_handle, nxp_edma_callback, (void *)data);
619+
}
560620

561-
#if defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && FSL_FEATURE_EDMA_HAS_CHANNEL_MUX
562-
/* First release any peripheral previously associated with this channel */
563-
EDMA_SetChannelMux(DEV_BASE(dev), hw_channel, 0);
564-
EDMA_SetChannelMux(DEV_BASE(dev), hw_channel, slot);
565-
#endif
566621

567-
LOG_DBG("channel is %d", channel);
568-
EDMA_EnableChannelInterrupts(DEV_BASE(dev), hw_channel, kEDMA_ErrorInterruptEnable);
622+
/* Configure a channel */
623+
static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
624+
struct dma_config *config)
625+
{
626+
unsigned int key;
627+
int ret = 0;
628+
629+
ret = dma_mcux_edma_validate_cfg(dev, channel, config);
630+
if (ret) {
631+
return ret;
632+
}
633+
634+
dma_mcux_edma_set_xfer_settings(dev, channel, config);
635+
636+
/* Lock and page in the channel configuration */
637+
key = irq_lock();
638+
639+
dma_mcux_edma_reset_channel(dev, channel);
569640

570641
/* Initialize all TCD pool as 0*/
571642
for (int i = 0; i < CONFIG_DMA_TCD_QUEUE_SIZE; i++) {
572643
memset(&DEV_CFG(dev)->tcdpool[channel][i], 0,
573644
sizeof(DEV_CFG(dev)->tcdpool[channel][i]));
574645
}
575646

576-
if (sg_mode && config->cyclic) {
577-
dma_mcux_edma_configure_sg_loop(dev, channel, config, transfer_type);
578-
} else if (sg_mode) {
579-
dma_mcux_edma_configure_sg_dynamic(dev, channel, config, transfer_type);
580-
} else {
581-
dma_mcux_edma_configure_basic(dev, channel, config, transfer_type);
582-
}
647+
dma_mcux_edma_configure_hardware(dev, channel, config);
583648

584-
if (config->dest_chaining_en) {
585-
LOG_DBG("link major channel %d", config->linked_channel);
586-
EDMA_SetChannelLink(DEV_BASE(dev), channel, kEDMA_MajorLink,
587-
config->linked_channel);
588-
}
589-
if (config->source_chaining_en) {
590-
LOG_DBG("link minor channel %d", config->linked_channel);
591-
EDMA_SetChannelLink(DEV_BASE(dev), channel, kEDMA_MinorLink,
592-
config->linked_channel);
593-
}
649+
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
594650

595651
data->busy = false;
596652
if (config->dma_callback) {
@@ -602,7 +658,7 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
602658

603659
irq_unlock(key);
604660

605-
return ret;
661+
return 0;
606662
}
607663

608664
static int dma_mcux_edma_start(const struct device *dev, uint32_t channel)

0 commit comments

Comments
 (0)