diff options
-rw-r--r-- | bsps/arm/imxrt/start/bspstart.c | 3 | ||||
-rw-r--r-- | bsps/include/fsl/edma.h | 218 | ||||
-rw-r--r-- | bsps/include/fsl/regs-edma.h | 977 | ||||
-rw-r--r-- | bsps/shared/dev/dma/fsl-edma.c | 349 | ||||
-rw-r--r-- | spec/build/bsps/arm/imxrt/bspimxrt.yml | 2 | ||||
-rw-r--r-- | spec/build/bsps/arm/imxrt/optfsledmaemlm.yml | 16 | ||||
-rw-r--r-- | spec/build/bsps/obj.yml | 5 |
7 files changed, 746 insertions, 824 deletions
diff --git a/bsps/arm/imxrt/start/bspstart.c b/bsps/arm/imxrt/start/bspstart.c index 884f0aaf92..445af04563 100644 --- a/bsps/arm/imxrt/start/bspstart.c +++ b/bsps/arm/imxrt/start/bspstart.c @@ -35,6 +35,7 @@ #include <bsp/irq.h> #include <bsp/linker-symbols.h> #include <bsp/flash-headers.h> +#include <fsl/edma.h> #include <fsl_clock.h> #include <libfdt.h> @@ -139,3 +140,5 @@ RTEMS_SYSINIT_ITEM(imxrt_lpi2c_init, RTEMS_SYSINIT_DEVICE_DRIVERS, RTEMS_SYSINIT_ORDER_MIDDLE); RTEMS_SYSINIT_ITEM(imxrt_ffec_init, RTEMS_SYSINIT_DEVICE_DRIVERS, RTEMS_SYSINIT_ORDER_MIDDLE); +RTEMS_SYSINIT_ITEM(fsl_edma_init, RTEMS_SYSINIT_DEVICE_DRIVERS, + RTEMS_SYSINIT_ORDER_FIRST); diff --git a/bsps/include/fsl/edma.h b/bsps/include/fsl/edma.h index 8b7d65d3b6..a2727f0c0e 100644 --- a/bsps/include/fsl/edma.h +++ b/bsps/include/fsl/edma.h @@ -1,29 +1,40 @@ /** * @file * - * @ingroup RTEMSBSPsPowerPCMPC55XX + * @ingroup RTEMSBSPsSharedFslEDMA * - * @brief Enhanced Direct Memory Access (eDMA). + * @brief Freescale / NXP Enhanced Direct Memory Access (eDMA). */ /* - * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved. + * Copyright (C) 2008-2020 embedded brains GmbH (http://www.embedded-brains.de) * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * <rtems@embedded-brains.de> + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LIBCPU_POWERPC_MPC55XX_EDMA_H -#define LIBCPU_POWERPC_MPC55XX_EDMA_H +#ifndef LIBBSP_SHARED_FSL_EDMA_H +#define LIBBSP_SHARED_FSL_EDMA_H -#include <mpc55xx/regs.h> +#include <fsl/regs-edma.h> #include <rtems.h> #include <rtems/chain.h> @@ -32,7 +43,9 @@ extern "C" { #endif /* __cplusplus */ -#if MPC55XX_CHIP_FAMILY == 551 +#ifdef LIBBSP_ARM_IMXRT_BSP_H + #define EDMA_CHANNEL_COUNT 32U +#elif MPC55XX_CHIP_FAMILY == 551 #define EDMA_CHANNEL_COUNT 16U #elif MPC55XX_CHIP_FAMILY == 564 #define EDMA_CHANNEL_COUNT 16U @@ -46,20 +59,27 @@ extern "C" { #define EDMA_CHANNELS_PER_MODULE 64U -#if EDMA_MODULE_COUNT == 1 - #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \ - (&EDMA.TCD[(channel_index)]) -#elif EDMA_MODULE_COUNT == 2 - #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \ - ((channel_index) < EDMA_CHANNELS_PER_MODULE ? \ - &EDMA_A.TCD[(channel_index)] \ - : &EDMA_B.TCD[(channel_index) - EDMA_CHANNELS_PER_MODULE]) -#else - #error "unsupported module count" +volatile struct fsl_edma_tcd *fsl_edma_tcd_of_channel_index(unsigned index); +unsigned fsl_edma_channel_index_of_tcd(volatile struct fsl_edma_tcd *edma_tcd); + +#ifdef LIBBSP_POWERPC_MPC55XXEVB_BSP_H + #error Legacy stuff. Move to compatibility layer. + #if EDMA_MODULE_COUNT == 1 + #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \ + (&EDMA.TCD[(channel_index)]) + #elif EDMA_MODULE_COUNT == 2 + #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \ + ((channel_index) < EDMA_CHANNELS_PER_MODULE ? \ + &EDMA_A.TCD[(channel_index)] \ + : &EDMA_B.TCD[(channel_index) - EDMA_CHANNELS_PER_MODULE]) + #else + #error "unsupported module count" + #endif #endif -/* FIXME: These values are only valid for the MPC5566 and MPC5674F */ +#ifdef LIBBSP_POWERPC_MPC55XXEVB_BSP_H typedef enum { +/* FIXME: These values are only valid for the MPC5566 and MPC5674F */ EDMA_EQADC_A_FISR0_CFFF0 = 0, EDMA_EQADC_A_FISR0_RFDF0 = 1, EDMA_EQADC_A_FISR1_CFFF1 = 2, @@ -155,15 +175,16 @@ typedef enum { EDMA_DECFILTER_H_IB = 64 + 26, EDMA_DECFILTER_H_OB = 64 + 27 #endif -} edma_channel; +} fsl_edma_channel; +#endif -typedef struct edma_channel_context { +typedef struct fsl_edma_channel_context { rtems_chain_node node; - volatile struct tcd_t *edma_tcd; - void (*done)(struct edma_channel_context *, uint32_t); -} edma_channel_context; + volatile struct fsl_edma_tcd *edma_tcd; + void (*done)(struct fsl_edma_channel_context *, uint32_t); +} fsl_edma_channel_context; -void mpc55xx_edma_init(void); +void fsl_edma_init(void); /** * @brief Obtains an eDMA channel. @@ -171,14 +192,18 @@ void mpc55xx_edma_init(void); * @retval RTEMS_SUCCESSFUL Successful operation. * @retval RTEMS_RESOURCE_IN_USE The channel is already in use. */ -rtems_status_code mpc55xx_edma_obtain_channel_by_tcd( - volatile struct tcd_t *edma_tcd +rtems_status_code fsl_edma_obtain_channel_by_tcd( + volatile struct fsl_edma_tcd *edma_tcd ); -void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd); +void fsl_edma_release_channel_by_tcd(volatile struct fsl_edma_tcd *edma_tcd); /** - * @brief Obtains an eDMA channel and registers the channel context. + * @brief Obtains a specific eDMA channel and registers the channel context. + * + * Tries to obtain the channel specified in the @a ctx. + * + * @a irq_priority will be ignored on all targets but MPC55xx based ones. * * The done handler of the channel context will be called * - during minor or major loop completions if interrupts are enabled in the @@ -191,12 +216,33 @@ void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd); * @retval RTEMS_RESOURCE_IN_USE The channel is already in use. * @retval RTEMS_IO_ERROR Unable to install interrupt handler for this channel. */ -rtems_status_code mpc55xx_edma_obtain_channel( - edma_channel_context *ctx, +rtems_status_code fsl_edma_obtain_channel( + fsl_edma_channel_context *ctx, unsigned irq_priority ); -void mpc55xx_edma_release_channel(edma_channel_context *ctx); +/** + * @brief Obtains a free eDMA channel and registers the channel context. + * + * Tries to obtain the next free DMA channel. The tcd field of @a ctx will be + * set accordingly. + * + * The done handler of the channel context will be called + * - during minor or major loop completions if interrupts are enabled in the + * corresponding TCD, or + * - in case a channel error occurs. + * + * An error status value not equal to zero indicates an error. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_RESOURCE_IN_USE No channels left. + * @retval RTEMS_IO_ERROR Unable to install interrupt handler. + */ +rtems_status_code fsl_edma_obtain_next_free_channel( + fsl_edma_channel_context *ctx +); + +void fsl_edma_release_channel(fsl_edma_channel_context *ctx); /** * @brief Copies a source TCD to an eDMA TCD. @@ -207,9 +253,9 @@ void mpc55xx_edma_release_channel(edma_channel_context *ctx); * This function can be used to start the channel if the START flags is * set in the source TCD. */ -void mpc55xx_edma_copy( - volatile struct tcd_t *edma_tcd, - const struct tcd_t *source_tcd +void fsl_edma_copy( + volatile struct fsl_edma_tcd *edma_tcd, + const struct fsl_edma_tcd *source_tcd ); /** @@ -218,112 +264,112 @@ void mpc55xx_edma_copy( * The DONE flag of the eDMA TCD is cleared before the actual copy operation. * This enables the setting of channel link or scatter/gather options. */ -void mpc55xx_edma_copy_and_enable_hardware_requests( - volatile struct tcd_t *edma_tcd, - const struct tcd_t *source_tcd +void fsl_edma_copy_and_enable_hardware_requests( + volatile struct fsl_edma_tcd *edma_tcd, + const struct fsl_edma_tcd *source_tcd ); -void mpc55xx_edma_sg_link( - volatile struct tcd_t *edma_tcd, - const struct tcd_t *source_tcd +void fsl_edma_sg_link( + volatile struct fsl_edma_tcd *edma_tcd, + const struct fsl_edma_tcd *source_tcd ); -static inline volatile struct EDMA_tag *mpc55xx_edma_by_tcd( - volatile struct tcd_t *edma_tcd +static inline volatile struct fsl_edma *fsl_edma_by_tcd( + volatile struct fsl_edma_tcd *edma_tcd ) { - return (volatile struct EDMA_tag *) + return (volatile struct fsl_edma *) ((uintptr_t) edma_tcd & ~(uintptr_t) 0x1fff); } -static inline unsigned mpc55xx_edma_channel_by_tcd( - volatile struct tcd_t *edma_tcd +static inline unsigned fsl_edma_channel_by_tcd( + volatile struct fsl_edma_tcd *edma_tcd ) { - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); + volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd); return edma_tcd - &edma->TCD[0]; } -static inline void mpc55xx_edma_enable_hardware_requests( - volatile struct tcd_t *edma_tcd +static inline void fsl_edma_enable_hardware_requests( + volatile struct fsl_edma_tcd *edma_tcd ) { - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); + volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd); unsigned channel = edma_tcd - &edma->TCD[0]; - edma->SERQR.R = (uint8_t) channel; + edma->SERQR = (uint8_t) channel; } -static inline void mpc55xx_edma_disable_hardware_requests( - volatile struct tcd_t *edma_tcd +static inline void fsl_edma_disable_hardware_requests( + volatile struct fsl_edma_tcd *edma_tcd ) { - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); + volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd); unsigned channel = edma_tcd - &edma->TCD[0]; - edma->CERQR.R = (uint8_t) channel; + edma->CERQR = (uint8_t) channel; } -static inline void mpc55xx_edma_enable_error_interrupts( - volatile struct tcd_t *edma_tcd +static inline void fsl_edma_enable_error_interrupts( + volatile struct fsl_edma_tcd *edma_tcd ) { - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); + volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd); unsigned channel = edma_tcd - &edma->TCD[0]; - edma->SEEIR.R = (uint8_t) channel; + edma->SEEIR = (uint8_t) channel; } -static inline void mpc55xx_edma_disable_error_interrupts( - volatile struct tcd_t *edma_tcd +static inline void fsl_edma_disable_error_interrupts( + volatile struct fsl_edma_tcd *edma_tcd ) { - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); + volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd); unsigned channel = edma_tcd - &edma->TCD[0]; - edma->CEEIR.R = (uint8_t) channel; + edma->CEEIR = (uint8_t) channel; } -static inline void mpc55xx_edma_set_start( - volatile struct tcd_t *edma_tcd +static inline void fsl_edma_set_start( + volatile struct fsl_edma_tcd *edma_tcd ) { - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); + volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd); unsigned channel = edma_tcd - &edma->TCD[0]; - edma->SSBR.R = (uint8_t) channel; + edma->SSBR = (uint8_t) channel; } -static inline void mpc55xx_edma_clear_done( - volatile struct tcd_t *edma_tcd +static inline void fsl_edma_clear_done( + volatile struct fsl_edma_tcd *edma_tcd ) { - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); + volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd); unsigned channel = edma_tcd - &edma->TCD[0]; - edma->CDSBR.R = (uint8_t) channel; + edma->CDSBR = (uint8_t) channel; } -static inline void mpc55xx_edma_clear_interrupts( - volatile struct tcd_t *edma_tcd +static inline void fsl_edma_clear_interrupts( + volatile struct fsl_edma_tcd *edma_tcd ) { - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); + volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd); unsigned channel = edma_tcd - &edma->TCD[0]; - edma->CIRQR.R = (uint8_t) channel; + edma->CIRQR = (uint8_t) channel; } -static inline bool mpc55xx_edma_is_done( - volatile struct tcd_t *edma_tcd +static inline bool fsl_edma_is_done( + volatile struct fsl_edma_tcd *edma_tcd ) { - return edma_tcd->BMF.B.DONE; + return ((edma_tcd->BMF & EDMA_TCD_BMF_DONE) != 0); } #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* LIBCPU_POWERPC_MPC55XX_EDMA_H */ +#endif /* LIBBSP_SHARED_FSL_EDMA_H */ diff --git a/bsps/include/fsl/regs-edma.h b/bsps/include/fsl/regs-edma.h index fda47dc1e6..4afdb9b4e4 100644 --- a/bsps/include/fsl/regs-edma.h +++ b/bsps/include/fsl/regs-edma.h @@ -1,21 +1,32 @@ /** * @file * - * @ingroup RTEMSBSPsPowerPCMPC55XX + * @ingroup RTEMSBSPsSharedFslEDMA */ /* - * Copyright (c) 2011 embedded brains GmbH. All rights reserved. + * Copyright (C) 2011-2020 embedded brains GmbH (http://www.embedded-brains.de) * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * <rtems@embedded-brains.de> + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************* @@ -49,647 +60,345 @@ * ********************************************************************/ -#ifndef LIBCPU_POWERPC_MPC55XX_REGS_EDMA_H -#define LIBCPU_POWERPC_MPC55XX_REGS_EDMA_H +#ifndef LIBBSP_SHARED_FSL_REGS_EDMA_H +#define LIBBSP_SHARED_FSL_REGS_EDMA_H #include <stdint.h> - +#include <bsp.h> #include <bspopts.h> #ifdef __cplusplus extern "C" { #endif -/****************************************************************************/ -/* MODULE : eDMA */ -/****************************************************************************/ - struct EDMA_tag { - union EDMA_CR_tag { - uint32_t R; - struct { -#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567 - uint32_t:14; - uint32_t CX:1; - uint32_t ECX:1; -#else - uint32_t:16; +#if (defined(MPC55XX_CHIP_FAMILY) && \ + (MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567)) + #define EDMA_HAS_CR_EBW 1 + #define EDMA_HAS_CR_CX_ECX 1 + #define EDMA_HAS_CR_EMLM_CLM_HALT_HOE 1 + #define EDMA_HAS_ESR_ECX 1 + #define EDMA_HAS_HRS 1 + #define EDMA_HAS_CPR_DPA 1 #endif - uint32_t GRP3PRI:2; - uint32_t GRP2PRI:2; - uint32_t GRP1PRI:2; - uint32_t GRP0PRI:2; -#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567 - uint32_t EMLM:1; - uint32_t CLM:1; - uint32_t HALT:1; - uint32_t HOE:1; -#else - uint32_t:4; + +#if defined(LIBBSP_ARM_IMXRT_BSP_H) + #define EDMA_HAS_CR_CX_ECX 1 + #define EDMA_HAS_CR_EMLM_CLM_HALT_HOE 1 + #define EDMA_HAS_CR_ACTIVE 1 + #define EDMA_HAS_CR_VERSION 1 + #define EDMA_HAS_ESR_ECX 1 + #define EDMA_HAS_HRS 1 + #define EDMA_HAS_EARS 1 + #define EDMA_HAS_CPR_DPA 1 #endif - uint32_t ERGA:1; - uint32_t ERCA:1; - uint32_t EDBG:1; - uint32_t EBW:1; - } B; - } CR; /* Control Register */ - - union { - uint32_t R; - struct { - uint32_t VLD:1; -#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567 - uint32_t:14; - uint32_t ECX:1; -#else - uint32_t:15; + +struct fsl_edma { + uint32_t CR; +#ifdef EDMA_HAS_CR_EBW + #define EDMA_CR_EBW (1 << 0) +#endif +#define EDMA_CR_EDBG (1 << 1) +#define EDMA_CR_ERCA (1 << 2) +#define EDMA_CR_ERGA (1 << 3) +#ifdef EDMA_HAS_CR_EMLM_CLM_HALT_HOE + #define EDMA_CR_HOE (1 << 4) + #define EDMA_CR_HALT (1 << 5) + #define EDMA_CR_CLM (1 << 6) + #define EDMA_CR_EMLM (1 << 7) +#endif +#define EDMA_CR_GRPxPRI_SHIFT(x) (8 + (x) * 2) +#define EDMA_CR_GRPxPRI_MASK(x) (0x3 << EDMA_CR_GRPxPRI_SHIFT(x)) +#define EDMA_CR_GRPxPRI(x,val) (((val) << EDMA_CR_GRPxPRI_SHIFT(x)) & EDMA_CR_GRPxPRI_MASK(x)) +#define EDMA_CR_GRPxPRI_GET(x,reg) (((reg) & EDMA_CR_GRPxPRI_MASK(x)) >> EDMA_CR_GRPxPRI_SHIFT(x)) +#ifdef EDMA_HAS_CR_CX_ECX + #define EDMA_CR_ECX (1 << 16) + #define EDMA_CR_CX (1 << 17) +#endif +#ifdef EDMA_HAS_CR_VERSION + #define EDMA_CR_VERSION_SHIFT (24) + #define EDMA_CR_VERSION_MASK (0x7F << EDMA_CR_VERSION_SHIFT) + #define EDMA_CR_VERSION(val) (((val) << EDMA_CR_VERSION_SHIFT) & EDMA_CR_VERSION_MASK) + #define EDMA_CR_VERSION_GET(reg) (((reg) & EDMA_CR_VERSION_MASK) >> EDMA_CR_VERSION_SHIFT) #endif - uint32_t GPE:1; - uint32_t CPE:1; - uint32_t ERRCHN:6; - uint32_t SAE:1; - uint32_t SOE:1; - uint32_t DAE:1; - uint32_t DOE:1; - uint32_t NCE:1; - uint32_t SGE:1; - uint32_t SBE:1; - uint32_t DBE:1; - } B; - } ESR; /* Error Status Register */ - - union { - uint32_t R; - struct { - uint32_t ERQ63:1; - uint32_t ERQ62:1; - uint32_t ERQ61:1; - uint32_t ERQ60:1; - uint32_t ERQ59:1; - uint32_t ERQ58:1; - uint32_t ERQ57:1; - uint32_t ERQ56:1; - uint32_t ERQ55:1; - uint32_t ERQ54:1; - uint32_t ERQ53:1; - uint32_t ERQ52:1; - uint32_t ERQ51:1; - uint32_t ERQ50:1; - uint32_t ERQ49:1; - uint32_t ERQ48:1; - uint32_t ERQ47:1; - uint32_t ERQ46:1; - uint32_t ERQ45:1; - uint32_t ERQ44:1; - uint32_t ERQ43:1; - uint32_t ERQ42:1; - uint32_t ERQ41:1; - uint32_t ERQ40:1; - uint32_t ERQ39:1; - uint32_t ERQ38:1; - uint32_t ERQ37:1; - uint32_t ERQ36:1; - uint32_t ERQ35:1; - uint32_t ERQ34:1; - uint32_t ERQ33:1; - uint32_t ERQ32:1; - } B; - } ERQRH; /* DMA Enable Request Register High */ - - union { - uint32_t R; - struct { - uint32_t ERQ31:1; - uint32_t ERQ30:1; - uint32_t ERQ29:1; - uint32_t ERQ28:1; - uint32_t ERQ27:1; - uint32_t ERQ26:1; - uint32_t ERQ25:1; - uint32_t ERQ24:1; - uint32_t ERQ23:1; - uint32_t ERQ22:1; - uint32_t ERQ21:1; - uint32_t ERQ20:1; - uint32_t ERQ19:1; - uint32_t ERQ18:1; - uint32_t ERQ17:1; - uint32_t ERQ16:1; - uint32_t ERQ15:1; - uint32_t ERQ14:1; - uint32_t ERQ13:1; - uint32_t ERQ12:1; - uint32_t ERQ11:1; - uint32_t ERQ10:1; - uint32_t ERQ09:1; - uint32_t ERQ08:1; - uint32_t ERQ07:1; - uint32_t ERQ06:1; - uint32_t ERQ05:1; - uint32_t ERQ04:1; - uint32_t ERQ03:1; - uint32_t ERQ02:1; - uint32_t ERQ01:1; - uint32_t ERQ00:1; - } B; - } ERQRL; /* DMA Enable Request Register Low */ - - union { - uint32_t R; - struct { - uint32_t EEI63:1; - uint32_t EEI62:1; - uint32_t EEI61:1; - uint32_t EEI60:1; - uint32_t EEI59:1; - uint32_t EEI58:1; - uint32_t EEI57:1; - uint32_t EEI56:1; - uint32_t EEI55:1; - uint32_t EEI54:1; - uint32_t EEI53:1; - uint32_t EEI52:1; - uint32_t EEI51:1; - uint32_t EEI50:1; - uint32_t EEI49:1; - uint32_t EEI48:1; - uint32_t EEI47:1; - uint32_t EEI46:1; - uint32_t EEI45:1; - uint32_t EEI44:1; - uint32_t EEI43:1; - uint32_t EEI42:1; - uint32_t EEI41:1; - uint32_t EEI40:1; - uint32_t EEI39:1; - uint32_t EEI38:1; - uint32_t EEI37:1; - uint32_t EEI36:1; - uint32_t EEI35:1; - uint32_t EEI34:1; - uint32_t EEI33:1; - uint32_t EEI32:1; - } B; - } EEIRH; /* DMA Enable Error Interrupt Register High */ - - union { - uint32_t R; - struct { - uint32_t EEI31:1; - uint32_t EEI30:1; - uint32_t EEI29:1; - uint32_t EEI28:1; - uint32_t EEI27:1; - uint32_t EEI26:1; - uint32_t EEI25:1; - uint32_t EEI24:1; - uint32_t EEI23:1; - uint32_t EEI22:1; - uint32_t EEI21:1; - uint32_t EEI20:1; - uint32_t EEI19:1; - uint32_t EEI18:1; - uint32_t EEI17:1; - uint32_t EEI16:1; - uint32_t EEI15:1; - uint32_t EEI14:1; - uint32_t EEI13:1; - uint32_t EEI12:1; - uint32_t EEI11:1; - uint32_t EEI10:1; - uint32_t EEI09:1; - uint32_t EEI08:1; - uint32_t EEI07:1; - uint32_t EEI06:1; - uint32_t EEI05:1; - uint32_t EEI04:1; - uint32_t EEI03:1; - uint32_t EEI02:1; - uint32_t EEI01:1; - uint32_t EEI00:1; - } B; - } EEIRL; /* DMA Enable Error Interrupt Register Low */ - - union { /* DMA Set Enable Request Register */ - uint8_t R; - struct { - uint8_t NOP:1; - uint8_t SERQ:7; - } B; - } SERQR; - - union { /* DMA Clear Enable Request Register */ - uint8_t R; - struct { - uint8_t NOP:1; - uint8_t CERQ:7; - } B; - } CERQR; - - union { /* DMA Set Enable Error Interrupt Register */ - uint8_t R; - struct { - uint8_t NOP:1; - uint8_t SEEI:7; - } B; - } SEEIR; - - union { /* DMA Clear Enable Error Interrupt Register */ - uint8_t R; - struct { - uint8_t NOP:1; - uint8_t CEEI:7; - } B; - } CEEIR; - - union { /* DMA Clear Interrupt Request Register */ - uint8_t R; - struct { - uint8_t NOP:1; - uint8_t CINT:7; - } B; - } CIRQR; - - union { /* DMA Clear error Register */ - uint8_t R; - struct { - uint8_t NOP:1; - uint8_t CERR:7; - } B; - } CER; - - union { /* Set Start Bit Register */ - uint8_t R; - struct { - uint8_t NOP:1; - uint8_t SSB:7; - } B; - } SSBR; - - union { /* Clear Done Status Bit Register */ - uint8_t R; - struct { - uint8_t NOP:1; - uint8_t CDSB:7; - } B; - } CDSBR; - - union { - uint32_t R; - struct { - uint32_t INT63:1; - uint32_t INT62:1; - uint32_t INT61:1; - uint32_t INT60:1; - uint32_t INT59:1; - uint32_t INT58:1; - uint32_t INT57:1; - uint32_t INT56:1; - uint32_t INT55:1; - uint32_t INT54:1; - uint32_t INT53:1; - uint32_t INT52:1; - uint32_t INT51:1; - uint32_t INT50:1; - uint32_t INT49:1; - uint32_t INT48:1; - uint32_t INT47:1; - uint32_t INT46:1; - uint32_t INT45:1; - uint32_t INT44:1; - uint32_t INT43:1; - uint32_t INT42:1; - uint32_t INT41:1; - uint32_t INT40:1; - uint32_t INT39:1; - uint32_t INT38:1; - uint32_t INT37:1; - uint32_t INT36:1; - uint32_t INT35:1; - uint32_t INT34:1; - uint32_t INT33:1; - uint32_t INT32:1; - } B; - } IRQRH; /* DMA Interrupt Request High */ - - union { - uint32_t R; - struct { - uint32_t INT31:1; - uint32_t INT30:1; - uint32_t INT29:1; - uint32_t INT28:1; - uint32_t INT27:1; - uint32_t INT26:1; - uint32_t INT25:1; - uint32_t INT24:1; - uint32_t INT23:1; - uint32_t INT22:1; - uint32_t INT21:1; - uint32_t INT20:1; - uint32_t INT19:1; - uint32_t INT18:1; - uint32_t INT17:1; - uint32_t INT16:1; - uint32_t INT15:1; - uint32_t INT14:1; - uint32_t INT13:1; - uint32_t INT12:1; - uint32_t INT11:1; - uint32_t INT10:1; - uint32_t INT09:1; - uint32_t INT08:1; - uint32_t INT07:1; - uint32_t INT06:1; - uint32_t INT05:1; - uint32_t INT04:1; - uint32_t INT03:1; - uint32_t INT02:1; - uint32_t INT01:1; - uint32_t INT00:1; - } B; - } IRQRL; /* DMA Interrupt Request Low */ - - union { - uint32_t R; - struct { - uint32_t ERR63:1; - uint32_t ERR62:1; - uint32_t ERR61:1; - uint32_t ERR60:1; - uint32_t ERR59:1; - uint32_t ERR58:1; - uint32_t ERR57:1; - uint32_t ERR56:1; - uint32_t ERR55:1; - uint32_t ERR54:1; - uint32_t ERR53:1; - uint32_t ERR52:1; - uint32_t ERR51:1; - uint32_t ERR50:1; - uint32_t ERR49:1; - uint32_t ERR48:1; - uint32_t ERR47:1; - uint32_t ERR46:1; - uint32_t ERR45:1; - uint32_t ERR44:1; - uint32_t ERR43:1; - uint32_t ERR42:1; - uint32_t ERR41:1; - uint32_t ERR40:1; - uint32_t ERR39:1; - uint32_t ERR38:1; - uint32_t ERR37:1; - uint32_t ERR36:1; - uint32_t ERR35:1; - uint32_t ERR34:1; - uint32_t ERR33:1; - uint32_t ERR32:1; - } B; - } ERH; /* DMA Error High */ - - union { - uint32_t R; - struct { - uint32_t ERR31:1; - uint32_t ERR30:1; - uint32_t ERR29:1; - uint32_t ERR28:1; - uint32_t ERR27:1; - uint32_t ERR26:1; - uint32_t ERR25:1; - uint32_t ERR24:1; - uint32_t ERR23:1; - uint32_t ERR22:1; - uint32_t ERR21:1; - uint32_t ERR20:1; - uint32_t ERR19:1; - uint32_t ERR18:1; - uint32_t ERR17:1; - uint32_t ERR16:1; - uint32_t ERR15:1; - uint32_t ERR14:1; - uint32_t ERR13:1; - uint32_t ERR12:1; - uint32_t ERR11:1; - uint32_t ERR10:1; - uint32_t ERR09:1; - uint32_t ERR08:1; - uint32_t ERR07:1; - uint32_t ERR06:1; - uint32_t ERR05:1; - uint32_t ERR04:1; - uint32_t ERR03:1; - uint32_t ERR02:1; - uint32_t ERR01:1; - uint32_t ERR00:1; - } B; - } ERL; /* DMA Error Low */ - -#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567 - union { /* hardware request status high */ - uint32_t R; - struct { - uint32_t HRS63:1; - uint32_t HRS62:1; - uint32_t HRS61:1; - uint32_t HRS60:1; - uint32_t HRS59:1; - uint32_t HRS58:1; - uint32_t HRS57:1; - uint32_t HRS56:1; - uint32_t HRS55:1; - uint32_t HRS54:1; - uint32_t HRS53:1; - uint32_t HRS52:1; - uint32_t HRS51:1; - uint32_t HRS50:1; - uint32_t HRS49:1; - uint32_t HRS48:1; - uint32_t HRS47:1; - uint32_t HRS46:1; - uint32_t HRS45:1; - uint32_t HRS44:1; - uint32_t HRS43:1; - uint32_t HRS42:1; - uint32_t HRS41:1; - uint32_t HRS40:1; - uint32_t HRS39:1; - uint32_t HRS38:1; - uint32_t HRS37:1; - uint32_t HRS36:1; - uint32_t HRS35:1; - uint32_t HRS34:1; - uint32_t HRS33:1; - uint32_t HRS32:1; - } B; - } HRSH; - - union { /* hardware request status low */ - uint32_t R; - struct { - uint32_t HRS31:1; - uint32_t HRS30:1; - uint32_t HRS29:1; - uint32_t HRS28:1; - uint32_t HRS27:1; - uint32_t HRS26:1; - uint32_t HRS25:1; - uint32_t HRS24:1; - uint32_t HRS23:1; - uint32_t HRS22:1; - uint32_t HRS21:1; - uint32_t HRS20:1; - uint32_t HRS19:1; - uint32_t HRS18:1; - uint32_t HRS17:1; - uint32_t HRS16:1; - uint32_t HRS15:1; - uint32_t HRS14:1; - uint32_t HRS13:1; - uint32_t HRS12:1; - uint32_t HRS11:1; - uint32_t HRS10:1; - uint32_t HRS09:1; - uint32_t HRS08:1; - uint32_t HRS07:1; - uint32_t HRS06:1; - uint32_t HRS05:1; - uint32_t HRS04:1; - uint32_t HRS03:1; - uint32_t HRS02:1; - uint32_t HRS01:1; - uint32_t HRS00:1; - } B; - } HRSL; - - uint32_t eDMA_reserved0038[50]; /* 0x0038-0x00FF */ +#ifdef EDMA_HAS_CR_ACTIVE + #define EDMA_CR_ACTIVE (1 << 31) +#endif + + uint32_t ESR; +#define EDMA_ESR_DBE (1 << 0) +#define EDMA_ESR_SBE (1 << 1) +#define EDMA_ESR_SGE (1 << 2) +#define EDMA_ESR_NCE (1 << 3) +#define EDMA_ESR_DOE (1 << 4) +#define EDMA_ESR_DAE (1 << 5) +#define EDMA_ESR_SOE (1 << 6) +#define EDMA_ESR_SAE (1 << 7) +#define EDMA_ESR_ERRCHN_SHIFT (8) +#define EDMA_ESR_ERRCHN_MASK (0x3F << EDMA_ESR_ERRCHN_SHIFT) +#define EDMA_ESR_ERRCHN(val) (((val) << EDMA_ESR_ERRCHN_SHIFT) & EDMA_ESR_ERRCHN_MASK) +#define EDMA_ESR_ERRCHN_GET(reg) (((reg) & EDMA_ESR_ERRCHN_MASK) >> EDMA_ESR_ERRCHN_SHIFT) +#define EDMA_ESR_CPE (1 << 14) +#define EDMA_ESR_GPE (1 << 15) +#ifdef EDMA_HAS_ESR_ECX + #define EDMA_ESR_ECX (1 << 16) +#endif +#define EDMA_ESR_VLD (1 << 31) + + uint32_t ERRQH; +#define EDMA_ERRQH_ERRQ(x) (1 << ((x) - 32)) + + uint32_t ERRQL; +#define EDMA_ERRQL_ERRQ(x) (1 << (x)) + + uint32_t EEIH; +#define EDMA_EEIH_EEI(x) (1 << ((x) - 32)) + + uint32_t EEIL; +#define EDMA_EEIL_EEI(x) (1 << (x)) + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + uint8_t SERQR; + uint8_t CERQR; + uint8_t SEEIR; + uint8_t CEEIR; +#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint8_t CEEIR; + uint8_t SEEIR; + uint8_t CERQR; + uint8_t SERQR; +#endif +#define EDMA_SERQR_NOP (1 << 7) +#define EDMA_SERQR_SAER (1 << 6) +#define EDMA_SERQR_SERQ_SHIFT (0) +#define EDMA_SERQR_SERQ_MASK (0x1F << EDMA_CIRQR_SERQ_SHIFT) +#define EDMA_SERQR_SERQ(val) (((val) << EDMA_CIRQR_SERQ_SHIFT) & EDMA_CIRQR_SERQ_MASK) +#define EDMA_SERQR_SERQ_GET(reg) (((reg) & EDMA_CIRQR_SERQ_MASK) >> EDMA_CIRQR_SERQ_SHIFT) +#define EDMA_CERQR_NOP (1 << 7) +#define EDMA_CERQR_CAER (1 << 6) +#define EDMA_CERQR_CERQ_SHIFT (0) +#define EDMA_CERQR_CERQ_MASK (0x1F << EDMA_CIRQR_CERQ_SHIFT) +#define EDMA_CERQR_CERQ(val) (((val) << EDMA_CIRQR_CERQ_SHIFT) & EDMA_CIRQR_CERQ_MASK) +#define EDMA_CERQR_CERQ_GET(reg) (((reg) & EDMA_CIRQR_CERQ_MASK) >> EDMA_CIRQR_CERQ_SHIFT) +#define EDMA_SEEIR_NOP (1 << 7) +#define EDMA_SEEIR_SAEE (1 << 6) +#define EDMA_SEEIR_SEEI_SHIFT (0) +#define EDMA_SEEIR_SEEI_MASK (0x1F << EDMA_CIRQR_SEEI_SHIFT) +#define EDMA_SEEIR_SEEI(val) (((val) << EDMA_CIRQR_SEEI_SHIFT) & EDMA_CIRQR_SEEI_MASK) +#define EDMA_SEEIR_SEEI_GET(reg) (((reg) & EDMA_CIRQR_SEEI_MASK) >> EDMA_CIRQR_SEEI_SHIFT) +#define EDMA_CEEIR_NOP (1 << 7) +#define EDMA_CEEIR_CAEE (1 << 6) +#define EDMA_CEEIR_CEEI_SHIFT (0) +#define EDMA_CEEIR_CEEI_MASK (0x1F << EDMA_CIRQR_CEEI_SHIFT) +#define EDMA_CEEIR_CEEI(val) (((val) << EDMA_CIRQR_CEEI_SHIFT) & EDMA_CIRQR_CEEI_MASK) +#define EDMA_CEEIR_CEEI_GET(reg) (((reg) & EDMA_CIRQR_CEEI_MASK) >> EDMA_CIRQR_CEEI_SHIFT) + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + uint8_t CIRQR; + uint8_t CER; + uint8_t SSBR; + uint8_t CDSBR; +#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint8_t CDSBR; + uint8_t SSBR; + uint8_t CER; + uint8_t CIRQR; +#endif +#define EDMA_CIRQR_NOP (1 << 7) +#define EDMA_CIRQR_CAIR (1 << 6) +#define EDMA_CIRQR_CINT_SHIFT (0) +#define EDMA_CIRQR_CINT_MASK (0x1F << EDMA_CIRQR_CINT_SHIFT) +#define EDMA_CIRQR_CINT(val) (((val) << EDMA_CIRQR_CINT_SHIFT) & EDMA_CIRQR_CINT_MASK) +#define EDMA_CIRQR_CINT_GET(reg) (((reg) & EDMA_CIRQR_CINT_MASK) >> EDMA_CIRQR_CINT_SHIFT) +#define EDMA_CER_NOP (1 << 7) +#define EDMA_CER_CAEI (1 << 6) +#define EDMA_CER_CERR_SHIFT (0) +#define EDMA_CER_CERR_MASK (0x1F << EDMA_CIRQR_CERR_SHIFT) +#define EDMA_CER_CERR(val) (((val) << EDMA_CIRQR_CERR_SHIFT) & EDMA_CIRQR_CERR_MASK) +#define EDMA_CER_CERR_GET(reg) (((reg) & EDMA_CIRQR_CERR_MASK) >> EDMA_CIRQR_CERR_SHIFT) +#define EDMA_SSBR_NOP (1 << 7) +#define EDMA_SSBR_SAST (1 << 6) +#define EDMA_SSBR_SSB_SHIFT (0) +#define EDMA_SSBR_SSB_MASK (0x1F << EDMA_CIRQR_SSB_SHIFT) +#define EDMA_SSBR_SSB(val) (((val) << EDMA_CIRQR_SSB_SHIFT) & EDMA_CIRQR_SSB_MASK) +#define EDMA_SSBR_SSB_GET(reg) (((reg) & EDMA_CIRQR_SSB_MASK) >> EDMA_CIRQR_SSB_SHIFT) +#define EDMA_CDSBR_NOP (1 << 7) +#define EDMA_CDSBR_CADN (1 << 6) +#define EDMA_CDSBR_CDSB_SHIFT (0) +#define EDMA_CDSBR_CDSB_MASK (0x1F << EDMA_CIRQR_CDSB_SHIFT) +#define EDMA_CDSBR_CDSB(val) (((val) << EDMA_CIRQR_CDSB_SHIFT) & EDMA_CIRQR_CDSB_MASK) +#define EDMA_CDSBR_CDSB_GET(reg) (((reg) & EDMA_CIRQR_CDSB_MASK) >> EDMA_CIRQR_CDSB_SHIFT) + + uint32_t IRQH; +#define EDMA_IRQH_INT(x) (1 << ((x) - 32)) + + uint32_t IRQL; +#define EDMA_IRQL_INT(x) (1 << ((x))) + + uint32_t ERH; +#define EDMA_ERH_ERR(x) (1 << ((x) - 32)) + + uint32_t ERL; +#define EDMA_ERL_ERR(x) (1 << ((x))) + +#ifdef EDMA_HAS_HRS + uint32_t HRS; +#define EDMA_HRSH_HRS(x) (1 << ((x) - 32)) + + uint32_t HRSL; +#define EDMA_HRSL_HRS(x) (1 << ((x))) #else - uint32_t edma_reserved1[52]; + uint32_t reserved0030[2]; #endif - union { - uint8_t R; - struct { - uint8_t ECP:1; -#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567 - uint8_t DPA:1; + uint32_t reserved0038[(0x44-0x38)/4]; + +#ifdef EDMA_HAS_EARS + uint32_t EARSL; +#define EDMA_EARSL_EDREQ(x) (1 << ((x))) /* iMXRT only */ #else - uint8_t:1; + uint32_t reserved0044; +#endif + + uint32_t reserved0048[(0x100-0x48)/4]; + + uint8_t CPR[64]; +#define EDMA_CPR_CHPRI_SHIFT (0) +#define EDMA_CPR_CHPRI_MASK (0xF << EDMA_CPR_CHPRI_SHIFT) +#define EDMA_CPR_CHPRI(val) (((val) << EDMA_CPR_CHPRI_SHIFT) & EDMA_CPR_CHPRI_MASK) +#define EDMA_CPR_CHPRI_GET(reg) (((reg) & EDMA_CPR_CHPRI_MASK) >> EDMA_CPR_CHPRI_SHIFT) +#define EDMA_CPR_GRPPRI_SHIFT (0) +#define EDMA_CPR_GRPPRI_MASK (0xF << EDMA_CPR_GRPPRI_SHIFT) +#define EDMA_CPR_GRPPRI(val) (((val) << EDMA_CPR_GRPPRI_SHIFT) & EDMA_CPR_GRPPRI_MASK) +#define EDMA_CPR_GRPPRI_GET(reg) (((reg) & EDMA_CPR_GRPPRI_MASK) >> EDMA_CPR_GRPPRI_SHIFT) +#ifdef EDMA_HAS_CPR_DPA + #define EDMA_CPR_DPA (1 << 6) #endif - uint8_t GRPPRI:2; - uint8_t CHPRI:4; - } B; - } CPR[64]; - - uint32_t edma_reserved2[944]; - -/****************************************************************************/ -/* DMA2 Transfer Control Descriptor */ -/****************************************************************************/ - struct tcd_t { - uint32_t SADDR; /* source address */ - - /* Source and destination fields */ - union tcd_SDF_tag { - uint32_t R; - struct { - uint16_t SMOD:5; /* source address modulo */ - uint16_t SSIZE:3; /* source transfer size */ - uint16_t DMOD:5; /* destination address modulo */ - uint16_t DSIZE:3; /* destination transfer size */ - int16_t SOFF; /* signed source address offset */ - } B; - } SDF; - - uint32_t NBYTES; /* inner (minor) byte count */ - - int32_t SLAST; /* last destination address adjustment, or - scatter/gather address (if e_sg = 1) */ - - uint32_t DADDR; /* destination address */ - - /* CITER and destination fields */ - union tcd_CDF_tag { - uint32_t R; - struct { - uint16_t CITERE_LINK:1; - uint16_t CITER:15; - int16_t DOFF; /* signed destination address offset */ - } B; - struct { - uint16_t CITERE_LINK:1; - uint16_t CITERLINKCH:6; - uint16_t CITER:9; - int16_t DOFF; - } B_ALT; - struct { - uint16_t CITER; - int16_t DOFF; - } B_NOLINK; - } CDF; - - int32_t DLAST_SGA; - - /* BITER and misc fields */ - union tcd_BMF_tag { - uint32_t R; - struct { - uint32_t BITERE_LINK:1; /* beginning ("major") iteration count */ - uint32_t BITER:15; - uint32_t BWC:2; /* bandwidth control */ - uint32_t MAJORLINKCH:6; /* enable channel-to-channel link */ - uint32_t DONE:1; /* channel done */ - uint32_t ACTIVE:1; /* channel active */ - uint32_t MAJORE_LINK:1; /* enable channel-to-channel link */ - uint32_t E_SG:1; /* enable scatter/gather descriptor */ - uint32_t D_REQ:1; /* disable ipd_req when done */ - uint32_t INT_HALF:1; /* interrupt on citer = (biter >> 1) */ - uint32_t INT_MAJ:1; /* interrupt on major loop completion */ - uint32_t START:1; /* explicit channel start */ - } B; - struct { - uint32_t BITERE_LINK:1; - uint32_t BITERLINKCH:6; - uint32_t BITER:9; - uint32_t BWC:2; - uint32_t MAJORLINKCH:6; - uint32_t DONE:1; - uint32_t ACTIVE:1; - uint32_t MAJORE_LINK:1; - uint32_t E_SG:1; - uint32_t D_REQ:1; - uint32_t INT_HALF:1; - uint32_t INT_MAJ:1; - uint32_t START:1; - } B_ALT; - struct { - uint16_t BITER; - uint16_t BWC:2; - uint16_t MAJORLINKCH:6; - uint16_t DONE:1; - uint16_t ACTIVE:1; - uint16_t MAJORE_LINK:1; - uint16_t E_SG:1; - uint16_t D_REQ:1; - uint16_t INT_HALF:1; - uint16_t INT_MAJ:1; - uint16_t START:1; - } B_NOLINK; - } BMF; - } TCD[64]; /* transfer_control_descriptor */ - }; +#define EDMA_CPR_ECP (1 << 7) + + uint32_t reserved0140[(0x1000-0x140)/4]; + + struct fsl_edma_tcd { + uint32_t SADDR; + uint32_t SDF; +#define EDMA_TCD_SDF_SMOD_SHIFT (27) +#define EDMA_TCD_SDF_SMOD_MASK (0x1F << EDMA_TCD_SDF_SMOD_SHIFT) +#define EDMA_TCD_SDF_SMOD(val) (((val) << EDMA_TCD_SDF_SMOD_SHIFT) & EDMA_TCD_SDF_SMOD_MASK) +#define EDMA_TCD_SDF_SMOD_GET(reg) (((reg) & EDMA_TCD_SDF_SMOD_MASK) >> EDMA_TCD_SDF_SMOD_SHIFT) +#define EDMA_TCD_SDF_SSIZE_SHIFT (24) +#define EDMA_TCD_SDF_SSIZE_MASK (0x7 << EDMA_TCD_SDF_SSIZE_SHIFT) +#define EDMA_TCD_SDF_SSIZE(val) (((val) << EDMA_TCD_SDF_SSIZE_SHIFT) & EDMA_TCD_SDF_SSIZE_MASK) +#define EDMA_TCD_SDF_SSIZE_GET(reg) (((reg) & EDMA_TCD_SDF_SSIZE_MASK) >> EDMA_TCD_SDF_SSIZE_SHIFT) +#define EDMA_TCD_SDF_SSIZE_8BIT EDMA_TCD_SDF_SSIZE(0) +#define EDMA_TCD_SDF_SSIZE_16BIT EDMA_TCD_SDF_SSIZE(1) +#define EDMA_TCD_SDF_SSIZE_32BIT EDMA_TCD_SDF_SSIZE(2) +#define EDMA_TCD_SDF_SSIZE_64BIT EDMA_TCD_SDF_SSIZE(3) +#define EDMA_TCD_SDF_SSIZE_32BYTE EDMA_TCD_SDF_SSIZE(5) +#define EDMA_TCD_SDF_DMOD_SHIFT (19) +#define EDMA_TCD_SDF_DMOD_MASK (0x1F << EDMA_TCD_SDF_DMOD_SHIFT) +#define EDMA_TCD_SDF_DMOD(val) (((val) << EDMA_TCD_SDF_DMOD_SHIFT) & EDMA_TCD_SDF_DMOD_MASK) +#define EDMA_TCD_SDF_DMOD_GET(reg) (((reg) & EDMA_TCD_SDF_DMOD_MASK) >> EDMA_TCD_SDF_DMOD_SHIFT) +#define EDMA_TCD_SDF_DSIZE_SHIFT (16) +#define EDMA_TCD_SDF_DSIZE_MASK (0x7 << EDMA_TCD_SDF_DSIZE_SHIFT) +#define EDMA_TCD_SDF_DSIZE(val) (((val) << EDMA_TCD_SDF_DSIZE_SHIFT) & EDMA_TCD_SDF_DSIZE_MASK) +#define EDMA_TCD_SDF_DSIZE_GET(reg) (((reg) & EDMA_TCD_SDF_DSIZE_MASK) >> EDMA_TCD_SDF_DSIZE_SHIFT) +#define EDMA_TCD_SDF_DSIZE_8BIT EDMA_TCD_SDF_DSIZE(0) +#define EDMA_TCD_SDF_DSIZE_16BIT EDMA_TCD_SDF_DSIZE(1) +#define EDMA_TCD_SDF_DSIZE_32BIT EDMA_TCD_SDF_DSIZE(2) +#define EDMA_TCD_SDF_DSIZE_64BIT EDMA_TCD_SDF_DSIZE(3) +#define EDMA_TCD_SDF_DSIZE_32BYTE EDMA_TCD_SDF_DSIZE(5) +#define EDMA_TCD_SDF_SOFF_SHIFT (0) +#define EDMA_TCD_SDF_SOFF_MASK (0xFFFF << EDMA_TCD_SDF_SOFF_SHIFT) +#define EDMA_TCD_SDF_SOFF(val) (((val) << EDMA_TCD_SDF_SOFF_SHIFT) & EDMA_TCD_SDF_SOFF_MASK) +#define EDMA_TCD_SDF_SOFF_GET(reg) (((reg) & EDMA_TCD_SDF_SOFF_MASK) >> EDMA_TCD_SDF_SOFF_SHIFT) + + uint32_t NBYTES; +#define EDMA_TCD_NBYTES_ALT_NBYTES_SHIFT (0) +#define EDMA_TCD_NBYTES_ALT_NBYTES_MASK (0x3FF << EDMA_TCD_NBYTES_ALT_NBYTES_SHIFT) +#define EDMA_TCD_NBYTES_ALT_NBYTES(val) (((val) << EDMA_TCD_NBYTES_ALT_NBYTES_SHIFT) & EDMA_TCD_NBYTES_ALT_NBYTES_MASK) +#define EDMA_TCD_NBYTES_ALT_MLOFF_SHIFT (10) +#define EDMA_TCD_NBYTES_ALT_MLOFF_MASK (0xFFFFF << EDMA_TCD_NBYTES_ALT_MLOFF_SHIFT) +#define EDMA_TCD_NBYTES_ALT_MLOFF(val) (((val) << EDMA_TCD_NBYTES_ALT_MLOFF_SHIFT) & EDMA_TCD_NBYTES_ALT_MLOFF_MASK) +#define EDMA_TCD_NBYTES_ALT_DMLOE (1 << 30) +#define EDMA_TCD_NBYTES_ALT_SMLOE (1 << 31) + int32_t SLAST; + uint32_t DADDR; + uint32_t CDF; +#define EDMA_TCD_CDF_CITERE_LINK (1 << 31) +#define EDMA_TCD_CDF_CITER_SHIFT (16) +#define EDMA_TCD_CDF_CITER_MASK (0x7FFF << EDMA_TCD_CDF_CITER_SHIFT) +#define EDMA_TCD_CDF_CITER(val) (((val) << EDMA_TCD_CDF_CITER_SHIFT) & EDMA_TCD_CDF_CITER_MASK) +#define EDMA_TCD_CDF_CITER_GET(reg) (((reg) & EDMA_TCD_CDF_CITER_MASK) >> EDMA_TCD_CDF_CITER_SHIFT) +#define EDMA_TCD_CDF_DOFF_SHIFT (0) +#define EDMA_TCD_CDF_DOFF_MASK (0xFFFF << EDMA_TCD_CDF_DOFF_SHIFT) +#define EDMA_TCD_CDF_DOFF(val) (((val) << EDMA_TCD_CDF_DOFF_SHIFT) & EDMA_TCD_CDF_DOFF_MASK) +#define EDMA_TCD_CDF_DOFF_GET(reg) (((reg) & EDMA_TCD_CDF_DOFF_MASK) >> EDMA_TCD_CDF_DOFF_SHIFT) + +#define EDMA_TCD_CDF_ALT_CITERLINKCH_SHIFT (25) +#define EDMA_TCD_CDF_ALT_CITERLINKCH_MASK (0x3F << EDMA_TCD_CDF_ALT_CITERLINKCH_SHIFT) +#define EDMA_TCD_CDF_ALT_CITERLINKCH(val) (((val) << EDMA_TCD_CDF_ALT_CITERLINKCH_SHIFT) & EDMA_TCD_CDF_ALT_CITERLINKCH_MASK) +#define EDMA_TCD_CDF_ALT_CITERLINKCH_GET(reg) (((reg) & EDMA_TCD_CDF_ALT_CITERLINKCH_MASK) >> EDMA_TCD_CDF_ALT_CITERLINKCH_SHIFT) +#define EDMA_TCD_CDF_ALT_CITER_SHIFT (16) +#define EDMA_TCD_CDF_ALT_CITER_MASK (0x1FF << EDMA_TCD_CDF_ALT_CITER_SHIFT) +#define EDMA_TCD_CDF_ALT_CITER(val) (((val) << EDMA_TCD_CDF_ALT_CITER_SHIFT) & EDMA_TCD_CDF_ALT_CITER_MASK) +#define EDMA_TCD_CDF_ALT_CITER_GET(reg) (((reg) & EDMA_TCD_CDF_ALT_CITER_MASK) >> EDMA_TCD_CDF_ALT_CITER_SHIFT) + +#define EDMA_TCD_CDF_NOLINK_CITER_SHIFT (16) +#define EDMA_TCD_CDF_NOLINK_CITER_MASK (0xFFFF << EDMA_TCD_CDF_NOLINK_CITER_SHIFT) +#define EDMA_TCD_CDF_NOLINK_CITER(val) (((val) << EDMA_TCD_CDF_NOLINK_CITER_SHIFT) & EDMA_TCD_CDF_NOLINK_CITER_MASK) +#define EDMA_TCD_CDF_NOLINK_CITER_GET(reg) (((reg) & EDMA_TCD_CDF_NOLINK_CITER_MASK) >> EDMA_TCD_CDF_NOLINK_CITER_SHIFT) + + int32_t DLAST_SGA; + uint32_t BMF; +#define EDMA_TCD_BMF_BITERE_LINK (1 << 31) +#define EDMA_TCD_BMF_BITER_SHIFT (16) +#define EDMA_TCD_BMF_BITER_MASK (0x7FFF << EDMA_TCD_BMF_BITER_SHIFT) +#define EDMA_TCD_BMF_BITER(val) (((val) << EDMA_TCD_BMF_BITER_SHIFT) & EDMA_TCD_BMF_BITER_MASK) +#define EDMA_TCD_BMF_BITER_GET(reg) (((reg) & EDMA_TCD_BMF_BITER_MASK) >> EDMA_TCD_BMF_BITER_SHIFT) +#define EDMA_TCD_BMF_BWC_SHIFT (14) +#define EDMA_TCD_BMF_BWC_MASK (0x3 << EDMA_TCD_BMF_BWC_SHIFT) +#define EDMA_TCD_BMF_BWC(val) (((val) << EDMA_TCD_BMF_BWC_SHIFT) & EDMA_TCD_BMF_BWC_MASK) +#define EDMA_TCD_BMF_BWC_GET(reg) (((reg) & EDMA_TCD_BMF_BWC_MASK) >> EDMA_TCD_BMF_BWC_SHIFT) +#define EDMA_TCD_BMF_MAJORLINKCH_SHIFT (8) +#define EDMA_TCD_BMF_MAJORLINKCH_MASK (0x3F << EDMA_TCD_BMF_MAJORLINKCH_SHIFT) +#define EDMA_TCD_BMF_MAJORLINKCH(val) (((val) << EDMA_TCD_BMF_MAJORLINKCH_SHIFT) & EDMA_TCD_BMF_MAJORLINKCH_MASK) +#define EDMA_TCD_BMF_MAJORLINKCH_GET(reg) (((reg) & EDMA_TCD_BMF_MAJORLINKCH_MASK) >> EDMA_TCD_BMF_MAJORLINKCH_SHIFT) +#define EDMA_TCD_BMF_DONE (1 << 7) +#define EDMA_TCD_BMF_ACTIVE (1 << 6) +#define EDMA_TCD_BMF_MAJORE_LINK (1 << 5) +#define EDMA_TCD_BMF_E_SG (1 << 4) +#define EDMA_TCD_BMF_D_REQ (1 << 3) +#define EDMA_TCD_BMF_INT_HALF (1 << 2) +#define EDMA_TCD_BMF_INT_MAJ (1 << 1) +#define EDMA_TCD_BMF_START (1 << 0) + +#define EDMA_TCD_BMF_ALT_BITERLINKCH_SHIFT (25) +#define EDMA_TCD_BMF_ALT_BITERLINKCH_MASK (0x3F << EDMA_TCD_BMF_ALT_BITERLINKCH_SHIFT) +#define EDMA_TCD_BMF_ALT_BITERLINKCH(val) (((val) << EDMA_TCD_BMF_ALT_BITERLINKCH_SHIFT) & EDMA_TCD_BMF_ALT_BITERLINKCH_MASK) +#define EDMA_TCD_BMF_ALT_BITERLINKCH_GET(reg) (((reg) & EDMA_TCD_BMF_ALT_BITERLINKCH_MASK) >> EDMA_TCD_BMF_ALT_BITERLINKCH_SHIFT) +#define EDMA_TCD_BMF_ALT_BITER_SHIFT (16) +#define EDMA_TCD_BMF_ALT_BITER_MASK (0x1FF << EDMA_TCD_BMF_ALT_BITER_SHIFT) +#define EDMA_TCD_BMF_ALT_BITER(val) (((val) << EDMA_TCD_BMF_ALT_BITER_SHIFT) & EDMA_TCD_BMF_ALT_BITER_MASK) +#define EDMA_TCD_BMF_ALT_BITER_GET(reg) (((reg) & EDMA_TCD_BMF_ALT_BITER_MASK) >> EDMA_TCD_BMF_ALT_BITER_SHIFT) + +#define EDMA_TCD_BMF_NOLINK_BITER_SHIFT (16) +#define EDMA_TCD_BMF_NOLINK_BITER_MASK (0xFFFF << EDMA_TCD_BMF_NOLINK_BITER_SHIFT) +#define EDMA_TCD_BMF_NOLINK_BITER(val) (((val) << EDMA_TCD_BMF_NOLINK_BITER_SHIFT) & EDMA_TCD_BMF_NOLINK_BITER_MASK) +#define EDMA_TCD_BMF_NOLINK_BITER_GET(reg) (((reg) & EDMA_TCD_BMF_NOLINK_BITER_MASK) >> EDMA_TCD_BMF_NOLINK_BITER_SHIFT) + + } TCD[64]; +}; #ifndef __cplusplus - static const struct tcd_t EDMA_TCD_DEFAULT = { - .SADDR = 0, - .SDF = { .R = 0 }, - .NBYTES = 0, - .SLAST = 0, - .DADDR = 0, - .CDF = { .R = 0 }, - .DLAST_SGA = 0, - .BMF = { .R = 0 } - }; +static const struct fsl_edma_tcd EDMA_TCD_DEFAULT = { + .SADDR = 0, + .SDF = 0, + .NBYTES = 0, + .SLAST = 0, + .DADDR = 0, + .CDF = 0, + .DLAST_SGA = 0, + .BMF = 0, +}; #endif /* __cplusplus */ #define EDMA_TCD_BITER_MASK 0x7fff @@ -707,4 +416,4 @@ extern "C" { } #endif /* __cplusplus */ -#endif /* LIBCPU_POWERPC_MPC55XX_REGS_EDMA_H */ +#endif /* LIBBSP_SHARED_FSL_REGS_EDMA_H */ diff --git a/bsps/shared/dev/dma/fsl-edma.c b/bsps/shared/dev/dma/fsl-edma.c index c34624ed10..b3e1bb2fc5 100644 --- a/bsps/shared/dev/dma/fsl-edma.c +++ b/bsps/shared/dev/dma/fsl-edma.c @@ -1,33 +1,47 @@ /** * @file * - * @ingroup RTEMSBSPsPowerPCMPC55XX + * @ingroup RTEMSBSPsSharedFslEDMA * - * @brief Enhanced Direct Memory Access (eDMA). + * @brief Freescale / NXP Enhanced Direct Memory Access (eDMA). */ /* - * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved. + * Copyright (C) 2008-2020 embedded brains GmbH (http://www.embedded-brains.de) * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * <rtems@embedded-brains.de> + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ -#include <mpc55xx/edma.h> -#include <mpc55xx/mpc55xx.h> +#include <fsl/edma.h> +#include <fsl/regs-edma.h> #include <assert.h> #include <bsp.h> #include <bsp/fatal.h> #include <bsp/irq.h> +#ifdef LIBBSP_ARM_IMXRT_BSP_H +#include <MIMXRT1052.h> +#endif #define EDMA_CHANNELS_PER_GROUP 32U @@ -43,32 +57,67 @@ static uint32_t edma_channel_occupation [EDMA_GROUP_COUNT]; static RTEMS_CHAIN_DEFINE_EMPTY(edma_channel_chain); -static unsigned edma_channel_index_of_tcd(volatile struct tcd_t *edma_tcd) +volatile struct fsl_edma *edma_inst[EDMA_MODULE_COUNT] = { +#ifdef LIBBSP_ARM_IMXRT_BSP_H + (volatile struct fsl_edma *) DMA0, +#else /* ! LIBBSP_ARM_IMXRT_BSP_H */ + #if EDMA_MODULE_COUNT == 1 + (volatile struct fsl_edma *) &EDMA, + #elif EDMA_MODULE_COUNT == 2 + (volatile struct fsl_edma *) &EDMA_A, + (volatile struct fsl_edma *) &EDMA_B, + #else + #error "unsupported module count" + #endif +#endif /* LIBBSP_ARM_IMXRT_BSP_H */ +}; + +unsigned fsl_edma_channel_index_of_tcd( + volatile struct fsl_edma_tcd *edma_tcd +) { - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); + volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd); unsigned channel = edma_tcd - &edma->TCD[0]; -#if EDMA_MODULE_COUNT == 1 - return channel; -#elif EDMA_MODULE_COUNT == 2 - return channel + (&EDMA_A == edma ? 0 : EDMA_CHANNELS_PER_MODULE); -#else +#if EDMA_MODULE_COUNT == 2 + if (edma_inst[1] == edma) { + channel += EDMA_CHANNELS_PER_MODULE; + } +#elif EDMA_MODULE_COUNT > 2 #error "unsupported module count" #endif + + return channel; } -static volatile struct EDMA_tag *edma_get_regs_by_module(unsigned module) +volatile struct fsl_edma_tcd *fsl_edma_tcd_of_channel_index(unsigned index) { -#if EDMA_MODULE_COUNT == 1 - return &EDMA; -#elif EDMA_MODULE_COUNT == 2 - return module == 0 ? &EDMA_A : &EDMA_B; -#else - #error "unsupported module count" -#endif + unsigned module = index / EDMA_CHANNELS_PER_MODULE; + unsigned channel = index % EDMA_CHANNELS_PER_MODULE; + + return &edma_inst[module]->TCD[channel]; } -static uint32_t edma_bit_array_set(unsigned channel, uint32_t *bit_array) +static volatile struct fsl_edma *fsl_edma_get_regs_by_module(unsigned module) +{ + return edma_inst[module]; +} + +static uint32_t fsl_edma_bit_array_get_lowest_0(uint32_t *bit_array) +{ + unsigned array; + + for (array = 0; array < EDMA_MODULE_COUNT; ++array) { + uint32_t first_0 = __builtin_ffs(~(bit_array[array])); + if (first_0 > 0) { + return (first_0 - 1) + array * 32; + } + } + + return UINT32_MAX; +} + +static uint32_t fsl_edma_bit_array_set(unsigned channel, uint32_t *bit_array) { unsigned array = channel / 32; uint32_t bit = 1U << (channel % 32); @@ -79,7 +128,7 @@ static uint32_t edma_bit_array_set(unsigned channel, uint32_t *bit_array) return previous; } -static uint32_t edma_bit_array_clear(unsigned channel, uint32_t *bit_array) +static uint32_t fsl_edma_bit_array_clear(unsigned channel, uint32_t *bit_array) { unsigned array = channel / 32; uint32_t bit = 1U << (channel % 32); @@ -90,11 +139,11 @@ static uint32_t edma_bit_array_clear(unsigned channel, uint32_t *bit_array) return previous; } -static void edma_interrupt_handler(void *arg) +static void fsl_edma_interrupt_handler(void *arg) { - edma_channel_context *ctx = arg; + fsl_edma_channel_context *ctx = arg; - mpc55xx_edma_clear_interrupts(ctx->edma_tcd); + fsl_edma_clear_interrupts(ctx->edma_tcd); (*ctx->done)(ctx, 0); } @@ -103,39 +152,40 @@ static void edma_interrupt_error_handler(void *arg) { rtems_chain_control *chain = &edma_channel_chain; rtems_chain_node *node = rtems_chain_first(chain); + uint32_t error_channels [] = { #if EDMA_GROUP_COUNT >= 1 - EDMA.ERL.R + edma_inst[0]->ERL, #endif #if EDMA_GROUP_COUNT >= 2 - , EDMA.ERH.R + edma_inst[0]->ERH, #endif #if EDMA_GROUP_COUNT >= 3 - , EDMA_B.ERL.R + edma_inst[1]->ERL, #endif }; uint32_t error_status [] = { #if EDMA_GROUP_COUNT >= 1 - EDMA.ESR.R + edma_inst[0]->ESR, #endif #if EDMA_GROUP_COUNT >= 3 - , EDMA_B.ESR.R + edma_inst[1]->ESR, #endif }; #if EDMA_GROUP_COUNT >= 1 - EDMA.ERL.R = error_channels [0]; + edma_inst[0]->ERL = error_channels [0]; #endif #if EDMA_GROUP_COUNT >= 2 - EDMA.ERH.R = error_channels [1]; + edma_inst[0]->ERH = error_channels [1]; #endif #if EDMA_GROUP_COUNT >= 3 - EDMA_B.ERL.R = error_channels [2]; + edma_inst[1]->ERL = error_channels [2]; #endif while (!rtems_chain_is_tail(chain, node)) { - edma_channel_context *ctx = (edma_channel_context *) node; - unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd); + fsl_edma_channel_context *ctx = (fsl_edma_channel_context *) node; + unsigned channel_index = fsl_edma_channel_index_of_tcd(ctx->edma_tcd); unsigned group_index = EDMA_GROUP_INDEX(channel_index); unsigned group_bit = EDMA_GROUP_BIT(channel_index); @@ -149,7 +199,7 @@ static void edma_interrupt_error_handler(void *arg) } } -void mpc55xx_edma_init(void) +void fsl_edma_init(void) { rtems_status_code sc = RTEMS_SUCCESSFUL; unsigned channel_remaining = EDMA_CHANNEL_COUNT; @@ -157,7 +207,7 @@ void mpc55xx_edma_init(void) unsigned group = 0; for (module = 0; module < EDMA_MODULE_COUNT; ++module) { - volatile struct EDMA_tag *edma = edma_get_regs_by_module(module); + volatile struct fsl_edma *edma = fsl_edma_get_regs_by_module(module); unsigned channel_count = channel_remaining < EDMA_CHANNELS_PER_MODULE ? channel_remaining : EDMA_CHANNELS_PER_MODULE; unsigned channel = 0; @@ -165,32 +215,36 @@ void mpc55xx_edma_init(void) channel_remaining -= channel_count; /* Disable requests */ - edma->CERQR.B.CERQ = 0x40; + edma->CERQR = EDMA_CERQR_CAER; /* Arbitration mode: group round robin, channel fixed */ - edma->CR.B.ERGA = 1; - edma->CR.B.ERCA = 0; + edma->CR |= EDMA_CR_ERGA; + edma->CR &= ~EDMA_CR_ERCA; +#if defined(BSP_FSL_EDMA_EMLM) + edma->CR |= EDMA_CR_EMLM; +#endif for (channel = 0; channel < channel_count; ++channel) { - volatile struct tcd_t *tcd = &edma->TCD [channel]; - edma->CPR [channel].R = 0x80U | (channel & 0xfU); + volatile struct fsl_edma_tcd *tcd = &edma->TCD [channel]; + edma->CPR [channel] = EDMA_CPR_ECP | EDMA_CPR_CHPRI(channel); /* Initialize TCD, stop channel first */ - tcd->BMF.R = 0; + tcd->BMF = 0; tcd->SADDR = 0; - tcd->SDF.R = 0; + tcd->SDF = 0; tcd->NBYTES = 0; tcd->SLAST = 0; tcd->DADDR = 0; - tcd->CDF.R = 0; + tcd->CDF = 0; tcd->DLAST_SGA = 0; } /* Clear interrupt requests */ - edma->CIRQR.B.CINT = 0x40; - edma->CER.B.CERR = 0x40; + edma->CIRQR = EDMA_CIRQR_CAIR; + edma->CER = EDMA_CER_CAEI; } for (group = 0; group < EDMA_GROUP_COUNT; ++group) { +#if defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H) sc = mpc55xx_interrupt_handler_install( MPC55XX_IRQ_EDMA_ERROR(group), "eDMA Error", @@ -199,23 +253,61 @@ void mpc55xx_edma_init(void) edma_interrupt_error_handler, NULL ); +#elif defined(LIBBSP_ARM_IMXRT_BSP_H) + sc = rtems_interrupt_handler_install( + DMA_ERROR_IRQn, + "eDMA Error", + RTEMS_INTERRUPT_UNIQUE, + edma_interrupt_error_handler, + NULL + ); +#else + #error "Unknown chip" +#endif if (sc != RTEMS_SUCCESSFUL) { bsp_fatal(MPC55XX_FATAL_EDMA_IRQ_INSTALL); } } } -rtems_status_code mpc55xx_edma_obtain_channel_by_tcd( - volatile struct tcd_t *edma_tcd +static rtems_status_code fsl_edma_obtain_next_free_channel_and_get_tcd( + volatile struct fsl_edma_tcd **edma_tcd +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + unsigned channel_index; + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + channel_index = fsl_edma_bit_array_get_lowest_0(&edma_channel_occupation [0]); + if (channel_index > EDMA_CHANNEL_COUNT) { + sc = RTEMS_RESOURCE_IN_USE; + } else { + fsl_edma_bit_array_set( + channel_index, + &edma_channel_occupation [0] + ); + } + rtems_interrupt_enable(level); + + if (sc == RTEMS_SUCCESSFUL) { + *edma_tcd = fsl_edma_tcd_of_channel_index(channel_index); + } + + return sc; +} + +rtems_status_code fsl_edma_obtain_channel_by_tcd( + volatile struct fsl_edma_tcd *edma_tcd ) { rtems_status_code sc = RTEMS_SUCCESSFUL; - unsigned channel_index = edma_channel_index_of_tcd(edma_tcd); + unsigned channel_index = fsl_edma_channel_index_of_tcd(edma_tcd); rtems_interrupt_level level; uint32_t channel_occupation; rtems_interrupt_disable(level); - channel_occupation = edma_bit_array_set( + channel_occupation = fsl_edma_bit_array_set( channel_index, &edma_channel_occupation [0] ); @@ -228,59 +320,108 @@ rtems_status_code mpc55xx_edma_obtain_channel_by_tcd( return sc; } -void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd) +void fsl_edma_release_channel_by_tcd(volatile struct fsl_edma_tcd *edma_tcd) { - unsigned channel_index = edma_channel_index_of_tcd(edma_tcd); + unsigned channel_index = fsl_edma_channel_index_of_tcd(edma_tcd); rtems_interrupt_level level; rtems_interrupt_disable(level); - edma_bit_array_clear(channel_index, &edma_channel_occupation [0]); + fsl_edma_bit_array_clear(channel_index, &edma_channel_occupation [0]); rtems_interrupt_enable(level); - mpc55xx_edma_disable_hardware_requests(edma_tcd); - mpc55xx_edma_disable_error_interrupts(edma_tcd); + fsl_edma_disable_hardware_requests(edma_tcd); + fsl_edma_disable_error_interrupts(edma_tcd); } -rtems_status_code mpc55xx_edma_obtain_channel( - edma_channel_context *ctx, +static rtems_status_code fsl_edma_install_obtained_channel( + fsl_edma_channel_context *ctx, unsigned irq_priority ) { - rtems_status_code sc = mpc55xx_edma_obtain_channel_by_tcd(ctx->edma_tcd); + unsigned channel_index = fsl_edma_channel_index_of_tcd(ctx->edma_tcd); + rtems_status_code sc; + +#if defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H) + sc = fsl_interrupt_handler_install( + MPC55XX_IRQ_EDMA(channel_index), + "eDMA Channel", + RTEMS_INTERRUPT_SHARED, + irq_priority, + fsl_edma_interrupt_handler, + ctx + ); +#elif defined(LIBBSP_ARM_IMXRT_BSP_H) + sc = rtems_interrupt_handler_install( + DMA0_DMA16_IRQn + (channel_index % 16), + "eDMA Channel", + RTEMS_INTERRUPT_SHARED, + fsl_edma_interrupt_handler, + ctx + ); +#else + #error "Unknown chip" +#endif if (sc == RTEMS_SUCCESSFUL) { - unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd); + rtems_chain_prepend(&edma_channel_chain, &ctx->node); + fsl_edma_enable_error_interrupts(ctx->edma_tcd); + } else { + fsl_edma_release_channel_by_tcd(ctx->edma_tcd); + sc = RTEMS_IO_ERROR; + } - sc = mpc55xx_interrupt_handler_install( - MPC55XX_IRQ_EDMA(channel_index), - "eDMA Channel", - RTEMS_INTERRUPT_SHARED, - irq_priority, - edma_interrupt_handler, - ctx + return sc; +} + +rtems_status_code fsl_edma_obtain_channel( + fsl_edma_channel_context *ctx, + unsigned irq_priority +) +{ + rtems_status_code sc = fsl_edma_obtain_channel_by_tcd(ctx->edma_tcd); + if (sc == RTEMS_SUCCESSFUL) { + sc = fsl_edma_install_obtained_channel(ctx, irq_priority); + } + + return sc; +} + +rtems_status_code fsl_edma_obtain_next_free_channel( + fsl_edma_channel_context *ctx +) +{ + rtems_status_code sc; + + sc = fsl_edma_obtain_next_free_channel_and_get_tcd(&ctx->edma_tcd); + if (sc == RTEMS_SUCCESSFUL) { + sc = fsl_edma_install_obtained_channel(ctx, +#ifdef LIBBSP_POWERPC_MPC55XXEVB_BSP_H + MPC55XX_INTC_DEFAULT_PRIORITY +#else + 0 +#endif ); - if (sc == RTEMS_SUCCESSFUL) { - rtems_chain_prepend(&edma_channel_chain, &ctx->node); - mpc55xx_edma_enable_error_interrupts(ctx->edma_tcd); - } else { - mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd); - sc = RTEMS_IO_ERROR; - } } return sc; } -void mpc55xx_edma_release_channel(edma_channel_context *ctx) +void fsl_edma_release_channel(fsl_edma_channel_context *ctx) { rtems_status_code sc = RTEMS_SUCCESSFUL; - unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd); + unsigned channel_index = fsl_edma_channel_index_of_tcd(ctx->edma_tcd); - mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd); + fsl_edma_release_channel_by_tcd(ctx->edma_tcd); rtems_chain_extract(&ctx->node); sc = rtems_interrupt_handler_remove( +#if defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H) MPC55XX_IRQ_EDMA(channel_index), - edma_interrupt_handler, +#elif defined(LIBBSP_ARM_IMXRT_BSP_H) + DMA0_DMA16_IRQn + (channel_index % 16), +#else + #error "Unknown chip" +#endif + fsl_edma_interrupt_handler, ctx ); if (sc != RTEMS_SUCCESSFUL) { @@ -288,42 +429,42 @@ void mpc55xx_edma_release_channel(edma_channel_context *ctx) } } -void mpc55xx_edma_copy( - volatile struct tcd_t *edma_tcd, - const struct tcd_t *source_tcd +void fsl_edma_copy( + volatile struct fsl_edma_tcd *edma_tcd, + const struct fsl_edma_tcd *source_tcd ) { /* Clear DONE flag */ - edma_tcd->BMF.R = 0; + edma_tcd->BMF = 0; edma_tcd->SADDR = source_tcd->SADDR; - edma_tcd->SDF.R = source_tcd->SDF.R; + edma_tcd->SDF = source_tcd->SDF; edma_tcd->NBYTES = source_tcd->NBYTES; edma_tcd->SLAST = source_tcd->SLAST; edma_tcd->DADDR = source_tcd->DADDR; - edma_tcd->CDF.R = source_tcd->CDF.R; + edma_tcd->CDF = source_tcd->CDF; edma_tcd->DLAST_SGA = source_tcd->DLAST_SGA; - edma_tcd->BMF.R = source_tcd->BMF.R; + edma_tcd->BMF = source_tcd->BMF; } -void mpc55xx_edma_copy_and_enable_hardware_requests( - volatile struct tcd_t *edma_tcd, - const struct tcd_t *source_tcd +void fsl_edma_copy_and_enable_hardware_requests( + volatile struct fsl_edma_tcd *edma_tcd, + const struct fsl_edma_tcd *source_tcd ) { - mpc55xx_edma_copy(edma_tcd, source_tcd); - mpc55xx_edma_enable_hardware_requests(edma_tcd); + fsl_edma_copy(edma_tcd, source_tcd); + fsl_edma_enable_hardware_requests(edma_tcd); } -void mpc55xx_edma_sg_link( - volatile struct tcd_t *edma_tcd, - const struct tcd_t *source_tcd +void fsl_edma_sg_link( + volatile struct fsl_edma_tcd *edma_tcd, + const struct fsl_edma_tcd *source_tcd ) { edma_tcd->DLAST_SGA = (int32_t) source_tcd; - edma_tcd->BMF.B.E_SG = 1; + edma_tcd->BMF |= EDMA_TCD_BMF_E_SG; - if (!edma_tcd->BMF.B.E_SG) { - mpc55xx_edma_copy(edma_tcd, source_tcd); + if ((edma_tcd->BMF & EDMA_TCD_BMF_E_SG) == 0) { + fsl_edma_copy(edma_tcd, source_tcd); } } diff --git a/spec/build/bsps/arm/imxrt/bspimxrt.yml b/spec/build/bsps/arm/imxrt/bspimxrt.yml index 30f7927f21..be4a4bb566 100644 --- a/spec/build/bsps/arm/imxrt/bspimxrt.yml +++ b/spec/build/bsps/arm/imxrt/bspimxrt.yml @@ -119,6 +119,8 @@ links: - role: build-dependency uid: ../../optconsoleirq - role: build-dependency + uid: optfsledmaemlm +- role: build-dependency uid: optlinkcmds - role: build-dependency uid: optmemflashcfgsz diff --git a/spec/build/bsps/arm/imxrt/optfsledmaemlm.yml b/spec/build/bsps/arm/imxrt/optfsledmaemlm.yml new file mode 100644 index 0000000000..80c840373d --- /dev/null +++ b/spec/build/bsps/arm/imxrt/optfsledmaemlm.yml @@ -0,0 +1,16 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +actions: +- get-boolean: null +- define-condition: null +build-type: option +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +default: true +default-by-variant: [] +description: | + Enable the minor loop mapping of the Freescale EDMA. +enabled-by: true +format: '{}' +links: [] +name: BSP_FSL_EDMA_EMLM +type: build diff --git a/spec/build/bsps/obj.yml b/spec/build/bsps/obj.yml index b598d54d16..abed6bc76f 100644 --- a/spec/build/bsps/obj.yml +++ b/spec/build/bsps/obj.yml @@ -28,6 +28,10 @@ install: source: - bsps/include/ofw/ofw.h - bsps/include/ofw/ofw_compat.h +- destination: ${BSP_INCLUDEDIR}/fsl + source: + - bsps/include/fsl/edma.h + - bsps/include/fsl/regs-edma.h - destination: ${BSP_INCLUDEDIR}/libchip source: - bsps/include/libchip/ata.h @@ -72,6 +76,7 @@ links: source: - bsps/shared/dev/display/disp_hcms29xx.c - bsps/shared/dev/display/font_hcms29xx.c +- bsps/shared/dev/dma/fsl-edma.c - bsps/shared/dev/i2c/i2c-2b-eeprom.c - bsps/shared/dev/i2c/i2c-ds1621.c - bsps/shared/dev/i2c/i2c-sc620.c |