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