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