7a26f905976d01ef838390182edc8386be35f0ea
[15.05/openwrt.git] / target / linux / generic / files / crypto / ocf / kirkwood / mvHal / mv_hal / ddr2 / spd / mvSpd.c
1 /*******************************************************************************
2 Copyright (C) Marvell International Ltd. and its affiliates
3
4 This software file (the "File") is owned and distributed by Marvell 
5 International Ltd. and/or its affiliates ("Marvell") under the following
6 alternative licensing terms.  Once you have made an election to distribute the
7 File under one of the following license alternatives, please (i) delete this
8 introductory statement regarding license alternatives, (ii) delete the two
9 license alternatives that you have not elected to use and (iii) preserve the
10 Marvell copyright notice above.
11
12 ********************************************************************************
13 Marvell Commercial License Option
14
15 If you received this File from Marvell and you have entered into a commercial
16 license agreement (a "Commercial License") with Marvell, the File is licensed
17 to you under the terms of the applicable Commercial License.
18
19 ********************************************************************************
20 Marvell GPL License Option
21
22 If you received this File from Marvell, you may opt to use, redistribute and/or 
23 modify this File in accordance with the terms and conditions of the General 
24 Public License Version 2, June 1991 (the "GPL License"), a copy of which is 
25 available along with the File in the license.txt file or by writing to the Free 
26 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or 
27 on the worldwide web at http://www.gnu.org/licenses/gpl.txt. 
28
29 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED 
30 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY 
31 DISCLAIMED.  The GPL License provides additional details about this warranty 
32 disclaimer.
33 ********************************************************************************
34 Marvell BSD License Option
35
36 If you received this File from Marvell, you may opt to use, redistribute and/or 
37 modify this File under the following licensing terms. 
38 Redistribution and use in source and binary forms, with or without modification, 
39 are permitted provided that the following conditions are met:
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     
52 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
53 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
54 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
55 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
56 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
57 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
58 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
59 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
60 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
61 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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
75 static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo, 
76                                             MV_DRAM_BANK_INFO *pBankInfo);
77 static MV_U32  cas2ps(MV_U8 spd_byte);
78 /*******************************************************************************
79 * mvDramBankGet - Get the DRAM bank paramters.
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 *******************************************************************************/
98 MV_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 *******************************************************************************/
143 static 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 *******************************************************************************/
217 MV_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 *******************************************************************************/
299 MV_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 *******************************************************************************/
634 MV_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 *******************************************************************************/
1447 static 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