spdmem.c revision 1.18 1 1.18 msaitoh /* $NetBSD: spdmem.c,v 1.18 2015/12/07 14:13:05 msaitoh Exp $ */
2 1.1 pgoyette
3 1.1 pgoyette /*
4 1.1 pgoyette * Copyright (c) 2007 Nicolas Joly
5 1.1 pgoyette * Copyright (c) 2007 Paul Goyette
6 1.1 pgoyette * Copyright (c) 2007 Tobias Nygren
7 1.1 pgoyette * All rights reserved.
8 1.1 pgoyette *
9 1.1 pgoyette * Redistribution and use in source and binary forms, with or without
10 1.1 pgoyette * modification, are permitted provided that the following conditions
11 1.1 pgoyette * are met:
12 1.1 pgoyette * 1. Redistributions of source code must retain the above copyright
13 1.1 pgoyette * notice, this list of conditions and the following disclaimer.
14 1.1 pgoyette * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 pgoyette * notice, this list of conditions and the following disclaimer in the
16 1.1 pgoyette * documentation and/or other materials provided with the distribution.
17 1.1 pgoyette * 3. The name of the author may not be used to endorse or promote products
18 1.1 pgoyette * derived from this software without specific prior written permission.
19 1.1 pgoyette *
20 1.1 pgoyette * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
21 1.1 pgoyette * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 1.1 pgoyette * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 1.1 pgoyette * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 1.1 pgoyette * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 1.1 pgoyette * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 1.1 pgoyette * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 1.1 pgoyette * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 1.1 pgoyette * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 1.1 pgoyette * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 1.1 pgoyette * POSSIBILITY OF SUCH DAMAGE.
31 1.1 pgoyette */
32 1.1 pgoyette
33 1.1 pgoyette /*
34 1.1 pgoyette * Serial Presence Detect (SPD) memory identification
35 1.1 pgoyette */
36 1.1 pgoyette
37 1.1 pgoyette #include <sys/cdefs.h>
38 1.18 msaitoh __KERNEL_RCSID(0, "$NetBSD: spdmem.c,v 1.18 2015/12/07 14:13:05 msaitoh Exp $");
39 1.1 pgoyette
40 1.1 pgoyette #include <sys/param.h>
41 1.1 pgoyette #include <sys/device.h>
42 1.1 pgoyette #include <sys/endian.h>
43 1.1 pgoyette #include <sys/sysctl.h>
44 1.1 pgoyette #include <machine/bswap.h>
45 1.1 pgoyette
46 1.1 pgoyette #include <dev/i2c/i2cvar.h>
47 1.1 pgoyette #include <dev/ic/spdmemreg.h>
48 1.1 pgoyette #include <dev/ic/spdmemvar.h>
49 1.1 pgoyette
50 1.1 pgoyette /* Routines for decoding spd data */
51 1.1 pgoyette static void decode_edofpm(const struct sysctlnode *, device_t, struct spdmem *);
52 1.1 pgoyette static void decode_rom(const struct sysctlnode *, device_t, struct spdmem *);
53 1.1 pgoyette static void decode_sdram(const struct sysctlnode *, device_t, struct spdmem *,
54 1.1 pgoyette int);
55 1.1 pgoyette static void decode_ddr(const struct sysctlnode *, device_t, struct spdmem *);
56 1.1 pgoyette static void decode_ddr2(const struct sysctlnode *, device_t, struct spdmem *);
57 1.1 pgoyette static void decode_ddr3(const struct sysctlnode *, device_t, struct spdmem *);
58 1.13 pgoyette static void decode_ddr4(const struct sysctlnode *, device_t, struct spdmem *);
59 1.1 pgoyette static void decode_fbdimm(const struct sysctlnode *, device_t, struct spdmem *);
60 1.1 pgoyette
61 1.3 pgoyette static void decode_size_speed(device_t, const struct sysctlnode *,
62 1.3 pgoyette int, int, int, int, bool, const char *, int);
63 1.1 pgoyette static void decode_voltage_refresh(device_t, struct spdmem *);
64 1.1 pgoyette
65 1.1 pgoyette #define IS_RAMBUS_TYPE (s->sm_len < 4)
66 1.1 pgoyette
67 1.12 matt static const char* const spdmem_basic_types[] = {
68 1.1 pgoyette "unknown",
69 1.1 pgoyette "FPM",
70 1.1 pgoyette "EDO",
71 1.1 pgoyette "Pipelined Nibble",
72 1.1 pgoyette "SDRAM",
73 1.1 pgoyette "ROM",
74 1.1 pgoyette "DDR SGRAM",
75 1.1 pgoyette "DDR SDRAM",
76 1.1 pgoyette "DDR2 SDRAM",
77 1.1 pgoyette "DDR2 SDRAM FB",
78 1.1 pgoyette "DDR2 SDRAM FB Probe",
79 1.12 matt "DDR3 SDRAM",
80 1.11 msaitoh "DDR4 SDRAM"
81 1.1 pgoyette };
82 1.1 pgoyette
83 1.13 pgoyette static const char* const spdmem_ddr4_module_types[] = {
84 1.13 pgoyette "DDR4 Extended",
85 1.13 pgoyette "DDR4 RDIMM",
86 1.13 pgoyette "DDR4 UDIMM",
87 1.13 pgoyette "DDR4 SO-DIMM",
88 1.13 pgoyette "DDR4 Load-Reduced DIMM",
89 1.13 pgoyette "DDR4 Mini-RDIMM",
90 1.13 pgoyette "DDR4 Mini-UDIMM",
91 1.13 pgoyette "DDR4 Reserved",
92 1.13 pgoyette "DDR4 72Bit SO-RDIMM",
93 1.13 pgoyette "DDR4 72Bit SO-UDIMM",
94 1.13 pgoyette "DDR4 Undefined",
95 1.13 pgoyette "DDR4 Reserved",
96 1.13 pgoyette "DDR4 16Bit SO-DIMM",
97 1.13 pgoyette "DDR4 32Bit SO-DIMM",
98 1.13 pgoyette "DDR4 Reserved",
99 1.13 pgoyette "DDR4 Undefined"
100 1.13 pgoyette };
101 1.13 pgoyette
102 1.12 matt static const char* const spdmem_superset_types[] = {
103 1.1 pgoyette "unknown",
104 1.1 pgoyette "ESDRAM",
105 1.1 pgoyette "DDR ESDRAM",
106 1.1 pgoyette "PEM EDO",
107 1.1 pgoyette "PEM SDRAM"
108 1.1 pgoyette };
109 1.1 pgoyette
110 1.12 matt static const char* const spdmem_voltage_types[] = {
111 1.1 pgoyette "TTL (5V tolerant)",
112 1.1 pgoyette "LvTTL (not 5V tolerant)",
113 1.1 pgoyette "HSTL 1.5V",
114 1.1 pgoyette "SSTL 3.3V",
115 1.1 pgoyette "SSTL 2.5V",
116 1.1 pgoyette "SSTL 1.8V"
117 1.1 pgoyette };
118 1.1 pgoyette
119 1.12 matt static const char* const spdmem_refresh_types[] = {
120 1.1 pgoyette "15.625us",
121 1.1 pgoyette "3.9us",
122 1.1 pgoyette "7.8us",
123 1.1 pgoyette "31.3us",
124 1.1 pgoyette "62.5us",
125 1.1 pgoyette "125us"
126 1.1 pgoyette };
127 1.1 pgoyette
128 1.12 matt static const char* const spdmem_parity_types[] = {
129 1.1 pgoyette "no parity or ECC",
130 1.1 pgoyette "data parity",
131 1.1 pgoyette "data ECC",
132 1.1 pgoyette "data parity and ECC",
133 1.1 pgoyette "cmd/addr parity",
134 1.1 pgoyette "cmd/addr/data parity",
135 1.1 pgoyette "cmd/addr parity, data ECC",
136 1.1 pgoyette "cmd/addr/data parity, data ECC"
137 1.1 pgoyette };
138 1.1 pgoyette
139 1.13 pgoyette int spd_rom_sizes[] = { 0, 128, 256, 384, 512 };
140 1.13 pgoyette
141 1.13 pgoyette
142 1.1 pgoyette /* Cycle time fractional values (units of .001 ns) for DDR2 SDRAM */
143 1.1 pgoyette static const uint16_t spdmem_cycle_frac[] = {
144 1.1 pgoyette 0, 100, 200, 300, 400, 500, 600, 700, 800, 900,
145 1.1 pgoyette 250, 333, 667, 750, 999, 999
146 1.1 pgoyette };
147 1.1 pgoyette
148 1.1 pgoyette /* Format string for timing info */
149 1.5 wiz #define LATENCY "tAA-tRCD-tRP-tRAS: %d-%d-%d-%d\n"
150 1.1 pgoyette
151 1.1 pgoyette /* CRC functions used for certain memory types */
152 1.1 pgoyette
153 1.1 pgoyette static uint16_t spdcrc16 (struct spdmem_softc *sc, int count)
154 1.1 pgoyette {
155 1.1 pgoyette uint16_t crc;
156 1.1 pgoyette int i, j;
157 1.1 pgoyette uint8_t val;
158 1.1 pgoyette crc = 0;
159 1.1 pgoyette for (j = 0; j <= count; j++) {
160 1.1 pgoyette val = (sc->sc_read)(sc, j);
161 1.1 pgoyette crc = crc ^ val << 8;
162 1.1 pgoyette for (i = 0; i < 8; ++i)
163 1.1 pgoyette if (crc & 0x8000)
164 1.1 pgoyette crc = crc << 1 ^ 0x1021;
165 1.1 pgoyette else
166 1.1 pgoyette crc = crc << 1;
167 1.1 pgoyette }
168 1.1 pgoyette return (crc & 0xFFFF);
169 1.1 pgoyette }
170 1.1 pgoyette
171 1.1 pgoyette int
172 1.1 pgoyette spdmem_common_probe(struct spdmem_softc *sc)
173 1.1 pgoyette {
174 1.1 pgoyette int cksum = 0;
175 1.1 pgoyette uint8_t i, val, spd_type;
176 1.1 pgoyette int spd_len, spd_crc_cover;
177 1.1 pgoyette uint16_t crc_calc, crc_spd;
178 1.1 pgoyette
179 1.1 pgoyette spd_type = (sc->sc_read)(sc, 2);
180 1.1 pgoyette
181 1.1 pgoyette /* For older memory types, validate the checksum over 1st 63 bytes */
182 1.1 pgoyette if (spd_type <= SPDMEM_MEMTYPE_DDR2SDRAM) {
183 1.1 pgoyette for (i = 0; i < 63; i++)
184 1.1 pgoyette cksum += (sc->sc_read)(sc, i);
185 1.1 pgoyette
186 1.1 pgoyette val = (sc->sc_read)(sc, 63);
187 1.1 pgoyette
188 1.1 pgoyette if (cksum == 0 || (cksum & 0xff) != val) {
189 1.1 pgoyette aprint_debug("spd checksum failed, calc = 0x%02x, "
190 1.1 pgoyette "spd = 0x%02x\n", cksum, val);
191 1.1 pgoyette return 0;
192 1.1 pgoyette } else
193 1.1 pgoyette return 1;
194 1.1 pgoyette }
195 1.1 pgoyette
196 1.1 pgoyette /* For DDR3 and FBDIMM, verify the CRC */
197 1.1 pgoyette else if (spd_type <= SPDMEM_MEMTYPE_DDR3SDRAM) {
198 1.1 pgoyette spd_len = (sc->sc_read)(sc, 0);
199 1.2 pgoyette if (spd_len & SPDMEM_SPDCRC_116)
200 1.1 pgoyette spd_crc_cover = 116;
201 1.1 pgoyette else
202 1.1 pgoyette spd_crc_cover = 125;
203 1.1 pgoyette switch (spd_len & SPDMEM_SPDLEN_MASK) {
204 1.1 pgoyette case SPDMEM_SPDLEN_128:
205 1.1 pgoyette spd_len = 128;
206 1.1 pgoyette break;
207 1.1 pgoyette case SPDMEM_SPDLEN_176:
208 1.1 pgoyette spd_len = 176;
209 1.1 pgoyette break;
210 1.1 pgoyette case SPDMEM_SPDLEN_256:
211 1.1 pgoyette spd_len = 256;
212 1.1 pgoyette break;
213 1.1 pgoyette default:
214 1.1 pgoyette return 0;
215 1.1 pgoyette }
216 1.1 pgoyette if (spd_crc_cover > spd_len)
217 1.1 pgoyette return 0;
218 1.1 pgoyette crc_calc = spdcrc16(sc, spd_crc_cover);
219 1.1 pgoyette crc_spd = (sc->sc_read)(sc, 127) << 8;
220 1.1 pgoyette crc_spd |= (sc->sc_read)(sc, 126);
221 1.1 pgoyette if (crc_calc != crc_spd) {
222 1.1 pgoyette aprint_debug("crc16 failed, covers %d bytes, "
223 1.1 pgoyette "calc = 0x%04x, spd = 0x%04x\n",
224 1.1 pgoyette spd_crc_cover, crc_calc, crc_spd);
225 1.1 pgoyette return 0;
226 1.1 pgoyette }
227 1.1 pgoyette return 1;
228 1.13 pgoyette } else if (spd_type == SPDMEM_MEMTYPE_DDR4SDRAM) {
229 1.13 pgoyette spd_len = (sc->sc_read)(sc, 0) & 0x0f;
230 1.13 pgoyette if ((unsigned int)spd_len > __arraycount(spd_rom_sizes))
231 1.13 pgoyette return 0;
232 1.13 pgoyette spd_len = spd_rom_sizes[spd_len];
233 1.17 msaitoh spd_crc_cover = 125; /* For byte 0 to 125 */
234 1.13 pgoyette if (spd_crc_cover > spd_len)
235 1.13 pgoyette return 0;
236 1.13 pgoyette crc_calc = spdcrc16(sc, spd_crc_cover);
237 1.13 pgoyette crc_spd = (sc->sc_read)(sc, 127) << 8;
238 1.13 pgoyette crc_spd |= (sc->sc_read)(sc, 126);
239 1.13 pgoyette if (crc_calc != crc_spd) {
240 1.13 pgoyette aprint_debug("crc16 failed, covers %d bytes, "
241 1.13 pgoyette "calc = 0x%04x, spd = 0x%04x\n",
242 1.13 pgoyette spd_crc_cover, crc_calc, crc_spd);
243 1.13 pgoyette return 0;
244 1.13 pgoyette }
245 1.13 pgoyette /*
246 1.13 pgoyette * We probably could also verify the CRC for the other
247 1.13 pgoyette * "pages" of SPD data in blocks 1 and 2, but we'll do
248 1.13 pgoyette * it some other time.
249 1.13 pgoyette */
250 1.13 pgoyette return 1;
251 1.13 pgoyette } else
252 1.13 pgoyette return 0;
253 1.1 pgoyette
254 1.1 pgoyette /* For unrecognized memory types, don't match at all */
255 1.1 pgoyette return 0;
256 1.1 pgoyette }
257 1.1 pgoyette
258 1.1 pgoyette void
259 1.1 pgoyette spdmem_common_attach(struct spdmem_softc *sc, device_t self)
260 1.1 pgoyette {
261 1.1 pgoyette struct spdmem *s = &(sc->sc_spd_data);
262 1.1 pgoyette const char *type;
263 1.1 pgoyette const char *rambus_rev = "Reserved";
264 1.1 pgoyette int dimm_size;
265 1.3 pgoyette unsigned int i, spd_len, spd_size;
266 1.1 pgoyette const struct sysctlnode *node = NULL;
267 1.1 pgoyette
268 1.1 pgoyette s->sm_len = (sc->sc_read)(sc, 0);
269 1.1 pgoyette s->sm_size = (sc->sc_read)(sc, 1);
270 1.1 pgoyette s->sm_type = (sc->sc_read)(sc, 2);
271 1.1 pgoyette
272 1.13 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_DDR4SDRAM) {
273 1.13 pgoyette /*
274 1.13 pgoyette * An even newer encoding with one byte holding both
275 1.13 pgoyette * the used-size and capacity values
276 1.13 pgoyette */
277 1.13 pgoyette spd_len = s->sm_len & 0x0f;
278 1.13 pgoyette spd_size = (s->sm_len >> 4) & 0x07;
279 1.13 pgoyette
280 1.13 pgoyette spd_len = spd_rom_sizes[spd_len];
281 1.13 pgoyette spd_size *= 512;
282 1.13 pgoyette
283 1.13 pgoyette } else if (s->sm_type >= SPDMEM_MEMTYPE_FBDIMM) {
284 1.13 pgoyette /*
285 1.13 pgoyette * FBDIMM and DDR3 (and probably all newer) have a different
286 1.13 pgoyette * encoding of the SPD EEPROM used/total sizes
287 1.13 pgoyette */
288 1.1 pgoyette spd_size = 64 << (s->sm_len & SPDMEM_SPDSIZE_MASK);
289 1.1 pgoyette switch (s->sm_len & SPDMEM_SPDLEN_MASK) {
290 1.1 pgoyette case SPDMEM_SPDLEN_128:
291 1.1 pgoyette spd_len = 128;
292 1.1 pgoyette break;
293 1.1 pgoyette case SPDMEM_SPDLEN_176:
294 1.1 pgoyette spd_len = 176;
295 1.1 pgoyette break;
296 1.1 pgoyette case SPDMEM_SPDLEN_256:
297 1.1 pgoyette spd_len = 256;
298 1.1 pgoyette break;
299 1.1 pgoyette default:
300 1.1 pgoyette spd_len = 64;
301 1.1 pgoyette break;
302 1.1 pgoyette }
303 1.1 pgoyette } else {
304 1.1 pgoyette spd_size = 1 << s->sm_size;
305 1.1 pgoyette spd_len = s->sm_len;
306 1.1 pgoyette if (spd_len < 64)
307 1.1 pgoyette spd_len = 64;
308 1.1 pgoyette }
309 1.1 pgoyette if (spd_len > spd_size)
310 1.1 pgoyette spd_len = spd_size;
311 1.1 pgoyette if (spd_len > sizeof(struct spdmem))
312 1.1 pgoyette spd_len = sizeof(struct spdmem);
313 1.1 pgoyette for (i = 3; i < spd_len; i++)
314 1.1 pgoyette ((uint8_t *)s)[i] = (sc->sc_read)(sc, i);
315 1.1 pgoyette
316 1.1 pgoyette /*
317 1.1 pgoyette * Setup our sysctl subtree, hw.spdmemN
318 1.1 pgoyette */
319 1.3 pgoyette sc->sc_sysctl_log = NULL;
320 1.9 pooka sysctl_createv(&sc->sc_sysctl_log, 0, NULL, &node,
321 1.9 pooka 0, CTLTYPE_NODE,
322 1.9 pooka device_xname(self), NULL, NULL, 0, NULL, 0,
323 1.9 pooka CTL_HW, CTL_CREATE, CTL_EOL);
324 1.1 pgoyette if (node != NULL && spd_len != 0)
325 1.3 pgoyette sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL,
326 1.1 pgoyette 0,
327 1.1 pgoyette CTLTYPE_STRUCT, "spd_data",
328 1.1 pgoyette SYSCTL_DESCR("raw spd data"), NULL,
329 1.1 pgoyette 0, s, spd_len,
330 1.1 pgoyette CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
331 1.1 pgoyette
332 1.1 pgoyette /*
333 1.1 pgoyette * Decode and print key SPD contents
334 1.1 pgoyette */
335 1.1 pgoyette if (IS_RAMBUS_TYPE) {
336 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_RAMBUS)
337 1.1 pgoyette type = "Rambus";
338 1.1 pgoyette else if (s->sm_type == SPDMEM_MEMTYPE_DIRECTRAMBUS)
339 1.1 pgoyette type = "Direct Rambus";
340 1.1 pgoyette else
341 1.1 pgoyette type = "Rambus (unknown)";
342 1.1 pgoyette
343 1.1 pgoyette switch (s->sm_len) {
344 1.1 pgoyette case 0:
345 1.1 pgoyette rambus_rev = "Invalid";
346 1.1 pgoyette break;
347 1.1 pgoyette case 1:
348 1.1 pgoyette rambus_rev = "0.7";
349 1.1 pgoyette break;
350 1.1 pgoyette case 2:
351 1.1 pgoyette rambus_rev = "1.0";
352 1.1 pgoyette break;
353 1.1 pgoyette default:
354 1.1 pgoyette rambus_rev = "Reserved";
355 1.1 pgoyette break;
356 1.1 pgoyette }
357 1.1 pgoyette } else {
358 1.1 pgoyette if (s->sm_type < __arraycount(spdmem_basic_types))
359 1.1 pgoyette type = spdmem_basic_types[s->sm_type];
360 1.1 pgoyette else
361 1.1 pgoyette type = "unknown memory type";
362 1.1 pgoyette
363 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_EDO &&
364 1.1 pgoyette s->sm_fpm.fpm_superset == SPDMEM_SUPERSET_EDO_PEM)
365 1.1 pgoyette type = spdmem_superset_types[SPDMEM_SUPERSET_EDO_PEM];
366 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_SDRAM &&
367 1.1 pgoyette s->sm_sdr.sdr_superset == SPDMEM_SUPERSET_SDRAM_PEM)
368 1.1 pgoyette type = spdmem_superset_types[SPDMEM_SUPERSET_SDRAM_PEM];
369 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_DDRSDRAM &&
370 1.1 pgoyette s->sm_ddr.ddr_superset == SPDMEM_SUPERSET_DDR_ESDRAM)
371 1.1 pgoyette type =
372 1.1 pgoyette spdmem_superset_types[SPDMEM_SUPERSET_DDR_ESDRAM];
373 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_SDRAM &&
374 1.1 pgoyette s->sm_sdr.sdr_superset == SPDMEM_SUPERSET_ESDRAM) {
375 1.1 pgoyette type = spdmem_superset_types[SPDMEM_SUPERSET_ESDRAM];
376 1.1 pgoyette }
377 1.13 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_DDR4SDRAM &&
378 1.13 pgoyette s->sm_ddr4.ddr4_mod_type <
379 1.13 pgoyette __arraycount(spdmem_ddr4_module_types)) {
380 1.13 pgoyette type = spdmem_ddr4_module_types[s->sm_ddr4.ddr4_mod_type];
381 1.13 pgoyette }
382 1.1 pgoyette }
383 1.1 pgoyette
384 1.1 pgoyette strlcpy(sc->sc_type, type, SPDMEM_TYPE_MAXLEN);
385 1.1 pgoyette if (node != NULL)
386 1.3 pgoyette sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL,
387 1.1 pgoyette 0,
388 1.1 pgoyette CTLTYPE_STRING, "mem_type",
389 1.1 pgoyette SYSCTL_DESCR("memory module type"), NULL,
390 1.1 pgoyette 0, sc->sc_type, 0,
391 1.1 pgoyette CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
392 1.1 pgoyette
393 1.1 pgoyette if (IS_RAMBUS_TYPE) {
394 1.8 soren aprint_naive("\n");
395 1.8 soren aprint_normal("\n");
396 1.8 soren aprint_normal_dev(self, "%s, SPD Revision %s", type, rambus_rev);
397 1.1 pgoyette dimm_size = 1 << (s->sm_rdr.rdr_rows + s->sm_rdr.rdr_cols - 13);
398 1.1 pgoyette if (dimm_size >= 1024)
399 1.1 pgoyette aprint_normal(", %dGB\n", dimm_size / 1024);
400 1.1 pgoyette else
401 1.1 pgoyette aprint_normal(", %dMB\n", dimm_size);
402 1.1 pgoyette
403 1.1 pgoyette /* No further decode for RAMBUS memory */
404 1.1 pgoyette return;
405 1.1 pgoyette }
406 1.1 pgoyette switch (s->sm_type) {
407 1.1 pgoyette case SPDMEM_MEMTYPE_EDO:
408 1.1 pgoyette case SPDMEM_MEMTYPE_FPM:
409 1.1 pgoyette decode_edofpm(node, self, s);
410 1.1 pgoyette break;
411 1.1 pgoyette case SPDMEM_MEMTYPE_ROM:
412 1.1 pgoyette decode_rom(node, self, s);
413 1.1 pgoyette break;
414 1.1 pgoyette case SPDMEM_MEMTYPE_SDRAM:
415 1.1 pgoyette decode_sdram(node, self, s, spd_len);
416 1.1 pgoyette break;
417 1.1 pgoyette case SPDMEM_MEMTYPE_DDRSDRAM:
418 1.1 pgoyette decode_ddr(node, self, s);
419 1.1 pgoyette break;
420 1.1 pgoyette case SPDMEM_MEMTYPE_DDR2SDRAM:
421 1.1 pgoyette decode_ddr2(node, self, s);
422 1.1 pgoyette break;
423 1.1 pgoyette case SPDMEM_MEMTYPE_DDR3SDRAM:
424 1.1 pgoyette decode_ddr3(node, self, s);
425 1.1 pgoyette break;
426 1.1 pgoyette case SPDMEM_MEMTYPE_FBDIMM:
427 1.1 pgoyette case SPDMEM_MEMTYPE_FBDIMM_PROBE:
428 1.1 pgoyette decode_fbdimm(node, self, s);
429 1.1 pgoyette break;
430 1.13 pgoyette case SPDMEM_MEMTYPE_DDR4SDRAM:
431 1.13 pgoyette decode_ddr4(node, self, s);
432 1.13 pgoyette break;
433 1.1 pgoyette }
434 1.8 soren
435 1.8 soren /* Dump SPD */
436 1.8 soren for (i = 0; i < spd_len; i += 16) {
437 1.8 soren unsigned int j, k;
438 1.8 soren aprint_debug_dev(self, "0x%02x:", i);
439 1.8 soren k = (spd_len > (i + 16)) ? i + 16 : spd_len;
440 1.8 soren for (j = i; j < k; j++)
441 1.8 soren aprint_debug(" %02x", ((uint8_t *)s)[j]);
442 1.8 soren aprint_debug("\n");
443 1.8 soren }
444 1.1 pgoyette }
445 1.1 pgoyette
446 1.3 pgoyette int
447 1.3 pgoyette spdmem_common_detach(struct spdmem_softc *sc, device_t self)
448 1.3 pgoyette {
449 1.3 pgoyette sysctl_teardown(&sc->sc_sysctl_log);
450 1.3 pgoyette
451 1.3 pgoyette return 0;
452 1.3 pgoyette }
453 1.3 pgoyette
454 1.1 pgoyette static void
455 1.3 pgoyette decode_size_speed(device_t self, const struct sysctlnode *node,
456 1.3 pgoyette int dimm_size, int cycle_time, int d_clk, int bits,
457 1.3 pgoyette bool round, const char *ddr_type_string, int speed)
458 1.1 pgoyette {
459 1.1 pgoyette int p_clk;
460 1.7 chs struct spdmem_softc *sc = device_private(self);
461 1.1 pgoyette
462 1.1 pgoyette if (dimm_size < 1024)
463 1.1 pgoyette aprint_normal("%dMB", dimm_size);
464 1.1 pgoyette else
465 1.1 pgoyette aprint_normal("%dGB", dimm_size / 1024);
466 1.1 pgoyette if (node != NULL)
467 1.3 pgoyette sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL,
468 1.1 pgoyette CTLFLAG_IMMEDIATE,
469 1.1 pgoyette CTLTYPE_INT, "size",
470 1.1 pgoyette SYSCTL_DESCR("module size in MB"), NULL,
471 1.1 pgoyette dimm_size, NULL, 0,
472 1.1 pgoyette CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
473 1.1 pgoyette
474 1.1 pgoyette if (cycle_time == 0) {
475 1.1 pgoyette aprint_normal("\n");
476 1.1 pgoyette return;
477 1.1 pgoyette }
478 1.1 pgoyette
479 1.1 pgoyette /*
480 1.1 pgoyette * Calculate p_clk first, since for DDR3 we need maximum significance.
481 1.1 pgoyette * DDR3 rating is not rounded to a multiple of 100. This results in
482 1.1 pgoyette * cycle_time of 1.5ns displayed as PC3-10666.
483 1.1 pgoyette *
484 1.1 pgoyette * For SDRAM, the speed is provided by the caller so we use it.
485 1.1 pgoyette */
486 1.1 pgoyette d_clk *= 1000 * 1000;
487 1.1 pgoyette if (speed)
488 1.1 pgoyette p_clk = speed;
489 1.1 pgoyette else
490 1.1 pgoyette p_clk = (d_clk * bits) / 8 / cycle_time;
491 1.1 pgoyette d_clk = ((d_clk + cycle_time / 2) ) / cycle_time;
492 1.1 pgoyette if (round) {
493 1.1 pgoyette if ((p_clk % 100) >= 50)
494 1.1 pgoyette p_clk += 50;
495 1.1 pgoyette p_clk -= p_clk % 100;
496 1.1 pgoyette }
497 1.1 pgoyette aprint_normal(", %dMHz (%s-%d)\n",
498 1.1 pgoyette d_clk, ddr_type_string, p_clk);
499 1.1 pgoyette if (node != NULL)
500 1.3 pgoyette sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL,
501 1.1 pgoyette CTLFLAG_IMMEDIATE,
502 1.1 pgoyette CTLTYPE_INT, "speed",
503 1.1 pgoyette SYSCTL_DESCR("memory speed in MHz"),
504 1.1 pgoyette NULL, d_clk, NULL, 0,
505 1.1 pgoyette CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
506 1.1 pgoyette }
507 1.1 pgoyette
508 1.1 pgoyette static void
509 1.1 pgoyette decode_voltage_refresh(device_t self, struct spdmem *s)
510 1.1 pgoyette {
511 1.1 pgoyette const char *voltage, *refresh;
512 1.1 pgoyette
513 1.1 pgoyette if (s->sm_voltage < __arraycount(spdmem_voltage_types))
514 1.1 pgoyette voltage = spdmem_voltage_types[s->sm_voltage];
515 1.1 pgoyette else
516 1.1 pgoyette voltage = "unknown";
517 1.1 pgoyette
518 1.1 pgoyette if (s->sm_refresh < __arraycount(spdmem_refresh_types))
519 1.1 pgoyette refresh = spdmem_refresh_types[s->sm_refresh];
520 1.1 pgoyette else
521 1.1 pgoyette refresh = "unknown";
522 1.1 pgoyette
523 1.1 pgoyette aprint_verbose_dev(self, "voltage %s, refresh time %s%s\n",
524 1.1 pgoyette voltage, refresh,
525 1.1 pgoyette s->sm_selfrefresh?" (self-refreshing)":"");
526 1.1 pgoyette }
527 1.1 pgoyette
528 1.1 pgoyette static void
529 1.18 msaitoh decode_edofpm(const struct sysctlnode *node, device_t self, struct spdmem *s)
530 1.18 msaitoh {
531 1.18 msaitoh
532 1.8 soren aprint_naive("\n");
533 1.8 soren aprint_normal("\n");
534 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
535 1.8 soren
536 1.1 pgoyette aprint_normal("\n");
537 1.1 pgoyette aprint_verbose_dev(self,
538 1.1 pgoyette "%d rows, %d cols, %d banks, %dns tRAC, %dns tCAC\n",
539 1.1 pgoyette s->sm_fpm.fpm_rows, s->sm_fpm.fpm_cols, s->sm_fpm.fpm_banks,
540 1.1 pgoyette s->sm_fpm.fpm_tRAC, s->sm_fpm.fpm_tCAC);
541 1.1 pgoyette }
542 1.1 pgoyette
543 1.1 pgoyette static void
544 1.18 msaitoh decode_rom(const struct sysctlnode *node, device_t self, struct spdmem *s)
545 1.18 msaitoh {
546 1.18 msaitoh
547 1.8 soren aprint_naive("\n");
548 1.8 soren aprint_normal("\n");
549 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
550 1.8 soren
551 1.1 pgoyette aprint_normal("\n");
552 1.1 pgoyette aprint_verbose_dev(self, "%d rows, %d cols, %d banks\n",
553 1.1 pgoyette s->sm_rom.rom_rows, s->sm_rom.rom_cols, s->sm_rom.rom_banks);
554 1.1 pgoyette }
555 1.1 pgoyette
556 1.1 pgoyette static void
557 1.1 pgoyette decode_sdram(const struct sysctlnode *node, device_t self, struct spdmem *s,
558 1.18 msaitoh int spd_len)
559 1.18 msaitoh {
560 1.1 pgoyette int dimm_size, cycle_time, bits, tAA, i, speed, freq;
561 1.1 pgoyette
562 1.8 soren aprint_naive("\n");
563 1.8 soren aprint_normal("\n");
564 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
565 1.8 soren
566 1.1 pgoyette aprint_normal("%s, %s, ",
567 1.1 pgoyette (s->sm_sdr.sdr_mod_attrs & SPDMEM_SDR_MASK_REG)?
568 1.1 pgoyette " (registered)":"",
569 1.1 pgoyette (s->sm_config < __arraycount(spdmem_parity_types))?
570 1.1 pgoyette spdmem_parity_types[s->sm_config]:"invalid parity");
571 1.1 pgoyette
572 1.1 pgoyette dimm_size = 1 << (s->sm_sdr.sdr_rows + s->sm_sdr.sdr_cols - 17);
573 1.1 pgoyette dimm_size *= s->sm_sdr.sdr_banks * s->sm_sdr.sdr_banks_per_chip;
574 1.1 pgoyette
575 1.1 pgoyette cycle_time = s->sm_sdr.sdr_cycle_whole * 1000 +
576 1.1 pgoyette s->sm_sdr.sdr_cycle_tenths * 100;
577 1.1 pgoyette bits = le16toh(s->sm_sdr.sdr_datawidth);
578 1.1 pgoyette if (s->sm_config == 1 || s->sm_config == 2)
579 1.1 pgoyette bits -= 8;
580 1.1 pgoyette
581 1.1 pgoyette /* Calculate speed here - from OpenBSD */
582 1.1 pgoyette if (spd_len >= 128)
583 1.1 pgoyette freq = ((uint8_t *)s)[126];
584 1.1 pgoyette else
585 1.1 pgoyette freq = 0;
586 1.1 pgoyette switch (freq) {
587 1.1 pgoyette /*
588 1.1 pgoyette * Must check cycle time since some PC-133 DIMMs
589 1.1 pgoyette * actually report PC-100
590 1.1 pgoyette */
591 1.1 pgoyette case 100:
592 1.1 pgoyette case 133:
593 1.1 pgoyette if (cycle_time < 8000)
594 1.1 pgoyette speed = 133;
595 1.1 pgoyette else
596 1.1 pgoyette speed = 100;
597 1.1 pgoyette break;
598 1.1 pgoyette case 0x66: /* Legacy DIMMs use _hex_ 66! */
599 1.1 pgoyette default:
600 1.1 pgoyette speed = 66;
601 1.1 pgoyette }
602 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 1, bits, FALSE,
603 1.3 pgoyette "PC", speed);
604 1.1 pgoyette
605 1.1 pgoyette aprint_verbose_dev(self,
606 1.1 pgoyette "%d rows, %d cols, %d banks, %d banks/chip, %d.%dns cycle time\n",
607 1.1 pgoyette s->sm_sdr.sdr_rows, s->sm_sdr.sdr_cols, s->sm_sdr.sdr_banks,
608 1.1 pgoyette s->sm_sdr.sdr_banks_per_chip, cycle_time/1000,
609 1.1 pgoyette (cycle_time % 1000) / 100);
610 1.1 pgoyette
611 1.1 pgoyette tAA = 0;
612 1.1 pgoyette for (i = 0; i < 8; i++)
613 1.1 pgoyette if (s->sm_sdr.sdr_tCAS & (1 << i))
614 1.1 pgoyette tAA = i;
615 1.1 pgoyette tAA++;
616 1.4 christos aprint_verbose_dev(self, LATENCY, tAA, s->sm_sdr.sdr_tRCD,
617 1.1 pgoyette s->sm_sdr.sdr_tRP, s->sm_sdr.sdr_tRAS);
618 1.1 pgoyette
619 1.1 pgoyette decode_voltage_refresh(self, s);
620 1.1 pgoyette }
621 1.1 pgoyette
622 1.1 pgoyette static void
623 1.18 msaitoh decode_ddr(const struct sysctlnode *node, device_t self, struct spdmem *s)
624 1.18 msaitoh {
625 1.1 pgoyette int dimm_size, cycle_time, bits, tAA, i;
626 1.1 pgoyette
627 1.8 soren aprint_naive("\n");
628 1.8 soren aprint_normal("\n");
629 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
630 1.8 soren
631 1.1 pgoyette aprint_normal("%s, %s, ",
632 1.1 pgoyette (s->sm_ddr.ddr_mod_attrs & SPDMEM_DDR_MASK_REG)?
633 1.1 pgoyette " (registered)":"",
634 1.1 pgoyette (s->sm_config < __arraycount(spdmem_parity_types))?
635 1.1 pgoyette spdmem_parity_types[s->sm_config]:"invalid parity");
636 1.1 pgoyette
637 1.1 pgoyette dimm_size = 1 << (s->sm_ddr.ddr_rows + s->sm_ddr.ddr_cols - 17);
638 1.1 pgoyette dimm_size *= s->sm_ddr.ddr_ranks * s->sm_ddr.ddr_banks_per_chip;
639 1.1 pgoyette
640 1.1 pgoyette cycle_time = s->sm_ddr.ddr_cycle_whole * 1000 +
641 1.1 pgoyette spdmem_cycle_frac[s->sm_ddr.ddr_cycle_tenths];
642 1.1 pgoyette bits = le16toh(s->sm_ddr.ddr_datawidth);
643 1.1 pgoyette if (s->sm_config == 1 || s->sm_config == 2)
644 1.1 pgoyette bits -= 8;
645 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, TRUE,
646 1.3 pgoyette "PC", 0);
647 1.1 pgoyette
648 1.1 pgoyette aprint_verbose_dev(self,
649 1.1 pgoyette "%d rows, %d cols, %d ranks, %d banks/chip, %d.%dns cycle time\n",
650 1.1 pgoyette s->sm_ddr.ddr_rows, s->sm_ddr.ddr_cols, s->sm_ddr.ddr_ranks,
651 1.1 pgoyette s->sm_ddr.ddr_banks_per_chip, cycle_time/1000,
652 1.1 pgoyette (cycle_time % 1000 + 50) / 100);
653 1.1 pgoyette
654 1.1 pgoyette tAA = 0;
655 1.1 pgoyette for (i = 2; i < 8; i++)
656 1.1 pgoyette if (s->sm_ddr.ddr_tCAS & (1 << i))
657 1.1 pgoyette tAA = i;
658 1.1 pgoyette tAA /= 2;
659 1.1 pgoyette
660 1.1 pgoyette #define __DDR_ROUND(scale, field) \
661 1.1 pgoyette ((scale * s->sm_ddr.field + cycle_time - 1) / cycle_time)
662 1.1 pgoyette
663 1.4 christos aprint_verbose_dev(self, LATENCY, tAA, __DDR_ROUND(250, ddr_tRCD),
664 1.1 pgoyette __DDR_ROUND(250, ddr_tRP), __DDR_ROUND(1000, ddr_tRAS));
665 1.1 pgoyette
666 1.1 pgoyette #undef __DDR_ROUND
667 1.1 pgoyette
668 1.1 pgoyette decode_voltage_refresh(self, s);
669 1.1 pgoyette }
670 1.1 pgoyette
671 1.1 pgoyette static void
672 1.18 msaitoh decode_ddr2(const struct sysctlnode *node, device_t self, struct spdmem *s)
673 1.18 msaitoh {
674 1.1 pgoyette int dimm_size, cycle_time, bits, tAA, i;
675 1.1 pgoyette
676 1.8 soren aprint_naive("\n");
677 1.8 soren aprint_normal("\n");
678 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
679 1.8 soren
680 1.1 pgoyette aprint_normal("%s, %s, ",
681 1.1 pgoyette (s->sm_ddr2.ddr2_mod_attrs & SPDMEM_DDR2_MASK_REG)?
682 1.1 pgoyette " (registered)":"",
683 1.1 pgoyette (s->sm_config < __arraycount(spdmem_parity_types))?
684 1.1 pgoyette spdmem_parity_types[s->sm_config]:"invalid parity");
685 1.1 pgoyette
686 1.1 pgoyette dimm_size = 1 << (s->sm_ddr2.ddr2_rows + s->sm_ddr2.ddr2_cols - 17);
687 1.1 pgoyette dimm_size *= (s->sm_ddr2.ddr2_ranks + 1) *
688 1.1 pgoyette s->sm_ddr2.ddr2_banks_per_chip;
689 1.1 pgoyette
690 1.1 pgoyette cycle_time = s->sm_ddr2.ddr2_cycle_whole * 1000 +
691 1.1 pgoyette spdmem_cycle_frac[s->sm_ddr2.ddr2_cycle_frac];
692 1.1 pgoyette bits = s->sm_ddr2.ddr2_datawidth;
693 1.1 pgoyette if ((s->sm_config & 0x03) != 0)
694 1.1 pgoyette bits -= 8;
695 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, TRUE,
696 1.3 pgoyette "PC2", 0);
697 1.1 pgoyette
698 1.1 pgoyette aprint_verbose_dev(self,
699 1.1 pgoyette "%d rows, %d cols, %d ranks, %d banks/chip, %d.%02dns cycle time\n",
700 1.1 pgoyette s->sm_ddr2.ddr2_rows, s->sm_ddr2.ddr2_cols,
701 1.1 pgoyette s->sm_ddr2.ddr2_ranks + 1, s->sm_ddr2.ddr2_banks_per_chip,
702 1.1 pgoyette cycle_time / 1000, (cycle_time % 1000 + 5) /10 );
703 1.1 pgoyette
704 1.1 pgoyette tAA = 0;
705 1.1 pgoyette for (i = 2; i < 8; i++)
706 1.1 pgoyette if (s->sm_ddr2.ddr2_tCAS & (1 << i))
707 1.1 pgoyette tAA = i;
708 1.1 pgoyette
709 1.1 pgoyette #define __DDR2_ROUND(scale, field) \
710 1.1 pgoyette ((scale * s->sm_ddr2.field + cycle_time - 1) / cycle_time)
711 1.1 pgoyette
712 1.4 christos aprint_verbose_dev(self, LATENCY, tAA, __DDR2_ROUND(250, ddr2_tRCD),
713 1.1 pgoyette __DDR2_ROUND(250, ddr2_tRP), __DDR2_ROUND(1000, ddr2_tRAS));
714 1.1 pgoyette
715 1.1 pgoyette #undef __DDR_ROUND
716 1.1 pgoyette
717 1.1 pgoyette decode_voltage_refresh(self, s);
718 1.1 pgoyette }
719 1.1 pgoyette
720 1.1 pgoyette static void
721 1.18 msaitoh decode_ddr3(const struct sysctlnode *node, device_t self, struct spdmem *s)
722 1.18 msaitoh {
723 1.1 pgoyette int dimm_size, cycle_time, bits;
724 1.1 pgoyette
725 1.8 soren aprint_naive("\n");
726 1.8 soren aprint_normal(": %18s\n", s->sm_ddr3.ddr3_part);
727 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
728 1.8 soren
729 1.1 pgoyette if (s->sm_ddr3.ddr3_mod_type ==
730 1.1 pgoyette SPDMEM_DDR3_TYPE_MINI_RDIMM ||
731 1.1 pgoyette s->sm_ddr3.ddr3_mod_type == SPDMEM_DDR3_TYPE_RDIMM)
732 1.1 pgoyette aprint_normal(" (registered)");
733 1.1 pgoyette aprint_normal(", %sECC, %stemp-sensor, ",
734 1.1 pgoyette (s->sm_ddr3.ddr3_hasECC)?"":"no ",
735 1.1 pgoyette (s->sm_ddr3.ddr3_has_therm_sensor)?"":"no ");
736 1.1 pgoyette
737 1.1 pgoyette /*
738 1.1 pgoyette * DDR3 size specification is quite different from others
739 1.1 pgoyette *
740 1.1 pgoyette * Module capacity is defined as
741 1.1 pgoyette * Chip_Capacity_in_bits / 8bits-per-byte *
742 1.1 pgoyette * external_bus_width / internal_bus_width
743 1.1 pgoyette * We further divide by 2**20 to get our answer in MB
744 1.1 pgoyette */
745 1.1 pgoyette dimm_size = (s->sm_ddr3.ddr3_chipsize + 28 - 20) - 3 +
746 1.1 pgoyette (s->sm_ddr3.ddr3_datawidth + 3) -
747 1.1 pgoyette (s->sm_ddr3.ddr3_chipwidth + 2);
748 1.1 pgoyette dimm_size = (1 << dimm_size) * (s->sm_ddr3.ddr3_physbanks + 1);
749 1.1 pgoyette
750 1.1 pgoyette cycle_time = (1000 * s->sm_ddr3.ddr3_mtb_dividend +
751 1.1 pgoyette (s->sm_ddr3.ddr3_mtb_divisor / 2)) /
752 1.1 pgoyette s->sm_ddr3.ddr3_mtb_divisor;
753 1.1 pgoyette cycle_time *= s->sm_ddr3.ddr3_tCKmin;
754 1.1 pgoyette bits = 1 << (s->sm_ddr3.ddr3_datawidth + 3);
755 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, FALSE,
756 1.3 pgoyette "PC3", 0);
757 1.1 pgoyette
758 1.1 pgoyette aprint_verbose_dev(self,
759 1.1 pgoyette "%d rows, %d cols, %d log. banks, %d phys. banks, "
760 1.1 pgoyette "%d.%03dns cycle time\n",
761 1.1 pgoyette s->sm_ddr3.ddr3_rows + 9, s->sm_ddr3.ddr3_cols + 12,
762 1.1 pgoyette 1 << (s->sm_ddr3.ddr3_logbanks + 3),
763 1.1 pgoyette s->sm_ddr3.ddr3_physbanks + 1,
764 1.1 pgoyette cycle_time/1000, cycle_time % 1000);
765 1.1 pgoyette
766 1.1 pgoyette #define __DDR3_CYCLES(field) (s->sm_ddr3.field / s->sm_ddr3.ddr3_tCKmin)
767 1.1 pgoyette
768 1.4 christos aprint_verbose_dev(self, LATENCY, __DDR3_CYCLES(ddr3_tAAmin),
769 1.1 pgoyette __DDR3_CYCLES(ddr3_tRCDmin), __DDR3_CYCLES(ddr3_tRPmin),
770 1.1 pgoyette (s->sm_ddr3.ddr3_tRAS_msb * 256 + s->sm_ddr3.ddr3_tRAS_lsb) /
771 1.1 pgoyette s->sm_ddr3.ddr3_tCKmin);
772 1.1 pgoyette
773 1.1 pgoyette #undef __DDR3_CYCLES
774 1.14 msaitoh
775 1.14 msaitoh /* For DDR3, Voltage is written in another area */
776 1.14 msaitoh if (!s->sm_ddr3.ddr3_NOT15V || s->sm_ddr3.ddr3_135V
777 1.14 msaitoh || s->sm_ddr3.ddr3_125V) {
778 1.14 msaitoh aprint_verbose("%s:", device_xname(self));
779 1.14 msaitoh if (!s->sm_ddr3.ddr3_NOT15V)
780 1.14 msaitoh aprint_verbose(" 1.5V");
781 1.14 msaitoh if (s->sm_ddr3.ddr3_135V)
782 1.14 msaitoh aprint_verbose(" 1.35V");
783 1.14 msaitoh if (s->sm_ddr3.ddr3_125V)
784 1.14 msaitoh aprint_verbose(" 1.25V");
785 1.14 msaitoh aprint_verbose(" operable\n");
786 1.14 msaitoh }
787 1.1 pgoyette }
788 1.1 pgoyette
789 1.1 pgoyette static void
790 1.18 msaitoh decode_fbdimm(const struct sysctlnode *node, device_t self, struct spdmem *s)
791 1.18 msaitoh {
792 1.1 pgoyette int dimm_size, cycle_time, bits;
793 1.1 pgoyette
794 1.8 soren aprint_naive("\n");
795 1.8 soren aprint_normal("\n");
796 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
797 1.8 soren
798 1.1 pgoyette /*
799 1.1 pgoyette * FB-DIMM module size calculation is very much like DDR3
800 1.1 pgoyette */
801 1.1 pgoyette dimm_size = s->sm_fbd.fbdimm_rows + 12 +
802 1.1 pgoyette s->sm_fbd.fbdimm_cols + 9 - 20 - 3;
803 1.1 pgoyette dimm_size = (1 << dimm_size) * (1 << (s->sm_fbd.fbdimm_banks + 2));
804 1.1 pgoyette
805 1.1 pgoyette cycle_time = (1000 * s->sm_fbd.fbdimm_mtb_dividend +
806 1.1 pgoyette (s->sm_fbd.fbdimm_mtb_divisor / 2)) /
807 1.1 pgoyette s->sm_fbd.fbdimm_mtb_divisor;
808 1.1 pgoyette bits = 1 << (s->sm_fbd.fbdimm_dev_width + 2);
809 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, TRUE,
810 1.3 pgoyette "PC2", 0);
811 1.1 pgoyette
812 1.1 pgoyette aprint_verbose_dev(self,
813 1.1 pgoyette "%d rows, %d cols, %d banks, %d.%02dns cycle time\n",
814 1.1 pgoyette s->sm_fbd.fbdimm_rows, s->sm_fbd.fbdimm_cols,
815 1.1 pgoyette 1 << (s->sm_fbd.fbdimm_banks + 2),
816 1.1 pgoyette cycle_time / 1000, (cycle_time % 1000 + 5) /10 );
817 1.1 pgoyette
818 1.1 pgoyette #define __FBDIMM_CYCLES(field) (s->sm_fbd.field / s->sm_fbd.fbdimm_tCKmin)
819 1.1 pgoyette
820 1.4 christos aprint_verbose_dev(self, LATENCY, __FBDIMM_CYCLES(fbdimm_tAAmin),
821 1.1 pgoyette __FBDIMM_CYCLES(fbdimm_tRCDmin), __FBDIMM_CYCLES(fbdimm_tRPmin),
822 1.18 msaitoh (s->sm_fbd.fbdimm_tRAS_msb * 256 + s->sm_fbd.fbdimm_tRAS_lsb) /
823 1.1 pgoyette s->sm_fbd.fbdimm_tCKmin);
824 1.1 pgoyette
825 1.1 pgoyette #undef __FBDIMM_CYCLES
826 1.1 pgoyette
827 1.1 pgoyette decode_voltage_refresh(self, s);
828 1.1 pgoyette }
829 1.13 pgoyette
830 1.13 pgoyette static void
831 1.18 msaitoh decode_ddr4(const struct sysctlnode *node, device_t self, struct spdmem *s)
832 1.18 msaitoh {
833 1.13 pgoyette int dimm_size, cycle_time;
834 1.13 pgoyette int tAA_clocks, tRCD_clocks,tRP_clocks, tRAS_clocks;
835 1.13 pgoyette
836 1.13 pgoyette aprint_naive("\n");
837 1.13 pgoyette aprint_normal(": %20s\n", s->sm_ddr4.ddr4_part_number);
838 1.13 pgoyette aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
839 1.13 pgoyette if (s->sm_ddr4.ddr4_mod_type < __arraycount(spdmem_ddr4_module_types))
840 1.13 pgoyette aprint_normal(" (%s)",
841 1.13 pgoyette spdmem_ddr4_module_types[s->sm_ddr4.ddr4_mod_type]);
842 1.13 pgoyette aprint_normal(", %stemp-sensor, ",
843 1.13 pgoyette (s->sm_ddr4.ddr4_has_therm_sensor)?"":"no ");
844 1.13 pgoyette
845 1.13 pgoyette /*
846 1.13 pgoyette * DDR4 size calculation from JEDEC spec
847 1.13 pgoyette *
848 1.13 pgoyette * Module capacity in bytes is defined as
849 1.13 pgoyette * Chip_Capacity_in_bits / 8bits-per-byte *
850 1.13 pgoyette * primary_bus_width / DRAM_width *
851 1.13 pgoyette * logical_ranks_per_DIMM
852 1.13 pgoyette *
853 1.13 pgoyette * logical_ranks_per DIMM equals package_ranks, but multiply
854 1.13 pgoyette * by diecount for 3DS packages
855 1.13 pgoyette *
856 1.13 pgoyette * We further divide by 2**20 to get our answer in MB
857 1.13 pgoyette */
858 1.13 pgoyette dimm_size = (s->sm_ddr4.ddr4_capacity + 28) /* chip_capacity */
859 1.13 pgoyette - 20 /* convert to MB */
860 1.13 pgoyette - 3 /* bits --> bytes */
861 1.13 pgoyette + (s->sm_ddr4.ddr4_primary_bus_width + 3); /* bus width */
862 1.13 pgoyette switch (s->sm_ddr4.ddr4_device_width) { /* DRAM width */
863 1.13 pgoyette case 0: dimm_size -= 2;
864 1.13 pgoyette break;
865 1.13 pgoyette case 1: dimm_size -= 3;
866 1.13 pgoyette break;
867 1.13 pgoyette case 2: dimm_size -= 4;
868 1.13 pgoyette break;
869 1.13 pgoyette case 4: dimm_size -= 5;
870 1.13 pgoyette break;
871 1.13 pgoyette default:
872 1.13 pgoyette dimm_size = -1; /* flag invalid value */
873 1.13 pgoyette }
874 1.17 msaitoh if (dimm_size >= 0) {
875 1.13 pgoyette dimm_size = (1 << dimm_size) *
876 1.13 pgoyette (s->sm_ddr4.ddr4_package_ranks + 1); /* log.ranks/DIMM */
877 1.13 pgoyette if (s->sm_ddr4.ddr4_signal_loading == 2) {
878 1.13 pgoyette dimm_size *= s->sm_ddr4.ddr4_diecount;
879 1.13 pgoyette }
880 1.13 pgoyette }
881 1.13 pgoyette
882 1.18 msaitoh #define __DDR4_VALUE(field) ((s->sm_ddr4.ddr4_##field##_mtb * 125 + \
883 1.18 msaitoh s->sm_ddr4.ddr4_##field##_ftb) - \
884 1.18 msaitoh ((s->sm_ddr4.ddr4_##field##_ftb > 127)?256:0))
885 1.13 pgoyette /*
886 1.13 pgoyette * For now, the only value for mtb is 1 = 125ps, and ftp = 1ps
887 1.13 pgoyette * so we don't need to figure out the time-base units - just
888 1.13 pgoyette * hard-code them for now.
889 1.13 pgoyette */
890 1.18 msaitoh cycle_time = __DDR4_VALUE(tCKAVGmin);
891 1.18 msaitoh aprint_normal("%d.%03dns cycle time (%dMHz), ", cycle_time/1000,
892 1.18 msaitoh cycle_time % 1000, 1000000 / cycle_time);
893 1.13 pgoyette
894 1.13 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2,
895 1.13 pgoyette 1 << (s->sm_ddr4.ddr4_device_width + 3),
896 1.13 pgoyette TRUE, "PC4", 0);
897 1.13 pgoyette
898 1.13 pgoyette aprint_verbose_dev(self,
899 1.13 pgoyette "%d rows, %d cols, %d banks, %d bank groups\n",
900 1.16 pgoyette s->sm_ddr4.ddr4_rows + 9, s->sm_ddr4.ddr4_cols + 12,
901 1.13 pgoyette 1 << (2 + s->sm_ddr4.ddr4_logbanks),
902 1.13 pgoyette 1 << s->sm_ddr4.ddr4_bankgroups);
903 1.13 pgoyette
904 1.13 pgoyette /*
905 1.13 pgoyette * Note that the ddr4_xxx_ftb fields are actually signed offsets from
906 1.13 pgoyette * the corresponding mtb value, so we might have to subtract 256!
907 1.13 pgoyette */
908 1.13 pgoyette
909 1.18 msaitoh tAA_clocks = __DDR4_VALUE(tAAmin) * 1000 / cycle_time;
910 1.18 msaitoh tRCD_clocks = __DDR4_VALUE(tRCDmin) * 1000 / cycle_time;
911 1.18 msaitoh tRP_clocks = __DDR4_VALUE(tRPmin) * 1000 / cycle_time;
912 1.13 pgoyette tRAS_clocks = (s->sm_ddr4.ddr4_tRASmin_msb * 256 +
913 1.13 pgoyette s->sm_ddr4.ddr4_tRASmin_lsb) * 125 * 1000 / cycle_time;
914 1.13 pgoyette
915 1.13 pgoyette /*
916 1.13 pgoyette * Per JEDEC spec, rounding is done by taking the time value, dividing
917 1.13 pgoyette * by the cycle time, subtracting .010 from the result, and then
918 1.13 pgoyette * rounded up to the nearest integer. Unfortunately, none of their
919 1.13 pgoyette * examples say what to do when the result of the subtraction is already
920 1.13 pgoyette * an integer. For now, assume that we still round up (so an interval
921 1.13 pgoyette * of exactly 12.010 clock cycles will be printed as 13).
922 1.13 pgoyette */
923 1.13 pgoyette #define __DDR4_ROUND(value) ((value - 10) / 1000 + 1)
924 1.13 pgoyette
925 1.13 pgoyette aprint_verbose_dev(self, LATENCY, __DDR4_ROUND(tAA_clocks),
926 1.18 msaitoh __DDR4_ROUND(tRCD_clocks),
927 1.13 pgoyette __DDR4_ROUND(tRP_clocks),
928 1.13 pgoyette __DDR4_ROUND(tRAS_clocks));
929 1.13 pgoyette
930 1.13 pgoyette #undef __DDR4_VALUE
931 1.13 pgoyette #undef __DDR4_ROUND
932 1.13 pgoyette }
933