Skip to content

Commit 25830ab

Browse files
yongxu-wang15abhinavnxp
authored andcommitted
drivers: dma: Update NXP EDMA driver for version 5
1. The edma version 5 share one driver with edma 4. 2. Edma5 tcd structure some difference, Use tcd type to distinguish, and Edma5 uses 64 bytes for alignment instead of 32. 3. Some platforms have some address offsets for certain memory when processing from a DMA perspective, such as imx95 cm7 TCM, so add offset processing. Signed-off-by: Yongxu Wang <yongxu.wang@nxp.com>
1 parent 99405ef commit 25830ab

File tree

6 files changed

+96
-28
lines changed

6 files changed

+96
-28
lines changed

drivers/dma/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE dma_handlers.c)
1717
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA dma_mcux_edma.c)
1818
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA_V3 dma_mcux_edma.c)
1919
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA_V4 dma_mcux_edma.c)
20+
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA_V5 dma_mcux_edma.c)
2021
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_LPC dma_mcux_lpc.c)
2122
zephyr_library_sources_ifdef(CONFIG_DMA_PL330 dma_pl330.c)
2223
zephyr_library_sources_ifdef(CONFIG_DMA_IPROC_PAX dma_iproc_pax_v1.c)

drivers/dma/Kconfig.mcux_edma

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@ config DMA_MCUX_EDMA_V4
2828
help
2929
DMA version 4 driver for MCUX series SoCs.
3030

31-
if DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4
31+
config DMA_MCUX_EDMA_V5
32+
bool "MCUX DMA v5 driver"
33+
default y
34+
depends on $(dt_compat_any_has_prop,$(EDMA_COMPAT),$(REV_PROP),5)
35+
help
36+
DMA version 5 driver for MCUX series SoCs.
37+
38+
if DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4 || DMA_MCUX_EDMA_V5
3239

3340
config DMA_TCD_QUEUE_SIZE
3441
int "number of TCD in a queue for SG mode"
@@ -55,4 +62,4 @@ config DMA_MCUX_USE_DTCM_FOR_DMA_DESCRIPTORS
5562
When this option is activated, the descriptors for DMA transfer are
5663
located in the DTCM (Data Tightly Coupled Memory).
5764

58-
endif # DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4
65+
endif # DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4 || DMA_MCUX_EDMA_V5

drivers/dma/dma_mcux_edma.c

Lines changed: 81 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,14 @@ LOG_MODULE_REGISTER(dma_mcux_edma, CONFIG_DMA_LOG_LEVEL);
3030
#define HAS_CHANNEL_GAP(n) DT_INST_NODE_HAS_PROP(n, channel_gap) ||
3131
#define DMA_MCUX_HAS_CHANNEL_GAP (DT_INST_FOREACH_STATUS_OKAY(HAS_CHANNEL_GAP) 0)
3232

