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
90static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
91
92/*******************************************************************************
93* mvTdmWinInit - Initialize TDM address decode windows
94*
95* DESCRIPTION:
96* This function initialize TDM window decode unit. It set the
97* default address decode
98* windows of the unit.
99*
100* INPUT:
101* None.
102*
103* OUTPUT:
104* None.
105*
106* RETURN:
107* MV_ERROR if setting fail.
108*******************************************************************************/
109
110MV_STATUS mvTdmWinInit(void)
111{
112    MV_U32 winNum;
113    MV_U32 winPrioIndex = 0;
114    MV_CPU_DEC_WIN cpuAddrDecWin;
115    MV_TDM_DEC_WIN tdmWin;
116    MV_STATUS status;
117
118    /*Disable all windows*/
119    for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++)
120    {
121        mvTdmWinEnable(winNum, MV_FALSE);
122    }
123
124    for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
125                      (winNum < TDM_MBUS_MAX_WIN)); )
126    {
127        status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex],
128                                     &cpuAddrDecWin);
129        if (MV_NO_SUCH == status)
130        {
131            winPrioIndex++;
132            continue;
133        }
134        if (MV_OK != status)
135        {
136            mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n");
137            return MV_ERROR;
138        }
139
140        if (cpuAddrDecWin.enable == MV_TRUE)
141        {
142            tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
143            tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
144            tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size;
145            tdmWin.enable = MV_TRUE;
146            tdmWin.target = tdmAddrDecPrioTap[winPrioIndex];
147            if (MV_OK != mvTdmWinSet(winNum, &tdmWin))
148            {
149                return MV_ERROR;
150            }
151            winNum++;
152        }
153        winPrioIndex++;
154    }
155    return MV_OK;
156}
157
158/*******************************************************************************
159* mvTdmWinSet - Set TDM target address window
160*
161* DESCRIPTION:
162* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
163* address window, also known as address decode window.
164* After setting this target window, the TDM will be able to access the
165* target within the address window.
166*
167* INPUT:
168* winNum - TDM to target address decode window number.
169* pAddrDecWin - TDM target window data structure.
170*
171* OUTPUT:
172* None.
173*
174* RETURN:
175* MV_ERROR if address window overlapps with other address decode windows.
176* MV_BAD_PARAM if base address is invalid parameter or target is
177* unknown.
178*
179*******************************************************************************/
180
181MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
182{
183    MV_TARGET_ATTRIB targetAttribs;
184    MV_DEC_REGS decRegs;
185    MV_U32 ctrlReg = 0;
186
187    /* Parameter checking */
188    if (winNum >= TDM_MBUS_MAX_WIN)
189    {
190        mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);
191        return MV_BAD_PARAM;
192    }
193    
194    /* Check if the requested window overlapps with current windows */
195    if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
196       {
197           mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);
198        return MV_ERROR;
199    }
200
201    /* check if address is aligned to the size */
202    if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
203    {
204        mvOsPrintf("mvTdmWinSet: Error setting TDM window %d to "\
205                   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
206                   winNum,
207                   mvCtrlTargetNameGet(pAddrDecWin->target),
208                   pAddrDecWin->addrWin.baseLow,
209                   pAddrDecWin->addrWin.size);
210        return MV_ERROR;
211    }
212
213    decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
214    decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
215
216    if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
217    {
218            mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");
219            return MV_ERROR;
220    }
221    
222    mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
223    
224    /* for the safe side we disable the window before writing the new
225    values */
226    mvTdmWinEnable(winNum, MV_FALSE);
227
228    ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);
229    ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);
230    ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK);
231
232    /* Write to address base and control registers */
233    MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);
234    MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);
235    /* Enable address decode target window */
236    if (pAddrDecWin->enable == MV_TRUE)
237    {
238        mvTdmWinEnable(winNum, MV_TRUE);
239    }
240    return MV_OK;
241}
242
243/*******************************************************************************
244* mvTdmWinGet - Get peripheral target address window.
245*
246* DESCRIPTION:
247* Get TDM peripheral target address window.
248*
249* INPUT:
250* winNum - TDM to target address decode window number.
251*
252* OUTPUT:
253* pAddrDecWin - TDM target window data structure.
254*
255* RETURN:
256* MV_ERROR if register parameters are invalid.
257*
258*******************************************************************************/
259
260MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
261{
262
263    MV_DEC_REGS decRegs;
264    MV_TARGET_ATTRIB targetAttrib;
265
266    /* Parameter checking */
267    if (winNum >= TDM_MBUS_MAX_WIN)
268    {
269        mvOsPrintf("mvTdmWinGet: ERR. Invalid winNum %d\n", winNum);
270        return MV_NOT_SUPPORTED;
271    }
272    
273    decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
274    decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
275 
276    if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
277    {
278        mvOsPrintf("mvTdmWinGet: mvCtrlRegToAddrDec Failed \n");
279        return MV_ERROR;
280    }
281     
282    /* attrib and targetId */
283    targetAttrib.attrib =
284        (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ATTRIB_MASK) >> TDM_WIN_ATTRIB_OFFS;
285    targetAttrib.targetId =
286        (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_TARGET_MASK) >> TDM_WIN_TARGET_OFFS;
287     
288    pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
289
290    /* Check if window is enabled */
291    if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
292    {
293        pAddrDecWin->enable = MV_TRUE;
294    }
295    else
296    {
297        pAddrDecWin->enable = MV_FALSE;
298    }
299    
300    return MV_OK;
301}
302
303/*******************************************************************************
304* mvTdmWinEnable - Enable/disable a TDM to target address window
305*
306* DESCRIPTION:
307* This function enable/disable a TDM to target address window.
308* According to parameter 'enable' the routine will enable the
309* window, thus enabling TDM accesses (before enabling the window it is
310* tested for overlapping). Otherwise, the window will be disabled.
311*
312* INPUT:
313* winNum - TDM to target address decode window number.
314* enable - Enable/disable parameter.
315*
316* OUTPUT:
317* N/A
318*
319* RETURN:
320* MV_ERROR if decode window number was wrong or enabled window overlapps.
321*
322*******************************************************************************/
323MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)
324{
325    MV_TDM_DEC_WIN addrDecWin;
326
327    if (MV_TRUE == enable)
328    {
329        if (winNum >= TDM_MBUS_MAX_WIN)
330        {
331            mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);
332            return MV_ERROR;
333        }
334        
335        /* First check for overlap with other enabled windows */
336        /* Get current window */
337        if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))
338        {
339            mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");
340            return MV_ERROR;
341        }
342        /* Check for overlapping */
343        if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
344        {
345            /* No Overlap. Enable address decode target window */
346            MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
347        }
348        else
349        { /* Overlap detected */
350            mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");
351            return MV_ERROR;
352        }
353    }
354    else
355    {
356        MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
357    }
358    return MV_OK;
359}
360
361
362/*******************************************************************************
363* tdmWinOverlapDetect - Detect TDM address windows overlapping
364*
365* DESCRIPTION:
366* An unpredicted behaviour is expected in case TDM address decode
367* windows overlapps.
368* This function detects TDM address decode windows overlapping of a
369* specified window. The function does not check the window itself for
370* overlapping. The function also skipps disabled address decode windows.
371*
372* INPUT:
373* winNum - address decode window number.
374* pAddrDecWin - An address decode window struct.
375*
376* OUTPUT:
377* None.
378*
379* RETURN:
380* MV_TRUE if the given address window overlap current address
381* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
382* from registers.
383*
384*******************************************************************************/
385static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
386{
387    MV_U32 winNumIndex;
388    MV_TDM_DEC_WIN addrDecWin;
389
390    for (winNumIndex = 0; winNumIndex < TDM_MBUS_MAX_WIN; winNumIndex++)
391    {
392        /* Do not check window itself */
393        if (winNumIndex == winNum)
394        {
395            continue;
396        }
397        /* Do not check disabled windows */
398        if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
399        {
400            /* Get window parameters */
401            if (MV_OK != mvTdmWinGet(winNumIndex, &addrDecWin))
402            {
403                DB(mvOsPrintf("dmaWinOverlapDetect: ERR. TargetWinGet failed\n"));
404                    return MV_ERROR;
405            }
406
407            if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
408            {
409                return MV_TRUE;
410            }
411        }
412    }
413    return MV_FALSE;
414}
415
416/*******************************************************************************
417* mvTdmAddrDecShow - Print the TDM address decode map.
418*
419* DESCRIPTION:
420* This function print the TDM address decode map.
421*
422* INPUT:
423* None.
424*
425* OUTPUT:
426* None.
427*
428* RETURN:
429* None.
430*
431*******************************************************************************/
432MV_VOID mvTdmAddrDecShow(MV_VOID)
433{
434    MV_TDM_DEC_WIN win;
435    int i;
436
437    mvOsOutput( "\n" );
438    mvOsOutput( "TDM:\n" );
439    mvOsOutput( "----\n" );
440
441    for( i = 0; i < TDM_MBUS_MAX_WIN; i++ )
442    {
443        memset( &win, 0, sizeof(MV_TDM_DEC_WIN) );
444
445        mvOsOutput( "win%d - ", i );
446
447        if (mvTdmWinGet(i, &win ) == MV_OK )
448        {
449            if( win.enable )
450            {
451                mvOsOutput( "%s base %08x, ",
452                mvCtrlTargetNameGet(win.target), win.addrWin.baseLow);
453                mvOsOutput( "...." );
454                mvSizePrint( win.addrWin.size );
455                mvOsOutput( "\n" );
456            }
457            else
458                mvOsOutput( "disable\n" );
459        }
460    }
461}
462
463

Archive Download this file



interactive