This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 5b7d69307c722176fc2f6bf19fc0406a30275e98
Author: Jukka Laitinen <[email protected]>
AuthorDate: Tue Sep 1 15:28:08 2026 +0300

    arch/arm/imxrt: Add iMXRT118x capable eDMA driver
    
    - Add driver supporting the DMA3 and DMA4 in iMXRT118x chips. The driver is 
first copied
      from imx93, and then changed just the relevant parts (function names, 
clocking and
      irq handling) to match the imx118x configuration.
    - Add the DMA channel numbering in hardware/rt118x/imxrt118x_dmamux.h from 
RM
      by claude.
    
    Assisted-by: Claude Code:claude-opus-4-7
    Signed-off-by: Jukka Laitinen <[email protected]>
---
 arch/arm/src/imxrt/CMakeLists.txt                  |    6 +-
 arch/arm/src/imxrt/Kconfig                         |    8 +
 arch/arm/src/imxrt/Make.defs                       |    4 +
 arch/arm/src/imxrt/hardware/imxrt_dmamux.h         |    2 +
 .../src/imxrt/hardware/rt118x/imxrt118x_dmamux.h   |  329 +++++
 .../arm/src/imxrt/hardware/rt118x/imxrt118x_edma.h |  444 ++++++
 arch/arm/src/imxrt/imxrt_edma.h                    |   29 +-
 arch/arm/src/imxrt/imxrt_edma_ver2.c               | 1529 ++++++++++++++++++++
 8 files changed, 2347 insertions(+), 4 deletions(-)

diff --git a/arch/arm/src/imxrt/CMakeLists.txt 
b/arch/arm/src/imxrt/CMakeLists.txt
index aeb4e487941..f16722d8def 100644
--- a/arch/arm/src/imxrt/CMakeLists.txt
+++ b/arch/arm/src/imxrt/CMakeLists.txt
@@ -96,7 +96,11 @@ if(CONFIG_BUILD_PROTECTED)
 endif()
 
 if(CONFIG_IMXRT_EDMA)
-  list(APPEND SRCS imxrt_edma.c)
+  if(CONFIG_IMXRT_EDMA_VER2)
+    list(APPEND SRCS imxrt_edma_ver2.c)
+  else()
+    list(APPEND SRCS imxrt_edma.c)
+  endif()
 endif()
 
 if(CONFIG_IMXRT_USDHC)
diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig
index 072575db570..384e6affb6c 100644
--- a/arch/arm/src/imxrt/Kconfig
+++ b/arch/arm/src/imxrt/Kconfig
@@ -237,6 +237,7 @@ config ARCH_FAMILY_IMXRT118x
        select IMXRT_CLOCKCONFIG_VER3
        select IMXRT_IOMUX_VER3
        select IMXRT_RGPIO
+       select IMXRT_EDMA_VER2
        ---help---
                i.MX RT1180 dual-core Crossover Processors (Cortex-M33 + 
Cortex-M7).
 
@@ -432,6 +433,13 @@ config IMXRT_RGPIO
                Selects the RGPIO driver (arch/arm/src/imxrt/imxrt_rgpio.c) that
                targets the RGPIO IP block used on RT118x.
 
+config IMXRT_EDMA_VER2
+       bool
+       default n
+       ---help---
+               Selects the RT118x eDMA driver variant
+               (arch/arm/src/imxrt/imxrt_edma_ver2.c) used by RT118x.
+
 config IMXRT_TRDC
        bool
        default n
diff --git a/arch/arm/src/imxrt/Make.defs b/arch/arm/src/imxrt/Make.defs
index 84d74cd4b23..67d7aff3a3f 100644
--- a/arch/arm/src/imxrt/Make.defs
+++ b/arch/arm/src/imxrt/Make.defs
@@ -92,8 +92,12 @@ CHIP_CSRCS += imxrt_userspace.c
 endif
 
 ifeq ($(CONFIG_IMXRT_EDMA),y)
+ifeq ($(CONFIG_IMXRT_EDMA_VER2),y)
+CHIP_CSRCS += imxrt_edma_ver2.c
+else
 CHIP_CSRCS += imxrt_edma.c
 endif
+endif
 
 ifdef CONFIG_IMXRT_USDHC
 CHIP_CSRCS += imxrt_usdhc.c
diff --git a/arch/arm/src/imxrt/hardware/imxrt_dmamux.h 
b/arch/arm/src/imxrt/hardware/imxrt_dmamux.h
index 70742bcd236..03b43b154b5 100644
--- a/arch/arm/src/imxrt/hardware/imxrt_dmamux.h
+++ b/arch/arm/src/imxrt/hardware/imxrt_dmamux.h
@@ -39,6 +39,8 @@
 #elif defined(CONFIG_ARCH_FAMILY_IMXRT117x)
 #  include "hardware/rt117x/imxrt117x_dmamux.h"
 #define IMXRT_DMAMUX_BASE IMXRT_DMAMUX0_BASE
+#elif defined(CONFIG_ARCH_FAMILY_IMXRT118x)
+#  include "hardware/rt118x/imxrt118x_dmamux.h"
 #else
 #  error Unrecognized i.MX RT architecture
 #endif