33+
#if defined(CONFIG_DMA_MCUX_EDMA_V5)
34+
typedef DMA5_Type DMAx_Type;
35+
#else
36+
typedef DMA_Type DMAx_Type;
37+
#endif
38+
3339
struct dma_mcux_edma_config {
34-
DMA_Type *base;
40+
DMAx_Type *base;
3541
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
3642
DMAMUX_Type **dmamux_base;
3743
#endif
@@ -116,7 +122,7 @@ struct dma_mcux_edma_data {
116122
#define DEV_CFG(dev) \
117123
((const struct dma_mcux_edma_config *const)dev->config)
118124
#define DEV_DATA(dev) ((struct dma_mcux_edma_data *)dev->data)
119-
#define DEV_BASE(dev) ((DMA_Type *)DEV_CFG(dev)->base)
125+
#define DEV_BASE(dev) ((DMAx_Type *)DEV_CFG(dev)->base)
120126

121127
#define DEV_CHANNEL_DATA(dev, ch) \
122128
((struct call_back *)(&(DEV_DATA(dev)->data_cb[ch])))
@@ -146,13 +152,13 @@ struct dma_mcux_edma_data {
146152
#else
147153
#define EDMA_HW_TCD_CH_ACTIVE_MASK (DMA_CSR_ACTIVE_MASK)
148154
#endif /* CONFIG_DMA_MCUX_EDMA_V3 */
149-
#elif defined(CONFIG_DMA_MCUX_EDMA_V4)
155+
#elif defined(CONFIG_DMA_MCUX_EDMA_V4) || defined(CONFIG_DMA_MCUX_EDMA_V5)
150156
/* Above macros have been defined in fsl_edma_core.h */
151157
#define EDMA_HW_TCD_CH_ACTIVE_MASK (DMA_CH_CSR_ACTIVE_MASK)
152158
#endif
153159

154160
/* Definations for HW TCD fields */
155-
#ifdef CONFIG_DMA_MCUX_EDMA
161+
#if defined(CONFIG_DMA_MCUX_EDMA) || defined(CONFIG_DMA_MCUX_EDMA_V5)
156162
#define EDMA_HW_TCD_SADDR(dev, ch) (DEV_BASE(dev)->TCD[ch].SADDR)
157163
#define EDMA_HW_TCD_DADDR(dev, ch) (DEV_BASE(dev)->TCD[ch].DADDR)
158164
#define EDMA_HW_TCD_BITER(dev, ch) (DEV_BASE(dev)->TCD[ch].BITER_ELINKNO)
@@ -203,7 +209,8 @@ static bool data_size_valid(const size_t data_size)
203209
return (data_size == 4U || data_size == 2U ||
204210
data_size == 1U || data_size == 8U ||
205211
data_size == 16U || data_size == 32U
206-
#if defined(CONFIG_DMA_MCUX_EDMA_V3) || defined(CONFIG_DMA_MCUX_EDMA_V4)
212+
#if defined(CONFIG_DMA_MCUX_EDMA_V3) || defined(CONFIG_DMA_MCUX_EDMA_V4) \
213+
|| defined(CONFIG_DMA_MCUX_EDMA_V5)
207214
|| data_size == 64U
208215
#endif
209216
);
@@ -440,32 +447,57 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
440447

441448
/* Init all TCDs with the para in transfer config and link them. */
442449
for (int i = 0; i < CONFIG_DMA_TCD_QUEUE_SIZE; i++) {
443-
EDMA_TcdSetTransferConfig(
450+
#if defined(CONFIG_DMA_MCUX_EDMA_V5)
451+
EDMA_TcdSetTransferConfigExt(DEV_BASE(dev),
444452
&DEV_CFG(dev)->tcdpool[channel][i], &data->transferConfig,
445453
&DEV_CFG(dev)->tcdpool[channel][(i + 1) %
446-
CONFIG_DMA_TCD_QUEUE_SIZE]);
447-
454+
CONFIG_DMA_TCD_QUEUE_SIZE]);
448455
/* Enable Major loop interrupt.*/
456+
EDMA_TcdEnableInterruptsExt(DEV_BASE(dev),
457+
&DEV_CFG(dev)->tcdpool[channel][i],
458+
kEDMA_MajorInterruptEnable);
459+
#else
460+
EDMA_TcdSetTransferConfig(&DEV_CFG(dev)->tcdpool[channel][i],
461+
&data->transferConfig,
462+
&DEV_CFG(dev)->tcdpool[channel][(i + 1) %
463+
CONFIG_DMA_TCD_QUEUE_SIZE]);
449464
EDMA_TcdEnableInterrupts(&DEV_CFG(dev)->tcdpool[channel][i],
450-
kEDMA_MajorInterruptEnable);
465+
kEDMA_MajorInterruptEnable);
466+
#endif
451467
}
452468

453469
/* Load valid transfer parameters */
454470
while (block_config != NULL && data->transfer_settings.empty_tcds > 0) {
455471
tcd = &(DEV_CFG(dev)->tcdpool[channel]
456472
[data->transfer_settings.write_idx]);
457473

458-
EDMA_TCD_SADDR(tcd, kEDMA_EDMA4Flag) = block_config->source_address;
459-
EDMA_TCD_DADDR(tcd, kEDMA_EDMA4Flag) = block_config->dest_address;
460-
EDMA_TCD_BITER(tcd, kEDMA_EDMA4Flag) =
474+
#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
475+
EDMA_TCD_SADDR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) =
476+
MEMORY_ConvertMemoryMapAddress(
477+
(uint32_t)(block_config->source_address),
478+
kMEMORY_Local2DMA);
479+
EDMA_TCD_DADDR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) =
480+
MEMORY_ConvertMemoryMapAddress(
481+
(uint32_t)(block_config->dest_address),
482+
kMEMORY_Local2DMA);
483+
#else
484+
485+
EDMA_TCD_SADDR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) =
486+
block_config->source_address;
487+
EDMA_TCD_DADDR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) =
488+
block_config->dest_address;
489+
#endif
490+
EDMA_TCD_BITER(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) =
461491
block_config->block_size / config->source_data_size;
462-
EDMA_TCD_CITER(tcd, kEDMA_EDMA4Flag) =
492+
EDMA_TCD_CITER(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) =
463493
block_config->block_size / config->source_data_size;
464494
/*Enable auto stop for last transfer.*/
465495
if (block_config->next_block == NULL) {
466-
EDMA_TCD_CSR(tcd, kEDMA_EDMA4Flag) |= DMA_CSR_DREQ(1U);
496+
EDMA_TCD_CSR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) |=
497+
DMA_CSR_DREQ(1U);
467498
} else {
468-
EDMA_TCD_CSR(tcd, kEDMA_EDMA4Flag) &= ~DMA_CSR_DREQ(1U);
499+
EDMA_TCD_CSR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) &=
500+
~DMA_CSR_DREQ(1U);
469501
}
470502

