You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/08/09 13:29:28 UTC

[incubator-nuttx] branch master updated (c18b5602e8 -> 2e7b594bf4)

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

pkarashchenko pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


    from c18b5602e8 fs/procfs: add mempool info to proc/mempool
     new 3813320c31 s32k1xx_edma:Add Looping and cleanup
     new 2e7b594bf4 s32k1xx:Add s32k146 DMAMUX

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/arm/src/s32k1xx/Kconfig                      |   1 +
 arch/arm/src/s32k1xx/hardware/s32k146_dmamux.h    |  91 +++++++++
 arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h    |  10 +-
 arch/arm/src/s32k1xx/hardware/s32k1xx_edma.h      |   6 +-
 arch/arm/src/s32k1xx/hardware/s32k1xx_memorymap.h |   4 +-
 arch/arm/src/s32k1xx/s32k1xx_edma.c               | 233 +++++++++-------------
 arch/arm/src/s32k1xx/s32k1xx_edma.h               |  33 ++-
 7 files changed, 219 insertions(+), 159 deletions(-)
 create mode 100644 arch/arm/src/s32k1xx/hardware/s32k146_dmamux.h


[incubator-nuttx] 02/02: s32k1xx:Add s32k146 DMAMUX

Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2e7b594bf41c728c4ad891498d513f2ca1329d65
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Thu Jul 28 12:50:29 2022 -0700

    s32k1xx:Add s32k146 DMAMUX
---
 arch/arm/src/s32k1xx/hardware/s32k146_dmamux.h | 91 ++++++++++++++++++++++++++
 arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h |  8 ++-
 2 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/arch/arm/src/s32k1xx/hardware/s32k146_dmamux.h b/arch/arm/src/s32k1xx/hardware/s32k146_dmamux.h
