blob: 4a1e8825430c748003c2443cb4808c4a1b1d91e3 [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";
Martin Roth2c6c3532023-02-23 16:55:09 -070041 case 0x0b03:
42 return "Nanya";
Patrick Rudolphff251d22021-02-11 15:09:22 +010043 default:
44 return NULL;
45 }
46}
Subrata Banik6de8b422021-10-26 20:46:21 +053047
48static void convert_default_module_type_to_spd_info(struct spd_info *info)
49{
50 info->form_factor = MEMORY_FORMFACTOR_UNKNOWN;
51 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
52}
53
Elyes Haouas5a047462022-12-28 11:43:49 +010054static void convert_ddr2_module_type_to_spd_info(enum spd_dimm_type_ddr2 module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +020055 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +053056{
57 switch (module_type) {
Elyes Haouas5a047462022-12-28 11:43:49 +010058 case SPD_DDR2_DIMM_TYPE_RDIMM:
59 case SPD_DDR2_DIMM_TYPE_MINI_RDIMM:
Ziang Wanga6df40c2023-05-29 15:53:56 +080060 info->form_factor = MEMORY_FORMFACTOR_DIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +053061 info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
62 break;
Elyes Haouas5a047462022-12-28 11:43:49 +010063 case SPD_DDR2_DIMM_TYPE_UDIMM:
64 case SPD_DDR2_DIMM_TYPE_MINI_UDIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053065 info->form_factor = MEMORY_FORMFACTOR_DIMM;
66 info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
67 break;
Elyes Haouas5a047462022-12-28 11:43:49 +010068 case SPD_DDR2_DIMM_TYPE_MICRO_DIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053069 info->form_factor = MEMORY_FORMFACTOR_DIMM;
70 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
71 break;
Elyes Haouas5a047462022-12-28 11:43:49 +010072 case SPD_DDR2_DIMM_TYPE_SO_DIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053073 info->form_factor = MEMORY_FORMFACTOR_SODIMM;
74 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
75 break;
76 default:
77 convert_default_module_type_to_spd_info(info);
78 break;
79 }
80}
81
Elyes Haouasf82e68c2022-12-28 12:33:58 +010082static void convert_ddr3_module_type_to_spd_info(enum spd_dimm_type_ddr3 module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +020083 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +053084{
85 switch (module_type) {
Elyes Haouasf82e68c2022-12-28 12:33:58 +010086 case SPD_DDR3_DIMM_TYPE_RDIMM:
87 case SPD_DDR3_DIMM_TYPE_MINI_RDIMM:
Ziang Wanga6df40c2023-05-29 15:53:56 +080088 info->form_factor = MEMORY_FORMFACTOR_DIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +053089 info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
90 break;
Elyes Haouasf82e68c2022-12-28 12:33:58 +010091 case SPD_DDR3_DIMM_TYPE_UDIMM:
92 case SPD_DDR3_DIMM_TYPE_MINI_UDIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053093 info->form_factor = MEMORY_FORMFACTOR_DIMM;
94 info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
95 break;
Elyes Haouasf82e68c2022-12-28 12:33:58 +010096 case SPD_DDR3_DIMM_TYPE_MICRO_DIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +053097 info->form_factor = MEMORY_FORMFACTOR_DIMM;
98 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
99 break;
Elyes Haouasf82e68c2022-12-28 12:33:58 +0100100 case SPD_DDR3_DIMM_TYPE_SO_DIMM:
101 case SPD_DDR3_DIMM_TYPE_72B_SO_UDIMM:
Subrata Banik6de8b422021-10-26 20:46:21 +0530102 info->form_factor = MEMORY_FORMFACTOR_SODIMM;
103 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
104 break;
105 default:
106 convert_default_module_type_to_spd_info(info);
107 break;
108 }
109}
110
111static void convert_ddr4_module_type_to_spd_info(enum ddr4_module_type module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200112 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +0530113{
114 switch (module_type) {
115 case DDR4_SPD_RDIMM:
116 case DDR4_SPD_MINI_RDIMM:
Ziang Wanga6df40c2023-05-29 15:53:56 +0800117 info->form_factor = MEMORY_FORMFACTOR_DIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +0530118 info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
119 break;
120 case DDR4_SPD_UDIMM:
121 case DDR4_SPD_MINI_UDIMM:
122 info->form_factor = MEMORY_FORMFACTOR_DIMM;
123 info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
124 break;
125 case DDR4_SPD_SODIMM:
126 case DDR4_SPD_72B_SO_UDIMM:
127 info->form_factor = MEMORY_FORMFACTOR_SODIMM;
128 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
129 break;
130 default:
131 convert_default_module_type_to_spd_info(info);
132 break;
133 }
134}
135
136static void convert_ddr5_module_type_to_spd_info(enum ddr5_module_type module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200137 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +0530138{
139 switch (module_type) {
140 case DDR5_SPD_RDIMM:
141 case DDR5_SPD_MINI_RDIMM:
Ziang Wanga6df40c2023-05-29 15:53:56 +0800142 info->form_factor = MEMORY_FORMFACTOR_DIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +0530143 info->type_detail = MEMORY_TYPE_DETAIL_REGISTERED;
144 break;
145 case DDR5_SPD_UDIMM:
146 case DDR5_SPD_MINI_UDIMM:
147 info->form_factor = MEMORY_FORMFACTOR_DIMM;
148 info->type_detail = MEMORY_TYPE_DETAIL_UNBUFFERED;
149 break;
150 case DDR5_SPD_SODIMM:
151 case DDR5_SPD_72B_SO_UDIMM:
152 info->form_factor = MEMORY_FORMFACTOR_SODIMM;
153 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
154 break;
155 case DDR5_SPD_2DPC:
156 info->form_factor = MEMORY_FORMFACTOR_PROPRIETARY_CARD;
157 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
158 break;
159 default:
160 convert_default_module_type_to_spd_info(info);
161 break;
162 }
163}
164
165static void convert_lpx_module_type_to_spd_info(enum lpx_module_type module_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200166 struct spd_info *info)
Subrata Banik6de8b422021-10-26 20:46:21 +0530167{
168 switch (module_type) {
169 case LPX_SPD_NONDIMM:
170 info->form_factor = MEMORY_FORMFACTOR_ROC;
171 info->type_detail = MEMORY_TYPE_DETAIL_UNKNOWN;
172 break;
173 default:
174 convert_default_module_type_to_spd_info(info);
175 break;
176 }
177}
178
179void get_spd_info(smbios_memory_type memory_type, uint8_t module_type, struct spd_info *info)
180{
181 switch (memory_type) {
182 case MEMORY_TYPE_DDR2:
183 convert_ddr2_module_type_to_spd_info(module_type, info);
184 break;
185 case MEMORY_TYPE_DDR3:
186 convert_ddr3_module_type_to_spd_info(module_type, info);
187 break;
188 case MEMORY_TYPE_DDR4:
189 convert_ddr4_module_type_to_spd_info(module_type, info);
190 break;
191 case MEMORY_TYPE_DDR5:
192 convert_ddr5_module_type_to_spd_info(module_type, info);
193 break;
194 case MEMORY_TYPE_LPDDR3:
195 case MEMORY_TYPE_LPDDR4:
196 case MEMORY_TYPE_LPDDR5:
197 convert_lpx_module_type_to_spd_info(module_type, info);
198 break;
199 default:
200 convert_default_module_type_to_spd_info(info);
201 break;
202 }
203}
204
205static uint8_t convert_default_form_factor_to_module_type(void)
206{
207 return SPD_UNDEFINED;
208}
209
210static uint8_t convert_ddrx_form_factor_to_module_type(smbios_memory_type memory_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200211 smbios_memory_form_factor form_factor)
Subrata Banik6de8b422021-10-26 20:46:21 +0530212{
213 uint8_t module_type;
214
215 switch (form_factor) {
216 case MEMORY_FORMFACTOR_DIMM:
Elyes Haouas5a047462022-12-28 11:43:49 +0100217 return SPD_DDR2_DIMM_TYPE_UDIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +0530218 case MEMORY_FORMFACTOR_RIMM:
Elyes Haouas5a047462022-12-28 11:43:49 +0100219 return SPD_DDR2_DIMM_TYPE_RDIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +0530220 case MEMORY_FORMFACTOR_SODIMM:
Elyes Haouas5a047462022-12-28 11:43:49 +0100221 module_type = (memory_type == MEMORY_TYPE_DDR2) ? SPD_DDR2_DIMM_TYPE_SO_DIMM :
Elyes Haouasf82e68c2022-12-28 12:33:58 +0100222 SPD_DDR3_DIMM_TYPE_SO_DIMM;
Subrata Banik6de8b422021-10-26 20:46:21 +0530223 return module_type;
224 default:
225 return convert_default_form_factor_to_module_type();
226 }
227}
228
229static uint8_t convert_lpx_form_factor_to_module_type(smbios_memory_form_factor form_factor)
230{
231 switch (form_factor) {
232 case MEMORY_FORMFACTOR_ROC:
233 return LPX_SPD_NONDIMM;
234 default:
235 return convert_default_form_factor_to_module_type();
236 }
237}
238
239uint8_t convert_form_factor_to_module_type(smbios_memory_type memory_type,
Elyes Haouasc705ecd2022-05-29 14:58:00 +0200240 smbios_memory_form_factor form_factor)
Subrata Banik6de8b422021-10-26 20:46:21 +0530241{
242 uint8_t module_type;
243
244 switch (memory_type) {
245 case MEMORY_TYPE_DDR2:
246 case MEMORY_TYPE_DDR3:
247 case MEMORY_TYPE_DDR4:
248 case MEMORY_TYPE_DDR5:
249 module_type = convert_ddrx_form_factor_to_module_type(memory_type, form_factor);
250 break;
251 case MEMORY_TYPE_LPDDR3:
252 case MEMORY_TYPE_LPDDR4:
253 case MEMORY_TYPE_LPDDR5:
254 module_type = convert_lpx_form_factor_to_module_type(form_factor);
255 break;
256 default:
257 module_type = convert_default_form_factor_to_module_type();
258 break;
259 }
260
261 return module_type;
262}