[rtems commit] bsps/shared: Adapt fsl-edma driver for imxrt

Christian Mauderer christianm at rtems.org
Thu Jan 21 09:26:34 UTC 2021


Module:    rtems
Branch:    master
Commit:    a434cc80cb00e2f15a51205d6b813fc8c58803ac
Changeset: http://git.rtems.org/rtems/commit/?id=a434cc80cb00e2f15a51205d6b813fc8c58803ac

Author:    Christian Mauderer <christian.mauderer at embedded-brains.de>
Date:      Tue Nov 24 17:22:38 2020 +0100

bsps/shared: Adapt fsl-edma driver for imxrt

Note: The changes have been done with portability in mind. The driver
should (in theory) be able to replace the original one in the MPC BSPs
too. For full compatibility an adaption layer and especially a test
would be necessary. Because both are missing, don't integrate it into
the MPC BSP now.

Update #4180

---

 bsps/arm/imxrt/start/bspstart.c              |   3 +
 bsps/include/fsl/edma.h                      | 218 +++---
 bsps/include/fsl/regs-edma.h                 | 977 ++++++++++-----------------
 bsps/shared/dev/dma/fsl-edma.c               | 349 +++++++---
 spec/build/bsps/arm/imxrt/bspimxrt.yml       |   2 +
 spec/build/bsps/arm/imxrt/optfsledmaemlm.yml |  16 +
 spec/build/bsps/obj.yml                      |   5 +
 7 files changed, 746 insertions(+), 824 deletions(-)

diff --git a/bsps/arm/imxrt/start/bspstart.c b/bsps/arm/imxrt/start/bspstart.c
index 884f0aa..445af04 100644
--- a/bsps/arm/imxrt/start/bspstart.c
+++ b/bsps/arm/imxrt/start/bspstart.c
@@ -35,6 +35,7 @@
 #include <bsp/irq.h>
 #include <bsp/linker-symbols.h>
 #include <bsp/flash-headers.h>
+#include <fsl/edma.h>
 
 #include <fsl_clock.h>
 #include <libfdt.h>
@@ -139,3 +140,5 @@ RTEMS_SYSINIT_ITEM(imxrt_lpi2c_init, RTEMS_SYSINIT_DEVICE_DRIVERS,
     RTEMS_SYSINIT_ORDER_MIDDLE);
 RTEMS_SYSINIT_ITEM(imxrt_ffec_init, RTEMS_SYSINIT_DEVICE_DRIVERS,
     RTEMS_SYSINIT_ORDER_MIDDLE);
+RTEMS_SYSINIT_ITEM(fsl_edma_init, RTEMS_SYSINIT_DEVICE_DRIVERS,
+    RTEMS_SYSINIT_ORDER_FIRST);
diff --git a/bsps/include/fsl/edma.h b/bsps/include/fsl/edma.h
index 8b7d65d..a2727f0 100644
--- a/bsps/include/fsl/edma.h
+++ b/bsps/include/fsl/edma.h
@@ -1,29 +1,40 @@
 /**
  * @file
  *
- * @ingroup RTEMSBSPsPowerPCMPC55XX
+ * @ingroup RTEMSBSPsSharedFslEDMA
  *
- * @brief Enhanced Direct Memory Access (eDMA).
+ * @brief Freescale / NXP Enhanced Direct Memory Access (eDMA).
  */
 
 /*
- * Copyright (c) 2008-2013 embedded brains GmbH.  All rights reserved.
+ * Copyright (C) 2008-2020 embedded brains GmbH (http://www.embedded-brains.de)
  *
- *  embedded brains GmbH
- *  Dornierstr. 4
- *  82178 Puchheim
- *  Germany
- *  <rtems at embedded-brains.de>
+ * 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.
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
  */
 
-#ifndef LIBCPU_POWERPC_MPC55XX_EDMA_H
-#define LIBCPU_POWERPC_MPC55XX_EDMA_H
+#ifndef LIBBSP_SHARED_FSL_EDMA_H
+#define LIBBSP_SHARED_FSL_EDMA_H
 
-#include <mpc55xx/regs.h>
+#include <fsl/regs-edma.h>
 
 #include <rtems.h>
 #include <rtems/chain.h>