new file mode 100644
index 0000000000..0c8480fa27
--- /dev/null
+++ b/arch/arm/src/s32k1xx/hardware/s32k146_dmamux.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+ * arch/arm/src/s32k1xx/hardware/s32k146_dmamux.h
+ *
+ * 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_S32K1XX_HARDWARE_S32K146_DMAMUX_H
+#define __ARCH_ARM_SRC_S32K1XX_HARDWARE_S32K146_DMAMUX_H
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Peripheral DMA request channels */
+
+#define S32K1XX_DMACHAN_DISABLED                   0  /* Disabled DMA Request */
+#define S32K1XX_DMACHAN_LPUART0_RX                 2  /* lpuart0  Receive DMA Request */
+#define S32K1XX_DMACHAN_LPUART0_TX                 3  /* lpuart0  Transmit DMA Request */
+#define S32K1XX_DMACHAN_LPUART1_RX                 4  /* lpuart1  Receive DMA Request */
+#define S32K1XX_DMACHAN_LPUART1_TX                 5  /* lpuart1  Transmit DMA Request */
+#define S32K1XX_DMACHAN_LPUART2_RX                 6  /* lpuart2  Receive DMA Request */
+#define S32K1XX_DMACHAN_LPUART2_TX                 7  /* lpuart2  Transmit DMA Request */
+#define S32K1XX_DMACHAN_FLEXIO_SHIFTER0            10 /* flexio FlexIO Shifter0 DMA Request */
+#define S32K1XX_DMACHAN_FLEXIO_SHIFTER1            11 /* flexio FlexIO Shifter1 DMA Request */
+#define S32K1XX_DMACHAN_FLEXIO_SHIFTER2            12 /* flexio / SAI1  FlexIO Shifter2 DMA Request / SAI1 DMA RX Request */
+#define S32K1XX_DMACHAN_FLEXIO_SHIFTER3            13 /* flexio / SAI1  FlexIO Shifter3 DMA Request / SAI1 DMA TX Request */
+#define S32K1XX_DMACHAN_LPSPI0_RX                  14 /* lpspi0 DMA RX Request */
+#define S32K1XX_DMACHAN_LPSPI0_TX                  15 /* lpspi0 DMA TX Request */
+#define S32K1XX_DMACHAN_LPSPI1_RX                  16 /* lpspi1 DMA RX Request */
+#define S32K1XX_DMACHAN_LPSPI1_TX                  17 /* lpspi1 DMA TX Request */
+#define S32K1XX_DMACHAN_LPSPI2_RX                  18 /* lpspi2 DMA RX Request */
+#define S32K1XX_DMACHAN_LPSPI2_TX                  19 /* lpspi2 DMA TX Request */
+#define S32K1XX_DMACHAN_FTM1_CHANNEL_0             20 /* ftm1 Channel 0 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM1_CHANNEL_1             21 /* ftm1 Channel 1 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM1_CHANNEL_2             22 /* ftm1 Channel 2 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM1_CHANNEL_3             23 /* ftm1 Channel 3 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM1_CHANNEL_4             24 /* ftm1 Channel 4 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM1_CHANNEL_5             25 /* ftm1 Channel 5 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM1_CHANNEL_6             26 /* ftm1 Channel 6 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM1_CHANNEL_7             27 /* ftm1 Channel 7 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM2_CHANNEL_0             28 /* ftm2 Channel 0 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM2_CHANNEL_1             29 /* ftm2 Channel 1 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM2_CHANNEL_2             30 /* ftm2 Channel 2 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM2_CHANNEL_3             31 /* ftm2 Channel 3 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM2_CHANNEL_4             32 /* ftm2 Channel 4 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM2_CHANNEL_5             33 /* ftm2 Channel 5 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM2_CHANNEL_6             34 /* ftm2 Channel 6 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM2_CHANNEL_7             35 /* ftm2 Channel 7 DMA transfer request */
+#define S32K1XX_DMACHAN_FTM0_OR_CH0_CH7            36 /* ftm0 'OR' of FTM0 channel 0 - 7 */
+#define S32K1XX_DMACHAN_FTM3_OR_CH0_CH7            37 /* ftm3 'OR' of FTM3 channel 0 - 7 */
+#define S32K1XX_DMACHAN_FTM4_OR_CH0_CH7            38 /* ftm4 'OR' of FTM4 channel 0 - 7 */
+#define S32K1XX_DMACHAN_FTM5_OR_CH0_CH7            39 /* ftm5 'OR' of FTM5 channel 0 - 7 */
+#define S32K1XX_DMACHAN_ADC0                       42 /* ftm6 'OR' of FTM6 channel 0 - 7 */
+#define S32K1XX_DMACHAN_ADC1                       43 /* ftm7 'OR' of FTM7 channel 0 - 7 */
+#define S32K1XX_DMACHAN_LPI2C0_RX                  44 /* lpi2c0 DMA RX Request */
+#define S32K1XX_DMACHAN_LPI2C0_TX                  45 /* lpi2c0 DMA TX Request */
+#define S32K1XX_DMACHAN_PDB0                       46 /* pdb0 DMA request */
+#define S32K1XX_DMACHAN_PDB1                       47 /* pdb1 DMA request */
+#define S32K1XX_DMACHAN_CMP0                       48 /* cmp0 DMA request */
+#define S32K1XX_DMACHAN_PORTA                      49 /* PORT PORTA DMA request */
+#define S32K1XX_DMACHAN_PORTB                      50 /* PORT PORTB DMA request */
+#define S32K1XX_DMACHAN_PORTC                      51 /* PORT PORTC DMA request */
+#define S32K1XX_DMACHAN_PORTD                      52 /* PORT PORTD DMA request */
+#define S32K1XX_DMACHAN_PORTE                      53 /* PORT PORTE DMA request */
+#define S32K1XX_DMACHAN_FLEXCAN0                   54 /* flexcan0 DMA request */
+#define S32K1XX_DMACHAN_FLEXCAN1                   55 /* flexcan1 DMA request */
+#define S32K1XX_DMACHAN_FLEXCAN2                   56 /* flexcan2 DMA request */
+#define S32K1XX_DMACHAN_LPTMR0                     59 /* lptmr0 LPTIMER DMA request */
+#define S32K1XX_DMACHAN_DMAMUX_ALWAYS_ENABLED0     62 /* Always On DMA request */
+#define S32K1XX_DMACHAN_DMAMUX_ALWAYS_ENABLED1     63 /* Always On DMA request */
+#define S32K1XX_DMACHAN_DMAMUX_ALWAYS_ENABLED1     63 /* Always On DMA request */
+#define S32K1XX_DMACHAN_DMAMUX_ALWAYS_ENABLED1     63 /* Always On DMA request */
+#define S32K1XX_DMACHAN_DMAMUX_ALWAYS_ENABLED1     63 /* Always On DMA request */
+#define S32K1XX_DMACHAN_DMAMUX_ALWAYS_ENABLED1     63 /* Always On DMA request */
+#define S32K1XX_DMACHAN_DMAMUX_ALWAYS_ENABLED1     63 /* Always On DMA request */
+
+#endif /* __ARCH_ARM_SRC_S32K1XX_HARDWARE_S32K146_DMAMUX_H */
diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h
index 23de5b8c65..315e07d88d 100644
--- a/arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h
+++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h
@@ -28,6 +28,12 @@
 #include <nuttx/config.h>
 #include <hardware/s32k1xx_memorymap.h>
 
+#if defined(CONFIG_ARCH_CHIP_S32K11X)
+#  error "Sorry no s32k11x_dmamux.h - Please author one"
+#elif defined(CONFIG_ARCH_CHIP_S32K14X)
+#  include <hardware/s32k146_dmamux.h>
+#endif
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -46,7 +52,7 @@
 
 /* DMAMUX Register Addresses ************************************************/
 
-#define S32K1XX_DMAMUX_CHCFG(n)         (S32K1XX_DMAMUX_BASE + S32K1XX_DMAMUX_CHCFG_OFFSET(n)) n=1..15 */
+#define S32K1XX_DMAMUX_CHCFG(n)         (S32K1XX_DMAMUX_BASE + S32K1XX_DMAMUX_CHCFG_OFFSET(n)) /* n=1..15 */
 
 /* DMAMUX Register Bitfield Definitions *************************************/
 


[incubator-nuttx] 01/02: s32k1xx_edma:Add Looping and cleanup

Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 3813320c31787f84a6a75884b34a7bfdf3df42c4
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Tue May 31 09:00:59 2022 -0700

    s32k1xx_edma:Add Looping and cleanup
    
    s32k1xx:EDMA Use aligned_data macros
    
    s32k1xx:EDMA CONFIG_ARCH_CHIP_S32K14x->CONFIG_ARCH_CHIP_S32K14X
    
    s32k1xx:EDMA remove FAR keyword
    
    s32k1xx:EDMA Fix C&P error from Kinetis
    
    s32k1xx:EDMA TCD Alignment of 32 Bytes to support Scatter/Gather
    
    s32k1xx:EDMA Fix access violation
    
    s32k1xx:dmamux fixed missing closing paren
