rename target/linux/generic-2.6 to generic
[15.05/openwrt.git] / target / linux / generic / files / crypto / ocf / kirkwood / mvHal / kw_family / ctrlEnv / sys / mvSysSdmmc.c
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
66 #include "mvTypes.h"
67 #include "mvCommon.h"
68 #include "mvOs.h"
69 #include "ctrlEnv/mvCtrlEnvLib.h"
70 #include "cpu/mvCpu.h"
71 #include "ctrlEnv/sys/mvCpuIf.h"
72 #include "mvRegs.h"
73 #include "ctrlEnv/sys/mvSysSdmmc.h"
74
75 MV_TARGET sdmmcAddrDecPrioTab[] =
76 {
77 #if defined(MV_INCLUDE_SDRAM_CS0)
78     SDRAM_CS0,
79 #endif
80 #if defined(MV_INCLUDE_SDRAM_CS1)
81     SDRAM_CS1,
82 #endif
83 #if defined(MV_INCLUDE_SDRAM_CS2)
84     SDRAM_CS2,
85 #endif
86 #if defined(MV_INCLUDE_SDRAM_CS3)
87     SDRAM_CS3,
88 #endif
89 #if defined(MV_INCLUDE_PEX)
90         PEX0_MEM,
91 #endif
92         TBL_TERM
93 };
94
95
96 /*******************************************************************************
97 * sdmmcWinOverlapDetect - Detect SDMMC address windows overlapping
98 *
99 * DESCRIPTION:
100 *       An unpredicted behaviur is expected in case SDMMC address decode 
101 *       windows overlapps.
102 *       This function detects SDMMC address decode windows overlapping of a 
103 *       specified window. The function does not check the window itself for 
104 *       overlapping. The function also skipps disabled address decode windows.
105 *
106 * INPUT:
107 *       winNum      - address decode window number.
108 *       pAddrDecWin - An address decode window struct.
109 *
110 * OUTPUT:
111 *       None.
112 *
113 * RETURN:
114 *       MV_TRUE if the given address window overlap current address
115 *       decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data 
116 *       from registers.
117 *
118 *******************************************************************************/
119 static MV_STATUS sdmmcWinOverlapDetect(int dev, MV_U32 winNum, 
120                                       MV_ADDR_WIN *pAddrWin)
121 {
122     MV_U32          winNumIndex;
123     MV_SDMMC_DEC_WIN  addrDecWin;
124
125     for(winNumIndex=0; winNumIndex<MV_SDMMC_MAX_ADDR_DECODE_WIN; winNumIndex++)
126     {
127         /* Do not check window itself       */
128         if (winNumIndex == winNum)
129         {
130             continue;
131         }
132
133         /* Get window parameters    */
134         if (MV_OK != mvSdmmcWinGet(dev, winNumIndex, &addrDecWin))
135         {
136             mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
137             return MV_ERROR;
138         }
139
140         /* Do not check disabled windows    */
141         if(addrDecWin.enable == MV_FALSE)
142         {
143             continue;
144         }
145
146         if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
147         {
148             return MV_TRUE;
149         }        
150     }
151     return MV_FALSE;
152 }
153
154
155 /*******************************************************************************
156 * mvSdmmcWinSet - Set SDMMC target address window
157 *
158 * DESCRIPTION:
159 *       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) 
160 *       address window, also known as address decode window. 
161 *       After setting this target window, the SDMMC will be able to access the 
162 *       target within the address window. 
163 *
164 * INPUT:
165 *       winNum      - SDMMC target address decode window number.
166 *       pAddrDecWin - SDMMC target window data structure.
167 *
168 * OUTPUT:
169 *       None.
170 *
171 * RETURN:
172 *       MV_ERROR if address window overlapps with other address decode windows.
173 *       MV_BAD_PARAM if base address is invalid parameter or target is 
174 *       unknown.
175 *
176 *******************************************************************************/
177 MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
178 {
179     MV_TARGET_ATTRIB    targetAttribs;
180     MV_DEC_REGS         decRegs;
181
182     /* Parameter checking   */
183     if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
184     {
185         mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
186         return MV_BAD_PARAM;
187     }
188     
189     /* Check if the requested window overlapps with current windows         */
190     if (MV_TRUE == sdmmcWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
191     {
192         mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
193         return MV_ERROR;
194     }
195
196     /* check if address is aligned to the size */
197     if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
198     {
199         mvOsPrintf("mvSdmmcWinSet:Error setting SDMMC window %d to "\
200                    "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
201                    winNum,
202                    mvCtrlTargetNameGet(pAddrDecWin->target), 
203                    pAddrDecWin->addrWin.baseLow,
204                    pAddrDecWin->addrWin.size);
205         return MV_ERROR;
206     }
207
208     decRegs.baseReg = 0;
209     decRegs.sizeReg = 0;
210
211     if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
212     {
213         mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
214         return MV_ERROR;
215     }
216
217     mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
218                                                                                                                          
219     /* set attributes */
220     decRegs.sizeReg &= ~MV_SDMMC_WIN_ATTR_MASK;
221     decRegs.sizeReg |= (targetAttribs.attrib << MV_SDMMC_WIN_ATTR_OFFSET);
222
223     /* set target ID */
224     decRegs.sizeReg &= ~MV_SDMMC_WIN_TARGET_MASK;
225     decRegs.sizeReg |= (targetAttribs.targetId << MV_SDMMC_WIN_TARGET_OFFSET);
226
227     if (pAddrDecWin->enable == MV_TRUE)
228     {
229         decRegs.sizeReg |= MV_SDMMC_WIN_ENABLE_MASK;
230     }
231     else
232     {
233         decRegs.sizeReg &= ~MV_SDMMC_WIN_ENABLE_MASK;
234     }
235
236     MV_REG_WRITE( MV_SDMMC_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
237     MV_REG_WRITE( MV_SDMMC_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
238     
239     return MV_OK;
240 }
241
242 /*******************************************************************************
243 * mvSdmmcWinGet - Get SDMMC peripheral target address window.
244 *
245 * DESCRIPTION:
246 *       Get SDMMC peripheral target address window.
247 *
248 * INPUT:
249 *       winNum - SDMMC target address decode window number.
250 *d
251 * OUTPUT:
252 *       pAddrDecWin - SDMMC target window data structure.
253 *
254 * RETURN:
255 *       MV_ERROR if register parameters are invalid.
256 *
257 *******************************************************************************/
258 MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
259 {
260     MV_DEC_REGS         decRegs;
261     MV_TARGET_ATTRIB    targetAttrib;
262                                                                                                                          
263     /* Parameter checking   */
264     if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
265     {
266         mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n", 
267                     __FUNCTION__, dev, winNum);
268         return MV_NOT_SUPPORTED;
269     }
270
271     decRegs.baseReg = MV_REG_READ( MV_SDMMC_WIN_BASE_REG(dev, winNum) );
272     decRegs.sizeReg = MV_REG_READ( MV_SDMMC_WIN_CTRL_REG(dev, winNum) );
273  
274     if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
275     {
276         mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
277         return MV_ERROR; 
278     }
279        
280     /* attrib and targetId */
281     targetAttrib.attrib = (decRegs.sizeReg & MV_SDMMC_WIN_ATTR_MASK) >> 
282                 MV_SDMMC_WIN_ATTR_OFFSET;
283     targetAttrib.targetId = (decRegs.sizeReg & MV_SDMMC_WIN_TARGET_MASK) >> 
284                 MV_SDMMC_WIN_TARGET_OFFSET;
285  
286     pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
287
288     /* Check if window is enabled   */
289     if(decRegs.sizeReg & MV_SDMMC_WIN_ENABLE_MASK) 
290     {
291         pAddrDecWin->enable = MV_TRUE;
292     }
293     else
294     {
295         pAddrDecWin->enable = MV_FALSE;
296     }
297     return MV_OK;
298 }
299 /*******************************************************************************
300 * mvSdmmcAddrDecShow - Print the SDMMC address decode map.
301 *
302 * DESCRIPTION:
303 *               This function print the SDMMC address decode map.
304 *
305 * INPUT:
306 *       None.
307 *
308 * OUTPUT:
309 *       None.
310 *
311 * RETURN:
312 *       None.
313 *
314 *******************************************************************************/
315 MV_VOID mvSdmmcAddrDecShow(MV_VOID)
316 {
317
318         MV_SDMMC_DEC_WIN win;
319         int i,j=0;
320
321
322
323         if (MV_FALSE == mvCtrlPwrClckGet(SDIO_UNIT_ID, 0)) 
324                 return;
325
326         mvOsOutput( "\n" );
327         mvOsOutput( "SDMMC %d:\n", j );
328         mvOsOutput( "----\n" );
329
330         for( i = 0; i < MV_SDMMC_MAX_ADDR_DECODE_WIN; i++ )
331         {
332             memset( &win, 0, sizeof(MV_SDMMC_DEC_WIN) );
333
334             mvOsOutput( "win%d - ", i );
335
336             if( mvSdmmcWinGet(j, i, &win ) == MV_OK )
337             {
338                 if( win.enable )
339                 {
340                     mvOsOutput( "%s base %08x, ",
341                     mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
342                     mvOsOutput( "...." );
343
344                     mvSizePrint( win.addrWin.size );
345     
346                     mvOsOutput( "\n" );
347                 }
348                 else
349                 mvOsOutput( "disable\n" );
350             }
351         }
352 }
353
354
355 /*******************************************************************************
356 * mvSdmmcWinInit - Initialize the integrated SDMMC target address window.
357 *
358 * DESCRIPTION:
359 *       Initialize the SDMMC peripheral target address window.
360 *
361 * INPUT:
362 *
363 *
364 * OUTPUT:
365 *     
366 *
367 * RETURN:
368 *       MV_ERROR if register parameters are invalid.
369 *
370 *******************************************************************************/
371 MV_STATUS mvSdmmcWinInit(MV_VOID)
372 {
373     int             winNum;
374     MV_SDMMC_DEC_WIN  sdmmcWin;
375     MV_CPU_DEC_WIN  cpuAddrDecWin;
376     MV_U32          status, winPrioIndex = 0;
377
378     /* Initiate Sdmmc address decode */
379
380     /* First disable all address decode windows */
381     for(winNum = 0; winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN; winNum++)
382     {
383         MV_U32  regVal = MV_REG_READ(MV_SDMMC_WIN_CTRL_REG(0, winNum));
384         regVal &= ~MV_SDMMC_WIN_ENABLE_MASK;
385         MV_REG_WRITE(MV_SDMMC_WIN_CTRL_REG(0, winNum), regVal);
386     }
387     
388     winNum = 0;
389     while( (sdmmcAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
390            (winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN) )
391     {
392         /* first get attributes from CPU If */
393         status = mvCpuIfTargetWinGet(sdmmcAddrDecPrioTab[winPrioIndex],
394                                      &cpuAddrDecWin);
395
396         if(MV_NO_SUCH == status)
397         {
398             winPrioIndex++;
399             continue;
400         }
401         if (MV_OK != status)
402         {
403             mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
404             return MV_ERROR;
405         }
406
407         if (cpuAddrDecWin.enable == MV_TRUE)
408         {
409             sdmmcWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
410             sdmmcWin.addrWin.baseLow  = cpuAddrDecWin.addrWin.baseLow;
411             sdmmcWin.addrWin.size     = cpuAddrDecWin.addrWin.size;
412             sdmmcWin.enable           = MV_TRUE;
413             sdmmcWin.target           = sdmmcAddrDecPrioTab[winPrioIndex];
414             
415             if(MV_OK != mvSdmmcWinSet(0/*dev*/, winNum, &sdmmcWin))
416             {
417                 return MV_ERROR;
418             }
419             winNum++;
420         }
421         winPrioIndex++;
422     }
423     return MV_OK;
424 }
425
426
427