Root/target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c

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

Archive Download this file



interactive