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