xref: /netbsd-src/sys/dev/ic/spdmemvar.h (revision 2744d7ee4228559870a0287d5183b1f876c1df4a)
1*2744d7eeSmsaitoh /* $NetBSD: spdmemvar.h,v 1.16 2020/03/24 04:12:13 msaitoh Exp $ */
2d41a3cefSpgoyette 
3d41a3cefSpgoyette /*
4d41a3cefSpgoyette  * Copyright (c) 2007 Paul Goyette
5d41a3cefSpgoyette  * Copyright (c) 2007 Tobias Nygren
6d41a3cefSpgoyette  * All rights reserved.
7d41a3cefSpgoyette  *
8d41a3cefSpgoyette  * Redistribution and use in source and binary forms, with or without
9d41a3cefSpgoyette  * modification, are permitted provided that the following conditions
10d41a3cefSpgoyette  * are met:
11d41a3cefSpgoyette  * 1. Redistributions of source code must retain the above copyright
12d41a3cefSpgoyette  *    notice, this list of conditions and the following disclaimer.
13d41a3cefSpgoyette  * 2. Redistributions in binary form must reproduce the above copyright
14d41a3cefSpgoyette  *    notice, this list of conditions and the following disclaimer in the
15d41a3cefSpgoyette  *    documentation and/or other materials provided with the distribution.
16d41a3cefSpgoyette  * 3. The name of the author may not be used to endorse or promote products
17d41a3cefSpgoyette  *    derived from this software without specific prior written permission.
18d41a3cefSpgoyette  *
19d41a3cefSpgoyette  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
20d41a3cefSpgoyette  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21d41a3cefSpgoyette  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22d41a3cefSpgoyette  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23d41a3cefSpgoyette  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24d41a3cefSpgoyette  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25d41a3cefSpgoyette  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26d41a3cefSpgoyette  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27d41a3cefSpgoyette  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28d41a3cefSpgoyette  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29d41a3cefSpgoyette  * POSSIBILITY OF SUCH DAMAGE.
30d41a3cefSpgoyette  */
31d41a3cefSpgoyette 
32d41a3cefSpgoyette /*
33d41a3cefSpgoyette  * This information is extracted from JEDEC standard SPD4_01 (www.jedec.org)
34d41a3cefSpgoyette  */
35d41a3cefSpgoyette 
36d41a3cefSpgoyette #if BYTE_ORDER == BIG_ENDIAN
37d41a3cefSpgoyette #define SPD_BITFIELD(a, b, c, d) d; c; b; a
38d41a3cefSpgoyette #else
39d41a3cefSpgoyette #define SPD_BITFIELD(a, b, c, d) a; b; c; d
40d41a3cefSpgoyette #endif
41d41a3cefSpgoyette 
4250d1d96aSpgoyette 	/*
4350d1d96aSpgoyette 	 * NOTE
4450d1d96aSpgoyette 	 *
4550d1d96aSpgoyette 	 * Fields with "offsets" are field widths, measured in bits,
4650d1d96aSpgoyette 	 * with "offset" additional bits.  Thus, a field with value
4750d1d96aSpgoyette 	 * of 2 with an offset of 14 defines a field with total width
4850d1d96aSpgoyette 	 * of 16 bits.
4950d1d96aSpgoyette 	 */
5050d1d96aSpgoyette 
51d41a3cefSpgoyette struct spdmem_fpm {				/* FPM and EDO DIMMS */
5250d1d96aSpgoyette 	uint8_t	fpm_len;
5350d1d96aSpgoyette 	uint8_t fpm_size;
5450d1d96aSpgoyette 	uint8_t fpm_type;
55d41a3cefSpgoyette 	uint8_t fpm_rows;
56d41a3cefSpgoyette 	uint8_t fpm_cols;
57d41a3cefSpgoyette 	uint8_t fpm_banks;
58d41a3cefSpgoyette 	uint16_t fpm_datawidth;			/* endian-sensitive */
59d41a3cefSpgoyette 	uint8_t fpm_voltage;
60d41a3cefSpgoyette 	uint8_t	fpm_tRAC;
61d41a3cefSpgoyette 	uint8_t fpm_tCAC;
62d41a3cefSpgoyette 	uint8_t fpm_config;
63d41a3cefSpgoyette 	SPD_BITFIELD(				\
64d41a3cefSpgoyette 		uint8_t fpm_refresh:7,		\
65d41a3cefSpgoyette 		uint8_t fpm_selfrefresh:1, ,	\
66d41a3cefSpgoyette 	);
67d41a3cefSpgoyette 	uint8_t fpm_dram_dramwidth;
68d41a3cefSpgoyette 	uint8_t fpm_dram_eccwidth;
69d41a3cefSpgoyette 	uint8_t	fpm_unused2[17];
70d41a3cefSpgoyette 	uint8_t	fpm_superset;
71d41a3cefSpgoyette 	uint8_t fpm_unused3[30];
72d41a3cefSpgoyette 	uint8_t	fpm_cksum;
73d41a3cefSpgoyette } __packed;
74d41a3cefSpgoyette 
75d41a3cefSpgoyette struct spdmem_sdram {				/* PC66/PC100/PC133 SDRAM */
7650d1d96aSpgoyette 	uint8_t	sdr_len;
7750d1d96aSpgoyette 	uint8_t sdr_size;
7850d1d96aSpgoyette 	uint8_t sdr_type;
79d41a3cefSpgoyette 	SPD_BITFIELD(				\
80d41a3cefSpgoyette 		uint8_t sdr_rows:4,		\
81d41a3cefSpgoyette 		uint8_t sdr_rows2:4, ,		\
82d41a3cefSpgoyette 	);
83d41a3cefSpgoyette 	SPD_BITFIELD(				\
84d41a3cefSpgoyette 		uint8_t sdr_cols:4,		\
85d41a3cefSpgoyette 		uint8_t sdr_cols2:4, ,		\
86d41a3cefSpgoyette 	);
87d41a3cefSpgoyette 	uint8_t sdr_banks;
88d41a3cefSpgoyette 	uint16_t sdr_datawidth;			/* endian-sensitive */
89d41a3cefSpgoyette 	uint8_t sdr_voltage;
90d41a3cefSpgoyette 	SPD_BITFIELD(				\
91d41a3cefSpgoyette 		uint8_t sdr_cycle_tenths:4,	\
92d41a3cefSpgoyette 		uint8_t sdr_cycle_whole:4, ,	\
93d41a3cefSpgoyette 	);
94d41a3cefSpgoyette 	SPD_BITFIELD(
95d41a3cefSpgoyette 		uint8_t sdr_tAC_tenths:4,	\
96d41a3cefSpgoyette 		uint8_t	sdr_tAC_whole:4, ,	\
97d41a3cefSpgoyette 	);
98d41a3cefSpgoyette 	uint8_t sdr_config;
99d41a3cefSpgoyette 	SPD_BITFIELD(				\
100d41a3cefSpgoyette 		uint8_t sdr_refresh:7,		\
101d41a3cefSpgoyette 		uint8_t sdr_selfrefresh:1, ,	\
102d41a3cefSpgoyette 	);
103d41a3cefSpgoyette 	SPD_BITFIELD(				\
104d41a3cefSpgoyette 		uint8_t sdr_dramwidth:7,	\
105d41a3cefSpgoyette 		uint8_t sdr_dram_asym_bank2:1, ,\
106d41a3cefSpgoyette 	);
107d41a3cefSpgoyette 	SPD_BITFIELD(				\
108d41a3cefSpgoyette 		uint8_t sdr_eccwidth:7,		\
109d41a3cefSpgoyette 		uint8_t sdr_ecc_asym_bank2:1, ,	\
110d41a3cefSpgoyette 	);
111d41a3cefSpgoyette 	uint8_t sdr_min_clk_delay;
112d41a3cefSpgoyette 	SPD_BITFIELD(				\
113d41a3cefSpgoyette 		uint8_t sdr_burstlengths:4,	\
114d41a3cefSpgoyette 		uint8_t sdr_unused1:4, ,	\
115d41a3cefSpgoyette 	);
116d41a3cefSpgoyette 	uint8_t sdr_banks_per_chip;
117d41a3cefSpgoyette 	uint8_t sdr_tCAS;
118d41a3cefSpgoyette 	uint8_t sdr_tCS;
119d41a3cefSpgoyette 	uint8_t sdr_tWE;
120d41a3cefSpgoyette 	uint8_t sdr_mod_attrs;
121d41a3cefSpgoyette 	uint8_t sdr_dev_attrs;
122d41a3cefSpgoyette 	uint8_t sdr_min_cc_1;
123d41a3cefSpgoyette 	uint8_t sdr_max_tAC_1;
124d41a3cefSpgoyette 	uint8_t sdr_min_cc_2;
125d41a3cefSpgoyette 	uint8_t sdr_max_tAC_2;
126d41a3cefSpgoyette 	uint8_t sdr_tRP;
127d41a3cefSpgoyette 	uint8_t sdr_tRRD;
128d41a3cefSpgoyette 	uint8_t sdr_tRCD;
129d41a3cefSpgoyette 	uint8_t sdr_tRAS;
130d41a3cefSpgoyette 	uint8_t sdr_module_rank_density;
131d41a3cefSpgoyette 	uint8_t sdr_tIS;
132d41a3cefSpgoyette #define	sdr_superset sdr_tIS
133d41a3cefSpgoyette 	uint8_t sdr_tIH;
134d41a3cefSpgoyette 	uint8_t sdr_tDS;
135d41a3cefSpgoyette 	uint8_t sdr_tDH;
136d41a3cefSpgoyette 	uint8_t sdr_unused2[5];
137d41a3cefSpgoyette 	uint8_t sdr_tRC;
138d41a3cefSpgoyette 	uint8_t	sdr_unused3[18];
139d41a3cefSpgoyette 	uint8_t	sdr_esdram;
140d41a3cefSpgoyette 	uint8_t	sdr_super_tech;
141d41a3cefSpgoyette 	uint8_t	sdr_spdrev;
142d41a3cefSpgoyette 	uint8_t	sdr_cksum;
143d41a3cefSpgoyette } __packed;
144d41a3cefSpgoyette 
145d41a3cefSpgoyette struct spdmem_rom {
14650d1d96aSpgoyette 	uint8_t	rom_len;
14750d1d96aSpgoyette 	uint8_t rom_size;
14850d1d96aSpgoyette 	uint8_t rom_type;
149d41a3cefSpgoyette 	uint8_t rom_rows;
150d41a3cefSpgoyette 	uint8_t rom_cols;
151d41a3cefSpgoyette 	uint8_t rom_banks;
152d41a3cefSpgoyette 	uint16_t rom_datawidth;			/* endian-sensitive */
153d41a3cefSpgoyette 	uint8_t rom_voltage;
154d41a3cefSpgoyette 	uint16_t rom_tAA;			/* endian-sensitive */
155d41a3cefSpgoyette 	uint8_t rom_config;
156d41a3cefSpgoyette 	uint8_t	rom_unused1;
157d41a3cefSpgoyette 	uint8_t	rom_tPA;
158d41a3cefSpgoyette 	uint8_t rom_tOE;
159d41a3cefSpgoyette 	uint16_t rom_tCE;			/* endian-sensitive */
160d41a3cefSpgoyette 	uint8_t	rom_burstlength;
161d41a3cefSpgoyette 	uint8_t rom_unused2[14];
162d41a3cefSpgoyette 	uint8_t	rom_superset[31];
163d41a3cefSpgoyette 	uint8_t	rom_cksum;
164d41a3cefSpgoyette } __packed;
165d41a3cefSpgoyette 
166d41a3cefSpgoyette 
167d41a3cefSpgoyette struct spdmem_ddr {				/* Dual Data Rate SDRAM */
16850d1d96aSpgoyette 	uint8_t	ddr_len;
16950d1d96aSpgoyette 	uint8_t ddr_size;
17050d1d96aSpgoyette 	uint8_t ddr_type;
171d41a3cefSpgoyette 	SPD_BITFIELD(				\
172d41a3cefSpgoyette 		uint8_t ddr_rows:4,		\
173d41a3cefSpgoyette 		uint8_t ddr_rows2:4, ,		\
174d41a3cefSpgoyette 	);
175d41a3cefSpgoyette 	SPD_BITFIELD(				\
176d41a3cefSpgoyette 		uint8_t ddr_cols:4,		\
177d41a3cefSpgoyette 		uint8_t ddr_cols2:4, ,		\
178d41a3cefSpgoyette 	);
179d41a3cefSpgoyette 	uint8_t ddr_ranks;
180d41a3cefSpgoyette 	uint16_t ddr_datawidth;			/* endian-sensitive */
181d41a3cefSpgoyette 	uint8_t ddr_voltage;
182d41a3cefSpgoyette 	SPD_BITFIELD(				\
183d41a3cefSpgoyette 		uint8_t ddr_cycle_tenths:4,	\
184d41a3cefSpgoyette 		uint8_t ddr_cycle_whole:4, ,	\
185d41a3cefSpgoyette 	);
186d41a3cefSpgoyette 	SPD_BITFIELD(				\
187d41a3cefSpgoyette 		uint8_t ddr_tAC_hundredths:4,	\
188d41a3cefSpgoyette 		uint8_t	ddr_tAC_tenths:4, ,	\
189d41a3cefSpgoyette 	);
190d41a3cefSpgoyette 	uint8_t ddr_config;
191d41a3cefSpgoyette 	SPD_BITFIELD(				\
192d41a3cefSpgoyette 		uint8_t ddr_refresh:7,		\
193d41a3cefSpgoyette 		uint8_t ddr_selfrefresh:1, ,	\
194d41a3cefSpgoyette 	);
195d41a3cefSpgoyette 	SPD_BITFIELD(				\
196d41a3cefSpgoyette 		uint8_t ddr_dramwidth:7,	\
197d41a3cefSpgoyette 		uint8_t ddr_dram_asym_bank2:1, ,\
198d41a3cefSpgoyette 	);
199d41a3cefSpgoyette 	SPD_BITFIELD(				\
200d41a3cefSpgoyette 		uint8_t ddr_eccwidth:7,		\
201d41a3cefSpgoyette 		uint8_t ddr_ecc_asym_bank2:1, ,	\
202d41a3cefSpgoyette 	);
203d41a3cefSpgoyette 	uint8_t ddr_min_clk_delay;
204d41a3cefSpgoyette 	SPD_BITFIELD(				\
205d41a3cefSpgoyette 		uint8_t ddr_burstlengths:4,	\
206d41a3cefSpgoyette 		uint8_t ddr_unused1:4, ,	\
207d41a3cefSpgoyette 	);
208d41a3cefSpgoyette 	uint8_t ddr_banks_per_chip;
209d41a3cefSpgoyette 	uint8_t ddr_tCAS;
210d41a3cefSpgoyette 	uint8_t ddr_tCS;
211d41a3cefSpgoyette 	uint8_t ddr_tWE;
212d41a3cefSpgoyette 	uint8_t ddr_mod_attrs;
213d41a3cefSpgoyette 	uint8_t ddr_dev_attrs;
214d41a3cefSpgoyette 	uint8_t ddr_min_cc_05;
215d41a3cefSpgoyette 	uint8_t ddr_max_tAC_05;
216d41a3cefSpgoyette 	uint8_t ddr_min_cc_1;
217d41a3cefSpgoyette 	uint8_t ddr_max_tAC_1;
218d41a3cefSpgoyette 	uint8_t ddr_tRP;
219d41a3cefSpgoyette 	uint8_t ddr_tRRD;
220d41a3cefSpgoyette 	uint8_t ddr_tRCD;
221d41a3cefSpgoyette 	uint8_t ddr_tRAS;
222d41a3cefSpgoyette 	uint8_t ddr_module_rank_density;
223d41a3cefSpgoyette 	uint8_t ddr_tIS;
224d41a3cefSpgoyette #define	ddr_superset ddr_tIS
225d41a3cefSpgoyette 	uint8_t ddr_tIH;
226d41a3cefSpgoyette 	uint8_t ddr_tDS;
227d41a3cefSpgoyette 	uint8_t ddr_tDH;
228d41a3cefSpgoyette 	uint8_t	ddr_unused2[5];
229d41a3cefSpgoyette 	uint8_t ddr_tRC;
230d41a3cefSpgoyette 	uint8_t ddr_tRFC;
231d41a3cefSpgoyette 	uint8_t ddr_tCK;
232d41a3cefSpgoyette 	uint8_t	ddr_tDQSQ;
233d41a3cefSpgoyette 	uint8_t	ddr_tQHS;
234d41a3cefSpgoyette 	uint8_t	ddr_unused3;
235d41a3cefSpgoyette 	uint8_t	ddr_height;
236d41a3cefSpgoyette 	uint8_t ddr_unused4[15];
237d41a3cefSpgoyette 	uint8_t	ddr_cksum;
238d41a3cefSpgoyette } __packed;
239d41a3cefSpgoyette 
240d41a3cefSpgoyette struct spdmem_ddr2 {				/* Dual Data Rate 2 SDRAM */
24150d1d96aSpgoyette 	uint8_t	ddr2_len;
24250d1d96aSpgoyette 	uint8_t ddr2_size;
24350d1d96aSpgoyette 	uint8_t ddr2_type;
244d41a3cefSpgoyette 	SPD_BITFIELD(				\
245d41a3cefSpgoyette 		uint8_t ddr2_rows:5,		\
246d41a3cefSpgoyette 		uint8_t ddr2_unused1:3,	,	\
247d41a3cefSpgoyette 	);
248d41a3cefSpgoyette 	SPD_BITFIELD(				\
249d41a3cefSpgoyette 		uint8_t ddr2_cols:4,		\
250d41a3cefSpgoyette 		uint8_t ddr2_unused2:4, ,	\
251d41a3cefSpgoyette 	);
252d41a3cefSpgoyette 	SPD_BITFIELD(				\
253d41a3cefSpgoyette 		uint8_t ddr2_ranks:3,
254d41a3cefSpgoyette 		uint8_t ddr2_cardoncard:1,	\
255d41a3cefSpgoyette 		uint8_t ddr2_package:1,		\
256d41a3cefSpgoyette 		uint8_t ddr2_height:3		\
257d41a3cefSpgoyette 	);
258d41a3cefSpgoyette 	uint8_t ddr2_datawidth;
259d41a3cefSpgoyette 	uint8_t	ddr2_unused3;
260d41a3cefSpgoyette 	uint8_t ddr2_voltage;
261d41a3cefSpgoyette 	SPD_BITFIELD(				\
262d41a3cefSpgoyette 		uint8_t ddr2_cycle_frac:4,	\
263d41a3cefSpgoyette 		uint8_t ddr2_cycle_whole:4, ,	\
264d41a3cefSpgoyette 	);
265d41a3cefSpgoyette 	SPD_BITFIELD(				\
266d41a3cefSpgoyette 		uint8_t ddr2_tAC_hundredths:4,	\
267d41a3cefSpgoyette 		uint8_t	ddr2_tAC_tenths:4, ,	\
268d41a3cefSpgoyette 	);
269d41a3cefSpgoyette 	uint8_t ddr2_config;
270d41a3cefSpgoyette 	SPD_BITFIELD(				\
271d41a3cefSpgoyette 		uint8_t ddr2_refresh:7,		\
272d41a3cefSpgoyette 		uint8_t ddr2_selfrefresh:1, ,	\
273d41a3cefSpgoyette 	);
274d41a3cefSpgoyette 	uint8_t	ddr2_dramwidth;
275d41a3cefSpgoyette 	uint8_t	ddr2_eccwidth;
276d41a3cefSpgoyette 	uint8_t	ddr2_unused4;
277d41a3cefSpgoyette 	SPD_BITFIELD(				\
278d41a3cefSpgoyette 		uint8_t ddr2_burstlengths:4,	\
279d41a3cefSpgoyette 		uint8_t ddr2_unused5:4, ,	\
280d41a3cefSpgoyette 	);
281d41a3cefSpgoyette 	uint8_t ddr2_banks_per_chip;
282d41a3cefSpgoyette 	uint8_t ddr2_tCAS;
283d41a3cefSpgoyette 	uint8_t ddr2_mechanical;
284d41a3cefSpgoyette 	uint8_t	ddr2_dimm_type;
285d41a3cefSpgoyette 	uint8_t ddr2_mod_attrs;
286d41a3cefSpgoyette 	uint8_t ddr2_dev_attrs;
287d41a3cefSpgoyette 	uint8_t ddr2_min_cc_1;
288d41a3cefSpgoyette 	uint8_t ddr2_max_tAC_1;
289d41a3cefSpgoyette 	uint8_t ddr2_min_cc_2;
290d41a3cefSpgoyette 	uint8_t ddr2_max_tAC_2;
291d41a3cefSpgoyette 	uint8_t ddr2_tRP;
292d41a3cefSpgoyette 	uint8_t ddr2_tRRD;
293d41a3cefSpgoyette 	uint8_t ddr2_tRCD;
294d41a3cefSpgoyette 	uint8_t ddr2_tRAS;
295d41a3cefSpgoyette 	uint8_t ddr2_module_rank_density;
296d41a3cefSpgoyette 	uint8_t ddr2_tIS;
297d41a3cefSpgoyette 	uint8_t ddr2_tIH;
298d41a3cefSpgoyette 	uint8_t ddr2_tDS;
299d41a3cefSpgoyette 	uint8_t ddr2_tDH;
300d41a3cefSpgoyette 	uint8_t ddr2_tWR;
301d41a3cefSpgoyette 	uint8_t ddr2_tWTR;
302d41a3cefSpgoyette 	uint8_t ddr2_tRTP;
303d41a3cefSpgoyette 	uint8_t ddr2_probe;
304d41a3cefSpgoyette 	uint8_t	ddr2_extensions;
305d41a3cefSpgoyette 	uint8_t	ddr2_tRC;
306d41a3cefSpgoyette 	uint8_t	ddr2_tRFC;
307d41a3cefSpgoyette 	uint8_t	ddr2_tCK;
308d41a3cefSpgoyette 	uint8_t	ddr2_tDQSQ;
309d41a3cefSpgoyette 	uint8_t	ddr2_tQHS;
310d41a3cefSpgoyette 	uint8_t	ddr2_pll_relock;
311d41a3cefSpgoyette 	uint8_t	ddr2_Tcasemax;
312d41a3cefSpgoyette 	uint8_t	ddr2_Psi_TA_DRAM;
313d41a3cefSpgoyette 	uint8_t	ddr2_dt0;
314d41a3cefSpgoyette 	uint8_t	ddr2_dt2NQ;
315d41a3cefSpgoyette 	uint8_t	ddr2_dr2P;
316d41a3cefSpgoyette 	uint8_t	ddr2_dt3N;
317d41a3cefSpgoyette 	uint8_t	ddr2_dt3Pfast;
318d41a3cefSpgoyette 	uint8_t	ddr2_dt3Pslow;
319d41a3cefSpgoyette 	uint8_t	ddr2_dt4R_4R4W_mode;
320d41a3cefSpgoyette 	uint8_t	ddr2_dt5B;
321d41a3cefSpgoyette 	uint8_t	ddr2_dt7;
322d41a3cefSpgoyette 	uint8_t	ddr2_Psi_TA_PLL;
323d41a3cefSpgoyette 	uint8_t	ddr2_Psi_TA_Reg;
324d41a3cefSpgoyette 	uint8_t	ddr2_dt_PLL_Active;
325d41a3cefSpgoyette 	uint8_t	ddr2_dt_Reg_Active;
326d41a3cefSpgoyette 	uint8_t ddr2_spdrev;
327d41a3cefSpgoyette 	uint8_t	ddr2_cksum;
328d41a3cefSpgoyette } __packed;
329d41a3cefSpgoyette 
330d41a3cefSpgoyette struct spdmem_fbdimm {				/* Fully-buffered DIMM */
33150d1d96aSpgoyette 	uint8_t	fbdimm_len;
33250d1d96aSpgoyette 	uint8_t fbdimm_size;
33350d1d96aSpgoyette 	uint8_t fbdimm_type;
334d41a3cefSpgoyette 	SPD_BITFIELD(				\
335d41a3cefSpgoyette 		uint8_t	fbdimm_ps1_voltage:4,	\
336d41a3cefSpgoyette 		uint8_t	fbdimm_ps2_voltage:4, ,	\
337d41a3cefSpgoyette 	);
338d41a3cefSpgoyette 	SPD_BITFIELD(				\
339d41a3cefSpgoyette 		uint8_t	fbdimm_banks:2,		\
340d41a3cefSpgoyette 		uint8_t	fbdimm_cols:3,		\
341d41a3cefSpgoyette 		uint8_t	fbdimm_rows:3,		\
342d41a3cefSpgoyette 	);
343d41a3cefSpgoyette 	SPD_BITFIELD(				\
344d41a3cefSpgoyette 		uint8_t	fbdimm_thick:3,		\
345d41a3cefSpgoyette 		uint8_t	fbdimm_height:3,	\
346d41a3cefSpgoyette 		uint8_t	fbdimm_unused1:2,	\
347d41a3cefSpgoyette 	);
348d41a3cefSpgoyette 	uint8_t	fbdimm_mod_type;
349d41a3cefSpgoyette 	SPD_BITFIELD(				\
350d41a3cefSpgoyette 		uint8_t	fbdimm_dev_width:3,	\
351d41a3cefSpgoyette 		uint8_t	fbdimm_ranks:3,		\
352d41a3cefSpgoyette 		uint8_t fbdimm_unused2:2,	\
353d41a3cefSpgoyette 	);
354d41a3cefSpgoyette 	SPD_BITFIELD(				\
355d41a3cefSpgoyette 		uint8_t	fbdimm_ftb_divisor:4,	\
35617c75893Smsaitoh 		uint8_t	fbdimm_ftb_dividend:4, ,\
357d41a3cefSpgoyette 	);
358d41a3cefSpgoyette 	uint8_t	fbdimm_mtb_dividend;
359d41a3cefSpgoyette 	uint8_t	fbdimm_mtb_divisor;
360d41a3cefSpgoyette 	uint8_t	fbdimm_tCKmin;
361d41a3cefSpgoyette 	uint8_t	fbdimm_tCKmax;
362d41a3cefSpgoyette 	uint8_t	fbdimm_tCAS;
363d41a3cefSpgoyette 	uint8_t	fbdimm_tAAmin;
364d41a3cefSpgoyette 	SPD_BITFIELD(				\
365d41a3cefSpgoyette 		uint8_t	fbdimm_tWR_min:4,	\
366d41a3cefSpgoyette 		uint8_t	fbdimm_WR_range:4, ,	\
367d41a3cefSpgoyette 	);
368d41a3cefSpgoyette 	uint8_t	fbdimm_tWR;
369d41a3cefSpgoyette 	SPD_BITFIELD(				\
370d41a3cefSpgoyette 		uint8_t	fbdimm_tWL_min:4,	\
371d41a3cefSpgoyette 		uint8_t	fbdimm_tWL_range:4, ,	\
372d41a3cefSpgoyette 	);
373d41a3cefSpgoyette 	SPD_BITFIELD(				\
374d41a3cefSpgoyette 		uint8_t	fbdimm_tAL_min:4,	\
375d41a3cefSpgoyette 		uint8_t	fbdimm_tAL_range:4, ,	\
376d41a3cefSpgoyette 	);
377d41a3cefSpgoyette 	uint8_t	fbdimm_tRCDmin;
378d41a3cefSpgoyette 	uint8_t	fbdimm_tRRDmin;
379d41a3cefSpgoyette 	uint8_t	fbdimm_tRPmin;
380d41a3cefSpgoyette 	SPD_BITFIELD(				\
381d41a3cefSpgoyette 		uint8_t	fbdimm_tRAS_msb:4,	\
382d41a3cefSpgoyette 		uint8_t	fbdimm_tRC_msb:4, ,	\
383d41a3cefSpgoyette 	);
384d41a3cefSpgoyette 	uint8_t	fbdimm_tRAS_lsb;
385d41a3cefSpgoyette 	uint8_t	fbdimm_tRC_lsb;
386d41a3cefSpgoyette 	uint16_t fbdimm_tRFC;			/* endian-sensitive */
387d41a3cefSpgoyette 	uint8_t	fbdimm_tWTR;
388d41a3cefSpgoyette 	uint8_t	fbdimm_tRTP;
389d41a3cefSpgoyette 	SPD_BITFIELD(				\
390d41a3cefSpgoyette 		uint8_t	fbdimm_burst_4:1,	\
391d41a3cefSpgoyette 		uint8_t	fbdimm_burst_8:1,	\
392d41a3cefSpgoyette 		uint8_t	fbdimm_unused3:6,	\
393d41a3cefSpgoyette 	);
394d41a3cefSpgoyette 	uint8_t	fbdimm_terms;
395d41a3cefSpgoyette 	uint8_t	fbdimm_drivers;
396d41a3cefSpgoyette 	uint8_t	fbdimm_tREFI;
397d41a3cefSpgoyette 	uint8_t	fbdimm_Tcasemax;
398d41a3cefSpgoyette 	uint8_t	fbdimm_Psi_TA_SDRAM;
399d41a3cefSpgoyette 	uint8_t	fbdimm_DT0;
400d41a3cefSpgoyette 	uint8_t	fbdimm_DT2N_DT2Q;
401d41a3cefSpgoyette 	uint8_t	fbdimm_DT2P;
402d41a3cefSpgoyette 	uint8_t	fbdimm_DT3N;
403d41a3cefSpgoyette 	uint8_t	fbdimm_DT4R_DT4R4W;
404d41a3cefSpgoyette 	uint8_t	fbdimm_DT5B;
405d41a3cefSpgoyette 	uint8_t	fbdimm_DT7;
406d41a3cefSpgoyette 	uint8_t	fbdimm_unused4[84];
407d41a3cefSpgoyette 	uint16_t fbdimm_crc;
408d41a3cefSpgoyette } __packed;
409d41a3cefSpgoyette 
410d41a3cefSpgoyette struct spdmem_rambus {				/* Direct Rambus DRAM */
41150d1d96aSpgoyette 	uint8_t	rdr_len;
41250d1d96aSpgoyette 	uint8_t rdr_size;
41350d1d96aSpgoyette 	uint8_t rdr_type;
414d41a3cefSpgoyette 	SPD_BITFIELD(				\
415d41a3cefSpgoyette 		uint8_t	rdr_rows:4,		\
416d41a3cefSpgoyette 		uint8_t	rdr_cols:4, ,		\
417d41a3cefSpgoyette 	);
418d41a3cefSpgoyette } __packed;
419d41a3cefSpgoyette 
420d41a3cefSpgoyette struct spdmem_ddr3 {				/* Dual Data Rate 3 SDRAM */
4215e0f0bcdSmsaitoh 	SPD_BITFIELD(				\
4225e0f0bcdSmsaitoh 		uint8_t	ddr3_ROM_used:4,	\
4235e0f0bcdSmsaitoh 		uint8_t	ddr3_ROM_size:3,	\
4245e0f0bcdSmsaitoh 		uint8_t	ddr3_crccover:1,	\
4255e0f0bcdSmsaitoh 	);
4265e0f0bcdSmsaitoh 	uint8_t	ddr3_romrev;
42750d1d96aSpgoyette 	uint8_t ddr3_type;
428d41a3cefSpgoyette 	uint8_t	ddr3_mod_type;
429d41a3cefSpgoyette 	SPD_BITFIELD(				\
430d41a3cefSpgoyette 		/* chipsize is offset by 28: 0 = 256M, 1 = 512M, ... */ \
431d41a3cefSpgoyette 		uint8_t ddr3_chipsize:4,	\
432d41a3cefSpgoyette 		/* logbanks is offset by 3 */	\
433d41a3cefSpgoyette 		uint8_t ddr3_logbanks:3,	\
434d41a3cefSpgoyette 		uint8_t ddr3_unused1:1,		\
435d41a3cefSpgoyette 	);
436d41a3cefSpgoyette 	/* cols is offset by 9, rows offset by 12 */
437d41a3cefSpgoyette 	SPD_BITFIELD(				\
438d41a3cefSpgoyette 		uint8_t ddr3_cols:3,		\
439d41a3cefSpgoyette 		uint8_t ddr3_rows:5, ,		\
440d41a3cefSpgoyette 	);
441d41a3cefSpgoyette 	SPD_BITFIELD(				\
442d41a3cefSpgoyette 		uint8_t ddr3_NOT15V:1,		\
443d41a3cefSpgoyette 		uint8_t ddr3_135V:1,		\
444d35fd4d2Smsaitoh 		uint8_t ddr3_125V:1,		\
445d41a3cefSpgoyette 		uint8_t	ddr3_unused2:5		\
446d41a3cefSpgoyette 	);
447d41a3cefSpgoyette 	/* chipwidth in bits offset by 2: 0 = X4, 1 = X8, 2 = X16 */
448d41a3cefSpgoyette 	/* physbanks is offset by 1 */
449d41a3cefSpgoyette 	SPD_BITFIELD(				\
450d41a3cefSpgoyette 		uint8_t ddr3_chipwidth:3,	\
451d41a3cefSpgoyette 		uint8_t ddr3_physbanks:5, ,	\
452d41a3cefSpgoyette 	);
453d41a3cefSpgoyette 	/* datawidth in bits offset by 3: 1 = 16b, 2 = 32b, 3 = 64b */
454d41a3cefSpgoyette 	SPD_BITFIELD(				\
455d41a3cefSpgoyette 		uint8_t ddr3_datawidth:3,	\
456d41a3cefSpgoyette 		uint8_t ddr3_hasECC:2,		\
457d41a3cefSpgoyette 		uint8_t ddr3_unused2a:3 ,	\
458d41a3cefSpgoyette 	);
459d41a3cefSpgoyette 	/* Fine time base, in pico-seconds */
460d41a3cefSpgoyette 	SPD_BITFIELD(				\
461d41a3cefSpgoyette 		uint8_t ddr3_ftb_divisor:4,	\
462d41a3cefSpgoyette 		uint8_t ddr3_ftb_dividend:4, ,	\
463d41a3cefSpgoyette 	);
464d41a3cefSpgoyette 	uint8_t ddr3_mtb_dividend;	/* 0x0108 = 0.1250ns */
465d41a3cefSpgoyette 	uint8_t	ddr3_mtb_divisor;	/* 0x010f = 0.0625ns */
466f2e2af51Smsaitoh 	uint8_t	ddr3_tCKmin_mtb;
467d41a3cefSpgoyette 	uint8_t	ddr3_unused3;
468d41a3cefSpgoyette 	uint16_t ddr3_CAS_sup;		/* Bit 0 ==> CAS 4 cycles */
469f2e2af51Smsaitoh 	uint8_t	ddr3_tAAmin_mtb;
470d41a3cefSpgoyette 	uint8_t	ddr3_tWRmin;
471f2e2af51Smsaitoh 	uint8_t	ddr3_tRCDmin_mtb;
472d41a3cefSpgoyette 	uint8_t	ddr3_tRRDmin;
473f2e2af51Smsaitoh 	uint8_t	ddr3_tRPmin_mtb;
474d41a3cefSpgoyette 	SPD_BITFIELD(				\
475d41a3cefSpgoyette 		uint8_t	ddr3_tRAS_msb:4,	\
476f2e2af51Smsaitoh 		uint8_t	ddr3_tRCmin_mtb_msb:4, , \
477d41a3cefSpgoyette 	);
478d41a3cefSpgoyette 	uint8_t	ddr3_tRAS_lsb;
479f2e2af51Smsaitoh 	uint8_t	ddr3_tRCmin_mtb_lsb;
480d41a3cefSpgoyette 	uint8_t	ddr3_tRFCmin_lsb;
481d41a3cefSpgoyette 	uint8_t	ddr3_tRFCmin_msb;
482d41a3cefSpgoyette 	uint8_t	ddr3_tWTRmin;
483d41a3cefSpgoyette 	uint8_t	ddr3_tRTPmin;
484d41a3cefSpgoyette 	SPD_BITFIELD(				\
485d41a3cefSpgoyette 		uint8_t	ddr3_tFAW_msb:4, , ,	\
486d41a3cefSpgoyette 	);
487d41a3cefSpgoyette 	uint8_t	ddr3_tFAW_lsb;
488d41a3cefSpgoyette 	uint8_t	ddr3_output_drvrs;
489d41a3cefSpgoyette 	SPD_BITFIELD(				\
490d41a3cefSpgoyette 		uint8_t	ddr3_ext_temp_range:1,	\
491d41a3cefSpgoyette 		uint8_t	ddr3_ext_temp_2x_refresh:1, \
492d41a3cefSpgoyette 		uint8_t	ddr3_asr_refresh:1,	\
493d41a3cefSpgoyette 		/* Bit 4 indicates on-die thermal sensor */
494d41a3cefSpgoyette 		/* Bit 7 indicates Partial-Array Self-Refresh (PASR) */
495d41a3cefSpgoyette 		uint8_t	ddr3_unused7:5		\
496d41a3cefSpgoyette 	);
497d41a3cefSpgoyette 	SPD_BITFIELD(				\
498d41a3cefSpgoyette 		uint8_t ddr3_therm_sensor_acc:7,\
499d41a3cefSpgoyette 		uint8_t ddr3_has_therm_sensor:1, , \
500d41a3cefSpgoyette 	);
501d41a3cefSpgoyette 	SPD_BITFIELD(				\
502d41a3cefSpgoyette 		uint8_t ddr3_non_std_devtype:7,	\
503d41a3cefSpgoyette 		uint8_t ddr3_std_device:1, ,	\
504d41a3cefSpgoyette 	);
505f2e2af51Smsaitoh 	uint8_t ddr3_tCKmin_ftb;
506f2e2af51Smsaitoh 	uint8_t ddr3_tAAmin_ftb;
507f2e2af51Smsaitoh 	uint8_t ddr3_tRCDmin_ftb;
508f2e2af51Smsaitoh 	uint8_t ddr3_tRPmin_ftb;
509f2e2af51Smsaitoh 	uint8_t ddr3_tRCmin_ftb;
510f2e2af51Smsaitoh 	uint8_t	ddr3_unused4[2];
511f2e2af51Smsaitoh 	uint8_t	ddr3_MAC;
512*2744d7eeSmsaitoh 	uint8_t	ddr3_unused4a[18];
513d41a3cefSpgoyette 	uint8_t	ddr3_mod_height;
514d41a3cefSpgoyette 	uint8_t	ddr3_mod_thickness;
515d41a3cefSpgoyette 	uint8_t	ddr3_ref_card;
516d41a3cefSpgoyette 	uint8_t	ddr3_mapping;
517d41a3cefSpgoyette 	uint8_t	ddr3_unused5[53];
518d41a3cefSpgoyette 	uint8_t	ddr3_mfgID_lsb;
519d41a3cefSpgoyette 	uint8_t	ddr3_mfgID_msb;
520d41a3cefSpgoyette 	uint8_t	ddr3_mfgloc;
521d41a3cefSpgoyette 	uint8_t	ddr3_mfg_year;
522d41a3cefSpgoyette 	uint8_t	ddr3_mfg_week;
523d41a3cefSpgoyette 	uint8_t	ddr3_serial[4];
524d41a3cefSpgoyette 	uint16_t ddr3_crc;
5254da9f6ddSsoren 	uint8_t ddr3_part[18];
5264da9f6ddSsoren 	uint8_t ddr3_rev[2];
5274da9f6ddSsoren 	uint8_t	ddr3_dram_mfgID_lsb;
5284da9f6ddSsoren 	uint8_t	ddr3_dram_mfgID_msb;
5294da9f6ddSsoren 	uint8_t ddr3_vendor[26];
530d41a3cefSpgoyette } __packed;
531d41a3cefSpgoyette 
53250d1d96aSpgoyette /* DDR4 info from JEDEC Standard No. 21-C, Annex L - 4.1.2.12 */
53350d1d96aSpgoyette 
53450d1d96aSpgoyette /* Module-type specific bytes - bytes 0x080 thru 0x0ff */
53550d1d96aSpgoyette 
53650d1d96aSpgoyette struct spdmem_ddr4_mod_unbuffered {
53750d1d96aSpgoyette 	SPD_BITFIELD(					\
53850d1d96aSpgoyette 		uint8_t	ddr4_unbuf_mod_height:4,	\
53950d1d96aSpgoyette 		uint8_t ddr4_unbuf_card_ext:4, ,	\
54050d1d96aSpgoyette 	);
54150d1d96aSpgoyette 	SPD_BITFIELD(					\
54250d1d96aSpgoyette 		uint8_t	ddr4_unbuf_max_thick_front:4,	\
54350d1d96aSpgoyette 		uint8_t	ddr4_unbuf_max_thick_back:4, ,	\
54450d1d96aSpgoyette 	);
54550d1d96aSpgoyette 	SPD_BITFIELD(					\
54650d1d96aSpgoyette 		uint8_t	ddr4_unbuf_refcard:5,		\
54750d1d96aSpgoyette 		uint8_t	ddr4_unbuf_refcard_rev:2,	\
54850d1d96aSpgoyette 		uint8_t	ddr4_unbuf_refcard_ext:1,	\
54950d1d96aSpgoyette 	);
55050d1d96aSpgoyette 	SPD_BITFIELD(					\
55150d1d96aSpgoyette 		uint8_t	ddr4_unbuf_mirror_mapping:1,	\
55250d1d96aSpgoyette 		uint8_t	ddr4_unbuf_unused1:7, ,		\
55350d1d96aSpgoyette 	);
55450d1d96aSpgoyette 	uint8_t	ddr4_unbuf_unused2[122];
55550d1d96aSpgoyette 	uint8_t	ddr4_unbuf_crc[2];
55650d1d96aSpgoyette } __packed;
55750d1d96aSpgoyette 
55850d1d96aSpgoyette struct spdmem_ddr4_mod_registered {
55950d1d96aSpgoyette 	SPD_BITFIELD(					\
56050d1d96aSpgoyette 		uint8_t	ddr4_reg_mod_height:4,	\
56150d1d96aSpgoyette 		uint8_t ddr4_reg_card_ext:4, ,	\
56250d1d96aSpgoyette 	);
56350d1d96aSpgoyette 	SPD_BITFIELD(					\
56450d1d96aSpgoyette 		uint8_t	ddr4_reg_max_thick_front:4,	\
56550d1d96aSpgoyette 		uint8_t	ddr4_reg_max_thick_back:4, ,	\
56650d1d96aSpgoyette 	);
56750d1d96aSpgoyette 	SPD_BITFIELD(					\
56850d1d96aSpgoyette 		uint8_t	ddr4_reg_refcard:5,		\
56950d1d96aSpgoyette 		uint8_t	ddr4_reg_refcard_rev:2,	\
57050d1d96aSpgoyette 		uint8_t	ddr4_reg_refcard_ext:1,	\
57150d1d96aSpgoyette 	);
57250d1d96aSpgoyette 	SPD_BITFIELD(					\
57350d1d96aSpgoyette 		uint8_t	ddr4_reg_regcnt:2,		\
57450d1d96aSpgoyette 		uint8_t	ddr4_reg_dram_rows:2,		\
57550d1d96aSpgoyette 		uint8_t	ddr4_reg_unused1:4,		\
57650d1d96aSpgoyette 	);
57750d1d96aSpgoyette 	SPD_BITFIELD(					\
57850d1d96aSpgoyette 		uint8_t	ddr4_reg_heat_spread_char:7,	\
57950d1d96aSpgoyette 		uint8_t	ddr4_reg_heat_spread_exist:1, ,	\
58050d1d96aSpgoyette 	);
58150d1d96aSpgoyette 	uint8_t	ddr4_reg_mfg_id_lsb;
58250d1d96aSpgoyette 	uint8_t	ddr4_reg_mfg_id_msb;
58350d1d96aSpgoyette 	uint8_t	ddr4_reg_revision;
58450d1d96aSpgoyette 	SPD_BITFIELD(					\
58550d1d96aSpgoyette 		uint8_t	ddr4_reg_mirror_mapping:1,	\
58650d1d96aSpgoyette 		uint8_t	ddr4_reg_unused2:7, ,		\
58750d1d96aSpgoyette 	);
58850d1d96aSpgoyette 	SPD_BITFIELD(					\
58950d1d96aSpgoyette 		uint8_t	ddr4_reg_output_drive_CKE:2,	\
59050d1d96aSpgoyette 		uint8_t	ddr4_reg_output_drive_ODT:2,	\
59150d1d96aSpgoyette 		uint8_t	ddr4_reg_output_drive_CmdAddr:2,\
59250d1d96aSpgoyette 		uint8_t	ddr4_reg_output_drive_chipsel:2	\
59350d1d96aSpgoyette 	);
59450d1d96aSpgoyette 	SPD_BITFIELD(					\
59550d1d96aSpgoyette 		uint8_t	ddr4_reg_output_drive_CK_Y0Y2:2,\
59650d1d96aSpgoyette 		uint8_t	ddr4_reg_output_drive_CK_Y1Y3:2,\
59750d1d96aSpgoyette 		uint8_t	ddr4_reg_unused3:4,		\
59850d1d96aSpgoyette 	);
59950d1d96aSpgoyette 	uint8_t	ddr4_reg_unused4[115];
60050d1d96aSpgoyette 	uint8_t	ddr4_reg_crc[2];
60150d1d96aSpgoyette } __packed;
60250d1d96aSpgoyette 
60350d1d96aSpgoyette struct spdmem_ddr4_mod_reduced_load {
60450d1d96aSpgoyette 	SPD_BITFIELD(					\
60550d1d96aSpgoyette 		uint8_t	ddr4_rload_mod_height:4,	\
60650d1d96aSpgoyette 		uint8_t ddr4_rload_card_ext:4, ,	\
60750d1d96aSpgoyette 	);
60850d1d96aSpgoyette 	SPD_BITFIELD(					\
60950d1d96aSpgoyette 		uint8_t	ddr4_rload_max_thick_front:4,	\
61050d1d96aSpgoyette 		uint8_t	ddr4_rload_max_thick_back:4, ,	\
61150d1d96aSpgoyette 	);
61250d1d96aSpgoyette 	SPD_BITFIELD(					\
61350d1d96aSpgoyette 		uint8_t	ddr4_rload_refcard:5,		\
61450d1d96aSpgoyette 		uint8_t	ddr4_rload_refcard_rev:2,	\
61550d1d96aSpgoyette 		uint8_t	ddr4_rload_refcard_ext:1,	\
61650d1d96aSpgoyette 	);
61750d1d96aSpgoyette 	SPD_BITFIELD(					\
61850d1d96aSpgoyette 		uint8_t	ddr4_rload_regcnt:2,		\
61950d1d96aSpgoyette 		uint8_t	ddr4_rload_dram_rows:2,		\
62050d1d96aSpgoyette 		uint8_t	ddr4_rload_unused1:4,		\
62150d1d96aSpgoyette 	);
62250d1d96aSpgoyette 	SPD_BITFIELD(					\
62350d1d96aSpgoyette 		uint8_t	ddr4_rload_unused2:7,		\
62450d1d96aSpgoyette 		uint8_t	ddr4_rload_heat_spread_exist:1, , \
62550d1d96aSpgoyette 	);
62650d1d96aSpgoyette 	uint8_t	ddr4_rload_reg_mfg_id_lsb;
62750d1d96aSpgoyette 	uint8_t	ddr4_rload_reg_mfg_id_msb;
62850d1d96aSpgoyette 	uint8_t	ddr4_rload_reg_revision;
62950d1d96aSpgoyette 	SPD_BITFIELD(					\
63050d1d96aSpgoyette 		uint8_t	ddr4_rload_reg_mirror_mapping:1,\
63150d1d96aSpgoyette 		uint8_t	ddr4_rload_unused3:7, ,		\
63250d1d96aSpgoyette 	);
63350d1d96aSpgoyette 	SPD_BITFIELD(					\
63450d1d96aSpgoyette 		uint8_t	ddr4_rload_output_drive_CKE:2,	\
63550d1d96aSpgoyette 		uint8_t	ddr4_rload_output_drive_ODT:2,	\
63650d1d96aSpgoyette 		uint8_t	ddr4_rload_output_drive_CmdAddr:2, \
63750d1d96aSpgoyette 		uint8_t	ddr4_rload_output_drive_chipsel:2  \
63850d1d96aSpgoyette 	);
63950d1d96aSpgoyette 	SPD_BITFIELD(					\
64050d1d96aSpgoyette 		uint8_t	ddr4_rload_output_drive_CK_Y0Y2:2, \
64150d1d96aSpgoyette 		uint8_t	ddr4_rload_output_drive_CK_Y1Y3:2, \
64250d1d96aSpgoyette 		uint8_t	ddr4_rload_unused4:4,		\
64350d1d96aSpgoyette 	);
64450d1d96aSpgoyette 	uint8_t	ddr4_rload_dbuff_revision;
64550d1d96aSpgoyette 	SPD_BITFIELD(					\
64650d1d96aSpgoyette 		uint8_t	ddr4_rload_VrefDQ_0:6,		\
64750d1d96aSpgoyette 		uint8_t	ddr4_rload_unused5:2, ,		\
64850d1d96aSpgoyette 	);
64950d1d96aSpgoyette 	SPD_BITFIELD(					\
65050d1d96aSpgoyette 		uint8_t	ddr4_rload_VrefDQ_1:6,		\
65150d1d96aSpgoyette 		uint8_t	ddr4_rload_unused6:2, ,		\
65250d1d96aSpgoyette 	);
65350d1d96aSpgoyette 	SPD_BITFIELD(					\
65450d1d96aSpgoyette 		uint8_t	ddr4_rload_VrefDQ_2:6,		\
65550d1d96aSpgoyette 		uint8_t	ddr4_rload_unused7:2, ,		\
65650d1d96aSpgoyette 	);
65750d1d96aSpgoyette 	SPD_BITFIELD(					\
65850d1d96aSpgoyette 		uint8_t	ddr4_rload_VrefDQ_3:6,		\
65950d1d96aSpgoyette 		uint8_t	ddr4_rload_unused8:2, ,		\
66050d1d96aSpgoyette 	);
66150d1d96aSpgoyette 	SPD_BITFIELD(					\
66250d1d96aSpgoyette 		uint8_t	ddr4_rload_VrefDQ_buffer:6,	\
66350d1d96aSpgoyette 		uint8_t	ddr4_rload_unused9:2, ,		\
66450d1d96aSpgoyette 	);
66550d1d96aSpgoyette 	SPD_BITFIELD(						\
66650d1d96aSpgoyette 		uint8_t	ddr4_rload_MDQ_Read_Term_Str_1866:3,	\
66750d1d96aSpgoyette 		uint8_t	ddr4_rload_unused10:1,			\
66850d1d96aSpgoyette 		uint8_t	ddr4_rload_MDQ_Drive_Str_1866:3,	\
66950d1d96aSpgoyette 		uint8_t	ddr4_rload_unused11:1			\
67050d1d96aSpgoyette 	);
67150d1d96aSpgoyette 	SPD_BITFIELD(						\
67250d1d96aSpgoyette 		uint8_t	ddr4_rload_MDQ_Read_Term_Str_2400:3,	\
67350d1d96aSpgoyette 		uint8_t	ddr4_rload_unused12:1,			\
67450d1d96aSpgoyette 		uint8_t	ddr4_rload_MDQ_Drive_Str_2400:3,	\
67550d1d96aSpgoyette 		uint8_t	ddr4_rload_unused13:1			\
67650d1d96aSpgoyette 	);
67750d1d96aSpgoyette 	SPD_BITFIELD(						\
67850d1d96aSpgoyette 		uint8_t	ddr4_rload_MDQ_Read_Term_Str_3200:3,	\
67950d1d96aSpgoyette 		uint8_t	ddr4_rload_unused14:1,			\
68050d1d96aSpgoyette 		uint8_t	ddr4_rload_MDQ_Drive_Str_3200:3,	\
68150d1d96aSpgoyette 		uint8_t	ddr4_rload_unused15:1			\
68250d1d96aSpgoyette 	);
68350d1d96aSpgoyette 	SPD_BITFIELD(						\
68450d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_Drive_Str_1866:2,	\
68550d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_Drive_Str_2400:2,	\
68650d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_Drive_Str_3200:2,	\
68750d1d96aSpgoyette 		uint8_t	ddr4_rload_unused16:2			\
68850d1d96aSpgoyette 	);
68950d1d96aSpgoyette 	SPD_BITFIELD(						\
69050d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_NOM_1866:3,	\
69150d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_WR_1866:3,	\
69250d1d96aSpgoyette 		uint8_t	ddr4_rload_unused17:2,			\
69350d1d96aSpgoyette 	);
69450d1d96aSpgoyette 	SPD_BITFIELD(						\
69550d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_NOM_2400:3,	\
69650d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_WR_2400:3,	\
69750d1d96aSpgoyette 		uint8_t	ddr4_rload_unused18:2,			\
69850d1d96aSpgoyette 	);
69950d1d96aSpgoyette 	SPD_BITFIELD(						\
70050d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_NOM_3200:3,	\
70150d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_WR_3200:3,	\
70250d1d96aSpgoyette 		uint8_t	ddr4_rload_unused19:2,			\
70350d1d96aSpgoyette 	);
70450d1d96aSpgoyette 	SPD_BITFIELD(						\
70550d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_PARK_01_1866:3,	\
70650d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_PARK_23_1866:3,	\
70750d1d96aSpgoyette 		uint8_t	ddr4_rload_unused20:2,			\
70850d1d96aSpgoyette 	);
70950d1d96aSpgoyette 	SPD_BITFIELD(						\
71050d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_PARK_01_2400:3,	\
71150d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_PARK_23_2400:3,	\
71250d1d96aSpgoyette 		uint8_t	ddr4_rload_unused21:2,			\
71350d1d96aSpgoyette 	);
71450d1d96aSpgoyette 	SPD_BITFIELD(						\
71550d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_PARK_01_3200:3,	\
71650d1d96aSpgoyette 		uint8_t	ddr4_rload_DRAM_ODT_RTT_PARK_23_3200:3,	\
71750d1d96aSpgoyette 		uint8_t	ddr4_rload_unused22:2,			\
71850d1d96aSpgoyette 	);
71950d1d96aSpgoyette 	uint8_t	ddr4_rload_unused23[99];
72050d1d96aSpgoyette 	uint8_t	ddr4_rload_crc[2];
72150d1d96aSpgoyette } __packed;
72250d1d96aSpgoyette 
72350d1d96aSpgoyette struct spdmem_ddr4 {				/* Dual Data Rate 4 SDRAM */
72450d1d96aSpgoyette 	SPD_BITFIELD(				\
72550d1d96aSpgoyette 		uint8_t	ddr4_ROM_used:4,	\
72650d1d96aSpgoyette 		uint8_t	ddr4_ROM_size:3,	\
72750d1d96aSpgoyette 		uint8_t	ddr4_unused0:1,		\
72850d1d96aSpgoyette 	);
72950d1d96aSpgoyette 	uint8_t	ddr4_romrev;
73050d1d96aSpgoyette 	uint8_t	ddr4_type;
73150d1d96aSpgoyette 	SPD_BITFIELD(				\
73250d1d96aSpgoyette 		uint8_t	ddr4_mod_type:4,	\
73319d53e8dSmsaitoh 		uint8_t	ddr4_hybrid_media:3,	\
73419d53e8dSmsaitoh 		uint8_t	ddr4_hybrid:1,		\
73550d1d96aSpgoyette 	);
73650d1d96aSpgoyette 	SPD_BITFIELD(				\
73750d1d96aSpgoyette 		/* capacity is offset by 28: 0 = 256M, 1 = 512M, ... */ \
73850d1d96aSpgoyette 		uint8_t	ddr4_capacity:4,	\
73950d1d96aSpgoyette 		/* logbanks is offset by 2 */	\
74050d1d96aSpgoyette 		uint8_t	ddr4_logbanks:2,	\
74150d1d96aSpgoyette 		/* bankgroups is offset by 0 */
74250d1d96aSpgoyette 		uint8_t	ddr4_bankgroups:2,	\
74350d1d96aSpgoyette 	);
74450d1d96aSpgoyette 	/* cols is offset by 9, rows offset by 12 */
74550d1d96aSpgoyette 	SPD_BITFIELD(				\
74650d1d96aSpgoyette 		uint8_t	ddr4_cols:3,		\
74750d1d96aSpgoyette 		uint8_t	ddr4_rows:3,		\
74850d1d96aSpgoyette 		uint8_t	ddr4_unused2:2,		\
74950d1d96aSpgoyette 	);
75050d1d96aSpgoyette 	SPD_BITFIELD(				\
75150d1d96aSpgoyette 		uint8_t	ddr4_signal_loading:2,	\
75250d1d96aSpgoyette 		uint8_t	ddr4_unused3:2,		\
75350d1d96aSpgoyette 		uint8_t	ddr4_diecount:3,	\
75450d1d96aSpgoyette 		uint8_t	ddr4_non_monolithic:1	\
75550d1d96aSpgoyette 	);
75650d1d96aSpgoyette 	SPD_BITFIELD(				\
75750d1d96aSpgoyette 		uint8_t ddr4_max_activate_count:4,	\
75850d1d96aSpgoyette 		uint8_t ddr4_max_activate_window:2,	\
75950d1d96aSpgoyette 		uint8_t ddr4_unused4:2,	\
76050d1d96aSpgoyette 	);
76150d1d96aSpgoyette 	uint8_t	ddr4_unused5;		/* SDRAM Thermal & Refresh Options */
76250d1d96aSpgoyette 	SPD_BITFIELD(				\
76350d1d96aSpgoyette 		uint8_t ddr4_unused6:6,		\
76450d1d96aSpgoyette 		uint8_t ddr4_ppr_support:2, ,	/* post package repair */ \
76550d1d96aSpgoyette 	);
76650d1d96aSpgoyette 	uint8_t ddr4_unused7;
76750d1d96aSpgoyette 	SPD_BITFIELD(				\
76850d1d96aSpgoyette 		uint8_t	ddr4_dram_vdd_12:2,	\
76950d1d96aSpgoyette 		uint8_t	ddr4_dram_vdd_tbd1:2,	\
77050d1d96aSpgoyette 		uint8_t	ddr4_dram_vdd_tbd2:2,	\
77150d1d96aSpgoyette 		uint8_t	ddr4_unused8:2		\
77250d1d96aSpgoyette 	);
77350d1d96aSpgoyette 	SPD_BITFIELD(				\
77450d1d96aSpgoyette 		/* device width is 0=4, 1=8, 2=16, or 4=32 bits */ \
77550d1d96aSpgoyette 		uint8_t	ddr4_device_width:3,	\
77650d1d96aSpgoyette 		/* number of package ranks is field value plus 1 */ \
77750d1d96aSpgoyette 		uint8_t	ddr4_package_ranks:3,	\
778e95ac17fSmsaitoh 		uint8_t	ddr4_rank_mix:1,	\
779e95ac17fSmsaitoh 		uint8_t	ddr4_unused9:1		\
78050d1d96aSpgoyette 	);
78150d1d96aSpgoyette 	SPD_BITFIELD(					\
78250d1d96aSpgoyette 		/* primary width is offset by 3, extension is offset by 2 */ \
78350d1d96aSpgoyette 		uint8_t	ddr4_primary_bus_width:3,	\
78450d1d96aSpgoyette 		uint8_t	ddr4_bus_width_extension:2,	\
78550d1d96aSpgoyette 		uint8_t	ddr4_unused10:3,		\
78650d1d96aSpgoyette 	);
78750d1d96aSpgoyette 	SPD_BITFIELD(				\
78850d1d96aSpgoyette 		uint8_t ddr4_unused11:7,	\
78950d1d96aSpgoyette 		uint8_t ddr4_has_therm_sensor:1, , \
79050d1d96aSpgoyette 	);
79150d1d96aSpgoyette 	SPD_BITFIELD(				\
79250d1d96aSpgoyette 		uint8_t ddr4_ext_mod_type:4,	\
79350d1d96aSpgoyette 		uint8_t ddr4_unused12:4, ,	\
79450d1d96aSpgoyette 	);
79550d1d96aSpgoyette 	uint8_t	ddr4_unused13;
79650d1d96aSpgoyette 	SPD_BITFIELD(				\
79750d1d96aSpgoyette 		/* units = 1ps (10**-12sec) */	\
79850d1d96aSpgoyette 		uint8_t	ddr4_fine_timebase:2,	\
79950d1d96aSpgoyette 		/* units = 125ps	    */	\
80050d1d96aSpgoyette 		uint8_t	ddr4_medium_timebase:2, ,	\
80150d1d96aSpgoyette 	);
80250d1d96aSpgoyette 	uint8_t	ddr4_tCKAVGmin_mtb;
80350d1d96aSpgoyette 	uint8_t	ddr4_tCKAVGmax_mtb;
80450d1d96aSpgoyette 	/* Bit 0 of CAS_supported[0 corresponds to CL=7 */
80550d1d96aSpgoyette 	uint8_t	ddr4_CAS_supported[4];
80650d1d96aSpgoyette 	uint8_t	ddr4_tAAmin_mtb;
80750d1d96aSpgoyette 	uint8_t	ddr4_tRCDmin_mtb;
80850d1d96aSpgoyette 	uint8_t	ddr4_tRPmin_mtb;
80950d1d96aSpgoyette 	SPD_BITFIELD(				\
81050d1d96aSpgoyette 		uint8_t	ddr4_tRASmin_msb:4,	\
81150d1d96aSpgoyette 		uint8_t	ddr4_tRCmin_mtb_msb:4, ,	\
81250d1d96aSpgoyette 	);
81350d1d96aSpgoyette 	uint8_t	ddr4_tRASmin_lsb;
81450d1d96aSpgoyette 	uint8_t	ddr4_tRCmin_mtb_lsb;
81550d1d96aSpgoyette 	uint8_t	ddr4_tRFC1min_lsb;
81650d1d96aSpgoyette 	uint8_t	ddr4_tRFC1min_msb;
81750d1d96aSpgoyette 	uint8_t	ddr4_tRFC2min_lsb;
81850d1d96aSpgoyette 	uint8_t	ddr4_tRFC2min_msb;
81950d1d96aSpgoyette 	uint8_t	ddr4_tRFC4min_lsb;
82050d1d96aSpgoyette 	uint8_t	ddr4_tRFC4min_msb;
82150d1d96aSpgoyette 	SPD_BITFIELD(				\
822c52f0d42Smsaitoh 		uint8_t	ddr4_tFAW_mtb_msb:4,	\
823c52f0d42Smsaitoh 		uint8_t	ddr4_unused14:4, ,	\
82450d1d96aSpgoyette 	);
82550d1d96aSpgoyette 	uint8_t	ddr4_tFAWmin_mtb_lsb;
82650d1d96aSpgoyette 	uint8_t	ddr4_tRRD_Smin_mtb;
82750d1d96aSpgoyette 	uint8_t	ddr4_tRRD_Lmin_mtb;
82850d1d96aSpgoyette 	uint8_t	ddr4_tCCD_Lmin_mtb;
82919d53e8dSmsaitoh 	uint8_t	ddr4_tWR_min_msb;
83019d53e8dSmsaitoh 	uint8_t	ddr4_tWR_min_mtb;
83119d53e8dSmsaitoh 	uint8_t	ddr4_tWTR_min;
83219d53e8dSmsaitoh 	uint8_t	ddr4_tWTR_Smin_mtb;
83319d53e8dSmsaitoh 	uint8_t	ddr4_tWTR_Lmin_mtb;
83419d53e8dSmsaitoh 	uint8_t	ddr4_unused15[14];
83550d1d96aSpgoyette 	uint8_t	ddr4_connector_map[18];
83650d1d96aSpgoyette 	uint8_t	ddr4_unused16[39];
83750d1d96aSpgoyette 	uint8_t	ddr4_tCCD_Lmin_ftb;
83850d1d96aSpgoyette 	uint8_t	ddr4_tRRD_Lmin_ftb;
83950d1d96aSpgoyette 	uint8_t	ddr4_tRRD_Smin_ftb;
84050d1d96aSpgoyette 	uint8_t	ddr4_tRCmin_ftb;
84150d1d96aSpgoyette 	uint8_t	ddr4_tRPmin_ftb;
84250d1d96aSpgoyette 	uint8_t	ddr4_tRCDmin_ftb;
84350d1d96aSpgoyette 	uint8_t	ddr4_tAAmin_ftb;
84450d1d96aSpgoyette 	uint8_t	ddr4_tCKAVGmax_ftb;
84550d1d96aSpgoyette 	uint8_t	ddr4_tCKAVGmin_ftb;
84650d1d96aSpgoyette 	uint16_t ddr4_crc;
84750d1d96aSpgoyette 	union {
84850d1d96aSpgoyette 		struct spdmem_ddr4_mod_unbuffered	u2_unbuf;
84950d1d96aSpgoyette 		struct spdmem_ddr4_mod_registered	u2_reg;
85050d1d96aSpgoyette 		struct spdmem_ddr4_mod_reduced_load	u2_red_load;
85150d1d96aSpgoyette 	} ddr4_u2;
85250d1d96aSpgoyette 	uint8_t	ddr4_unused17[64];
85350d1d96aSpgoyette 	uint8_t	ddr4_module_mfg_lsb;
85450d1d96aSpgoyette 	uint8_t	ddr4_module_mfg_msb;
85550d1d96aSpgoyette 	uint8_t	ddr4_module_mfg_loc;
85650d1d96aSpgoyette 	uint8_t	ddr4_module_mfg_year;
85750d1d96aSpgoyette 	uint8_t	ddr4_module_mfg_week;
85850d1d96aSpgoyette 	uint8_t	ddr4_serial_number[4];
85950d1d96aSpgoyette 	uint8_t	ddr4_part_number[20];
86050d1d96aSpgoyette 	uint8_t	ddr4_revision_code;
86150d1d96aSpgoyette 	uint8_t	ddr4_dram_mfgID_lsb;
86250d1d96aSpgoyette 	uint8_t	ddr4_dram_mfgID_msb;
86350d1d96aSpgoyette 	uint8_t	ddr4_dram_stepping;
86450d1d96aSpgoyette 	uint8_t ddr4_mfg_specific_data[29];
86550d1d96aSpgoyette 	uint8_t	ddr4_unused18[2];
866aead28a1Sozaki-r 	uint8_t	ddr4_user_data[128];
86750d1d96aSpgoyette } __packed;
86850d1d96aSpgoyette 
869d41a3cefSpgoyette struct spdmem {
870d41a3cefSpgoyette 	union {
871d41a3cefSpgoyette 		struct spdmem_fbdimm	u1_fbd;
872d41a3cefSpgoyette 		struct spdmem_fpm	u1_fpm;
873d41a3cefSpgoyette 		struct spdmem_ddr 	u1_ddr;
874d41a3cefSpgoyette 		struct spdmem_ddr2	u1_ddr2;
875d41a3cefSpgoyette 		struct spdmem_sdram	u1_sdr;
876d41a3cefSpgoyette 		struct spdmem_rambus	u1_rdr;
877d41a3cefSpgoyette 		struct spdmem_rom	u1_rom;
878d41a3cefSpgoyette 		struct spdmem_ddr3	u1_ddr3;
87950d1d96aSpgoyette 		struct spdmem_ddr4	u1_ddr4;
880d41a3cefSpgoyette 	} sm_u1;
881d41a3cefSpgoyette } __packed;
882d41a3cefSpgoyette #define	sm_fbd		sm_u1.u1_fbd
883d41a3cefSpgoyette #define	sm_fpm		sm_u1.u1_fpm
884d41a3cefSpgoyette #define	sm_ddr		sm_u1.u1_ddr
885d41a3cefSpgoyette #define	sm_ddr2		sm_u1.u1_ddr2
886d41a3cefSpgoyette #define	sm_rdr		sm_u1.u1_rdr
887d41a3cefSpgoyette #define	sm_rom		sm_u1.u1_rom
888d41a3cefSpgoyette #define	sm_ddr3		sm_u1.u1_ddr3
889d41a3cefSpgoyette #define	sm_sdr		sm_u1.u1_sdr
89050d1d96aSpgoyette #define	sm_ddr4		sm_u1.u1_ddr4
891d41a3cefSpgoyette 
892d41a3cefSpgoyette /* some fields are in the same place for all memory types */
893d41a3cefSpgoyette 
89450d1d96aSpgoyette #define sm_len		sm_fpm.fpm_len
89550d1d96aSpgoyette #define sm_size		sm_fpm.fpm_size
89650d1d96aSpgoyette #define sm_type		sm_fpm.fpm_type
897d41a3cefSpgoyette #define sm_cksum	sm_fpm.fpm_cksum
898d41a3cefSpgoyette #define sm_config	sm_fpm.fpm_config
899d41a3cefSpgoyette #define sm_voltage	sm_fpm.fpm_voltage
900d41a3cefSpgoyette #define	sm_refresh	sm_fpm.fpm_refresh
901d41a3cefSpgoyette #define	sm_selfrefresh	sm_fpm.fpm_selfrefresh
902d41a3cefSpgoyette 
90319d53e8dSmsaitoh #define SPDMEM_TYPE_MAXLEN 40
904d41a3cefSpgoyette 
905d41a3cefSpgoyette struct spdmem_softc {
906be9c8c17Smsaitoh 	int		(*sc_read)(struct spdmem_softc *, uint16_t, uint8_t *);
907d41a3cefSpgoyette 	struct spdmem	sc_spd_data;
908e3bc45f1Spgoyette 	struct sysctllog *sc_sysctl_log;
909d41a3cefSpgoyette 	char		sc_type[SPDMEM_TYPE_MAXLEN];
910d41a3cefSpgoyette };
911d41a3cefSpgoyette 
912d41a3cefSpgoyette int  spdmem_common_probe(struct spdmem_softc *);
913d41a3cefSpgoyette void spdmem_common_attach(struct spdmem_softc *, device_t);
914e3bc45f1Spgoyette int  spdmem_common_detach(struct spdmem_softc *, device_t);
915