---
 arch/arm/src/s32k1xx/Kconfig                      |   1 +
 arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h    |   2 +-
 arch/arm/src/s32k1xx/hardware/s32k1xx_edma.h      |   6 +-
 arch/arm/src/s32k1xx/hardware/s32k1xx_memorymap.h |   4 +-
 arch/arm/src/s32k1xx/s32k1xx_edma.c               | 233 +++++++++-------------
 arch/arm/src/s32k1xx/s32k1xx_edma.h               |  33 ++-
 6 files changed, 121 insertions(+), 158 deletions(-)

diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig
index 57ee616db5..a011e6002c 100644
--- a/arch/arm/src/s32k1xx/Kconfig
+++ b/arch/arm/src/s32k1xx/Kconfig
@@ -200,6 +200,7 @@ menu "S32K1XX Peripheral Selection"
 config S32K1XX_EDMA
 	bool "eDMA"
 	default n
+	select ARCH_DMA
 
 config S32K1XX_ENET
 	bool "Ethernet"
diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h
index 577bb2d0e8..23de5b8c65 100644
--- a/arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h
+++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_dmamux.h
@@ -36,7 +36,7 @@
 
 #if defined(CONFIG_ARCH_CHIP_S32K11X)
 #  define S32K1XX_NDMACH  4
-#elif defined(CONFIG_ARCH_CHIP_S32K14X
+#elif defined(CONFIG_ARCH_CHIP_S32K14X)
 #  define S32K1XX_NDMACH  16
 #endif
 
diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_edma.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_edma.h
index 1d8604584c..ff9bad7d4f 100644
--- a/arch/arm/src/s32k1xx/hardware/s32k1xx_edma.h
+++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_edma.h
@@ -34,7 +34,7 @@
 
 #if defined(CONFIG_ARCH_CHIP_S32K11X)
 #  define S32K1XX_EDMA_NCHANNELS              4
-#elif defined(CONFIG_ARCH_CHIP_S32K14x)
+#elif defined(CONFIG_ARCH_CHIP_S32K14X)
 #  define S32K1XX_EDMA_NCHANNELS              16
 #else
 #  error "Unknown number of DMA channels for this S32K1xx part"
@@ -837,8 +837,8 @@
  * Public Types
  ****************************************************************************/
 
-/* In-memory representation of the 32-byte Transfer Control Descriptor
- * (TCD)
+/* Hardware representation of the 32-byte Transfer
+ * Control Descriptor (TCD)
  */
 
 struct s32k1xx_edmatcd_s
diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_memorymap.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_memorymap.h
index dc7e6f5b62..e12dec7a5a 100644
--- a/arch/arm/src/s32k1xx/hardware/s32k1xx_memorymap.h
+++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_memorymap.h
@@ -34,8 +34,8 @@
 #define S32K1XX_AIPS_LITE_BASE   0x40000000  /* Peripheral bridge (AIPS-Lite) */
 #  define S32K1XX_FLASHCFG_BASE  0x40000400  /* FLASH Configuration bytes */
 #  define S32K1XX_MSCM_BASE      0x40001000  /* MSCM */
-#  define S32K1XX_DMAC_BASE      0x40008000  /* DMA controller */
-#  define S32K1XX_DMADESC_BASE   0x40008000  /* DMA transfer control descriptors */
+#  define S32K1XX_EDMA_BASE      0x40008000  /* EDMA controller */
+#  define S32K1XX_EDMADESC_BASE  0x40008000  /* EDMA transfer control descriptors */
 #  define S32K1XX_MPU_BASE       0x4000d000  /* MPU */
 #  define S32K1XX_GPIOCTL_BASE   0x4000f000  /* GPIO controller */
 #  define S32K1XX_GPIOALIAS_BASE 0x400ff000  /* GPIO controller (alias) */
diff --git a/arch/arm/src/s32k1xx/s32k1xx_edma.c b/arch/arm/src/s32k1xx/s32k1xx_edma.c
index 1236b5fd9a..e0b0493ef3 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_edma.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_edma.c
@@ -86,22 +86,16 @@
  */
 
 #ifdef CONFIG_ARMV7M_DCACHE
-/* Align to the cache line size which we assume is >= 8 */
-
-#  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)
-
+#  define EDMA_ALIGN  ARMV7M_DCACHE_LINESIZE
 #else
-/* Special alignment is not required in this case,
- * but we will align to 8-bytes
- */
+/* 32 byte alignment for TCDs is required for scatter gather */
 
-#  define EDMA_ALIGN        8
-#  define EDMA_ALIGN_MASK   7
-#  define EDMA_ALIGN_UP(n)  (((n) + 7) & ~7)
+#define EDMA_ALIGN        32
 #endif
 
