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