Root/target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c

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#include "ddr1_2/mvDram.h"
66#include "boardEnv/mvBoardEnvLib.h"
67
68#undef MV_DEBUG
69#ifdef MV_DEBUG
70#define DB(x) x
71#else
72#define DB(x)
73#endif
74
75static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
76                                            MV_DRAM_BANK_INFO *pBankInfo);
77static MV_U32 cas2ps(MV_U8 spd_byte);
78/*******************************************************************************
79* mvDramBankGet - Get the DRAM bank paramters.
80*
81* DESCRIPTION:
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.
87*
88* INPUT:
89* bankNum - Board DRAM bank number.
90*
91* OUTPUT:
92* pBankInfo - DRAM bank information struct.
93*
94* RETURN:
95* MV_FAIL - Bank parameters could not be read.
96*
97*******************************************************************************/
98MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
99{
100    MV_DIMM_INFO dimmInfo;
101
102    DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
103    /* zero pBankInfo structure */
104    memset(pBankInfo, 0, sizeof(*pBankInfo));
105
106    if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
107    {
108        DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
109        return MV_BAD_PARAM;
110    }
111    if( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
112    {
113    DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
114    return MV_FAIL;
115    }
116    if((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
117    {
118    DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
119    return MV_FAIL;
120    }
121
122    /* convert Dimm info to Bank info */
123    cpyDimm2BankInfo(&dimmInfo, pBankInfo);
124    
125    return MV_OK;
126}
127
128/*******************************************************************************
129* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
130*
131* DESCRIPTION:
132* Convert a Dimm info struct into a bank info struct.
133*
134* INPUT:
135* pDimmInfo - DIMM information structure.
136*
137* OUTPUT:
138* pBankInfo - DRAM bank information struct.
139*
140* RETURN:
141* None.
142*
143*******************************************************************************/
144static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
145                                                MV_DRAM_BANK_INFO *pBankInfo)
146{
147    pBankInfo->memoryType = pDimmInfo->memoryType;
148
149    /* DIMM dimensions */
150    pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
151    pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
152    pBankInfo->dataWidth = pDimmInfo->dataWidth;
153    pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
154    pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
155    pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
156    pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
157    pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
158    pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
159 
160    /* DIMM timing parameters */
161    pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
162    pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
163                                    pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
164    pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
165                                    pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
166
167    pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
168    pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
169    pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
170    pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
171    pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
172    pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
173    pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
174    pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
175               
176    /* Parameters calculated from the extracted DIMM information */
177    pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
178    pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
179    pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
180                                 pDimmInfo->numOfModuleBanks;
181 
182    /* DIMM attributes (MV_TRUE for yes) */
183
184    if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
185        (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
186    {
187        if (pDimmInfo->dimmAttributes & BIT1)
188            pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
189        else
190            pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
191    }
192    else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
193    {
194        if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
195            pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
196        else
197            pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
198    }
199
200    return;
201}
202
203/*******************************************************************************
204* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
205*
206* DESCRIPTION:
207* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
208*
209* INPUT:
210* None.
211*
212* OUTPUT:
213* None.
214*
215* RETURN:
216* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
217*
218*******************************************************************************/
219MV_STATUS dimmSpdCpy(MV_VOID)
220{
221    MV_U32 i;
222    MV_U32 spdChecksum;
223     
224    MV_TWSI_SLAVE twsiSlave;
225    MV_U8 data[SPD_SIZE];
226
227    /* zero dimmInfo structure */
228    memset(data, 0, SPD_SIZE);
229
230    /* read the dimm eeprom */
231    DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
232    twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
233    twsiSlave.slaveAddr.type = ADDR7_BIT;
234    twsiSlave.validOffset = MV_TRUE;
235    twsiSlave.offset = 0;
236    twsiSlave.moreThen256 = MV_FALSE;
237
238    if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
239            &twsiSlave, data, SPD_SIZE) )
240    {
241        DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
242        return MV_FAIL;
243    }
244    DB(puts("DRAM: Reading dimm info succeded.\n"));
245    
246    /* calculate SPD checksum */
247    spdChecksum = 0;
248    
249    for(i = 0 ; i <= 62 ; i++)
250    {
251        spdChecksum += data[i];
252    }
253    
254    if ((spdChecksum & 0xff) != data[63])
255    {
256        DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
257                            (MV_U32)(spdChecksum & 0xff), data[63]));
258    }
259    else
260    {
261        DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
262    }
263
264    /* copy the SPD content 1:1 into the DIMM 1 SPD */
265    twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
266    twsiSlave.slaveAddr.type = ADDR7_BIT;
267    twsiSlave.validOffset = MV_TRUE;
268    twsiSlave.offset = 0;
269    twsiSlave.moreThen256 = MV_FALSE;
270
271    for(i = 0 ; i < SPD_SIZE ; i++)
272    {
273    twsiSlave.offset = i;
274    if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL,
275                    &twsiSlave, &data[i], 1) )
276    {
277        mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
278        return MV_FAIL;
279    }
280    mvOsDelay(5);
281    }
282    
283    DB(puts("DRAM: Reading dimm info succeded.\n"));
284    return MV_OK;
285}
286
287/*******************************************************************************
288* dimmSpdGet - Get the SPD parameters.
289*
290* DESCRIPTION:
291* Read the DIMM SPD parameters into given struct parameter.
292*
293* INPUT:
294* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
295*
296* OUTPUT:
297* pDimmInfo - DIMM information structure.
298*
299* RETURN:
300* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
301*
302*******************************************************************************/
303MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
304{
305    MV_U32 i;
306    MV_U32 density = 1;
307    MV_U32 spdChecksum;
308     
309    MV_TWSI_SLAVE twsiSlave;
310    MV_U8 data[SPD_SIZE];
311
312    if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
313    {
314        DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
315        return MV_BAD_PARAM;
316    }
317
318    /* zero dimmInfo structure */
319    memset(data, 0, SPD_SIZE);
320
321    /* read the dimm eeprom */
322    DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
323    twsiSlave.slaveAddr.address = (dimmNum == 0) ?
324                            MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
325    twsiSlave.slaveAddr.type = ADDR7_BIT;
326    twsiSlave.validOffset = MV_TRUE;
327    twsiSlave.offset = 0;
328    twsiSlave.moreThen256 = MV_FALSE;
329
330    if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
331            &twsiSlave, data, SPD_SIZE) )
332    {
333        DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
334        return MV_FAIL;
335    }
336    DB(puts("DRAM: Reading dimm info succeded.\n"));
337    
338    /* calculate SPD checksum */
339    spdChecksum = 0;
340    
341        for(i = 0 ; i <= 62 ; i++)
342        {
343        spdChecksum += data[i];
344    }
345    
346    if ((spdChecksum & 0xff) != data[63])
347    {
348        DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
349                            (MV_U32)(spdChecksum & 0xff), data[63]));
350    }
351    else
352    {
353        DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
354    }
355
356    /* copy the SPD content 1:1 into the dimmInfo structure*/
357    for(i = 0 ; i < SPD_SIZE ; i++)
358    {
359        pDimmInfo->spdRawData[i] = data[i];
360        DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
361    }
362
363    DB(mvOsPrintf("DRAM SPD Information:\n"));
364
365    /* Memory type (DDR / SDRAM) */
366    switch (data[DIMM_MEM_TYPE])
367    {
368        case (DIMM_MEM_TYPE_SDRAM):
369            pDimmInfo->memoryType = MEM_TYPE_SDRAM;
370            DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
371            break;
372        case (DIMM_MEM_TYPE_DDR1):
373            pDimmInfo->memoryType = MEM_TYPE_DDR1;
374            DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
375            break;
376        case (DIMM_MEM_TYPE_DDR2):
377            pDimmInfo->memoryType = MEM_TYPE_DDR2;
378            DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
379            break;
380        default:
381            mvOsPrintf("ERROR: Undefined memory type!\n");
382            return MV_ERROR;
383    }
384
385    
386    /* Number Of Row Addresses */
387    pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
388    DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
389        
390    /* Number Of Column Addresses */
391    pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
392    DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
393        
394    /* Number Of Module Banks */
395    pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
396    DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
397                                                  pDimmInfo->numOfModuleBanks));
398        
399    /* Number of module banks encoded differently for DDR2 */
400    if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
401        pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
402
403    /* Data Width */
404    pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
405    DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
406        
407    /* Minimum Cycle Time At Max CasLatancy */
408    pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
409
410    /* Error Check Type */
411    pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
412    DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
413                                                    pDimmInfo->errorCheckType));
414
415    /* Refresh Interval */
416    pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
417    DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
418                                                   pDimmInfo->refreshInterval));
419    
420    /* Sdram Width */
421    pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
422    DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
423        
424    /* Error Check Data Width */
425    pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
426    DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
427                                               pDimmInfo->errorCheckDataWidth));
428    
429    /* Burst Length Supported */
430    /* SDRAM/DDR1:
431                    *******-******-******-******-******-******-******-*******
432                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
433                    *******-******-******-******-******-******-******-*******
434    burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
435                    *********************************************************/
436    /* DDR2:
437                    *******-******-******-******-******-******-******-*******
438                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
439                    *******-******-******-******-******-******-******-*******
440    burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
441                    *********************************************************/
442
443    pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
444    DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
445                                              pDimmInfo->burstLengthSupported));
446    
447    /* Number Of Banks On Each Device */
448    pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
449    DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
450                                            pDimmInfo->numOfBanksOnEachDevice));
451    
452    /* Suported Cas Latencies */
453                   
454    /* SDRAM:
455            *******-******-******-******-******-******-******-*******
456            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
457            *******-******-******-******-******-******-******-*******
458    CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
459            ********************************************************/
460
461    /* DDR 1:
462            *******-******-******-******-******-******-******-*******
463            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
464            *******-******-******-******-******-******-******-*******
465    CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
466            *********************************************************/
467
468    /* DDR 2:
469            *******-******-******-******-******-******-******-*******
470            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
471            *******-******-******-******-******-******-******-*******
472    CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
473            *********************************************************/
474    
475    pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
476    DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
477                                              pDimmInfo->suportedCasLatencies));
478
479    /* For DDR2 only, get the DIMM type information */
480    if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
481    {
482        pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
483        DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
484                                                      pDimmInfo->dimmTypeInfo));
485    }
486
487    /* SDRAM Modules Attributes */
488    pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
489    DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
490                                                    pDimmInfo->dimmAttributes));
491    
492    /* Minimum Cycle Time At Max CasLatancy Minus 1*/
493    pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
494                                    cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
495
496    /* Minimum Cycle Time At Max CasLatancy Minus 2*/
497    pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
498                                    cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
499
500    pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
501    DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
502                                               pDimmInfo->minRowPrechargeTime));
503    pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
504    DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
505                                           pDimmInfo->minRowActiveToRowActive));
506    pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
507    DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
508                                                  pDimmInfo->minRasToCasDelay));
509    pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
510    DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
511                                                  pDimmInfo->minRasPulseWidth));
512        
513    /* DIMM Bank Density */
514    pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
515    DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
516                                                   pDimmInfo->dimmBankDensity));
517
518    /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
519    pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
520    DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
521                                              pDimmInfo->minWriteRecoveryTime));
522    
523    /* Only DDR2 includes Internal Write To Read Command Delay field. */
524    pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
525    DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
526                                            pDimmInfo->minWriteToReadCmdDelay));
527    
528    /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
529    pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
530    DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
531                                            pDimmInfo->minReadToPrechCmdDelay));
532    
533    /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
534    pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
535    DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
536                                             pDimmInfo->minRefreshToActiveCmd));
537                 
538    /* calculating the sdram density. Representing device density from */
539    /* bit 20 to allow representation of 4GB and above. */
540    /* For example, if density is 512Mbit 0x20000000, will be represent in */
541    /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
542    /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
543    density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
544    pDimmInfo->deviceDensity = density *
545                                pDimmInfo->numOfBanksOnEachDevice *
546                                pDimmInfo->sdramWidth;
547    DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
548    
549    /* Number of devices includeing Error correction */
550    pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
551                                  pDimmInfo->numOfModuleBanks;
552    DB(mvOsPrintf("DRAM numberOfDevices %d\n",
553                                                   pDimmInfo->numberOfDevices));
554
555    pDimmInfo->size = 0;
556
557    /* Note that pDimmInfo->size is in MB units */
558    if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
559    {
560        if (pDimmInfo->dimmBankDensity & BIT0)
561            pDimmInfo->size += 1024; /* Equal to 1GB */
562        else if (pDimmInfo->dimmBankDensity & BIT1)
563            pDimmInfo->size += 8; /* Equal to 8MB */
564        else if (pDimmInfo->dimmBankDensity & BIT2)
565            pDimmInfo->size += 16; /* Equal to 16MB */
566        else if (pDimmInfo->dimmBankDensity & BIT3)
567            pDimmInfo->size += 32; /* Equal to 32MB */
568        else if (pDimmInfo->dimmBankDensity & BIT4)
569            pDimmInfo->size += 64; /* Equal to 64MB */
570        else if (pDimmInfo->dimmBankDensity & BIT5)
571            pDimmInfo->size += 128; /* Equal to 128MB */
572        else if (pDimmInfo->dimmBankDensity & BIT6)
573            pDimmInfo->size += 256; /* Equal to 256MB */
574        else if (pDimmInfo->dimmBankDensity & BIT7)
575            pDimmInfo->size += 512; /* Equal to 512MB */
576    }
577    else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
578    {
579        if (pDimmInfo->dimmBankDensity & BIT0)
580            pDimmInfo->size += 1024; /* Equal to 1GB */
581        else if (pDimmInfo->dimmBankDensity & BIT1)
582            pDimmInfo->size += 2048; /* Equal to 2GB */
583        else if (pDimmInfo->dimmBankDensity & BIT2)
584            pDimmInfo->size += 16; /* Equal to 16MB */
585        else if (pDimmInfo->dimmBankDensity & BIT3)
586            pDimmInfo->size += 32; /* Equal to 32MB */
587        else if (pDimmInfo->dimmBankDensity & BIT4)
588            pDimmInfo->size += 64; /* Equal to 64MB */
589        else if (pDimmInfo->dimmBankDensity & BIT5)
590            pDimmInfo->size += 128; /* Equal to 128MB */
591        else if (pDimmInfo->dimmBankDensity & BIT6)
592            pDimmInfo->size += 256; /* Equal to 256MB */
593        else if (pDimmInfo->dimmBankDensity & BIT7)
594            pDimmInfo->size += 512; /* Equal to 512MB */
595    }
596    else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
597    {
598        if (pDimmInfo->dimmBankDensity & BIT0)
599            pDimmInfo->size += 1024; /* Equal to 1GB */
600        else if (pDimmInfo->dimmBankDensity & BIT1)
601            pDimmInfo->size += 2048; /* Equal to 2GB */
602        else if (pDimmInfo->dimmBankDensity & BIT2)
603            pDimmInfo->size += 4096; /* Equal to 4GB */
604        else if (pDimmInfo->dimmBankDensity & BIT3)
605            pDimmInfo->size += 8192; /* Equal to 8GB */
606        else if (pDimmInfo->dimmBankDensity & BIT4)
607            pDimmInfo->size += 16384; /* Equal to 16GB */
608        else if (pDimmInfo->dimmBankDensity & BIT5)
609            pDimmInfo->size += 128; /* Equal to 128MB */
610        else if (pDimmInfo->dimmBankDensity & BIT6)
611            pDimmInfo->size += 256; /* Equal to 256MB */
612        else if (pDimmInfo->dimmBankDensity & BIT7)
613            pDimmInfo->size += 512; /* Equal to 512MB */
614    }
615    
616    pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
617
618    DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
619
620    return MV_OK;
621}
622
623/*******************************************************************************
624* dimmSpdPrint - Print the SPD parameters.
625*
626* DESCRIPTION:
627* Print the Dimm SPD parameters.
628*
629* INPUT:
630* pDimmInfo - DIMM information structure.
631*
632* OUTPUT:
633* None.
634*
635* RETURN:
636* None.
637*
638*******************************************************************************/
639MV_VOID dimmSpdPrint(MV_U32 dimmNum)
640{
641    MV_DIMM_INFO dimmInfo;
642    MV_U32 i, temp = 0;
643    MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
644    MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
645    MV_U32 busClkPs;
646    MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
647            temp_buf[40], *spdRawData;
648
649    busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
650
651    spdRawData = dimmInfo.spdRawData;
652    
653    if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
654    {
655        mvOsOutput("ERROR: Could not read SPD information!\n");
656        return;
657    }
658
659    /* find Manufactura of Dimm Module */
660    mvOsOutput("\nManufacturer's JEDEC ID Code: ");
661    for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
662    {
663        mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
664    }
665    mvOsOutput("\n");
666
667    /* Manufacturer's Specific Data */
668    for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
669    {
670        temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
671    }
672    mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
673
674    /* Module Part Number */
675    for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
676    {
677        temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
678    }
679    mvOsOutput("Module Part Number: %s\n", temp_buf);
680
681    /* Module Serial Number */
682    for(i = 0; i < sizeof(MV_U32); i++)
683    {
684        temp |= spdRawData[95+i] << 8*i;
685    }
686    mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
687                                    (long)temp);
688
689    /* find Manufac-Data of Dimm Module */
690    mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
691                        ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
692                        ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
693    /* find modul_revision of Dimm Module */
694    mvOsOutput("Module Revision: %d.%d\n",
695                                                spdRawData[91], spdRawData[92]);
696
697    /* find manufac_place of Dimm Module */
698    mvOsOutput("manufac_place: %d\n", spdRawData[72]);
699    
700    /* go over the first 35 I2C data bytes */
701    for(i = 2 ; i <= 35 ; i++)
702       switch(i)
703        {
704            case 2: /* Memory type (DDR1/2 / SDRAM) */
705                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
706                    mvOsOutput("Dram Type is: SDRAM\n");
707                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
708                    mvOsOutput("Dram Type is: SDRAM DDR1\n");
709                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
710                    mvOsOutput("Dram Type is: SDRAM DDR2\n");
711                else
712                    mvOsOutput("Dram Type unknown\n");
713                break;
714/*----------------------------------------------------------------------------*/
715
716            case 3: /* Number Of Row Addresses */
717                mvOsOutput("Module Number of row addresses: %d\n",
718                                                        dimmInfo.numOfRowAddr);
719                break;
720/*----------------------------------------------------------------------------*/
721    
722            case 4: /* Number Of Column Addresses */
723                mvOsOutput("Module Number of col addresses: %d\n",
724                                                        dimmInfo.numOfColAddr);
725                break;
726/*----------------------------------------------------------------------------*/
727    
728            case 5: /* Number Of Module Banks */
729                mvOsOutput("Number of Banks on Mod.: %d\n",
730                                                    dimmInfo.numOfModuleBanks);
731                break;
732/*----------------------------------------------------------------------------*/
733    
734            case 6: /* Data Width */
735                mvOsOutput("Module Data Width: %d bit\n",
736                                                           dimmInfo.dataWidth);
737                break;
738/*----------------------------------------------------------------------------*/
739    
740            case 8: /* Voltage Interface */
741                switch(spdRawData[i])
742                {
743                    case 0x0:
744                        mvOsOutput("Module is TTL_5V_TOLERANT\n");
745                        break;
746                    case 0x1:
747                        mvOsOutput("Module is LVTTL\n");
748                        break;
749                    case 0x2:
750                        mvOsOutput("Module is HSTL_1_5V\n");
751                        break;
752                    case 0x3:
753                        mvOsOutput("Module is SSTL_3_3V\n");
754                        break;
755                    case 0x4:
756                        mvOsOutput("Module is SSTL_2_5V\n");
757                        break;
758                    case 0x5:
759                        if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
760                        {
761                            mvOsOutput("Module is SSTL_1_8V\n");
762                            break;
763                        }
764                    default:
765                        mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
766                        break;
767                }
768                break;
769/*----------------------------------------------------------------------------*/
770    
771            case 9: /* Minimum Cycle Time At Max CasLatancy */
772                leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
773                rightOfPoint = (spdRawData[i] & 0x0f) * 10;
774                
775                /* DDR2 addition of right of point */
776                if ((spdRawData[i] & 0x0f) == 0xA)
777                {
778                    rightOfPoint = 25;
779                }
780                if ((spdRawData[i] & 0x0f) == 0xB)
781                {
782                    rightOfPoint = 33;
783                }
784                if ((spdRawData[i] & 0x0f) == 0xC)
785                {
786                    rightOfPoint = 66;
787                }
788                if ((spdRawData[i] & 0x0f) == 0xD)
789                {
790                    rightOfPoint = 75;
791                }
792                mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
793                                                    leftOfPoint, rightOfPoint);
794                break;
795/*----------------------------------------------------------------------------*/
796    
797            case 10: /* Clock To Data Out */
798                div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
799                time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
800                                                      ((spdRawData[i] & 0x0f));
801                leftOfPoint = time_tmp / div;
802                rightOfPoint = time_tmp % div;
803                mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
804                                                    leftOfPoint, rightOfPoint);
805                break;
806/*----------------------------------------------------------------------------*/
807    
808            case 11: /* Error Check Type */
809                mvOsOutput("Error Check Type (0=NONE): %d\n",
810                                                      dimmInfo.errorCheckType);
811                break;
812/*----------------------------------------------------------------------------*/
813
814            case 12: /* Refresh Interval */
815                mvOsOutput("Refresh Rate: %x\n",
816                                                     dimmInfo.refreshInterval);
817                break;
818/*----------------------------------------------------------------------------*/
819    
820            case 13: /* Sdram Width */
821                mvOsOutput("Sdram Width: %d bits\n",
822                                                          dimmInfo.sdramWidth);
823                break;
824/*----------------------------------------------------------------------------*/
825    
826            case 14: /* Error Check Data Width */
827                mvOsOutput("Error Check Data Width: %d bits\n",
828                                                 dimmInfo.errorCheckDataWidth);
829                break;
830/*----------------------------------------------------------------------------*/
831
832           case 15: /* Minimum Clock Delay is unsupported */
833                if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
834                    (dimmInfo.memoryType == MEM_TYPE_DDR1))
835                {
836                    mvOsOutput("Minimum Clk Delay back to back: %d\n",
837                                                                spdRawData[i]);
838                }
839                break;
840/*----------------------------------------------------------------------------*/
841    
842            case 16: /* Burst Length Supported */
843    /* SDRAM/DDR1:
844                    *******-******-******-******-******-******-******-*******
845                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
846                    *******-******-******-******-******-******-******-*******
847    burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
848                    *********************************************************/
849    /* DDR2:
850                    *******-******-******-******-******-******-******-*******
851                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
852                    *******-******-******-******-******-******-******-*******
853    burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
854                    *********************************************************/
855                mvOsOutput("Burst Length Supported: ");
856                if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
857                    (dimmInfo.memoryType == MEM_TYPE_DDR1))
858                {
859                    if (dimmInfo.burstLengthSupported & BIT0)
860                        mvOsOutput("1, ");
861                    if (dimmInfo.burstLengthSupported & BIT1)
862                        mvOsOutput("2, ");
863                }
864                if (dimmInfo.burstLengthSupported & BIT2)
865                    mvOsOutput("4, ");
866                if (dimmInfo.burstLengthSupported & BIT3)
867                    mvOsOutput("8, ");
868                
869                mvOsOutput(" Bit \n");
870                break;
871/*----------------------------------------------------------------------------*/
872    
873            case 17: /* Number Of Banks On Each Device */
874                mvOsOutput("Number Of Banks On Each Chip: %d\n",
875                                              dimmInfo.numOfBanksOnEachDevice);
876                break;
877/*----------------------------------------------------------------------------*/
878    
879            case 18: /* Suported Cas Latencies */
880                   
881            /* SDRAM:
882                    *******-******-******-******-******-******-******-*******
883                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
884                    *******-******-******-******-******-******-******-*******
885            CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
886                    ********************************************************/
887
888            /* DDR 1:
889                    *******-******-******-******-******-******-******-*******
890                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
891                    *******-******-******-******-******-******-******-*******
892            CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
893                    *********************************************************/
894
895            /* DDR 2:
896                    *******-******-******-******-******-******-******-*******
897                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
898                    *******-******-******-******-******-******-******-*******
899            CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
900                    *********************************************************/
901
902                mvOsOutput("Suported Cas Latencies: (CL) ");
903                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
904                {
905                    for (k = 0; k <=7; k++)
906                    {
907                        if (dimmInfo.suportedCasLatencies & (1 << k))
908                            mvOsOutput("%d, ", k+1);
909                    }
910                }
911                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
912                {
913                    if (dimmInfo.suportedCasLatencies & BIT0)
914                        mvOsOutput("1, ");
915                    if (dimmInfo.suportedCasLatencies & BIT1)
916                        mvOsOutput("1.5, ");
917                    if (dimmInfo.suportedCasLatencies & BIT2)
918                        mvOsOutput("2, ");
919                    if (dimmInfo.suportedCasLatencies & BIT3)
920                        mvOsOutput("2.5, ");
921                    if (dimmInfo.suportedCasLatencies & BIT4)
922                        mvOsOutput("3, ");
923                    if (dimmInfo.suportedCasLatencies & BIT5)
924                        mvOsOutput("3.5, ");
925                }
926                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
927                {
928                    if (dimmInfo.suportedCasLatencies & BIT2)
929                        mvOsOutput("2, ");
930                    if (dimmInfo.suportedCasLatencies & BIT3)
931                        mvOsOutput("3, ");
932                    if (dimmInfo.suportedCasLatencies & BIT4)
933                        mvOsOutput("4, ");
934                    if (dimmInfo.suportedCasLatencies & BIT5)
935                        mvOsOutput("5, ");
936                }
937                else
938                    mvOsOutput("?.?, ");
939                mvOsOutput("\n");
940                break;
941/*----------------------------------------------------------------------------*/
942    
943            case 20: /* DDR2 DIMM type info */
944                if (dimmInfo.memoryType == MEM_TYPE_DDR2)
945                {
946                    if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
947                        mvOsOutput("Registered DIMM (RDIMM)\n");
948                    else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
949                        mvOsOutput("Unbuffered DIMM (UDIMM)\n");
950                    else
951                        mvOsOutput("Unknown DIMM type.\n");
952                }
953
954                break;
955/*----------------------------------------------------------------------------*/
956   
957            case 21: /* SDRAM Modules Attributes */
958                mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
959                
960                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
961                {
962                    if (dimmInfo.dimmAttributes & BIT0)
963                        mvOsOutput(" Buffered Addr/Control Input: Yes\n");
964                    else
965                        mvOsOutput(" Buffered Addr/Control Input: No\n");
966
967                    if (dimmInfo.dimmAttributes & BIT1)
968                        mvOsOutput(" Registered Addr/Control Input: Yes\n");
969                    else
970                        mvOsOutput(" Registered Addr/Control Input: No\n");
971   
972                    if (dimmInfo.dimmAttributes & BIT2)
973                        mvOsOutput(" On-Card PLL (clock): Yes \n");
974                    else
975                        mvOsOutput(" On-Card PLL (clock): No \n");
976
977                    if (dimmInfo.dimmAttributes & BIT3)
978                        mvOsOutput(" Bufferd DQMB Input: Yes \n");
979                    else
980                        mvOsOutput(" Bufferd DQMB Inputs: No \n");
981   
982                    if (dimmInfo.dimmAttributes & BIT4)
983                        mvOsOutput(" Registered DQMB Inputs: Yes \n");
984                    else
985                        mvOsOutput(" Registered DQMB Inputs: No \n");
986 
987                    if (dimmInfo.dimmAttributes & BIT5)
988                        mvOsOutput(" Differential Clock Input: Yes \n");
989                    else
990                        mvOsOutput(" Differential Clock Input: No \n");
991   
992                    if (dimmInfo.dimmAttributes & BIT6)
993                        mvOsOutput(" redundant Row Addressing: Yes \n");
994                    else
995                        mvOsOutput(" redundant Row Addressing: No \n");
996                }
997                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
998                {
999                    if (dimmInfo.dimmAttributes & BIT0)
1000                        mvOsOutput(" Buffered Addr/Control Input: Yes\n");
1001                    else
1002                        mvOsOutput(" Buffered Addr/Control Input: No\n");
1003   
1004                    if (dimmInfo.dimmAttributes & BIT1)
1005                        mvOsOutput(" Registered Addr/Control Input: Yes\n");
1006                    else
1007                        mvOsOutput(" Registered Addr/Control Input: No\n");
1008   
1009                    if (dimmInfo.dimmAttributes & BIT2)
1010                        mvOsOutput(" On-Card PLL (clock): Yes \n");
1011                    else
1012                        mvOsOutput(" On-Card PLL (clock): No \n");
1013            
1014                    if (dimmInfo.dimmAttributes & BIT3)
1015                        mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
1016                    else
1017                        mvOsOutput(" FET Switch On-Card Enabled: No \n");
1018                    
1019                    if (dimmInfo.dimmAttributes & BIT4)
1020                        mvOsOutput(" FET Switch External Enabled: Yes \n");
1021                    else
1022                        mvOsOutput(" FET Switch External Enabled: No \n");
1023
1024                    if (dimmInfo.dimmAttributes & BIT5)
1025                        mvOsOutput(" Differential Clock Input: Yes \n");
1026                    else
1027                        mvOsOutput(" Differential Clock Input: No \n");
1028                }
1029                else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
1030                {
1031                    mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
1032                                        (dimmInfo.dimmAttributes & 0x3) + 1);
1033            
1034                    mvOsOutput(" Number of PLLs on the DIMM: %d\n",
1035                                      ((dimmInfo.dimmAttributes) >> 2) & 0x3);
1036               
1037                    if (dimmInfo.dimmAttributes & BIT4)
1038                        mvOsOutput(" FET Switch External Enabled: Yes \n");
1039                    else
1040                        mvOsOutput(" FET Switch External Enabled: No \n");
1041
1042                    if (dimmInfo.dimmAttributes & BIT6)
1043                        mvOsOutput(" Analysis probe installed: Yes \n");
1044                    else
1045                        mvOsOutput(" Analysis probe installed: No \n");
1046                }
1047                
1048                break;
1049/*----------------------------------------------------------------------------*/
1050
1051            case 22: /* Suported AutoPreCharge */
1052                mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
1053                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1054                {
1055                    if ( spdRawData[i] & BIT0 )
1056                        mvOsOutput(" Early Ras Precharge: Yes \n");
1057                    else
1058                        mvOsOutput(" Early Ras Precharge: No \n");
1059                                                        
1060                    if ( spdRawData[i] & BIT1 )
1061                        mvOsOutput(" AutoPreCharge: Yes \n");
1062                    else
1063                        mvOsOutput(" AutoPreCharge: No \n");
1064                                                            
1065                    if ( spdRawData[i] & BIT2 )
1066                        mvOsOutput(" Precharge All: Yes \n");
1067                    else
1068                        mvOsOutput(" Precharge All: No \n");
1069                                                        
1070                    if ( spdRawData[i] & BIT3 )
1071                        mvOsOutput(" Write 1/ReadBurst: Yes \n");
1072                    else
1073                        mvOsOutput(" Write 1/ReadBurst: No \n");
1074                                                        
1075                    if ( spdRawData[i] & BIT4 )
1076                        mvOsOutput(" lower VCC tolerance: 5%%\n");
1077                    else
1078                        mvOsOutput(" lower VCC tolerance: 10%%\n");
1079                                                        
1080                    if ( spdRawData[i] & BIT5 )
1081                        mvOsOutput(" upper VCC tolerance: 5%%\n");
1082                    else
1083                        mvOsOutput(" upper VCC tolerance: 10%%\n");
1084                }
1085                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
1086                {
1087                    if ( spdRawData[i] & BIT0 )
1088                        mvOsOutput(" Supports Weak Driver: Yes \n");
1089                    else
1090                        mvOsOutput(" Supports Weak Driver: No \n");
1091
1092                    if ( !(spdRawData[i] & BIT4) )
1093                        mvOsOutput(" lower VCC tolerance: 0.2V\n");
1094   
1095                    if ( !(spdRawData[i] & BIT5) )
1096                        mvOsOutput(" upper VCC tolerance: 0.2V\n");
1097
1098                    if ( spdRawData[i] & BIT6 )
1099                        mvOsOutput(" Concurrent Auto Preharge: Yes \n");
1100                    else
1101                        mvOsOutput(" Concurrent Auto Preharge: No \n");
1102
1103                    if ( spdRawData[i] & BIT7 )
1104                        mvOsOutput(" Supports Fast AP: Yes \n");
1105                    else
1106                        mvOsOutput(" Supports Fast AP: No \n");
1107                }
1108                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
1109                {
1110                    if ( spdRawData[i] & BIT0 )
1111                        mvOsOutput(" Supports Weak Driver: Yes \n");
1112                    else
1113                        mvOsOutput(" Supports Weak Driver: No \n");
1114                }
1115                break;
1116/*----------------------------------------------------------------------------*/
1117    
1118            case 23:
1119            /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
1120                leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1121                rightOfPoint = (spdRawData[i] & 0x0f) * 10;
1122                
1123                /* DDR2 addition of right of point */
1124                if ((spdRawData[i] & 0x0f) == 0xA)
1125                {
1126                    rightOfPoint = 25;
1127                }
1128                if ((spdRawData[i] & 0x0f) == 0xB)
1129                {
1130                    rightOfPoint = 33;
1131                }
1132                if ((spdRawData[i] & 0x0f) == 0xC)
1133                {
1134                    rightOfPoint = 66;
1135                }
1136                if ((spdRawData[i] & 0x0f) == 0xD)
1137                {
1138                    rightOfPoint = 75;
1139                }
1140
1141                mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
1142                           "(0 = Not supported): %d.%d [ns]\n",
1143                           leftOfPoint, rightOfPoint );
1144                break;
1145/*----------------------------------------------------------------------------*/
1146    
1147            case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
1148                div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
1149                time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1150                                                    ((spdRawData[i] & 0x0f));
1151                leftOfPoint = time_tmp / div;
1152                rightOfPoint = time_tmp % div;
1153                mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
1154                                                    leftOfPoint, rightOfPoint);
1155                break;
1156/*----------------------------------------------------------------------------*/
1157    
1158            case 25:
1159            /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
1160                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1161                {
1162                    leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
1163                    rightOfPoint = (spdRawData[i] & 0x3) * 25;
1164                }
1165                else /* DDR1 or DDR2 */
1166                {
1167                    leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1168                    rightOfPoint = (spdRawData[i] & 0x0f) * 10;
1169                    
1170                    /* DDR2 addition of right of point */
1171                    if ((spdRawData[i] & 0x0f) == 0xA)
1172                    {
1173                        rightOfPoint = 25;
1174                    }
1175                    if ((spdRawData[i] & 0x0f) == 0xB)
1176                    {
1177                        rightOfPoint = 33;
1178                    }
1179                    if ((spdRawData[i] & 0x0f) == 0xC)
1180                    {
1181                        rightOfPoint = 66;
1182                    }
1183                    if ((spdRawData[i] & 0x0f) == 0xD)
1184                    {
1185                        rightOfPoint = 75;
1186                    }
1187                }
1188                mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
1189                           "(0 = Not supported): %d.%d [ns]\n",
1190                           leftOfPoint, rightOfPoint );
1191                break;
1192/*----------------------------------------------------------------------------*/
1193    
1194            case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
1195                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1196                {
1197                    leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
1198                    rightOfPoint = (spdRawData[i] & 0x3) * 25;
1199                }
1200                else /* DDR1 or DDR2 */
1201                {
1202                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1203                                                      ((spdRawData[i] & 0x0f));
1204                    leftOfPoint = 0;
1205                    rightOfPoint = time_tmp;
1206                }
1207                mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
1208                                                  leftOfPoint, rightOfPoint );
1209                break;
1210/*----------------------------------------------------------------------------*/
1211    
1212            case 27: /* Minimum Row Precharge Time */
1213                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
1214                maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1215                                                                    0xff : 0xfc;
1216                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1217                                                                    0x00 : 0x03;
1218                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
1219                rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
1220                temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
1221                trp_clocks = (temp + (busClkPs-1)) / busClkPs;
1222                mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
1223                           "in Clk cycles %d\n",
1224                           leftOfPoint, rightOfPoint, trp_clocks);
1225                break;
1226/*----------------------------------------------------------------------------*/
1227    
1228            case 28: /* Minimum Row Active to Row Active Time */
1229                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
1230                maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1231                                                                    0xff : 0xfc;
1232                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1233                                                                    0x00 : 0x03;
1234                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
1235                rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
1236                temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
1237                trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
1238                mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
1239                           "%d.%d = in Clk cycles %d\n",
1240                            leftOfPoint, rightOfPoint, trp_clocks);
1241                break;
1242/*----------------------------------------------------------------------------*/
1243    
1244            case 29: /* Minimum Ras-To-Cas Delay */
1245                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
1246                maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1247                                                                    0xff : 0xfc;
1248                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
1249                                                                    0x00 : 0x03;
1250                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
1251                rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
1252                temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
1253                trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
1254                mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
1255                           "in Clk cycles %d\n",
1256                           leftOfPoint, rightOfPoint, trp_clocks);
1257                break;
1258/*----------------------------------------------------------------------------*/
1259   
1260            case 30: /* Minimum Ras Pulse Width */
1261                tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
1262                mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
1263                           "in Clk cycles %d\n", spdRawData[i], tras_clocks);
1264                break;
1265/*----------------------------------------------------------------------------*/
1266    
1267            case 31: /* Module Bank Density */
1268                mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
1269
1270                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1271                {
1272                    if (dimmInfo.dimmBankDensity & BIT0)
1273                        mvOsOutput("1GB, ");
1274                    if (dimmInfo.dimmBankDensity & BIT1)
1275                        mvOsOutput("8MB, ");
1276                    if (dimmInfo.dimmBankDensity & BIT2)
1277                        mvOsOutput("16MB, ");
1278                    if (dimmInfo.dimmBankDensity & BIT3)
1279                        mvOsOutput("32MB, ");
1280                    if (dimmInfo.dimmBankDensity & BIT4)
1281                        mvOsOutput("64MB, ");
1282                    if (dimmInfo.dimmBankDensity & BIT5)
1283                        mvOsOutput("128MB, ");
1284                    if (dimmInfo.dimmBankDensity & BIT6)
1285                        mvOsOutput("256MB, ");
1286                    if (dimmInfo.dimmBankDensity & BIT7)
1287                        mvOsOutput("512MB, ");
1288                }
1289                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
1290                {
1291                    if (dimmInfo.dimmBankDensity & BIT0)
1292                        mvOsOutput("1GB, ");
1293                    if (dimmInfo.dimmBankDensity & BIT1)
1294                        mvOsOutput("2GB, ");
1295                    if (dimmInfo.dimmBankDensity & BIT2)
1296                        mvOsOutput("16MB, ");
1297                    if (dimmInfo.dimmBankDensity & BIT3)
1298                        mvOsOutput("32MB, ");
1299                    if (dimmInfo.dimmBankDensity & BIT4)
1300                        mvOsOutput("64MB, ");
1301                    if (dimmInfo.dimmBankDensity & BIT5)
1302                        mvOsOutput("128MB, ");
1303                    if (dimmInfo.dimmBankDensity & BIT6)
1304                        mvOsOutput("256MB, ");
1305                    if (dimmInfo.dimmBankDensity & BIT7)
1306                        mvOsOutput("512MB, ");
1307                }
1308                else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
1309                {
1310                    if (dimmInfo.dimmBankDensity & BIT0)
1311                        mvOsOutput("1GB, ");
1312                    if (dimmInfo.dimmBankDensity & BIT1)
1313                        mvOsOutput("2GB, ");
1314                    if (dimmInfo.dimmBankDensity & BIT2)
1315                        mvOsOutput("4GB, ");
1316                    if (dimmInfo.dimmBankDensity & BIT3)
1317                        mvOsOutput("8GB, ");
1318                    if (dimmInfo.dimmBankDensity & BIT4)
1319                        mvOsOutput("16GB, ");
1320                    if (dimmInfo.dimmBankDensity & BIT5)
1321                    mvOsOutput("128MB, ");
1322                        if (dimmInfo.dimmBankDensity & BIT6)
1323                    mvOsOutput("256MB, ");
1324                        if (dimmInfo.dimmBankDensity & BIT7)
1325                    mvOsOutput("512MB, ");
1326                }
1327                mvOsOutput("\n");
1328                break;
1329/*----------------------------------------------------------------------------*/
1330    
1331            case 32: /* Address And Command Setup Time (measured in ns/1000) */
1332                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1333                {
1334                    rightOfPoint = (spdRawData[i] & 0x0f);
1335                    leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1336                    if(leftOfPoint > 7)
1337                    {
1338                    leftOfPoint *= -1;
1339                    }
1340                }
1341                else /* DDR1 or DDR2 */
1342                {
1343                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1344                                                      ((spdRawData[i] & 0x0f));
1345                    leftOfPoint = time_tmp / 100;
1346                    rightOfPoint = time_tmp % 100;
1347                }
1348                mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
1349                                                     leftOfPoint, rightOfPoint);
1350                break;
1351/*----------------------------------------------------------------------------*/
1352    
1353            case 33: /* Address And Command Hold Time */
1354                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1355                {
1356                    rightOfPoint = (spdRawData[i] & 0x0f);
1357                    leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1358                    if(leftOfPoint > 7)
1359                    {
1360                    leftOfPoint *= -1;
1361                    }
1362                }
1363                else /* DDR1 or DDR2 */
1364                {
1365                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1366                                                      ((spdRawData[i] & 0x0f));
1367                    leftOfPoint = time_tmp / 100;
1368                    rightOfPoint = time_tmp % 100;
1369                }
1370                mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
1371                                                   leftOfPoint, rightOfPoint);
1372                break;
1373/*----------------------------------------------------------------------------*/
1374    
1375            case 34: /* Data Input Setup Time */
1376                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1377                {
1378                    rightOfPoint = (spdRawData[i] & 0x0f);
1379                    leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1380                    if(leftOfPoint > 7)
1381                    {
1382                        leftOfPoint *= -1;
1383                    }
1384                }
1385                else /* DDR1 or DDR2 */
1386                {
1387                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1388                                                      ((spdRawData[i] & 0x0f));
1389                    leftOfPoint = time_tmp / 100;
1390                    rightOfPoint = time_tmp % 100;
1391                }
1392                mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
1393                                                    leftOfPoint, rightOfPoint);
1394                break;
1395/*----------------------------------------------------------------------------*/
1396    
1397            case 35: /* Data Input Hold Time */
1398                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1399                {
1400                    rightOfPoint = (spdRawData[i] & 0x0f);
1401                    leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1402                    if(leftOfPoint > 7)
1403                    {
1404                        leftOfPoint *= -1;
1405                    }
1406                }
1407                else /* DDR1 or DDR2 */
1408                {
1409                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
1410                                                      ((spdRawData[i] & 0x0f));
1411                    leftOfPoint = time_tmp / 100;
1412                    rightOfPoint = time_tmp % 100;
1413                }
1414                mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
1415                                                    leftOfPoint, rightOfPoint);
1416                break;
1417/*----------------------------------------------------------------------------*/
1418    
1419            case 36: /* Relevant for DDR2 only: Write Recovery Time */
1420                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
1421                rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
1422                mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
1423                                                    leftOfPoint, rightOfPoint);
1424                break;
1425/*----------------------------------------------------------------------------*/
1426        }
1427    
1428}
1429
1430
1431/*
1432 * translate ns.ns/10 coding of SPD timing values
1433 * into ps unit values
1434 */
1435/*******************************************************************************
1436* cas2ps - Translate x.y ns parameter to pico-seconds values
1437*
1438* DESCRIPTION:
1439* This function translates x.y nano seconds to its value in pico seconds.
1440* For example 3.75ns will return 3750.
1441*
1442* INPUT:
1443* spd_byte - DIMM SPD byte.
1444*
1445* OUTPUT:
1446* None.
1447*
1448* RETURN:
1449* value in pico seconds.
1450*
1451*******************************************************************************/
1452static MV_U32 cas2ps(MV_U8 spd_byte)
1453{
1454    MV_U32 ns, ns10;
1455    
1456    /* isolate upper nibble */
1457    ns = (spd_byte >> 4) & 0x0F;
1458    /* isolate lower nibble */
1459    ns10 = (spd_byte & 0x0F);
1460    
1461    if( ns10 < 10 ) {
1462        ns10 *= 10;
1463    }
1464    else if( ns10 == 10 )
1465        ns10 = 25;
1466    else if( ns10 == 11 )
1467        ns10 = 33;
1468    else if( ns10 == 12 )
1469        ns10 = 66;
1470    else if( ns10 == 13 )
1471        ns10 = 75;
1472    else
1473    {
1474        mvOsOutput("cas2ps Err. unsupported cycle time.\n");
1475    }
1476    
1477    return (ns*1000 + ns10*10);
1478}
1479
1480

Archive Download this file



interactive