blob: 68974525b35e73599d4dadb3b8006fd9581c6cf4 [file] [log] [blame]
David Hendricks6638f872015-11-04 14:52:02 -08001/*
2 * Copyright 2015, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "lib/nonspd.h"
33
David Hendricks0fa54152016-03-16 15:08:56 -070034const struct nonspd_mem_info elpida_lpddr3_edfa164a2ma_jd_f = {
David Hendricks6638f872015-11-04 14:52:02 -080035 .dram_type = SPD_DRAM_TYPE_LPDDR3,
36 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
37
38 .module_size_mbits = 8192,
39 .num_ranks = 2,
40 .device_width = 32,
41 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800, DDR_933 },
42
43 .module_mfg_id = { .msb = 0x2c, .lsb = 0x80 },
44 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x80 },
45
46 .part_num =
47 { 'E', 'D', 'F', 'A', '1', '6', '4', 'A', '2', 'M', 'A', '-',
48 'J', 'D', '-', 'F',},
49};
50
David Hendricks0fa54152016-03-16 15:08:56 -070051const struct nonspd_mem_info elpida_lpddr3_f8132a3ma_gd_f = {
David Hendricks6638f872015-11-04 14:52:02 -080052 .dram_type = SPD_DRAM_TYPE_LPDDR3,
53 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
54
55 .module_size_mbits = 8192,
56 .num_ranks = 2,
57 .device_width = 32,
58 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800 },
59
60 .module_mfg_id = { .msb = 0x2c, .lsb = 0x80 },
61 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x80 },
62
63 .part_num =
64 { 'F', '8', '1', '3', '2', 'A', '3', 'M', 'A', '-', 'G', 'D',
65 '-', 'F',},
66};
67
David Hendricks0fa54152016-03-16 15:08:56 -070068const struct nonspd_mem_info elpida_lpddr3_fa232a2ma_gc_f = {
David Hendricks6638f872015-11-04 14:52:02 -080069 .dram_type = SPD_DRAM_TYPE_LPDDR3,
70 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
71
72 .module_size_mbits = 16384,
73 .num_ranks = 2,
74 .device_width = 32,
75 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800 },
76
77 .module_mfg_id = { .msb = 0x2c, .lsb = 0x80 },
78 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x80 },
79
80 .part_num =
81 { 'F', 'A', '2', '3', '2', 'A', '2', 'M', 'A', '-', 'G', 'C',
82 '-', 'F',},
83};
84
David Hendricks0fa54152016-03-16 15:08:56 -070085const struct nonspd_mem_info hynix_ddr3l_h5tc4g63afr_pba = {
David Hendricks6638f872015-11-04 14:52:02 -080086 .dram_type = SPD_DRAM_TYPE_DDR3,
87 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
88
89 .module_size_mbits = 4096,
90 .num_ranks = 1,
91 .device_width = 16,
92 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800 },
93
94 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
95 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
96
97 .serial_num = { 0, 0, 0, 0 },
98 .part_num =
99 { 'H', '5', 'T', 'C', '4', 'G', '6', '3', 'A', 'F', 'R', '-',
100 'P', 'B', 'A'},
101};
102
David Hendricks0fa54152016-03-16 15:08:56 -0700103const struct nonspd_mem_info hynix_ddr3l_h5tc4g63cfr_pba = {
David Hendricks6638f872015-11-04 14:52:02 -0800104 .dram_type = SPD_DRAM_TYPE_DDR3,
105 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
106
107 .module_size_mbits = 4096,
108 .num_ranks = 1,
109 .device_width = 16,
110 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800 },
111
112 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
113 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
114
115 .serial_num = { 0, 0, 0, 0 },
116 .part_num =
117 { 'H', '5', 'T', 'C', '4', 'G', '6', '3', 'C', 'F', 'R', '-',
118 'P', 'B', 'A'},
119};
120
Zheng Pan56c19e52018-10-23 17:01:11 -0700121const struct nonspd_mem_info hynix_ddr3l_h5tc4g63efr_rda = {
122 .dram_type = SPD_DRAM_TYPE_DDR3,
123 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
124
125 .module_size_mbits = 4096,
126 .num_ranks = 1,
127 .device_width = 16,
128 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800, DDR_933 },
129
130 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
131 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
132
133 .serial_num = { 0, 0, 0, 0 },
134 .part_num =
135 { 'H', '5', 'T', 'C', '4', 'G', '6', '3', 'E', 'F', 'R', '-',
136 'R', 'D', 'A'},
137};
138
David Hendricks0fa54152016-03-16 15:08:56 -0700139const struct nonspd_mem_info hynix_lpddr3_h9ccnnn8gtmlar_nud = {
David Hendricks6638f872015-11-04 14:52:02 -0800140 .dram_type = SPD_DRAM_TYPE_LPDDR3,
141 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
142
143 .module_size_mbits = 8192,
144 .num_ranks = 1,
145 .device_width = 32,
146 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800 },
147
148 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
149 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
150
151 .part_num =
152 { 'H', '9', 'C', 'C', 'N', 'N', 'N', '8', 'G', 'T', 'M', 'L',
153 'A', 'R', '-', 'N', 'U', 'D',},
154};
155
Milton Chiang5664fe32016-11-29 14:59:49 +0800156const struct nonspd_mem_info hynix_lpddr3_h9ccnnnbjtalar_nud = {
157 .dram_type = SPD_DRAM_TYPE_LPDDR3,
158 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
159
160 .module_size_mbits = 16384,
161 .num_ranks = 2,
162 .device_width = 32,
163 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800 },
164
165 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
166 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
167
168 .part_num =
169 { 'H', '9', 'C', 'C', 'N', 'N', 'N', 'B', 'J', 'T', 'A', 'L',
170 'A', 'R', '-', 'N', 'U', 'D',},
171};
172
David Hendricks0fa54152016-03-16 15:08:56 -0700173const struct nonspd_mem_info hynix_lpddr3_h9ccnnnbjtmlar_nud = {
David Hendricks6638f872015-11-04 14:52:02 -0800174 .dram_type = SPD_DRAM_TYPE_LPDDR3,
175 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
176
177 .module_size_mbits = 16384,
178 .num_ranks = 2,
179 .device_width = 32,
180 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800 },
181
182 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
183 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
184
185 .part_num =
186 { 'H', '9', 'C', 'C', 'N', 'N', 'N', 'B', 'J', 'T', 'M', 'L',
187 'A', 'R', '-', 'N', 'U', 'D',},
188};
189
David Hendricks0fa54152016-03-16 15:08:56 -0700190const struct nonspd_mem_info hynix_ddr3l_h5tc8g63amr_pba = {
David Hendricks6638f872015-11-04 14:52:02 -0800191 .dram_type = SPD_DRAM_TYPE_DDR3,
192 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
193 .module_size_mbits = 8192,
194 .num_ranks = 2,
195 .device_width = 16,
196 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800 },
197
198 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
199 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
200
201 .serial_num = { 0, 0, 0, 0 },
202 .part_num =
203 { 'H', '5', 'T', 'C', '8', 'G', '6', '3', 'A', 'M', 'R', '-',
204 'P', 'B', 'A' },
205};
206
David Hendricks0fa54152016-03-16 15:08:56 -0700207const struct nonspd_mem_info hynix_lpddr3_h9ccnnnbptblbr_nud = {
Loop Wu2a7e0fc2016-01-20 14:39:46 +0800208 .dram_type = SPD_DRAM_TYPE_LPDDR3,
209 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
210
211 .module_size_mbits = 16384,
212 .num_ranks = 2,
213 .device_width = 32,
214 .ddr_freq = { DDR_667, DDR_800, DDR_933 },
215
216 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
217 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
218
219 .part_num =
220 { 'H', '9', 'C', 'C', 'N', 'N', 'N', 'B', 'P', 'T', 'B', 'L',
221 'B', 'R', '-', 'N', 'U', 'D',},
222};
223
Milton Chiang1bcd0e62016-04-12 16:38:25 +0800224const struct nonspd_mem_info hynix_lpddr3_h9ccnnnbltblar_nud = {
225 .dram_type = SPD_DRAM_TYPE_LPDDR3,
226 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
227
228 .module_size_mbits = 16384,
229 .num_ranks = 2,
230 .device_width = 32,
231 .ddr_freq = { DDR_667, DDR_800, DDR_933 },
232
233 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
234 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
235
236 .part_num =
237 { 'H', '9', 'C', 'C', 'N', 'N', 'N', 'B', 'L', 'T', 'B', 'L',
238 'A', 'R', '-', 'N', 'U', 'D',},
239};
240
Kevin Chiu55250dd2016-11-08 17:21:23 +0800241const struct nonspd_mem_info hynix_lpddr4_h9hcnnn8kumlhr = {
242 .dram_type = SPD_DRAM_TYPE_LPDDR4,
243
244 .module_size_mbits = 8192,
245 .num_ranks = 1,
246 .device_width = 32,
247 .ddr_freq = { DDR_667, DDR_800, DDR_933, DDR_1067, DDR_1400},
248
249 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
250 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
251
252 .part_num =
253 { 'H', '9', 'H', 'C', 'N', 'N', 'N', '8', 'K', 'U', 'M', 'L',
254 'H', 'R',},
255};
256
257const struct nonspd_mem_info hynix_lpddr4_h9hcnnnbpumlhr = {
258 .dram_type = SPD_DRAM_TYPE_LPDDR4,
259
260 .module_size_mbits = 16384,
261 .num_ranks = 2,
262 .device_width = 32,
263 .ddr_freq = { DDR_667, DDR_800, DDR_933, DDR_1067, DDR_1400},
264
265 .module_mfg_id = { .msb = 0xad, .lsb = 0x80 },
266 .dram_mfg_id = { .msb = 0xad, .lsb = 0x80 },
267
268 .part_num =
269 { 'H', '9', 'H', 'C', 'N', 'N', 'N', 'B', 'P', 'U', 'M', 'L',
270 'H', 'R',},
271};
272
David Hendricks6638f872015-11-04 14:52:02 -0800273const struct nonspd_mem_info micron_mt41k256m16ha = {
274 .dram_type = SPD_DRAM_TYPE_DDR3,
275 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
276
277 .module_size_mbits = 4096,
278 .num_ranks = 1,
279 .device_width = 16,
280 .ddr_freq = { DDR_533, DDR_667, DDR_800 },
281
282 .module_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
283 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
284
285 .serial_num = { 0, 0, 0, 0 },
286 .part_num = { 'M', 'T', '4', '1', 'K', '2', '5', '6', 'M',
287 '1', '6', 'H', 'A', '-', '1', '2', '5' },
288};
289
Milton Chiang5664fe32016-11-29 14:59:49 +0800290const struct nonspd_mem_info micron_mt52l256m32d1pf = {
291 .dram_type = SPD_DRAM_TYPE_DDR3,
292 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
293
294 .module_size_mbits = 8192,
295 .num_ranks = 1,
296 .device_width = 32,
297 .ddr_freq = { DDR_800, DDR_933, DDR_1067 },
298
299 .module_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
300 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
301
302 .serial_num = { 0, 0, 0, 0 },
303 .part_num = { 'M', 'T', '5', '2', 'L', '2', '5', '6', 'M',
304 '3', '2', 'D', '1', 'P', 'F', '-', '0', '9',
305 '3', 'W', 'T', ':', 'B' },
306};
307
308const struct nonspd_mem_info micron_mt52l512m32d2pf = {
309 .dram_type = SPD_DRAM_TYPE_DDR3,
310 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
311
312 .module_size_mbits = 16384,
313 .num_ranks = 2,
314 .device_width = 32,
315 .ddr_freq = { DDR_800, DDR_933, DDR_1067 },
316
317 .module_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
318 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
319
320 .serial_num = { 0, 0, 0, 0 },
321 .part_num = { 'M', 'T', '5', '2', 'L', '5', '1', '2', 'M',
322 '3', '2', 'D', '2', 'P', 'F', '-', '0', '9',
323 '3', 'W', 'T', ':', 'B' },
324};
325
David Hendricks97303242015-11-11 14:41:40 -0800326const struct nonspd_mem_info nanya_ddr3l_nt5cc256m16dp_di = {
327 .dram_type = SPD_DRAM_TYPE_DDR3,
328 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
329
330 .module_size_mbits = 4096,
331 .num_ranks = 1,
332 .device_width = 16,
333 /* CL = 11, CWL = 8, min = 1.25ns, max <1.5ns */
334 .ddr_freq = { DDR_667, DDR_800 },
335 .module_mfg_id = { .msb = 0x0b, .lsb = 0x03 },
336 .dram_mfg_id = { .msb = 0x0b, .lsb = 0x03 },
337
338 .serial_num = { 0, 0, 0, 0 },
339 .part_num = { 'N', 'T', '5', 'C', 'C', '2', '5', '6',
340 'M', '1', '6', 'D', 'P', '-', 'D', 'I' },
341};
342
Zheng Pan56c19e52018-10-23 17:01:11 -0700343const struct nonspd_mem_info nanya_ddr3l_nt5cc256m16er_ek = {
344 .dram_type = SPD_DRAM_TYPE_DDR3,
345 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
346
347 .module_size_mbits = 4096,
348 .num_ranks = 1,
349 .device_width = 16,
350 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800, DDR_933 },
351 .module_mfg_id = { .msb = 0x0b, .lsb = 0x03 },
352 .dram_mfg_id = { .msb = 0x0b, .lsb = 0x03 },
353
354 .serial_num = { 0, 0, 0, 0 },
355 .part_num = { 'N', 'T', '5', 'C', 'C', '2', '5', '6',
356 'M', '1', '6', 'E', 'R', '-', 'E', 'K' },
357};
358
David Hendricks6638f872015-11-04 14:52:02 -0800359const struct nonspd_mem_info samsung_k4b4g1646d = {
360 .dram_type = SPD_DRAM_TYPE_DDR3,
361 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
362
363 .module_size_mbits = 4096,
364 .num_ranks = 1,
365 .device_width = 16,
366 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800 },
367
368 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
369 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
370
371 .serial_num = { 0, 0, 0, 0 },
372 .part_num =
373 { 'K', '4', 'B', '4', 'G', '1', '6', '4', '6', 'D',
374 '-', 'B', 'Y', 'K', '0' },
375};
376
377const struct nonspd_mem_info samsung_k4b4g1646e = {
378 .dram_type = SPD_DRAM_TYPE_DDR3,
379 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
380
381 .module_size_mbits = 4096,
382 .num_ranks = 1,
383 .device_width = 16,
384 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800 },
385
386 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
387 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
388
389 .serial_num = { 0, 0, 0, 0 },
390 .part_num =
391 { 'K', '4', 'B', '4', 'G', '1', '6', '4', '6', 'E',
392 '-', 'B', 'Y', 'K', '0' },
393};
394
Zheng Pan56c19e52018-10-23 17:01:11 -0700395const struct nonspd_mem_info samsung_k4b4g1646e_byma = {
396 .dram_type = SPD_DRAM_TYPE_DDR3,
397 .module_type.ddr3_type = DDR3_MODULE_TYPE_UNDEFINED,
398
399 .module_size_mbits = 4096,
400 .num_ranks = 1,
401 .device_width = 16,
402 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800, DDR_933 },
403
404 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
405 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
406
407 .serial_num = { 0, 0, 0, 0 },
408 .part_num =
409 { 'K', '4', 'B', '4', 'G', '1', '6', '4', '6', 'E',
410 '-', 'B', 'Y', 'M', 'A' },
411};
412
David Hendricks0fa54152016-03-16 15:08:56 -0700413const struct nonspd_mem_info samsung_ddr3l_k4b4g1646d_byk0 = {
David Hendricks6638f872015-11-04 14:52:02 -0800414 .dram_type = SPD_DRAM_TYPE_DDR3,
415 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
416
417 .module_size_mbits = 4096,
418 .num_ranks = 1,
419 .device_width = 16,
420 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800 },
421
422 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
423 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
424
425 .serial_num = { 0, 0, 0, 0 },
426 .part_num =
427 { 'K', '4', 'B', '4', 'G', '1', '6', '4', '6', 'D', '-',
428 'B', 'Y', 'K', '0' },
429};
430
David Hendricks0fa54152016-03-16 15:08:56 -0700431const struct nonspd_mem_info samsung_ddr3l_k4b4g1646q_hyk0 = {
David Hendricks6638f872015-11-04 14:52:02 -0800432 .dram_type = SPD_DRAM_TYPE_DDR3,
433 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
434
435 .module_size_mbits = 4096,
436 .num_ranks = 1,
437 .device_width = 16,
438 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800 },
439
440 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
441 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
442
443 .serial_num = { 0, 0, 0, 0 },
444 .part_num =
445 { 'K', '4', 'B', '4', 'G', '1', '6', '4', '6', 'Q', '-',
446 'H', 'Y', 'K', '0' },
447};
448
David Hendricks0fa54152016-03-16 15:08:56 -0700449const struct nonspd_mem_info samsung_ddr3l_k4b8g1646q_myk0 = {
David Hendricks6638f872015-11-04 14:52:02 -0800450 .dram_type = SPD_DRAM_TYPE_DDR3,
451 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
452 .module_size_mbits = 8192,
453 .num_ranks = 2,
454 .device_width = 16,
455 .ddr_freq = { DDR_333, DDR_400, DDR_533, DDR_667, DDR_800 },
456
457 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
458 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
459
460 .serial_num = { 0, 0, 0, 0 },
461 .part_num =
462 { 'K', '4', 'B', '8', 'G', '1', '6', '4', '6', 'Q', '-',
463 'M', 'Y', 'K', '0' },
464};
465
David Hendricks0fa54152016-03-16 15:08:56 -0700466const struct nonspd_mem_info samsung_lpddr3_k3qf2f20em_agce = {
David Hendricks6638f872015-11-04 14:52:02 -0800467 .dram_type = SPD_DRAM_TYPE_LPDDR3,
468 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
469
470 .module_size_mbits = 8192,
471 .num_ranks = 2,
472 .device_width = 32,
473 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800 },
474
475 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
476 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
477
478 .part_num =
479 { 'K', '3', 'Q', 'F', '2', 'F', '2', '0', 'E', 'M', '-',
480 'A', 'G', 'C', 'E' },
481};
482
Vincent Palatin90af8e62016-05-20 12:12:49 -0700483const struct nonspd_mem_info samsung_lpddr3_k4e6e304eb_egce = {
484 .dram_type = SPD_DRAM_TYPE_LPDDR3,
485 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
486
487 .module_size_mbits = 16384,
488 .num_ranks = 2,
489 .device_width = 32,
490 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800, DDR_933},
491
492 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
493 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
494
495 .part_num =
496 { 'K', '4', 'E', '6', 'E', '3', '0', '4', 'E', 'B', '-',
497 'E', 'G', 'C', 'E' },
498};
499
David Hendricks0fa54152016-03-16 15:08:56 -0700500const struct nonspd_mem_info samsung_lpddr3_k4e6e304ee_egce = {
David Hendricks6638f872015-11-04 14:52:02 -0800501 .dram_type = SPD_DRAM_TYPE_LPDDR3,
502 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
503
504 .module_size_mbits = 16384,
505 .num_ranks = 2,
506 .device_width = 32,
507 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800, DDR_933},
508
509 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
510 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
511
512 .part_num =
513 { 'K', '4', 'E', '6', 'E', '3', '0', '4', 'E', 'E', '-',
514 'E', 'G', 'C', 'E' },
515};
516
Milton Chiang1bcd0e62016-04-12 16:38:25 +0800517const struct nonspd_mem_info samsung_lpddr3_k4e6e304eb_egcf = {
518 .dram_type = SPD_DRAM_TYPE_LPDDR3,
519 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
520
521 .module_size_mbits = 16384,
522 .num_ranks = 2,
523 .device_width = 32,
524 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800, DDR_933},
525
526 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
527 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
528
529 .part_num =
530 { 'K', '4', 'E', '6', 'E', '3', '0', '4', 'E', 'B', '-',
531 'E', 'G', 'C', 'F' },
532};
533
David Hendricks0fa54152016-03-16 15:08:56 -0700534const struct nonspd_mem_info samsung_lpddr3_k4e8e304ed_egcc = {
David Hendricks6638f872015-11-04 14:52:02 -0800535 .dram_type = SPD_DRAM_TYPE_DDR3,
536 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
537
538 .module_size_mbits = 8192,
539 .num_ranks = 2,
540 .device_width = 32,
541 .ddr_freq = { DDR_533 },
542
543 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
544 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
545
546 .serial_num = { 0, 0, 0, 0 },
547 .part_num =
548 { 'K', '4', 'E', '8', 'E', '3', '0', '4', 'E', 'D', '-',
549 'E', 'G', 'C', 'C' },
550};
551
David Hendricks0fa54152016-03-16 15:08:56 -0700552const struct nonspd_mem_info samsung_lpddr3_k4e8e304ee_egce = {
David Hendricks6638f872015-11-04 14:52:02 -0800553 .dram_type = SPD_DRAM_TYPE_LPDDR3,
554 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
555
556 .module_size_mbits = 8192,
557 .num_ranks = 2,
558 .device_width = 32,
559 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800, DDR_933 },
560
561 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
562 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
563
564 .part_num =
565 { 'K', '4', 'E', '8', 'E', '3', '0', '4', 'E', 'E', '-',
566 'E', 'G', 'C', 'E' },
567};
Vincent Palatin90af8e62016-05-20 12:12:49 -0700568
569const struct nonspd_mem_info samsung_lpddr3_k4e8e324eb_egcf = {
570 .dram_type = SPD_DRAM_TYPE_LPDDR3,
571 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
572
573 .module_size_mbits = 8192,
574 .num_ranks = 2,
575 .device_width = 32,
576 .ddr_freq = { DDR_400, DDR_533, DDR_667, DDR_800, DDR_933 },
577
578 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
579 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
580
581 .part_num =
582 { 'K', '4', 'E', '8', 'E', '3', '2', '4', 'E', 'B', '-',
583 'E', 'G', 'C', 'F' },
584};
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700585
Loop Wue0fa3212016-12-01 16:25:41 +0800586const struct nonspd_mem_info micron_lpddr3_mt52l256m32d1pf_107wtb = {
587 .dram_type = SPD_DRAM_TYPE_LPDDR3,
588 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
589
590 .module_size_mbits = 8192,
591 .num_ranks = 1,
592 .device_width = 32,
593 .ddr_freq = { DDR_667, DDR_800, DDR_933 },
594
595 .module_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
596 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
597
598 .part_num =
599 { 'M', 'T', '5', '2', 'L', '2', '5', '6', 'M', '3', '2', 'D',
600 '1', 'P', 'F', '-', '1', '0', '7', 'W', 'T', ':', 'B' },
601};
602
jiazi Yang5e3d5942017-04-05 22:30:45 -0400603const struct nonspd_mem_info micron_lpddr3_mt52l256m64d2pp_107wtb = {
604 .dram_type = SPD_DRAM_TYPE_LPDDR3,
605 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
606
607 .module_size_mbits = 8192,
608 .num_ranks = 1,
609 .device_width = 32,
610 .ddr_freq = { DDR_667, DDR_800, DDR_933 },
611
612 .module_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
613 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
614
615 .part_num =
616 { 'M', 'T', '5', '2', 'L', '2', '5', '6', 'M', '6', '4', 'D',
617 '2', 'P', 'P', '-', '1', '0', '7', 'W', 'T', ':', 'B' },
618};
619
Loop Wue0fa3212016-12-01 16:25:41 +0800620const struct nonspd_mem_info micron_lpddr3_mt52l512m32d2pf_107wtb = {
621 .dram_type = SPD_DRAM_TYPE_LPDDR3,
622 .module_type.ddr3_type = DDR3_MODULE_TYPE_SO_DIMM,
623
624 .module_size_mbits = 16384,
625 .num_ranks = 2,
626 .device_width = 32,
627 .ddr_freq = { DDR_667, DDR_800, DDR_933 },
628
629 .module_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
630 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
631
632 .part_num =
633 { 'M', 'T', '5', '2', 'L', '5', '1', '2', 'M', '3', '2', 'D',
634 '2', 'P', 'F', '-', '1', '0', '7', 'W', 'T', ':', 'B' },
635};
636
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700637static const struct nonspd_mem_info micron_lpddr4_mt53b256m32d1np = {
638 .dram_type = SPD_DRAM_TYPE_LPDDR4,
639
640 .module_size_mbits = 8192,
641 .num_ranks = 1,
642 .device_width = 32,
643 .ddr_freq = { DDR_667, DDR_800, DDR_933, DDR_1067, DDR_1400},
644
645 .module_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
646 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
647
648 .part_num =
649 { 'M', 'T', '5', '3', 'B', '2', '5', '6', 'M', '3', '2', 'D',
650 '1', 'N', 'P'},
651};
652
653static const struct nonspd_mem_info micron_lpddr4_mt53b512m32d2np = {
654 .dram_type = SPD_DRAM_TYPE_LPDDR4,
655
656 .module_size_mbits = 16384,
657 .num_ranks = 2,
658 .device_width = 32,
659 .ddr_freq = { DDR_667, DDR_800, DDR_933, DDR_1067, DDR_1400},
660
661 .module_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
662 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
663
664 .part_num =
665 { 'M', 'T', '5', '3', 'B', '5', '1', '2', 'M', '3', '2', 'D',
666 '2', 'N', 'P'},
667};
668
ren kuoc9202c92018-05-14 19:46:20 +0800669static const struct nonspd_mem_info micron_lpddr4_mt53e512m32d2np = {
670 .dram_type = SPD_DRAM_TYPE_LPDDR4,
671
672 .module_size_mbits = 16384,
673 .num_ranks = 2,
674 .device_width = 32,
675 .ddr_freq = { DDR_667, DDR_800, DDR_933, DDR_1067, DDR_1400},
676
677 .module_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
678 .dram_mfg_id = { .msb = 0x2c, .lsb = 0x00 },
679
680 .part_num =
681 { 'M', 'T', '5', '3', 'E', '5', '1', '2', 'M', '3', '2', 'D',
682 '2', 'N', 'P'},
683};
684
Philip Chencccc7042018-09-25 20:31:37 -0700685const struct nonspd_mem_info samsung_lpddr4_k3uh5h50mm_agcj = {
686 .dram_type = SPD_DRAM_TYPE_LPDDR4,
687
688 .module_size_mbits = 32768,
689 .num_ranks = 2,
690 .device_width = 32,
691 .ddr_freq = { DDR_1355 },
692
693 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
694 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
695
696 .part_num =
697 { 'K', '3', 'U', 'H', '5', 'H', '5', '0', 'M', 'M', '-',
698 'A', 'G', 'C', 'J' },
699};
700
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700701static const struct nonspd_mem_info samsung_lpddr4_k4f6e304hb_mgcj = {
702 .dram_type = SPD_DRAM_TYPE_LPDDR4,
703
704 .module_size_mbits = 16384,
705 .num_ranks = 2,
706 .device_width = 32,
707 .ddr_freq = { DDR_667, DDR_800, DDR_933, DDR_1067, DDR_1400},
708
709 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
710 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
711
712 .part_num =
713 { 'K', '4', 'F', '6', 'E', '3', '0', '4', 'H', 'B', '-',
714 'M', 'G', 'C', 'J' },
715};
716
ren kuo500c9c62018-05-24 17:57:50 +0800717static const struct nonspd_mem_info samsung_lpddr4_k4f6e3s4hm_mgcj = {
718 .dram_type = SPD_DRAM_TYPE_LPDDR4,
719
720 .module_size_mbits = 16384,
721 .num_ranks = 1,
722 .device_width = 32,
723 .ddr_freq = { DDR_667, DDR_800, DDR_933, DDR_1067, DDR_1400},
724
725 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
726 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
727
728 .part_num =
729 { 'K', '4', 'F', '6', 'E', '3', 'S', '4', 'H', 'M', '-',
730 'M', 'G', 'C', 'J' },
731};
732
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700733static const struct nonspd_mem_info samsung_lpddr4_k4f8e304hb_mgcj = {
734 .dram_type = SPD_DRAM_TYPE_LPDDR4,
735
736 .module_size_mbits = 8192,
737 .num_ranks = 1,
738 .device_width = 32,
739 .ddr_freq = { DDR_667, DDR_800, DDR_933, DDR_1067, DDR_1400},
740
741 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
742 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
743
744 .part_num =
745 { 'K', '4', 'F', '8', 'E', '3', '0', '4', 'H', 'B', '-',
746 'M', 'G', 'C', 'J' },
747};
748
749static const struct nonspd_mem_info samsung_lpddr4_k4f6e304hb_mgch = {
750 .dram_type = SPD_DRAM_TYPE_LPDDR4,
751
752 .module_size_mbits = 8192,
753 .num_ranks = 1,
754 .device_width = 32,
755 .ddr_freq = { DDR_667, DDR_800, DDR_933, DDR_1067, DDR_1400},
756
757 .module_mfg_id = { .msb = 0xce, .lsb = 0x00 },
758 .dram_mfg_id = { .msb = 0xce, .lsb = 0x00 },
759
760 .part_num =
761 { 'K', '4', 'F', '6', 'E', '3', '0', '4', 'H', 'B', '-',
762 'M', 'G', 'C', 'H' },
763};
764
Marco Chena18bbb22018-08-13 16:10:55 +0800765// This one is reserved for storing mem info from SMBIOS if no explicit entry
766// was added above.
767static struct nonspd_mem_info part_extracted_from_smbios = {
768 .part_num =
769 { 'U', 'N', 'P', 'R', 'O', 'V', 'I', 'S', 'I', 'O', 'N', 'E', 'D'},
770};
771
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700772static const struct nonspd_mem_info *nospdmemory[] = {
773 &elpida_lpddr3_edfa164a2ma_jd_f,
774 &elpida_lpddr3_f8132a3ma_gd_f,
775 &elpida_lpddr3_fa232a2ma_gc_f,
776 &hynix_ddr3l_h5tc4g63afr_pba,
777 &hynix_ddr3l_h5tc4g63cfr_pba,
Zheng Pan56c19e52018-10-23 17:01:11 -0700778 &hynix_ddr3l_h5tc4g63efr_rda,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700779 &hynix_lpddr3_h9ccnnn8gtmlar_nud,
Milton Chiang5664fe32016-11-29 14:59:49 +0800780 &hynix_lpddr3_h9ccnnnbjtalar_nud,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700781 &hynix_lpddr3_h9ccnnnbjtmlar_nud,
782 &hynix_ddr3l_h5tc8g63amr_pba,
783 &hynix_lpddr3_h9ccnnnbptblbr_nud,
784 &hynix_lpddr3_h9ccnnnbltblar_nud,
Kevin Chiu55250dd2016-11-08 17:21:23 +0800785 &hynix_lpddr4_h9hcnnn8kumlhr,
786 &hynix_lpddr4_h9hcnnnbpumlhr,
Marco Chena18bbb22018-08-13 16:10:55 +0800787 &micron_lpddr3_mt52l256m32d1pf_107wtb,
788 &micron_lpddr3_mt52l256m64d2pp_107wtb,
789 &micron_lpddr3_mt52l512m32d2pf_107wtb,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700790 &micron_lpddr4_mt53b256m32d1np,
791 &micron_lpddr4_mt53b512m32d2np,
ren kuoc9202c92018-05-14 19:46:20 +0800792 &micron_lpddr4_mt53e512m32d2np,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700793 &micron_mt41k256m16ha,
Milton Chiang5664fe32016-11-29 14:59:49 +0800794 &micron_mt52l256m32d1pf,
795 &micron_mt52l512m32d2pf,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700796 &nanya_ddr3l_nt5cc256m16dp_di,
Zheng Pan56c19e52018-10-23 17:01:11 -0700797 &nanya_ddr3l_nt5cc256m16er_ek,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700798 &samsung_k4b4g1646d,
799 &samsung_k4b4g1646e,
Zheng Pan56c19e52018-10-23 17:01:11 -0700800 &samsung_k4b4g1646e_byma,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700801 &samsung_ddr3l_k4b4g1646d_byk0,
802 &samsung_ddr3l_k4b4g1646q_hyk0,
803 &samsung_ddr3l_k4b8g1646q_myk0,
804 &samsung_lpddr3_k3qf2f20em_agce,
805 &samsung_lpddr3_k4e6e304eb_egce,
806 &samsung_lpddr3_k4e6e304ee_egce,
807 &samsung_lpddr3_k4e6e304eb_egcf,
808 &samsung_lpddr3_k4e8e304ed_egcc,
809 &samsung_lpddr3_k4e8e304ee_egce,
810 &samsung_lpddr3_k4e8e324eb_egcf,
Philip Chencccc7042018-09-25 20:31:37 -0700811 &samsung_lpddr4_k3uh5h50mm_agcj,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700812 &samsung_lpddr4_k4f6e304hb_mgch,
813 &samsung_lpddr4_k4f6e304hb_mgcj,
ren kuo500c9c62018-05-24 17:57:50 +0800814 &samsung_lpddr4_k4f6e3s4hm_mgcj,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700815 &samsung_lpddr4_k4f8e304hb_mgcj,
816};
817
Marco Chena18bbb22018-08-13 16:10:55 +0800818static int transfer_speed_from_smbios_to_nonspd_mem_info(
819 struct smbios_table *table,
820 struct nonspd_mem_info *info)
821{
822 for (int index = DDR_333; index < DDR_FREQ_MAX; index++) {
823 if (table->data.mem_device.speed == atoi(ddr_freq_prettyprint[index])) {
824 info->ddr_freq[0] = index;
825 return 0;
826 }
827 }
828
829 lprintf(LOG_ERR, "%s: mem speed %hu in SMBIOS is out of range.",
830 __func__, table->data.mem_device.speed);
831 return -1;
832}
833
834static int extract_mem_info_from_smbios(
835 struct smbios_table *table,
836 struct nonspd_mem_info *info)
837{
838 const char *smbios_part_num;
Marco Chen05511cb2018-10-01 08:35:37 +0800839 size_t smbios_part_num_len, max_part_num_len;
Marco Chena18bbb22018-08-13 16:10:55 +0800840 uint32_t size;
841
Marco Chen05511cb2018-10-01 08:35:37 +0800842 max_part_num_len = sizeof(info->part_num) - 1;
Marco Chena18bbb22018-08-13 16:10:55 +0800843 smbios_part_num = table->string[table->data.mem_device.part_number];
Marco Chen05511cb2018-10-01 08:35:37 +0800844 smbios_part_num_len = strlen(smbios_part_num);
Marco Chena18bbb22018-08-13 16:10:55 +0800845
846 if (!smbios_part_num_len ||
Marco Chen05511cb2018-10-01 08:35:37 +0800847 smbios_part_num_len > max_part_num_len) {
Marco Chena18bbb22018-08-13 16:10:55 +0800848 lprintf(LOG_ERR, "%s: SMBIOS Memory info table: part num is missing. "
849 "Or len of part number %lu is larger then buffer %lu."
850 , __func__, (unsigned long)smbios_part_num_len,
Marco Chen05511cb2018-10-01 08:35:37 +0800851 (unsigned long)max_part_num_len);
Marco Chena18bbb22018-08-13 16:10:55 +0800852 return -1;
853 }
854
855 size = (table->data.mem_device.size & 0x7fff) * 8;
856 info->module_size_mbits =
857 (table->data.mem_device.size & 0x8000 ? size * 1024 : size);
858
Marco Chen05511cb2018-10-01 08:35:37 +0800859 strncpy((char *)info->part_num, smbios_part_num, max_part_num_len);
Marco Chena18bbb22018-08-13 16:10:55 +0800860 return transfer_speed_from_smbios_to_nonspd_mem_info(table, info);
861}
862
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700863int spd_set_nonspd_info(struct platform_intf *intf,
864 const struct nonspd_mem_info **info)
865{
866 int dimm = 0, index;
867 struct smbios_table table;
868
869 if (smbios_find_table(intf, SMBIOS_TYPE_MEMORY, dimm, &table,
870 SMBIOS_LEGACY_ENTRY_BASE,
871 SMBIOS_LEGACY_ENTRY_LEN) < 0) {
872 lprintf(LOG_ERR, "%s: SMBIOS Memory info table missing\n"
873 , __func__);
874 return -1;
875 }
876
877 for (index = 0; index < ARRAY_SIZE(nospdmemory); index++) {
878 if (!strncmp(table.string[table.data.mem_device.part_number],
Brian Norrisd7384fb2018-04-30 11:05:23 -0700879 (const char *)nospdmemory[index]->part_num,
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700880 sizeof(nospdmemory[index]->part_num))) {
881 *info = nospdmemory[index];
882 break;
883 }
884 }
885
Marco Chena18bbb22018-08-13 16:10:55 +0800886 if (index < ARRAY_SIZE(nospdmemory)) {
887 return 0;
888 }
889
890 // memory device from SMBIOS is mapped into a nonspd_mem_info.
891 if (extract_mem_info_from_smbios(&table, &part_extracted_from_smbios)) {
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700892 return -1;
893 }
894
Marco Chena18bbb22018-08-13 16:10:55 +0800895 *info = &part_extracted_from_smbios;
896
Ravi Sarawadi7ef277d2016-08-16 17:04:00 -0700897 return 0;
898}