rename target/linux/generic-2.6 to generic
[15.05/openwrt.git] / target / linux / generic / files / crypto / ocf / kirkwood / mvHal / mv_hal / ddr2 / mvDramIf.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 /* includes */
67 #include "ddr2/mvDramIf.h"
68 #include "ctrlEnv/sys/mvCpuIf.h"
69
70 #include "ddr2/mvDramIfStaticInit.h"
71
72 /* #define MV_DEBUG */
73 #ifdef MV_DEBUG
74 #define DB(x) x
75 #else
76 #define DB(x)
77 #endif
78
79 /* DRAM bank presence encoding */
80 #define BANK_PRESENT_CS0                            0x1
81 #define BANK_PRESENT_CS0_CS1                    0x3
82 #define BANK_PRESENT_CS0_CS2                    0x5
83 #define BANK_PRESENT_CS0_CS1_CS2                0x7
84 #define BANK_PRESENT_CS0_CS2_CS3                0xd
85 #define BANK_PRESENT_CS0_CS2_CS3_CS4    0xf
86
87 /* locals   */
88 #ifndef MV_STATIC_DRAM_ON_BOARD
89 static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
90 static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32  busClk, MV_STATUS TTmode );
91 static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32  busClk);
92 static MV_U32 sdramModeRegCalc(MV_U32 minCas);
93 static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
94 static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1);
95 static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk);
96 static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl);
97 static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk);
98 static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
99 static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas);
100 static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas);
101 #endif
102 MV_32 DRAM_CS_Order[MV_DRAM_MAX_CS] = {N_A
103
104 #ifdef MV_INCLUDE_SDRAM_CS1
105                 ,N_A
106 #endif
107 #ifdef MV_INCLUDE_SDRAM_CS2
108                 ,N_A
109 #endif
110 #ifdef MV_INCLUDE_SDRAM_CS3
111     ,N_A
112 #endif
113         };
114 /* Get DRAM size of CS num */
115 MV_U32 mvDramCsSizeGet(MV_U32 csNum)
116 {
117         MV_DRAM_BANK_INFO bankInfo;
118         MV_U32  size, deviceW, dimmW;
119 #ifdef MV78XX0  
120         MV_U32  temp;
121 #endif
122
123         if(MV_OK == mvDramBankInfoGet(csNum, &bankInfo))
124         {
125                 if (0 == bankInfo.size)
126                         return 0;
127
128                 /* Note that the Dimm width might be different then the device DRAM width */
129 #ifdef MV78XX0  
130                 temp = MV_REG_READ(SDRAM_CONFIG_REG);
131                 deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
132 #else
133                 deviceW = 16 /* KW family */;
134 #endif
135                 dimmW = bankInfo.dataWidth - (bankInfo.dataWidth % 16);
136                 size = ((bankInfo.size << 20) / (dimmW/deviceW)); 
137                 return size;
138         }
139         else
140                 return 0;
141 }
142 /*******************************************************************************
143 * mvDramIfDetect - Prepare DRAM interface configuration values.
144 *
145 * DESCRIPTION:
146 *       This function implements the full DRAM detection and timing 
147 *       configuration for best system performance.
148 *       Since this routine runs from a ROM device (Boot Flash), its stack 
149 *       resides on RAM, that might be the system DRAM. Changing DRAM 
150 *       configuration values while keeping vital data in DRAM is risky. That
151 *       is why the function does not preform the configuration setting but 
152 *       prepare those in predefined 32bit registers (in this case IDMA 
153 *       registers are used) for other routine to perform the settings.
154 *       The function will call for board DRAM SPD information for each DRAM 
155 *       chip select. The function will then analyze those SPD parameters of 
156 *       all DRAM banks in order to decide on DRAM configuration compatible 
157 *       for all DRAM banks.
158 *       The function will set the CPU DRAM address decode registers.
159 *       Note: This routine prepares values that will overide configuration of
160 *       mvDramBasicAsmInit().
161 *       
162 * INPUT:
163 *       forcedCl - Forced CAL Latency. If equal to zero, do not force.
164 *       eccDisable - Force down the ECC.
165 *
166 * OUTPUT:
167 *       None.
168 *
169 * RETURN:
170 *       None.
171 *
172 *******************************************************************************/
173 MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable)
174 {
175         MV_32   MV_DRAM_CS_order[MV_DRAM_MAX_CS] = {
176                 SDRAM_CS0
177 #ifdef MV_INCLUDE_SDRAM_CS1
178                 ,SDRAM_CS1
179 #endif
180 #ifdef MV_INCLUDE_SDRAM_CS2
181                 ,SDRAM_CS2
182 #endif
183 #ifdef MV_INCLUDE_SDRAM_CS3
184                 ,SDRAM_CS3
185 #endif
186                 };
187         MV_U32  busClk, deviceW, dimmW;
188         MV_U32 numOfAllDevices = 0;
189         MV_STATUS TTMode; 
190 #ifndef MV_STATIC_DRAM_ON_BOARD
191         MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
192         MV_U32  size, base = 0, i, j, temp, busClkPs;
193         MV_U8   minCas;
194         MV_CPU_DEC_WIN dramDecWin;
195         dramDecWin.addrWin.baseHigh = 0;
196 #endif
197
198         busClk = mvBoardSysClkGet();
199
200         if (0 == busClk)
201         {
202                 mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
203                 return MV_ERROR;
204         }
205         
206 #ifndef MV_STATIC_DRAM_ON_BOARD
207
208         busClkPs = 1000000000 / (busClk / 1000);  /* in ps units */
209         /* we will use bank 0 as the representative of the all the DRAM banks,  */
210         /* since bank 0 must exist.                                             */      
211         for(i = 0; i < MV_DRAM_MAX_CS; i++)
212         { 
213                 /* if Bank exist */
214                 if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
215                 {
216                         DB(mvOsPrintf("Dram: Find bank %d\n", i));
217                         /* check it isn't SDRAM */
218                         if(bankInfo[i].memoryType != MEM_TYPE_DDR2)
219                         {
220                                 mvOsOutput("Dram: ERR. SDRAM type not supported !!!\n");
221                                 return MV_ERROR;
222                         }
223
224                         /* All banks must support the Mclk freqency */
225                         if(bankInfo[i].minCycleTimeAtMaxCasLatPs > busClkPs)
226                         {
227                                 mvOsOutput("Dram: ERR. Bank %d doesn't support memory clock!!!\n", i);
228                                 return MV_ERROR;
229                         }
230
231                         /* All banks must support registry in order to activate it */
232                         if(bankInfo[i].registeredAddrAndControlInputs != 
233                            bankInfo[0].registeredAddrAndControlInputs)
234                         {
235                                 mvOsOutput("Dram: ERR. different Registered settings !!!\n");
236                                 return MV_ERROR;
237                         }
238
239                         /* All banks must support same ECC mode */
240                         if(bankInfo[i].errorCheckType != 
241                            bankInfo[0].errorCheckType)
242                         {
243                                 mvOsOutput("Dram: ERR. different ECC settings !!!\n");
244                                 return MV_ERROR;
245                         }
246
247                 }
248                 else
249                 {
250                         if( i == 0 ) /* bank 0 doesn't exist */
251                         {
252                                 mvOsOutput("Dram: ERR. Fail to detect bank 0 !!!\n");
253                                 return MV_ERROR;
254                         }
255                         else
256                         {
257                                 DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
258                                 bankInfo[i].size = 0;     /* Mark this bank as non exist */
259                         }
260                 }
261         }
262
263 #ifdef MV_INCLUDE_SDRAM_CS2
264         if (bankInfo[SDRAM_CS0].size <  bankInfo[SDRAM_CS2].size)
265         {
266                 MV_DRAM_CS_order[0] = SDRAM_CS2;
267                 MV_DRAM_CS_order[1] = SDRAM_CS3;
268                 MV_DRAM_CS_order[2] = SDRAM_CS0;
269                 MV_DRAM_CS_order[3] = SDRAM_CS1;
270                 DRAM_CS_Order[0] = SDRAM_CS2;
271                 DRAM_CS_Order[1] = SDRAM_CS3;
272                 DRAM_CS_Order[2] = SDRAM_CS0;
273                 DRAM_CS_Order[3] = SDRAM_CS1;
274
275         }
276         else
277 #endif
278         {
279                 MV_DRAM_CS_order[0] = SDRAM_CS0;
280                 MV_DRAM_CS_order[1] = SDRAM_CS1;
281                 DRAM_CS_Order[0] = SDRAM_CS0;
282                 DRAM_CS_Order[1] = SDRAM_CS1;
283 #ifdef MV_INCLUDE_SDRAM_CS2
284                 MV_DRAM_CS_order[2] = SDRAM_CS2;
285                 MV_DRAM_CS_order[3] = SDRAM_CS3;
286                 DRAM_CS_Order[2] = SDRAM_CS2;
287                 DRAM_CS_Order[3] = SDRAM_CS3;
288 #endif
289         }
290
291         for(j = 0; j < MV_DRAM_MAX_CS; j++)
292         {
293                 i = MV_DRAM_CS_order[j];
294                 
295                 if (0 == bankInfo[i].size)
296                         continue;
297
298                         /* Init the CPU window decode */
299                         /* Note that the Dimm width might be different then the device DRAM width */
300 #ifdef MV78XX0  
301                         temp = MV_REG_READ(SDRAM_CONFIG_REG);
302                         deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
303 #else
304                         deviceW = 16 /* KW family */;
305 #endif
306                         dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
307                         size = ((bankInfo[i].size << 20) / (dimmW/deviceW)); 
308                 
309                         /* We can not change DRAM window settings while excecuting      */
310                         /* code from it. That is why we skip the DRAM CS[0], saving     */
311                         /* it to the ROM configuration routine                          */
312
313                         numOfAllDevices += bankInfo[i].numberOfDevices;
314                         if (i == MV_DRAM_CS_order[0])
315                         {
316                                 MV_U32 sizeToReg;
317                                 /* Translate the given window size to register format           */
318                                 sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
319                                 /* Size parameter validity check.                           */
320                                 if (-1 == sizeToReg)
321                                 {
322                                         mvOsOutput("DRAM: mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
323                                                            ,i);
324                                         return MV_BAD_PARAM;
325                                 }
326
327                                 DB(mvOsPrintf("Dram: Bank 0 Size - %x\n",sizeToReg);)
328                                 sizeToReg = (sizeToReg << SCSR_SIZE_OFFS);
329                                 sizeToReg |= SCSR_WIN_EN;
330                                 MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
331                         }
332                         else
333                         {
334                                 dramDecWin.addrWin.baseLow = base;
335                                 dramDecWin.addrWin.size = size;
336                                 dramDecWin.enable = MV_TRUE;
337                                 DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
338                                 
339                                 /* Check if the DRAM size is more then 3GByte */
340                                 if (base < 0xC0000000)
341                                 {
342                                         DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
343                                 if (MV_OK != mvCpuIfTargetWinSet(i, &dramDecWin))
344                                         {
345                                                 mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", SDRAM_CS0 + i);
346                                                 return  MV_ERROR;
347                                         }
348                                 }
349                         }
350                         
351                         base += size;
352
353                         /* update the suportedCasLatencies mask */
354                         bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
355         }
356
357         /* calculate minimum CAS */
358         minCas = minCasCalc(&bankInfo[0], &bankInfo[2], busClk, forcedCl);
359         if (0 == minCas) 
360         {
361                 mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
362                                    (busClk / 1000000));
363
364                 minCas = DDR2_CL_4; /* Continue with this CAS */
365                 mvOsOutput("Set default CAS latency 4\n");
366         }
367
368         /* calc SDRAM_CONFIG_REG  and save it to temp register */
369         temp = sdramConfigRegCalc(&bankInfo[0],&bankInfo[2], busClk);
370         if(-1 == temp)
371         {
372                 mvOsOutput("Dram: ERR. sdramConfigRegCalc failed !!!\n");
373                 return MV_ERROR;
374         }
375
376         /* check if ECC is enabled by the user */
377         if(eccDisable)  
378         {       
379                 /* turn off ECC*/
380                 temp &= ~BIT18;
381         }
382         DB(mvOsPrintf("Dram: sdramConfigRegCalc - %x\n",temp);)
383         MV_REG_WRITE(DRAM_BUF_REG1, temp);
384         
385         /* calc SDRAM_MODE_REG  and save it to temp register */ 
386         temp = sdramModeRegCalc(minCas);
387         if(-1 == temp)
388         {
389                 mvOsOutput("Dram: ERR. sdramModeRegCalc failed !!!\n");
390                 return MV_ERROR;
391         }
392         DB(mvOsPrintf("Dram: sdramModeRegCalc - %x\n",temp);)
393         MV_REG_WRITE(DRAM_BUF_REG2, temp);
394
395         /* calc SDRAM_EXTENDED_MODE_REG  and save it to temp register */ 
396         temp = sdramExtModeRegCalc(&bankInfo[0], busClk);
397         if(-1 == temp)
398         {
399                 mvOsOutput("Dram: ERR. sdramExtModeRegCalc failed !!!\n");
400                 return MV_ERROR;
401         }
402         DB(mvOsPrintf("Dram: sdramExtModeRegCalc - %x\n",temp);)
403         MV_REG_WRITE(DRAM_BUF_REG10, temp);
404
405         /* calc D_UNIT_CONTROL_LOW  and save it to temp register */
406         TTMode = MV_FALSE;
407         DB(mvOsPrintf("Dram: numOfAllDevices = %x\n",numOfAllDevices);)
408         if( (numOfAllDevices > 9) && (bankInfo[0].registeredAddrAndControlInputs == MV_FALSE) )
409         {
410                 if ( ( (numOfAllDevices > 9) && (busClk > MV_BOARD_SYSCLK_200MHZ) ) ||
411                         (numOfAllDevices > 18) )
412                 {
413                         mvOsOutput("Enable 2T ");
414                         TTMode = MV_TRUE;
415                 }
416         }
417
418         temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas, busClk, TTMode ); 
419         if(-1 == temp)
420         {
421                 mvOsOutput("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
422                 return MV_ERROR;
423         }
424         DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc - %x\n",temp);)
425         MV_REG_WRITE(DRAM_BUF_REG3, temp); 
426
427         /* calc D_UNIT_CONTROL_HIGH  and save it to temp register */
428         temp = dunitCtrlHighRegCalc(&bankInfo[0], busClk); 
429         if(-1 == temp)
430         {
431                 mvOsOutput("Dram: ERR. dunitCtrlHighRegCalc failed !!!\n");
432                 return MV_ERROR;
433         }
434         DB(mvOsPrintf("Dram: dunitCtrlHighRegCalc - %x\n",temp);)
435         /* check if ECC is enabled by the user */
436         if(eccDisable)  
437         {       
438                 /* turn off sample stage if no ecc */
439                 temp &= ~SDRAM__D2P_EN;;
440         }
441         MV_REG_WRITE(DRAM_BUF_REG13, temp); 
442
443         /* calc SDRAM_ADDR_CTRL_REG  and save it to temp register */
444         temp = sdramAddrCtrlRegCalc(&bankInfo[0],&bankInfo[2]);
445         if(-1 == temp)
446         {
447                 mvOsOutput("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
448                 return MV_ERROR;
449         }
450         DB(mvOsPrintf("Dram: sdramAddrCtrlRegCalc - %x\n",temp);)
451         MV_REG_WRITE(DRAM_BUF_REG4, temp);
452
453         /* calc SDRAM_TIMING_CTRL_LOW_REG  and save it to temp register */
454         temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
455         if(-1 == temp)
456         {
457                 mvOsOutput("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
458                 return MV_ERROR;
459         }
460         DB(mvOsPrintf("Dram: sdramTimeCtrlLowRegCalc - %x\n",temp);)
461         MV_REG_WRITE(DRAM_BUF_REG5, temp);
462
463         /* calc SDRAM_TIMING_CTRL_HIGH_REG  and save it to temp register */
464         temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
465         if(-1 == temp)
466         {
467                 mvOsOutput("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
468                 return MV_ERROR;
469         }
470         DB(mvOsPrintf("Dram: sdramTimeCtrlHighRegCalc - %x\n",temp);)
471         MV_REG_WRITE(DRAM_BUF_REG6, temp);
472
473         sdramDDr2OdtConfig(bankInfo);
474
475         /* calc DDR2_SDRAM_TIMING_LOW_REG  and save it to temp register */
476         temp = sdramDdr2TimeLoRegCalc(minCas);
477         if(-1 == temp)
478         {
479                 mvOsOutput("Dram: ERR. sdramDdr2TimeLoRegCalc failed !!!\n");
480                 return MV_ERROR;
481         }
482         DB(mvOsPrintf("Dram: sdramDdr2TimeLoRegCalc - %x\n",temp);)
483         MV_REG_WRITE(DRAM_BUF_REG11, temp);
484
485         /* calc DDR2_SDRAM_TIMING_HIGH_REG  and save it to temp register */
486         temp = sdramDdr2TimeHiRegCalc(minCas);
487         if(-1 == temp)
488         {
489                 mvOsOutput("Dram: ERR. sdramDdr2TimeHiRegCalc failed !!!\n");
490                 return MV_ERROR;
491         }
492         DB(mvOsPrintf("Dram: sdramDdr2TimeHiRegCalc - %x\n",temp);)
493         MV_REG_WRITE(DRAM_BUF_REG12, temp);
494 #endif
495         
496         /* Note that DDR SDRAM Address/Control and Data pad calibration     */
497         /* settings is done in mvSdramIfConfig.s                            */
498
499         return MV_OK;
500 }
501
502
503 /*******************************************************************************
504 * mvDramIfBankBaseGet - Get DRAM interface bank base.
505 *
506 * DESCRIPTION:
507 *       This function returns the 32 bit base address of a given DRAM bank.
508 *
509 * INPUT:
510 *       bankNum - Bank number.
511 *
512 * OUTPUT:
513 *       None.
514 *
515 * RETURN:
516 *       DRAM bank size. If bank is disabled or paramter is invalid, the 
517 *               function returns -1.
518 *
519 *******************************************************************************/
520 MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum)
521 {
522         DB(mvOsPrintf("Dram: mvDramIfBankBaseGet Bank %d base addr is %x \n",
523                                   bankNum, mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum)));
524         return mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum);
525 }
526
527 /*******************************************************************************
528 * mvDramIfBankSizeGet - Get DRAM interface bank size.
529 *
530 * DESCRIPTION:
531 *       This function returns the size of a given DRAM bank.
532 *
533 * INPUT:
534 *       bankNum - Bank number.
535 *
536 * OUTPUT:
537 *       None.
538 *
539 * RETURN:
540 *       DRAM bank size. If bank is disabled the function return '0'. In case 
541 *               or paramter is invalid, the function returns -1.
542 *
543 *******************************************************************************/
544 MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum)
545 {
546         DB(mvOsPrintf("Dram: mvDramIfBankSizeGet Bank %d size is %x \n",
547                                   bankNum, mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum)));
548         return mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum);
549 }
550
551
552 /*******************************************************************************
553 * mvDramIfSizeGet - Get DRAM interface total size.
554 *
555 * DESCRIPTION:
556 *       This function get the DRAM total size.
557 *
558 * INPUT:
559 *       None.
560 *
561 * OUTPUT:
562 *       None.
563 *
564 * RETURN:
565 *       DRAM total size. In case or paramter is invalid, the function 
566 *               returns -1.
567 *
568 *******************************************************************************/
569 MV_U32 mvDramIfSizeGet(MV_VOID)
570 {
571         MV_U32 size = 0, i;
572         
573         for(i = 0; i < MV_DRAM_MAX_CS; i++)
574                 size += mvDramIfBankSizeGet(i);
575         
576         DB(mvOsPrintf("Dram: mvDramIfSizeGet size is %x \n",size));
577         return size;
578 }
579
580 /*******************************************************************************
581 * mvDramIfSingleBitErrThresholdSet - Set single bit ECC threshold.
582 *
583 * DESCRIPTION:
584 *       The ECC single bit error threshold is the number of single bit 
585 *       errors to happen before the Dunit generates an interrupt.
586 *       This function set single bit ECC threshold.
587 *
588 * INPUT:
589 *       threshold - threshold.
590 *
591 * OUTPUT:
592 *       None.
593 *
594 * RETURN:
595 *       MV_BAD_PARAM if threshold is to big, MV_OK otherwise.
596 *
597 *******************************************************************************/
598 MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold)
599 {
600     MV_U32 regVal; 
601
602     if (threshold > SECR_THRECC_MAX)
603     {
604         return MV_BAD_PARAM;
605     }
606
607     regVal = MV_REG_READ(SDRAM_ECC_CONTROL_REG);
608     regVal &= ~SECR_THRECC_MASK;
609     regVal |= ((SECR_THRECC(threshold) & SECR_THRECC_MASK));
610     MV_REG_WRITE(SDRAM_ECC_CONTROL_REG, regVal);
611
612     return MV_OK;
613 }
614
615 #ifndef MV_STATIC_DRAM_ON_BOARD
616 /*******************************************************************************
617 * minCasCalc - Calculate the Minimum CAS latency which can be used.
618 *
619 * DESCRIPTION:
620 *       Calculate the minimum CAS latency that can be used, base on the DRAM
621 *       parameters and the SDRAM bus Clock freq.
622 *
623 * INPUT:
624 *       busClk    - the DRAM bus Clock.
625 *       pBankInfo - bank info parameters.
626 *       forcedCl - Forced CAS Latency multiplied by 10. If equal to zero, do not force.
627 *
628 * OUTPUT:
629 *       None
630 *
631 * RETURN:
632 *       The minimum CAS Latency. The function returns 0 if max CAS latency
633 *               supported by banks is incompatible with system bus clock frequancy.
634 *
635 *******************************************************************************/
636
637 static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl)
638 {
639         MV_U32 count = 1, j;
640         MV_U32 busClkPs = 1000000000 / (busClk / 1000);  /* in ps units */
641         MV_U32 startBit, stopBit;
642         MV_U32 minCas0 = 0, minCas2 = 0;
643         
644         
645         /*     DDR 2:
646                         *******-******-******-******-******-******-******-******* 
647                         * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * 
648                         *******-******-******-******-******-******-******-******* 
649         CAS     =       * TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  * 
650         Disco VI=       * TBD  | TBD  |  5   |  4   |  3   |  TBD   | TBD | TBD * 
651         Disco Duo=      * TBD  |   6  |  5   |  4   |  3   |  TBD   | TBD | TBD * 
652                         *********************************************************/
653         
654         
655         /* If we are asked to use the forced CAL  we change the suported CAL to be forcedCl only */
656         if (forcedCl)
657         {
658                 mvOsOutput("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), (forcedCl % 10));
659         
660                         if (forcedCl == 30)
661                                 pBankInfo->suportedCasLatencies = 0x08;
662                         else if (forcedCl == 40)
663                                 pBankInfo->suportedCasLatencies = 0x10;
664                         else if (forcedCl == 50)
665                                 pBankInfo->suportedCasLatencies = 0x20;
666                         else if (forcedCl == 60)
667                                 pBankInfo->suportedCasLatencies = 0x40;
668                         else
669                         {
670                                 mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n", 
671                                                    (forcedCl / 10), (forcedCl % 10));
672                                 pBankInfo->suportedCasLatencies = 0x10;
673                         }
674
675                 return pBankInfo->suportedCasLatencies;        
676         }   
677         
678         /* go over the supported cas mask from Max Cas down and check if the    */
679         /* SysClk stands in its time requirments.                               */
680
681         DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
682                                                                 pBankInfo->suportedCasLatencies,busClkPs ));
683         count = 1;
684         for(j = 7; j > 0; j--)
685         {
686                 if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
687                 {
688                         /* Reset the bits for CL incompatible for the sysClk */
689                         switch (count)
690                         {
691                                 case 1: 
692                                         if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs) 
693                                                 pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
694                                         count++;
695                                         break;
696                                 case 2: 
697                                         if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
698                                                 pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
699                                         count++;
700                                         break;
701                                 case 3: 
702                                         if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
703                                                 pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
704                                         count++;
705                                         break;
706                                 default: 
707                                         pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
708                                         break;
709                         }
710                 }
711         }
712         
713         DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
714                                                                                         pBankInfo->suportedCasLatencies ));
715
716         count = 1;
717         DB(mvOsPrintf("Dram2: minCasCalc supported mask = %x busClkPs = %x \n",
718                                                                 pBankInfo2->suportedCasLatencies,busClkPs ));
719         for(j = 7; j > 0; j--)
720         {
721                 if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
722                 {
723                         /* Reset the bits for CL incompatible for the sysClk */
724                         switch (count)
725                         {
726                                 case 1: 
727                                         if (pBankInfo2->minCycleTimeAtMaxCasLatPs > busClkPs) 
728                                                 pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
729                                         count++;
730                                         break;
731                                 case 2: 
732                                         if (pBankInfo2->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
733                                                 pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
734                                         count++;
735                                         break;
736                                 case 3: 
737                                         if (pBankInfo2->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
738                                                 pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
739                                         count++;
740                                         break;
741                                 default: 
742                                         pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
743                                         break;
744                         }
745                 }
746         }
747         
748         DB(mvOsPrintf("Dram2: minCasCalc support = %x (after SysCC calc)\n",
749                                                                         pBankInfo2->suportedCasLatencies ));
750
751         startBit = 3;   /* DDR2 support CL start with CL3 (bit 3) */
752         stopBit  = 6;   /* DDR2 support CL stops with CL6 (bit 6) */
753
754         for(j = startBit; j <= stopBit ; j++)
755         {
756                 if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
757                 {
758                         DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
759                         minCas0 = (BIT0 << j);
760                         break;
761                 }
762         }
763
764         for(j = startBit; j <= stopBit ; j++)
765         {
766                 if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
767                 {
768                         DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
769                         minCas2 = (BIT0 << j);
770                         break;
771                 }
772         }
773         
774         if (minCas2 > minCas0)
775                 return minCas2;
776         else
777                 return minCas0;
778         
779         return 0; 
780 }
781
782 /*******************************************************************************
783 * sdramConfigRegCalc - Calculate sdram config register
784 *
785 * DESCRIPTION: Calculate sdram config register optimized value based
786 *                       on the bank info parameters.
787 *
788 * INPUT:
789 *       busClk    - the DRAM bus Clock.
790 *       pBankInfo - sdram bank parameters
791 *
792 * OUTPUT:
793 *       None
794 *
795 * RETURN:
796 *       sdram config reg value.
797 *
798 *******************************************************************************/
799 static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk)
800 {
801         MV_U32 sdramConfig = 0;
802         MV_U32 refreshPeriod;
803         
804         busClk /= 1000000; /* we work with busClk in MHz */
805         
806         sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
807         
808         /* figure out the memory refresh internal */
809         switch (pBankInfo->refreshInterval & 0xf)
810         {
811                 case 0x0: /* refresh period is 15.625 usec */
812                                 refreshPeriod = 15625;
813                                 break;
814                 case 0x1: /* refresh period is 3.9 usec         */
815                                 refreshPeriod = 3900;
816                                 break;
817                 case 0x2: /* refresh period is 7.8 usec         */
818                                 refreshPeriod = 7800;
819                                 break;
820                 case 0x3: /* refresh period is 31.3 usec        */
821                                 refreshPeriod = 31300;
822                                 break;
823                 case 0x4: /* refresh period is 62.5 usec        */
824                                 refreshPeriod = 62500;
825                                 break;
826                 case 0x5: /* refresh period is 125 usec         */
827                                 refreshPeriod = 125000;
828                                 break;
829                 default:  /* refresh period undefined                                   */
830                                 mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
831                                 return -1;
832     }
833         
834         /* Now the refreshPeriod is in register format value */
835         refreshPeriod = (busClk * refreshPeriod) / 1000;
836         
837         DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n", 
838                                   refreshPeriod));
839
840         /* make sure the refresh value is only 14 bits */
841         if(refreshPeriod > SDRAM_REFRESH_MAX)
842         {
843                 refreshPeriod = SDRAM_REFRESH_MAX;
844                 DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n", 
845                                           refreshPeriod));
846         }
847         
848         /* Clear the refresh field */
849         sdramConfig &= ~SDRAM_REFRESH_MASK;
850         
851         /* Set new value to refresh field */
852         sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
853         
854         /*  registered DRAM ? */
855         if ( pBankInfo->registeredAddrAndControlInputs )
856         {
857                 /* it's registered DRAM, so set the reg. DRAM bit */
858                 sdramConfig |= SDRAM_REGISTERED;
859                 DB(mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");)
860         }
861
862         /* ECC and IERR support */
863         sdramConfig &= ~SDRAM_ECC_MASK;    /* Clear ECC field */
864         sdramConfig &= ~SDRAM_IERR_MASK;    /* Clear IErr field */
865
866         if ( pBankInfo->errorCheckType ) 
867         {
868                 sdramConfig |= SDRAM_ECC_EN;
869                 sdramConfig |= SDRAM_IERR_REPORTE; 
870                 DB(mvOsPrintf("Dram: mvDramIfDetect Enabling ECC\n"));
871         }
872         else
873         {
874                 sdramConfig |= SDRAM_ECC_DIS;
875                 sdramConfig |= SDRAM_IERR_IGNORE; 
876                 DB(mvOsPrintf("Dram: mvDramIfDetect Disabling ECC!\n"));
877         }
878         /* Set static default settings */
879         sdramConfig |= SDRAM_CONFIG_DV;
880         
881         DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
882                                   sdramConfig));
883         
884         return sdramConfig;  
885 }
886
887 /*******************************************************************************
888 * sdramModeRegCalc - Calculate sdram mode register
889 *
890 * DESCRIPTION: Calculate sdram mode register optimized value based
891 *                       on the bank info parameters and the minCas.
892 *
893 * INPUT:
894 *       minCas    - minimum CAS supported. 
895 *
896 * OUTPUT:
897 *       None
898 *
899 * RETURN:
900 *       sdram mode reg value.
901 *
902 *******************************************************************************/
903 static MV_U32 sdramModeRegCalc(MV_U32 minCas)
904 {
905         MV_U32 sdramMode;
906                 
907         sdramMode = MV_REG_READ(SDRAM_MODE_REG);
908         
909         /* Clear CAS Latency field */
910         sdramMode &= ~SDRAM_CL_MASK;
911         
912         DB(mvOsPrintf("DRAM CAS Latency ");)
913         
914                 switch (minCas)
915                 {
916                         case DDR2_CL_3: 
917                                 sdramMode |= SDRAM_DDR2_CL_3;
918                                 DB(mvOsPrintf("3.\n");)
919                                 break;
920                         case DDR2_CL_4: 
921                                 sdramMode |= SDRAM_DDR2_CL_4;
922                                 DB(mvOsPrintf("4.\n");)
923                                 break;
924                         case DDR2_CL_5: 
925                                 sdramMode |= SDRAM_DDR2_CL_5;
926                                 DB(mvOsPrintf("5.\n");)
927                                 break;
928                         case DDR2_CL_6: 
929                                 sdramMode |= SDRAM_DDR2_CL_6;
930                                 DB(mvOsPrintf("6.\n");)
931                                 break;
932                         default:
933                                 mvOsOutput("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
934                                 return -1;
935         }
936
937         DB(mvOsPrintf("\nsdramModeRegCalc register 0x%x\n", sdramMode ));
938
939         return sdramMode;
940 }
941 /*******************************************************************************
942 * sdramExtModeRegCalc - Calculate sdram Extended mode register
943 *
944 * DESCRIPTION: 
945 *               Return sdram Extended mode register value based
946 *               on the bank info parameters and bank presence.
947 *
948 * INPUT:
949 *       pBankInfo - sdram bank parameters
950 *       busClk - DRAM frequency
951 *
952 * OUTPUT:
953 *       None
954 *
955 * RETURN:
956 *       sdram Extended mode reg value.
957 *
958 *******************************************************************************/
959 static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
960 {
961         MV_U32 populateBanks = 0;
962         int bankNum;
963
964                 /* Represent the populate banks in binary form */
965                 for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
966                 {
967                         if (0 != pBankInfo[bankNum].size)
968                         {
969                                 populateBanks |= (1 << bankNum);
970                         }
971                 }
972         
973                 switch(populateBanks)
974                 {
975                         case(BANK_PRESENT_CS0):
976                         case(BANK_PRESENT_CS0_CS1):
977                                 return DDR_SDRAM_EXT_MODE_CS0_CS1_DV;
978                 
979                         case(BANK_PRESENT_CS0_CS2):
980                         case(BANK_PRESENT_CS0_CS1_CS2):
981                         case(BANK_PRESENT_CS0_CS2_CS3):
982                         case(BANK_PRESENT_CS0_CS2_CS3_CS4):
983                                 if (busClk >= MV_BOARD_SYSCLK_267MHZ)
984                                     return DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV;
985                                 else
986                                     return DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV;
987                 
988                         default:
989                                 mvOsOutput("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
990                                 return -1;
991                 } 
992         return 0;
993 }
994
995 /*******************************************************************************
996 * dunitCtrlLowRegCalc - Calculate sdram dunit control low register
997 *
998 * DESCRIPTION: Calculate sdram dunit control low register optimized value based
999 *                       on the bank info parameters and the minCas.
1000 *
1001 * INPUT:
1002 *       pBankInfo - sdram bank parameters
1003 *       minCas    - minimum CAS supported. 
1004 *
1005 * OUTPUT:
1006 *       None
1007 *
1008 * RETURN:
1009 *       sdram dunit control low reg value.
1010 *
1011 *******************************************************************************/
1012 static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32  busClk, MV_STATUS TTMode)
1013 {
1014         MV_U32 dunitCtrlLow, cl;
1015         MV_U32 sbOutR[4]={3,5,7,9} ;
1016         MV_U32 sbOutU[4]={1,3,5,7} ;
1017         
1018         dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
1019
1020         DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
1021
1022         /* Clear StBurstOutDel field */
1023         dunitCtrlLow &= ~SDRAM_SB_OUT_MASK;
1024         
1025         /* Clear StBurstInDel field */
1026         dunitCtrlLow &= ~SDRAM_SB_IN_MASK;
1027
1028         /* Clear CtrlPos field */
1029         dunitCtrlLow &= ~SDRAM_CTRL_POS_MASK;
1030
1031         /* Clear 2T field */
1032         dunitCtrlLow &= ~SDRAM_2T_MASK;
1033         if (TTMode == MV_TRUE)
1034         {
1035                 dunitCtrlLow |= SDRAM_2T_MODE;
1036         }
1037         
1038         /* For proper sample of read data set the Dunit Control register's      */
1039         /* stBurstInDel bits [27:24]                                            */
1040         /*              200MHz - 267MHz None reg  = CL + 1                      */
1041         /*              200MHz - 267MHz reg       = CL + 2                      */
1042         /*              > 267MHz None reg  = CL + 2                     */
1043         /*              > 267MHz reg      = CL + 3                      */
1044         
1045         /* For proper sample of read data set the Dunit Control register's      */
1046         /* stBurstOutDel bits [23:20]                                           */
1047                         /********-********-********-********-
1048                         *  CL=3  |  CL=4  |  CL=5  |  CL=6  |
1049                         *********-********-********-********-
1050         Not Reg.        *  0001  |  0011  |  0101  |  0111  |
1051                         *********-********-********-********-
1052         Registered      *  0011  |  0101  |  0111  |  1001  |
1053                         *********-********-********-********/
1054     
1055                 /* Set Dunit Control low default value */
1056                 dunitCtrlLow |= SDRAM_DUNIT_CTRL_LOW_DDR2_DV; 
1057
1058                 switch (minCas)
1059                 {
1060                         case DDR2_CL_3: cl = 3; break;
1061                         case DDR2_CL_4: cl = 4; break;
1062                         case DDR2_CL_5: cl = 5; break;
1063                         case DDR2_CL_6: cl = 6; break;
1064                         default:
1065                                 mvOsOutput("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", minCas);
1066                                 return -1;
1067                 }
1068
1069                 /* registerd DDR SDRAM? */
1070                 if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
1071                 {
1072                         dunitCtrlLow |= (sbOutR[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
1073                 }
1074                 else
1075                 {
1076                         dunitCtrlLow |= (sbOutU[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
1077                 }
1078
1079                 DB(mvOsPrintf("\n\ndunitCtrlLowRegCalc: CL = %d, frequencies=%d\n", cl, busClk));
1080
1081                 if (busClk <= MV_BOARD_SYSCLK_267MHZ)
1082                 {
1083                         if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
1084                                 cl = cl + 2;
1085                         else
1086                                 cl = cl + 1;
1087                 }
1088                 else
1089                 {
1090                         if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
1091                                 cl = cl + 3;
1092                         else
1093                                 cl = cl + 2;
1094                 }
1095                 
1096         DB(mvOsPrintf("dunitCtrlLowRegCalc: SDRAM_SB_IN_DEL_OFFS = %d \n", cl));
1097                 dunitCtrlLow |= cl << SDRAM_SB_IN_DEL_OFFS;
1098
1099         DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
1100
1101         return dunitCtrlLow;
1102 }  
1103
1104 /*******************************************************************************
1105 * dunitCtrlHighRegCalc - Calculate sdram dunit control high register
1106 *
1107 * DESCRIPTION: Calculate sdram dunit control high register optimized value based
1108 *                       on the bus clock.
1109 *
1110 * INPUT:
1111 *       busClk    - DRAM frequency. 
1112 *
1113 * OUTPUT:
1114 *       None
1115 *
1116 * RETURN:
1117 *       sdram dunit control high reg value.
1118 *
1119 *******************************************************************************/
1120 static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32  busClk)
1121 {
1122         MV_U32 dunitCtrlHigh;
1123         dunitCtrlHigh = MV_REG_READ(SDRAM_DUNIT_CTRL_HI_REG);
1124         if(busClk > MV_BOARD_SYSCLK_300MHZ) 
1125                 dunitCtrlHigh |= SDRAM__P2D_EN;
1126         else
1127                 dunitCtrlHigh &= ~SDRAM__P2D_EN;
1128
1129         if(busClk > MV_BOARD_SYSCLK_267MHZ) 
1130             dunitCtrlHigh |= (SDRAM__WR_MESH_DELAY_EN | SDRAM__PUP_ZERO_SKEW_EN | SDRAM__ADD_HALF_FCC_EN);
1131
1132         /* If ECC support we turn on D2P sample */
1133         dunitCtrlHigh &= ~SDRAM__D2P_EN;    /* Clear D2P bit */
1134         if (( pBankInfo->errorCheckType ) && (busClk > MV_BOARD_SYSCLK_267MHZ))
1135                 dunitCtrlHigh |= SDRAM__D2P_EN;
1136
1137         return dunitCtrlHigh;
1138 }
1139
1140 /*******************************************************************************
1141 * sdramAddrCtrlRegCalc - Calculate sdram address control register
1142 *
1143 * DESCRIPTION: Calculate sdram address control register optimized value based
1144 *                       on the bank info parameters and the minCas.
1145 *
1146 * INPUT:
1147 *       pBankInfo - sdram bank parameters
1148 *
1149 * OUTPUT:
1150 *       None
1151 *
1152 * RETURN:
1153 *       sdram address control reg value.
1154 *
1155 *******************************************************************************/
1156 static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1)
1157 {
1158         MV_U32 addrCtrl = 0;
1159         
1160         if (pBankInfoDIMM1->size)
1161         {
1162                 switch (pBankInfoDIMM1->sdramWidth)
1163                 {
1164                         case 4:  /* memory is x4 */
1165                                 mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
1166                                 return -1;
1167                                 break;
1168                         case 8:  /* memory is x8 */
1169                                 addrCtrl |= SDRAM_ADDRSEL_X8(2) | SDRAM_ADDRSEL_X8(3);
1170                                 DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x8\n"));
1171                                 break;
1172                         case 16:
1173                                 addrCtrl |= SDRAM_ADDRSEL_X16(2) | SDRAM_ADDRSEL_X16(3);
1174                                 DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x16\n"));
1175                                 break;
1176                         default: /* memory width unsupported */
1177                                 mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
1178                                 return -1;
1179                 }
1180         }
1181
1182         switch (pBankInfo->sdramWidth)
1183         {
1184                 case 4:  /* memory is x4 */
1185                         mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
1186                         return -1;
1187                         break;
1188                 case 8:  /* memory is x8 */
1189                         addrCtrl |= SDRAM_ADDRSEL_X8(0) | SDRAM_ADDRSEL_X8(1);
1190                         DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x8\n"));
1191                         break;
1192                 case 16:
1193                         addrCtrl |= SDRAM_ADDRSEL_X16(0) | SDRAM_ADDRSEL_X16(1);
1194                         DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x16\n"));
1195                         break;
1196                 default: /* memory width unsupported */
1197                         mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
1198                         return -1;
1199         }
1200
1201         /* Note that density is in MB units */
1202         switch (pBankInfo->deviceDensity) 
1203         {
1204                 case 256:                 /* 256 Mbit */
1205                         DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
1206                         addrCtrl |= SDRAM_DSIZE_256Mb(0) | SDRAM_DSIZE_256Mb(1);
1207                         break;
1208                 case 512:                /* 512 Mbit */
1209                         DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
1210                         addrCtrl |= SDRAM_DSIZE_512Mb(0) | SDRAM_DSIZE_512Mb(1);
1211                         break;
1212                 case 1024:                /* 1 Gbit */
1213                         DB(mvOsPrintf("DRAM Device Density 1Gbit\n"));
1214                         addrCtrl |= SDRAM_DSIZE_1Gb(0) | SDRAM_DSIZE_1Gb(1);
1215                         break;
1216                 case 2048:                /* 2 Gbit */
1217                         DB(mvOsPrintf("DRAM Device Density 2Gbit\n"));
1218                         addrCtrl |= SDRAM_DSIZE_2Gb(0) | SDRAM_DSIZE_2Gb(1);
1219                         break;
1220                 default:
1221                         mvOsOutput("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
1222                        pBankInfo->deviceDensity);
1223                         return -1;
1224         }
1225
1226         if (pBankInfoDIMM1->size)
1227         {
1228                 switch (pBankInfoDIMM1->deviceDensity) 
1229                 {
1230                         case 256:                 /* 256 Mbit */
1231                                 DB(mvOsPrintf("DIMM2: DRAM Device Density 256Mbit\n"));
1232                                 addrCtrl |= SDRAM_DSIZE_256Mb(2) | SDRAM_DSIZE_256Mb(3);
1233                                 break;
1234                         case 512:                /* 512 Mbit */
1235                                 DB(mvOsPrintf("DIMM2: DRAM Device Density 512Mbit\n"));
1236                                 addrCtrl |= SDRAM_DSIZE_512Mb(2) | SDRAM_DSIZE_512Mb(3);
1237                                 break;
1238                         case 1024:                /* 1 Gbit */
1239                                 DB(mvOsPrintf("DIMM2: DRAM Device Density 1Gbit\n"));
1240                                 addrCtrl |= SDRAM_DSIZE_1Gb(2) | SDRAM_DSIZE_1Gb(3);
1241                                 break;
1242                         case 2048:                /* 2 Gbit */
1243                                 DB(mvOsPrintf("DIMM2: DRAM Device Density 2Gbit\n"));
1244                                 addrCtrl |= SDRAM_DSIZE_2Gb(2) | SDRAM_DSIZE_2Gb(3);
1245                                 break;
1246                         default:
1247                                 mvOsOutput("DIMM2: Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
1248                                                    pBankInfoDIMM1->deviceDensity);
1249                                 return -1;
1250                 }
1251         }
1252         /* SDRAM address control */
1253         DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
1254
1255         return addrCtrl;
1256 }
1257
1258 /*******************************************************************************
1259 * sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
1260 *
1261 * DESCRIPTION: 
1262 *       This function calculates sdram timing control low register 
1263 *       optimized value based on the bank info parameters and the minCas.
1264 *
1265 * INPUT:
1266 *           pBankInfo - sdram bank parameters
1267 *       minCas    - minimum CAS supported. 
1268 *       busClk    - Bus clock
1269 *
1270 * OUTPUT:
1271 *       None
1272 *
1273 * RETURN:
1274 *       sdram timing control low reg value.
1275 *
1276 *******************************************************************************/
1277 static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk)
1278 {
1279     MV_U32 tRp  = 0;
1280     MV_U32 tRrd = 0;
1281     MV_U32 tRcd = 0;
1282     MV_U32 tRas = 0;
1283     MV_U32 tWr  = 0;
1284     MV_U32 tWtr = 0;
1285     MV_U32 tRtp = 0;
1286     MV_U32 timeCtrlLow = 0;
1287         
1288     MV_U32 bankNum;
1289     
1290     busClk = busClk / 1000000;    /* In MHz */
1291
1292     /* Scan all DRAM banks to find maximum timing values */
1293     for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
1294     {
1295         tRp  = MV_MAX(tRp,  pBankInfo[bankNum].minRowPrechargeTime);
1296         tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
1297         tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
1298         tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
1299     }
1300
1301     /* Extract timing (in ns) from SPD value. We ignore the tenth ns part.  */
1302     /* by shifting the data two bits right.                                 */
1303     tRp  = tRp  >> 2;    /* For example 0x50 -> 20ns                        */
1304     tRrd = tRrd >> 2;
1305     tRcd = tRcd >> 2;
1306         
1307     /* Extract clock cycles from time parameter. We need to round up        */
1308     tRp  = ((busClk * tRp)  / 1000) + (((busClk * tRp)  % 1000) ? 1 : 0);
1309     DB(mvOsPrintf("Dram  Timing Low: tRp = %d ", tRp));
1310     tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
1311         /* JEDEC min reqeirments tRrd = 2 */
1312         if (tRrd < 2)
1313                 tRrd = 2;
1314     DB(mvOsPrintf("tRrd = %d ", tRrd));
1315     tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
1316     DB(mvOsPrintf("tRcd = %d ", tRcd));
1317     tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
1318     DB(mvOsPrintf("tRas = %d ", tRas));
1319
1320     /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2   */
1321         /* Scan all DRAM banks to find maximum timing values */
1322         for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
1323         {
1324             tWr  = MV_MAX(tWr,  pBankInfo[bankNum].minWriteRecoveryTime);
1325             tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
1326             tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
1327         }
1328         
1329         /* Extract timing (in ns) from SPD value. We ignore the tenth ns    */
1330         /* part by shifting the data two bits right.                        */
1331         tWr  = tWr  >> 2;    /* For example 0x50 -> 20ns                    */
1332         tWtr = tWtr >> 2;
1333         tRtp = tRtp >> 2;
1334         /* Extract clock cycles from time parameter. We need to round up    */
1335         tWr  = ((busClk * tWr)  / 1000) + (((busClk * tWr)  % 1000) ? 1 : 0);
1336         DB(mvOsPrintf("tWr = %d ", tWr));
1337         tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
1338         /* JEDEC min reqeirments tWtr = 2 */
1339         if (tWtr < 2)
1340                 tWtr = 2;
1341         DB(mvOsPrintf("tWtr = %d ", tWtr));
1342         tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
1343         /* JEDEC min reqeirments tRtp = 2 */
1344         if (tRtp < 2)
1345         tRtp = 2;
1346         DB(mvOsPrintf("tRtp = %d ", tRtp));
1347
1348         /* Note: value of 0 in register means one cycle, 1 means two and so on  */
1349         timeCtrlLow = (((tRp  - 1) << SDRAM_TRP_OFFS) |
1350                     ((tRrd - 1) << SDRAM_TRRD_OFFS) |
1351                     ((tRcd - 1) << SDRAM_TRCD_OFFS) |
1352                     (((tRas - 1) << SDRAM_TRAS_OFFS) & SDRAM_TRAS_MASK)|
1353                     ((tWr  - 1) << SDRAM_TWR_OFFS)  |
1354                     ((tWtr - 1) << SDRAM_TWTR_OFFS)     |
1355                     ((tRtp - 1) << SDRAM_TRTP_OFFS));
1356         
1357         /* Check extended tRas bit */
1358         if ((tRas - 1) & BIT4)
1359             timeCtrlLow |= (1 << SDRAM_EXT_TRAS_OFFS);
1360
1361         return timeCtrlLow;
1362 }
1363
1364 /*******************************************************************************
1365 * sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
1366 *
1367 * DESCRIPTION: 
1368 *       This function calculates sdram timing control high register 
1369 *       optimized value based on the bank info parameters and the bus clock.
1370 *
1371 * INPUT:
1372 *           pBankInfo - sdram bank parameters
1373 *       busClk    - Bus clock
1374 *
1375 * OUTPUT:
1376 *       None
1377 *
1378 * RETURN:
1379 *       sdram timing control high reg value.
1380 *
1381 *******************************************************************************/
1382 static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
1383 {
1384         MV_U32 tRfc;
1385         MV_U32 timingHigh;
1386         MV_U32 timeNs = 0;
1387         MV_U32 bankNum;
1388         
1389         busClk = busClk / 1000000;    /* In MHz */
1390
1391         /* Set DDR timing high register static configuration bits */
1392         timingHigh = MV_REG_READ(SDRAM_TIMING_CTRL_HIGH_REG);
1393         
1394         /* Set DDR timing high register default value */
1395         timingHigh |= SDRAM_TIMING_CTRL_HIGH_REG_DV;  
1396         
1397         /* Clear tRfc field */
1398         timingHigh &= ~SDRAM_TRFC_MASK;
1399
1400         /* Scan all DRAM banks to find maximum timing values */
1401         for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
1402         {
1403                 timeNs = MV_MAX(timeNs,  pBankInfo[bankNum].minRefreshToActiveCmd);
1404                 DB(mvOsPrintf("Dram:  Timing High: minRefreshToActiveCmd = %d\n", 
1405                                 pBankInfo[bankNum].minRefreshToActiveCmd));
1406         }
1407         if(busClk >= 333 && mvCtrlModelGet() == MV_78XX0_A1_REV)
1408     {
1409         timingHigh |= 0x1 << SDRAM_TR2W_W2R_OFFS;
1410     }
1411
1412         tRfc = ((busClk * timeNs)  / 1000) + (((busClk * timeNs)  % 1000) ? 1 : 0);
1413         /* Note: value of 0 in register means one cycle, 1 means two and so on  */
1414         DB(mvOsPrintf("Dram:  Timing High: tRfc = %d\n", tRfc));
1415         timingHigh |= (((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS);
1416         DB(mvOsPrintf("Dram:  Timing High: tRfc = %d\n", tRfc));
1417         
1418         /* SDRAM timing high */
1419         DB(mvOsPrintf("Dram: setting timing high with: %x \n", timingHigh));
1420
1421         return timingHigh;
1422 }
1423 /*******************************************************************************
1424 * sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
1425 *
1426 * DESCRIPTION: 
1427 *       This function config DDR2 On Die Termination (ODT) registers.
1428 *       
1429 * INPUT:
1430 *               pBankInfo - bank info parameters.
1431 *
1432 * OUTPUT:
1433 *       None
1434 *
1435 * RETURN:
1436 *       None
1437 *******************************************************************************/
1438 static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
1439 {
1440         MV_U32 populateBanks = 0;
1441         MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
1442         int bankNum;
1443         
1444         /* Represent the populate banks in binary form */
1445         for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
1446         {
1447                 if (0 != pBankInfo[bankNum].size)
1448                 {
1449                                 populateBanks |= (1 << bankNum);
1450                         }
1451                 }
1452         
1453         switch(populateBanks)
1454         {
1455                 case(BANK_PRESENT_CS0):
1456                 case(BANK_PRESENT_CS0_CS1):
1457                         odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS1_DV;
1458                         odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS1_DV;
1459                         dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV;
1460                         break;
1461                 case(BANK_PRESENT_CS0_CS2):
1462                 case(BANK_PRESENT_CS0_CS1_CS2):
1463                 case(BANK_PRESENT_CS0_CS2_CS3):
1464                 case(BANK_PRESENT_CS0_CS2_CS3_CS4):
1465                         odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV;
1466                         odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV;
1467                         dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV;
1468                         break;
1469                 default:
1470                         DB(mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n"));
1471                         return;
1472         }
1473         /* DDR2 SDRAM ODT ctrl low  */
1474         DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl low with: %x \n", odtCtrlLow));
1475         MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
1476
1477         /* DDR2 SDRAM ODT ctrl high  */
1478         DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl high with: %x \n", odtCtrlHigh));
1479         MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
1480
1481         /* DDR2 DUNIT ODT ctrl  */
1482         if ( ((mvCtrlModelGet() == MV_78XX0_DEV_ID) && (mvCtrlRevGet() == MV_78XX0_Y0_REV)) ||
1483                 (mvCtrlModelGet() == MV_76100_DEV_ID) ||
1484                 (mvCtrlModelGet() == MV_78100_DEV_ID) ||
1485                 (mvCtrlModelGet() == MV_78200_DEV_ID) )
1486                 dunitOdtCtrl &= ~(BIT9|BIT8); /* Clear ODT always on */
1487
1488         DB(mvOsPrintf("DUNIT: DDR2 setting ODT ctrl with: %x \n", dunitOdtCtrl));
1489         MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
1490         return;
1491 }
1492 /*******************************************************************************
1493 * sdramDdr2TimeLoRegCalc - Set DDR2 DRAM Timing Low registers.
1494 *
1495 * DESCRIPTION: 
1496 *       This function config DDR2 DRAM Timing low registers.
1497 *       
1498 * INPUT:
1499 *       minCas    - minimum CAS supported. 
1500 *
1501 * OUTPUT:
1502 *       None
1503 *
1504 * RETURN:
1505 *       DDR2 sdram timing low reg value.
1506 *******************************************************************************/
1507 static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas)
1508 {
1509         MV_U8 cl = -1;
1510         MV_U32 ddr2TimeLoReg;
1511
1512         /* read and clear the feilds we are going to set */
1513         ddr2TimeLoReg = MV_REG_READ(SDRAM_DDR2_TIMING_LO_REG);
1514         ddr2TimeLoReg &= ~(SD2TLR_TODT_ON_RD_MASK       | 
1515                            SD2TLR_TODT_OFF_RD_MASK      | 
1516                            SD2TLR_TODT_ON_CTRL_RD_MASK  |
1517                            SD2TLR_TODT_OFF_CTRL_RD_MASK);
1518
1519         if( minCas == DDR2_CL_3 )
1520         {
1521                 cl = 3;
1522         }
1523         else if( minCas == DDR2_CL_4 )
1524         {
1525                 cl = 4;
1526         }
1527         else if( minCas == DDR2_CL_5 )
1528         {
1529                 cl = 5;
1530         }
1531         else if( minCas == DDR2_CL_6 )
1532         {
1533                 cl = 6;
1534         }
1535         else
1536         {
1537                 DB(mvOsPrintf("sdramDdr2TimeLoRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
1538                                 minCas));
1539                 cl = 4;
1540         }
1541
1542         ddr2TimeLoReg |= ((cl-3) << SD2TLR_TODT_ON_RD_OFFS);
1543         ddr2TimeLoReg |= ( cl << SD2TLR_TODT_OFF_RD_OFFS);
1544         ddr2TimeLoReg |= ( cl << SD2TLR_TODT_ON_CTRL_RD_OFFS);
1545         ddr2TimeLoReg |= ((cl+3) << SD2TLR_TODT_OFF_CTRL_RD_OFFS);
1546
1547         /* DDR2 SDRAM timing low */
1548         DB(mvOsPrintf("Dram: DDR2 setting timing low with: %x \n", ddr2TimeLoReg));
1549
1550         return ddr2TimeLoReg;
1551 }
1552
1553 /*******************************************************************************
1554 * sdramDdr2TimeHiRegCalc - Set DDR2 DRAM Timing High registers.
1555 *
1556 * DESCRIPTION: 
1557 *       This function config DDR2 DRAM Timing high registers.
1558 *       
1559 * INPUT:
1560 *       minCas    - minimum CAS supported. 
1561 *
1562 * OUTPUT:
1563 *       None
1564 *
1565 * RETURN:
1566 *       DDR2 sdram timing high reg value.
1567 *******************************************************************************/
1568 static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas)
1569 {
1570         MV_U8 cl = -1;
1571         MV_U32 ddr2TimeHiReg;
1572
1573         /* read and clear the feilds we are going to set */
1574         ddr2TimeHiReg = MV_REG_READ(SDRAM_DDR2_TIMING_HI_REG);
1575         ddr2TimeHiReg &= ~(SD2THR_TODT_ON_WR_MASK       |
1576                            SD2THR_TODT_OFF_WR_MASK      |
1577                            SD2THR_TODT_ON_CTRL_WR_MASK  |
1578                            SD2THR_TODT_OFF_CTRL_WR_MASK);
1579
1580         if( minCas == DDR2_CL_3 )
1581         {
1582                 cl = 3;
1583         }
1584         else if( minCas == DDR2_CL_4 )
1585         {
1586                 cl = 4;
1587         }
1588         else if( minCas == DDR2_CL_5 )
1589         {
1590                 cl = 5;
1591         }
1592         else if( minCas == DDR2_CL_6 )
1593         {
1594                 cl = 6;
1595         }
1596         else
1597         {
1598                 mvOsOutput("sdramDdr2TimeHiRegCalc: CAS latency %d unsupported. using CAS latency 4\n", 
1599                                 minCas);
1600                 cl = 4;
1601         }
1602
1603         ddr2TimeHiReg |= ((cl-3) << SD2THR_TODT_ON_WR_OFFS);
1604         ddr2TimeHiReg |= ( cl << SD2THR_TODT_OFF_WR_OFFS);
1605         ddr2TimeHiReg |= ( cl << SD2THR_TODT_ON_CTRL_WR_OFFS);
1606         ddr2TimeHiReg |= ((cl+3) << SD2THR_TODT_OFF_CTRL_WR_OFFS);
1607
1608         /* DDR2 SDRAM timin high  */
1609         DB(mvOsPrintf("Dram: DDR2 setting timing high with: %x \n", ddr2TimeHiReg));
1610
1611         return ddr2TimeHiReg;
1612 }
1613 #endif
1614
1615 /*******************************************************************************
1616 * mvDramIfCalGet - Get CAS Latency
1617 *
1618 * DESCRIPTION: 
1619 *       This function get the CAS Latency.
1620 *
1621 * INPUT:
1622 *       None
1623 *
1624 * OUTPUT:
1625 *       None
1626 *
1627 * RETURN:
1628 *       CAS latency times 10 (to avoid using floating point).
1629 *
1630 *******************************************************************************/
1631 MV_U32 mvDramIfCalGet(void)
1632 {
1633         MV_U32 sdramCasLat, casLatMask;
1634         
1635     casLatMask = (MV_REG_READ(SDRAM_MODE_REG) & SDRAM_CL_MASK);
1636
1637     switch (casLatMask)
1638     {
1639         case SDRAM_DDR2_CL_3: 
1640             sdramCasLat = 30;
1641             break;
1642         case SDRAM_DDR2_CL_4: 
1643             sdramCasLat = 40;
1644             break;
1645         case SDRAM_DDR2_CL_5: 
1646             sdramCasLat = 50;
1647             break;
1648         case SDRAM_DDR2_CL_6: 
1649             sdramCasLat = 60;
1650             break;
1651         default:
1652             mvOsOutput("mvDramIfCalGet: Err, unknown DDR2 CAL\n");
1653             return -1;
1654     }                                  
1655     
1656     return sdramCasLat;
1657 }
1658
1659
1660 /*******************************************************************************
1661 * mvDramIfSelfRefreshSet - Put the dram in self refresh mode - 
1662 *
1663 * DESCRIPTION: 
1664 *               add support in power management.
1665 *                          
1666 *
1667 * INPUT:
1668 *       None
1669 *
1670 * OUTPUT:
1671 *       None
1672 *
1673 * RETURN:
1674 *       None
1675 *
1676 *******************************************************************************/
1677
1678 MV_VOID mvDramIfSelfRefreshSet()
1679 {
1680     MV_U32 operReg;
1681
1682       operReg =  MV_REG_READ(SDRAM_OPERATION_REG);
1683       MV_REG_WRITE(SDRAM_OPERATION_REG ,operReg |SDRAM_CMD_SLF_RFRSH);
1684       /* Read until register is reset to 0 */
1685       while(MV_REG_READ(SDRAM_OPERATION_REG));
1686 }
1687 /*******************************************************************************
1688 * mvDramIfDimGetSPDversion - return DIMM SPD version.
1689 *
1690 * DESCRIPTION:
1691 *               This function prints the DRAM controller information.
1692 *
1693 * INPUT:
1694 *               None.
1695 *
1696 * OUTPUT:
1697 *               None.
1698 *
1699 * RETURN:
1700 *               None.
1701 *
1702 *******************************************************************************/
1703 static void mvDramIfDimGetSPDversion(MV_U32 *pMajor, MV_U32 *pMinor, MV_U32 bankNum)
1704 {
1705         MV_DIMM_INFO dimmInfo;
1706         if (bankNum >= MV_DRAM_MAX_CS )
1707         {
1708                 DB(mvOsPrintf("Dram: mvDramIfDimGetSPDversion bad params \n")); 
1709                 return ;
1710         }
1711         memset(&dimmInfo,0,sizeof(dimmInfo));
1712         if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
1713         {
1714                 DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
1715                 return ;
1716         }
1717         *pMajor = dimmInfo.spdRawData[DIMM_SPD_VERSION]/10;
1718         *pMinor = dimmInfo.spdRawData[DIMM_SPD_VERSION]%10;
1719 }
1720 /*******************************************************************************
1721 * mvDramIfShow - Show DRAM controller information.
1722 *
1723 * DESCRIPTION:
1724 *               This function prints the DRAM controller information.
1725 *
1726 * INPUT:
1727 *               None.
1728 *
1729 * OUTPUT:
1730 *               None.
1731 *
1732 * RETURN:
1733 *               None.
1734 *
1735 *******************************************************************************/
1736 void mvDramIfShow(void)
1737 {
1738     int i, sdramCasLat, sdramCsSize;
1739         MV_U32 Major=0, Minor=0;
1740     
1741     mvOsOutput("DRAM Controller info:\n");
1742     
1743     mvOsOutput("Total DRAM ");
1744     mvSizePrint(mvDramIfSizeGet());
1745     mvOsOutput("\n");
1746
1747         for(i = 0; i < MV_DRAM_MAX_CS; i++)
1748         { 
1749         sdramCsSize = mvDramIfBankSizeGet(i);
1750         if (sdramCsSize)
1751         {
1752                         if (0 == (i & 1))
1753                         {
1754                                 mvDramIfDimGetSPDversion(&Major, &Minor,i);
1755                                 mvOsOutput("DIMM %d version %d.%d\n", i/2, Major, Minor);
1756                         }
1757             mvOsOutput("\tDRAM CS[%d] ", i);
1758             mvSizePrint(sdramCsSize);
1759             mvOsOutput("\n");
1760         }
1761     }
1762     sdramCasLat = mvDramIfCalGet();
1763
1764     if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_ECC_EN)
1765     {
1766         mvOsOutput("ECC enabled, ");
1767     }
1768     else
1769     {
1770         mvOsOutput("ECC Disabled, ");
1771     }
1772     
1773     if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_REGISTERED)
1774     {
1775         mvOsOutput("Registered DIMM\n");
1776     }
1777     else
1778     {
1779         mvOsOutput("Non registered DIMM\n");
1780     }
1781
1782     mvOsOutput("Configured CAS Latency %d.%d\n", sdramCasLat/10, sdramCasLat%10);
1783 }
1784 /*******************************************************************************
1785 * mvDramIfGetFirstCS - find the  DRAM bank on the lower address
1786
1787 *
1788 * DESCRIPTION:
1789 *       This function return the fisrt CS on address 0
1790 *
1791 * INPUT:
1792 *               None.
1793 *
1794 * OUTPUT:
1795 *               None.
1796 *
1797 * RETURN:
1798 *       SDRAM_CS0 or SDRAM_CS2
1799 *
1800 *******************************************************************************/
1801 MV_U32 mvDramIfGetFirstCS(void)
1802 {
1803         MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
1804
1805         if (DRAM_CS_Order[0] == N_A)
1806         {
1807                 mvDramBankInfoGet(SDRAM_CS0, &bankInfo[SDRAM_CS0]);
1808 #ifdef MV_INCLUDE_SDRAM_CS2
1809                 mvDramBankInfoGet(SDRAM_CS2, &bankInfo[SDRAM_CS2]);
1810 #endif 
1811                 
1812 #ifdef MV_INCLUDE_SDRAM_CS2
1813                 if (bankInfo[SDRAM_CS0].size <  bankInfo[SDRAM_CS2].size)
1814                 {
1815                         DRAM_CS_Order[0] = SDRAM_CS2;
1816                         DRAM_CS_Order[1] = SDRAM_CS3;
1817                         DRAM_CS_Order[2] = SDRAM_CS0;
1818                         DRAM_CS_Order[3] = SDRAM_CS1;
1819
1820                         return SDRAM_CS2;
1821                 }
1822 #endif
1823                 DRAM_CS_Order[0] = SDRAM_CS0;
1824                 DRAM_CS_Order[1] = SDRAM_CS1;
1825 #ifdef MV_INCLUDE_SDRAM_CS2
1826                 DRAM_CS_Order[2] = SDRAM_CS2;
1827                 DRAM_CS_Order[3] = SDRAM_CS3;
1828 #endif  
1829                 return SDRAM_CS0;
1830         }
1831         return DRAM_CS_Order[0];
1832 }
1833 /*******************************************************************************
1834 * mvDramIfGetCSorder - 
1835
1836 *
1837 * DESCRIPTION:
1838 *       This function return the fisrt CS on address 0
1839 *
1840 * INPUT:
1841 *               CS number.
1842 *
1843 * OUTPUT:
1844 *               CS order.
1845 *
1846 * RETURN:
1847 *       SDRAM_CS0 or SDRAM_CS2
1848
1849 * NOTE: mvDramIfGetFirstCS must be caled before this subroutine
1850 *******************************************************************************/
1851 MV_U32 mvDramIfGetCSorder(MV_U32 csOrder )
1852 {
1853         return DRAM_CS_Order[csOrder];
1854 }
1855