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