Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:42

0001 /**
0002  * @file
0003  *
0004  * @ingroup RTEMSBSPsSharedFslEDMA
0005  *
0006  * @brief Freescale / NXP Enhanced Direct Memory Access (eDMA).
0007  */
0008 
0009 /*
0010  * Copyright (C) 2008, 2020 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 #ifndef LIBBSP_SHARED_FSL_EDMA_H
0035 #define LIBBSP_SHARED_FSL_EDMA_H
0036 
0037 #include <fsl/regs-edma.h>
0038 
0039 #include <rtems.h>
0040 #include <rtems/chain.h>
0041 
0042 #ifdef __cplusplus
0043 extern "C" {
0044 #endif /* __cplusplus */
0045 
0046 #ifdef LIBBSP_ARM_IMXRT_BSP_H
0047   #define EDMA_CHANNEL_COUNT 32U
0048 #elif MPC55XX_CHIP_FAMILY == 551
0049   #define EDMA_CHANNEL_COUNT 16U
0050 #elif MPC55XX_CHIP_FAMILY == 564
0051   #define EDMA_CHANNEL_COUNT 16U
0052 #elif MPC55XX_CHIP_FAMILY == 567
0053   #define EDMA_CHANNEL_COUNT 96U
0054 #else
0055   #define EDMA_CHANNEL_COUNT 64U
0056 #endif
0057 
0058 #define EDMA_MODULE_COUNT ((EDMA_CHANNEL_COUNT + 63U) / 64U)
0059 
0060 #define EDMA_CHANNELS_PER_MODULE 64U
0061 
0062 volatile struct fsl_edma_tcd *fsl_edma_tcd_of_channel_index(unsigned index);
0063 unsigned fsl_edma_channel_index_of_tcd(volatile struct fsl_edma_tcd *edma_tcd);
0064 
0065 #ifdef LIBBSP_POWERPC_MPC55XXEVB_BSP_H
0066   #error Legacy stuff. Move to compatibility layer.
0067   #if EDMA_MODULE_COUNT == 1
0068     #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \
0069       (&EDMA.TCD[(channel_index)])
0070   #elif EDMA_MODULE_COUNT == 2
0071     #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \
0072       ((channel_index) < EDMA_CHANNELS_PER_MODULE ? \
0073         &EDMA_A.TCD[(channel_index)] \
0074           : &EDMA_B.TCD[(channel_index) - EDMA_CHANNELS_PER_MODULE])
0075   #else
0076     #error "unsupported module count"
0077   #endif
0078 #endif
0079 
0080 #ifdef LIBBSP_POWERPC_MPC55XXEVB_BSP_H
0081 typedef enum {
0082 /* FIXME: These values are only valid for the MPC5566 and MPC5674F */
0083   EDMA_EQADC_A_FISR0_CFFF0 = 0,
0084   EDMA_EQADC_A_FISR0_RFDF0 = 1,
0085   EDMA_EQADC_A_FISR1_CFFF1 = 2,
0086   EDMA_EQADC_A_FISR1_RFDF1 = 3,
0087   EDMA_EQADC_A_FISR2_CFFF2 = 4,
0088   EDMA_EQADC_A_FISR2_RFDF2 = 5,
0089   EDMA_EQADC_A_FISR3_CFFF3 = 6,
0090   EDMA_EQADC_A_FISR3_RFDF3 = 7,
0091   EDMA_EQADC_A_FISR4_CFFF4 = 8,
0092   EDMA_EQADC_A_FISR4_RFDF4 = 9,
0093   EDMA_EQADC_A_FISR5_CFFF5 = 10,
0094   EDMA_EQADC_A_FISR5_RFDF5 = 11,
0095   EDMA_DSPI_B_SR_TFFF = 12,
0096   EDMA_DSPI_B_SR_RFDF = 13,
0097   EDMA_DSPI_C_SR_TFFF = 14,
0098   EDMA_DSPI_C_SR_RFDF = 15,
0099   EDMA_DSPI_D_SR_TFFF = 16,
0100   EDMA_DSPI_D_SR_RFDF = 17,
0101   EDMA_ESCI_A_COMBTX = 18,
0102   EDMA_ESCI_A_COMBRX = 19,
0103   EDMA_EMIOS_GFR_F0 = 20,
0104   EDMA_EMIOS_GFR_F1 = 21,
0105   EDMA_EMIOS_GFR_F2 = 22,
0106   EDMA_EMIOS_GFR_F3 = 23,
0107   EDMA_EMIOS_GFR_F4 = 24,
0108   EDMA_EMIOS_GFR_F8 = 25,
0109   EDMA_EMIOS_GFR_F9 = 26,
0110   EDMA_ETPU_CDTRSR_A_DTRS0 = 27,
0111   EDMA_ETPU_CDTRSR_A_DTRS1 = 28,
0112   EDMA_ETPU_CDTRSR_A_DTRS2 = 29,
0113   EDMA_ETPU_CDTRSR_A_DTRS14 = 30,
0114   EDMA_ETPU_CDTRSR_A_DTRS15 = 31,
0115   EDMA_DSPI_A_SR_TFFF = 32,
0116   EDMA_DSPI_A_SR_RFDF = 33,
0117   EDMA_ESCI_B_COMBTX = 34,
0118   EDMA_ESCI_B_COMBRX = 35,
0119   EDMA_EMIOS_GFR_F6 = 36,
0120   EDMA_EMIOS_GFR_F7 = 37,
0121   EDMA_EMIOS_GFR_F10 = 38,
0122   EDMA_EMIOS_GFR_F11 = 39,
0123   EDMA_EMIOS_GFR_F16 = 40,
0124   EDMA_EMIOS_GFR_F17 = 41,
0125   EDMA_EMIOS_GFR_F18 = 42,
0126   EDMA_EMIOS_GFR_F19 = 43,
0127   EDMA_ETPU_CDTRSR_A_DTRS12 = 44,
0128   EDMA_ETPU_CDTRSR_A_DTRS13 = 45,
0129   EDMA_ETPU_CDTRSR_A_DTRS28 = 46,
0130   EDMA_ETPU_CDTRSR_A_DTRS29 = 47,
0131   EDMA_SIU_EISR_EIF0 = 48,
0132   EDMA_SIU_EISR_EIF1 = 49,
0133   EDMA_SIU_EISR_EIF2 = 50,
0134   EDMA_SIU_EISR_EIF3 = 51,
0135   EDMA_ETPU_CDTRSR_B_DTRS0 = 52,
0136   EDMA_ETPU_CDTRSR_B_DTRS1 = 53,
0137   EDMA_ETPU_CDTRSR_B_DTRS2 = 54,
0138   EDMA_ETPU_CDTRSR_B_DTRS3 = 55,
0139   EDMA_ETPU_CDTRSR_B_DTRS12 = 56,
0140   EDMA_ETPU_CDTRSR_B_DTRS13 = 57,
0141   EDMA_ETPU_CDTRSR_B_DTRS14 = 58,
0142   EDMA_ETPU_CDTRSR_B_DTRS15 = 59,
0143   EDMA_ETPU_CDTRSR_B_DTRS28 = 60,
0144   EDMA_ETPU_CDTRSR_B_DTRS29 = 61,
0145   EDMA_ETPU_CDTRSR_B_DTRS30 = 62,
0146   EDMA_ETPU_CDTRSR_B_DTRS31 = 63
0147   #if MPC55XX_CHIP_FAMILY == 567
0148     ,
0149     EDMA_EQADC_B_FISR0_CFFF0 = 64 + 0,
0150     EDMA_EQADC_B_FISR0_RFDF0 = 64 + 1,
0151     EDMA_EQADC_B_FISR1_CFFF1 = 64 + 2,
0152     EDMA_EQADC_B_FISR1_RFDF1 = 64 + 3,
0153     EDMA_EQADC_B_FISR2_CFFF2 = 64 + 4,
0154     EDMA_EQADC_B_FISR2_RFDF2 = 64 + 5,
0155     EDMA_EQADC_B_FISR3_CFFF3 = 64 + 6,
0156     EDMA_EQADC_B_FISR3_RFDF3 = 64 + 7,
0157     EDMA_EQADC_B_FISR4_CFFF4 = 64 + 8,
0158     EDMA_EQADC_B_FISR4_RFDF4 = 64 + 9,
0159     EDMA_EQADC_B_FISR5_CFFF5 = 64 + 10,
0160     EDMA_EQADC_B_FISR5_RFDF5 = 64 + 11,
0161     EDMA_DECFILTER_A_IB = 64 + 12,
0162     EDMA_DECFILTER_A_OB = 64 + 13,
0163     EDMA_DECFILTER_B_IB = 64 + 14,
0164     EDMA_DECFILTER_B_OB = 64 + 15,
0165     EDMA_DECFILTER_C_IB = 64 + 16,
0166     EDMA_DECFILTER_C_OB = 64 + 17,
0167     EDMA_DECFILTER_D_IB = 64 + 18,
0168     EDMA_DECFILTER_D_OB = 64 + 19,
0169     EDMA_DECFILTER_E_IB = 64 + 20,
0170     EDMA_DECFILTER_E_OB = 64 + 21,
0171     EDMA_DECFILTER_F_IB = 64 + 22,
0172     EDMA_DECFILTER_F_OB = 64 + 23,
0173     EDMA_DECFILTER_G_IB = 64 + 24,
0174     EDMA_DECFILTER_G_OB = 64 + 25,
0175     EDMA_DECFILTER_H_IB = 64 + 26,
0176     EDMA_DECFILTER_H_OB = 64 + 27
0177   #endif
0178 } fsl_edma_channel;
0179 #endif
0180 
0181 typedef struct fsl_edma_channel_context {
0182   rtems_chain_node node;
0183   volatile struct fsl_edma_tcd *edma_tcd;
0184   void (*done)(struct fsl_edma_channel_context *, uint32_t);
0185 } fsl_edma_channel_context;
0186 
0187 void fsl_edma_init(void);
0188 
0189 /**
0190  * @brief Obtains an eDMA channel.
0191  *
0192  * @retval RTEMS_SUCCESSFUL Successful operation.
0193  * @retval RTEMS_RESOURCE_IN_USE The channel is already in use.
0194  */
0195 rtems_status_code fsl_edma_obtain_channel_by_tcd(
0196   volatile struct fsl_edma_tcd *edma_tcd
0197 );
0198 
0199 void fsl_edma_release_channel_by_tcd(volatile struct fsl_edma_tcd *edma_tcd);
0200 
0201 /**
0202  * @brief Obtains a specific eDMA channel and registers the channel context.
0203  *
0204  * Tries to obtain the channel specified in the @a ctx.
0205  *
0206  * @a irq_priority will be ignored on all targets but MPC55xx based ones.
0207  *
0208  * The done handler of the channel context will be called
0209  * - during minor or major loop completions if interrupts are enabled in the
0210  *   corresponding TCD, or
0211  * - in case a channel error occurs.
0212  *
0213  * An error status value not equal to zero indicates an error.
0214  *
0215  * @retval RTEMS_SUCCESSFUL Successful operation.
0216  * @retval RTEMS_RESOURCE_IN_USE The channel is already in use.
0217  * @retval RTEMS_IO_ERROR Unable to install interrupt handler for this channel.
0218  */
0219 rtems_status_code fsl_edma_obtain_channel(
0220   fsl_edma_channel_context *ctx,
0221   unsigned irq_priority
0222 );
0223 
0224 /**
0225  * @brief Obtains a free eDMA channel and registers the channel context.
0226  *
0227  * Tries to obtain the next free DMA channel. The tcd field of @a ctx will be
0228  * set accordingly.
0229  *
0230  * The done handler of the channel context will be called
0231  * - during minor or major loop completions if interrupts are enabled in the
0232  *   corresponding TCD, or
0233  * - in case a channel error occurs.
0234  *
0235  * An error status value not equal to zero indicates an error.
0236  *
0237  * @retval RTEMS_SUCCESSFUL Successful operation.
0238  * @retval RTEMS_RESOURCE_IN_USE No channels left.
0239  * @retval RTEMS_IO_ERROR Unable to install interrupt handler.
0240  */
0241 rtems_status_code fsl_edma_obtain_next_free_channel(
0242   fsl_edma_channel_context *ctx
0243 );
0244 
0245 void fsl_edma_release_channel(fsl_edma_channel_context *ctx);
0246 
0247 /**
0248  * @brief Copies a source TCD to an eDMA TCD.
0249  *
0250  * The DONE flag of the eDMA TCD is cleared before the actual copy operation.
0251  * This enables the setting of channel link or scatter/gather options.
0252  *
0253  * This function can be used to start the channel if the START flags is
0254  * set in the source TCD.
0255  */
0256 void fsl_edma_copy(
0257   volatile struct fsl_edma_tcd *edma_tcd,
0258   const struct fsl_edma_tcd *source_tcd
0259 );
0260 
0261 /**
0262  * @brief Copies a source TCD to an eDMA TCD and enables hardware requests.
0263  *
0264  * The DONE flag of the eDMA TCD is cleared before the actual copy operation.
0265  * This enables the setting of channel link or scatter/gather options.
0266  */
0267 void fsl_edma_copy_and_enable_hardware_requests(
0268   volatile struct fsl_edma_tcd *edma_tcd,
0269   const struct fsl_edma_tcd *source_tcd
0270 );
0271 
0272 void fsl_edma_sg_link(
0273   volatile struct fsl_edma_tcd *edma_tcd,
0274   const struct fsl_edma_tcd *source_tcd
0275 );
0276 
0277 static inline volatile struct fsl_edma *fsl_edma_by_tcd(
0278   volatile struct fsl_edma_tcd *edma_tcd
0279 )
0280 {
0281   return (volatile struct fsl_edma *)
0282     ((uintptr_t) edma_tcd & ~(uintptr_t) 0x1fff);
0283 }
0284 
0285 static inline unsigned fsl_edma_channel_by_tcd(
0286   volatile struct fsl_edma_tcd *edma_tcd
0287 )
0288 {
0289   volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
0290 
0291   return edma_tcd - &edma->TCD[0];
0292 }
0293 
0294 static inline void fsl_edma_enable_hardware_requests(
0295   volatile struct fsl_edma_tcd *edma_tcd
0296 )
0297 {
0298   volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
0299   unsigned channel = edma_tcd - &edma->TCD[0];
0300 
0301   edma->SERQR = (uint8_t) channel;
0302 }
0303 
0304 static inline void fsl_edma_disable_hardware_requests(
0305   volatile struct fsl_edma_tcd *edma_tcd
0306 )
0307 {
0308   volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
0309   unsigned channel = edma_tcd - &edma->TCD[0];
0310 
0311   edma->CERQR = (uint8_t) channel;
0312 }
0313 
0314 static inline void fsl_edma_enable_error_interrupts(
0315   volatile struct fsl_edma_tcd *edma_tcd
0316 )
0317 {
0318   volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
0319   unsigned channel = edma_tcd - &edma->TCD[0];
0320 
0321   edma->SEEIR = (uint8_t) channel;
0322 }
0323 
0324 static inline void fsl_edma_disable_error_interrupts(
0325   volatile struct fsl_edma_tcd *edma_tcd
0326 )
0327 {
0328   volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
0329   unsigned channel = edma_tcd - &edma->TCD[0];
0330 
0331   edma->CEEIR = (uint8_t) channel;
0332 }
0333 
0334 static inline void fsl_edma_set_start(
0335   volatile struct fsl_edma_tcd *edma_tcd
0336 )
0337 {
0338   volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
0339   unsigned channel = edma_tcd - &edma->TCD[0];
0340 
0341   edma->SSBR = (uint8_t) channel;
0342 }
0343 
0344 static inline void fsl_edma_clear_done(
0345   volatile struct fsl_edma_tcd *edma_tcd
0346 )
0347 {
0348   volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
0349   unsigned channel = edma_tcd - &edma->TCD[0];
0350 
0351   edma->CDSBR = (uint8_t) channel;
0352 }
0353 
0354 static inline void fsl_edma_clear_interrupts(
0355   volatile struct fsl_edma_tcd *edma_tcd
0356 )
0357 {
0358   volatile struct fsl_edma *edma = fsl_edma_by_tcd(edma_tcd);
0359   unsigned channel = edma_tcd - &edma->TCD[0];
0360 
0361   edma->CIRQR = (uint8_t) channel;
0362 }
0363 
0364 static inline bool fsl_edma_is_done(
0365   volatile struct fsl_edma_tcd *edma_tcd
0366 )
0367 {
0368   return ((edma_tcd->BMF & EDMA_TCD_BMF_DONE) != 0);
0369 }
0370 
0371 #ifdef __cplusplus
0372 }
0373 #endif /* __cplusplus */
0374 
0375 #endif /* LIBBSP_SHARED_FSL_EDMA_H */