@@ -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
282282static 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+ struct call_back * data = DEV_CHANNEL_DATA (dev , channel );
291+ edma_transfer_type_t transfer_type = data -> transfer_settings .transfer_type ;
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+
320337static 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
608664static int dma_mcux_edma_start (const struct device * dev , uint32_t channel )
0 commit comments