Root/target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c

1/*******************************************************************************
2Copyright (C) Marvell International Ltd. and its affiliates
3
4This software file (the "File") is owned and distributed by Marvell
5International Ltd. and/or its affiliates ("Marvell") under the following
6alternative licensing terms. Once you have made an election to distribute the
7File under one of the following license alternatives, please (i) delete this
8introductory statement regarding license alternatives, (ii) delete the two
9license alternatives that you have not elected to use and (iii) preserve the
10Marvell copyright notice above.
11
12********************************************************************************
13Marvell Commercial License Option
14
15If you received this File from Marvell and you have entered into a commercial
16license agreement (a "Commercial License") with Marvell, the File is licensed
17to you under the terms of the applicable Commercial License.
18
19********************************************************************************
20Marvell GPL License Option
21
22If you received this File from Marvell, you may opt to use, redistribute and/or
23modify this File in accordance with the terms and conditions of the General
24Public License Version 2, June 1991 (the "GPL License"), a copy of which is
25available along with the File in the license.txt file or by writing to the Free
26Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
28
29THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31DISCLAIMED. The GPL License provides additional details about this warranty
32disclaimer.
33********************************************************************************
34Marvell BSD License Option
35
36If you received this File from Marvell, you may opt to use, redistribute and/or
37modify this File under the following licensing terms.
38Redistribution and use in source and binary forms, with or without modification,
39are permitted provided that the following conditions are met:
40
41    * Redistributions of source code must retain the above copyright notice,
42        this list of conditions and the following disclaimer.
43
44    * Redistributions in binary form must reproduce the above copyright
45        notice, this list of conditions and the following disclaimer in the
46        documentation and/or other materials provided with the distribution.
47
48    * Neither the name of Marvell nor the names of its contributors may be
49        used to endorse or promote products derived from this software without
50        specific prior written permission.
51    
52THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
53ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
56ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62
63*******************************************************************************/
64
65
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 */
87static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
88#if defined(MV_INC_BOARD_DDIM)
89static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
90static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas);
91static MV_U32 sdramModeRegCalc(MV_U32 minCas);
92static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
93static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
94static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
95static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
96                         MV_U32 forcedCl);
97static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
98                                      MV_U32 minCas, MV_U32 busClk);
99static 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*******************************************************************************/
132MV_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*******************************************************************************/
360static 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*******************************************************************************/
503static 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*******************************************************************************/
609static 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*******************************************************************************/
695static 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*******************************************************************************/
755static 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            *********-********-********-********-********-*********
776Not Reg. * 0011 | 0011 | 0100 | 0100 | 0101 | TBD *
777            *********-********-********-********-********-*********
778Registered * 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*******************************************************************************/
872static 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*******************************************************************************/
930static 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*******************************************************************************/
1053static 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*******************************************************************************/
1142static 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*******************************************************************************/
1217MV_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*******************************************************************************/
1309MV_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*******************************************************************************/
1371MV_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*******************************************************************************/
1431static 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*******************************************************************************/
1486MV_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*******************************************************************************/
1531MV_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*******************************************************************************/
1572MV_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
1600

Archive Download this file



interactive