xref: /aosp_15_r20/external/coreboot/src/device/dram/spd.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <device/dram/ddr2.h>
4 #include <device/dram/ddr3.h>
5 #include <device/dram/ddr4.h>
6 #include <device/dram/ddr5.h>
7 #include <device/dram/spd.h>
8 #include <spd.h>
9 #include <stddef.h>
10 
spd_manufacturer_name(const uint16_t mod_id)11 const char *spd_manufacturer_name(const uint16_t mod_id)
12 {
13 	switch (mod_id) {
14 	case 0x9b85:
15 		return "Crucial";
16 	case 0x4304:
17 		return "Ramaxel";
18 	case 0x4f01:
19 		return "Transcend";
20 	case 0x9801:
21 		return "Kingston";
22 	case 0x987f:
23 	case 0xad00:
24 		return "Hynix";
25 	case 0x9e02:
26 		return "Corsair";
27 	case 0xb004:
28 		return "OCZ";
29 	case 0xad80:
30 		return "Hynix/Hyundai";
31 	case 0x3486:
32 		return "Super Talent";
33 	case 0xcd04:
34 		return "GSkill";
35 	case 0xce80:
36 	case 0xce00:
37 		return "Samsung";
38 	case 0xfe02:
39 		return "Elpida";
40 	case 0x2c80:
41 	case 0x2c00:
42 		return "Micron";
43 	case 0x0b03:
44 		return "Nanya";
45 	default:
46 		return NULL;
47 	}
48 }
49 
convert_default_module_type_to_spd_info(struct spd_info * info)50 static void convert_default_module_type_to_spd_info(struct spd_info *info)
51 {
52 	info->form_factor = MEMORY_FORMFACTOR_UNKNOWN;
53 	info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
54 }
55 
convert_ddr2_module_type_to_spd_info(enum spd_dimm_type_ddr2 module_type,struct spd_info * info)56 static void convert_ddr2_module_type_to_spd_info(enum spd_dimm_type_ddr2 module_type,
57 						 struct spd_info *info)
58 {
59 	switch (module_type) {
60 	case SPD_DDR2_DIMM_TYPE_RDIMM:
61 	case SPD_DDR2_DIMM_TYPE_MINI_RDIMM:
62 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
63 		info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
64 		break;
65 	case SPD_DDR2_DIMM_TYPE_UDIMM:
66 	case SPD_DDR2_DIMM_TYPE_MINI_UDIMM:
67 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
68 		info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
69 		break;
70 	case SPD_DDR2_DIMM_TYPE_MICRO_DIMM:
71 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
72 		info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
73 		break;
74 	case SPD_DDR2_DIMM_TYPE_SO_DIMM:
75 		info->form_factor = MEMORY_FORMFACTOR_SODIMM;
76 		info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
77 		break;
78 	default:
79 		convert_default_module_type_to_spd_info(info);
80 		break;
81 	}
82 }
83 
convert_ddr3_module_type_to_spd_info(enum spd_dimm_type_ddr3 module_type,struct spd_info * info)84 static void convert_ddr3_module_type_to_spd_info(enum spd_dimm_type_ddr3 module_type,
85 						 struct spd_info *info)
86 {
87 	switch (module_type) {
88 	case SPD_DDR3_DIMM_TYPE_RDIMM:
89 	case SPD_DDR3_DIMM_TYPE_MINI_RDIMM:
90 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
91 		info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
92 		break;
93 	case SPD_DDR3_DIMM_TYPE_UDIMM:
94 	case SPD_DDR3_DIMM_TYPE_MINI_UDIMM:
95 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
96 		info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
97 		break;
98 	case SPD_DDR3_DIMM_TYPE_MICRO_DIMM:
99 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
100 		info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
101 		break;
102 	case SPD_DDR3_DIMM_TYPE_SO_DIMM:
103 	case SPD_DDR3_DIMM_TYPE_72B_SO_UDIMM:
104 		info->form_factor = MEMORY_FORMFACTOR_SODIMM;
105 		info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
106 		break;
107 	default:
108 		convert_default_module_type_to_spd_info(info);
109 		break;
110 	}
111 }
112 
convert_ddr4_module_type_to_spd_info(enum spd_dimm_type_ddr4 module_type,struct spd_info * info)113 static void convert_ddr4_module_type_to_spd_info(enum spd_dimm_type_ddr4 module_type,
114 						 struct spd_info *info)
115 {
116 	switch (module_type) {
117 	case SPD_DDR4_DIMM_TYPE_RDIMM:
118 	case SPD_DDR4_DIMM_TYPE_MINI_RDIMM:
119 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
120 		info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
121 		break;
122 	case SPD_DDR4_DIMM_TYPE_UDIMM:
123 	case SPD_DDR4_DIMM_TYPE_MINI_UDIMM:
124 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
125 		info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
126 		break;
127 	case SPD_DDR4_DIMM_TYPE_SO_DIMM:
128 	case SPD_DDR4_DIMM_TYPE_72B_SO_RDIMM:
129 		info->form_factor = MEMORY_FORMFACTOR_SODIMM;
130 		info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
131 		break;
132 	default:
133 		convert_default_module_type_to_spd_info(info);
134 		break;
135 	}
136 }
137 
convert_ddr5_module_type_to_spd_info(enum spd_dimm_type_ddr5 module_type,struct spd_info * info)138 static void convert_ddr5_module_type_to_spd_info(enum spd_dimm_type_ddr5 module_type,
139 						 struct spd_info *info)
140 {
141 	switch (module_type) {
142 	case SPD_DDR5_DIMM_TYPE_RDIMM:
143 	case SPD_DDR5_DIMM_TYPE_MINI_RDIMM:
144 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
145 		info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
146 		break;
147 	case SPD_DDR5_DIMM_TYPE_UDIMM:
148 	case SPD_DDR5_DIMM_TYPE_MINI_UDIMM:
149 		info->form_factor = MEMORY_FORMFACTOR_DIMM;
150 		info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
151 		break;
152 	case SPD_DDR5_DIMM_TYPE_SODIMM:
153 	case SPD_DDR5_DIMM_TYPE_72B_SO_UDIMM:
154 		info->form_factor = MEMORY_FORMFACTOR_SODIMM;
155 		info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
156 		break;
157 	case SPD_DDR5_DIMM_TYPE_2DPC:
158 		info->form_factor = MEMORY_FORMFACTOR_PROPRIETARY_CARD;
159 		info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
160 		break;
161 	default:
162 		convert_default_module_type_to_spd_info(info);
163 		break;
164 	}
165 }
166 
convert_lpx_module_type_to_spd_info(enum lpx_module_type module_type,struct spd_info * info)167 static void convert_lpx_module_type_to_spd_info(enum lpx_module_type module_type,
168 						struct spd_info *info)
169 {
170 	switch (module_type) {
171 	case LPX_SPD_NONDIMM:
172 		info->form_factor = MEMORY_FORMFACTOR_ROC;
173 		info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
174 		break;
175 	default:
176 		convert_default_module_type_to_spd_info(info);
177 		break;
178 	}
179 }
180 
get_spd_info(smbios_memory_type memory_type,uint8_t module_type,struct spd_info * info)181 void get_spd_info(smbios_memory_type memory_type, uint8_t module_type, struct spd_info *info)
182 {
183 	switch (memory_type) {
184 	case MEMORY_TYPE_DDR2:
185 		convert_ddr2_module_type_to_spd_info(module_type, info);
186 		break;
187 	case MEMORY_TYPE_DDR3:
188 		convert_ddr3_module_type_to_spd_info(module_type, info);
189 		break;
190 	case MEMORY_TYPE_DDR4:
191 		convert_ddr4_module_type_to_spd_info(module_type, info);
192 		break;
193 	case MEMORY_TYPE_DDR5:
194 		convert_ddr5_module_type_to_spd_info(module_type, info);
195 		break;
196 	case MEMORY_TYPE_LPDDR3:
197 	case MEMORY_TYPE_LPDDR4:
198 	case MEMORY_TYPE_LPDDR5:
199 		convert_lpx_module_type_to_spd_info(module_type, info);
200 		break;
201 	default:
202 		convert_default_module_type_to_spd_info(info);
203 		break;
204 	}
205 }
206 
convert_default_form_factor_to_module_type(void)207 static uint8_t convert_default_form_factor_to_module_type(void)
208 {
209 	return SPD_UNDEFINED;
210 }
211 
convert_ddrx_form_factor_to_module_type(smbios_memory_type memory_type,smbios_memory_form_factor form_factor)212 static uint8_t convert_ddrx_form_factor_to_module_type(smbios_memory_type memory_type,
213 						       smbios_memory_form_factor form_factor)
214 {
215 	uint8_t module_type;
216 
217 	switch (form_factor) {
218 	case MEMORY_FORMFACTOR_DIMM:
219 		return SPD_DDR2_DIMM_TYPE_UDIMM;
220 	case MEMORY_FORMFACTOR_RIMM:
221 		return SPD_DDR2_DIMM_TYPE_RDIMM;
222 	case MEMORY_FORMFACTOR_SODIMM:
223 		module_type = (memory_type == MEMORY_TYPE_DDR2) ? SPD_DDR2_DIMM_TYPE_SO_DIMM :
224 								  SPD_DDR3_DIMM_TYPE_SO_DIMM;
225 		return module_type;
226 	default:
227 		return convert_default_form_factor_to_module_type();
228 	}
229 }
230 
convert_lpx_form_factor_to_module_type(smbios_memory_form_factor form_factor)231 static uint8_t convert_lpx_form_factor_to_module_type(smbios_memory_form_factor form_factor)
232 {
233 	switch (form_factor) {
234 	case MEMORY_FORMFACTOR_ROC:
235 		return LPX_SPD_NONDIMM;
236 	default:
237 		return convert_default_form_factor_to_module_type();
238 	}
239 }
240 
convert_form_factor_to_module_type(smbios_memory_type memory_type,smbios_memory_form_factor form_factor)241 uint8_t convert_form_factor_to_module_type(smbios_memory_type memory_type,
242 					   smbios_memory_form_factor form_factor)
243 {
244 	uint8_t module_type;
245 
246 	switch (memory_type) {
247 	case MEMORY_TYPE_DDR2:
248 	case MEMORY_TYPE_DDR3:
249 	case MEMORY_TYPE_DDR4:
250 	case MEMORY_TYPE_DDR5:
251 		module_type = convert_ddrx_form_factor_to_module_type(memory_type, form_factor);
252 		break;
253 	case MEMORY_TYPE_LPDDR3:
254 	case MEMORY_TYPE_LPDDR4:
255 	case MEMORY_TYPE_LPDDR5:
256 		module_type = convert_lpx_form_factor_to_module_type(form_factor);
257 		break;
258 	default:
259 		module_type = convert_default_form_factor_to_module_type();
260 		break;
261 	}
262 
263 	return module_type;
264 }
265