@@ -32,7 +43,9 @@
 extern "C" {
 #endif /* __cplusplus */
 
-#if MPC55XX_CHIP_FAMILY == 551
+#ifdef LIBBSP_ARM_IMXRT_BSP_H
+  #define EDMA_CHANNEL_COUNT 32U
+#elif MPC55XX_CHIP_FAMILY == 551
   #define EDMA_CHANNEL_COUNT 16U
 #elif MPC55XX_CHIP_FAMILY == 564
   #define EDMA_CHANNEL_COUNT 16U
@@ -46,20 +59,27 @@ extern "C" {
 
 #define EDMA_CHANNELS_PER_MODULE 64U
 
-#if EDMA_MODULE_COUNT == 1
-  #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \
-    (&EDMA.TCD[(channel_index)])
-#elif EDMA_MODULE_COUNT == 2
-  #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \
-    ((channel_index) < EDMA_CHANNELS_PER_MODULE ? \
-      &EDMA_A.TCD[(channel_index)] \
-        : &EDMA_B.TCD[(channel_index) - EDMA_CHANNELS_PER_MODULE])
-#else
-  #error "unsupported module count"
+volatile struct fsl_edma_tcd *fsl_edma_tcd_of_channel_index(unsigned index);
+unsigned fsl_edma_channel_index_of_tcd(volatile struct fsl_edma_tcd *edma_tcd);
+
+#ifdef LIBBSP_POWERPC_MPC55XXEVB_BSP_H
+  #error Legacy stuff. Move to compatibility layer.
+  #if EDMA_MODULE_COUNT == 1
+    #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \
+      (&EDMA.TCD[(channel_index)])
+  #elif EDMA_MODULE_COUNT == 2
+    #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \
+      ((channel_index) < EDMA_CHANNELS_PER_MODULE ? \
+        &EDMA_A.TCD[(channel_index)] \
+          : &EDMA_B.TCD[(channel_index) - EDMA_CHANNELS_PER_MODULE])
+  #else
+    #error "unsupported module count"
+  #endif
 #endif
 
-/* FIXME: These values are only valid for the MPC5566 and MPC5674F */
+#ifdef LIBBSP_POWERPC_MPC55XXEVB_BSP_H
 typedef enum {
+/* FIXME: These values are only valid for the MPC5566 and MPC5674F */
   EDMA_EQADC_A_FISR0_CFFF0 = 0,
   EDMA_EQADC_A_FISR0_RFDF0 = 1,
   EDMA_EQADC_A_FISR1_CFFF1 = 2,
@@ -155,15 +175,16 @@ typedef enum {
     EDMA_DECFILTER_H_IB = 64 + 26,
     EDMA_DECFILTER_H_OB = 64 + 27
   #endif
-} edma_channel;
+} fsl_edma_channel;
+#endif
 
-typedef struct edma_channel_context {
+typedef struct fsl_edma_channel_context {
   rtems_chain_node node;
-  volatile struct tcd_t *edma_tcd;
-  void (*done)(struct edma_channel_context *, uint32_t);
-} edma_channel_context;
+  volatile struct fsl_edma_tcd *edma_tcd;
+  void (*done)(struct fsl_edma_channel_context *, uint32_t);
+} fsl_edma_channel_context;
 
-void mpc55xx_edma_init(void);
+void fsl_edma_init(void);
 
 /**
  * @brief Obtains an eDMA channel.
@@ -171,14 +192,18 @@ void mpc55xx_edma_init(void);
  * @retval RTEMS_SUCCESSFUL Successful operation.
  * @retval RTEMS_RESOURCE_IN_USE The channel is already in use.
  */
-rtems_status_code mpc55xx_edma_obtain_channel_by_tcd(
-  volatile struct tcd_t *edma_tcd
+rtems_status_code fsl_edma_obtain_channel_by_tcd(
+  volatile struct fsl_edma_tcd *edma_tcd
 );
 
-void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd);
+void fsl_edma_release_channel_by_tcd(volatile struct fsl_edma_tcd *edma_tcd);
 
 /**
- * @brief Obtains an eDMA channel and registers the channel context.
+ * @brief Obtains a specific eDMA channel and registers the channel context.
+ *
+ * Tries to obtain the channel specified in the @a ctx.
+ *
+ * @a irq_priority will be ignored on all targets but MPC55xx based ones.
  *
  * The done handler of the channel context will be called
  * - during minor or major loop completions if interrupts are enabled in the
@@ -191,12 +216,33 @@ void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd);
  * @retval RTEMS_RESOURCE_IN_USE The channel is already in use.
  * @retval RTEMS_IO_ERROR Unable to install interrupt handler for this channel.
  */
-rtems_status_code mpc55xx_edma_obtain_channel(
-  edma_channel_context *ctx,
+rtems_status_code fsl_edma_obtain_channel(
+  fsl_edma_channel_context *ctx,
   unsigned irq_priority
 );
 
-void mpc55xx_edma_release_channel(edma_channel_context *ctx);
+/**
+ * @brief Obtains a free eDMA channel and registers the channel context.
+ *
+ * Tries to obtain the next free DMA channel. The tcd field of @a ctx will be
+ * set accordingly.
+ *
+ * The done handler of the channel context will be called
+ * - during minor or major loop completions if interrupts are enabled in the
+ *   corresponding TCD, or
+ * - in case a channel error occurs.
+ *
+ * An error status value not equal to zero indicates an error.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_RESOURCE_IN_USE No channels left.
+ * @retval RTEMS_IO_ERROR Unable to install interrupt handler.
+ */
+rtems_status_code fsl_edma_obtain_next_free_channel(
+  fsl_edma_channel_context *ctx
+);
+
+void fsl_edma_release_channel(fsl_edma_channel_context *ctx);
 
 /**
  * @brief Copies a source TCD to an eDMA TCD.
@@ -207,9 +253,9 @@ void mpc55xx_edma_release_channel(edma_channel_context *ctx);
  * This function can be used to start the channel if the START flags is
  * set in the source TCD.
  */
-void mpc55xx_edma_copy(
-  volatile struct tcd_t *edma_tcd,
-  const struct tcd_t *source_tcd
+void fsl_edma_copy(
+  volatile struct fsl_edma_tcd *edma_tcd,
+  const struct fsl_edma_tcd *source_tcd
 );
 
 /**
@@ -218,112 +264,112 @@ void mpc55xx_edma_copy(
  * The DONE flag of the eDMA TCD is cleared before the actual copy operation.
  * This enables the setting of channel link or scatter/gather options.
  */
-void mpc55xx_edma_copy_and_enable_hardware_requests(
-  volatile struct tcd_t *edma_tcd,
-  const struct tcd_t *source_tcd
+void fsl_edma_copy_and_enable_hardware_requests(
+  volatile struct fsl_edma_tcd *edma_tcd,
+  const struct fsl_edma_tcd *source_tcd
 );
 
-void mpc55xx_edma_sg_link(
-  volatile struct tcd_t *edma_tcd,
-  const struct tcd_t *source_tcd
+void fsl_edma_sg_link(
+  volatile struct fsl_edma_tcd *edma_tcd,
+  const struct fsl_edma_tcd *source_tcd
 );
 
-static inline volatile struct EDMA_tag *mpc55xx_edma_by_tcd(
-  volatile struct tcd_t *edma_tcd
+static inline volatile struct fsl_edma *fsl_edma_by_tcd(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  return (volatile struct EDMA_tag *)
+  return (volatile struct fsl_edma *)
     ((uintptr_t) edma_tcd & ~(uintptr_t) 0x1fff);
 }
 
-static inline unsigned mpc55xx_edma_channel_by_tcd(
-  volatile struct tcd_t *edma_tcd
+static inline unsigned fsl_edma_channel_by_tcd(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
+  volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
 
   return edma_tcd - &edma->TCD[0];
 }
 
-static inline void mpc55xx_edma_enable_hardware_requests(
-  volatile struct tcd_t *edma_tcd
+static inline void fsl_edma_enable_hardware_requests(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
+  volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
   unsigned channel = edma_tcd - &edma->TCD[0];
 
-  edma->SERQR.R = (uint8_t) channel;
+  edma->SERQR = (uint8_t) channel;
 }
 
-static inline void mpc55xx_edma_disable_hardware_requests(
-  volatile struct tcd_t *edma_tcd
+static inline void fsl_edma_disable_hardware_requests(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
+  volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
   unsigned channel = edma_tcd - &edma->TCD[0];
 
-  edma->CERQR.R = (uint8_t) channel;
+  edma->CERQR = (uint8_t) channel;
 }
 
-static inline void mpc55xx_edma_enable_error_interrupts(
-  volatile struct tcd_t *edma_tcd
+static inline void fsl_edma_enable_error_interrupts(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
+  volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
   unsigned channel = edma_tcd - &edma->TCD[0];
 
-  edma->SEEIR.R = (uint8_t) channel;
+  edma->SEEIR = (uint8_t) channel;
 }
 
-static inline void mpc55xx_edma_disable_error_interrupts(
-  volatile struct tcd_t *edma_tcd
+static inline void fsl_edma_disable_error_interrupts(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
+  volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
   unsigned channel = edma_tcd - &edma->TCD[0];
 
-  edma->CEEIR.R = (uint8_t) channel;
+  edma->CEEIR = (uint8_t) channel;
 }
 
-static inline void mpc55xx_edma_set_start(
-  volatile struct tcd_t *edma_tcd
+static inline void fsl_edma_set_start(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
+  volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
   unsigned channel = edma_tcd - &edma->TCD[0];
 
-  edma->SSBR.R = (uint8_t) channel;
+  edma->SSBR = (uint8_t) channel;
 }
 
-static inline void mpc55xx_edma_clear_done(
-  volatile struct tcd_t *edma_tcd
+static inline void fsl_edma_clear_done(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
+  volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
   unsigned channel = edma_tcd - &edma->TCD[0];
 
-  edma->CDSBR.R = (uint8_t) channel;
+  edma->CDSBR = (uint8_t) channel;
 }
 
-static inline void mpc55xx_edma_clear_interrupts(
-  volatile struct tcd_t *edma_tcd
+static inline void fsl_edma_clear_interrupts(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
+  volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
   unsigned channel = edma_tcd - &edma->TCD[0];
 
-  edma->CIRQR.R = (uint8_t) channel;
+  edma->CIRQR = (uint8_t) channel;
 }
 
-static inline bool mpc55xx_edma_is_done(
-  volatile struct tcd_t *edma_tcd
+static inline bool fsl_edma_is_done(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
-  return edma_tcd->BMF.B.DONE;
+  return ((edma_tcd->BMF & EDMA_TCD_BMF_DONE) != 0);
 }
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif /* LIBCPU_POWERPC_MPC55XX_EDMA_H */
+#endif /* LIBBSP_SHARED_FSL_EDMA_H */
diff --git a/bsps/include/fsl/regs-edma.h b/bsps/include/fsl/regs-edma.h
index fda47dc..4afdb9b 100644
--- a/bsps/include/fsl/regs-edma.h
+++ b/bsps/include/fsl/regs-edma.h
@@ -1,21 +1,32 @@
 /**
  * @file
  *
- * @ingroup RTEMSBSPsPowerPCMPC55XX
+ * @ingroup RTEMSBSPsSharedFslEDMA
  */
 
 /*
- * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
+ * Copyright (C) 2011-2020 embedded brains GmbH (http://www.embedded-brains.de)
  *
- *  embedded brains GmbH
- *  Obere Lagerstr. 30
- *  82178 Puchheim
- *  Germany
- *  <rtems at embedded-brains.de>
+ * 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.
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
  */
 
 /*********************************************************************
@@ -49,647 +60,345 @@
  *
  ********************************************************************/
 
-#ifndef LIBCPU_POWERPC_MPC55XX_REGS_EDMA_H
-#define LIBCPU_POWERPC_MPC55XX_REGS_EDMA_H
+#ifndef LIBBSP_SHARED_FSL_REGS_EDMA_H
+#define LIBBSP_SHARED_FSL_REGS_EDMA_H
 
 #include <stdint.h>
-
+#include <bsp.h>
 #include <bspopts.h>
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
-/****************************************************************************/
-/*                          MODULE : eDMA                                   */
-/****************************************************************************/
-    struct EDMA_tag {
-        union EDMA_CR_tag {
-            uint32_t R;
-            struct {
-#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567
-                uint32_t:14;
-                uint32_t CX:1;
-                uint32_t ECX:1;
-#else
-                uint32_t:16;
+#if (defined(MPC55XX_CHIP_FAMILY) && \
+    (MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567))
+  #define EDMA_HAS_CR_EBW 1
+  #define EDMA_HAS_CR_CX_ECX 1
+  #define EDMA_HAS_CR_EMLM_CLM_HALT_HOE 1
+  #define EDMA_HAS_ESR_ECX 1
+  #define EDMA_HAS_HRS 1
+  #define EDMA_HAS_CPR_DPA 1
 #endif
-                uint32_t GRP3PRI:2;
-                uint32_t GRP2PRI:2;
-                uint32_t GRP1PRI:2;
-                uint32_t GRP0PRI:2;
-#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567
-                uint32_t EMLM:1;
-                uint32_t CLM:1;
-                uint32_t HALT:1;
-                uint32_t HOE:1;
-#else
-                  uint32_t:4;
+
+#if defined(LIBBSP_ARM_IMXRT_BSP_H)
+  #define EDMA_HAS_CR_CX_ECX 1
+  #define EDMA_HAS_CR_EMLM_CLM_HALT_HOE 1
+  #define EDMA_HAS_CR_ACTIVE 1
+  #define EDMA_HAS_CR_VERSION 1
+  #define EDMA_HAS_ESR_ECX 1
+  #define EDMA_HAS_HRS 1
+  #define EDMA_HAS_EARS 1
+  #define EDMA_HAS_CPR_DPA 1
 #endif
-                uint32_t ERGA:1;
-                uint32_t ERCA:1;
-                uint32_t EDBG:1;
-                uint32_t EBW:1;
-            } B;
-        } CR;                   /* Control Register */
-
-        union {
-            uint32_t R;
-            struct {
-                uint32_t VLD:1;
-#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567
-                uint32_t:14;
-                uint32_t ECX:1;
-#else
-                  uint32_t:15;
+
+struct fsl_edma {
+  uint32_t CR;
+#ifdef EDMA_HAS_CR_EBW
+  #define EDMA_CR_EBW               (1 << 0)
+#endif
+#define EDMA_CR_EDBG                (1 << 1)
+#define EDMA_CR_ERCA                (1 << 2)
+#define EDMA_CR_ERGA                (1 << 3)
+#ifdef EDMA_HAS_CR_EMLM_CLM_HALT_HOE
+  #define EDMA_CR_HOE               (1 << 4)
+  #define EDMA_CR_HALT              (1 << 5)
+  #define EDMA_CR_CLM               (1 << 6)
+  #define EDMA_CR_EMLM              (1 << 7)
+#endif
+#define EDMA_CR_GRPxPRI_SHIFT(x)    (8 + (x) * 2)
+#define EDMA_CR_GRPxPRI_MASK(x)     (0x3 << EDMA_CR_GRPxPRI_SHIFT(x))
+#define EDMA_CR_GRPxPRI(x,val)      (((val) << EDMA_CR_GRPxPRI_SHIFT(x)) & EDMA_CR_GRPxPRI_MASK(x))
+#define EDMA_CR_GRPxPRI_GET(x,reg)  (((reg) & EDMA_CR_GRPxPRI_MASK(x)) >> EDMA_CR_GRPxPRI_SHIFT(x))
+#ifdef EDMA_HAS_CR_CX_ECX
+  #define EDMA_CR_ECX               (1 << 16)
+  #define EDMA_CR_CX                (1 << 17)
+#endif
+#ifdef EDMA_HAS_CR_VERSION
+  #define EDMA_CR_VERSION_SHIFT     (24)
+  #define EDMA_CR_VERSION_MASK      (0x7F << EDMA_CR_VERSION_SHIFT)
+  #define EDMA_CR_VERSION(val)      (((val) << EDMA_CR_VERSION_SHIFT) & EDMA_CR_VERSION_MASK)
+  #define EDMA_CR_VERSION_GET(reg)  (((reg) & EDMA_CR_VERSION_MASK) >> EDMA_CR_VERSION_SHIFT)
 #endif
-                uint32_t GPE:1;
-                uint32_t CPE:1;
-                uint32_t ERRCHN:6;
-                uint32_t SAE:1;
-                uint32_t SOE:1;
-                uint32_t DAE:1;
-                uint32_t DOE:1;
-                uint32_t NCE:1;
-                uint32_t SGE:1;
-                uint32_t SBE:1;
-                uint32_t DBE:1;
-            } B;
-        } ESR;                  /* Error Status Register */
-
-        union {
-            uint32_t R;
-            struct {
-                uint32_t ERQ63:1;
-                uint32_t ERQ62:1;
-                uint32_t ERQ61:1;
-                uint32_t ERQ60:1;
-                uint32_t ERQ59:1;
-                uint32_t ERQ58:1;
-                uint32_t ERQ57:1;
-                uint32_t ERQ56:1;
-                uint32_t ERQ55:1;
-                uint32_t ERQ54:1;
-                uint32_t ERQ53:1;
-                uint32_t ERQ52:1;
-                uint32_t ERQ51:1;
-                uint32_t ERQ50:1;
-                uint32_t ERQ49:1;
-                uint32_t ERQ48:1;
-                uint32_t ERQ47:1;
-                uint32_t ERQ46:1;
-                uint32_t ERQ45:1;
-                uint32_t ERQ44:1;
-                uint32_t ERQ43:1;
-                uint32_t ERQ42:1;
-                uint32_t ERQ41:1;
-                uint32_t ERQ40:1;
-                uint32_t ERQ39:1;
-                uint32_t ERQ38:1;
-                uint32_t ERQ37:1;
-                uint32_t ERQ36:1;
-                uint32_t ERQ35:1;
-                uint32_t ERQ34:1;
-                uint32_t ERQ33:1;
-                uint32_t ERQ32:1;
-            } B;
-        } ERQRH;                /* DMA Enable Request Register High */
-
-        union {
-            uint32_t R;
-            struct {
-                uint32_t ERQ31:1;
-                uint32_t ERQ30:1;
-                uint32_t ERQ29:1;
-                uint32_t ERQ28:1;
-                uint32_t ERQ27:1;
-                uint32_t ERQ26:1;
-                uint32_t ERQ25:1;
-                uint32_t ERQ24:1;
-                uint32_t ERQ23:1;
-                uint32_t ERQ22:1;
-                uint32_t ERQ21:1;
-                uint32_t ERQ20:1;
-                uint32_t ERQ19:1;
-                uint32_t ERQ18:1;
-                uint32_t ERQ17:1;
-                uint32_t ERQ16:1;
-                uint32_t ERQ15:1;
-                uint32_t ERQ14:1;
-                uint32_t ERQ13:1;
-                uint32_t ERQ12:1;
-                uint32_t ERQ11:1;
-                uint32_t ERQ10:1;
-                uint32_t ERQ09:1;
-                uint32_t ERQ08:1;
-                uint32_t ERQ07:1;
-                uint32_t ERQ06:1;
-                uint32_t ERQ05:1;
-                uint32_t ERQ04:1;
-                uint32_t ERQ03:1;
-                uint32_t ERQ02:1;
-                uint32_t ERQ01:1;
-                uint32_t ERQ00:1;
-            } B;
-        } ERQRL;                /* DMA Enable Request Register Low */
-
-        union {
-            uint32_t R;
-            struct {
-                uint32_t EEI63:1;
-                uint32_t EEI62:1;
-                uint32_t EEI61:1;
-                uint32_t EEI60:1;
-                uint32_t EEI59:1;
-                uint32_t EEI58:1;
-                uint32_t EEI57:1;
-                uint32_t EEI56:1;
-                uint32_t EEI55:1;
-                uint32_t EEI54:1;
-                uint32_t EEI53:1;
-                uint32_t EEI52:1;
-                uint32_t EEI51:1;
-                uint32_t EEI50:1;
-                uint32_t EEI49:1;
-                uint32_t EEI48:1;
-                uint32_t EEI47:1;
-                uint32_t EEI46:1;
-                uint32_t EEI45:1;
-                uint32_t EEI44:1;
-                uint32_t EEI43:1;
-                uint32_t EEI42:1;
-                uint32_t EEI41:1;
-                uint32_t EEI40:1;
-                uint32_t EEI39:1;
-                uint32_t EEI38:1;
-                uint32_t EEI37:1;
-                uint32_t EEI36:1;
-                uint32_t EEI35:1;
-                uint32_t EEI34:1;
-                uint32_t EEI33:1;
-                uint32_t EEI32:1;
-            } B;
-        } EEIRH;                /* DMA Enable Error Interrupt Register High */
-
-        union {
-            uint32_t R;
-            struct {
-                uint32_t EEI31:1;
-                uint32_t EEI30:1;
-                uint32_t EEI29:1;
-                uint32_t EEI28:1;
-                uint32_t EEI27:1;
-                uint32_t EEI26:1;
-                uint32_t EEI25:1;
-                uint32_t EEI24:1;
-                uint32_t EEI23:1;
-                uint32_t EEI22:1;
-                uint32_t EEI21:1;
-                uint32_t EEI20:1;
-                uint32_t EEI19:1;
-                uint32_t EEI18:1;
-                uint32_t EEI17:1;
-                uint32_t EEI16:1;
-                uint32_t EEI15:1;
-                uint32_t EEI14:1;
-                uint32_t EEI13:1;
-                uint32_t EEI12:1;
-                uint32_t EEI11:1;
-                uint32_t EEI10:1;
-                uint32_t EEI09:1;
-                uint32_t EEI08:1;
-                uint32_t EEI07:1;
-                uint32_t EEI06:1;
-                uint32_t EEI05:1;
-                uint32_t EEI04:1;
-                uint32_t EEI03:1;
-                uint32_t EEI02:1;
-                uint32_t EEI01:1;
-                uint32_t EEI00:1;
-            } B;
-        } EEIRL;                /* DMA Enable Error Interrupt Register Low */
-
-        union {                /* DMA Set Enable Request Register */
-            uint8_t R;
-            struct {
-                uint8_t NOP:1;
-                uint8_t SERQ:7;
-            } B;
-        } SERQR;
-
-        union {                /* DMA Clear Enable Request Register */
-            uint8_t R;
-            struct {
-                uint8_t NOP:1;
-                uint8_t CERQ:7;
-            } B;
-        } CERQR;
-
-        union {                /* DMA Set Enable Error Interrupt Register */
-            uint8_t R;
-            struct {
-                uint8_t NOP:1;
-                uint8_t SEEI:7;
-            } B;
-        } SEEIR;
-
-        union {                /* DMA Clear Enable Error Interrupt Register */
-            uint8_t R;
-            struct {
-                uint8_t NOP:1;
-                uint8_t CEEI:7;
-            } B;
-        } CEEIR;
-
-        union {                /* DMA Clear Interrupt Request Register */
-            uint8_t R;
-            struct {
-                uint8_t NOP:1;
-                uint8_t CINT:7;
-            } B;
-        } CIRQR;
-
-        union {                  /* DMA Clear error Register */
-            uint8_t R;
-            struct {
-                uint8_t NOP:1;
-                uint8_t CERR:7;
-            } B;
-        } CER;
-
-        union {                 /* Set Start Bit Register */
-            uint8_t R;
-            struct {
-                uint8_t NOP:1;
-                uint8_t SSB:7;
-            } B;
-        } SSBR;
-
-        union {                /* Clear Done Status Bit Register */
-            uint8_t R;
-            struct {
-                uint8_t NOP:1;
-                uint8_t CDSB:7;
-            } B;
-        } CDSBR;
-
-        union {
-            uint32_t R;
-            struct {
-                uint32_t INT63:1;
-                uint32_t INT62:1;
-                uint32_t INT61:1;
-                uint32_t INT60:1;
-                uint32_t INT59:1;
-                uint32_t INT58:1;
-                uint32_t INT57:1;
-                uint32_t INT56:1;
-                uint32_t INT55:1;
-                uint32_t INT54:1;
-                uint32_t INT53:1;
-                uint32_t INT52:1;
-                uint32_t INT51:1;
-                uint32_t INT50:1;
-                uint32_t INT49:1;
-                uint32_t INT48:1;
-                uint32_t INT47:1;
-                uint32_t INT46:1;
-                uint32_t INT45:1;
-                uint32_t INT44:1;
-                uint32_t INT43:1;
-                uint32_t INT42:1;
-                uint32_t INT41:1;
-                uint32_t INT40:1;
-                uint32_t INT39:1;
-                uint32_t INT38:1;
-                uint32_t INT37:1;
-                uint32_t INT36:1;
-                uint32_t INT35:1;
-                uint32_t INT34:1;
-                uint32_t INT33:1;
-                uint32_t INT32:1;
-            } B;
-        } IRQRH;                /* DMA Interrupt Request High */
-
-        union {
-            uint32_t R;
-            struct {
-                uint32_t INT31:1;
-                uint32_t INT30:1;
-                uint32_t INT29:1;
-                uint32_t INT28:1;
-                uint32_t INT27:1;
-                uint32_t INT26:1;
-                uint32_t INT25:1;
-                uint32_t INT24:1;
-                uint32_t INT23:1;
-                uint32_t INT22:1;
-                uint32_t INT21:1;
-                uint32_t INT20:1;
-                uint32_t INT19:1;
-                uint32_t INT18:1;
-                uint32_t INT17:1;
-                uint32_t INT16:1;
-                uint32_t INT15:1;
-                uint32_t INT14:1;
-                uint32_t INT13:1;
-                uint32_t INT12:1;
-                uint32_t INT11:1;
-                uint32_t INT10:1;
-                uint32_t INT09:1;
-                uint32_t INT08:1;
-                uint32_t INT07:1;
-                uint32_t INT06:1;
-                uint32_t INT05:1;
-                uint32_t INT04:1;
-                uint32_t INT03:1;
-                uint32_t INT02:1;
-                uint32_t INT01:1;
-                uint32_t INT00:1;
-            } B;
-        } IRQRL;                /* DMA Interrupt Request Low */
-
-        union {
-            uint32_t R;
-            struct {
-                uint32_t ERR63:1;
-                uint32_t ERR62:1;
-                uint32_t ERR61:1;
-                uint32_t ERR60:1;
-                uint32_t ERR59:1;
-                uint32_t ERR58:1;
-                uint32_t ERR57:1;
-                uint32_t ERR56:1;
-                uint32_t ERR55:1;
-                uint32_t ERR54:1;
-                uint32_t ERR53:1;
-                uint32_t ERR52:1;
-                uint32_t ERR51:1;
-                uint32_t ERR50:1;
-                uint32_t ERR49:1;
-                uint32_t ERR48:1;
-                uint32_t ERR47:1;
-                uint32_t ERR46:1;
-                uint32_t ERR45:1;
-                uint32_t ERR44:1;
-                uint32_t ERR43:1;
-                uint32_t ERR42:1;
-                uint32_t ERR41:1;
-                uint32_t ERR40:1;
-                uint32_t ERR39:1;
-                uint32_t ERR38:1;
-                uint32_t ERR37:1;
-                uint32_t ERR36:1;
-                uint32_t ERR35:1;
-                uint32_t ERR34:1;
-                uint32_t ERR33:1;
-                uint32_t ERR32:1;
-            } B;
-        } ERH;                  /* DMA Error High */
-
-        union {
-            uint32_t R;
-            struct {
-                uint32_t ERR31:1;
-                uint32_t ERR30:1;
-                uint32_t ERR29:1;
-                uint32_t ERR28:1;
-                uint32_t ERR27:1;
-                uint32_t ERR26:1;
-                uint32_t ERR25:1;
-                uint32_t ERR24:1;
-                uint32_t ERR23:1;
-                uint32_t ERR22:1;
-                uint32_t ERR21:1;
-                uint32_t ERR20:1;
-                uint32_t ERR19:1;
-                uint32_t ERR18:1;
-                uint32_t ERR17:1;
-                uint32_t ERR16:1;
-                uint32_t ERR15:1;
-                uint32_t ERR14:1;
-                uint32_t ERR13:1;
-                uint32_t ERR12:1;
-                uint32_t ERR11:1;
-                uint32_t ERR10:1;
-                uint32_t ERR09:1;
-                uint32_t ERR08:1;
-                uint32_t ERR07:1;
-                uint32_t ERR06:1;
-                uint32_t ERR05:1;
-                uint32_t ERR04:1;
-                uint32_t ERR03:1;
-                uint32_t ERR02:1;
-                uint32_t ERR01:1;
-                uint32_t ERR00:1;
-            } B;
-        } ERL;                  /* DMA Error Low */
-
-#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567
-        union {                  /* hardware request status high */
-            uint32_t R;
-            struct {
-                uint32_t HRS63:1;
-                uint32_t HRS62:1;
-                uint32_t HRS61:1;
-                uint32_t HRS60:1;
-                uint32_t HRS59:1;
-                uint32_t HRS58:1;
-                uint32_t HRS57:1;
-                uint32_t HRS56:1;
-                uint32_t HRS55:1;
-                uint32_t HRS54:1;
-                uint32_t HRS53:1;
-                uint32_t HRS52:1;
-                uint32_t HRS51:1;
-                uint32_t HRS50:1;
-                uint32_t HRS49:1;
-                uint32_t HRS48:1;
-                uint32_t HRS47:1;
-                uint32_t HRS46:1;
-                uint32_t HRS45:1;
-                uint32_t HRS44:1;
-                uint32_t HRS43:1;
-                uint32_t HRS42:1;
-                uint32_t HRS41:1;
-                uint32_t HRS40:1;
-                uint32_t HRS39:1;
-                uint32_t HRS38:1;
-                uint32_t HRS37:1;
-                uint32_t HRS36:1;
-                uint32_t HRS35:1;
-                uint32_t HRS34:1;
-                uint32_t HRS33:1;
-                uint32_t HRS32:1;
-            } B;
-        } HRSH;
-
-        union {                  /* hardware request status low */
-            uint32_t R;
-            struct {
-                uint32_t HRS31:1;
-                uint32_t HRS30:1;
-                uint32_t HRS29:1;
-                uint32_t HRS28:1;
-                uint32_t HRS27:1;
-                uint32_t HRS26:1;
-                uint32_t HRS25:1;
-                uint32_t HRS24:1;
-                uint32_t HRS23:1;
-                uint32_t HRS22:1;
-                uint32_t HRS21:1;
-                uint32_t HRS20:1;
-                uint32_t HRS19:1;
-                uint32_t HRS18:1;
-                uint32_t HRS17:1;
-                uint32_t HRS16:1;
-                uint32_t HRS15:1;
-                uint32_t HRS14:1;
-                uint32_t HRS13:1;
-                uint32_t HRS12:1;
-                uint32_t HRS11:1;
-                uint32_t HRS10:1;
-                uint32_t HRS09:1;
-                uint32_t HRS08:1;
-                uint32_t HRS07:1;
-                uint32_t HRS06:1;
-                uint32_t HRS05:1;
-                uint32_t HRS04:1;
-                uint32_t HRS03:1;
-                uint32_t HRS02:1;
-                uint32_t HRS01:1;
-                uint32_t HRS00:1;
-            } B;
-        } HRSL;
-
-        uint32_t eDMA_reserved0038[50];  /* 0x0038-0x00FF */
+#ifdef EDMA_HAS_CR_ACTIVE
+  #define EDMA_CR_ACTIVE            (1 << 31)
+#endif
+
+  uint32_t ESR;
+#define EDMA_ESR_DBE                (1 << 0)
+#define EDMA_ESR_SBE                (1 << 1)
+#define EDMA_ESR_SGE                (1 << 2)
+#define EDMA_ESR_NCE                (1 << 3)
+#define EDMA_ESR_DOE                (1 << 4)
+#define EDMA_ESR_DAE                (1 << 5)
+#define EDMA_ESR_SOE                (1 << 6)
+#define EDMA_ESR_SAE                (1 << 7)
+#define EDMA_ESR_ERRCHN_SHIFT       (8)
+#define EDMA_ESR_ERRCHN_MASK        (0x3F << EDMA_ESR_ERRCHN_SHIFT)
+#define EDMA_ESR_ERRCHN(val)        (((val) << EDMA_ESR_ERRCHN_SHIFT) & EDMA_ESR_ERRCHN_MASK)
+#define EDMA_ESR_ERRCHN_GET(reg)    (((reg) & EDMA_ESR_ERRCHN_MASK) >> EDMA_ESR_ERRCHN_SHIFT)
+#define EDMA_ESR_CPE                (1 << 14)
+#define EDMA_ESR_GPE                (1 << 15)
+#ifdef EDMA_HAS_ESR_ECX
+  #define EDMA_ESR_ECX              (1 << 16)
+#endif
+#define EDMA_ESR_VLD                (1 << 31)
+
+  uint32_t ERRQH;
+#define EDMA_ERRQH_ERRQ(x)          (1 << ((x) - 32))
+
+  uint32_t ERRQL;
+#define EDMA_ERRQL_ERRQ(x)          (1 << (x))
+
+  uint32_t EEIH;
+#define EDMA_EEIH_EEI(x)            (1 << ((x) - 32))
+
+  uint32_t EEIL;
+#define EDMA_EEIL_EEI(x)            (1 << (x))
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+  uint8_t SERQR;
+  uint8_t CERQR;
+  uint8_t SEEIR;
+  uint8_t CEEIR;
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  uint8_t CEEIR;
+  uint8_t SEEIR;
+  uint8_t CERQR;
+  uint8_t SERQR;
+#endif
+#define EDMA_SERQR_NOP            (1 << 7)
+#define EDMA_SERQR_SAER           (1 << 6)
+#define EDMA_SERQR_SERQ_SHIFT     (0)
+#define EDMA_SERQR_SERQ_MASK      (0x1F << EDMA_CIRQR_SERQ_SHIFT)
+#define EDMA_SERQR_SERQ(val)      (((val) << EDMA_CIRQR_SERQ_SHIFT) & EDMA_CIRQR_SERQ_MASK)
+#define EDMA_SERQR_SERQ_GET(reg)  (((reg) & EDMA_CIRQR_SERQ_MASK) >> EDMA_CIRQR_SERQ_SHIFT)
+#define EDMA_CERQR_NOP            (1 << 7)
+#define EDMA_CERQR_CAER           (1 << 6)
+#define EDMA_CERQR_CERQ_SHIFT     (0)
+#define EDMA_CERQR_CERQ_MASK      (0x1F << EDMA_CIRQR_CERQ_SHIFT)
+#define EDMA_CERQR_CERQ(val)      (((val) << EDMA_CIRQR_CERQ_SHIFT) & EDMA_CIRQR_CERQ_MASK)
+#define EDMA_CERQR_CERQ_GET(reg)  (((reg) & EDMA_CIRQR_CERQ_MASK) >> EDMA_CIRQR_CERQ_SHIFT)
+#define EDMA_SEEIR_NOP            (1 << 7)
+#define EDMA_SEEIR_SAEE           (1 << 6)
+#define EDMA_SEEIR_SEEI_SHIFT     (0)
+#define EDMA_SEEIR_SEEI_MASK      (0x1F << EDMA_CIRQR_SEEI_SHIFT)
+#define EDMA_SEEIR_SEEI(val)      (((val) << EDMA_CIRQR_SEEI_SHIFT) & EDMA_CIRQR_SEEI_MASK)
+#define EDMA_SEEIR_SEEI_GET(reg)  (((reg) & EDMA_CIRQR_SEEI_MASK) >> EDMA_CIRQR_SEEI_SHIFT)
+#define EDMA_CEEIR_NOP            (1 << 7)
+#define EDMA_CEEIR_CAEE           (1 << 6)
+#define EDMA_CEEIR_CEEI_SHIFT     (0)
+#define EDMA_CEEIR_CEEI_MASK      (0x1F << EDMA_CIRQR_CEEI_SHIFT)
+#define EDMA_CEEIR_CEEI(val)      (((val) << EDMA_CIRQR_CEEI_SHIFT) & EDMA_CIRQR_CEEI_MASK)
+#define EDMA_CEEIR_CEEI_GET(reg)  (((reg) & EDMA_CIRQR_CEEI_MASK) >> EDMA_CIRQR_CEEI_SHIFT)
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+  uint8_t CIRQR;
+  uint8_t CER;
+  uint8_t SSBR;
+  uint8_t CDSBR;
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  uint8_t CDSBR;
+  uint8_t SSBR;
+  uint8_t CER;
+  uint8_t CIRQR;
+#endif
+#define EDMA_CIRQR_NOP            (1 << 7)
+#define EDMA_CIRQR_CAIR           (1 << 6)
+#define EDMA_CIRQR_CINT_SHIFT     (0)
+#define EDMA_CIRQR_CINT_MASK      (0x1F << EDMA_CIRQR_CINT_SHIFT)
+#define EDMA_CIRQR_CINT(val)      (((val) << EDMA_CIRQR_CINT_SHIFT) & EDMA_CIRQR_CINT_MASK)
+#define EDMA_CIRQR_CINT_GET(reg)  (((reg) & EDMA_CIRQR_CINT_MASK) >> EDMA_CIRQR_CINT_SHIFT)
+#define EDMA_CER_NOP              (1 << 7)
+#define EDMA_CER_CAEI             (1 << 6)
+#define EDMA_CER_CERR_SHIFT       (0)
+#define EDMA_CER_CERR_MASK        (0x1F << EDMA_CIRQR_CERR_SHIFT)
+#define EDMA_CER_CERR(val)        (((val) << EDMA_CIRQR_CERR_SHIFT) & EDMA_CIRQR_CERR_MASK)
+#define EDMA_CER_CERR_GET(reg)    (((reg) & EDMA_CIRQR_CERR_MASK) >> EDMA_CIRQR_CERR_SHIFT)
+#define EDMA_SSBR_NOP             (1 << 7)
+#define EDMA_SSBR_SAST            (1 << 6)
+#define EDMA_SSBR_SSB_SHIFT       (0)
+#define EDMA_SSBR_SSB_MASK        (0x1F << EDMA_CIRQR_SSB_SHIFT)
+#define EDMA_SSBR_SSB(val)        (((val) << EDMA_CIRQR_SSB_SHIFT) & EDMA_CIRQR_SSB_MASK)
+#define EDMA_SSBR_SSB_GET(reg)    (((reg) & EDMA_CIRQR_SSB_MASK) >> EDMA_CIRQR_SSB_SHIFT)
+#define EDMA_CDSBR_NOP            (1 << 7)
+#define EDMA_CDSBR_CADN           (1 << 6)
+#define EDMA_CDSBR_CDSB_SHIFT     (0)
+#define EDMA_CDSBR_CDSB_MASK      (0x1F << EDMA_CIRQR_CDSB_SHIFT)
+#define EDMA_CDSBR_CDSB(val)      (((val) << EDMA_CIRQR_CDSB_SHIFT) & EDMA_CIRQR_CDSB_MASK)
+#define EDMA_CDSBR_CDSB_GET(reg)  (((reg) & EDMA_CIRQR_CDSB_MASK) >> EDMA_CIRQR_CDSB_SHIFT)
+
+  uint32_t IRQH;
+#define EDMA_IRQH_INT(x)         (1 << ((x) - 32))
+
+  uint32_t IRQL;
+#define EDMA_IRQL_INT(x)         (1 << ((x)))
+
+  uint32_t ERH;
+#define EDMA_ERH_ERR(x)          (1 << ((x) - 32))
+
+  uint32_t ERL;
+#define EDMA_ERL_ERR(x)          (1 << ((x)))
+
+#ifdef EDMA_HAS_HRS
+  uint32_t HRS;
+#define EDMA_HRSH_HRS(x)         (1 << ((x) - 32))
+
+  uint32_t HRSL;
+#define EDMA_HRSL_HRS(x)         (1 << ((x)))
 #else
-        uint32_t edma_reserved1[52];
+  uint32_t reserved0030[2];
 #endif
 
-        union {
-            uint8_t R;
-            struct {
-                uint8_t ECP:1;
-#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567
-                uint8_t DPA:1;
+  uint32_t reserved0038[(0x44-0x38)/4];
+
+#ifdef EDMA_HAS_EARS
+  uint32_t EARSL;
+#define EDMA_EARSL_EDREQ(x)      (1 << ((x)))       /* iMXRT only */
 #else
-                  uint8_t:1;
+  uint32_t reserved0044;
+#endif
+
+  uint32_t reserved0048[(0x100-0x48)/4];
+
+  uint8_t CPR[64];
+#define EDMA_CPR_CHPRI_SHIFT       (0)
+#define EDMA_CPR_CHPRI_MASK        (0xF << EDMA_CPR_CHPRI_SHIFT)
+#define EDMA_CPR_CHPRI(val)        (((val) << EDMA_CPR_CHPRI_SHIFT) & EDMA_CPR_CHPRI_MASK)
+#define EDMA_CPR_CHPRI_GET(reg)    (((reg) & EDMA_CPR_CHPRI_MASK) >> EDMA_CPR_CHPRI_SHIFT)
+#define EDMA_CPR_GRPPRI_SHIFT      (0)
+#define EDMA_CPR_GRPPRI_MASK       (0xF << EDMA_CPR_GRPPRI_SHIFT)
+#define EDMA_CPR_GRPPRI(val)       (((val) << EDMA_CPR_GRPPRI_SHIFT) & EDMA_CPR_GRPPRI_MASK)
+#define EDMA_CPR_GRPPRI_GET(reg)   (((reg) & EDMA_CPR_GRPPRI_MASK) >> EDMA_CPR_GRPPRI_SHIFT)
+#ifdef EDMA_HAS_CPR_DPA
+  #define EDMA_CPR_DPA             (1 << 6)
 #endif
-                uint8_t GRPPRI:2;
-                uint8_t CHPRI:4;
-            } B;
-        } CPR[64];
-
-        uint32_t edma_reserved2[944];
-
-/****************************************************************************/
-/*       DMA2 Transfer Control Descriptor                                   */
-/****************************************************************************/
-        struct tcd_t {
-            uint32_t SADDR;    /* source address */
-
-            /* Source and destination fields */
-            union tcd_SDF_tag {
-                uint32_t R;
-                struct {
-                    uint16_t SMOD:5;   /* source address modulo */
-                    uint16_t SSIZE:3;  /* source transfer size */
-                    uint16_t DMOD:5;   /* destination address modulo */
-                    uint16_t DSIZE:3;  /* destination transfer size */
-                    int16_t SOFF;      /* signed source address offset */
-                } B;
-            } SDF;
-
-            uint32_t NBYTES;   /* inner (“minor”) byte count */
-
-            int32_t SLAST;     /* last destination address adjustment, or
-                                   scatter/gather address (if e_sg = 1) */
-
-            uint32_t DADDR;    /* destination address */
-
-            /* CITER and destination fields */
-            union tcd_CDF_tag {
-                uint32_t R;
-                struct {
-                    uint16_t CITERE_LINK:1;
-                    uint16_t CITER:15;
-                    int16_t DOFF;      /* signed destination address offset */
-                } B;
-                struct {
-		    uint16_t CITERE_LINK:1;
-		    uint16_t CITERLINKCH:6;
-		    uint16_t CITER:9;
-                    int16_t DOFF;
-                } B_ALT;
-                struct {
-                    uint16_t CITER;
-                    int16_t DOFF;
-                } B_NOLINK;
-            } CDF;
-
-            int32_t DLAST_SGA;
-
-            /* BITER and misc fields */
-            union tcd_BMF_tag {
-                uint32_t R;
-                struct {
-                    uint32_t BITERE_LINK:1;    /* beginning ("major") iteration count */
-                    uint32_t BITER:15;
-                    uint32_t BWC:2;    /* bandwidth control */
-                    uint32_t MAJORLINKCH:6;    /* enable channel-to-channel link */
-                    uint32_t DONE:1;   /* channel done */
-                    uint32_t ACTIVE:1; /* channel active */
-                    uint32_t MAJORE_LINK:1;    /* enable channel-to-channel link */
-                    uint32_t E_SG:1;   /* enable scatter/gather descriptor */
-                    uint32_t D_REQ:1;  /* disable ipd_req when done */
-                    uint32_t INT_HALF:1;       /* interrupt on citer = (biter >> 1) */
-                    uint32_t INT_MAJ:1;        /* interrupt on major loop completion */
-                    uint32_t START:1;  /* explicit channel start */
-                } B;
-                struct {
-                    uint32_t BITERE_LINK:1;
-                    uint32_t BITERLINKCH:6;
-                    uint32_t BITER:9;
-                    uint32_t BWC:2;
-                    uint32_t MAJORLINKCH:6;
-                    uint32_t DONE:1;
-                    uint32_t ACTIVE:1;
-                    uint32_t MAJORE_LINK:1;
-                    uint32_t E_SG:1;
-                    uint32_t D_REQ:1;
-                    uint32_t INT_HALF:1;
-                    uint32_t INT_MAJ:1;
-                    uint32_t START:1;
-                } B_ALT;
-                struct {
-                    uint16_t BITER;
-                    uint16_t BWC:2;
-                    uint16_t MAJORLINKCH:6;
-                    uint16_t DONE:1;
-                    uint16_t ACTIVE:1;
-                    uint16_t MAJORE_LINK:1;
-                    uint16_t E_SG:1;
-                    uint16_t D_REQ:1;
-                    uint16_t INT_HALF:1;
-                    uint16_t INT_MAJ:1;
-                    uint16_t START:1;
-                } B_NOLINK;
-            } BMF;
-        } TCD[64];              /* transfer_control_descriptor */
-    };
+#define EDMA_CPR_ECP               (1 << 7)
+
+  uint32_t reserved0140[(0x1000-0x140)/4];
+
+  struct fsl_edma_tcd {
+    uint32_t SADDR;
+    uint32_t SDF;
+#define EDMA_TCD_SDF_SMOD_SHIFT      (27)
+#define EDMA_TCD_SDF_SMOD_MASK       (0x1F << EDMA_TCD_SDF_SMOD_SHIFT)
+#define EDMA_TCD_SDF_SMOD(val)       (((val) << EDMA_TCD_SDF_SMOD_SHIFT) & EDMA_TCD_SDF_SMOD_MASK)
+#define EDMA_TCD_SDF_SMOD_GET(reg)   (((reg) & EDMA_TCD_SDF_SMOD_MASK) >> EDMA_TCD_SDF_SMOD_SHIFT)
+#define EDMA_TCD_SDF_SSIZE_SHIFT     (24)
+#define EDMA_TCD_SDF_SSIZE_MASK      (0x7 << EDMA_TCD_SDF_SSIZE_SHIFT)
+#define EDMA_TCD_SDF_SSIZE(val)      (((val) << EDMA_TCD_SDF_SSIZE_SHIFT) & EDMA_TCD_SDF_SSIZE_MASK)
+#define EDMA_TCD_SDF_SSIZE_GET(reg)  (((reg) & EDMA_TCD_SDF_SSIZE_MASK) >> EDMA_TCD_SDF_SSIZE_SHIFT)
+#define EDMA_TCD_SDF_SSIZE_8BIT      EDMA_TCD_SDF_SSIZE(0)
+#define EDMA_TCD_SDF_SSIZE_16BIT     EDMA_TCD_SDF_SSIZE(1)
+#define EDMA_TCD_SDF_SSIZE_32BIT     EDMA_TCD_SDF_SSIZE(2)
+#define EDMA_TCD_SDF_SSIZE_64BIT     EDMA_TCD_SDF_SSIZE(3)
+#define EDMA_TCD_SDF_SSIZE_32BYTE    EDMA_TCD_SDF_SSIZE(5)
+#define EDMA_TCD_SDF_DMOD_SHIFT      (19)
+#define EDMA_TCD_SDF_DMOD_MASK       (0x1F << EDMA_TCD_SDF_DMOD_SHIFT)
+#define EDMA_TCD_SDF_DMOD(val)       (((val) << EDMA_TCD_SDF_DMOD_SHIFT) & EDMA_TCD_SDF_DMOD_MASK)
+#define EDMA_TCD_SDF_DMOD_GET(reg)   (((reg) & EDMA_TCD_SDF_DMOD_MASK) >> EDMA_TCD_SDF_DMOD_SHIFT)
+#define EDMA_TCD_SDF_DSIZE_SHIFT     (16)
+#define EDMA_TCD_SDF_DSIZE_MASK      (0x7 << EDMA_TCD_SDF_DSIZE_SHIFT)
+#define EDMA_TCD_SDF_DSIZE(val)      (((val) << EDMA_TCD_SDF_DSIZE_SHIFT) & EDMA_TCD_SDF_DSIZE_MASK)
+#define EDMA_TCD_SDF_DSIZE_GET(reg)  (((reg) & EDMA_TCD_SDF_DSIZE_MASK) >> EDMA_TCD_SDF_DSIZE_SHIFT)
+#define EDMA_TCD_SDF_DSIZE_8BIT      EDMA_TCD_SDF_DSIZE(0)
+#define EDMA_TCD_SDF_DSIZE_16BIT     EDMA_TCD_SDF_DSIZE(1)
+#define EDMA_TCD_SDF_DSIZE_32BIT     EDMA_TCD_SDF_DSIZE(2)
+#define EDMA_TCD_SDF_DSIZE_64BIT     EDMA_TCD_SDF_DSIZE(3)
+#define EDMA_TCD_SDF_DSIZE_32BYTE    EDMA_TCD_SDF_DSIZE(5)
+#define EDMA_TCD_SDF_SOFF_SHIFT      (0)
+#define EDMA_TCD_SDF_SOFF_MASK       (0xFFFF << EDMA_TCD_SDF_SOFF_SHIFT)
+#define EDMA_TCD_SDF_SOFF(val)       (((val) << EDMA_TCD_SDF_SOFF_SHIFT) & EDMA_TCD_SDF_SOFF_MASK)
+#define EDMA_TCD_SDF_SOFF_GET(reg)   (((reg) & EDMA_TCD_SDF_SOFF_MASK) >> EDMA_TCD_SDF_SOFF_SHIFT)
+
+    uint32_t NBYTES;
+#define EDMA_TCD_NBYTES_ALT_NBYTES_SHIFT    (0)
+#define EDMA_TCD_NBYTES_ALT_NBYTES_MASK     (0x3FF << EDMA_TCD_NBYTES_ALT_NBYTES_SHIFT)
+#define EDMA_TCD_NBYTES_ALT_NBYTES(val)     (((val) << EDMA_TCD_NBYTES_ALT_NBYTES_SHIFT) & EDMA_TCD_NBYTES_ALT_NBYTES_MASK)
+#define EDMA_TCD_NBYTES_ALT_MLOFF_SHIFT     (10)
+#define EDMA_TCD_NBYTES_ALT_MLOFF_MASK      (0xFFFFF << EDMA_TCD_NBYTES_ALT_MLOFF_SHIFT)
+#define EDMA_TCD_NBYTES_ALT_MLOFF(val)      (((val) << EDMA_TCD_NBYTES_ALT_MLOFF_SHIFT) & EDMA_TCD_NBYTES_ALT_MLOFF_MASK)
+#define EDMA_TCD_NBYTES_ALT_DMLOE           (1 << 30)
+#define EDMA_TCD_NBYTES_ALT_SMLOE           (1 << 31)
+    int32_t SLAST;
+    uint32_t DADDR;
+    uint32_t CDF;
+#define EDMA_TCD_CDF_CITERE_LINK    (1 << 31)
+#define EDMA_TCD_CDF_CITER_SHIFT    (16)
+#define EDMA_TCD_CDF_CITER_MASK     (0x7FFF << EDMA_TCD_CDF_CITER_SHIFT)
+#define EDMA_TCD_CDF_CITER(val)     (((val) << EDMA_TCD_CDF_CITER_SHIFT) & EDMA_TCD_CDF_CITER_MASK)
+#define EDMA_TCD_CDF_CITER_GET(reg) (((reg) & EDMA_TCD_CDF_CITER_MASK) >> EDMA_TCD_CDF_CITER_SHIFT)
+#define EDMA_TCD_CDF_DOFF_SHIFT     (0)
+#define EDMA_TCD_CDF_DOFF_MASK      (0xFFFF << EDMA_TCD_CDF_DOFF_SHIFT)
+#define EDMA_TCD_CDF_DOFF(val)      (((val) << EDMA_TCD_CDF_DOFF_SHIFT) & EDMA_TCD_CDF_DOFF_MASK)
+#define EDMA_TCD_CDF_DOFF_GET(reg)  (((reg) & EDMA_TCD_CDF_DOFF_MASK) >> EDMA_TCD_CDF_DOFF_SHIFT)
+
+#define EDMA_TCD_CDF_ALT_CITERLINKCH_SHIFT    (25)
+#define EDMA_TCD_CDF_ALT_CITERLINKCH_MASK     (0x3F << EDMA_TCD_CDF_ALT_CITERLINKCH_SHIFT)
+#define EDMA_TCD_CDF_ALT_CITERLINKCH(val)     (((val) << EDMA_TCD_CDF_ALT_CITERLINKCH_SHIFT) & EDMA_TCD_CDF_ALT_CITERLINKCH_MASK)
+#define EDMA_TCD_CDF_ALT_CITERLINKCH_GET(reg) (((reg) & EDMA_TCD_CDF_ALT_CITERLINKCH_MASK) >> EDMA_TCD_CDF_ALT_CITERLINKCH_SHIFT)
+#define EDMA_TCD_CDF_ALT_CITER_SHIFT          (16)
+#define EDMA_TCD_CDF_ALT_CITER_MASK           (0x1FF << EDMA_TCD_CDF_ALT_CITER_SHIFT)
+#define EDMA_TCD_CDF_ALT_CITER(val)           (((val) << EDMA_TCD_CDF_ALT_CITER_SHIFT) & EDMA_TCD_CDF_ALT_CITER_MASK)
+#define EDMA_TCD_CDF_ALT_CITER_GET(reg)       (((reg) & EDMA_TCD_CDF_ALT_CITER_MASK) >> EDMA_TCD_CDF_ALT_CITER_SHIFT)
+
+#define EDMA_TCD_CDF_NOLINK_CITER_SHIFT    (16)
+#define EDMA_TCD_CDF_NOLINK_CITER_MASK     (0xFFFF << EDMA_TCD_CDF_NOLINK_CITER_SHIFT)
+#define EDMA_TCD_CDF_NOLINK_CITER(val)     (((val) << EDMA_TCD_CDF_NOLINK_CITER_SHIFT) & EDMA_TCD_CDF_NOLINK_CITER_MASK)
+#define EDMA_TCD_CDF_NOLINK_CITER_GET(reg) (((reg) & EDMA_TCD_CDF_NOLINK_CITER_MASK) >> EDMA_TCD_CDF_NOLINK_CITER_SHIFT)
+
+    int32_t DLAST_SGA;
+    uint32_t BMF;
+#define EDMA_TCD_BMF_BITERE_LINK          (1 << 31)
+#define EDMA_TCD_BMF_BITER_SHIFT          (16)
+#define EDMA_TCD_BMF_BITER_MASK           (0x7FFF << EDMA_TCD_BMF_BITER_SHIFT)
+#define EDMA_TCD_BMF_BITER(val)           (((val) << EDMA_TCD_BMF_BITER_SHIFT) & EDMA_TCD_BMF_BITER_MASK)
+#define EDMA_TCD_BMF_BITER_GET(reg)       (((reg) & EDMA_TCD_BMF_BITER_MASK) >> EDMA_TCD_BMF_BITER_SHIFT)
+#define EDMA_TCD_BMF_BWC_SHIFT            (14)
+#define EDMA_TCD_BMF_BWC_MASK             (0x3 << EDMA_TCD_BMF_BWC_SHIFT)
+#define EDMA_TCD_BMF_BWC(val)             (((val) << EDMA_TCD_BMF_BWC_SHIFT) & EDMA_TCD_BMF_BWC_MASK)
+#define EDMA_TCD_BMF_BWC_GET(reg)         (((reg) & EDMA_TCD_BMF_BWC_MASK) >> EDMA_TCD_BMF_BWC_SHIFT)
+#define EDMA_TCD_BMF_MAJORLINKCH_SHIFT    (8)
+#define EDMA_TCD_BMF_MAJORLINKCH_MASK     (0x3F << EDMA_TCD_BMF_MAJORLINKCH_SHIFT)
+#define EDMA_TCD_BMF_MAJORLINKCH(val)     (((val) << EDMA_TCD_BMF_MAJORLINKCH_SHIFT) & EDMA_TCD_BMF_MAJORLINKCH_MASK)
+#define EDMA_TCD_BMF_MAJORLINKCH_GET(reg) (((reg) & EDMA_TCD_BMF_MAJORLINKCH_MASK) >> EDMA_TCD_BMF_MAJORLINKCH_SHIFT)
+#define EDMA_TCD_BMF_DONE                 (1 << 7)
+#define EDMA_TCD_BMF_ACTIVE               (1 << 6)
+#define EDMA_TCD_BMF_MAJORE_LINK          (1 << 5)
+#define EDMA_TCD_BMF_E_SG                 (1 << 4)
+#define EDMA_TCD_BMF_D_REQ                (1 << 3)
+#define EDMA_TCD_BMF_INT_HALF             (1 << 2)
+#define EDMA_TCD_BMF_INT_MAJ              (1 << 1)
+#define EDMA_TCD_BMF_START                (1 << 0)
+
+#define EDMA_TCD_BMF_ALT_BITERLINKCH_SHIFT    (25)
+#define EDMA_TCD_BMF_ALT_BITERLINKCH_MASK     (0x3F << EDMA_TCD_BMF_ALT_BITERLINKCH_SHIFT)
+#define EDMA_TCD_BMF_ALT_BITERLINKCH(val)     (((val) << EDMA_TCD_BMF_ALT_BITERLINKCH_SHIFT) & EDMA_TCD_BMF_ALT_BITERLINKCH_MASK)
+#define EDMA_TCD_BMF_ALT_BITERLINKCH_GET(reg) (((reg) & EDMA_TCD_BMF_ALT_BITERLINKCH_MASK) >> EDMA_TCD_BMF_ALT_BITERLINKCH_SHIFT)
+#define EDMA_TCD_BMF_ALT_BITER_SHIFT          (16)
+#define EDMA_TCD_BMF_ALT_BITER_MASK           (0x1FF << EDMA_TCD_BMF_ALT_BITER_SHIFT)
+#define EDMA_TCD_BMF_ALT_BITER(val)           (((val) << EDMA_TCD_BMF_ALT_BITER_SHIFT) & EDMA_TCD_BMF_ALT_BITER_MASK)
+#define EDMA_TCD_BMF_ALT_BITER_GET(reg)       (((reg) & EDMA_TCD_BMF_ALT_BITER_MASK) >> EDMA_TCD_BMF_ALT_BITER_SHIFT)
+
+#define EDMA_TCD_BMF_NOLINK_BITER_SHIFT    (16)
+#define EDMA_TCD_BMF_NOLINK_BITER_MASK     (0xFFFF << EDMA_TCD_BMF_NOLINK_BITER_SHIFT)
+#define EDMA_TCD_BMF_NOLINK_BITER(val)     (((val) << EDMA_TCD_BMF_NOLINK_BITER_SHIFT) & EDMA_TCD_BMF_NOLINK_BITER_MASK)
+#define EDMA_TCD_BMF_NOLINK_BITER_GET(reg) (((reg) & EDMA_TCD_BMF_NOLINK_BITER_MASK) >> EDMA_TCD_BMF_NOLINK_BITER_SHIFT)
+
+  } TCD[64];
+};
 
 #ifndef  __cplusplus
-    static const struct tcd_t EDMA_TCD_DEFAULT = {
-        .SADDR = 0,
-        .SDF = { .R = 0 },
-        .NBYTES = 0,
-        .SLAST = 0,
-        .DADDR = 0,
-        .CDF = { .R = 0 },
-        .DLAST_SGA = 0,
-        .BMF = { .R = 0 }
-    };
+static const struct fsl_edma_tcd EDMA_TCD_DEFAULT = {
+    .SADDR = 0,
+    .SDF = 0,
+    .NBYTES = 0,
+    .SLAST = 0,
+    .DADDR = 0,
+    .CDF = 0,
+    .DLAST_SGA = 0,
+    .BMF = 0,
+};
 #endif /* __cplusplus */
 
 #define EDMA_TCD_BITER_MASK 0x7fff
@@ -707,4 +416,4 @@ extern "C" {
 }
 #endif /* __cplusplus */
 
-#endif /* LIBCPU_POWERPC_MPC55XX_REGS_EDMA_H */
+#endif /* LIBBSP_SHARED_FSL_REGS_EDMA_H */
diff --git a/bsps/shared/dev/dma/fsl-edma.c b/bsps/shared/dev/dma/fsl-edma.c
index c34624e..b3e1bb2 100644
--- a/bsps/shared/dev/dma/fsl-edma.c
+++ b/bsps/shared/dev/dma/fsl-edma.c
@@ -1,33 +1,47 @@
 /**
  * @file
  *
- * @ingroup RTEMSBSPsPowerPCMPC55XX
+ * @ingroup RTEMSBSPsSharedFslEDMA
  *
- * @brief Enhanced Direct Memory Access (eDMA).
+ * @brief Freescale / NXP Enhanced Direct Memory Access (eDMA).
  */
 
 /*
- * Copyright (c) 2008-2013 embedded brains GmbH.  All rights reserved.
+ * Copyright (C) 2008-2020 embedded brains GmbH (http://www.embedded-brains.de)
  *
- *  embedded brains GmbH
- *  Dornierstr. 4
- *  82178 Puchheim
- *  Germany
- *  <rtems at embedded-brains.de>
+ * 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.
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
  */
 
-#include <mpc55xx/edma.h>
-#include <mpc55xx/mpc55xx.h>
+#include <fsl/edma.h>
+#include <fsl/regs-edma.h>
 
 #include <assert.h>
 
 #include <bsp.h>
 #include <bsp/fatal.h>
 #include <bsp/irq.h>
+#ifdef LIBBSP_ARM_IMXRT_BSP_H
+#include <MIMXRT1052.h>
+#endif
 
 #define EDMA_CHANNELS_PER_GROUP 32U
 
@@ -43,32 +57,67 @@ static uint32_t edma_channel_occupation [EDMA_GROUP_COUNT];
 
 static RTEMS_CHAIN_DEFINE_EMPTY(edma_channel_chain);
 
-static unsigned edma_channel_index_of_tcd(volatile struct tcd_t *edma_tcd)
+volatile struct fsl_edma *edma_inst[EDMA_MODULE_COUNT] = {
+#ifdef LIBBSP_ARM_IMXRT_BSP_H
+  (volatile struct fsl_edma *) DMA0,
+#else /* ! LIBBSP_ARM_IMXRT_BSP_H */
+  #if EDMA_MODULE_COUNT == 1
+    (volatile struct fsl_edma *) &EDMA,
+  #elif EDMA_MODULE_COUNT == 2
+    (volatile struct fsl_edma *) &EDMA_A,
+    (volatile struct fsl_edma *) &EDMA_B,
+  #else
+    #error "unsupported module count"
+  #endif
+#endif /* LIBBSP_ARM_IMXRT_BSP_H */
+};
+
+unsigned fsl_edma_channel_index_of_tcd(
+  volatile struct fsl_edma_tcd *edma_tcd
+)
 {
-  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
+  volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
   unsigned channel = edma_tcd - &edma->TCD[0];
 
-#if EDMA_MODULE_COUNT == 1
-  return channel;
-#elif EDMA_MODULE_COUNT == 2
-  return channel + (&EDMA_A == edma ? 0 : EDMA_CHANNELS_PER_MODULE);
-#else
+#if EDMA_MODULE_COUNT == 2
+  if (edma_inst[1] == edma) {
+    channel += EDMA_CHANNELS_PER_MODULE;
+  }
+#elif EDMA_MODULE_COUNT > 2
   #error "unsupported module count"
 #endif
+
+  return channel;
 }
 
-static volatile struct EDMA_tag *edma_get_regs_by_module(unsigned module)
+volatile struct fsl_edma_tcd *fsl_edma_tcd_of_channel_index(unsigned index)
 {
-#if EDMA_MODULE_COUNT == 1
-  return &EDMA;
-#elif EDMA_MODULE_COUNT == 2
-  return module == 0 ? &EDMA_A : &EDMA_B;
-#else
-  #error "unsupported module count"
-#endif
+  unsigned module = index / EDMA_CHANNELS_PER_MODULE;
+  unsigned channel = index % EDMA_CHANNELS_PER_MODULE;
+
+  return &edma_inst[module]->TCD[channel];
 }
 
-static uint32_t edma_bit_array_set(unsigned channel, uint32_t *bit_array)
+static volatile struct fsl_edma *fsl_edma_get_regs_by_module(unsigned module)
+{
+  return edma_inst[module];
+}
+
+static uint32_t fsl_edma_bit_array_get_lowest_0(uint32_t *bit_array)
+{
+  unsigned array;
+
+  for (array = 0; array < EDMA_MODULE_COUNT; ++array) {
+    uint32_t first_0 = __builtin_ffs(~(bit_array[array]));
+    if (first_0 > 0) {
+      return (first_0 - 1) + array * 32;
+    }
+  }
+
+  return UINT32_MAX;
+}
+
+static uint32_t fsl_edma_bit_array_set(unsigned channel, uint32_t *bit_array)
 {
   unsigned array = channel / 32;
   uint32_t bit = 1U << (channel % 32);
@@ -79,7 +128,7 @@ static uint32_t edma_bit_array_set(unsigned channel, uint32_t *bit_array)
   return previous;
 }
 
-static uint32_t edma_bit_array_clear(unsigned channel, uint32_t *bit_array)
+static uint32_t fsl_edma_bit_array_clear(unsigned channel, uint32_t *bit_array)
 {
   unsigned array = channel / 32;
   uint32_t bit = 1U << (channel % 32);
@@ -90,11 +139,11 @@ static uint32_t edma_bit_array_clear(unsigned channel, uint32_t *bit_array)
   return previous;
 }
 
-static void edma_interrupt_handler(void *arg)
+static void fsl_edma_interrupt_handler(void *arg)
 {
-  edma_channel_context *ctx = arg;
+  fsl_edma_channel_context *ctx = arg;
 
-  mpc55xx_edma_clear_interrupts(ctx->edma_tcd);
+  fsl_edma_clear_interrupts(ctx->edma_tcd);
 
   (*ctx->done)(ctx, 0);
 }
@@ -103,39 +152,40 @@ static void edma_interrupt_error_handler(void *arg)
 {
   rtems_chain_control *chain = &edma_channel_chain;
   rtems_chain_node *node = rtems_chain_first(chain);
+
   uint32_t error_channels [] = {
 #if EDMA_GROUP_COUNT >= 1
-    EDMA.ERL.R
+    edma_inst[0]->ERL,
 #endif
 #if EDMA_GROUP_COUNT >= 2
-    , EDMA.ERH.R
+    edma_inst[0]->ERH,
 #endif
 #if EDMA_GROUP_COUNT >= 3
-    , EDMA_B.ERL.R
+    edma_inst[1]->ERL,
 #endif
   };
   uint32_t error_status [] = {
 #if EDMA_GROUP_COUNT >= 1
-    EDMA.ESR.R
+    edma_inst[0]->ESR,
 #endif
 #if EDMA_GROUP_COUNT >= 3
-    , EDMA_B.ESR.R
+    edma_inst[1]->ESR,
 #endif
   };
 
 #if EDMA_GROUP_COUNT >= 1
-  EDMA.ERL.R = error_channels [0];
+  edma_inst[0]->ERL = error_channels [0];
 #endif
 #if EDMA_GROUP_COUNT >= 2
-  EDMA.ERH.R = error_channels [1];
+  edma_inst[0]->ERH = error_channels [1];
 #endif
 #if EDMA_GROUP_COUNT >= 3
-  EDMA_B.ERL.R = error_channels [2];
+  edma_inst[1]->ERL = error_channels [2];
 #endif
 
   while (!rtems_chain_is_tail(chain, node)) {
-    edma_channel_context *ctx = (edma_channel_context *) node;
-    unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
+    fsl_edma_channel_context *ctx = (fsl_edma_channel_context *) node;
+    unsigned channel_index = fsl_edma_channel_index_of_tcd(ctx->edma_tcd);
     unsigned group_index = EDMA_GROUP_INDEX(channel_index);
     unsigned group_bit = EDMA_GROUP_BIT(channel_index);
 
@@ -149,7 +199,7 @@ static void edma_interrupt_error_handler(void *arg)
   }
 }
 
-void mpc55xx_edma_init(void)
+void fsl_edma_init(void)
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
   unsigned channel_remaining = EDMA_CHANNEL_COUNT;
@@ -157,7 +207,7 @@ void mpc55xx_edma_init(void)
   unsigned group = 0;
 
   for (module = 0; module < EDMA_MODULE_COUNT; ++module) {
-    volatile struct EDMA_tag *edma = edma_get_regs_by_module(module);
+    volatile struct fsl_edma *edma = fsl_edma_get_regs_by_module(module);
     unsigned channel_count = channel_remaining < EDMA_CHANNELS_PER_MODULE ?
       channel_remaining : EDMA_CHANNELS_PER_MODULE;
     unsigned channel = 0;
@@ -165,32 +215,36 @@ void mpc55xx_edma_init(void)
     channel_remaining -= channel_count;
 
     /* Disable requests */
-    edma->CERQR.B.CERQ = 0x40;
+    edma->CERQR = EDMA_CERQR_CAER;
 
     /* Arbitration mode: group round robin, channel fixed */
-    edma->CR.B.ERGA = 1;
-    edma->CR.B.ERCA = 0;
+    edma->CR |= EDMA_CR_ERGA;
+    edma->CR &= ~EDMA_CR_ERCA;
+#if defined(BSP_FSL_EDMA_EMLM)
+    edma->CR |= EDMA_CR_EMLM;
+#endif
     for (channel = 0; channel < channel_count; ++channel) {
-      volatile struct tcd_t *tcd = &edma->TCD [channel];
-      edma->CPR [channel].R = 0x80U | (channel & 0xfU);
+      volatile struct fsl_edma_tcd *tcd = &edma->TCD [channel];
+      edma->CPR [channel] = EDMA_CPR_ECP | EDMA_CPR_CHPRI(channel);
 
       /* Initialize TCD, stop channel first */
-      tcd->BMF.R = 0;
+      tcd->BMF = 0;
       tcd->SADDR = 0;
-      tcd->SDF.R = 0;
+      tcd->SDF = 0;
       tcd->NBYTES = 0;
       tcd->SLAST = 0;
       tcd->DADDR = 0;
-      tcd->CDF.R = 0;
+      tcd->CDF = 0;
       tcd->DLAST_SGA = 0;
     }
 
     /* Clear interrupt requests */
-    edma->CIRQR.B.CINT = 0x40;
-    edma->CER.B.CERR = 0x40;
+    edma->CIRQR = EDMA_CIRQR_CAIR;
+    edma->CER = EDMA_CER_CAEI;
   }
 
   for (group = 0; group < EDMA_GROUP_COUNT; ++group) {
+#if defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
     sc = mpc55xx_interrupt_handler_install(
       MPC55XX_IRQ_EDMA_ERROR(group),
       "eDMA Error",
@@ -199,23 +253,61 @@ void mpc55xx_edma_init(void)
       edma_interrupt_error_handler,
       NULL
     );
+#elif defined(LIBBSP_ARM_IMXRT_BSP_H)
+    sc = rtems_interrupt_handler_install(
+      DMA_ERROR_IRQn,
+      "eDMA Error",
+      RTEMS_INTERRUPT_UNIQUE,
+      edma_interrupt_error_handler,
+      NULL
+    );
+#else
+  #error "Unknown chip"
+#endif
     if (sc != RTEMS_SUCCESSFUL) {
       bsp_fatal(MPC55XX_FATAL_EDMA_IRQ_INSTALL);
     }
   }
 }
 
-rtems_status_code mpc55xx_edma_obtain_channel_by_tcd(
-  volatile struct tcd_t *edma_tcd
+static rtems_status_code fsl_edma_obtain_next_free_channel_and_get_tcd(
+  volatile struct fsl_edma_tcd **edma_tcd
+)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+  unsigned channel_index;
+  rtems_interrupt_level level;
+
+  rtems_interrupt_disable(level);
+  channel_index = fsl_edma_bit_array_get_lowest_0(&edma_channel_occupation [0]);
+  if (channel_index > EDMA_CHANNEL_COUNT) {
+    sc = RTEMS_RESOURCE_IN_USE;
+  } else {
+    fsl_edma_bit_array_set(
+      channel_index,
+      &edma_channel_occupation [0]
+    );
+  }
+  rtems_interrupt_enable(level);
+
+  if (sc == RTEMS_SUCCESSFUL) {
+    *edma_tcd = fsl_edma_tcd_of_channel_index(channel_index);
+  }
+
+  return sc;
+}
+
+rtems_status_code fsl_edma_obtain_channel_by_tcd(
+  volatile struct fsl_edma_tcd *edma_tcd
 )
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
-  unsigned channel_index = edma_channel_index_of_tcd(edma_tcd);
+  unsigned channel_index = fsl_edma_channel_index_of_tcd(edma_tcd);
   rtems_interrupt_level level;
   uint32_t channel_occupation;
 
   rtems_interrupt_disable(level);
-  channel_occupation = edma_bit_array_set(
+  channel_occupation = fsl_edma_bit_array_set(
     channel_index,
     &edma_channel_occupation [0]
   );
@@ -228,59 +320,108 @@ rtems_status_code mpc55xx_edma_obtain_channel_by_tcd(
   return sc;
 }
 
-void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd)
+void fsl_edma_release_channel_by_tcd(volatile struct fsl_edma_tcd *edma_tcd)
 {
-  unsigned channel_index = edma_channel_index_of_tcd(edma_tcd);
+  unsigned channel_index = fsl_edma_channel_index_of_tcd(edma_tcd);
   rtems_interrupt_level level;
 
   rtems_interrupt_disable(level);
-  edma_bit_array_clear(channel_index, &edma_channel_occupation [0]);
+  fsl_edma_bit_array_clear(channel_index, &edma_channel_occupation [0]);
   rtems_interrupt_enable(level);
 
-  mpc55xx_edma_disable_hardware_requests(edma_tcd);
-  mpc55xx_edma_disable_error_interrupts(edma_tcd);
+  fsl_edma_disable_hardware_requests(edma_tcd);
+  fsl_edma_disable_error_interrupts(edma_tcd);
 }
 
-rtems_status_code mpc55xx_edma_obtain_channel(
-  edma_channel_context *ctx,
+static rtems_status_code fsl_edma_install_obtained_channel(
+  fsl_edma_channel_context *ctx,
   unsigned irq_priority
 )
 {
-  rtems_status_code sc = mpc55xx_edma_obtain_channel_by_tcd(ctx->edma_tcd);
+  unsigned channel_index = fsl_edma_channel_index_of_tcd(ctx->edma_tcd);
+  rtems_status_code sc;
+
+#if defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
+  sc = fsl_interrupt_handler_install(
+    MPC55XX_IRQ_EDMA(channel_index),
+    "eDMA Channel",
+    RTEMS_INTERRUPT_SHARED,
+    irq_priority,
+    fsl_edma_interrupt_handler,
+    ctx
+  );
+#elif defined(LIBBSP_ARM_IMXRT_BSP_H)
+  sc = rtems_interrupt_handler_install(
+    DMA0_DMA16_IRQn + (channel_index % 16),
+    "eDMA Channel",
+    RTEMS_INTERRUPT_SHARED,
+    fsl_edma_interrupt_handler,
+    ctx
+  );
+#else
+  #error "Unknown chip"
+#endif
   if (sc == RTEMS_SUCCESSFUL) {
-    unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
+    rtems_chain_prepend(&edma_channel_chain, &ctx->node);
+    fsl_edma_enable_error_interrupts(ctx->edma_tcd);
+  } else {
+    fsl_edma_release_channel_by_tcd(ctx->edma_tcd);
+    sc = RTEMS_IO_ERROR;
+  }
 
-    sc = mpc55xx_interrupt_handler_install(
-      MPC55XX_IRQ_EDMA(channel_index),
-      "eDMA Channel",
-      RTEMS_INTERRUPT_SHARED,
-      irq_priority,
-      edma_interrupt_handler,
-      ctx
+  return sc;
+}
+
+rtems_status_code fsl_edma_obtain_channel(
+  fsl_edma_channel_context *ctx,
+  unsigned irq_priority
+)
+{
+  rtems_status_code sc = fsl_edma_obtain_channel_by_tcd(ctx->edma_tcd);
+  if (sc == RTEMS_SUCCESSFUL) {
+    sc = fsl_edma_install_obtained_channel(ctx, irq_priority);
+  }
+
+  return sc;
+}
+
+rtems_status_code fsl_edma_obtain_next_free_channel(
+  fsl_edma_channel_context *ctx
+)
+{
+  rtems_status_code sc;
+
+  sc = fsl_edma_obtain_next_free_channel_and_get_tcd(&ctx->edma_tcd);
+  if (sc == RTEMS_SUCCESSFUL) {
+    sc = fsl_edma_install_obtained_channel(ctx,
+#ifdef LIBBSP_POWERPC_MPC55XXEVB_BSP_H
+      MPC55XX_INTC_DEFAULT_PRIORITY
+#else
+      0
+#endif
     );
-    if (sc == RTEMS_SUCCESSFUL) {
-      rtems_chain_prepend(&edma_channel_chain, &ctx->node);
-      mpc55xx_edma_enable_error_interrupts(ctx->edma_tcd);
-    } else {
-      mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
-      sc = RTEMS_IO_ERROR;
-    }
   }
 
   return sc;
 }
 
-void mpc55xx_edma_release_channel(edma_channel_context *ctx)
+void fsl_edma_release_channel(fsl_edma_channel_context *ctx)
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
-  unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
+  unsigned channel_index = fsl_edma_channel_index_of_tcd(ctx->edma_tcd);
 
-  mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
+  fsl_edma_release_channel_by_tcd(ctx->edma_tcd);
   rtems_chain_extract(&ctx->node);
 
   sc = rtems_interrupt_handler_remove(
+#if defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
     MPC55XX_IRQ_EDMA(channel_index),
-    edma_interrupt_handler,
+#elif defined(LIBBSP_ARM_IMXRT_BSP_H)
+    DMA0_DMA16_IRQn + (channel_index % 16),
+#else
+  #error "Unknown chip"
+#endif
+    fsl_edma_interrupt_handler,
     ctx
   );
   if (sc != RTEMS_SUCCESSFUL) {
@@ -288,42 +429,42 @@ void mpc55xx_edma_release_channel(edma_channel_context *ctx)
   }
 }
 
-void mpc55xx_edma_copy(
-  volatile struct tcd_t *edma_tcd,
-  const struct tcd_t *source_tcd
+void fsl_edma_copy(
+  volatile struct fsl_edma_tcd *edma_tcd,
+  const struct fsl_edma_tcd *source_tcd
 )
 {
   /* Clear DONE flag */
-  edma_tcd->BMF.R = 0;
+  edma_tcd->BMF = 0;
 
   edma_tcd->SADDR = source_tcd->SADDR;
-  edma_tcd->SDF.R = source_tcd->SDF.R;
+  edma_tcd->SDF = source_tcd->SDF;
   edma_tcd->NBYTES = source_tcd->NBYTES;
   edma_tcd->SLAST = source_tcd->SLAST;
   edma_tcd->DADDR = source_tcd->DADDR;
-  edma_tcd->CDF.R = source_tcd->CDF.R;
+  edma_tcd->CDF = source_tcd->CDF;
   edma_tcd->DLAST_SGA = source_tcd->DLAST_SGA;
-  edma_tcd->BMF.R = source_tcd->BMF.R;
+  edma_tcd->BMF = source_tcd->BMF;
 }
 
-void mpc55xx_edma_copy_and_enable_hardware_requests(
-  volatile struct tcd_t *edma_tcd,
-  const struct tcd_t *source_tcd
+void fsl_edma_copy_and_enable_hardware_requests(
+  volatile struct fsl_edma_tcd *edma_tcd,
+  const struct fsl_edma_tcd *source_tcd
 )
 {
-  mpc55xx_edma_copy(edma_tcd, source_tcd);
-  mpc55xx_edma_enable_hardware_requests(edma_tcd);
+  fsl_edma_copy(edma_tcd, source_tcd);
+  fsl_edma_enable_hardware_requests(edma_tcd);
 }
 
-void mpc55xx_edma_sg_link(
-  volatile struct tcd_t *edma_tcd,
-  const struct tcd_t *source_tcd
+void fsl_edma_sg_link(
+  volatile struct fsl_edma_tcd *edma_tcd,
+  const struct fsl_edma_tcd *source_tcd
 )
 {
   edma_tcd->DLAST_SGA = (int32_t) source_tcd;
-  edma_tcd->BMF.B.E_SG = 1;
+  edma_tcd->BMF |= EDMA_TCD_BMF_E_SG;
 
-  if (!edma_tcd->BMF.B.E_SG) {
-    mpc55xx_edma_copy(edma_tcd, source_tcd);
+  if ((edma_tcd->BMF & EDMA_TCD_BMF_E_SG) == 0) {
+    fsl_edma_copy(edma_tcd, source_tcd);
   }
 }
diff --git a/spec/build/bsps/arm/imxrt/bspimxrt.yml b/spec/build/bsps/arm/imxrt/bspimxrt.yml
index 30f7927..be4a4bb 100644
--- a/spec/build/bsps/arm/imxrt/bspimxrt.yml
+++ b/spec/build/bsps/arm/imxrt/bspimxrt.yml
@@ -119,6 +119,8 @@ links:
 - role: build-dependency
   uid: ../../optconsoleirq
 - role: build-dependency
+  uid: optfsledmaemlm
+- role: build-dependency
   uid: optlinkcmds
 - role: build-dependency
   uid: optmemflashcfgsz
diff --git a/spec/build/bsps/arm/imxrt/optfsledmaemlm.yml b/spec/build/bsps/arm/imxrt/optfsledmaemlm.yml
new file mode 100644
index 0000000..80c8403
--- /dev/null
+++ b/spec/build/bsps/arm/imxrt/optfsledmaemlm.yml
@@ -0,0 +1,16 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+actions:
+- get-boolean: null
+- define-condition: null
+build-type: option
+copyrights:
+- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+default: true
+default-by-variant: []
+description: |
+  Enable the minor loop mapping of the Freescale EDMA.
+enabled-by: true
+format: '{}'
+links: []
+name: BSP_FSL_EDMA_EMLM
+type: build
diff --git a/spec/build/bsps/obj.yml b/spec/build/bsps/obj.yml
index b598d54..abed6bc 100644
--- a/spec/build/bsps/obj.yml
+++ b/spec/build/bsps/obj.yml
@@ -28,6 +28,10 @@ install:
   source:
   - bsps/include/ofw/ofw.h
   - bsps/include/ofw/ofw_compat.h
+- destination: ${BSP_INCLUDEDIR}/fsl
+  source:
+  - bsps/include/fsl/edma.h
+  - bsps/include/fsl/regs-edma.h
 - destination: ${BSP_INCLUDEDIR}/libchip
   source:
   - bsps/include/libchip/ata.h
@@ -72,6 +76,7 @@ links:
 source:
 - bsps/shared/dev/display/disp_hcms29xx.c
 - bsps/shared/dev/display/font_hcms29xx.c
+- bsps/shared/dev/dma/fsl-edma.c
 - bsps/shared/dev/i2c/i2c-2b-eeprom.c
 - bsps/shared/dev/i2c/i2c-ds1621.c
 - bsps/shared/dev/i2c/i2c-sc620.c



More information about the vc mailing list