• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <soc/gpio.h>
5 #include <soc/setup.h>
6 #include <soc/dmc.h>
7 #include <soc/clk.h>
8 
9 const struct mem_timings mem_timings[] = {
10 	{
11 		.mem_manuf = MEM_MANUF_ELPIDA,
12 		.mem_type = DDR_MODE_DDR3,
13 		.frequency_mhz = 800,
14 		.mpll_mdiv = 0x64,
15 		.mpll_pdiv = 0x3,
16 		.mpll_sdiv = 0x0,
17 		.cpll_mdiv = 0xde,
18 		.cpll_pdiv = 0x4,
19 		.cpll_sdiv = 0x2,
20 		.gpll_mdiv = 0x215,
21 		.gpll_pdiv = 0xc,
22 		.gpll_sdiv = 0x1,
23 		.epll_mdiv = 0x60,
24 		.epll_pdiv = 0x3,
25 		.epll_sdiv = 0x3,
26 		.vpll_mdiv = 0x96,
27 		.vpll_pdiv = 0x3,
28 		.vpll_sdiv = 0x2,
29 
30 		.bpll_mdiv = 0x64,
31 		.bpll_pdiv = 0x3,
32 		.bpll_sdiv = 0x0,
33 		.use_bpll = 0,
34 		.pclk_cdrex_ratio = 0x5,
35 		.direct_cmd_msr = {
36 			0x00020018, 0x00030000, 0x00010042, 0x00000d70
37 		},
38 		.timing_ref = 0x000000bb,
39 		.timing_row = 0x8c36660f,
40 		.timing_data = 0x3630580b,
41 		.timing_power = 0x41000a44,
42 		.phy0_dqs = 0x08080808,
43 		.phy1_dqs = 0x08080808,
44 		.phy0_dq = 0x08080808,
45 		.phy1_dq = 0x08080808,
46 		.phy0_tFS = 0x4,
47 		.phy1_tFS = 0x4,
48 		.phy0_pulld_dqs = 0xf,
49 		.phy1_pulld_dqs = 0xf,
50 
51 		.lpddr3_ctrl_phy_reset = 0x1,
52 		.ctrl_start_point = 0x10,
53 		.ctrl_inc = 0x10,
54 		.ctrl_start = 0x1,
55 		.ctrl_dll_on = 0x1,
56 		.ctrl_ref = 0x8,
57 
58 		.ctrl_force = 0x1a,
59 		.ctrl_rdlat = 0x0b,
60 		.ctrl_bstlen = 0x08,
61 
62 		.fp_resync = 0x8,
63 		.iv_size = 0x7,
64 		.dfi_init_start = 1,
65 		.aref_en = 1,
66 
67 		.rd_fetch = 0x3,
68 
69 		.zq_mode_dds = 0x7,
70 		.zq_mode_term = 0x1,
71 		.zq_mode_noterm = 0,
72 
73 		/*
74 		* Dynamic Clock: Always Running
75 		* Memory Burst length: 8
76 		* Number of chips: 1
77 		* Memory Bus width: 32 bit
78 		* Memory Type: DDR3
79 		* Additional Latancy for PLL: 0 Cycle
80 		*/
81 		.memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
82 			DMC_MEMCONTROL_DPWRDN_DISABLE |
83 			DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
84 			DMC_MEMCONTROL_TP_DISABLE |
85 			DMC_MEMCONTROL_DSREF_ENABLE |
86 			DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
87 			DMC_MEMCONTROL_MEM_TYPE_DDR3 |
88 			DMC_MEMCONTROL_MEM_WIDTH_32BIT |
89 			DMC_MEMCONTROL_NUM_CHIP_1 |
90 			DMC_MEMCONTROL_BL_8 |
91 			DMC_MEMCONTROL_PZQ_DISABLE |
92 			DMC_MEMCONTROL_MRR_BYTE_7_0,
93 		.memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED |
94 			DMC_MEMCONFIGx_CHIP_COL_10 |
95 			DMC_MEMCONFIGx_CHIP_ROW_15 |
96 			DMC_MEMCONFIGx_CHIP_BANK_8,
97 		.membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
98 		.membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
99 		.prechconfig_tp_cnt = 0xff,
100 		.dpwrdn_cyc = 0xff,
101 		.dsref_cyc = 0xffff,
102 		.concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
103 			DMC_CONCONTROL_TIMEOUT_LEVEL0 |
104 			DMC_CONCONTROL_RD_FETCH_DISABLE |
105 			DMC_CONCONTROL_EMPTY_DISABLE |
106 			DMC_CONCONTROL_AREF_EN_DISABLE |
107 			DMC_CONCONTROL_IO_PD_CON_DISABLE,
108 		.dmc_channels = 2,
109 		.chips_per_channel = 2,
110 		.chips_to_configure = 1,
111 		.send_zq_init = 1,
112 		.impedance = IMP_OUTPUT_DRV_30_OHM,
113 		.gate_leveling_enable = 0,
114 	}, {
115 		.mem_manuf = MEM_MANUF_SAMSUNG,
116 		.mem_type = DDR_MODE_DDR3,
117 		.frequency_mhz = 800,
118 		.mpll_mdiv = 0x64,
119 		.mpll_pdiv = 0x3,
120 		.mpll_sdiv = 0x0,
121 		.cpll_mdiv = 0xde,
122 		.cpll_pdiv = 0x4,
123 		.cpll_sdiv = 0x2,
124 		.gpll_mdiv = 0x215,
125 		.gpll_pdiv = 0xc,
126 		.gpll_sdiv = 0x1,
127 		.epll_mdiv = 0x60,
128 		.epll_pdiv = 0x3,
129 		.epll_sdiv = 0x3,
130 		.vpll_mdiv = 0x96,
131 		.vpll_pdiv = 0x3,
132 		.vpll_sdiv = 0x2,
133 
134 		.bpll_mdiv = 0x64,
135 		.bpll_pdiv = 0x3,
136 		.bpll_sdiv = 0x0,
137 		.use_bpll = 0,
138 		.pclk_cdrex_ratio = 0x5,
139 		.direct_cmd_msr = {
140 			0x00020018, 0x00030000, 0x00010000, 0x00000d70
141 		},
142 		.timing_ref = 0x000000bb,
143 		.timing_row = 0x8c36660f,
144 		.timing_data = 0x3630580b,
145 		.timing_power = 0x41000a44,
146 		.phy0_dqs = 0x08080808,
147 		.phy1_dqs = 0x08080808,
148 		.phy0_dq = 0x08080808,
149 		.phy1_dq = 0x08080808,
150 		.phy0_tFS = 0x8,
151 		.phy1_tFS = 0x8,
152 		.phy0_pulld_dqs = 0xf,
153 		.phy1_pulld_dqs = 0xf,
154 
155 		.lpddr3_ctrl_phy_reset = 0x1,
156 		.ctrl_start_point = 0x10,
157 		.ctrl_inc = 0x10,
158 		.ctrl_start = 0x1,
159 		.ctrl_dll_on = 0x1,
160 		.ctrl_ref = 0x8,
161 
162 		.ctrl_force = 0x1a,
163 		.ctrl_rdlat = 0x0b,
164 		.ctrl_bstlen = 0x08,
165 
166 		.fp_resync = 0x8,
167 		.iv_size = 0x7,
168 		.dfi_init_start = 1,
169 		.aref_en = 1,
170 
171 		.rd_fetch = 0x3,
172 
173 		.zq_mode_dds = 0x5,
174 		.zq_mode_term = 0x1,
175 		.zq_mode_noterm = 1,
176 
177 		/*
178 		* Dynamic Clock: Always Running
179 		* Memory Burst length: 8
180 		* Number of chips: 1
181 		* Memory Bus width: 32 bit
182 		* Memory Type: DDR3
183 		* Additional Latancy for PLL: 0 Cycle
184 		*/
185 		.memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
186 			DMC_MEMCONTROL_DPWRDN_DISABLE |
187 			DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
188 			DMC_MEMCONTROL_TP_DISABLE |
189 			DMC_MEMCONTROL_DSREF_ENABLE |
190 			DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
191 			DMC_MEMCONTROL_MEM_TYPE_DDR3 |
192 			DMC_MEMCONTROL_MEM_WIDTH_32BIT |
193 			DMC_MEMCONTROL_NUM_CHIP_1 |
194 			DMC_MEMCONTROL_BL_8 |
195 			DMC_MEMCONTROL_PZQ_DISABLE |
196 			DMC_MEMCONTROL_MRR_BYTE_7_0,
197 		.memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED |
198 			DMC_MEMCONFIGx_CHIP_COL_10 |
199 			DMC_MEMCONFIGx_CHIP_ROW_15 |
200 			DMC_MEMCONFIGx_CHIP_BANK_8,
201 		.membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
202 		.membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
203 		.prechconfig_tp_cnt = 0xff,
204 		.dpwrdn_cyc = 0xff,
205 		.dsref_cyc = 0xffff,
206 		.concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
207 			DMC_CONCONTROL_TIMEOUT_LEVEL0 |
208 			DMC_CONCONTROL_RD_FETCH_DISABLE |
209 			DMC_CONCONTROL_EMPTY_DISABLE |
210 			DMC_CONCONTROL_AREF_EN_DISABLE |
211 			DMC_CONCONTROL_IO_PD_CON_DISABLE,
212 		.dmc_channels = 2,
213 		.chips_per_channel = 2,
214 		.chips_to_configure = 1,
215 		.send_zq_init = 1,
216 		.impedance = IMP_OUTPUT_DRV_40_OHM,
217 		.gate_leveling_enable = 1,
218 	},
219 	{
220 		.mem_manuf = MEM_MANUF_ELPIDA,
221 		.mem_type = DDR_MODE_DDR3,
222 		.frequency_mhz = 780,
223 		.mpll_mdiv = 0x64,
224 		.mpll_pdiv = 0x3,
225 		.mpll_sdiv = 0x0,
226 		.cpll_mdiv = 0xde,
227 		.cpll_pdiv = 0x4,
228 		.cpll_sdiv = 0x2,
229 		.gpll_mdiv = 0x215,
230 		.gpll_pdiv = 0xc,
231 		.gpll_sdiv = 0x1,
232 		.epll_mdiv = 0x60,
233 		.epll_pdiv = 0x3,
234 		.epll_sdiv = 0x3,
235 		.vpll_mdiv = 0x96,
236 		.vpll_pdiv = 0x3,
237 		.vpll_sdiv = 0x2,
238 
239 		.bpll_mdiv = 0x82,
240 		.bpll_pdiv = 0x4,
241 		.bpll_sdiv = 0x0,
242 		.use_bpll = 1,
243 		.pclk_cdrex_ratio = 0x5,
244 		.direct_cmd_msr = {
245 			0x00020018, 0x00030000, 0x00010042, 0x00000d70
246 		},
247 		.timing_ref = 0x000000bb,
248 		.timing_row = 0x8c36660f,
249 		.timing_data = 0x3630580b,
250 		.timing_power = 0x41000a44,
251 		.phy0_dqs = 0x08080808,
252 		.phy1_dqs = 0x08080808,
253 		.phy0_dq = 0x08080808,
254 		.phy1_dq = 0x08080808,
255 		.phy0_tFS = 0x4,
256 		.phy1_tFS = 0x4,
257 		.phy0_pulld_dqs = 0xf,
258 		.phy1_pulld_dqs = 0xf,
259 
260 		.lpddr3_ctrl_phy_reset = 0x1,
261 		.ctrl_start_point = 0x10,
262 		.ctrl_inc = 0x10,
263 		.ctrl_start = 0x1,
264 		.ctrl_dll_on = 0x1,
265 		.ctrl_ref = 0x8,
266 
267 		.ctrl_force = 0x1a,
268 		.ctrl_rdlat = 0x0b,
269 		.ctrl_bstlen = 0x08,
270 
271 		.fp_resync = 0x8,
272 		.iv_size = 0x7,
273 		.dfi_init_start = 1,
274 		.aref_en = 1,
275 
276 		.rd_fetch = 0x3,
277 
278 		.zq_mode_dds = 0x7,
279 		.zq_mode_term = 0x1,
280 		.zq_mode_noterm = 0,
281 
282 		/*
283 		* Dynamic Clock: Always Running
284 		* Memory Burst length: 8
285 		* Number of chips: 1
286 		* Memory Bus width: 32 bit
287 		* Memory Type: DDR3
288 		* Additional Latancy for PLL: 0 Cycle
289 		*/
290 		.memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
291 			DMC_MEMCONTROL_DPWRDN_DISABLE |
292 			DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
293 			DMC_MEMCONTROL_TP_DISABLE |
294 			DMC_MEMCONTROL_DSREF_ENABLE |
295 			DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
296 			DMC_MEMCONTROL_MEM_TYPE_DDR3 |
297 			DMC_MEMCONTROL_MEM_WIDTH_32BIT |
298 			DMC_MEMCONTROL_NUM_CHIP_1 |
299 			DMC_MEMCONTROL_BL_8 |
300 			DMC_MEMCONTROL_PZQ_DISABLE |
301 			DMC_MEMCONTROL_MRR_BYTE_7_0,
302 		.memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED |
303 			DMC_MEMCONFIGx_CHIP_COL_10 |
304 			DMC_MEMCONFIGx_CHIP_ROW_15 |
305 			DMC_MEMCONFIGx_CHIP_BANK_8,
306 		.membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
307 		.membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
308 		.prechconfig_tp_cnt = 0xff,
309 		.dpwrdn_cyc = 0xff,
310 		.dsref_cyc = 0xffff,
311 		.concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
312 			DMC_CONCONTROL_TIMEOUT_LEVEL0 |
313 			DMC_CONCONTROL_RD_FETCH_DISABLE |
314 			DMC_CONCONTROL_EMPTY_DISABLE |
315 			DMC_CONCONTROL_AREF_EN_DISABLE |
316 			DMC_CONCONTROL_IO_PD_CON_DISABLE,
317 		.dmc_channels = 2,
318 		.chips_per_channel = 2,
319 		.chips_to_configure = 1,
320 		.send_zq_init = 1,
321 		.impedance = IMP_OUTPUT_DRV_30_OHM,
322 		.gate_leveling_enable = 0,
323 	}, {
324 		.mem_manuf = MEM_MANUF_SAMSUNG,
325 		.mem_type = DDR_MODE_DDR3,
326 		.frequency_mhz = 780,
327 		.mpll_mdiv = 0x64,
328 		.mpll_pdiv = 0x3,
329 		.mpll_sdiv = 0x0,
330 		.cpll_mdiv = 0xde,
331 		.cpll_pdiv = 0x4,
332 		.cpll_sdiv = 0x2,
333 		.gpll_mdiv = 0x215,
334 		.gpll_pdiv = 0xc,
335 		.gpll_sdiv = 0x1,
336 		.epll_mdiv = 0x60,
337 		.epll_pdiv = 0x3,
338 		.epll_sdiv = 0x3,
339 		.vpll_mdiv = 0x96,
340 		.vpll_pdiv = 0x3,
341 		.vpll_sdiv = 0x2,
342 
343 		.bpll_mdiv = 0x82,
344 		.bpll_pdiv = 0x4,
345 		.bpll_sdiv = 0x0,
346 		.use_bpll = 1,
347 		.pclk_cdrex_ratio = 0x5,
348 		.direct_cmd_msr = {
349 			0x00020018, 0x00030000, 0x00010000, 0x00000d70
350 		},
351 		.timing_ref = 0x000000bb,
352 		.timing_row = 0x8c36660f,
353 		.timing_data = 0x3630580b,
354 		.timing_power = 0x41000a44,
355 		.phy0_dqs = 0x08080808,
356 		.phy1_dqs = 0x08080808,
357 		.phy0_dq = 0x08080808,
358 		.phy1_dq = 0x08080808,
359 		.phy0_tFS = 0x8,
360 		.phy1_tFS = 0x8,
361 		.phy0_pulld_dqs = 0xf,
362 		.phy1_pulld_dqs = 0xf,
363 
364 		.lpddr3_ctrl_phy_reset = 0x1,
365 		.ctrl_start_point = 0x10,
366 		.ctrl_inc = 0x10,
367 		.ctrl_start = 0x1,
368 		.ctrl_dll_on = 0x1,
369 		.ctrl_ref = 0x8,
370 
371 		.ctrl_force = 0x1a,
372 		.ctrl_rdlat = 0x0b,
373 		.ctrl_bstlen = 0x08,
374 
375 		.fp_resync = 0x8,
376 		.iv_size = 0x7,
377 		.dfi_init_start = 1,
378 		.aref_en = 1,
379 
380 		.rd_fetch = 0x3,
381 
382 		.zq_mode_dds = 0x5,
383 		.zq_mode_term = 0x1,
384 		.zq_mode_noterm = 1,
385 
386 		/*
387 		* Dynamic Clock: Always Running
388 		* Memory Burst length: 8
389 		* Number of chips: 1
390 		* Memory Bus width: 32 bit
391 		* Memory Type: DDR3
392 		* Additional Latancy for PLL: 0 Cycle
393 		*/
394 		.memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
395 			DMC_MEMCONTROL_DPWRDN_DISABLE |
396 			DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
397 			DMC_MEMCONTROL_TP_DISABLE |
398 			DMC_MEMCONTROL_DSREF_ENABLE |
399 			DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
400 			DMC_MEMCONTROL_MEM_TYPE_DDR3 |
401 			DMC_MEMCONTROL_MEM_WIDTH_32BIT |
402 			DMC_MEMCONTROL_NUM_CHIP_1 |
403 			DMC_MEMCONTROL_BL_8 |
404 			DMC_MEMCONTROL_PZQ_DISABLE |
405 			DMC_MEMCONTROL_MRR_BYTE_7_0,
406 		.memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED |
407 			DMC_MEMCONFIGx_CHIP_COL_10 |
408 			DMC_MEMCONFIGx_CHIP_ROW_15 |
409 			DMC_MEMCONFIGx_CHIP_BANK_8,
410 		.membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
411 		.membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
412 		.prechconfig_tp_cnt = 0xff,
413 		.dpwrdn_cyc = 0xff,
414 		.dsref_cyc = 0xffff,
415 		.concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
416 			DMC_CONCONTROL_TIMEOUT_LEVEL0 |
417 			DMC_CONCONTROL_RD_FETCH_DISABLE |
418 			DMC_CONCONTROL_EMPTY_DISABLE |
419 			DMC_CONCONTROL_AREF_EN_DISABLE |
420 			DMC_CONCONTROL_IO_PD_CON_DISABLE,
421 		.dmc_channels = 2,
422 		.chips_per_channel = 2,
423 		.chips_to_configure = 1,
424 		.send_zq_init = 1,
425 		.impedance = IMP_OUTPUT_DRV_40_OHM,
426 		.gate_leveling_enable = 1,
427 	}
428 };
429 
430 #define BOARD_ID0_GPIO	88	/* GPD0, pin 0 */
431 #define BOARD_ID1_GPIO	89	/* GPD0, pin 1 */
432 
433 enum board_config {
434 	DAISY_CONFIG_UNKNOWN = -1,
435 	DAISY_CONFIG_SAMSUNG_EVT,
436 	DAISY_CONFIG_ELPIDA_EVT,
437 	DAISY_CONFIG_SAMSUNG_DVT,
438 	DAISY_CONFIG_ELPIDA_DVT,
439 	DAISY_CONFIG_SAMSUNG_PVT,
440 	DAISY_CONFIG_ELPIDA_PVT,
441 	DAISY_CONFIG_SAMSUNG_MP,
442 	DAISY_CONFIG_ELPIDA_MP,
443 	DAISY_CONFIG_RSVD,
444 };
445 
446 struct {
447 	enum mvl3 id0, id1;
448 	enum board_config config;
449 } id_map[] = {
450 	/*  ID0      ID1         config */
451 	{ LOGIC_0, LOGIC_0, DAISY_CONFIG_SAMSUNG_MP },
452 	{ LOGIC_0, LOGIC_1, DAISY_CONFIG_ELPIDA_MP },
453 	{ LOGIC_1, LOGIC_0, DAISY_CONFIG_SAMSUNG_DVT },
454 	{ LOGIC_1, LOGIC_1, DAISY_CONFIG_ELPIDA_DVT },
455 	{ LOGIC_0, LOGIC_Z, DAISY_CONFIG_SAMSUNG_PVT },
456 	{ LOGIC_1, LOGIC_Z, DAISY_CONFIG_ELPIDA_PVT },
457 	{ LOGIC_Z, LOGIC_0, DAISY_CONFIG_SAMSUNG_MP },
458 	{ LOGIC_Z, LOGIC_Z, DAISY_CONFIG_ELPIDA_MP },
459 	{ LOGIC_Z, LOGIC_1, DAISY_CONFIG_RSVD },
460 };
461 
board_get_config(void)462 static int board_get_config(void)
463 {
464 	int i;
465 	int id0, id1;
466 	enum board_config config = DAISY_CONFIG_UNKNOWN;
467 
468 	id0 = gpio_read_mvl3(BOARD_ID0_GPIO);
469 	id1 = gpio_read_mvl3(BOARD_ID1_GPIO);
470 	if (id0 < 0 || id1 < 0)
471 		return -1;
472 
473 	for (i = 0; i < ARRAY_SIZE(id_map); i++) {
474 		if (id0 == id_map[i].id0 && id1 == id_map[i].id1) {
475 			config = id_map[i].config;
476 			break;
477 		}
478 	}
479 
480 	return config;
481 }
482 
get_mem_timings(void)483 struct mem_timings *get_mem_timings(void)
484 {
485 	int i;
486 	enum board_config config;
487 	enum ddr_mode mem_type;
488 	unsigned int frequency_mhz;
489 	enum mem_manuf mem_manuf;
490 	const struct mem_timings *mem;
491 
492 	config = board_get_config();
493 	switch (config) {
494 	case DAISY_CONFIG_ELPIDA_EVT:
495 	case DAISY_CONFIG_ELPIDA_DVT:
496 	case DAISY_CONFIG_ELPIDA_PVT:
497 	case DAISY_CONFIG_ELPIDA_MP:
498 		mem_manuf = MEM_MANUF_ELPIDA;
499 		mem_type = DDR_MODE_DDR3;
500 		frequency_mhz = 800;
501 		break;
502 	case DAISY_CONFIG_SAMSUNG_EVT:
503 	case DAISY_CONFIG_SAMSUNG_DVT:
504 	case DAISY_CONFIG_SAMSUNG_PVT:
505 	case DAISY_CONFIG_SAMSUNG_MP:
506 		mem_manuf = MEM_MANUF_SAMSUNG;
507 		mem_type = DDR_MODE_DDR3;
508 		frequency_mhz = 800;
509 		break;
510 	default:
511 		printk(BIOS_CRIT, "Unknown board configuration.\n");
512 		return NULL;
513 	}
514 
515 	for (i = 0, mem = mem_timings; i < ARRAY_SIZE(mem_timings);
516 			i++, mem++) {
517 		if (mem->mem_type == mem_type &&
518 			mem->frequency_mhz == frequency_mhz &&
519 			mem->mem_manuf == mem_manuf)
520 			return (struct mem_timings *)mem;
521 	}
522 
523 	return NULL;
524 }
525