~ubuntu-branches/ubuntu/karmic/linux-mvl-dove/karmic-proposed

« back to all changes in this revision

Viewing changes to arch/arm/mach-kirkwood/mv_hal_support/kw_family/ctrlEnv/sys/mvSysTdm.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader
  • Date: 2010-03-10 22:24:12 UTC
  • mto: (15.1.2 karmic-security)
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20100310222412-k86m3r53jw0je7x1
Tags: upstream-2.6.31
ImportĀ upstreamĀ versionĀ 2.6.31

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*******************************************************************************
2
 
Copyright (C) Marvell International Ltd. and its affiliates
3
 
 
4
 
This software file (the "File") is owned and distributed by Marvell 
5
 
International Ltd. and/or its affiliates ("Marvell") under the following
6
 
alternative licensing terms.  Once you have made an election to distribute the
7
 
File under one of the following license alternatives, please (i) delete this
8
 
introductory statement regarding license alternatives, (ii) delete the two
9
 
license alternatives that you have not elected to use and (iii) preserve the
10
 
Marvell copyright notice above.
11
 
 
12
 
********************************************************************************
13
 
Marvell Commercial License Option
14
 
 
15
 
If you received this File from Marvell and you have entered into a commercial
16
 
license agreement (a "Commercial License") with Marvell, the File is licensed
17
 
to you under the terms of the applicable Commercial License.
18
 
 
19
 
********************************************************************************
20
 
Marvell GPL License Option
21
 
 
22
 
If you received this File from Marvell, you may opt to use, redistribute and/or 
23
 
modify this File in accordance with the terms and conditions of the General 
24
 
Public License Version 2, June 1991 (the "GPL License"), a copy of which is 
25
 
available along with the File in the license.txt file or by writing to the Free 
26
 
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or 
27
 
on the worldwide web at http://www.gnu.org/licenses/gpl.txt. 
28
 
 
29
 
THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED 
30
 
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY 
31
 
DISCLAIMED.  The GPL License provides additional details about this warranty 
32
 
disclaimer.
33
 
********************************************************************************
34
 
Marvell BSD License Option
35
 
 
36
 
If you received this File from Marvell, you may opt to use, redistribute and/or 
37
 
modify this File under the following licensing terms. 
38
 
Redistribution and use in source and binary forms, with or without modification, 
39
 
are permitted provided that the following conditions are met:
40
 
 
41
 
    *   Redistributions of source code must retain the above copyright notice,
42
 
            this list of conditions and the following disclaimer. 
43
 
 
44
 
    *   Redistributions in binary form must reproduce the above copyright
45
 
        notice, this list of conditions and the following disclaimer in the
46
 
        documentation and/or other materials provided with the distribution. 
47
 
 
48
 
    *   Neither the name of Marvell nor the names of its contributors may be 
49
 
        used to endorse or promote products derived from this software without 
50
 
        specific prior written permission. 
51
 
    
52
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
53
 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
54
 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
55
 
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
56
 
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
57
 
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
58
 
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
59
 
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
60
 
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
61
 
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62
 
 
63
 
*******************************************************************************/
64
 
 
65
 
#include "voiceband/tdm/mvTdm.h"
66
 
#include "mvSysTdm.h"
67
 
 
68
 
 
69
 
/* defines  */
70
 
#ifdef MV_DEBUG
71
 
        #define DB(x)   x
72
 
#else
73
 
        #define DB(x)
74
 
#endif  
75
 
 
76
 
static MV_TARGET tdmAddrDecPrioTap[] =
77
 
{
78
 
        PEX0_MEM,
79
 
        SDRAM_CS0,
80
 
        SDRAM_CS1,
81
 
        SDRAM_CS2,
82
 
        SDRAM_CS3,
83
 
        DEVICE_CS0,
84
 
        DEVICE_CS1,
85
 
        DEVICE_CS2,
86
 
        DEV_BOOCS,
87
 
        PEX0_IO,
88
 
        TBL_TERM
89
 
};
90
 
 
91
 
 
92
 
static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
93
 
 
94
 
