blob: cfaf86f51738c000d5b78fe74a563dfcbda6da86 [file] [log] [blame]
Patrick Rudolphff251d22021-02-11 15:09:22 +01001/* SPDX-License-Identifier: GPL-2.0-or-later */
2
Elyes Haouas5a047462022-12-28 11:43:49 +01003#include <device/dram/ddr2.h>
Elyes Haouasf82e68c2022-12-28 12:33:58 +01004#include <device/dram/ddr3.h>
Patrick Rudolphff251d22021-02-11 15:09:22 +01005#include <device/dram/spd.h>
Subrata Banik6de8b422021-10-26 20:46:21 +05306#include <spd.h>
Elyes Haouas04c3b5a2022-10-07 10:08:05 +02007#include <stddef.h>
Patrick Rudolphff251d22021-02-11 15:09:22 +01008
9const char *spd_manufacturer_name(const uint16_t mod_id)
10{
11 switch (mod_id) {
12 case 0x9b85:
13 return "Crucial";
14 case 0x4304:
15 return "Ramaxel";
16 case 0x4f01:
17 return "Transcend";
18 case 0x9801:
19 return "Kingston";
20 case 0x987f:
JingleHsuWiwynn5f08ef92021-09-16 13:43:34 +080021 case 0xad00:
Patrick Rudolphff251d22021-02-11 15:09:22 +010022 return "Hynix";
23 case 0x9e02:
24 return "Corsair";
25 case 0xb004:
26 return "OCZ";
27 case 0xad80:
28 return "Hynix/Hyundai";
29 case 0x3486:
30 return "Super Talent";
31 case 0xcd04:
32 return "GSkill";
33 case 0xce80:
JingleHsuWiwynn5f08ef92021-09-16 13:43:34 +080034 case 0xce00:
Patrick Rudolphff251d22021-02-11 15:09:22 +010035 return "Samsung";
36 case 0xfe02:
37 return "Elpida";
38 case 0x2c80:
JingleHsuWiwynn5f08ef92021-09-16 13:43:34 +080039 case 0x2c00:
Patrick Rudolphff251d22021-02-11 15:09:22 +010040 return "Micron";
41 default:
42 return NULL;
43 }
44}
Subrata Banik6de8b422021-10-26 20:46:21 +053045
46static void convert_default_module_type_to_spd_info(struct spd_info *info)
47{
48 info->form_factor = MEMORY_FORMFACTOR_UNKNOWN;
49 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
50}
51
Elyes Haouas5a047462022-12-28 11:43:49 +010052static void convert_ddr2_module_type_to_spd_info(enum spd_dimm_type_ddr2 module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +020053 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +053054{
55 switch (module_type) {
Elyes Haouas5a047462022-12-28 11:43:49 +010056 case SPD_DDR2_DIMM_TYPE_RDIMM:
57 case SPD_DDR2_DIMM_TYPE_MINI_RDIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053058 info->form_factor = MEMORY_FORMFACTOR_RIMM;
59 info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
60 break;
Elyes Haouas5a047462022-12-28 11:43:49 +010061 case SPD_DDR2_DIMM_TYPE_UDIMM:
62 case SPD_DDR2_DIMM_TYPE_MINI_UDIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053063 info->form_factor = MEMORY_FORMFACTOR_DIMM;
64 info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
65 break;
Elyes Haouas5a047462022-12-28 11:43:49 +010066 case SPD_DDR2_DIMM_TYPE_MICRO_DIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053067 info->form_factor = MEMORY_FORMFACTOR_DIMM;
68 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
69 break;
Elyes Haouas5a047462022-12-28 11:43:49 +010070 case SPD_DDR2_DIMM_TYPE_SO_DIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053071 info->form_factor = MEMORY_FORMFACTOR_SODIMM;
72 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
73 break;
74 default:
75 convert_default_module_type_to_spd_info(info);
76 break;
77 }
78}
79
Elyes Haouasf82e68c2022-12-28 12:33:58 +010080static void convert_ddr3_module_type_to_spd_info(enum spd_dimm_type_ddr3 module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +020081 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +053082{
83 switch (module_type) {
Elyes Haouasf82e68c2022-12-28 12:33:58 +010084 case SPD_DDR3_DIMM_TYPE_RDIMM:
85 case SPD_DDR3_DIMM_TYPE_MINI_RDIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053086 info->form_factor = MEMORY_FORMFACTOR_RIMM;
87 info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
88 break;
Elyes Haouasf82e68c2022-12-28 12:33:58 +010089 case SPD_DDR3_DIMM_TYPE_UDIMM:
90 case SPD_DDR3_DIMM_TYPE_MINI_UDIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053091 info->form_factor = MEMORY_FORMFACTOR_DIMM;
92 info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
93 break;
Elyes Haouasf82e68c2022-12-28 12:33:58 +010094 case SPD_DDR3_DIMM_TYPE_MICRO_DIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053095 info->form_factor = MEMORY_FORMFACTOR_DIMM;
96 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
97 break;
Elyes Haouasf82e68c2022-12-28 12:33:58 +010098 case SPD_DDR3_DIMM_TYPE_SO_DIMM:
99 case SPD_DDR3_DIMM_TYPE_72B_SO_UDIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +0530100 info->form_factor = MEMORY_FORMFACTOR_SODIMM;
101 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
102 break;
103 default:
104 convert_default_module_type_to_spd_info(info);
105 break;
106 }
107}
108
109static void convert_ddr4_module_type_to_spd_info(enum ddr4_module_type module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200110 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +0530111{
112 switch (module_type) {
113 case DDR4_SPD_RDIMM:
114 case DDR4_SPD_MINI_RDIMM:
115 info->form_factor = MEMORY_FORMFACTOR_RIMM;
116 info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
117 break;
118 case DDR4_SPD_UDIMM:
119 case DDR4_SPD_MINI_UDIMM:
120 info->form_factor = MEMORY_FORMFACTOR_DIMM;
121 info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
122 break;
123 case DDR4_SPD_SODIMM:
124 case DDR4_SPD_72B_SO_UDIMM:
125 info->form_factor = MEMORY_FORMFACTOR_SODIMM;
126 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
127 break;
128 default:
129 convert_default_module_type_to_spd_info(info);
130 break;
131 }
132}
133
134static void convert_ddr5_module_type_to_spd_info(enum ddr5_module_type module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200135 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +0530136{
137 switch (module_type) {
138 case DDR5_SPD_RDIMM:
139 case DDR5_SPD_MINI_RDIMM:
140 info->form_factor = MEMORY_FORMFACTOR_RIMM;
141 info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
142 break;
143 case DDR5_SPD_UDIMM:
144 case DDR5_SPD_MINI_UDIMM:
145 info->form_factor = MEMORY_FORMFACTOR_DIMM;
146 info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
147 break;
148 case DDR5_SPD_SODIMM:
149 case DDR5_SPD_72B_SO_UDIMM:
150 info->form_factor = MEMORY_FORMFACTOR_SODIMM;
151 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
152 break;
153 case DDR5_SPD_2DPC:
154 info->form_factor = MEMORY_FORMFACTOR_PROPRIETARY_CARD;
155 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
156 break;
157 default:
158 convert_default_module_type_to_spd_info(info);
159 break;
160 }
161}
162
163static void convert_lpx_module_type_to_spd_info(enum lpx_module_type module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200164 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +0530165{
166 switch (module_type) {
167 case LPX_SPD_NONDIMM:
168 info->form_factor = MEMORY_FORMFACTOR_ROC;
169 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
170 break;
171 default:
172 convert_default_module_type_to_spd_info(info);
173 break;
174 }
175}
176
177void get_spd_info(smbios_memory_type memory_type, uint8_t module_type, struct spd_info *info)
178{
179 switch (memory_type) {
180 case MEMORY_TYPE_DDR2:
181 convert_ddr2_module_type_to_spd_info(module_type, info);
182 break;
183 case MEMORY_TYPE_DDR3:
184 convert_ddr3_module_type_to_spd_info(module_type, info);
185 break;
186 case MEMORY_TYPE_DDR4:
187 convert_ddr4_module_type_to_spd_info(module_type, info);
188 break;
189 case MEMORY_TYPE_DDR5:
190 convert_ddr5_module_type_to_spd_info(module_type, info);
191 break;
192 case MEMORY_TYPE_LPDDR3:
193 case MEMORY_TYPE_LPDDR4:
194 case MEMORY_TYPE_LPDDR5:
195 convert_lpx_module_type_to_spd_info(module_type, info);
196 break;
197 default:
198 convert_default_module_type_to_spd_info(info);
199 break;
200 }
201}
202
203static uint8_t convert_default_form_factor_to_module_type(void)
204{
205 return SPD_UNDEFINED;
206}
207
208static uint8_t convert_ddrx_form_factor_to_module_type(smbios_memory_type memory_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200209 smbios_memory_form_factor form_factor)
Subrata Banik6de8b422021-10-26 20:46:21 +0530210{
211 uint8_t module_type;
212
213 switch (form_factor) {
214 case MEMORY_FORMFACTOR_DIMM:
Elyes Haouas5a047462022-12-28 11:43:49 +0100215 return SPD_DDR2_DIMM_TYPE_UDIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +0530216 case MEMORY_FORMFACTOR_RIMM:
Elyes Haouas5a047462022-12-28 11:43:49 +0100217 return SPD_DDR2_DIMM_TYPE_RDIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +0530218 case MEMORY_FORMFACTOR_SODIMM:
Elyes Haouas5a047462022-12-28 11:43:49 +0100219 module_type = (memory_type == MEMORY_TYPE_DDR2) ? SPD_DDR2_DIMM_TYPE_SO_DIMM :
Elyes Haouasf82e68c2022-12-28 12:33:58 +0100220 SPD_DDR3_DIMM_TYPE_SO_DIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +0530221 return module_type;
222 default:
223 return convert_default_form_factor_to_module_type();
224 }
225}
226
227static uint8_t convert_lpx_form_factor_to_module_type(smbios_memory_form_factor form_factor)
228{
229 switch (form_factor) {
230 case MEMORY_FORMFACTOR_ROC:
231 return LPX_SPD_NONDIMM;
232 default:
233 return convert_default_form_factor_to_module_type();
234 }
235}
236
237uint8_t convert_form_factor_to_module_type(smbios_memory_type memory_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200238 smbios_memory_form_factor form_factor)
Subrata Banik6de8b422021-10-26 20:46:21 +0530239{
240 uint8_t module_type;
241
242 switch (memory_type) {
243 case MEMORY_TYPE_DDR2:
244 case MEMORY_TYPE_DDR3:
245 case MEMORY_TYPE_DDR4:
246 case MEMORY_TYPE_DDR5:
247 module_type = convert_ddrx_form_factor_to_module_type(memory_type, form_factor);
248 break;
249 case MEMORY_TYPE_LPDDR3:
250 case MEMORY_TYPE_LPDDR4:
251 case MEMORY_TYPE_LPDDR5:
252 module_type = convert_lpx_form_factor_to_module_type(form_factor);
253 break;
254 default:
255 module_type = convert_default_form_factor_to_module_type();
256 break;
257 }
258
259 return module_type;
260}