diff --git a/arch/arm/src/imxrt/hardware/rt118x/imxrt118x_dmamux.h 
b/arch/arm/src/imxrt/hardware/rt118x/imxrt118x_dmamux.h
new file mode 100644
index 00000000000..3dc5519ba40
--- /dev/null
+++ b/arch/arm/src/imxrt/hardware/rt118x/imxrt118x_dmamux.h
@@ -0,0 +1,329 @@
+/****************************************************************************
+ * arch/arm/src/imxrt/hardware/rt118x/imxrt118x_dmamux.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_DMAMUX_H
+#define __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_DMAMUX_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+
+#include "hardware/imxrt_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* eDMA3/eDMA4 request source constants (IMXRT1180RM Ch. 5) */
+
+#define IMXRT_DMA_ENGINE_EDMA3       (0)
+#define IMXRT_DMA_ENGINE_EDMA4       (1)
+
+#define IMXRT_DMA_SRC_ENGINE_SHIFT   (8)
+#define IMXRT_DMA_SRC_ENGINE_MASK    (0xff << IMXRT_DMA_SRC_ENGINE_SHIFT)
+#define IMXRT_DMA_SRC_MUX_SHIFT      (0)
+#define IMXRT_DMA_SRC_MUX_MASK       (0xff << IMXRT_DMA_SRC_MUX_SHIFT)
+#define EDMA_MUX_MASK                IMXRT_DMA_SRC_MUX_MASK
+
+#define IMXRT_DMA_SRC(_engine, _mux) \
+  (((_engine) << IMXRT_DMA_SRC_ENGINE_SHIFT) | \
+   ((_mux) << IMXRT_DMA_SRC_MUX_SHIFT))
+
+#define IMXRT_DMA_SRC_ENGINE(_v) \
+  (((_v) & IMXRT_DMA_SRC_ENGINE_MASK) >> IMXRT_DMA_SRC_ENGINE_SHIFT)
+#define IMXRT_DMA_SRC_MUX(_v) \
+  (((_v) & IMXRT_DMA_SRC_MUX_MASK) >> IMXRT_DMA_SRC_MUX_SHIFT)
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+static inline uintptr_t imxrt_dmamux_get_dmabase(uint16_t dmamux)
+{
+  return (IMXRT_DMA_SRC_ENGINE(dmamux) == IMXRT_DMA_ENGINE_EDMA3) ?
+         IMXRT_DMA3_BASE : IMXRT_DMA4_BASE;
+}
+
+#endif /* __ASSEMBLY__ */
+
+/* eDMA3 (AONMIX) request sources */
+
+#define IMXRT_DMACHAN_CAN1                            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 1)
+#define IMXRT_DMACHAN_GPIO1_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 3)
+#define IMXRT_DMACHAN_GPIO1_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 4)
+#define IMXRT_DMACHAN_I3_C1_TO_BUS_REQUEST            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 5)
+#define IMXRT_DMACHAN_I3_C1_FROM_BUS_REQUEST          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 6)
+#define IMXRT_DMACHAN_LPI2_C1_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 7)
+#define IMXRT_DMACHAN_LPI2_C1_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 8)
+#define IMXRT_DMACHAN_LPI2_C2_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 9)
+#define IMXRT_DMACHAN_LPI2_C2_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 10)
+#define IMXRT_DMACHAN_LPSPI1_TX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 11)
+#define IMXRT_DMACHAN_LPSPI1_RX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 12)
+#define IMXRT_DMACHAN_LPSPI2_TX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 13)
+#define IMXRT_DMACHAN_LPSPI2_RX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 14)
+#define IMXRT_DMACHAN_LPTMR1_REQUEST                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 15)
+#define IMXRT_DMACHAN_LPUART1_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 16)
+#define IMXRT_DMACHAN_LPUART1_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 17)
+#define IMXRT_DMACHAN_LPUART2_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 18)
+#define IMXRT_DMACHAN_LPUART2_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 19)
+#define IMXRT_DMACHAN_EDGELOCK_REQUEST                
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 20)
+#define IMXRT_DMACHAN_SAI1_TX                         
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 21)
+#define IMXRT_DMACHAN_SAI1_RX                         
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 22)
+#define IMXRT_DMACHAN_TPM1_REQUEST0_REQUEST2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 23)
+#define IMXRT_DMACHAN_TPM1_REQUEST1_REQUEST3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 24)
+#define IMXRT_DMACHAN_TPM1_OVERFLOW_REQUEST           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 25)
+#define IMXRT_DMACHAN_TPM2_REQUEST0_REQUEST2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 26)
+#define IMXRT_DMACHAN_TPM2_REQUEST1_REQUEST3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 27)
+#define IMXRT_DMACHAN_TPM2_OVERFLOW_REQUEST           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 28)
+#define IMXRT_DMACHAN_LPUART7_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 29)
+#define IMXRT_DMACHAN_LPUART7_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 30)
+#define IMXRT_DMACHAN_FLEX_SPI2_TX                    
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 33)
+#define IMXRT_DMACHAN_FLEX_SPI2_RX                    
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 34)
+#define IMXRT_DMACHAN_CAN3                            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 38)
+#define IMXRT_DMACHAN_LPUART12_TX                     
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 31)
+#define IMXRT_DMACHAN_LPUART12_RX                     
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA3, 32)
+
+/* eDMA4 (WAKEUPMIX / MEGAMIX) request sources */
+
+#define IMXRT_DMACHAN_GPIO2_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 2)
+#define IMXRT_DMACHAN_GPIO2_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 3)
+#define IMXRT_DMACHAN_GPIO3_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 4)
+#define IMXRT_DMACHAN_GPIO3_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 5)
+#define IMXRT_DMACHAN_I3_C2_TO_BUS_REQUEST            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 6)
+#define IMXRT_DMACHAN_I3_C2_FROM_BUS_REQUEST          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 7)
+#define IMXRT_DMACHAN_LPI2_C3_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 8)
+#define IMXRT_DMACHAN_LPI2_C3_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 9)
+#define IMXRT_DMACHAN_LPI2_C4_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 10)
+#define IMXRT_DMACHAN_LPI2_C4_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 11)
+#define IMXRT_DMACHAN_LPSPI3_TX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 12)
+#define IMXRT_DMACHAN_LPSPI3_RX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 13)
+#define IMXRT_DMACHAN_LPSPI4_TX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 14)
+#define IMXRT_DMACHAN_LPSPI4_RX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 15)
+#define IMXRT_DMACHAN_LPUART3_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 17)
+#define IMXRT_DMACHAN_LPUART3_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 18)
+#define IMXRT_DMACHAN_LPUART4_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 19)
+#define IMXRT_DMACHAN_LPUART4_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 20)
+#define IMXRT_DMACHAN_LPUART5_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 21)
+#define IMXRT_DMACHAN_LPUART5_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 22)
+#define IMXRT_DMACHAN_LPUART6_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 23)
+#define IMXRT_DMACHAN_LPUART6_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 24)
+#define IMXRT_DMACHAN_TPM3_REQUEST0_REQUEST2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 25)
+#define IMXRT_DMACHAN_TPM3_REQUEST1_REQUEST3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 26)
+#define IMXRT_DMACHAN_TPM3_OVERFLOW_REQUEST           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 27)
+#define IMXRT_DMACHAN_FLEX_IO1_REQUEST0               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 37)
+#define IMXRT_DMACHAN_FLEX_IO1_REQUEST1               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 38)
+#define IMXRT_DMACHAN_FLEX_IO1_REQUEST2               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 39)
+#define IMXRT_DMACHAN_FLEX_IO1_REQUEST3               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 40)
+#define IMXRT_DMACHAN_FLEX_IO1_REQUEST4               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 41)
+#define IMXRT_DMACHAN_FLEX_IO1_REQUEST5               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 42)
+#define IMXRT_DMACHAN_FLEX_IO1_REQUEST6               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 43)
+#define IMXRT_DMACHAN_FLEX_IO1_REQUEST7               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 44)
+#define IMXRT_DMACHAN_FLEX_IO2_REQUEST0               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 45)
+#define IMXRT_DMACHAN_FLEX_IO2_REQUEST1               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 46)
+#define IMXRT_DMACHAN_FLEX_IO2_REQUEST2               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 47)
+#define IMXRT_DMACHAN_FLEX_IO2_REQUEST3               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 48)
+#define IMXRT_DMACHAN_FLEX_IO2_REQUEST4               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 49)
+#define IMXRT_DMACHAN_FLEX_IO2_REQUEST5               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 50)
+#define IMXRT_DMACHAN_FLEX_IO2_REQUEST6               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 51)
+#define IMXRT_DMACHAN_FLEX_IO2_REQUEST7               
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 52)
+#define IMXRT_DMACHAN_FLEX_SPI1_TX                    
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 53)
+#define IMXRT_DMACHAN_FLEX_SPI1_RX                    
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 54)
+#define IMXRT_DMACHAN_ADC1_REQUEST0                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 57)
+#define IMXRT_DMACHAN_FLEX_PWM3_CAPTURE_SUB0          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 74)
+#define IMXRT_DMACHAN_FLEX_PWM3_CAPTURE_SUB1          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 75)
+#define IMXRT_DMACHAN_FLEX_PWM3_CAPTURE_SUB2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 76)
+#define IMXRT_DMACHAN_FLEX_PWM3_CAPTURE_SUB3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 77)
+#define IMXRT_DMACHAN_FLEX_PWM3_VALUE_SUB0            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 78)
+#define IMXRT_DMACHAN_FLEX_PWM3_VALUE_SUB1            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 79)
+#define IMXRT_DMACHAN_FLEX_PWM3_VALUE_SUB2            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 80)
+#define IMXRT_DMACHAN_FLEX_PWM3_VALUE_SUB3            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 81)
+#define IMXRT_DMACHAN_FLEX_PWM4_CAPTURE_SUB0          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 82)
+#define IMXRT_DMACHAN_FLEX_PWM4_CAPTURE_SUB1          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 83)
+#define IMXRT_DMACHAN_FLEX_PWM4_CAPTURE_SUB2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 84)
+#define IMXRT_DMACHAN_FLEX_PWM4_CAPTURE_SUB3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 85)
+#define IMXRT_DMACHAN_FLEX_PWM4_VALUE_SUB0            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 86)
+#define IMXRT_DMACHAN_FLEX_PWM4_VALUE_SUB1            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 87)
+#define IMXRT_DMACHAN_FLEX_PWM4_VALUE_SUB2            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 88)
+#define IMXRT_DMACHAN_FLEX_PWM4_VALUE_SUB3            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 89)
+#define IMXRT_DMACHAN_QTIMER1_CAPT_TIMER0             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 90)
+#define IMXRT_DMACHAN_QTIMER1_CAPT_TIMER1             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 91)
+#define IMXRT_DMACHAN_QTIMER1_CAPT_TIMER2             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 92)
+#define IMXRT_DMACHAN_QTIMER1_CAPT_TIMER3             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 93)
+#define IMXRT_DMACHAN_QTIMER1_CMPLD1_TIMER0_CMPLD2_TIMER1 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 94)
+#define IMXRT_DMACHAN_QTIMER1_CMPLD1_TIMER1_CMPLD2_TIMER0 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 95)
+#define IMXRT_DMACHAN_QTIMER1_CMPLD1_TIMER2_CMPLD2_TIMER3 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 96)
+#define IMXRT_DMACHAN_QTIMER1_CMPLD1_TIMER3_CMPLD2_TIMER2 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 97)
+#define IMXRT_DMACHAN_QTIMER2_CAPT_TIMER0             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 98)
+#define IMXRT_DMACHAN_QTIMER2_CAPT_TIMER1             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 99)
+#define IMXRT_DMACHAN_QTIMER2_CAPT_TIMER2             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 100)
+#define IMXRT_DMACHAN_QTIMER2_CAPT_TIMER3             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 101)
+#define IMXRT_DMACHAN_QTIMER2_CMPLD1_TIMER0_CMPLD2_TIMER1 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 102)
+#define IMXRT_DMACHAN_QTIMER2_CMPLD1_TIMER1_CMPLD2_TIMER0 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 103)
+#define IMXRT_DMACHAN_QTIMER2_CMPLD1_TIMER2_CMPLD2_TIMER3 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 104)
+#define IMXRT_DMACHAN_QTIMER2_CMPLD1_TIMER3_CMPLD2_TIMER2 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 105)
+#define IMXRT_DMACHAN_QTIMER3_CAPT_TIMER0             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 106)
+#define IMXRT_DMACHAN_QTIMER3_CAPT_TIMER1             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 107)
+#define IMXRT_DMACHAN_QTIMER3_CAPT_TIMER2             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 108)
+#define IMXRT_DMACHAN_QTIMER3_CAPT_TIMER3             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 109)
+#define IMXRT_DMACHAN_QTIMER3_CMPLD1_TIMER0_CMPLD2_TIMER1 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 110)
+#define IMXRT_DMACHAN_QTIMER3_CMPLD1_TIMER1_CMPLD2_TIMER0 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 111)
+#define IMXRT_DMACHAN_QTIMER3_CMPLD1_TIMER2_CMPLD2_TIMER3 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 112)
+#define IMXRT_DMACHAN_QTIMER3_CMPLD1_TIMER3_CMPLD2_TIMER2 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 113)
+#define IMXRT_DMACHAN_QTIMER4_CAPT_TIMER0             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 114)
+#define IMXRT_DMACHAN_QTIMER4_CAPT_TIMER1             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 115)
+#define IMXRT_DMACHAN_QTIMER4_CAPT_TIMER2             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 116)
+#define IMXRT_DMACHAN_QTIMER4_CAPT_TIMER3             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 117)
+#define IMXRT_DMACHAN_QTIMER4_CMPLD1_TIMER0_CMPLD2_TIMER1 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 118)
+#define IMXRT_DMACHAN_QTIMER4_CMPLD1_TIMER1_CMPLD2_TIMER0 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 119)
+#define IMXRT_DMACHAN_QTIMER4_CMPLD1_TIMER2_CMPLD2_TIMER3 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 120)
+#define IMXRT_DMACHAN_QTIMER4_CMPLD1_TIMER3_CMPLD2_TIMER2 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 121)
+#define IMXRT_DMACHAN_XBAR1_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 154)
+#define IMXRT_DMACHAN_XBAR1_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 155)
+#define IMXRT_DMACHAN_XBAR1_REQUEST2                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 156)
+#define IMXRT_DMACHAN_XBAR1_REQUEST3                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 157)
+#define IMXRT_DMACHAN_ADC2_REQUEST0                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 158)
+#define IMXRT_DMACHAN_EQDC1                           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 159)
+#define IMXRT_DMACHAN_EQDC2                           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 160)
+#define IMXRT_DMACHAN_EQDC3                           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 161)
+#define IMXRT_DMACHAN_EQDC4                           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 162)
+#define IMXRT_DMACHAN_LPI2_C5_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 163)
+#define IMXRT_DMACHAN_LPI2_C5_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 164)
+#define IMXRT_DMACHAN_LPSPI5_TX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 167)
+#define IMXRT_DMACHAN_LPSPI5_RX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 168)
+#define IMXRT_DMACHAN_LPSPI6_TX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 169)
+#define IMXRT_DMACHAN_LPSPI6_RX                       
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 170)
+#define IMXRT_DMACHAN_LPUART8_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 178)
+#define IMXRT_DMACHAN_LPUART8_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 179)
+#define IMXRT_DMACHAN_DAC                             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 186)
+#define IMXRT_DMACHAN_CMP3                            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 189)
+#define IMXRT_DMACHAN_ASRC_REQUEST1                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 191)
+#define IMXRT_DMACHAN_ASRC_REQUEST2                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 192)
+#define IMXRT_DMACHAN_ASRC_REQUEST3                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 193)
+#define IMXRT_DMACHAN_ASRC_REQUEST4                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 194)
+#define IMXRT_DMACHAN_ASRC_REQUEST5                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 195)
+#define IMXRT_DMACHAN_ASRC_REQUEST6                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 196)
+#define IMXRT_DMACHAN_SPDIF_RX                        
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 197)
+#define IMXRT_DMACHAN_SPDIF_TX                        
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 198)
+#define IMXRT_DMACHAN_PDM_RX                          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 199)
+#define IMXRT_DMACHAN_GPIO4_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 200)
+#define IMXRT_DMACHAN_GPIO4_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 201)
+#define IMXRT_DMACHAN_GPIO5_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 202)
+#define IMXRT_DMACHAN_GPIO5_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 203)
+#define IMXRT_DMACHAN_GPIO6_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 204)
+#define IMXRT_DMACHAN_GPIO6_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 205)
+#define IMXRT_DMACHAN_SINC3_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 216)
+#define IMXRT_DMACHAN_SINC3_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 217)
+#define IMXRT_DMACHAN_SINC3_REQUEST2                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 218)
+#define IMXRT_DMACHAN_SINC3_REQUEST3                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 219)
+#define IMXRT_DMACHAN_ADC1_REQUEST1                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 220)
+#define IMXRT_DMACHAN_ADC2_REQUEST1                   
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 221)
+#define IMXRT_DMACHAN_LPTMR2_REQUEST                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 16)
+#define IMXRT_DMACHAN_TPM4_REQUEST0_REQUEST2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 28)
+#define IMXRT_DMACHAN_TPM4_REQUEST1_REQUEST3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 29)
+#define IMXRT_DMACHAN_TPM4_OVERFLOW_REQUEST           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 30)
+#define IMXRT_DMACHAN_FLEX_PWM1_CAPTURE_SUB0          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 58)
+#define IMXRT_DMACHAN_FLEX_PWM1_CAPTURE_SUB1          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 59)
+#define IMXRT_DMACHAN_FLEX_PWM1_CAPTURE_SUB2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 60)
+#define IMXRT_DMACHAN_FLEX_PWM1_CAPTURE_SUB3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 61)
+#define IMXRT_DMACHAN_FLEX_PWM1_VALUE_SUB0            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 62)
+#define IMXRT_DMACHAN_FLEX_PWM1_VALUE_SUB1            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 63)
+#define IMXRT_DMACHAN_FLEX_PWM1_VALUE_SUB2            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 64)
+#define IMXRT_DMACHAN_FLEX_PWM1_VALUE_SUB3            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 65)
+#define IMXRT_DMACHAN_FLEX_PWM2_CAPTURE_SUB0          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 66)
+#define IMXRT_DMACHAN_FLEX_PWM2_CAPTURE_SUB1          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 67)
+#define IMXRT_DMACHAN_FLEX_PWM2_CAPTURE_SUB2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 68)
+#define IMXRT_DMACHAN_FLEX_PWM2_CAPTURE_SUB3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 69)
+#define IMXRT_DMACHAN_FLEX_PWM2_VALUE_SUB0            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 70)
+#define IMXRT_DMACHAN_FLEX_PWM2_VALUE_SUB1            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 71)
+#define IMXRT_DMACHAN_FLEX_PWM2_VALUE_SUB2            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 72)
+#define IMXRT_DMACHAN_FLEX_PWM2_VALUE_SUB3            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 73)
+#define IMXRT_DMACHAN_QTIMER5_CAPT_TIMER0             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 122)
+#define IMXRT_DMACHAN_QTIMER5_CAPT_TIMER1             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 123)
+#define IMXRT_DMACHAN_QTIMER5_CAPT_TIMER2             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 124)
+#define IMXRT_DMACHAN_QTIMER5_CAPT_TIMER3             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 125)
+#define IMXRT_DMACHAN_QTIMER5_CMPLD1_TIMER0_CMPLD2_TIMER1 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 126)
+#define IMXRT_DMACHAN_QTIMER5_CMPLD1_TIMER1_CMPLD2_TIMER0 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 127)
+#define IMXRT_DMACHAN_QTIMER5_CMPLD1_TIMER2_CMPLD2_TIMER3 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 128)
+#define IMXRT_DMACHAN_QTIMER5_CMPLD1_TIMER3_CMPLD2_TIMER2 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 129)
+#define IMXRT_DMACHAN_QTIMER6_CAPT_TIMER0             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 130)
+#define IMXRT_DMACHAN_QTIMER6_CAPT_TIMER1             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 131)
+#define IMXRT_DMACHAN_QTIMER6_CAPT_TIMER2             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 132)
+#define IMXRT_DMACHAN_QTIMER6_CAPT_TIMER3             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 133)
+#define IMXRT_DMACHAN_QTIMER6_CMPLD1_TIMER0_CMPLD2_TIMER1 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 134)
+#define IMXRT_DMACHAN_QTIMER6_CMPLD1_TIMER1_CMPLD2_TIMER0 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 135)
+#define IMXRT_DMACHAN_QTIMER6_CMPLD1_TIMER2_CMPLD2_TIMER3 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 136)
+#define IMXRT_DMACHAN_QTIMER6_CMPLD1_TIMER3_CMPLD2_TIMER2 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 137)
+#define IMXRT_DMACHAN_QTIMER7_CAPT_TIMER0             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 138)
+#define IMXRT_DMACHAN_QTIMER7_CAPT_TIMER1             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 139)
+#define IMXRT_DMACHAN_QTIMER7_CAPT_TIMER2             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 140)
+#define IMXRT_DMACHAN_QTIMER7_CAPT_TIMER3             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 141)
+#define IMXRT_DMACHAN_QTIMER7_CMPLD1_TIMER0_CMPLD2_TIMER1 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 142)
+#define IMXRT_DMACHAN_QTIMER7_CMPLD1_TIMER1_CMPLD2_TIMER0 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 143)
+#define IMXRT_DMACHAN_QTIMER7_CMPLD1_TIMER2_CMPLD2_TIMER3 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 144)
+#define IMXRT_DMACHAN_QTIMER7_CMPLD1_TIMER3_CMPLD2_TIMER2 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 145)
+#define IMXRT_DMACHAN_QTIMER8_CAPT_TIMER0             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 146)
+#define IMXRT_DMACHAN_QTIMER8_CAPT_TIMER1             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 147)
+#define IMXRT_DMACHAN_QTIMER8_CAPT_TIMER2             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 148)
+#define IMXRT_DMACHAN_QTIMER8_CAPT_TIMER3             
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 149)
+#define IMXRT_DMACHAN_QTIMER8_CMPLD1_TIMER0_CMPLD2_TIMER1 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 150)
+#define IMXRT_DMACHAN_QTIMER8_CMPLD1_TIMER1_CMPLD2_TIMER0 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 151)
+#define IMXRT_DMACHAN_QTIMER8_CMPLD1_TIMER2_CMPLD2_TIMER3 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 152)
+#define IMXRT_DMACHAN_QTIMER8_CMPLD1_TIMER3_CMPLD2_TIMER2 
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 153)
+#define IMXRT_DMACHAN_LPI2_C6_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 165)
+#define IMXRT_DMACHAN_LPI2_C6_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 166)
+#define IMXRT_DMACHAN_LPTMR3_REQUEST                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 171)
+#define IMXRT_DMACHAN_SAI2_TX                         
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 180)
+#define IMXRT_DMACHAN_SAI2_RX                         
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 181)
+#define IMXRT_DMACHAN_SAI4_TX                         
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 184)
+#define IMXRT_DMACHAN_SAI4_RX                         
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 185)
+#define IMXRT_DMACHAN_SINC1_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 208)
+#define IMXRT_DMACHAN_SINC1_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 209)
+#define IMXRT_DMACHAN_SINC1_REQUEST2                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 210)
+#define IMXRT_DMACHAN_SINC1_REQUEST3                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 211)
+#define IMXRT_DMACHAN_SINC2_REQUEST0                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 212)
+#define IMXRT_DMACHAN_SINC2_REQUEST1                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 213)
+#define IMXRT_DMACHAN_SINC2_REQUEST2                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 214)
+#define IMXRT_DMACHAN_SINC2_REQUEST3                  
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 215)
+#define IMXRT_DMACHAN_CAN2                            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 1)
+#define IMXRT_DMACHAN_TPM5_REQUEST0_REQUEST2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 31)
+#define IMXRT_DMACHAN_TPM5_REQUEST1_REQUEST3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 32)
+#define IMXRT_DMACHAN_TPM5_OVERFLOW_REQUEST           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 33)
+#define IMXRT_DMACHAN_TPM6_REQUEST0_REQUEST2          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 34)
+#define IMXRT_DMACHAN_TPM6_REQUEST1_REQUEST3          
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 35)
+#define IMXRT_DMACHAN_TPM6_OVERFLOW_REQUEST           
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 36)
+#define IMXRT_DMACHAN_LPUART9_TX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 172)
+#define IMXRT_DMACHAN_LPUART9_RX                      
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 173)
+#define IMXRT_DMACHAN_LPUART10_TX                     
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 174)
+#define IMXRT_DMACHAN_LPUART10_RX                     
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 175)
+#define IMXRT_DMACHAN_LPUART11_TX                     
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 176)
+#define IMXRT_DMACHAN_LPUART11_RX                     
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 177)
+#define IMXRT_DMACHAN_SAI3_TX                         
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 182)
+#define IMXRT_DMACHAN_SAI3_RX                         
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 183)
+#define IMXRT_DMACHAN_CMP1                            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 187)
+#define IMXRT_DMACHAN_CMP2                            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 188)
+#define IMXRT_DMACHAN_CMP4                            
IMXRT_DMA_SRC(IMXRT_DMA_ENGINE_EDMA4, 190)
+
+#endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_DMAMUX_H */
diff --git a/arch/arm/src/imxrt/hardware/rt118x/imxrt118x_edma.h 
b/arch/arm/src/imxrt/hardware/rt118x/imxrt118x_edma.h
new file mode 100644
index 00000000000..32b94afb8e0
--- /dev/null
+++ b/arch/arm/src/imxrt/hardware/rt118x/imxrt118x_edma.h
@@ -0,0 +1,444 @@
+/****************************************************************************
+ * arch/arm/src/imxrt/hardware/rt118x/imxrt118x_edma.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_EDMA_H
+#define __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_EDMA_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "hardware/imxrt_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define EDMA_CONFIG_SWSTART              (1 << 6) /* Start by software trigger 
*/
+
+/* eDMA3 / eDMA4 Register Offsets */
+
+#define IMXRT_EDMA_CSR_OFFSET              (0x000000)              /* 
Management Page Control Register (CSR) */
+#define IMXRT_EDMA_ES_OFFSET               (0x000004)              /* 
Management Page Error Status Register (ES) */
+#define IMXRT_EDMA_CH_GRPRI_OFFSET(n)      (0x000100 + ((n) << 2)) /* Channel 
n Arbitration Group Register (CHn_GRPRI) */
+
+/* eDMA3 only */
+
+#define IMXRT_EDMA_INT_OFFSET              (0x000008) /* Management Page 
Interrupt Request Status Register (INT) */
+#define IMXRT_EDMA_HRS_OFFSET              (0x00000c) /* Management Page 
Hardware Request Status Register (HRS) */
+
+/* eDMA4 only */
+
+#define IMXRT_EDMA_INT_LOW_OFFSET          (0x000008) /* Management Page 
Interrupt Request Status Register (INT_LOW) */
+#define IMXRT_EDMA_INT_HIGH_OFFSET         (0x00000c) /* Management Page 
Interrupt Request Status Register (INT_HIGH) */
+#define IMXRT_EDMA_HRS_LOW_OFFSET          (0x000010) /* Management Page 
Hardware Request Status Register (HRS_LOW) */
+#define IMXRT_EDMA_HRS_HIGH_OFFSET         (0x000014) /* Management Page 
Hardware Request Status Register (HRS_HIGH) */
+
+/* eDMA3 / eDMA4 Register Addresses */
+
+#define IMXRT_EDMA_CSR(n)                  ((n) + IMXRT_EDMA_CSR_OFFSET)
+#define IMXRT_EDMA_ES(n)                   ((n) + IMXRT_EDMA_ES_OFFSET)
+#define IMXRT_EDMA_CH_GRPRI(n,c)           ((n) + 
IMXRT_EDMA_CH_GRPRI_OFFSET(c))
+
+/* eDMA3 only */
+
+#define IMXRT_EDMA_INT                     (IMXRT_DMA3_BASE + 
IMXRT_EDMA_INT_OFFSET)
+#define IMXRT_EDMA_HRS                     (IMXRT_DMA3_BASE + 
IMXRT_EDMA_HRS_OFFSET)
+
+/* eDMA4 only */
+
+#define IMXRT_EDMA_INT_LOW                 (IMXRT_DMA4_BASE + 
IMXRT_EDMA_INT_LOW_OFFSET)
+#define IMXRT_EDMA_INT_HIGH                (IMXRT_DMA4_BASE + 
IMXRT_EDMA_INT_HIGH_OFFSET)
+#define IMXRT_EDMA_HRS_LOW                 (IMXRT_DMA4_BASE + 
IMXRT_EDMA_HRS_LOW_OFFSET)
+#define IMXRT_EDMA_HRS_HIGH                (IMXRT_DMA4_BASE + 
IMXRT_EDMA_HRS_HIGH_OFFSET)
+
+/* eDMA Transfer Control Descriptor (TCD) Register Offsets */
+
+#define IMXRT_EDMA_CH_CSR_OFFSET           (0x000000) /* Channel Control and 
Status Register (CH0_CSR) */
+#define IMXRT_EDMA_CH_ES_OFFSET            (0x000004) /* Channel Error Status 
Register (CH0_ES) */
+#define IMXRT_EDMA_CH_INT_OFFSET           (0x000008) /* Channel Interrupt 
Status Register (CH0_INT) */
+#define IMXRT_EDMA_CH_SBR_OFFSET           (0x00000c) /* Channel System Bus 
Register (CH0_SBR) */
+#define IMXRT_EDMA_CH_PRI_OFFSET           (0x000010) /* Channel Priority 
Register (CH0_PRI) */
+#define IMXRT_EDMA_CH_MUX_OFFSET           (0x000014) /* Channel Multiplexor 
Configuration (CH0_MUX) (eDMA4 only) */
+#define IMXRT_EDMA_CH_MATTR_OFFSET         (0x000018) /* Memory Attributes 
Register (CH0_MATTR) (eDMA4 only) */
+#define IMXRT_EDMA_TCD_SADDR_OFFSET        (0x000020) /* TCD Source Address 
Register (TCD0_SADDR) */
+#define IMXRT_EDMA_TCD_SOFF_OFFSET         (0x000024) /* TCD Signed Source 
Address Offset Register (TCD0_SOFF) */
+#define IMXRT_EDMA_TCD_ATTR_OFFSET         (0x000026) /* TCD Transfer 
Attributes (TCD0_ATTR) */
+#define IMXRT_EDMA_TCD_NBYTES_OFFSET       (0x000028) /* TCD Transfer Size 
(TCD0_NBYTES) */
+#define IMXRT_EDMA_TCD_SLAST_SDA_OFFSET    (0x00002c) /* TCD Last Source 
Address Adjustment / Store DADDR Address Register (TCD0_SLAST_SDA) */
+#define IMXRT_EDMA_TCD_DADDR_OFFSET        (0x000030) /* TCD Destination 
Address Register (TCD0_DADDR) */
+#define IMXRT_EDMA_TCD_DOFF_OFFSET         (0x000034) /* TCD Signed 
Destination Address Offset Register (TCD0_DOFF) */
+#define IMXRT_EDMA_TCD_CITER_OFFSET        (0x000036) /* TCD Current Major 
Loop Count Register (TCD0_CITER) */
+#define IMXRT_EDMA_TCD_DLAST_SGA_OFFSET    (0x000038) /* TCD Last Destination 
Address Adjustment / Scatter Gather Address Register (TCD0_DLAST_SGA)*/
+#define IMXRT_EDMA_TCD_CSR_OFFSET          (0x00003c) /* TCD Control and 
Status Register (TCD0_CSR) */
+#define IMXRT_EDMA_TCD_BITER_OFFSET        (0x00003e) /* TCD Beginning Major 
Loop Count Register (TCD0_BITER) */
+
+/* eDMA 3 and eDMA 4 have TCD instance offsets, but same base offset */
+
+#define IMXRT_EDMA_TCD_BASE_OFFSET         (0x10000) /* Offset to TCD for both 
eDMA3/4 */
+#define IMXRT_EDMA3_TCD_INST_OFFSET        (0x10000) /* Per instance TCD 
offset for eDMA3 */
+#define IMXRT_EDMA4_TCD_INST_OFFSET        (0x8000)  /* Per instance TCD 
offset for eDMA4 */
+#define IMXRT_EDMA_TCD_BASE(n)             ((n) + IMXRT_EDMA_TCD_BASE_OFFSET)
+#define IMXRT_EDMA_TCD_INST_OFFSET(n)      ((n) == IMXRT_DMA3_BASE ? 
IMXRT_EDMA3_TCD_INST_OFFSET : IMXRT_EDMA4_TCD_INST_OFFSET)
+#define IMXRT_EDMA_TCD(n,t)                (IMXRT_EDMA_TCD_BASE(n) + (t) * 
IMXRT_EDMA_TCD_INST_OFFSET(n))
+
+/* eDMA Transfer Control Descriptor (TCD) Register Addresses ****************/
+
+#define IMXRT_EDMA_CH_CSR(n,t)             (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_CH_CSR_OFFSET)
+#define IMXRT_EDMA_CH_ES(n,t)              (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_CH_ES_OFFSET)
+#define IMXRT_EDMA_CH_INT(n,t)             (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_CH_INT_OFFSET)
+#define IMXRT_EDMA_CH_SBR(n,t)             (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_CH_SBR_OFFSET)
+#define IMXRT_EDMA_CH_PRI(n,t)             (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_CH_PRI_OFFSET)
+#define IMXRT_EDMA_CH_MUX(n,t)             (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_CH_MUX_OFFSET)
+#define IMXRT_EDMA_TCD_SADDR(n,t)          (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_SADDR_OFFSET)
+#define IMXRT_EDMA_TCD_SOFF(n,t)           (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_SOFF_OFFSET)
+#define IMXRT_EDMA_TCD_ATTR(n,t)           (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_ATTR_OFFSET)
+#define IMXRT_EDMA_TCD_NBYTES(n,t)         (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_NBYTES_OFFSET)
+#define IMXRT_EDMA_TCD_SLAST_SDA(n,t)      (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_SLAST_SDA_OFFSET)
+#define IMXRT_EDMA_TCD_DADDR(n,t)          (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_DADDR_OFFSET)
+#define IMXRT_EDMA_TCD_DOFF(n,t)           (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_DOFF_OFFSET)
+#define IMXRT_EDMA_TCD_CITER(n,t)          (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_CITER_OFFSET)
+#define IMXRT_EDMA_TCD_DLAST_SGA(n,t)      (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_DLAST_SGA_OFFSET)
+#define IMXRT_EDMA_TCD_CSR(n,t)            (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_CSR_OFFSET)
+#define IMXRT_EDMA_TCD_BITER(n,t)          (IMXRT_EDMA_TCD(n,t) + 
IMXRT_EDMA_TCD_BITER_OFFSET)
+
+/* eDMA Register Bitfield Definitions ***************************************/
+
+/* Management Page Control Register (CSR) */
+
+                                                    /* Bit 0: Reserved */
+#define EDMA_CSR_EDBG                     (1 << 1)  /* Bit 1: Enable Debug 
(EDBG) */
+#define EDMA_CSR_ERCA                     (1 << 2)  /* Bit 2: Enable Round 
Robin Channel Arbitration (ERCA) */
+                                                    /* Bit 3: Reserved */
+#define EDMA_CSR_HAE                      (1 << 4)  /* Bit 4: Halt After Error 
(HAE) */
+#define EDMA_CSR_HALT                     (1 << 5)  /* Bit 5: Halt DMA 
Operations (HALT) */
+#define EDMA_CSR_GCLC                     (1 << 6)  /* Bit 6: Global Channel 
Linking Control (GCLC) */
+#define EDMA_CSR_GMRC                     (1 << 7)  /* Bit 7: Global Master ID 
Replication Control (GMRC) */
+#define EDMA_CSR_ECX                      (1 << 8)  /* Bit 8: Cancel Transfer 
With Error (ECX) */
+#define EDMA_CSR_CX                       (1 << 9)  /* Bit 9: Cancel Transfer 
(CX) */
+                                                    /* Bits 10-23: Reserved */
+#define EDMA_CSR_ACTIVE_ID_SHIFT          (24)      /* Bits 24-28: Active 
Channel ID (ACTIVE_ID) */
+#define EDMA_CSR_ACTIVE_ID_MASK           (0x1f << EDMA_CSR_ACTIVE_ID_SHIFT)
+                                                    /* Bits 29-30: Reserved */
+#define EDMA_CSR_ACTIVE                   (1 << 31) /* Bit 31: DMA Active 
Status (ACTIVE) */
+
+/* Management Page Error Status Register (ES) */
+
+#define EDMA_ES_DBE                       (1 << 0)  /* Bit 0: Destination Bus 
Error (DBE) */
+#define EDMA_ES_SBE                       (1 << 1)  /* Bit 1: Source Bus Error 
(SBE) */
+#define EDMA_ES_SGE                       (1 << 2)  /* Bit 2: Scatter/Gather 
Configuration Error (SGE) */
+#define EDMA_ES_NCE                       (1 << 3)  /* Bit 3: NBYTES/CITER 
Configuration Error (NCE) */
+#define EDMA_ES_DOE                       (1 << 4)  /* Bit 4: Destination 
Offset Error (DOE) */
+#define EDMA_ES_DAE                       (1 << 5)  /* Bit 5: Destination 
Address Error (DAE) */
+#define EDMA_ES_SOE                       (1 << 6)  /* Bit 6: Source Offset 
Error (SOE) */
+#define EDMA_ES_SAE                       (1 << 7)  /* Bit 7: Source Address 
Error (SAE) */
+#define EDMA_ES_ECX                       (1 << 8)  /* Bit 8: Transfer 
Canceled (ECX) */
+                                                    /* Bits 9-23: Reserved */
+#define EDMA_ES_ERRCHN_SHIFT              (24)      /* Bits 24-28: Error 
Channel Number or Canceled Channel Number (ERRCHN) */
+#define EDMA_ES_ERRCHN_MASK               (0x1f << EDMA_ES_ERRCHN_SHIFT)
+                                                    /* Bits 29-30: Reserved */
+#define EDMA_ES_VLD                       (1 << 31) /* Bit 31: Logical OR of 
all ERR status fields (VALID) */
+
+/* Management Page Interrupt Request Status Register (INT) */
+
+#define EDMA_INT(n)                       (1 << (n)) /* Bit n: Interrupt 
Request Status (INT) */
+
+/* Management Page Hardware Request Status Register (HRS) */
+
+#define EDMA_HRS(n)                       (1 << (n)) /* Bit n: Hardware 
Request Status (HRS) */
+
+/* Channel n Arbitration Group Register (CHn_GRPRI) */
+
+#define EDMA_CH_GRPRI_SHIFT               (0)       /* Bits 0-4: Arbitration 
Group For Channel n (GRPRI) */
+#define EDMA_CH_GRPRI_MASK                (0x1f << EDMA_CH_GRPRI_SHIFT)
+                                                    /* Bits 5-31: Reserved */
+
+/* eDMA Transfer Control Descriptor (TCD) Bitfield Definitions **************/
+
+/* Channel n Control and Status Register (CHn_CSR) */
+
+#define EDMA_CH_CSR_ERQ                   (1 << 0)  /* Bit 0: Enable DMA 
Request (ERQ) */
+#define EDMA_CH_CSR_EARQ                  (1 << 1)  /* Bit 1: Enable 
Asynchronous DMA Request in Stop Mode for Channel (EARQ) */
+#define EDMA_CH_CSR_EEI                   (1 << 2)  /* Bit 2: Enable Error 
Interrupt (EEI) */
+#define EDMA_CH_CSR_EBW                   (1 << 3)  /* Bit 3: Enable Buffered 
Writes (EBW) */
+                                                    /* Bit 4-29: Reserved */
+#define EDMA_CH_CSR_DONE                  (1 << 30) /* Bit 30: Channel Done 
(DONE) */
+#define EDMA_CH_CSR_ACTIVE                (1 << 31) /* Bit 31: CHannel Active 
(ACTIVE) */
+
+/* Channel n Error Status Register (CHn_ES) */
+
+#define EDMA_CH_ES_DBE                    (1 << 0)  /* Bit 0: Destination Bus 
Error (DBE) */
+#define EDMA_CH_ES_SBE                    (1 << 1)  /* Bit 1: Source Bus Error 
(SBE) */
+#define EDMA_CH_ES_SGE                    (1 << 2)  /* Bit 2: Scatter/Gather 
Configuration Error (SGE) */
+#define EDMA_CH_ES_NCE                    (1 << 3)  /* Bit 3: NBYTES/CITER 
Configuration Error (NCE) */
+#define EDMA_CH_ES_DOE                    (1 << 4)  /* Bit 4: Destination 
Offset Error (DOE) */
+#define EDMA_CH_ES_DAE                    (1 << 5)  /* Bit 5: Destination 
Address Error (DAE) */
+#define EDMA_CH_ES_SOE                    (1 << 6)  /* Bit 6: Source Offset 
Error (SOE) */
+#define EDMA_CH_ES_SAE                    (1 << 7)  /* Bit 7: Source Address 
Error (SAE) */
+                                                    /* Bit 8-30: Reserved */
+#define EDMA_CH_ES_ERR                    (1 << 31) /* Bit 31: Error in this 
channel (ERR) */
+
+/* Channel n Interrupt Status Register (CHn_INT) */
+
+#define EDMA_CH_INT                       (1 << 0)  /* Bit 0: Interrupt 
Request (INT) */
+                                                    /* Bits 1-31: Reserved */
+
+/* Channel n System Bus Register (CHn_SBR) */
+
+#define EDMA_CH_SBR_MID_SHIFT             (0)       /* Bits 0-3: Master ID 
(MID) */
+#define EDMA_CH_SBR_MID_MASK              (0x0f << EDMA_CH_SBR_MID_SHIFT)
+                                                    /* Bits 4-13: Reserved */
+#define EDMA_CH_SBR_SEC                   (1 << 14) /* Bit 14: Security Level 
(SEC) */
+#define EDMA_CH_SBR_PAL                   (1 << 15) /* Bit 15: Privileged 
Access Level (PAL) */
+#define EDMA_CH_SBR_EMI                   (1 << 16) /* Bit 16: Enable Master 
ID Replication (EMI) */
+#define EDMA_CH_SBR_ATTR_SHIFT            (17)      /* Bits 17-19: Attribute 
Output (ATTR) */
+#define EDMA_CH_SBR_ATTR_MASK             (0x07 << EDMA_CH_SBR_ATTR_SHIFT)
+                                                    /* Bits 20-31: Reserved */
+
+/* Channel n Priority Register (CHn_PRI) */
+
+#define EDMA_CH_PRI_APL_SHIFT             (0)       /* Bits 0-2: Arbitration 
Priority Level (APL) */
+#define EDMA_CH_PRI_APL_MASK              (0x07 << EDMA_CH_PRI_APL_SHIFT)
+                                                    /* Bits 3-29: Reserved */
+#define EDMA_CH_PRI_DPA                   (1 << 30) /* Bit 30: Disable Preempt 
Ability (DPA) */
+#define EDMA_CH_PRI_ECP                   (1 << 31) /* Bit 31: Enable Channel 
Preemption (ECP) */
+
+/* Channel Multiplexor Configuration (CHn_MUX).  On RT1180 the mux source
+ * ID field is 8-bit for eDMA4 (up to 256 sources) and 6-bit for eDMA3.
+ * Using the wider mask is safe since unused high bits are reserved.
+ */
+
+#define EDMA_CH_SRC_SHIFT                 (0)       /* Bits 0-7: Service 
Request Source */
+#define EDMA_CH_SRC_MASK                  (0xff << EDMA_CH_SRC_SHIFT)
+
+/* TCDn Source Address Register (TCDn_SADDR) */
+
+#define EDMA_TCD_SADDR_SHIFT              (0)       /* Bits 0-31: Source 
Address (SADDR) */
+#define EDMA_TCD_SADDR_MASK               (0xffffffff << EDMA_TCD_SADDR_SHIFT)
+
+/* TCDn Signed Source Address Offset Register (TCDn_SOFF) */
+
+#define EDMA_TCD_SOFF_SHIFT               (0)       /* Bits 0-31: Source 
Address Signed Offset (SOFF) */
+#define EDMA_TCD_SOFF_MASK                (0xffffffff << EDMA_TCD_SOFF_SHIFT)
+
+/* TCDn Transfer Attributes (TCDn_ATTR) */
+
+#define EDMA_TCD_ATTR_DSIZE_SHIFT         (0)       /* Bits 0-2: Destination 
Data Transfer Size (DSIZE) */
+#define EDMA_TCD_ATTR_DSIZE_MASK          (0x07 << EDMA_TCD_ATTR_DSIZE_SHIFT)
+#define EDMA_TCD_ATTR_DSIZE(n)            (((n) << EDMA_TCD_ATTR_DSIZE_SHIFT) 
& EDMA_TCD_ATTR_DSIZE_MASK)
+#define EDMA_TCD_ATTR_DMOD_SHIFT          (3)       /* Bits 3-7: Destination 
Address Modulo (DMOD) */
+#define EDMA_TCD_ATTR_DMOD_MASK           (0x1f << EDMA_TCD_ATTR_DMOD_SHIFT)
+#define EDMA_TCD_ATTR_DMOD(n)             (((n) << EDMA_TCD_ATTR_DMOD_SHIFT) & 
EDMA_TCD_ATTR_DMOD_MASK)
+#define EDMA_TCD_ATTR_SSIZE_SHIFT         (8)       /* Bits 8-10: Source Data 
Transfer Size (SSIZE) */
+#define EDMA_TCD_ATTR_SSIZE_MASK          (0x07 << EDMA_TCD_ATTR_SSIZE_SHIFT)
+#define EDMA_TCD_ATTR_SSIZE(n)            (((n) << EDMA_TCD_ATTR_SSIZE_SHIFT) 
& EDMA_TCD_ATTR_SSIZE_MASK)
+#  define EDMA_TCD_ATTR_SSIZE_8BIT        (0x00 << EDMA_TCD_ATTR_SSIZE_SHIFT) 
/* 8-bit */
+#  define EDMA_TCD_ATTR_SSIZE_16BIT       (0x01 << EDMA_TCD_ATTR_SSIZE_SHIFT) 
/* 16-bit */
+#  define EDMA_TCD_ATTR_SSIZE_32BIT       (0x02 << EDMA_TCD_ATTR_SSIZE_SHIFT) 
/* 32-bit */
+#  define EDMA_TCD_ATTR_SSIZE_64BIT       (0x03 << EDMA_TCD_ATTR_SSIZE_SHIFT) 
/* 64-bit */
+#  define EDMA_TCD_ATTR_SSIZE_16BYTE      (0x04 << EDMA_TCD_ATTR_SSIZE_SHIFT) 
/* 16-byte */
+#  define EDMA_TCD_ATTR_SSIZE_32BYTE      (0x05 << EDMA_TCD_ATTR_SSIZE_SHIFT) 
/* 32-byte */
+#  define EDMA_TCD_ATTR_SSIZE_64BYTE      (0x06 << EDMA_TCD_ATTR_SSIZE_SHIFT) 
/* 64-byte */
+
+#define EDMA_TCD_ATTR_SMOD_SHIFT          (11)      /* Bits 11-15: Source 
Address Modulo (SMOD) */
+#define EDMA_TCD_ATTR_SMOD_MASK           (0x1f << EDMA_TCD_ATTR_SMOD_SHIFT)
+#define EDMA_TCD_ATTR_SMOD(n)             (((n) << EDMA_TCD_ATTR_SMOD_SHIFT) & 
EDMA_TCD_ATTR_SMOD_MASK)
+
+/* TCDn Transfer Size (TCDn_NBYTES) */
+
+#define EDMA_TCD_NBYTES_SHIFT             (0)       /* Bits 0-29: Number of 
Bytes to Transfer per Service Request (NBYTES) */
+#define EDMA_TCD_NBYTES_MASK              (0x3fffffff << EDMA_TCD_NBYTES_SHIFT)
+#define EDMA_TCD_NBYTES_MASK_MLOFF        (0x03ff << EDMA_TCD_NBYTES_SHIFT)
+#define EDMA_TCD_NBYTES_MLOFF_SHIFT       (10)      /* Bits 10-29: Minor Loop 
Offset (MLOFF) */
+#define EDMA_TCD_NBYTES_MLOFF_MASK        (0x0fffff << 
EDMA_TCD_NBYTES_MLOFF_SHIFT)
+#define EDMA_TCD_NBYTES_DMLOE             (1 << 30) /* Bit 30: Destination 
Minor Loop Offset Enable (DMLOE) */
+#define EDMA_TCD_NBYTES_SMLOE             (1 << 31) /* Bit 31: Source Minor 
Loop Offset Enable (SMLOE) */
+
+/* TCDn Last Source Address Adjustment / Store DADDR Address Register
+ * (TCDn_SLAST_SDA)
+ */
+
+#define EDMA_TCD_SLAST_SDA_SHIFT          (0)       /* Bits 0-31: Last Source 
Address Adjustment / Store DADDR Address (SLAST_SDA) */
+#define EDMA_TCD_SLAST_SDA_MASK           (0xffffffff << 
EDMA_TCD_SLAST_SDA_SHIFT)
+
+/* TCDn Destination Address Register (TCDn_DADDR) */
+
+#define EDMA_TCD_DADDR_SHIFT              (0)       /* Bits 0-31: Destination 
Address (DADDR) */
+#define EDMA_TCD_DADDR_MASK               (0xffffffff << EDMA_TCD_DADDR_SHIFT)
+
+/* TCDn Signed Destination Address Offset Register (TCDn_DOFF) */
+
+#define EDMA_TCD_DOFF_SHIFT               (0)       /* Bits 0-15: Destination 
Address Signed Offset (DOFF) */
+#define EDMA_TCD_DOFF_MASK                (0xffff << EDMA_TCD_DOFF_SHIFT)
+
+/* TCDn Current Major Loop Count Register (TCDn_CITER) */
+
+#define EDMA_TCD_CITER_SHIFT              (0)       /* Bits 0-14: Current 
Major Iteration Count (CITER) */
+#define EDMA_TCD_CITER_MASK               (0x7fff << EDMA_TCD_CITER_SHIFT)
+#define EDMA_TCD_CITER_MASK_ELINK         (0x01ff << EDMA_TCD_CITER_SHIFT)
+#define EDMA_TCD_CITER_LINKCH_SHIFT       (9)       /* Bits 9-13: Minor Loop 
Link Channel Number (LINKCH) */
+#define EDMA_TCD_CITER_LINKCH_MASK        (0x1f << EDMA_TCD_CITER_LINKCH_SHIFT)
+#define EDMA_TCD_CITER_LINKCH(n)          (((n) << 
EDMA_TCD_CITER_LINKCH_SHIFT) & EDMA_TCD_CITER_LINKCH_SHIFT)
+#define EDMA_TCD_CITER_ELINK              (1 << 15) /* Bit 15: Enable Link 
(ELINK) */
+
+/* TCDn Last Destination Address Adjustment / Scatter Gather Address Register
+ * (TCDn_DLAST_SGA)
+ */
+
+#define EDMA_TCD_DLAST_SGA_SHIFT          (0)       /* Bits 0-31: Last 
Destination Address Adjustment / Scatter Gather Address (DLAST_SGA) */
+#define EDMA_TCD_DLAST_SGA_MASK           (0xffffffff << 
EDMA_TCD_DLAST_SGA_SHIFT)
+
+/* TCDn Control and Status Register (TCDn_CSR) */
+
+#define EDMA_TCD_CSR_START                (1 << 0)  /* Bit 0: Channel Start 
(START) */
+#define EDMA_TCD_CSR_INTMAJOR             (1 << 1)  /* Bit 1: Enable Interrupt 
if Major count complete (INTMAJOR) */
+#define EDMA_TCD_CSR_INTHALF              (1 << 2)  /* Bit 2: Enable Interrupt 
if Major Count Half-complete (INTHALF) */
+#define EDMA_TCD_CSR_DREQ                 (1 << 3)  /* Bit 3: Disable Request 
(DREQ) */
+#define EDMA_TCD_CSR_ESG                  (1 << 4)  /* Bit 4: Enable 
Scatter/Gather Processing (ESG) */
+#define EDMA_TCD_CSR_MAJORELINK           (1 << 5)  /* Bit 5: Enable Link When 
Major Loop Complete (MAJORELINK) */
+#define EDMA_TCD_CSR_EEOP                 (1 << 6)  /* Bit 6: Enable 
End-Of-Packet Processing (EEOP) */
+#define EDMA_TCD_CSR_ESDA                 (1 << 7)  /* Bit 7: Enable Store 
Destination Address (ESDA) */
+#define EDMA_TCD_CSR_MAJORLINKCH_SHIFT    (8)       /* Bits 8-12: Major Loop 
Link Channel Number (MAJORLINKCH) */
+#define EDMA_TCD_CSR_MAJORLINKCH_MASK     (0x1f << 
EDMA_TCD_CSR_MAJORLINKCH_SHIFT)
+#define EDMA_TCD_CSR_MAJORLINKCH(n)       (((n) << 
EDMA_TCD_CSR_MAJORLINKCH_SHIFT) & EDMA_TCD_CSR_MAJORLINKCH_MASK)
+                                                    /* Bit 13: Reserved */
+#define EDMA_TCD_CSR_BWC_SHIFT            (14)      /* Bits 14-15: Bandwidth 
Control (BWC) */
+#define EDMA_TCD_CSR_BWC_MASK             (0x03 << EDMA_TCD_CSR_BWC_SHIFT)
+#  define EDMA_TCD_CSR_BWC_NOSTALL        (0x00 << EDMA_TCD_CSR_BWC_SHIFT) /* 
No eDMA engine stalls */
+#  define EDMA_TCD_CSR_BWC_HPE            (0x01 << EDMA_TCD_CSR_BWC_SHIFT) /* 
Enable eDMA master high-priority elevation (HPE) mode */
+#  define EDMA_TCD_CSR_BWC_4CYCLES        (0x02 << EDMA_TCD_CSR_BWC_SHIFT) /* 
eDMA engine stalls for 4 cycles after each R/W */
+#  define EDMA_TCD_CSR_BWC_8CYCLES        (0x03 << EDMA_TCD_CSR_BWC_SHIFT) /* 
eDMA engine stalls for 8 cycles after each R/W */
+
+/* TCDn Beginning Major Loop Count Register (TCDn_BITER) */
+
+#define EDMA_TCD_BITER_SHIFT              (0)       /* Bits 0-14: Starting 
Major Iteration Count (BITER) */
+#define EDMA_TCD_BITER_MASK               (0x7fff << EDMA_TCD_BITER_SHIFT)
+#define EDMA_TCD_BITER_MASK_ELINK         (0x01ff << EDMA_TCD_BITER_SHIFT)
+#define EDMA_TCD_BITER_LINKCH_SHIFT       (9)       /* Bits 9-13: Link Channel 
Number (LINKCH) */
+#define EDMA_TCD_BITER_LINKCH_MASK        (0x1f << EDMA_TCD_BITER_LINKCH_SHIFT)
+#define EDMA_TCD_BITER_LINKCH(n)          (((n) << 
EDMA_TCD_BITER_LINKCH_SHIFT) & EDMA_TCD_BITER_LINKCH_MASK)
+#define EDMA_TCD_BITER_ELINK              (1 << 15) /* Bit 15: Enable Link 
(ELINK) */
+
+/* Amount of channels */
+
+#define DMA3_CHANNEL_COUNT                (32)
+#define DMA4_CHANNEL_COUNT                (64)
+#define IMXRT_EDMA_NCHANNELS              (DMA3_CHANNEL_COUNT + 
DMA4_CHANNEL_COUNT)
+
+/* Amount of interrupt sources */
+
+#define DMA3_IRQ_COUNT                    (32) /* Error interrupt not counted 
*/
+#define DMA4_IRQ_COUNT                    (16) /* Error interrupt not counted;
+                                                * 4 channels share one IRQ */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* In-memory representation of the 32-byte Transfer Control Descriptor
+ * (TCD)
+ */
+
+struct imxrt_edmatcd_s
+{
+  uint32_t   saddr;         /* Offset: 0x0000  TCD Source Address */
+  uint16_t   soff;          /* Offset: 0x0004  TCD Signed Source Address 
Offset */
+  uint16_t   attr;          /* Offset: 0x0006  TCD Transfer Attributes */
+  uint32_t   nbytes;        /* Offset: 0x0008  TCD Signed Minor Loop Offset / 
Byte Count */
+  uint32_t   slast;         /* Offset: 0x000c  TCD Last Source Address 
Adjustment */
+  uint32_t   daddr;         /* Offset: 0x0010  TCD Destination Address */
+  uint16_t   doff;          /* Offset: 0x0014  TCD Signed Destination Address 
Offset */
+  uint16_t   citer;         /* Offset: 0x0016  TCD Current Minor Loop Link, 
Major Loop Count */
+  uint32_t   dlastsga;      /* Offset: 0x0018  TCD Last Destination Address 
Adjustment/Scatter Gather Address */
+  uint16_t   csr;           /* Offset: 0x001c  TCD Control and Status */
+  uint16_t   biter;         /* Offset: 0x001e  TCD Beginning Minor Loop Link, 
Major Loop Count */
+};
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imxrt_edma_tcdhasmux
+ *
+ * Description:
+ *   Check if DMA TCD has TCD.MUX register.
+ *
+ * Input Parameters:
+ *   dmabase - The eDMA base.
+ *
+ * Returned Value:
+ *   true if TCD.MUX exists; false if not.
+ *
+ ****************************************************************************/
+
+static inline bool imxrt_edma_tcdhasmux(uintptr_t dmabase)
+{
+  /* On RT1180 both eDMA3 and eDMA4 have per-channel CH_MUX registers. */
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: imxrt_edma_choffset
+ *
+ * Description:
+ *   Channel offset in global channel list for dma base.
+ *
+ * Input Parameters:
+ *   base - The eDMA base.
+ *
+ * Returned Value:
+ *   Channel offset.
+ *
+ ****************************************************************************/
+
+static inline uint32_t imxrt_edma_choffset(uintptr_t base)
+{
+  return base == IMXRT_DMA3_BASE ? 0 : DMA3_CHANNEL_COUNT;
+}
+
+/****************************************************************************
+ * Name: imxrt_edma_chmax
+ *
+ * Description:
+ *   Max channel in global channel list for dma base.
+ *
+ * Input Parameters:
+ *   base - The eDMA base.
+ *
+ * Returned Value:
+ *   Channel max.
+ *
+ ****************************************************************************/
+
+static inline uint32_t imxrt_edma_chmax(uintptr_t base)
+{
+  return base == IMXRT_DMA3_BASE ? DMA3_CHANNEL_COUNT : IMXRT_EDMA_NCHANNELS;
+}
+
+#endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_EDMA_H */
diff --git a/arch/arm/src/imxrt/imxrt_edma.h b/arch/arm/src/imxrt/imxrt_edma.h
index 8bca05b09bc..a24c5429207 100644
--- a/arch/arm/src/imxrt/imxrt_edma.h
+++ b/arch/arm/src/imxrt/imxrt_edma.h
@@ -99,7 +99,12 @@
 #include <nuttx/config.h>
 
 #include <stdint.h>
-#include "hardware/imxrt_edma.h"
+
+#ifdef CONFIG_IMXRT_EDMA_VER2
+#  include "hardware/rt118x/imxrt118x_edma.h"
+#else
+#  include "hardware/imxrt_edma.h"
+#endif
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -138,13 +143,26 @@ typedef void *DMACH_HANDLE;
 typedef void (*edma_callback_t)(DMACH_HANDLE handle,
                                 void *arg, bool done, int result);
 
-/* eDMA transfer sizes */
+/* eDMA transfer type */
+
+enum imxrt_edma_xfrtype_e
+{
+  EDMA_MEM2MEM = 0,      /* Transfer from memory to memory */
+  EDMA_PERIPH2MEM,       /* Transfer from peripheral to memory */
+  EDMA_MEM2PERIPH,       /* Transfer from memory to peripheral */
+};
 
-enum kinetis_edma_sizes_e
+/* eDMA transfer sises */
+
+enum imxrt_edma_sizes_e
 {
   EDMA_8BIT    = 0,      /* Transfer data size 8 */
   EDMA_16BIT   = 1,      /* Transfer data size 16 */
   EDMA_32BIT   = 2,      /* Transfer data size 32 */
+  EDMA_64BIT   = 3,      /* Transfer data size 64 */
+  EDMA_16BYTE  = 4,      /* Transfer data size 16-byte */
+  EDMA_32BYTE  = 5,      /* Transfer data size 32-byte */
+  EDMA_64BYTE  = 6,      /* Transfer data size 64-byte */
 };
 
 /* This structure holds the source/destination transfer attribute
@@ -166,6 +184,11 @@ struct imxrt_edma_xfrconfig_s
 #else
   uint32_t nbytes;     /* Bytes to transfer in a minor loop */
 #endif
+#ifdef CONFIG_IMXRT_EDMA_VER2
+  uint8_t smod;
+  uint8_t dmod;
+  uint8_t bwc;
+#endif
 #ifdef CONFIG_IMXRT_EDMA_ELINK
   DMACH_HANDLE linkch; /* Link channel (With EDMA_CONFIG_LINKTYPE_* flags) */
 #endif
diff --git a/arch/arm/src/imxrt/imxrt_edma_ver2.c 
b/arch/arm/src/imxrt/imxrt_edma_ver2.c
new file mode 100644
index 00000000000..1be42a936ec
--- /dev/null
+++ b/arch/arm/src/imxrt/imxrt_edma_ver2.c
@@ -0,0 +1,1529 @@
+/****************************************************************************
+ * arch/arm/src/imxrt/imxrt_edma_ver2.c
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * SPDX-FileCopyrightText: 2019, 2021, 2023 Gregory Nutt.
+ * SPDX-FileCopyrightText: 2022 NXP
+ * SPDX-FileCopyrightText: 2016-2017 NXP
+ * SPDX-FileCopyrightText: 2015, Freescale Semiconductor, Inc.
+ * SPDX-FileContributor: Gregory Nutt <[email protected]>
+ * SPDX-FileContributor: David Sidrane <[email protected]>
+ * SPDX-FileContributor: Peter van der Perk <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/queue.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/mutex.h>
+#include <nuttx/semaphore.h>
+
+#include "arm_internal.h"
+#include "sched/sched.h"
+
+#include "chip.h"
+#include "imxrt_edma.h"
+#include "imxrt_clockconfig.h"
+
+#include "hardware/imxrt_ccm.h"
+#include "hardware/rt118x/imxrt118x_edma.h"
+#include "hardware/imxrt_dmamux.h"
+
+#ifdef CONFIG_IMXRT_EDMA
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* TCD Alignment.
+ *
+ * eDMA TCDs must be aligned with the D-Cache line boundaries to facilitate
+ * cache operations on the TCDs when the D-Cache is enabled.
+ *
+ * NOTE:  The TCDs are 32-bytes in length.  We implicitly assume that the
+ * D-Cache line size is also 32-bits.  Otherwise, padding would be required
+ * at the ends of the TCDS and buffers to protect data after the end of from
+ * invalidation.
+ */
+
+#define EDMA_ALIGN        ARMV7M_DCACHE_LINESIZE
+#define EDMA_ALIGN_MASK   (EDMA_ALIGN - 1)
+#define EDMA_ALIGN_UP(n)  (((n) + EDMA_ALIGN_MASK) & ~EDMA_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* State of a DMA channel */
+
+enum imxrt_dmastate_e
+{
+  IMXRT_DMA_IDLE = 0,             /* No DMA in progress */
+  IMXRT_DMA_CONFIGURED,           /* DMA configured, but not yet started */
+  IMXRT_DMA_ACTIVE                /* DMA has been started and is in progress */
+};
+
+/* This structure describes one DMA channel */
+
+struct imxrt_dmach_s
+{
+  uintptr_t base;                 /* DMA engine base address */
+  uint32_t flags;                 /* DMA channel flags */
+  bool inuse;                     /* true: The DMA channel is in use */
+  uint8_t dmamux;                 /* DMAMUX channel number */
+  uint8_t chan;                   /* DMA channel number (either eDMA3 or 
eDMA4) */
+  uint8_t state;                  /* Channel state.  See enum imxrt_dmastate_e 
*/
+  edma_callback_t callback;       /* Callback invoked when the DMA completes */
+  void *arg;                      /* Argument passed to callback function */
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+  /* That TCD list is linked through the DLAST SGA field.  The first transfer
+   * to be performed is at the head of the list.  Subsequent TCDs are added
+   * at the tail of the list.
+   */
+
+  struct imxrt_edmatcd_s *head;   /* First TCD in the list */
+  struct imxrt_edmatcd_s *tail;   /* Last TCD in the list */
+#endif
+};
+
+/* This structure describes the state of the eDMA controller */
+
+struct imxrt_edma_s
+{
+  /* These mutex protect the DMA channel and descriptor tables */
+
+  mutex_t chlock;                 /* Protects channel table */
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+  sem_t dsem;                     /* Supports wait for free descriptors */
+#endif
+
+  /* This array describes each DMA channel */
+
+  struct imxrt_dmach_s dmach[IMXRT_EDMA_NCHANNELS];
+  spinlock_t lock;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The state of the eDMA */
+
+static struct imxrt_edma_s g_edma =
+{
+  .chlock = NXMUTEX_INITIALIZER,
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+  .dsem = SEM_INITIALIZER(CONFIG_IMXRT_EDMA_NTCD),
+#endif
+  .lock = SP_UNLOCKED
+};
+
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+/* This is a singly-linked list of free TCDs */
+
+static sq_queue_t g_tcd_free;
+
+/* This is a pool of pre-allocated TCDs */
+
+static struct imxrt_edmatcd_s g_tcd_pool[CONFIG_IMXRT_EDMA_NTCD]
+              aligned_data(EDMA_ALIGN);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imxrt_tcd_alloc
+ *
+ * Description:
+ *   Allocate an in-memory, TCD
+ *
+ ****************************************************************************/
+
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+static struct imxrt_edmatcd_s *imxrt_tcd_alloc(void)
+{
+  struct imxrt_edmatcd_s *tcd;
+  irqstate_t flags;
+
+  /* Take the 'dsem'.  When we hold the the 'dsem', then we know that one
+   * TCD is reserved for us in the free list.
+   *
+   * NOTE: We use a critical section here because we may block waiting for
+   * the 'dsem'.  The critical section will be suspended while we are
+   * waiting.
+   */
+
+  nxsem_wait_uninterruptible(&g_edma.dsem);
+
+  /* Now there should be a TCD in the free list reserved just for us */
+
+  flags = spin_lock_irqsave(&g_edma.lock);
+  tcd = (struct imxrt_edmatcd_s *)sq_remfirst(&g_tcd_free);
+  DEBUGASSERT(tcd != NULL);
+
+  spin_unlock_irqrestore(&g_edma.lock, flags);
+  return tcd;
+}
+#endif
+
+/****************************************************************************
+ * Name: imxrt_tcd_free
+ *
+ * Description:
+ *   Free an in-memory, TCD
+ *
+ ****************************************************************************/
+
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+static void imxrt_tcd_free_nolock(struct imxrt_edmatcd_s *tcd)
+{
+  /* Add the the TCD to the end of the free list and post the 'dsem',
+   * possibly waking up another thread that might be waiting for
+   * a TCD.
+   */
+
+  sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
+  nxsem_post(&g_edma.dsem);
+}
+
+static void imxrt_tcd_free(struct imxrt_edmatcd_s *tcd)
+{
+  irqstate_t flags;
+
+  /* Add the TCD to the end of the free list and post the 'dsem',
+   * possibly waking up another thread that might be waiting for
+   * a TCD.
+   */
+
+  flags = spin_lock_irqsave_nopreempt(&g_edma.lock);
+  imxrt_tcd_free_nolock(tcd);
+  spin_unlock_irqrestore_nopreempt(&g_edma.lock, flags);
+}
+#endif
+
+/****************************************************************************
+ * Name: imxrt_tcd_initialize()
+ *
+ * Description:
+ *   Initialize the TCD free list from the pool of pre-allocated TCDs.
+ *
+ * Assumptions:
+ *   Called early in the initialization sequence so no special protection is
+ *   necessary.
+ *
+ ****************************************************************************/
+
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+static inline void imxrt_tcd_initialize(void)
+{
+  sq_entry_t *tcd;
+  int i;
+
+  /* Add each pre-allocated TCD to the tail of the TCD free list */
+
+  sq_init(&g_tcd_free);
+  for (i = 0; i < CONFIG_IMXRT_EDMA_NTCD; i++)
+    {
+      tcd = (sq_entry_t *)&g_tcd_pool[i];
+      sq_addlast(tcd, &g_tcd_free);
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: imxrt_tcd_chanlink
+ *
+ * Description:
+ *   This function configures either a minor link or a major link. The minor
+ *   link means the channel link is triggered every time CITER decreases by 1
+ *   The major link means that the channel link  is triggered when the CITER
+ *   is exhausted.
+ *
+ *   NOTE: Users should ensure that DONE flag is cleared before calling this
+ *   interface, or the configuration is invalid.
+ *
+ * Input Parameters:
+ *   tcd  - Point to the TCD structure.
+ *   type - Channel link type.
+ *   chan - The linked channel number.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_IMXRT_EDMA_ELINK
+static inline void imxrt_tcd_chanlink(uint8_t flags,
+                                     struct imxrt_dmach_s *linkch,
+                                     struct imxrt_edmatcd_s *tcd)
+{
+  uint16_t regval16;
+
+  flags &= EDMA_CONFIG_LINKTYPE_MASK;
+
+  if (linkch == NULL || flags == EDMA_CONFIG_LINKTYPE_LINKNONE)
+    {
+      /* No link or no link channel provided */
+
+      /* Disable minor links */
+
+      /* Disable major link */
+
+      tcd->csr   &= ~EDMA_TCD_CSR_MAJORELINK;
+    }
+  else if (flags == EDMA_CONFIG_LINKTYPE_MINORLINK) /* Minor link config */
+    {
+      /* Enable minor link */
+
+      tcd->citer |= EDMA_TCD_CITER_ELINK;
+      tcd->biter |= EDMA_TCD_BITER_ELINK;
+
+      /* Set linked channel */
+
+      regval16    = tcd->citer;
+      regval16   &= ~EDMA_TCD_CITER_LINKCH_MASK;
+      regval16   |= EDMA_TCD_CITER_LINKCH(linkch->chan);
+      tcd->citer  = regval16;
+
+      regval16    = tcd->biter;
+      regval16   &= ~EDMA_TCD_BITER_LINKCH_MASK;
+      regval16   |= EDMA_TCD_BITER_LINKCH(linkch->chan);
+      tcd->biter  = regval16;
+    }
+  else /* if (flags == EDMA_CONFIG_LINKTYPE_MAJORLINK)  Major link config */
+    {
+      /* Enable major link */
+
+      regval16    = tcd->csr;
+      regval16   |= EDMA_TCD_CSR_MAJORELINK;
+      tcd->csr    = regval16;
+
+      /* Set major linked channel */
+
+      regval16   &= ~EDMA_TCD_CSR_MAJORLINKCH_MASK;
+      regval16   |=  EDMA_TCD_CSR_MAJORLINKCH(linkch->chan);
+      tcd->csr    = regval16;
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: imxrt_tcd_configure
+ *
+ * Description:
+ *  Configure all TCD registers to the specified values.  'tcd' is an
+ *  'overlay' that may refer either to either the TCD register set or to an
+ *  in-memory TCD structure.
+ *
+ ****************************************************************************/
+
+static inline void imxrt_tcd_configure(struct imxrt_edmatcd_s *tcd,
+                            const struct imxrt_edma_xfrconfig_s *config)
+{
+  tcd->saddr    = config->saddr;
+  tcd->soff     = config->soff;
+  tcd->attr     = EDMA_TCD_ATTR_SSIZE(config->ssize) |  /* Transfer Attributes 
*/
+                  EDMA_TCD_ATTR_DSIZE(config->dsize);
+#ifdef CONFIG_IMXRT_EDMA_MOD
+  tcd->attr     |= EDMA_TCD_ATTR_SMOD(config->smod) |  /* Transfer Attributes 
*/
+                   EDMA_TCD_ATTR_DMOD(config->dmod);
+#endif
+  tcd->nbytes   = config->nbytes;
+  tcd->slast    = config->flags & EDMA_CONFIG_LOOPSRC ?
+                                  -(config->iter * config->nbytes) : 0;
+
+  tcd->daddr    = config->daddr;
+  tcd->doff     = config->doff;
+  tcd->citer    = config->iter & EDMA_TCD_CITER_MASK;
+  tcd->biter    = config->iter & EDMA_TCD_BITER_MASK;
+  tcd->csr      = config->flags & EDMA_CONFIG_LOOP_MASK ?
+                                  0 : EDMA_TCD_CSR_DREQ;
+  tcd->csr     |= config->flags & EDMA_CONFIG_INTHALF ?
+                                  EDMA_TCD_CSR_INTHALF : 0;
+  tcd->dlastsga = config->flags & EDMA_CONFIG_LOOPDEST ?
+                                  -(config->iter * config->nbytes) : 0;
+
+  /* And special case flags */
+
+#ifdef CONFIG_IMXRT_EDMA_ELINK
+  /* Configure major/minor link mapping */
+
+  imxrt_tcd_chanlink(config->flags, (struct imxrt_dmach_s *)config->linkch,
+                    tcd);
+#endif
+}
+
+/****************************************************************************
+ * Name: imxrt_tcd_instantiate
+ *
+ * Description:
+ *   Copy an in-memory TCD into eDMA channel TCD registers
+ *
+ ****************************************************************************/
+
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+static void imxrt_tcd_instantiate(struct imxrt_dmach_s *dmach,
+                                  const struct imxrt_edmatcd_s *tcd)
+{
+  uintptr_t base = IMXRT_EDMA_TCD(dmach->base, dmach->chan);
+
+  /* Push tcd into hardware TCD register */
+
+  /* Clear DONE bit first, otherwise ESG cannot be set */
+
+  putreg16(0,             base + IMXRT_EDMA_TCD_CSR_OFFSET);
+
+  putreg32(tcd->saddr,    base + IMXRT_EDMA_TCD_SADDR_OFFSET);
+  putreg16(tcd->soff,     base + IMXRT_EDMA_TCD_SOFF_OFFSET);
+  putreg16(tcd->attr,     base + IMXRT_EDMA_TCD_ATTR_OFFSET);
+  putreg32(tcd->nbytes,   base + IMXRT_EDMA_TCD_NBYTES_OFFSET);
+  putreg32(tcd->slast,    base + IMXRT_EDMA_TCD_SLAST_SDA_OFFSET);
+  putreg32(tcd->daddr,    base + IMXRT_EDMA_TCD_DADDR_OFFSET);
+  putreg16(tcd->doff,     base + IMXRT_EDMA_TCD_DOFF_OFFSET);
+  putreg16(tcd->citer,    base + IMXRT_EDMA_TCD_CITER_OFFSET);
+  putreg32(tcd->dlastsga, base + IMXRT_EDMA_TCD_DLAST_SGA_OFFSET);
+
+  putreg16(tcd->csr,      base + IMXRT_EDMA_TCD_CSR_OFFSET);
+
+  putreg16(tcd->biter,    base + IMXRT_EDMA_TCD_BITER_OFFSET);
+}
+#endif
+
+/****************************************************************************
+ * Name: imxrt_dmaterminate
+ *
+ * Description:
+ *   Terminate the DMA transfer and disable the DMA channel
+ *
+ ****************************************************************************/
+
+static void imxrt_dmaterminate(struct imxrt_dmach_s *dmach, int result)
+{
+  uintptr_t base = IMXRT_EDMA_TCD(dmach->base, dmach->chan);
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+  struct imxrt_edmatcd_s *tcd;
+  struct imxrt_edmatcd_s *next;
+#endif
+  edma_callback_t callback;
+  void *arg;
+
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave_nopreempt(&g_edma.lock);
+
+  /* Disable channel IRQ requests */
+
+  putreg32(EDMA_CH_INT, base + IMXRT_EDMA_CH_INT_OFFSET);
+
+  /* Clear CSR to disable channel. Because if the given channel started,
+   * transfer CSR will be not zero. Because if it is the last transfer, DREQ
+   * will be set.  If not, ESG will be set.
+   */
+
+  putreg32(0, base + IMXRT_EDMA_CH_CSR_OFFSET);
+
+  putreg16(0, base + IMXRT_EDMA_TCD_CSR_OFFSET);
+
+  /* Cancel next TCD transfer. */
+
+  putreg32(0, base + IMXRT_EDMA_TCD_DLAST_SGA_OFFSET);
+
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+  /* Return all allocated TCDs to the free list */
+
+  for (tcd = dmach->head; tcd != NULL; tcd = next)
+    {
+      /* If channel looped to itself we are done
+       * if not continue to free tcds in chain
+       */
+
+      next = dmach->flags & EDMA_CONFIG_LOOPDEST ?
+             NULL : (struct imxrt_edmatcd_s *)((uintptr_t)tcd->dlastsga);
+
+      imxrt_tcd_free_nolock(tcd);
+    }
+
+  dmach->head = NULL;
+  dmach->tail = NULL;
+#endif
+
+  /* Perform the DMA complete callback */
+
+  callback = dmach->callback;
+  arg      = dmach->arg;
+
+  dmach->callback = NULL;
+  dmach->arg      = NULL;
+  dmach->state    = IMXRT_DMA_IDLE;
+
+  spin_unlock_irqrestore_nopreempt(&g_edma.lock, flags);
+
+  if (callback)
+    {
+      callback((DMACH_HANDLE)dmach, arg, true, result);
+    }
+}
+
+/****************************************************************************
+ * Name: imxrt_edma_intstatus
+ *
+ * Description:
+ *   DMA interrupt status per eDMA engine and channel.
+ *
+ ****************************************************************************/
+
+static inline uint32_t imxrt_edma_intstatus(uintptr_t base, uint8_t chan)
+{
+  /* The status register varies depending on eDMA instance and channel */
+
+#ifdef IMXRT_DMA3_BASE
+  /* eDMA3 uses the normal INT register */
+
+  if (base == IMXRT_DMA3_BASE)
+    {
+      return getreg32(IMXRT_EDMA_INT);
+    }
+#endif
+
+#ifdef IMXRT_DMA4_BASE
+  /* eDMA4 has two INT status registers, holding 32 statuses each */
+
+  if (chan > 31)
+    {
+      return getreg32(IMXRT_EDMA_INT_HIGH);
+    }
+
+  return getreg32(IMXRT_EDMA_INT_LOW);
+#endif
+}
+
+/****************************************************************************
+ * Name: imxrt_edma_isr
+ *
+ * Description:
+ *   DMA interrupt service routine. The vector handler calls this with the
+ *   appropriate parameters.
+ *
+ ****************************************************************************/
+
+static int imxrt_edma_isr(int irq, void *context, void *arg)
+{
+  struct imxrt_dmach_s *dmach;
+  uintptr_t base;
+  uint32_t  regval32;
+  uint32_t  errval32;
+  uint8_t   chan;
+  int       result;
+
+  /* 'arg' should the DMA channel instance. */
+
+  dmach = (struct imxrt_dmach_s *)arg;
+  DEBUGASSERT(dmach != NULL);
+
+  chan  = dmach->chan;
+  base  = IMXRT_EDMA_TCD(dmach->base, dmach->chan);
+
+  /* Get the eDMA Error Status register value. */
+
+  errval32  = getreg32(base + IMXRT_EDMA_CH_ES_OFFSET);
+
+  if (errval32 & EDMA_CH_ES_ERR)
+    {
+      DEBUGASSERT(dmach->state == IMXRT_DMA_ACTIVE);
+
+      /* Clear the error */
+
+      putreg32(EDMA_CH_ES_ERR, base + IMXRT_EDMA_CH_ES_OFFSET);
+
+      /* Clear the pending eDMA channel interrupt */
+
+      putreg32(EDMA_CH_INT, base + IMXRT_EDMA_CH_INT_OFFSET);
+
+      imxrt_dmaterminate(dmach, -EIO);
+      return OK;
+    }
+
+  /* Check for an eDMA pending interrupt on this channel */
+
+  regval32 = imxrt_edma_intstatus(dmach->base, dmach->chan);
+  if ((regval32 & EDMA_INT(chan & 31)) != 0)
+    {
+      /* An interrupt is pending.
+       * This should only happen if the channel is active.
+       */
+
+      DEBUGASSERT(dmach->state == IMXRT_DMA_ACTIVE);
+
+      /* Clear the pending eDMA channel interrupt */
+
+      putreg32(EDMA_CH_INT, base + IMXRT_EDMA_CH_INT_OFFSET);
+
+      /* Get the eDMA TCD Control and Status register value. */
+
+      regval32 = getreg32(base + IMXRT_EDMA_CH_CSR_OFFSET);
+
+      /* Check if transfer has finished. */
+
+      if ((regval32 & EDMA_CH_CSR_DONE) != 0)
+        {
+          /* Clear the pending DONE interrupt status. */
+
+          regval32 |= EDMA_CH_CSR_DONE;
+          putreg32(regval32, base + IMXRT_EDMA_CH_CSR_OFFSET);
+          result = OK;
+        }
+      else
+        {
+          /* Perform the half or end-of-major-cycle DMA callback */
+
+          if (dmach->callback != NULL)
+            {
+              dmach->callback((DMACH_HANDLE)dmach, dmach->arg, false, OK);
+            }
+
+          return OK;
+        }
+
+      /* Terminate the transfer when it is done. */
+
+      if ((dmach->flags & EDMA_CONFIG_LOOP_MASK) == 0)
+        {
+          imxrt_dmaterminate(dmach, result);
+        }
+      else if (dmach->callback != NULL)
+        {
+          dmach->callback((DMACH_HANDLE)dmach, dmach->arg, true, result);
+        }
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: imxrt_edma_interrupt
+ *
+ * Description:
+ *   DMA interrupt handler.  This function clears the channel major
+ *   interrupt flag and calls the callback function if it is not NULL.
+ *
+ *   NOTE:  For the case using TCD queue, when the major iteration count is
+ *   exhausted, additional operations are performed.  These include the
+ *   final address adjustments and reloading of the BITER field into the
+ *   CITER.  Assertion of an optional interrupt request also occurs at this
+ *   time, as does a possible fetch of a new TCD from memory using the
+ *   scatter/gather address pointer included in the descriptor (if scatter/
+ *   gather is enabled).
+ *
+ ****************************************************************************/
+
+static int imxrt_edma_interrupt(int irq, void *context, void *arg)
+{
+  struct imxrt_dmach_s *dmach = (struct imxrt_dmach_s *)arg;
+
+#ifdef IMXRT_DMA3_BASE
+  if ((irq >= IMXRT_IRQ_DMA3_CH0) && (irq <= IMXRT_IRQ_DMA3_CH31))
+    {
+      /* eDMA3 interrupt has a single source */
+
+      imxrt_edma_isr(irq, context, dmach);
+    }
+#endif
+
+#ifdef IMXRT_DMA4_BASE
+  if ((irq >= IMXRT_IRQ_DMA4_CH0_CH1_CH32_CH33) &&
+      (irq <= IMXRT_IRQ_DMA4_CH30_CH31_CH62_CH63))
+    {
+      /* eDMA4 interrupt has four sources on iMXRT8x */
+
+      imxrt_edma_isr(irq, context, dmach);
+      imxrt_edma_isr(irq, context, dmach + 1);
+      imxrt_edma_isr(irq, context, dmach + 32);
+      imxrt_edma_isr(irq, context, dmach + 33);
+    }
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: imxrt_edma_configure
+ *
+ * Description:
+ *   Configure eDMA instance.
+ *
+ ****************************************************************************/
+
+static void imxrt_edma_configure(uintptr_t base)
+{
+  uint32_t regval;
+
+  /* Configure the eDMA controllers */
+
+  regval = getreg32(IMXRT_EDMA_CSR(base));
+  regval &= ~(EDMA_CSR_EDBG | EDMA_CSR_ERCA | EDMA_CSR_HAE | EDMA_CSR_GCLC |
+              EDMA_CSR_GMRC);
+
+#ifdef CONFIG_IMXRT_EDMA_EDBG
+  regval |= EDMA_CSR_EDBG;   /* Enable Debug */
+#endif
+#ifdef CONFIG_IMXRT_EDMA_ERCA
+  regval |= EDMA_CSR_ERCA;   /* Enable Round Robin Channel Arbitration */
+#endif
+#ifdef CONFIG_IMXRT_EDMA_ERGA
+  regval |= EDMA_CSR_ERGA;   /* Enable Round Robin Group Arbitration */
+#endif
+#ifdef CONFIG_IMXRT_EDMA_HOE
+  regval |= EDMA_CSR_HAE;    /* Halt On Error */
+#endif
+#ifdef CONFIG_IMXRT_EDMA_CLM
+  regval |= EDMA_CSR_GCLC;   /* Continuous Link Mode */
+#endif
+
+  putreg32(regval, IMXRT_EDMA_CSR(base));
+}
+
+/****************************************************************************
+ * Name: imxrt_find_free_ch
+ *
+ * Description:
+ *   Configure eDMA instance.
+ *
+ ****************************************************************************/
+
+static struct imxrt_dmach_s * imxrt_find_free_ch(uint16_t dmamux)
+{
+  struct imxrt_dmach_s *candidate;
+  uintptr_t base;
+  unsigned int chndx;
+  unsigned int offset;
+  unsigned int max;
+
+  /* eDMA base for MUX */
+
+  base = imxrt_dmamux_get_dmabase(dmamux);
+
+  /* On RT118x both eDMA3 and eDMA4 have per-channel CH_MUX registers so
+   * any free channel of the correct engine can be used.
+   */
+
+  offset = imxrt_edma_choffset(base);
+  max    = imxrt_edma_chmax(base);
+
+  for (chndx = offset; chndx < max; chndx++)
+    {
+      candidate = &g_edma.dmach[chndx];
+      if (!candidate->inuse)
+        {
+          return candidate;
+        }
+    }
+
+  return NULL;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm_dma_initialize
+ *
+ * Description:
+ *   Initialize the DMA subsystem
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void weak_function arm_dma_initialize(void)
+{
+  struct imxrt_dmach_s *dmach;
+  uintptr_t base;
+  int chan;
+  int i;
+
+  dmainfo("Initialize eDMA\n");
+
+  /* Configure the instances. */
+
+  dmach = &g_edma.dmach[0];
+
+#ifdef IMXRT_DMA3_BASE
+  /* Configure eDMA3's LPCG29 (m33_clk_root). That root is already configured
+   * by the M33 boot ROM so we only need to enable the LPCG.
+   */
+
+  imxrt_ccm_gate_on(CCM_LPCG_EDMA3, true);
+
+  imxrt_edma_configure(IMXRT_DMA3_BASE);
+
+  /* Initialize the channel */
+
+  for (i = 0; i < DMA3_CHANNEL_COUNT; i++, dmach++)
+    {
+      dmach->base = IMXRT_DMA3_BASE;
+      dmach->chan = i;
+
+      irq_attach(IMXRT_IRQ_DMA3_CH0 + i, imxrt_edma_interrupt, dmach);
+    }
+#endif
+
+#ifdef IMXRT_DMA4_BASE
+  /* Configure eDMA4's clock root and enable its LPCG.
+   *
+   * wakeup_axi_clk_root = SYS_PLL3_OUT (480 MHz) / 2 = 240 MHz.
+   */
+
+  imxrt_ccm_configure_root_clock(CCM_CR_WAKEUP_AXI, SYS_PLL3_OUT, 2);
+
+  /* Enable peripheral clock (eDMA4: wakeup_axi_clk_root, LPCG30) */
+
+  imxrt_ccm_gate_on(CCM_LPCG_EDMA4, true);
+
+  imxrt_edma_configure(IMXRT_DMA4_BASE);
+
+  /* Initialize the channel */
+
+  for (i = 0; i < DMA4_CHANNEL_COUNT; i++, dmach++)
+    {
+      dmach->base = IMXRT_DMA4_BASE;
+      dmach->chan = i;
+
+      /* Each eDMA4 interrupt is shared by four channels: n, n+1, n+32 and
+       * n+33.  So IRQ (DMA4_CH0_CH1_CH32_CH33 + k) serves the channels
+       * 2k, 2k+1, 2k+32 and 2k+33, and the 64 channels are covered by the
+       * 32 lowest channel handles only.  Attach every second channel of
+       * the lower half and pass that channel's handle as the argument.
+       */
+
+      if (i < (DMA4_CHANNEL_COUNT / 2) && (i & 0x01) == 0)
+        {
+          irq_attach(IMXRT_IRQ_DMA4_CH0_CH1_CH32_CH33 + (i >> 1),
+                     imxrt_edma_interrupt, dmach);
+        }
+    }
+#endif
+
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+  /* Initialize the list of free TCDs from the pool of pre-allocated TCDs. */
+
+  imxrt_tcd_initialize();
+#endif
+
+  /* Disable all DMA channel interrupts at the eDMA controller */
+
+  for (i = 0; i < IMXRT_EDMA_NCHANNELS; i++)
+    {
+      /* DMA engine base and TCD channel */
+
+      base = g_edma.dmach[i].base;
+      chan = g_edma.dmach[i].chan;
+
+      /* Disable all DMA channels and DMA channel interrupts */
+
+      putreg32(0, IMXRT_EDMA_TCD(base, chan) + IMXRT_EDMA_CH_CSR_OFFSET);
+
+      /* Clear interrupt if any */
+
+      putreg32(1, IMXRT_EDMA_TCD(base, chan) + IMXRT_EDMA_CH_INT_OFFSET);
+
+      /* Set all TCD CSR, biter and citer entries to 0 so that
+       * will be 0 when DONE is not set so that imxrt_dmach_getcount
+       * reports 0.
+       */
+
+      putreg16(0, IMXRT_EDMA_TCD(base, chan) + IMXRT_EDMA_TCD_CSR_OFFSET);
+      putreg16(0, IMXRT_EDMA_TCD(base, chan) + IMXRT_EDMA_TCD_CITER_OFFSET);
+      putreg16(0, IMXRT_EDMA_TCD(base, chan) + IMXRT_EDMA_TCD_BITER_OFFSET);
+    }
+
+#ifdef IMXRT_DMA3_BASE
+  /* Clear all pending DMA channel interrupts */
+
+  putreg32(0xffffffff, IMXRT_EDMA_INT);
+
+  /* Enable the channel interrupts at the NVIC (still disabled at the eDMA
+   * controller).
+   */
+
+  for (i = 0; i < DMA3_IRQ_COUNT; i++)
+    {
+      up_enable_irq(IMXRT_IRQ_DMA3_CH0 + i);
+    }
+#endif
+
+#ifdef IMXRT_DMA4_BASE
+  /* Clear all pending DMA channel interrupts */
+
+  putreg32(0xffffffff, IMXRT_EDMA_INT_LOW);
+  putreg32(0xffffffff, IMXRT_EDMA_INT_HIGH);
+
+  /* Enable the channel interrupts at the NVIC (still disabled at the eDMA
+   * controller).
+   */
+
+  for (i = 0; i < DMA4_IRQ_COUNT; i++)
+    {
+      up_enable_irq(IMXRT_IRQ_DMA4_CH0_CH1_CH32_CH33 + i);
+    }
+#endif
+}
+
+/****************************************************************************
+ * Name: imxrt_dmach_alloc
+ *
+ *   Allocate a DMA channel.  This function sets aside a DMA channel,
+ *   initializes the DMAMUX for the channel, then gives the caller exclusive
+ *   access to the DMA channel.
+ *
+ * Input Parameters:
+ *
+ *   dmamux - DMAMUX configuration see DMAMUX channel configuration register
+ *            bit-field definitions in hardware/imxrt_dmamux.h.
+ *            Settings include:
+ *
+ *            DMAMUX_CHCFG_SOURCE     Chip-specific DMA source (required)
+ *            DMAMUX_CHCFG_TRIG       DMA Channel Trigger Enable (optional)
+ *            DMAMUX_CHCFG_ENBL       DMA Mux Channel Enable (required)
+ *
+ *            A value of zero will disable the DMAMUX channel.
+ *   dchpri - DCHPRI channel priority configuration.  See DCHPRI channel
+ *            configuration register bit-field definitions in
+ *            hardware/imxrt_edma.h.  Meaningful settings include:
+ *
+ *            EDMA_DCHPRI_CHPRI       Channel Arbitration Priority
+ *            DCHPRI_DPA              Disable Preempt Ability
+ *            DCHPRI_ECP              Enable Channel Preemption
+ *
+ *            The power-on default, 0x05, is a reasonable choice.
+ *
+ * Returned Value:
+ *   If a DMA channel is available, this function returns a non-NULL, void*
+ *   DMA channel handle.  NULL is returned on any failure.
+ *
+ ****************************************************************************/
+
+DMACH_HANDLE imxrt_dmach_alloc(uint32_t dmamux, uint8_t dchpri)
+{
+  struct imxrt_dmach_s *dmach;
+  uintptr_t base;
+  uint32_t regval;
+  int ret;
+
+  /* Search for an available DMA channel */
+
+  dmach = NULL;
+  ret = nxmutex_lock(&g_edma.chlock);
+  if (ret < 0)
+    {
+      return NULL;
+    }
+
+  /* Find channel for this DMA MUX */
+
+  dmach = imxrt_find_free_ch(dmamux);
+  if (dmach)
+    {
+      dmach->inuse  = true;
+      dmach->state  = IMXRT_DMA_IDLE;
+      dmach->dmamux = dmamux & EDMA_MUX_MASK;
+
+      /* TCD register base */
+
+      base = IMXRT_EDMA_TCD(dmach->base, dmach->chan);
+
+      /* Clear any pending interrupts on the channel */
+
+      putreg32(0, base + IMXRT_EDMA_CH_CSR_OFFSET);
+
+      /* Make sure that the channel is disabled. */
+
+      putreg32(EDMA_CH_INT, base + IMXRT_EDMA_CH_INT_OFFSET);
+
+      regval = getreg32(base + IMXRT_EDMA_CH_SBR_OFFSET);
+      regval |= EDMA_CH_SBR_EMI | EDMA_CH_SBR_SEC | EDMA_CH_SBR_PAL;
+      putreg32(regval, base + IMXRT_EDMA_CH_SBR_OFFSET);
+
+      /* Set the DMAMUX source */
+
+      if (imxrt_edma_tcdhasmux(dmach->base))
+        {
+          /* Set reset value first to CH MUX */
+
+          putreg8(0, base + IMXRT_EDMA_CH_MUX_OFFSET);
+          dmainfo("CH%d: MUX:%u->%p\n", dmach->chan, dmach->dmamux,
+                  (void *)(base + IMXRT_EDMA_CH_MUX_OFFSET));
+          putreg8(dmach->dmamux, base + IMXRT_EDMA_CH_MUX_OFFSET);
+        }
+    }
+
+  nxmutex_unlock(&g_edma.chlock);
+
+  /* Show the result of the allocation */
+
+  if (dmach != NULL)
+    {
+      dmainfo("CH%d: returning dmach: %p\n", dmach->chan, dmach);
+    }
+  else
+    {
+      dmaerr("ERROR: Failed allocate eDMA channel\n");
+    }
+
+  return (DMACH_HANDLE)dmach;
+}
+
+/****************************************************************************
+ * Name: imxrt_dmach_free
+ *
+ * Description:
+ *   Release a DMA channel.  NOTE:  The 'handle' used in this argument must
+ *   NEVER be used again until imxrt_dmach_alloc() is called again to
+ *   re-gain a valid handle.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void imxrt_dmach_free(DMACH_HANDLE handle)
+{
+  struct imxrt_dmach_s *dmach = (struct imxrt_dmach_s *)handle;
+  uintptr_t base = IMXRT_EDMA_TCD(dmach->base, dmach->chan);
+
+  dmainfo("dmach: %p\n", dmach);
+  DEBUGASSERT(dmach != NULL && dmach->inuse &&
+              dmach->state != IMXRT_DMA_ACTIVE);
+
+  /* Mark the channel no longer in use.  Clearing the inuse flag is an atomic
+   * operation and so should be safe.
+   */
+
+  dmach->flags = 0;
+  dmach->inuse = false;                /* No longer in use */
+  dmach->state = IMXRT_DMA_IDLE;       /* Better not be active! */
+
+  /* Make sure that the channel is disabled. */
+
+  putreg32(EDMA_CH_INT, base + IMXRT_EDMA_CH_INT_OFFSET);
+
+  /* Disable the associated DMAMUX */
+
+  if (imxrt_edma_tcdhasmux(dmach->base))
+    {
+      putreg8(0, base + IMXRT_EDMA_CH_MUX_OFFSET);
+    }
+}
+
+/****************************************************************************
+ * Name: imxrt_dmach_xfrsetup
+ *
+ * Description:
+ *   This function adds the eDMA transfer to the DMA sequence.  The request
+ *   is setup according to the content of the transfer configuration
+ *   structure. For "normal" DMA, imxrt_dmach_xfrsetup is called only once.
+ *   Scatter/gather DMA is accomplished by calling this function repeatedly,
+ *   once for each transfer in the sequence.  Scatter/gather DMA processing
+ *   is enabled automatically when the second transfer configuration is
+ *   received.
+ *
+ *   This function may be called multiple times to handle multiple,
+ *   discontinuous transfers (scatter-gather)
+ *
+ * Input Parameters:
+ *   handle - DMA channel handle created by imxrt_dmach_alloc()
+ *   config - A DMA transfer configuration instance, populated by the
+ *            The content of 'config' describes the transfer
+ *
+ * Returned Value
+ *   Zero (OK) is returned on success; a negated errno value is returned on
+ *   any failure.
+ *
+ ****************************************************************************/
+
+int imxrt_dmach_xfrsetup(DMACH_HANDLE handle,
+                        const struct imxrt_edma_xfrconfig_s *config)
+{
+  struct imxrt_dmach_s *dmach = (struct imxrt_dmach_s *)handle;
+  uintptr_t base = IMXRT_EDMA_TCD(dmach->base, dmach->chan);
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+  struct imxrt_edmatcd_s *tcd;
+  struct imxrt_edmatcd_s *prev;
+  uint16_t mask = config->flags & EDMA_CONFIG_INTMAJOR ? 0 :
+                                  EDMA_TCD_CSR_INTMAJOR;
+  uint16_t regval16;
+#else
+  uint32_t regval32;
+#endif
+
+  DEBUGASSERT(dmach != NULL);
+  dmainfo("dmach%u: %p config: %p\n", dmach->chan, dmach, config);
+
+  dmach->flags  = config->flags;
+
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+  /* Scatter/gather DMA is supported */
+
+  /* Allocate a TCD, waiting if necessary */
+
+  tcd = imxrt_tcd_alloc();
+
+  /* Configure current TCD block transfer. */
+
+  imxrt_tcd_configure(tcd, config);
+
+  /* Enable the interrupt when the major iteration count completes for this
+   * TCD.  For "normal" DMAs, this will correspond to the DMA DONE
+   * interrupt; for scatter gather DMAs, multiple interrupts will be
+   * generated with the final being the DONE interrupt.
+   */
+
+  tcd->csr |= EDMA_TCD_CSR_INTMAJOR;
+
+  /* Is this the first descriptor in the list? */
+
+  if (dmach->head == NULL)
+    {
+      /* Yes.. add it to the list */
+
+      dmach->head  = tcd;
+      dmach->tail  = tcd;
+
+      /* And instantiate the first TCD in the DMA channel TCD registers. */
+
+      imxrt_tcd_instantiate(dmach, tcd);
+    }
+  else
+    {
+      /* Cannot mix transfer types */
+
+      if (dmach->flags & EDMA_CONFIG_LOOP_MASK)
+        {
+          imxrt_tcd_free(tcd);
+          return -EINVAL;
+        }
+
+      /* Chain from previous descriptor in the list. */
+
+      /* Enable scatter/gather feature in the previous TCD. */
+
+      prev           = dmach->tail;
+      regval16       = prev->csr;
+      regval16      &= ~(EDMA_TCD_CSR_DREQ | mask);
+      regval16      |= EDMA_TCD_CSR_ESG;
+      prev->csr      = regval16;
+
+      prev->dlastsga = (uint32_t)((uintptr_t)tcd);
+      dmach->tail    = tcd;
+
+      /* Clean cache associated with the previous TCD memory */
+
+      up_clean_dcache((uintptr_t)prev,
+                      (uintptr_t)prev + sizeof(struct imxrt_edmatcd_s));
+
+      /* Check if the TCD block in the DMA channel registers is the same as
+       * the previous previous TCD.  This can happen if the previous TCD was
+       * the first TCD and has already be loaded into the TCD registers.
+       */
+
+      if (dmach->head == prev)
+        {
+          /* Enable scatter/gather also in the TCD registers. */
+
+          regval16  = getreg16(base + IMXRT_EDMA_TCD_CSR_OFFSET);
+          regval16 &= ~(EDMA_TCD_CSR_DREQ | mask);
+          regval16 |= EDMA_TCD_CSR_ESG;
+          putreg16(regval16, base + IMXRT_EDMA_TCD_CSR_OFFSET);
+
+          putreg32((uint32_t)((uintptr_t)tcd),
+                   base + IMXRT_EDMA_TCD_DLAST_SGA_OFFSET);
+        }
+    }
+
+  /* Clean cache associated with the TCD memory */
+
+  up_clean_dcache((uintptr_t)tcd,
+                  (uintptr_t)tcd + sizeof(struct imxrt_edmatcd_s));
+#else
+
+  /* Scatter/gather DMA is NOT supported */
+
+  /* Check if eDMA is busy: if the channel has started transfer, CSR will be
+   * non-zero.
+   */
+
+  regval32  = getreg32(base + IMXRT_EDMA_CH_CSR_OFFSET);
+
+  if (regval32 != 0 && (regval32 & EDMA_CH_CSR_DONE) == 0)
+    {
+      return -EBUSY;
+    }
+
+  /* Configure channel TCD registers to the values specified in config. */
+
+  imxrt_tcd_configure((struct imxrt_edmatcd_s *)
+                     (base + IMXRT_EDMA_TCD_SADDR_OFFSET), config);
+
+  /* Enable the DONE interrupt when the major iteration count completes. */
+
+  modifyreg16(base + IMXRT_EDMA_TCD_CSR_OFFSET, 0, EDMA_TCD_CSR_INTMAJOR);
+#endif
+
+  dmach->state = IMXRT_DMA_CONFIGURED;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: imxrt_dmach_start
+ *
+ * Description:
+ *   Start the DMA transfer.  This function should be called after the final
+ *   call to imxrt_dmach_xfrsetup() in order to avoid race conditions.
+ *
+ *   At the conclusion of each major DMA loop, a callback to the user
+ *   provided function is made:  |For "normal" DMAs, this will correspond to
+ *   the DMA DONE interrupt; for scatter gather DMAs,
+ *   this will be generated with the final TCD.
+ *
+ *   At the conclusion of the DMA, the DMA channel is reset, all TCDs are
+ *   freed, and the callback function is called with the the success/fail
+ *   result of the DMA.
+ *
+ *   NOTE: On Rx DMAs (peripheral-to-memory or memory-to-memory), it is
+ *   necessary to invalidate the destination memory.  That is not done
+ *   automatically by the DMA module.  Invalidation of the destination memory
+ *   regions is the responsibility of the caller.
+ *
+ * Input Parameters:
+ *   handle   - DMA channel handle created by imxrt_dmach_alloc()
+ *   callback - The callback to be invoked when the DMA is completes or is
+ *              aborted.
+ *   arg      - An argument that accompanies the callback
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned on
+ *   any failure.
+ *
+ ****************************************************************************/
+
+int imxrt_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
+                     void *arg)
+{
+  struct imxrt_dmach_s *dmach = (struct imxrt_dmach_s *)handle;
+  uintptr_t base = IMXRT_EDMA_TCD(dmach->base, dmach->chan);
+  irqstate_t flags;
+  uint32_t regval;
+  uint8_t chan;
+
+  DEBUGASSERT(dmach != NULL && dmach->state == IMXRT_DMA_CONFIGURED);
+  chan            = dmach->chan;
+  dmainfo("dmach%u: %p callback: %p arg: %p\n", chan, dmach, callback, arg);
+
+  /* Save the callback info.  This will be invoked when the DMA completes */
+
+  flags           = spin_lock_irqsave(&g_edma.lock);
+  dmach->callback = callback;
+  dmach->arg      = arg;
+
+#if CONFIG_IMXRT_EDMA_NTCD > 0
+  /* Although it is not recommended, it might be possible to call this
+   * function multiple times while adding TCDs on the fly.
+   */
+
+  if (dmach->state != IMXRT_DMA_ACTIVE)
+#endif
+    {
+      dmach->state   = IMXRT_DMA_ACTIVE;
+
+      regval         = getreg32(base + IMXRT_EDMA_CH_CSR_OFFSET);
+      regval        |= EDMA_CH_CSR_ERQ | EDMA_CH_CSR_EEI;
+      putreg32(regval, base + IMXRT_EDMA_CH_CSR_OFFSET);
+
+      if ((dmach->flags & EDMA_CONFIG_SWSTART) != 0)
+        {
+          putreg16(getreg16(base + IMXRT_EDMA_TCD_CSR_OFFSET) |
+                   EDMA_TCD_CSR_START,
+                   base + IMXRT_EDMA_TCD_CSR_OFFSET);
+        }
+    }
+
+  spin_unlock_irqrestore(&g_edma.lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: imxrt_dmach_stop
+ *
+ * Description:
+ *   Cancel the DMA.  After imxrt_dmach_stop() is called, the DMA channel
+ *   is reset, all TCDs are freed, and imxrt_dmarx/txsetup() must be called
+ *   before imxrt_dmach_start() can be called again.
+ *
+ * Input Parameters:
+ *   handle   - DMA channel handle created by imxrt_dmach_alloc()
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void imxrt_dmach_stop(DMACH_HANDLE handle)
+{
+  struct imxrt_dmach_s *dmach = (struct imxrt_dmach_s *)handle;
+
+  dmainfo("dmach: %p\n", dmach);
+  DEBUGASSERT(dmach != NULL);
+
+  imxrt_dmaterminate(dmach, -EINTR);
+}
+
+/****************************************************************************
+ * Name: imxrt_dmach_getcount
+ *
+ * Description:
+ *   This function checks the TCD (Task Control Descriptor) status for a
+ *   specified eDMA channel and returns the the number of major loop counts
+ *   that have not finished.
+ *
+ *   NOTES:
+ *   1. This function can only be used to get unfinished major loop count of
+ *      transfer without the next TCD, or it might be inaccuracy.
+ *   2. The unfinished/remaining transfer bytes cannot be obtained directly
+ *      from registers while the channel is running.
+ *
+ *   Because to calculate the remaining bytes, the initial NBYTES configured
+ *   in DMA_TCDn_NBYTES_MLNO register is needed while the eDMA IP does not
+ *   support getting it while a channel is active.  In another words, the
+ *   NBYTES value reading is always the actual (decrementing) NBYTES value
+ *   the dma_engine is working with while a channel is running.
+ *   Consequently, to get the remaining transfer bytes, a software-saved
+ *   initial value of NBYTES (for example copied before enabling the channel)
+ *   is needed. The formula to calculate it is shown below:
+ *
+ *     RemainingBytes = RemainingMajorLoopCount *
+ *                      NBYTES(initially configured)
+ *
+ * Input Parameters:
+ *   handle  - DMA channel handle created by imxrt_dmach_alloc()
+ *
+ * Returned Value:
+ *   Major loop count which has not been transferred yet for the current TCD.
+ *
+ ****************************************************************************/
+
+unsigned int imxrt_dmach_getcount(DMACH_HANDLE handle)
+{
+  struct imxrt_dmach_s *dmach = (struct imxrt_dmach_s *)handle;
+  uintptr_t base = IMXRT_EDMA_TCD(dmach->base, dmach->chan);
+  unsigned int remaining = 0;
+  uintptr_t regval32;
+  uint16_t regval16;
+
+  DEBUGASSERT(dmach != NULL);
+
+  /* If the DMA is done, then the remaining count is zero */
+
+  regval32  = getreg32(base + IMXRT_EDMA_CH_CSR_OFFSET);
+
+  if ((regval32 & EDMA_CH_CSR_DONE) == 0)
+    {
+      /* Calculate the unfinished bytes */
+
+      regval16 = getreg16(base + IMXRT_EDMA_TCD_CITER_OFFSET);
+
+      if ((regval16 & EDMA_TCD_CITER_ELINK) != 0)
+        {
+          remaining = (regval16 & EDMA_TCD_CITER_MASK_ELINK) >>
+                      EDMA_TCD_CITER_SHIFT;
+        }
+      else
+        {
+          remaining = (regval16 & EDMA_TCD_CITER_MASK) >>
+                       EDMA_TCD_CITER_SHIFT;
+        }
+    }
+
+  return remaining;
+}
+
+/****************************************************************************
+ * Name: imxrt_dmach_idle
+ *
+ * Description:
+ *   This function checks if the dma is idle
+ *
+ * Returned Value:
+ *   0  - if idle
+ *   !0 - not
+ *
+ ****************************************************************************/
+
+unsigned int imxrt_dmach_idle(DMACH_HANDLE handle)
+{
+  struct imxrt_dmach_s *dmach = (struct imxrt_dmach_s *)handle;
+
+  return dmach->state == IMXRT_DMA_IDLE ? 0 : -1;
+}
+
+/****************************************************************************
+ * Name: imxrt_dmasample
+ *
+ * Description:
+ *   Sample DMA register contents
+ *
+ * Assumptions:
+ *   - DMA handle allocated by imxrt_dmach_alloc()
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+void imxrt_dmasample(DMACH_HANDLE handle, struct imxrt_dmaregs_s *regs)
+{
+  struct imxrt_dmach_s *dmach = (struct imxrt_dmach_s *)handle;
+  unsigned int chan;
+  irqstate_t flags;
+  uintptr_t base = IMXRT_EDMA_TCD(dmach->base, dmach->chan);
+
+  DEBUGASSERT(dmach != NULL && regs != NULL);
+  chan           = dmach->chan;
+  regs->chan     = chan;
+
+  /* eDMA Global Registers */
+
+  flags          = spin_lock_irqsave(&g_edma.lock);
+
+  /* REVISIT: eDMA4 does not show INT_HIGH / HRS_HIGH values correctly */
+
+  regs->cr       = getreg32(IMXRT_EDMA_CSR(base)); /* Control */
+  regs->es       = getreg32(IMXRT_EDMA_ES(base));  /* Error Status */
+  regs->req      = getreg32(IMXRT_EDMA_INT);       /* Interrupt Request */
+  regs->hrs      = getreg32(IMXRT_EDMA_HRS);       /* Hardware Request Status 
*/
+
+  /* eDMA TCD */
+
+  regs->saddr    = getreg32(base + IMXRT_EDMA_TCD_SADDR_OFFSET);
+  regs->soff     = getreg16(base + IMXRT_EDMA_TCD_SOFF_OFFSET);
+  regs->attr     = getreg16(base + IMXRT_EDMA_TCD_ATTR_OFFSET);
+  regs->nbml     = getreg32(base + IMXRT_EDMA_TCD_NBYTES_OFFSET);
+  regs->slast    = getreg32(base + IMXRT_EDMA_TCD_SLAST_SDA_OFFSET);
+  regs->daddr    = getreg32(base + IMXRT_EDMA_TCD_DADDR_OFFSET);
+  regs->doff     = getreg16(base + IMXRT_EDMA_TCD_DOFF_OFFSET);
+  regs->citer    = getreg16(base + IMXRT_EDMA_TCD_CITER_OFFSET);
+  regs->dlastsga = getreg32(base + IMXRT_EDMA_TCD_DLAST_SGA_OFFSET);
+  regs->csr      = getreg16(base + IMXRT_EDMA_TCD_CSR_OFFSET);
+  regs->biter    = getreg16(base + IMXRT_EDMA_TCD_BITER_OFFSET);
+
+  /* DMAMUX registers */
+
+  if (imxrt_edma_tcdhasmux(dmach->base))
+    {
+      regs->dmamux = getreg32(base + IMXRT_EDMA_CH_MUX_OFFSET);
+    }
+  else
+    {
+      regs->dmamux = 0;
+    }
+
+  spin_unlock_irqrestore(&g_edma.lock, flags);
+}
+#endif /* CONFIG_DEBUG_DMA */
+
+/****************************************************************************
+ * Name: imxrt_dmadump
+ *
+ * Description:
+ *   Dump previously sampled DMA register contents
+ *
+ * Assumptions:
+ *   - DMA handle allocated by imxrt_dmach_alloc()
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+void imxrt_dmadump(const struct imxrt_dmaregs_s *regs, const char *msg)
+{
+  unsigned int chan;
+
+  DEBUGASSERT(regs != NULL && msg != NULL);
+
+  chan = regs->chan;
+  DEBUGASSERT(chan < IMXRT_EDMA_NCHANNELS);
+
+  dmainfo("%s\n", msg);
+  dmainfo("  eDMA Global Registers:\n");
+  dmainfo("          CR: %08x\n", (unsigned int)regs->cr);
+  dmainfo("          ES: %08x\n", (unsigned int)regs->es);
+  dmainfo("         INT: %08x\n", (unsigned int)regs->req);
+  dmainfo("        EARS: %08x\n", (unsigned int)regs->hrs);
+
+  /* eDMA Channel registers */
+
+  dmainfo("  eDMA Channel %u Registers:\n", chan);
+  dmainfo("    DCHPRI: %02x\n", regs->dchpri);
+
+  /* eDMA TCD */
+
+  dmainfo("  eDMA Channel %u TCD Registers:\n", chan);
+  dmainfo("       SADDR: %08x\n", (unsigned int)regs->saddr);
+  dmainfo("        SOFF: %04x\n", (unsigned int)regs->soff);
+  dmainfo("        ATTR: %04x\n", (unsigned int)regs->attr);
+  dmainfo("        NBML: %05x\n", (unsigned int)regs->nbml);
+  dmainfo("       SLAST: %05x\n", (unsigned int)regs->slast);
+  dmainfo("       DADDR: %05x\n", (unsigned int)regs->daddr);
+  dmainfo("        DOFF: %04x\n", (unsigned int)regs->doff);
+  dmainfo("       CITER: %04x\n", (unsigned int)regs->citer);
+  dmainfo("    DLASTSGA: %08x\n", (unsigned int)regs->dlastsga);
+  dmainfo("         CSR: %04x\n", (unsigned int)regs->csr);
+  dmainfo("       BITER: %04x\n", (unsigned int)regs->biter);
+
+  /* DMAMUX registers */
+
+  dmainfo("  DMAMUX Channel %u Registers:\n", chan);
+  dmainfo("      DMAMUX: %08x\n", (unsigned int)regs->dmamux);
+}
+#endif /* CONFIG_DEBUG_DMA */
+#endif /* CONFIG_IMXRT_EDMA */

Reply via email to