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