471503
data->transfer_settings.write_idx =
@@ -566,7 +598,8 @@ static int dma_mcux_edma_start(const struct device *dev, uint32_t channel)
566598
LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]);
567599
#endif
568600

569-
#if !defined(CONFIG_DMA_MCUX_EDMA_V3) && !defined(CONFIG_DMA_MCUX_EDMA_V4)
601+
#if !defined(CONFIG_DMA_MCUX_EDMA_V3) && !defined(CONFIG_DMA_MCUX_EDMA_V4) \
602+
&& !defined(CONFIG_DMA_MCUX_EDMA_V5)
570603
LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR);
571604
#endif
572605
data->busy = true;
@@ -667,13 +700,20 @@ static int dma_mcux_edma_reload(const struct device *dev, uint32_t channel,
667700
tcd = &(DEV_CFG(dev)->tcdpool[channel][data->transfer_settings.write_idx]);
668701
pre_tcd = &(DEV_CFG(dev)->tcdpool[channel][pre_idx]);
669702

670-
EDMA_TCD_SADDR(tcd, kEDMA_EDMA4Flag) = src;
671-
EDMA_TCD_DADDR(tcd, kEDMA_EDMA4Flag) = dst;
672-
EDMA_TCD_BITER(tcd, kEDMA_EDMA4Flag) = size;
673-
EDMA_TCD_CITER(tcd, kEDMA_EDMA4Flag) = size;
703+
#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
704+
EDMA_TCD_SADDR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) =
705+
MEMORY_ConvertMemoryMapAddress(src, kMEMORY_Local2DMA);
706+
EDMA_TCD_DADDR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) =
707+
MEMORY_ConvertMemoryMapAddress(dst, kMEMORY_Local2DMA);
708+
#else
709+
EDMA_TCD_SADDR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) = src;
710+
EDMA_TCD_DADDR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) = dst;
711+
#endif
712+
EDMA_TCD_BITER(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) = size;
713+
EDMA_TCD_CITER(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) = size;
674714
/* Enable automatically stop */
675-
EDMA_TCD_CSR(tcd, kEDMA_EDMA4Flag) |= DMA_CSR_DREQ(1U);
676-
sw_id = EDMA_TCD_DLAST_SGA(tcd, kEDMA_EDMA4Flag);
715+
EDMA_TCD_CSR(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) |= DMA_CSR_DREQ(1U);
716+
sw_id = EDMA_TCD_DLAST_SGA(tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev)));
677717

678718
/* Block the peripheral's hardware request trigger to prevent
679719
* starting the DMA before updating the TCDs. Make sure the
@@ -704,7 +744,8 @@ static int dma_mcux_edma_reload(const struct device *dev, uint32_t channel,
704744
/* Previous TCD can automatically start this TCD.
705745
* Enable the peripheral DMA request in the previous TCD
706746
*/
707-
EDMA_TCD_CSR(pre_tcd, kEDMA_EDMA4Flag) &= ~DMA_CSR_DREQ(1U);
747+
EDMA_TCD_CSR(pre_tcd, EDMA_TCD_TYPE((void *)DEV_BASE(dev))) &=
748+
~DMA_CSR_DREQ(1U);
708749

