Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * RTEMS generic MCF548x BSP
0005  *
0006  * This file contains glue functions to the Freescale MC_DMA API
0007  */
0008 
0009 /*
0010  * Copyright (C) 2004, 2009 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 #include <rtems.h>
0035 #include <rtems/error.h>
0036 #include <bsp.h>
0037 #include <mcf548x/mcf548x.h>
0038 #include <mcf548x/MCD_dma.h>
0039 #include <mcf548x/mcdma_glue.h>
0040 
0041 #define MCDMA_INT_ENABLE(reg,chan)   (reg &= ~(1 << (chan)))
0042 #define MCDMA_INT_DISABLE(reg,chan)  (reg |=  (1 << (chan)))
0043 #define MCDMA_CLEAR_IEVENT(reg,chan) (reg  =  (1 << (chan)))
0044 
0045 #define MCDMA_INT_BIT_IMPL           0x0000FFFF /* implemented IRQ sources (bitmask for IPEND... */
0046 #define MCDMA_IRQ_VECTOR    (48+64)
0047 #define MCDMA_IRQ_LEVEL     (2)
0048 #define MCDMA_IRQ_PRIORITY  (2)
0049 /*=========================================================================*\
0050 | Function:                                                                 |
0051 \*-------------------------------------------------------------------------*/
0052 void mcdma_glue_irq_enable
0053 (
0054 /*-------------------------------------------------------------------------*\
0055 | Purpose:                                                                  |
0056 |   enable interrupt for given task number                                  |
0057 +---------------------------------------------------------------------------+
0058 | Input Parameters:                                                         |
0059 \*-------------------------------------------------------------------------*/
0060  int mcdma_channo                              /* task number to enable    */
0061 )
0062 /*-------------------------------------------------------------------------*\
0063 | Return Value:                                                             |
0064 |    none                                                                   |
0065 \*=========================================================================*/
0066 {
0067   rtems_interrupt_level level;
0068   if (0 != ((1UL<<mcdma_channo) & MCDMA_INT_BIT_IMPL)) {
0069     rtems_interrupt_disable(level);
0070     /*
0071      * valid task number
0072      * enable interrupt in mcdma mask
0073      */
0074     MCDMA_INT_ENABLE(MCF548X_DMA_DIMR,mcdma_channo);
0075     rtems_interrupt_enable(level);
0076   }
0077 }
0078 
0079 /*=========================================================================*\
0080 | Function:                                                                 |
0081 \*-------------------------------------------------------------------------*/
0082 void mcdma_glue_irq_disable
0083 (
0084 /*-------------------------------------------------------------------------*\
0085 | Purpose:                                                                  |
0086 |   disable interrupt for given task number                                 |
0087 +---------------------------------------------------------------------------+
0088 | Input Parameters:                                                         |
0089 \*-------------------------------------------------------------------------*/
0090  int mcdma_channo                              /* task number to disable   */
0091 )
0092 /*-------------------------------------------------------------------------*\
0093 | Return Value:                                                             |
0094 |    none                                                                   |
0095 \*=========================================================================*/
0096 {
0097   rtems_interrupt_level level;
0098   if (0 != ((1UL<<mcdma_channo) & MCDMA_INT_BIT_IMPL)) {
0099     rtems_interrupt_disable(level);
0100     /*
0101      * valid task number
0102      * disable interrupt in mcdma mask
0103      */
0104     MCDMA_INT_DISABLE(MCF548X_DMA_DIMR,mcdma_channo);
0105     rtems_interrupt_enable(level);
0106   }
0107 }
0108 
0109 typedef struct {
0110   void (*the_handler)(void *param);
0111   void *the_param;
0112 } mcdma_glue_irq_handlers_t;
0113 
0114 mcdma_glue_irq_handlers_t mcdma_glue_irq_handlers[32];
0115 
0116 /*=========================================================================*\
0117 | Function:                                                                 |
0118 \*-------------------------------------------------------------------------*/
0119 void mcdma_glue_irq_install
0120 (
0121 /*-------------------------------------------------------------------------*\
0122 | Purpose:                                                                  |
0123 |   install given function as mcdma interrupt handler                    |
0124 +---------------------------------------------------------------------------+
0125 | Input Parameters:                                                         |
0126 \*-------------------------------------------------------------------------*/
0127  int mcdma_channo,                          /* task number for handler  */
0128  void (*the_handler)(void *),               /* function to call         */
0129  void *the_param
0130 )
0131 /*-------------------------------------------------------------------------*\
0132 | Return Value:                                                             |
0133 |    none                                                                   |
0134 \*=========================================================================*/
0135 {
0136   if (0 != ((1UL<<mcdma_channo) & MCDMA_INT_BIT_IMPL)) {
0137     /*
0138      * valid task number
0139      * install handler
0140      */
0141     mcdma_glue_irq_handlers[mcdma_channo].the_handler = the_handler;
0142     mcdma_glue_irq_handlers[mcdma_channo].the_param   = the_param;
0143   }
0144 }
0145 
0146 /*=========================================================================*\
0147 | Function:                                                                 |
0148 \*-------------------------------------------------------------------------*/
0149 static rtems_isr mcdma_glue_irq_dispatcher
0150 (
0151 /*-------------------------------------------------------------------------*\
0152 | Purpose:                                                                  |
0153 |   general mcdma interrupt handler/dispatcher                              |
0154 +---------------------------------------------------------------------------+
0155 | Input Parameters:                                                         |
0156 \*-------------------------------------------------------------------------*/
0157  rtems_vector_number v                   /* irq specific handle (not used) */
0158 
0159 )
0160 /*-------------------------------------------------------------------------*\
0161 | Return Value:                                                             |
0162 |    none                                                                   |
0163 \*=========================================================================*/
0164 {
0165   uint32_t pending;
0166   int curr_channo;
0167 
0168   pending = MCF548X_DMA_DIPR & ~MCF548X_DMA_DIMR;
0169   curr_channo = 0;
0170   while (pending != 0) {
0171     if ((pending & (1UL<<curr_channo)) != 0) {
0172       if (mcdma_glue_irq_handlers[curr_channo].the_handler == NULL) {
0173     /*
0174      * This should never happen. we have a pending IRQ but no handler
0175      * let's clear this pending bit
0176      */
0177     MCDMA_CLEAR_IEVENT(MCF548X_DMA_DIPR,curr_channo);
0178       }
0179       else {
0180     /*
0181      * call proper handler
0182      */
0183     mcdma_glue_irq_handlers[curr_channo].the_handler
0184       (mcdma_glue_irq_handlers[curr_channo].the_param);
0185       }
0186       /*
0187        * clear this bit in our pending copy
0188        * and go to next bit
0189        */
0190       pending &= ~(1<<curr_channo);
0191     }
0192     curr_channo++;
0193   }
0194 }
0195 
0196 static bool mcdma_glue_is_initialized = false;
0197 /*=========================================================================*\
0198 | Function:                                                                 |
0199 \*-------------------------------------------------------------------------*/
0200 void mcdma_glue_init
0201 (
0202 /*-------------------------------------------------------------------------*\
0203 | Purpose:                                                                  |
0204 |   initialize the mcdma module (if not yet done):                          |
0205 |   - load code                                                             |
0206 |   - initialize registers                                                  |
0207 |   - initialize bus arbiter                                                |
0208 |   - initialize interrupt control                                          |
0209 +---------------------------------------------------------------------------+
0210 | Input Parameters:                                                         |
0211 \*-------------------------------------------------------------------------*/
0212  void *sram_base         /* base address for SRAM, to be used for DMA task */
0213 )
0214 /*-------------------------------------------------------------------------*\
0215 | Return Value:                                                             |
0216 |    none                                                                   |
0217 \*=========================================================================*/
0218 {
0219   rtems_isr_entry old_handler;
0220   if (!mcdma_glue_is_initialized) {
0221     mcdma_glue_is_initialized = true;
0222 
0223     MCD_initDma((dmaRegs *)&MCF548X_DMA_TASKBAR,
0224         sram_base,
0225         MCD_TT_FLAGS_DEF);
0226 
0227     /*
0228      * initialize interrupt dispatcher
0229      */
0230     if(rtems_interrupt_catch(mcdma_glue_irq_dispatcher,
0231                  MCDMA_IRQ_VECTOR,
0232                  &old_handler)) {
0233       rtems_panic ("Can't attach MFC548x MCDma interrupt handler\n");
0234     }
0235     MCF548X_INTC_ICRn(MCDMA_IRQ_VECTOR - 64) =
0236       MCF548X_INTC_ICRn_IL(MCDMA_IRQ_LEVEL) |
0237       MCF548X_INTC_ICRn_IP(MCDMA_IRQ_PRIORITY);
0238 
0239     MCF548X_INTC_IMRH &= ~(1 << (MCDMA_IRQ_VECTOR % 32));
0240   }
0241 }