xref: /openbsd/sys/dev/spdmem.c (revision b7d4deb4)
1 /*	$OpenBSD: spdmem.c,v 1.7 2019/12/21 12:33:03 kettenis Exp $	*/
2 /* $NetBSD: spdmem.c,v 1.3 2007/09/20 23:09:59 xtraeme Exp $ */
3 
4 /*
5  * Copyright (c) 2007 Jonathan Gray <jsg@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  * Copyright (c) 2007 Nicolas Joly
22  * Copyright (c) 2007 Paul Goyette
23  * Copyright (c) 2007 Tobias Nygren
24  * All rights reserved.
25  *
26  * Redistribution and use in source and binary forms, with or without
27  * modification, are permitted provided that the following conditions
28  * are met:
29  * 1. Redistributions of source code must retain the above copyright
30  *    notice, this list of conditions and the following disclaimer.
31  * 2. Redistributions in binary form must reproduce the above copyright
32  *    notice, this list of conditions and the following disclaimer in the
33  *    documentation and/or other materials provided with the distribution.
34  * 3. The name of the author may not be used to endorse or promote products
35  *    derived from this software without specific prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
38  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
39  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
41  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47  * POSSIBILITY OF SUCH DAMAGE.
48  */
49 
50 /*
51  * Serial Presence Detect (SPD) memory identification
52  */
53 
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/device.h>
57 
58 #include <dev/spdmemvar.h>
59 
60 /* Encodings of the size used/total byte for certain memory types    */
61 #define	SPDMEM_SPDSIZE_MASK		0x0F	/* SPD EEPROM Size   */
62 
63 #define	SPDMEM_SPDLEN_128		0x00	/* SPD EEPROM Sizes  */
64 #define	SPDMEM_SPDLEN_176		0x10
65 #define	SPDMEM_SPDLEN_256		0x20
66 #define	SPDMEM_SPDLEN_MASK		0x70	/* Bits 4 - 6        */
67 
68 #define	SPDMEM_DDR4_SPDLEN_128		0x01	/* SPD EEPROM Sizes  */
69 #define	SPDMEM_DDR4_SPDLEN_256		0x02
70 #define	SPDMEM_DDR4_SPDLEN_384		0x03
71 #define	SPDMEM_DDR4_SPDLEN_512		0x04
72 #define	SPDMEM_DDR4_SPDLEN_MASK		0x0f	/* Bits 4 - 6        */
73 
74 #define	SPDMEM_SPDCRC_116		0x80	/* CRC Bytes covered */
75 #define	SPDMEM_SPDCRC_125		0x00
76 #define	SPDMEM_SPDCRC_MASK		0x80	/* Bit 7             */
77 
78 /* possible values for the memory type */
79 #define	SPDMEM_MEMTYPE_FPM		0x01
80 #define	SPDMEM_MEMTYPE_EDO		0x02
81 #define	SPDMEM_MEMTYPE_PIPE_NIBBLE	0x03
82 #define	SPDMEM_MEMTYPE_SDRAM		0x04
83 #define	SPDMEM_MEMTYPE_ROM		0x05
84 #define	SPDMEM_MEMTYPE_DDRSGRAM		0x06
85 #define	SPDMEM_MEMTYPE_DDRSDRAM		0x07
86 #define	SPDMEM_MEMTYPE_DDR2SDRAM	0x08
87 #define	SPDMEM_MEMTYPE_FBDIMM		0x09
88 #define	SPDMEM_MEMTYPE_FBDIMM_PROBE	0x0a
89 #define	SPDMEM_MEMTYPE_DDR3SDRAM	0x0b
90 #define	SPDMEM_MEMTYPE_DDR4SDRAM	0x0c
91 					/* 0xd reserved */
92 #define	SPDMEM_MEMTYPE_DDR4ESDRAM	0x0e
93 #define	SPDMEM_MEMTYPE_LPDDR3SDRAM	0x0f
94 #define	SPDMEM_MEMTYPE_LPDDR4SDRAM	0x10
95 #define	SPDMEM_MEMTYPE_LPDDR4XSDRAM	0x11
96 #define	SPDMEM_MEMTYPE_DDR5SDRAM	0x12
97 #define	SPDMEM_MEMTYPE_LPDDR5SDRAM	0x13
98 
99 #define	SPDMEM_MEMTYPE_NONE		0xff
100 
101 #define SPDMEM_MEMTYPE_DIRECT_RAMBUS	0x01
102 #define SPDMEM_MEMTYPE_RAMBUS		0x11
103 
104 /* possible values for the supply voltage */
105 #define	SPDMEM_VOLTAGE_TTL_5V		0x00
106 #define	SPDMEM_VOLTAGE_TTL_LV		0x01
107 #define	SPDMEM_VOLTAGE_HSTTL_1_5V	0x02
108 #define	SPDMEM_VOLTAGE_SSTL_3_3V	0x03
109 #define	SPDMEM_VOLTAGE_SSTL_2_5V	0x04
110 #define	SPDMEM_VOLTAGE_SSTL_1_8V	0x05
111 
112 /* possible values for module configuration */
113 #define	SPDMEM_MODCONFIG_PARITY		0x01
114 #define	SPDMEM_MODCONFIG_ECC		0x02
115 
116 /* for DDR2, module configuration is a bit-mask field */
117 #define	SPDMEM_MODCONFIG_HAS_DATA_PARITY	0x01
118 #define	SPDMEM_MODCONFIG_HAS_DATA_ECC		0x02
119 #define	SPDMEM_MODCONFIG_HAS_ADDR_CMD_PARITY	0x04
120 
121 /* possible values for the refresh field */
122 #define	SPDMEM_REFRESH_STD		0x00
123 #define	SPDMEM_REFRESH_QUARTER		0x01
124 #define	SPDMEM_REFRESH_HALF		0x02
125 #define	SPDMEM_REFRESH_TWOX		0x03
126 #define	SPDMEM_REFRESH_FOURX		0x04
127 #define	SPDMEM_REFRESH_EIGHTX		0x05
128 #define	SPDMEM_REFRESH_SELFREFRESH	0x80
129 
130 /* superset types */
131 #define	SPDMEM_SUPERSET_ESDRAM		0x01
132 #define	SPDMEM_SUPERSET_DDR_ESDRAM	0x02
133 #define	SPDMEM_SUPERSET_EDO_PEM		0x03
134 #define	SPDMEM_SUPERSET_SDR_PEM		0x04
135 
136 /* FPM and EDO DIMMS */
137 #define SPDMEM_FPM_ROWS			0x00
138 #define SPDMEM_FPM_COLS			0x01
139 #define SPDMEM_FPM_BANKS		0x02
140 #define SPDMEM_FPM_CONFIG		0x08
141 #define SPDMEM_FPM_REFRESH		0x09
142 #define SPDMEM_FPM_SUPERSET		0x0c
143 
144 /* PC66/PC100/PC133 SDRAM */
145 #define SPDMEM_SDR_ROWS			0x00
146 #define SPDMEM_SDR_COLS			0x01
147 #define SPDMEM_SDR_BANKS		0x02
148 #define SPDMEM_SDR_CYCLE		0x06
149 #define SPDMEM_SDR_BANKS_PER_CHIP	0x0e
150 #define SPDMEM_SDR_MOD_ATTRIB		0x12
151 #define SPDMEM_SDR_SUPERSET		0x1d
152 
153 #define SPDMEM_SDR_FREQUENCY		126
154 #define SPDMEM_SDR_CAS			127
155 #define SPDMEM_SDR_FREQ_66		0x66
156 #define SPDMEM_SDR_FREQ_100		0x64
157 #define SPDMEM_SDR_FREQ_133		0x85
158 #define SPDMEM_SDR_CAS2			(1 << 1)
159 #define SPDMEM_SDR_CAS3			(1 << 2)
160 
161 /* Rambus Direct DRAM */
162 #define SPDMEM_RDR_MODULE_TYPE		0x00
163 #define SPDMEM_RDR_ROWS_COLS		0x01
164 #define SPDMEM_RDR_BANK			0x02
165 
166 #define SPDMEM_RDR_TYPE_RIMM		1
167 #define SPDMEM_RDR_TYPE_SORIMM		2
168 #define SPDMEM_RDR_TYPE_EMBED		3
169 #define SPDMEM_RDR_TYPE_RIMM32		4
170 
171 /* Dual Data Rate SDRAM */
172 #define SPDMEM_DDR_ROWS			0x00
173 #define SPDMEM_DDR_COLS			0x01
174 #define SPDMEM_DDR_RANKS		0x02
175 #define SPDMEM_DDR_DATAWIDTH		0x03
176 #define SPDMEM_DDR_VOLTAGE		0x05
177 #define SPDMEM_DDR_CYCLE		0x06
178 #define SPDMEM_DDR_REFRESH		0x09
179 #define SPDMEM_DDR_BANKS_PER_CHIP	0x0e
180 #define SPDMEM_DDR_CAS			0x0f
181 #define SPDMEM_DDR_MOD_ATTRIB		0x12
182 #define SPDMEM_DDR_SUPERSET		0x1d
183 
184 #define SPDMEM_DDR_ATTRIB_REG		(1 << 1)
185 
186 /* Dual Data Rate 2 SDRAM */
187 #define SPDMEM_DDR2_ROWS		0x00
188 #define SPDMEM_DDR2_COLS		0x01
189 #define SPDMEM_DDR2_RANKS		0x02
190 #define SPDMEM_DDR2_DATAWIDTH		0x03
191 #define SPDMEM_DDR2_VOLTAGE		0x05
192 #define SPDMEM_DDR2_CYCLE		0x06
193 #define SPDMEM_DDR2_DIMMTYPE		0x11
194 #define SPDMEM_DDR2_RANK_DENSITY	0x1c
195 
196 #define SPDMEM_DDR2_TYPE_REGMASK	((1 << 4) | (1 << 0))
197 #define SPDMEM_DDR2_SODIMM		(1 << 2)
198 #define SPDMEM_DDR2_MICRO_DIMM		(1 << 3)
199 #define SPDMEM_DDR2_MINI_RDIMM		(1 << 4)
200 #define SPDMEM_DDR2_MINI_UDIMM		(1 << 5)
201 
202 /* DDR2 FB-DIMM SDRAM */
203 #define SPDMEM_FBDIMM_ADDR		0x01
204 #define SPDMEM_FBDIMM_RANKS		0x04
205 #define SPDMEM_FBDIMM_MTB_DIVIDEND	0x06
206 #define SPDMEM_FBDIMM_MTB_DIVISOR	0x07
207 #define SPDMEM_FBDIMM_PROTO		0x4e
208 
209 #define SPDMEM_FBDIMM_RANKS_WIDTH		0x07
210 #define SPDMEM_FBDIMM_ADDR_BANKS		0x02
211 #define SPDMEM_FBDIMM_ADDR_COL			0x0c
212 #define SPDMEM_FBDIMM_ADDR_COL_SHIFT		2
213 #define SPDMEM_FBDIMM_ADDR_ROW			0xe0
214 #define SPDMEM_FBDIMM_ADDR_ROW_SHIFT		5
215 #define SPDMEM_FBDIMM_PROTO_ECC			(1 << 1)
216 
217 
218 /* Dual Data Rate 3 SDRAM */
219 #define SPDMEM_DDR3_MODTYPE		0x00
220 #define SPDMEM_DDR3_DENSITY		0x01
221 #define SPDMEM_DDR3_MOD_ORG		0x04
222 #define SPDMEM_DDR3_DATAWIDTH		0x05
223 #define SPDMEM_DDR3_MTB_DIVIDEND	0x07
224 #define SPDMEM_DDR3_MTB_DIVISOR		0x08
225 #define SPDMEM_DDR3_TCKMIN		0x09
226 #define SPDMEM_DDR3_THERMAL		0x1d
227 
228 #define SPDMEM_DDR3_DENSITY_CAPMASK		0x0f
229 #define SPDMEM_DDR3_MOD_ORG_CHIPWIDTH_MASK	0x07
230 #define SPDMEM_DDR3_MOD_ORG_BANKS_SHIFT		3
231 #define SPDMEM_DDR3_MOD_ORG_BANKS_MASK		0x07
232 #define SPDMEM_DDR3_DATAWIDTH_ECCMASK		(1 << 3)
233 #define SPDMEM_DDR3_DATAWIDTH_PRIMASK		0x07
234 #define SPDMEM_DDR3_THERMAL_PRESENT		(1 << 7)
235 
236 #define SPDMEM_DDR3_RDIMM		0x01
237 #define SPDMEM_DDR3_UDIMM		0x02
238 #define SPDMEM_DDR3_SODIMM		0x03
239 #define SPDMEM_DDR3_MICRO_DIMM		0x04
240 #define SPDMEM_DDR3_MINI_RDIMM		0x05
241 #define SPDMEM_DDR3_MINI_UDIMM		0x06
242 
243 /* Dual Data Rate 4 SDRAM */
244 #define	SPDMEM_DDR4_MODTYPE		0x00
245 #define	SPDMEM_DDR4_DENSITY		0x01
246 #define	SPDMEM_DDR4_PACK_TYPE		0x03
247 #define	SPDMEM_DDR4_MOD_ORG		0x09
248 #define	SPDMEM_DDR4_DATAWIDTH		0x0a
249 #define	SPDMEM_DDR4_THERMAL		0x0b
250 #define	SPDMEM_DDR4_TCKMIN_MTB		0x0f
251 #define	SPDMEM_DDR4_TCKMIN_FTB		0x7d	/* not offset by 3 */
252 
253 #define	SPDMEM_DDR4_DENSITY_CAPMASK		0x0f
254 #define	SPDMEM_DDR4_PACK_TYPE_SIG_LOAD_MASK	0x03
255 #define	SPDMEM_DDR4_PACK_TYPE_SIG_SINGLE_LOAD	0x02
256 #define	SPDMEM_DDR4_PACK_TYPE_DIE_COUNT_SHIFT	4
257 #define	SPDMEM_DDR4_PACK_TYPE_DIE_COUNT_MASK	0x07
258 #define	SPDMEM_DDR4_MOD_ORG_CHIPWIDTH_MASK	0x07
259 #define	SPDMEM_DDR4_MOD_ORG_BANKS_SHIFT		3
260 #define	SPDMEM_DDR4_MOD_ORG_BANKS_MASK		0x07
261 #define	SPDMEM_DDR4_DATAWIDTH_ECCMASK		(1 << 3)
262 #define	SPDMEM_DDR4_DATAWIDTH_PRIMASK		0x07
263 #define	SPDMEM_DDR4_THERMAL_PRESENT		(1 << 7)
264 
265 #define	SPDMEM_DDR4_RDIMM		0x01
266 #define	SPDMEM_DDR4_UDIMM		0x02
267 #define	SPDMEM_DDR4_SODIMM		0x03
268 #define	SPDMEM_DDR4_LRDIMM		0x04
269 #define	SPDMEM_DDR4_MINI_RDIMM		0x05
270 #define	SPDMEM_DDR4_MINI_UDIMM		0x06
271 #define	SPDMEM_DDR4_LP_DIMM		0x07
272 #define	SPDMEM_DDR4_72B_SO_RDIMM	0x08
273 #define	SPDMEM_DDR4_72B_SO_UDIMM	0x09
274 #define	SPDMEM_DDR4_16B_SO_DIMM		0x0c
275 #define	SPDMEM_DDR4_32B_SO_DIMM		0x0d
276 #define	SPDMEM_DDR4_NON_DIMM		0x0e
277 #define	SPDMEM_DDR4_MODTYPE_MASK	0x0f
278 #define	SPDMEM_DDR4_MODTYPE_HYBRID	0x80
279 
280 static const uint8_t ddr2_cycle_tenths[] = {
281 	0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 25, 33, 66, 75, 0, 0
282 };
283 
284 #define SPDMEM_TYPE_MAXLEN 16
285 
286 uint16_t	spdmem_crc16(struct spdmem_softc *, int);
287 static inline
288 uint8_t		spdmem_read(struct spdmem_softc *, uint8_t);
289 void		spdmem_sdram_decode(struct spdmem_softc *, struct spdmem *);
290 void		spdmem_rdr_decode(struct spdmem_softc *, struct spdmem *);
291 void		spdmem_ddr_decode(struct spdmem_softc *, struct spdmem *);
292 void		spdmem_ddr2_decode(struct spdmem_softc *, struct spdmem *);
293 void		spdmem_fbdimm_decode(struct spdmem_softc *, struct spdmem *);
294 void		spdmem_ddr3_decode(struct spdmem_softc *, struct spdmem *);
295 
296 struct cfdriver spdmem_cd = {
297 	NULL, "spdmem", DV_DULL
298 };
299 
300 #define IS_RAMBUS_TYPE (s->sm_len < 4)
301 
302 static const char *spdmem_basic_types[] = {
303 	"unknown",
304 	"FPM",
305 	"EDO",
306 	"Pipelined Nibble",
307 	"SDRAM",
308 	"ROM",
309 	"DDR SGRAM",
310 	"DDR SDRAM",
311 	"DDR2 SDRAM",
312 	"DDR2 SDRAM FB-DIMM",
313 	"DDR2 SDRAM FB-DIMM Probe",
314 	"DDR3 SDRAM",
315 	"DDR4 SDRAM",
316 	"unknown",
317 	"DDR4E SDRAM",
318 	"LPDDR3 SDRAM",
319 	"LPDDR4 SDRAM",
320 	"LPDDR4X SDRAM",
321 	"DDR5 SDRAM",
322 	"LPDDR5 SDRAM"
323 };
324 
325 static const char *spdmem_superset_types[] = {
326 	"unknown",
327 	"ESDRAM",
328 	"DDR ESDRAM",
329 	"PEM EDO",
330 	"PEM SDRAM"
331 };
332 
333 static const char *spdmem_parity_types[] = {
334 	"non-parity",
335 	"data parity",
336 	"ECC",
337 	"data parity and ECC",
338 	"cmd/addr parity",
339 	"cmd/addr/data parity",
340 	"cmd/addr parity, data ECC",
341 	"cmd/addr/data parity, data ECC"
342 };
343 
344 static inline uint8_t
spdmem_read(struct spdmem_softc * sc,uint8_t reg)345 spdmem_read(struct spdmem_softc *sc, uint8_t reg)
346 {
347 	return (*sc->sc_read)(sc, reg);
348 }
349 
350 /* CRC functions used for certain memory types */
351 uint16_t
spdmem_crc16(struct spdmem_softc * sc,int count)352 spdmem_crc16(struct spdmem_softc *sc, int count)
353 {
354 	uint16_t crc;
355 	int i, j;
356 	uint8_t val;
357 	crc = 0;
358 	for (j = 0; j <= count; j++) {
359 		val = spdmem_read(sc, j);
360 		crc = crc ^ val << 8;
361 		for (i = 0; i < 8; ++i)
362 			if (crc & 0x8000)
363 				crc = crc << 1 ^ 0x1021;
364 			else
365 				crc = crc << 1;
366 	}
367 	return (crc & 0xFFFF);
368 }
369 
370 void
spdmem_sdram_decode(struct spdmem_softc * sc,struct spdmem * s)371 spdmem_sdram_decode(struct spdmem_softc *sc, struct spdmem *s)
372 {
373 	const char *type;
374 	int dimm_size, p_clk;
375 	int num_banks, per_chip;
376 	uint8_t rows, cols;
377 
378 	type = spdmem_basic_types[s->sm_type];
379 
380 	if (s->sm_data[SPDMEM_SDR_SUPERSET] == SPDMEM_SUPERSET_SDR_PEM)
381 		type = spdmem_superset_types[SPDMEM_SUPERSET_SDR_PEM];
382 	if (s->sm_data[SPDMEM_SDR_SUPERSET] == SPDMEM_SUPERSET_ESDRAM)
383 		type = spdmem_superset_types[SPDMEM_SUPERSET_ESDRAM];
384 
385 	num_banks = s->sm_data[SPDMEM_SDR_BANKS];
386 	per_chip = s->sm_data[SPDMEM_SDR_BANKS_PER_CHIP];
387 	rows = s->sm_data[SPDMEM_SDR_ROWS] & 0x0f;
388 	cols = s->sm_data[SPDMEM_SDR_COLS] & 0x0f;
389 	dimm_size = (1 << (rows + cols - 17)) * num_banks * per_chip;
390 
391 	if (dimm_size > 0) {
392 		if (dimm_size < 1024)
393 			printf(" %dMB", dimm_size);
394 		else
395 			printf(" %dGB", dimm_size / 1024);
396 	}
397 
398 	printf(" %s", type);
399 
400 	if (s->sm_data[SPDMEM_DDR_MOD_ATTRIB] & SPDMEM_DDR_ATTRIB_REG)
401 		printf(" registered");
402 
403 	if (s->sm_data[SPDMEM_FPM_CONFIG] < 8)
404 		printf(" %s",
405 		    spdmem_parity_types[s->sm_data[SPDMEM_FPM_CONFIG]]);
406 
407 	p_clk = 66;
408 	if (s->sm_len >= 128) {
409 		switch (spdmem_read(sc, SPDMEM_SDR_FREQUENCY)) {
410 		case SPDMEM_SDR_FREQ_100:
411 		case SPDMEM_SDR_FREQ_133:
412 			/* We need to check ns to decide here */
413 			if (s->sm_data[SPDMEM_SDR_CYCLE] < 0x80)
414 				p_clk = 133;
415 			else
416 				p_clk = 100;
417 			break;
418 		case SPDMEM_SDR_FREQ_66:
419 		default:
420 			p_clk = 66;
421 			break;
422 		}
423 	}
424 	printf(" PC%d", p_clk);
425 
426 	/* Print CAS latency */
427 	if (s->sm_len < 128)
428 		return;
429 	if (spdmem_read(sc, SPDMEM_SDR_CAS) & SPDMEM_SDR_CAS2)
430 		printf("CL2");
431 	else if (spdmem_read(sc, SPDMEM_SDR_CAS) & SPDMEM_SDR_CAS3)
432 		printf("CL3");
433 }
434 
435 void
spdmem_rdr_decode(struct spdmem_softc * sc,struct spdmem * s)436 spdmem_rdr_decode(struct spdmem_softc *sc, struct spdmem *s)
437 {
438 	int rimm_size;
439 	uint8_t row_bits, col_bits, bank_bits;
440 
441 	row_bits = s->sm_data[SPDMEM_RDR_ROWS_COLS] >> 4;
442 	col_bits = s->sm_data[SPDMEM_RDR_ROWS_COLS] & 0x0f;
443 	bank_bits = s->sm_data[SPDMEM_RDR_BANK] & 0x07;
444 
445 	/* subtracting 13 here is a cheaper way of dividing by 8k later */
446 	rimm_size = 1 << (row_bits + col_bits + bank_bits - 13);
447 
448 	if (rimm_size < 1024)
449 		printf(" %dMB ", rimm_size);
450 	else
451 		printf(" %dGB ", rimm_size / 1024);
452 
453 	switch(s->sm_data[SPDMEM_RDR_MODULE_TYPE]) {
454 	case SPDMEM_RDR_TYPE_RIMM:
455 		printf("RIMM");
456 		break;
457 	case SPDMEM_RDR_TYPE_SORIMM:
458 		printf("SO-RIMM");
459 		break;
460 	case SPDMEM_RDR_TYPE_EMBED:
461 		printf("Embedded Rambus");
462 		break;
463 	case SPDMEM_RDR_TYPE_RIMM32:
464 		printf("RIMM32");
465 		break;
466 	}
467 }
468 
469 void
spdmem_ddr_decode(struct spdmem_softc * sc,struct spdmem * s)470 spdmem_ddr_decode(struct spdmem_softc *sc, struct spdmem *s)
471 {
472 	const char *type;
473 	int dimm_size, cycle_time, d_clk, p_clk, bits;
474 	int i, num_banks, per_chip;
475 	uint8_t config, rows, cols, cl;
476 
477 	type = spdmem_basic_types[s->sm_type];
478 
479 	if (s->sm_data[SPDMEM_DDR_SUPERSET] == SPDMEM_SUPERSET_DDR_ESDRAM)
480 		type = spdmem_superset_types[SPDMEM_SUPERSET_DDR_ESDRAM];
481 
482 	num_banks = s->sm_data[SPDMEM_SDR_BANKS];
483 	per_chip = s->sm_data[SPDMEM_SDR_BANKS_PER_CHIP];
484 	rows = s->sm_data[SPDMEM_SDR_ROWS] & 0x0f;
485 	cols = s->sm_data[SPDMEM_SDR_COLS] & 0x0f;
486 	dimm_size = (1 << (rows + cols - 17)) * num_banks * per_chip;
487 
488 	if (dimm_size > 0) {
489 		if (dimm_size < 1024)
490 			printf(" %dMB", dimm_size);
491 		else
492 			printf(" %dGB", dimm_size / 1024);
493 	}
494 
495 	printf(" %s", type);
496 
497 	if (s->sm_data[SPDMEM_DDR_MOD_ATTRIB] & SPDMEM_DDR_ATTRIB_REG)
498 		printf(" registered");
499 
500 	if (s->sm_data[SPDMEM_FPM_CONFIG] < 8)
501 		printf(" %s",
502 		    spdmem_parity_types[s->sm_data[SPDMEM_FPM_CONFIG]]);
503 
504 	/* cycle_time is expressed in units of 0.01 ns */
505 	cycle_time = (s->sm_data[SPDMEM_DDR_CYCLE] >> 4) * 100 +
506 	    (s->sm_data[SPDMEM_DDR_CYCLE] & 0x0f) * 10;
507 
508 	if (cycle_time != 0) {
509 		/*
510 		 * cycle time is scaled by a factor of 100 to avoid using
511 		 * floating point.  Calculate memory speed as the number
512 		 * of cycles per microsecond.
513 		 * DDR uses dual-pumped clock
514 		 */
515 		d_clk = 100 * 1000 * 2;
516 		config = s->sm_data[SPDMEM_FPM_CONFIG];
517 		bits = s->sm_data[SPDMEM_DDR_DATAWIDTH] |
518 		    (s->sm_data[SPDMEM_DDR_DATAWIDTH + 1] << 8);
519 		if (config == 1 || config == 2)
520 			bits -= 8;
521 
522 		d_clk /= cycle_time;
523 		p_clk = d_clk * bits / 8;
524 		if ((p_clk % 100) >= 50)
525 			p_clk += 50;
526 		p_clk -= p_clk % 100;
527 		printf(" PC%d", p_clk);
528 	}
529 
530 	/* Print CAS latency */
531 	for (i = 6; i >= 0; i--) {
532 		if (s->sm_data[SPDMEM_DDR_CAS] & (1 << i)) {
533 			cl = ((i * 10) / 2) + 10;
534 			printf("CL%d.%d", cl / 10, cl % 10);
535 			break;
536 		}
537 	}
538 }
539 
540 void
spdmem_ddr2_decode(struct spdmem_softc * sc,struct spdmem * s)541 spdmem_ddr2_decode(struct spdmem_softc *sc, struct spdmem *s)
542 {
543 	const char *type;
544 	int dimm_size, cycle_time, d_clk, p_clk, bits;
545 	int i, num_ranks, density;
546 	uint8_t config;
547 
548 	type = spdmem_basic_types[s->sm_type];
549 
550 	num_ranks = (s->sm_data[SPDMEM_DDR2_RANKS] & 0x7) + 1;
551 	density = (s->sm_data[SPDMEM_DDR2_RANK_DENSITY] & 0xf0) |
552 	    ((s->sm_data[SPDMEM_DDR2_RANK_DENSITY] & 0x0f) << 8);
553 	dimm_size = num_ranks * density * 4;
554 
555 	if (dimm_size > 0) {
556 		if (dimm_size < 1024)
557 			printf(" %dMB", dimm_size);
558 		else
559 			printf(" %dGB", dimm_size / 1024);
560 	}
561 
562 	printf(" %s", type);
563 
564 	if (s->sm_data[SPDMEM_DDR2_DIMMTYPE] & SPDMEM_DDR2_TYPE_REGMASK)
565 		printf(" registered");
566 
567 	if (s->sm_data[SPDMEM_FPM_CONFIG] < 8)
568 		printf(" %s",
569 		    spdmem_parity_types[s->sm_data[SPDMEM_FPM_CONFIG]]);
570 
571 	/* cycle_time is expressed in units of 0.01 ns */
572 	cycle_time = (s->sm_data[SPDMEM_DDR2_CYCLE] >> 4) * 100 +
573 	    ddr2_cycle_tenths[(s->sm_data[SPDMEM_DDR2_CYCLE] & 0x0f)];
574 
575 	if (cycle_time != 0) {
576 		/*
577 		 * cycle time is scaled by a factor of 100 to avoid using
578 		 * floating point.  Calculate memory speed as the number
579 		 * of cycles per microsecond.
580 		 * DDR2 uses quad-pumped clock
581 		 */
582 		d_clk = 100 * 1000 * 4;
583 		config = s->sm_data[SPDMEM_FPM_CONFIG];
584 		bits = s->sm_data[SPDMEM_DDR2_DATAWIDTH];
585 		if ((config & 0x03) != 0)
586 			bits -= 8;
587 		d_clk /= cycle_time;
588 		d_clk = (d_clk + 1) / 2;
589 		p_clk = d_clk * bits / 8;
590 		p_clk -= p_clk % 100;
591 		printf(" PC2-%d", p_clk);
592 	}
593 
594 	/* Print CAS latency */
595 	for (i = 7; i >= 2; i--) {
596 		if (s->sm_data[SPDMEM_DDR_CAS] & (1 << i)) {
597 			printf("CL%d", i);
598 			break;
599 		}
600 	}
601 
602 	switch (s->sm_data[SPDMEM_DDR2_DIMMTYPE]) {
603 	case SPDMEM_DDR2_SODIMM:
604 		printf(" SO-DIMM");
605 		break;
606 	case SPDMEM_DDR2_MICRO_DIMM:
607 		printf(" Micro-DIMM");
608 		break;
609 	case SPDMEM_DDR2_MINI_RDIMM:
610 	case SPDMEM_DDR2_MINI_UDIMM:
611 		printf(" Mini-DIMM");
612 		break;
613 	}
614 }
615 
616 void
spdmem_fbdimm_decode(struct spdmem_softc * sc,struct spdmem * s)617 spdmem_fbdimm_decode(struct spdmem_softc *sc, struct spdmem *s)
618 {
619 	int dimm_size, cycle_time, d_clk, p_clk, bits;
620 	uint8_t rows, cols, dividend, divisor;
621 	/*
622 	 * FB-DIMM is very much like DDR3
623 	 */
624 
625 	cols = (s->sm_data[SPDMEM_FBDIMM_ADDR] & SPDMEM_FBDIMM_ADDR_COL) >>
626 	    SPDMEM_FBDIMM_ADDR_COL_SHIFT;
627 	rows = (s->sm_data[SPDMEM_FBDIMM_ADDR] & SPDMEM_FBDIMM_ADDR_ROW) >>
628 	    SPDMEM_FBDIMM_ADDR_ROW_SHIFT;
629 	dimm_size = rows + 12 + cols +  9 - 20 - 3;
630 
631 	if (dimm_size < 1024)
632 		printf(" %dMB", dimm_size);
633 	else
634 		printf(" %dGB", dimm_size / 1024);
635 
636 	dividend = s->sm_data[SPDMEM_FBDIMM_MTB_DIVIDEND];
637 	divisor = s->sm_data[SPDMEM_FBDIMM_MTB_DIVISOR];
638 
639 	cycle_time = (1000 * dividend + (divisor / 2)) / divisor;
640 
641 	if (cycle_time != 0) {
642 		/*
643 		 * cycle time is scaled by a factor of 1000 to avoid using
644 		 * floating point.  Calculate memory speed as the number
645 		 * of cycles per microsecond.
646 		 */
647 		d_clk = 1000 * 1000;
648 
649 		/* DDR2 FB-DIMM uses a dual-pumped clock */
650 		d_clk *= 2;
651 		bits = 1 << ((s->sm_data[SPDMEM_FBDIMM_RANKS] &
652 		    SPDMEM_FBDIMM_RANKS_WIDTH) + 2);
653 
654 		p_clk = (d_clk * bits) / 8 / cycle_time;
655 		p_clk -= p_clk % 100;
656 		printf(" PC2-%d", p_clk);
657 	}
658 }
659 
660 void
spdmem_ddr3_decode(struct spdmem_softc * sc,struct spdmem * s)661 spdmem_ddr3_decode(struct spdmem_softc *sc, struct spdmem *s)
662 {
663 	const char *type;
664 	int dimm_size, cycle_time, d_clk, p_clk, bits;
665 	uint8_t mtype, chipsize, dividend, divisor;
666 	uint8_t datawidth, chipwidth, physbanks;
667 
668 	type = spdmem_basic_types[s->sm_type];
669 
670 	chipsize = s->sm_data[SPDMEM_DDR3_DENSITY] &
671 	    SPDMEM_DDR3_DENSITY_CAPMASK;
672 	datawidth = s->sm_data[SPDMEM_DDR3_DATAWIDTH] &
673 	    SPDMEM_DDR3_DATAWIDTH_PRIMASK;
674 	chipwidth = s->sm_data[SPDMEM_DDR3_MOD_ORG] &
675 	    SPDMEM_DDR3_MOD_ORG_CHIPWIDTH_MASK;
676 	physbanks = (s->sm_data[SPDMEM_DDR3_MOD_ORG] >>
677 	    SPDMEM_DDR3_MOD_ORG_BANKS_SHIFT) & SPDMEM_DDR3_MOD_ORG_BANKS_MASK;
678 
679 	dimm_size = (chipsize + 28 - 20) - 3 + (datawidth + 3) -
680 	    (chipwidth + 2);
681 	dimm_size = (1 << dimm_size) * (physbanks + 1);
682 
683 	if (dimm_size < 1024)
684 		printf(" %dMB", dimm_size);
685 	else
686 		printf(" %dGB", dimm_size / 1024);
687 
688 	printf(" %s", type);
689 
690 	mtype = s->sm_data[SPDMEM_DDR3_MODTYPE];
691 	if (mtype == SPDMEM_DDR3_RDIMM || mtype == SPDMEM_DDR3_MINI_RDIMM)
692 		printf(" registered");
693 
694 	if (s->sm_data[SPDMEM_DDR3_DATAWIDTH] & SPDMEM_DDR3_DATAWIDTH_ECCMASK)
695 		printf(" ECC");
696 
697 	dividend = s->sm_data[SPDMEM_DDR3_MTB_DIVIDEND];
698 	divisor = s->sm_data[SPDMEM_DDR3_MTB_DIVISOR];
699 	cycle_time = (1000 * dividend +  (divisor / 2)) / divisor;
700 	cycle_time *= s->sm_data[SPDMEM_DDR3_TCKMIN];
701 
702 	if (cycle_time != 0) {
703 		/*
704 		 * cycle time is scaled by a factor of 1000 to avoid using
705 		 * floating point.  Calculate memory speed as the number
706 		 * of cycles per microsecond.
707 		 * DDR3 uses a dual-pumped clock
708 		 */
709 		d_clk = 1000 * 1000;
710 		d_clk *= 2;
711 		bits = 1 << ((s->sm_data[SPDMEM_DDR3_DATAWIDTH] &
712 		    SPDMEM_DDR3_DATAWIDTH_PRIMASK) + 3);
713 		/*
714 		 * Calculate p_clk first, since for DDR3 we need maximum
715 		 * significance.  DDR3 rating is not rounded to a multiple
716 		 * of 100.  This results in cycle_time of 1.5ns displayed
717 		 * as p_clk PC3-10666 (d_clk DDR3-1333)
718 		 */
719 		p_clk = (d_clk * bits) / 8 / cycle_time;
720 		p_clk -= (p_clk % 100);
721 		d_clk = ((d_clk + cycle_time / 2) ) / cycle_time;
722 		printf(" PC3-%d", p_clk);
723 	}
724 
725 	switch (s->sm_data[SPDMEM_DDR3_MODTYPE]) {
726 	case SPDMEM_DDR3_SODIMM:
727 		printf(" SO-DIMM");
728 		break;
729 	case SPDMEM_DDR3_MICRO_DIMM:
730 		printf(" Micro-DIMM");
731 		break;
732 	case SPDMEM_DDR3_MINI_RDIMM:
733 	case SPDMEM_DDR3_MINI_UDIMM:
734 		printf(" Mini-DIMM");
735 		break;
736 	}
737 
738 	if (s->sm_data[SPDMEM_DDR3_THERMAL] & SPDMEM_DDR3_THERMAL_PRESENT)
739 		printf(" with thermal sensor");
740 }
741 
742 void
spdmem_ddr4_decode(struct spdmem_softc * sc,struct spdmem * s)743 spdmem_ddr4_decode(struct spdmem_softc *sc, struct spdmem *s)
744 {
745 	static const int ddr4_chipsize[16] = { 256, 512, 1024, 2048, 4096,
746 	    8 * 1024, 16 * 1024, 32 * 1024, 12 * 1024, 24 * 1024,
747 	    3 * 1024, 6 * 1024, 18 * 1024 };
748 	const char *type;
749 	int dimm_size, cycle_time, d_clk, p_clk, bits;
750 	uint8_t mtype, chipsize, mtb;
751 	int8_t ftb;
752 	uint8_t datawidth, chipwidth, physbanks, diecount = 0;
753 
754 	type = spdmem_basic_types[s->sm_type];
755 
756 	chipsize = s->sm_data[SPDMEM_DDR4_DENSITY] &
757 	    SPDMEM_DDR4_DENSITY_CAPMASK;
758 	datawidth = s->sm_data[SPDMEM_DDR4_DATAWIDTH] &
759 	    SPDMEM_DDR4_DATAWIDTH_PRIMASK;
760 	chipwidth = s->sm_data[SPDMEM_DDR4_MOD_ORG] &
761 	    SPDMEM_DDR4_MOD_ORG_CHIPWIDTH_MASK;
762 	physbanks = (s->sm_data[SPDMEM_DDR4_MOD_ORG] >>
763 	    SPDMEM_DDR4_MOD_ORG_BANKS_SHIFT) & SPDMEM_DDR4_MOD_ORG_BANKS_MASK;
764 
765 	if ((s->sm_data[SPDMEM_DDR4_PACK_TYPE] &
766 	    SPDMEM_DDR4_PACK_TYPE_SIG_LOAD_MASK) ==
767 	    SPDMEM_DDR4_PACK_TYPE_SIG_SINGLE_LOAD) {
768 		diecount = (s->sm_data[SPDMEM_DDR4_PACK_TYPE] >>
769 		    SPDMEM_DDR4_PACK_TYPE_DIE_COUNT_SHIFT) &
770 		    SPDMEM_DDR4_PACK_TYPE_DIE_COUNT_MASK;
771 	}
772 
773 	dimm_size = (datawidth + 3) - (chipwidth + 2);
774 	dimm_size = (ddr4_chipsize[chipsize] / 8) * (1 << dimm_size) *
775 	    (physbanks + 1) * (diecount + 1);
776 
777 	if (dimm_size < 1024)
778 		printf(" %dMB", dimm_size);
779 	else
780 		printf(" %dGB", dimm_size / 1024);
781 
782 	printf(" %s", type);
783 
784 	mtype = s->sm_data[SPDMEM_DDR4_MODTYPE];
785 	if (mtype & SPDMEM_DDR4_MODTYPE_HYBRID)
786 		printf(" hybrid");
787 	mtype &= SPDMEM_DDR4_MODTYPE_MASK;
788 	if (mtype == SPDMEM_DDR4_RDIMM || mtype == SPDMEM_DDR4_MINI_RDIMM ||
789 	    mtype == SPDMEM_DDR4_72B_SO_RDIMM)
790 		printf(" registered");
791 	if (mtype == SPDMEM_DDR4_72B_SO_UDIMM ||
792 	    mtype == SPDMEM_DDR4_72B_SO_RDIMM)
793 		printf(" 72-bit");
794 	if (mtype == SPDMEM_DDR4_32B_SO_DIMM)
795 		printf(" 32-bit");
796 	if (mtype == SPDMEM_DDR4_16B_SO_DIMM)
797 		printf(" 16-bit");
798 
799 	if (s->sm_data[SPDMEM_DDR4_DATAWIDTH] & SPDMEM_DDR4_DATAWIDTH_ECCMASK)
800 		printf(" ECC");
801 
802 	mtb = s->sm_data[SPDMEM_DDR4_TCKMIN_MTB];
803 	/* SPDMEM_DDR4_TCKMIN_FTB (addr 125) is outside of s->sm_data */
804 	ftb = spdmem_read(sc, SPDMEM_DDR4_TCKMIN_FTB);
805 	cycle_time = mtb * 125 + ftb; /* in ps */
806 
807 	if (cycle_time != 0) {
808 		/*
809 		 * cycle time is scaled by a factor of 1000 to avoid using
810 		 * floating point.  Calculate memory speed as the number
811 		 * of cycles per microsecond.
812 		 * DDR4 uses a dual-pumped clock
813 		 */
814 		d_clk = 1000 * 1000;
815 		d_clk *= 2;
816 		bits = 1 << ((s->sm_data[SPDMEM_DDR4_DATAWIDTH] &
817 		    SPDMEM_DDR4_DATAWIDTH_PRIMASK) + 3);
818 
819 		p_clk = (d_clk * bits) / 8 / cycle_time;
820 		p_clk -= (p_clk % 100);
821 		printf(" PC4-%d", p_clk);
822 	}
823 
824 	switch (s->sm_data[SPDMEM_DDR4_MODTYPE] & SPDMEM_DDR4_MODTYPE_MASK) {
825 	case SPDMEM_DDR4_SODIMM:
826 	case SPDMEM_DDR4_72B_SO_RDIMM:
827 	case SPDMEM_DDR4_72B_SO_UDIMM:
828 	case SPDMEM_DDR4_16B_SO_DIMM:
829 	case SPDMEM_DDR4_32B_SO_DIMM:
830 		printf(" SO-DIMM");
831 		break;
832 	case SPDMEM_DDR4_LRDIMM:
833 		printf(" LR-DIMM");
834 		break;
835 	case SPDMEM_DDR4_MINI_RDIMM:
836 	case SPDMEM_DDR4_MINI_UDIMM:
837 		printf(" Mini-DIMM");
838 		break;
839 	case SPDMEM_DDR4_LP_DIMM:
840 		printf(" LP-DIMM");
841 		break;
842 	case SPDMEM_DDR4_NON_DIMM:
843 		printf(" non-DIMM solution");
844 		break;
845 	}
846 
847 	if (s->sm_data[SPDMEM_DDR4_THERMAL] & SPDMEM_DDR4_THERMAL_PRESENT)
848 		printf(" with thermal sensor");
849 }
850 
851 int
spdmem_probe(struct spdmem_softc * sc)852 spdmem_probe(struct spdmem_softc *sc)
853 {
854 	uint8_t i, val, type;
855 	int cksum = 0;
856 	int spd_len, spd_crc_cover;
857 	uint16_t crc_calc, crc_spd;
858 
859 	type = spdmem_read(sc, 2);
860 	/* For older memory types, validate the checksum over 1st 63 bytes */
861 	if (type <= SPDMEM_MEMTYPE_DDR2SDRAM) {
862 		for (i = 0; i < 63; i++)
863 			cksum += spdmem_read(sc, i);
864 
865 		val = spdmem_read(sc, 63);
866 
867 		if (cksum == 0 || (cksum & 0xff) != val) {
868 			return 0;
869 		} else
870 			return 1;
871 	}
872 
873 	/* For DDR3 and FBDIMM, verify the CRC */
874 	else if (type <= SPDMEM_MEMTYPE_DDR3SDRAM) {
875 		spd_len = spdmem_read(sc, 0);
876 		if (spd_len & SPDMEM_SPDCRC_116)
877 			spd_crc_cover = 116;
878 		else
879 			spd_crc_cover = 125;
880 		switch (spd_len & SPDMEM_SPDLEN_MASK) {
881 		case SPDMEM_SPDLEN_128:
882 			spd_len = 128;
883 			break;
884 		case SPDMEM_SPDLEN_176:
885 			spd_len = 176;
886 			break;
887 		case SPDMEM_SPDLEN_256:
888 			spd_len = 256;
889 			break;
890 		default:
891 			return 0;
892 		}
893 calc_crc:
894 		if (spd_crc_cover > spd_len)
895 			return 0;
896 		crc_calc = spdmem_crc16(sc, spd_crc_cover);
897 		crc_spd = spdmem_read(sc, 127) << 8;
898 		crc_spd |= spdmem_read(sc, 126);
899 		if (crc_calc != crc_spd) {
900 			return 0;
901 		}
902 		return 1;
903 	} else if (type <= SPDMEM_MEMTYPE_LPDDR4SDRAM) {
904 		spd_len = spdmem_read(sc, 0);
905 		spd_crc_cover = 125;
906 		switch (spd_len & SPDMEM_DDR4_SPDLEN_MASK) {
907 		case SPDMEM_DDR4_SPDLEN_128:
908 			spd_len = 128;
909 			break;
910 		case SPDMEM_DDR4_SPDLEN_256:
911 			spd_len = 256;
912 			break;
913 		case SPDMEM_DDR4_SPDLEN_384:
914 			spd_len = 384;
915 			break;
916 		case SPDMEM_DDR4_SPDLEN_512:
917 			spd_len = 512;
918 			break;
919 		default:
920 			return 0;
921 		}
922 		goto calc_crc;
923 	}
924 
925 	return 0;
926 }
927 
928 void
spdmem_attach_common(struct spdmem_softc * sc)929 spdmem_attach_common(struct spdmem_softc *sc)
930 {
931 	struct spdmem *s = &(sc->sc_spd_data);
932 	int i;
933 
934 	/* All SPD have at least 64 bytes of data including checksum */
935 	for (i = 0; i < 64; i++) {
936 		((uint8_t *)s)[i] = spdmem_read(sc, i);
937 	}
938 
939 	/*
940 	 * Decode and print SPD contents
941 	 */
942 	if (s->sm_len < 4) {
943 		if (s->sm_type == SPDMEM_MEMTYPE_DIRECT_RAMBUS)
944 			spdmem_rdr_decode(sc, s);
945 		else
946 			printf(" no decode method for Rambus memory");
947 	} else {
948 		switch(s->sm_type) {
949 		case SPDMEM_MEMTYPE_EDO:
950 		case SPDMEM_MEMTYPE_SDRAM:
951 			spdmem_sdram_decode(sc, s);
952 			break;
953 		case SPDMEM_MEMTYPE_DDRSDRAM:
954 			spdmem_ddr_decode(sc, s);
955 			break;
956 		case SPDMEM_MEMTYPE_DDR2SDRAM:
957 			spdmem_ddr2_decode(sc, s);
958 			break;
959 		case SPDMEM_MEMTYPE_FBDIMM:
960 		case SPDMEM_MEMTYPE_FBDIMM_PROBE:
961 			spdmem_fbdimm_decode(sc, s);
962 			break;
963 		case SPDMEM_MEMTYPE_DDR3SDRAM:
964 			spdmem_ddr3_decode(sc, s);
965 			break;
966 		case SPDMEM_MEMTYPE_DDR4SDRAM:
967 		case SPDMEM_MEMTYPE_DDR4ESDRAM:
968 		case SPDMEM_MEMTYPE_LPDDR3SDRAM:
969 		case SPDMEM_MEMTYPE_LPDDR4SDRAM:
970 			spdmem_ddr4_decode(sc, s);
971 			break;
972 		case SPDMEM_MEMTYPE_NONE:
973 			printf(" no EEPROM found");
974 			break;
975 		default:
976 			if (s->sm_type <= SPDMEM_MEMTYPE_LPDDR5SDRAM)
977 				printf(" no decode method for %s memory",
978 				    spdmem_basic_types[s->sm_type]);
979 			else
980 				printf(" unknown memory type %d", s->sm_type);
981 			break;
982 		}
983 	}
984 
985 	printf("\n");
986 }
987