1 /*******************************************************************************
2 Copyright (C) Marvell International Ltd. and its affiliates
4 This software file (the "File") is owned and distributed by Marvell
5 International Ltd. and/or its affiliates ("Marvell") under the following
6 alternative licensing terms. Once you have made an election to distribute the
7 File under one of the following license alternatives, please (i) delete this
8 introductory statement regarding license alternatives, (ii) delete the two
9 license alternatives that you have not elected to use and (iii) preserve the
10 Marvell copyright notice above.
12 ********************************************************************************
13 Marvell Commercial License Option
15 If you received this File from Marvell and you have entered into a commercial
16 license agreement (a "Commercial License") with Marvell, the File is licensed
17 to you under the terms of the applicable Commercial License.
19 ********************************************************************************
20 Marvell GPL License Option
22 If you received this File from Marvell, you may opt to use, redistribute and/or
23 modify this File in accordance with the terms and conditions of the General
24 Public License Version 2, June 1991 (the "GPL License"), a copy of which is
25 available along with the File in the license.txt file or by writing to the Free
26 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27 on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
29 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31 DISCLAIMED. The GPL License provides additional details about this warranty
33 ********************************************************************************
34 Marvell BSD License Option
36 If you received this File from Marvell, you may opt to use, redistribute and/or
37 modify this File under the following licensing terms.
38 Redistribution and use in source and binary forms, with or without modification,
39 are permitted provided that the following conditions are met:
41 * Redistributions of source code must retain the above copyright notice,
42 this list of conditions and the following disclaimer.
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.
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.
52 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
53 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
56 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59 ANY 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
61 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63 *******************************************************************************/
65 #include "ddr2/spd/mvSpd.h"
66 #include "boardEnv/mvBoardEnvLib.h"
68 /* #define MV_DEBUG */
75 static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
76 MV_DRAM_BANK_INFO *pBankInfo);
77 static MV_U32 cas2ps(MV_U8 spd_byte);
78 /*******************************************************************************
79 * mvDramBankGet - Get the DRAM bank paramters.
82 * This function retrieves DRAM bank parameters as described in
83 * DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
84 * has its DRAM on DIMMs it will use its EEPROM to extract SPD data
85 * from it. Otherwise, if the DRAM is soldered on board, the function
86 * should insert its bank information into MV_DRAM_BANK_INFO struct.
89 * bankNum - Board DRAM bank number.
92 * pBankInfo - DRAM bank information struct.
95 * MV_FAIL - Bank parameters could not be read.
97 *******************************************************************************/
98 MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
100 MV_DIMM_INFO dimmInfo;
102 DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
103 /* zero pBankInfo structure */
105 if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
107 DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
110 memset(pBankInfo, 0, sizeof(*pBankInfo));
112 if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
114 DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
117 if ((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
119 DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
122 /* convert Dimm info to Bank info */
123 cpyDimm2BankInfo(&dimmInfo, pBankInfo);
127 /*******************************************************************************
128 * cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
131 * Convert a Dimm info struct into a bank info struct.
134 * pDimmInfo - DIMM information structure.
137 * pBankInfo - DRAM bank information struct.
142 *******************************************************************************/
143 static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
144 MV_DRAM_BANK_INFO *pBankInfo)
146 pBankInfo->memoryType = pDimmInfo->memoryType;
148 /* DIMM dimensions */
149 pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
150 pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
151 pBankInfo->dataWidth = pDimmInfo->dataWidth;
152 pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
153 pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
154 pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
155 pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
156 pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
157 pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
159 /* DIMM timing parameters */
160 pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
161 pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
162 pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
163 pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
164 pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
166 pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
167 pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
168 pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
169 pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
170 pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
171 pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
172 pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
173 pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
175 /* Parameters calculated from the extracted DIMM information */
176 pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
177 pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
178 pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
179 pDimmInfo->numOfModuleBanks;
181 /* DIMM attributes (MV_TRUE for yes) */
183 if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
184 (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
186 if (pDimmInfo->dimmAttributes & BIT1)
187 pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
189 pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
191 else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
193 if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
194 pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
196 pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
201 /*******************************************************************************
202 * dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
205 * Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
214 * MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
216 *******************************************************************************/
217 MV_STATUS dimmSpdCpy(MV_VOID)
222 MV_TWSI_SLAVE twsiSlave;
223 MV_U8 data[SPD_SIZE];
225 /* zero dimmInfo structure */
226 memset(data, 0, SPD_SIZE);
228 /* read the dimm eeprom */
229 DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
230 twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
231 twsiSlave.slaveAddr.type = ADDR7_BIT;
232 twsiSlave.validOffset = MV_TRUE;
233 twsiSlave.offset = 0;
234 twsiSlave.moreThen256 = MV_FALSE;
236 if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
238 DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
241 DB(puts("DRAM: Reading dimm info succeded.\n"));
243 /* calculate SPD checksum */
246 for(i = 0 ; i <= 62 ; i++)
248 spdChecksum += data[i];
251 if ((spdChecksum & 0xff) != data[63])
253 DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
254 (MV_U32)(spdChecksum & 0xff), data[63]));
258 DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
261 /* copy the SPD content 1:1 into the DIMM 1 SPD */
262 twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
263 twsiSlave.slaveAddr.type = ADDR7_BIT;
264 twsiSlave.validOffset = MV_TRUE;
265 twsiSlave.offset = 0;
266 twsiSlave.moreThen256 = MV_FALSE;
268 for(i = 0 ; i < SPD_SIZE ; i++)
270 twsiSlave.offset = i;
271 if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, &data[i], 1) )
273 mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
279 DB(puts("DRAM: Reading dimm info succeded.\n"));
283 /*******************************************************************************
284 * dimmSpdGet - Get the SPD parameters.
287 * Read the DIMM SPD parameters into given struct parameter.
290 * dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
293 * pDimmInfo - DIMM information structure.
296 * MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
298 *******************************************************************************/
299 MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
305 MV_TWSI_SLAVE twsiSlave;
306 MV_U8 data[SPD_SIZE];
308 if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
310 DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
314 /* zero dimmInfo structure */
315 memset(data, 0, SPD_SIZE);
317 /* read the dimm eeprom */
318 DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
319 twsiSlave.slaveAddr.address = (dimmNum == 0) ?
320 MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
321 twsiSlave.slaveAddr.type = ADDR7_BIT;
322 twsiSlave.validOffset = MV_TRUE;
323 twsiSlave.offset = 0;
324 twsiSlave.moreThen256 = MV_FALSE;
326 if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
328 DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
331 DB(puts("DRAM: Reading dimm info succeded.\n"));
333 /* calculate SPD checksum */
336 for(i = 0 ; i <= 62 ; i++)
338 spdChecksum += data[i];
341 if ((spdChecksum & 0xff) != data[63])
343 DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
344 (MV_U32)(spdChecksum & 0xff), data[63]));
348 DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
351 /* copy the SPD content 1:1 into the dimmInfo structure*/
352 for(i = 0 ; i < SPD_SIZE ; i++)
354 pDimmInfo->spdRawData[i] = data[i];
355 DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
358 DB(mvOsPrintf("DRAM SPD Information:\n"));
360 /* Memory type (DDR / SDRAM) */
361 switch (data[DIMM_MEM_TYPE])
363 case (DIMM_MEM_TYPE_SDRAM):
364 pDimmInfo->memoryType = MEM_TYPE_SDRAM;
365 DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
367 case (DIMM_MEM_TYPE_DDR1):
368 pDimmInfo->memoryType = MEM_TYPE_DDR1;
369 DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
371 case (DIMM_MEM_TYPE_DDR2):
372 pDimmInfo->memoryType = MEM_TYPE_DDR2;
373 DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
376 mvOsPrintf("ERROR: Undefined memory type!\n");
381 /* Number Of Row Addresses */
382 pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
383 DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
385 /* Number Of Column Addresses */
386 pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
387 DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
389 /* Number Of Module Banks */
390 pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
391 DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
392 pDimmInfo->numOfModuleBanks));
394 /* Number of module banks encoded differently for DDR2 */
395 if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
396 pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
399 pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
400 DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
402 /* Minimum Cycle Time At Max CasLatancy */
403 pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
405 /* Error Check Type */
406 pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
407 DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
408 pDimmInfo->errorCheckType));
410 /* Refresh Interval */
411 pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
412 DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
413 pDimmInfo->refreshInterval));
416 pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
417 DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
419 /* Error Check Data Width */
420 pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
421 DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
422 pDimmInfo->errorCheckDataWidth));
424 /* Burst Length Supported */
426 *******-******-******-******-******-******-******-*******
427 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
428 *******-******-******-******-******-******-******-*******
429 burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
430 *********************************************************/
432 *******-******-******-******-******-******-******-*******
433 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
434 *******-******-******-******-******-******-******-*******
435 burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
436 *********************************************************/
438 pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
439 DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
440 pDimmInfo->burstLengthSupported));
442 /* Number Of Banks On Each Device */
443 pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
444 DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
445 pDimmInfo->numOfBanksOnEachDevice));
447 /* Suported Cas Latencies */
450 *******-******-******-******-******-******-******-*******
451 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
452 *******-******-******-******-******-******-******-*******
453 CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
454 ********************************************************/
457 *******-******-******-******-******-******-******-*******
458 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
459 *******-******-******-******-******-******-******-*******
460 CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
461 *********************************************************/
464 *******-******-******-******-******-******-******-*******
465 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
466 *******-******-******-******-******-******-******-*******
467 CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
468 *********************************************************/
470 pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
471 DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
472 pDimmInfo->suportedCasLatencies));
474 /* For DDR2 only, get the DIMM type information */
475 if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
477 pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
478 DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
479 pDimmInfo->dimmTypeInfo));
482 /* SDRAM Modules Attributes */
483 pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
484 DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
485 pDimmInfo->dimmAttributes));
487 /* Minimum Cycle Time At Max CasLatancy Minus 1*/
488 pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
489 cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
491 /* Minimum Cycle Time At Max CasLatancy Minus 2*/
492 pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
493 cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
495 pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
496 DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
497 pDimmInfo->minRowPrechargeTime));
498 pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
499 DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
500 pDimmInfo->minRowActiveToRowActive));
501 pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
502 DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
503 pDimmInfo->minRasToCasDelay));
504 pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
505 DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
506 pDimmInfo->minRasPulseWidth));
508 /* DIMM Bank Density */
509 pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
510 DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
511 pDimmInfo->dimmBankDensity));
513 /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
514 pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
515 DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
516 pDimmInfo->minWriteRecoveryTime));
518 /* Only DDR2 includes Internal Write To Read Command Delay field. */
519 pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
520 DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
521 pDimmInfo->minWriteToReadCmdDelay));
523 /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
524 pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
525 DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
526 pDimmInfo->minReadToPrechCmdDelay));
528 /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
529 pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
530 DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
531 pDimmInfo->minRefreshToActiveCmd));
533 /* calculating the sdram density. Representing device density from */
534 /* bit 20 to allow representation of 4GB and above. */
535 /* For example, if density is 512Mbit 0x20000000, will be represent in */
536 /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
537 /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
538 density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
539 pDimmInfo->deviceDensity = density *
540 pDimmInfo->numOfBanksOnEachDevice *
541 pDimmInfo->sdramWidth;
542 DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
544 /* Number of devices includeing Error correction */
545 pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
546 pDimmInfo->numOfModuleBanks;
547 DB(mvOsPrintf("DRAM numberOfDevices %d\n",
548 pDimmInfo->numberOfDevices));
552 /* Note that pDimmInfo->size is in MB units */
553 if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
555 if (pDimmInfo->dimmBankDensity & BIT0)
556 pDimmInfo->size += 1024; /* Equal to 1GB */
557 else if (pDimmInfo->dimmBankDensity & BIT1)
558 pDimmInfo->size += 8; /* Equal to 8MB */
559 else if (pDimmInfo->dimmBankDensity & BIT2)
560 pDimmInfo->size += 16; /* Equal to 16MB */
561 else if (pDimmInfo->dimmBankDensity & BIT3)
562 pDimmInfo->size += 32; /* Equal to 32MB */
563 else if (pDimmInfo->dimmBankDensity & BIT4)
564 pDimmInfo->size += 64; /* Equal to 64MB */
565 else if (pDimmInfo->dimmBankDensity & BIT5)
566 pDimmInfo->size += 128; /* Equal to 128MB */
567 else if (pDimmInfo->dimmBankDensity & BIT6)
568 pDimmInfo->size += 256; /* Equal to 256MB */
569 else if (pDimmInfo->dimmBankDensity & BIT7)
570 pDimmInfo->size += 512; /* Equal to 512MB */
572 else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
574 if (pDimmInfo->dimmBankDensity & BIT0)
575 pDimmInfo->size += 1024; /* Equal to 1GB */
576 else if (pDimmInfo->dimmBankDensity & BIT1)
577 pDimmInfo->size += 2048; /* Equal to 2GB */
578 else if (pDimmInfo->dimmBankDensity & BIT2)
579 pDimmInfo->size += 16; /* Equal to 16MB */
580 else if (pDimmInfo->dimmBankDensity & BIT3)
581 pDimmInfo->size += 32; /* Equal to 32MB */
582 else if (pDimmInfo->dimmBankDensity & BIT4)
583 pDimmInfo->size += 64; /* Equal to 64MB */
584 else if (pDimmInfo->dimmBankDensity & BIT5)
585 pDimmInfo->size += 128; /* Equal to 128MB */
586 else if (pDimmInfo->dimmBankDensity & BIT6)
587 pDimmInfo->size += 256; /* Equal to 256MB */
588 else if (pDimmInfo->dimmBankDensity & BIT7)
589 pDimmInfo->size += 512; /* Equal to 512MB */
591 else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
593 if (pDimmInfo->dimmBankDensity & BIT0)
594 pDimmInfo->size += 1024; /* Equal to 1GB */
595 else if (pDimmInfo->dimmBankDensity & BIT1)
596 pDimmInfo->size += 2048; /* Equal to 2GB */
597 else if (pDimmInfo->dimmBankDensity & BIT2)
598 pDimmInfo->size += 4096; /* Equal to 4GB */
599 else if (pDimmInfo->dimmBankDensity & BIT3)
600 pDimmInfo->size += 8192; /* Equal to 8GB */
601 else if (pDimmInfo->dimmBankDensity & BIT4)
602 pDimmInfo->size += 16384; /* Equal to 16GB */
603 else if (pDimmInfo->dimmBankDensity & BIT5)
604 pDimmInfo->size += 128; /* Equal to 128MB */
605 else if (pDimmInfo->dimmBankDensity & BIT6)
606 pDimmInfo->size += 256; /* Equal to 256MB */
607 else if (pDimmInfo->dimmBankDensity & BIT7)
608 pDimmInfo->size += 512; /* Equal to 512MB */
611 pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
613 DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
618 /*******************************************************************************
619 * dimmSpdPrint - Print the SPD parameters.
622 * Print the Dimm SPD parameters.
625 * pDimmInfo - DIMM information structure.
633 *******************************************************************************/
634 MV_VOID dimmSpdPrint(MV_U32 dimmNum)
636 MV_DIMM_INFO dimmInfo;
638 MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
639 MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
641 MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
642 temp_buf[40], *spdRawData;
644 busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
646 spdRawData = dimmInfo.spdRawData;
648 if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
650 mvOsOutput("ERROR: Could not read SPD information!\n");
654 /* find Manufactura of Dimm Module */
655 mvOsOutput("\nManufacturer's JEDEC ID Code: ");
656 for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
658 mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
662 /* Manufacturer's Specific Data */
663 for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
665 temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
667 mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
669 /* Module Part Number */
670 for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
672 temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
674 mvOsOutput("Module Part Number: %s\n", temp_buf);
676 /* Module Serial Number */
677 for(i = 0; i < sizeof(MV_U32); i++)
679 temp |= spdRawData[95+i] << 8*i;
681 mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
684 /* find Manufac-Data of Dimm Module */
685 mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
686 ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
687 ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
688 /* find modul_revision of Dimm Module */
689 mvOsOutput("Module Revision: %d.%d\n",
690 spdRawData[62]/10, spdRawData[62]%10);
692 /* find manufac_place of Dimm Module */
693 mvOsOutput("manufac_place: %d\n", spdRawData[72]);
695 /* go over the first 35 I2C data bytes */
696 for(i = 2 ; i <= 35 ; i++)
699 case 2: /* Memory type (DDR1/2 / SDRAM) */
700 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
701 mvOsOutput("Dram Type is: SDRAM\n");
702 else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
703 mvOsOutput("Dram Type is: SDRAM DDR1\n");
704 else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
705 mvOsOutput("Dram Type is: SDRAM DDR2\n");
707 mvOsOutput("Dram Type unknown\n");
709 /*----------------------------------------------------------------------------*/
711 case 3: /* Number Of Row Addresses */
712 mvOsOutput("Module Number of row addresses: %d\n",
713 dimmInfo.numOfRowAddr);
715 /*----------------------------------------------------------------------------*/
717 case 4: /* Number Of Column Addresses */
718 mvOsOutput("Module Number of col addresses: %d\n",
719 dimmInfo.numOfColAddr);
721 /*----------------------------------------------------------------------------*/
723 case 5: /* Number Of Module Banks */
724 mvOsOutput("Number of Banks on Mod.: %d\n",
725 dimmInfo.numOfModuleBanks);
727 /*----------------------------------------------------------------------------*/
729 case 6: /* Data Width */
730 mvOsOutput("Module Data Width: %d bit\n",
733 /*----------------------------------------------------------------------------*/
735 case 8: /* Voltage Interface */
736 switch(spdRawData[i])
739 mvOsOutput("Module is TTL_5V_TOLERANT\n");
742 mvOsOutput("Module is LVTTL\n");
745 mvOsOutput("Module is HSTL_1_5V\n");
748 mvOsOutput("Module is SSTL_3_3V\n");
751 mvOsOutput("Module is SSTL_2_5V\n");
754 if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
756 mvOsOutput("Module is SSTL_1_8V\n");
760 mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
764 /*----------------------------------------------------------------------------*/
766 case 9: /* Minimum Cycle Time At Max CasLatancy */
767 leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
768 rightOfPoint = (spdRawData[i] & 0x0f) * 10;
770 /* DDR2 addition of right of point */
771 if ((spdRawData[i] & 0x0f) == 0xA)
775 if ((spdRawData[i] & 0x0f) == 0xB)
779 if ((spdRawData[i] & 0x0f) == 0xC)
783 if ((spdRawData[i] & 0x0f) == 0xD)
787 mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
788 leftOfPoint, rightOfPoint);
790 /*----------------------------------------------------------------------------*/
792 case 10: /* Clock To Data Out */
793 div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
794 time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
795 ((spdRawData[i] & 0x0f));
796 leftOfPoint = time_tmp / div;
797 rightOfPoint = time_tmp % div;
798 mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
799 leftOfPoint, rightOfPoint);
801 /*----------------------------------------------------------------------------*/
803 case 11: /* Error Check Type */
804 mvOsOutput("Error Check Type (0=NONE): %d\n",
805 dimmInfo.errorCheckType);
807 /*----------------------------------------------------------------------------*/
809 case 12: /* Refresh Interval */
810 mvOsOutput("Refresh Rate: %x\n",
811 dimmInfo.refreshInterval);
813 /*----------------------------------------------------------------------------*/
815 case 13: /* Sdram Width */
816 mvOsOutput("Sdram Width: %d bits\n",
817 dimmInfo.sdramWidth);
819 /*----------------------------------------------------------------------------*/
821 case 14: /* Error Check Data Width */
822 mvOsOutput("Error Check Data Width: %d bits\n",
823 dimmInfo.errorCheckDataWidth);
825 /*----------------------------------------------------------------------------*/
827 case 15: /* Minimum Clock Delay is unsupported */
828 if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
829 (dimmInfo.memoryType == MEM_TYPE_DDR1))
831 mvOsOutput("Minimum Clk Delay back to back: %d\n",
835 /*----------------------------------------------------------------------------*/
837 case 16: /* Burst Length Supported */
839 *******-******-******-******-******-******-******-*******
840 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
841 *******-******-******-******-******-******-******-*******
842 burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
843 *********************************************************/
845 *******-******-******-******-******-******-******-*******
846 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
847 *******-******-******-******-******-******-******-*******
848 burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
849 *********************************************************/
850 mvOsOutput("Burst Length Supported: ");
851 if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
852 (dimmInfo.memoryType == MEM_TYPE_DDR1))
854 if (dimmInfo.burstLengthSupported & BIT0)
856 if (dimmInfo.burstLengthSupported & BIT1)
859 if (dimmInfo.burstLengthSupported & BIT2)
861 if (dimmInfo.burstLengthSupported & BIT3)
864 mvOsOutput(" Bit \n");
866 /*----------------------------------------------------------------------------*/
868 case 17: /* Number Of Banks On Each Device */
869 mvOsOutput("Number Of Banks On Each Chip: %d\n",
870 dimmInfo.numOfBanksOnEachDevice);
872 /*----------------------------------------------------------------------------*/
874 case 18: /* Suported Cas Latencies */
877 *******-******-******-******-******-******-******-*******
878 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
879 *******-******-******-******-******-******-******-*******
880 CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
881 ********************************************************/
884 *******-******-******-******-******-******-******-*******
885 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
886 *******-******-******-******-******-******-******-*******
887 CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
888 *********************************************************/
891 *******-******-******-******-******-******-******-*******
892 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
893 *******-******-******-******-******-******-******-*******
894 CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
895 *********************************************************/
897 mvOsOutput("Suported Cas Latencies: (CL) ");
898 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
900 for (k = 0; k <=7; k++)
902 if (dimmInfo.suportedCasLatencies & (1 << k))
903 mvOsOutput("%d, ", k+1);
906 else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
908 if (dimmInfo.suportedCasLatencies & BIT0)
910 if (dimmInfo.suportedCasLatencies & BIT1)
912 if (dimmInfo.suportedCasLatencies & BIT2)
914 if (dimmInfo.suportedCasLatencies & BIT3)
916 if (dimmInfo.suportedCasLatencies & BIT4)
918 if (dimmInfo.suportedCasLatencies & BIT5)
921 else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
923 if (dimmInfo.suportedCasLatencies & BIT2)
925 if (dimmInfo.suportedCasLatencies & BIT3)
927 if (dimmInfo.suportedCasLatencies & BIT4)
929 if (dimmInfo.suportedCasLatencies & BIT5)
936 /*----------------------------------------------------------------------------*/
938 case 20: /* DDR2 DIMM type info */
939 if (dimmInfo.memoryType == MEM_TYPE_DDR2)
941 if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
942 mvOsOutput("Registered DIMM (RDIMM)\n");
943 else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
944 mvOsOutput("Unbuffered DIMM (UDIMM)\n");
946 mvOsOutput("Unknown DIMM type.\n");
950 /*----------------------------------------------------------------------------*/
952 case 21: /* SDRAM Modules Attributes */
953 mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
955 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
957 if (dimmInfo.dimmAttributes & BIT0)
958 mvOsOutput(" Buffered Addr/Control Input: Yes\n");
960 mvOsOutput(" Buffered Addr/Control Input: No\n");
962 if (dimmInfo.dimmAttributes & BIT1)
963 mvOsOutput(" Registered Addr/Control Input: Yes\n");
965 mvOsOutput(" Registered Addr/Control Input: No\n");
967 if (dimmInfo.dimmAttributes & BIT2)
968 mvOsOutput(" On-Card PLL (clock): Yes \n");
970 mvOsOutput(" On-Card PLL (clock): No \n");
972 if (dimmInfo.dimmAttributes & BIT3)
973 mvOsOutput(" Bufferd DQMB Input: Yes \n");
975 mvOsOutput(" Bufferd DQMB Inputs: No \n");
977 if (dimmInfo.dimmAttributes & BIT4)
978 mvOsOutput(" Registered DQMB Inputs: Yes \n");
980 mvOsOutput(" Registered DQMB Inputs: No \n");
982 if (dimmInfo.dimmAttributes & BIT5)
983 mvOsOutput(" Differential Clock Input: Yes \n");
985 mvOsOutput(" Differential Clock Input: No \n");
987 if (dimmInfo.dimmAttributes & BIT6)
988 mvOsOutput(" redundant Row Addressing: Yes \n");
990 mvOsOutput(" redundant Row Addressing: No \n");
992 else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
994 if (dimmInfo.dimmAttributes & BIT0)
995 mvOsOutput(" Buffered Addr/Control Input: Yes\n");
997 mvOsOutput(" Buffered Addr/Control Input: No\n");
999 if (dimmInfo.dimmAttributes & BIT1)
1000 mvOsOutput(" Registered Addr/Control Input: Yes\n");
1002 mvOsOutput(" Registered Addr/Control Input: No\n");
1004 if (dimmInfo.dimmAttributes & BIT2)
1005 mvOsOutput(" On-Card PLL (clock): Yes \n");
1007 mvOsOutput(" On-Card PLL (clock): No \n");
1009 if (dimmInfo.dimmAttributes & BIT3)
1010 mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
1012 mvOsOutput(" FET Switch On-Card Enabled: No \n");
1014 if (dimmInfo.dimmAttributes & BIT4)
1015 mvOsOutput(" FET Switch External Enabled: Yes \n");
1017 mvOsOutput(" FET Switch External Enabled: No \n");
1019 if (dimmInfo.dimmAttributes & BIT5)
1020 mvOsOutput(" Differential Clock Input: Yes \n");
1022 mvOsOutput(" Differential Clock Input: No \n");
1024 else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
1026 mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
1027 (dimmInfo.dimmAttributes & 0x3) + 1);
1029 mvOsOutput(" Number of PLLs on the DIMM: %d\n",
1030 ((dimmInfo.dimmAttributes) >> 2) & 0x3);
1032 if (dimmInfo.dimmAttributes & BIT4)
1033 mvOsOutput(" FET Switch External Enabled: Yes \n");
1035 mvOsOutput(" FET Switch External Enabled: No \n");
1037 if (dimmInfo.dimmAttributes & BIT6)
1038 mvOsOutput(" Analysis probe installed: Yes \n");
1040 mvOsOutput(" Analysis probe installed: No \n");
1044 /*----------------------------------------------------------------------------*/
1046 case 22: /* Suported AutoPreCharge */
1047 mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
1048 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1050 if ( spdRawData[i] & BIT0 )
1051 mvOsOutput(" Early Ras Precharge: Yes \n");
1053 mvOsOutput(" Early Ras Precharge: No \n");
1055 if ( spdRawData[i] & BIT1 )
1056 mvOsOutput(" AutoPreCharge: Yes \n");
1058 mvOsOutput(" AutoPreCharge: No \n");
1060 if ( spdRawData[i] & BIT2 )
1061 mvOsOutput(" Precharge All: Yes \n");
1063 mvOsOutput(" Precharge All: No \n");
1065 if ( spdRawData[i] & BIT3 )
1066 mvOsOutput(" Write 1/ReadBurst: Yes \n");
1068 mvOsOutput(" Write 1/ReadBurst: No \n");
1070 if ( spdRawData[i] & BIT4 )
1071 mvOsOutput(" lower VCC tolerance: 5%%\n");
1073 mvOsOutput(" lower VCC tolerance: 10%%\n");
1075 if ( spdRawData[i] & BIT5 )
1076 mvOsOutput(" upper VCC tolerance: 5%%\n");
1078 mvOsOutput(" upper VCC tolerance: 10%%\n");
1080 else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
1082 if ( spdRawData[i] & BIT0 )
1083 mvOsOutput(" Supports Weak Driver: Yes \n");
1085 mvOsOutput(" Supports Weak Driver: No \n");
1087 if ( !(spdRawData[i] & BIT4) )
1088 mvOsOutput(" lower VCC tolerance: 0.2V\n");
1090 if ( !(spdRawData[i] & BIT5) )
1091 mvOsOutput(" upper VCC tolerance: 0.2V\n");
1093 if ( spdRawData[i] & BIT6 )
1094 mvOsOutput(" Concurrent Auto Preharge: Yes \n");
1096 mvOsOutput(" Concurrent Auto Preharge: No \n");
1098 if ( spdRawData[i] & BIT7 )
1099 mvOsOutput(" Supports Fast AP: Yes \n");
1101 mvOsOutput(" Supports Fast AP: No \n");
1103 else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
1105 if ( spdRawData[i] & BIT0 )
1106 mvOsOutput(" Supports Weak Driver: Yes \n");
1108 mvOsOutput(" Supports Weak Driver: No \n");
1111 /*----------------------------------------------------------------------------*/
1114 /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
1115 leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1116 rightOfPoint = (spdRawData[i] & 0x0f) * 10;
1118 /* DDR2 addition of right of point */
1119 if ((spdRawData[i] & 0x0f) == 0xA)
1123 if ((spdRawData[i] & 0x0f) == 0xB)
1127 if ((spdRawData[i] & 0x0f) == 0xC)
1131 if ((spdRawData[i] & 0x0f) == 0xD)
1136 mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
1137 "(0 = Not supported): %d.%d [ns]\n",
1138 leftOfPoint, rightOfPoint );
1140 /*----------------------------------------------------------------------------*/
1142 case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
1143 div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
1144 time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1145 ((spdRawData[i] & 0x0f));
1146 leftOfPoint = time_tmp / div;
1147 rightOfPoint = time_tmp % div;
1148 mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
1149 leftOfPoint, rightOfPoint);
1151 /*----------------------------------------------------------------------------*/
1154 /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
1155 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1157 leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
1158 rightOfPoint = (spdRawData[i] & 0x3) * 25;
1160 else /* DDR1 or DDR2 */
1162 leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1163 rightOfPoint = (spdRawData[i] & 0x0f) * 10;
1165 /* DDR2 addition of right of point */
1166 if ((spdRawData[i] & 0x0f) == 0xA)
1170 if ((spdRawData[i] & 0x0f) == 0xB)
1174 if ((spdRawData[i] & 0x0f) == 0xC)
1178 if ((spdRawData[i] & 0x0f) == 0xD)
1183 mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
1184 "(0 = Not supported): %d.%d [ns]\n",
1185 leftOfPoint, rightOfPoint );
1187 /*----------------------------------------------------------------------------*/
1189 case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
1190 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1192 leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
1193 rightOfPoint = (spdRawData[i] & 0x3) * 25;
1195 else /* DDR1 or DDR2 */
1197 time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1198 ((spdRawData[i] & 0x0f));
1200 rightOfPoint = time_tmp;
1202 mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
1203 leftOfPoint, rightOfPoint );
1205 /*----------------------------------------------------------------------------*/
1207 case 27: /* Minimum Row Precharge Time */
1208 shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
1209 maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1211 maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1213 leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
1214 rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
1215 temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
1216 trp_clocks = (temp + (busClkPs-1)) / busClkPs;
1217 mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
1218 "in Clk cycles %d\n",
1219 leftOfPoint, rightOfPoint, trp_clocks);
1221 /*----------------------------------------------------------------------------*/
1223 case 28: /* Minimum Row Active to Row Active Time */
1224 shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
1225 maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1227 maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1229 leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
1230 rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
1231 temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
1232 trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
1233 mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
1234 "%d.%d = in Clk cycles %d\n",
1235 leftOfPoint, rightOfPoint, trp_clocks);
1237 /*----------------------------------------------------------------------------*/
1239 case 29: /* Minimum Ras-To-Cas Delay */
1240 shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
1241 maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1243 maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1245 leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
1246 rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
1247 temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
1248 trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
1249 mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
1250 "in Clk cycles %d\n",
1251 leftOfPoint, rightOfPoint, trp_clocks);
1253 /*----------------------------------------------------------------------------*/
1255 case 30: /* Minimum Ras Pulse Width */
1256 tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
1257 mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
1258 "in Clk cycles %d\n", spdRawData[i], tras_clocks);
1260 /*----------------------------------------------------------------------------*/
1262 case 31: /* Module Bank Density */
1263 mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
1265 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1267 if (dimmInfo.dimmBankDensity & BIT0)
1268 mvOsOutput("1GB, ");
1269 if (dimmInfo.dimmBankDensity & BIT1)
1270 mvOsOutput("8MB, ");
1271 if (dimmInfo.dimmBankDensity & BIT2)
1272 mvOsOutput("16MB, ");
1273 if (dimmInfo.dimmBankDensity & BIT3)
1274 mvOsOutput("32MB, ");
1275 if (dimmInfo.dimmBankDensity & BIT4)
1276 mvOsOutput("64MB, ");
1277 if (dimmInfo.dimmBankDensity & BIT5)
1278 mvOsOutput("128MB, ");
1279 if (dimmInfo.dimmBankDensity & BIT6)
1280 mvOsOutput("256MB, ");
1281 if (dimmInfo.dimmBankDensity & BIT7)
1282 mvOsOutput("512MB, ");
1284 else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
1286 if (dimmInfo.dimmBankDensity & BIT0)
1287 mvOsOutput("1GB, ");
1288 if (dimmInfo.dimmBankDensity & BIT1)
1289 mvOsOutput("2GB, ");
1290 if (dimmInfo.dimmBankDensity & BIT2)
1291 mvOsOutput("16MB, ");
1292 if (dimmInfo.dimmBankDensity & BIT3)
1293 mvOsOutput("32MB, ");
1294 if (dimmInfo.dimmBankDensity & BIT4)
1295 mvOsOutput("64MB, ");
1296 if (dimmInfo.dimmBankDensity & BIT5)
1297 mvOsOutput("128MB, ");
1298 if (dimmInfo.dimmBankDensity & BIT6)
1299 mvOsOutput("256MB, ");
1300 if (dimmInfo.dimmBankDensity & BIT7)
1301 mvOsOutput("512MB, ");
1303 else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
1305 if (dimmInfo.dimmBankDensity & BIT0)
1306 mvOsOutput("1GB, ");
1307 if (dimmInfo.dimmBankDensity & BIT1)
1308 mvOsOutput("2GB, ");
1309 if (dimmInfo.dimmBankDensity & BIT2)
1310 mvOsOutput("4GB, ");
1311 if (dimmInfo.dimmBankDensity & BIT3)
1312 mvOsOutput("8GB, ");
1313 if (dimmInfo.dimmBankDensity & BIT4)
1314 mvOsOutput("16GB, ");
1315 if (dimmInfo.dimmBankDensity & BIT5)
1316 mvOsOutput("128MB, ");
1317 if (dimmInfo.dimmBankDensity & BIT6)
1318 mvOsOutput("256MB, ");
1319 if (dimmInfo.dimmBankDensity & BIT7)
1320 mvOsOutput("512MB, ");
1324 /*----------------------------------------------------------------------------*/
1326 case 32: /* Address And Command Setup Time (measured in ns/1000) */
1327 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1329 rightOfPoint = (spdRawData[i] & 0x0f);
1330 leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1336 else /* DDR1 or DDR2 */
1338 time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1339 ((spdRawData[i] & 0x0f));
1340 leftOfPoint = time_tmp / 100;
1341 rightOfPoint = time_tmp % 100;
1343 mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
1344 leftOfPoint, rightOfPoint);
1346 /*----------------------------------------------------------------------------*/
1348 case 33: /* Address And Command Hold Time */
1349 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1351 rightOfPoint = (spdRawData[i] & 0x0f);
1352 leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1358 else /* DDR1 or DDR2 */
1360 time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1361 ((spdRawData[i] & 0x0f));
1362 leftOfPoint = time_tmp / 100;
1363 rightOfPoint = time_tmp % 100;
1365 mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
1366 leftOfPoint, rightOfPoint);
1368 /*----------------------------------------------------------------------------*/
1370 case 34: /* Data Input Setup Time */
1371 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1373 rightOfPoint = (spdRawData[i] & 0x0f);
1374 leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1380 else /* DDR1 or DDR2 */
1382 time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1383 ((spdRawData[i] & 0x0f));
1384 leftOfPoint = time_tmp / 100;
1385 rightOfPoint = time_tmp % 100;
1387 mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
1388 leftOfPoint, rightOfPoint);
1390 /*----------------------------------------------------------------------------*/
1392 case 35: /* Data Input Hold Time */
1393 if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1395 rightOfPoint = (spdRawData[i] & 0x0f);
1396 leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1402 else /* DDR1 or DDR2 */
1404 time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1405 ((spdRawData[i] & 0x0f));
1406 leftOfPoint = time_tmp / 100;
1407 rightOfPoint = time_tmp % 100;
1409 mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
1410 leftOfPoint, rightOfPoint);
1412 /*----------------------------------------------------------------------------*/
1414 case 36: /* Relevant for DDR2 only: Write Recovery Time */
1415 leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
1416 rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
1417 mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
1418 leftOfPoint, rightOfPoint);
1420 /*----------------------------------------------------------------------------*/
1427 * translate ns.ns/10 coding of SPD timing values
1428 * into ps unit values
1430 /*******************************************************************************
1431 * cas2ps - Translate x.y ns parameter to pico-seconds values
1434 * This function translates x.y nano seconds to its value in pico seconds.
1435 * For example 3.75ns will return 3750.
1438 * spd_byte - DIMM SPD byte.
1444 * value in pico seconds.
1446 *******************************************************************************/
1447 static MV_U32 cas2ps(MV_U8 spd_byte)
1451 /* isolate upper nibble */
1452 ns = (spd_byte >> 4) & 0x0F;
1453 /* isolate lower nibble */
1454 ns10 = (spd_byte & 0x0F);
1459 else if( ns10 == 10 )
1461 else if( ns10 == 11 )
1463 else if( ns10 == 12 )
1465 else if( ns10 == 13 )
1469 mvOsOutput("cas2ps Err. unsupported cycle time.\n");
1472 return (ns*1000 + ns10*10);