blob: 0eba0e384c552ed9134b9c167b9c0f1882804f7f [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Patrick Rudolph6e53ae62017-01-31 19:43:17 +01002
3/**
4 * @file ddr2.c
5 *
6 * \brief Utilities for decoding DDR2 SPDs
7 */
8
9#include <console/console.h>
10#include <device/device.h>
11#include <device/dram/ddr2.h>
Arthur Heymans3397aa12017-03-01 20:10:55 +010012#include <lib.h>
Patrick Rudolph6e53ae62017-01-31 19:43:17 +010013#include <string.h>
Elyes HAOUASbd1683d2019-05-15 21:05:37 +020014#include <types.h>
Patrick Rudolph6e53ae62017-01-31 19:43:17 +010015
16/*==============================================================================
17 * = DDR2 SPD decoding helpers
18 *----------------------------------------------------------------------------*/
19
20/**
21 * \brief Checks if the DIMM is Registered based on byte[20] of the SPD
22 *
23 * Tells if the DIMM type is registered or not.
24 *
25 * @param type DIMM type. This is byte[20] of the SPD.
26 */
Arthur Heymansfc31e442018-02-12 15:12:34 +010027int spd_dimm_is_registered_ddr2(enum spd_dimm_type_ddr2 type)
Patrick Rudolph6e53ae62017-01-31 19:43:17 +010028{
Arthur Heymansfc31e442018-02-12 15:12:34 +010029 if ((type == SPD_DDR2_DIMM_TYPE_RDIMM)
30 || (type == SPD_DDR2_DIMM_TYPE_72B_SO_RDIMM)
31 || (type == SPD_DDR2_DIMM_TYPE_MINI_RDIMM))
Patrick Rudolph6e53ae62017-01-31 19:43:17 +010032 return 1;
33
34 return 0;
35}
36
37/**
38 * \brief Calculate the checksum of a DDR2 SPD unique identifier
39 *
40 * @param spd pointer to raw SPD data
41 * @param len length of data in SPD
42 *
43 * @return the checksum of SPD data bytes 63, or 0 when spd data is truncated.
44 */
45u8 spd_ddr2_calc_checksum(u8 *spd, int len)
46{
47 int i;
48 u8 c = 0;
49
50 if (len < 63)
51 /* Not enough bytes available to get the checksum */
52 return 0;
53
54 for (i = 0; i < 63; i++)
55 c += spd[i];
56
57 return c;
58}
59
60/**
Arthur Heymans97b337b2018-01-22 01:26:53 +010061 * \brief Calculate the CRC of a DDR2 SPD unique identifier
62 *
63 * @param spd pointer to raw SPD data
64 * @param len length of data in SPD
65 *
66 * @return the CRC of SPD data bytes 64..72 and 93..98, or 0
67 * when spd data is truncated.
68 */
69u16 spd_ddr2_calc_unique_crc(const u8 *spd, int len)
70{
71 u8 id_bytes[15];
72 int i, j = 0;
73 if (len < 98)
74 /* Not enough bytes available to get the CRC */
75 return 0;
76 for (i = 64; i <= 72; i++)
77 id_bytes[j++] = spd[i];
78 for (i = 93; i <= 98; i++)
79 id_bytes[j++] = spd[i];
80
Andrey Petrov3f85edb2019-08-01 14:18:06 -070081 return ddr_crc16(id_bytes, 15);
Arthur Heymans97b337b2018-01-22 01:26:53 +010082}
83
84/**
Patrick Rudolph6e53ae62017-01-31 19:43:17 +010085 * \brief Return size of SPD.
86 *
87 * Returns size of SPD. Usually 128 Byte.
88 */
89u32 spd_decode_spd_size_ddr2(u8 byte0)
90{
91 return MIN(byte0, SPD_SIZE_MAX_DDR2);
92}
93
94/**
95 * \brief Return size of eeprom.
96 *
97 * Returns size of eeprom. Usually 256 Byte.
98 */
99u32 spd_decode_eeprom_size_ddr2(u8 byte1)
100{
101 if (!byte1)
102 return 0;
103
104 if (byte1 > 0x0e)
105 return 0x3fff;
106
107 return 1 << byte1;
108}
109
110/**
111 * \brief Return index of MSB set
112 *
Elyes HAOUAS05b1cb82018-09-05 17:37:56 +0200113 * Returns the index of MSB set.
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100114 */
Arthur Heymans3397aa12017-03-01 20:10:55 +0100115u8 spd_get_msbs(u8 c)
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100116{
Arthur Heymans3397aa12017-03-01 20:10:55 +0100117 return log2(c);
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100118}
119
120/**
121 * \brief Decode SPD tck cycle time
122 *
123 * Decodes a raw SPD data from a DDR2 DIMM.
124 * Returns cycle time in 1/256th ns.
125 */
Arthur Heymans2785c112017-09-10 20:57:37 +0200126static int spd_decode_tck_time(u32 *tck, u8 c)
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100127{
128 u8 high, low;
129
130 high = c >> 4;
131
132 switch (c & 0xf) {
133 case 0xa:
134 low = 25;
135 break;
136 case 0xb:
137 low = 33;
138 break;
139 case 0xc:
140 low = 66;
141 break;
142 case 0xd:
143 low = 75;
144 break;
Arthur Heymans2785c112017-09-10 20:57:37 +0200145 case 0xe:
146 case 0xf:
147 printk(BIOS_WARNING, "Invalid tck setting. "
148 "lower nibble is 0x%x\n", c & 0xf);
149 return CB_ERR;
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100150 default:
151 low = (c & 0xf) * 10;
152 }
153
Arthur Heymans2785c112017-09-10 20:57:37 +0200154 *tck = ((high * 100 + low) << 8) / 100;
155 return CB_SUCCESS;
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100156}
157
158/**
159 * \brief Decode SPD bcd style timings
160 *
161 * Decodes a raw SPD data from a DDR2 DIMM.
162 * Returns cycle time in 1/256th ns.
163 */
Arthur Heymans2785c112017-09-10 20:57:37 +0200164static int spd_decode_bcd_time(u32 *bcd, u8 c)
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100165{
166 u8 high, low;
167
168 high = c >> 4;
169 low = c & 0xf;
Arthur Heymans2785c112017-09-10 20:57:37 +0200170 if (high >= 10 || low >= 10)
171 return CB_ERR;
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100172
Arthur Heymans2785c112017-09-10 20:57:37 +0200173 *bcd = ((high * 10 + low) << 8) / 100;
174 return CB_SUCCESS;
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100175}
176
177/**
178 * \brief Decode SPD tRP, tRRP cycle time
179 *
180 * Decodes a raw SPD data from a DDR2 DIMM.
181 * Returns cycle time in 1/256th ns.
182 */
183static u32 spd_decode_quarter_time(u8 c)
184{
185 u8 high, low;
186
187 high = c >> 2;
188 low = 25 * (c & 0x3);
189
190 return ((high * 100 + low) << 8) / 100;
191}
192
193/**
194 * \brief Decode SPD tRR time
195 *
196 * Decodes a raw SPD data from a DDR2 DIMM.
197 * Returns cycle time in 1/256th us.
198 */
Arthur Heymans2785c112017-09-10 20:57:37 +0200199static int spd_decode_tRR_time(u32 *tRR, u8 c)
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100200{
Arthur Heymans7eb01572017-09-21 08:28:23 +0200201 switch (c & ~0x80) {
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100202 default:
Arthur Heymans2785c112017-09-10 20:57:37 +0200203 printk(BIOS_WARNING, "Invalid tRR value 0x%x\n", c);
204 return CB_ERR;
Arthur Heymans7eb01572017-09-21 08:28:23 +0200205 case 0x0:
Arthur Heymans2785c112017-09-10 20:57:37 +0200206 *tRR = 15625 << 8;
Patrick Georgia2248cb2017-09-22 18:21:52 +0200207 break;
Arthur Heymans7eb01572017-09-21 08:28:23 +0200208 case 0x1:
Arthur Heymans2785c112017-09-10 20:57:37 +0200209 *tRR = 15625 << 6;
Patrick Georgia2248cb2017-09-22 18:21:52 +0200210 break;
Arthur Heymans7eb01572017-09-21 08:28:23 +0200211 case 0x2:
Arthur Heymans2785c112017-09-10 20:57:37 +0200212 *tRR = 15625 << 7;
Patrick Georgia2248cb2017-09-22 18:21:52 +0200213 break;
Arthur Heymans7eb01572017-09-21 08:28:23 +0200214 case 0x3:
Arthur Heymans2785c112017-09-10 20:57:37 +0200215 *tRR = 15625 << 9;
Patrick Georgia2248cb2017-09-22 18:21:52 +0200216 break;
Arthur Heymans7eb01572017-09-21 08:28:23 +0200217 case 0x4:
Arthur Heymans2785c112017-09-10 20:57:37 +0200218 *tRR = 15625 << 10;
Patrick Georgia2248cb2017-09-22 18:21:52 +0200219 break;
Arthur Heymans7eb01572017-09-21 08:28:23 +0200220 case 0x5:
Arthur Heymans2785c112017-09-10 20:57:37 +0200221 *tRR = 15625 << 11;
Patrick Georgia2248cb2017-09-22 18:21:52 +0200222 break;
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100223 }
Arthur Heymans2785c112017-09-10 20:57:37 +0200224 return CB_SUCCESS;
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100225}
226
227/**
228 * \brief Decode SPD tRC,tRFC time
229 *
230 * Decodes a raw SPD data from a DDR2 DIMM.
231 * Returns cycle time in 1/256th us.
232 */
233static void spd_decode_tRCtRFC_time(u8 *spd_40_41_42, u32 *tRC, u32 *tRFC)
234{
235 u8 b40, b41, b42;
236
237 b40 = spd_40_41_42[0];
238 b41 = spd_40_41_42[1];
239 b42 = spd_40_41_42[2];
240
241 *tRC = b41 * 100;
242 *tRFC = b42 * 100;
243
244 if (b40 & 0x01)
245 *tRFC += 256 * 100;
246
247 switch ((b40 >> 1) & 0x07) {
248 case 1:
249 *tRFC += 25;
250 break;
251 case 2:
252 *tRFC += 33;
253 break;
254 case 3:
255 *tRFC += 50;
256 break;
257 case 4:
258 *tRFC += 66;
259 break;
260 case 5:
261 *tRFC += 75;
262 break;
263 default:
264 break;
265 }
266
267 switch ((b40 >> 4) & 0x07) {
268 case 1:
269 *tRC += 25;
270 break;
271 case 2:
272 *tRC += 33;
273 break;
274 case 3:
275 *tRC += 50;
276 break;
277 case 4:
278 *tRC += 66;
279 break;
280 case 5:
281 *tRC += 75;
282 break;
283 default:
284 break;
285 }
286
287 /* Convert to 1/256th us */
288 *tRC = (*tRC << 8) / 100;
289 *tRFC = (*tRFC << 8) / 100;
290}
291
292/**
293 * \brief Decode the raw SPD data
294 *
295 * Decodes a raw SPD data from a DDR2 DIMM, and organizes it into a
296 * @ref dimm_attr structure. The SPD data must first be read in a contiguous
297 * array, and passed to this function.
298 *
299 * @param dimm pointer to @ref dimm_attr structure where the decoded data is to
300 * be stored
301 * @param spd array of raw data previously read from the SPD.
302 *
303 * @return @ref spd_status enumerator
304 * SPD_STATUS_OK -- decoding was successful
305 * SPD_STATUS_INVALID -- invalid SPD or not a DDR2 SPD
306 * SPD_STATUS_CRC_ERROR -- CRC did not verify
307 * SPD_STATUS_INVALID_FIELD -- A field with an invalid value was
308 * detected.
309 */
Arthur Heymansfc31e442018-02-12 15:12:34 +0100310int spd_decode_ddr2(struct dimm_attr_ddr2_st *dimm, u8 spd[SPD_SIZE_MAX_DDR2])
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100311{
312 u8 spd_size, cl, reg8;
313 u16 eeprom_size;
314 int ret = SPD_STATUS_OK;
315
316 memset(dimm, 0, sizeof(*dimm));
317
318 spd_size = spd_decode_spd_size_ddr2(spd[0]);
319 eeprom_size = spd_decode_eeprom_size_ddr2(spd[1]);
320
321 printram("EEPROM with 0x%04x bytes\n", eeprom_size);
322 printram("SPD contains 0x%02x bytes\n", spd_size);
323
324 if (spd_size < 64 || eeprom_size < 64) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200325 printk(BIOS_WARNING, "ERROR: SPD to small\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100326 dimm->dram_type = SPD_MEMORY_TYPE_UNDEFINED;
327 return SPD_STATUS_INVALID;
328 }
329
330 if (spd_ddr2_calc_checksum(spd, spd_size) != spd[63]) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200331 printk(BIOS_WARNING, "ERROR: SPD checksum error\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100332 dimm->dram_type = SPD_MEMORY_TYPE_UNDEFINED;
333 return SPD_STATUS_CRC_ERROR;
334 }
Arthur Heymansb5d4dd12017-09-25 12:47:41 +0200335 dimm->checksum = spd[63];
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100336
337 reg8 = spd[62];
338 if ((reg8 & 0xf0) != 0x10) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200339 printk(BIOS_WARNING,
340 "ERROR: Unsupported SPD revision %01x.%01x\n",
341 reg8 >> 4, reg8 & 0xf);
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100342 dimm->dram_type = SPD_MEMORY_TYPE_UNDEFINED;
343 return SPD_STATUS_INVALID;
344 }
345 dimm->rev = reg8;
346 printram(" Revision : %01x.%01x\n", dimm->rev >> 4, dimm->rev & 0xf);
347
348 reg8 = spd[2];
349 printram(" Type : 0x%02x\n", reg8);
350 if (reg8 != 0x08) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200351 printk(BIOS_WARNING, "ERROR: Unsupported SPD type %x\n", reg8);
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100352 dimm->dram_type = SPD_MEMORY_TYPE_UNDEFINED;
353 return SPD_STATUS_INVALID;
354 }
355 dimm->dram_type = SPD_MEMORY_TYPE_SDRAM_DDR2;
356
357 dimm->row_bits = spd[3];
358 printram(" Rows : %u\n", dimm->row_bits);
359 if ((dimm->row_bits > 31) ||
360 ((dimm->row_bits > 15) && (dimm->rev < 0x13))) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200361 printk(BIOS_WARNING,
362 "SPD decode: invalid number of memory rows\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100363 ret = SPD_STATUS_INVALID_FIELD;
364 }
365
366 dimm->col_bits = spd[4];
367 printram(" Columns : %u\n", dimm->col_bits);
368 if (dimm->col_bits > 15) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200369 printk(BIOS_WARNING,
370 "SPD decode: invalid number of memory columns\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100371 ret = SPD_STATUS_INVALID_FIELD;
372 }
373
374 dimm->ranks = (spd[5] & 0x7) + 1;
375 printram(" Ranks : %u\n", dimm->ranks);
376
377 dimm->mod_width = spd[6];
378 printram(" Module data width : x%u\n", dimm->mod_width);
379 if (!dimm->mod_width) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200380 printk(BIOS_WARNING, "SPD decode: invalid module data width\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100381 ret = SPD_STATUS_INVALID_FIELD;
382 }
383
384 dimm->width = spd[13];
385 printram(" SDRAM width : x%u\n", dimm->width);
386 if (!dimm->width) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200387 printk(BIOS_WARNING, "SPD decode: invalid SDRAM width\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100388 ret = SPD_STATUS_INVALID_FIELD;
389 }
390
391 dimm->banks = spd[17];
392 printram(" Banks : %u\n", dimm->banks);
393 if (!dimm->banks) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200394 printk(BIOS_WARNING,
395 "SPD decode: invalid module banks count\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100396 ret = SPD_STATUS_INVALID_FIELD;
397 }
398
399 switch (spd[8]) {
400 case 0:
401 dimm->flags.operable_5_00V = 1;
402 printram(" Voltage : 5.0V\n");
403 break;
404 case 1:
405 dimm->flags.operable_3_33V = 1;
406 printram(" Voltage : 3.3V\n");
407 break;
408 case 2:
409 dimm->flags.operable_1_50V = 1;
410 printram(" Voltage : 1.5V\n");
411 break;
412 case 3:
413 dimm->flags.operable_3_33V = 1;
414 printram(" Voltage : 3.3V\n");
415 break;
416 case 4:
417 dimm->flags.operable_2_50V = 1;
418 printram(" Voltage : 2.5V\n");
419 break;
420 case 5:
421 dimm->flags.operable_1_80V = 1;
422 printram(" Voltage : 1.8V\n");
423 break;
424 default:
Arthur Heymans2785c112017-09-10 20:57:37 +0200425 printk(BIOS_WARNING, "SPD decode: unknown voltage level.\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100426 ret = SPD_STATUS_INVALID_FIELD;
427 }
428
429 dimm->cas_supported = spd[18];
430 if ((dimm->cas_supported & 0x3) || !dimm->cas_supported) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200431 printk(BIOS_WARNING,
432 "SPD decode: invalid CAS support advertised.\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100433 ret = SPD_STATUS_INVALID_FIELD;
434 }
435 printram(" Supported CAS mask : 0x%x\n", dimm->cas_supported);
436
437 if ((dimm->rev < 0x13) && (dimm->cas_supported & 0x80)) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200438 printk(BIOS_WARNING,
439 "SPD decode: invalid CAS support advertised.\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100440 ret = SPD_STATUS_INVALID_FIELD;
441 }
442 if ((dimm->rev < 0x12) && (dimm->cas_supported & 0x40)) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200443 printk(BIOS_WARNING,
444 "SPD decode: invalid CAS support advertised.\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100445 ret = SPD_STATUS_INVALID_FIELD;
446 }
447
448 /* CL=X */
449 cl = spd_get_msbs(dimm->cas_supported);
450
451 /* SDRAM Cycle time at Maximum Supported CAS Latency (CL), CL=X */
Arthur Heymans2785c112017-09-10 20:57:37 +0200452 if (spd_decode_tck_time(&dimm->cycle_time[cl], spd[9]) != CB_SUCCESS) {
453 printk(BIOS_WARNING,
454 "SPD decode: invalid min tCL for CAS%d\n", cl);
455 ret = SPD_STATUS_INVALID_FIELD;
456 }
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100457 /* SDRAM Access from Clock */
Arthur Heymans2785c112017-09-10 20:57:37 +0200458 if (spd_decode_bcd_time(&dimm->access_time[cl], spd[10])
459 != CB_SUCCESS) {
460 printk(BIOS_WARNING,
461 "SPD decode: invalid min tAC for CAS%d\n", cl);
462 ret = SPD_STATUS_INVALID_FIELD;
463 }
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100464
465 if (dimm->cas_supported & (1 << (cl - 1))) {
466 /* Minimum Clock Cycle at CLX-1 */
Arthur Heymans2785c112017-09-10 20:57:37 +0200467 if (spd_decode_tck_time(&dimm->cycle_time[cl - 1], spd[23])
468 != CB_SUCCESS) {
469 printk(BIOS_WARNING,
470 "SPD decode: invalid min tCL for CAS%d\n",
471 cl - 1);
472 ret = SPD_STATUS_INVALID_FIELD;
473 }
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100474 /* Maximum Data Access Time (tAC) from Clock at CLX-1 */
Arthur Heymans2785c112017-09-10 20:57:37 +0200475 if (spd_decode_bcd_time(&dimm->access_time[cl - 1], spd[24])
476 != CB_SUCCESS) {
477 printk(BIOS_WARNING,
478 "SPD decode: invalid min tAC for CAS%d\n",
479 cl - 1);
480 ret = SPD_STATUS_INVALID_FIELD;
481 }
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100482 }
483 if (dimm->cas_supported & (1 << (cl - 2))) {
484 /* Minimum Clock Cycle at CLX-2 */
Arthur Heymans2785c112017-09-10 20:57:37 +0200485 if (spd_decode_tck_time(&dimm->cycle_time[cl - 2], spd[25])
486 != CB_SUCCESS) {
487 printk(BIOS_WARNING,
488 "SPD decode: invalid min tCL for CAS%d\n",
489 cl - 2);
490 ret = SPD_STATUS_INVALID_FIELD;
491 }
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100492 /* Maximum Data Access Time (tAC) from Clock at CLX-2 */
Arthur Heymans2785c112017-09-10 20:57:37 +0200493 if (spd_decode_bcd_time(&dimm->access_time[cl - 2], spd[26])
494 != CB_SUCCESS) {
495 printk(BIOS_WARNING,
496 "SPD decode: invalid min tAC for CAS%d\n",
497 cl - 2);
498 ret = SPD_STATUS_INVALID_FIELD;
499 }
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100500 }
501
502 reg8 = (spd[31] >> 5) | (spd[31] << 3);
503 if (!reg8) {
Arthur Heymans2785c112017-09-10 20:57:37 +0200504 printk(BIOS_WARNING,
505 "SPD decode: invalid rank density.\n");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100506 ret = SPD_STATUS_INVALID_FIELD;
507 }
508
509 /* Rank density */
510 dimm->ranksize_mb = 128 * reg8;
511 /* Module density */
512 dimm->size_mb = dimm->ranksize_mb * dimm->ranks;
513 if (dimm->size_mb < 1024)
514 printram(" Capacity : %u MB\n", dimm->size_mb);
515 else
516 printram(" Capacity : %u GB\n", dimm->size_mb >> 10);
517
518 /* SDRAM Maximum Cycle Time (tCKmax) */
Arthur Heymans2785c112017-09-10 20:57:37 +0200519 if (spd_decode_bcd_time(&dimm->tCK, spd[43]) != CB_SUCCESS) {
520 printk(BIOS_WARNING, "SPD decode: invalid Max tCK\n");
521 ret = SPD_STATUS_INVALID_FIELD;
522 }
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100523 /* Minimum Write Recovery Time (tWRmin) */
524 dimm->tWR = spd_decode_quarter_time(spd[36]);
525 /* Minimum RAS# to CAS# Delay Time (tRCDmin) */
526 dimm->tRCD = spd_decode_quarter_time(spd[29]);
527 /* Minimum Row Active to Row Active Delay Time (tRRDmin) */
528 dimm->tRRD = spd_decode_quarter_time(spd[28]);
529 /* Minimum Row Precharge Delay Time (tRPmin) */
530 dimm->tRP = spd_decode_quarter_time(spd[27]);
531 /* Minimum Active to Precharge Delay Time (tRASmin) */
532 dimm->tRAS = spd[30] << 8;
533 /* Minimum Active to Active/Refresh Delay Time (tRCmin) */
534 /* Minimum Refresh Recovery Delay Time (tRFCmin) */
535 spd_decode_tRCtRFC_time(&spd[40], &dimm->tRC, &dimm->tRFC);
536 /* Minimum Internal Write to Read Command Delay Time (tWTRmin) */
537 dimm->tWTR = spd_decode_quarter_time(spd[37]);
538 /* Minimum Internal Read to Precharge Command Delay Time (tRTPmin) */
539 dimm->tRTP = spd_decode_quarter_time(spd[38]);
540 /* Data Input Setup Time Before Strobe */
Arthur Heymans2785c112017-09-10 20:57:37 +0200541 if (spd_decode_bcd_time(&dimm->tDS, spd[34]) != CB_SUCCESS) {
542 printk(BIOS_WARNING, "SPD decode: invalid tDS\n");
543 ret = SPD_STATUS_INVALID_FIELD;
544 }
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100545 /* Data Input Hold Time After Strobe */
Arthur Heymans2785c112017-09-10 20:57:37 +0200546 if (spd_decode_bcd_time(&dimm->tDH, spd[35]) != CB_SUCCESS) {
547 printk(BIOS_WARNING, "SPD decode: invalid tDH\n");
548 ret = SPD_STATUS_INVALID_FIELD;
549 }
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100550 /* SDRAM Device DQS-DQ Skew for DQS and associated DQ signals */
551 dimm->tDQSQ = (spd[44] << 8) / 100;
552 /* SDRAM Device Maximum Read Data Hold Skew Factor */
553 dimm->tQHS = (spd[45] << 8) / 100;
554 /* PLL Relock Time in us */
555 dimm->tPLL = spd[46] << 8;
556 /* Refresh rate in us */
Arthur Heymans2785c112017-09-10 20:57:37 +0200557 if (spd_decode_tRR_time(&dimm->tRR, spd[12]) != CB_SUCCESS)
558 ret = SPD_STATUS_INVALID_FIELD;
Arthur Heymans7eb01572017-09-21 08:28:23 +0200559 dimm->flags.self_refresh = (spd[12] >> 7) & 1;
560 printram("The assembly supports self refresh: %s\n",
Bill XIEc8050f42017-09-25 15:54:04 +0800561 dimm->flags.self_refresh ? "true" : "false");
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100562
563 /* Number of PLLs on DIMM */
564 if (dimm->rev >= 0x11)
565 dimm->plls = (spd[21] >> 2) & 0x3;
566
567 /* SDRAM Thermal and Refresh Options */
568 printram(" General features :");
569 if ((dimm->rev >= 0x12) && (spd[22] & 0x04)) {
570 dimm->flags.pasr = 1;
571 printram(" PASR");
572 }
573 if ((dimm->rev >= 0x12) && (spd[22] & 0x02)) {
574 dimm->flags.terminate_50ohms = 1;
575 printram(" 50Ohm");
576 }
577 if (spd[22] & 0x01) {
578 dimm->flags.weak_driver = 1;
579 printram(" WEAK_DRIVER");
580 }
581 printram("\n");
582
583 /* SDRAM Supported Burst length */
584 printram(" Burst length :");
Elyes HAOUASec193542018-03-11 18:34:53 +0100585 if (spd[16] & 0x08) {
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100586 dimm->flags.bl8 = 1;
587 printram(" BL8");
588 }
Elyes HAOUASec193542018-03-11 18:34:53 +0100589 if (spd[16] & 0x04) {
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100590 dimm->flags.bl4 = 1;
591 printram(" BL4");
592 }
593 printram("\n");
594
Arthur Heymansfc31e442018-02-12 15:12:34 +0100595 dimm->dimm_type = spd[20] & SPD_DDR2_DIMM_TYPE_MASK;
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100596 printram(" Dimm type : %x\n", dimm->dimm_type);
597
598 dimm->flags.is_ecc = !!(spd[11] & 0x3);
599 printram(" ECC support : %x\n", dimm->flags.is_ecc);
600
601 dimm->flags.stacked = !!(spd[5] & 0x10);
602 printram(" Package : %s\n",
603 dimm->flags.stacked ? "stack" : "planar");
604
605 if (spd_size > 71) {
606 memcpy(&dimm->manufacturer_id, &spd[64], 4);
607 printram(" Manufacturer ID : %x\n", dimm->manufacturer_id);
608 }
609
610 if (spd_size > 90) {
611 dimm->part_number[16] = 0;
612 memcpy(dimm->part_number, &spd[73], 16);
613 printram(" Part number : %s\n", dimm->part_number);
614 }
615
616 if (spd_size > 94) {
617 dimm->year = spd[93] + 2000;
618 dimm->weeks = spd[94];
619 printram(" Date : %d week %d\n", dimm->year, dimm->weeks);
620 }
621
622 if (spd_size > 98) {
623 memcpy(&dimm->serial, &spd[95], 4);
624 printram(" Serial number : 0x%08x\n", dimm->serial);
625 }
626 return ret;
627}
628
629/*
630 * The information printed below has a more informational character, and is not
631 * necessarily tied in to RAM init debugging. Hence, we stop using printram(),
632 * and use the standard printk()'s below.
633 */
634
635static void print_ns(const char *msg, u32 val)
636{
637 u32 mant, fp;
638 mant = val / 256;
639 fp = (val % 256) * 1000 / 256;
640
641 printk(BIOS_INFO, "%s%3u.%.3u ns\n", msg, mant, fp);
642}
643
644static void print_us(const char *msg, u32 val)
645{
646 u32 mant, fp;
647 mant = val / 256;
648 fp = (val % 256) * 1000 / 256;
649
650 printk(BIOS_INFO, "%s%3u.%.3u us\n", msg, mant, fp);
651}
652
653/**
654* \brief Print the info in DIMM
655*
Martin Rothf48acbd2020-07-24 12:24:27 -0600656* Print info about the DIMM. Useful to use when CONFIG(DEBUG_RAM_SETUP) is
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100657* selected, or for a purely informative output.
658*
659* @param dimm pointer to already decoded @ref dimm_attr structure
660*/
Arthur Heymansfc31e442018-02-12 15:12:34 +0100661void dram_print_spd_ddr2(const struct dimm_attr_ddr2_st *dimm)
Patrick Rudolph6e53ae62017-01-31 19:43:17 +0100662{
663 char buf[32];
664 int i;
665
666 printk(BIOS_INFO, " Row addr bits : %u\n", dimm->row_bits);
667 printk(BIOS_INFO, " Column addr bits : %u\n", dimm->col_bits);
668 printk(BIOS_INFO, " Number of ranks : %u\n", dimm->ranks);
669 printk(BIOS_INFO, " DIMM Capacity : %u MB\n", dimm->size_mb);
670 printk(BIOS_INFO, " Width : x%u\n", dimm->width);
671 printk(BIOS_INFO, " Banks : %u\n", dimm->banks);
672
673 /* CAS Latencies Supported */
674 printk(BIOS_INFO, " CAS latencies :");
675 for (i = 2; i < 8; i++) {
676 if (dimm->cas_supported & (1 << i))
677 printk(BIOS_INFO, " %u", i);
678 }
679 printk(BIOS_INFO, "\n");
680
681 for (i = 2; i < 8; i++) {
682 if (!(dimm->cas_supported & (1 << i)))
683 continue;
684
685 strcpy(buf, " tCK at CLx : ");
686 /* Simple snprintf replacement */
687 buf[11] = '0' + i;
688 print_ns(buf, dimm->cycle_time[i]);
689
690 strcpy(buf, " tAC at CLx : ");
691 /* Simple snprintf replacement */
692 buf[11] = '0' + i;
693 print_ns(buf, dimm->access_time[i]);
694 }
695 print_ns(" tCKmax : ", dimm->tCK);
696 print_ns(" tWRmin : ", dimm->tWR);
697 print_ns(" tRCDmin : ", dimm->tRCD);
698 print_ns(" tRRDmin : ", dimm->tRRD);
699 print_ns(" tRPmin : ", dimm->tRP);
700 print_ns(" tRASmin : ", dimm->tRAS);
701 print_ns(" tRCmin : ", dimm->tRC);
702 print_ns(" tRFCmin : ", dimm->tRFC);
703 print_ns(" tWTRmin : ", dimm->tWTR);
704 print_ns(" tRTPmin : ", dimm->tRTP);
705 print_ns(" tDS : ", dimm->tDS);
706 print_ns(" tDH : ", dimm->tDH);
707 print_ns(" tDQSQmax : ", dimm->tDQSQ);
708 print_ns(" tQHSmax : ", dimm->tQHS);
709 print_us(" tPLL : ", dimm->tPLL);
710 print_us(" tRR : ", dimm->tRR);
711}
Arthur Heymans3397aa12017-03-01 20:10:55 +0100712
713void normalize_tck(u32 *tclk)
714{
715 if (*tclk <= TCK_800MHZ) {
716 *tclk = TCK_800MHZ;
717 } else if (*tclk <= TCK_666MHZ) {
718 *tclk = TCK_666MHZ;
719 } else if (*tclk <= TCK_533MHZ) {
720 *tclk = TCK_533MHZ;
721 } else if (*tclk <= TCK_400MHZ) {
722 *tclk = TCK_400MHZ;
723 } else if (*tclk <= TCK_333MHZ) {
724 *tclk = TCK_333MHZ;
725 } else if (*tclk <= TCK_266MHZ) {
726 *tclk = TCK_266MHZ;
727 } else if (*tclk <= TCK_200MHZ) {
728 *tclk = TCK_200MHZ;
729 } else {
730 *tclk = 0;
731 printk(BIOS_ERR, "Too slow common tCLK found\n");
732 }
733}