709750
if (data->transfer_settings.empty_tcds == CONFIG_DMA_TCD_QUEUE_SIZE - 1 ||
710751
hw_id == (uint32_t)tcd) {
@@ -723,7 +764,7 @@ static int dma_mcux_edma_reload(const struct device *dev, uint32_t channel,
723764
*/
724765
EDMA_ClearChannelStatusFlags(DEV_BASE(dev), channel, kEDMA_DoneFlag);
725766
EDMA_HW_TCD_CSR(dev, channel) |= DMA_CSR_ESG_MASK;
726-
#elif (CONFIG_DMA_MCUX_EDMA_V3 || CONFIG_DMA_MCUX_EDMA_V4)
767+
#elif (CONFIG_DMA_MCUX_EDMA_V3 || CONFIG_DMA_MCUX_EDMA_V4 || CONFIG_DMA_MCUX_EDMA_V5)
727768
/*We have not verified if this issue exist on V3/V4 HW, jut place a holder here. */
728769
#endif
729770
/* TCDs are configured. Resume DMA */
@@ -802,6 +843,14 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel,
802843
LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_ES);
803844
LOG_DBG("DMA CHx_INT 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_INT);
804845
LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->CH[hw_channel].TCD_CSR);
846+
#elif defined(CONFIG_DMA_MCUX_EDMA_V5)
847+
LOG_DBG("DMA MP_CSR 0x%x", DEV_BASE(dev)->MP_CSR);
848+
LOG_DBG("DMA MP_ES 0x%x", DEV_BASE(dev)->MP_ES);
849+
LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->TCD[hw_channel].CH_ES);
850+
LOG_DBG("DMA CHx_CSR 0x%x", DEV_BASE(dev)->TCD[hw_channel].CH_CSR);
851+
LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->TCD[hw_channel].CH_ES);
852+
LOG_DBG("DMA CHx_INT 0x%x", DEV_BASE(dev)->TCD[hw_channel].CH_INT);
853+
LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->TCD[hw_channel].CSR);
805854
#else
806855
LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR);
807856
LOG_DBG("DMA INT 0x%x", DEV_BASE(dev)->INT);
@@ -957,16 +1006,22 @@ static int dma_mcux_edma_init(const struct device *dev)
9571006
#define CHANNELS_PER_MUX(n)
9581007
#endif
9591008

1009+
#if defined(CONFIG_DMA_MCUX_EDMA_V5)
1010+
#define DMA_TCD_ALIGN_SIZE 64
1011+
#else
1012+
#define DMA_TCD_ALIGN_SIZE 32
1013+
#endif
1014+
9601015
/*
9611016
* define the dma
9621017
*/
9631018
#define DMA_INIT(n) \
9641019
DMAMUX_BASE_INIT_DEFINE(n) \
9651020
static void dma_imx_config_func_##n(const struct device *dev); \
966-
static __aligned(32) EDMA_TCDPOOL_CACHE_ATTR edma_tcd_t \
1021+
static __aligned(DMA_TCD_ALIGN_SIZE) EDMA_TCDPOOL_CACHE_ATTR edma_tcd_t \
9671022
dma_tcdpool##n[DT_INST_PROP(n, dma_channels)][CONFIG_DMA_TCD_QUEUE_SIZE];\
9681023
static const struct dma_mcux_edma_config dma_config_##n = { \
969-
.base = (DMA_Type *)DT_INST_REG_ADDR(n), \
1024+
.base = (DMAx_Type *)DT_INST_REG_ADDR(n), \
9701025
DMAMUX_BASE_INIT(n) \
9711026
.dma_requests = DT_INST_PROP(n, dma_requests), \
9721027
.dma_channels = DT_INST_PROP(n, dma_channels), \

drivers/dma/dma_mcux_edma.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@
1818
#include "fsl_dmamux.h"
1919
#endif
2020

21+
#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
22+
#include "fsl_memory.h"
23+
#endif
2124
#endif /* DMA_MCUX_EDMA_H_*/

dts/bindings/dma/nxp,mcux-edma.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ properties:
6262
- 2
6363
- 3
6464
- 4
65+
- 5
6566
description: |
6667
eDMA IP revision number.
6768

modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ set_variable_ifdef(CONFIG_DMA_MCUX_EDMA CONFIG_MCUX_COMPONENT_driver.edm
6262
set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_V3 CONFIG_MCUX_COMPONENT_driver.dma3)
6363
set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_V4 CONFIG_MCUX_COMPONENT_driver.edma4)
6464
set_variable_ifdef(CONFIG_DMA_NXP_EDMA CONFIG_MCUX_COMPONENT_driver.edma_rev2)
65+
set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_V5 CONFIG_MCUX_COMPONENT_driver.edma4)
6566
set_variable_ifdef(CONFIG_ENTROPY_MCUX_RNGA CONFIG_MCUX_COMPONENT_driver.rnga)
6667
set_variable_ifdef(CONFIG_ENTROPY_MCUX_TRNG CONFIG_MCUX_COMPONENT_driver.trng)
6768
set_variable_ifdef(CONFIG_ENTROPY_MCUX_CAAM CONFIG_MCUX_COMPONENT_driver.caam)

0 commit comments

Comments
 (0)