/*******************************************************************************
95
 
* mvTdmWinInit - Initialize TDM address decode windows 
96
 
*
97
 
* DESCRIPTION:
98
 
*               This function initialize TDM window decode unit. It set the 
99
 
*               default address decode
100
 
*               windows of the unit.
101
 
*
102
 
* INPUT:
103
 
*       None.
104
 
*
105
 
* OUTPUT:
106
 
*       None.
107
 
*
108
 
* RETURN:
109
 
*       MV_ERROR if setting fail.
110
 
*******************************************************************************/
111
 
 
112
 
MV_STATUS mvTdmWinInit(void)
113
 
{
114
 
        MV_U32          winNum;
115
 
        MV_U32          winPrioIndex = 0;
116
 
        MV_CPU_DEC_WIN cpuAddrDecWin;
117
 
        MV_TDM_DEC_WIN tdmWin;
118
 
        MV_STATUS status;
119
 
 
120
 
        /*Disable all windows*/ 
121
 
        for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++)
122
 
        {
123
 
                mvTdmWinEnable(winNum, MV_FALSE);
124
 
        }
125
 
 
126
 
        for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) && 
127
 
                                          (winNum < TDM_MBUS_MAX_WIN)); )
128
 
        {       
129
 
                status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex], 
130
 
                                                                         &cpuAddrDecWin);
131
 
        if (MV_NO_SUCH == status)
132
 
        {
133
 
            winPrioIndex++;
134
 
            continue;
135
 
        }
136
 
                if (MV_OK != status)
137
 
                {
138
 
                        mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n");
139
 
                        return MV_ERROR;
140
 
                }
141
 
 
142
 
        if (cpuAddrDecWin.enable == MV_TRUE)
143
 
                {
144
 
                        tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
145
 
                        tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
146
 
                        tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size;
147
 
                        tdmWin.enable = MV_TRUE;
148
 
                    tdmWin.target = tdmAddrDecPrioTap[winPrioIndex];
149
 
                    if (MV_OK != mvTdmWinSet(winNum, &tdmWin))
150
 
                    {
151
 
                            return MV_ERROR;
152
 
                    }
153
 
                    winNum++;
154
 
                }
155
 
                winPrioIndex++;                 
156
 
    }
157
 
        return MV_OK;
158
 
}
159
 
 
160
 
/*******************************************************************************
161
 
* mvTdmWinSet - Set TDM target address window
162
 
*
163
 
* DESCRIPTION:
164
 
*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
165
 
*       address window, also known as address decode window.
166
 
*       After setting this target window, the TDM will be able to access the
167
 
*       target within the address window.
168
 
*
169
 
* INPUT:
170
 
*       winNum      - TDM to target address decode window number.
171
 
*       pAddrDecWin - TDM target window data structure.
172
 
*
173
 
* OUTPUT:
174
 
*       None.
175
 
*
176
 
* RETURN:
177
 
*       MV_ERROR if address window overlapps with other address decode windows.
178
 
*       MV_BAD_PARAM if base address is invalid parameter or target is
179
 
*       unknown.
180
 
*
181
 
*******************************************************************************/
182
 
 
183
 
MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
184
 
{
185
 
        MV_TARGET_ATTRIB targetAttribs;
186
 
        MV_DEC_REGS decRegs;
187
 
        MV_U32 ctrlReg = 0;
188
 
 
189
 
    /* Parameter checking   */
190
 
    if (winNum >= TDM_MBUS_MAX_WIN)
191
 
    {
192
 
                mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);
193
 
        return MV_BAD_PARAM;
194
 
    }
195
 
    
196
 
    /* Check if the requested window overlapps with current windows         */
197
 
    if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
198
 
        {
199
 
        mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);
200
 
                return MV_ERROR;
201
 
        }
202
 
 
203
 
        /* check if address is aligned to the size */
204
 
        if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
205
 
        {
206
 
                mvOsPrintf("mvTdmWinSet: Error setting TDM window %d to "\
207
 
                                   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
208
 
                                   winNum,
209
 
                                   mvCtrlTargetNameGet(pAddrDecWin->target), 
210
 
                                   pAddrDecWin->addrWin.baseLow,
211
 
                                   pAddrDecWin->addrWin.size);
212
 
                return MV_ERROR;
213
 
        }
214
 
 
215
 
        decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
216
 
        decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >>  TDM_WIN_SIZE_OFFS;
217
 
 
218
 
        if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
219
 
        {
220
 
                        mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");
221
 
                        return MV_ERROR;
222
 
        }
223
 
        
224
 
        mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
