• 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/ddr1_2/
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