xref: /openbmc/u-boot/drivers/ddr/fsl/options.c (revision c507d306)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
25614e71bSYork Sun /*
3c0c32af0SYork Sun  * Copyright 2008, 2010-2016 Freescale Semiconductor, Inc.
4c0c32af0SYork Sun  * Copyright 2017-2018 NXP Semiconductor
55614e71bSYork Sun  */
65614e71bSYork Sun 
75614e71bSYork Sun #include <common.h>
85614e71bSYork Sun #include <hwconfig.h>
95614e71bSYork Sun #include <fsl_ddr_sdram.h>
105614e71bSYork Sun 
115614e71bSYork Sun #include <fsl_ddr.h>
12457e51cfSSimon Glass #if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
13457e51cfSSimon Glass 	defined(CONFIG_ARM)
146e2941d7SSimon Glass #include <asm/arch/clock.h>
156e2941d7SSimon Glass #endif
165614e71bSYork Sun 
175614e71bSYork Sun /*
185614e71bSYork Sun  * Use our own stack based buffer before relocation to allow accessing longer
195614e71bSYork Sun  * hwconfig strings that might be in the environment before we've relocated.
205614e71bSYork Sun  * This is pretty fragile on both the use of stack and if the buffer is big
2100caae6dSSimon Glass  * enough. However we will get a warning from env_get_f() for the latter.
225614e71bSYork Sun  */
235614e71bSYork Sun 
245614e71bSYork Sun /* Board-specific functions defined in each board's ddr.c */
fsl_ddr_board_options(memctl_options_t * popts,dimm_params_t * pdimm,unsigned int ctrl_num)25*50dcbd1fSPriyanka Jain void __weak fsl_ddr_board_options(memctl_options_t *popts,
265614e71bSYork Sun 				  dimm_params_t *pdimm,
27*50dcbd1fSPriyanka Jain 				  unsigned int ctrl_num)
28*50dcbd1fSPriyanka Jain {
29*50dcbd1fSPriyanka Jain 	return;
30*50dcbd1fSPriyanka Jain }
315614e71bSYork Sun 
325614e71bSYork Sun struct dynamic_odt {
335614e71bSYork Sun 	unsigned int odt_rd_cfg;
345614e71bSYork Sun 	unsigned int odt_wr_cfg;
355614e71bSYork Sun 	unsigned int odt_rtt_norm;
365614e71bSYork Sun 	unsigned int odt_rtt_wr;
375614e71bSYork Sun };
385614e71bSYork Sun 
3919601dd9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
4019601dd9SYork Sun /* Quad rank is not verified yet due availability.
4119601dd9SYork Sun  * Replacing 20 OHM with 34 OHM since DDR4 doesn't have 20 OHM option
4219601dd9SYork Sun  */
4397fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt single_Q[4] = {
4419601dd9SYork Sun 	{	/* cs0 */
4519601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
4619601dd9SYork Sun 		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
4719601dd9SYork Sun 		DDR4_RTT_34_OHM,	/* unverified */
4819601dd9SYork Sun 		DDR4_RTT_120_OHM
4919601dd9SYork Sun 	},
5019601dd9SYork Sun 	{	/* cs1 */
5119601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
5219601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
5319601dd9SYork Sun 		DDR4_RTT_OFF,
5419601dd9SYork Sun 		DDR4_RTT_120_OHM
5519601dd9SYork Sun 	},
5619601dd9SYork Sun 	{	/* cs2 */
5719601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
5819601dd9SYork Sun 		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
5919601dd9SYork Sun 		DDR4_RTT_34_OHM,
6019601dd9SYork Sun 		DDR4_RTT_120_OHM
6119601dd9SYork Sun 	},
6219601dd9SYork Sun 	{	/* cs3 */
6319601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
6419601dd9SYork Sun 		FSL_DDR_ODT_NEVER,	/* tied high */
6519601dd9SYork Sun 		DDR4_RTT_OFF,
6619601dd9SYork Sun 		DDR4_RTT_120_OHM
6719601dd9SYork Sun 	}
6819601dd9SYork Sun };
6919601dd9SYork Sun 
7097fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt single_D[4] = {
7119601dd9SYork Sun 	{	/* cs0 */
7219601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
7319601dd9SYork Sun 		FSL_DDR_ODT_ALL,
7419601dd9SYork Sun 		DDR4_RTT_40_OHM,
7519601dd9SYork Sun 		DDR4_RTT_OFF
7619601dd9SYork Sun 	},
7719601dd9SYork Sun 	{	/* cs1 */
7819601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
7919601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
8019601dd9SYork Sun 		DDR4_RTT_OFF,
8119601dd9SYork Sun 		DDR4_RTT_OFF
8219601dd9SYork Sun 	},
8319601dd9SYork Sun 	{0, 0, 0, 0},
8419601dd9SYork Sun 	{0, 0, 0, 0}
8519601dd9SYork Sun };
8619601dd9SYork Sun 
8797fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt single_S[4] = {
8819601dd9SYork Sun 	{	/* cs0 */
8919601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
9019601dd9SYork Sun 		FSL_DDR_ODT_ALL,
9119601dd9SYork Sun 		DDR4_RTT_40_OHM,
9219601dd9SYork Sun 		DDR4_RTT_OFF
9319601dd9SYork Sun 	},
9419601dd9SYork Sun 	{0, 0, 0, 0},
9519601dd9SYork Sun 	{0, 0, 0, 0},
9619601dd9SYork Sun 	{0, 0, 0, 0},
9719601dd9SYork Sun };
9819601dd9SYork Sun 
9997fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_DD[4] = {
10019601dd9SYork Sun 	{	/* cs0 */
10119601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
10219601dd9SYork Sun 		FSL_DDR_ODT_SAME_DIMM,
10319601dd9SYork Sun 		DDR4_RTT_120_OHM,
10419601dd9SYork Sun 		DDR4_RTT_OFF
10519601dd9SYork Sun 	},
10619601dd9SYork Sun 	{	/* cs1 */
10719601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
10819601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
10919601dd9SYork Sun 		DDR4_RTT_34_OHM,
11019601dd9SYork Sun 		DDR4_RTT_OFF
11119601dd9SYork Sun 	},
11219601dd9SYork Sun 	{	/* cs2 */
11319601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
11419601dd9SYork Sun 		FSL_DDR_ODT_SAME_DIMM,
11519601dd9SYork Sun 		DDR4_RTT_120_OHM,
11619601dd9SYork Sun 		DDR4_RTT_OFF
11719601dd9SYork Sun 	},
11819601dd9SYork Sun 	{	/* cs3 */
11919601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
12019601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
12119601dd9SYork Sun 		DDR4_RTT_34_OHM,
12219601dd9SYork Sun 		DDR4_RTT_OFF
12319601dd9SYork Sun 	}
12419601dd9SYork Sun };
12519601dd9SYork Sun 
12697fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_DS[4] = {
12719601dd9SYork Sun 	{	/* cs0 */
12819601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
12919601dd9SYork Sun 		FSL_DDR_ODT_SAME_DIMM,
13019601dd9SYork Sun 		DDR4_RTT_120_OHM,
13119601dd9SYork Sun 		DDR4_RTT_OFF
13219601dd9SYork Sun 	},
13319601dd9SYork Sun 	{	/* cs1 */
13419601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
13519601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
13619601dd9SYork Sun 		DDR4_RTT_34_OHM,
13719601dd9SYork Sun 		DDR4_RTT_OFF
13819601dd9SYork Sun 	},
13919601dd9SYork Sun 	{	/* cs2 */
14019601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
14119601dd9SYork Sun 		FSL_DDR_ODT_ALL,
14219601dd9SYork Sun 		DDR4_RTT_34_OHM,
14319601dd9SYork Sun 		DDR4_RTT_120_OHM
14419601dd9SYork Sun 	},
14519601dd9SYork Sun 	{0, 0, 0, 0}
14619601dd9SYork Sun };
14797fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_SD[4] = {
14819601dd9SYork Sun 	{	/* cs0 */
14919601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
15019601dd9SYork Sun 		FSL_DDR_ODT_ALL,
15119601dd9SYork Sun 		DDR4_RTT_34_OHM,
15219601dd9SYork Sun 		DDR4_RTT_120_OHM
15319601dd9SYork Sun 	},
15419601dd9SYork Sun 	{0, 0, 0, 0},
15519601dd9SYork Sun 	{	/* cs2 */
15619601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
15719601dd9SYork Sun 		FSL_DDR_ODT_SAME_DIMM,
15819601dd9SYork Sun 		DDR4_RTT_120_OHM,
15919601dd9SYork Sun 		DDR4_RTT_OFF
16019601dd9SYork Sun 	},
16119601dd9SYork Sun 	{	/* cs3 */
16219601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
16319601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
16419601dd9SYork Sun 		DDR4_RTT_34_OHM,
16519601dd9SYork Sun 		DDR4_RTT_OFF
16619601dd9SYork Sun 	}
16719601dd9SYork Sun };
16819601dd9SYork Sun 
16997fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_SS[4] = {
17019601dd9SYork Sun 	{	/* cs0 */
17119601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
17219601dd9SYork Sun 		FSL_DDR_ODT_ALL,
17319601dd9SYork Sun 		DDR4_RTT_34_OHM,
17419601dd9SYork Sun 		DDR4_RTT_120_OHM
17519601dd9SYork Sun 	},
17619601dd9SYork Sun 	{0, 0, 0, 0},
17719601dd9SYork Sun 	{	/* cs2 */
17819601dd9SYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
17919601dd9SYork Sun 		FSL_DDR_ODT_ALL,
18019601dd9SYork Sun 		DDR4_RTT_34_OHM,
18119601dd9SYork Sun 		DDR4_RTT_120_OHM
18219601dd9SYork Sun 	},
18319601dd9SYork Sun 	{0, 0, 0, 0}
18419601dd9SYork Sun };
18519601dd9SYork Sun 
18697fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_D0[4] = {
18719601dd9SYork Sun 	{	/* cs0 */
18819601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
18919601dd9SYork Sun 		FSL_DDR_ODT_SAME_DIMM,
19019601dd9SYork Sun 		DDR4_RTT_40_OHM,
19119601dd9SYork Sun 		DDR4_RTT_OFF
19219601dd9SYork Sun 	},
19319601dd9SYork Sun 	{	/* cs1 */
19419601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
19519601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
19619601dd9SYork Sun 		DDR4_RTT_OFF,
19719601dd9SYork Sun 		DDR4_RTT_OFF
19819601dd9SYork Sun 	},
19919601dd9SYork Sun 	{0, 0, 0, 0},
20019601dd9SYork Sun 	{0, 0, 0, 0}
20119601dd9SYork Sun };
20219601dd9SYork Sun 
20397fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_0D[4] = {
20419601dd9SYork Sun 	{0, 0, 0, 0},
20519601dd9SYork Sun 	{0, 0, 0, 0},
20619601dd9SYork Sun 	{	/* cs2 */
20719601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
20819601dd9SYork Sun 		FSL_DDR_ODT_SAME_DIMM,
20919601dd9SYork Sun 		DDR4_RTT_40_OHM,
21019601dd9SYork Sun 		DDR4_RTT_OFF
21119601dd9SYork Sun 	},
21219601dd9SYork Sun 	{	/* cs3 */
21319601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
21419601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
21519601dd9SYork Sun 		DDR4_RTT_OFF,
21619601dd9SYork Sun 		DDR4_RTT_OFF
21719601dd9SYork Sun 	}
21819601dd9SYork Sun };
21919601dd9SYork Sun 
22097fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_S0[4] = {
22119601dd9SYork Sun 	{	/* cs0 */
22219601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
22319601dd9SYork Sun 		FSL_DDR_ODT_CS,
22419601dd9SYork Sun 		DDR4_RTT_40_OHM,
22519601dd9SYork Sun 		DDR4_RTT_OFF
22619601dd9SYork Sun 	},
22719601dd9SYork Sun 	{0, 0, 0, 0},
22819601dd9SYork Sun 	{0, 0, 0, 0},
22919601dd9SYork Sun 	{0, 0, 0, 0}
23019601dd9SYork Sun 
23119601dd9SYork Sun };
23219601dd9SYork Sun 
23397fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_0S[4] = {
23419601dd9SYork Sun 	{0, 0, 0, 0},
23519601dd9SYork Sun 	{0, 0, 0, 0},
23619601dd9SYork Sun 	{	/* cs2 */
23719601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
23819601dd9SYork Sun 		FSL_DDR_ODT_CS,
23919601dd9SYork Sun 		DDR4_RTT_40_OHM,
24019601dd9SYork Sun 		DDR4_RTT_OFF
24119601dd9SYork Sun 	},
24219601dd9SYork Sun 	{0, 0, 0, 0}
24319601dd9SYork Sun 
24419601dd9SYork Sun };
24519601dd9SYork Sun 
24697fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt odt_unknown[4] = {
24719601dd9SYork Sun 	{	/* cs0 */
24819601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
24919601dd9SYork Sun 		FSL_DDR_ODT_CS,
25019601dd9SYork Sun 		DDR4_RTT_120_OHM,
25119601dd9SYork Sun 		DDR4_RTT_OFF
25219601dd9SYork Sun 	},
25319601dd9SYork Sun 	{	/* cs1 */
25419601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
25519601dd9SYork Sun 		FSL_DDR_ODT_CS,
25619601dd9SYork Sun 		DDR4_RTT_120_OHM,
25719601dd9SYork Sun 		DDR4_RTT_OFF
25819601dd9SYork Sun 	},
25919601dd9SYork Sun 	{	/* cs2 */
26019601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
26119601dd9SYork Sun 		FSL_DDR_ODT_CS,
26219601dd9SYork Sun 		DDR4_RTT_120_OHM,
26319601dd9SYork Sun 		DDR4_RTT_OFF
26419601dd9SYork Sun 	},
26519601dd9SYork Sun 	{	/* cs3 */
26619601dd9SYork Sun 		FSL_DDR_ODT_NEVER,
26719601dd9SYork Sun 		FSL_DDR_ODT_CS,
26819601dd9SYork Sun 		DDR4_RTT_120_OHM,
26919601dd9SYork Sun 		DDR4_RTT_OFF
27019601dd9SYork Sun 	}
27119601dd9SYork Sun };
27219601dd9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
27397fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt single_Q[4] = {
2745614e71bSYork Sun 	{	/* cs0 */
2755614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
2765614e71bSYork Sun 		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
2775614e71bSYork Sun 		DDR3_RTT_20_OHM,
2785614e71bSYork Sun 		DDR3_RTT_120_OHM
2795614e71bSYork Sun 	},
2805614e71bSYork Sun 	{	/* cs1 */
2815614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
2825614e71bSYork Sun 		FSL_DDR_ODT_NEVER,	/* tied high */
2835614e71bSYork Sun 		DDR3_RTT_OFF,
2845614e71bSYork Sun 		DDR3_RTT_120_OHM
2855614e71bSYork Sun 	},
2865614e71bSYork Sun 	{	/* cs2 */
2875614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
2885614e71bSYork Sun 		FSL_DDR_ODT_CS_AND_OTHER_DIMM,
2895614e71bSYork Sun 		DDR3_RTT_20_OHM,
2905614e71bSYork Sun 		DDR3_RTT_120_OHM
2915614e71bSYork Sun 	},
2925614e71bSYork Sun 	{	/* cs3 */
2935614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
2945614e71bSYork Sun 		FSL_DDR_ODT_NEVER,	/* tied high */
2955614e71bSYork Sun 		DDR3_RTT_OFF,
2965614e71bSYork Sun 		DDR3_RTT_120_OHM
2975614e71bSYork Sun 	}
2985614e71bSYork Sun };
2995614e71bSYork Sun 
30097fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt single_D[4] = {
3015614e71bSYork Sun 	{	/* cs0 */
3025614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
3035614e71bSYork Sun 		FSL_DDR_ODT_ALL,
3045614e71bSYork Sun 		DDR3_RTT_40_OHM,
3055614e71bSYork Sun 		DDR3_RTT_OFF
3065614e71bSYork Sun 	},
3075614e71bSYork Sun 	{	/* cs1 */
3085614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
3095614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
3105614e71bSYork Sun 		DDR3_RTT_OFF,
3115614e71bSYork Sun 		DDR3_RTT_OFF
3125614e71bSYork Sun 	},
3135614e71bSYork Sun 	{0, 0, 0, 0},
3145614e71bSYork Sun 	{0, 0, 0, 0}
3155614e71bSYork Sun };
3165614e71bSYork Sun 
31797fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt single_S[4] = {
3185614e71bSYork Sun 	{	/* cs0 */
3195614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
3205614e71bSYork Sun 		FSL_DDR_ODT_ALL,
3215614e71bSYork Sun 		DDR3_RTT_40_OHM,
3225614e71bSYork Sun 		DDR3_RTT_OFF
3235614e71bSYork Sun 	},
3245614e71bSYork Sun 	{0, 0, 0, 0},
3255614e71bSYork Sun 	{0, 0, 0, 0},
3265614e71bSYork Sun 	{0, 0, 0, 0},
3275614e71bSYork Sun };
3285614e71bSYork Sun 
32997fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_DD[4] = {
3305614e71bSYork Sun 	{	/* cs0 */
3315614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
3325614e71bSYork Sun 		FSL_DDR_ODT_SAME_DIMM,
3335614e71bSYork Sun 		DDR3_RTT_120_OHM,
3345614e71bSYork Sun 		DDR3_RTT_OFF
3355614e71bSYork Sun 	},
3365614e71bSYork Sun 	{	/* cs1 */
3375614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3385614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3395614e71bSYork Sun 		DDR3_RTT_30_OHM,
3405614e71bSYork Sun 		DDR3_RTT_OFF
3415614e71bSYork Sun 	},
3425614e71bSYork Sun 	{	/* cs2 */
3435614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
3445614e71bSYork Sun 		FSL_DDR_ODT_SAME_DIMM,
3455614e71bSYork Sun 		DDR3_RTT_120_OHM,
3465614e71bSYork Sun 		DDR3_RTT_OFF
3475614e71bSYork Sun 	},
3485614e71bSYork Sun 	{	/* cs3 */
3495614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3505614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3515614e71bSYork Sun 		DDR3_RTT_30_OHM,
3525614e71bSYork Sun 		DDR3_RTT_OFF
3535614e71bSYork Sun 	}
3545614e71bSYork Sun };
3555614e71bSYork Sun 
35697fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_DS[4] = {
3575614e71bSYork Sun 	{	/* cs0 */
3585614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
3595614e71bSYork Sun 		FSL_DDR_ODT_SAME_DIMM,
3605614e71bSYork Sun 		DDR3_RTT_120_OHM,
3615614e71bSYork Sun 		DDR3_RTT_OFF
3625614e71bSYork Sun 	},
3635614e71bSYork Sun 	{	/* cs1 */
3645614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3655614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3665614e71bSYork Sun 		DDR3_RTT_30_OHM,
3675614e71bSYork Sun 		DDR3_RTT_OFF
3685614e71bSYork Sun 	},
3695614e71bSYork Sun 	{	/* cs2 */
3705614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3715614e71bSYork Sun 		FSL_DDR_ODT_ALL,
3725614e71bSYork Sun 		DDR3_RTT_20_OHM,
3735614e71bSYork Sun 		DDR3_RTT_120_OHM
3745614e71bSYork Sun 	},
3755614e71bSYork Sun 	{0, 0, 0, 0}
3765614e71bSYork Sun };
37797fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_SD[4] = {
3785614e71bSYork Sun 	{	/* cs0 */
3795614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3805614e71bSYork Sun 		FSL_DDR_ODT_ALL,
3815614e71bSYork Sun 		DDR3_RTT_20_OHM,
3825614e71bSYork Sun 		DDR3_RTT_120_OHM
3835614e71bSYork Sun 	},
3845614e71bSYork Sun 	{0, 0, 0, 0},
3855614e71bSYork Sun 	{	/* cs2 */
3865614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
3875614e71bSYork Sun 		FSL_DDR_ODT_SAME_DIMM,
3885614e71bSYork Sun 		DDR3_RTT_120_OHM,
3895614e71bSYork Sun 		DDR3_RTT_OFF
3905614e71bSYork Sun 	},
3915614e71bSYork Sun 	{	/* cs3 */
3925614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3935614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
3945614e71bSYork Sun 		DDR3_RTT_20_OHM,
3955614e71bSYork Sun 		DDR3_RTT_OFF
3965614e71bSYork Sun 	}
3975614e71bSYork Sun };
3985614e71bSYork Sun 
39997fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_SS[4] = {
4005614e71bSYork Sun 	{	/* cs0 */
4015614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
4025614e71bSYork Sun 		FSL_DDR_ODT_ALL,
4035614e71bSYork Sun 		DDR3_RTT_30_OHM,
4045614e71bSYork Sun 		DDR3_RTT_120_OHM
4055614e71bSYork Sun 	},
4065614e71bSYork Sun 	{0, 0, 0, 0},
4075614e71bSYork Sun 	{	/* cs2 */
4085614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
4095614e71bSYork Sun 		FSL_DDR_ODT_ALL,
4105614e71bSYork Sun 		DDR3_RTT_30_OHM,
4115614e71bSYork Sun 		DDR3_RTT_120_OHM
4125614e71bSYork Sun 	},
4135614e71bSYork Sun 	{0, 0, 0, 0}
4145614e71bSYork Sun };
4155614e71bSYork Sun 
41697fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_D0[4] = {
4175614e71bSYork Sun 	{	/* cs0 */
4185614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4195614e71bSYork Sun 		FSL_DDR_ODT_SAME_DIMM,
4205614e71bSYork Sun 		DDR3_RTT_40_OHM,
4215614e71bSYork Sun 		DDR3_RTT_OFF
4225614e71bSYork Sun 	},
4235614e71bSYork Sun 	{	/* cs1 */
4245614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4255614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4265614e71bSYork Sun 		DDR3_RTT_OFF,
4275614e71bSYork Sun 		DDR3_RTT_OFF
4285614e71bSYork Sun 	},
4295614e71bSYork Sun 	{0, 0, 0, 0},
4305614e71bSYork Sun 	{0, 0, 0, 0}
4315614e71bSYork Sun };
4325614e71bSYork Sun 
43397fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_0D[4] = {
4345614e71bSYork Sun 	{0, 0, 0, 0},
4355614e71bSYork Sun 	{0, 0, 0, 0},
4365614e71bSYork Sun 	{	/* cs2 */
4375614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4385614e71bSYork Sun 		FSL_DDR_ODT_SAME_DIMM,
4395614e71bSYork Sun 		DDR3_RTT_40_OHM,
4405614e71bSYork Sun 		DDR3_RTT_OFF
4415614e71bSYork Sun 	},
4425614e71bSYork Sun 	{	/* cs3 */
4435614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4445614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4455614e71bSYork Sun 		DDR3_RTT_OFF,
4465614e71bSYork Sun 		DDR3_RTT_OFF
4475614e71bSYork Sun 	}
4485614e71bSYork Sun };
4495614e71bSYork Sun 
45097fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_S0[4] = {
4515614e71bSYork Sun 	{	/* cs0 */
4525614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4535614e71bSYork Sun 		FSL_DDR_ODT_CS,
4545614e71bSYork Sun 		DDR3_RTT_40_OHM,
4555614e71bSYork Sun 		DDR3_RTT_OFF
4565614e71bSYork Sun 	},
4575614e71bSYork Sun 	{0, 0, 0, 0},
4585614e71bSYork Sun 	{0, 0, 0, 0},
4595614e71bSYork Sun 	{0, 0, 0, 0}
4605614e71bSYork Sun 
4615614e71bSYork Sun };
4625614e71bSYork Sun 
46397fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_0S[4] = {
4645614e71bSYork Sun 	{0, 0, 0, 0},
4655614e71bSYork Sun 	{0, 0, 0, 0},
4665614e71bSYork Sun 	{	/* cs2 */
4675614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4685614e71bSYork Sun 		FSL_DDR_ODT_CS,
4695614e71bSYork Sun 		DDR3_RTT_40_OHM,
4705614e71bSYork Sun 		DDR3_RTT_OFF
4715614e71bSYork Sun 	},
4725614e71bSYork Sun 	{0, 0, 0, 0}
4735614e71bSYork Sun 
4745614e71bSYork Sun };
4755614e71bSYork Sun 
47697fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt odt_unknown[4] = {
4775614e71bSYork Sun 	{	/* cs0 */
4785614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4795614e71bSYork Sun 		FSL_DDR_ODT_CS,
4805614e71bSYork Sun 		DDR3_RTT_120_OHM,
4815614e71bSYork Sun 		DDR3_RTT_OFF
4825614e71bSYork Sun 	},
4835614e71bSYork Sun 	{	/* cs1 */
4845614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4855614e71bSYork Sun 		FSL_DDR_ODT_CS,
4865614e71bSYork Sun 		DDR3_RTT_120_OHM,
4875614e71bSYork Sun 		DDR3_RTT_OFF
4885614e71bSYork Sun 	},
4895614e71bSYork Sun 	{	/* cs2 */
4905614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4915614e71bSYork Sun 		FSL_DDR_ODT_CS,
4925614e71bSYork Sun 		DDR3_RTT_120_OHM,
4935614e71bSYork Sun 		DDR3_RTT_OFF
4945614e71bSYork Sun 	},
4955614e71bSYork Sun 	{	/* cs3 */
4965614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
4975614e71bSYork Sun 		FSL_DDR_ODT_CS,
4985614e71bSYork Sun 		DDR3_RTT_120_OHM,
4995614e71bSYork Sun 		DDR3_RTT_OFF
5005614e71bSYork Sun 	}
5015614e71bSYork Sun };
50219601dd9SYork Sun #else	/* CONFIG_SYS_FSL_DDR3 */
50397fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt single_Q[4] = {
5045614e71bSYork Sun 	{0, 0, 0, 0},
5055614e71bSYork Sun 	{0, 0, 0, 0},
5065614e71bSYork Sun 	{0, 0, 0, 0},
5075614e71bSYork Sun 	{0, 0, 0, 0}
5085614e71bSYork Sun };
5095614e71bSYork Sun 
51097fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt single_D[4] = {
5115614e71bSYork Sun 	{	/* cs0 */
5125614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5135614e71bSYork Sun 		FSL_DDR_ODT_ALL,
5145614e71bSYork Sun 		DDR2_RTT_150_OHM,
5155614e71bSYork Sun 		DDR2_RTT_OFF
5165614e71bSYork Sun 	},
5175614e71bSYork Sun 	{	/* cs1 */
5185614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5195614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5205614e71bSYork Sun 		DDR2_RTT_OFF,
5215614e71bSYork Sun 		DDR2_RTT_OFF
5225614e71bSYork Sun 	},
5235614e71bSYork Sun 	{0, 0, 0, 0},
5245614e71bSYork Sun 	{0, 0, 0, 0}
5255614e71bSYork Sun };
5265614e71bSYork Sun 
52797fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt single_S[4] = {
5285614e71bSYork Sun 	{	/* cs0 */
5295614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5305614e71bSYork Sun 		FSL_DDR_ODT_ALL,
5315614e71bSYork Sun 		DDR2_RTT_150_OHM,
5325614e71bSYork Sun 		DDR2_RTT_OFF
5335614e71bSYork Sun 	},
5345614e71bSYork Sun 	{0, 0, 0, 0},
5355614e71bSYork Sun 	{0, 0, 0, 0},
5365614e71bSYork Sun 	{0, 0, 0, 0},
5375614e71bSYork Sun };
5385614e71bSYork Sun 
53997fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_DD[4] = {
5405614e71bSYork Sun 	{	/* cs0 */
5415614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5425614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5435614e71bSYork Sun 		DDR2_RTT_75_OHM,
5445614e71bSYork Sun 		DDR2_RTT_OFF
5455614e71bSYork Sun 	},
5465614e71bSYork Sun 	{	/* cs1 */
5475614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5485614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5495614e71bSYork Sun 		DDR2_RTT_OFF,
5505614e71bSYork Sun 		DDR2_RTT_OFF
5515614e71bSYork Sun 	},
5525614e71bSYork Sun 	{	/* cs2 */
5535614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5545614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5555614e71bSYork Sun 		DDR2_RTT_75_OHM,
5565614e71bSYork Sun 		DDR2_RTT_OFF
5575614e71bSYork Sun 	},
5585614e71bSYork Sun 	{	/* cs3 */
5595614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5605614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5615614e71bSYork Sun 		DDR2_RTT_OFF,
5625614e71bSYork Sun 		DDR2_RTT_OFF
5635614e71bSYork Sun 	}
5645614e71bSYork Sun };
5655614e71bSYork Sun 
56697fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_DS[4] = {
5675614e71bSYork Sun 	{	/* cs0 */
5685614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5695614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5705614e71bSYork Sun 		DDR2_RTT_75_OHM,
5715614e71bSYork Sun 		DDR2_RTT_OFF
5725614e71bSYork Sun 	},
5735614e71bSYork Sun 	{	/* cs1 */
5745614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5755614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
5765614e71bSYork Sun 		DDR2_RTT_OFF,
5775614e71bSYork Sun 		DDR2_RTT_OFF
5785614e71bSYork Sun 	},
5795614e71bSYork Sun 	{	/* cs2 */
5805614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5815614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5825614e71bSYork Sun 		DDR2_RTT_75_OHM,
5835614e71bSYork Sun 		DDR2_RTT_OFF
5845614e71bSYork Sun 	},
5855614e71bSYork Sun 	{0, 0, 0, 0}
5865614e71bSYork Sun };
5875614e71bSYork Sun 
58897fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_SD[4] = {
5895614e71bSYork Sun 	{	/* cs0 */
5905614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5915614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5925614e71bSYork Sun 		DDR2_RTT_75_OHM,
5935614e71bSYork Sun 		DDR2_RTT_OFF
5945614e71bSYork Sun 	},
5955614e71bSYork Sun 	{0, 0, 0, 0},
5965614e71bSYork Sun 	{	/* cs2 */
5975614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5985614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
5995614e71bSYork Sun 		DDR2_RTT_75_OHM,
6005614e71bSYork Sun 		DDR2_RTT_OFF
6015614e71bSYork Sun 	},
6025614e71bSYork Sun 	{	/* cs3 */
6035614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6045614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6055614e71bSYork Sun 		DDR2_RTT_OFF,
6065614e71bSYork Sun 		DDR2_RTT_OFF
6075614e71bSYork Sun 	}
6085614e71bSYork Sun };
6095614e71bSYork Sun 
61097fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_SS[4] = {
6115614e71bSYork Sun 	{	/* cs0 */
6125614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
6135614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
6145614e71bSYork Sun 		DDR2_RTT_75_OHM,
6155614e71bSYork Sun 		DDR2_RTT_OFF
6165614e71bSYork Sun 	},
6175614e71bSYork Sun 	{0, 0, 0, 0},
6185614e71bSYork Sun 	{	/* cs2 */
6195614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
6205614e71bSYork Sun 		FSL_DDR_ODT_OTHER_DIMM,
6215614e71bSYork Sun 		DDR2_RTT_75_OHM,
6225614e71bSYork Sun 		DDR2_RTT_OFF
6235614e71bSYork Sun 	},
6245614e71bSYork Sun 	{0, 0, 0, 0}
6255614e71bSYork Sun };
6265614e71bSYork Sun 
62797fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_D0[4] = {
6285614e71bSYork Sun 	{	/* cs0 */
6295614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6305614e71bSYork Sun 		FSL_DDR_ODT_ALL,
6315614e71bSYork Sun 		DDR2_RTT_150_OHM,
6325614e71bSYork Sun 		DDR2_RTT_OFF
6335614e71bSYork Sun 	},
6345614e71bSYork Sun 	{	/* cs1 */
6355614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6365614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6375614e71bSYork Sun 		DDR2_RTT_OFF,
6385614e71bSYork Sun 		DDR2_RTT_OFF
6395614e71bSYork Sun 	},
6405614e71bSYork Sun 	{0, 0, 0, 0},
6415614e71bSYork Sun 	{0, 0, 0, 0}
6425614e71bSYork Sun };
6435614e71bSYork Sun 
64497fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_0D[4] = {
6455614e71bSYork Sun 	{0, 0, 0, 0},
6465614e71bSYork Sun 	{0, 0, 0, 0},
6475614e71bSYork Sun 	{	/* cs2 */
6485614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6495614e71bSYork Sun 		FSL_DDR_ODT_ALL,
6505614e71bSYork Sun 		DDR2_RTT_150_OHM,
6515614e71bSYork Sun 		DDR2_RTT_OFF
6525614e71bSYork Sun 	},
6535614e71bSYork Sun 	{	/* cs3 */
6545614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6555614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6565614e71bSYork Sun 		DDR2_RTT_OFF,
6575614e71bSYork Sun 		DDR2_RTT_OFF
6585614e71bSYork Sun 	}
6595614e71bSYork Sun };
6605614e71bSYork Sun 
66197fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_S0[4] = {
6625614e71bSYork Sun 	{	/* cs0 */
6635614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6645614e71bSYork Sun 		FSL_DDR_ODT_CS,
6655614e71bSYork Sun 		DDR2_RTT_150_OHM,
6665614e71bSYork Sun 		DDR2_RTT_OFF
6675614e71bSYork Sun 	},
6685614e71bSYork Sun 	{0, 0, 0, 0},
6695614e71bSYork Sun 	{0, 0, 0, 0},
6705614e71bSYork Sun 	{0, 0, 0, 0}
6715614e71bSYork Sun 
6725614e71bSYork Sun };
6735614e71bSYork Sun 
67497fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt dual_0S[4] = {
6755614e71bSYork Sun 	{0, 0, 0, 0},
6765614e71bSYork Sun 	{0, 0, 0, 0},
6775614e71bSYork Sun 	{	/* cs2 */
6785614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6795614e71bSYork Sun 		FSL_DDR_ODT_CS,
6805614e71bSYork Sun 		DDR2_RTT_150_OHM,
6815614e71bSYork Sun 		DDR2_RTT_OFF
6825614e71bSYork Sun 	},
6835614e71bSYork Sun 	{0, 0, 0, 0}
6845614e71bSYork Sun 
6855614e71bSYork Sun };
6865614e71bSYork Sun 
68797fbf26dSThomas Schaefer static __maybe_unused const struct dynamic_odt odt_unknown[4] = {
6885614e71bSYork Sun 	{	/* cs0 */
6895614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6905614e71bSYork Sun 		FSL_DDR_ODT_CS,
6915614e71bSYork Sun 		DDR2_RTT_75_OHM,
6925614e71bSYork Sun 		DDR2_RTT_OFF
6935614e71bSYork Sun 	},
6945614e71bSYork Sun 	{	/* cs1 */
6955614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6965614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
6975614e71bSYork Sun 		DDR2_RTT_OFF,
6985614e71bSYork Sun 		DDR2_RTT_OFF
6995614e71bSYork Sun 	},
7005614e71bSYork Sun 	{	/* cs2 */
7015614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
7025614e71bSYork Sun 		FSL_DDR_ODT_CS,
7035614e71bSYork Sun 		DDR2_RTT_75_OHM,
7045614e71bSYork Sun 		DDR2_RTT_OFF
7055614e71bSYork Sun 	},
7065614e71bSYork Sun 	{	/* cs3 */
7075614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
7085614e71bSYork Sun 		FSL_DDR_ODT_NEVER,
7095614e71bSYork Sun 		DDR2_RTT_OFF,
7105614e71bSYork Sun 		DDR2_RTT_OFF
7115614e71bSYork Sun 	}
7125614e71bSYork Sun };
7135614e71bSYork Sun #endif
7145614e71bSYork Sun 
7155614e71bSYork Sun /*
7165614e71bSYork Sun  * Automatically seleect bank interleaving mode based on DIMMs
7175614e71bSYork Sun  * in this order: cs0_cs1_cs2_cs3, cs0_cs1, null.
7185614e71bSYork Sun  * This function only deal with one or two slots per controller.
7195614e71bSYork Sun  */
auto_bank_intlv(dimm_params_t * pdimm)7205614e71bSYork Sun static inline unsigned int auto_bank_intlv(dimm_params_t *pdimm)
7215614e71bSYork Sun {
7225614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
7235614e71bSYork Sun 	if (pdimm[0].n_ranks == 4)
7245614e71bSYork Sun 		return FSL_DDR_CS0_CS1_CS2_CS3;
7255614e71bSYork Sun 	else if (pdimm[0].n_ranks == 2)
7265614e71bSYork Sun 		return FSL_DDR_CS0_CS1;
7275614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
7285614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
7295614e71bSYork Sun 	if (pdimm[0].n_ranks == 4)
7305614e71bSYork Sun 		return FSL_DDR_CS0_CS1_CS2_CS3;
7315614e71bSYork Sun #endif
7325614e71bSYork Sun 	if (pdimm[0].n_ranks == 2) {
7335614e71bSYork Sun 		if (pdimm[1].n_ranks == 2)
7345614e71bSYork Sun 			return FSL_DDR_CS0_CS1_CS2_CS3;
7355614e71bSYork Sun 		else
7365614e71bSYork Sun 			return FSL_DDR_CS0_CS1;
7375614e71bSYork Sun 	}
7385614e71bSYork Sun #endif
7395614e71bSYork Sun 	return 0;
7405614e71bSYork Sun }
7415614e71bSYork Sun 
populate_memctl_options(const common_timing_params_t * common_dimm,memctl_options_t * popts,dimm_params_t * pdimm,unsigned int ctrl_num)74256848428SYork Sun unsigned int populate_memctl_options(const common_timing_params_t *common_dimm,
7435614e71bSYork Sun 			memctl_options_t *popts,
7445614e71bSYork Sun 			dimm_params_t *pdimm,
7455614e71bSYork Sun 			unsigned int ctrl_num)
7465614e71bSYork Sun {
7475614e71bSYork Sun 	unsigned int i;
74886b840b7SJeremy Gebben 	char buf[HWCONFIG_BUFFER_SIZE];
74934e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || \
75034e026f9SYork Sun 	defined(CONFIG_SYS_FSL_DDR2) || \
75134e026f9SYork Sun 	defined(CONFIG_SYS_FSL_DDR4)
7525614e71bSYork Sun 	const struct dynamic_odt *pdodt = odt_unknown;
7535614e71bSYork Sun #endif
754564e9383SYork Sun #if (CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4)
7555614e71bSYork Sun 	ulong ddr_freq;
756564e9383SYork Sun #endif
7575614e71bSYork Sun 
7585614e71bSYork Sun 	/*
7595614e71bSYork Sun 	 * Extract hwconfig from environment since we have not properly setup
7605614e71bSYork Sun 	 * the environment but need it for ddr config params
7615614e71bSYork Sun 	 */
76286b840b7SJeremy Gebben 	if (env_get_f("hwconfig", buf, sizeof(buf)) < 0)
76386b840b7SJeremy Gebben 		buf[0] = '\0';
7645614e71bSYork Sun 
76534e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || \
76634e026f9SYork Sun 	defined(CONFIG_SYS_FSL_DDR2) || \
76734e026f9SYork Sun 	defined(CONFIG_SYS_FSL_DDR4)
7685614e71bSYork Sun 	/* Chip select options. */
769349689b8SYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
7705614e71bSYork Sun 	switch (pdimm[0].n_ranks) {
7715614e71bSYork Sun 	case 1:
7725614e71bSYork Sun 		pdodt = single_S;
7735614e71bSYork Sun 		break;
7745614e71bSYork Sun 	case 2:
7755614e71bSYork Sun 		pdodt = single_D;
7765614e71bSYork Sun 		break;
7775614e71bSYork Sun 	case 4:
7785614e71bSYork Sun 		pdodt = single_Q;
7795614e71bSYork Sun 		break;
7805614e71bSYork Sun 	}
781349689b8SYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
7825614e71bSYork Sun 	switch (pdimm[0].n_ranks) {
7835614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
7845614e71bSYork Sun 	case 4:
7855614e71bSYork Sun 		pdodt = single_Q;
7865614e71bSYork Sun 		if (pdimm[1].n_ranks)
787349689b8SYork Sun 			printf("Error: Quad- and Dual-rank DIMMs cannot be used together\n");
7885614e71bSYork Sun 		break;
7895614e71bSYork Sun #endif
7905614e71bSYork Sun 	case 2:
7915614e71bSYork Sun 		switch (pdimm[1].n_ranks) {
7925614e71bSYork Sun 		case 2:
7935614e71bSYork Sun 			pdodt = dual_DD;
7945614e71bSYork Sun 			break;
7955614e71bSYork Sun 		case 1:
7965614e71bSYork Sun 			pdodt = dual_DS;
7975614e71bSYork Sun 			break;
7985614e71bSYork Sun 		case 0:
7995614e71bSYork Sun 			pdodt = dual_D0;
8005614e71bSYork Sun 			break;
8015614e71bSYork Sun 		}
8025614e71bSYork Sun 		break;
8035614e71bSYork Sun 	case 1:
8045614e71bSYork Sun 		switch (pdimm[1].n_ranks) {
8055614e71bSYork Sun 		case 2:
8065614e71bSYork Sun 			pdodt = dual_SD;
8075614e71bSYork Sun 			break;
8085614e71bSYork Sun 		case 1:
8095614e71bSYork Sun 			pdodt = dual_SS;
8105614e71bSYork Sun 			break;
8115614e71bSYork Sun 		case 0:
8125614e71bSYork Sun 			pdodt = dual_S0;
8135614e71bSYork Sun 			break;
8145614e71bSYork Sun 		}
8155614e71bSYork Sun 		break;
8165614e71bSYork Sun 	case 0:
8175614e71bSYork Sun 		switch (pdimm[1].n_ranks) {
8185614e71bSYork Sun 		case 2:
8195614e71bSYork Sun 			pdodt = dual_0D;
8205614e71bSYork Sun 			break;
8215614e71bSYork Sun 		case 1:
8225614e71bSYork Sun 			pdodt = dual_0S;
8235614e71bSYork Sun 			break;
8245614e71bSYork Sun 		}
8255614e71bSYork Sun 		break;
8265614e71bSYork Sun 	}
827349689b8SYork Sun #endif	/* CONFIG_DIMM_SLOTS_PER_CTLR */
828349689b8SYork Sun #endif	/* CONFIG_SYS_FSL_DDR2, 3, 4 */
8295614e71bSYork Sun 
8305614e71bSYork Sun 	/* Pick chip-select local options. */
8315614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
83234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || \
83334e026f9SYork Sun 	defined(CONFIG_SYS_FSL_DDR2) || \
83434e026f9SYork Sun 	defined(CONFIG_SYS_FSL_DDR4)
8355614e71bSYork Sun 		popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg;
8365614e71bSYork Sun 		popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg;
8375614e71bSYork Sun 		popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm;
8385614e71bSYork Sun 		popts->cs_local_opts[i].odt_rtt_wr = pdodt[i].odt_rtt_wr;
8395614e71bSYork Sun #else
8405614e71bSYork Sun 		popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER;
8415614e71bSYork Sun 		popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS;
8425614e71bSYork Sun #endif
8435614e71bSYork Sun 		popts->cs_local_opts[i].auto_precharge = 0;
8445614e71bSYork Sun 	}
8455614e71bSYork Sun 
8465614e71bSYork Sun 	/* Pick interleaving mode. */
8475614e71bSYork Sun 
8485614e71bSYork Sun 	/*
8495614e71bSYork Sun 	 * 0 = no interleaving
8505614e71bSYork Sun 	 * 1 = interleaving between 2 controllers
8515614e71bSYork Sun 	 */
8525614e71bSYork Sun 	popts->memctl_interleaving = 0;
8535614e71bSYork Sun 
8545614e71bSYork Sun 	/*
8555614e71bSYork Sun 	 * 0 = cacheline
8565614e71bSYork Sun 	 * 1 = page
8575614e71bSYork Sun 	 * 2 = (logical) bank
8585614e71bSYork Sun 	 * 3 = superbank (only if CS interleaving is enabled)
8595614e71bSYork Sun 	 */
8605614e71bSYork Sun 	popts->memctl_interleaving_mode = 0;
8615614e71bSYork Sun 
8625614e71bSYork Sun 	/*
8635614e71bSYork Sun 	 * 0: cacheline: bit 30 of the 36-bit physical addr selects the memctl
8645614e71bSYork Sun 	 * 1: page:      bit to the left of the column bits selects the memctl
8655614e71bSYork Sun 	 * 2: bank:      bit to the left of the bank bits selects the memctl
8665614e71bSYork Sun 	 * 3: superbank: bit to the left of the chip select selects the memctl
8675614e71bSYork Sun 	 *
8685614e71bSYork Sun 	 * NOTE: ba_intlv (rank interleaving) is independent of memory
8695614e71bSYork Sun 	 * controller interleaving; it is only within a memory controller.
8705614e71bSYork Sun 	 * Must use superbank interleaving if rank interleaving is used and
8715614e71bSYork Sun 	 * memory controller interleaving is enabled.
8725614e71bSYork Sun 	 */
8735614e71bSYork Sun 
8745614e71bSYork Sun 	/*
8755614e71bSYork Sun 	 * 0 = no
8765614e71bSYork Sun 	 * 0x40 = CS0,CS1
8775614e71bSYork Sun 	 * 0x20 = CS2,CS3
8785614e71bSYork Sun 	 * 0x60 = CS0,CS1 + CS2,CS3
8795614e71bSYork Sun 	 * 0x04 = CS0,CS1,CS2,CS3
8805614e71bSYork Sun 	 */
8815614e71bSYork Sun 	popts->ba_intlv_ctl = 0;
8825614e71bSYork Sun 
8835614e71bSYork Sun 	/* Memory Organization Parameters */
88456848428SYork Sun 	popts->registered_dimm_en = common_dimm->all_dimms_registered;
8855614e71bSYork Sun 
8865614e71bSYork Sun 	/* Operational Mode Paramters */
8875614e71bSYork Sun 
8885614e71bSYork Sun 	/* Pick ECC modes */
8895614e71bSYork Sun 	popts->ecc_mode = 0;		  /* 0 = disabled, 1 = enabled */
8905614e71bSYork Sun #ifdef CONFIG_DDR_ECC
8915614e71bSYork Sun 	if (hwconfig_sub_f("fsl_ddr", "ecc", buf)) {
8925614e71bSYork Sun 		if (hwconfig_subarg_cmp_f("fsl_ddr", "ecc", "on", buf))
8935614e71bSYork Sun 			popts->ecc_mode = 1;
8945614e71bSYork Sun 	} else
8955614e71bSYork Sun 		popts->ecc_mode = 1;
8965614e71bSYork Sun #endif
897b06f6f2fSYork Sun 	/* 1 = use memory controler to init data */
898b06f6f2fSYork Sun 	popts->ecc_init_using_memctl = popts->ecc_mode ? 1 : 0;
8995614e71bSYork Sun 
9005614e71bSYork Sun 	/*
9015614e71bSYork Sun 	 * Choose DQS config
9025614e71bSYork Sun 	 * 0 for DDR1
9035614e71bSYork Sun 	 * 1 for DDR2
9045614e71bSYork Sun 	 */
9055614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
9065614e71bSYork Sun 	popts->dqs_config = 0;
9075614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) || defined(CONFIG_SYS_FSL_DDR3)
9085614e71bSYork Sun 	popts->dqs_config = 1;
9095614e71bSYork Sun #endif
9105614e71bSYork Sun 
9115614e71bSYork Sun 	/* Choose self-refresh during sleep. */
9125614e71bSYork Sun 	popts->self_refresh_in_sleep = 1;
9135614e71bSYork Sun 
9145614e71bSYork Sun 	/* Choose dynamic power management mode. */
9155614e71bSYork Sun 	popts->dynamic_power = 0;
9165614e71bSYork Sun 
9175614e71bSYork Sun 	/*
9185614e71bSYork Sun 	 * check first dimm for primary sdram width
9195614e71bSYork Sun 	 * presuming all dimms are similar
9205614e71bSYork Sun 	 * 0 = 64-bit, 1 = 32-bit, 2 = 16-bit
9215614e71bSYork Sun 	 */
9225614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
9235614e71bSYork Sun 	if (pdimm[0].n_ranks != 0) {
9245614e71bSYork Sun 		if ((pdimm[0].data_width >= 64) && \
9255614e71bSYork Sun 			(pdimm[0].data_width <= 72))
9265614e71bSYork Sun 			popts->data_bus_width = 0;
9270e0de24bSxypron.glpk@gmx.de 		else if ((pdimm[0].data_width >= 32) && \
9285614e71bSYork Sun 			(pdimm[0].data_width <= 40))
9295614e71bSYork Sun 			popts->data_bus_width = 1;
9305614e71bSYork Sun 		else {
9315614e71bSYork Sun 			panic("Error: data width %u is invalid!\n",
9325614e71bSYork Sun 				pdimm[0].data_width);
9335614e71bSYork Sun 		}
9345614e71bSYork Sun 	}
9355614e71bSYork Sun #else
9365614e71bSYork Sun 	if (pdimm[0].n_ranks != 0) {
9375614e71bSYork Sun 		if (pdimm[0].primary_sdram_width == 64)
9385614e71bSYork Sun 			popts->data_bus_width = 0;
9395614e71bSYork Sun 		else if (pdimm[0].primary_sdram_width == 32)
9405614e71bSYork Sun 			popts->data_bus_width = 1;
9415614e71bSYork Sun 		else if (pdimm[0].primary_sdram_width == 16)
9425614e71bSYork Sun 			popts->data_bus_width = 2;
9435614e71bSYork Sun 		else {
9445614e71bSYork Sun 			panic("Error: primary sdram width %u is invalid!\n",
9455614e71bSYork Sun 				pdimm[0].primary_sdram_width);
9465614e71bSYork Sun 		}
9475614e71bSYork Sun 	}
9485614e71bSYork Sun #endif
9495614e71bSYork Sun 
9505614e71bSYork Sun 	popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0;
9515614e71bSYork Sun 
9525614e71bSYork Sun 	/* Choose burst length. */
95334e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
9545614e71bSYork Sun #if defined(CONFIG_E500MC)
9555614e71bSYork Sun 	popts->otf_burst_chop_en = 0;	/* on-the-fly burst chop disable */
9565614e71bSYork Sun 	popts->burst_length = DDR_BL8;	/* Fixed 8-beat burst len */
9575614e71bSYork Sun #else
9585614e71bSYork Sun 	if ((popts->data_bus_width == 1) || (popts->data_bus_width == 2)) {
9595614e71bSYork Sun 		/* 32-bit or 16-bit bus */
9605614e71bSYork Sun 		popts->otf_burst_chop_en = 0;
9615614e71bSYork Sun 		popts->burst_length = DDR_BL8;
9625614e71bSYork Sun 	} else {
9635614e71bSYork Sun 		popts->otf_burst_chop_en = 1;	/* on-the-fly burst chop */
9645614e71bSYork Sun 		popts->burst_length = DDR_OTF;	/* on-the-fly BC4 and BL8 */
9655614e71bSYork Sun 	}
9665614e71bSYork Sun #endif
9675614e71bSYork Sun #else
9685614e71bSYork Sun 	popts->burst_length = DDR_BL4;	/* has to be 4 for DDR2 */
9695614e71bSYork Sun #endif
9705614e71bSYork Sun 
9715614e71bSYork Sun 	/* Choose ddr controller address mirror mode */
97234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
9736b95be22SYork Sun 	for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
9746b95be22SYork Sun 		if (pdimm[i].n_ranks) {
9756b95be22SYork Sun 			popts->mirrored_dimm = pdimm[i].mirrored_dimm;
9766b95be22SYork Sun 			break;
9776b95be22SYork Sun 		}
9786b95be22SYork Sun 	}
9795614e71bSYork Sun #endif
9805614e71bSYork Sun 
9815614e71bSYork Sun 	/* Global Timing Parameters. */
98203e664d8SYork Sun 	debug("mclk_ps = %u ps\n", get_memory_clk_period_ps(ctrl_num));
9835614e71bSYork Sun 
9845614e71bSYork Sun 	/* Pick a caslat override. */
9855614e71bSYork Sun 	popts->cas_latency_override = 0;
9865614e71bSYork Sun 	popts->cas_latency_override_value = 3;
9875614e71bSYork Sun 	if (popts->cas_latency_override) {
9885614e71bSYork Sun 		debug("using caslat override value = %u\n",
9895614e71bSYork Sun 		       popts->cas_latency_override_value);
9905614e71bSYork Sun 	}
9915614e71bSYork Sun 
9925614e71bSYork Sun 	/* Decide whether to use the computed derated latency */
9935614e71bSYork Sun 	popts->use_derated_caslat = 0;
9945614e71bSYork Sun 
9955614e71bSYork Sun 	/* Choose an additive latency. */
9965614e71bSYork Sun 	popts->additive_latency_override = 0;
9975614e71bSYork Sun 	popts->additive_latency_override_value = 3;
9985614e71bSYork Sun 	if (popts->additive_latency_override) {
9995614e71bSYork Sun 		debug("using additive latency override value = %u\n",
10005614e71bSYork Sun 		       popts->additive_latency_override_value);
10015614e71bSYork Sun 	}
10025614e71bSYork Sun 
10035614e71bSYork Sun 	/*
10045614e71bSYork Sun 	 * 2T_EN setting
10055614e71bSYork Sun 	 *
10065614e71bSYork Sun 	 * Factors to consider for 2T_EN:
10075614e71bSYork Sun 	 *	- number of DIMMs installed
10085614e71bSYork Sun 	 *	- number of components, number of active ranks
10095614e71bSYork Sun 	 *	- how much time you want to spend playing around
10105614e71bSYork Sun 	 */
10115614e71bSYork Sun 	popts->twot_en = 0;
10125614e71bSYork Sun 	popts->threet_en = 0;
10135614e71bSYork Sun 
1014eb118807SShengzhou Liu 	/* for RDIMM and DDR4 UDIMM/discrete memory, address parity enable */
1015eb118807SShengzhou Liu 	if (popts->registered_dimm_en)
1016eb118807SShengzhou Liu 		popts->ap_en = 1; /* 0 = disable,  1 = enable */
1017eb118807SShengzhou Liu 	else
1018eb118807SShengzhou Liu 		popts->ap_en = 0; /* disabled for DDR4 UDIMM/discrete default */
1019eb118807SShengzhou Liu 
1020eb118807SShengzhou Liu 	if (hwconfig_sub_f("fsl_ddr", "parity", buf)) {
1021eb118807SShengzhou Liu 		if (hwconfig_subarg_cmp_f("fsl_ddr", "parity", "on", buf)) {
1022eb118807SShengzhou Liu 			if (popts->registered_dimm_en ||
1023eb118807SShengzhou Liu 			    (CONFIG_FSL_SDRAM_TYPE == SDRAM_TYPE_DDR4))
10245614e71bSYork Sun 				popts->ap_en = 1;
1025eb118807SShengzhou Liu 		}
1026eb118807SShengzhou Liu 	}
10275614e71bSYork Sun 
10285614e71bSYork Sun 	/*
10295614e71bSYork Sun 	 * BSTTOPRE precharge interval
10305614e71bSYork Sun 	 *
10315614e71bSYork Sun 	 * Set this to 0 for global auto precharge
103234e026f9SYork Sun 	 * The value of 0x100 has been used for DDR1, DDR2, DDR3.
103334e026f9SYork Sun 	 * It is not wrong. Any value should be OK. The performance depends on
103456848428SYork Sun 	 * applications. There is no one good value for all. One way to set
103556848428SYork Sun 	 * is to use 1/4 of refint value.
10365614e71bSYork Sun 	 */
103756848428SYork Sun 	popts->bstopre = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps)
103856848428SYork Sun 			 >> 2;
10395614e71bSYork Sun 
10405614e71bSYork Sun 	/*
10415614e71bSYork Sun 	 * Window for four activates -- tFAW
10425614e71bSYork Sun 	 *
10435614e71bSYork Sun 	 * FIXME: UM: applies only to DDR2/DDR3 with eight logical banks only
10445614e71bSYork Sun 	 * FIXME: varies depending upon number of column addresses or data
10455614e71bSYork Sun 	 * FIXME: width, was considering looking at pdimm->primary_sdram_width
10465614e71bSYork Sun 	 */
10475614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
104803e664d8SYork Sun 	popts->tfaw_window_four_activates_ps = mclk_to_picos(ctrl_num, 1);
10495614e71bSYork Sun 
10505614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
10515614e71bSYork Sun 	/*
10525614e71bSYork Sun 	 * x4/x8;  some datasheets have 35000
10535614e71bSYork Sun 	 * x16 wide columns only?  Use 50000?
10545614e71bSYork Sun 	 */
10555614e71bSYork Sun 	popts->tfaw_window_four_activates_ps = 37500;
10565614e71bSYork Sun 
105734e026f9SYork Sun #else
10585614e71bSYork Sun 	popts->tfaw_window_four_activates_ps = pdimm[0].tfaw_ps;
10595614e71bSYork Sun #endif
10605614e71bSYork Sun 	popts->zq_en = 0;
10615614e71bSYork Sun 	popts->wrlvl_en = 0;
106234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
10635614e71bSYork Sun 	/*
10645614e71bSYork Sun 	 * due to ddr3 dimm is fly-by topology
10655614e71bSYork Sun 	 * we suggest to enable write leveling to
10665614e71bSYork Sun 	 * meet the tQDSS under different loading.
10675614e71bSYork Sun 	 */
10685614e71bSYork Sun 	popts->wrlvl_en = 1;
10695614e71bSYork Sun 	popts->zq_en = 1;
10705614e71bSYork Sun 	popts->wrlvl_override = 0;
10715614e71bSYork Sun #endif
10725614e71bSYork Sun 
10735614e71bSYork Sun 	/*
10745614e71bSYork Sun 	 * Check interleaving configuration from environment.
10755614e71bSYork Sun 	 * Please refer to doc/README.fsl-ddr for the detail.
10765614e71bSYork Sun 	 *
10775614e71bSYork Sun 	 * If memory controller interleaving is enabled, then the data
10785614e71bSYork Sun 	 * bus widths must be programmed identically for all memory controllers.
10795614e71bSYork Sun 	 *
10806b1e1254SYork Sun 	 * Attempt to set all controllers to the same chip select
10815614e71bSYork Sun 	 * interleaving mode. It will do a best effort to get the
10825614e71bSYork Sun 	 * requested ranks interleaved together such that the result
10835614e71bSYork Sun 	 * should be a subset of the requested configuration.
10846b1e1254SYork Sun 	 *
10856b1e1254SYork Sun 	 * if CONFIG_SYS_FSL_DDR_INTLV_256B is defined, mandatory interleaving
10866b1e1254SYork Sun 	 * with 256 Byte is enabled.
10875614e71bSYork Sun 	 */
108851370d56SYork Sun #if (CONFIG_SYS_NUM_DDR_CTLRS > 1)
10895614e71bSYork Sun 	if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf))
10906b1e1254SYork Sun #ifdef CONFIG_SYS_FSL_DDR_INTLV_256B
10916b1e1254SYork Sun 		;
10926b1e1254SYork Sun #else
10935614e71bSYork Sun 		goto done;
10946b1e1254SYork Sun #endif
10955614e71bSYork Sun 	if (pdimm[0].n_ranks == 0) {
10965614e71bSYork Sun 		printf("There is no rank on CS0 for controller %d.\n", ctrl_num);
10975614e71bSYork Sun 		popts->memctl_interleaving = 0;
10985614e71bSYork Sun 		goto done;
10995614e71bSYork Sun 	}
11005614e71bSYork Sun 	popts->memctl_interleaving = 1;
11016b1e1254SYork Sun #ifdef CONFIG_SYS_FSL_DDR_INTLV_256B
11026b1e1254SYork Sun 	popts->memctl_interleaving_mode = FSL_DDR_256B_INTERLEAVING;
11036b1e1254SYork Sun 	popts->memctl_interleaving = 1;
11046b1e1254SYork Sun 	debug("256 Byte interleaving\n");
1105349689b8SYork Sun #else
11065614e71bSYork Sun 	/*
11075614e71bSYork Sun 	 * test null first. if CONFIG_HWCONFIG is not defined
11085614e71bSYork Sun 	 * hwconfig_arg_cmp returns non-zero
11095614e71bSYork Sun 	 */
11105614e71bSYork Sun 	if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
11115614e71bSYork Sun 				    "null", buf)) {
11125614e71bSYork Sun 		popts->memctl_interleaving = 0;
11135614e71bSYork Sun 		debug("memory controller interleaving disabled.\n");
11145614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11155614e71bSYork Sun 					"ctlr_intlv",
11165614e71bSYork Sun 					"cacheline", buf)) {
11175614e71bSYork Sun 		popts->memctl_interleaving_mode =
111851370d56SYork Sun 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
11195614e71bSYork Sun 			0 : FSL_DDR_CACHE_LINE_INTERLEAVING;
11205614e71bSYork Sun 		popts->memctl_interleaving =
112151370d56SYork Sun 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
11225614e71bSYork Sun 			0 : 1;
11235614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11245614e71bSYork Sun 					"ctlr_intlv",
11255614e71bSYork Sun 					"page", buf)) {
11265614e71bSYork Sun 		popts->memctl_interleaving_mode =
112751370d56SYork Sun 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
11285614e71bSYork Sun 			0 : FSL_DDR_PAGE_INTERLEAVING;
11295614e71bSYork Sun 		popts->memctl_interleaving =
113051370d56SYork Sun 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
11315614e71bSYork Sun 			0 : 1;
11325614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11335614e71bSYork Sun 					"ctlr_intlv",
11345614e71bSYork Sun 					"bank", buf)) {
11355614e71bSYork Sun 		popts->memctl_interleaving_mode =
113651370d56SYork Sun 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
11375614e71bSYork Sun 			0 : FSL_DDR_BANK_INTERLEAVING;
11385614e71bSYork Sun 		popts->memctl_interleaving =
113951370d56SYork Sun 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
11405614e71bSYork Sun 			0 : 1;
11415614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11425614e71bSYork Sun 					"ctlr_intlv",
11435614e71bSYork Sun 					"superbank", buf)) {
11445614e71bSYork Sun 		popts->memctl_interleaving_mode =
114551370d56SYork Sun 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
11465614e71bSYork Sun 			0 : FSL_DDR_SUPERBANK_INTERLEAVING;
11475614e71bSYork Sun 		popts->memctl_interleaving =
114851370d56SYork Sun 			((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ?
11495614e71bSYork Sun 			0 : 1;
115051370d56SYork Sun #if (CONFIG_SYS_NUM_DDR_CTLRS == 3)
11515614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11525614e71bSYork Sun 					"ctlr_intlv",
11535614e71bSYork Sun 					"3way_1KB", buf)) {
11545614e71bSYork Sun 		popts->memctl_interleaving_mode =
11555614e71bSYork Sun 			FSL_DDR_3WAY_1KB_INTERLEAVING;
11565614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11575614e71bSYork Sun 					"ctlr_intlv",
11585614e71bSYork Sun 					"3way_4KB", buf)) {
11595614e71bSYork Sun 		popts->memctl_interleaving_mode =
11605614e71bSYork Sun 			FSL_DDR_3WAY_4KB_INTERLEAVING;
11615614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11625614e71bSYork Sun 					"ctlr_intlv",
11635614e71bSYork Sun 					"3way_8KB", buf)) {
11645614e71bSYork Sun 		popts->memctl_interleaving_mode =
11655614e71bSYork Sun 			FSL_DDR_3WAY_8KB_INTERLEAVING;
116651370d56SYork Sun #elif (CONFIG_SYS_NUM_DDR_CTLRS == 4)
11675614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11685614e71bSYork Sun 					"ctlr_intlv",
11695614e71bSYork Sun 					"4way_1KB", buf)) {
11705614e71bSYork Sun 		popts->memctl_interleaving_mode =
11715614e71bSYork Sun 			FSL_DDR_4WAY_1KB_INTERLEAVING;
11725614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11735614e71bSYork Sun 					"ctlr_intlv",
11745614e71bSYork Sun 					"4way_4KB", buf)) {
11755614e71bSYork Sun 		popts->memctl_interleaving_mode =
11765614e71bSYork Sun 			FSL_DDR_4WAY_4KB_INTERLEAVING;
11775614e71bSYork Sun 	} else if (hwconfig_subarg_cmp_f("fsl_ddr",
11785614e71bSYork Sun 					"ctlr_intlv",
11795614e71bSYork Sun 					"4way_8KB", buf)) {
11805614e71bSYork Sun 		popts->memctl_interleaving_mode =
11815614e71bSYork Sun 			FSL_DDR_4WAY_8KB_INTERLEAVING;
11825614e71bSYork Sun #endif
11835614e71bSYork Sun 	} else {
11845614e71bSYork Sun 		popts->memctl_interleaving = 0;
11855614e71bSYork Sun 		printf("hwconfig has unrecognized parameter for ctlr_intlv.\n");
11865614e71bSYork Sun 	}
1187349689b8SYork Sun #endif	/* CONFIG_SYS_FSL_DDR_INTLV_256B */
11885614e71bSYork Sun done:
118951370d56SYork Sun #endif /* CONFIG_SYS_NUM_DDR_CTLRS > 1 */
11905614e71bSYork Sun 	if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) &&
11915614e71bSYork Sun 		(CONFIG_CHIP_SELECTS_PER_CTRL > 1)) {
11925614e71bSYork Sun 		/* test null first. if CONFIG_HWCONFIG is not defined,
11935614e71bSYork Sun 		 * hwconfig_subarg_cmp_f returns non-zero */
11945614e71bSYork Sun 		if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
11955614e71bSYork Sun 					    "null", buf))
11965614e71bSYork Sun 			debug("bank interleaving disabled.\n");
11975614e71bSYork Sun 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
11985614e71bSYork Sun 						 "cs0_cs1", buf))
11995614e71bSYork Sun 			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1;
12005614e71bSYork Sun 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
12015614e71bSYork Sun 						 "cs2_cs3", buf))
12025614e71bSYork Sun 			popts->ba_intlv_ctl = FSL_DDR_CS2_CS3;
12035614e71bSYork Sun 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
12045614e71bSYork Sun 						 "cs0_cs1_and_cs2_cs3", buf))
12055614e71bSYork Sun 			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_AND_CS2_CS3;
12065614e71bSYork Sun 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
12075614e71bSYork Sun 						 "cs0_cs1_cs2_cs3", buf))
12085614e71bSYork Sun 			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3;
12095614e71bSYork Sun 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
12105614e71bSYork Sun 						"auto", buf))
12115614e71bSYork Sun 			popts->ba_intlv_ctl = auto_bank_intlv(pdimm);
12125614e71bSYork Sun 		else
12135614e71bSYork Sun 			printf("hwconfig has unrecognized parameter for bank_intlv.\n");
12145614e71bSYork Sun 		switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
12155614e71bSYork Sun 		case FSL_DDR_CS0_CS1_CS2_CS3:
12165614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
12175614e71bSYork Sun 			if (pdimm[0].n_ranks < 4) {
12185614e71bSYork Sun 				popts->ba_intlv_ctl = 0;
12195614e71bSYork Sun 				printf("Not enough bank(chip-select) for "
12205614e71bSYork Sun 					"CS0+CS1+CS2+CS3 on controller %d, "
12215614e71bSYork Sun 					"interleaving disabled!\n", ctrl_num);
12225614e71bSYork Sun 			}
12235614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
12245614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
12255614e71bSYork Sun 			if (pdimm[0].n_ranks == 4)
12265614e71bSYork Sun 				break;
12275614e71bSYork Sun #endif
12285614e71bSYork Sun 			if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) {
12295614e71bSYork Sun 				popts->ba_intlv_ctl = 0;
12305614e71bSYork Sun 				printf("Not enough bank(chip-select) for "
12315614e71bSYork Sun 					"CS0+CS1+CS2+CS3 on controller %d, "
12325614e71bSYork Sun 					"interleaving disabled!\n", ctrl_num);
12335614e71bSYork Sun 			}
12345614e71bSYork Sun 			if (pdimm[0].capacity != pdimm[1].capacity) {
12355614e71bSYork Sun 				popts->ba_intlv_ctl = 0;
12365614e71bSYork Sun 				printf("Not identical DIMM size for "
12375614e71bSYork Sun 					"CS0+CS1+CS2+CS3 on controller %d, "
12385614e71bSYork Sun 					"interleaving disabled!\n", ctrl_num);
12395614e71bSYork Sun 			}
12405614e71bSYork Sun #endif
12415614e71bSYork Sun 			break;
12425614e71bSYork Sun 		case FSL_DDR_CS0_CS1:
12435614e71bSYork Sun 			if (pdimm[0].n_ranks < 2) {
12445614e71bSYork Sun 				popts->ba_intlv_ctl = 0;
12455614e71bSYork Sun 				printf("Not enough bank(chip-select) for "
12465614e71bSYork Sun 					"CS0+CS1 on controller %d, "
12475614e71bSYork Sun 					"interleaving disabled!\n", ctrl_num);
12485614e71bSYork Sun 			}
12495614e71bSYork Sun 			break;
12505614e71bSYork Sun 		case FSL_DDR_CS2_CS3:
12515614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
12525614e71bSYork Sun 			if (pdimm[0].n_ranks < 4) {
12535614e71bSYork Sun 				popts->ba_intlv_ctl = 0;
12545614e71bSYork Sun 				printf("Not enough bank(chip-select) for CS2+CS3 "
12555614e71bSYork Sun 					"on controller %d, interleaving disabled!\n", ctrl_num);
12565614e71bSYork Sun 			}
12575614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
12585614e71bSYork Sun 			if (pdimm[1].n_ranks < 2) {
12595614e71bSYork Sun 				popts->ba_intlv_ctl = 0;
12605614e71bSYork Sun 				printf("Not enough bank(chip-select) for CS2+CS3 "
12615614e71bSYork Sun 					"on controller %d, interleaving disabled!\n", ctrl_num);
12625614e71bSYork Sun 			}
12635614e71bSYork Sun #endif
12645614e71bSYork Sun 			break;
12655614e71bSYork Sun 		case FSL_DDR_CS0_CS1_AND_CS2_CS3:
12665614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
12675614e71bSYork Sun 			if (pdimm[0].n_ranks < 4) {
12685614e71bSYork Sun 				popts->ba_intlv_ctl = 0;
12695614e71bSYork Sun 				printf("Not enough bank(CS) for CS0+CS1 and "
12705614e71bSYork Sun 					"CS2+CS3 on controller %d, "
12715614e71bSYork Sun 					"interleaving disabled!\n", ctrl_num);
12725614e71bSYork Sun 			}
12735614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
12745614e71bSYork Sun 			if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) {
12755614e71bSYork Sun 				popts->ba_intlv_ctl = 0;
12765614e71bSYork Sun 				printf("Not enough bank(CS) for CS0+CS1 and "
12775614e71bSYork Sun 					"CS2+CS3 on controller %d, "
12785614e71bSYork Sun 					"interleaving disabled!\n", ctrl_num);
12795614e71bSYork Sun 			}
12805614e71bSYork Sun #endif
12815614e71bSYork Sun 			break;
12825614e71bSYork Sun 		default:
12835614e71bSYork Sun 			popts->ba_intlv_ctl = 0;
12845614e71bSYork Sun 			break;
12855614e71bSYork Sun 		}
12865614e71bSYork Sun 	}
12875614e71bSYork Sun 
12885614e71bSYork Sun 	if (hwconfig_sub_f("fsl_ddr", "addr_hash", buf)) {
12895614e71bSYork Sun 		if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash", "null", buf))
12905614e71bSYork Sun 			popts->addr_hash = 0;
12915614e71bSYork Sun 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash",
12925614e71bSYork Sun 					       "true", buf))
12935614e71bSYork Sun 			popts->addr_hash = 1;
12945614e71bSYork Sun 	}
12955614e71bSYork Sun 
12965614e71bSYork Sun 	if (pdimm[0].n_ranks == 4)
12975614e71bSYork Sun 		popts->quad_rank_present = 1;
12985614e71bSYork Sun 
1299c0c32af0SYork Sun 	popts->package_3ds = pdimm->package_3ds;
1300c0c32af0SYork Sun 
1301564e9383SYork Sun #if (CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4)
130203e664d8SYork Sun 	ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
13035614e71bSYork Sun 	if (popts->registered_dimm_en) {
13045614e71bSYork Sun 		popts->rcw_override = 1;
13055614e71bSYork Sun 		popts->rcw_1 = 0x000a5a00;
13065614e71bSYork Sun 		if (ddr_freq <= 800)
13075614e71bSYork Sun 			popts->rcw_2 = 0x00000000;
13085614e71bSYork Sun 		else if (ddr_freq <= 1066)
13095614e71bSYork Sun 			popts->rcw_2 = 0x00100000;
13105614e71bSYork Sun 		else if (ddr_freq <= 1333)
13115614e71bSYork Sun 			popts->rcw_2 = 0x00200000;
13125614e71bSYork Sun 		else
13135614e71bSYork Sun 			popts->rcw_2 = 0x00300000;
13145614e71bSYork Sun 	}
1315564e9383SYork Sun #endif
13165614e71bSYork Sun 
13175614e71bSYork Sun 	fsl_ddr_board_options(popts, pdimm, ctrl_num);
13185614e71bSYork Sun 
13195614e71bSYork Sun 	return 0;
13205614e71bSYork Sun }
13215614e71bSYork Sun 
check_interleaving_options(fsl_ddr_info_t * pinfo)13225614e71bSYork Sun void check_interleaving_options(fsl_ddr_info_t *pinfo)
13235614e71bSYork Sun {
13245614e71bSYork Sun 	int i, j, k, check_n_ranks, intlv_invalid = 0;
13255614e71bSYork Sun 	unsigned int check_intlv, check_n_row_addr, check_n_col_addr;
13265614e71bSYork Sun 	unsigned long long check_rank_density;
13275614e71bSYork Sun 	struct dimm_params_s *dimm;
13281d71efbbSYork Sun 	int first_ctrl = pinfo->first_ctrl;
13291d71efbbSYork Sun 	int last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
13301d71efbbSYork Sun 
13315614e71bSYork Sun 	/*
13325614e71bSYork Sun 	 * Check if all controllers are configured for memory
13335614e71bSYork Sun 	 * controller interleaving. Identical dimms are recommended. At least
13345614e71bSYork Sun 	 * the size, row and col address should be checked.
13355614e71bSYork Sun 	 */
13365614e71bSYork Sun 	j = 0;
13371d71efbbSYork Sun 	check_n_ranks = pinfo->dimm_params[first_ctrl][0].n_ranks;
13381d71efbbSYork Sun 	check_rank_density = pinfo->dimm_params[first_ctrl][0].rank_density;
13391d71efbbSYork Sun 	check_n_row_addr =  pinfo->dimm_params[first_ctrl][0].n_row_addr;
13401d71efbbSYork Sun 	check_n_col_addr = pinfo->dimm_params[first_ctrl][0].n_col_addr;
13411d71efbbSYork Sun 	check_intlv = pinfo->memctl_opts[first_ctrl].memctl_interleaving_mode;
13421d71efbbSYork Sun 	for (i = first_ctrl; i <= last_ctrl; i++) {
13435614e71bSYork Sun 		dimm = &pinfo->dimm_params[i][0];
13445614e71bSYork Sun 		if (!pinfo->memctl_opts[i].memctl_interleaving) {
13455614e71bSYork Sun 			continue;
13465614e71bSYork Sun 		} else if (((check_rank_density != dimm->rank_density) ||
13475614e71bSYork Sun 		     (check_n_ranks != dimm->n_ranks) ||
13485614e71bSYork Sun 		     (check_n_row_addr != dimm->n_row_addr) ||
13495614e71bSYork Sun 		     (check_n_col_addr != dimm->n_col_addr) ||
13505614e71bSYork Sun 		     (check_intlv !=
13515614e71bSYork Sun 			pinfo->memctl_opts[i].memctl_interleaving_mode))){
13525614e71bSYork Sun 			intlv_invalid = 1;
13535614e71bSYork Sun 			break;
13545614e71bSYork Sun 		} else {
13555614e71bSYork Sun 			j++;
13565614e71bSYork Sun 		}
13575614e71bSYork Sun 
13585614e71bSYork Sun 	}
13595614e71bSYork Sun 	if (intlv_invalid) {
13601d71efbbSYork Sun 		for (i = first_ctrl; i <= last_ctrl; i++)
13615614e71bSYork Sun 			pinfo->memctl_opts[i].memctl_interleaving = 0;
13625614e71bSYork Sun 		printf("Not all DIMMs are identical. "
13635614e71bSYork Sun 			"Memory controller interleaving disabled.\n");
13645614e71bSYork Sun 	} else {
13655614e71bSYork Sun 		switch (check_intlv) {
13666b1e1254SYork Sun 		case FSL_DDR_256B_INTERLEAVING:
13675614e71bSYork Sun 		case FSL_DDR_CACHE_LINE_INTERLEAVING:
13685614e71bSYork Sun 		case FSL_DDR_PAGE_INTERLEAVING:
13695614e71bSYork Sun 		case FSL_DDR_BANK_INTERLEAVING:
13705614e71bSYork Sun 		case FSL_DDR_SUPERBANK_INTERLEAVING:
137151370d56SYork Sun #if (3 == CONFIG_SYS_NUM_DDR_CTLRS)
13725614e71bSYork Sun 				k = 2;
1373349689b8SYork Sun #else
137451370d56SYork Sun 				k = CONFIG_SYS_NUM_DDR_CTLRS;
1375349689b8SYork Sun #endif
13765614e71bSYork Sun 			break;
13775614e71bSYork Sun 		case FSL_DDR_3WAY_1KB_INTERLEAVING:
13785614e71bSYork Sun 		case FSL_DDR_3WAY_4KB_INTERLEAVING:
13795614e71bSYork Sun 		case FSL_DDR_3WAY_8KB_INTERLEAVING:
13805614e71bSYork Sun 		case FSL_DDR_4WAY_1KB_INTERLEAVING:
13815614e71bSYork Sun 		case FSL_DDR_4WAY_4KB_INTERLEAVING:
13825614e71bSYork Sun 		case FSL_DDR_4WAY_8KB_INTERLEAVING:
13835614e71bSYork Sun 		default:
138451370d56SYork Sun 			k = CONFIG_SYS_NUM_DDR_CTLRS;
13855614e71bSYork Sun 			break;
13865614e71bSYork Sun 		}
13875614e71bSYork Sun 		debug("%d of %d controllers are interleaving.\n", j, k);
13885614e71bSYork Sun 		if (j && (j != k)) {
13891d71efbbSYork Sun 			for (i = first_ctrl; i <= last_ctrl; i++)
13905614e71bSYork Sun 				pinfo->memctl_opts[i].memctl_interleaving = 0;
13911d71efbbSYork Sun 			if ((last_ctrl - first_ctrl) > 1)
13921d71efbbSYork Sun 				puts("Not all controllers have compatible interleaving mode. All disabled.\n");
13935614e71bSYork Sun 		}
13945614e71bSYork Sun 	}
13955614e71bSYork Sun 	debug("Checking interleaving options completed\n");
13965614e71bSYork Sun }
13975614e71bSYork Sun 
fsl_use_spd(void)13985614e71bSYork Sun int fsl_use_spd(void)
13995614e71bSYork Sun {
14005614e71bSYork Sun 	int use_spd = 0;
14015614e71bSYork Sun 
14025614e71bSYork Sun #ifdef CONFIG_DDR_SPD
140386b840b7SJeremy Gebben 	char buf[HWCONFIG_BUFFER_SIZE];
14045614e71bSYork Sun 
14055614e71bSYork Sun 	/*
14065614e71bSYork Sun 	 * Extract hwconfig from environment since we have not properly setup
14075614e71bSYork Sun 	 * the environment but need it for ddr config params
14085614e71bSYork Sun 	 */
140986b840b7SJeremy Gebben 	if (env_get_f("hwconfig", buf, sizeof(buf)) < 0)
141086b840b7SJeremy Gebben 		buf[0] = '\0';
14115614e71bSYork Sun 
14125614e71bSYork Sun 	/* if hwconfig is not enabled, or "sdram" is not defined, use spd */
14135614e71bSYork Sun 	if (hwconfig_sub_f("fsl_ddr", "sdram", buf)) {
14145614e71bSYork Sun 		if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram", "spd", buf))
14155614e71bSYork Sun 			use_spd = 1;
14165614e71bSYork Sun 		else if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram",
14175614e71bSYork Sun 					       "fixed", buf))
14185614e71bSYork Sun 			use_spd = 0;
14195614e71bSYork Sun 		else
14205614e71bSYork Sun 			use_spd = 1;
14215614e71bSYork Sun 	} else
14225614e71bSYork Sun 		use_spd = 1;
14235614e71bSYork Sun #endif
14245614e71bSYork Sun 
14255614e71bSYork Sun 	return use_spd;
14265614e71bSYork Sun }
1427