rename target/linux/generic-2.6 to generic
[15.05/openwrt.git] / target / linux / generic / files / crypto / ocf / kirkwood / mvHal / mv_hal / ddr1_2 / 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 "ddr1_2/mvDramIf.h"
68 #include "ctrlEnv/sys/mvCpuIf.h"
69
70
71
72 #ifdef MV_DEBUG
73 #define DB(x) x
74 #else
75 #define DB(x)
76 #endif
77
78 /* DRAM bank presence encoding */
79 #define BANK_PRESENT_CS0                                0x1
80 #define BANK_PRESENT_CS0_CS1                    0x3
81 #define BANK_PRESENT_CS0_CS2                    0x5
82 #define BANK_PRESENT_CS0_CS1_CS2                0x7
83 #define BANK_PRESENT_CS0_CS2_CS3                0xd
84 #define BANK_PRESENT_CS0_CS2_CS3_CS4    0xf
85
86 /* locals   */
87 static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
88 #if defined(MV_INC_BOARD_DDIM)
89 static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
90 static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas);
91 static MV_U32 sdramModeRegCalc(MV_U32 minCas);
92 static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
93 static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
94 static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
95 static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk, 
96                                                  MV_U32 forcedCl);
97 static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, 
98                                                                           MV_U32 minCas, MV_U32 busClk);
99 static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, 
100                                                                            MV_U32 busClk);
101
102 /*******************************************************************************
103 * mvDramIfDetect - Prepare DRAM interface configuration values.
104 *
105 * DESCRIPTION:
106 *       This function implements the full DRAM detection and timing 
107 *       configuration for best system performance.
108 *       Since this routine runs from a ROM device (Boot Flash), its stack 
109 *       resides on RAM, that might be the system DRAM. Changing DRAM 
110 *       configuration values while keeping vital data in DRAM is risky. That
111 *       is why the function does not preform the configuration setting but 
112 *       prepare those in predefined 32bit registers (in this case IDMA 
113 *       registers are used) for other routine to perform the settings.
114 *       The function will call for board DRAM SPD information for each DRAM 
115 *       chip select. The function will then analyze those SPD parameters of 
116 *       all DRAM banks in order to decide on DRAM configuration compatible 
117 *       for all DRAM banks.
118 *       The function will set the CPU DRAM address decode registers.
119 *       Note: This routine prepares values that will overide configuration of
120 *       mvDramBasicAsmInit().
121 *       
122 * INPUT:
123 *       forcedCl - Forced CAL Latency. If equal to zero, do not force.
124 *
125 * OUTPUT:
126 *       None.
127 *
128 * RETURN:
129 *       None.
130 *
131 *******************************************************************************/
132 MV_STATUS mvDramIfDetect(MV_U32 forcedCl)
133 {
134         MV_U32 retVal = MV_OK;  /* return value */
135         MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
136         MV_U32  busClk, size, base = 0, i, temp, deviceW, dimmW;
137         MV_U8   minCas;
138         MV_DRAM_DEC_WIN dramDecWin;
139
140         dramDecWin.addrWin.baseHigh = 0;
141
142         busClk = mvBoardSysClkGet();
143         
144         if (0 == busClk)
145         {
146                 mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
147                 return MV_ERROR;
148         }
149         
150         /* Close DRAM banks except bank 0 (in case code is excecuting from it...) */
151 #if defined(MV_INCLUDE_SDRAM_CS1)
152         for(i= SDRAM_CS1; i < MV_DRAM_MAX_CS; i++)
153                 mvCpuIfTargetWinEnable(i, MV_FALSE);
154 #endif
155
156         /* we will use bank 0 as the representative of the all the DRAM banks,  */
157         /* since bank 0 must exist.                                             */      
158         for(i = 0; i < MV_DRAM_MAX_CS; i++)
159         { 
160                 /* if Bank exist */
161                 if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
162                 {
163                         /* check it isn't SDRAM */
164                         if(bankInfo[i].memoryType == MEM_TYPE_SDRAM)
165                         {
166                                 mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n");
167                                 return MV_ERROR;
168                         }
169                         /* All banks must support registry in order to activate it */
170                         if(bankInfo[i].registeredAddrAndControlInputs != 
171                            bankInfo[0].registeredAddrAndControlInputs)
172                         {
173                                 mvOsPrintf("Dram: ERR. different Registered settings !!!\n");
174                                 return MV_ERROR;
175                         }
176
177                         /* Init the CPU window decode */
178                         /* Note that the size in Bank info is in MB units                       */
179                         /* Note that the Dimm width might be different then the device DRAM width */
180                         temp = MV_REG_READ(SDRAM_CONFIG_REG);
181                         
182                         deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32;
183                         dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
184                         size = ((bankInfo[i].size << 20) / (dimmW/deviceW)); 
185
186                         /* We can not change DRAM window settings while excecuting      */
187                         /* code from it. That is why we skip the DRAM CS[0], saving     */
188                         /* it to the ROM configuration routine  */
189                         if(i == SDRAM_CS0)
190                         {
191                                 MV_U32 sizeToReg;
192                                 
193                                 /* Translate the given window size to register format */
194                                 sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
195
196                                 /* Size parameter validity check. */
197                                 if (-1 == sizeToReg)
198                                 {
199                                         mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
200                                                            ,i);
201                                         return MV_BAD_PARAM;
202                                 }
203                 
204                                 /* Size is located at upper 16 bits */
205                                 sizeToReg <<= SCSR_SIZE_OFFS;
206
207                                 /* enable it */
208                                 sizeToReg |= SCSR_WIN_EN;
209
210                                 MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
211                         }
212                         else
213                         {
214                                 dramDecWin.addrWin.baseLow = base;
215                                 dramDecWin.addrWin.size = size;
216                                 dramDecWin.enable = MV_TRUE;
217                                 
218                                 if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin))
219                                 {
220                                         mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", 
221                                                            SDRAM_CS0 + i);
222                                         return MV_ERROR;
223                                 }
224                         }
225                         
226                         base += size;
227
228                         /* update the suportedCasLatencies mask */
229                         bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
230
231                 }
232                 else
233                 {
234                         if( i == 0 ) /* bank 0 doesn't exist */
235                         {
236                                 mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n");
237                                 return MV_ERROR;
238                         }
239                         else
240                         {
241                                 DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
242                                 bankInfo[i].size = 0;     /* Mark this bank as non exist */
243                         }
244                 }
245         }
246
247         /* calculate minimum CAS */
248         minCas = minCasCalc(&bankInfo[0], busClk, forcedCl);
249         if (0 == minCas) 
250         {
251                 mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
252                                    (busClk / 1000000));
253
254                 if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
255                 {
256                         minCas = DDR2_CL_4; /* Continue with this CAS */
257                         mvOsPrintf("Set default CAS latency 4\n");
258                 }
259                 else
260                 {
261                         minCas = DDR1_CL_3; /* Continue with this CAS */
262                         mvOsPrintf("Set default CAS latency 3\n");
263                 }
264         }
265
266         /* calc SDRAM_CONFIG_REG  and save it to temp register */
267         temp = sdramConfigRegCalc(&bankInfo[0], busClk);
268         if(-1 == temp)
269         {
270                 mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n");
271                 return MV_ERROR;
272         }
273         MV_REG_WRITE(DRAM_BUF_REG1, temp);
274
275         /* calc SDRAM_MODE_REG  and save it to temp register */ 
276         temp = sdramModeRegCalc(minCas);
277         if(-1 == temp)
278         {
279                 mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
280                 return MV_ERROR;
281         }
282         MV_REG_WRITE(DRAM_BUF_REG2, temp);
283
284         /* calc SDRAM_EXTENDED_MODE_REG  and save it to temp register */ 
285         temp = sdramExtModeRegCalc(&bankInfo[0]);
286         if(-1 == temp)
287         {
288                 mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
289                 return MV_ERROR;
290         }
291         MV_REG_WRITE(DRAM_BUF_REG10, temp);
292
293         /* calc D_UNIT_CONTROL_LOW  and save it to temp register */
294         temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas); 
295         if(-1 == temp)
296         {
297                 mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
298                 return MV_ERROR;
299         }
300         MV_REG_WRITE(DRAM_BUF_REG3, temp); 
301
302         /* calc SDRAM_ADDR_CTRL_REG  and save it to temp register */
303         temp = sdramAddrCtrlRegCalc(&bankInfo[0]);
304         if(-1 == temp)
305         {
306                 mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
307                 return MV_ERROR;
308         }
309         MV_REG_WRITE(DRAM_BUF_REG4, temp);
310
311         /* calc SDRAM_TIMING_CTRL_LOW_REG  and save it to temp register */
312         temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
313         if(-1 == temp)
314         {
315                 mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
316                 return MV_ERROR;
317         }
318         MV_REG_WRITE(DRAM_BUF_REG5, temp);
319
320         /* calc SDRAM_TIMING_CTRL_HIGH_REG  and save it to temp register */
321         temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
322         if(-1 == temp)
323         {
324                 mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
325                 return MV_ERROR;
326         }
327         MV_REG_WRITE(DRAM_BUF_REG6, temp);
328
329         /* Config DDR2 On Die Termination (ODT) registers */
330         if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
331         {
332                 sdramDDr2OdtConfig(bankInfo);
333         }
334         
335         /* Note that DDR SDRAM Address/Control and Data pad calibration     */
336         /* settings is done in mvSdramIfConfig.s                            */
337
338         return retVal;
339 }
340
341 /*******************************************************************************
342 * minCasCalc - Calculate the Minimum CAS latency which can be used.
343 *
344 * DESCRIPTION:
345 *       Calculate the minimum CAS latency that can be used, base on the DRAM
346 *       parameters and the SDRAM bus Clock freq.
347 *
348 * INPUT:
349 *       busClk    - the DRAM bus Clock.
350 *       pBankInfo - bank info parameters.
351 *
352 * OUTPUT:
353 *       None
354 *
355 * RETURN:
356 *       The minimum CAS Latency. The function returns 0 if max CAS latency
357 *               supported by banks is incompatible with system bus clock frequancy.
358 *
359 *******************************************************************************/
360 static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk, 
361                                                  MV_U32 forcedCl)
362 {
363         MV_U32 count = 1, j;
364         MV_U32 busClkPs = 1000000000 / (busClk / 1000);  /* in ps units */
365         MV_U32 startBit, stopBit;
366         
367         /*     DDR 1:
368                         *******-******-******-******-******-******-******-******* 
369                         * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * 
370                         *******-******-******-******-******-******-******-******* 
371         CAS     =       * TBD  |  4   | 3.5  |   3  | 2.5  |  2   | 1.5  |   1  * 
372                         *********************************************************/
373         
374         /*     DDR 2:
375                         *******-******-******-******-******-******-******-******* 
376                         * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * 
377                         *******-******-******-******-******-******-******-******* 
378         CAS     =       * TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  * 
379                         *********************************************************/
380         
381         
382         /* If we are asked to use the forced CAL */
383         if (forcedCl)
384         {
385                 mvOsPrintf("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), 
386                                                                                                         (forcedCl % 10));
387         
388                 if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
389                 {
390                         if (forcedCl == 30)
391                                 pBankInfo->suportedCasLatencies = 0x08;
392                         else if (forcedCl == 40)
393                                 pBankInfo->suportedCasLatencies = 0x10;
394                         else
395                         {
396                                 mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n", 
397                                                    (forcedCl / 10), (forcedCl % 10));
398                                 pBankInfo->suportedCasLatencies = 0x10;
399                         }
400                 }
401                 else
402                 {
403                         if (forcedCl == 15)
404                                 pBankInfo->suportedCasLatencies = 0x02;
405                         else if (forcedCl == 20)
406                                 pBankInfo->suportedCasLatencies = 0x04;
407                         else if (forcedCl == 25)
408                                 pBankInfo->suportedCasLatencies = 0x08;
409                         else if (forcedCl == 30)
410                                 pBankInfo->suportedCasLatencies = 0x10;
411                         else if (forcedCl == 40)
412                                 pBankInfo->suportedCasLatencies = 0x40;
413                         else
414                         {
415                                 mvOsPrintf("Forced CL %d.%d not supported. Set default CL 3\n", 
416                                                    (forcedCl / 10), (forcedCl % 10));
417                                 pBankInfo->suportedCasLatencies = 0x10;
418                         }
419                 }
420         
421                 return pBankInfo->suportedCasLatencies;        
422         }   
423         
424         /* go over the supported cas mask from Max Cas down and check if the    */
425         /* SysClk stands in its time requirments.                                                               */
426         
427         
428         DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
429                                                                 pBankInfo->suportedCasLatencies,busClkPs ));
430         for(j = 7; j > 0; j--)
431         {
432                 if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
433                 {
434                         /* Reset the bits for CL incompatible for the sysClk            */
435                         switch (count)
436                         {
437                                 case 1: 
438                                         if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs) 
439                                                 pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
440                                         count++;
441                                         break;
442                                 case 2: 
443                                         if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
444                                                 pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
445                                         count++;
446                                         break;
447                                 case 3: 
448                                         if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
449                                                 pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
450                                         count++;
451                                         break;
452                                 default: 
453                                         pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
454                                         break;
455                         }
456                 }
457         }
458         
459         DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
460                                   pBankInfo->suportedCasLatencies ));
461         
462         /* SDRAM DDR1 controller supports CL 1.5 to 3.5 */
463         /* SDRAM DDR2 controller supports CL 3 to 5     */
464         if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
465         {
466                 startBit = 3;   /* DDR2 support CL start with CL3 (bit 3) */
467                 stopBit  = 5;   /* DDR2 support CL stops with CL5 (bit 5) */
468         }
469         else
470         {
471                 startBit = 1;   /* DDR1 support CL start with CL1.5 (bit 3) */
472                 stopBit  = 4;   /* DDR1 support CL stops with CL3 (bit 4)   */
473         }
474         
475         for(j = startBit; j <= stopBit ; j++)
476         {
477                 if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
478                 {
479                         DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
480                         return (BIT0 << j);
481                 }
482         }
483         
484         return 0; 
485 }
486
487 /*******************************************************************************
488 * sdramConfigRegCalc - Calculate sdram config register
489 *
490 * DESCRIPTION: Calculate sdram config register optimized value based
491 *                       on the bank info parameters.
492 *
493 * INPUT:
494 *       pBankInfo - sdram bank parameters
495 *
496 * OUTPUT:
497 *       None
498 *
499 * RETURN:
500 *       sdram config reg value.
501 *
502 *******************************************************************************/
503 static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
504 {
505         MV_U32 sdramConfig = 0;
506         MV_U32 refreshPeriod;
507         
508         busClk /= 1000000; /* we work with busClk in MHz */
509         
510         sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
511         
512         /* figure out the memory refresh internal */
513         switch (pBankInfo->refreshInterval & 0xf)
514         {
515                 case 0x0: /* refresh period is 15.625 usec */
516                         refreshPeriod = 15625;
517                         break;
518                 case 0x1: /* refresh period is 3.9 usec         */
519                         refreshPeriod = 3900;
520                         break;
521                 case 0x2: /* refresh period is 7.8 usec         */
522                         refreshPeriod = 7800;
523                         break;
524                 case 0x3: /* refresh period is 31.3 usec        */
525                         refreshPeriod = 31300;
526                         break;
527                 case 0x4: /* refresh period is 62.5 usec        */
528                         refreshPeriod = 62500;
529                         break;
530                 case 0x5: /* refresh period is 125 usec         */
531                         refreshPeriod = 125000;
532                         break;
533                 default:  /* refresh period undefined                                   */
534                         mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
535                         return -1;
536         }
537         
538         /* Now the refreshPeriod is in register format value */
539         refreshPeriod = (busClk * refreshPeriod) / 1000;
540         
541         DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n", 
542                                   refreshPeriod));
543
544         /* make sure the refresh value is only 14 bits */
545         if(refreshPeriod > SDRAM_REFRESH_MAX)
546         {
547                 refreshPeriod = SDRAM_REFRESH_MAX;
548                 DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n", 
549                                           refreshPeriod));
550         }
551         
552         /* Clear the refresh field */
553         sdramConfig &= ~SDRAM_REFRESH_MASK;
554         
555         /* Set new value to refresh field */
556         sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
557         
558         /*  registered DRAM ? */
559         if ( pBankInfo->registeredAddrAndControlInputs )
560         {
561                 /* it's registered DRAM, so set the reg. DRAM bit */
562                 sdramConfig |= SDRAM_REGISTERED;
563                 mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");
564         }
565         
566         /* set DDR SDRAM devices configuration */
567         sdramConfig &= ~SDRAM_DCFG_MASK;    /* Clear Dcfg field */
568         
569         switch (pBankInfo->sdramWidth)
570         {
571                 case 8:  /* memory is x8 */
572                         sdramConfig |= SDRAM_DCFG_X8_DEV;
573                         DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x8\n"));
574                         break;
575                 case 16:
576                         sdramConfig |= SDRAM_DCFG_X16_DEV;
577                         DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x16\n"));
578                         break;
579                 default: /* memory width unsupported */
580                         mvOsPrintf("Dram: ERR. DRAM chip width is unknown!\n");
581                         return -1;
582         }
583
584         /* Set static default settings */
585         sdramConfig |= SDRAM_CONFIG_DV;
586         
587         DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
588                                   sdramConfig));
589         
590         return sdramConfig;  
591 }
592
593 /*******************************************************************************
594 * sdramModeRegCalc - Calculate sdram mode register
595 *
596 * DESCRIPTION: Calculate sdram mode register optimized value based
597 *                       on the bank info parameters and the minCas.
598 *
599 * INPUT:
600 *       minCas    - minimum CAS supported. 
601 *
602 * OUTPUT:
603 *       None
604 *
605 * RETURN:
606 *       sdram mode reg value.
607 *
608 *******************************************************************************/
609 static MV_U32 sdramModeRegCalc(MV_U32 minCas)
610 {
611         MV_U32 sdramMode;
612                 
613         sdramMode = MV_REG_READ(SDRAM_MODE_REG);
614         
615         /* Clear CAS Latency field */
616         sdramMode &= ~SDRAM_CL_MASK;
617         
618         mvOsPrintf("DRAM CAS Latency ");
619         
620         if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
621         {               
622                 switch (minCas)
623                 {
624                         case DDR2_CL_3: 
625                                 sdramMode |= SDRAM_DDR2_CL_3;
626                                 mvOsPrintf("3.\n");
627                                 break;
628                         case DDR2_CL_4: 
629                                 sdramMode |= SDRAM_DDR2_CL_4;
630                                 mvOsPrintf("4.\n");
631                                 break;
632                         case DDR2_CL_5: 
633                                 sdramMode |= SDRAM_DDR2_CL_5;
634                                 mvOsPrintf("5.\n");
635                                 break;
636                         default:
637                                 mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
638                                 return -1;
639                 }
640         sdramMode |= DDR2_MODE_REG_DV;
641         }
642         else    /* DDR1 */
643         {
644                 switch (minCas)
645                 {                       
646                         case DDR1_CL_1_5: 
647                                 sdramMode |= SDRAM_DDR1_CL_1_5;
648                                 mvOsPrintf("1.5\n");
649                                 break;
650                         case DDR1_CL_2: 
651                                 sdramMode |= SDRAM_DDR1_CL_2;
652                                 mvOsPrintf("2\n");
653                                 break;            
654                         case DDR1_CL_2_5: 
655                                 sdramMode |= SDRAM_DDR1_CL_2_5;
656                                 mvOsPrintf("2.5\n");
657                                 break;
658                         case DDR1_CL_3: 
659                                 sdramMode |= SDRAM_DDR1_CL_3;
660                                 mvOsPrintf("3\n");
661                                 break;
662                         case DDR1_CL_4: 
663                                 sdramMode |= SDRAM_DDR1_CL_4;
664                                 mvOsPrintf("4\n");
665                                 break;
666                         default:
667                                 mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
668                                 return -1;      
669                 }
670                 sdramMode |= DDR1_MODE_REG_DV;          
671         }
672         
673         DB(mvOsPrintf("nsdramModeRegCalc register 0x%x\n", sdramMode ));
674
675         return sdramMode;
676 }
677
678 /*******************************************************************************
679 * sdramExtModeRegCalc - Calculate sdram Extended mode register
680 *
681 * DESCRIPTION: 
682 *               Return sdram Extended mode register value based
683 *               on the bank info parameters and bank presence.
684 *
685 * INPUT:
686 *       pBankInfo - sdram bank parameters
687 *
688 * OUTPUT:
689 *       None
690 *
691 * RETURN:
692 *       sdram Extended mode reg value.
693 *
694 *******************************************************************************/
695 static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
696 {
697         MV_U32 populateBanks = 0;
698         int bankNum;
699         if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
700         {
701         /* Represent the populate banks in binary form */
702         for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
703         {
704                 if (0 != pBankInfo[bankNum].size)
705                 {
706                                 populateBanks |= (1 << bankNum);
707                         }
708                 }
709         
710                 switch(populateBanks)
711                 {
712                         case(BANK_PRESENT_CS0):
713                                 return DDR_SDRAM_EXT_MODE_CS0_DV;
714                 
715                         case(BANK_PRESENT_CS0_CS1):
716                                 return DDR_SDRAM_EXT_MODE_CS0_DV;
717                 
718                         case(BANK_PRESENT_CS0_CS2):
719                                 return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
720                 
721                         case(BANK_PRESENT_CS0_CS1_CS2):
722                                 return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
723                 
724                         case(BANK_PRESENT_CS0_CS2_CS3):
725                                 return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
726                 
727                         case(BANK_PRESENT_CS0_CS2_CS3_CS4):
728                                 return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
729                 
730                         default:
731                                 mvOsPrintf("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
732                                 return -1;
733                 } 
734         }
735         return 0;
736 }
737
738 /*******************************************************************************
739 * dunitCtrlLowRegCalc - Calculate sdram dunit control low register
740 *
741 * DESCRIPTION: Calculate sdram dunit control low register optimized value based
742 *                       on the bank info parameters and the minCas.
743 *
744 * INPUT:
745 *       pBankInfo - sdram bank parameters
746 *       minCas    - minimum CAS supported. 
747 *
748 * OUTPUT:
749 *       None
750 *
751 * RETURN:
752 *       sdram dunit control low reg value.
753 *
754 *******************************************************************************/
755 static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas)
756 {
757         MV_U32 dunitCtrlLow;
758         
759         dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
760         
761         /* Clear StBurstDel field */
762         dunitCtrlLow &= ~SDRAM_ST_BURST_DEL_MASK;
763         
764 #ifdef MV_88W8660
765         /* Clear address/control output timing field */
766         dunitCtrlLow &= ~SDRAM_CTRL_POS_RISE;
767 #endif /* MV_88W8660 */
768
769         DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
770         
771         /* For proper sample of read data set the Dunit Control register's      */
772         /* stBurstDel bits [27:24]                                              */
773                         /********-********-********-********-********-*********
774                         * CL=1.5 |  CL=2  | CL=2.5 |  CL=3  |  CL=4  |  CL=5  *
775                         *********-********-********-********-********-*********
776 Not Reg.        *  0011  |  0011  |  0100  |  0100  |  0101  |  TBD   *
777                         *********-********-********-********-********-*********
778 Registered      *  0100  |  0100  |  0101  |  0101  |  0110  |  TBD   *
779                         *********-********-********-********-********-*********/
780     
781         if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
782         {
783                 switch (minCas)
784                 {
785                         case DDR2_CL_3: 
786                                         /* registerd DDR SDRAM? */
787                                 if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)               
788                                         dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
789                                 else
790                                         dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
791                                 break;
792                         case DDR2_CL_4: 
793                                 /* registerd DDR SDRAM? */
794                                 if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)               
795                                         dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
796                                 else
797                                         dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS; 
798                                 break;
799                         default:
800                                 mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", 
801                                                    minCas);
802                                 return -1;
803                 }
804         }
805         else    /* DDR1 */
806         {
807                 switch (minCas)
808                 {
809                         case DDR1_CL_1_5: 
810                                 /* registerd DDR SDRAM? */
811                                 if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
812                                         dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
813                                 else
814                                         dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
815                                 break;
816                         case DDR1_CL_2: 
817                                 /* registerd DDR SDRAM? */
818                                 if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
819                                         dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
820                                 else
821                                         dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
822                                 break;
823                         case DDR1_CL_2_5: 
824                                 /* registerd DDR SDRAM? */
825                                 if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
826                                         dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
827                                 else
828                                         dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS; 
829                                 break;
830                         case DDR1_CL_3: 
831                                 /* registerd DDR SDRAM? */
832                                 if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
833                                         dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
834                                 else
835                                         dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS; 
836                                 break;
837                         case DDR1_CL_4: 
838                                 /* registerd DDR SDRAM? */
839                                 if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
840                                         dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
841                                 else
842                                         dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS; 
843                                 break;
844                         default:
845                                 mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", 
846                                                    minCas);
847                                 return -1;
848         }
849         
850         }
851         DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
852
853         return dunitCtrlLow;
854 }  
855                                                                     
856 /*******************************************************************************
857 * sdramAddrCtrlRegCalc - Calculate sdram address control register
858 *
859 * DESCRIPTION: Calculate sdram address control register optimized value based
860 *                       on the bank info parameters and the minCas.
861 *
862 * INPUT:
863 *       pBankInfo - sdram bank parameters
864 *
865 * OUTPUT:
866 *       None
867 *
868 * RETURN:
869 *       sdram address control reg value.
870 *
871 *******************************************************************************/
872 static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
873 {
874         MV_U32 addrCtrl = 0;
875         
876         /* Set Address Control register static configuration bits */
877         addrCtrl = MV_REG_READ(SDRAM_ADDR_CTRL_REG);
878         
879         /* Set address control default value */
880         addrCtrl |= SDRAM_ADDR_CTRL_DV;  
881         
882         /* Clear DSize field */
883         addrCtrl &= ~SDRAM_DSIZE_MASK;
884         
885         /* Note that density is in MB units */
886         switch (pBankInfo->deviceDensity) 
887         {
888                 case 128:                 /* 128 Mbit */
889                         DB(mvOsPrintf("DRAM Device Density 128Mbit\n"));
890                         addrCtrl |= SDRAM_DSIZE_128Mb;
891                         break;
892                 case 256:                 /* 256 Mbit */
893                         DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
894                         addrCtrl |= SDRAM_DSIZE_256Mb;
895                         break;
896                 case 512:                /* 512 Mbit */
897                         DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
898                         addrCtrl |= SDRAM_DSIZE_512Mb;
899                         break;
900                 default:
901                         mvOsPrintf("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
902                        pBankInfo->deviceDensity);
903                         return -1;
904         }
905      
906         /* SDRAM address control */
907         DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
908
909         return addrCtrl;
910 }
911
912 /*******************************************************************************
913 * sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
914 *
915 * DESCRIPTION: 
916 *       This function calculates sdram timing control low register 
917 *       optimized value based on the bank info parameters and the minCas.
918 *
919 * INPUT:
920 *           pBankInfo - sdram bank parameters
921 *       busClk    - Bus clock
922 *
923 * OUTPUT:
924 *       None
925 *
926 * RETURN:
927 *       sdram timinf control low reg value.
928 *
929 *******************************************************************************/
930 static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, 
931                                                 MV_U32 minCas, MV_U32 busClk)
932 {
933         MV_U32 tRp  = 0;
934         MV_U32 tRrd = 0;
935         MV_U32 tRcd = 0;
936         MV_U32 tRas = 0;
937         MV_U32 tWr  = 0;
938         MV_U32 tWtr = 0;
939         MV_U32 tRtp = 0;
940         
941         MV_U32 bankNum;
942         
943         busClk = busClk / 1000000;    /* In MHz */
944         
945         /* Scan all DRAM banks to find maximum timing values */
946         for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
947         {
948                 tRp  = MV_MAX(tRp,  pBankInfo[bankNum].minRowPrechargeTime);
949                 tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
950                 tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
951                 tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
952         }
953         
954         /* Extract timing (in ns) from SPD value. We ignore the tenth ns part.  */
955         /* by shifting the data two bits right.                                 */
956         tRp  = tRp  >> 2;    /* For example 0x50 -> 20ns                        */
957         tRrd = tRrd >> 2;
958         tRcd = tRcd >> 2;
959         
960         /* Extract clock cycles from time parameter. We need to round up        */
961         tRp  = ((busClk * tRp)  / 1000) + (((busClk * tRp)  % 1000) ? 1 : 0);
962         /* Micron work around for 133MHz */
963         if (busClk == 133)
964                 tRp += 1;
965         DB(mvOsPrintf("Dram  Timing Low: tRp = %d ", tRp));
966         tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
967         /* JEDEC min reqeirments tRrd = 2 */
968         if (tRrd < 2)
969                 tRrd = 2;
970         DB(mvOsPrintf("tRrd = %d ", tRrd));
971         tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
972         DB(mvOsPrintf("tRcd = %d ", tRcd));
973         tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
974         DB(mvOsPrintf("tRas = %d ", tRas));
975         
976         /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2   */
977         if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
978         {
979                 /* Scan all DRAM banks to find maximum timing values */
980                 for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
981                 {
982                         tWr  = MV_MAX(tWr,  pBankInfo[bankNum].minWriteRecoveryTime);
983                         tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
984                         tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
985                 }
986                 
987                 /* Extract timing (in ns) from SPD value. We ignore the tenth ns    */
988                 /* part by shifting the data two bits right.                        */
989                 tWr  = tWr  >> 2;    /* For example 0x50 -> 20ns                    */
990                 tWtr = tWtr >> 2;
991                 tRtp = tRtp >> 2;
992         
993                 /* Extract clock cycles from time parameter. We need to round up    */
994                 tWr  = ((busClk * tWr)  / 1000) + (((busClk * tWr)  % 1000) ? 1 : 0);
995                 DB(mvOsPrintf("tWr = %d ", tWr));
996                 tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
997                 /* JEDEC min reqeirments tWtr = 2 */
998                 if (tWtr < 2)
999                         tWtr = 2;
1000                 DB(mvOsPrintf("tWtr = %d ", tWtr));
1001                 tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
1002                 /* JEDEC min reqeirments tRtp = 2 */
1003                 if (tRtp < 2)
1004                         tRtp = 2;
1005                 DB(mvOsPrintf("tRtp = %d ", tRtp));
1006         }
1007         else
1008         {    
1009                 tWr  = ((busClk*SDRAM_TWR) / 1000) + (((busClk*SDRAM_TWR) % 1000)?1:0);
1010                 
1011                 if ((200 == busClk) || ((100 == busClk) && (DDR1_CL_1_5 == minCas)))
1012                 {
1013                         tWtr = 2;
1014                 }
1015                 else
1016                 {
1017                         tWtr = 1;
1018                 }
1019                 
1020                 tRtp = 2; /* Must be set to 0x1 (two cycles) when using DDR1 */
1021         }
1022         
1023         DB(mvOsPrintf("tWtr = %d\n", tWtr));
1024         
1025         /* Note: value of 0 in register means one cycle, 1 means two and so on  */
1026         return (((tRp  - 1) << SDRAM_TRP_OFFS)  |
1027                         ((tRrd - 1) << SDRAM_TRRD_OFFS) |
1028                         ((tRcd - 1) << SDRAM_TRCD_OFFS) |
1029                         ((tRas - 1) << SDRAM_TRAS_OFFS) |
1030                         ((tWr  - 1) << SDRAM_TWR_OFFS)  |
1031                         ((tWtr - 1) << SDRAM_TWTR_OFFS) |
1032                         ((tRtp - 1) << SDRAM_TRTP_OFFS));
1033 }
1034
1035 /*******************************************************************************
1036 * sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
1037 *
1038 * DESCRIPTION: 
1039 *       This function calculates sdram timing control high register 
1040 *       optimized value based on the bank info parameters and the bus clock.
1041 *
1042 * INPUT:
1043 *           pBankInfo - sdram bank parameters
1044 *       busClk    - Bus clock
1045 *
1046 * OUTPUT:
1047 *       None
1048 *
1049 * RETURN:
1050 *       sdram timinf control high reg value.
1051 *
1052 *******************************************************************************/
1053 static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, 
1054                                                                 MV_U32 busClk)
1055 {
1056         MV_U32 tRfc;
1057         MV_U32 timeNs = 0;
1058         int bankNum;
1059         MV_U32 sdramTw2wCyc = 0;
1060         
1061         busClk = busClk / 1000000;    /* In MHz */
1062         
1063         /* tRfc is different for DDR1 and DDR2. */
1064         if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
1065         {
1066                 MV_U32 bankNum;
1067         
1068                 /* Scan all DRAM banks to find maximum timing values */
1069                 for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
1070                         timeNs = MV_MAX(timeNs,  pBankInfo[bankNum].minRefreshToActiveCmd);
1071         }
1072         else
1073         {
1074                 if (pBankInfo[0].deviceDensity == _1G)
1075                 {
1076                         timeNs = SDRAM_TRFC_1G;
1077                 }
1078                 else
1079                 {
1080                         if (200 == busClk)
1081                         {
1082                                 timeNs = SDRAM_TRFC_64_512M_AT_200MHZ;
1083                         }
1084                         else
1085                         {
1086                                 timeNs = SDRAM_TRFC_64_512M;
1087                         }
1088                 }
1089         }
1090         
1091         tRfc = ((busClk * timeNs)  / 1000) + (((busClk * timeNs)  % 1000) ? 1 : 0);
1092         
1093         DB(mvOsPrintf("Dram  Timing High: tRfc = %d\n", tRfc));
1094
1095         
1096         /* Represent the populate banks in binary form */
1097         for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
1098         {
1099                 if (0 != pBankInfo[bankNum].size)
1100                         sdramTw2wCyc++;
1101         }
1102
1103         /* If we have more the 1 bank then we need the TW2W in 1 for ODT switch */      
1104         if (sdramTw2wCyc > 1)
1105                 sdramTw2wCyc = 1;
1106         else
1107                 sdramTw2wCyc = 0;
1108
1109         /* Note: value of 0 in register means one cycle, 1 means two and so on  */
1110         return ((((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS)             |
1111                         ((SDRAM_TR2R_CYC - 1)                   << SDRAM_TR2R_OFFS)             |
1112                         ((SDRAM_TR2WW2R_CYC - 1)                << SDRAM_TR2W_W2R_OFFS) |
1113                         (((tRfc - 1) >> 4)                              << SDRAM_TRFC_EXT_OFFS) |
1114                         (sdramTw2wCyc                                   << SDRAM_TW2W_OFFS));
1115         
1116 }
1117
1118 /*******************************************************************************
1119 * sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
1120 *
1121 * DESCRIPTION: 
1122 *       This function config DDR2 On Die Termination (ODT) registers.
1123 *       ODT configuration is done according to DIMM presence:
1124 *       
1125 *       Presence          Ctrl Low    Ctrl High  Dunit Ctrl   Ext Mode  
1126 *       CS0              0x84210000  0x00000000  0x0000780F  0x00000440 
1127 *       CS0+CS1          0x84210000  0x00000000  0x0000780F  0x00000440 
1128 *       CS0+CS2          0x030C030C  0x00000000  0x0000740F  0x00000404 
1129 *       CS0+CS1+CS2      0x030C030C  0x00000000  0x0000740F  0x00000404 
1130 *       CS0+CS2+CS3      0x030C030C  0x00000000  0x0000740F  0x00000404 
1131 *       CS0+CS1+CS2+CS3  0x030C030C  0x00000000  0x0000740F  0x00000404 
1132 *               
1133 * INPUT:
1134 *               pBankInfo - bank info parameters.
1135 *
1136 * OUTPUT:
1137 *       None
1138 *
1139 * RETURN:
1140 *       None
1141 *******************************************************************************/
1142 static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
1143 {
1144         MV_U32 populateBanks = 0;
1145         MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
1146         int bankNum;
1147         
1148         /* Represent the populate banks in binary form */
1149         for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
1150         {
1151                 if (0 != pBankInfo[bankNum].size)
1152                 {
1153                                 populateBanks |= (1 << bankNum);
1154                         }
1155                 }
1156         
1157         switch(populateBanks)
1158         {
1159                 case(BANK_PRESENT_CS0):
1160                         odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_DV;
1161                         odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_DV;
1162                         dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
1163                         break;
1164                 case(BANK_PRESENT_CS0_CS1):
1165                         odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_DV;
1166                         odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_DV;
1167                         dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
1168                         break;
1169                 case(BANK_PRESENT_CS0_CS2):
1170                         odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
1171                         odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
1172                         dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
1173                         break;
1174                 case(BANK_PRESENT_CS0_CS1_CS2):
1175                         odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
1176                         odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
1177                         dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
1178                         break;
1179                 case(BANK_PRESENT_CS0_CS2_CS3):
1180                         odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
1181                         odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
1182                         dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
1183                         break;
1184                 case(BANK_PRESENT_CS0_CS2_CS3_CS4):
1185                         odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
1186                         odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
1187                         dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
1188                         break;
1189                 default:
1190                         mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n");
1191                         return;
1192         } 
1193         MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
1194         MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
1195         MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
1196         return;
1197 }
1198 #endif /* defined(MV_INC_BOARD_DDIM) */
1199
1200 /*******************************************************************************
1201 * mvDramIfWinSet - Set DRAM interface address decode window
1202 *
1203 * DESCRIPTION: 
1204 *       This function sets DRAM interface address decode window.
1205 *
1206 * INPUT:
1207 *           target      - System target. Use only SDRAM targets.
1208 *       pAddrDecWin - SDRAM address window structure.
1209 *
1210 * OUTPUT:
1211 *       None
1212 *
1213 * RETURN:
1214 *       MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
1215 *       otherwise.
1216 *******************************************************************************/
1217 MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
1218 {
1219         MV_U32 baseReg=0,sizeReg=0;
1220         MV_U32 baseToReg=0 , sizeToReg=0;
1221
1222     /* Check parameters */
1223         if (!MV_TARGET_IS_DRAM(target))
1224         {
1225                 mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
1226                 return MV_BAD_PARAM;
1227         }
1228
1229     /* Check if the requested window overlaps with current enabled windows      */
1230     if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
1231         {
1232         mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
1233                 return MV_BAD_PARAM;
1234         }
1235
1236         /* check if address is aligned to the size */
1237         if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
1238         {
1239                 mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
1240                                    "\nAddress 0x%08x is unaligned to size 0x%x.\n",
1241                    target, 
1242                                    pAddrDecWin->addrWin.baseLow,
1243                                    pAddrDecWin->addrWin.size);
1244                 return MV_ERROR;
1245         }
1246
1247         /* read base register*/
1248         baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
1249
1250         /* read size register */
1251         sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
1252
1253         /* BaseLow[31:16] => base register [31:16]              */
1254         baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
1255
1256         /* Write to address decode Base Address Register                  */
1257         baseReg &= ~SCBAR_BASE_MASK;
1258         baseReg |= baseToReg;
1259
1260         /* Translate the given window size to register format                   */
1261         sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
1262
1263         /* Size parameter validity check.                                   */
1264         if (-1 == sizeToReg)
1265         {
1266                 mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
1267                 return MV_BAD_PARAM;
1268         }
1269
1270         /* set size */
1271         sizeReg &= ~SCSR_SIZE_MASK;
1272         /* Size is located at upper 16 bits */
1273         sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
1274
1275         /* enable/Disable */
1276         if (MV_TRUE == pAddrDecWin->enable)
1277         {
1278                 sizeReg |= SCSR_WIN_EN;
1279         }
1280         else
1281         {
1282                 sizeReg &= ~SCSR_WIN_EN;
1283         }
1284
1285         /* 3) Write to address decode Base Address Register                   */
1286         MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg);
1287
1288         /* Write to address decode Size Register                                */
1289         MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg);
1290         
1291         return MV_OK;
1292 }
1293 /*******************************************************************************
1294 * mvDramIfWinGet - Get DRAM interface address decode window
1295 *
1296 * DESCRIPTION: 
1297 *       This function gets DRAM interface address decode window.
1298 *
1299 * INPUT:
1300 *           target - System target. Use only SDRAM targets.
1301 *
1302 * OUTPUT:
1303 *       pAddrDecWin - SDRAM address window structure.
1304 *
1305 * RETURN:
1306 *       MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
1307 *       otherwise.
1308 *******************************************************************************/
1309 MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
1310 {
1311         MV_U32 baseReg,sizeReg;
1312         MV_U32 sizeRegVal;
1313
1314         /* Check parameters */
1315         if (!MV_TARGET_IS_DRAM(target))
1316         {
1317                 mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
1318                 return MV_ERROR;
1319         }
1320
1321         /* Read base and size registers */
1322         sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
1323         baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
1324
1325         sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
1326
1327         pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
1328                                                                                          SCSR_SIZE_ALIGNMENT);
1329
1330     /* Check if ctrlRegToSize returned OK */
1331         if (-1 == pAddrDecWin->addrWin.size)
1332         {
1333                 mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
1334                 return MV_ERROR;
1335         }
1336
1337         /* Extract base address                                         */
1338         /* Base register [31:16] ==> baseLow[31:16]             */
1339         pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
1340
1341         pAddrDecWin->addrWin.baseHigh =  0;
1342
1343
1344         if (sizeReg & SCSR_WIN_EN)
1345         {
1346                 pAddrDecWin->enable = MV_TRUE;
1347         }
1348         else
1349         {
1350                 pAddrDecWin->enable = MV_FALSE;                 
1351         }
1352
1353         return MV_OK;
1354 }
1355 /*******************************************************************************
1356 * mvDramIfWinEnable - Enable/Disable SDRAM address decode window
1357 *
1358 * DESCRIPTION: 
1359 *               This function enable/Disable SDRAM address decode window.
1360 *
1361 * INPUT:
1362 *           target - System target. Use only SDRAM targets.
1363 *
1364 * OUTPUT:
1365 *               None.
1366 *
1367 * RETURN:
1368 *               MV_ERROR in case function parameter are invalid, MV_OK otherewise.
1369 *
1370 *******************************************************************************/
1371 MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable)
1372 {
1373         MV_DRAM_DEC_WIN         addrDecWin;
1374
1375         /* Check parameters */
1376         if (!MV_TARGET_IS_DRAM(target))
1377         {
1378                 mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
1379                 return MV_ERROR;
1380         }
1381
1382         if (enable == MV_TRUE) 
1383         {   /* First check for overlap with other enabled windows                               */
1384                 if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
1385                 {
1386                         mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n", 
1387                                                                         target);
1388                         return MV_ERROR;
1389                 }
1390                 /* Check for overlapping */
1391                 if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
1392                 {
1393                         /* No Overlap. Enable address decode winNum window              */
1394                         MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
1395                 }
1396                 else
1397                 {   /* Overlap detected */
1398                         mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
1399                                                                         target);
1400                         return MV_ERROR;
1401                 }
1402         }
1403         else
1404         {   /* Disable address decode winNum window                             */
1405                 MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
1406         }
1407
1408         return MV_OK;
1409 }
1410
1411 /*******************************************************************************
1412 * sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
1413 *
1414 * DESCRIPTION:
1415 *               This function scan each SDRAM address decode window to test if it 
1416 *               overlapps the given address windoow 
1417 *
1418 * INPUT:
1419 *       target      - SDRAM target where the function skips checking.
1420 *       pAddrDecWin - The tested address window for overlapping with 
1421 *                                         SDRAM windows.
1422 *
1423 * OUTPUT:
1424 *       None.
1425 *
1426 * RETURN:
1427 *       MV_TRUE if the given address window overlaps any enabled address
1428 *       decode map, MV_FALSE otherwise.
1429 *
1430 *******************************************************************************/
1431 static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
1432 {
1433         MV_TARGET       targetNum;
1434         MV_DRAM_DEC_WIN         addrDecWin;
1435         
1436         for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
1437         {
1438                 /* don't check our winNum or illegal targets */
1439                 if (targetNum == target)
1440                 {
1441                         continue;
1442                 }
1443                 
1444                 /* Get window parameters        */
1445                 if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
1446                 {
1447                         mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
1448                         return MV_ERROR;
1449                 }
1450         
1451                 /* Do not check disabled windows        */
1452                 if (MV_FALSE == addrDecWin.enable)
1453                 {
1454                         continue;
1455                 }
1456         
1457                 if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
1458                 {                    
1459                         mvOsPrintf(
1460                         "sdramIfWinOverlap: Required target %d overlap winNum %d\n", 
1461                         target, targetNum);
1462                         return MV_TRUE;           
1463                 }
1464         }
1465         
1466         return MV_FALSE;
1467 }
1468
1469 /*******************************************************************************
1470 * mvDramIfBankSizeGet - Get DRAM interface bank size.
1471 *
1472 * DESCRIPTION:
1473 *       This function returns the size of a given DRAM bank.
1474 *
1475 * INPUT:
1476 *       bankNum - Bank number.
1477 *
1478 * OUTPUT:
1479 *       None.
1480 *
1481 * RETURN:
1482 *       DRAM bank size. If bank is disabled the function return '0'. In case 
1483 *               or paramter is invalid, the function returns -1.
1484 *
1485 *******************************************************************************/
1486 MV_32 mvDramIfBankSizeGet(MV_U32 bankNum)
1487 {
1488     MV_DRAM_DEC_WIN     addrDecWin;
1489         
1490         /* Check parameters */
1491         if (!MV_TARGET_IS_DRAM(bankNum))
1492         {
1493                 mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
1494                 return -1;
1495         }
1496         /* Get window parameters        */
1497         if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
1498         {
1499                 mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
1500                 return -1;
1501         }
1502         
1503         if (MV_TRUE == addrDecWin.enable)
1504         {
1505                 return addrDecWin.addrWin.size;
1506         }
1507         else
1508         {
1509                 return 0;
1510         }
1511 }
1512
1513
1514 /*******************************************************************************
1515 * mvDramIfSizeGet - Get DRAM interface total size.
1516 *
1517 * DESCRIPTION:
1518 *       This function get the DRAM total size.
1519 *
1520 * INPUT:
1521 *       None.
1522 *
1523 * OUTPUT:
1524 *       None.
1525 *
1526 * RETURN:
1527 *       DRAM total size. In case or paramter is invalid, the function 
1528 *               returns -1.
1529 *
1530 *******************************************************************************/
1531 MV_32 mvDramIfSizeGet(MV_VOID)
1532 {
1533         MV_U32 totalSize = 0, bankSize = 0, bankNum;
1534         
1535         for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
1536         {
1537                 bankSize = mvDramIfBankSizeGet(bankNum);
1538
1539                 if (-1 == bankSize)
1540                 {
1541                         mvOsPrintf("Dram: mvDramIfSizeGet error with bank %d \n",bankNum);
1542                         return -1;
1543                 }
1544                 else
1545                 {
1546                         totalSize += bankSize;
1547                 }
1548         }
1549         
1550         DB(mvOsPrintf("Dram: Total DRAM size is 0x%x \n",totalSize));
1551         
1552         return totalSize;
1553 }
1554
1555 /*******************************************************************************
1556 * mvDramIfBankBaseGet - Get DRAM interface bank base.
1557 *
1558 * DESCRIPTION:
1559 *       This function returns the 32 bit base address of a given DRAM bank.
1560 *
1561 * INPUT:
1562 *       bankNum - Bank number.
1563 *
1564 * OUTPUT:
1565 *       None.
1566 *
1567 * RETURN:
1568 *       DRAM bank size. If bank is disabled or paramter is invalid, the 
1569 *               function returns -1.
1570 *
1571 *******************************************************************************/
1572 MV_32 mvDramIfBankBaseGet(MV_U32 bankNum)
1573 {
1574     MV_DRAM_DEC_WIN     addrDecWin;
1575         
1576         /* Check parameters */
1577         if (!MV_TARGET_IS_DRAM(bankNum))
1578         {
1579                 mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
1580                 return -1;
1581         }
1582         /* Get window parameters        */
1583         if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
1584         {
1585                 mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
1586                 return -1;
1587         }
1588         
1589         if (MV_TRUE == addrDecWin.enable)
1590         {
1591                 return addrDecWin.addrWin.baseLow;
1592         }
1593         else
1594         {
1595                 return -1;
1596         }
1597 }
1598
1599