forked from Imagelibrary/rtems
bsps/shared: Copy fsl-edma from mpc55xx
This is a preparation for making the driver universal. Update #4180
This commit is contained in:
329
bsps/include/fsl/edma.h
Normal file
329
bsps/include/fsl/edma.h
Normal file
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSBSPsPowerPCMPC55XX
|
||||
*
|
||||
* @brief Enhanced Direct Memory Access (eDMA).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef LIBCPU_POWERPC_MPC55XX_EDMA_H
|
||||
#define LIBCPU_POWERPC_MPC55XX_EDMA_H
|
||||
|
||||
#include <mpc55xx/regs.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/chain.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if MPC55XX_CHIP_FAMILY == 551
|
||||
#define EDMA_CHANNEL_COUNT 16U
|
||||
#elif MPC55XX_CHIP_FAMILY == 564
|
||||
#define EDMA_CHANNEL_COUNT 16U
|
||||
#elif MPC55XX_CHIP_FAMILY == 567
|
||||
#define EDMA_CHANNEL_COUNT 96U
|
||||
#else
|
||||
#define EDMA_CHANNEL_COUNT 64U
|
||||
#endif
|
||||
|
||||
#define EDMA_MODULE_COUNT ((EDMA_CHANNEL_COUNT + 63U) / 64U)
|
||||
|
||||
#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"
|
||||
#endif
|
||||
|
||||
/* FIXME: These values are only valid for the MPC5566 and MPC5674F */
|
||||
typedef enum {
|
||||
EDMA_EQADC_A_FISR0_CFFF0 = 0,
|
||||
EDMA_EQADC_A_FISR0_RFDF0 = 1,
|
||||
EDMA_EQADC_A_FISR1_CFFF1 = 2,
|
||||
EDMA_EQADC_A_FISR1_RFDF1 = 3,
|
||||
EDMA_EQADC_A_FISR2_CFFF2 = 4,
|
||||
EDMA_EQADC_A_FISR2_RFDF2 = 5,
|
||||
EDMA_EQADC_A_FISR3_CFFF3 = 6,
|
||||
EDMA_EQADC_A_FISR3_RFDF3 = 7,
|
||||
EDMA_EQADC_A_FISR4_CFFF4 = 8,
|
||||
EDMA_EQADC_A_FISR4_RFDF4 = 9,
|
||||
EDMA_EQADC_A_FISR5_CFFF5 = 10,
|
||||
EDMA_EQADC_A_FISR5_RFDF5 = 11,
|
||||
EDMA_DSPI_B_SR_TFFF = 12,
|
||||
EDMA_DSPI_B_SR_RFDF = 13,
|
||||
EDMA_DSPI_C_SR_TFFF = 14,
|
||||
EDMA_DSPI_C_SR_RFDF = 15,
|
||||
EDMA_DSPI_D_SR_TFFF = 16,
|
||||
EDMA_DSPI_D_SR_RFDF = 17,
|
||||
EDMA_ESCI_A_COMBTX = 18,
|
||||
EDMA_ESCI_A_COMBRX = 19,
|
||||
EDMA_EMIOS_GFR_F0 = 20,
|
||||
EDMA_EMIOS_GFR_F1 = 21,
|
||||
EDMA_EMIOS_GFR_F2 = 22,
|
||||
EDMA_EMIOS_GFR_F3 = 23,
|
||||
EDMA_EMIOS_GFR_F4 = 24,
|
||||
EDMA_EMIOS_GFR_F8 = 25,
|
||||
EDMA_EMIOS_GFR_F9 = 26,
|
||||
EDMA_ETPU_CDTRSR_A_DTRS0 = 27,
|
||||
EDMA_ETPU_CDTRSR_A_DTRS1 = 28,
|
||||
EDMA_ETPU_CDTRSR_A_DTRS2 = 29,
|
||||
EDMA_ETPU_CDTRSR_A_DTRS14 = 30,
|
||||
EDMA_ETPU_CDTRSR_A_DTRS15 = 31,
|
||||
EDMA_DSPI_A_SR_TFFF = 32,
|
||||
EDMA_DSPI_A_SR_RFDF = 33,
|
||||
EDMA_ESCI_B_COMBTX = 34,
|
||||
EDMA_ESCI_B_COMBRX = 35,
|
||||
EDMA_EMIOS_GFR_F6 = 36,
|
||||
EDMA_EMIOS_GFR_F7 = 37,
|
||||
EDMA_EMIOS_GFR_F10 = 38,
|
||||
EDMA_EMIOS_GFR_F11 = 39,
|
||||
EDMA_EMIOS_GFR_F16 = 40,
|
||||
EDMA_EMIOS_GFR_F17 = 41,
|
||||
EDMA_EMIOS_GFR_F18 = 42,
|
||||
EDMA_EMIOS_GFR_F19 = 43,
|
||||
EDMA_ETPU_CDTRSR_A_DTRS12 = 44,
|
||||
EDMA_ETPU_CDTRSR_A_DTRS13 = 45,
|
||||
EDMA_ETPU_CDTRSR_A_DTRS28 = 46,
|
||||
EDMA_ETPU_CDTRSR_A_DTRS29 = 47,
|
||||
EDMA_SIU_EISR_EIF0 = 48,
|
||||
EDMA_SIU_EISR_EIF1 = 49,
|
||||
EDMA_SIU_EISR_EIF2 = 50,
|
||||
EDMA_SIU_EISR_EIF3 = 51,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS0 = 52,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS1 = 53,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS2 = 54,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS3 = 55,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS12 = 56,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS13 = 57,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS14 = 58,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS15 = 59,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS28 = 60,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS29 = 61,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS30 = 62,
|
||||
EDMA_ETPU_CDTRSR_B_DTRS31 = 63
|
||||
#if MPC55XX_CHIP_FAMILY == 567
|
||||
,
|
||||
EDMA_EQADC_B_FISR0_CFFF0 = 64 + 0,
|
||||
EDMA_EQADC_B_FISR0_RFDF0 = 64 + 1,
|
||||
EDMA_EQADC_B_FISR1_CFFF1 = 64 + 2,
|
||||
EDMA_EQADC_B_FISR1_RFDF1 = 64 + 3,
|
||||
EDMA_EQADC_B_FISR2_CFFF2 = 64 + 4,
|
||||
EDMA_EQADC_B_FISR2_RFDF2 = 64 + 5,
|
||||
EDMA_EQADC_B_FISR3_CFFF3 = 64 + 6,
|
||||
EDMA_EQADC_B_FISR3_RFDF3 = 64 + 7,
|
||||
EDMA_EQADC_B_FISR4_CFFF4 = 64 + 8,
|
||||
EDMA_EQADC_B_FISR4_RFDF4 = 64 + 9,
|
||||
EDMA_EQADC_B_FISR5_CFFF5 = 64 + 10,
|
||||
EDMA_EQADC_B_FISR5_RFDF5 = 64 + 11,
|
||||
EDMA_DECFILTER_A_IB = 64 + 12,
|
||||
EDMA_DECFILTER_A_OB = 64 + 13,
|
||||
EDMA_DECFILTER_B_IB = 64 + 14,
|
||||
EDMA_DECFILTER_B_OB = 64 + 15,
|
||||
EDMA_DECFILTER_C_IB = 64 + 16,
|
||||
EDMA_DECFILTER_C_OB = 64 + 17,
|
||||
EDMA_DECFILTER_D_IB = 64 + 18,
|
||||
EDMA_DECFILTER_D_OB = 64 + 19,
|
||||
EDMA_DECFILTER_E_IB = 64 + 20,
|
||||
EDMA_DECFILTER_E_OB = 64 + 21,
|
||||
EDMA_DECFILTER_F_IB = 64 + 22,
|
||||
EDMA_DECFILTER_F_OB = 64 + 23,
|
||||
EDMA_DECFILTER_G_IB = 64 + 24,
|
||||
EDMA_DECFILTER_G_OB = 64 + 25,
|
||||
EDMA_DECFILTER_H_IB = 64 + 26,
|
||||
EDMA_DECFILTER_H_OB = 64 + 27
|
||||
#endif
|
||||
} edma_channel;
|
||||
|
||||
typedef struct edma_channel_context {
|
||||
rtems_chain_node node;
|
||||
volatile struct tcd_t *edma_tcd;
|
||||
void (*done)(struct edma_channel_context *, uint32_t);
|
||||
} edma_channel_context;
|
||||
|
||||
void mpc55xx_edma_init(void);
|
||||
|
||||
/**
|
||||
* @brief Obtains an eDMA channel.
|
||||
*
|
||||
* @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
|
||||
);
|
||||
|
||||
void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd);
|
||||
|
||||
/**
|
||||
* @brief Obtains an eDMA channel and registers the channel context.
|
||||
*
|
||||
* 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 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,
|
||||
unsigned irq_priority
|
||||
);
|
||||
|
||||
void mpc55xx_edma_release_channel(edma_channel_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief Copies a source TCD to an eDMA TCD.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Copies a source TCD to an eDMA TCD and enables hardware requests.
|
||||
*
|
||||
* 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 mpc55xx_edma_sg_link(
|
||||
volatile struct tcd_t *edma_tcd,
|
||||
const struct tcd_t *source_tcd
|
||||
);
|
||||
|
||||
static inline volatile struct EDMA_tag *mpc55xx_edma_by_tcd(
|
||||
volatile struct tcd_t *edma_tcd
|
||||
)
|
||||
{
|
||||
return (volatile struct EDMA_tag *)
|
||||
((uintptr_t) edma_tcd & ~(uintptr_t) 0x1fff);
|
||||
}
|
||||
|
||||
static inline unsigned mpc55xx_edma_channel_by_tcd(
|
||||
volatile struct tcd_t *edma_tcd
|
||||
)
|
||||
{
|
||||
volatile struct EDMA_tag *edma = mpc55xx_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
|
||||
)
|
||||
{
|
||||
volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
|
||||
unsigned channel = edma_tcd - &edma->TCD[0];
|
||||
|
||||
edma->SERQR.R = (uint8_t) channel;
|
||||
}
|
||||
|
||||
static inline void mpc55xx_edma_disable_hardware_requests(
|
||||
volatile struct tcd_t *edma_tcd
|
||||
)
|
||||
{
|
||||
volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
|
||||
unsigned channel = edma_tcd - &edma->TCD[0];
|
||||
|
||||
edma->CERQR.R = (uint8_t) channel;
|
||||
}
|
||||
|
||||
static inline void mpc55xx_edma_enable_error_interrupts(
|
||||
volatile struct tcd_t *edma_tcd
|
||||
)
|
||||
{
|
||||
volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
|
||||
unsigned channel = edma_tcd - &edma->TCD[0];
|
||||
|
||||
edma->SEEIR.R = (uint8_t) channel;
|
||||
}
|
||||
|
||||
static inline void mpc55xx_edma_disable_error_interrupts(
|
||||
volatile struct tcd_t *edma_tcd
|
||||
)
|
||||
{
|
||||
volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
|
||||
unsigned channel = edma_tcd - &edma->TCD[0];
|
||||
|
||||
edma->CEEIR.R = (uint8_t) channel;
|
||||
}
|
||||
|
||||
static inline void mpc55xx_edma_set_start(
|
||||
volatile struct tcd_t *edma_tcd
|
||||
)
|
||||
{
|
||||
volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
|
||||
unsigned channel = edma_tcd - &edma->TCD[0];
|
||||
|
||||
edma->SSBR.R = (uint8_t) channel;
|
||||
}
|
||||
|
||||
static inline void mpc55xx_edma_clear_done(
|
||||
volatile struct tcd_t *edma_tcd
|
||||
)
|
||||
{
|
||||
volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
|
||||
unsigned channel = edma_tcd - &edma->TCD[0];
|
||||
|
||||
edma->CDSBR.R = (uint8_t) channel;
|
||||
}
|
||||
|
||||
static inline void mpc55xx_edma_clear_interrupts(
|
||||
volatile struct tcd_t *edma_tcd
|
||||
)
|
||||
{
|
||||
volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
|
||||
unsigned channel = edma_tcd - &edma->TCD[0];
|
||||
|
||||
edma->CIRQR.R = (uint8_t) channel;
|
||||
}
|
||||
|
||||
static inline bool mpc55xx_edma_is_done(
|
||||
volatile struct tcd_t *edma_tcd
|
||||
)
|
||||
{
|
||||
return edma_tcd->BMF.B.DONE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBCPU_POWERPC_MPC55XX_EDMA_H */
|
||||
710
bsps/include/fsl/regs-edma.h
Normal file
710
bsps/include/fsl/regs-edma.h
Normal file
@@ -0,0 +1,710 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSBSPsPowerPCMPC55XX
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Copyright:
|
||||
* Freescale Semiconductor, INC. All Rights Reserved.
|
||||
* You are hereby granted a copyright license to use, modify, and
|
||||
* distribute the SOFTWARE so long as this entire notice is
|
||||
* retained without alteration in any modified and/or redistributed
|
||||
* versions, and that such modified versions are clearly identified
|
||||
* as such. No licenses are granted by implication, estoppel or
|
||||
* otherwise under any patents or trademarks of Freescale
|
||||
* Semiconductor, Inc. This software is provided on an "AS IS"
|
||||
* basis and without warranty.
|
||||
*
|
||||
* To the maximum extent permitted by applicable law, Freescale
|
||||
* Semiconductor DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
|
||||
* REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
|
||||
* AND ANY ACCOMPANYING WRITTEN MATERIALS.
|
||||
*
|
||||
* To the maximum extent permitted by applicable law, IN NO EVENT
|
||||
* SHALL Freescale Semiconductor BE LIABLE FOR ANY DAMAGES WHATSOEVER
|
||||
* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
|
||||
* BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER
|
||||
* PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
|
||||
*
|
||||
* Freescale Semiconductor assumes no responsibility for the
|
||||
* maintenance and support of this software
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
#ifndef LIBCPU_POWERPC_MPC55XX_REGS_EDMA_H
|
||||
#define LIBCPU_POWERPC_MPC55XX_REGS_EDMA_H
|
||||
|
||||
#include <stdint.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;
|
||||
#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;
|
||||
#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;
|
||||
#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 */
|
||||
#else
|
||||
uint32_t edma_reserved1[52];
|
||||
#endif
|
||||
|
||||
union {
|
||||
uint8_t R;
|
||||
struct {
|
||||
uint8_t ECP:1;
|
||||
#if MPC55XX_CHIP_FAMILY == 566 || MPC55XX_CHIP_FAMILY == 567
|
||||
uint8_t DPA:1;
|
||||
#else
|
||||
uint8_t:1;
|
||||
#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 */
|
||||
};
|
||||
|
||||
#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 }
|
||||
};
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define EDMA_TCD_BITER_MASK 0x7fff
|
||||
|
||||
#define EDMA_TCD_BITER_SIZE (EDMA_TCD_BITER_MASK + 1)
|
||||
|
||||
#define EDMA_TCD_BITER_LINKED_MASK 0x1ff
|
||||
|
||||
#define EDMA_TCD_BITER_LINKED_SIZE (EDMA_TCD_BITER_LINKED_MASK + 1)
|
||||
|
||||
#define EDMA_TCD_LINK_AND_BITER(link, biter) \
|
||||
(((link) << 9) + ((biter) & EDMA_TCD_BITER_LINKED_MASK))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBCPU_POWERPC_MPC55XX_REGS_EDMA_H */
|
||||
329
bsps/shared/dev/dma/fsl-edma.c
Normal file
329
bsps/shared/dev/dma/fsl-edma.c
Normal file
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSBSPsPowerPCMPC55XX
|
||||
*
|
||||
* @brief Enhanced Direct Memory Access (eDMA).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <mpc55xx/edma.h>
|
||||
#include <mpc55xx/mpc55xx.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/fatal.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#define EDMA_CHANNELS_PER_GROUP 32U
|
||||
|
||||
#define EDMA_GROUP_COUNT ((EDMA_CHANNEL_COUNT + 31U) / 32U)
|
||||
|
||||
#define EDMA_GROUP_INDEX(channel) ((channel) / EDMA_CHANNELS_PER_GROUP)
|
||||
|
||||
#define EDMA_GROUP_BIT(channel) (1U << ((channel) % EDMA_CHANNELS_PER_GROUP))
|
||||
|
||||
#define EDMA_MODULE_INDEX(channel) ((channel) / EDMA_CHANNELS_PER_MODULE)
|
||||
|
||||
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 EDMA_tag *edma = mpc55xx_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
|
||||
#error "unsupported module count"
|
||||
#endif
|
||||
}
|
||||
|
||||
static volatile struct EDMA_tag *edma_get_regs_by_module(unsigned module)
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
static uint32_t edma_bit_array_set(unsigned channel, uint32_t *bit_array)
|
||||
{
|
||||
unsigned array = channel / 32;
|
||||
uint32_t bit = 1U << (channel % 32);
|
||||
uint32_t previous = bit_array [array];
|
||||
|
||||
bit_array [array] = previous | bit;
|
||||
|
||||
return previous;
|
||||
}
|
||||
|
||||
static uint32_t edma_bit_array_clear(unsigned channel, uint32_t *bit_array)
|
||||
{
|
||||
unsigned array = channel / 32;
|
||||
uint32_t bit = 1U << (channel % 32);
|
||||
uint32_t previous = bit_array [array];
|
||||
|
||||
bit_array [array] = previous & ~bit;
|
||||
|
||||
return previous;
|
||||
}
|
||||
|
||||
static void edma_interrupt_handler(void *arg)
|
||||
{
|
||||
edma_channel_context *ctx = arg;
|
||||
|
||||
mpc55xx_edma_clear_interrupts(ctx->edma_tcd);
|
||||
|
||||
(*ctx->done)(ctx, 0);
|
||||
}
|
||||
|
||||
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
|
||||
#endif
|
||||
#if EDMA_GROUP_COUNT >= 2
|
||||
, EDMA.ERH.R
|
||||
#endif
|
||||
#if EDMA_GROUP_COUNT >= 3
|
||||
, EDMA_B.ERL.R
|
||||
#endif
|
||||
};
|
||||
uint32_t error_status [] = {
|
||||
#if EDMA_GROUP_COUNT >= 1
|
||||
EDMA.ESR.R
|
||||
#endif
|
||||
#if EDMA_GROUP_COUNT >= 3
|
||||
, EDMA_B.ESR.R
|
||||
#endif
|
||||
};
|
||||
|
||||
#if EDMA_GROUP_COUNT >= 1
|
||||
EDMA.ERL.R = error_channels [0];
|
||||
#endif
|
||||
#if EDMA_GROUP_COUNT >= 2
|
||||
EDMA.ERH.R = error_channels [1];
|
||||
#endif
|
||||
#if EDMA_GROUP_COUNT >= 3
|
||||
EDMA_B.ERL.R = 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);
|
||||
unsigned group_index = EDMA_GROUP_INDEX(channel_index);
|
||||
unsigned group_bit = EDMA_GROUP_BIT(channel_index);
|
||||
|
||||
if ((error_channels [group_index] & group_bit) != 0) {
|
||||
unsigned module_index = EDMA_MODULE_INDEX(channel_index);
|
||||
|
||||
(*ctx->done)(ctx, error_status [module_index]);
|
||||
}
|
||||
|
||||
node = rtems_chain_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
void mpc55xx_edma_init(void)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
unsigned channel_remaining = EDMA_CHANNEL_COUNT;
|
||||
unsigned module = 0;
|
||||
unsigned group = 0;
|
||||
|
||||
for (module = 0; module < EDMA_MODULE_COUNT; ++module) {
|
||||
volatile struct EDMA_tag *edma = edma_get_regs_by_module(module);
|
||||
unsigned channel_count = channel_remaining < EDMA_CHANNELS_PER_MODULE ?
|
||||
channel_remaining : EDMA_CHANNELS_PER_MODULE;
|
||||
unsigned channel = 0;
|
||||
|
||||
channel_remaining -= channel_count;
|
||||
|
||||
/* Disable requests */
|
||||
edma->CERQR.B.CERQ = 0x40;
|
||||
|
||||
/* Arbitration mode: group round robin, channel fixed */
|
||||
edma->CR.B.ERGA = 1;
|
||||
edma->CR.B.ERCA = 0;
|
||||
for (channel = 0; channel < channel_count; ++channel) {
|
||||
volatile struct tcd_t *tcd = &edma->TCD [channel];
|
||||
edma->CPR [channel].R = 0x80U | (channel & 0xfU);
|
||||
|
||||
/* Initialize TCD, stop channel first */
|
||||
tcd->BMF.R = 0;
|
||||
tcd->SADDR = 0;
|
||||
tcd->SDF.R = 0;
|
||||
tcd->NBYTES = 0;
|
||||
tcd->SLAST = 0;
|
||||
tcd->DADDR = 0;
|
||||
tcd->CDF.R = 0;
|
||||
tcd->DLAST_SGA = 0;
|
||||
}
|
||||
|
||||
/* Clear interrupt requests */
|
||||
edma->CIRQR.B.CINT = 0x40;
|
||||
edma->CER.B.CERR = 0x40;
|
||||
}
|
||||
|
||||
for (group = 0; group < EDMA_GROUP_COUNT; ++group) {
|
||||
sc = mpc55xx_interrupt_handler_install(
|
||||
MPC55XX_IRQ_EDMA_ERROR(group),
|
||||
"eDMA Error",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
MPC55XX_INTC_DEFAULT_PRIORITY,
|
||||
edma_interrupt_error_handler,
|
||||
NULL
|
||||
);
|
||||
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
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
unsigned channel_index = 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_index,
|
||||
&edma_channel_occupation [0]
|
||||
);
|
||||
rtems_interrupt_enable(level);
|
||||
|
||||
if ((channel_occupation & EDMA_GROUP_BIT(channel_index)) != 0) {
|
||||
sc = RTEMS_RESOURCE_IN_USE;
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd)
|
||||
{
|
||||
unsigned channel_index = 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]);
|
||||
rtems_interrupt_enable(level);
|
||||
|
||||
mpc55xx_edma_disable_hardware_requests(edma_tcd);
|
||||
mpc55xx_edma_disable_error_interrupts(edma_tcd);
|
||||
}
|
||||
|
||||
rtems_status_code mpc55xx_edma_obtain_channel(
|
||||
edma_channel_context *ctx,
|
||||
unsigned irq_priority
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = mpc55xx_edma_obtain_channel_by_tcd(ctx->edma_tcd);
|
||||
if (sc == RTEMS_SUCCESSFUL) {
|
||||
unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
|
||||
|
||||
sc = mpc55xx_interrupt_handler_install(
|
||||
MPC55XX_IRQ_EDMA(channel_index),
|
||||
"eDMA Channel",
|
||||
RTEMS_INTERRUPT_SHARED,
|
||||
irq_priority,
|
||||
edma_interrupt_handler,
|
||||
ctx
|
||||
);
|
||||
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)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
|
||||
|
||||
mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
|
||||
rtems_chain_extract(&ctx->node);
|
||||
|
||||
sc = rtems_interrupt_handler_remove(
|
||||
MPC55XX_IRQ_EDMA(channel_index),
|
||||
edma_interrupt_handler,
|
||||
ctx
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
bsp_fatal(MPC55XX_FATAL_EDMA_IRQ_REMOVE);
|
||||
}
|
||||
}
|
||||
|
||||
void mpc55xx_edma_copy(
|
||||
volatile struct tcd_t *edma_tcd,
|
||||
const struct tcd_t *source_tcd
|
||||
)
|
||||
{
|
||||
/* Clear DONE flag */
|
||||
edma_tcd->BMF.R = 0;
|
||||
|
||||
edma_tcd->SADDR = source_tcd->SADDR;
|
||||
edma_tcd->SDF.R = source_tcd->SDF.R;
|
||||
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->DLAST_SGA = source_tcd->DLAST_SGA;
|
||||
edma_tcd->BMF.R = source_tcd->BMF.R;
|
||||
}
|
||||
|
||||
void mpc55xx_edma_copy_and_enable_hardware_requests(
|
||||
volatile struct tcd_t *edma_tcd,
|
||||
const struct tcd_t *source_tcd
|
||||
)
|
||||
{
|
||||
mpc55xx_edma_copy(edma_tcd, source_tcd);
|
||||
mpc55xx_edma_enable_hardware_requests(edma_tcd);
|
||||
}
|
||||
|
||||
void mpc55xx_edma_sg_link(
|
||||
volatile struct tcd_t *edma_tcd,
|
||||
const struct tcd_t *source_tcd
|
||||
)
|
||||
{
|
||||
edma_tcd->DLAST_SGA = (int32_t) source_tcd;
|
||||
edma_tcd->BMF.B.E_SG = 1;
|
||||
|
||||
if (!edma_tcd->BMF.B.E_SG) {
|
||||
mpc55xx_edma_copy(edma_tcd, source_tcd);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user