Squashed commit of the following:
arch/arm/src/imxrt: May eDMA channel linking a configuration option. Add support to select the DMA channel priority and pre-emption controls. arch/arm/src/imxrt: Update some HowTo comments in the eDMA header file. arch/arm/src/imxrt: Fix a logic error in parmater passing. Caller does not know actual channel number when setting up linked channel, only the channel handler.
This commit is contained in:
parent
890656f043
commit
db0cdfc407
@ -345,6 +345,26 @@ config IMXRT_EDMA_NTCD
|
|||||||
which case only the TCD channel registers will be used and scatter-
|
which case only the TCD channel registers will be used and scatter-
|
||||||
will not be supported.
|
will not be supported.
|
||||||
|
|
||||||
|
config IMXRT_EDMA_ELINK
|
||||||
|
bool "Channeling Linking"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
This option enables optional minor or major loop channel linking:
|
||||||
|
|
||||||
|
Minor loop channel linking: As the channel completes the minor
|
||||||
|
loop, this flag enables linking to another channel. The link target
|
||||||
|
channel initiates a channel service request via an internal
|
||||||
|
mechanism that sets the TCDn_CSR[START] bit of the specified
|
||||||
|
channel.
|
||||||
|
|
||||||
|
If minor loop channel linking is disabled, this link mechanism is
|
||||||
|
suppressed in favor of the major loop channel linking.
|
||||||
|
|
||||||
|
Major loop channel linking: As the channel completes the minor
|
||||||
|
loop, this option enables the linking to another channel. The link
|
||||||
|
target channel initiates a channel service request via an internal
|
||||||
|
mechanism that sets the TCDn_CSR[START] bit of the linked channel.
|
||||||
|
|
||||||
config IMXRT_EDMA_ERCA
|
config IMXRT_EDMA_ERCA
|
||||||
bool "Round Robin Channel Arbitration"
|
bool "Round Robin Channel Arbitration"
|
||||||
default n
|
default n
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
/* DMAMUX Register Addresses ********************************************************/
|
/* DMAMUX Register Addresses ********************************************************/
|
||||||
|
|
||||||
#define IMXRT_DMAMUX_CHCF(n) (IMXRT_DMAMUX_BASE + IMXRT_DMAMUX_CHCFG_OFFSET(n))
|
#define IMXRT_DMAMUX_CHCFG(n) (IMXRT_DMAMUX_BASE + IMXRT_DMAMUX_CHCFG_OFFSET(n))
|
||||||
# define IMXRT_DMAMUX_CHCFG0 (IMXRT_DMAMUX_BASE + IMXRT_DMAMUX_CHCFG0_OFFSET)
|
# define IMXRT_DMAMUX_CHCFG0 (IMXRT_DMAMUX_BASE + IMXRT_DMAMUX_CHCFG0_OFFSET)
|
||||||
# define IMXRT_DMAMUX_CHCFG1 (IMXRT_DMAMUX_BASE + IMXRT_DMAMUX_CHCFG1_OFFSET)
|
# define IMXRT_DMAMUX_CHCFG1 (IMXRT_DMAMUX_BASE + IMXRT_DMAMUX_CHCFG1_OFFSET)
|
||||||
# define IMXRT_DMAMUX_CHCFG2 (IMXRT_DMAMUX_BASE + IMXRT_DMAMUX_CHCFG2_OFFSET)
|
# define IMXRT_DMAMUX_CHCFG2 (IMXRT_DMAMUX_BASE + IMXRT_DMAMUX_CHCFG2_OFFSET)
|
||||||
|
@ -352,55 +352,17 @@ static inline void imxrt_tcd_initialize(void)
|
|||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
static void imxrt_tcd_chanlink(uint8_t flags, uint8_t chan,
|
#ifdef CONFIG_IMXRT_EDMA_ELINK
|
||||||
|
static inline void imxrt_tcd_chanlink(uint8_t flags, struct imxrt_dmach_s *linkch,
|
||||||
struct imxrt_edmatcd_s *tcd)
|
struct imxrt_edmatcd_s *tcd)
|
||||||
{
|
|
||||||
switch (flags & EDMA_CONFIG_LINKTYPE_MASK)
|
|
||||||
{
|
|
||||||
case EDMA_CONFIG_LINKTYPE_MINORLINK: /* Minor link config */
|
|
||||||
{
|
{
|
||||||
uint16_t regval16;
|
uint16_t regval16;
|
||||||
|
|
||||||
/* Enable minor link */
|
flags &= EDMA_CONFIG_LINKTYPE_MASK;
|
||||||
|
|
||||||
tcd->citer |= EDMA_TCD_CITER_ELINK_ELINK;
|
if (linkch == NULL || flags == EDMA_CONFIG_LINKTYPE_LINKNONE)
|
||||||
tcd->biter |= EDMA_TCD_BITER_ELINK_ELINK;
|
|
||||||
|
|
||||||
/* Set linked channel */
|
|
||||||
|
|
||||||
regval16 = tcd->citer;
|
|
||||||
regval16 &= ~EDMA_TCD_CITER_ELINK_LINKCH_MASK;
|
|
||||||
regval16 |= EDMA_TCD_CITER_ELINK_LINKCH(chan);
|
|
||||||
tcd->citer = regval16;
|
|
||||||
|
|
||||||
regval16 = tcd->biter;
|
|
||||||
regval16 &= ~EDMA_TCD_BITER_ELINK_LINKCH_MASK;
|
|
||||||
regval16 |= EDMA_TCD_BITER_ELINK_LINKCH(chan);
|
|
||||||
tcd->biter = regval16;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EDMA_CONFIG_LINKTYPE_MAJORLINK: /* Major link config */
|
|
||||||
{
|
|
||||||
uint16_t regval16;
|
|
||||||
|
|
||||||
/* Enable major link */
|
|
||||||
|
|
||||||
regval16 = tcd->csr;
|
|
||||||
regval16 |= EDMA_TCD_CSR_MAJORELINK;
|
|
||||||
tcd->csr = regval16;
|
|
||||||
|
|
||||||
/* Set major linked channel */
|
|
||||||
|
|
||||||
regval16 &= ~EDMA_TCD_CSR_MAJORLINKCH_MASK;
|
|
||||||
regval16 |= EDMA_TCD_CSR_MAJORLINKCH(chan);
|
|
||||||
tcd->csr = regval16;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EDMA_CONFIG_LINKTYPE_LINKNONE: /* link none */
|
|
||||||
default:
|
|
||||||
{
|
{
|
||||||
|
/* No link or no link channel provided */
|
||||||
/* Disable minor links */
|
/* Disable minor links */
|
||||||
|
|
||||||
tcd->citer &= ~EDMA_TCD_CITER_ELINK;
|
tcd->citer &= ~EDMA_TCD_CITER_ELINK;
|
||||||
@ -410,9 +372,41 @@ static void imxrt_tcd_chanlink(uint8_t flags, uint8_t chan,
|
|||||||
|
|
||||||
tcd->csr &= ~EDMA_TCD_CSR_MAJORELINK;
|
tcd->csr &= ~EDMA_TCD_CSR_MAJORELINK;
|
||||||
}
|
}
|
||||||
break;
|
else if (flags == EDMA_CONFIG_LINKTYPE_MINORLINK) /* Minor link config */
|
||||||
|
{
|
||||||
|
/* Enable minor link */
|
||||||
|
|
||||||
|
tcd->citer |= EDMA_TCD_CITER_ELINK_ELINK;
|
||||||
|
tcd->biter |= EDMA_TCD_BITER_ELINK_ELINK;
|
||||||
|
|
||||||
|
/* Set linked channel */
|
||||||
|
|
||||||
|
regval16 = tcd->citer;
|
||||||
|
regval16 &= ~EDMA_TCD_CITER_ELINK_LINKCH_MASK;
|
||||||
|
regval16 |= EDMA_TCD_CITER_ELINK_LINKCH(linkch->chan);
|
||||||
|
tcd->citer = regval16;
|
||||||
|
|
||||||
|
regval16 = tcd->biter;
|
||||||
|
regval16 &= ~EDMA_TCD_BITER_ELINK_LINKCH_MASK;
|
||||||
|
regval16 |= EDMA_TCD_BITER_ELINK_LINKCH(linkch->chan);
|
||||||
|
tcd->biter = regval16;
|
||||||
|
}
|
||||||
|
else /* if (flags == EDMA_CONFIG_LINKTYPE_MAJORLINK) Major link config */
|
||||||
|
{
|
||||||
|
/* Enable major link */
|
||||||
|
|
||||||
|
regval16 = tcd->csr;
|
||||||
|
regval16 |= EDMA_TCD_CSR_MAJORELINK;
|
||||||
|
tcd->csr = regval16;
|
||||||
|
|
||||||
|
/* Set major linked channel */
|
||||||
|
|
||||||
|
regval16 &= ~EDMA_TCD_CSR_MAJORLINKCH_MASK;
|
||||||
|
regval16 |= EDMA_TCD_CSR_MAJORLINKCH(linkch->chan);
|
||||||
|
tcd->csr = regval16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: imxrt_tcd_configure
|
* Name: imxrt_tcd_configure
|
||||||
@ -435,14 +429,19 @@ static inline void imxrt_tcd_configure(struct imxrt_edmatcd_s *tcd,
|
|||||||
tcd->slast = tcd->slast;
|
tcd->slast = tcd->slast;
|
||||||
tcd->daddr = config->daddr;
|
tcd->daddr = config->daddr;
|
||||||
tcd->doff = config->doff;
|
tcd->doff = config->doff;
|
||||||
tcd->citer = config->iter;
|
tcd->citer = config->iter & EDMA_TCD_CITER_CITER_MASK;
|
||||||
tcd->biter = config->iter;
|
tcd->biter = config->iter & EDMA_TCD_BITER_BITER_MASK;
|
||||||
tcd->csr = EDMA_TCD_CSR_DREQ; /* Assume last transfer */
|
tcd->csr = EDMA_TCD_CSR_DREQ; /* Assume last transfer */
|
||||||
tcd->dlastsga = 0;
|
tcd->dlastsga = 0;
|
||||||
|
|
||||||
/* And special case flags */
|
/* And special case flags */
|
||||||
|
|
||||||
imxrt_tcd_chanlink(config->flags, config->linkch, tcd);
|
#ifdef CONFIG_IMXRT_EDMA_ELINK
|
||||||
|
/* Configure major/minor link mapping */
|
||||||
|
|
||||||
|
imxrt_tcd_chanlink(config->flags, (struct imxrt_dmach_s *)config->linkch,
|
||||||
|
tcd);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -841,6 +840,15 @@ void weak_function up_dmainitialize(void)
|
|||||||
* DMAMUX_CHCFG_ENBL DMA Mux Channel Enable (required)
|
* DMAMUX_CHCFG_ENBL DMA Mux Channel Enable (required)
|
||||||
*
|
*
|
||||||
* A value of zero will disable the DMAMUX channel.
|
* A value of zero will disable the DMAMUX channel.
|
||||||
|
* dchpri - DCHPRI channel priority configuration. See DCHPRI channel
|
||||||
|
* configuration register bit-field definitions in
|
||||||
|
* chip/imxrt_edma.h. Meaningful settings include:
|
||||||
|
*
|
||||||
|
* EDMA_DCHPRI_CHPRI Channel Arbitration Priority
|
||||||
|
* DCHPRI_DPA Disable Preempt Ability
|
||||||
|
* DCHPRI_ECP Enable Channel Preemption
|
||||||
|
*
|
||||||
|
* The power-on default, 0x05, is a reasonable choice.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* If a DMA channel is available, this function returns a non-NULL, void*
|
* If a DMA channel is available, this function returns a non-NULL, void*
|
||||||
@ -848,7 +856,7 @@ void weak_function up_dmainitialize(void)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
DMACH_HANDLE imxrt_dmach_alloc(uint32_t dmamux)
|
DMACH_HANDLE imxrt_dmach_alloc(uint32_t dmamux, uint8_t dchpri)
|
||||||
{
|
{
|
||||||
struct imxrt_dmach_s *dmach;
|
struct imxrt_dmach_s *dmach;
|
||||||
unsigned int chndx;
|
unsigned int chndx;
|
||||||
|
@ -43,6 +43,56 @@
|
|||||||
#ifndef __ARCH_ARM_SRC_IMXRT_IMXRT_EDMAC_H
|
#ifndef __ARCH_ARM_SRC_IMXRT_IMXRT_EDMAC_H
|
||||||
#define __ARCH_ARM_SRC_IMXRT_IMXRT_EDMAC_H
|
#define __ARCH_ARM_SRC_IMXRT_IMXRT_EDMAC_H
|
||||||
|
|
||||||
|
/* General Usage:
|
||||||
|
*
|
||||||
|
* 1. Allocate a DMA channel
|
||||||
|
*
|
||||||
|
* DMACH_HANDLE handle;
|
||||||
|
* handle = edma_dmach_alloc(dmamux, dchpri);
|
||||||
|
*
|
||||||
|
* Where 'dmamux' is the channel DMAMUX configuration register setting and
|
||||||
|
* 'dchpri' is the channel DCHPRIO priority register setting.
|
||||||
|
*
|
||||||
|
* 2. Create the transfer configuration:
|
||||||
|
*
|
||||||
|
* struct imxrt_edma_xfrconfig_s config;
|
||||||
|
* config.saddr = ..;
|
||||||
|
* config.daddr = ..;
|
||||||
|
* etc.
|
||||||
|
*
|
||||||
|
* 3. Setup the transfer in hardware:
|
||||||
|
*
|
||||||
|
* int ret;
|
||||||
|
* ret = imxrt_dmach_xfrsetup(handle, &config);
|
||||||
|
*
|
||||||
|
* 4. If you are setting up a scatter gather DMA (with CONFIG_IMXRT_EDMA_NTCD > 0),
|
||||||
|
* then repeat steps 2 and 3 for each segment of the transfer.
|
||||||
|
*
|
||||||
|
* 5. Start the DMA:
|
||||||
|
*
|
||||||
|
* ret = imxrt_dmach_start(handle, my_callback_func, priv);
|
||||||
|
*
|
||||||
|
* Where my_callback_func() is called when the DMA completes or an error occurs.
|
||||||
|
* 'priv' represents some internal driver state that will be provided with the
|
||||||
|
* callback.
|
||||||
|
*
|
||||||
|
* 6. If you need to stop the DMA and free resources (such as if a timeout occurs),
|
||||||
|
* then:
|
||||||
|
*
|
||||||
|
* i mxrt_dmach_stop(handle);
|
||||||
|
*
|
||||||
|
* 7. The callback will be received when the DMA completes (or an error occurs).
|
||||||
|
* After that, you may free the DMA channel, or re-use it on subsequent DMAs.
|
||||||
|
*
|
||||||
|
* imxrt_dmach_free(handle);
|
||||||
|
*
|
||||||
|
* Almost non-invasive debug instrumentation is available. You may call
|
||||||
|
* imxrt_dmasample() to save the current state of the eDMA registers at any given
|
||||||
|
* point in time. At some later, postmortem analysis, you can dump the content of
|
||||||
|
* the buffered registers with imxrt_dmadump(). imxrt_dmasample() is also available
|
||||||
|
* for monitoring DMA progress.
|
||||||
|
*/
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Included Files
|
* Included Files
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
@ -59,9 +109,8 @@
|
|||||||
/* Configuration flags.
|
/* Configuration flags.
|
||||||
*
|
*
|
||||||
* REVISIT: Many missing options that should be represented as flags:
|
* REVISIT: Many missing options that should be represented as flags:
|
||||||
* 1. DCHPRIO priority, pre-emption flags
|
* 1. Bandwidth
|
||||||
* 2. Bandwidth
|
* 2. Source/Destination modulo
|
||||||
* 3. Source/Destination modulo
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define EDMA_CONFIG_LINKTYPE_SHIFT (0) /* Bits 0-1: Link type */
|
#define EDMA_CONFIG_LINKTYPE_SHIFT (0) /* Bits 0-1: Link type */
|
||||||
@ -99,12 +148,14 @@ struct imxrt_edma_xfrconfig_s
|
|||||||
uint8_t ssize; /* Source data transfer size (see TCD_ATTR_SIZE_* definitions in chip/. */
|
uint8_t ssize; /* Source data transfer size (see TCD_ATTR_SIZE_* definitions in chip/. */
|
||||||
uint8_t dsize; /* Destination data transfer size. */
|
uint8_t dsize; /* Destination data transfer size. */
|
||||||
uint8_t ttype; /* Transfer type (see enum imxrt_edma_xfrtype_e). */
|
uint8_t ttype; /* Transfer type (see enum imxrt_edma_xfrtype_e). */
|
||||||
uint8_t linkch; /* Link channel (With EDMA_CONFIG_LINKTYPE_* flags) */
|
|
||||||
#ifdef CONFIG_IMXRT_EDMA_EMLIM
|
#ifdef CONFIG_IMXRT_EDMA_EMLIM
|
||||||
uint16_t nbytes; /* Bytes to transfer in a minor loop */
|
uint16_t nbytes; /* Bytes to transfer in a minor loop */
|
||||||
#else
|
#else
|
||||||
uint32_t nbytes; /* Bytes to transfer in a minor loop */
|
uint32_t nbytes; /* Bytes to transfer in a minor loop */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_IMXRT_EDMA_ELINK
|
||||||
|
DMACH_HANDLE linkch; /* Link channel (With EDMA_CONFIG_LINKTYPE_* flags) */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */
|
/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */
|
||||||
@ -171,7 +222,7 @@ extern "C"
|
|||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
/************************************************************************************
|
/****************************************************************************
|
||||||
* Name: imxrt_dmach_alloc
|
* Name: imxrt_dmach_alloc
|
||||||
*
|
*
|
||||||
* Allocate a DMA channel. This function sets aside a DMA channel,
|
* Allocate a DMA channel. This function sets aside a DMA channel,
|
||||||
@ -188,14 +239,23 @@ extern "C"
|
|||||||
* DMAMUX_CHCFG_ENBL DMA Mux Channel Enable (required)
|
* DMAMUX_CHCFG_ENBL DMA Mux Channel Enable (required)
|
||||||
*
|
*
|
||||||
* A value of zero will disable the DMAMUX channel.
|
* A value of zero will disable the DMAMUX channel.
|
||||||
|
* dchpri - DCHPRI channel priority configuration. See DCHPRI channel
|
||||||
|
* configuration register bit-field definitions in
|
||||||
|
* chip/imxrt_edma.h. Meaningful settings include:
|
||||||
|
*
|
||||||
|
* EDMA_DCHPRI_CHPRI Channel Arbitration Priority
|
||||||
|
* DCHPRI_DPA Disable Preempt Ability
|
||||||
|
* DCHPRI_ECP Enable Channel Preemption
|
||||||
|
*
|
||||||
|
* The power-on default, 0x05, is a reasonable choice.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* If a DMA channel is available, this function returns a non-NULL, void*
|
* If a DMA channel is available, this function returns a non-NULL, void*
|
||||||
* DMA channel handle. NULL is returned on any failure.
|
* DMA channel handle. NULL is returned on any failure.
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
DMACH_HANDLE imxrt_dmach_alloc(uint32_t dmamux);
|
DMACH_HANDLE imxrt_dmach_alloc(uint32_t dmamux, uint8_t dchpri);
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: imxrt_dmach_free
|
* Name: imxrt_dmach_free
|
||||||
|
Loading…
Reference in New Issue
Block a user