1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (C) Marvell International Ltd. and its affiliates
9 #include "mv_ddr_topology.h"
12 * Based on JEDEC Standard No. 21-C, 4.1.2.L-4:
13 * Serial Presence Detect (SPD) for DDR4 SDRAM Modules
16 /* block 0: base configuration and dram parameters */
17 #define MV_DDR_SPD_DATA_BLOCK0_SIZE 128
18 /* block 1: module specific parameters sub-block */
19 #define MV_DDR_SPD_DATA_BLOCK1M_SIZE 64
20 /* block 1: hybrid memory parameters sub-block */
21 #define MV_DDR_SPD_DATA_BLOCK1H_SIZE 64
22 /* block 2: extended function parameter block */
23 #define MV_DDR_SPD_DATA_BLOCK2E_SIZE 64
24 /* block 2: manufacturing information */
25 #define MV_DDR_SPD_DATA_BLOCK2M_SIZE 64
26 /* block 3: end user programmable */
27 #define MV_DDR_SPD_DATA_BLOCK3_SIZE 128
29 #define MV_DDR_SPD_DEV_TYPE_DDR4 0xc
30 #define MV_DDR_SPD_MODULE_TYPE_UDIMM 0x2
31 #define MV_DDR_SPD_MODULE_TYPE_SO_DIMM 0x3
32 #define MV_DDR_SPD_MODULE_TYPE_MINI_UDIMM 0x6
33 #define MV_DDR_SPD_MODULE_TYPE_72BIT_SO_UDIMM 0x9
34 #define MV_DDR_SPD_MODULE_TYPE_16BIT_SO_DIMM 0xc
35 #define MV_DDR_SPD_MODULE_TYPE_32BIT_SO_DIMM 0xd
38 * TODO: For now, the struct contains block 0 & block 1 with module specific
39 * parameters for unbuffered memory module types only.
41 union mv_ddr_spd_data {
42 unsigned char all_bytes[MV_DDR_SPD_DATA_BLOCK0_SIZE +
43 MV_DDR_SPD_DATA_BLOCK1M_SIZE];
46 union { /* num of bytes used/num of bytes in spd device/crc coverage */
47 unsigned char all_bits;
49 unsigned char spd_bytes_used:4,
54 union { /* spd revision */
55 unsigned char all_bits;
57 unsigned char addtions_level:4,
61 unsigned char byte_2; /* key_byte/dram device type */
62 union { /* key byte/module type */
63 unsigned char all_bits;
65 unsigned char module_type:4,
70 union { /* sdram density & banks */
71 unsigned char all_bits;
73 unsigned char die_capacity:4,
78 union { /* sdram addressing */
79 unsigned char all_bits;
81 unsigned char col_address:3,
86 union { /* sdram package type */
87 unsigned char all_bits;
89 unsigned char signal_loading:2,
95 union { /* sdram optional features */
96 unsigned char all_bits;
98 unsigned char mac:4, /* max activate count */
99 t_maw:2, /* max activate window */
100 reserved:2; /* all 0s */
103 unsigned char byte_8; /* sdram thermal & refresh options; reserved; 0x00 */
104 union { /* other sdram optional features */
105 unsigned char all_bits;
107 unsigned char reserved:5, /* all 0s */
109 ppr:2; /* post package repair */
112 union { /* secondary sdram package type */
113 unsigned char all_bits;
115 unsigned char signal_loading:2,
116 density_ratio:2, /* dram density ratio */
118 sdram_package_type:1;
121 union { /* module nominal voltage, vdd */
122 unsigned char all_bits;
124 unsigned char operable:1,
126 reserved:5; /* all 0s */
129 union { /* module organization*/
130 unsigned char all_bits;
132 unsigned char device_width:3,
133 dimm_pkg_ranks_num:3, /* package ranks per dimm number */
138 union { /* module memory bus width */
139 unsigned char all_bits;
141 unsigned char primary_bus_width:3, /* in bits */
142 bus_width_ext:2, /* in bits */
143 reserved:3; /* all 0s */
146 union { /* module thernal sensor */
147 unsigned char all_bits;
149 unsigned char reserved:7,
153 union { /* extended module type */
154 unsigned char all_bits;
156 unsigned char ext_base_module_type:4,
157 reserved:4; /* all 0s */
160 unsigned char byte_16; /* reserved; 0x00 */
161 union { /* timebases */
162 unsigned char all_bits;
164 unsigned char ftb:2, /* fine timebase */
165 mtb:2, /* medium timebase */
166 reserved:4; /* all 0s */
169 unsigned char byte_18; /* sdram min cycle time (t ck avg min), mtb */
170 unsigned char byte_19; /* sdram max cycle time (t ck avg max), mtb */
171 unsigned char byte_20; /* cas latencies supported, first byte */
172 unsigned char byte_21; /* cas latencies supported, second byte */
173 unsigned char byte_22; /* cas latencies supported, third byte */
174 unsigned char byte_23; /* cas latencies supported, fourth byte */
175 unsigned char byte_24; /* min cas latency time (t aa min), mtb */
176 unsigned char byte_25; /* min ras to cas delay time (t rcd min), mtb */
177 unsigned char byte_26; /* min row precharge delay time (t rp min), mtb */
178 union { /* upper nibbles for t ras min & t rc min */
179 unsigned char all_bits;
181 unsigned char t_ras_min_msn:4, /* t ras min most significant nibble */
182 t_rc_min_msn:4; /* t rc min most significant nibble */
185 unsigned char byte_28; /* min active to precharge delay time (t ras min), l-s-byte, mtb */
186 unsigned char byte_29; /* min active to active/refresh delay time (t rc min), l-s-byte, mtb */
187 unsigned char byte_30; /* min refresh recovery delay time (t rfc1 min), l-s-byte, mtb */
188 unsigned char byte_31; /* min refresh recovery delay time (t rfc1 min), m-s-byte, mtb */
189 unsigned char byte_32; /* min refresh recovery delay time (t rfc2 min), l-s-byte, mtb */
190 unsigned char byte_33; /* min refresh recovery delay time (t rfc2 min), m-s-byte, mtb */
191 unsigned char byte_34; /* min refresh recovery delay time (t rfc4 min), l-s-byte, mtb */
192 unsigned char byte_35; /* min refresh recovery delay time (t rfc4 min), m-s-byte, mtb */
193 union { /* upper nibble for t faw */
194 unsigned char all_bits;
196 unsigned char t_faw_min_msn:4, /* t faw min most significant nibble */
200 unsigned char byte_37; /* min four activate window delay time (t faw min), l-s-byte, mtb */
201 /* byte 38: min activate to activate delay time (t rrd_s min), diff bank group, mtb */
202 unsigned char byte_38;
203 /* byte 39: min activate to activate delay time (t rrd_l min), same bank group, mtb */
204 unsigned char byte_39;
205 unsigned char byte_40; /* min cas to cas delay time (t ccd_l min), same bank group, mtb */
206 union { /* upper nibble for t wr min */
207 unsigned char all_bits;
209 unsigned char t_wr_min_msn:4, /* t wr min most significant nibble */
213 unsigned char byte_42; /* min write recovery time (t wr min) */
214 union { /* upper nibbles for t wtr min */
215 unsigned char all_bits;
217 unsigned char t_wtr_s_min_msn:4, /* t wtr s min most significant nibble */
218 t_wtr_l_min_msn:4; /* t wtr l min most significant nibble */
221 unsigned char byte_44; /* min write to read time (t wtr s min), diff bank group, mtb */
222 unsigned char byte_45; /* min write to read time (t wtr l min), same bank group, mtb */
223 unsigned char bytes_46_59[14]; /* reserved; all 0s */
224 unsigned char bytes_60_77[18]; /* TODO: connector to sdram bit mapping */
225 unsigned char bytes_78_116[39]; /* reserved; all 0s */
226 /* fine offset for min cas to cas delay time (t ccd_l min), same bank group, ftb */
227 unsigned char byte_117;
228 /* fine offset for min activate to activate delay time (t rrd_l min), same bank group, ftb */
229 unsigned char byte_118;
230 /* fine offset for min activate to activate delay time (t rrd_s min), diff bank group, ftb */
231 unsigned char byte_119;
232 /* fine offset for min active to active/refresh delay time (t rc min), ftb */
233 unsigned char byte_120;
234 unsigned char byte_121; /* fine offset for min row precharge delay time (t rp min), ftb */
235 unsigned char byte_122; /* fine offset for min ras to cas delay time (t rcd min), ftb */
236 unsigned char byte_123; /* fine offset for min cas latency time (t aa min), ftb */
237 unsigned char byte_124; /* fine offset for sdram max cycle time (t ck avg max), ftb */
238 unsigned char byte_125; /* fine offset for sdram min cycle time (t ck avg min), ftb */
239 unsigned char byte_126; /* crc for base configuration section, l-s-byte */
240 unsigned char byte_127; /* crc for base configuration section, m-s-byte */
242 * block 1: module specific parameters for unbuffered memory module types only
244 union { /* (unbuffered) raw card extension, module nominal height */
245 unsigned char all_bits;
247 unsigned char nom_height_max:5, /* in mm */
251 union { /* (unbuffered) module maximum thickness */
252 unsigned char all_bits;
254 unsigned char front_thickness_max:4, /* in mm */
255 back_thickness_max:4; /* in mm */
258 union { /* (unbuffered) reference raw card used */
259 unsigned char all_bits;
261 unsigned char ref_raw_card:5,
266 union { /* (unbuffered) address mapping from edge connector to dram */
267 unsigned char all_bits;
269 unsigned char rank_1_mapping:1,
273 unsigned char bytes_132_191[60]; /* reserved; all 0s */
277 int mv_ddr_spd_timing_calc(union mv_ddr_spd_data *spd_data, unsigned int timing_data[]);
278 enum mv_ddr_dev_width mv_ddr_spd_dev_width_get(union mv_ddr_spd_data *spd_data);
279 enum mv_ddr_die_capacity mv_ddr_spd_die_capacity_get(union mv_ddr_spd_data *spd_data);
280 unsigned char mv_ddr_spd_mem_mirror_get(union mv_ddr_spd_data *spd_data);
281 unsigned char mv_ddr_spd_cs_bit_mask_get(union mv_ddr_spd_data *spd_data);
282 unsigned char mv_ddr_spd_dev_type_get(union mv_ddr_spd_data *spd_data);
283 unsigned char mv_ddr_spd_module_type_get(union mv_ddr_spd_data *spd_data);
284 int mv_ddr_spd_supported_cls_calc(union mv_ddr_spd_data *spd_data);
285 unsigned int mv_ddr_spd_supported_cl_get(unsigned int cl);
286 enum mv_ddr_pkg_rank mv_ddr_spd_pri_bus_width_get(union mv_ddr_spd_data *spd_data);
287 enum mv_ddr_pkg_rank mv_ddr_spd_bus_width_ext_get(union mv_ddr_spd_data *spd_data);
289 #endif /* _MV_DDR_SPD_H */