blob: db545ef68df0739762aea6a3a55b202f0a4dbb92 [file] [log] [blame]
stroesec096c842004-12-16 18:21:17 +00001/*
2 * (C) Copyright 2001
3 * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*************************************************************************
25 * adaption for the Marvell DB64360 Board
26 * Ingo Assmus (ingo.assmus@keymile.com)
27 *
28 * adaption for the cpci750 Board
29 * Reinhard Arlt (reinhard.arlt@esd-electronics.com)
30 *************************************************************************/
31
32
33/* sdram_init.c - automatic memory sizing */
34
35#include <common.h>
36#include <74xx_7xx.h>
37#include "../../Marvell/include/memory.h"
38#include "../../Marvell/include/pci.h"
39#include "../../Marvell/include/mv_gen_reg.h"
40#include <net.h>
41
42#include "eth.h"
43#include "mpsc.h"
44#include "../../Marvell/common/i2c.h"
45#include "64360.h"
46#include "mv_regs.h"
47
48
49#undef DEBUG
50/* #define DEBUG */
51#ifdef CONFIG_PCI
52#define MAP_PCI
53#endif /* of CONFIG_PCI */
54
55#ifdef DEBUG
56#define DP(x) x
57#else
58#define DP(x)
59#endif
60
61int set_dfcdlInit(void); /* setup delay line of Mv64360 */
62
63/* ------------------------------------------------------------------------- */
64
65int
66memory_map_bank(unsigned int bankNo,
67 unsigned int bankBase,
68 unsigned int bankLength)
69{
70#ifdef MAP_PCI
71 PCI_HOST host;
72#endif
73
74
75#ifdef DEBUG
76 if (bankLength > 0) {
77 printf("mapping bank %d at %08x - %08x\n",
78 bankNo, bankBase, bankBase + bankLength - 1);
79 } else {
80 printf("unmapping bank %d\n", bankNo);
81 }
82#endif
83
84 memoryMapBank(bankNo, bankBase, bankLength);
85
86#ifdef MAP_PCI
87 for (host=PCI_HOST0;host<=PCI_HOST1;host++) {
88 const int features=
89 PREFETCH_ENABLE |
90 DELAYED_READ_ENABLE |
91 AGGRESSIVE_PREFETCH |
92 READ_LINE_AGGRESSIVE_PREFETCH |
93 READ_MULTI_AGGRESSIVE_PREFETCH |
94 MAX_BURST_4 |
95 PCI_NO_SWAP;
96
97 pciMapMemoryBank(host, bankNo, bankBase, bankLength);
98
99 pciSetRegionSnoopMode(host, bankNo, PCI_SNOOP_WB, bankBase,
100 bankLength);
101
102 pciSetRegionFeatures(host, bankNo, features, bankBase, bankLength);
103 }
104#endif
105 return 0;
106}
107
108#define GB (1 << 30)
109
110/* much of this code is based on (or is) the code in the pip405 port */
111/* thanks go to the authors of said port - Josh */
112
113/* structure to store the relevant information about an sdram bank */
114typedef struct sdram_info {
115 uchar drb_size;
116 uchar registered, ecc;
117 uchar tpar;
118 uchar tras_clocks;
119 uchar burst_len;
120 uchar banks, slot;
121} sdram_info_t;
122
123/* Typedefs for 'gtAuxilGetDIMMinfo' function */
124
125typedef enum _memoryType {SDRAM, DDR} MEMORY_TYPE;
126
127typedef enum _voltageInterface {TTL_5V_TOLERANT, LVTTL, HSTL_1_5V,
wdenk07d7e6b2004-12-16 21:44:03 +0000128 SSTL_3_3V, SSTL_2_5V, VOLTAGE_UNKNOWN,
129 } VOLTAGE_INTERFACE;
stroesec096c842004-12-16 18:21:17 +0000130
131typedef enum _max_CL_supported_DDR {DDR_CL_1=1, DDR_CL_1_5=2, DDR_CL_2=4, DDR_CL_2_5=8, DDR_CL_3=16, DDR_CL_3_5=32, DDR_CL_FAULT} MAX_CL_SUPPORTED_DDR;
132typedef enum _max_CL_supported_SD {SD_CL_1=1, SD_CL_2, SD_CL_3, SD_CL_4, SD_CL_5, SD_CL_6, SD_CL_7, SD_FAULT} MAX_CL_SUPPORTED_SD;
133
134
135/* SDRAM/DDR information struct */
136typedef struct _gtMemoryDimmInfo
137{
138 MEMORY_TYPE memoryType;
139 unsigned int numOfRowAddresses;
140 unsigned int numOfColAddresses;
141 unsigned int numOfModuleBanks;
142 unsigned int dataWidth;
143 VOLTAGE_INTERFACE voltageInterface;
144 unsigned int errorCheckType; /* ECC , PARITY..*/
145 unsigned int sdramWidth; /* 4,8,16 or 32 */;
146 unsigned int errorCheckDataWidth; /* 0 - no, 1 - Yes */
147 unsigned int minClkDelay;
148 unsigned int burstLengthSupported;
149 unsigned int numOfBanksOnEachDevice;
150 unsigned int suportedCasLatencies;
151 unsigned int RefreshInterval;
152 unsigned int maxCASlatencySupported_LoP; /* LoP left of point (measured in ns) */
153 unsigned int maxCASlatencySupported_RoP; /* RoP right of point (measured in ns)*/
154 MAX_CL_SUPPORTED_DDR maxClSupported_DDR;
155 MAX_CL_SUPPORTED_SD maxClSupported_SD;
156 unsigned int moduleBankDensity;
157 /* module attributes (true for yes) */
158 bool bufferedAddrAndControlInputs;
159 bool registeredAddrAndControlInputs;
160 bool onCardPLL;
161 bool bufferedDQMBinputs;
162 bool registeredDQMBinputs;
163 bool differentialClockInput;
164 bool redundantRowAddressing;
165
166 /* module general attributes */
167 bool suportedAutoPreCharge;
168 bool suportedPreChargeAll;
169 bool suportedEarlyRasPreCharge;
170 bool suportedWrite1ReadBurst;
171 bool suported5PercentLowVCC;
172 bool suported5PercentUpperVCC;
173 /* module timing parameters */
174 unsigned int minRasToCasDelay;
175 unsigned int minRowActiveRowActiveDelay;
176 unsigned int minRasPulseWidth;
177 unsigned int minRowPrechargeTime; /* measured in ns */
178
179 int addrAndCommandHoldTime; /* LoP left of point (measured in ns) */
180 int addrAndCommandSetupTime; /* (measured in ns/100) */
181 int dataInputSetupTime; /* LoP left of point (measured in ns) */
182 int dataInputHoldTime; /* LoP left of point (measured in ns) */
183/* tAC times for highest 2nd and 3rd highest CAS Latency values */
184 unsigned int clockToDataOut_LoP; /* LoP left of point (measured in ns) */
185 unsigned int clockToDataOut_RoP; /* RoP right of point (measured in ns)*/
186 unsigned int clockToDataOutMinus1_LoP; /* LoP left of point (measured in ns) */
187 unsigned int clockToDataOutMinus1_RoP; /* RoP right of point (measured in ns)*/
188 unsigned int clockToDataOutMinus2_LoP; /* LoP left of point (measured in ns) */
189 unsigned int clockToDataOutMinus2_RoP; /* RoP right of point (measured in ns)*/
190
191 unsigned int minimumCycleTimeAtMaxCasLatancy_LoP; /* LoP left of point (measured in ns) */
192 unsigned int minimumCycleTimeAtMaxCasLatancy_RoP; /* RoP right of point (measured in ns)*/
193
194 unsigned int minimumCycleTimeAtMaxCasLatancyMinus1_LoP; /* LoP left of point (measured in ns) */
195 unsigned int minimumCycleTimeAtMaxCasLatancyMinus1_RoP; /* RoP right of point (measured in ns)*/
196
197 unsigned int minimumCycleTimeAtMaxCasLatancyMinus2_LoP; /* LoP left of point (measured in ns) */
198 unsigned int minimumCycleTimeAtMaxCasLatancyMinus2_RoP; /* RoP right of point (measured in ns)*/
199
200 /* Parameters calculated from
201 the extracted DIMM information */
202 unsigned int size;
203 unsigned int deviceDensity; /* 16,64,128,256 or 512 Mbit */
204 unsigned int numberOfDevices;
205 uchar drb_size; /* DRAM size in n*64Mbit */
206 uchar slot; /* Slot Number this module is inserted in */
207 uchar spd_raw_data[128]; /* Content of SPD-EEPROM copied 1:1 */
208#ifdef DEBUG
209 uchar manufactura[8]; /* Content of SPD-EEPROM Byte 64-71 */
210 uchar modul_id[18]; /* Content of SPD-EEPROM Byte 73-90 */
211 uchar vendor_data[27]; /* Content of SPD-EEPROM Byte 99-125 */
212 unsigned long modul_serial_no; /* Content of SPD-EEPROM Byte 95-98 */
213 unsigned int manufac_date; /* Content of SPD-EEPROM Byte 93-94 */
214 unsigned int modul_revision; /* Content of SPD-EEPROM Byte 91-92 */
215 uchar manufac_place; /* Content of SPD-EEPROM Byte 72 */
216
217#endif
218} AUX_MEM_DIMM_INFO;
219
220
221/*
222 * translate ns.ns/10 coding of SPD timing values
223 * into 10 ps unit values
224 */
225static inline unsigned short
226NS10to10PS(unsigned char spd_byte)
227{
228 unsigned short ns, ns10;
229
230 /* isolate upper nibble */
231 ns = (spd_byte >> 4) & 0x0F;
232 /* isolate lower nibble */
233 ns10 = (spd_byte & 0x0F);
234
235 return(ns*100 + ns10*10);
236}
237
238/*
239 * translate ns coding of SPD timing values
240 * into 10 ps unit values
241 */
242static inline unsigned short
243NSto10PS(unsigned char spd_byte)
244{
245 return(spd_byte*100);
246}
247
248/* This code reads the SPD chip on the sdram and populates
249 * the array which is passed in with the relevant information */
250/* static int check_dimm(uchar slot, AUX_MEM_DIMM_INFO *info) */
wdenk07d7e6b2004-12-16 21:44:03 +0000251static int check_dimm (uchar slot, AUX_MEM_DIMM_INFO * dimmInfo)
stroesec096c842004-12-16 18:21:17 +0000252{
wdenk07d7e6b2004-12-16 21:44:03 +0000253 DECLARE_GLOBAL_DATA_PTR;
stroesec096c842004-12-16 18:21:17 +0000254
wdenk07d7e6b2004-12-16 21:44:03 +0000255 unsigned long spd_checksum;
stroesec096c842004-12-16 18:21:17 +0000256
257 uchar addr = slot == 0 ? DIMM0_I2C_ADDR : DIMM1_I2C_ADDR;
258 int ret;
wdenk07d7e6b2004-12-16 21:44:03 +0000259 unsigned int i, j, density = 1, devicesForErrCheck = 0;
260
stroesec096c842004-12-16 18:21:17 +0000261#ifdef DEBUG
wdenk07d7e6b2004-12-16 21:44:03 +0000262 unsigned int k;
stroesec096c842004-12-16 18:21:17 +0000263#endif
wdenk07d7e6b2004-12-16 21:44:03 +0000264 unsigned int rightOfPoint = 0, leftOfPoint = 0, mult, div, time_tmp;
265 int sign = 1, shift, maskLeftOfPoint, maskRightOfPoint;
stroesec096c842004-12-16 18:21:17 +0000266 uchar supp_cal, cal_val;
267 ulong memclk, tmemclk;
268 ulong tmp;
wdenk07d7e6b2004-12-16 21:44:03 +0000269 uchar trp_clocks = 0, trcd_clocks, tras_clocks, trrd_clocks;
stroesec096c842004-12-16 18:21:17 +0000270 uchar data[128];
271
272 memclk = gd->bus_clk;
wdenk07d7e6b2004-12-16 21:44:03 +0000273 tmemclk = 1000000000 / (memclk / 100); /* in 10 ps units */
stroesec096c842004-12-16 18:21:17 +0000274
wdenk07d7e6b2004-12-16 21:44:03 +0000275 memset (data, 0, sizeof (data));
stroesec096c842004-12-16 18:21:17 +0000276
277
278 ret = 0;
279
wdenk07d7e6b2004-12-16 21:44:03 +0000280 DP (puts ("before i2c read\n"));
stroesec096c842004-12-16 18:21:17 +0000281
wdenk07d7e6b2004-12-16 21:44:03 +0000282 ret = i2c_read (addr, 0, 2, data, 128);
stroesec096c842004-12-16 18:21:17 +0000283
wdenk07d7e6b2004-12-16 21:44:03 +0000284 DP (puts ("after i2c read\n"));
stroesec096c842004-12-16 18:21:17 +0000285
wdenk07d7e6b2004-12-16 21:44:03 +0000286 if ((data[64] != 'e') || (data[65] != 's') || (data[66] != 'd')
287 || (data[67] != '-') || (data[68] != 'g') || (data[69] != 'm')
288 || (data[70] != 'b') || (data[71] != 'h')) {
289 ret = -1;
290 }
stroesec096c842004-12-16 18:21:17 +0000291
wdenk07d7e6b2004-12-16 21:44:03 +0000292 if ((ret != 0) && (slot == 0)) {
293 memset (data, 0, sizeof (data));
294 data[0] = 0x80;
295 data[1] = 0x08;
296 data[2] = 0x07;
297 data[3] = 0x0c;
298 data[4] = 0x09;
299 data[5] = 0x01;
300 data[6] = 0x48;
301 data[7] = 0x00;
302 data[8] = 0x04;
303 data[9] = 0x75;
304 data[10] = 0x80;
305 data[11] = 0x02;
306 data[12] = 0x80;
307 data[13] = 0x10;
308 data[14] = 0x08;
309 data[15] = 0x01;
310 data[16] = 0x0e;
311 data[17] = 0x04;
312 data[18] = 0x0c;
313 data[19] = 0x01;
314 data[20] = 0x02;
315 data[21] = 0x20;
316 data[22] = 0x00;
317 data[23] = 0xa0;
318 data[24] = 0x80;
319 data[25] = 0x00;
320 data[26] = 0x00;
321 data[27] = 0x50;
322 data[28] = 0x3c;
323 data[29] = 0x50;
324 data[30] = 0x32;
325 data[31] = 0x10;
326 data[32] = 0xb0;
327 data[33] = 0xb0;
328 data[34] = 0x60;
329 data[35] = 0x60;
330 data[64] = 'e';
331 data[65] = 's';
332 data[66] = 'd';
333 data[67] = '-';
334 data[68] = 'g';
335 data[69] = 'm';
336 data[70] = 'b';
337 data[71] = 'h';
338 ret = 0;
339 }
stroesec096c842004-12-16 18:21:17 +0000340
341 /* zero all the values */
wdenk07d7e6b2004-12-16 21:44:03 +0000342 memset (dimmInfo, 0, sizeof (*dimmInfo));
stroesec096c842004-12-16 18:21:17 +0000343
wdenk07d7e6b2004-12-16 21:44:03 +0000344 /* copy the SPD content 1:1 into the dimmInfo structure */
345 for (i = 0; i <= 127; i++) {
346 dimmInfo->spd_raw_data[i] = data[i];
347 }
stroesec096c842004-12-16 18:21:17 +0000348
349 if (ret) {
wdenk07d7e6b2004-12-16 21:44:03 +0000350 DP (printf ("No DIMM in slot %d [err = %x]\n", slot, ret));
stroesec096c842004-12-16 18:21:17 +0000351 return 0;
wdenk07d7e6b2004-12-16 21:44:03 +0000352 } else
353 dimmInfo->slot = slot; /* start to fill up dimminfo for this "slot" */
stroesec096c842004-12-16 18:21:17 +0000354
355#ifdef CFG_DISPLAY_DIMM_SPD_CONTENT
356
wdenk07d7e6b2004-12-16 21:44:03 +0000357 for (i = 0; i <= 127; i++) {
358 printf ("SPD-EEPROM Byte %3d = %3x (%3d)\n", i, data[i],
359 data[i]);
360 }
stroesec096c842004-12-16 18:21:17 +0000361
362#endif
363#ifdef DEBUG
wdenk07d7e6b2004-12-16 21:44:03 +0000364 /* find Manufacturer of Dimm Module */
365 for (i = 0; i < sizeof (dimmInfo->manufactura); i++) {
366 dimmInfo->manufactura[i] = data[64 + i];
367 }
368 printf ("\nThis RAM-Module is produced by: %s\n",
369 dimmInfo->manufactura);
stroesec096c842004-12-16 18:21:17 +0000370
wdenk07d7e6b2004-12-16 21:44:03 +0000371 /* find Manul-ID of Dimm Module */
372 for (i = 0; i < sizeof (dimmInfo->modul_id); i++) {
373 dimmInfo->modul_id[i] = data[73 + i];
374 }
375 printf ("The Module-ID of this RAM-Module is: %s\n",
376 dimmInfo->modul_id);
stroesec096c842004-12-16 18:21:17 +0000377
wdenk07d7e6b2004-12-16 21:44:03 +0000378 /* find Vendor-Data of Dimm Module */
379 for (i = 0; i < sizeof (dimmInfo->vendor_data); i++) {
380 dimmInfo->vendor_data[i] = data[99 + i];
381 }
382 printf ("Vendor Data of this RAM-Module is: %s\n",
383 dimmInfo->vendor_data);
stroesec096c842004-12-16 18:21:17 +0000384
wdenk07d7e6b2004-12-16 21:44:03 +0000385 /* find modul_serial_no of Dimm Module */
386 dimmInfo->modul_serial_no = (*((unsigned long *) (&data[95])));
387 printf ("Serial No. of this RAM-Module is: %ld (%lx)\n",
388 dimmInfo->modul_serial_no, dimmInfo->modul_serial_no);
stroesec096c842004-12-16 18:21:17 +0000389
wdenk07d7e6b2004-12-16 21:44:03 +0000390 /* find Manufac-Data of Dimm Module */
391 dimmInfo->manufac_date = (*((unsigned int *) (&data[93])));
392 printf ("Manufactoring Date of this RAM-Module is: %d.%d\n", data[93], data[94]); /*dimmInfo->manufac_date */
stroesec096c842004-12-16 18:21:17 +0000393
wdenk07d7e6b2004-12-16 21:44:03 +0000394 /* find modul_revision of Dimm Module */
395 dimmInfo->modul_revision = (*((unsigned int *) (&data[91])));
396 printf ("Module Revision of this RAM-Module is: %d.%d\n", data[91], data[92]); /* dimmInfo->modul_revision */
stroesec096c842004-12-16 18:21:17 +0000397
wdenk07d7e6b2004-12-16 21:44:03 +0000398 /* find manufac_place of Dimm Module */
399 dimmInfo->manufac_place = (*((unsigned char *) (&data[72])));
400 printf ("manufac_place of this RAM-Module is: %d\n",
401 dimmInfo->manufac_place);
stroesec096c842004-12-16 18:21:17 +0000402
403#endif
404/*------------------------------------------------------------------------------------------------------------------------------*/
405/* calculate SPD checksum */
406/*------------------------------------------------------------------------------------------------------------------------------*/
wdenk07d7e6b2004-12-16 21:44:03 +0000407 spd_checksum = 0;
408#if 0 /* test-only */
409 for (i = 0; i <= 62; i++) {
410 spd_checksum += data[i];
411 }
stroesec096c842004-12-16 18:21:17 +0000412
wdenk07d7e6b2004-12-16 21:44:03 +0000413 if ((spd_checksum & 0xff) != data[63]) {
414 printf ("### Error in SPD Checksum !!! Is_value: %2x should value %2x\n", (unsigned int) (spd_checksum & 0xff), data[63]);
415 hang ();
416 }
stroesec096c842004-12-16 18:21:17 +0000417
wdenk07d7e6b2004-12-16 21:44:03 +0000418 else
419 printf ("SPD Checksum ok!\n");
stroesec096c842004-12-16 18:21:17 +0000420#endif /* test-only */
421
422/*------------------------------------------------------------------------------------------------------------------------------*/
wdenk07d7e6b2004-12-16 21:44:03 +0000423 for (i = 2; i <= 35; i++) {
424 switch (i) {
425 case 2: /* Memory type (DDR / SDRAM) */
426 dimmInfo->memoryType = (data[i] == 0x7) ? DDR : SDRAM;
427#ifdef DEBUG
428 if (dimmInfo->memoryType == 0)
429 DP (printf
430 ("Dram_type in slot %d is: SDRAM\n",
431 dimmInfo->slot));
432 if (dimmInfo->memoryType == 1)
433 DP (printf
434 ("Dram_type in slot %d is: DDRAM\n",
435 dimmInfo->slot));
436#endif
437 break;
stroesec096c842004-12-16 18:21:17 +0000438/*------------------------------------------------------------------------------------------------------------------------------*/
439
wdenk07d7e6b2004-12-16 21:44:03 +0000440 case 3: /* Number Of Row Addresses */
441 dimmInfo->numOfRowAddresses = data[i];
442 DP (printf
443 ("Module Number of row addresses: %d\n",
444 dimmInfo->numOfRowAddresses));
445 break;
stroesec096c842004-12-16 18:21:17 +0000446/*------------------------------------------------------------------------------------------------------------------------------*/
447
wdenk07d7e6b2004-12-16 21:44:03 +0000448 case 4: /* Number Of Column Addresses */
449 dimmInfo->numOfColAddresses = data[i];
450 DP (printf
451 ("Module Number of col addresses: %d\n",
452 dimmInfo->numOfColAddresses));
453 break;
stroesec096c842004-12-16 18:21:17 +0000454/*------------------------------------------------------------------------------------------------------------------------------*/
455
wdenk07d7e6b2004-12-16 21:44:03 +0000456 case 5: /* Number Of Module Banks */
457 dimmInfo->numOfModuleBanks = data[i];
458 DP (printf
459 ("Number of Banks on Mod. : %d\n",
460 dimmInfo->numOfModuleBanks));
461 break;
stroesec096c842004-12-16 18:21:17 +0000462/*------------------------------------------------------------------------------------------------------------------------------*/
463
wdenk07d7e6b2004-12-16 21:44:03 +0000464 case 6: /* Data Width */
465 dimmInfo->dataWidth = data[i];
466 DP (printf
467 ("Module Data Width: %d\n",
468 dimmInfo->dataWidth));
469 break;
stroesec096c842004-12-16 18:21:17 +0000470/*------------------------------------------------------------------------------------------------------------------------------*/
471
wdenk07d7e6b2004-12-16 21:44:03 +0000472 case 8: /* Voltage Interface */
473 switch (data[i]) {
474 case 0x0:
475 dimmInfo->voltageInterface = TTL_5V_TOLERANT;
476 DP (printf
477 ("Module is TTL_5V_TOLERANT\n"));
478 break;
479 case 0x1:
480 dimmInfo->voltageInterface = LVTTL;
481 DP (printf
482 ("Module is LVTTL\n"));
483 break;
484 case 0x2:
485 dimmInfo->voltageInterface = HSTL_1_5V;
486 DP (printf
487 ("Module is TTL_5V_TOLERANT\n"));
488 break;
489 case 0x3:
490 dimmInfo->voltageInterface = SSTL_3_3V;
491 DP (printf
492 ("Module is HSTL_1_5V\n"));
493 break;
494 case 0x4:
495 dimmInfo->voltageInterface = SSTL_2_5V;
496 DP (printf
497 ("Module is SSTL_2_5V\n"));
498 break;
499 default:
500 dimmInfo->voltageInterface = VOLTAGE_UNKNOWN;
501 DP (printf
502 ("Module is VOLTAGE_UNKNOWN\n"));
503 break;
504 }
505 break;
stroesec096c842004-12-16 18:21:17 +0000506/*------------------------------------------------------------------------------------------------------------------------------*/
507
wdenk07d7e6b2004-12-16 21:44:03 +0000508 case 9: /* Minimum Cycle Time At Max CasLatancy */
509 shift = (dimmInfo->memoryType == DDR) ? 4 : 2;
510 mult = (dimmInfo->memoryType == DDR) ? 10 : 25;
511 maskLeftOfPoint =
512 (dimmInfo->memoryType == DDR) ? 0xf0 : 0xfc;
513 maskRightOfPoint =
514 (dimmInfo->memoryType == DDR) ? 0xf : 0x03;
515 leftOfPoint = (data[i] & maskLeftOfPoint) >> shift;
516 rightOfPoint = (data[i] & maskRightOfPoint) * mult;
517 dimmInfo->minimumCycleTimeAtMaxCasLatancy_LoP =
518 leftOfPoint;
519 dimmInfo->minimumCycleTimeAtMaxCasLatancy_RoP =
520 rightOfPoint;
521 DP (printf
522 ("Minimum Cycle Time At Max CasLatancy: %d.%d [ns]\n",
523 leftOfPoint, rightOfPoint));
524 break;
stroesec096c842004-12-16 18:21:17 +0000525/*------------------------------------------------------------------------------------------------------------------------------*/
526
wdenk07d7e6b2004-12-16 21:44:03 +0000527 case 10: /* Clock To Data Out */
528 div = (dimmInfo->memoryType == DDR) ? 100 : 10;
529 time_tmp =
530 (((data[i] & 0xf0) >> 4) * 10) +
531 ((data[i] & 0x0f));
532 leftOfPoint = time_tmp / div;
533 rightOfPoint = time_tmp % div;
534 dimmInfo->clockToDataOut_LoP = leftOfPoint;
535 dimmInfo->clockToDataOut_RoP = rightOfPoint;
536 DP (printf
537 ("Clock To Data Out: %d.%2d [ns]\n",
538 leftOfPoint, rightOfPoint));
539 /*dimmInfo->clockToDataOut */
540 break;
stroesec096c842004-12-16 18:21:17 +0000541/*------------------------------------------------------------------------------------------------------------------------------*/
542
543#ifdef CONFIG_ECC
wdenk07d7e6b2004-12-16 21:44:03 +0000544 case 11: /* Error Check Type */
545 dimmInfo->errorCheckType = data[i];
546 DP (printf
547 ("Error Check Type (0=NONE): %d\n",
548 dimmInfo->errorCheckType));
549 break;
stroesec096c842004-12-16 18:21:17 +0000550#endif
551/*------------------------------------------------------------------------------------------------------------------------------*/
552
wdenk07d7e6b2004-12-16 21:44:03 +0000553 case 12: /* Refresh Interval */
554 dimmInfo->RefreshInterval = data[i];
555 DP (printf
556 ("RefreshInterval (80= Self refresh Normal, 15.625us) : %x\n",
557 dimmInfo->RefreshInterval));
558 break;
stroesec096c842004-12-16 18:21:17 +0000559/*------------------------------------------------------------------------------------------------------------------------------*/
560
wdenk07d7e6b2004-12-16 21:44:03 +0000561 case 13: /* Sdram Width */
562 dimmInfo->sdramWidth = data[i];
563 DP (printf
564 ("Sdram Width: %d\n",
565 dimmInfo->sdramWidth));
566 break;
stroesec096c842004-12-16 18:21:17 +0000567/*------------------------------------------------------------------------------------------------------------------------------*/
568
wdenk07d7e6b2004-12-16 21:44:03 +0000569 case 14: /* Error Check Data Width */
570 dimmInfo->errorCheckDataWidth = data[i];
571 DP (printf
572 ("Error Check Data Width: %d\n",
573 dimmInfo->errorCheckDataWidth));
574 break;
stroesec096c842004-12-16 18:21:17 +0000575/*------------------------------------------------------------------------------------------------------------------------------*/
576
wdenk07d7e6b2004-12-16 21:44:03 +0000577 case 15: /* Minimum Clock Delay */
578 dimmInfo->minClkDelay = data[i];
579 DP (printf
580 ("Minimum Clock Delay: %d\n",
581 dimmInfo->minClkDelay));
582 break;
stroesec096c842004-12-16 18:21:17 +0000583/*------------------------------------------------------------------------------------------------------------------------------*/
584
wdenk07d7e6b2004-12-16 21:44:03 +0000585 case 16: /* Burst Length Supported */
586 /******-******-******-*******
587 * bit3 | bit2 | bit1 | bit0 *
588 *******-******-******-*******
589 burst length = * 8 | 4 | 2 | 1 *
590 *****************************
stroesec096c842004-12-16 18:21:17 +0000591
wdenk07d7e6b2004-12-16 21:44:03 +0000592 If for example bit0 and bit2 are set, the burst
593 length supported are 1 and 4. */
stroesec096c842004-12-16 18:21:17 +0000594
wdenk07d7e6b2004-12-16 21:44:03 +0000595 dimmInfo->burstLengthSupported = data[i];
stroesec096c842004-12-16 18:21:17 +0000596#ifdef DEBUG
wdenk07d7e6b2004-12-16 21:44:03 +0000597 DP (printf
598 ("Burst Length Supported: "));
599 if (dimmInfo->burstLengthSupported & 0x01)
600 DP (printf ("1, "));
601 if (dimmInfo->burstLengthSupported & 0x02)
602 DP (printf ("2, "));
603 if (dimmInfo->burstLengthSupported & 0x04)
604 DP (printf ("4, "));
605 if (dimmInfo->burstLengthSupported & 0x08)
606 DP (printf ("8, "));
607 DP (printf (" Bit \n"));
stroesec096c842004-12-16 18:21:17 +0000608#endif
wdenk07d7e6b2004-12-16 21:44:03 +0000609 break;
stroesec096c842004-12-16 18:21:17 +0000610/*------------------------------------------------------------------------------------------------------------------------------*/
611
wdenk07d7e6b2004-12-16 21:44:03 +0000612 case 17: /* Number Of Banks On Each Device */
613 dimmInfo->numOfBanksOnEachDevice = data[i];
614 DP (printf
615 ("Number Of Banks On Each Chip: %d\n",
616 dimmInfo->numOfBanksOnEachDevice));
617 break;
stroesec096c842004-12-16 18:21:17 +0000618/*------------------------------------------------------------------------------------------------------------------------------*/
619
wdenk07d7e6b2004-12-16 21:44:03 +0000620 case 18: /* Suported Cas Latencies */
stroesec096c842004-12-16 18:21:17 +0000621
wdenk07d7e6b2004-12-16 21:44:03 +0000622 /* DDR:
623 *******-******-******-******-******-******-******-*******
624 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
625 *******-******-******-******-******-******-******-*******
626 CAS = * TBD | TBD | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
627 *********************************************************
628 SDRAM:
629 *******-******-******-******-******-******-******-*******
630 * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
631 *******-******-******-******-******-******-******-*******
632 CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
633 ********************************************************/
634 dimmInfo->suportedCasLatencies = data[i];
stroesec096c842004-12-16 18:21:17 +0000635#ifdef DEBUG
wdenk07d7e6b2004-12-16 21:44:03 +0000636 DP (printf
637 ("Suported Cas Latencies: (CL) "));
638 if (dimmInfo->memoryType == 0) { /* SDRAM */
639 for (k = 0; k <= 7; k++) {
640 if (dimmInfo->
641 suportedCasLatencies & (1 << k))
642 DP (printf
643 ("%d, ",
644 k + 1));
645 }
stroesec096c842004-12-16 18:21:17 +0000646
wdenk07d7e6b2004-12-16 21:44:03 +0000647 } else { /* DDR-RAM */
stroesec096c842004-12-16 18:21:17 +0000648
wdenk07d7e6b2004-12-16 21:44:03 +0000649 if (dimmInfo->suportedCasLatencies & 1)
650 DP (printf ("1, "));
651 if (dimmInfo->suportedCasLatencies & 2)
652 DP (printf ("1.5, "));
653 if (dimmInfo->suportedCasLatencies & 4)
654 DP (printf ("2, "));
655 if (dimmInfo->suportedCasLatencies & 8)
656 DP (printf ("2.5, "));
657 if (dimmInfo->suportedCasLatencies & 16)
658 DP (printf ("3, "));
659 if (dimmInfo->suportedCasLatencies & 32)
660 DP (printf ("3.5, "));
661
662 }
663 DP (printf ("\n"));
stroesec096c842004-12-16 18:21:17 +0000664#endif
wdenk07d7e6b2004-12-16 21:44:03 +0000665 /* Calculating MAX CAS latency */
666 for (j = 7; j > 0; j--) {
667 if (((dimmInfo->
668 suportedCasLatencies >> j) & 0x1) ==
669 1) {
670 switch (dimmInfo->memoryType) {
671 case DDR:
672 /* CAS latency 1, 1.5, 2, 2.5, 3, 3.5 */
673 switch (j) {
674 case 7:
675 DP (printf
676 ("Max. Cas Latencies (DDR): ERROR !!!\n"));
677 dimmInfo->
678 maxClSupported_DDR
679 =
680 DDR_CL_FAULT;
681 hang ();
682 break;
683 case 6:
684 DP (printf
685 ("Max. Cas Latencies (DDR): ERROR !!!\n"));
686 dimmInfo->
687 maxClSupported_DDR
688 =
689 DDR_CL_FAULT;
690 hang ();
691 break;
692 case 5:
693 DP (printf
694 ("Max. Cas Latencies (DDR): 3.5 clk's\n"));
695 dimmInfo->
696 maxClSupported_DDR
697 = DDR_CL_3_5;
698 break;
699 case 4:
700 DP (printf
701 ("Max. Cas Latencies (DDR): 3 clk's \n"));
702 dimmInfo->
703 maxClSupported_DDR
704 = DDR_CL_3;
705 break;
706 case 3:
707 DP (printf
708 ("Max. Cas Latencies (DDR): 2.5 clk's \n"));
709 dimmInfo->
710 maxClSupported_DDR
711 = DDR_CL_2_5;
712 break;
713 case 2:
714 DP (printf
715 ("Max. Cas Latencies (DDR): 2 clk's \n"));
716 dimmInfo->
717 maxClSupported_DDR
718 = DDR_CL_2;
719 break;
720 case 1:
721 DP (printf
722 ("Max. Cas Latencies (DDR): 1.5 clk's \n"));
723 dimmInfo->
724 maxClSupported_DDR
725 = DDR_CL_1_5;
726 break;
727 }
728 dimmInfo->
729 maxCASlatencySupported_LoP
730 =
731 1 +
732 (int) (5 * j / 10);
733 if (((5 * j) % 10) != 0)
734 dimmInfo->
735 maxCASlatencySupported_RoP
736 = 5;
737 else
738 dimmInfo->
739 maxCASlatencySupported_RoP
740 = 0;
741 DP (printf
742 ("Max. Cas Latencies (DDR LoP.RoP Notation): %d.%d \n",
743 dimmInfo->
744 maxCASlatencySupported_LoP,
745 dimmInfo->
746 maxCASlatencySupported_RoP));
747 break;
748 case SDRAM:
749 /* CAS latency 1, 2, 3, 4, 5, 6, 7 */
750 dimmInfo->maxClSupported_SD = j; /* Cas Latency DDR-RAM Coded */
751 DP (printf
752 ("Max. Cas Latencies (SD): %d\n",
753 dimmInfo->
754 maxClSupported_SD));
755 dimmInfo->
756 maxCASlatencySupported_LoP
757 = j;
758 dimmInfo->
759 maxCASlatencySupported_RoP
760 = 0;
761 DP (printf
762 ("Max. Cas Latencies (DDR LoP.RoP Notation): %d.%d \n",
763 dimmInfo->
764 maxCASlatencySupported_LoP,
765 dimmInfo->
766 maxCASlatencySupported_RoP));
767 break;
768 }
769 break;
770 }
stroesec096c842004-12-16 18:21:17 +0000771 }
wdenk07d7e6b2004-12-16 21:44:03 +0000772 break;
stroesec096c842004-12-16 18:21:17 +0000773/*------------------------------------------------------------------------------------------------------------------------------*/
774
wdenk07d7e6b2004-12-16 21:44:03 +0000775 case 21: /* Buffered Address And Control Inputs */
776 DP (printf ("\nModul Attributes (SPD Byte 21): \n"));
777 dimmInfo->bufferedAddrAndControlInputs =
778 data[i] & BIT0;
779 dimmInfo->registeredAddrAndControlInputs =
780 (data[i] & BIT1) >> 1;
781 dimmInfo->onCardPLL = (data[i] & BIT2) >> 2;
782 dimmInfo->bufferedDQMBinputs = (data[i] & BIT3) >> 3;
783 dimmInfo->registeredDQMBinputs =
784 (data[i] & BIT4) >> 4;
785 dimmInfo->differentialClockInput =
786 (data[i] & BIT5) >> 5;
787 dimmInfo->redundantRowAddressing =
788 (data[i] & BIT6) >> 6;
stroesec096c842004-12-16 18:21:17 +0000789#ifdef DEBUG
wdenk07d7e6b2004-12-16 21:44:03 +0000790 if (dimmInfo->bufferedAddrAndControlInputs == 1)
791 DP (printf
792 (" - Buffered Address/Control Input: Yes \n"));
793 else
794 DP (printf
795 (" - Buffered Address/Control Input: No \n"));
stroesec096c842004-12-16 18:21:17 +0000796
wdenk07d7e6b2004-12-16 21:44:03 +0000797 if (dimmInfo->registeredAddrAndControlInputs == 1)
798 DP (printf
799 (" - Registered Address/Control Input: Yes \n"));
800 else
801 DP (printf
802 (" - Registered Address/Control Input: No \n"));
stroesec096c842004-12-16 18:21:17 +0000803
wdenk07d7e6b2004-12-16 21:44:03 +0000804 if (dimmInfo->onCardPLL == 1)
805 DP (printf
806 (" - On-Card PLL (clock): Yes \n"));
807 else
808 DP (printf
809 (" - On-Card PLL (clock): No \n"));
stroesec096c842004-12-16 18:21:17 +0000810
wdenk07d7e6b2004-12-16 21:44:03 +0000811 if (dimmInfo->bufferedDQMBinputs == 1)
812 DP (printf
813 (" - Bufferd DQMB Inputs: Yes \n"));
814 else
815 DP (printf
816 (" - Bufferd DQMB Inputs: No \n"));
stroesec096c842004-12-16 18:21:17 +0000817
wdenk07d7e6b2004-12-16 21:44:03 +0000818 if (dimmInfo->registeredDQMBinputs == 1)
819 DP (printf
820 (" - Registered DQMB Inputs: Yes \n"));
821 else
822 DP (printf
823 (" - Registered DQMB Inputs: No \n"));
stroesec096c842004-12-16 18:21:17 +0000824
wdenk07d7e6b2004-12-16 21:44:03 +0000825 if (dimmInfo->differentialClockInput == 1)
826 DP (printf
827 (" - Differential Clock Input: Yes \n"));
828 else
829 DP (printf
830 (" - Differential Clock Input: No \n"));
stroesec096c842004-12-16 18:21:17 +0000831
wdenk07d7e6b2004-12-16 21:44:03 +0000832 if (dimmInfo->redundantRowAddressing == 1)
833 DP (printf
834 (" - redundant Row Addressing: Yes \n"));
835 else
836 DP (printf
837 (" - redundant Row Addressing: No \n"));
stroesec096c842004-12-16 18:21:17 +0000838
839#endif
wdenk07d7e6b2004-12-16 21:44:03 +0000840 break;
stroesec096c842004-12-16 18:21:17 +0000841/*------------------------------------------------------------------------------------------------------------------------------*/
842
wdenk07d7e6b2004-12-16 21:44:03 +0000843 case 22: /* Suported AutoPreCharge */
844 DP (printf ("\nModul Attributes (SPD Byte 22): \n"));
845 dimmInfo->suportedEarlyRasPreCharge = data[i] & BIT0;
846 dimmInfo->suportedAutoPreCharge =
847 (data[i] & BIT1) >> 1;
848 dimmInfo->suportedPreChargeAll =
849 (data[i] & BIT2) >> 2;
850 dimmInfo->suportedWrite1ReadBurst =
851 (data[i] & BIT3) >> 3;
852 dimmInfo->suported5PercentLowVCC =
853 (data[i] & BIT4) >> 4;
854 dimmInfo->suported5PercentUpperVCC =
855 (data[i] & BIT5) >> 5;
stroesec096c842004-12-16 18:21:17 +0000856#ifdef DEBUG
wdenk07d7e6b2004-12-16 21:44:03 +0000857 if (dimmInfo->suportedEarlyRasPreCharge == 1)
858 DP (printf
859 (" - Early Ras Precharge: Yes \n"));
860 else
861 DP (printf
862 (" - Early Ras Precharge: No \n"));
stroesec096c842004-12-16 18:21:17 +0000863
wdenk07d7e6b2004-12-16 21:44:03 +0000864 if (dimmInfo->suportedAutoPreCharge == 1)
865 DP (printf
866 (" - AutoPreCharge: Yes \n"));
867 else
868 DP (printf
869 (" - AutoPreCharge: No \n"));
stroesec096c842004-12-16 18:21:17 +0000870
wdenk07d7e6b2004-12-16 21:44:03 +0000871 if (dimmInfo->suportedPreChargeAll == 1)
872 DP (printf
873 (" - Precharge All: Yes \n"));
874 else
875 DP (printf
876 (" - Precharge All: No \n"));
stroesec096c842004-12-16 18:21:17 +0000877
wdenk07d7e6b2004-12-16 21:44:03 +0000878 if (dimmInfo->suportedWrite1ReadBurst == 1)
879 DP (printf
880 (" - Write 1/ReadBurst: Yes \n"));
881 else
882 DP (printf
883 (" - Write 1/ReadBurst: No \n"));
stroesec096c842004-12-16 18:21:17 +0000884
wdenk07d7e6b2004-12-16 21:44:03 +0000885 if (dimmInfo->suported5PercentLowVCC == 1)
886 DP (printf
887 (" - lower VCC tolerance: 5 Percent \n"));
888 else
889 DP (printf
890 (" - lower VCC tolerance: 10 Percent \n"));
stroesec096c842004-12-16 18:21:17 +0000891
wdenk07d7e6b2004-12-16 21:44:03 +0000892 if (dimmInfo->suported5PercentUpperVCC == 1)
893 DP (printf
894 (" - upper VCC tolerance: 5 Percent \n"));
895 else
896 DP (printf
897 (" - upper VCC tolerance: 10 Percent \n"));
stroesec096c842004-12-16 18:21:17 +0000898
899#endif
wdenk07d7e6b2004-12-16 21:44:03 +0000900 break;
stroesec096c842004-12-16 18:21:17 +0000901/*------------------------------------------------------------------------------------------------------------------------------*/
902
wdenk07d7e6b2004-12-16 21:44:03 +0000903 case 23: /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
904 shift = (dimmInfo->memoryType == DDR) ? 4 : 2;
905 mult = (dimmInfo->memoryType == DDR) ? 10 : 25;
906 maskLeftOfPoint =
907 (dimmInfo->memoryType == DDR) ? 0xf0 : 0xfc;
908 maskRightOfPoint =
909 (dimmInfo->memoryType == DDR) ? 0xf : 0x03;
910 leftOfPoint = (data[i] & maskLeftOfPoint) >> shift;
911 rightOfPoint = (data[i] & maskRightOfPoint) * mult;
912 dimmInfo->minimumCycleTimeAtMaxCasLatancyMinus1_LoP =
913 leftOfPoint;
914 dimmInfo->minimumCycleTimeAtMaxCasLatancyMinus1_RoP =
915 rightOfPoint;
916 DP (printf
917 ("Minimum Cycle Time At 2nd highest CasLatancy (0 = Not supported): %d.%d [ns]\n",
918 leftOfPoint, rightOfPoint));
919 /*dimmInfo->minimumCycleTimeAtMaxCasLatancy */
920 break;
stroesec096c842004-12-16 18:21:17 +0000921/*------------------------------------------------------------------------------------------------------------------------------*/
922
wdenk07d7e6b2004-12-16 21:44:03 +0000923 case 24: /* Clock To Data Out 2nd highest Cas Latency Value */
924 div = (dimmInfo->memoryType == DDR) ? 100 : 10;
925 time_tmp =
926 (((data[i] & 0xf0) >> 4) * 10) +
927 ((data[i] & 0x0f));
928 leftOfPoint = time_tmp / div;
929 rightOfPoint = time_tmp % div;
930 dimmInfo->clockToDataOutMinus1_LoP = leftOfPoint;
931 dimmInfo->clockToDataOutMinus1_RoP = rightOfPoint;
932 DP (printf
933 ("Clock To Data Out (2nd CL value): %d.%2d [ns]\n",
934 leftOfPoint, rightOfPoint));
935 break;
stroesec096c842004-12-16 18:21:17 +0000936/*------------------------------------------------------------------------------------------------------------------------------*/
937
wdenk07d7e6b2004-12-16 21:44:03 +0000938 case 25: /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
939 shift = (dimmInfo->memoryType == DDR) ? 4 : 2;
940 mult = (dimmInfo->memoryType == DDR) ? 10 : 25;
941 maskLeftOfPoint =
942 (dimmInfo->memoryType == DDR) ? 0xf0 : 0xfc;
943 maskRightOfPoint =
944 (dimmInfo->memoryType == DDR) ? 0xf : 0x03;
945 leftOfPoint = (data[i] & maskLeftOfPoint) >> shift;
946 rightOfPoint = (data[i] & maskRightOfPoint) * mult;
947 dimmInfo->minimumCycleTimeAtMaxCasLatancyMinus2_LoP =
948 leftOfPoint;
949 dimmInfo->minimumCycleTimeAtMaxCasLatancyMinus2_RoP =
950 rightOfPoint;
951 DP (printf
952 ("Minimum Cycle Time At 3rd highest CasLatancy (0 = Not supported): %d.%d [ns]\n",
953 leftOfPoint, rightOfPoint));
954 /*dimmInfo->minimumCycleTimeAtMaxCasLatancy */
955 break;
stroesec096c842004-12-16 18:21:17 +0000956/*------------------------------------------------------------------------------------------------------------------------------*/
957
wdenk07d7e6b2004-12-16 21:44:03 +0000958 case 26: /* Clock To Data Out 3rd highest Cas Latency Value */
959 div = (dimmInfo->memoryType == DDR) ? 100 : 10;
960 time_tmp =
961 (((data[i] & 0xf0) >> 4) * 10) +
962 ((data[i] & 0x0f));
963 leftOfPoint = time_tmp / div;
964 rightOfPoint = time_tmp % div;
965 dimmInfo->clockToDataOutMinus2_LoP = leftOfPoint;
966 dimmInfo->clockToDataOutMinus2_RoP = rightOfPoint;
967 DP (printf
968 ("Clock To Data Out (3rd CL value): %d.%2d [ns]\n",
969 leftOfPoint, rightOfPoint));
970 break;
stroesec096c842004-12-16 18:21:17 +0000971/*------------------------------------------------------------------------------------------------------------------------------*/
972
wdenk07d7e6b2004-12-16 21:44:03 +0000973 case 27: /* Minimum Row Precharge Time */
974 shift = (dimmInfo->memoryType == DDR) ? 2 : 0;
975 maskLeftOfPoint =
976 (dimmInfo->memoryType == DDR) ? 0xfc : 0xff;
977 maskRightOfPoint =
978 (dimmInfo->memoryType == DDR) ? 0x03 : 0x00;
979 leftOfPoint = ((data[i] & maskLeftOfPoint) >> shift);
980 rightOfPoint = (data[i] & maskRightOfPoint) * 25;
stroesec096c842004-12-16 18:21:17 +0000981
wdenk07d7e6b2004-12-16 21:44:03 +0000982 dimmInfo->minRowPrechargeTime = ((leftOfPoint * 100) + rightOfPoint); /* measured in n times 10ps Intervals */
983 trp_clocks =
984 (dimmInfo->minRowPrechargeTime +
985 (tmemclk - 1)) / tmemclk;
986 DP (printf
987 ("*** 1 clock cycle = %ld 10ps intervalls = %ld.%ld ns****\n",
988 tmemclk, tmemclk / 100, tmemclk % 100));
989 DP (printf
990 ("Minimum Row Precharge Time [ns]: %d.%2d = in Clk cycles %d\n",
991 leftOfPoint, rightOfPoint, trp_clocks));
992 break;
stroesec096c842004-12-16 18:21:17 +0000993/*------------------------------------------------------------------------------------------------------------------------------*/
994
wdenk07d7e6b2004-12-16 21:44:03 +0000995 case 28: /* Minimum Row Active to Row Active Time */
996 shift = (dimmInfo->memoryType == DDR) ? 2 : 0;
997 maskLeftOfPoint =
998 (dimmInfo->memoryType == DDR) ? 0xfc : 0xff;
999 maskRightOfPoint =
1000 (dimmInfo->memoryType == DDR) ? 0x03 : 0x00;
1001 leftOfPoint = ((data[i] & maskLeftOfPoint) >> shift);
1002 rightOfPoint = (data[i] & maskRightOfPoint) * 25;
stroesec096c842004-12-16 18:21:17 +00001003
wdenk07d7e6b2004-12-16 21:44:03 +00001004 dimmInfo->minRowActiveRowActiveDelay = ((leftOfPoint * 100) + rightOfPoint); /* measured in 100ns Intervals */
1005 trrd_clocks =
1006 (dimmInfo->minRowActiveRowActiveDelay +
1007 (tmemclk - 1)) / tmemclk;
1008 DP (printf
1009 ("Minimum Row Active -To- Row Active Delay [ns]: %d.%2d = in Clk cycles %d\n",
1010 leftOfPoint, rightOfPoint, trp_clocks));
1011 break;
stroesec096c842004-12-16 18:21:17 +00001012/*------------------------------------------------------------------------------------------------------------------------------*/
1013
wdenk07d7e6b2004-12-16 21:44:03 +00001014 case 29: /* Minimum Ras-To-Cas Delay */
1015 shift = (dimmInfo->memoryType == DDR) ? 2 : 0;
1016 maskLeftOfPoint =
1017 (dimmInfo->memoryType == DDR) ? 0xfc : 0xff;
1018 maskRightOfPoint =
1019 (dimmInfo->memoryType == DDR) ? 0x03 : 0x00;
1020 leftOfPoint = ((data[i] & maskLeftOfPoint) >> shift);
1021 rightOfPoint = (data[i] & maskRightOfPoint) * 25;
stroesec096c842004-12-16 18:21:17 +00001022
wdenk07d7e6b2004-12-16 21:44:03 +00001023 dimmInfo->minRowActiveRowActiveDelay = ((leftOfPoint * 100) + rightOfPoint); /* measured in 100ns Intervals */
1024 trcd_clocks =
1025 (dimmInfo->minRowActiveRowActiveDelay +
1026 (tmemclk - 1)) / tmemclk;
1027 DP (printf
1028 ("Minimum Ras-To-Cas Delay [ns]: %d.%2d = in Clk cycles %d\n",
1029 leftOfPoint, rightOfPoint, trp_clocks));
1030 break;
stroesec096c842004-12-16 18:21:17 +00001031/*------------------------------------------------------------------------------------------------------------------------------*/
1032
wdenk07d7e6b2004-12-16 21:44:03 +00001033 case 30: /* Minimum Ras Pulse Width */
1034 dimmInfo->minRasPulseWidth = data[i];
1035 tras_clocks =
1036 (NSto10PS (data[i]) +
1037 (tmemclk - 1)) / tmemclk;
1038 DP (printf
1039 ("Minimum Ras Pulse Width [ns]: %d = in Clk cycles %d\n",
1040 dimmInfo->minRasPulseWidth, tras_clocks));
stroesec096c842004-12-16 18:21:17 +00001041
wdenk07d7e6b2004-12-16 21:44:03 +00001042 break;
stroesec096c842004-12-16 18:21:17 +00001043/*------------------------------------------------------------------------------------------------------------------------------*/
1044
wdenk07d7e6b2004-12-16 21:44:03 +00001045 case 31: /* Module Bank Density */
1046 dimmInfo->moduleBankDensity = data[i];
1047 DP (printf
1048 ("Module Bank Density: %d\n",
1049 dimmInfo->moduleBankDensity));
stroesec096c842004-12-16 18:21:17 +00001050#ifdef DEBUG
wdenk07d7e6b2004-12-16 21:44:03 +00001051 DP (printf
1052 ("*** Offered Densities (more than 1 = Multisize-Module): "));
1053 {
1054 if (dimmInfo->moduleBankDensity & 1)
1055 DP (printf ("4MB, "));
1056 if (dimmInfo->moduleBankDensity & 2)
1057 DP (printf ("8MB, "));
1058 if (dimmInfo->moduleBankDensity & 4)
1059 DP (printf ("16MB, "));
1060 if (dimmInfo->moduleBankDensity & 8)
1061 DP (printf ("32MB, "));
1062 if (dimmInfo->moduleBankDensity & 16)
1063 DP (printf ("64MB, "));
1064 if (dimmInfo->moduleBankDensity & 32)
1065 DP (printf ("128MB, "));
1066 if ((dimmInfo->moduleBankDensity & 64)
1067 || (dimmInfo->moduleBankDensity & 128)) {
1068 DP (printf ("ERROR, "));
1069 hang ();
1070 }
stroesec096c842004-12-16 18:21:17 +00001071 }
wdenk07d7e6b2004-12-16 21:44:03 +00001072 DP (printf ("\n"));
stroesec096c842004-12-16 18:21:17 +00001073#endif
wdenk07d7e6b2004-12-16 21:44:03 +00001074 break;
stroesec096c842004-12-16 18:21:17 +00001075/*------------------------------------------------------------------------------------------------------------------------------*/
1076
wdenk07d7e6b2004-12-16 21:44:03 +00001077 case 32: /* Address And Command Setup Time (measured in ns/1000) */
1078 sign = 1;
1079 switch (dimmInfo->memoryType) {
1080 case DDR:
1081 time_tmp =
1082 (((data[i] & 0xf0) >> 4) * 10) +
1083 ((data[i] & 0x0f));
1084 leftOfPoint = time_tmp / 100;
1085 rightOfPoint = time_tmp % 100;
1086 break;
1087 case SDRAM:
1088 leftOfPoint = (data[i] & 0xf0) >> 4;
1089 if (leftOfPoint > 7) {
1090 leftOfPoint = data[i] & 0x70 >> 4;
1091 sign = -1;
1092 }
1093 rightOfPoint = (data[i] & 0x0f);
1094 break;
1095 }
1096 dimmInfo->addrAndCommandSetupTime =
1097 (leftOfPoint * 100 + rightOfPoint) * sign;
1098 DP (printf
1099 ("Address And Command Setup Time [ns]: %d.%d\n",
1100 sign * leftOfPoint, rightOfPoint));
1101 break;
stroesec096c842004-12-16 18:21:17 +00001102/*------------------------------------------------------------------------------------------------------------------------------*/
1103
wdenk07d7e6b2004-12-16 21:44:03 +00001104 case 33: /* Address And Command Hold Time */
1105 sign = 1;
1106 switch (dimmInfo->memoryType) {
1107 case DDR:
1108 time_tmp =
1109 (((data[i] & 0xf0) >> 4) * 10) +
1110 ((data[i] & 0x0f));
1111 leftOfPoint = time_tmp / 100;
1112 rightOfPoint = time_tmp % 100;
1113 break;
1114 case SDRAM:
1115 leftOfPoint = (data[i] & 0xf0) >> 4;
1116 if (leftOfPoint > 7) {
1117 leftOfPoint = data[i] & 0x70 >> 4;
1118 sign = -1;
1119 }
1120 rightOfPoint = (data[i] & 0x0f);
1121 break;
1122 }
1123 dimmInfo->addrAndCommandHoldTime =
1124 (leftOfPoint * 100 + rightOfPoint) * sign;
1125 DP (printf
1126 ("Address And Command Hold Time [ns]: %d.%d\n",
1127 sign * leftOfPoint, rightOfPoint));
1128 break;
stroesec096c842004-12-16 18:21:17 +00001129/*------------------------------------------------------------------------------------------------------------------------------*/
1130
wdenk07d7e6b2004-12-16 21:44:03 +00001131 case 34: /* Data Input Setup Time */
1132 sign = 1;
1133 switch (dimmInfo->memoryType) {
1134 case DDR:
1135 time_tmp =
1136 (((data[i] & 0xf0) >> 4) * 10) +
1137 ((data[i] & 0x0f));
1138 leftOfPoint = time_tmp / 100;
1139 rightOfPoint = time_tmp % 100;
1140 break;
1141 case SDRAM:
1142 leftOfPoint = (data[i] & 0xf0) >> 4;
1143 if (leftOfPoint > 7) {
1144 leftOfPoint = data[i] & 0x70 >> 4;
1145 sign = -1;
1146 }
1147 rightOfPoint = (data[i] & 0x0f);
1148 break;
1149 }
1150 dimmInfo->dataInputSetupTime =
1151 (leftOfPoint * 100 + rightOfPoint) * sign;
1152 DP (printf
1153 ("Data Input Setup Time [ns]: %d.%d\n",
1154 sign * leftOfPoint, rightOfPoint));
1155 break;
stroesec096c842004-12-16 18:21:17 +00001156/*------------------------------------------------------------------------------------------------------------------------------*/
1157
wdenk07d7e6b2004-12-16 21:44:03 +00001158 case 35: /* Data Input Hold Time */
1159 sign = 1;
1160 switch (dimmInfo->memoryType) {
1161 case DDR:
1162 time_tmp =
1163 (((data[i] & 0xf0) >> 4) * 10) +
1164 ((data[i] & 0x0f));
1165 leftOfPoint = time_tmp / 100;
1166 rightOfPoint = time_tmp % 100;
1167 break;
1168 case SDRAM:
1169 leftOfPoint = (data[i] & 0xf0) >> 4;
1170 if (leftOfPoint > 7) {
1171 leftOfPoint = data[i] & 0x70 >> 4;
1172 sign = -1;
1173 }
1174 rightOfPoint = (data[i] & 0x0f);
1175 break;
1176 }
1177 dimmInfo->dataInputHoldTime =
1178 (leftOfPoint * 100 + rightOfPoint) * sign;
1179 DP (printf
1180 ("Data Input Hold Time [ns]: %d.%d\n\n",
1181 sign * leftOfPoint, rightOfPoint));
1182 break;
stroesec096c842004-12-16 18:21:17 +00001183/*------------------------------------------------------------------------------------------------------------------------------*/
wdenk07d7e6b2004-12-16 21:44:03 +00001184 }
1185 }
1186 /* calculating the sdram density */
1187 for (i = 0;
1188 i < dimmInfo->numOfRowAddresses + dimmInfo->numOfColAddresses;
1189 i++) {
1190 density = density * 2;
1191 }
1192 dimmInfo->deviceDensity = density * dimmInfo->numOfBanksOnEachDevice *
1193 dimmInfo->sdramWidth;
1194 dimmInfo->numberOfDevices =
1195 (dimmInfo->dataWidth / dimmInfo->sdramWidth) *
1196 dimmInfo->numOfModuleBanks;
1197 devicesForErrCheck =
1198 (dimmInfo->dataWidth - 64) / dimmInfo->sdramWidth;
1199 if ((dimmInfo->errorCheckType == 0x1)
1200 || (dimmInfo->errorCheckType == 0x2)
1201 || (dimmInfo->errorCheckType == 0x3)) {
1202 dimmInfo->size =
1203 (dimmInfo->deviceDensity / 8) *
1204 (dimmInfo->numberOfDevices - devicesForErrCheck);
1205 } else {
1206 dimmInfo->size =
1207 (dimmInfo->deviceDensity / 8) *
1208 dimmInfo->numberOfDevices;
1209 }
stroesec096c842004-12-16 18:21:17 +00001210
wdenk07d7e6b2004-12-16 21:44:03 +00001211 /* compute the module DRB size */
1212 tmp = (1 <<
1213 (dimmInfo->numOfRowAddresses + dimmInfo->numOfColAddresses));
1214 tmp *= dimmInfo->numOfModuleBanks;
1215 tmp *= dimmInfo->sdramWidth;
1216 tmp = tmp >> 24; /* div by 0x4000000 (64M) */
1217 dimmInfo->drb_size = (uchar) tmp;
1218 DP (printf ("Module DRB size (n*64Mbit): %d\n", dimmInfo->drb_size));
stroesec096c842004-12-16 18:21:17 +00001219
1220 /* try a CAS latency of 3 first... */
1221
1222 /* bit 1 is CL2, bit 2 is CL3 */
1223 supp_cal = (dimmInfo->suportedCasLatencies & 0x1c) >> 1;
1224
1225 cal_val = 0;
1226 if (supp_cal & 8) {
wdenk07d7e6b2004-12-16 21:44:03 +00001227 if (NS10to10PS (data[9]) <= tmemclk)
stroesec096c842004-12-16 18:21:17 +00001228 cal_val = 6;
1229 }
1230 if (supp_cal & 4) {
wdenk07d7e6b2004-12-16 21:44:03 +00001231 if (NS10to10PS (data[9]) <= tmemclk)
stroesec096c842004-12-16 18:21:17 +00001232 cal_val = 5;
1233 }
1234
1235 /* then 2... */
1236 if (supp_cal & 2) {
wdenk07d7e6b2004-12-16 21:44:03 +00001237 if (NS10to10PS (data[23]) <= tmemclk)
stroesec096c842004-12-16 18:21:17 +00001238 cal_val = 4;
1239 }
1240
wdenk07d7e6b2004-12-16 21:44:03 +00001241 DP (printf ("cal_val = %d\n", cal_val * 5));
stroesec096c842004-12-16 18:21:17 +00001242
1243 /* bummer, did't work... */
1244 if (cal_val == 0) {
wdenk07d7e6b2004-12-16 21:44:03 +00001245 DP (printf ("Couldn't find a good CAS latency\n"));
1246 hang ();
stroesec096c842004-12-16 18:21:17 +00001247 return 0;
1248 }
1249
wdenk07d7e6b2004-12-16 21:44:03 +00001250 return true;
stroesec096c842004-12-16 18:21:17 +00001251}
1252
1253/* sets up the GT properly with information passed in */
wdenk07d7e6b2004-12-16 21:44:03 +00001254int setup_sdram (AUX_MEM_DIMM_INFO * info)
stroesec096c842004-12-16 18:21:17 +00001255{
1256 ulong tmp, check;
wdenk07d7e6b2004-12-16 21:44:03 +00001257 ulong tmp_sdram_mode = 0; /* 0x141c */
1258 ulong tmp_dunit_control_low = 0; /* 0x1404 */
stroesec096c842004-12-16 18:21:17 +00001259 int i;
1260
1261 /* sanity checking */
wdenk07d7e6b2004-12-16 21:44:03 +00001262 if (!info->numOfModuleBanks) {
1263 printf ("setup_sdram called with 0 banks\n");
stroesec096c842004-12-16 18:21:17 +00001264 return 1;
1265 }
1266
1267 /* delay line */
1268
1269 /* Program the GT with the discovered data */
1270 if (info->registeredAddrAndControlInputs == true)
wdenk07d7e6b2004-12-16 21:44:03 +00001271 DP (printf
1272 ("Module is registered, but we do not support registered Modules !!!\n"));
stroesec096c842004-12-16 18:21:17 +00001273
1274
1275 /* delay line */
wdenk07d7e6b2004-12-16 21:44:03 +00001276 set_dfcdlInit (); /* may be its not needed */
1277 DP (printf ("Delay line set done\n"));
stroesec096c842004-12-16 18:21:17 +00001278
wdenk07d7e6b2004-12-16 21:44:03 +00001279 /* set SDRAM mode NOP */ /* To_do check it */
1280 GT_REG_WRITE (SDRAM_OPERATION, 0x5);
1281 while (GTREGREAD (SDRAM_OPERATION) != 0) {
1282 DP (printf
1283 ("\n*** SDRAM_OPERATION 1418: Module still busy ... please wait... ***\n"));
1284 }
stroesec096c842004-12-16 18:21:17 +00001285
1286 /* SDRAM configuration */
wdenk07d7e6b2004-12-16 21:44:03 +00001287 GT_REG_WRITE (SDRAM_CONFIG, 0x58200400);
1288 DP (printf ("sdram_conf 0x1400: %08x\n", GTREGREAD (SDRAM_CONFIG)));
stroesec096c842004-12-16 18:21:17 +00001289
wdenk07d7e6b2004-12-16 21:44:03 +00001290 /* SDRAM open pages controll keep open as much as I can */
1291 GT_REG_WRITE (SDRAM_OPEN_PAGES_CONTROL, 0x0);
1292 DP (printf
1293 ("sdram_open_pages_controll 0x1414: %08x\n",
1294 GTREGREAD (SDRAM_OPEN_PAGES_CONTROL)));
stroesec096c842004-12-16 18:21:17 +00001295
1296
1297 /* SDRAM D_UNIT_CONTROL_LOW 0x1404 */
wdenk07d7e6b2004-12-16 21:44:03 +00001298 tmp = (GTREGREAD (D_UNIT_CONTROL_LOW) & 0x01); /* Clock Domain Sync from power on reset */
stroesec096c842004-12-16 18:21:17 +00001299 if (tmp == 0)
wdenk07d7e6b2004-12-16 21:44:03 +00001300 DP (printf ("Core Signals are sync (by HW-Setting)!!!\n"));
stroesec096c842004-12-16 18:21:17 +00001301 else
wdenk07d7e6b2004-12-16 21:44:03 +00001302 DP (printf
1303 ("Core Signals syncs. are bypassed (by HW-Setting)!!!\n"));
stroesec096c842004-12-16 18:21:17 +00001304
wdenk07d7e6b2004-12-16 21:44:03 +00001305 /* SDRAM set CAS Lentency according to SPD information */
1306 switch (info->memoryType) {
1307 case SDRAM:
1308 DP (printf ("### SD-RAM not supported yet !!!\n"));
1309 hang ();
1310 /* ToDo fill SD-RAM if needed !!!!! */
1311 break;
stroesec096c842004-12-16 18:21:17 +00001312
wdenk07d7e6b2004-12-16 21:44:03 +00001313 case DDR:
1314 DP (printf ("### SET-CL for DDR-RAM\n"));
stroesec096c842004-12-16 18:21:17 +00001315
wdenk07d7e6b2004-12-16 21:44:03 +00001316 switch (info->maxClSupported_DDR) {
1317 case DDR_CL_3:
1318 tmp_dunit_control_low = 0x3c000000; /* Read-Data sampled on falling edge of Clk */
1319 tmp_sdram_mode = 0x32; /* CL=3 Burstlength = 4 */
1320 DP (printf
1321 ("Max. CL is 3 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
1322 tmp_sdram_mode, tmp_dunit_control_low));
1323 break;
stroesec096c842004-12-16 18:21:17 +00001324
wdenk07d7e6b2004-12-16 21:44:03 +00001325 case DDR_CL_2_5:
1326 if (tmp == 1) { /* clocks sync */
1327 tmp_dunit_control_low = 0x24000000; /* Read-Data sampled on falling edge of Clk */
1328 tmp_sdram_mode = 0x62; /* CL=2,5 Burstlength = 4 */
1329 DP (printf
1330 ("Max. CL is 2,5s CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
1331 tmp_sdram_mode, tmp_dunit_control_low));
1332 } else { /* clk sync. bypassed */
stroesec096c842004-12-16 18:21:17 +00001333
wdenk07d7e6b2004-12-16 21:44:03 +00001334 tmp_dunit_control_low = 0x03000000; /* Read-Data sampled on rising edge of Clk */
1335 tmp_sdram_mode = 0x62; /* CL=2,5 Burstlength = 4 */
1336 DP (printf
1337 ("Max. CL is 2,5 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
1338 tmp_sdram_mode, tmp_dunit_control_low));
1339 }
1340 break;
stroesec096c842004-12-16 18:21:17 +00001341
wdenk07d7e6b2004-12-16 21:44:03 +00001342 case DDR_CL_2:
1343 if (tmp == 1) { /* Sync */
1344 tmp_dunit_control_low = 0x03000000; /* Read-Data sampled on rising edge of Clk */
1345 tmp_sdram_mode = 0x22; /* CL=2 Burstlength = 4 */
1346 DP (printf
1347 ("Max. CL is 2s CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
1348 tmp_sdram_mode, tmp_dunit_control_low));
1349 } else { /* Not sync. */
stroesec096c842004-12-16 18:21:17 +00001350
wdenk07d7e6b2004-12-16 21:44:03 +00001351 tmp_dunit_control_low = 0x3b000000; /* Read-Data sampled on rising edge of Clk */
1352 tmp_sdram_mode = 0x22; /* CL=2 Burstlength = 4 */
1353 DP (printf
1354 ("Max. CL is 2 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
1355 tmp_sdram_mode, tmp_dunit_control_low));
1356 }
1357 break;
1358
1359 case DDR_CL_1_5:
1360 if (tmp == 1) { /* Sync */
1361 tmp_dunit_control_low = 0x23000000; /* Read-Data sampled on falling edge of Clk */
1362 tmp_sdram_mode = 0x52; /* CL=1,5 Burstlength = 4 */
1363 DP (printf
1364 ("Max. CL is 1,5s CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
1365 tmp_sdram_mode, tmp_dunit_control_low));
1366 } else { /* not sync */
1367
1368 tmp_dunit_control_low = 0x1a000000; /* Read-Data sampled on rising edge of Clk */
1369 tmp_sdram_mode = 0x52; /* CL=1,5 Burstlength = 4 */
1370 DP (printf
1371 ("Max. CL is 1,5 CLKs 0x141c= %08lx, 0x1404 = %08lx\n",
1372 tmp_sdram_mode, tmp_dunit_control_low));
1373 }
1374 break;
1375
1376 default:
1377 printf ("Max. CL is out of range %d\n",
1378 info->maxClSupported_DDR);
1379 hang ();
1380 break;
1381 }
stroesec096c842004-12-16 18:21:17 +00001382 break;
wdenk07d7e6b2004-12-16 21:44:03 +00001383 }
stroesec096c842004-12-16 18:21:17 +00001384
1385 /* Write results of CL detection procedure */
wdenk07d7e6b2004-12-16 21:44:03 +00001386 GT_REG_WRITE (SDRAM_MODE, tmp_sdram_mode);
1387 /* set SDRAM mode SetCommand 0x1418 */
1388 GT_REG_WRITE (SDRAM_OPERATION, 0x3);
1389 while (GTREGREAD (SDRAM_OPERATION) != 0) {
1390 DP (printf
1391 ("\n*** SDRAM_OPERATION 1418 after SDRAM_MODE: Module still busy ... please wait... ***\n"));
1392 }
stroesec096c842004-12-16 18:21:17 +00001393
1394
1395 /* SDRAM D_UNIT_CONTROL_LOW 0x1404 */
wdenk07d7e6b2004-12-16 21:44:03 +00001396 tmp = (GTREGREAD (D_UNIT_CONTROL_LOW) & 0x01); /* Clock Domain Sync from power on reset */
1397 if (tmp != 1) { /*clocks are not sync */
1398 /* asyncmode */
1399 GT_REG_WRITE (D_UNIT_CONTROL_LOW,
1400 (GTREGREAD (D_UNIT_CONTROL_LOW) & 0x7F) |
1401 0x18110780 | tmp_dunit_control_low);
1402 } else {
1403 /* syncmode */
1404 GT_REG_WRITE (D_UNIT_CONTROL_LOW,
1405 (GTREGREAD (D_UNIT_CONTROL_LOW) & 0x7F) |
1406 0x00110000 | tmp_dunit_control_low);
1407 }
stroesec096c842004-12-16 18:21:17 +00001408
wdenk07d7e6b2004-12-16 21:44:03 +00001409 /* set SDRAM mode SetCommand 0x1418 */
1410 GT_REG_WRITE (SDRAM_OPERATION, 0x3);
1411 while (GTREGREAD (SDRAM_OPERATION) != 0) {
1412 DP (printf
1413 ("\n*** SDRAM_OPERATION 1418 after D_UNIT_CONTROL_LOW: Module still busy ... please wait... ***\n"));
1414 }
stroesec096c842004-12-16 18:21:17 +00001415
1416/*------------------------------------------------------------------------------ */
1417
1418
1419 /* bank parameters */
1420 /* SDRAM address decode register */
1421 /* program this with the default value */
1422 tmp = 0x02;
1423
1424
wdenk07d7e6b2004-12-16 21:44:03 +00001425 DP (printf ("drb_size (n*64Mbit): %d\n", info->drb_size));
stroesec096c842004-12-16 18:21:17 +00001426 switch (info->drb_size) {
wdenk07d7e6b2004-12-16 21:44:03 +00001427 case 1: /* 64 Mbit */
1428 case 2: /* 128 Mbit */
1429 DP (printf ("RAM-Device_size 64Mbit or 128Mbit)\n"));
stroesec096c842004-12-16 18:21:17 +00001430 tmp |= (0x00 << 4);
1431 break;
wdenk07d7e6b2004-12-16 21:44:03 +00001432 case 4: /* 256 Mbit */
1433 case 8: /* 512 Mbit */
1434 DP (printf ("RAM-Device_size 256Mbit or 512Mbit)\n"));
stroesec096c842004-12-16 18:21:17 +00001435 tmp |= (0x01 << 4);
1436 break;
wdenk07d7e6b2004-12-16 21:44:03 +00001437 case 16: /* 1 Gbit */
1438 case 32: /* 2 Gbit */
1439 DP (printf ("RAM-Device_size 1Gbit or 2Gbit)\n"));
stroesec096c842004-12-16 18:21:17 +00001440 tmp |= (0x02 << 4);
1441 break;
1442 default:
wdenk07d7e6b2004-12-16 21:44:03 +00001443 printf ("Error in dram size calculation\n");
1444 DP (printf ("Assume: RAM-Device_size 1Gbit or 2Gbit)\n"));
stroesec096c842004-12-16 18:21:17 +00001445 tmp |= (0x02 << 4);
1446 return 1;
1447 }
1448
1449 /* SDRAM bank parameters */
1450 /* the param registers for slot 1 (banks 2+3) are offset by 0x8 */
wdenk07d7e6b2004-12-16 21:44:03 +00001451 DP (printf
1452 ("setting up slot %d config with: %08lx \n", info->slot, tmp));
1453 GT_REG_WRITE (SDRAM_ADDR_CONTROL, tmp);
stroesec096c842004-12-16 18:21:17 +00001454
1455/* ------------------------------------------------------------------------------ */
1456
wdenk07d7e6b2004-12-16 21:44:03 +00001457 DP (printf
1458 ("setting up sdram_timing_control_low with: %08x \n",
1459 0x11511220));
1460 GT_REG_WRITE (SDRAM_TIMING_CONTROL_LOW, 0x11511220);
stroesec096c842004-12-16 18:21:17 +00001461
1462
1463/* ------------------------------------------------------------------------------ */
1464
1465 /* SDRAM configuration */
wdenk07d7e6b2004-12-16 21:44:03 +00001466 tmp = GTREGREAD (SDRAM_CONFIG);
stroesec096c842004-12-16 18:21:17 +00001467
wdenk07d7e6b2004-12-16 21:44:03 +00001468 if (info->registeredAddrAndControlInputs
1469 || info->registeredDQMBinputs) {
1470 tmp |= (1 << 17);
1471 DP (printf
1472 ("SPD says: registered Addr. and Cont.: %d; registered DQMBinputs: %d\n",
1473 info->registeredAddrAndControlInputs,
1474 info->registeredDQMBinputs));
stroesec096c842004-12-16 18:21:17 +00001475 }
1476
1477 /* Use buffer 1 to return read data to the CPU
1478 * Page 426 MV64360 */
1479 tmp |= (1 << 26);
wdenk07d7e6b2004-12-16 21:44:03 +00001480 DP (printf
1481 ("Before Buffer assignment - sdram_conf: %08x\n",
1482 GTREGREAD (SDRAM_CONFIG)));
1483 DP (printf
1484 ("After Buffer assignment - sdram_conf: %08x\n",
1485 GTREGREAD (SDRAM_CONFIG)));
stroesec096c842004-12-16 18:21:17 +00001486
wdenk07d7e6b2004-12-16 21:44:03 +00001487 /* SDRAM timing To_do: */
stroesec096c842004-12-16 18:21:17 +00001488
1489
wdenk07d7e6b2004-12-16 21:44:03 +00001490 tmp = GTREGREAD (SDRAM_TIMING_CONTROL_HIGH);
1491 DP (printf ("# sdram_timing_control_high is : %08lx \n", tmp));
stroesec096c842004-12-16 18:21:17 +00001492
1493 /* SDRAM address decode register */
1494 /* program this with the default value */
wdenk07d7e6b2004-12-16 21:44:03 +00001495 tmp = GTREGREAD (SDRAM_ADDR_CONTROL);
1496 DP (printf
1497 ("SDRAM address control (before: decode): %08x ",
1498 GTREGREAD (SDRAM_ADDR_CONTROL)));
1499 GT_REG_WRITE (SDRAM_ADDR_CONTROL, (tmp | 0x2));
1500 DP (printf
1501 ("SDRAM address control (after: decode): %08x\n",
1502 GTREGREAD (SDRAM_ADDR_CONTROL)));
stroesec096c842004-12-16 18:21:17 +00001503
1504 /* set the SDRAM configuration for each bank */
1505
1506/* for (i = info->slot * 2; i < ((info->slot * 2) + info->banks); i++) */
1507 {
1508 i = info->slot;
wdenk07d7e6b2004-12-16 21:44:03 +00001509 DP (printf
1510 ("\n*** Running a MRS cycle for bank %d ***\n", i));
stroesec096c842004-12-16 18:21:17 +00001511
1512 /* map the bank */
wdenk07d7e6b2004-12-16 21:44:03 +00001513 memory_map_bank (i, 0, GB / 4);
1514#if 1 /* test only */
1515 /* set SDRAM mode */ /* To_do check it */
1516 GT_REG_WRITE (SDRAM_OPERATION, 0x3);
1517 check = GTREGREAD (SDRAM_OPERATION);
1518 DP (printf
1519 ("\n*** SDRAM_OPERATION 1418 (0 = Normal Operation) = %08lx ***\n",
1520 check));
stroesec096c842004-12-16 18:21:17 +00001521
1522
1523 /* switch back to normal operation mode */
wdenk07d7e6b2004-12-16 21:44:03 +00001524 GT_REG_WRITE (SDRAM_OPERATION, 0);
1525 check = GTREGREAD (SDRAM_OPERATION);
1526 DP (printf
1527 ("\n*** SDRAM_OPERATION 1418 (0 = Normal Operation) = %08lx ***\n",
1528 check));
stroesec096c842004-12-16 18:21:17 +00001529#endif /* test only */
1530 /* unmap the bank */
wdenk07d7e6b2004-12-16 21:44:03 +00001531 memory_map_bank (i, 0, 0);
stroesec096c842004-12-16 18:21:17 +00001532 }
1533
1534 return 0;
1535}
1536
1537/*
1538 * Check memory range for valid RAM. A simple memory test determines
1539 * the actually available RAM size between addresses `base' and
1540 * `base + maxsize'. Some (not all) hardware errors are detected:
1541 * - short between address lines
1542 * - short between data lines
1543 */
1544long int
1545dram_size(long int *base, long int maxsize)
1546{
1547 volatile long int *addr, *b=base;
1548 long int cnt, val, save1, save2;
1549
1550#define STARTVAL (1<<20) /* start test at 1M */
1551 for (cnt = STARTVAL/sizeof(long); cnt < maxsize/sizeof(long); cnt <<= 1) {
1552 addr = base + cnt; /* pointer arith! */
1553
1554 save1=*addr; /* save contents of addr */
1555 save2=*b; /* save contents of base */
1556
1557 *addr=cnt; /* write cnt to addr */
1558 *b=0; /* put null at base */
1559
1560 /* check at base address */
1561 if ((*b) != 0) {
1562 *addr=save1; /* restore *addr */
1563 *b=save2; /* restore *b */
1564 return (0);
1565 }
1566 val = *addr; /* read *addr */
1567 val = *addr; /* read *addr */
1568
1569 *addr=save1;
1570 *b=save2;
1571
1572 if (val != cnt) {
wdenk07d7e6b2004-12-16 21:44:03 +00001573 DP(printf("Found %08x at Address %08x (failure)\n", (unsigned int)val, (unsigned int) addr));
stroesec096c842004-12-16 18:21:17 +00001574 /* fix boundary condition.. STARTVAL means zero */
1575 if(cnt==STARTVAL/sizeof(long)) cnt=0;
1576 return (cnt * sizeof(long));
1577 }
1578 }
1579 return maxsize;
1580}
1581
1582/* ------------------------------------------------------------------------- */
1583
1584/* ppcboot interface function to SDRAM init - this is where all the
1585 * controlling logic happens */
1586long int
1587initdram(int board_type)
1588{
1589 int s0 = 0, s1 = 0;
1590 int checkbank[4] = { [0 ... 3] = 0 };
wdenk07d7e6b2004-12-16 21:44:03 +00001591 ulong bank_no, realsize, total, check;
stroesec096c842004-12-16 18:21:17 +00001592 AUX_MEM_DIMM_INFO dimmInfo1;
1593 AUX_MEM_DIMM_INFO dimmInfo2;
1594 int nhr;
1595
1596 /* first, use the SPD to get info about the SDRAM/ DDRRAM */
1597
1598 /* check the NHR bit and skip mem init if it's already done */
1599 nhr = get_hid0() & (1 << 16);
1600
1601 if (nhr) {
1602 printf("Skipping SD- DDRRAM setup due to NHR bit being set\n");
1603 } else {
1604 /* DIMM0 */
1605 s0 = check_dimm(0, &dimmInfo1);
1606
1607 /* DIMM1 */
1608 s1 = check_dimm(1, &dimmInfo2);
1609
1610 memory_map_bank(0, 0, 0);
1611 memory_map_bank(1, 0, 0);
1612 memory_map_bank(2, 0, 0);
1613 memory_map_bank(3, 0, 0);
1614
1615 if (dimmInfo1.numOfModuleBanks && setup_sdram(&dimmInfo1)) {
1616 printf("Setup for DIMM1 failed.\n");
1617 }
1618
1619 if (dimmInfo2.numOfModuleBanks && setup_sdram(&dimmInfo2)) {
1620 printf("Setup for DIMM2 failed.\n");
1621 }
1622
1623 /* set the NHR bit */
1624 set_hid0(get_hid0() | (1 << 16));
1625 }
1626 /* next, size the SDRAM banks */
1627
1628 realsize = total = 0;
1629 check = GB/4;
1630 if (dimmInfo1.numOfModuleBanks > 0) {checkbank[0] = 1; printf("-- DIMM1 has 1 bank\n");}
1631 if (dimmInfo1.numOfModuleBanks > 1) {checkbank[1] = 1; printf("-- DIMM1 has 2 banks\n");}
1632 if (dimmInfo1.numOfModuleBanks > 2)
1633 printf("Error, SPD claims DIMM1 has >2 banks\n");
1634
1635 if (dimmInfo2.numOfModuleBanks > 0) {checkbank[2] = 1; printf("-- DIMM2 has 1 bank\n");}
1636 if (dimmInfo2.numOfModuleBanks > 1) {checkbank[3] = 1; printf("-- DIMM2 has 2 banks\n");}
1637 if (dimmInfo2.numOfModuleBanks > 2)
1638 printf("Error, SPD claims DIMM2 has >2 banks\n");
1639
1640 for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) {
1641 /* skip over banks that are not populated */
1642 if (! checkbank[bank_no])
1643 continue;
1644
1645 if ((total + check) > CFG_GT_REGS)
1646 check = CFG_GT_REGS - total;
1647
1648 memory_map_bank(bank_no, total, check);
1649 realsize = dram_size((long int *)total, check);
1650 memory_map_bank(bank_no, total, realsize);
1651
1652 total += realsize;
1653 }
1654
1655/* Setup Ethernet DMA Adress window to DRAM Area */
wdenk07d7e6b2004-12-16 21:44:03 +00001656 return(total);
stroesec096c842004-12-16 18:21:17 +00001657}
1658
1659/* ***************************************************************************************
1660! * SDRAM INIT *
1661! * This procedure detect all Sdram types: 64, 128, 256, 512 Mbit, 1Gbit and 2Gb *
1662! * This procedure fits only the Atlantis *
1663! * *
1664! *************************************************************************************** */
1665
1666
1667/* ***************************************************************************************
1668! * DFCDL initialize MV643xx Design Considerations *
1669! * *
1670! *************************************************************************************** */
wdenk07d7e6b2004-12-16 21:44:03 +00001671int set_dfcdlInit (void)
stroesec096c842004-12-16 18:21:17 +00001672{
wdenk07d7e6b2004-12-16 21:44:03 +00001673 int i;
1674 unsigned int dfcdl_word = 0x0000014f;
1675
1676 for (i = 0; i < 64; i++) {
1677 GT_REG_WRITE (SRAM_DATA0, dfcdl_word);
1678 }
1679 GT_REG_WRITE (DFCDL_CONFIG0, 0x00300000); /* enable dynamic delay line updating */
stroesec096c842004-12-16 18:21:17 +00001680
1681
wdenk07d7e6b2004-12-16 21:44:03 +00001682 return (0);
stroesec096c842004-12-16 18:21:17 +00001683}