OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [misc/] [freescale/] [edma/] [current/] [src/] [hal_freescale_edma.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//===========================================================================
2
//
3
//      hal_freescale_edma.c
4
//
5
//      Freescale eDMA support library
6
//
7
//===========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 2011 Free Software Foundation, Inc.                        
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//===========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     Ilija Kocho <ilijak@siva.com.mk>
43
// Date:          2011-11-04
44
// Purpose:       Freescale eDMA specific functions
45
// Description:
46
//
47
//####DESCRIPTIONEND####
48
//
49
//===========================================================================
50
 
51
#include <pkgconf/hal.h>
52
#include <pkgconf/hal_freescale_edma.h>
53
#ifdef CYGPKG_KERNEL
54
#include <pkgconf/kernel.h>
55
#endif
56
 
57
#include <cyg/infra/diag.h>
58
#include <cyg/infra/cyg_type.h>
59
#include <cyg/infra/cyg_trac.h>         // tracing macros
60
#include <cyg/infra/cyg_ass.h>          // assertion macros
61
 
62
#include <cyg/hal/hal_arch.h>           // HAL header
63
#include <cyg/hal/hal_intr.h>           // HAL header
64
#include <cyg/hal/hal_if.h>             // HAL header
65
#include <cyg/hal/freescale_edma.h>     // Freescale eDMA defs
66
 
67
// Channel priority register index
68
const cyg_uint8 const PRICHAN_I[CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM] =
69
{
70
    FREESCALE_DMA_PRI_CH0,  FREESCALE_DMA_PRI_CH1,
71
    FREESCALE_DMA_PRI_CH2,  FREESCALE_DMA_PRI_CH3,
72
    FREESCALE_DMA_PRI_CH4,  FREESCALE_DMA_PRI_CH5,
73
    FREESCALE_DMA_PRI_CH6,  FREESCALE_DMA_PRI_CH7,
74
    FREESCALE_DMA_PRI_CH8,  FREESCALE_DMA_PRI_CH9,
75
    FREESCALE_DMA_PRI_CH10, FREESCALE_DMA_PRI_CH11,
76
    FREESCALE_DMA_PRI_CH12, FREESCALE_DMA_PRI_CH13,
77
    FREESCALE_DMA_PRI_CH14, FREESCALE_DMA_PRI_CH15
78
};
79
 
80
// Find an eDMA channel with given priority
81
volatile cyg_uint8*
82
hal_freescale_edma_find_chan_with_pri(cyghwr_hal_freescale_edma_t *edma_p,
83
                                 cyg_uint8 pri)
84
{
85
    volatile cyg_uint8 *chan_p;
86
 
87
    for(chan_p = &edma_p->dchpri[0];
88
        chan_p < &edma_p->dchpri[CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM];
89
        chan_p++)
90
    {
91
        if(*chan_p == pri) break;
92
    }
93
    if(chan_p >= &edma_p->dchpri[CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM])
94
        chan_p = NULL;
95
    return chan_p;
96
}
97
 
98
// Initialize an eDMA channel
99
// If DMA prority change is required than old priority is assigned to the channel
100
// that before this call had requested priority.
101
void
102
hal_freescale_edma_init_1chan(
103
                           cyghwr_hal_freescale_edma_t *edma_p,
104
                           cyghwr_hal_freescale_dmamux_t *dmamux_p,
105
                           const cyghwr_hal_freescale_dma_chan_set_t *chan_p)
106
{
107
    cyg_uint8 oldprio;
108
    volatile cyg_uint8 *prev_ch_reqprio_p; // Previous chan with req. prio.
109
    volatile cyg_uint8 *chcfg_p = &dmamux_p->chcfg[chan_p->dma_chan_i];
110
 
111
    edma_p->cerq = chan_p->dma_chan_i;
112
 
113
    if(chan_p->dma_src & FREESCALE_DMAMUX_CHCFG_SOURCE_M) {
114
        *chcfg_p = chan_p->dma_src;
115
    } else if(!(chan_p->dma_src & FREESCALE_DMAMUX_CHCFG_ASIS)) {
116
        *chcfg_p = 0;
117
    }
118
 
119
    if((chan_p->dma_prio != FREESCALE_EDMA_DCHPRI_ASIS) &&
120
       (edma_p->dchpri[PRICHAN_I[chan_p->dma_chan_i]] != chan_p->dma_prio))
121
    {
122
        if((prev_ch_reqprio_p =
123
            hal_freescale_edma_find_chan_with_pri(edma_p, chan_p->dma_prio)))
124
        {
125
            oldprio = edma_p->dchpri[PRICHAN_I[chan_p->dma_chan_i]];
126
            edma_p->dchpri[PRICHAN_I[chan_p->dma_chan_i]] = chan_p->dma_prio;
127
            *prev_ch_reqprio_p = oldprio;
128
        }
129
    }
130
}
131
 
132
 
133
// Init DMA controller
134
 
135
const cyg_uint32 FREESCALE_EDMA_CR_INI = 0
136
#ifdef CYGOPT_HAL_FREESCALE_EDMA_EMLM
137
       | FREESCALE_EDMA_CR_EMLM_M
138
#endif
139
#ifdef CYGOPT_HAL_FREESCALE_EDMA_CLM
140
       | FREESCALE_EDMA_CR_CLM_M
141
#endif
142
#ifdef CYGOPT_HAL_FREESCALE_EDMA_ERCA
143
       | FREESCALE_EDMA_CR_ERCA_M
144
#endif
145
      ;
146
 
147
void
148
hal_freescale_edma_init(cyghwr_hal_freescale_edma_t *edma_p)
149
{
150
    edma_p->cr |= FREESCALE_EDMA_CR_INI;
151
}
152
 
153
// Initialize a set of DMA channels
154
void
155
hal_freescale_edma_init_chanset(cyghwr_hal_freescale_dma_set_t *inidat_p)
156
{
157
    cyghwr_hal_freescale_edma_t *edma_p;
158
    cyghwr_hal_freescale_dmamux_t *dmamux_p;
159
    const cyghwr_hal_freescale_dma_chan_set_t *chan_p;
160
 
161
    edma_p = inidat_p->edma_p;
162
 
163
    hal_freescale_edma_init(edma_p);
164
 
165
    dmamux_p = inidat_p->dmamux_p;
166
    for(chan_p = inidat_p->chan_p;
167
        chan_p < inidat_p->chan_p + inidat_p->chan_n;
168
        chan_p++)
169
    {
170
        hal_freescale_edma_init_1chan(edma_p, dmamux_p, chan_p);
171
    }
172
    edma_p->es = 0;
173
}
174
 
175
#if CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM > 16
176
#define DMA_CHANMASK_FORMAT "0x%08x"
177
#else
178
#define DMA_CHANMASK_FORMAT "0x%04x"
179
#endif
180
 
181
#define EDMA_DIAG_PRINTF_FORMAT(__mf) "CR=0x%08x ES=0x%08x ERQ=" __mf \
182
        " INT=" __mf " ERR=" __mf " HRS=" __mf "\n"
183
 
184
// Display DMA configuration
185
void
186
hal_freescale_edma_diag(cyghwr_hal_freescale_dma_set_t *inidat_p, cyg_uint32 mask)
187
{
188
    cyghwr_hal_freescale_edma_t *edma_p;
189
    cyghwr_hal_freescale_dmamux_t *dmamux_p;
190
    const cyghwr_hal_freescale_dma_chan_set_t *chan_p;
191
    cyg_uint8 chan_i;
192
    cyg_uint32 chan_p_i;
193
 
194
    edma_p = inidat_p->edma_p;
195
    dmamux_p = inidat_p->dmamux_p;
196
    diag_printf("DMAMUX: %p DMA: %p\n", dmamux_p, edma_p);
197
    diag_printf(EDMA_DIAG_PRINTF_FORMAT(DMA_CHANMASK_FORMAT),
198
                edma_p->cr, edma_p->es,
199
                edma_p->erq, edma_p->irq, edma_p->err, edma_p->hrs);
200
 
201
    for(chan_i = 0; chan_i < CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM; chan_i++){
202
        if(mask & 0x1){
203
            diag_printf("Chan %2d: CHCFG=0x%02x (%2d) DCHPRI=0x%02x", chan_i,
204
                        dmamux_p->chcfg[chan_i],
205
                        FREESCALE_DMAMUX_CHCFG_SOURCE(dmamux_p->chcfg[chan_i]),
206
                        edma_p->dchpri[PRICHAN_I[chan_i]]);
207
            chan_p = inidat_p->chan_p;
208
            for(chan_p_i = 0; chan_p_i < inidat_p->chan_n; chan_p_i++){
209
                if(chan_p->dma_chan_i == chan_i){
210
                    diag_printf(" ISR_NUM=%2d[0x%02x] ISR_PRI=%3d[0x%02x]",
211
                                chan_p->isr_num, chan_p->isr_num,
212
                                chan_p->isr_prio, chan_p->isr_prio);
213
                }
214
                chan_p++;
215
            }
216
            diag_printf("\n");
217
        }
218
        mask >>= 1;
219
    }
220
}
221
 
222
// Initialize eDMA channel TCD
223
void
224
hal_freescale_edma_transfer_init(cyghwr_hal_freescale_edma_t *edma_p,
225
                                 cyg_uint8 chan_i,
226
                                 const cyghwr_hal_freescale_edma_tcd_t *tcd_cfg_p)
227
{
228
    HAL_DMA_TRANSFER_CLEAR(edma_p, chan_i);
229
    edma_p->tcd[chan_i] = *tcd_cfg_p;
230
}
231
 
232
// Show eDMA TCD
233
void hal_freescale_edma_tcd_diag(cyghwr_hal_freescale_edma_tcd_t *tcd_p, cyg_int32 chan_i, const char *prefix)
234
{
235
    if(chan_i < 0) {
236
        diag_printf("TCD %p chan %s:\n", tcd_p, prefix);
237
        prefix = "";
238
    } else {
239
        diag_printf("%sTCD %p chan %d:\n", "", tcd_p, chan_i);
240
    }
241
 
242
        diag_printf("%s    saddr=%p soff=0x%04x, attr=0x%04x\n", prefix,
243
                    tcd_p->saddr, tcd_p->soff, tcd_p->attr);
244
        diag_printf("%s    daddr=%p doff=0x%04x\n", prefix,
245
                    tcd_p->daddr, tcd_p->doff);
246
        diag_printf("%s    nbytes=%d [0x%08x], slast=%d [0x%08x]\n", prefix,
247
                    tcd_p->nbytes.mlno, tcd_p->nbytes.mlno,
248
                    tcd_p->slast, tcd_p->slast);
249
        diag_printf("%s    %s=%d [%p]\n", prefix,
250
                    (tcd_p->csr & FREESCALE_EDMA_CSR_ESG_M) ? "sga" : "dlast",
251
                    tcd_p->dlast, tcd_p->sga);
252
        diag_printf("%s    biter = %d, citer = %d\n", prefix,
253
                    tcd_p->biter.elinkno, tcd_p->citer.elinkno);
254
        diag_printf("%s    CSR=0x%04x\n", prefix, tcd_p->csr);
255
}
256
 
257
// Show eDMA TCD set
258
void hal_freescale_edma_transfer_diag(cyghwr_hal_freescale_edma_t
259
                                      *edma_p, cyg_uint8 chan_i, cyg_bool recurse)
260
{
261
    cyghwr_hal_freescale_edma_tcd_t *tcd_p;
262
    const char *prefix = "";
263
 
264
    for(tcd_p = &edma_p->tcd[chan_i]; tcd_p; tcd_p = tcd_p->sga){
265
        hal_freescale_edma_tcd_diag(tcd_p, chan_i, prefix);
266
        if(!(recurse && (tcd_p->csr & FREESCALE_EDMA_CSR_ESG_M)))
267
            break;
268
        prefix = "  ";
269
    }
270
}
271
 
272
// end of freescale_dma.h

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.