xref: /openbmc/u-boot/drivers/ddr/fsl/options.c (revision 2838c07f)
1 /*
2  * Copyright 2008, 2010-2014 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <hwconfig.h>
9 #include <fsl_ddr_sdram.h>
10 
11 #include <fsl_ddr.h>
12 
13 /*
14  * Use our own stack based buffer before relocation to allow accessing longer
15  * hwconfig strings that might be in the environment before we've relocated.
16  * This is pretty fragile on both the use of stack and if the buffer is big
17  * enough. However we will get a warning from getenv_f for the later.
18  */
19 
20 /* Board-specific functions defined in each board's ddr.c */
21 extern void fsl_ddr_board_options(memctl_options_t *popts,
22 		dimm_params_t *pdimm,
23 		unsigned int ctrl_num);
24 
25 struct dynamic_odt {
26 	unsigned int odt_rd_cfg;
27 	unsigned int odt_wr_cfg;
28 	unsigned int odt_rtt_norm;
29 	unsigned int odt_rtt_wr;
30 };
31 
32 #ifdef CONFIG_SYS_FSL_DDR4
33 /* Quad rank is not verified yet due availability.
34  * Replacing 20 OHM with 34 OHM since DDR4 doesn't have 20 OHM option
35  */
36 static __maybe_unused const struct dynamic_odt single_Q[4] = {
37 	{	/* cs0 */
38 		FSL_DDR_ODT_NEVER,
39 		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
40 		DDR4_RTT_34_OHM,	/* unverified */
41 		DDR4_RTT_120_OHM
42 	},
43 	{	/* cs1 */
44 		FSL_DDR_ODT_NEVER,
45 		FSL_DDR_ODT_NEVER,
46 		DDR4_RTT_OFF,
47 		DDR4_RTT_120_OHM
48 	},
49 	{	/* cs2 */
50 		FSL_DDR_ODT_NEVER,
51 		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
52 		DDR4_RTT_34_OHM,
53 		DDR4_RTT_120_OHM
54 	},
55 	{	/* cs3 */
56 		FSL_DDR_ODT_NEVER,
57 		FSL_DDR_ODT_NEVER,	/* tied high */
58 		DDR4_RTT_OFF,
59 		DDR4_RTT_120_OHM
60 	}
61 };
62 
63 static __maybe_unused const struct dynamic_odt single_D[4] = {
64 	{	/* cs0 */
65 		FSL_DDR_ODT_NEVER,
66 		FSL_DDR_ODT_ALL,
67 		DDR4_RTT_40_OHM,
68 		DDR4_RTT_OFF
69 	},
70 	{	/* cs1 */
71 		FSL_DDR_ODT_NEVER,
72 		FSL_DDR_ODT_NEVER,
73 		DDR4_RTT_OFF,
74 		DDR4_RTT_OFF
75 	},
76 	{0, 0, 0, 0},
77 	{0, 0, 0, 0}
78 };
79 
80 static __maybe_unused const struct dynamic_odt single_S[4] = {
81 	{	/* cs0 */
82 		FSL_DDR_ODT_NEVER,
83 		FSL_DDR_ODT_ALL,
84 		DDR4_RTT_40_OHM,
85 		DDR4_RTT_OFF
86 	},
87 	{0, 0, 0, 0},
88 	{0, 0, 0, 0},
89 	{0, 0, 0, 0},
90 };
91 
92 static __maybe_unused const struct dynamic_odt dual_DD[4] = {
93 	{	/* cs0 */
94 		FSL_DDR_ODT_NEVER,
95 		FSL_DDR_ODT_SAME_DIMM,
96 		DDR4_RTT_120_OHM,
97 		DDR4_RTT_OFF
98 	},
99 	{	/* cs1 */
100 		FSL_DDR_ODT_OTHER_DIMM,
101 		FSL_DDR_ODT_OTHER_DIMM,
102 		DDR4_RTT_34_OHM,
103 		DDR4_RTT_OFF
104 	},
105 	{	/* cs2 */
106 		FSL_DDR_ODT_NEVER,
107 		FSL_DDR_ODT_SAME_DIMM,
108 		DDR4_RTT_120_OHM,
109 		DDR4_RTT_OFF
110 	},
111 	{	/* cs3 */
112 		FSL_DDR_ODT_OTHER_DIMM,
113 		FSL_DDR_ODT_OTHER_DIMM,
114 		DDR4_RTT_34_OHM,
115 		DDR4_RTT_OFF
116 	}
117 };
118 
119 static __maybe_unused const struct dynamic_odt dual_DS[4] = {
120 	{	/* cs0 */
121 		FSL_DDR_ODT_NEVER,
122 		FSL_DDR_ODT_SAME_DIMM,
123 		DDR4_RTT_120_OHM,
124 		DDR4_RTT_OFF
125 	},
126 	{	/* cs1 */
127 		FSL_DDR_ODT_OTHER_DIMM,
128 		FSL_DDR_ODT_OTHER_DIMM,
129 		DDR4_RTT_34_OHM,
130 		DDR4_RTT_OFF
131 	},
132 	{	/* cs2 */
133 		FSL_DDR_ODT_OTHER_DIMM,
134 		FSL_DDR_ODT_ALL,
135 		DDR4_RTT_34_OHM,
136 		DDR4_RTT_120_OHM
137 	},
138 	{0, 0, 0, 0}
139 };
140 static __maybe_unused const struct dynamic_odt dual_SD[4] = {
141 	{	/* cs0 */
142 		FSL_DDR_ODT_OTHER_DIMM,
143 		FSL_DDR_ODT_ALL,
144 		DDR4_RTT_34_OHM,
145 		DDR4_RTT_120_OHM
146 	},
147 	{0, 0, 0, 0},
148 	{	/* cs2 */
149 		FSL_DDR_ODT_NEVER,
150 		FSL_DDR_ODT_SAME_DIMM,
151 		DDR4_RTT_120_OHM,
152 		DDR4_RTT_OFF
153 	},
154 	{	/* cs3 */
155 		FSL_DDR_ODT_OTHER_DIMM,
156 		FSL_DDR_ODT_OTHER_DIMM,
157 		DDR4_RTT_34_OHM,
158 		DDR4_RTT_OFF
159 	}
160 };
161 
162 static __maybe_unused const struct dynamic_odt dual_SS[4] = {
163 	{	/* cs0 */
164 		FSL_DDR_ODT_OTHER_DIMM,
165 		FSL_DDR_ODT_ALL,
166 		DDR4_RTT_34_OHM,
167 		DDR4_RTT_120_OHM
168 	},
169 	{0, 0, 0, 0},
170 	{	/* cs2 */
171 		FSL_DDR_ODT_OTHER_DIMM,
172 		FSL_DDR_ODT_ALL,
173 		DDR4_RTT_34_OHM,
174 		DDR4_RTT_120_OHM
175 	},
176 	{0, 0, 0, 0}
177 };
178 
179 static __maybe_unused const struct dynamic_odt dual_D0[4] = {
180 	{	/* cs0 */
181 		FSL_DDR_ODT_NEVER,
182 		FSL_DDR_ODT_SAME_DIMM,
183 		DDR4_RTT_40_OHM,
184 		DDR4_RTT_OFF
185 	},
186 	{	/* cs1 */
187 		FSL_DDR_ODT_NEVER,
188 		FSL_DDR_ODT_NEVER,
189 		DDR4_RTT_OFF,
190 		DDR4_RTT_OFF
191 	},
192 	{0, 0, 0, 0},
193 	{0, 0, 0, 0}
194 };
195 
196 static __maybe_unused const struct dynamic_odt dual_0D[4] = {
197 	{0, 0, 0, 0},
198 	{0, 0, 0, 0},
199 	{	/* cs2 */
200 		FSL_DDR_ODT_NEVER,
201 		FSL_DDR_ODT_SAME_DIMM,
202 		DDR4_RTT_40_OHM,
203 		DDR4_RTT_OFF
204 	},
205 	{	/* cs3 */
206 		FSL_DDR_ODT_NEVER,
207 		FSL_DDR_ODT_NEVER,
208 		DDR4_RTT_OFF,
209 		DDR4_RTT_OFF
210 	}
211 };
212 
213 static __maybe_unused const struct dynamic_odt dual_S0[4] = {
214 	{	/* cs0 */
215 		FSL_DDR_ODT_NEVER,
216 		FSL_DDR_ODT_CS,
217 		DDR4_RTT_40_OHM,
218 		DDR4_RTT_OFF
219 	},
220 	{0, 0, 0, 0},
221 	{0, 0, 0, 0},
222 	{0, 0, 0, 0}
223 
224 };
225 
226 static __maybe_unused const struct dynamic_odt dual_0S[4] = {
227 	{0, 0, 0, 0},
228 	{0, 0, 0, 0},
229 	{	/* cs2 */
230 		FSL_DDR_ODT_NEVER,
231 		FSL_DDR_ODT_CS,
232 		DDR4_RTT_40_OHM,
233 		DDR4_RTT_OFF
234 	},
235 	{0, 0, 0, 0}
236 
237 };
238 
239 static __maybe_unused const struct dynamic_odt odt_unknown[4] = {
240 	{	/* cs0 */
241 		FSL_DDR_ODT_NEVER,
242 		FSL_DDR_ODT_CS,
243 		DDR4_RTT_120_OHM,
244 		DDR4_RTT_OFF
245 	},
246 	{	/* cs1 */
247 		FSL_DDR_ODT_NEVER,
248 		FSL_DDR_ODT_CS,
249 		DDR4_RTT_120_OHM,
250 		DDR4_RTT_OFF
251 	},
252 	{	/* cs2 */
253 		FSL_DDR_ODT_NEVER,
254 		FSL_DDR_ODT_CS,
255 		DDR4_RTT_120_OHM,
256 		DDR4_RTT_OFF
257 	},
258 	{	/* cs3 */
259 		FSL_DDR_ODT_NEVER,
260 		FSL_DDR_ODT_CS,
261 		DDR4_RTT_120_OHM,
262 		DDR4_RTT_OFF
263 	}
264 };
265 #elif defined(CONFIG_SYS_FSL_DDR3)
266 static __maybe_unused const struct dynamic_odt single_Q[4] = {
267 	{	/* cs0 */
268 		FSL_DDR_ODT_NEVER,
269 		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
270 		DDR3_RTT_20_OHM,
271 		DDR3_RTT_120_OHM
272 	},
273 	{	/* cs1 */
274 		FSL_DDR_ODT_NEVER,
275 		FSL_DDR_ODT_NEVER,	/* tied high */
276 		DDR3_RTT_OFF,
277 		DDR3_RTT_120_OHM
278 	},
279 	{	/* cs2 */
280 		FSL_DDR_ODT_NEVER,
281 		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
282 		DDR3_RTT_20_OHM,
283 		DDR3_RTT_120_OHM
284 	},
285 	{	/* cs3 */
286 		FSL_DDR_ODT_NEVER,
287 		FSL_DDR_ODT_NEVER,	/* tied high */
288 		DDR3_RTT_OFF,
289 		DDR3_RTT_120_OHM
290 	}
291 };
292 
293 static __maybe_unused const struct dynamic_odt single_D[4] = {
294 	{	/* cs0 */
295 		FSL_DDR_ODT_NEVER,
296 		FSL_DDR_ODT_ALL,
297 		DDR3_RTT_40_OHM,
298 		DDR3_RTT_OFF
299 	},
300 	{	/* cs1 */
301 		FSL_DDR_ODT_NEVER,
302 		FSL_DDR_ODT_NEVER,
303 		DDR3_RTT_OFF,
304 		DDR3_RTT_OFF
305 	},
306 	{0, 0, 0, 0},
307 	{0, 0, 0, 0}
308 };
309 
310 static __maybe_unused const struct dynamic_odt single_S[4] = {
311 	{	/* cs0 */
312 		FSL_DDR_ODT_NEVER,
313 		FSL_DDR_ODT_ALL,
314 		DDR3_RTT_40_OHM,
315 		DDR3_RTT_OFF
316 	},
317 	{0, 0, 0, 0},
318 	{0, 0, 0, 0},
319 	{0, 0, 0, 0},
320 };
321 
322 static __maybe_unused const struct dynamic_odt dual_DD[4] = {
323 	{	/* cs0 */
324 		FSL_DDR_ODT_NEVER,
325 		FSL_DDR_ODT_SAME_DIMM,
326 		DDR3_RTT_120_OHM,
327 		DDR3_RTT_OFF
328 	},
329 	{	/* cs1 */
330 		FSL_DDR_ODT_OTHER_DIMM,
331 		FSL_DDR_ODT_OTHER_DIMM,
332 		DDR3_RTT_30_OHM,
333 		DDR3_RTT_OFF
334 	},
335 	{	/* cs2 */
336 		FSL_DDR_ODT_NEVER,
337 		FSL_DDR_ODT_SAME_DIMM,
338 		DDR3_RTT_120_OHM,
339 		DDR3_RTT_OFF
340 	},
341 	{	/* cs3 */
342 		FSL_DDR_ODT_OTHER_DIMM,
343 		FSL_DDR_ODT_OTHER_DIMM,
344 		DDR3_RTT_30_OHM,
345 		DDR3_RTT_OFF
346 	}
347 };
348 
349 static __maybe_unused const struct dynamic_odt dual_DS[4] = {
350 	{	/* cs0 */
351 		FSL_DDR_ODT_NEVER,
352 		FSL_DDR_ODT_SAME_DIMM,
353 		DDR3_RTT_120_OHM,
354 		DDR3_RTT_OFF
355 	},
356 	{	/* cs1 */
357 		FSL_DDR_ODT_OTHER_DIMM,
358 		FSL_DDR_ODT_OTHER_DIMM,
359 		DDR3_RTT_30_OHM,
360 		DDR3_RTT_OFF
361 	},
362 	{	/* cs2 */
363 		FSL_DDR_ODT_OTHER_DIMM,
364 		FSL_DDR_ODT_ALL,
365 		DDR3_RTT_20_OHM,
366 		DDR3_RTT_120_OHM
367 	},
368 	{0, 0, 0, 0}
369 };
370 static __maybe_unused const struct dynamic_odt dual_SD[4] = {
371 	{	/* cs0 */
372 		FSL_DDR_ODT_OTHER_DIMM,
373 		FSL_DDR_ODT_ALL,
374 		DDR3_RTT_20_OHM,
375 		DDR3_RTT_120_OHM
376 	},
377 	{0, 0, 0, 0},
378 	{	/* cs2 */
379 		FSL_DDR_ODT_NEVER,
380 		FSL_DDR_ODT_SAME_DIMM,
381 		DDR3_RTT_120_OHM,
382 		DDR3_RTT_OFF
383 	},
384 	{	/* cs3 */
385 		FSL_DDR_ODT_OTHER_DIMM,
386 		FSL_DDR_ODT_OTHER_DIMM,
387 		DDR3_RTT_20_OHM,
388 		DDR3_RTT_OFF
389 	}
390 };
391 
392 static __maybe_unused const struct dynamic_odt dual_SS[4] = {
393 	{	/* cs0 */
394 		FSL_DDR_ODT_OTHER_DIMM,
395 		FSL_DDR_ODT_ALL,
396 		DDR3_RTT_30_OHM,
397 		DDR3_RTT_120_OHM
398 	},
399 	{0, 0, 0, 0},
400 	{	/* cs2 */
401 		FSL_DDR_ODT_OTHER_DIMM,
402 		FSL_DDR_ODT_ALL,
403 		DDR3_RTT_30_OHM,
404 		DDR3_RTT_120_OHM
405 	},
406 	{0, 0, 0, 0}
407 };
408 
409 static __maybe_unused const struct dynamic_odt dual_D0[4] = {
410 	{	/* cs0 */
411 		FSL_DDR_ODT_NEVER,
412 		FSL_DDR_ODT_SAME_DIMM,
413 		DDR3_RTT_40_OHM,
414 		DDR3_RTT_OFF
415 	},
416 	{	/* cs1 */
417 		FSL_DDR_ODT_NEVER,
418 		FSL_DDR_ODT_NEVER,
419 		DDR3_RTT_OFF,
420 		DDR3_RTT_OFF
421 	},
422 	{0, 0, 0, 0},
423 	{0, 0, 0, 0}
424 };
425 
426 static __maybe_unused const struct dynamic_odt dual_0D[4] = {
427 	{0, 0, 0, 0},
428 	{0, 0, 0, 0},
429 	{	/* cs2 */
430 		FSL_DDR_ODT_NEVER,
431 		FSL_DDR_ODT_SAME_DIMM,
432 		DDR3_RTT_40_OHM,
433 		DDR3_RTT_OFF
434 	},
435 	{	/* cs3 */
436 		FSL_DDR_ODT_NEVER,
437 		FSL_DDR_ODT_NEVER,
438 		DDR3_RTT_OFF,
439 		DDR3_RTT_OFF
440 	}
441 };
442 
443 static __maybe_unused const struct dynamic_odt dual_S0[4] = {
444 	{	/* cs0 */
445 		FSL_DDR_ODT_NEVER,
446 		FSL_DDR_ODT_CS,
447 		DDR3_RTT_40_OHM,
448 		DDR3_RTT_OFF
449 	},
450 	{0, 0, 0, 0},
451 	{0, 0, 0, 0},
452 	{0, 0, 0, 0}
453 
454 };
455 
456 static __maybe_unused const struct dynamic_odt dual_0S[4] = {
457 	{0, 0, 0, 0},
458 	{0, 0, 0, 0},
459 	{	/* cs2 */
460 		FSL_DDR_ODT_NEVER,
461 		FSL_DDR_ODT_CS,
462 		DDR3_RTT_40_OHM,
463 		DDR3_RTT_OFF
464 	},
465 	{0, 0, 0, 0}
466 
467 };
468 
469 static __maybe_unused const struct dynamic_odt odt_unknown[4] = {
470 	{	/* cs0 */
471 		FSL_DDR_ODT_NEVER,
472 		FSL_DDR_ODT_CS,
473 		DDR3_RTT_120_OHM,
474 		DDR3_RTT_OFF
475 	},
476 	{	/* cs1 */
477 		FSL_DDR_ODT_NEVER,
478 		FSL_DDR_ODT_CS,
479 		DDR3_RTT_120_OHM,
480 		DDR3_RTT_OFF
481 	},
482 	{	/* cs2 */
483 		FSL_DDR_ODT_NEVER,
484 		FSL_DDR_ODT_CS,
485 		DDR3_RTT_120_OHM,
486 		DDR3_RTT_OFF
487 	},
488 	{	/* cs3 */
489 		FSL_DDR_ODT_NEVER,
490 		FSL_DDR_ODT_CS,
491 		DDR3_RTT_120_OHM,
492 		DDR3_RTT_OFF
493 	}
494 };
495 #else	/* CONFIG_SYS_FSL_DDR3 */
496 static __maybe_unused const struct dynamic_odt single_Q[4] = {
497 	{0, 0, 0, 0},
498 	{0, 0, 0, 0},
499 	{0, 0, 0, 0},
500 	{0, 0, 0, 0}
501 };
502 
503 static __maybe_unused const struct dynamic_odt single_D[4] = {
504 	{	/* cs0 */
505 		FSL_DDR_ODT_NEVER,
506 		FSL_DDR_ODT_ALL,
507 		DDR2_RTT_150_OHM,
508 		DDR2_RTT_OFF
509 	},
510 	{	/* cs1 */
511 		FSL_DDR_ODT_NEVER,
512 		FSL_DDR_ODT_NEVER,
513 		DDR2_RTT_OFF,
514 		DDR2_RTT_OFF
515 	},
516 	{0, 0, 0, 0},
517 	{0, 0, 0, 0}
518 };
519 
520 static __maybe_unused const struct dynamic_odt single_S[4] = {
521 	{	/* cs0 */
522 		FSL_DDR_ODT_NEVER,
523 		FSL_DDR_ODT_ALL,
524 		DDR2_RTT_150_OHM,
525 		DDR2_RTT_OFF
526 	},
527 	{0, 0, 0, 0},
528 	{0, 0, 0, 0},
529 	{0, 0, 0, 0},
530 };
531 
532 static __maybe_unused const struct dynamic_odt dual_DD[4] = {
533 	{	/* cs0 */
534 		FSL_DDR_ODT_OTHER_DIMM,
535 		FSL_DDR_ODT_OTHER_DIMM,
536 		DDR2_RTT_75_OHM,
537 		DDR2_RTT_OFF
538 	},
539 	{	/* cs1 */
540 		FSL_DDR_ODT_NEVER,
541 		FSL_DDR_ODT_NEVER,
542 		DDR2_RTT_OFF,
543 		DDR2_RTT_OFF
544 	},
545 	{	/* cs2 */
546 		FSL_DDR_ODT_OTHER_DIMM,
547 		FSL_DDR_ODT_OTHER_DIMM,
548 		DDR2_RTT_75_OHM,
549 		DDR2_RTT_OFF
550 	},
551 	{	/* cs3 */
552 		FSL_DDR_ODT_NEVER,
553 		FSL_DDR_ODT_NEVER,
554 		DDR2_RTT_OFF,
555 		DDR2_RTT_OFF
556 	}
557 };
558 
559 static __maybe_unused const struct dynamic_odt dual_DS[4] = {
560 	{	/* cs0 */
561 		FSL_DDR_ODT_OTHER_DIMM,
562 		FSL_DDR_ODT_OTHER_DIMM,
563 		DDR2_RTT_75_OHM,
564 		DDR2_RTT_OFF
565 	},
566 	{	/* cs1 */
567 		FSL_DDR_ODT_NEVER,
568 		FSL_DDR_ODT_NEVER,
569 		DDR2_RTT_OFF,
570 		DDR2_RTT_OFF
571 	},
572 	{	/* cs2 */
573 		FSL_DDR_ODT_OTHER_DIMM,
574 		FSL_DDR_ODT_OTHER_DIMM,
575 		DDR2_RTT_75_OHM,
576 		DDR2_RTT_OFF
577 	},
578 	{0, 0, 0, 0}
579 };
580 
581 static __maybe_unused const struct dynamic_odt dual_SD[4] = {
582 	{	/* cs0 */
583 		FSL_DDR_ODT_OTHER_DIMM,
584 		FSL_DDR_ODT_OTHER_DIMM,
585 		DDR2_RTT_75_OHM,
586 		DDR2_RTT_OFF
587 	},
588 	{0, 0, 0, 0},
589 	{	/* cs2 */
590 		FSL_DDR_ODT_OTHER_DIMM,
591 		FSL_DDR_ODT_OTHER_DIMM,
592 		DDR2_RTT_75_OHM,
593 		DDR2_RTT_OFF
594 	},
595 	{	/* cs3 */
596 		FSL_DDR_ODT_NEVER,
597 		FSL_DDR_ODT_NEVER,
598 		DDR2_RTT_OFF,
599 		DDR2_RTT_OFF
600 	}
601 };
602 
603 static __maybe_unused const struct dynamic_odt dual_SS[4] = {
604 	{	/* cs0 */
605 		FSL_DDR_ODT_OTHER_DIMM,
606 		FSL_DDR_ODT_OTHER_DIMM,
607 		DDR2_RTT_75_OHM,
608 		DDR2_RTT_OFF
609 	},
610 	{0, 0, 0, 0},
611 	{	/* cs2 */
612 		FSL_DDR_ODT_OTHER_DIMM,
613 		FSL_DDR_ODT_OTHER_DIMM,
614 		DDR2_RTT_75_OHM,
615 		DDR2_RTT_OFF
616 	},
617 	{0, 0, 0, 0}
618 };
619 
620 static __maybe_unused const struct dynamic_odt dual_D0[4] = {
621 	{	/* cs0 */
622 		FSL_DDR_ODT_NEVER,
623 		FSL_DDR_ODT_ALL,
624 		DDR2_RTT_150_OHM,
625 		DDR2_RTT_OFF
626 	},
627 	{	/* cs1 */
628 		FSL_DDR_ODT_NEVER,
629 		FSL_DDR_ODT_NEVER,
630 		DDR2_RTT_OFF,
631 		DDR2_RTT_OFF
632 	},
633 	{0, 0, 0, 0},
634 	{0, 0, 0, 0}
635 };
636 
637 static __maybe_unused const struct dynamic_odt dual_0D[4] = {
638 	{0, 0, 0, 0},
639 	{0, 0, 0, 0},
640 	{	/* cs2 */
641 		FSL_DDR_ODT_NEVER,
642 		FSL_DDR_ODT_ALL,
643 		DDR2_RTT_150_OHM,
644 		DDR2_RTT_OFF
645 	},
646 	{	/* cs3 */
647 		FSL_DDR_ODT_NEVER,
648 		FSL_DDR_ODT_NEVER,
649 		DDR2_RTT_OFF,
650 		DDR2_RTT_OFF
651 	}
652 };
653 
654 static __maybe_unused const struct dynamic_odt dual_S0[4] = {
655 	{	/* cs0 */
656 		FSL_DDR_ODT_NEVER,
657 		FSL_DDR_ODT_CS,
658 		DDR2_RTT_150_OHM,
659 		DDR2_RTT_OFF
660 	},
661 	{0, 0, 0, 0},
662 	{0, 0, 0, 0},
663 	{0, 0, 0, 0}
664 
665 };
666 
667 static __maybe_unused const struct dynamic_odt dual_0S[4] = {
668 	{0, 0, 0, 0},
669 	{0, 0, 0, 0},
670 	{	/* cs2 */
671 		FSL_DDR_ODT_NEVER,
672 		FSL_DDR_ODT_CS,
673 		DDR2_RTT_150_OHM,
674 		DDR2_RTT_OFF
675 	},
676 	{0, 0, 0, 0}
677 
678 };
679 
680 static __maybe_unused const struct dynamic_odt odt_unknown[4] = {
681 	{	/* cs0 */
682 		FSL_DDR_ODT_NEVER,
683 		FSL_DDR_ODT_CS,
684 		DDR2_RTT_75_OHM,
685 		DDR2_RTT_OFF
686 	},
687 	{	/* cs1 */
688 		FSL_DDR_ODT_NEVER,
689 		FSL_DDR_ODT_NEVER,
690 		DDR2_RTT_OFF,
691 		DDR2_RTT_OFF
692 	},
693 	{	/* cs2 */
694 		FSL_DDR_ODT_NEVER,
695 		FSL_DDR_ODT_CS,
696 		DDR2_RTT_75_OHM,
697 		DDR2_RTT_OFF
698 	},
699 	{	/* cs3 */
700 		FSL_DDR_ODT_NEVER,
701 		FSL_DDR_ODT_NEVER,
702 		DDR2_RTT_OFF,
703 		DDR2_RTT_OFF
704 	}
705 };
706 #endif
707 
708 /*
709  * Automatically seleect bank interleaving mode based on DIMMs
710  * in this order: cs0_cs1_cs2_cs3, cs0_cs1, null.
711  * This function only deal with one or two slots per controller.
712  */
713 static inline unsigned int auto_bank_intlv(dimm_params_t *pdimm)
714 {
715 #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
716 	if (pdimm[0].n_ranks == 4)
717 		return FSL_DDR_CS0_CS1_CS2_CS3;
718 	else if (pdimm[0].n_ranks == 2)
719 		return FSL_DDR_CS0_CS1;
720 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
721 #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
722 	if (pdimm[0].n_ranks == 4)
723 		return FSL_DDR_CS0_CS1_CS2_CS3;
724 #endif
725 	if (pdimm[0].n_ranks == 2) {
726 		if (pdimm[1].n_ranks == 2)
727 			return FSL_DDR_CS0_CS1_CS2_CS3;
728 		else
729 			return FSL_DDR_CS0_CS1;
730 	}
731 #endif
732 	return 0;
733 }
734 
735 unsigned int populate_memctl_options(const common_timing_params_t *common_dimm,
736 			memctl_options_t *popts,
737 			dimm_params_t *pdimm,
738 			unsigned int ctrl_num)
739 {
740 	unsigned int i;
741 	char buffer[HWCONFIG_BUFFER_SIZE];
742 	char *buf = NULL;
743 #if defined(CONFIG_SYS_FSL_DDR3) || \
744 	defined(CONFIG_SYS_FSL_DDR2) || \
745 	defined(CONFIG_SYS_FSL_DDR4)
746 	const struct dynamic_odt *pdodt = odt_unknown;
747 #endif
748 	ulong ddr_freq;
749 
750 	/*
751 	 * Extract hwconfig from environment since we have not properly setup
752 	 * the environment but need it for ddr config params
753 	 */
754 	if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
755 		buf = buffer;
756 
757 #if defined(CONFIG_SYS_FSL_DDR3) || \
758 	defined(CONFIG_SYS_FSL_DDR2) || \
759 	defined(CONFIG_SYS_FSL_DDR4)
760 	/* Chip select options. */
761 #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
762 	switch (pdimm[0].n_ranks) {
763 	case 1:
764 		pdodt = single_S;
765 		break;
766 	case 2:
767 		pdodt = single_D;
768 		break;
769 	case 4:
770 		pdodt = single_Q;
771 		break;
772 	}
773 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
774 	switch (pdimm[0].n_ranks) {
775 #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
776 	case 4:
777 		pdodt = single_Q;
778 		if (pdimm[1].n_ranks)
779 			printf("Error: Quad- and Dual-rank DIMMs cannot be used together\n");
780 		break;
781 #endif
782 	case 2:
783 		switch (pdimm[1].n_ranks) {
784 		case 2:
785 			pdodt = dual_DD;
786 			break;
787 		case 1:
788 			pdodt = dual_DS;
789 			break;
790 		case 0:
791 			pdodt = dual_D0;
792 			break;
793 		}
794 		break;
795 	case 1:
796 		switch (pdimm[1].n_ranks) {
797 		case 2:
798 			pdodt = dual_SD;
799 			break;
800 		case 1:
801 			pdodt = dual_SS;
802 			break;
803 		case 0:
804 			pdodt = dual_S0;
805 			break;
806 		}
807 		break;
808 	case 0:
809 		switch (pdimm[1].n_ranks) {
810 		case 2:
811 			pdodt = dual_0D;
812 			break;
813 		case 1:
814 			pdodt = dual_0S;
815 			break;
816 		}
817 		break;
818 	}
819 #endif	/* CONFIG_DIMM_SLOTS_PER_CTLR */
820 #endif	/* CONFIG_SYS_FSL_DDR2, 3, 4 */
821 
822 	/* Pick chip-select local options. */
823 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
824 #if defined(CONFIG_SYS_FSL_DDR3) || \
825 	defined(CONFIG_SYS_FSL_DDR2) || \
826 	defined(CONFIG_SYS_FSL_DDR4)
827 		popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg;
828 		popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg;
829 		popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm;
830 		popts->cs_local_opts[i].odt_rtt_wr = pdodt[i].odt_rtt_wr;
831 #else
832 		popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER;
833 		popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS;
834 #endif
835 		popts->cs_local_opts[i].auto_precharge = 0;
836 	}
837 
838 	/* Pick interleaving mode. */
839 
840 	/*
841 	 * 0 = no interleaving
842 	 * 1 = interleaving between 2 controllers
843 	 */
844 	popts->memctl_interleaving = 0;
845 
846 	/*
847 	 * 0 = cacheline
848 	 * 1 = page
849 	 * 2 = (logical) bank
850 	 * 3 = superbank (only if CS interleaving is enabled)
851 	 */
852 	popts->memctl_interleaving_mode = 0;
853 
854 	/*
855 	 * 0: cacheline: bit 30 of the 36-bit physical addr selects the memctl
856 	 * 1: page:      bit to the left of the column bits selects the memctl
857 	 * 2: bank:      bit to the left of the bank bits selects the memctl
858 	 * 3: superbank: bit to the left of the chip select selects the memctl
859 	 *
860 	 * NOTE: ba_intlv (rank interleaving) is independent of memory
861 	 * controller interleaving; it is only within a memory controller.
862 	 * Must use superbank interleaving if rank interleaving is used and
863 	 * memory controller interleaving is enabled.
864 	 */
865 
866 	/*
867 	 * 0 = no
868 	 * 0x40 = CS0,CS1
869 	 * 0x20 = CS2,CS3
870 	 * 0x60 = CS0,CS1 + CS2,CS3
871 	 * 0x04 = CS0,CS1,CS2,CS3
872 	 */
873 	popts->ba_intlv_ctl = 0;
874 
875 	/* Memory Organization Parameters */
876 	popts->registered_dimm_en = common_dimm->all_dimms_registered;
877 
878 	/* Operational Mode Paramters */
879 
880 	/* Pick ECC modes */
881 	popts->ecc_mode = 0;		  /* 0 = disabled, 1 = enabled */
882 #ifdef CONFIG_DDR_ECC
883 	if (hwconfig_sub_f("fsl_ddr", "ecc", buf)) {
884 		if (hwconfig_subarg_cmp_f("fsl_ddr", "ecc", "on", buf))
885 			popts->ecc_mode = 1;
886 	} else
887 		popts->ecc_mode = 1;
888 #endif
889 	/* 1 = use memory controler to init data */
890 	popts->ecc_init_using_memctl = popts->ecc_mode ? 1 : 0;
891 
892 	/*
893 	 * Choose DQS config
894 	 * 0 for DDR1
895 	 * 1 for DDR2
896 	 */
897 #if defined(CONFIG_SYS_FSL_DDR1)
898 	popts->dqs_config = 0;
899 #elif defined(CONFIG_SYS_FSL_DDR2) || defined(CONFIG_SYS_FSL_DDR3)
900 	popts->dqs_config = 1;
901 #endif
902 
903 	/* Choose self-refresh during sleep. */
904 	popts->self_refresh_in_sleep = 1;
905 
906 	/* Choose dynamic power management mode. */
907 	popts->dynamic_power = 0;
908 
909 	/*
910 	 * check first dimm for primary sdram width
911 	 * presuming all dimms are similar
912 	 * 0 = 64-bit, 1 = 32-bit, 2 = 16-bit
913 	 */
914 #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
915 	if (pdimm[0].n_ranks != 0) {
916 		if ((pdimm[0].data_width >= 64) && \
917 			(pdimm[0].data_width <= 72))
918 			popts->data_bus_width = 0;
919 		else if ((pdimm[0].data_width >= 32) && \
920 			(pdimm[0].data_width <= 40))
921 			popts->data_bus_width = 1;
922 		else {
923 			panic("Error: data width %u is invalid!\n",
924 				pdimm[0].data_width);
925 		}
926 	}
927 #else
928 	if (pdimm[0].n_ranks != 0) {
929 		if (pdimm[0].primary_sdram_width == 64)
930 			popts->data_bus_width = 0;
931 		else if (pdimm[0].primary_sdram_width == 32)
932 			popts->data_bus_width = 1;
933 		else if (pdimm[0].primary_sdram_width == 16)
934 			popts->data_bus_width = 2;
935 		else {
936 			panic("Error: primary sdram width %u is invalid!\n",
937 				pdimm[0].primary_sdram_width);
938 		}
939 	}
940 #endif
941 
942 	popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0;
943 
944 	/* Choose burst length. */
945 #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
946 #if defined(CONFIG_E500MC)
947 	popts->otf_burst_chop_en = 0;	/* on-the-fly burst chop disable */
948 	popts->burst_length = DDR_BL8;	/* Fixed 8-beat burst len */
949 #else
950 	if ((popts->data_bus_width == 1) || (popts->data_bus_width == 2)) {
951 		/* 32-bit or 16-bit bus */
952 		popts->otf_burst_chop_en = 0;
953 		popts->burst_length = DDR_BL8;
954 	} else {
955 		popts->otf_burst_chop_en = 1;	/* on-the-fly burst chop */
956 		popts->burst_length = DDR_OTF;	/* on-the-fly BC4 and BL8 */
957 	}
958 #endif
959 #else
960 	popts->burst_length = DDR_BL4;	/* has to be 4 for DDR2 */
961 #endif
962 
963 	/* Choose ddr controller address mirror mode */
964 #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
965 	for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
966 		if (pdimm[i].n_ranks) {
967 			popts->mirrored_dimm = pdimm[i].mirrored_dimm;
968 			break;
969 		}
970 	}
971 #endif
972 
973 	/* Global Timing Parameters. */
974 	debug("mclk_ps = %u ps\n", get_memory_clk_period_ps(ctrl_num));
975 
976 	/* Pick a caslat override. */
977 	popts->cas_latency_override = 0;
978 	popts->cas_latency_override_value = 3;
979 	if (popts->cas_latency_override) {
980 		debug("using caslat override value = %u\n",
981 		       popts->cas_latency_override_value);
982 	}
983 
984 	/* Decide whether to use the computed derated latency */
985 	popts->use_derated_caslat = 0;
986 
987 	/* Choose an additive latency. */
988 	popts->additive_latency_override = 0;
989 	popts->additive_latency_override_value = 3;
990 	if (popts->additive_latency_override) {
991 		debug("using additive latency override value = %u\n",
992 		       popts->additive_latency_override_value);
993 	}
994 
995 	/*
996 	 * 2T_EN setting
997 	 *
998 	 * Factors to consider for 2T_EN:
999 	 *	- number of DIMMs installed
1000 	 *	- number of components, number of active ranks
1001 	 *	- how much time you want to spend playing around
1002 	 */
1003 	popts->twot_en = 0;
1004 	popts->threet_en = 0;
1005 
1006 	/* for RDIMM and DDR4 UDIMM/discrete memory, address parity enable */
1007 	if (popts->registered_dimm_en)
1008 		popts->ap_en = 1; /* 0 = disable,  1 = enable */
1009 	else
1010 		popts->ap_en = 0; /* disabled for DDR4 UDIMM/discrete default */
1011 
1012 	if (hwconfig_sub_f("fsl_ddr", "parity", buf)) {
1013 		if (hwconfig_subarg_cmp_f("fsl_ddr", "parity", "on", buf)) {
1014 			if (popts->registered_dimm_en ||
1015 			    (CONFIG_FSL_SDRAM_TYPE == SDRAM_TYPE_DDR4))
1016 				popts->ap_en = 1;
1017 		}
1018 	}
1019 
1020 	/*
1021 	 * BSTTOPRE precharge interval
1022 	 *
1023 	 * Set this to 0 for global auto precharge
1024 	 * The value of 0x100 has been used for DDR1, DDR2, DDR3.
1025 	 * It is not wrong. Any value should be OK. The performance depends on
1026 	 * applications. There is no one good value for all. One way to set
1027 	 * is to use 1/4 of refint value.
1028 	 */
1029 	popts->bstopre = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps)
1030 			 >> 2;
1031 
1032 	/*
1033 	 * Window for four activates -- tFAW
1034 	 *
1035 	 * FIXME: UM: applies only to DDR2/DDR3 with eight logical banks only
1036 	 * FIXME: varies depending upon number of column addresses or data
1037 	 * FIXME: width, was considering looking at pdimm->primary_sdram_width
1038 	 */
1039 #if defined(CONFIG_SYS_FSL_DDR1)
1040 	popts->tfaw_window_four_activates_ps = mclk_to_picos(ctrl_num, 1);
1041 
1042 #elif defined(CONFIG_SYS_FSL_DDR2)
1043 	/*
1044 	 * x4/x8;  some datasheets have 35000
1045 	 * x16 wide columns only?  Use 50000?
1046 	 */
1047 	popts->tfaw_window_four_activates_ps = 37500;
1048 
1049 #else
1050 	popts->tfaw_window_four_activates_ps = pdimm[0].tfaw_ps;
1051 #endif
1052 	popts->zq_en = 0;
1053 	popts->wrlvl_en = 0;
1054 #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
1055 	/*
1056 	 * due to ddr3 dimm is fly-by topology
1057 	 * we suggest to enable write leveling to
1058 	 * meet the tQDSS under different loading.
1059 	 */
1060 	popts->wrlvl_en = 1;
1061 	popts->zq_en = 1;
1062 	popts->wrlvl_override = 0;
1063 #endif
1064 
1065 	/*
1066 	 * Check interleaving configuration from environment.
1067 	 * Please refer to doc/README.fsl-ddr for the detail.
1068 	 *
1069 	 * If memory controller interleaving is enabled, then the data
1070 	 * bus widths must be programmed identically for all memory controllers.
1071 	 *
1072 	 * Attempt to set all controllers to the same chip select
1073 	 * interleaving mode. It will do a best effort to get the
1074 	 * requested ranks interleaved together such that the result
1075 	 * should be a subset of the requested configuration.
1076 	 *
1077 	 * if CONFIG_SYS_FSL_DDR_INTLV_256B is defined, mandatory interleaving
1078 	 * with 256 Byte is enabled.
1079 	 */
1080 #if (CONFIG_SYS_NUM_DDR_CTLRS > 1)
1081 	if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf))
1082 #ifdef CONFIG_SYS_FSL_DDR_INTLV_256B
1083 		;
1084 #else
1085 		goto done;
1086 #endif
1087 	if (pdimm[0].n_ranks == 0) {
1088 		printf("There is no rank on CS0 for controller %d.\n", ctrl_num);
1089 		popts->memctl_interleaving = 0;
1090 		goto done;
1091 	}
1092 	popts->memctl_interleaving = 1;
1093 #ifdef CONFIG_SYS_FSL_DDR_INTLV_256B
1094 	popts->memctl_interleaving_mode = FSL_DDR_256B_INTERLEAVING;
1095 	popts->memctl_interleaving = 1;
1096 	debug("256 Byte interleaving\n");
1097 #else
1098 	/*
1099 	 * test null first. if CONFIG_HWCONFIG is not defined
1100 	 * hwconfig_arg_cmp returns non-zero
1101 	 */
1102 	if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
1103 				    "null", buf)) {
1104 		popts->memctl_interleaving = 0;
1105 		debug("memory controller interleaving disabled.\n");
1106 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1107 					"ctlr_intlv",
1108 					"cacheline", buf)) {
1109 		popts->memctl_interleaving_mode =
1110 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
1111 			0 : FSL_DDR_CACHE_LINE_INTERLEAVING;
1112 		popts->memctl_interleaving =
1113 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
1114 			0 : 1;
1115 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1116 					"ctlr_intlv",
1117 					"page", buf)) {
1118 		popts->memctl_interleaving_mode =
1119 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
1120 			0 : FSL_DDR_PAGE_INTERLEAVING;
1121 		popts->memctl_interleaving =
1122 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
1123 			0 : 1;
1124 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1125 					"ctlr_intlv",
1126 					"bank", buf)) {
1127 		popts->memctl_interleaving_mode =
1128 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
1129 			0 : FSL_DDR_BANK_INTERLEAVING;
1130 		popts->memctl_interleaving =
1131 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
1132 			0 : 1;
1133 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1134 					"ctlr_intlv",
1135 					"superbank", buf)) {
1136 		popts->memctl_interleaving_mode =
1137 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
1138 			0 : FSL_DDR_SUPERBANK_INTERLEAVING;
1139 		popts->memctl_interleaving =
1140 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
1141 			0 : 1;
1142 #if (CONFIG_SYS_NUM_DDR_CTLRS == 3)
1143 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1144 					"ctlr_intlv",
1145 					"3way_1KB", buf)) {
1146 		popts->memctl_interleaving_mode =
1147 			FSL_DDR_3WAY_1KB_INTERLEAVING;
1148 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1149 					"ctlr_intlv",
1150 					"3way_4KB", buf)) {
1151 		popts->memctl_interleaving_mode =
1152 			FSL_DDR_3WAY_4KB_INTERLEAVING;
1153 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1154 					"ctlr_intlv",
1155 					"3way_8KB", buf)) {
1156 		popts->memctl_interleaving_mode =
1157 			FSL_DDR_3WAY_8KB_INTERLEAVING;
1158 #elif (CONFIG_SYS_NUM_DDR_CTLRS == 4)
1159 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1160 					"ctlr_intlv",
1161 					"4way_1KB", buf)) {
1162 		popts->memctl_interleaving_mode =
1163 			FSL_DDR_4WAY_1KB_INTERLEAVING;
1164 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1165 					"ctlr_intlv",
1166 					"4way_4KB", buf)) {
1167 		popts->memctl_interleaving_mode =
1168 			FSL_DDR_4WAY_4KB_INTERLEAVING;
1169 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
1170 					"ctlr_intlv",
1171 					"4way_8KB", buf)) {
1172 		popts->memctl_interleaving_mode =
1173 			FSL_DDR_4WAY_8KB_INTERLEAVING;
1174 #endif
1175 	} else {
1176 		popts->memctl_interleaving = 0;
1177 		printf("hwconfig has unrecognized parameter for ctlr_intlv.\n");
1178 	}
1179 #endif	/* CONFIG_SYS_FSL_DDR_INTLV_256B */
1180 done:
1181 #endif /* CONFIG_SYS_NUM_DDR_CTLRS > 1 */
1182 	if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) &&
1183 		(CONFIG_CHIP_SELECTS_PER_CTRL > 1)) {
1184 		/* test null first. if CONFIG_HWCONFIG is not defined,
1185 		 * hwconfig_subarg_cmp_f returns non-zero */
1186 		if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
1187 					    "null", buf))
1188 			debug("bank interleaving disabled.\n");
1189 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
1190 						 "cs0_cs1", buf))
1191 			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1;
1192 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
1193 						 "cs2_cs3", buf))
1194 			popts->ba_intlv_ctl = FSL_DDR_CS2_CS3;
1195 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
1196 						 "cs0_cs1_and_cs2_cs3", buf))
1197 			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_AND_CS2_CS3;
1198 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
1199 						 "cs0_cs1_cs2_cs3", buf))
1200 			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3;
1201 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
1202 						"auto", buf))
1203 			popts->ba_intlv_ctl = auto_bank_intlv(pdimm);
1204 		else
1205 			printf("hwconfig has unrecognized parameter for bank_intlv.\n");
1206 		switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
1207 		case FSL_DDR_CS0_CS1_CS2_CS3:
1208 #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
1209 			if (pdimm[0].n_ranks < 4) {
1210 				popts->ba_intlv_ctl = 0;
1211 				printf("Not enough bank(chip-select) for "
1212 					"CS0+CS1+CS2+CS3 on controller %d, "
1213 					"interleaving disabled!\n", ctrl_num);
1214 			}
1215 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
1216 #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
1217 			if (pdimm[0].n_ranks == 4)
1218 				break;
1219 #endif
1220 			if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) {
1221 				popts->ba_intlv_ctl = 0;
1222 				printf("Not enough bank(chip-select) for "
1223 					"CS0+CS1+CS2+CS3 on controller %d, "
1224 					"interleaving disabled!\n", ctrl_num);
1225 			}
1226 			if (pdimm[0].capacity != pdimm[1].capacity) {
1227 				popts->ba_intlv_ctl = 0;
1228 				printf("Not identical DIMM size for "
1229 					"CS0+CS1+CS2+CS3 on controller %d, "
1230 					"interleaving disabled!\n", ctrl_num);
1231 			}
1232 #endif
1233 			break;
1234 		case FSL_DDR_CS0_CS1:
1235 			if (pdimm[0].n_ranks < 2) {
1236 				popts->ba_intlv_ctl = 0;
1237 				printf("Not enough bank(chip-select) for "
1238 					"CS0+CS1 on controller %d, "
1239 					"interleaving disabled!\n", ctrl_num);
1240 			}
1241 			break;
1242 		case FSL_DDR_CS2_CS3:
1243 #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
1244 			if (pdimm[0].n_ranks < 4) {
1245 				popts->ba_intlv_ctl = 0;
1246 				printf("Not enough bank(chip-select) for CS2+CS3 "
1247 					"on controller %d, interleaving disabled!\n", ctrl_num);
1248 			}
1249 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
1250 			if (pdimm[1].n_ranks < 2) {
1251 				popts->ba_intlv_ctl = 0;
1252 				printf("Not enough bank(chip-select) for CS2+CS3 "
1253 					"on controller %d, interleaving disabled!\n", ctrl_num);
1254 			}
1255 #endif
1256 			break;
1257 		case FSL_DDR_CS0_CS1_AND_CS2_CS3:
1258 #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
1259 			if (pdimm[0].n_ranks < 4) {
1260 				popts->ba_intlv_ctl = 0;
1261 				printf("Not enough bank(CS) for CS0+CS1 and "
1262 					"CS2+CS3 on controller %d, "
1263 					"interleaving disabled!\n", ctrl_num);
1264 			}
1265 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
1266 			if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) {
1267 				popts->ba_intlv_ctl = 0;
1268 				printf("Not enough bank(CS) for CS0+CS1 and "
1269 					"CS2+CS3 on controller %d, "
1270 					"interleaving disabled!\n", ctrl_num);
1271 			}
1272 #endif
1273 			break;
1274 		default:
1275 			popts->ba_intlv_ctl = 0;
1276 			break;
1277 		}
1278 	}
1279 
1280 	if (hwconfig_sub_f("fsl_ddr", "addr_hash", buf)) {
1281 		if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash", "null", buf))
1282 			popts->addr_hash = 0;
1283 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash",
1284 					       "true", buf))
1285 			popts->addr_hash = 1;
1286 	}
1287 
1288 	if (pdimm[0].n_ranks == 4)
1289 		popts->quad_rank_present = 1;
1290 
1291 	ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
1292 	if (popts->registered_dimm_en) {
1293 		popts->rcw_override = 1;
1294 		popts->rcw_1 = 0x000a5a00;
1295 		if (ddr_freq <= 800)
1296 			popts->rcw_2 = 0x00000000;
1297 		else if (ddr_freq <= 1066)
1298 			popts->rcw_2 = 0x00100000;
1299 		else if (ddr_freq <= 1333)
1300 			popts->rcw_2 = 0x00200000;
1301 		else
1302 			popts->rcw_2 = 0x00300000;
1303 	}
1304 
1305 	fsl_ddr_board_options(popts, pdimm, ctrl_num);
1306 
1307 	return 0;
1308 }
1309 
1310 void check_interleaving_options(fsl_ddr_info_t *pinfo)
1311 {
1312 	int i, j, k, check_n_ranks, intlv_invalid = 0;
1313 	unsigned int check_intlv, check_n_row_addr, check_n_col_addr;
1314 	unsigned long long check_rank_density;
1315 	struct dimm_params_s *dimm;
1316 	int first_ctrl = pinfo->first_ctrl;
1317 	int last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
1318 
1319 	/*
1320 	 * Check if all controllers are configured for memory
1321 	 * controller interleaving. Identical dimms are recommended. At least
1322 	 * the size, row and col address should be checked.
1323 	 */
1324 	j = 0;
1325 	check_n_ranks = pinfo->dimm_params[first_ctrl][0].n_ranks;
1326 	check_rank_density = pinfo->dimm_params[first_ctrl][0].rank_density;
1327 	check_n_row_addr =  pinfo->dimm_params[first_ctrl][0].n_row_addr;
1328 	check_n_col_addr = pinfo->dimm_params[first_ctrl][0].n_col_addr;
1329 	check_intlv = pinfo->memctl_opts[first_ctrl].memctl_interleaving_mode;
1330 	for (i = first_ctrl; i <= last_ctrl; i++) {
1331 		dimm = &pinfo->dimm_params[i][0];
1332 		if (!pinfo->memctl_opts[i].memctl_interleaving) {
1333 			continue;
1334 		} else if (((check_rank_density != dimm->rank_density) ||
1335 		     (check_n_ranks != dimm->n_ranks) ||
1336 		     (check_n_row_addr != dimm->n_row_addr) ||
1337 		     (check_n_col_addr != dimm->n_col_addr) ||
1338 		     (check_intlv !=
1339 			pinfo->memctl_opts[i].memctl_interleaving_mode))){
1340 			intlv_invalid = 1;
1341 			break;
1342 		} else {
1343 			j++;
1344 		}
1345 
1346 	}
1347 	if (intlv_invalid) {
1348 		for (i = first_ctrl; i <= last_ctrl; i++)
1349 			pinfo->memctl_opts[i].memctl_interleaving = 0;
1350 		printf("Not all DIMMs are identical. "
1351 			"Memory controller interleaving disabled.\n");
1352 	} else {
1353 		switch (check_intlv) {
1354 		case FSL_DDR_256B_INTERLEAVING:
1355 		case FSL_DDR_CACHE_LINE_INTERLEAVING:
1356 		case FSL_DDR_PAGE_INTERLEAVING:
1357 		case FSL_DDR_BANK_INTERLEAVING:
1358 		case FSL_DDR_SUPERBANK_INTERLEAVING:
1359 #if (3 == CONFIG_SYS_NUM_DDR_CTLRS)
1360 				k = 2;
1361 #else
1362 				k = CONFIG_SYS_NUM_DDR_CTLRS;
1363 #endif
1364 			break;
1365 		case FSL_DDR_3WAY_1KB_INTERLEAVING:
1366 		case FSL_DDR_3WAY_4KB_INTERLEAVING:
1367 		case FSL_DDR_3WAY_8KB_INTERLEAVING:
1368 		case FSL_DDR_4WAY_1KB_INTERLEAVING:
1369 		case FSL_DDR_4WAY_4KB_INTERLEAVING:
1370 		case FSL_DDR_4WAY_8KB_INTERLEAVING:
1371 		default:
1372 			k = CONFIG_SYS_NUM_DDR_CTLRS;
1373 			break;
1374 		}
1375 		debug("%d of %d controllers are interleaving.\n", j, k);
1376 		if (j && (j != k)) {
1377 			for (i = first_ctrl; i <= last_ctrl; i++)
1378 				pinfo->memctl_opts[i].memctl_interleaving = 0;
1379 			if ((last_ctrl - first_ctrl) > 1)
1380 				puts("Not all controllers have compatible interleaving mode. All disabled.\n");
1381 		}
1382 	}
1383 	debug("Checking interleaving options completed\n");
1384 }
1385 
1386 int fsl_use_spd(void)
1387 {
1388 	int use_spd = 0;
1389 
1390 #ifdef CONFIG_DDR_SPD
1391 	char buffer[HWCONFIG_BUFFER_SIZE];
1392 	char *buf = NULL;
1393 
1394 	/*
1395 	 * Extract hwconfig from environment since we have not properly setup
1396 	 * the environment but need it for ddr config params
1397 	 */
1398 	if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
1399 		buf = buffer;
1400 
1401 	/* if hwconfig is not enabled, or "sdram" is not defined, use spd */
1402 	if (hwconfig_sub_f("fsl_ddr", "sdram", buf)) {
1403 		if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram", "spd", buf))
1404 			use_spd = 1;
1405 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram",
1406 					       "fixed", buf))
1407 			use_spd = 0;
1408 		else
1409 			use_spd = 1;
1410 	} else
1411 		use_spd = 1;
1412 #endif
1413 
1414 	return use_spd;
1415 }
1416