Sync usage with man page.
[netbsd-mini2440.git] / sys / dev / i2c / spdmem.c
blob04b2f7455280a0eb326ac8c4ead5ed6731fcc138
1 /* $NetBSD: spdmem.c,v 1.14 2009/02/22 17:28:51 pgoyette Exp $ */
3 /*
4 * Copyright (c) 2007 Nicolas Joly
5 * Copyright (c) 2007 Paul Goyette
6 * Copyright (c) 2007 Tobias Nygren
7 * All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * Serial Presence Detect (SPD) memory identification
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: spdmem.c,v 1.14 2009/02/22 17:28:51 pgoyette Exp $");
40 #include <sys/param.h>
41 #include <sys/device.h>
42 #include <sys/endian.h>
43 #include <sys/sysctl.h>
44 #include <machine/bswap.h>
46 #include <dev/i2c/i2cvar.h>
47 #include <dev/i2c/spdmemreg.h>
48 #include <dev/i2c/spdmemvar.h>
50 static int spdmem_match(device_t, cfdata_t, void *);
51 static void spdmem_attach(device_t, device_t, void *);
52 SYSCTL_SETUP_PROTO(sysctl_spdmem_setup);
54 static uint8_t spdmem_read(struct spdmem_softc *, uint8_t);
56 /* Routines for decoding spd data */
57 static void decode_edofpm(const struct sysctlnode *, device_t, struct spdmem *);
58 static void decode_rom(const struct sysctlnode *, device_t, struct spdmem *);
59 static void decode_sdram(const struct sysctlnode *, device_t, struct spdmem *);
60 static void decode_ddr(const struct sysctlnode *, device_t, struct spdmem *);
61 static void decode_ddr2(const struct sysctlnode *, device_t, struct spdmem *);
62 static void decode_ddr3(const struct sysctlnode *, device_t, struct spdmem *);
63 static void decode_fbdimm(const struct sysctlnode *, device_t, struct spdmem *);
65 static void decode_size_speed(const struct sysctlnode *, int, int, int, int,
66 bool, const char *);
67 static void decode_voltage_refresh(device_t, struct spdmem *);
69 CFATTACH_DECL_NEW(spdmem, sizeof(struct spdmem_softc),
70 spdmem_match, spdmem_attach, NULL, NULL);
72 #define IS_RAMBUS_TYPE (s->sm_len < 4)
74 static const char* spdmem_basic_types[] = {
75 "unknown",
76 "FPM",
77 "EDO",
78 "Pipelined Nibble",
79 "SDRAM",
80 "ROM",
81 "DDR SGRAM",
82 "DDR SDRAM",
83 "DDR2 SDRAM",
84 "DDR2 SDRAM FB",
85 "DDR2 SDRAM FB Probe",
86 "DDR3 SDRAM"
89 static const char* spdmem_superset_types[] = {
90 "unknown",
91 "ESDRAM",
92 "DDR ESDRAM",
93 "PEM EDO",
94 "PEM SDRAM"
97 static const char* spdmem_voltage_types[] = {
98 "TTL (5V tolerant)",
99 "LvTTL (not 5V tolerant)",
100 "HSTL 1.5V",
101 "SSTL 3.3V",
102 "SSTL 2.5V",
103 "SSTL 1.8V"
106 static const char* spdmem_refresh_types[] = {
107 "15.625us",
108 "3.9us",
109 "7.8us",
110 "31.3us",
111 "62.5us",
112 "125us"
115 static const char* spdmem_parity_types[] = {
116 "no parity or ECC",
117 "data parity",
118 "data ECC",
119 "data parity and ECC",
120 "cmd/addr parity",
121 "cmd/addr/data parity",
122 "cmd/addr parity, data ECC",
123 "cmd/addr/data parity, data ECC"
126 /* Cycle time fractional values (units of .001 ns) for DDR2 SDRAM */
127 static const uint16_t spdmem_cycle_frac[] = {
128 0, 100, 200, 300, 400, 500, 600, 700, 800, 900,
129 250, 333, 667, 750, 999, 999
132 /* Format string for timing info */
133 static const char* latency="tAA-tRCD-tRP-tRAS: %d-%d-%d-%d\n";
135 /* sysctl stuff */
136 static int hw_node = CTL_EOL;
138 /* CRC functions used for certain memory types */
140 static uint16_t spdcrc16 (struct spdmem_softc *sc, int count)
142 uint16_t crc;
143 int i, j;
144 uint8_t val;
145 crc = 0;
146 for (j = 0; j <= count; j++) {
147 val = spdmem_read(sc, j);
148 crc = crc ^ val << 8;
149 for (i = 0; i < 8; ++i)
150 if (crc & 0x8000)
151 crc = crc << 1 ^ 0x1021;
152 else
153 crc = crc << 1;
155 return (crc & 0xFFFF);
157 static int
158 spdmem_match(device_t parent, cfdata_t match, void *aux)
160 struct i2c_attach_args *ia = aux;
161 struct spdmem_softc sc;
162 int cksum = 0;
163 uint8_t i, val, spd_type;
164 int spd_len, spd_crc_cover;
165 uint16_t crc_calc, crc_spd;
167 if ((ia->ia_addr & SPDMEM_ADDRMASK) != SPDMEM_ADDR)
168 return 0;
170 sc.sc_tag = ia->ia_tag;
171 sc.sc_addr = ia->ia_addr;
173 spd_type = spdmem_read(&sc, 2);
175 /* For older memory types, validate the checksum over 1st 63 bytes */
176 if (spd_type <= SPDMEM_MEMTYPE_DDR2SDRAM) {
177 for (i = 0; i < 63; i++)
178 cksum += spdmem_read(&sc, i);
180 val = spdmem_read(&sc, 63);
182 if (cksum == 0 || (cksum & 0xff) != val) {
183 aprint_debug("spd addr 0x%2x: ", sc.sc_addr);
184 aprint_debug("spd checksum failed, calc = 0x%02x, "
185 "spd = 0x%02x\n", cksum, val);
186 return 0;
187 } else
188 return 1;
191 /* For DDR3 and FBDIMM, verify the CRC */
192 else if (spd_type <= SPDMEM_MEMTYPE_DDR3SDRAM) {
193 spd_len = spdmem_read(&sc, 0);
194 if (spd_len && SPDMEM_SPDCRC_116)
195 spd_crc_cover = 116;
196 else
197 spd_crc_cover = 125;
198 switch (spd_len & SPDMEM_SPDLEN_MASK) {
199 case SPDMEM_SPDLEN_128:
200 spd_len = 128;
201 break;
202 case SPDMEM_SPDLEN_176:
203 spd_len = 176;
204 break;
205 case SPDMEM_SPDLEN_256:
206 spd_len = 256;
207 break;
208 default:
209 return 0;
211 if (spd_crc_cover > spd_len)
212 return 0;
213 crc_calc = spdcrc16(&sc, spd_crc_cover);
214 crc_spd = spdmem_read(&sc, 127) << 8;
215 crc_spd |= spdmem_read(&sc, 126);
216 if (crc_calc != crc_spd) {
217 aprint_debug("spd addr 0x%2x: ", sc.sc_addr);
218 aprint_debug("crc16 failed, covers %d bytes, "
219 "calc = 0x%04x, spd = 0x%04x\n",
220 spd_crc_cover, crc_calc, crc_spd);
221 return 0;
223 return 1;
226 /* For unrecognized memory types, don't match at all */
227 return 0;
230 static void
231 spdmem_attach(device_t parent, device_t self, void *aux)
233 struct spdmem_softc *sc = device_private(self);
234 struct i2c_attach_args *ia = aux;
235 struct spdmem *s = &(sc->sc_spd_data);
236 const char *type;
237 const char *rambus_rev = "Reserved";
238 int dimm_size;
239 int i;
240 unsigned int spd_len, spd_size;
241 const struct sysctlnode *node = NULL;
243 sc->sc_tag = ia->ia_tag;
244 sc->sc_addr = ia->ia_addr;
246 if (!pmf_device_register(self, NULL, NULL))
247 aprint_error_dev(self, "couldn't establish power handler\n");
250 * FBDIMM and DDR3 (and probably all newer) have a different
251 * encoding of the SPD EEPROM used/total sizes
253 s->sm_len = spdmem_read(sc, 0);
254 s->sm_size = spdmem_read(sc, 1);
255 s->sm_type = spdmem_read(sc, 2);
257 if (s->sm_type >= SPDMEM_MEMTYPE_FBDIMM) {
258 spd_size = 64 << (s->sm_len & SPDMEM_SPDSIZE_MASK);
259 switch (s->sm_len & SPDMEM_SPDLEN_MASK) {
260 case SPDMEM_SPDLEN_128:
261 spd_len = 128;
262 break;
263 case SPDMEM_SPDLEN_176:
264 spd_len = 176;
265 break;
266 case SPDMEM_SPDLEN_256:
267 spd_len = 256;
268 break;
269 default:
270 spd_len = 64;
271 break;
273 } else {
274 spd_size = 1 << s->sm_size;
275 spd_len = s->sm_len;
276 if (spd_len < 64)
277 spd_len = 64;
279 if (spd_len > spd_size)
280 spd_len = spd_size;
281 if (spd_len > sizeof(struct spdmem))
282 spd_len = sizeof(struct spdmem);
283 for (i = 3; i < spd_len; i++)
284 ((uint8_t *)s)[i] = spdmem_read(sc, i);
286 #ifdef DEBUG
287 for (i = 0; i < spd_len; i += 16) {
288 int j, k;
289 aprint_debug("\n");
290 aprint_debug_dev(self, "0x%02x:", i);
291 k = (spd_len > i + 16) ? spd_len : i + 16;
292 for (j = i; j < k; j++)
293 aprint_debug(" %02x", ((uint8_t *)s)[j]);
295 aprint_debug("\n");
296 aprint_debug_dev(self, "");
297 #endif
300 * Setup our sysctl subtree, hw.spdmemN
302 if (hw_node != CTL_EOL)
303 sysctl_createv(NULL, 0, NULL, &node,
304 0, CTLTYPE_NODE,
305 device_xname(self), NULL, NULL, 0, NULL, 0,
306 CTL_HW, CTL_CREATE, CTL_EOL);
307 if (node != NULL && spd_len != 0)
308 sysctl_createv(NULL, 0, NULL, NULL,
310 CTLTYPE_STRUCT, "spd_data",
311 SYSCTL_DESCR("raw spd data"), NULL,
312 0, s, spd_len,
313 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
316 * Decode and print key SPD contents
318 if (IS_RAMBUS_TYPE) {
319 if (s->sm_type == SPDMEM_MEMTYPE_RAMBUS)
320 type = "Rambus";
321 else if (s->sm_type == SPDMEM_MEMTYPE_DIRECTRAMBUS)
322 type = "Direct Rambus";
323 else
324 type = "Rambus (unknown)";
326 switch (s->sm_len) {
327 case 0:
328 rambus_rev = "Invalid";
329 break;
330 case 1:
331 rambus_rev = "0.7";
332 break;
333 case 2:
334 rambus_rev = "1.0";
335 break;
336 default:
337 rambus_rev = "Reserved";
338 break;
340 } else {
341 if (s->sm_type < __arraycount(spdmem_basic_types))
342 type = spdmem_basic_types[s->sm_type];
343 else
344 type = "unknown memory type";
346 if (s->sm_type == SPDMEM_MEMTYPE_EDO &&
347 s->sm_fpm.fpm_superset == SPDMEM_SUPERSET_EDO_PEM)
348 type = spdmem_superset_types[SPDMEM_SUPERSET_EDO_PEM];
349 if (s->sm_type == SPDMEM_MEMTYPE_SDRAM &&
350 s->sm_sdr.sdr_superset == SPDMEM_SUPERSET_SDRAM_PEM)
351 type = spdmem_superset_types[SPDMEM_SUPERSET_SDRAM_PEM];
352 if (s->sm_type == SPDMEM_MEMTYPE_DDRSDRAM &&
353 s->sm_ddr.ddr_superset == SPDMEM_SUPERSET_DDR_ESDRAM)
354 type =
355 spdmem_superset_types[SPDMEM_SUPERSET_DDR_ESDRAM];
356 if (s->sm_type == SPDMEM_MEMTYPE_SDRAM &&
357 s->sm_sdr.sdr_superset == SPDMEM_SUPERSET_ESDRAM) {
358 type = spdmem_superset_types[SPDMEM_SUPERSET_ESDRAM];
362 aprint_normal("\n");
363 aprint_normal_dev(self, "%s", type);
364 strlcpy(sc->sc_type, type, SPDMEM_TYPE_MAXLEN);
365 if (node != NULL)
366 sysctl_createv(NULL, 0, NULL, NULL,
368 CTLTYPE_STRING, "mem_type",
369 SYSCTL_DESCR("memory module type"), NULL,
370 0, sc->sc_type, 0,
371 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
373 if (IS_RAMBUS_TYPE) {
374 aprint_normal(", SPD Revision %s", rambus_rev);
375 dimm_size = 1 << (s->sm_rdr.rdr_rows + s->sm_rdr.rdr_cols - 13);
376 if (dimm_size >= 1024)
377 aprint_normal(", %dGB\n", dimm_size / 1024);
378 else
379 aprint_normal(", %dMB\n", dimm_size);
381 /* No further decode for RAMBUS memory */
382 return;
384 switch (s->sm_type) {
385 case SPDMEM_MEMTYPE_EDO:
386 case SPDMEM_MEMTYPE_FPM:
387 decode_edofpm(node, self, s);
388 break;
389 case SPDMEM_MEMTYPE_ROM:
390 decode_rom(node, self, s);
391 break;
392 case SPDMEM_MEMTYPE_SDRAM:
393 decode_sdram(node, self, s);
394 break;
395 case SPDMEM_MEMTYPE_DDRSDRAM:
396 decode_ddr(node, self, s);
397 break;
398 case SPDMEM_MEMTYPE_DDR2SDRAM:
399 decode_ddr2(node, self, s);
400 break;
401 case SPDMEM_MEMTYPE_DDR3SDRAM:
402 decode_ddr3(node, self, s);
403 break;
404 case SPDMEM_MEMTYPE_FBDIMM:
405 case SPDMEM_MEMTYPE_FBDIMM_PROBE:
406 decode_fbdimm(node, self, s);
407 break;
411 static uint8_t
412 spdmem_read(struct spdmem_softc *sc, uint8_t reg)
414 uint8_t val;
416 iic_acquire_bus(sc->sc_tag, 0);
417 iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, &reg, 1,
418 &val, 1, 0);
419 iic_release_bus(sc->sc_tag, 0);
421 return val;
424 SYSCTL_SETUP(sysctl_spdmem_setup, "sysctl hw.spdmem subtree setup")
426 const struct sysctlnode *node;
428 if (sysctl_createv(clog, 0, NULL, &node,
429 CTLFLAG_PERMANENT,
430 CTLTYPE_NODE, "hw", NULL,
431 NULL, 0, NULL, 0,
432 CTL_HW, CTL_EOL) != 0)
433 return;
435 hw_node = node->sysctl_num;
438 static void
439 decode_size_speed(const struct sysctlnode *node, int dimm_size, int cycle_time,
440 int d_clk, int bits, bool round, const char *ddr_type_string)
442 int p_clk;
444 if (dimm_size < 1024)
445 aprint_normal("%dMB", dimm_size);
446 else
447 aprint_normal("%dGB", dimm_size / 1024);
448 if (node != NULL)
449 sysctl_createv(NULL, 0, NULL, NULL,
450 CTLFLAG_IMMEDIATE,
451 CTLTYPE_INT, "size",
452 SYSCTL_DESCR("module size in MB"), NULL,
453 dimm_size, NULL, 0,
454 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
456 if (cycle_time == 0) {
457 aprint_normal("\n");
458 return;
462 * Calculate p_clk first, since for DDR3 we need maximum significance.
463 * DDR3 rating is not rounded to a multiple of 100. This results in
464 * cycle_time of 1.5ns displayed as PC3-10666.
466 d_clk *= 1000 * 1000;
467 p_clk = (d_clk * bits) / 8 / cycle_time;
468 d_clk = ((d_clk + cycle_time / 2) ) / cycle_time;
469 if (round) {
470 if ((p_clk % 100) >= 50)
471 p_clk += 50;
472 p_clk -= p_clk % 100;
474 aprint_normal(", %dMHz (%s-%d)\n",
475 d_clk, ddr_type_string, p_clk);
476 if (node != NULL)
477 sysctl_createv(NULL, 0, NULL, NULL,
478 CTLFLAG_IMMEDIATE,
479 CTLTYPE_INT, "speed",
480 SYSCTL_DESCR("memory speed in MHz"),
481 NULL, d_clk, NULL, 0,
482 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
485 static void
486 decode_voltage_refresh(device_t self, struct spdmem *s)
488 const char *voltage, *refresh;
490 if (s->sm_voltage < __arraycount(spdmem_voltage_types))
491 voltage = spdmem_voltage_types[s->sm_voltage];
492 else
493 voltage = "unknown";
495 if (s->sm_refresh < __arraycount(spdmem_refresh_types))
496 refresh = spdmem_refresh_types[s->sm_refresh];
497 else
498 refresh = "unknown";
500 aprint_verbose_dev(self, "voltage %s, refresh time %s%s\n",
501 voltage, refresh,
502 s->sm_selfrefresh?" (self-refreshing)":"");
505 static void
506 decode_edofpm(const struct sysctlnode *node, device_t self, struct spdmem *s) {
507 aprint_normal("\n");
508 aprint_verbose_dev(self,
509 "%d rows, %d cols, %d banks, %dns tRAC, %dns tCAC\n",
510 s->sm_fpm.fpm_rows, s->sm_fpm.fpm_cols, s->sm_fpm.fpm_banks,
511 s->sm_fpm.fpm_tRAC, s->sm_fpm.fpm_tCAC);
514 static void
515 decode_rom(const struct sysctlnode *node, device_t self, struct spdmem *s) {
516 aprint_normal("\n");
517 aprint_verbose_dev(self, "%d rows, %d cols, %d banks\n",
518 s->sm_rom.rom_rows, s->sm_rom.rom_cols, s->sm_rom.rom_banks);
521 static void
522 decode_sdram(const struct sysctlnode *node, device_t self, struct spdmem *s) {
523 int dimm_size, cycle_time, bits, tAA, i;
525 aprint_normal("%s, %s, ",
526 (s->sm_sdr.sdr_mod_attrs & SPDMEM_SDR_MASK_REG)?
527 " (registered)":"",
528 (s->sm_config < __arraycount(spdmem_parity_types))?
529 spdmem_parity_types[s->sm_config]:"invalid parity");
531 dimm_size = 1 << (s->sm_sdr.sdr_rows + s->sm_sdr.sdr_cols - 17);
532 dimm_size *= s->sm_sdr.sdr_banks * s->sm_sdr.sdr_banks_per_chip;
534 cycle_time = s->sm_sdr.sdr_cycle_whole * 1000 +
535 s->sm_sdr.sdr_cycle_tenths * 100;
536 bits = le16toh(s->sm_sdr.sdr_datawidth);
537 if (s->sm_config == 1 || s->sm_config == 2)
538 bits -= 8;
539 decode_size_speed(node, dimm_size, cycle_time, 1, bits, TRUE, "PC");
541 aprint_verbose_dev(self,
542 "%d rows, %d cols, %d banks, %d banks/chip, %d.%dns cycle time\n",
543 s->sm_sdr.sdr_rows, s->sm_sdr.sdr_cols, s->sm_sdr.sdr_banks,
544 s->sm_sdr.sdr_banks_per_chip, cycle_time/1000,
545 (cycle_time % 1000) / 100);
547 tAA = 0;
548 for (i = 0; i < 8; i++)
549 if (s->sm_sdr.sdr_tCAS & (1 << i))
550 tAA = i;
551 tAA++;
552 aprint_verbose_dev(self, latency, tAA, s->sm_sdr.sdr_tRCD,
553 s->sm_sdr.sdr_tRP, s->sm_sdr.sdr_tRAS);
555 decode_voltage_refresh(self, s);
558 static void
559 decode_ddr(const struct sysctlnode *node, device_t self, struct spdmem *s) {
560 int dimm_size, cycle_time, bits, tAA, i;
562 aprint_normal("%s, %s, ",
563 (s->sm_ddr.ddr_mod_attrs & SPDMEM_DDR_MASK_REG)?
564 " (registered)":"",
565 (s->sm_config < __arraycount(spdmem_parity_types))?
566 spdmem_parity_types[s->sm_config]:"invalid parity");
568 dimm_size = 1 << (s->sm_ddr.ddr_rows + s->sm_ddr.ddr_cols - 17);
569 dimm_size *= s->sm_ddr.ddr_ranks * s->sm_ddr.ddr_banks_per_chip;
571 cycle_time = s->sm_ddr.ddr_cycle_whole * 1000 +
572 spdmem_cycle_frac[s->sm_ddr.ddr_cycle_tenths];
573 bits = le16toh(s->sm_ddr.ddr_datawidth);
574 if (s->sm_config == 1 || s->sm_config == 2)
575 bits -= 8;
576 decode_size_speed(node, dimm_size, cycle_time, 2, bits, TRUE, "PC");
578 aprint_verbose_dev(self,
579 "%d rows, %d cols, %d ranks, %d banks/chip, %d.%dns cycle time\n",
580 s->sm_ddr.ddr_rows, s->sm_ddr.ddr_cols, s->sm_ddr.ddr_ranks,
581 s->sm_ddr.ddr_banks_per_chip, cycle_time/1000,
582 (cycle_time % 1000 + 50) / 100);
584 tAA = 0;
585 for (i = 2; i < 8; i++)
586 if (s->sm_ddr.ddr_tCAS & (1 << i))
587 tAA = i;
588 tAA /= 2;
590 #define __DDR_ROUND(scale, field) \
591 ((scale * s->sm_ddr.field + cycle_time - 1) / cycle_time)
593 aprint_verbose_dev(self, latency, tAA, __DDR_ROUND(250, ddr_tRCD),
594 __DDR_ROUND(250, ddr_tRP), __DDR_ROUND(1000, ddr_tRAS));
596 #undef __DDR_ROUND
598 decode_voltage_refresh(self, s);
601 static void
602 decode_ddr2(const struct sysctlnode *node, device_t self, struct spdmem *s) {
603 int dimm_size, cycle_time, bits, tAA, i;
605 aprint_normal("%s, %s, ",
606 (s->sm_ddr2.ddr2_mod_attrs & SPDMEM_DDR2_MASK_REG)?
607 " (registered)":"",
608 (s->sm_config < __arraycount(spdmem_parity_types))?
609 spdmem_parity_types[s->sm_config]:"invalid parity");
611 dimm_size = 1 << (s->sm_ddr2.ddr2_rows + s->sm_ddr2.ddr2_cols - 17);
612 dimm_size *= (s->sm_ddr2.ddr2_ranks + 1) *
613 s->sm_ddr2.ddr2_banks_per_chip;
615 cycle_time = s->sm_ddr2.ddr2_cycle_whole * 1000 +
616 spdmem_cycle_frac[s->sm_ddr2.ddr2_cycle_frac];
617 bits = s->sm_ddr2.ddr2_datawidth;
618 if ((s->sm_config & 0x03) != 0)
619 bits -= 8;
620 decode_size_speed(node, dimm_size, cycle_time, 2, bits, TRUE, "PC2");
622 aprint_verbose_dev(self,
623 "%d rows, %d cols, %d ranks, %d banks/chip, %d.%02dns cycle time\n",
624 s->sm_ddr2.ddr2_rows, s->sm_ddr2.ddr2_cols,
625 s->sm_ddr2.ddr2_ranks + 1, s->sm_ddr2.ddr2_banks_per_chip,
626 cycle_time / 1000, (cycle_time % 1000 + 5) /10 );
628 tAA = 0;
629 for (i = 2; i < 8; i++)
630 if (s->sm_ddr2.ddr2_tCAS & (1 << i))
631 tAA = i;
633 #define __DDR2_ROUND(scale, field) \
634 ((scale * s->sm_ddr2.field + cycle_time - 1) / cycle_time)
636 aprint_verbose_dev(self, latency, tAA, __DDR2_ROUND(250, ddr2_tRCD),
637 __DDR2_ROUND(250, ddr2_tRP), __DDR2_ROUND(1000, ddr2_tRAS));
639 #undef __DDR_ROUND
641 decode_voltage_refresh(self, s);
644 static void
645 decode_ddr3(const struct sysctlnode *node, device_t self, struct spdmem *s) {
646 int dimm_size, cycle_time, bits;
648 if (s->sm_ddr3.ddr3_mod_type ==
649 SPDMEM_DDR3_TYPE_MINI_RDIMM ||
650 s->sm_ddr3.ddr3_mod_type == SPDMEM_DDR3_TYPE_RDIMM)
651 aprint_normal(" (registered)");
652 aprint_normal(", %sECC, %stemp-sensor, ",
653 (s->sm_ddr3.ddr3_hasECC)?"":"no ",
654 (s->sm_ddr3.ddr3_has_therm_sensor)?"":"no ");
657 * DDR3 size specification is quite different from others
659 * Module capacity is defined as
660 * Chip_Capacity_in_bits / 8bits-per-byte *
661 * external_bus_width / internal_bus_width
662 * We further divide by 2**20 to get our answer in MB
664 dimm_size = (s->sm_ddr3.ddr3_chipsize + 28 - 20) - 3 +
665 (s->sm_ddr3.ddr3_datawidth + 3) -
666 (s->sm_ddr3.ddr3_chipwidth + 2);
667 dimm_size = (1 << dimm_size) * (s->sm_ddr3.ddr3_physbanks + 1);
669 cycle_time = (1000 * s->sm_ddr3.ddr3_mtb_dividend +
670 (s->sm_ddr3.ddr3_mtb_divisor / 2)) /
671 s->sm_ddr3.ddr3_mtb_divisor;
672 cycle_time *= s->sm_ddr3.ddr3_tCKmin;
673 bits = 1 << (s->sm_ddr3.ddr3_datawidth + 3);
674 decode_size_speed(node, dimm_size, cycle_time, 2, bits, FALSE, "PC3");
676 aprint_verbose_dev(self,
677 "%d rows, %d cols, %d log. banks, %d phys. banks, "
678 "%d.%03dns cycle time\n",
679 s->sm_ddr3.ddr3_rows + 9, s->sm_ddr3.ddr3_cols + 12,
680 1 << (s->sm_ddr3.ddr3_logbanks + 3),
681 s->sm_ddr3.ddr3_physbanks + 1,
682 cycle_time/1000, cycle_time % 1000);
684 #define __DDR3_CYCLES(field) (s->sm_ddr3.field / s->sm_ddr3.ddr3_tCKmin)
686 aprint_verbose_dev(self, latency, __DDR3_CYCLES(ddr3_tAAmin),
687 __DDR3_CYCLES(ddr3_tRCDmin), __DDR3_CYCLES(ddr3_tRPmin),
688 (s->sm_ddr3.ddr3_tRAS_msb * 256 + s->sm_ddr3.ddr3_tRAS_lsb) /
689 s->sm_ddr3.ddr3_tCKmin);
691 #undef __DDR3_CYCLES
694 static void
695 decode_fbdimm(const struct sysctlnode *node, device_t self, struct spdmem *s) {
696 int dimm_size, cycle_time, bits;
699 * FB-DIMM module size calculation is very much like DDR3
701 dimm_size = s->sm_fbd.fbdimm_rows + 12 +
702 s->sm_fbd.fbdimm_cols + 9 - 20 - 3;
703 dimm_size = (1 << dimm_size) * (1 << (s->sm_fbd.fbdimm_banks + 2));
705 cycle_time = (1000 * s->sm_fbd.fbdimm_mtb_dividend +
706 (s->sm_fbd.fbdimm_mtb_divisor / 2)) /
707 s->sm_fbd.fbdimm_mtb_divisor;
708 bits = 1 << (s->sm_fbd.fbdimm_dev_width + 2);
709 decode_size_speed(node, dimm_size, cycle_time, 2, bits, TRUE, "PC2");
711 aprint_verbose_dev(self,
712 "%d rows, %d cols, %d banks, %d.%02dns cycle time\n",
713 s->sm_fbd.fbdimm_rows, s->sm_fbd.fbdimm_cols,
714 1 << (s->sm_fbd.fbdimm_banks + 2),
715 cycle_time / 1000, (cycle_time % 1000 + 5) /10 );
717 #define __FBDIMM_CYCLES(field) (s->sm_fbd.field / s->sm_fbd.fbdimm_tCKmin)
719 aprint_verbose_dev(self, latency, __FBDIMM_CYCLES(fbdimm_tAAmin),
720 __FBDIMM_CYCLES(fbdimm_tRCDmin), __FBDIMM_CYCLES(fbdimm_tRPmin),
721 (s->sm_fbd.fbdimm_tRAS_msb * 256 +
722 s->sm_fbd.fbdimm_tRAS_lsb) /
723 s->sm_fbd.fbdimm_tCKmin);
725 #undef __FBDIMM_CYCLES
727 decode_voltage_refresh(self, s);