drivers: dma: Update NXP EDMA driver for version 4
1. Update EDMA driver for version 4 2. The DMAMux module is not always present. Use the feature define to make this optional. 3. Use the EDMA_SetChannelMux API for SoC's that supports this feature. Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
This commit is contained in:
parent
f9e3084daf
commit
55abfcb31e
|
@ -16,6 +16,7 @@ zephyr_library_sources_ifdef(CONFIG_DMA_SAM0 dma_sam0.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_USERSPACE dma_handlers.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA dma_mcux_edma.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA_V3 dma_mcux_edma.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA_V4 dma_mcux_edma.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_LPC dma_mcux_lpc.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_DMA_PL330 dma_pl330.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_DMA_IPROC_PAX dma_iproc_pax_v1.c)
|
||||
|
|
|
@ -18,7 +18,14 @@ config DMA_MCUX_EDMA_V3
|
|||
help
|
||||
DMA version 3 driver for MCUX series SoCs.
|
||||
|
||||
if DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3
|
||||
config DMA_MCUX_EDMA_V4
|
||||
bool "MCUX DMA v4 driver"
|
||||
default y
|
||||
depends on DT_HAS_NXP_MCUX_EDMA_V4_ENABLED
|
||||
help
|
||||
DMA version 4 driver for MCUX series SoCs.
|
||||
|
||||
if DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4
|
||||
|
||||
config DMA_TCD_QUEUE_SIZE
|
||||
int "number of TCD in a queue for SG mode"
|
||||
|
@ -41,4 +48,4 @@ config DMA_MCUX_USE_DTCM_FOR_DMA_DESCRIPTORS
|
|||
When this option is activated, the descriptors for DMA transfer are
|
||||
located in the DTCM (Data Tightly Coupled Memory).
|
||||
|
||||
endif # DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3
|
||||
endif # DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 NXP Semiconductor INC.
|
||||
* All rights reserved.
|
||||
* Copyright 2020-23 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -28,6 +27,8 @@
|
|||
#define DT_DRV_COMPAT nxp_mcux_edma
|
||||
#elif CONFIG_DMA_MCUX_EDMA_V3
|
||||
#define DT_DRV_COMPAT nxp_mcux_edma_v3
|
||||
#elif CONFIG_DMA_MCUX_EDMA_V4
|
||||
#define DT_DRV_COMPAT nxp_mcux_edma_v4
|
||||
#endif
|
||||
|
||||
LOG_MODULE_REGISTER(dma_mcux_edma, CONFIG_DMA_LOG_LEVEL);
|
||||
|
@ -37,7 +38,9 @@ LOG_MODULE_REGISTER(dma_mcux_edma, CONFIG_DMA_LOG_LEVEL);
|
|||
|
||||
struct dma_mcux_edma_config {
|
||||
DMA_Type *base;
|
||||
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
|
||||
DMAMUX_Type **dmamux_base;
|
||||
#endif
|
||||
uint8_t channels_per_mux;
|
||||
uint8_t dmamux_reg_offset;
|
||||
int dma_channels; /* number of channels */
|
||||
|
@ -120,11 +123,13 @@ struct dma_mcux_edma_data {
|
|||
#define DEV_EDMA_HANDLE(dev, ch) \
|
||||
((edma_handle_t *)(&(DEV_CHANNEL_DATA(dev, ch)->edma_handle)))
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
|
||||
#define DEV_DMAMUX_BASE(dev, idx) ((DMAMUX_Type *)DEV_CFG(dev)->dmamux_base[idx])
|
||||
#define DEV_DMAMUX_IDX(dev, ch) (ch / DEV_CFG(dev)->channels_per_mux)
|
||||
|
||||
#define DEV_DMAMUX_CHANNEL(dev, ch) \
|
||||
(ch % DEV_CFG(dev)->channels_per_mux) ^ (DEV_CFG(dev)->dmamux_reg_offset)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The hardware channel (takes the gap into account) is used when access DMA registers.
|
||||
|
@ -163,7 +168,7 @@ static bool data_size_valid(const size_t data_size)
|
|||
return (data_size == 4U || data_size == 2U ||
|
||||
data_size == 1U || data_size == 8U ||
|
||||
data_size == 16U || data_size == 32U
|
||||
#ifdef CONFIG_DMA_MCUX_EDMA_V3
|
||||
#if defined(CONFIG_DMA_MCUX_EDMA_V3) || defined(CONFIG_DMA_MCUX_EDMA_V4)
|
||||
|| data_size == 64U
|
||||
#endif
|
||||
);
|
||||
|
@ -246,7 +251,6 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
|
|||
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
|
||||
struct dma_block_config *block_config = config->head_block;
|
||||
uint32_t slot = config->dma_slot;
|
||||
uint8_t dmamux_idx, dmamux_channel;
|
||||
uint32_t hw_channel;
|
||||
edma_transfer_type_t transfer_type;
|
||||
unsigned int key;
|
||||
|
@ -263,8 +267,12 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
|
|||
}
|
||||
|
||||
hw_channel = dma_mcux_edma_add_channel_gap(dev, channel);
|
||||
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
|
||||
uint8_t dmamux_idx, dmamux_channel;
|
||||
|
||||
dmamux_idx = DEV_DMAMUX_IDX(dev, channel);
|
||||
dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel);
|
||||
#endif
|
||||
data->transfer_settings.valid = false;
|
||||
|
||||
switch (config->channel_direction) {
|
||||
|
@ -314,6 +322,8 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
|
|||
/* Lock and page in the channel configuration */
|
||||
key = irq_lock();
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
|
||||
|
||||
#if DT_INST_PROP(0, nxp_a_on)
|
||||
if (config->source_handshake || config->dest_handshake ||
|
||||
transfer_type == kEDMA_MemoryToMemory) {
|
||||
|
@ -330,6 +340,8 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
|
|||
/* dam_imx_rt_set_channel_priority(dev, channel, config); */
|
||||
DMAMUX_EnableChannel(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel);
|
||||
|
||||
#endif
|
||||
|
||||
if (data->busy) {
|
||||
EDMA_AbortTransfer(p_handle);
|
||||
}
|
||||
|
@ -337,6 +349,12 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
|
|||
EDMA_CreateHandle(p_handle, DEV_BASE(dev), hw_channel);
|
||||
EDMA_SetCallback(p_handle, nxp_edma_callback, (void *)data);
|
||||
|
||||
#if defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && FSL_FEATURE_EDMA_HAS_CHANNEL_MUX
|
||||
/* First release any peripheral previously associated with this channel */
|
||||
EDMA_SetChannelMux(DEV_BASE(dev), hw_channel, 0);
|
||||
EDMA_SetChannelMux(DEV_BASE(dev), hw_channel, slot);
|
||||
#endif
|
||||
|
||||
LOG_DBG("channel is %d", channel);
|
||||
EDMA_EnableChannelInterrupts(DEV_BASE(dev), hw_channel, kEDMA_ErrorInterruptEnable);
|
||||
|
||||
|
@ -377,7 +395,7 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
|
|||
LOG_ERR("Error submitting EDMA Transfer: 0x%x", submit_status);
|
||||
ret = -EFAULT;
|
||||
}
|
||||
#ifdef CONFIG_DMA_MCUX_EDMA_V3
|
||||
#if defined(CONFIG_DMA_MCUX_EDMA_V3) || defined(CONFIG_DMA_MCUX_EDMA_V4)
|
||||
LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->CH[hw_channel].TCD_CSR);
|
||||
#else
|
||||
LOG_DBG("data csr is 0x%x", DEV_BASE(dev)->TCD[hw_channel].CSR);
|
||||
|
@ -411,13 +429,17 @@ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel,
|
|||
static int dma_mcux_edma_start(const struct device *dev, uint32_t channel)
|
||||
{
|
||||
struct call_back *data = DEV_CHANNEL_DATA(dev, channel);
|
||||
|
||||
LOG_DBG("START TRANSFER");
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
|
||||
uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel);
|
||||
uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel);
|
||||
|
||||
LOG_DBG("START TRANSFER");
|
||||
LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DMA_MCUX_EDMA_V3
|
||||
#if !defined(CONFIG_DMA_MCUX_EDMA_V3) && !defined(CONFIG_DMA_MCUX_EDMA_V4)
|
||||
LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR);
|
||||
#endif
|
||||
data->busy = true;
|
||||
|
@ -518,9 +540,6 @@ cleanup:
|
|||
static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel,
|
||||
struct dma_status *status)
|
||||
{
|
||||
uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel);
|
||||
uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel);
|
||||
|
||||
uint32_t hw_channel = dma_mcux_edma_add_channel_gap(dev, channel);
|
||||
|
||||
if (DEV_CHANNEL_DATA(dev, channel)->busy) {
|
||||
|
@ -532,9 +551,15 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel,
|
|||
status->pending_length = 0;
|
||||
}
|
||||
status->dir = DEV_CHANNEL_DATA(dev, channel)->transfer_settings.direction;
|
||||
LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]);
|
||||
|
||||
#ifdef CONFIG_DMA_MCUX_EDMA_V3
|
||||
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
|
||||
uint8_t dmamux_idx = DEV_DMAMUX_IDX(dev, channel);
|
||||
uint8_t dmamux_channel = DEV_DMAMUX_CHANNEL(dev, channel);
|
||||
|
||||
LOG_DBG("DMAMUX CHCFG 0x%x", DEV_DMAMUX_BASE(dev, dmamux_idx)->CHCFG[dmamux_channel]);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DMA_MCUX_EDMA_V3) || defined(CONFIG_DMA_MCUX_EDMA_V4)
|
||||
LOG_DBG("DMA MP_CSR 0x%x", DEV_BASE(dev)->MP_CSR);
|
||||
LOG_DBG("DMA MP_ES 0x%x", DEV_BASE(dev)->MP_ES);
|
||||
LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_ES);
|
||||
|
@ -584,13 +609,16 @@ static int dma_mcux_edma_init(const struct device *dev)
|
|||
struct dma_mcux_edma_data *data = dev->data;
|
||||
|
||||
edma_config_t userConfig = { 0 };
|
||||
uint8_t i;
|
||||
|
||||
LOG_DBG("INIT NXP EDMA");
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < config->dma_channels / config->channels_per_mux; i++) {
|
||||
DMAMUX_Init(DEV_DMAMUX_BASE(dev, i));
|
||||
}
|
||||
#endif
|
||||
|
||||
EDMA_GetDefaultConfig(&userConfig);
|
||||
EDMA_Init(DEV_BASE(dev), &userConfig);
|
||||
|
@ -654,9 +682,6 @@ static int dma_mcux_edma_init(const struct device *dev)
|
|||
LOG_DBG("install irq done"); \
|
||||
}
|
||||
|
||||
#define DMA_MCUX_EDMA_MUX(idx, n) \
|
||||
(DMAMUX_Type *)DT_INST_REG_ADDR_BY_IDX(n, UTIL_INC(idx))
|
||||
|
||||
#if DMA_MCUX_HAS_CHANNEL_GAP
|
||||
#define DMA_MCUX_EDMA_CHANNEL_GAP(n) \
|
||||
.channel_gap = DT_INST_PROP_OR(n, channel_gap, \
|
||||
|
@ -665,21 +690,37 @@ static int dma_mcux_edma_init(const struct device *dev)
|
|||
#define DMA_MCUX_EDMA_CHANNEL_GAP(n)
|
||||
#endif
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
|
||||
#define DMA_MCUX_EDMA_MUX(idx, n) \
|
||||
(DMAMUX_Type *)DT_INST_REG_ADDR_BY_IDX(n, UTIL_INC(idx))
|
||||
|
||||
#define DMAMUX_BASE_INIT_DEFINE(n) \
|
||||
static DMAMUX_Type *dmamux_base_##n[] = { \
|
||||
LISTIFY(UTIL_DEC(DT_NUM_REGS(DT_DRV_INST(n))), \
|
||||
DMA_MCUX_EDMA_MUX, (,), n) \
|
||||
};
|
||||
|
||||
#define DMAMUX_BASE_INIT(n) .dmamux_base = &dmamux_base_##n[0],
|
||||
#define CHANNELS_PER_MUX(n) .channels_per_mux = DT_INST_PROP(n, dma_channels) / \
|
||||
ARRAY_SIZE(dmamux_base_##n),
|
||||
|
||||
#else
|
||||
#define DMAMUX_BASE_INIT_DEFINE(n)
|
||||
#define DMAMUX_BASE_INIT(n)
|
||||
#define CHANNELS_PER_MUX(n)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* define the dma
|
||||
*/
|
||||
#define DMA_INIT(n) \
|
||||
DMAMUX_BASE_INIT_DEFINE(n) \
|
||||
static void dma_imx_config_func_##n(const struct device *dev); \
|
||||
static DMAMUX_Type *dmamux_base_##n[] = { \
|
||||
LISTIFY(UTIL_DEC(DT_NUM_REGS(DT_DRV_INST(n))), \
|
||||
DMA_MCUX_EDMA_MUX, (,), n) \
|
||||
}; \
|
||||
static const struct dma_mcux_edma_config dma_config_##n = { \
|
||||
.base = (DMA_Type *)DT_INST_REG_ADDR(n), \
|
||||
.dmamux_base = &dmamux_base_##n[0], \
|
||||
DMAMUX_BASE_INIT(n) \
|
||||
.dma_channels = DT_INST_PROP(n, dma_channels), \
|
||||
.channels_per_mux = DT_INST_PROP(n, dma_channels) / \
|
||||
ARRAY_SIZE(dmamux_base_##n), \
|
||||
CHANNELS_PER_MUX(n) \
|
||||
.irq_config_func = dma_imx_config_func_##n, \
|
||||
.dmamux_reg_offset = DT_INST_PROP(n, dmamux_reg_offset), \
|
||||
DMA_MCUX_EDMA_CHANNEL_GAP(n) \
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 NXP Semiconductor INC.
|
||||
* All rights reserved.
|
||||
* Copyright 2020-23 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -15,6 +14,8 @@
|
|||
#include <fsl_common.h>
|
||||
|
||||
#include "fsl_edma.h"
|
||||
#if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT
|
||||
#include "fsl_dmamux.h"
|
||||
#endif
|
||||
|
||||
#endif /* DMA_MCUX_EDMA_H_*/
|
||||
|
|
14
dts/bindings/dma/nxp,mcux-edma-v4.yaml
Normal file
14
dts/bindings/dma/nxp,mcux-edma-v4.yaml
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Copyright 2024 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: NXP MCUX EDMA version 4 controller
|
||||
|
||||
compatible: "nxp,mcux-edma-v4"
|
||||
|
||||
include: nxp,mcux-edma.yaml
|
||||
|
||||
properties:
|
||||
no-error-irq:
|
||||
type: boolean
|
||||
description: |
|
||||
If the SoCs don't have a separate interrupt id for error IRQ.
|
Loading…
Reference in a new issue