225
 
        
226
 
        /* for the safe side we disable the window before writing the new
227
 
        values */
228
 
        mvTdmWinEnable(winNum, MV_FALSE);
229
 
 
230
 
        ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);
231
 
        ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);
232
 
        ctrlReg |= (decRegs.sizeReg << TDM_WIN_SIZE_OFFS);
233
 
 
234
 
        /* Write to address base and control registers  */
235
 
        MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);
236
 
        MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);  
237
 
        /* Enable address decode target window  */
238
 
        if (pAddrDecWin->enable == MV_TRUE)
239
 
        {
240
 
                mvTdmWinEnable(winNum, MV_TRUE);
241
 
        }    
242
 
        return MV_OK;
243
 
}
244
 
 
245
 
/*******************************************************************************
246
 
* mvTdmWinGet - Get peripheral target address window.
247
 
*
248
 
* DESCRIPTION:
249
 
*               Get TDM peripheral target address window.
250
 
*
251
 
* INPUT:
252
 
*       winNum - TDM to target address decode window number.
253
 
*
254
 
* OUTPUT:
255
 
*       pAddrDecWin - TDM target window data structure.
256
 
*
257
 
* RETURN:
258
 
*       MV_ERROR if register parameters are invalid.
259
 
*
260
 
*******************************************************************************/
261
 
 
262
 
MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
263
 
{
264
 
 
265
 
        MV_DEC_REGS decRegs;
266
 
        MV_TARGET_ATTRIB targetAttrib;
267
 
 
268
 
        /* Parameter checking   */
269
 
        if (winNum >= TDM_MBUS_MAX_WIN)
270
 
        {
271
 
                mvOsPrintf("mvTdmWinGet: ERR. Invalid winNum %d\n", winNum);
272
 
                return MV_NOT_SUPPORTED;
273
 
        }
274
 
        
275
 
        decRegs.baseReg =  MV_REG_READ(TDM_WIN_BASE_REG(winNum));                                                                           
276
 
        decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >>  TDM_WIN_SIZE_OFFS;
277
 
 
278
 
        if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
279
 
        {
280
 
                mvOsPrintf("mvTdmWinGet: mvCtrlRegToAddrDec Failed \n");
281
 
                return MV_ERROR;
282
 
        }
283
 
         
284
 
        /* attrib and targetId */
285
 
        targetAttrib.attrib = 
286
 
                (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ATTRIB_MASK) >>  TDM_WIN_ATTRIB_OFFS;
287
 
        targetAttrib.targetId = 
288
 
                (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_TARGET_MASK) >>  TDM_WIN_TARGET_OFFS;
289
 
         
290
 
        pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
291
 
 
292
 
        /* Check if window is enabled   */
293
 
        if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
294
 
        {
295
 
                pAddrDecWin->enable = MV_TRUE;
296
 
        }
297
 
        else
298
 
        {
299
 
                pAddrDecWin->enable = MV_FALSE;
300
 
        }
301
 
        
302
 
        return MV_OK;
303
 
}
304
 
 
305
 
/*******************************************************************************
306
 
* mvTdmWinEnable - Enable/disable a TDM to target address window
307
 
*
308
 
* DESCRIPTION:
309
 
*       This function enable/disable a TDM to target address window.
310
 
*       According to parameter 'enable' the routine will enable the
311
 
*       window, thus enabling TDM accesses (before enabling the window it is
312
 
*       tested for overlapping). Otherwise, the window will be disabled.
313
 
*
314
 
* INPUT:
315
 
*       winNum - TDM to target address decode window number.
316
 
*       enable - Enable/disable parameter.
317
 
*
318
 
* OUTPUT:
319
 
*       N/A
320
 
*
321
 
* RETURN:
322
 
*       MV_ERROR if decode window number was wrong or enabled window overlapps.
323
 
*
324
 
*******************************************************************************/
325
 
MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)
326
 
{
327
 
        MV_TDM_DEC_WIN addrDecWin;
328
 
 
329
 
        if (MV_TRUE == enable)
330
 
        {
331
 
                if (winNum >= TDM_MBUS_MAX_WIN)
332
 
                {
333
 
                        mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);
334
 
                        return MV_ERROR;
335
 
                }       
336
 
                
337
 
                /* First check for overlap with other enabled windows                           */
338
 
                /* Get current window */
339
 
                if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))
