source: trunk/target/linux/generic-2.6/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c @ 21356

Last change on this file since 21356 was 21356, checked in by jow, 7 years ago

[generic-2.6] update OCF framework to version 20100325

File size: 63.9 KB
Line 
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 "ddr2/spd/mvSpd.h"
66#include "boardEnv/mvBoardEnvLib.h"
67
68/* #define 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
105    if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
106    {
107        DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n")); 
108        return MV_BAD_PARAM;
109    }
110    memset(pBankInfo, 0, sizeof(*pBankInfo));
111
112        if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
113        {
114                DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
115                return MV_FAIL;
116        }
117        if ((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
118        {
119                DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
120                return MV_FAIL;
121        }
122        /* convert Dimm info to Bank info */
123    cpyDimm2BankInfo(&dimmInfo, pBankInfo);
124    return MV_OK;
125}
126
127/*******************************************************************************
128* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
129*
130* DESCRIPTION:
131*       Convert a Dimm info struct into a bank info struct.
132*
133* INPUT:
134*       pDimmInfo - DIMM information structure.
135*
136* OUTPUT:
137*       pBankInfo  - DRAM bank information struct.
138*
139* RETURN:
140*       None.
141*
142*******************************************************************************/
143static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo, 
144                                                MV_DRAM_BANK_INFO *pBankInfo)
145{
146    pBankInfo->memoryType = pDimmInfo->memoryType;       
147
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;
158 
159    /* DIMM timing parameters */
160    pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
161    pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps = 
162                                    pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
163    pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps = 
164                                    pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
165
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;
174               
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;
180 
181    /* DIMM attributes (MV_TRUE for yes) */
182
183    if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
184        (pDimmInfo->memoryType == MEM_TYPE_DDR1)   )
185    {   
186        if (pDimmInfo->dimmAttributes & BIT1)
187            pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
188        else
189            pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
190    }
191    else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
192    {
193        if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
194            pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
195        else
196            pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
197    }
198
199    return;
200}
201/*******************************************************************************
202* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
203*
204* DESCRIPTION:
205*       Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
206*
207* INPUT:
208*       None.
209*
210* OUTPUT:
211*       None.
212*
213* RETURN:
214*       MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
215*
216*******************************************************************************/
217MV_STATUS dimmSpdCpy(MV_VOID)
218{
219    MV_U32 i;
220    MV_U32 spdChecksum;
221     
222    MV_TWSI_SLAVE twsiSlave;
223    MV_U8 data[SPD_SIZE];
224
225    /* zero dimmInfo structure */
226    memset(data, 0, SPD_SIZE);
227
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;
235
236    if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
237    {
238        DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
239        return MV_FAIL;
240    }
241    DB(puts("DRAM: Reading dimm info succeded.\n"));
242   
243    /* calculate SPD checksum */
244    spdChecksum = 0;
245   
246    for(i = 0 ; i <= 62 ; i++)
247    {
248        spdChecksum += data[i];
249    }
250   
251    if ((spdChecksum & 0xff) != data[63])
252    {
253        DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
254                            (MV_U32)(spdChecksum & 0xff), data[63]));
255    }
256    else
257    {
258        DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
259    }
260
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;
267
268    for(i = 0 ; i < SPD_SIZE ; i++)
269    {
270        twsiSlave.offset = i;
271        if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, &data[i], 1) )
272        {
273            mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
274            return MV_FAIL;
275        }
276        mvOsDelay(5);
277    }
278   
279    DB(puts("DRAM: Reading dimm info succeded.\n"));
280    return MV_OK;
281}
282
283/*******************************************************************************
284* dimmSpdGet - Get the SPD parameters.
285*
286* DESCRIPTION:
287*       Read the DIMM SPD parameters into given struct parameter.
288*
289* INPUT:
290*       dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
291*
292* OUTPUT:
293*       pDimmInfo - DIMM information structure.
294*
295* RETURN:
296*       MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
297*
298*******************************************************************************/
299MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
300{
301    MV_U32 i;
302    MV_U32 density = 1;
303    MV_U32 spdChecksum;
304     
305    MV_TWSI_SLAVE twsiSlave;
306    MV_U8 data[SPD_SIZE];
307
308    if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
309    {
310        DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n")); 
311        return MV_BAD_PARAM;
312    }
313
314    /* zero dimmInfo structure */
315    memset(data, 0, SPD_SIZE);
316
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;
325
326    if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
327    {
328        DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
329        return MV_FAIL;
330    }
331    DB(puts("DRAM: Reading dimm info succeded.\n"));
332   
333    /* calculate SPD checksum */
334    spdChecksum = 0;
335   
336        for(i = 0 ; i <= 62 ; i++)
337        {
338        spdChecksum += data[i];
339    }
340   
341    if ((spdChecksum & 0xff) != data[63])
342    {
343        DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
344                            (MV_U32)(spdChecksum & 0xff), data[63]));
345    }
346    else
347    {
348        DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
349    }
350
351    /* copy the SPD content 1:1 into the dimmInfo structure*/
352    for(i = 0 ; i < SPD_SIZE ; i++)
353    {
354        pDimmInfo->spdRawData[i] = data[i];
355        DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
356    }
357
358    DB(mvOsPrintf("DRAM SPD Information:\n"));
359
360    /* Memory type (DDR / SDRAM) */
361    switch (data[DIMM_MEM_TYPE])
362    {
363        case (DIMM_MEM_TYPE_SDRAM):
364            pDimmInfo->memoryType = MEM_TYPE_SDRAM;
365            DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
366            break;
367        case (DIMM_MEM_TYPE_DDR1):
368            pDimmInfo->memoryType = MEM_TYPE_DDR1;
369            DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
370            break;
371        case (DIMM_MEM_TYPE_DDR2):
372            pDimmInfo->memoryType = MEM_TYPE_DDR2;
373            DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
374            break;
375        default:
376            mvOsPrintf("ERROR: Undefined memory type!\n");
377            return MV_ERROR;
378    }
379
380   
381    /* Number Of Row Addresses */
382    pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
383    DB(mvOsPrintf("DRAM numOfRowAddr[3]         %d\n",pDimmInfo->numOfRowAddr));
384       
385    /* Number Of Column Addresses */
386    pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
387    DB(mvOsPrintf("DRAM numOfColAddr[4]         %d\n",pDimmInfo->numOfColAddr));
388       
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));
393       
394    /* Number of module banks encoded differently for DDR2 */
395    if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
396        pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
397
398    /* Data Width */
399    pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
400    DB(mvOsPrintf("DRAM dataWidth[6]            0x%x\n", pDimmInfo->dataWidth));
401       
402    /* Minimum Cycle Time At Max CasLatancy */
403    pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
404
405    /* Error Check Type */
406    pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
407    DB(mvOsPrintf("DRAM errorCheckType[11]      0x%x\n", 
408                                                    pDimmInfo->errorCheckType));
409
410    /* Refresh Interval */
411    pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
412    DB(mvOsPrintf("DRAM refreshInterval[12]     0x%x\n", 
413                                                   pDimmInfo->refreshInterval));
414   
415    /* Sdram Width */
416    pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
417    DB(mvOsPrintf("DRAM sdramWidth[13]          0x%x\n",pDimmInfo->sdramWidth));
418       
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));
423   
424    /* Burst Length Supported */
425    /*     SDRAM/DDR1:
426                    *******-******-******-******-******-******-******-*******
427                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
428                    *******-******-******-******-******-******-******-*******
429    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   |  2   |   1  *
430                    *********************************************************/ 
431    /*     DDR2:
432                    *******-******-******-******-******-******-******-*******
433                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
434                    *******-******-******-******-******-******-******-*******
435    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   | TBD  | TBD  *
436                    *********************************************************/ 
437
438    pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
439    DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n", 
440                                              pDimmInfo->burstLengthSupported));
441   
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));
446   
447    /* Suported Cas Latencies */
448                   
449    /*      SDRAM:
450            *******-******-******-******-******-******-******-*******
451            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
452            *******-******-******-******-******-******-******-*******
453    CAS =   * TBD  |  7   |  6   |  5   |  4   |  3   |   2  |   1  *
454            ********************************************************/ 
455
456    /*     DDR 1:
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            *********************************************************/
462
463    /*     DDR 2:
464            *******-******-******-******-******-******-******-*******
465            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
466            *******-******-******-******-******-******-******-*******
467    CAS =   * TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  *
468            *********************************************************/
469   
470    pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
471    DB(mvOsPrintf("DRAM suportedCasLatencies[18]    0x%x\n", 
472                                              pDimmInfo->suportedCasLatencies));
473
474    /* For DDR2 only, get the DIMM type information */
475    if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
476    {   
477        pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
478        DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n", 
479                                                      pDimmInfo->dimmTypeInfo));
480    }
481
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));
486   
487    /* Minimum Cycle Time At Max CasLatancy Minus 1*/
488    pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps = 
489                                    cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
490
491    /* Minimum Cycle Time At Max CasLatancy Minus 2*/
492    pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps = 
493                                    cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
494
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));
507       
508    /* DIMM Bank Density */
509    pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
510    DB(mvOsPrintf("DRAM dimmBankDensity[31]         0x%x\n", 
511                                                   pDimmInfo->dimmBankDensity));
512
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));
517   
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));
522   
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));
527   
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));
532                 
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));
543   
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));
549
550    pDimmInfo->size = 0; 
551
552    /* Note that pDimmInfo->size is in MB units */
553    if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
554    {
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   */
571    }
572    else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
573    {
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   */
590    }
591    else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
592    {
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   */
609    }
610   
611    pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
612
613    DB(mvOsPrintf("Dram: dimm size    %dMB \n",pDimmInfo->size));
614
615    return MV_OK;
616}
617
618/*******************************************************************************
619* dimmSpdPrint - Print the SPD parameters.
620*
621* DESCRIPTION:
622*       Print the Dimm SPD parameters.
623*
624* INPUT:
625*       pDimmInfo - DIMM information structure.
626*
627* OUTPUT:
628*       None.
629*
630* RETURN:
631*       None.
632*
633*******************************************************************************/
634MV_VOID dimmSpdPrint(MV_U32 dimmNum)
635{
636    MV_DIMM_INFO dimmInfo;
637    MV_U32  i, temp = 0;
638    MV_U32  k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
639    MV_U32  rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
640    MV_U32  busClkPs;
641    MV_U8   trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
642            temp_buf[40], *spdRawData;
643
644    busClkPs = 1000000000 / (mvBoardSysClkGet() / 100);  /* in 10 ps units */
645
646    spdRawData = dimmInfo.spdRawData;
647   
648    if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
649    {
650        mvOsOutput("ERROR: Could not read SPD information!\n");
651        return;
652    }
653
654    /* find Manufactura of Dimm Module */
655    mvOsOutput("\nManufacturer's JEDEC ID Code:   ");
656    for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
657    {
658        mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
659    }
660    mvOsOutput("\n");
661
662    /* Manufacturer's Specific Data */
663    for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
664    {
665        temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
666    }
667    mvOsOutput("Manufacturer's Specific Data:   %s\n", temp_buf);
668
669    /* Module Part Number */
670    for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
671    {
672        temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
673    }
674    mvOsOutput("Module Part Number:             %s\n", temp_buf);
675
676    /* Module Serial Number */
677    for(i = 0; i < sizeof(MV_U32); i++)
678    {
679        temp |= spdRawData[95+i] << 8*i;
680    }
681    mvOsOutput("DIMM Serial No.                 %ld (%lx)\n", (long)temp, 
682                                    (long)temp);
683
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); 
691
692    /* find manufac_place of Dimm Module */
693    mvOsOutput("manufac_place:                  %d\n", spdRawData[72]);
694   
695    /* go over the first 35 I2C data bytes */
696    for(i = 2 ; i <= 35 ; i++)
697       switch(i)
698        {
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");
706                else
707                    mvOsOutput("Dram Type unknown\n");
708                break;
709/*----------------------------------------------------------------------------*/
710
711            case 3/* Number Of Row Addresses */
712                mvOsOutput("Module Number of row addresses: %d\n", 
713                                                        dimmInfo.numOfRowAddr);
714                break;
715/*----------------------------------------------------------------------------*/
716   
717            case 4/* Number Of Column Addresses */
718                mvOsOutput("Module Number of col addresses: %d\n", 
719                                                        dimmInfo.numOfColAddr);
720                break;
721/*----------------------------------------------------------------------------*/
722   
723            case 5/* Number Of Module Banks */
724                mvOsOutput("Number of Banks on Mod.:        %d\n", 
725                                                    dimmInfo.numOfModuleBanks);
726                break;
727/*----------------------------------------------------------------------------*/
728   
729            case 6/* Data Width */
730                mvOsOutput("Module Data Width:              %d bit\n", 
731                                                           dimmInfo.dataWidth);
732                break;
733/*----------------------------------------------------------------------------*/
734   
735            case 8/* Voltage Interface */
736                switch(spdRawData[i])
737                {
738                    case 0x0:
739                        mvOsOutput("Module is               TTL_5V_TOLERANT\n");
740                        break;
741                    case 0x1:
742                        mvOsOutput("Module is               LVTTL\n");
743                        break;
744                    case 0x2:
745                        mvOsOutput("Module is               HSTL_1_5V\n");
746                        break;
747                    case 0x3:
748                        mvOsOutput("Module is               SSTL_3_3V\n");
749                        break;
750                    case 0x4:
751                        mvOsOutput("Module is               SSTL_2_5V\n");
752                        break;
753                    case 0x5:
754                        if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
755                        {
756                            mvOsOutput("Module is                 SSTL_1_8V\n");
757                            break;
758                        }
759                    default:
760                        mvOsOutput("Module is               VOLTAGE_UNKNOWN\n");
761                        break;
762                }
763                break;
764/*----------------------------------------------------------------------------*/
765   
766            case 9/* Minimum Cycle Time At Max CasLatancy */
767                leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
768                rightOfPoint = (spdRawData[i] & 0x0f) * 10;
769               
770                /* DDR2 addition of right of point */
771                if ((spdRawData[i] & 0x0f) == 0xA)
772                {
773                    rightOfPoint = 25;
774                }
775                if ((spdRawData[i] & 0x0f) == 0xB)
776                {
777                    rightOfPoint = 33;
778                }
779                if ((spdRawData[i] & 0x0f) == 0xC)
780                {
781                    rightOfPoint = 66;
782                }
783                if ((spdRawData[i] & 0x0f) == 0xD)
784                {
785                    rightOfPoint = 75;
786                }
787                mvOsOutput("Minimum Cycle Time At Max CL:   %d.%d [ns]\n",
788                                                    leftOfPoint, rightOfPoint);
789                break;
790/*----------------------------------------------------------------------------*/
791   
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);
800                break;
801/*----------------------------------------------------------------------------*/
802   
803            case 11: /* Error Check Type */
804                mvOsOutput("Error Check Type (0=NONE):      %d\n", 
805                                                      dimmInfo.errorCheckType);
806                break;
807/*----------------------------------------------------------------------------*/
808
809            case 12: /* Refresh Interval */
810                mvOsOutput("Refresh Rate:                   %x\n", 
811                                                     dimmInfo.refreshInterval);
812                break;
813/*----------------------------------------------------------------------------*/
814   
815            case 13: /* Sdram Width */
816                mvOsOutput("Sdram Width:                    %d bits\n",     
817                                                          dimmInfo.sdramWidth);
818                break;
819/*----------------------------------------------------------------------------*/
820   
821            case 14: /* Error Check Data Width */
822                mvOsOutput("Error Check Data Width:         %d bits\n", 
823                                                 dimmInfo.errorCheckDataWidth);
824                break;
825/*----------------------------------------------------------------------------*/
826
827           case 15: /* Minimum Clock Delay is unsupported */
828                if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
829                    (dimmInfo.memoryType == MEM_TYPE_DDR1))
830                {
831                    mvOsOutput("Minimum Clk Delay back to back: %d\n", 
832                                                                spdRawData[i]);
833                }
834                break;
835/*----------------------------------------------------------------------------*/
836   
837            case 16: /* Burst Length Supported */
838    /*     SDRAM/DDR1:
839                    *******-******-******-******-******-******-******-*******
840                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
841                    *******-******-******-******-******-******-******-*******
842    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   |  2   |   1  *
843                    *********************************************************/ 
844    /*     DDR2:
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))
853                {
854                    if (dimmInfo.burstLengthSupported & BIT0)
855                        mvOsOutput("1, ");
856                    if (dimmInfo.burstLengthSupported & BIT1)
857                        mvOsOutput("2, ");
858                }
859                if (dimmInfo.burstLengthSupported & BIT2)
860                    mvOsOutput("4, ");
861                if (dimmInfo.burstLengthSupported & BIT3) 
862                    mvOsOutput("8, ");
863               
864                mvOsOutput(" Bit \n");
865                break;
866/*----------------------------------------------------------------------------*/
867   
868            case 17: /* Number Of Banks On Each Device */
869                mvOsOutput("Number Of Banks On Each Chip:   %d\n", 
870                                              dimmInfo.numOfBanksOnEachDevice);
871                break;
872/*----------------------------------------------------------------------------*/
873   
874            case 18: /* Suported Cas Latencies */
875                   
876            /*      SDRAM:
877                    *******-******-******-******-******-******-******-*******
878                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
879                    *******-******-******-******-******-******-******-*******
880            CAS =   * TBD  |  7   |  6   |  5   |  4   |  3   |   2  |   1  *
881                    ********************************************************/ 
882
883            /*     DDR 1:
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                    *********************************************************/
889
890            /*     DDR 2:
891                    *******-******-******-******-******-******-******-*******
892                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
893                    *******-******-******-******-******-******-******-*******
894            CAS =   * TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  *
895                    *********************************************************/
896
897                mvOsOutput("Suported Cas Latencies: (CL)                        ");
898                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
899                {
900                    for (k = 0; k <=7; k++)
901                    {
902                        if (dimmInfo.suportedCasLatencies & (1 << k))
903                            mvOsOutput("%d,             ", k+1);
904                    }
905                }
906                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
907                {
908                    if (dimmInfo.suportedCasLatencies & BIT0)
909                        mvOsOutput("1, ");
910                    if (dimmInfo.suportedCasLatencies & BIT1)
911                        mvOsOutput("1.5, ");
912                    if (dimmInfo.suportedCasLatencies & BIT2)
913                        mvOsOutput("2, ");
914                    if (dimmInfo.suportedCasLatencies & BIT3)
915                        mvOsOutput("2.5, ");
916                    if (dimmInfo.suportedCasLatencies & BIT4)
917                        mvOsOutput("3, ");
918                    if (dimmInfo.suportedCasLatencies & BIT5)
919                        mvOsOutput("3.5, ");
920                }
921                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
922                {
923                    if (dimmInfo.suportedCasLatencies & BIT2)
924                        mvOsOutput("2, ");
925                    if (dimmInfo.suportedCasLatencies & BIT3)
926                        mvOsOutput("3, ");
927                    if (dimmInfo.suportedCasLatencies & BIT4)
928                        mvOsOutput("4, ");
929                    if (dimmInfo.suportedCasLatencies & BIT5)
930                        mvOsOutput("5, ");             
931                }
932                else
933                    mvOsOutput("?.?, ");               
934                mvOsOutput("\n");
935                break;
936/*----------------------------------------------------------------------------*/
937   
938            case 20:   /* DDR2 DIMM type info */
939                if (dimmInfo.memoryType == MEM_TYPE_DDR2)
940                {
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");
945                    else 
946                        mvOsOutput("Unknown DIMM type.\n");
947                }
948
949                break;
950/*----------------------------------------------------------------------------*/
951   
952            case 21: /* SDRAM Modules Attributes */
953                mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
954               
955                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
956                {
957                    if (dimmInfo.dimmAttributes & BIT0)
958                        mvOsOutput(" Buffered Addr/Control Input:   Yes\n");
959                    else
960                        mvOsOutput(" Buffered Addr/Control Input:   No\n");
961
962                    if (dimmInfo.dimmAttributes & BIT1)
963                        mvOsOutput(" Registered Addr/Control Input: Yes\n");
964                    else
965                        mvOsOutput(" Registered Addr/Control Input: No\n");
966   
967                    if (dimmInfo.dimmAttributes & BIT2)
968                        mvOsOutput(" On-Card PLL (clock):           Yes \n");
969                    else
970                        mvOsOutput(" On-Card PLL (clock):           No \n");
971
972                    if (dimmInfo.dimmAttributes & BIT3)
973                        mvOsOutput(" Bufferd DQMB Input:            Yes \n");
974                    else
975                        mvOsOutput(" Bufferd DQMB Inputs:           No \n");
976   
977                    if (dimmInfo.dimmAttributes & BIT4)
978                        mvOsOutput(" Registered DQMB Inputs:        Yes \n");
979                    else
980                        mvOsOutput(" Registered DQMB Inputs:        No \n");
981 
982                    if (dimmInfo.dimmAttributes & BIT5)
983                        mvOsOutput(" Differential Clock Input:      Yes \n");
984                    else
985                        mvOsOutput(" Differential Clock Input:      No \n");
986   
987                    if (dimmInfo.dimmAttributes & BIT6)
988                        mvOsOutput(" redundant Row Addressing:      Yes \n");
989                    else
990                        mvOsOutput(" redundant Row Addressing:      No \n");
991                }
992                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
993                {
994                    if (dimmInfo.dimmAttributes & BIT0)
995                        mvOsOutput(" Buffered Addr/Control Input:   Yes\n");
996                    else 
997                        mvOsOutput(" Buffered Addr/Control Input:   No\n");
998   
999                    if (dimmInfo.dimmAttributes & BIT1)
1000                        mvOsOutput(" Registered Addr/Control Input: Yes\n");
1001                    else
1002                        mvOsOutput(" Registered Addr/Control Input: No\n");
1003   
1004                    if (dimmInfo.dimmAttributes & BIT2)
1005                        mvOsOutput(" On-Card PLL (clock):           Yes \n");
1006                    else
1007                        mvOsOutput(" On-Card PLL (clock):           No \n");
1008           
1009                    if (dimmInfo.dimmAttributes & BIT3)
1010                        mvOsOutput(" FET Switch On-Card Enabled:    Yes \n");
1011                    else
1012                        mvOsOutput(" FET Switch On-Card Enabled:    No \n");
1013                   
1014                    if (dimmInfo.dimmAttributes & BIT4)
1015                        mvOsOutput(" FET Switch External Enabled:   Yes \n");
1016                    else
1017                        mvOsOutput(" FET Switch External Enabled:   No \n");
1018
1019                    if (dimmInfo.dimmAttributes & BIT5)
1020                        mvOsOutput(" Differential Clock Input:      Yes \n");
1021                    else
1022                        mvOsOutput(" Differential Clock Input:      No \n");
1023                }
1024                else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
1025                {
1026                    mvOsOutput(" Number of Active Registers on the DIMM: %d\n", 
1027                                        (dimmInfo.dimmAttributes & 0x3) + 1);
1028           
1029                    mvOsOutput(" Number of PLLs on the DIMM: %d\n", 
1030                                      ((dimmInfo.dimmAttributes) >> 2) & 0x3);
1031               
1032                    if (dimmInfo.dimmAttributes & BIT4)
1033                        mvOsOutput(" FET Switch External Enabled:   Yes \n");
1034                    else
1035                        mvOsOutput(" FET Switch External Enabled:   No \n");
1036
1037                    if (dimmInfo.dimmAttributes & BIT6)
1038                        mvOsOutput(" Analysis probe installed:      Yes \n");
1039                    else
1040                        mvOsOutput(" Analysis probe installed:      No \n");
1041                }
1042               
1043                break;
1044/*----------------------------------------------------------------------------*/
1045
1046            case 22: /* Suported AutoPreCharge */
1047                mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
1048                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1049                {
1050                    if ( spdRawData[i] & BIT0 )
1051                        mvOsOutput(" Early Ras Precharge:           Yes \n");
1052                    else
1053                        mvOsOutput(" Early Ras Precharge:           No \n");
1054                                                       
1055                    if ( spdRawData[i] & BIT1 )                 
1056                        mvOsOutput(" AutoPreCharge:                 Yes \n");
1057                    else
1058                        mvOsOutput(" AutoPreCharge:                 No \n");
1059                                                           
1060                    if ( spdRawData[i] & BIT2 )                 
1061                        mvOsOutput(" Precharge All:                 Yes \n");
1062                    else
1063                        mvOsOutput(" Precharge All:                 No \n");
1064                                                       
1065                    if ( spdRawData[i] & BIT3 )                 
1066                        mvOsOutput(" Write 1/ReadBurst:             Yes \n");
1067                    else
1068                        mvOsOutput(" Write 1/ReadBurst:             No \n");
1069                                                       
1070                    if ( spdRawData[i] & BIT4 )                 
1071                        mvOsOutput(" lower VCC tolerance:           5%%\n");
1072                    else
1073                        mvOsOutput(" lower VCC tolerance:           10%%\n");
1074                                                       
1075                    if ( spdRawData[i] & BIT5 )                 
1076                        mvOsOutput(" upper VCC tolerance:           5%%\n");
1077                    else
1078                        mvOsOutput(" upper VCC tolerance:           10%%\n");
1079                }
1080                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
1081                {
1082                    if ( spdRawData[i] & BIT0 )
1083                        mvOsOutput(" Supports Weak Driver:          Yes \n");
1084                    else
1085                        mvOsOutput(" Supports Weak Driver:          No \n");
1086
1087                    if ( !(spdRawData[i] & BIT4) )
1088                        mvOsOutput(" lower VCC tolerance:           0.2V\n");
1089   
1090                    if ( !(spdRawData[i] & BIT5) )
1091                        mvOsOutput(" upper VCC tolerance:           0.2V\n");
1092
1093                    if ( spdRawData[i] & BIT6 )
1094                        mvOsOutput(" Concurrent Auto Preharge:      Yes \n");
1095                    else
1096                        mvOsOutput(" Concurrent Auto Preharge:      No \n");
1097
1098                    if ( spdRawData[i] & BIT7 )
1099                        mvOsOutput(" Supports Fast AP:              Yes \n");
1100                    else
1101                        mvOsOutput(" Supports Fast AP:              No \n");
1102                }
1103                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
1104                {
1105                    if ( spdRawData[i] & BIT0 )
1106                        mvOsOutput(" Supports Weak Driver:          Yes \n");
1107                    else
1108                        mvOsOutput(" Supports Weak Driver:          No \n");
1109                }
1110                break;
1111/*----------------------------------------------------------------------------*/
1112   
1113            case 23:
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;
1117               
1118                /* DDR2 addition of right of point */
1119                if ((spdRawData[i] & 0x0f) == 0xA)
1120                {
1121                    rightOfPoint = 25;
1122                }
1123                if ((spdRawData[i] & 0x0f) == 0xB)
1124                {
1125                    rightOfPoint = 33;
1126                }
1127                if ((spdRawData[i] & 0x0f) == 0xC)
1128                {
1129                    rightOfPoint = 66;
1130                }
1131                if ((spdRawData[i] & 0x0f) == 0xD)
1132                {
1133                    rightOfPoint = 75;
1134                }
1135
1136                mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
1137                           "(0 = Not supported): %d.%d [ns]\n",
1138                           leftOfPoint, rightOfPoint );
1139                break;
1140/*----------------------------------------------------------------------------*/
1141   
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);
1150                break;
1151/*----------------------------------------------------------------------------*/
1152   
1153            case 25:
1154            /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
1155                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1156                {
1157                    leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
1158                    rightOfPoint = (spdRawData[i] & 0x3) * 25;
1159                }
1160                else    /* DDR1 or DDR2 */ 
1161                {
1162                    leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
1163                    rightOfPoint = (spdRawData[i] & 0x0f) * 10;
1164                   
1165                    /* DDR2 addition of right of point */
1166                    if ((spdRawData[i] & 0x0f) == 0xA)
1167                    {
1168                        rightOfPoint = 25;
1169                    }
1170                    if ((spdRawData[i] & 0x0f) == 0xB)
1171                    {
1172                        rightOfPoint = 33;
1173                    }
1174                    if ((spdRawData[i] & 0x0f) == 0xC)
1175                    {
1176                        rightOfPoint = 66;
1177                    }
1178                    if ((spdRawData[i] & 0x0f) == 0xD)
1179                    {
1180                        rightOfPoint = 75;
1181                    }
1182                }
1183                mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy" 
1184                           "(0 = Not supported): %d.%d [ns]\n",
1185                           leftOfPoint, rightOfPoint );
1186                break;
1187/*----------------------------------------------------------------------------*/
1188   
1189            case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
1190                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1191                {
1192                    leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
1193                    rightOfPoint = (spdRawData[i] & 0x3) * 25;
1194                }
1195                else    /* DDR1 or DDR2 */ 
1196                {
1197                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + 
1198                                                      ((spdRawData[i] & 0x0f));
1199                    leftOfPoint     = 0;
1200                    rightOfPoint    = time_tmp;
1201                }
1202                mvOsOutput("Clock To Data Out (3rd CL value):           %d.%2d[ns]\n",
1203                                                  leftOfPoint, rightOfPoint );
1204                break;
1205/*----------------------------------------------------------------------------*/
1206   
1207            case 27: /* Minimum Row Precharge Time */
1208                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
1209                maskLeftOfPoint  = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 
1210                                                                    0xff : 0xfc;
1211                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 
1212                                                                    0x00 : 0x03;
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);
1220                break;
1221/*----------------------------------------------------------------------------*/
1222   
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) ? 
1226                                                                    0xff : 0xfc;
1227                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 
1228                                                                    0x00 : 0x03;
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);
1236                break;
1237/*----------------------------------------------------------------------------*/
1238   
1239            case 29: /* Minimum Ras-To-Cas Delay */
1240                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
1241                maskLeftOfPoint  = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 
1242                                                                    0xff : 0xfc;
1243                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 
1244                                                                    0x00 : 0x03;
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);
1252                break;
1253/*----------------------------------------------------------------------------*/
1254   
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);
1259                break;
1260/*----------------------------------------------------------------------------*/
1261   
1262            case 31: /* Module Bank Density */
1263                mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
1264
1265                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1266                {
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, ");
1283                }
1284                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
1285                {
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, ");
1302                }
1303                else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
1304                {
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, ");
1321                }
1322                mvOsOutput("\n");
1323                break;
1324/*----------------------------------------------------------------------------*/
1325   
1326            case 32: /* Address And Command Setup Time (measured in ns/1000) */
1327                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1328                {
1329                    rightOfPoint = (spdRawData[i] & 0x0f);
1330                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;
1331                    if(leftOfPoint > 7)
1332                    {
1333                    leftOfPoint *= -1;
1334                    }
1335                }
1336                else /* DDR1 or DDR2 */
1337                {
1338                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + 
1339                                                      ((spdRawData[i] & 0x0f));
1340                    leftOfPoint = time_tmp / 100;
1341                    rightOfPoint = time_tmp % 100; 
1342                }
1343                mvOsOutput("Address And Command Setup Time [ns]:                %d.%d\n",
1344                                                     leftOfPoint, rightOfPoint);
1345                break;
1346/*----------------------------------------------------------------------------*/
1347   
1348            case 33: /* Address And Command Hold Time */
1349                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1350                {
1351                    rightOfPoint = (spdRawData[i] & 0x0f);
1352                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;
1353                    if(leftOfPoint > 7)
1354                    {
1355                    leftOfPoint *= -1;
1356                    }
1357                }
1358                else /* DDR1 or DDR2 */
1359                {
1360                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + 
1361                                                      ((spdRawData[i] & 0x0f));
1362                    leftOfPoint = time_tmp / 100;
1363                    rightOfPoint = time_tmp % 100;                 
1364                }
1365                mvOsOutput("Address And Command Hold Time [ns]:                 %d.%d\n",
1366                                                   leftOfPoint, rightOfPoint);
1367                break;
1368/*----------------------------------------------------------------------------*/
1369   
1370            case 34: /* Data Input Setup Time */
1371                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1372                {
1373                    rightOfPoint = (spdRawData[i] & 0x0f);
1374                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;
1375                    if(leftOfPoint > 7)
1376                    {
1377                        leftOfPoint *= -1;
1378                    }
1379                }
1380                else /* DDR1 or DDR2 */
1381                {
1382                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + 
1383                                                      ((spdRawData[i] & 0x0f));
1384                    leftOfPoint = time_tmp / 100;
1385                    rightOfPoint = time_tmp % 100;                 
1386                }
1387                mvOsOutput("Data Input Setup Time [ns]:                         %d.%d\n", 
1388                                                    leftOfPoint, rightOfPoint);
1389                break;
1390/*----------------------------------------------------------------------------*/
1391   
1392            case 35: /* Data Input Hold Time */
1393                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
1394                {
1395                    rightOfPoint = (spdRawData[i] & 0x0f);
1396                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;
1397                    if(leftOfPoint > 7)
1398                    {
1399                        leftOfPoint *= -1;
1400                    }
1401                }
1402                else /* DDR1 or DDR2 */
1403                {
1404                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + 
1405                                                      ((spdRawData[i] & 0x0f));
1406                    leftOfPoint = time_tmp / 100;
1407                    rightOfPoint = time_tmp % 100;                 
1408                }
1409                mvOsOutput("Data Input Hold Time [ns]:                  %d.%d\n\n", 
1410                                                    leftOfPoint, rightOfPoint);
1411                break;
1412/*----------------------------------------------------------------------------*/
1413   
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);
1419                break;
1420/*----------------------------------------------------------------------------*/
1421        }
1422   
1423}
1424
1425
1426/*
1427 * translate ns.ns/10 coding of SPD timing values
1428 * into ps unit values
1429 */
1430/*******************************************************************************
1431*  cas2ps - Translate x.y ns parameter to pico-seconds values
1432*
1433* DESCRIPTION:
1434*       This function translates x.y nano seconds to its value in pico seconds.
1435*       For example 3.75ns will return 3750.
1436*
1437* INPUT:
1438*       spd_byte - DIMM SPD byte.
1439*
1440* OUTPUT:
1441*       None.
1442*
1443* RETURN:
1444*       value in pico seconds.
1445*
1446*******************************************************************************/
1447static MV_U32  cas2ps(MV_U8 spd_byte)
1448{
1449    MV_U32 ns, ns10;
1450   
1451    /* isolate upper nibble */
1452    ns = (spd_byte >> 4) & 0x0F;
1453    /* isolate lower nibble */
1454    ns10 = (spd_byte & 0x0F);
1455   
1456    if( ns10 < 10 ) {
1457        ns10 *= 10;
1458    }
1459    else if( ns10 == 10 )
1460        ns10 = 25;
1461    else if( ns10 == 11 )
1462        ns10 = 33;
1463    else if( ns10 == 12 )
1464        ns10 = 66;
1465    else if( ns10 == 13 )
1466        ns10 = 75;
1467    else 
1468    {
1469        mvOsOutput("cas2ps Err. unsupported cycle time.\n");
1470    }
1471   
1472    return (ns*1000 + ns10*10);
1473}
1474
Note: See TracBrowser for help on using the repository browser.