+#define EDMA_ALIGN_MASK   (EDMA_ALIGN - 1)
+#define EDMA_ALIGN_UP(n)  (((n) + EDMA_ALIGN_MASK) & ~EDMA_ALIGN_MASK)
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -119,10 +113,10 @@ enum s32k1xx_dmastate_e
 
 struct s32k1xx_dmach_s
 {
-  uint8_t chan;                   /* DMA channel number (0-S32K1XX_EDMA_NCHANNELS) */
-  bool inuse;                     /* true: The DMA channel is in use */
-  uint8_t ttype;                  /* Transfer type: M2M, M2P, P2M, or P2P */
-  uint8_t state;                  /* Channel state.  See enum s32k1xx_dmastate_e */
+  uint8_t  chan;                  /* DMA channel number (0-S32K1XX_EDMA_NCHANNELS) */
+  bool     inuse;                 /* true: The DMA channel is in use */
+  uint8_t  state;                 /* Channel state.  See enum s32k1xx_dmastate_e */
+  uint8_t  dmamux;                /* The DMAMUX channel selection */
   uint32_t flags;                 /* DMA channel flags */
   edma_callback_t callback;       /* Callback invoked when the DMA completes */
   void *arg;                      /* Argument passed to callback function */
@@ -338,18 +332,13 @@ static inline void s32k1xx_tcd_chanlink(uint8_t flags,
 
   if (linkch == NULL || flags == EDMA_CONFIG_LINKTYPE_LINKNONE)
     {
-#if 0 /* Already done */
       /* No link or no link channel provided */
 
-      /* Disable minor links */
-
-      tcd->citer &= ~EDMA_TCD_CITER_ELINK;
-      tcd->biter &= ~EDMA_TCD_BITER_ELINK;
+      /* Disable minor links is done in s32k1xx_tcd_configure */
 
       /* Disable major link */
 
       tcd->csr   &= ~EDMA_TCD_CSR_MAJORELINK;
-#endif
     }
   else if (flags == EDMA_CONFIG_LINKTYPE_MINORLINK) /* Minor link config */
     {
@@ -405,13 +394,16 @@ static inline void s32k1xx_tcd_configure(struct s32k1xx_edmatcd_s *tcd,
   tcd->attr     = EDMA_TCD_ATTR_SSIZE(config->ssize) |  /* Transfer Attributes */
                   EDMA_TCD_ATTR_DSIZE(config->dsize);
   tcd->nbytes   = config->nbytes;
-  tcd->slast    = tcd->slast;
+  tcd->slast    = config->flags & EDMA_CONFIG_LOOPSRC ?  -config->iter : 0;
   tcd->daddr    = config->daddr;
   tcd->doff     = config->doff;
   tcd->citer    = config->iter & EDMA_TCD_CITER_CITER_MASK;
   tcd->biter    = config->iter & EDMA_TCD_BITER_BITER_MASK;
-  tcd->csr      = EDMA_TCD_CSR_DREQ; /* Assume last transfer */
-  tcd->dlastsga = 0;
+  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 : 0;
 
   /* And special case flags */
 
@@ -440,6 +432,10 @@ static void s32k1xx_tcd_instantiate(struct s32k1xx_dmach_s *dmach,
 
   /* Push tcd into hardware TCD register */
 
+  /* Clear DONE bit first, otherwise ESG cannot be set */
+
+  putreg16(0,             base + S32K1XX_EDMA_TCD_CSR_OFFSET);
+
   putreg32(tcd->saddr,    base + S32K1XX_EDMA_TCD_SADDR_OFFSET);
   putreg16(tcd->soff,     base + S32K1XX_EDMA_TCD_SOFF_OFFSET);
   putreg16(tcd->attr,     base + S32K1XX_EDMA_TCD_ATTR_OFFSET);
@@ -450,9 +446,6 @@ static void s32k1xx_tcd_instantiate(struct s32k1xx_dmach_s *dmach,
   putreg16(tcd->citer,    base + S32K1XX_EDMA_TCD_CITER_ELINK_OFFSET);
   putreg32(tcd->dlastsga, base + S32K1XX_EDMA_TCD_DLASTSGA_OFFSET);
 
-  /* Clear DONE bit first, otherwise ESG cannot be set */
-
-  putreg16(0,             base + S32K1XX_EDMA_TCD_CSR_OFFSET);
   putreg16(tcd->csr,      base + S32K1XX_EDMA_TCD_CSR_OFFSET);
 
   putreg16(tcd->biter,    base + S32K1XX_EDMA_TCD_BITER_ELINK_OFFSET);
@@ -488,25 +481,25 @@ static void s32k1xx_dmaterminate(struct s32k1xx_dmach_s *dmach, int result)
   regval8         = EDMA_CERQ(chan);
   putreg8(regval8, S32K1XX_EDMA_CERQ);
 
-  /* 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.
-   */
-
   regaddr         = S32K1XX_EDMA_TCD_CSR(chan);
   putreg16(0, regaddr);
 
   /* Cancel next TCD transfer. */
 
   regaddr         = S32K1XX_EDMA_TCD_DLASTSGA(chan);
-  putreg16(0, regaddr);
+  putreg32(0, regaddr);
 
 #if CONFIG_S32K1XX_EDMA_NTCD > 0
   /* Return all allocated TCDs to the free list */
 
   for (tcd = dmach->head; tcd != NULL; tcd = next)
     {
-      next = (struct s32k1xx_edmatcd_s *)tcd->dlastsga;
+      /* If channel looped to itself we are done
+       * if not continue to free tcds in chain
+       */
+
+       next = dmach->flags & EDMA_CONFIG_LOOPDEST ?
+              NULL : (struct s32k1xx_edmatcd_s *)tcd->dlastsga;
       s32k1xx_tcd_free(tcd);
     }
 
@@ -514,15 +507,6 @@ static void s32k1xx_dmaterminate(struct s32k1xx_dmach_s *dmach, int result)
   dmach->tail = NULL;
 #endif
 
-  /* Check for an Rx (memory-to-peripheral/memory-to-memory) DMA transfer */
-
-  if (dmach->ttype == EMDA_MEM2MEM || dmach->ttype == EMDA_PERIPH2MEM)
-    {
-      /* Invalidate the cache to force reloads from memory. */
-
-#warning Missing logic
-    }
-
   /* Perform the DMA complete callback */
 
   if (dmach->callback)
@@ -556,13 +540,13 @@ static int s32k1xx_edma_interrupt(int irq, void *context, void *arg)
 {
   struct s32k1xx_dmach_s *dmach;
   uintptr_t regaddr;
-  uint32_t regval32;
-  uint16_t regval16;
-  uint8_t regval8;
-  uint8_t chan;
-  int result;
+  uint32_t  regval32;
+  uint16_t  regval16;
+  uint8_t   regval8;
+  uint8_t   chan;
+  int       result;
 
-  /* 'arg' should the DMA channel instance. */
+  /* 'arg' should be the DMA channel instance. */
 
   dmach = (struct s32k1xx_dmach_s *)arg;
   DEBUGASSERT(dmach != NULL);
@@ -584,7 +568,7 @@ static int s32k1xx_edma_interrupt(int irq, void *context, void *arg)
       /* Clear the pending eDMA channel interrupt */
 
       regval8 = EDMA_CINT(chan);
-      putreg32(regval8, S32K1XX_EDMA_CINT);
+      putreg8(regval8, S32K1XX_EDMA_CINT);
 
       /* Get the eDMA TCD Control and Status register value. */
 
@@ -604,7 +588,7 @@ static int s32k1xx_edma_interrupt(int irq, void *context, void *arg)
       else
         {
 #if CONFIG_S32K1XX_EDMA_NTCD > 0
-          /* Perform the end-of-major-cycle DMA callback */
+          /* Perform the half or end-of-major-cycle DMA callback */
 
           if (dmach->callback != NULL)
             {
@@ -612,7 +596,7 @@ static int s32k1xx_edma_interrupt(int irq, void *context, void *arg)
                               false, OK);
             }
 
-          return;
+          return OK;
 #else
           /* Otherwise the interrupt was not expected! */
 
@@ -623,8 +607,18 @@ static int s32k1xx_edma_interrupt(int irq, void *context, void *arg)
 
       /* Terminate the transfer when it is done. */
 
-      s32k1xx_dmaterminate(dmach, result);
+      if ((dmach->flags & EDMA_CONFIG_LOOP_MASK) == 0)
+        {
+          s32k1xx_dmaterminate(dmach, result);
+        }
+      else if (dmach->callback != NULL)
+        {
+          dmach->callback((DMACH_HANDLE)dmach, dmach->arg,
+                          true, result);
+        }
     }
+
+  return OK;
 }
 
 /****************************************************************************
@@ -661,7 +655,7 @@ static int s32k1xx_error_interrupt(int irq, void *context, void *arg)
           /* Clear the pending error interrupt status. */
 
           regval8 = EDMA_CERR(chan);
-          putreg32(regval8, S32K1XX_EDMA_CERR);
+          putreg8(regval8, S32K1XX_EDMA_CERR);
 
           /* Remove the bit from the sample ERR register so that perhaps we
            * can exit this loop early.
@@ -755,24 +749,12 @@ void weak_function arm_dma_initialize(void)
 
   /* Attach DMA interrupt vectors. */
 
-  irq_attach(S32K1XX_IRQ_DMACH0,  s32k1xx_edma_interrupt, &g_edma.dmach[0]);
-  irq_attach(S32K1XX_IRQ_DMACH1,  s32k1xx_edma_interrupt, &g_edma.dmach[1]);
-  irq_attach(S32K1XX_IRQ_DMACH2,  s32k1xx_edma_interrupt, &g_edma.dmach[2]);
-  irq_attach(S32K1XX_IRQ_DMACH3,  s32k1xx_edma_interrupt, &g_edma.dmach[3]);
-#if S32K1XX_EDMA_NCHANNELS > 4
-  irq_attach(S32K1XX_IRQ_DMACH4,  s32k1xx_edma_interrupt, &g_edma.dmach[4]);
-  irq_attach(S32K1XX_IRQ_DMACH5,  s32k1xx_edma_interrupt, &g_edma.dmach[5]);
-  irq_attach(S32K1XX_IRQ_DMACH6,  s32k1xx_edma_interrupt, &g_edma.dmach[6]);
-  irq_attach(S32K1XX_IRQ_DMACH7,  s32k1xx_edma_interrupt, &g_edma.dmach[7]);
-  irq_attach(S32K1XX_IRQ_DMACH8,  s32k1xx_edma_interrupt, &g_edma.dmach[8]);
-  irq_attach(S32K1XX_IRQ_DMACH9,  s32k1xx_edma_interrupt, &g_edma.dmach[9]);
-  irq_attach(S32K1XX_IRQ_DMACH10, s32k1xx_edma_interrupt, &g_edma.dmach[10]);
-  irq_attach(S32K1XX_IRQ_DMACH11, s32k1xx_edma_interrupt, &g_edma.dmach[11]);
-  irq_attach(S32K1XX_IRQ_DMACH12, s32k1xx_edma_interrupt, &g_edma.dmach[12]);
-  irq_attach(S32K1XX_IRQ_DMACH13, s32k1xx_edma_interrupt, &g_edma.dmach[13]);
-  irq_attach(S32K1XX_IRQ_DMACH14, s32k1xx_edma_interrupt, &g_edma.dmach[14]);
-  irq_attach(S32K1XX_IRQ_DMACH15, s32k1xx_edma_interrupt, &g_edma.dmach[15]);
-#endif
+  for (i = 0; i < S32K1XX_EDMA_NCHANNELS; i++)
+    {
+      irq_attach(S32K1XX_IRQ_DMACH0 + i,
+                 s32k1xx_edma_interrupt, &g_edma.dmach[i]);
+    }
+
   /* Attach the DMA error interrupt vector */
 
   irq_attach(S32K1XX_IRQ_DMACH_ERR, s32k1xx_error_interrupt, NULL);
@@ -790,6 +772,14 @@ void weak_function arm_dma_initialize(void)
 
       regaddr = S32K1XX_EDMA_TCD_CSR(i);
       putreg16(0, regaddr);
+
+      /* Set all TCD entries to 0 so that biter and citer
+       * will be 0 when DONE is not set so that s32k1xx_dmach_getcount
+       * reports 0.
+       */
+
+      memset((void *)S32K1XX_EDMA_TCD_BASE(i), 0,
+             sizeof(struct s32k1xx_edmatcd_s));
     }
 
   /* Clear all pending DMA channel interrupts */
@@ -800,24 +790,10 @@ void weak_function arm_dma_initialize(void)
    * controller).
    */
 
-  up_enable_irq(S32K1XX_IRQ_DMACH0);
-  up_enable_irq(S32K1XX_IRQ_DMACH1);
-  up_enable_irq(S32K1XX_IRQ_DMACH2);
-  up_enable_irq(S32K1XX_IRQ_DMACH3);
-#if S32K1XX_EDMA_NCHANNELS > 4
-  up_enable_irq(S32K1XX_IRQ_DMACH4);
-  up_enable_irq(S32K1XX_IRQ_DMACH5);
-  up_enable_irq(S32K1XX_IRQ_DMACH6);
-  up_enable_irq(S32K1XX_IRQ_DMACH7);
-  up_enable_irq(S32K1XX_IRQ_DMACH8);
-  up_enable_irq(S32K1XX_IRQ_DMACH9);
-  up_enable_irq(S32K1XX_IRQ_DMACH10);
-  up_enable_irq(S32K1XX_IRQ_DMACH11);
-  up_enable_irq(S32K1XX_IRQ_DMACH12);
-  up_enable_irq(S32K1XX_IRQ_DMACH13);
-  up_enable_irq(S32K1XX_IRQ_DMACH14);
-  up_enable_irq(S32K1XX_IRQ_DMACH15);
-#endif
+  for (i = 0; i < S32K1XX_EDMA_NCHANNELS; i++)
+    {
+      up_enable_irq(S32K1XX_IRQ_DMACH0 + i);
+    }
 
   /* Enable the DMA error interrupt */
 
@@ -837,7 +813,6 @@ void weak_function arm_dma_initialize(void)
  *            Settings include:
  *
  *            DMAMUX_CHCFG_SOURCE     Chip-specific DMA source (required)
- *            DMAMUX_CHCFG_AON        DMA Channel Always Enable (optional)
  *            DMAMUX_CHCFG_TRIG       DMA Channel Trigger Enable (optional)
  *            DMAMUX_CHCFG_ENBL       DMA Mux Channel Enable (required)
  *
@@ -858,7 +833,7 @@ void weak_function arm_dma_initialize(void)
  *
  ****************************************************************************/
 
-DMACH_HANDLE s32k1xx_dmach_alloc(uint32_t dmamux, uint8_t dchpri)
+DMACH_HANDLE s32k1xx_dmach_alloc(uint8_t dmamux, uint8_t dchpri)
 {
   struct s32k1xx_dmach_s *dmach;
   unsigned int chndx;
@@ -884,6 +859,7 @@ DMACH_HANDLE s32k1xx_dmach_alloc(uint32_t dmamux, uint8_t dchpri)
           dmach        = candidate;
           dmach->inuse = true;
           dmach->state = S32K1XX_DMA_IDLE;
+          dmach->dmamux = dmamux;
 
           /* Clear any pending interrupts on the channel */
 
@@ -896,10 +872,9 @@ DMACH_HANDLE s32k1xx_dmach_alloc(uint32_t dmamux, uint8_t dchpri)
           regval8 = EDMA_CERQ(chndx);
           putreg8(regval8, S32K1XX_EDMA_CERQ);
 
-          /* Set the DMAMUX register associated with this channel */
+          /* Disable the associated DMAMUX for now */
 
-          regaddr = S32K1XX_DMAMUX_CHCFG(chndx);
-          putreg32(dmamux, regaddr);
+          putreg8(0, S32K1XX_DMAMUX_CHCFG(chndx));
           break;
         }
     }
@@ -936,7 +911,6 @@ DMACH_HANDLE s32k1xx_dmach_alloc(uint32_t dmamux, uint8_t dchpri)
 void s32k1xx_dmach_free(DMACH_HANDLE handle)
 {
   struct s32k1xx_dmach_s *dmach = (struct s32k1xx_dmach_s *)handle;
-  uintptr_t regaddr;
   uint8_t regval8;
 
   dmainfo("dmach: %p\n", dmach);
@@ -958,8 +932,7 @@ void s32k1xx_dmach_free(DMACH_HANDLE handle)
 
   /* Disable the associated DMAMUX */
 
-  regaddr = S32K1XX_DMAMUX_CHCFG(dmach->chan);
-  putreg32(0, regaddr);
+  putreg8(0, S32K1XX_DMAMUX_CHCFG(dmach->chan));
 }
 
 /****************************************************************************
@@ -995,12 +968,16 @@ int s32k1xx_dmach_xfrsetup(DMACH_HANDLE *handle,
 #if CONFIG_S32K1XX_EDMA_NTCD > 0
   struct s32k1xx_edmatcd_s *tcd;
   struct s32k1xx_edmatcd_s *prev;
+  uint16_t mask = config->flags & EDMA_CONFIG_INTMAJOR ? 0 :
+                                  EDMA_TCD_CSR_INTMAJOR;
 #endif
   uintptr_t regaddr;
   uint16_t regval16;
 
   DEBUGASSERT(dmach != NULL);
-  dmainfo("dmach%u: %p config: %p\n", dmach, config);
+  dmainfo("dmach%u: %p config: %p\n", dmach->chan, dmach, config);
+
+  dmach->flags  = config->flags;
 
 #if CONFIG_S32K1XX_EDMA_NTCD > 0
   /* Scatter/gather DMA is supported */
@@ -1029,7 +1006,6 @@ int s32k1xx_dmach_xfrsetup(DMACH_HANDLE *handle,
 
       dmach->head  = tcd;
       dmach->tail  = tcd;
-      dmach->ttype = config->ttype;
 
       /* And instantiate the first TCD in the DMA channel TCD registers. */
 
@@ -1037,11 +1013,9 @@ int s32k1xx_dmach_xfrsetup(DMACH_HANDLE *handle,
     }
   else
     {
-      /* Cannot mix transfer types (only because of cache-related operations.
-       * this restriction could be removed with some effort).
-       */
+      /* Cannot mix transfer types */
 
-      if (dmach->ttype != config->ttype)
+      if (dmach->flags & EDMA_CONFIG_LOOP_MASK)
         {
           s32k1xx_tcd_free(tcd);
           return -EINVAL;
@@ -1053,8 +1027,9 @@ int s32k1xx_dmach_xfrsetup(DMACH_HANDLE *handle,
 
       prev           = dmach->tail;
       regval16       = prev->csr;
-      regval16      &= ~EDMA_TCD_CSR_DREQ;
+      regval16      &= ~(EDMA_TCD_CSR_DREQ | mask);
       regval16      |= EDMA_TCD_CSR_ESG;
+
       prev->csr      = regval16;
 
       prev->dlastsga = (uint32_t)tcd;
@@ -1076,7 +1051,7 @@ int s32k1xx_dmach_xfrsetup(DMACH_HANDLE *handle,
 
           regaddr   = S32K1XX_EDMA_TCD_CSR(dmach->chan);
           regval16  = getreg16(regaddr);
-          regval16 &= ~EDMA_TCD_CSR_DREQ;
+          regval16 &= ~(EDMA_TCD_CSR_DREQ | mask);
           regval16 |= EDMA_TCD_CSR_ESG;
           putreg16(regval16, regaddr);
 
@@ -1115,34 +1090,9 @@ int s32k1xx_dmach_xfrsetup(DMACH_HANDLE *handle,
   modifyreg16(regaddr, 0, EDMA_TCD_CSR_INTMAJOR);
 #endif
 
-  /* Check for an Rx (memory-to-peripheral/memory-to-memory) DMA transfer */
+  /* Set the DMAMUX source and enable and optional trigger */
 
-  if (dmach->ttype == EMDA_MEM2MEM || dmach->ttype == EMDA_PERIPH2MEM)
-    {
-      /* Invalidate caches associated with the destination DMA memory.
-       * REVISIT:  nbytes is the number of bytes transferred on each
-       * minor loop.  The following is only valid when the major loop
-       * is one.
-       */
-
-      up_invalidate_dcache((uintptr_t)config->daddr,
-                           (uintptr_t)config->daddr + config->nbytes);
-    }
-
-  /* Check for an Tx (peripheral-to-memory/memory-to-memory) DMA transfer */
-
-  if (dmach->ttype == EMDA_MEM2MEM || dmach->ttype == EMDA_MEM2PERIPH)
-    {
-      /* Clean caches associated with the source DMA memory.
-       * REVISIT:  nbytes is the number of bytes transferred on each
-       * minor loop.  The following is only valid when the major loop
-       * is one.
-       */
-#warning Missing logic
-
-      up_clean_dcache((uintptr_t)config->saddr,
-                      (uintptr_t)config->saddr + config->nbytes);
-    }
+  putreg8(dmach->dmamux, S32K1XX_DMAMUX_CHCFG(dmach->chan));
 
   dmach->state = S32K1XX_DMA_CONFIGURED;
   return OK;
@@ -1155,10 +1105,10 @@ int s32k1xx_dmach_xfrsetup(DMACH_HANDLE *handle,
  *   Start the DMA transfer.  This function should be called after the final
  *   call to s32k1xx_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, multiple interrupts
- *   will be generated with the final being the DONE interrupt.
+ *   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
@@ -1191,14 +1141,13 @@ int s32k1xx_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
 
   DEBUGASSERT(dmach != NULL && dmach->state == S32K1XX_DMA_CONFIGURED);
   chan            = dmach->chan;
-  dmainfo("dmach%u: %p callback: %p arg: %p\n", dmach, chan, callback, arg);
+  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(NULL);
   dmach->callback = callback;
   dmach->arg      = arg;
-  dmach->state    = S32K1XX_DMA_ACTIVE;
 
 #if CONFIG_S32K1XX_EDMA_NTCD > 0
   /* Although it is not recommended, it might be possible to call this
@@ -1208,6 +1157,8 @@ int s32k1xx_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
   if (dmach->state != S32K1XX_DMA_ACTIVE)
 #endif
     {
+      dmach->state    = S32K1XX_DMA_ACTIVE;
+
       /* Enable channel ERROR interrupts */
 
       regval8         = EDMA_SEEI(chan);
@@ -1216,7 +1167,7 @@ int s32k1xx_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
       /* Enable the DMA request for this channel */
 
       regval8         = EDMA_SERQ(chan);
-      putreg8(regval8, S32K1XX_EDMA_SERQ_OFFSET);
+      putreg8(regval8, S32K1XX_EDMA_SERQ);
     }
 
   spin_unlock_irqrestore(NULL, flags);
diff --git a/arch/arm/src/s32k1xx/s32k1xx_edma.h b/arch/arm/src/s32k1xx/s32k1xx_edma.h
index cd29a6d4e2..ac85a0a03f 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_edma.h
+++ b/arch/arm/src/s32k1xx/s32k1xx_edma.h
@@ -122,6 +122,18 @@
 #  define EDMA_CONFIG_LINKTYPE_MINORLINK (1 << EDMA_CONFIG_LINKTYPE_SHIFT) /* Channel link after each minor loop */
 #  define EDMA_CONFIG_LINKTYPE_MAJORLINK (2 << EDMA_CONFIG_LINKTYPE_SHIFT) /* Channel link when major loop count exhausted */
 
+#define EDMA_CONFIG_LOOP_SHIFT           (2) /* Bits 2-3: Loop type */
+#define EDMA_CONFIG_LOOP_MASK            (3 << EDMA_CONFIG_LOOP_SHIFT)
+#  define EDMA_CONFIG_LOOPNONE           (0 << EDMA_CONFIG_LOOP_SHIFT) /* No looping */
+#  define EDMA_CONFIG_LOOPSRC            (1 << EDMA_CONFIG_LOOP_SHIFT) /* Source looping */
+#  define EDMA_CONFIG_LOOPDEST           (2 << EDMA_CONFIG_LOOP_SHIFT) /* Dest looping */
+
+#define EDMA_CONFIG_INTHALF              (1 << 4) /* Bits 4: Int on HALF */
+#define EDMA_CONFIG_INTMAJOR             (1 << 5) /* Bits 5: Int on all Major completion
+                                                   * Default is only on last completion
+                                                   * if using scatter gather
+                                                   */
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
@@ -130,19 +142,19 @@ typedef void *DMACH_HANDLE;
 typedef void (*edma_callback_t)(DMACH_HANDLE handle,
                                 void *arg, bool done, int result);
 
-/* eDMA transfer type */
-
-enum s32k1xx_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 */
-};
-
 /* This structure holds the source/destination transfer attribute
  * configuration.
  */
 
+/* eDMA transfer sizes */
+
+enum s32k1xx_edma_sizes_e
+{
+  EDMA_8BIT    = 0,      /* Transfer data size 8 */
+  EDMA_16BIT   = 1,      /* Transfer data size 16 */
+  EDMA_32BIT   = 2,      /* Transfer data size 32 */
+};
+
 struct s32k1xx_edma_xfrconfig_s
 {
     uint32_t saddr;      /* Source data address. */
@@ -153,7 +165,6 @@ struct s32k1xx_edma_xfrconfig_s
     uint8_t  flags;      /* See EDMA_CONFIG_* definitions */
     uint8_t  ssize;      /* Source data transfer size (see TCD_ATTR_SIZE_* definitions in rdware/. */
     uint8_t  dsize;      /* Destination data transfer size. */
-    uint8_t  ttype;      /* Transfer type (see enum s32k1xx_edma_xfrtype_e). */
 #ifdef CONFIG_S32K1XX_EDMA_EMLIM
     uint16_t nbytes;     /* Bytes to transfer in a minor loop */
 #else
@@ -264,7 +275,7 @@ extern "C"
  *
  ****************************************************************************/
 
-DMACH_HANDLE s32k1xx_dmach_alloc(uint32_t dmamux, uint8_t dchpri);
+DMACH_HANDLE s32k1xx_dmach_alloc(uint8_t dmamux, uint8_t dchpri);
 
 /****************************************************************************
  * Name: s32k1xx_dmach_free