340
 
                {
341
 
                        mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");
342
 
                        return MV_ERROR;
343
 
                }
344
 
                /* Check for overlapping */
345
 
                if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
346
 
                {
347
 
                        /* No Overlap. Enable address decode target window */
348
 
                        MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
349
 
                }
350
 
                else
351
 
                {   /* Overlap detected */
352
 
                        mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");
353
 
                        return MV_ERROR;
354
 
                }
355
 
        }
356
 
        else
357
 
        {
358
 
                MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);        
359
 
        }
360
 
        return MV_OK;
361
 
}
362
 
 
363
 
 
364
 
/*******************************************************************************
365
 
* tdmWinOverlapDetect - Detect TDM address windows overlapping
366
 
*
367
 
* DESCRIPTION:
368
 
*       An unpredicted behaviour is expected in case TDM address decode 
369
 
*       windows overlapps.
370
 
*       This function detects TDM address decode windows overlapping of a 
371
 
*       specified window. The function does not check the window itself for 
372
 
*       overlapping. The function also skipps disabled address decode windows.
373
 
*
374
 
* INPUT:
375
 
*       winNum      - address decode window number.
376
 
*       pAddrDecWin - An address decode window struct.
377
 
*
378
 
* OUTPUT:
379
 
*       None.
380
 
*
381
 
* RETURN:
382
 
*       MV_TRUE if the given address window overlap current address
383
 
*       decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data 
384
 
*       from registers.
385
 
*
386
 
*******************************************************************************/
387
 
static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
388
 
{
389
 
    MV_U32              winNumIndex;
390
 
    MV_TDM_DEC_WIN      addrDecWin;
391
 
 
392
 
    for (winNumIndex = 0; winNumIndex < TDM_MBUS_MAX_WIN; winNumIndex++)
393
 
    {
394
 
                /* Do not check window itself           */
395
 
        if (winNumIndex == winNum)
396
 
                {
397
 
                        continue;
398
 
                }
399
 
                /* Do not check disabled windows        */
400
 
                if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
401
 
                {
402
 
                        /* Get window parameters        */
403
 
                        if (MV_OK != mvTdmWinGet(winNumIndex, &addrDecWin))
404
 
                        {
405
 
                                DB(mvOsPrintf("dmaWinOverlapDetect: ERR. TargetWinGet failed\n"));
406
 
                        return MV_ERROR;
407
 
                        }
408
 
 
409
 
                        if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
410
 
                        {
411
 
                                return MV_TRUE;
412
 
                        }        
413
 
                }
414
 
    }
415
 
        return MV_FALSE;
416
 
}
417
 
 
418
 
/*******************************************************************************
419
 
* mvTdmAddrDecShow - Print the TDM address decode map.
420
 
*
421
 
* DESCRIPTION:
422
 
*       This function print the TDM address decode map.
423
 
*
424
 
* INPUT:
425
 
*       None.
426
 
*
427
 
* OUTPUT:
428
 
*       None.
429
 
*
430
 
* RETURN:
431
 
*       None.
432
 
*
433
 
*******************************************************************************/
434
 
MV_VOID mvTdmAddrDecShow(MV_VOID)
435
 
{
436
 
        MV_TDM_DEC_WIN win;
437
 
        int i;
438
 
 
439
 
        mvOsOutput( "\n" );
440
 
        mvOsOutput( "TDM:\n" );
441
 
        mvOsOutput( "----\n" );
442
 
 
443
 
        for( i = 0; i < TDM_MBUS_MAX_WIN; i++ )
444
 
        {
445
 
                memset( &win, 0, sizeof(MV_TDM_DEC_WIN) );
446
 
 
447
 
                mvOsOutput( "win%d - ", i );
448
 
 
449
 
                if (mvTdmWinGet(i, &win ) == MV_OK )
450
 
                {
451
 
                        if( win.enable )
452
 
                        {
453
 
                mvOsOutput( "%s base %08x, ",
454
 
                mvCtrlTargetNameGet(win.target), win.addrWin.baseLow);
455
 
                mvOsOutput( "...." );
456
 
                mvSizePrint( win.addrWin.size );
457
 
                                mvOsOutput( "\n" );
458
 
                        }
459
 
                        else
460
 
                                mvOsOutput( "disable\n" );
461
 
                }
462
 
        }
463
 
}
464