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