xref: /openbmc/u-boot/drivers/ddr/fsl/ctrl_regs.c (revision d7c865bdf2588c5f5936cc92fe679c68397196e3)
15614e71bSYork Sun /*
234e026f9SYork Sun  * Copyright 2008-2014 Freescale Semiconductor, Inc.
35614e71bSYork Sun  *
45614e71bSYork Sun  * SPDX-License-Identifier:	GPL-2.0+
55614e71bSYork Sun  */
65614e71bSYork Sun 
75614e71bSYork Sun /*
85614e71bSYork Sun  * Generic driver for Freescale DDR/DDR2/DDR3 memory controller.
95614e71bSYork Sun  * Based on code from spd_sdram.c
105614e71bSYork Sun  * Author: James Yang [at freescale.com]
115614e71bSYork Sun  */
125614e71bSYork Sun 
135614e71bSYork Sun #include <common.h>
145614e71bSYork Sun #include <fsl_ddr_sdram.h>
155614e71bSYork Sun 
165614e71bSYork Sun #include <fsl_ddr.h>
179a17eb5bSYork Sun #include <fsl_immap.h>
185614e71bSYork Sun #include <asm/io.h>
195614e71bSYork Sun 
205614e71bSYork Sun /*
215614e71bSYork Sun  * Determine Rtt value.
225614e71bSYork Sun  *
235614e71bSYork Sun  * This should likely be either board or controller specific.
245614e71bSYork Sun  *
255614e71bSYork Sun  * Rtt(nominal) - DDR2:
265614e71bSYork Sun  *	0 = Rtt disabled
275614e71bSYork Sun  *	1 = 75 ohm
285614e71bSYork Sun  *	2 = 150 ohm
295614e71bSYork Sun  *	3 = 50 ohm
305614e71bSYork Sun  * Rtt(nominal) - DDR3:
315614e71bSYork Sun  *	0 = Rtt disabled
325614e71bSYork Sun  *	1 = 60 ohm
335614e71bSYork Sun  *	2 = 120 ohm
345614e71bSYork Sun  *	3 = 40 ohm
355614e71bSYork Sun  *	4 = 20 ohm
365614e71bSYork Sun  *	5 = 30 ohm
375614e71bSYork Sun  *
385614e71bSYork Sun  * FIXME: Apparently 8641 needs a value of 2
395614e71bSYork Sun  * FIXME: Old code seys if 667 MHz or higher, use 3 on 8572
405614e71bSYork Sun  *
415614e71bSYork Sun  * FIXME: There was some effort down this line earlier:
425614e71bSYork Sun  *
435614e71bSYork Sun  *	unsigned int i;
445614e71bSYork Sun  *	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL/2; i++) {
455614e71bSYork Sun  *		if (popts->dimmslot[i].num_valid_cs
465614e71bSYork Sun  *		    && (popts->cs_local_opts[2*i].odt_rd_cfg
475614e71bSYork Sun  *			|| popts->cs_local_opts[2*i].odt_wr_cfg)) {
485614e71bSYork Sun  *			rtt = 2;
495614e71bSYork Sun  *			break;
505614e71bSYork Sun  *		}
515614e71bSYork Sun  *	}
525614e71bSYork Sun  */
535614e71bSYork Sun static inline int fsl_ddr_get_rtt(void)
545614e71bSYork Sun {
555614e71bSYork Sun 	int rtt;
565614e71bSYork Sun 
575614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
585614e71bSYork Sun 	rtt = 0;
595614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
605614e71bSYork Sun 	rtt = 3;
615614e71bSYork Sun #else
625614e71bSYork Sun 	rtt = 0;
635614e71bSYork Sun #endif
645614e71bSYork Sun 
655614e71bSYork Sun 	return rtt;
665614e71bSYork Sun }
675614e71bSYork Sun 
6834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
6934e026f9SYork Sun /*
7034e026f9SYork Sun  * compute CAS write latency according to DDR4 spec
7134e026f9SYork Sun  * CWL = 9 for <= 1600MT/s
7234e026f9SYork Sun  *       10 for <= 1866MT/s
7334e026f9SYork Sun  *       11 for <= 2133MT/s
7434e026f9SYork Sun  *       12 for <= 2400MT/s
7534e026f9SYork Sun  *       14 for <= 2667MT/s
7634e026f9SYork Sun  *       16 for <= 2933MT/s
7734e026f9SYork Sun  *       18 for higher
7834e026f9SYork Sun  */
7903e664d8SYork Sun static inline unsigned int compute_cas_write_latency(
8003e664d8SYork Sun 				const unsigned int ctrl_num)
8134e026f9SYork Sun {
8234e026f9SYork Sun 	unsigned int cwl;
8303e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
8434e026f9SYork Sun 	if (mclk_ps >= 1250)
8534e026f9SYork Sun 		cwl = 9;
8634e026f9SYork Sun 	else if (mclk_ps >= 1070)
8734e026f9SYork Sun 		cwl = 10;
8834e026f9SYork Sun 	else if (mclk_ps >= 935)
8934e026f9SYork Sun 		cwl = 11;
9034e026f9SYork Sun 	else if (mclk_ps >= 833)
9134e026f9SYork Sun 		cwl = 12;
9234e026f9SYork Sun 	else if (mclk_ps >= 750)
9334e026f9SYork Sun 		cwl = 14;
9434e026f9SYork Sun 	else if (mclk_ps >= 681)
9534e026f9SYork Sun 		cwl = 16;
9634e026f9SYork Sun 	else
9734e026f9SYork Sun 		cwl = 18;
9834e026f9SYork Sun 
9934e026f9SYork Sun 	return cwl;
10034e026f9SYork Sun }
10134e026f9SYork Sun #else
1025614e71bSYork Sun /*
1035614e71bSYork Sun  * compute the CAS write latency according to DDR3 spec
1045614e71bSYork Sun  * CWL = 5 if tCK >= 2.5ns
1055614e71bSYork Sun  *       6 if 2.5ns > tCK >= 1.875ns
1065614e71bSYork Sun  *       7 if 1.875ns > tCK >= 1.5ns
1075614e71bSYork Sun  *       8 if 1.5ns > tCK >= 1.25ns
1085614e71bSYork Sun  *       9 if 1.25ns > tCK >= 1.07ns
1095614e71bSYork Sun  *       10 if 1.07ns > tCK >= 0.935ns
1105614e71bSYork Sun  *       11 if 0.935ns > tCK >= 0.833ns
1115614e71bSYork Sun  *       12 if 0.833ns > tCK >= 0.75ns
1125614e71bSYork Sun  */
11303e664d8SYork Sun static inline unsigned int compute_cas_write_latency(
11403e664d8SYork Sun 				const unsigned int ctrl_num)
1155614e71bSYork Sun {
1165614e71bSYork Sun 	unsigned int cwl;
11703e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
1185614e71bSYork Sun 
1195614e71bSYork Sun 	if (mclk_ps >= 2500)
1205614e71bSYork Sun 		cwl = 5;
1215614e71bSYork Sun 	else if (mclk_ps >= 1875)
1225614e71bSYork Sun 		cwl = 6;
1235614e71bSYork Sun 	else if (mclk_ps >= 1500)
1245614e71bSYork Sun 		cwl = 7;
1255614e71bSYork Sun 	else if (mclk_ps >= 1250)
1265614e71bSYork Sun 		cwl = 8;
1275614e71bSYork Sun 	else if (mclk_ps >= 1070)
1285614e71bSYork Sun 		cwl = 9;
1295614e71bSYork Sun 	else if (mclk_ps >= 935)
1305614e71bSYork Sun 		cwl = 10;
1315614e71bSYork Sun 	else if (mclk_ps >= 833)
1325614e71bSYork Sun 		cwl = 11;
1335614e71bSYork Sun 	else if (mclk_ps >= 750)
1345614e71bSYork Sun 		cwl = 12;
1355614e71bSYork Sun 	else {
1365614e71bSYork Sun 		cwl = 12;
1375614e71bSYork Sun 		printf("Warning: CWL is out of range\n");
1385614e71bSYork Sun 	}
1395614e71bSYork Sun 	return cwl;
1405614e71bSYork Sun }
14134e026f9SYork Sun #endif
1425614e71bSYork Sun 
1435614e71bSYork Sun /* Chip Select Configuration (CSn_CONFIG) */
1445614e71bSYork Sun static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr,
1455614e71bSYork Sun 			       const memctl_options_t *popts,
1465614e71bSYork Sun 			       const dimm_params_t *dimm_params)
1475614e71bSYork Sun {
1485614e71bSYork Sun 	unsigned int cs_n_en = 0; /* Chip Select enable */
1495614e71bSYork Sun 	unsigned int intlv_en = 0; /* Memory controller interleave enable */
1505614e71bSYork Sun 	unsigned int intlv_ctl = 0; /* Interleaving control */
1515614e71bSYork Sun 	unsigned int ap_n_en = 0; /* Chip select n auto-precharge enable */
1525614e71bSYork Sun 	unsigned int odt_rd_cfg = 0; /* ODT for reads configuration */
1535614e71bSYork Sun 	unsigned int odt_wr_cfg = 0; /* ODT for writes configuration */
1545614e71bSYork Sun 	unsigned int ba_bits_cs_n = 0; /* Num of bank bits for SDRAM on CSn */
1555614e71bSYork Sun 	unsigned int row_bits_cs_n = 0; /* Num of row bits for SDRAM on CSn */
1565614e71bSYork Sun 	unsigned int col_bits_cs_n = 0; /* Num of ocl bits for SDRAM on CSn */
1575614e71bSYork Sun 	int go_config = 0;
15834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
15934e026f9SYork Sun 	unsigned int bg_bits_cs_n = 0; /* Num of bank group bits */
16034e026f9SYork Sun #else
16134e026f9SYork Sun 	unsigned int n_banks_per_sdram_device;
16234e026f9SYork Sun #endif
1635614e71bSYork Sun 
1645614e71bSYork Sun 	/* Compute CS_CONFIG only for existing ranks of each DIMM.  */
1655614e71bSYork Sun 	switch (i) {
1665614e71bSYork Sun 	case 0:
1675614e71bSYork Sun 		if (dimm_params[dimm_number].n_ranks > 0) {
1685614e71bSYork Sun 			go_config = 1;
1695614e71bSYork Sun 			/* These fields only available in CS0_CONFIG */
1705614e71bSYork Sun 			if (!popts->memctl_interleaving)
1715614e71bSYork Sun 				break;
1725614e71bSYork Sun 			switch (popts->memctl_interleaving_mode) {
1736b1e1254SYork Sun 			case FSL_DDR_256B_INTERLEAVING:
1745614e71bSYork Sun 			case FSL_DDR_CACHE_LINE_INTERLEAVING:
1755614e71bSYork Sun 			case FSL_DDR_PAGE_INTERLEAVING:
1765614e71bSYork Sun 			case FSL_DDR_BANK_INTERLEAVING:
1775614e71bSYork Sun 			case FSL_DDR_SUPERBANK_INTERLEAVING:
1785614e71bSYork Sun 				intlv_en = popts->memctl_interleaving;
1795614e71bSYork Sun 				intlv_ctl = popts->memctl_interleaving_mode;
1805614e71bSYork Sun 				break;
1815614e71bSYork Sun 			default:
1825614e71bSYork Sun 				break;
1835614e71bSYork Sun 			}
1845614e71bSYork Sun 		}
1855614e71bSYork Sun 		break;
1865614e71bSYork Sun 	case 1:
1875614e71bSYork Sun 		if ((dimm_number == 0 && dimm_params[0].n_ranks > 1) || \
1885614e71bSYork Sun 		    (dimm_number == 1 && dimm_params[1].n_ranks > 0))
1895614e71bSYork Sun 			go_config = 1;
1905614e71bSYork Sun 		break;
1915614e71bSYork Sun 	case 2:
1925614e71bSYork Sun 		if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \
1935614e71bSYork Sun 		   (dimm_number >= 1 && dimm_params[dimm_number].n_ranks > 0))
1945614e71bSYork Sun 			go_config = 1;
1955614e71bSYork Sun 		break;
1965614e71bSYork Sun 	case 3:
1975614e71bSYork Sun 		if ((dimm_number == 0 && dimm_params[0].n_ranks > 3) || \
1985614e71bSYork Sun 		    (dimm_number == 1 && dimm_params[1].n_ranks > 1) || \
1995614e71bSYork Sun 		    (dimm_number == 3 && dimm_params[3].n_ranks > 0))
2005614e71bSYork Sun 			go_config = 1;
2015614e71bSYork Sun 		break;
2025614e71bSYork Sun 	default:
2035614e71bSYork Sun 		break;
2045614e71bSYork Sun 	}
2055614e71bSYork Sun 	if (go_config) {
2065614e71bSYork Sun 		cs_n_en = 1;
2075614e71bSYork Sun 		ap_n_en = popts->cs_local_opts[i].auto_precharge;
2085614e71bSYork Sun 		odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg;
2095614e71bSYork Sun 		odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg;
21034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
21134e026f9SYork Sun 		ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits;
21234e026f9SYork Sun 		bg_bits_cs_n = dimm_params[dimm_number].bank_group_bits;
21334e026f9SYork Sun #else
2145614e71bSYork Sun 		n_banks_per_sdram_device
2155614e71bSYork Sun 			= dimm_params[dimm_number].n_banks_per_sdram_device;
2165614e71bSYork Sun 		ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2;
21734e026f9SYork Sun #endif
2185614e71bSYork Sun 		row_bits_cs_n = dimm_params[dimm_number].n_row_addr - 12;
2195614e71bSYork Sun 		col_bits_cs_n = dimm_params[dimm_number].n_col_addr - 8;
2205614e71bSYork Sun 	}
2215614e71bSYork Sun 	ddr->cs[i].config = (0
2225614e71bSYork Sun 		| ((cs_n_en & 0x1) << 31)
2235614e71bSYork Sun 		| ((intlv_en & 0x3) << 29)
2245614e71bSYork Sun 		| ((intlv_ctl & 0xf) << 24)
2255614e71bSYork Sun 		| ((ap_n_en & 0x1) << 23)
2265614e71bSYork Sun 
2275614e71bSYork Sun 		/* XXX: some implementation only have 1 bit starting at left */
2285614e71bSYork Sun 		| ((odt_rd_cfg & 0x7) << 20)
2295614e71bSYork Sun 
2305614e71bSYork Sun 		/* XXX: Some implementation only have 1 bit starting at left */
2315614e71bSYork Sun 		| ((odt_wr_cfg & 0x7) << 16)
2325614e71bSYork Sun 
2335614e71bSYork Sun 		| ((ba_bits_cs_n & 0x3) << 14)
2345614e71bSYork Sun 		| ((row_bits_cs_n & 0x7) << 8)
23534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
23634e026f9SYork Sun 		| ((bg_bits_cs_n & 0x3) << 4)
23734e026f9SYork Sun #endif
2385614e71bSYork Sun 		| ((col_bits_cs_n & 0x7) << 0)
2395614e71bSYork Sun 		);
2405614e71bSYork Sun 	debug("FSLDDR: cs[%d]_config = 0x%08x\n", i,ddr->cs[i].config);
2415614e71bSYork Sun }
2425614e71bSYork Sun 
2435614e71bSYork Sun /* Chip Select Configuration 2 (CSn_CONFIG_2) */
2445614e71bSYork Sun /* FIXME: 8572 */
2455614e71bSYork Sun static void set_csn_config_2(int i, fsl_ddr_cfg_regs_t *ddr)
2465614e71bSYork Sun {
2475614e71bSYork Sun 	unsigned int pasr_cfg = 0;	/* Partial array self refresh config */
2485614e71bSYork Sun 
2495614e71bSYork Sun 	ddr->cs[i].config_2 = ((pasr_cfg & 7) << 24);
2505614e71bSYork Sun 	debug("FSLDDR: cs[%d]_config_2 = 0x%08x\n", i, ddr->cs[i].config_2);
2515614e71bSYork Sun }
2525614e71bSYork Sun 
2535614e71bSYork Sun /* -3E = 667 CL5, -25 = CL6 800, -25E = CL5 800 */
2545614e71bSYork Sun 
2555614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1)
25684baed2aSYork Sun /*
25784baed2aSYork Sun  * Check DIMM configuration, return 2 if quad-rank or two dual-rank
25884baed2aSYork Sun  * Return 1 if other two slots configuration. Return 0 if single slot.
25984baed2aSYork Sun  */
2605614e71bSYork Sun static inline int avoid_odt_overlap(const dimm_params_t *dimm_params)
2615614e71bSYork Sun {
2625614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 1
2635614e71bSYork Sun 	if (dimm_params[0].n_ranks == 4)
26484baed2aSYork Sun 		return 2;
2655614e71bSYork Sun #endif
2665614e71bSYork Sun 
2675614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 2
2685614e71bSYork Sun 	if ((dimm_params[0].n_ranks == 2) &&
2695614e71bSYork Sun 		(dimm_params[1].n_ranks == 2))
27084baed2aSYork Sun 		return 2;
2715614e71bSYork Sun 
2725614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
2735614e71bSYork Sun 	if (dimm_params[0].n_ranks == 4)
27484baed2aSYork Sun 		return 2;
2755614e71bSYork Sun #endif
27684baed2aSYork Sun 
27784baed2aSYork Sun 	if ((dimm_params[0].n_ranks != 0) &&
27884baed2aSYork Sun 	    (dimm_params[2].n_ranks != 0))
27984baed2aSYork Sun 		return 1;
2805614e71bSYork Sun #endif
2815614e71bSYork Sun 	return 0;
2825614e71bSYork Sun }
2835614e71bSYork Sun 
2845614e71bSYork Sun /*
2855614e71bSYork Sun  * DDR SDRAM Timing Configuration 0 (TIMING_CFG_0)
2865614e71bSYork Sun  *
2875614e71bSYork Sun  * Avoid writing for DDR I.  The new PQ38 DDR controller
2885614e71bSYork Sun  * dreams up non-zero default values to be backwards compatible.
2895614e71bSYork Sun  */
29003e664d8SYork Sun static void set_timing_cfg_0(const unsigned int ctrl_num,
29103e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
2925614e71bSYork Sun 				const memctl_options_t *popts,
2935614e71bSYork Sun 				const dimm_params_t *dimm_params)
2945614e71bSYork Sun {
2955614e71bSYork Sun 	unsigned char trwt_mclk = 0;   /* Read-to-write turnaround */
2965614e71bSYork Sun 	unsigned char twrt_mclk = 0;   /* Write-to-read turnaround */
2975614e71bSYork Sun 	/* 7.5 ns on -3E; 0 means WL - CL + BL/2 + 1 */
2985614e71bSYork Sun 	unsigned char trrt_mclk = 0;   /* Read-to-read turnaround */
2995614e71bSYork Sun 	unsigned char twwt_mclk = 0;   /* Write-to-write turnaround */
3005614e71bSYork Sun 
3015614e71bSYork Sun 	/* Active powerdown exit timing (tXARD and tXARDS). */
3025614e71bSYork Sun 	unsigned char act_pd_exit_mclk;
3035614e71bSYork Sun 	/* Precharge powerdown exit timing (tXP). */
3045614e71bSYork Sun 	unsigned char pre_pd_exit_mclk;
3055614e71bSYork Sun 	/* ODT powerdown exit timing (tAXPD). */
30634e026f9SYork Sun 	unsigned char taxpd_mclk = 0;
3075614e71bSYork Sun 	/* Mode register set cycle time (tMRD). */
3085614e71bSYork Sun 	unsigned char tmrd_mclk;
309bb578322SYork Sun #if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
31003e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
311bb578322SYork Sun #endif
3125614e71bSYork Sun 
31334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
31434e026f9SYork Sun 	/* tXP=max(4nCK, 6ns) */
315b4141195SMasahiro Yamada 	int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
31634e026f9SYork Sun 	trwt_mclk = 2;
31734e026f9SYork Sun 	twrt_mclk = 1;
31803e664d8SYork Sun 	act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
31934e026f9SYork Sun 	pre_pd_exit_mclk = act_pd_exit_mclk;
32034e026f9SYork Sun 	/*
32134e026f9SYork Sun 	 * MRS_CYC = max(tMRD, tMOD)
32234e026f9SYork Sun 	 * tMRD = 8nCK, tMOD = max(24nCK, 15ns)
32334e026f9SYork Sun 	 */
32403e664d8SYork Sun 	tmrd_mclk = max(24U, picos_to_mclk(ctrl_num, 15000));
32534e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
32603e664d8SYork Sun 	unsigned int data_rate = get_ddr_freq(ctrl_num);
327bb578322SYork Sun 	int txp;
328938bbb60SYork Sun 	unsigned int ip_rev;
32984baed2aSYork Sun 	int odt_overlap;
3305614e71bSYork Sun 	/*
3315614e71bSYork Sun 	 * (tXARD and tXARDS). Empirical?
3325614e71bSYork Sun 	 * The DDR3 spec has not tXARD,
3335614e71bSYork Sun 	 * we use the tXP instead of it.
334bb578322SYork Sun 	 * tXP=max(3nCK, 7.5ns) for DDR3-800, 1066
335bb578322SYork Sun 	 *     max(3nCK, 6ns) for DDR3-1333, 1600, 1866, 2133
3365614e71bSYork Sun 	 * spec has not the tAXPD, we use
3375614e71bSYork Sun 	 * tAXPD=1, need design to confirm.
3385614e71bSYork Sun 	 */
339b4141195SMasahiro Yamada 	txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000));
340bb578322SYork Sun 
341938bbb60SYork Sun 	ip_rev = fsl_ddr_get_version();
342938bbb60SYork Sun 	if (ip_rev >= 0x40700) {
343938bbb60SYork Sun 		/*
344938bbb60SYork Sun 		 * MRS_CYC = max(tMRD, tMOD)
345938bbb60SYork Sun 		 * tMRD = 4nCK (8nCK for RDIMM)
346938bbb60SYork Sun 		 * tMOD = max(12nCK, 15ns)
347938bbb60SYork Sun 		 */
34803e664d8SYork Sun 		tmrd_mclk = max((unsigned int)12,
34903e664d8SYork Sun 				picos_to_mclk(ctrl_num, 15000));
350938bbb60SYork Sun 	} else {
351938bbb60SYork Sun 		/*
352938bbb60SYork Sun 		 * MRS_CYC = tMRD
353938bbb60SYork Sun 		 * tMRD = 4nCK (8nCK for RDIMM)
354938bbb60SYork Sun 		 */
355938bbb60SYork Sun 		if (popts->registered_dimm_en)
356938bbb60SYork Sun 			tmrd_mclk = 8;
357938bbb60SYork Sun 		else
3585614e71bSYork Sun 			tmrd_mclk = 4;
359938bbb60SYork Sun 	}
360938bbb60SYork Sun 
3615614e71bSYork Sun 	/* set the turnaround time */
3625614e71bSYork Sun 
3635614e71bSYork Sun 	/*
36484baed2aSYork Sun 	 * for single quad-rank DIMM and two-slot DIMMs
3655614e71bSYork Sun 	 * to avoid ODT overlap
3665614e71bSYork Sun 	 */
36784baed2aSYork Sun 	odt_overlap = avoid_odt_overlap(dimm_params);
36884baed2aSYork Sun 	switch (odt_overlap) {
36984baed2aSYork Sun 	case 2:
3705614e71bSYork Sun 		twwt_mclk = 2;
3715614e71bSYork Sun 		trrt_mclk = 1;
37284baed2aSYork Sun 		break;
37384baed2aSYork Sun 	case 1:
37484baed2aSYork Sun 		twwt_mclk = 1;
37584baed2aSYork Sun 		trrt_mclk = 0;
37684baed2aSYork Sun 		break;
37784baed2aSYork Sun 	default:
37884baed2aSYork Sun 		break;
3795614e71bSYork Sun 	}
38084baed2aSYork Sun 
3815614e71bSYork Sun 	/* for faster clock, need more time for data setup */
3825614e71bSYork Sun 	trwt_mclk = (data_rate/1000000 > 1800) ? 2 : 1;
3835614e71bSYork Sun 
3845614e71bSYork Sun 	if ((data_rate/1000000 > 1150) || (popts->memctl_interleaving))
3855614e71bSYork Sun 		twrt_mclk = 1;
3865614e71bSYork Sun 
3875614e71bSYork Sun 	if (popts->dynamic_power == 0) {	/* powerdown is not used */
3885614e71bSYork Sun 		act_pd_exit_mclk = 1;
3895614e71bSYork Sun 		pre_pd_exit_mclk = 1;
3905614e71bSYork Sun 		taxpd_mclk = 1;
3915614e71bSYork Sun 	} else {
3925614e71bSYork Sun 		/* act_pd_exit_mclk = tXARD, see above */
39303e664d8SYork Sun 		act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
3945614e71bSYork Sun 		/* Mode register MR0[A12] is '1' - fast exit */
3955614e71bSYork Sun 		pre_pd_exit_mclk = act_pd_exit_mclk;
3965614e71bSYork Sun 		taxpd_mclk = 1;
3975614e71bSYork Sun 	}
3985614e71bSYork Sun #else /* CONFIG_SYS_FSL_DDR2 */
3995614e71bSYork Sun 	/*
4005614e71bSYork Sun 	 * (tXARD and tXARDS). Empirical?
4015614e71bSYork Sun 	 * tXARD = 2 for DDR2
4025614e71bSYork Sun 	 * tXP=2
4035614e71bSYork Sun 	 * tAXPD=8
4045614e71bSYork Sun 	 */
4055614e71bSYork Sun 	act_pd_exit_mclk = 2;
4065614e71bSYork Sun 	pre_pd_exit_mclk = 2;
4075614e71bSYork Sun 	taxpd_mclk = 8;
4085614e71bSYork Sun 	tmrd_mclk = 2;
4095614e71bSYork Sun #endif
4105614e71bSYork Sun 
4115614e71bSYork Sun 	if (popts->trwt_override)
4125614e71bSYork Sun 		trwt_mclk = popts->trwt;
4135614e71bSYork Sun 
4145614e71bSYork Sun 	ddr->timing_cfg_0 = (0
4155614e71bSYork Sun 		| ((trwt_mclk & 0x3) << 30)	/* RWT */
4165614e71bSYork Sun 		| ((twrt_mclk & 0x3) << 28)	/* WRT */
4175614e71bSYork Sun 		| ((trrt_mclk & 0x3) << 26)	/* RRT */
4185614e71bSYork Sun 		| ((twwt_mclk & 0x3) << 24)	/* WWT */
419d4263b8aSYork Sun 		| ((act_pd_exit_mclk & 0xf) << 20)  /* ACT_PD_EXIT */
4205614e71bSYork Sun 		| ((pre_pd_exit_mclk & 0xF) << 16)  /* PRE_PD_EXIT */
4215614e71bSYork Sun 		| ((taxpd_mclk & 0xf) << 8)	/* ODT_PD_EXIT */
422d4263b8aSYork Sun 		| ((tmrd_mclk & 0x1f) << 0)	/* MRS_CYC */
4235614e71bSYork Sun 		);
4245614e71bSYork Sun 	debug("FSLDDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
4255614e71bSYork Sun }
42684baed2aSYork Sun #endif	/* !defined(CONFIG_SYS_FSL_DDR1) */
4275614e71bSYork Sun 
4285614e71bSYork Sun /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */
42903e664d8SYork Sun static void set_timing_cfg_3(const unsigned int ctrl_num,
43003e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
4315614e71bSYork Sun 			     const memctl_options_t *popts,
4325614e71bSYork Sun 			     const common_timing_params_t *common_dimm,
433d4263b8aSYork Sun 			     unsigned int cas_latency,
434d4263b8aSYork Sun 			     unsigned int additive_latency)
4355614e71bSYork Sun {
4365614e71bSYork Sun 	/* Extended precharge to activate interval (tRP) */
4375614e71bSYork Sun 	unsigned int ext_pretoact = 0;
4385614e71bSYork Sun 	/* Extended Activate to precharge interval (tRAS) */
4395614e71bSYork Sun 	unsigned int ext_acttopre = 0;
4405614e71bSYork Sun 	/* Extended activate to read/write interval (tRCD) */
4415614e71bSYork Sun 	unsigned int ext_acttorw = 0;
4425614e71bSYork Sun 	/* Extended refresh recovery time (tRFC) */
4435614e71bSYork Sun 	unsigned int ext_refrec;
4445614e71bSYork Sun 	/* Extended MCAS latency from READ cmd */
4455614e71bSYork Sun 	unsigned int ext_caslat = 0;
446d4263b8aSYork Sun 	/* Extended additive latency */
447d4263b8aSYork Sun 	unsigned int ext_add_lat = 0;
4485614e71bSYork Sun 	/* Extended last data to precharge interval (tWR) */
4495614e71bSYork Sun 	unsigned int ext_wrrec = 0;
4505614e71bSYork Sun 	/* Control Adjust */
4515614e71bSYork Sun 	unsigned int cntl_adj = 0;
4525614e71bSYork Sun 
45303e664d8SYork Sun 	ext_pretoact = picos_to_mclk(ctrl_num, common_dimm->trp_ps) >> 4;
45403e664d8SYork Sun 	ext_acttopre = picos_to_mclk(ctrl_num, common_dimm->tras_ps) >> 4;
45503e664d8SYork Sun 	ext_acttorw = picos_to_mclk(ctrl_num, common_dimm->trcd_ps) >> 4;
4565614e71bSYork Sun 	ext_caslat = (2 * cas_latency - 1) >> 4;
457d4263b8aSYork Sun 	ext_add_lat = additive_latency >> 4;
45834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
45903e664d8SYork Sun 	ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8) >> 4;
46034e026f9SYork Sun #else
46103e664d8SYork Sun 	ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8) >> 4;
4625614e71bSYork Sun 	/* ext_wrrec only deals with 16 clock and above, or 14 with OTF */
46334e026f9SYork Sun #endif
46403e664d8SYork Sun 	ext_wrrec = (picos_to_mclk(ctrl_num, common_dimm->twr_ps) +
4655614e71bSYork Sun 		(popts->otf_burst_chop_en ? 2 : 0)) >> 4;
4665614e71bSYork Sun 
4675614e71bSYork Sun 	ddr->timing_cfg_3 = (0
4685614e71bSYork Sun 		| ((ext_pretoact & 0x1) << 28)
4695614e71bSYork Sun 		| ((ext_acttopre & 0x3) << 24)
4705614e71bSYork Sun 		| ((ext_acttorw & 0x1) << 22)
4715614e71bSYork Sun 		| ((ext_refrec & 0x1F) << 16)
4725614e71bSYork Sun 		| ((ext_caslat & 0x3) << 12)
473d4263b8aSYork Sun 		| ((ext_add_lat & 0x1) << 10)
4745614e71bSYork Sun 		| ((ext_wrrec & 0x1) << 8)
4755614e71bSYork Sun 		| ((cntl_adj & 0x7) << 0)
4765614e71bSYork Sun 		);
4775614e71bSYork Sun 	debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3);
4785614e71bSYork Sun }
4795614e71bSYork Sun 
4805614e71bSYork Sun /* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */
48103e664d8SYork Sun static void set_timing_cfg_1(const unsigned int ctrl_num,
48203e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
4835614e71bSYork Sun 			     const memctl_options_t *popts,
4845614e71bSYork Sun 			     const common_timing_params_t *common_dimm,
4855614e71bSYork Sun 			     unsigned int cas_latency)
4865614e71bSYork Sun {
4875614e71bSYork Sun 	/* Precharge-to-activate interval (tRP) */
4885614e71bSYork Sun 	unsigned char pretoact_mclk;
4895614e71bSYork Sun 	/* Activate to precharge interval (tRAS) */
4905614e71bSYork Sun 	unsigned char acttopre_mclk;
4915614e71bSYork Sun 	/*  Activate to read/write interval (tRCD) */
4925614e71bSYork Sun 	unsigned char acttorw_mclk;
4935614e71bSYork Sun 	/* CASLAT */
4945614e71bSYork Sun 	unsigned char caslat_ctrl;
4955614e71bSYork Sun 	/*  Refresh recovery time (tRFC) ; trfc_low */
4965614e71bSYork Sun 	unsigned char refrec_ctrl;
4975614e71bSYork Sun 	/* Last data to precharge minimum interval (tWR) */
4985614e71bSYork Sun 	unsigned char wrrec_mclk;
4995614e71bSYork Sun 	/* Activate-to-activate interval (tRRD) */
5005614e71bSYork Sun 	unsigned char acttoact_mclk;
5015614e71bSYork Sun 	/* Last write data pair to read command issue interval (tWTR) */
5025614e71bSYork Sun 	unsigned char wrtord_mclk;
50334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
50434e026f9SYork Sun 	/* DDR4 supports 10, 12, 14, 16, 18, 20, 24 */
50534e026f9SYork Sun 	static const u8 wrrec_table[] = {
50634e026f9SYork Sun 		10, 10, 10, 10, 10,
50734e026f9SYork Sun 		10, 10, 10, 10, 10,
50834e026f9SYork Sun 		12, 12, 14, 14, 16,
50934e026f9SYork Sun 		16, 18, 18, 20, 20,
51034e026f9SYork Sun 		24, 24, 24, 24};
51134e026f9SYork Sun #else
5125614e71bSYork Sun 	/* DDR_SDRAM_MODE doesn't support 9,11,13,15 */
5135614e71bSYork Sun 	static const u8 wrrec_table[] = {
5145614e71bSYork Sun 		1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0};
51534e026f9SYork Sun #endif
5165614e71bSYork Sun 
51703e664d8SYork Sun 	pretoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trp_ps);
51803e664d8SYork Sun 	acttopre_mclk = picos_to_mclk(ctrl_num, common_dimm->tras_ps);
51903e664d8SYork Sun 	acttorw_mclk = picos_to_mclk(ctrl_num, common_dimm->trcd_ps);
5205614e71bSYork Sun 
5215614e71bSYork Sun 	/*
5225614e71bSYork Sun 	 * Translate CAS Latency to a DDR controller field value:
5235614e71bSYork Sun 	 *
5245614e71bSYork Sun 	 *      CAS Lat DDR I   DDR II  Ctrl
5255614e71bSYork Sun 	 *      Clocks  SPD Bit SPD Bit Value
5265614e71bSYork Sun 	 *      ------- ------- ------- -----
5275614e71bSYork Sun 	 *      1.0     0               0001
5285614e71bSYork Sun 	 *      1.5     1               0010
5295614e71bSYork Sun 	 *      2.0     2       2       0011
5305614e71bSYork Sun 	 *      2.5     3               0100
5315614e71bSYork Sun 	 *      3.0     4       3       0101
5325614e71bSYork Sun 	 *      3.5     5               0110
5335614e71bSYork Sun 	 *      4.0             4       0111
5345614e71bSYork Sun 	 *      4.5                     1000
5355614e71bSYork Sun 	 *      5.0             5       1001
5365614e71bSYork Sun 	 */
5375614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
5385614e71bSYork Sun 	caslat_ctrl = (cas_latency + 1) & 0x07;
5395614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
5405614e71bSYork Sun 	caslat_ctrl = 2 * cas_latency - 1;
5415614e71bSYork Sun #else
5425614e71bSYork Sun 	/*
5435614e71bSYork Sun 	 * if the CAS latency more than 8 cycle,
5445614e71bSYork Sun 	 * we need set extend bit for it at
5455614e71bSYork Sun 	 * TIMING_CFG_3[EXT_CASLAT]
5465614e71bSYork Sun 	 */
54734e026f9SYork Sun 	if (fsl_ddr_get_version() <= 0x40400)
5485614e71bSYork Sun 		caslat_ctrl = 2 * cas_latency - 1;
54934e026f9SYork Sun 	else
55034e026f9SYork Sun 		caslat_ctrl = (cas_latency - 1) << 1;
5515614e71bSYork Sun #endif
5525614e71bSYork Sun 
55334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
55403e664d8SYork Sun 	refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8;
55503e664d8SYork Sun 	wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
55603e664d8SYork Sun 	acttoact_mclk = max(picos_to_mclk(ctrl_num, common_dimm->trrds_ps), 4U);
55703e664d8SYork Sun 	wrtord_mclk = max(2U, picos_to_mclk(ctrl_num, 2500));
558349689b8SYork Sun 	if ((wrrec_mclk < 1) || (wrrec_mclk > 24))
559349689b8SYork Sun 		printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
56034e026f9SYork Sun 	else
56134e026f9SYork Sun 		wrrec_mclk = wrrec_table[wrrec_mclk - 1];
56234e026f9SYork Sun #else
56303e664d8SYork Sun 	refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8;
56403e664d8SYork Sun 	wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
56503e664d8SYork Sun 	acttoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trrd_ps);
56603e664d8SYork Sun 	wrtord_mclk = picos_to_mclk(ctrl_num, common_dimm->twtr_ps);
567349689b8SYork Sun 	if ((wrrec_mclk < 1) || (wrrec_mclk > 16))
568349689b8SYork Sun 		printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
5695614e71bSYork Sun 	else
5705614e71bSYork Sun 		wrrec_mclk = wrrec_table[wrrec_mclk - 1];
57134e026f9SYork Sun #endif
5725614e71bSYork Sun 	if (popts->otf_burst_chop_en)
5735614e71bSYork Sun 		wrrec_mclk += 2;
5745614e71bSYork Sun 
5755614e71bSYork Sun 	/*
5765614e71bSYork Sun 	 * JEDEC has min requirement for tRRD
5775614e71bSYork Sun 	 */
5785614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR3)
5795614e71bSYork Sun 	if (acttoact_mclk < 4)
5805614e71bSYork Sun 		acttoact_mclk = 4;
5815614e71bSYork Sun #endif
5825614e71bSYork Sun 	/*
5835614e71bSYork Sun 	 * JEDEC has some min requirements for tWTR
5845614e71bSYork Sun 	 */
5855614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2)
5865614e71bSYork Sun 	if (wrtord_mclk < 2)
5875614e71bSYork Sun 		wrtord_mclk = 2;
5885614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
5895614e71bSYork Sun 	if (wrtord_mclk < 4)
5905614e71bSYork Sun 		wrtord_mclk = 4;
5915614e71bSYork Sun #endif
5925614e71bSYork Sun 	if (popts->otf_burst_chop_en)
5935614e71bSYork Sun 		wrtord_mclk += 2;
5945614e71bSYork Sun 
5955614e71bSYork Sun 	ddr->timing_cfg_1 = (0
5965614e71bSYork Sun 		| ((pretoact_mclk & 0x0F) << 28)
5975614e71bSYork Sun 		| ((acttopre_mclk & 0x0F) << 24)
5985614e71bSYork Sun 		| ((acttorw_mclk & 0xF) << 20)
5995614e71bSYork Sun 		| ((caslat_ctrl & 0xF) << 16)
6005614e71bSYork Sun 		| ((refrec_ctrl & 0xF) << 12)
6015614e71bSYork Sun 		| ((wrrec_mclk & 0x0F) << 8)
6025614e71bSYork Sun 		| ((acttoact_mclk & 0x0F) << 4)
6035614e71bSYork Sun 		| ((wrtord_mclk & 0x0F) << 0)
6045614e71bSYork Sun 		);
6055614e71bSYork Sun 	debug("FSLDDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1);
6065614e71bSYork Sun }
6075614e71bSYork Sun 
6085614e71bSYork Sun /* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */
60903e664d8SYork Sun static void set_timing_cfg_2(const unsigned int ctrl_num,
61003e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
6115614e71bSYork Sun 			     const memctl_options_t *popts,
6125614e71bSYork Sun 			     const common_timing_params_t *common_dimm,
6135614e71bSYork Sun 			     unsigned int cas_latency,
6145614e71bSYork Sun 			     unsigned int additive_latency)
6155614e71bSYork Sun {
6165614e71bSYork Sun 	/* Additive latency */
6175614e71bSYork Sun 	unsigned char add_lat_mclk;
6185614e71bSYork Sun 	/* CAS-to-preamble override */
6195614e71bSYork Sun 	unsigned short cpo;
6205614e71bSYork Sun 	/* Write latency */
6215614e71bSYork Sun 	unsigned char wr_lat;
6225614e71bSYork Sun 	/*  Read to precharge (tRTP) */
6235614e71bSYork Sun 	unsigned char rd_to_pre;
6245614e71bSYork Sun 	/* Write command to write data strobe timing adjustment */
6255614e71bSYork Sun 	unsigned char wr_data_delay;
6265614e71bSYork Sun 	/* Minimum CKE pulse width (tCKE) */
6275614e71bSYork Sun 	unsigned char cke_pls;
6285614e71bSYork Sun 	/* Window for four activates (tFAW) */
6295614e71bSYork Sun 	unsigned short four_act;
630bb578322SYork Sun #ifdef CONFIG_SYS_FSL_DDR3
63103e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
632bb578322SYork Sun #endif
6335614e71bSYork Sun 
6345614e71bSYork Sun 	/* FIXME add check that this must be less than acttorw_mclk */
6355614e71bSYork Sun 	add_lat_mclk = additive_latency;
6365614e71bSYork Sun 	cpo = popts->cpo_override;
6375614e71bSYork Sun 
6385614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
6395614e71bSYork Sun 	/*
6405614e71bSYork Sun 	 * This is a lie.  It should really be 1, but if it is
6415614e71bSYork Sun 	 * set to 1, bits overlap into the old controller's
6425614e71bSYork Sun 	 * otherwise unused ACSM field.  If we leave it 0, then
6435614e71bSYork Sun 	 * the HW will magically treat it as 1 for DDR 1.  Oh Yea.
6445614e71bSYork Sun 	 */
6455614e71bSYork Sun 	wr_lat = 0;
6465614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
6475614e71bSYork Sun 	wr_lat = cas_latency - 1;
6485614e71bSYork Sun #else
64903e664d8SYork Sun 	wr_lat = compute_cas_write_latency(ctrl_num);
6505614e71bSYork Sun #endif
6515614e71bSYork Sun 
65234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
65303e664d8SYork Sun 	rd_to_pre = picos_to_mclk(ctrl_num, 7500);
65434e026f9SYork Sun #else
65503e664d8SYork Sun 	rd_to_pre = picos_to_mclk(ctrl_num, common_dimm->trtp_ps);
65634e026f9SYork Sun #endif
6575614e71bSYork Sun 	/*
6585614e71bSYork Sun 	 * JEDEC has some min requirements for tRTP
6595614e71bSYork Sun 	 */
6605614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2)
6615614e71bSYork Sun 	if (rd_to_pre  < 2)
6625614e71bSYork Sun 		rd_to_pre  = 2;
66334e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
6645614e71bSYork Sun 	if (rd_to_pre < 4)
6655614e71bSYork Sun 		rd_to_pre = 4;
6665614e71bSYork Sun #endif
6675614e71bSYork Sun 	if (popts->otf_burst_chop_en)
6685614e71bSYork Sun 		rd_to_pre += 2; /* according to UM */
6695614e71bSYork Sun 
6705614e71bSYork Sun 	wr_data_delay = popts->write_data_delay;
67134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
67234e026f9SYork Sun 	cpo = 0;
67303e664d8SYork Sun 	cke_pls = max(3U, picos_to_mclk(ctrl_num, 5000));
674bb578322SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
675bb578322SYork Sun 	/*
676bb578322SYork Sun 	 * cke pulse = max(3nCK, 7.5ns) for DDR3-800
677bb578322SYork Sun 	 *             max(3nCK, 5.625ns) for DDR3-1066, 1333
678bb578322SYork Sun 	 *             max(3nCK, 5ns) for DDR3-1600, 1866, 2133
679bb578322SYork Sun 	 */
68003e664d8SYork Sun 	cke_pls = max(3U, picos_to_mclk(ctrl_num, mclk_ps > 1870 ? 7500 :
681bb578322SYork Sun 					(mclk_ps > 1245 ? 5625 : 5000)));
68234e026f9SYork Sun #else
683bb578322SYork Sun 	cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR;
68434e026f9SYork Sun #endif
68503e664d8SYork Sun 	four_act = picos_to_mclk(ctrl_num,
68603e664d8SYork Sun 				 popts->tfaw_window_four_activates_ps);
6875614e71bSYork Sun 
6885614e71bSYork Sun 	ddr->timing_cfg_2 = (0
6895614e71bSYork Sun 		| ((add_lat_mclk & 0xf) << 28)
6905614e71bSYork Sun 		| ((cpo & 0x1f) << 23)
6915614e71bSYork Sun 		| ((wr_lat & 0xf) << 19)
69234e026f9SYork Sun 		| ((wr_lat & 0x10) << 14)
6935614e71bSYork Sun 		| ((rd_to_pre & RD_TO_PRE_MASK) << RD_TO_PRE_SHIFT)
6945614e71bSYork Sun 		| ((wr_data_delay & WR_DATA_DELAY_MASK) << WR_DATA_DELAY_SHIFT)
6955614e71bSYork Sun 		| ((cke_pls & 0x7) << 6)
6965614e71bSYork Sun 		| ((four_act & 0x3f) << 0)
6975614e71bSYork Sun 		);
6985614e71bSYork Sun 	debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2);
6995614e71bSYork Sun }
7005614e71bSYork Sun 
7015614e71bSYork Sun /* DDR SDRAM Register Control Word */
7025614e71bSYork Sun static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr,
7035614e71bSYork Sun 			       const memctl_options_t *popts,
7045614e71bSYork Sun 			       const common_timing_params_t *common_dimm)
7055614e71bSYork Sun {
7065614e71bSYork Sun 	if (common_dimm->all_dimms_registered &&
7075614e71bSYork Sun 	    !common_dimm->all_dimms_unbuffered)	{
7085614e71bSYork Sun 		if (popts->rcw_override) {
7095614e71bSYork Sun 			ddr->ddr_sdram_rcw_1 = popts->rcw_1;
7105614e71bSYork Sun 			ddr->ddr_sdram_rcw_2 = popts->rcw_2;
7115614e71bSYork Sun 		} else {
7125614e71bSYork Sun 			ddr->ddr_sdram_rcw_1 =
7135614e71bSYork Sun 				common_dimm->rcw[0] << 28 | \
7145614e71bSYork Sun 				common_dimm->rcw[1] << 24 | \
7155614e71bSYork Sun 				common_dimm->rcw[2] << 20 | \
7165614e71bSYork Sun 				common_dimm->rcw[3] << 16 | \
7175614e71bSYork Sun 				common_dimm->rcw[4] << 12 | \
7185614e71bSYork Sun 				common_dimm->rcw[5] << 8 | \
7195614e71bSYork Sun 				common_dimm->rcw[6] << 4 | \
7205614e71bSYork Sun 				common_dimm->rcw[7];
7215614e71bSYork Sun 			ddr->ddr_sdram_rcw_2 =
7225614e71bSYork Sun 				common_dimm->rcw[8] << 28 | \
7235614e71bSYork Sun 				common_dimm->rcw[9] << 24 | \
7245614e71bSYork Sun 				common_dimm->rcw[10] << 20 | \
7255614e71bSYork Sun 				common_dimm->rcw[11] << 16 | \
7265614e71bSYork Sun 				common_dimm->rcw[12] << 12 | \
7275614e71bSYork Sun 				common_dimm->rcw[13] << 8 | \
7285614e71bSYork Sun 				common_dimm->rcw[14] << 4 | \
7295614e71bSYork Sun 				common_dimm->rcw[15];
7305614e71bSYork Sun 		}
7315614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1);
7325614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2);
7335614e71bSYork Sun 	}
7345614e71bSYork Sun }
7355614e71bSYork Sun 
7365614e71bSYork Sun /* DDR SDRAM control configuration (DDR_SDRAM_CFG) */
7375614e71bSYork Sun static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
7385614e71bSYork Sun 			       const memctl_options_t *popts,
7395614e71bSYork Sun 			       const common_timing_params_t *common_dimm)
7405614e71bSYork Sun {
7415614e71bSYork Sun 	unsigned int mem_en;		/* DDR SDRAM interface logic enable */
7425614e71bSYork Sun 	unsigned int sren;		/* Self refresh enable (during sleep) */
7435614e71bSYork Sun 	unsigned int ecc_en;		/* ECC enable. */
7445614e71bSYork Sun 	unsigned int rd_en;		/* Registered DIMM enable */
7455614e71bSYork Sun 	unsigned int sdram_type;	/* Type of SDRAM */
7465614e71bSYork Sun 	unsigned int dyn_pwr;		/* Dynamic power management mode */
7475614e71bSYork Sun 	unsigned int dbw;		/* DRAM dta bus width */
7485614e71bSYork Sun 	unsigned int eight_be = 0;	/* 8-beat burst enable, DDR2 is zero */
7495614e71bSYork Sun 	unsigned int ncap = 0;		/* Non-concurrent auto-precharge */
7505614e71bSYork Sun 	unsigned int threet_en;		/* Enable 3T timing */
7515614e71bSYork Sun 	unsigned int twot_en;		/* Enable 2T timing */
7525614e71bSYork Sun 	unsigned int ba_intlv_ctl;	/* Bank (CS) interleaving control */
7535614e71bSYork Sun 	unsigned int x32_en = 0;	/* x32 enable */
7545614e71bSYork Sun 	unsigned int pchb8 = 0;		/* precharge bit 8 enable */
7555614e71bSYork Sun 	unsigned int hse;		/* Global half strength override */
756d28cb671SYork Sun 	unsigned int acc_ecc_en = 0;	/* Accumulated ECC enable */
7575614e71bSYork Sun 	unsigned int mem_halt = 0;	/* memory controller halt */
7585614e71bSYork Sun 	unsigned int bi = 0;		/* Bypass initialization */
7595614e71bSYork Sun 
7605614e71bSYork Sun 	mem_en = 1;
7615614e71bSYork Sun 	sren = popts->self_refresh_in_sleep;
7625614e71bSYork Sun 	if (common_dimm->all_dimms_ecc_capable) {
7635614e71bSYork Sun 		/* Allow setting of ECC only if all DIMMs are ECC. */
7645614e71bSYork Sun 		ecc_en = popts->ecc_mode;
7655614e71bSYork Sun 	} else {
7665614e71bSYork Sun 		ecc_en = 0;
7675614e71bSYork Sun 	}
7685614e71bSYork Sun 
7695614e71bSYork Sun 	if (common_dimm->all_dimms_registered &&
7705614e71bSYork Sun 	    !common_dimm->all_dimms_unbuffered)	{
7715614e71bSYork Sun 		rd_en = 1;
7725614e71bSYork Sun 		twot_en = 0;
7735614e71bSYork Sun 	} else {
7745614e71bSYork Sun 		rd_en = 0;
7755614e71bSYork Sun 		twot_en = popts->twot_en;
7765614e71bSYork Sun 	}
7775614e71bSYork Sun 
7785614e71bSYork Sun 	sdram_type = CONFIG_FSL_SDRAM_TYPE;
7795614e71bSYork Sun 
7805614e71bSYork Sun 	dyn_pwr = popts->dynamic_power;
7815614e71bSYork Sun 	dbw = popts->data_bus_width;
7825614e71bSYork Sun 	/* 8-beat burst enable DDR-III case
7835614e71bSYork Sun 	 * we must clear it when use the on-the-fly mode,
7845614e71bSYork Sun 	 * must set it when use the 32-bits bus mode.
7855614e71bSYork Sun 	 */
78634e026f9SYork Sun 	if ((sdram_type == SDRAM_TYPE_DDR3) ||
78734e026f9SYork Sun 	    (sdram_type == SDRAM_TYPE_DDR4)) {
7885614e71bSYork Sun 		if (popts->burst_length == DDR_BL8)
7895614e71bSYork Sun 			eight_be = 1;
7905614e71bSYork Sun 		if (popts->burst_length == DDR_OTF)
7915614e71bSYork Sun 			eight_be = 0;
7925614e71bSYork Sun 		if (dbw == 0x1)
7935614e71bSYork Sun 			eight_be = 1;
7945614e71bSYork Sun 	}
7955614e71bSYork Sun 
7965614e71bSYork Sun 	threet_en = popts->threet_en;
7975614e71bSYork Sun 	ba_intlv_ctl = popts->ba_intlv_ctl;
7985614e71bSYork Sun 	hse = popts->half_strength_driver_enable;
7995614e71bSYork Sun 
800d28cb671SYork Sun 	/* set when ddr bus width < 64 */
801d28cb671SYork Sun 	acc_ecc_en = (dbw != 0 && ecc_en == 1) ? 1 : 0;
802d28cb671SYork Sun 
8035614e71bSYork Sun 	ddr->ddr_sdram_cfg = (0
8045614e71bSYork Sun 			| ((mem_en & 0x1) << 31)
8055614e71bSYork Sun 			| ((sren & 0x1) << 30)
8065614e71bSYork Sun 			| ((ecc_en & 0x1) << 29)
8075614e71bSYork Sun 			| ((rd_en & 0x1) << 28)
8085614e71bSYork Sun 			| ((sdram_type & 0x7) << 24)
8095614e71bSYork Sun 			| ((dyn_pwr & 0x1) << 21)
8105614e71bSYork Sun 			| ((dbw & 0x3) << 19)
8115614e71bSYork Sun 			| ((eight_be & 0x1) << 18)
8125614e71bSYork Sun 			| ((ncap & 0x1) << 17)
8135614e71bSYork Sun 			| ((threet_en & 0x1) << 16)
8145614e71bSYork Sun 			| ((twot_en & 0x1) << 15)
8155614e71bSYork Sun 			| ((ba_intlv_ctl & 0x7F) << 8)
8165614e71bSYork Sun 			| ((x32_en & 0x1) << 5)
8175614e71bSYork Sun 			| ((pchb8 & 0x1) << 4)
8185614e71bSYork Sun 			| ((hse & 0x1) << 3)
819d28cb671SYork Sun 			| ((acc_ecc_en & 0x1) << 2)
8205614e71bSYork Sun 			| ((mem_halt & 0x1) << 1)
8215614e71bSYork Sun 			| ((bi & 0x1) << 0)
8225614e71bSYork Sun 			);
8235614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_cfg = 0x%08x\n", ddr->ddr_sdram_cfg);
8245614e71bSYork Sun }
8255614e71bSYork Sun 
8265614e71bSYork Sun /* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */
82703e664d8SYork Sun static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num,
82803e664d8SYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
8295614e71bSYork Sun 			       const memctl_options_t *popts,
8305614e71bSYork Sun 			       const unsigned int unq_mrs_en)
8315614e71bSYork Sun {
8325614e71bSYork Sun 	unsigned int frc_sr = 0;	/* Force self refresh */
8335614e71bSYork Sun 	unsigned int sr_ie = 0;		/* Self-refresh interrupt enable */
8345614e71bSYork Sun 	unsigned int odt_cfg = 0;	/* ODT configuration */
8355614e71bSYork Sun 	unsigned int num_pr;		/* Number of posted refreshes */
8365614e71bSYork Sun 	unsigned int slow = 0;		/* DDR will be run less than 1250 */
8375614e71bSYork Sun 	unsigned int x4_en = 0;		/* x4 DRAM enable */
8385614e71bSYork Sun 	unsigned int obc_cfg;		/* On-The-Fly Burst Chop Cfg */
8395614e71bSYork Sun 	unsigned int ap_en;		/* Address Parity Enable */
8405614e71bSYork Sun 	unsigned int d_init;		/* DRAM data initialization */
8415614e71bSYork Sun 	unsigned int rcw_en = 0;	/* Register Control Word Enable */
8425614e71bSYork Sun 	unsigned int md_en = 0;		/* Mirrored DIMM Enable */
8435614e71bSYork Sun 	unsigned int qd_en = 0;		/* quad-rank DIMM Enable */
8445614e71bSYork Sun 	int i;
84534e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4
84634e026f9SYork Sun 	unsigned int dll_rst_dis = 1;	/* DLL reset disable */
84734e026f9SYork Sun 	unsigned int dqs_cfg;		/* DQS configuration */
8485614e71bSYork Sun 
8495614e71bSYork Sun 	dqs_cfg = popts->dqs_config;
85034e026f9SYork Sun #endif
8515614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
8525614e71bSYork Sun 		if (popts->cs_local_opts[i].odt_rd_cfg
8535614e71bSYork Sun 			|| popts->cs_local_opts[i].odt_wr_cfg) {
8545614e71bSYork Sun 			odt_cfg = SDRAM_CFG2_ODT_ONLY_READ;
8555614e71bSYork Sun 			break;
8565614e71bSYork Sun 		}
8575614e71bSYork Sun 	}
8585614e71bSYork Sun 
8595614e71bSYork Sun 	num_pr = 1;	/* Make this configurable */
8605614e71bSYork Sun 
8615614e71bSYork Sun 	/*
8625614e71bSYork Sun 	 * 8572 manual says
8635614e71bSYork Sun 	 *     {TIMING_CFG_1[PRETOACT]
8645614e71bSYork Sun 	 *      + [DDR_SDRAM_CFG_2[NUM_PR]
8655614e71bSYork Sun 	 *        * ({EXT_REFREC || REFREC} + 8 + 2)]}
8665614e71bSYork Sun 	 *      << DDR_SDRAM_INTERVAL[REFINT]
8675614e71bSYork Sun 	 */
86834e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
8695614e71bSYork Sun 	obc_cfg = popts->otf_burst_chop_en;
8705614e71bSYork Sun #else
8715614e71bSYork Sun 	obc_cfg = 0;
8725614e71bSYork Sun #endif
8735614e71bSYork Sun 
8745614e71bSYork Sun #if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)
87503e664d8SYork Sun 	slow = get_ddr_freq(ctrl_num) < 1249000000;
8765614e71bSYork Sun #endif
8775614e71bSYork Sun 
8785614e71bSYork Sun 	if (popts->registered_dimm_en) {
8795614e71bSYork Sun 		rcw_en = 1;
8805614e71bSYork Sun 		ap_en = popts->ap_en;
8815614e71bSYork Sun 	} else {
8825614e71bSYork Sun 		ap_en = 0;
8835614e71bSYork Sun 	}
8845614e71bSYork Sun 
8855614e71bSYork Sun 	x4_en = popts->x4_en ? 1 : 0;
8865614e71bSYork Sun 
8875614e71bSYork Sun #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
8885614e71bSYork Sun 	/* Use the DDR controller to auto initialize memory. */
8895614e71bSYork Sun 	d_init = popts->ecc_init_using_memctl;
8905614e71bSYork Sun 	ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE;
8915614e71bSYork Sun 	debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init);
8925614e71bSYork Sun #else
8935614e71bSYork Sun 	/* Memory will be initialized via DMA, or not at all. */
8945614e71bSYork Sun 	d_init = 0;
8955614e71bSYork Sun #endif
8965614e71bSYork Sun 
89734e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
8985614e71bSYork Sun 	md_en = popts->mirrored_dimm;
8995614e71bSYork Sun #endif
9005614e71bSYork Sun 	qd_en = popts->quad_rank_present ? 1 : 0;
9015614e71bSYork Sun 	ddr->ddr_sdram_cfg_2 = (0
9025614e71bSYork Sun 		| ((frc_sr & 0x1) << 31)
9035614e71bSYork Sun 		| ((sr_ie & 0x1) << 30)
90434e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4
9055614e71bSYork Sun 		| ((dll_rst_dis & 0x1) << 29)
9065614e71bSYork Sun 		| ((dqs_cfg & 0x3) << 26)
90734e026f9SYork Sun #endif
9085614e71bSYork Sun 		| ((odt_cfg & 0x3) << 21)
9095614e71bSYork Sun 		| ((num_pr & 0xf) << 12)
9105614e71bSYork Sun 		| ((slow & 1) << 11)
9115614e71bSYork Sun 		| (x4_en << 10)
9125614e71bSYork Sun 		| (qd_en << 9)
9135614e71bSYork Sun 		| (unq_mrs_en << 8)
9145614e71bSYork Sun 		| ((obc_cfg & 0x1) << 6)
9155614e71bSYork Sun 		| ((ap_en & 0x1) << 5)
9165614e71bSYork Sun 		| ((d_init & 0x1) << 4)
9175614e71bSYork Sun 		| ((rcw_en & 0x1) << 2)
9185614e71bSYork Sun 		| ((md_en & 0x1) << 0)
9195614e71bSYork Sun 		);
9205614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_cfg_2 = 0x%08x\n", ddr->ddr_sdram_cfg_2);
9215614e71bSYork Sun }
9225614e71bSYork Sun 
92334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
9245614e71bSYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
92503e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
92603e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
9275614e71bSYork Sun 				const memctl_options_t *popts,
9285614e71bSYork Sun 				const common_timing_params_t *common_dimm,
9295614e71bSYork Sun 				const unsigned int unq_mrs_en)
9305614e71bSYork Sun {
9315614e71bSYork Sun 	unsigned short esdmode2 = 0;	/* Extended SDRAM mode 2 */
9325614e71bSYork Sun 	unsigned short esdmode3 = 0;	/* Extended SDRAM mode 3 */
9335614e71bSYork Sun 	int i;
93434e026f9SYork Sun 	unsigned int wr_crc = 0;	/* Disable */
9355614e71bSYork Sun 	unsigned int rtt_wr = 0;	/* Rtt_WR - dynamic ODT off */
9365614e71bSYork Sun 	unsigned int srt = 0;	/* self-refresh temerature, normal range */
93703e664d8SYork Sun 	unsigned int cwl = compute_cas_write_latency(ctrl_num) - 9;
93834e026f9SYork Sun 	unsigned int mpr = 0;	/* serial */
93934e026f9SYork Sun 	unsigned int wc_lat;
94003e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
9415614e71bSYork Sun 
9425614e71bSYork Sun 	if (popts->rtt_override)
9435614e71bSYork Sun 		rtt_wr = popts->rtt_wr_override_value;
9445614e71bSYork Sun 	else
9455614e71bSYork Sun 		rtt_wr = popts->cs_local_opts[0].odt_rtt_wr;
9465614e71bSYork Sun 
9475614e71bSYork Sun 	if (common_dimm->extended_op_srt)
9485614e71bSYork Sun 		srt = common_dimm->extended_op_srt;
9495614e71bSYork Sun 
9505614e71bSYork Sun 	esdmode2 = (0
95134e026f9SYork Sun 		| ((wr_crc & 0x1) << 12)
9525614e71bSYork Sun 		| ((rtt_wr & 0x3) << 9)
95334e026f9SYork Sun 		| ((srt & 0x3) << 6)
95434e026f9SYork Sun 		| ((cwl & 0x7) << 3));
95534e026f9SYork Sun 
95634e026f9SYork Sun 	if (mclk_ps >= 1250)
95734e026f9SYork Sun 		wc_lat = 0;
95834e026f9SYork Sun 	else if (mclk_ps >= 833)
95934e026f9SYork Sun 		wc_lat = 1;
96034e026f9SYork Sun 	else
96134e026f9SYork Sun 		wc_lat = 2;
96234e026f9SYork Sun 
96334e026f9SYork Sun 	esdmode3 = (0
96434e026f9SYork Sun 		| ((mpr & 0x3) << 11)
96534e026f9SYork Sun 		| ((wc_lat & 0x3) << 9));
96634e026f9SYork Sun 
9675614e71bSYork Sun 	ddr->ddr_sdram_mode_2 = (0
9685614e71bSYork Sun 				 | ((esdmode2 & 0xFFFF) << 16)
9695614e71bSYork Sun 				 | ((esdmode3 & 0xFFFF) << 0)
9705614e71bSYork Sun 				 );
9715614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2);
9725614e71bSYork Sun 
9735614e71bSYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
9745614e71bSYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
9755614e71bSYork Sun 			if (popts->rtt_override)
9765614e71bSYork Sun 				rtt_wr = popts->rtt_wr_override_value;
9775614e71bSYork Sun 			else
9785614e71bSYork Sun 				rtt_wr = popts->cs_local_opts[i].odt_rtt_wr;
9795614e71bSYork Sun 
9805614e71bSYork Sun 			esdmode2 &= 0xF9FF;	/* clear bit 10, 9 */
9815614e71bSYork Sun 			esdmode2 |= (rtt_wr & 0x3) << 9;
9825614e71bSYork Sun 			switch (i) {
9835614e71bSYork Sun 			case 1:
9845614e71bSYork Sun 				ddr->ddr_sdram_mode_4 = (0
9855614e71bSYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
9865614e71bSYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
9875614e71bSYork Sun 					);
9885614e71bSYork Sun 				break;
9895614e71bSYork Sun 			case 2:
9905614e71bSYork Sun 				ddr->ddr_sdram_mode_6 = (0
9915614e71bSYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
9925614e71bSYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
9935614e71bSYork Sun 					);
9945614e71bSYork Sun 				break;
9955614e71bSYork Sun 			case 3:
9965614e71bSYork Sun 				ddr->ddr_sdram_mode_8 = (0
9975614e71bSYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
9985614e71bSYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
9995614e71bSYork Sun 					);
10005614e71bSYork Sun 				break;
10015614e71bSYork Sun 			}
10025614e71bSYork Sun 		}
10035614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n",
10045614e71bSYork Sun 		      ddr->ddr_sdram_mode_4);
10055614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n",
10065614e71bSYork Sun 		      ddr->ddr_sdram_mode_6);
10075614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n",
10085614e71bSYork Sun 		      ddr->ddr_sdram_mode_8);
10095614e71bSYork Sun 	}
10105614e71bSYork Sun }
101134e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
101234e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
101303e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
101403e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
101534e026f9SYork Sun 				const memctl_options_t *popts,
101634e026f9SYork Sun 				const common_timing_params_t *common_dimm,
101734e026f9SYork Sun 				const unsigned int unq_mrs_en)
101834e026f9SYork Sun {
101934e026f9SYork Sun 	unsigned short esdmode2 = 0;	/* Extended SDRAM mode 2 */
102034e026f9SYork Sun 	unsigned short esdmode3 = 0;	/* Extended SDRAM mode 3 */
102134e026f9SYork Sun 	int i;
102234e026f9SYork Sun 	unsigned int rtt_wr = 0;	/* Rtt_WR - dynamic ODT off */
102334e026f9SYork Sun 	unsigned int srt = 0;	/* self-refresh temerature, normal range */
102434e026f9SYork Sun 	unsigned int asr = 0;	/* auto self-refresh disable */
102503e664d8SYork Sun 	unsigned int cwl = compute_cas_write_latency(ctrl_num) - 5;
102634e026f9SYork Sun 	unsigned int pasr = 0;	/* partial array self refresh disable */
102734e026f9SYork Sun 
102834e026f9SYork Sun 	if (popts->rtt_override)
102934e026f9SYork Sun 		rtt_wr = popts->rtt_wr_override_value;
103034e026f9SYork Sun 	else
103134e026f9SYork Sun 		rtt_wr = popts->cs_local_opts[0].odt_rtt_wr;
103234e026f9SYork Sun 
103334e026f9SYork Sun 	if (common_dimm->extended_op_srt)
103434e026f9SYork Sun 		srt = common_dimm->extended_op_srt;
103534e026f9SYork Sun 
103634e026f9SYork Sun 	esdmode2 = (0
103734e026f9SYork Sun 		| ((rtt_wr & 0x3) << 9)
103834e026f9SYork Sun 		| ((srt & 0x1) << 7)
103934e026f9SYork Sun 		| ((asr & 0x1) << 6)
104034e026f9SYork Sun 		| ((cwl & 0x7) << 3)
104134e026f9SYork Sun 		| ((pasr & 0x7) << 0));
104234e026f9SYork Sun 	ddr->ddr_sdram_mode_2 = (0
104334e026f9SYork Sun 				 | ((esdmode2 & 0xFFFF) << 16)
104434e026f9SYork Sun 				 | ((esdmode3 & 0xFFFF) << 0)
104534e026f9SYork Sun 				 );
104634e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2);
104734e026f9SYork Sun 
104834e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
104934e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
105034e026f9SYork Sun 			if (popts->rtt_override)
105134e026f9SYork Sun 				rtt_wr = popts->rtt_wr_override_value;
105234e026f9SYork Sun 			else
105334e026f9SYork Sun 				rtt_wr = popts->cs_local_opts[i].odt_rtt_wr;
105434e026f9SYork Sun 
105534e026f9SYork Sun 			esdmode2 &= 0xF9FF;	/* clear bit 10, 9 */
105634e026f9SYork Sun 			esdmode2 |= (rtt_wr & 0x3) << 9;
105734e026f9SYork Sun 			switch (i) {
105834e026f9SYork Sun 			case 1:
105934e026f9SYork Sun 				ddr->ddr_sdram_mode_4 = (0
106034e026f9SYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
106134e026f9SYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
106234e026f9SYork Sun 					);
106334e026f9SYork Sun 				break;
106434e026f9SYork Sun 			case 2:
106534e026f9SYork Sun 				ddr->ddr_sdram_mode_6 = (0
106634e026f9SYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
106734e026f9SYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
106834e026f9SYork Sun 					);
106934e026f9SYork Sun 				break;
107034e026f9SYork Sun 			case 3:
107134e026f9SYork Sun 				ddr->ddr_sdram_mode_8 = (0
107234e026f9SYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
107334e026f9SYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
107434e026f9SYork Sun 					);
107534e026f9SYork Sun 				break;
107634e026f9SYork Sun 			}
107734e026f9SYork Sun 		}
107834e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n",
107934e026f9SYork Sun 			ddr->ddr_sdram_mode_4);
108034e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n",
108134e026f9SYork Sun 			ddr->ddr_sdram_mode_6);
108234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n",
108334e026f9SYork Sun 			ddr->ddr_sdram_mode_8);
108434e026f9SYork Sun 	}
108534e026f9SYork Sun }
108634e026f9SYork Sun 
108734e026f9SYork Sun #else /* for DDR2 and DDR1 */
108834e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
108903e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
109003e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
109134e026f9SYork Sun 				const memctl_options_t *popts,
109234e026f9SYork Sun 				const common_timing_params_t *common_dimm,
109334e026f9SYork Sun 				const unsigned int unq_mrs_en)
109434e026f9SYork Sun {
109534e026f9SYork Sun 	unsigned short esdmode2 = 0;	/* Extended SDRAM mode 2 */
109634e026f9SYork Sun 	unsigned short esdmode3 = 0;	/* Extended SDRAM mode 3 */
109734e026f9SYork Sun 
109834e026f9SYork Sun 	ddr->ddr_sdram_mode_2 = (0
109934e026f9SYork Sun 				 | ((esdmode2 & 0xFFFF) << 16)
110034e026f9SYork Sun 				 | ((esdmode3 & 0xFFFF) << 0)
110134e026f9SYork Sun 				 );
110234e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2);
110334e026f9SYork Sun }
110434e026f9SYork Sun #endif
110534e026f9SYork Sun 
110634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
110734e026f9SYork Sun /* DDR SDRAM Mode configuration 9 (DDR_SDRAM_MODE_9) */
110834e026f9SYork Sun static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
110934e026f9SYork Sun 				const memctl_options_t *popts,
111034e026f9SYork Sun 				const common_timing_params_t *common_dimm,
111134e026f9SYork Sun 				const unsigned int unq_mrs_en)
111234e026f9SYork Sun {
111334e026f9SYork Sun 	int i;
111434e026f9SYork Sun 	unsigned short esdmode4 = 0;	/* Extended SDRAM mode 4 */
111534e026f9SYork Sun 	unsigned short esdmode5;	/* Extended SDRAM mode 5 */
111634e026f9SYork Sun 
111734e026f9SYork Sun 	esdmode5 = 0x00000400;		/* Data mask enabled */
111834e026f9SYork Sun 
111934e026f9SYork Sun 	ddr->ddr_sdram_mode_9 = (0
112034e026f9SYork Sun 				 | ((esdmode4 & 0xffff) << 16)
112134e026f9SYork Sun 				 | ((esdmode5 & 0xffff) << 0)
112234e026f9SYork Sun 				);
112334e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9);
112434e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
112534e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
112634e026f9SYork Sun 			switch (i) {
112734e026f9SYork Sun 			case 1:
112834e026f9SYork Sun 				ddr->ddr_sdram_mode_11 = (0
112934e026f9SYork Sun 					| ((esdmode4 & 0xFFFF) << 16)
113034e026f9SYork Sun 					| ((esdmode5 & 0xFFFF) << 0)
113134e026f9SYork Sun 					);
113234e026f9SYork Sun 				break;
113334e026f9SYork Sun 			case 2:
113434e026f9SYork Sun 				ddr->ddr_sdram_mode_13 = (0
113534e026f9SYork Sun 					| ((esdmode4 & 0xFFFF) << 16)
113634e026f9SYork Sun 					| ((esdmode5 & 0xFFFF) << 0)
113734e026f9SYork Sun 					);
113834e026f9SYork Sun 				break;
113934e026f9SYork Sun 			case 3:
114034e026f9SYork Sun 				ddr->ddr_sdram_mode_15 = (0
114134e026f9SYork Sun 					| ((esdmode4 & 0xFFFF) << 16)
114234e026f9SYork Sun 					| ((esdmode5 & 0xFFFF) << 0)
114334e026f9SYork Sun 					);
114434e026f9SYork Sun 				break;
114534e026f9SYork Sun 			}
114634e026f9SYork Sun 		}
114734e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_11 = 0x%08x\n",
114834e026f9SYork Sun 		      ddr->ddr_sdram_mode_11);
114934e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_13 = 0x%08x\n",
115034e026f9SYork Sun 		      ddr->ddr_sdram_mode_13);
115134e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_15 = 0x%08x\n",
115234e026f9SYork Sun 		      ddr->ddr_sdram_mode_15);
115334e026f9SYork Sun 	}
115434e026f9SYork Sun }
115534e026f9SYork Sun 
115634e026f9SYork Sun /* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */
115703e664d8SYork Sun static void set_ddr_sdram_mode_10(const unsigned int ctrl_num,
115803e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
115934e026f9SYork Sun 				const memctl_options_t *popts,
116034e026f9SYork Sun 				const common_timing_params_t *common_dimm,
116134e026f9SYork Sun 				const unsigned int unq_mrs_en)
116234e026f9SYork Sun {
116334e026f9SYork Sun 	int i;
116434e026f9SYork Sun 	unsigned short esdmode6 = 0;	/* Extended SDRAM mode 6 */
116534e026f9SYork Sun 	unsigned short esdmode7 = 0;	/* Extended SDRAM mode 7 */
116603e664d8SYork Sun 	unsigned int tccdl_min = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
116734e026f9SYork Sun 
116834e026f9SYork Sun 	esdmode6 = ((tccdl_min - 4) & 0x7) << 10;
116934e026f9SYork Sun 
117034e026f9SYork Sun 	ddr->ddr_sdram_mode_10 = (0
117134e026f9SYork Sun 				 | ((esdmode6 & 0xffff) << 16)
117234e026f9SYork Sun 				 | ((esdmode7 & 0xffff) << 0)
117334e026f9SYork Sun 				);
117434e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_10) = 0x%08x\n", ddr->ddr_sdram_mode_10);
117534e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
117634e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
117734e026f9SYork Sun 			switch (i) {
117834e026f9SYork Sun 			case 1:
117934e026f9SYork Sun 				ddr->ddr_sdram_mode_12 = (0
118034e026f9SYork Sun 					| ((esdmode6 & 0xFFFF) << 16)
118134e026f9SYork Sun 					| ((esdmode7 & 0xFFFF) << 0)
118234e026f9SYork Sun 					);
118334e026f9SYork Sun 				break;
118434e026f9SYork Sun 			case 2:
118534e026f9SYork Sun 				ddr->ddr_sdram_mode_14 = (0
118634e026f9SYork Sun 					| ((esdmode6 & 0xFFFF) << 16)
118734e026f9SYork Sun 					| ((esdmode7 & 0xFFFF) << 0)
118834e026f9SYork Sun 					);
118934e026f9SYork Sun 				break;
119034e026f9SYork Sun 			case 3:
119134e026f9SYork Sun 				ddr->ddr_sdram_mode_16 = (0
119234e026f9SYork Sun 					| ((esdmode6 & 0xFFFF) << 16)
119334e026f9SYork Sun 					| ((esdmode7 & 0xFFFF) << 0)
119434e026f9SYork Sun 					);
119534e026f9SYork Sun 				break;
119634e026f9SYork Sun 			}
119734e026f9SYork Sun 		}
119834e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_12 = 0x%08x\n",
119934e026f9SYork Sun 		      ddr->ddr_sdram_mode_12);
120034e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_14 = 0x%08x\n",
120134e026f9SYork Sun 		      ddr->ddr_sdram_mode_14);
120234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_16 = 0x%08x\n",
120334e026f9SYork Sun 		      ddr->ddr_sdram_mode_16);
120434e026f9SYork Sun 	}
120534e026f9SYork Sun }
120634e026f9SYork Sun 
120734e026f9SYork Sun #endif
12085614e71bSYork Sun 
12095614e71bSYork Sun /* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */
121003e664d8SYork Sun static void set_ddr_sdram_interval(const unsigned int ctrl_num,
121103e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
12125614e71bSYork Sun 				const memctl_options_t *popts,
12135614e71bSYork Sun 				const common_timing_params_t *common_dimm)
12145614e71bSYork Sun {
12155614e71bSYork Sun 	unsigned int refint;	/* Refresh interval */
12165614e71bSYork Sun 	unsigned int bstopre;	/* Precharge interval */
12175614e71bSYork Sun 
121803e664d8SYork Sun 	refint = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps);
12195614e71bSYork Sun 
12205614e71bSYork Sun 	bstopre = popts->bstopre;
12215614e71bSYork Sun 
12225614e71bSYork Sun 	/* refint field used 0x3FFF in earlier controllers */
12235614e71bSYork Sun 	ddr->ddr_sdram_interval = (0
12245614e71bSYork Sun 				   | ((refint & 0xFFFF) << 16)
12255614e71bSYork Sun 				   | ((bstopre & 0x3FFF) << 0)
12265614e71bSYork Sun 				   );
12275614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_interval = 0x%08x\n", ddr->ddr_sdram_interval);
12285614e71bSYork Sun }
12295614e71bSYork Sun 
123034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
12315614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
123203e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num,
123303e664d8SYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
12345614e71bSYork Sun 			       const memctl_options_t *popts,
12355614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
12365614e71bSYork Sun 			       unsigned int cas_latency,
12375614e71bSYork Sun 			       unsigned int additive_latency,
12385614e71bSYork Sun 			       const unsigned int unq_mrs_en)
12395614e71bSYork Sun {
124034e026f9SYork Sun 	int i;
124134e026f9SYork Sun 	unsigned short esdmode;		/* Extended SDRAM mode */
124234e026f9SYork Sun 	unsigned short sdmode;		/* SDRAM mode */
124334e026f9SYork Sun 
124434e026f9SYork Sun 	/* Mode Register - MR1 */
124534e026f9SYork Sun 	unsigned int qoff = 0;		/* Output buffer enable 0=yes, 1=no */
124634e026f9SYork Sun 	unsigned int tdqs_en = 0;	/* TDQS Enable: 0=no, 1=yes */
124734e026f9SYork Sun 	unsigned int rtt;
124834e026f9SYork Sun 	unsigned int wrlvl_en = 0;	/* Write level enable: 0=no, 1=yes */
124934e026f9SYork Sun 	unsigned int al = 0;		/* Posted CAS# additive latency (AL) */
125034e026f9SYork Sun 	unsigned int dic = 0;		/* Output driver impedance, 40ohm */
125134e026f9SYork Sun 	unsigned int dll_en = 1;	/* DLL Enable  1=Enable (Normal),
125234e026f9SYork Sun 						       0=Disable (Test/Debug) */
125334e026f9SYork Sun 
125434e026f9SYork Sun 	/* Mode Register - MR0 */
125534e026f9SYork Sun 	unsigned int wr = 0;	/* Write Recovery */
125634e026f9SYork Sun 	unsigned int dll_rst;	/* DLL Reset */
125734e026f9SYork Sun 	unsigned int mode;	/* Normal=0 or Test=1 */
125834e026f9SYork Sun 	unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */
125934e026f9SYork Sun 	/* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */
126034e026f9SYork Sun 	unsigned int bt;
126134e026f9SYork Sun 	unsigned int bl;	/* BL: Burst Length */
126234e026f9SYork Sun 
126334e026f9SYork Sun 	unsigned int wr_mclk;
126434e026f9SYork Sun 	/* DDR4 support WR 10, 12, 14, 16, 18, 20, 24 */
126534e026f9SYork Sun 	static const u8 wr_table[] = {
126634e026f9SYork Sun 		0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6};
126734e026f9SYork Sun 	/* DDR4 support CAS 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24 */
126834e026f9SYork Sun 	static const u8 cas_latency_table[] = {
126934e026f9SYork Sun 		0, 1, 2, 3, 4, 5, 6, 7, 8, 8,
127034e026f9SYork Sun 		9, 9, 10, 10, 11, 11};
127134e026f9SYork Sun 
127234e026f9SYork Sun 	if (popts->rtt_override)
127334e026f9SYork Sun 		rtt = popts->rtt_override_value;
127434e026f9SYork Sun 	else
127534e026f9SYork Sun 		rtt = popts->cs_local_opts[0].odt_rtt_norm;
127634e026f9SYork Sun 
127734e026f9SYork Sun 	if (additive_latency == (cas_latency - 1))
127834e026f9SYork Sun 		al = 1;
127934e026f9SYork Sun 	if (additive_latency == (cas_latency - 2))
128034e026f9SYork Sun 		al = 2;
128134e026f9SYork Sun 
128234e026f9SYork Sun 	if (popts->quad_rank_present)
128334e026f9SYork Sun 		dic = 1;	/* output driver impedance 240/7 ohm */
128434e026f9SYork Sun 
128534e026f9SYork Sun 	/*
128634e026f9SYork Sun 	 * The esdmode value will also be used for writing
128734e026f9SYork Sun 	 * MR1 during write leveling for DDR3, although the
128834e026f9SYork Sun 	 * bits specifically related to the write leveling
128934e026f9SYork Sun 	 * scheme will be handled automatically by the DDR
129034e026f9SYork Sun 	 * controller. so we set the wrlvl_en = 0 here.
129134e026f9SYork Sun 	 */
129234e026f9SYork Sun 	esdmode = (0
129334e026f9SYork Sun 		| ((qoff & 0x1) << 12)
129434e026f9SYork Sun 		| ((tdqs_en & 0x1) << 11)
129534e026f9SYork Sun 		| ((rtt & 0x7) << 8)
129634e026f9SYork Sun 		| ((wrlvl_en & 0x1) << 7)
129734e026f9SYork Sun 		| ((al & 0x3) << 3)
129834e026f9SYork Sun 		| ((dic & 0x3) << 1)   /* DIC field is split */
129934e026f9SYork Sun 		| ((dll_en & 0x1) << 0)
130034e026f9SYork Sun 		);
130134e026f9SYork Sun 
130234e026f9SYork Sun 	/*
130334e026f9SYork Sun 	 * DLL control for precharge PD
130434e026f9SYork Sun 	 * 0=slow exit DLL off (tXPDLL)
130534e026f9SYork Sun 	 * 1=fast exit DLL on (tXP)
130634e026f9SYork Sun 	 */
130734e026f9SYork Sun 
130803e664d8SYork Sun 	wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
130934e026f9SYork Sun 	if (wr_mclk <= 24) {
131034e026f9SYork Sun 		wr = wr_table[wr_mclk - 10];
131134e026f9SYork Sun 	} else {
131234e026f9SYork Sun 		printf("Error: unsupported write recovery for mode register wr_mclk = %d\n",
131334e026f9SYork Sun 		       wr_mclk);
131434e026f9SYork Sun 	}
131534e026f9SYork Sun 
131634e026f9SYork Sun 	dll_rst = 0;	/* dll no reset */
131734e026f9SYork Sun 	mode = 0;	/* normal mode */
131834e026f9SYork Sun 
131934e026f9SYork Sun 	/* look up table to get the cas latency bits */
132034e026f9SYork Sun 	if (cas_latency >= 9 && cas_latency <= 24)
132134e026f9SYork Sun 		caslat = cas_latency_table[cas_latency - 9];
132234e026f9SYork Sun 	else
132334e026f9SYork Sun 		printf("Error: unsupported cas latency for mode register\n");
132434e026f9SYork Sun 
132534e026f9SYork Sun 	bt = 0;	/* Nibble sequential */
132634e026f9SYork Sun 
132734e026f9SYork Sun 	switch (popts->burst_length) {
132834e026f9SYork Sun 	case DDR_BL8:
132934e026f9SYork Sun 		bl = 0;
133034e026f9SYork Sun 		break;
133134e026f9SYork Sun 	case DDR_OTF:
133234e026f9SYork Sun 		bl = 1;
133334e026f9SYork Sun 		break;
133434e026f9SYork Sun 	case DDR_BC4:
133534e026f9SYork Sun 		bl = 2;
133634e026f9SYork Sun 		break;
133734e026f9SYork Sun 	default:
133834e026f9SYork Sun 		printf("Error: invalid burst length of %u specified. ",
133934e026f9SYork Sun 		       popts->burst_length);
134034e026f9SYork Sun 		puts("Defaulting to on-the-fly BC4 or BL8 beats.\n");
134134e026f9SYork Sun 		bl = 1;
134234e026f9SYork Sun 		break;
134334e026f9SYork Sun 	}
134434e026f9SYork Sun 
134534e026f9SYork Sun 	sdmode = (0
134634e026f9SYork Sun 		  | ((wr & 0x7) << 9)
134734e026f9SYork Sun 		  | ((dll_rst & 0x1) << 8)
134834e026f9SYork Sun 		  | ((mode & 0x1) << 7)
134934e026f9SYork Sun 		  | (((caslat >> 1) & 0x7) << 4)
135034e026f9SYork Sun 		  | ((bt & 0x1) << 3)
135134e026f9SYork Sun 		  | ((caslat & 1) << 2)
135234e026f9SYork Sun 		  | ((bl & 0x3) << 0)
135334e026f9SYork Sun 		  );
135434e026f9SYork Sun 
135534e026f9SYork Sun 	ddr->ddr_sdram_mode = (0
135634e026f9SYork Sun 			       | ((esdmode & 0xFFFF) << 16)
135734e026f9SYork Sun 			       | ((sdmode & 0xFFFF) << 0)
135834e026f9SYork Sun 			       );
135934e026f9SYork Sun 
136034e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode);
136134e026f9SYork Sun 
136234e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
136334e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
136434e026f9SYork Sun 			if (popts->rtt_override)
136534e026f9SYork Sun 				rtt = popts->rtt_override_value;
136634e026f9SYork Sun 			else
136734e026f9SYork Sun 				rtt = popts->cs_local_opts[i].odt_rtt_norm;
136834e026f9SYork Sun 
136934e026f9SYork Sun 			esdmode &= 0xF8FF;	/* clear bit 10,9,8 for rtt */
137034e026f9SYork Sun 			esdmode |= (rtt & 0x7) << 8;
137134e026f9SYork Sun 			switch (i) {
137234e026f9SYork Sun 			case 1:
137334e026f9SYork Sun 				ddr->ddr_sdram_mode_3 = (0
137434e026f9SYork Sun 				       | ((esdmode & 0xFFFF) << 16)
137534e026f9SYork Sun 				       | ((sdmode & 0xFFFF) << 0)
137634e026f9SYork Sun 				       );
137734e026f9SYork Sun 				break;
137834e026f9SYork Sun 			case 2:
137934e026f9SYork Sun 				ddr->ddr_sdram_mode_5 = (0
138034e026f9SYork Sun 				       | ((esdmode & 0xFFFF) << 16)
138134e026f9SYork Sun 				       | ((sdmode & 0xFFFF) << 0)
138234e026f9SYork Sun 				       );
138334e026f9SYork Sun 				break;
138434e026f9SYork Sun 			case 3:
138534e026f9SYork Sun 				ddr->ddr_sdram_mode_7 = (0
138634e026f9SYork Sun 				       | ((esdmode & 0xFFFF) << 16)
138734e026f9SYork Sun 				       | ((sdmode & 0xFFFF) << 0)
138834e026f9SYork Sun 				       );
138934e026f9SYork Sun 				break;
139034e026f9SYork Sun 			}
139134e026f9SYork Sun 		}
139234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n",
139334e026f9SYork Sun 		      ddr->ddr_sdram_mode_3);
139434e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
139534e026f9SYork Sun 		      ddr->ddr_sdram_mode_5);
139634e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
139734e026f9SYork Sun 		      ddr->ddr_sdram_mode_5);
139834e026f9SYork Sun 	}
139934e026f9SYork Sun }
140034e026f9SYork Sun 
140134e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
140234e026f9SYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
140303e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num,
140403e664d8SYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
140534e026f9SYork Sun 			       const memctl_options_t *popts,
140634e026f9SYork Sun 			       const common_timing_params_t *common_dimm,
140734e026f9SYork Sun 			       unsigned int cas_latency,
140834e026f9SYork Sun 			       unsigned int additive_latency,
140934e026f9SYork Sun 			       const unsigned int unq_mrs_en)
141034e026f9SYork Sun {
141134e026f9SYork Sun 	int i;
14125614e71bSYork Sun 	unsigned short esdmode;		/* Extended SDRAM mode */
14135614e71bSYork Sun 	unsigned short sdmode;		/* SDRAM mode */
14145614e71bSYork Sun 
14155614e71bSYork Sun 	/* Mode Register - MR1 */
14165614e71bSYork Sun 	unsigned int qoff = 0;		/* Output buffer enable 0=yes, 1=no */
14175614e71bSYork Sun 	unsigned int tdqs_en = 0;	/* TDQS Enable: 0=no, 1=yes */
14185614e71bSYork Sun 	unsigned int rtt;
14195614e71bSYork Sun 	unsigned int wrlvl_en = 0;	/* Write level enable: 0=no, 1=yes */
14205614e71bSYork Sun 	unsigned int al = 0;		/* Posted CAS# additive latency (AL) */
14215614e71bSYork Sun 	unsigned int dic = 0;		/* Output driver impedance, 40ohm */
14225614e71bSYork Sun 	unsigned int dll_en = 0;	/* DLL Enable  0=Enable (Normal),
14235614e71bSYork Sun 						       1=Disable (Test/Debug) */
14245614e71bSYork Sun 
14255614e71bSYork Sun 	/* Mode Register - MR0 */
14265614e71bSYork Sun 	unsigned int dll_on;	/* DLL control for precharge PD, 0=off, 1=on */
14275614e71bSYork Sun 	unsigned int wr = 0;	/* Write Recovery */
14285614e71bSYork Sun 	unsigned int dll_rst;	/* DLL Reset */
14295614e71bSYork Sun 	unsigned int mode;	/* Normal=0 or Test=1 */
14305614e71bSYork Sun 	unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */
14315614e71bSYork Sun 	/* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */
14325614e71bSYork Sun 	unsigned int bt;
14335614e71bSYork Sun 	unsigned int bl;	/* BL: Burst Length */
14345614e71bSYork Sun 
14355614e71bSYork Sun 	unsigned int wr_mclk;
14365614e71bSYork Sun 	/*
14375614e71bSYork Sun 	 * DDR_SDRAM_MODE doesn't support 9,11,13,15
14385614e71bSYork Sun 	 * Please refer JEDEC Standard No. 79-3E for Mode Register MR0
14395614e71bSYork Sun 	 * for this table
14405614e71bSYork Sun 	 */
14415614e71bSYork Sun 	static const u8 wr_table[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0};
14425614e71bSYork Sun 
14435614e71bSYork Sun 	if (popts->rtt_override)
14445614e71bSYork Sun 		rtt = popts->rtt_override_value;
14455614e71bSYork Sun 	else
14465614e71bSYork Sun 		rtt = popts->cs_local_opts[0].odt_rtt_norm;
14475614e71bSYork Sun 
14485614e71bSYork Sun 	if (additive_latency == (cas_latency - 1))
14495614e71bSYork Sun 		al = 1;
14505614e71bSYork Sun 	if (additive_latency == (cas_latency - 2))
14515614e71bSYork Sun 		al = 2;
14525614e71bSYork Sun 
14535614e71bSYork Sun 	if (popts->quad_rank_present)
14545614e71bSYork Sun 		dic = 1;	/* output driver impedance 240/7 ohm */
14555614e71bSYork Sun 
14565614e71bSYork Sun 	/*
14575614e71bSYork Sun 	 * The esdmode value will also be used for writing
14585614e71bSYork Sun 	 * MR1 during write leveling for DDR3, although the
14595614e71bSYork Sun 	 * bits specifically related to the write leveling
14605614e71bSYork Sun 	 * scheme will be handled automatically by the DDR
14615614e71bSYork Sun 	 * controller. so we set the wrlvl_en = 0 here.
14625614e71bSYork Sun 	 */
14635614e71bSYork Sun 	esdmode = (0
14645614e71bSYork Sun 		| ((qoff & 0x1) << 12)
14655614e71bSYork Sun 		| ((tdqs_en & 0x1) << 11)
14665614e71bSYork Sun 		| ((rtt & 0x4) << 7)   /* rtt field is split */
14675614e71bSYork Sun 		| ((wrlvl_en & 0x1) << 7)
14685614e71bSYork Sun 		| ((rtt & 0x2) << 5)   /* rtt field is split */
14695614e71bSYork Sun 		| ((dic & 0x2) << 4)   /* DIC field is split */
14705614e71bSYork Sun 		| ((al & 0x3) << 3)
14715614e71bSYork Sun 		| ((rtt & 0x1) << 2)  /* rtt field is split */
14725614e71bSYork Sun 		| ((dic & 0x1) << 1)   /* DIC field is split */
14735614e71bSYork Sun 		| ((dll_en & 0x1) << 0)
14745614e71bSYork Sun 		);
14755614e71bSYork Sun 
14765614e71bSYork Sun 	/*
14775614e71bSYork Sun 	 * DLL control for precharge PD
14785614e71bSYork Sun 	 * 0=slow exit DLL off (tXPDLL)
14795614e71bSYork Sun 	 * 1=fast exit DLL on (tXP)
14805614e71bSYork Sun 	 */
14815614e71bSYork Sun 	dll_on = 1;
14825614e71bSYork Sun 
148303e664d8SYork Sun 	wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
14845614e71bSYork Sun 	if (wr_mclk <= 16) {
14855614e71bSYork Sun 		wr = wr_table[wr_mclk - 5];
14865614e71bSYork Sun 	} else {
14875614e71bSYork Sun 		printf("Error: unsupported write recovery for mode register "
14885614e71bSYork Sun 		       "wr_mclk = %d\n", wr_mclk);
14895614e71bSYork Sun 	}
14905614e71bSYork Sun 
14915614e71bSYork Sun 	dll_rst = 0;	/* dll no reset */
14925614e71bSYork Sun 	mode = 0;	/* normal mode */
14935614e71bSYork Sun 
14945614e71bSYork Sun 	/* look up table to get the cas latency bits */
14955614e71bSYork Sun 	if (cas_latency >= 5 && cas_latency <= 16) {
14965614e71bSYork Sun 		unsigned char cas_latency_table[] = {
14975614e71bSYork Sun 			0x2,	/* 5 clocks */
14985614e71bSYork Sun 			0x4,	/* 6 clocks */
14995614e71bSYork Sun 			0x6,	/* 7 clocks */
15005614e71bSYork Sun 			0x8,	/* 8 clocks */
15015614e71bSYork Sun 			0xa,	/* 9 clocks */
15025614e71bSYork Sun 			0xc,	/* 10 clocks */
15035614e71bSYork Sun 			0xe,	/* 11 clocks */
15045614e71bSYork Sun 			0x1,	/* 12 clocks */
15055614e71bSYork Sun 			0x3,	/* 13 clocks */
15065614e71bSYork Sun 			0x5,	/* 14 clocks */
15075614e71bSYork Sun 			0x7,	/* 15 clocks */
15085614e71bSYork Sun 			0x9,	/* 16 clocks */
15095614e71bSYork Sun 		};
15105614e71bSYork Sun 		caslat = cas_latency_table[cas_latency - 5];
15115614e71bSYork Sun 	} else {
15125614e71bSYork Sun 		printf("Error: unsupported cas latency for mode register\n");
15135614e71bSYork Sun 	}
15145614e71bSYork Sun 
15155614e71bSYork Sun 	bt = 0;	/* Nibble sequential */
15165614e71bSYork Sun 
15175614e71bSYork Sun 	switch (popts->burst_length) {
15185614e71bSYork Sun 	case DDR_BL8:
15195614e71bSYork Sun 		bl = 0;
15205614e71bSYork Sun 		break;
15215614e71bSYork Sun 	case DDR_OTF:
15225614e71bSYork Sun 		bl = 1;
15235614e71bSYork Sun 		break;
15245614e71bSYork Sun 	case DDR_BC4:
15255614e71bSYork Sun 		bl = 2;
15265614e71bSYork Sun 		break;
15275614e71bSYork Sun 	default:
15285614e71bSYork Sun 		printf("Error: invalid burst length of %u specified. "
15295614e71bSYork Sun 			" Defaulting to on-the-fly BC4 or BL8 beats.\n",
15305614e71bSYork Sun 			popts->burst_length);
15315614e71bSYork Sun 		bl = 1;
15325614e71bSYork Sun 		break;
15335614e71bSYork Sun 	}
15345614e71bSYork Sun 
15355614e71bSYork Sun 	sdmode = (0
15365614e71bSYork Sun 		  | ((dll_on & 0x1) << 12)
15375614e71bSYork Sun 		  | ((wr & 0x7) << 9)
15385614e71bSYork Sun 		  | ((dll_rst & 0x1) << 8)
15395614e71bSYork Sun 		  | ((mode & 0x1) << 7)
15405614e71bSYork Sun 		  | (((caslat >> 1) & 0x7) << 4)
15415614e71bSYork Sun 		  | ((bt & 0x1) << 3)
15425614e71bSYork Sun 		  | ((caslat & 1) << 2)
15435614e71bSYork Sun 		  | ((bl & 0x3) << 0)
15445614e71bSYork Sun 		  );
15455614e71bSYork Sun 
15465614e71bSYork Sun 	ddr->ddr_sdram_mode = (0
15475614e71bSYork Sun 			       | ((esdmode & 0xFFFF) << 16)
15485614e71bSYork Sun 			       | ((sdmode & 0xFFFF) << 0)
15495614e71bSYork Sun 			       );
15505614e71bSYork Sun 
15515614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode);
15525614e71bSYork Sun 
15535614e71bSYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
15545614e71bSYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
15555614e71bSYork Sun 			if (popts->rtt_override)
15565614e71bSYork Sun 				rtt = popts->rtt_override_value;
15575614e71bSYork Sun 			else
15585614e71bSYork Sun 				rtt = popts->cs_local_opts[i].odt_rtt_norm;
15595614e71bSYork Sun 
15605614e71bSYork Sun 			esdmode &= 0xFDBB;	/* clear bit 9,6,2 */
15615614e71bSYork Sun 			esdmode |= (0
15625614e71bSYork Sun 				| ((rtt & 0x4) << 7)   /* rtt field is split */
15635614e71bSYork Sun 				| ((rtt & 0x2) << 5)   /* rtt field is split */
15645614e71bSYork Sun 				| ((rtt & 0x1) << 2)  /* rtt field is split */
15655614e71bSYork Sun 				);
15665614e71bSYork Sun 			switch (i) {
15675614e71bSYork Sun 			case 1:
15685614e71bSYork Sun 				ddr->ddr_sdram_mode_3 = (0
15695614e71bSYork Sun 				       | ((esdmode & 0xFFFF) << 16)
15705614e71bSYork Sun 				       | ((sdmode & 0xFFFF) << 0)
15715614e71bSYork Sun 				       );
15725614e71bSYork Sun 				break;
15735614e71bSYork Sun 			case 2:
15745614e71bSYork Sun 				ddr->ddr_sdram_mode_5 = (0
15755614e71bSYork Sun 				       | ((esdmode & 0xFFFF) << 16)
15765614e71bSYork Sun 				       | ((sdmode & 0xFFFF) << 0)
15775614e71bSYork Sun 				       );
15785614e71bSYork Sun 				break;
15795614e71bSYork Sun 			case 3:
15805614e71bSYork Sun 				ddr->ddr_sdram_mode_7 = (0
15815614e71bSYork Sun 				       | ((esdmode & 0xFFFF) << 16)
15825614e71bSYork Sun 				       | ((sdmode & 0xFFFF) << 0)
15835614e71bSYork Sun 				       );
15845614e71bSYork Sun 				break;
15855614e71bSYork Sun 			}
15865614e71bSYork Sun 		}
15875614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n",
15885614e71bSYork Sun 			ddr->ddr_sdram_mode_3);
15895614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
15905614e71bSYork Sun 			ddr->ddr_sdram_mode_5);
15915614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
15925614e71bSYork Sun 			ddr->ddr_sdram_mode_5);
15935614e71bSYork Sun 	}
15945614e71bSYork Sun }
15955614e71bSYork Sun 
15965614e71bSYork Sun #else /* !CONFIG_SYS_FSL_DDR3 */
15975614e71bSYork Sun 
15985614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
159903e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num,
160003e664d8SYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
16015614e71bSYork Sun 			       const memctl_options_t *popts,
16025614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
16035614e71bSYork Sun 			       unsigned int cas_latency,
16045614e71bSYork Sun 			       unsigned int additive_latency,
16055614e71bSYork Sun 			       const unsigned int unq_mrs_en)
16065614e71bSYork Sun {
16075614e71bSYork Sun 	unsigned short esdmode;		/* Extended SDRAM mode */
16085614e71bSYork Sun 	unsigned short sdmode;		/* SDRAM mode */
16095614e71bSYork Sun 
16105614e71bSYork Sun 	/*
16115614e71bSYork Sun 	 * FIXME: This ought to be pre-calculated in a
16125614e71bSYork Sun 	 * technology-specific routine,
16135614e71bSYork Sun 	 * e.g. compute_DDR2_mode_register(), and then the
16145614e71bSYork Sun 	 * sdmode and esdmode passed in as part of common_dimm.
16155614e71bSYork Sun 	 */
16165614e71bSYork Sun 
16175614e71bSYork Sun 	/* Extended Mode Register */
16185614e71bSYork Sun 	unsigned int mrs = 0;		/* Mode Register Set */
16195614e71bSYork Sun 	unsigned int outputs = 0;	/* 0=Enabled, 1=Disabled */
16205614e71bSYork Sun 	unsigned int rdqs_en = 0;	/* RDQS Enable: 0=no, 1=yes */
16215614e71bSYork Sun 	unsigned int dqs_en = 0;	/* DQS# Enable: 0=enable, 1=disable */
16225614e71bSYork Sun 	unsigned int ocd = 0;		/* 0x0=OCD not supported,
16235614e71bSYork Sun 					   0x7=OCD default state */
16245614e71bSYork Sun 	unsigned int rtt;
16255614e71bSYork Sun 	unsigned int al;		/* Posted CAS# additive latency (AL) */
16265614e71bSYork Sun 	unsigned int ods = 0;		/* Output Drive Strength:
16275614e71bSYork Sun 						0 = Full strength (18ohm)
16285614e71bSYork Sun 						1 = Reduced strength (4ohm) */
16295614e71bSYork Sun 	unsigned int dll_en = 0;	/* DLL Enable  0=Enable (Normal),
16305614e71bSYork Sun 						       1=Disable (Test/Debug) */
16315614e71bSYork Sun 
16325614e71bSYork Sun 	/* Mode Register (MR) */
16335614e71bSYork Sun 	unsigned int mr;	/* Mode Register Definition */
16345614e71bSYork Sun 	unsigned int pd;	/* Power-Down Mode */
16355614e71bSYork Sun 	unsigned int wr;	/* Write Recovery */
16365614e71bSYork Sun 	unsigned int dll_res;	/* DLL Reset */
16375614e71bSYork Sun 	unsigned int mode;	/* Normal=0 or Test=1 */
16385614e71bSYork Sun 	unsigned int caslat = 0;/* CAS# latency */
16395614e71bSYork Sun 	/* BT: Burst Type (0=Sequential, 1=Interleaved) */
16405614e71bSYork Sun 	unsigned int bt;
16415614e71bSYork Sun 	unsigned int bl;	/* BL: Burst Length */
16425614e71bSYork Sun 
16435614e71bSYork Sun 	dqs_en = !popts->dqs_config;
16445614e71bSYork Sun 	rtt = fsl_ddr_get_rtt();
16455614e71bSYork Sun 
16465614e71bSYork Sun 	al = additive_latency;
16475614e71bSYork Sun 
16485614e71bSYork Sun 	esdmode = (0
16495614e71bSYork Sun 		| ((mrs & 0x3) << 14)
16505614e71bSYork Sun 		| ((outputs & 0x1) << 12)
16515614e71bSYork Sun 		| ((rdqs_en & 0x1) << 11)
16525614e71bSYork Sun 		| ((dqs_en & 0x1) << 10)
16535614e71bSYork Sun 		| ((ocd & 0x7) << 7)
16545614e71bSYork Sun 		| ((rtt & 0x2) << 5)   /* rtt field is split */
16555614e71bSYork Sun 		| ((al & 0x7) << 3)
16565614e71bSYork Sun 		| ((rtt & 0x1) << 2)   /* rtt field is split */
16575614e71bSYork Sun 		| ((ods & 0x1) << 1)
16585614e71bSYork Sun 		| ((dll_en & 0x1) << 0)
16595614e71bSYork Sun 		);
16605614e71bSYork Sun 
16615614e71bSYork Sun 	mr = 0;		 /* FIXME: CHECKME */
16625614e71bSYork Sun 
16635614e71bSYork Sun 	/*
16645614e71bSYork Sun 	 * 0 = Fast Exit (Normal)
16655614e71bSYork Sun 	 * 1 = Slow Exit (Low Power)
16665614e71bSYork Sun 	 */
16675614e71bSYork Sun 	pd = 0;
16685614e71bSYork Sun 
16695614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
16705614e71bSYork Sun 	wr = 0;       /* Historical */
16715614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
167203e664d8SYork Sun 	wr = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
16735614e71bSYork Sun #endif
16745614e71bSYork Sun 	dll_res = 0;
16755614e71bSYork Sun 	mode = 0;
16765614e71bSYork Sun 
16775614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
16785614e71bSYork Sun 	if (1 <= cas_latency && cas_latency <= 4) {
16795614e71bSYork Sun 		unsigned char mode_caslat_table[4] = {
16805614e71bSYork Sun 			0x5,	/* 1.5 clocks */
16815614e71bSYork Sun 			0x2,	/* 2.0 clocks */
16825614e71bSYork Sun 			0x6,	/* 2.5 clocks */
16835614e71bSYork Sun 			0x3	/* 3.0 clocks */
16845614e71bSYork Sun 		};
16855614e71bSYork Sun 		caslat = mode_caslat_table[cas_latency - 1];
16865614e71bSYork Sun 	} else {
16875614e71bSYork Sun 		printf("Warning: unknown cas_latency %d\n", cas_latency);
16885614e71bSYork Sun 	}
16895614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
16905614e71bSYork Sun 	caslat = cas_latency;
16915614e71bSYork Sun #endif
16925614e71bSYork Sun 	bt = 0;
16935614e71bSYork Sun 
16945614e71bSYork Sun 	switch (popts->burst_length) {
16955614e71bSYork Sun 	case DDR_BL4:
16965614e71bSYork Sun 		bl = 2;
16975614e71bSYork Sun 		break;
16985614e71bSYork Sun 	case DDR_BL8:
16995614e71bSYork Sun 		bl = 3;
17005614e71bSYork Sun 		break;
17015614e71bSYork Sun 	default:
17025614e71bSYork Sun 		printf("Error: invalid burst length of %u specified. "
17035614e71bSYork Sun 			" Defaulting to 4 beats.\n",
17045614e71bSYork Sun 			popts->burst_length);
17055614e71bSYork Sun 		bl = 2;
17065614e71bSYork Sun 		break;
17075614e71bSYork Sun 	}
17085614e71bSYork Sun 
17095614e71bSYork Sun 	sdmode = (0
17105614e71bSYork Sun 		  | ((mr & 0x3) << 14)
17115614e71bSYork Sun 		  | ((pd & 0x1) << 12)
17125614e71bSYork Sun 		  | ((wr & 0x7) << 9)
17135614e71bSYork Sun 		  | ((dll_res & 0x1) << 8)
17145614e71bSYork Sun 		  | ((mode & 0x1) << 7)
17155614e71bSYork Sun 		  | ((caslat & 0x7) << 4)
17165614e71bSYork Sun 		  | ((bt & 0x1) << 3)
17175614e71bSYork Sun 		  | ((bl & 0x7) << 0)
17185614e71bSYork Sun 		  );
17195614e71bSYork Sun 
17205614e71bSYork Sun 	ddr->ddr_sdram_mode = (0
17215614e71bSYork Sun 			       | ((esdmode & 0xFFFF) << 16)
17225614e71bSYork Sun 			       | ((sdmode & 0xFFFF) << 0)
17235614e71bSYork Sun 			       );
17245614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode);
17255614e71bSYork Sun }
17265614e71bSYork Sun #endif
17275614e71bSYork Sun 
17285614e71bSYork Sun /* DDR SDRAM Data Initialization (DDR_DATA_INIT) */
17295614e71bSYork Sun static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr)
17305614e71bSYork Sun {
17315614e71bSYork Sun 	unsigned int init_value;	/* Initialization value */
17325614e71bSYork Sun 
17335614e71bSYork Sun #ifdef CONFIG_MEM_INIT_VALUE
17345614e71bSYork Sun 	init_value = CONFIG_MEM_INIT_VALUE;
17355614e71bSYork Sun #else
17365614e71bSYork Sun 	init_value = 0xDEADBEEF;
17375614e71bSYork Sun #endif
17385614e71bSYork Sun 	ddr->ddr_data_init = init_value;
17395614e71bSYork Sun }
17405614e71bSYork Sun 
17415614e71bSYork Sun /*
17425614e71bSYork Sun  * DDR SDRAM Clock Control (DDR_SDRAM_CLK_CNTL)
17435614e71bSYork Sun  * The old controller on the 8540/60 doesn't have this register.
17445614e71bSYork Sun  * Hope it's OK to set it (to 0) anyway.
17455614e71bSYork Sun  */
17465614e71bSYork Sun static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr,
17475614e71bSYork Sun 					 const memctl_options_t *popts)
17485614e71bSYork Sun {
17495614e71bSYork Sun 	unsigned int clk_adjust;	/* Clock adjust */
1750*d7c865bdSCurt Brune 	unsigned int ss_en = 0;		/* Source synchronous enable */
17515614e71bSYork Sun 
1752*d7c865bdSCurt Brune #if defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
1753*d7c865bdSCurt Brune 	/* Per FSL Application Note: AN2805 */
1754*d7c865bdSCurt Brune 	ss_en = 1;
1755*d7c865bdSCurt Brune #endif
17565614e71bSYork Sun 	clk_adjust = popts->clk_adjust;
1757*d7c865bdSCurt Brune 	ddr->ddr_sdram_clk_cntl = (0
1758*d7c865bdSCurt Brune 				   | ((ss_en & 0x1) << 31)
1759*d7c865bdSCurt Brune 				   | ((clk_adjust & 0xF) << 23)
1760*d7c865bdSCurt Brune 				   );
17615614e71bSYork Sun 	debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl);
17625614e71bSYork Sun }
17635614e71bSYork Sun 
17645614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_ADDR) */
17655614e71bSYork Sun static void set_ddr_init_addr(fsl_ddr_cfg_regs_t *ddr)
17665614e71bSYork Sun {
17675614e71bSYork Sun 	unsigned int init_addr = 0;	/* Initialization address */
17685614e71bSYork Sun 
17695614e71bSYork Sun 	ddr->ddr_init_addr = init_addr;
17705614e71bSYork Sun }
17715614e71bSYork Sun 
17725614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_EXT_ADDR) */
17735614e71bSYork Sun static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr)
17745614e71bSYork Sun {
17755614e71bSYork Sun 	unsigned int uia = 0;	/* Use initialization address */
17765614e71bSYork Sun 	unsigned int init_ext_addr = 0;	/* Initialization address */
17775614e71bSYork Sun 
17785614e71bSYork Sun 	ddr->ddr_init_ext_addr = (0
17795614e71bSYork Sun 				  | ((uia & 0x1) << 31)
17805614e71bSYork Sun 				  | (init_ext_addr & 0xF)
17815614e71bSYork Sun 				  );
17825614e71bSYork Sun }
17835614e71bSYork Sun 
17845614e71bSYork Sun /* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */
17855614e71bSYork Sun static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr,
17865614e71bSYork Sun 				const memctl_options_t *popts)
17875614e71bSYork Sun {
17885614e71bSYork Sun 	unsigned int rwt = 0; /* Read-to-write turnaround for same CS */
17895614e71bSYork Sun 	unsigned int wrt = 0; /* Write-to-read turnaround for same CS */
17905614e71bSYork Sun 	unsigned int rrt = 0; /* Read-to-read turnaround for same CS */
17915614e71bSYork Sun 	unsigned int wwt = 0; /* Write-to-write turnaround for same CS */
17925614e71bSYork Sun 	unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */
17935614e71bSYork Sun 
179434e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
17955614e71bSYork Sun 	if (popts->burst_length == DDR_BL8) {
17965614e71bSYork Sun 		/* We set BL/2 for fixed BL8 */
17975614e71bSYork Sun 		rrt = 0;	/* BL/2 clocks */
17985614e71bSYork Sun 		wwt = 0;	/* BL/2 clocks */
17995614e71bSYork Sun 	} else {
18005614e71bSYork Sun 		/* We need to set BL/2 + 2 to BC4 and OTF */
18015614e71bSYork Sun 		rrt = 2;	/* BL/2 + 2 clocks */
18025614e71bSYork Sun 		wwt = 2;	/* BL/2 + 2 clocks */
18035614e71bSYork Sun 	}
180434e026f9SYork Sun #endif
180534e026f9SYork Sun 
180634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
180734e026f9SYork Sun 	dll_lock = 2;	/* tDLLK = 1024 clocks */
180834e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
18095614e71bSYork Sun 	dll_lock = 1;	/* tDLLK = 512 clocks from spec */
18105614e71bSYork Sun #endif
18115614e71bSYork Sun 	ddr->timing_cfg_4 = (0
18125614e71bSYork Sun 			     | ((rwt & 0xf) << 28)
18135614e71bSYork Sun 			     | ((wrt & 0xf) << 24)
18145614e71bSYork Sun 			     | ((rrt & 0xf) << 20)
18155614e71bSYork Sun 			     | ((wwt & 0xf) << 16)
18165614e71bSYork Sun 			     | (dll_lock & 0x3)
18175614e71bSYork Sun 			     );
18185614e71bSYork Sun 	debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4);
18195614e71bSYork Sun }
18205614e71bSYork Sun 
18215614e71bSYork Sun /* DDR SDRAM Timing Configuration 5 (TIMING_CFG_5) */
18225614e71bSYork Sun static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr, unsigned int cas_latency)
18235614e71bSYork Sun {
18245614e71bSYork Sun 	unsigned int rodt_on = 0;	/* Read to ODT on */
18255614e71bSYork Sun 	unsigned int rodt_off = 0;	/* Read to ODT off */
18265614e71bSYork Sun 	unsigned int wodt_on = 0;	/* Write to ODT on */
18275614e71bSYork Sun 	unsigned int wodt_off = 0;	/* Write to ODT off */
18285614e71bSYork Sun 
182934e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
183034e026f9SYork Sun 	unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
183134e026f9SYork Sun 			      ((ddr->timing_cfg_2 & 0x00040000) >> 14);
18325614e71bSYork Sun 	/* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */
183334e026f9SYork Sun 	if (cas_latency >= wr_lat)
183434e026f9SYork Sun 		rodt_on = cas_latency - wr_lat + 1;
18355614e71bSYork Sun 	rodt_off = 4;	/*  4 clocks */
18365614e71bSYork Sun 	wodt_on = 1;	/*  1 clocks */
18375614e71bSYork Sun 	wodt_off = 4;	/*  4 clocks */
18385614e71bSYork Sun #endif
18395614e71bSYork Sun 
18405614e71bSYork Sun 	ddr->timing_cfg_5 = (0
18415614e71bSYork Sun 			     | ((rodt_on & 0x1f) << 24)
18425614e71bSYork Sun 			     | ((rodt_off & 0x7) << 20)
18435614e71bSYork Sun 			     | ((wodt_on & 0x1f) << 12)
18445614e71bSYork Sun 			     | ((wodt_off & 0x7) << 8)
18455614e71bSYork Sun 			     );
18465614e71bSYork Sun 	debug("FSLDDR: timing_cfg_5 = 0x%08x\n", ddr->timing_cfg_5);
18475614e71bSYork Sun }
18485614e71bSYork Sun 
184934e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
185034e026f9SYork Sun static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr)
185134e026f9SYork Sun {
185234e026f9SYork Sun 	unsigned int hs_caslat = 0;
185334e026f9SYork Sun 	unsigned int hs_wrlat = 0;
185434e026f9SYork Sun 	unsigned int hs_wrrec = 0;
185534e026f9SYork Sun 	unsigned int hs_clkadj = 0;
185634e026f9SYork Sun 	unsigned int hs_wrlvl_start = 0;
185734e026f9SYork Sun 
185834e026f9SYork Sun 	ddr->timing_cfg_6 = (0
185934e026f9SYork Sun 			     | ((hs_caslat & 0x1f) << 24)
186034e026f9SYork Sun 			     | ((hs_wrlat & 0x1f) << 19)
186134e026f9SYork Sun 			     | ((hs_wrrec & 0x1f) << 12)
186234e026f9SYork Sun 			     | ((hs_clkadj & 0x1f) << 6)
186334e026f9SYork Sun 			     | ((hs_wrlvl_start & 0x1f) << 0)
186434e026f9SYork Sun 			    );
186534e026f9SYork Sun 	debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6);
186634e026f9SYork Sun }
186734e026f9SYork Sun 
186803e664d8SYork Sun static void set_timing_cfg_7(const unsigned int ctrl_num,
186903e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
187034e026f9SYork Sun 			     const common_timing_params_t *common_dimm)
187134e026f9SYork Sun {
187234e026f9SYork Sun 	unsigned int txpr, tcksre, tcksrx;
187334e026f9SYork Sun 	unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd;
187434e026f9SYork Sun 
187503e664d8SYork Sun 	txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000));
187603e664d8SYork Sun 	tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
187703e664d8SYork Sun 	tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
187834e026f9SYork Sun 	par_lat = 0;
187934e026f9SYork Sun 	cs_to_cmd = 0;
188034e026f9SYork Sun 
188134e026f9SYork Sun 	if (txpr <= 200)
188234e026f9SYork Sun 		cke_rst = 0;
188334e026f9SYork Sun 	else if (txpr <= 256)
188434e026f9SYork Sun 		cke_rst = 1;
188534e026f9SYork Sun 	else if (txpr <= 512)
188634e026f9SYork Sun 		cke_rst = 2;
188734e026f9SYork Sun 	else
188834e026f9SYork Sun 		cke_rst = 3;
188934e026f9SYork Sun 
189034e026f9SYork Sun 	if (tcksre <= 19)
189134e026f9SYork Sun 		cksre = tcksre - 5;
189234e026f9SYork Sun 	else
189334e026f9SYork Sun 		cksre = 15;
189434e026f9SYork Sun 
189534e026f9SYork Sun 	if (tcksrx <= 19)
189634e026f9SYork Sun 		cksrx = tcksrx - 5;
189734e026f9SYork Sun 	else
189834e026f9SYork Sun 		cksrx = 15;
189934e026f9SYork Sun 
190034e026f9SYork Sun 	ddr->timing_cfg_7 = (0
190134e026f9SYork Sun 			     | ((cke_rst & 0x3) << 28)
190234e026f9SYork Sun 			     | ((cksre & 0xf) << 24)
190334e026f9SYork Sun 			     | ((cksrx & 0xf) << 20)
190434e026f9SYork Sun 			     | ((par_lat & 0xf) << 16)
190534e026f9SYork Sun 			     | ((cs_to_cmd & 0xf) << 4)
190634e026f9SYork Sun 			    );
190734e026f9SYork Sun 	debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7);
190834e026f9SYork Sun }
190934e026f9SYork Sun 
191003e664d8SYork Sun static void set_timing_cfg_8(const unsigned int ctrl_num,
191103e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
191234e026f9SYork Sun 			     const memctl_options_t *popts,
191334e026f9SYork Sun 			     const common_timing_params_t *common_dimm,
191434e026f9SYork Sun 			     unsigned int cas_latency)
191534e026f9SYork Sun {
191634e026f9SYork Sun 	unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg;
191734e026f9SYork Sun 	unsigned int acttoact_bg, wrtord_bg, pre_all_rec;
191803e664d8SYork Sun 	unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
191934e026f9SYork Sun 	unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
192034e026f9SYork Sun 			      ((ddr->timing_cfg_2 & 0x00040000) >> 14);
192134e026f9SYork Sun 
192234e026f9SYork Sun 	rwt_bg = cas_latency + 2 + 4 - wr_lat;
192334e026f9SYork Sun 	if (rwt_bg < tccdl)
192434e026f9SYork Sun 		rwt_bg = tccdl - rwt_bg;
192534e026f9SYork Sun 	else
192634e026f9SYork Sun 		rwt_bg = 0;
192734e026f9SYork Sun 
192834e026f9SYork Sun 	wrt_bg = wr_lat + 4 + 1 - cas_latency;
192934e026f9SYork Sun 	if (wrt_bg < tccdl)
193034e026f9SYork Sun 		wrt_bg = tccdl - wrt_bg;
193134e026f9SYork Sun 	else
193234e026f9SYork Sun 		wrt_bg = 0;
193334e026f9SYork Sun 
193434e026f9SYork Sun 	if (popts->burst_length == DDR_BL8) {
193534e026f9SYork Sun 		rrt_bg = tccdl - 4;
193634e026f9SYork Sun 		wwt_bg = tccdl - 4;
193734e026f9SYork Sun 	} else {
193834e026f9SYork Sun 		rrt_bg = tccdl - 2;
1939dc1437afSYork Sun 		wwt_bg = tccdl - 2;
194034e026f9SYork Sun 	}
194134e026f9SYork Sun 
194203e664d8SYork Sun 	acttoact_bg = picos_to_mclk(ctrl_num, common_dimm->trrdl_ps);
194303e664d8SYork Sun 	wrtord_bg = max(4U, picos_to_mclk(ctrl_num, 7500));
19443d75ec95SYork Sun 	if (popts->otf_burst_chop_en)
19453d75ec95SYork Sun 		wrtord_bg += 2;
19463d75ec95SYork Sun 
194734e026f9SYork Sun 	pre_all_rec = 0;
194834e026f9SYork Sun 
194934e026f9SYork Sun 	ddr->timing_cfg_8 = (0
195034e026f9SYork Sun 			     | ((rwt_bg & 0xf) << 28)
195134e026f9SYork Sun 			     | ((wrt_bg & 0xf) << 24)
195234e026f9SYork Sun 			     | ((rrt_bg & 0xf) << 20)
195334e026f9SYork Sun 			     | ((wwt_bg & 0xf) << 16)
195434e026f9SYork Sun 			     | ((acttoact_bg & 0xf) << 12)
195534e026f9SYork Sun 			     | ((wrtord_bg & 0xf) << 8)
195634e026f9SYork Sun 			     | ((pre_all_rec & 0x1f) << 0)
195734e026f9SYork Sun 			    );
195834e026f9SYork Sun 
195934e026f9SYork Sun 	debug("FSLDDR: timing_cfg_8 = 0x%08x\n", ddr->timing_cfg_8);
196034e026f9SYork Sun }
196134e026f9SYork Sun 
196234e026f9SYork Sun static void set_timing_cfg_9(fsl_ddr_cfg_regs_t *ddr)
196334e026f9SYork Sun {
196434e026f9SYork Sun 	ddr->timing_cfg_9 = 0;
196534e026f9SYork Sun 	debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9);
196634e026f9SYork Sun }
196734e026f9SYork Sun 
1968f80d6472SYork Sun /* This function needs to be called after set_ddr_sdram_cfg() is called */
196934e026f9SYork Sun static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr,
197034e026f9SYork Sun 			       const dimm_params_t *dimm_params)
197134e026f9SYork Sun {
1972f80d6472SYork Sun 	unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1;
1973f80d6472SYork Sun 
197434e026f9SYork Sun 	ddr->dq_map_0 = ((dimm_params->dq_mapping[0] & 0x3F) << 26) |
197534e026f9SYork Sun 			((dimm_params->dq_mapping[1] & 0x3F) << 20) |
197634e026f9SYork Sun 			((dimm_params->dq_mapping[2] & 0x3F) << 14) |
197734e026f9SYork Sun 			((dimm_params->dq_mapping[3] & 0x3F) << 8) |
197834e026f9SYork Sun 			((dimm_params->dq_mapping[4] & 0x3F) << 2);
197934e026f9SYork Sun 
198034e026f9SYork Sun 	ddr->dq_map_1 = ((dimm_params->dq_mapping[5] & 0x3F) << 26) |
198134e026f9SYork Sun 			((dimm_params->dq_mapping[6] & 0x3F) << 20) |
198234e026f9SYork Sun 			((dimm_params->dq_mapping[7] & 0x3F) << 14) |
198334e026f9SYork Sun 			((dimm_params->dq_mapping[10] & 0x3F) << 8) |
198434e026f9SYork Sun 			((dimm_params->dq_mapping[11] & 0x3F) << 2);
198534e026f9SYork Sun 
198634e026f9SYork Sun 	ddr->dq_map_2 = ((dimm_params->dq_mapping[12] & 0x3F) << 26) |
198734e026f9SYork Sun 			((dimm_params->dq_mapping[13] & 0x3F) << 20) |
198834e026f9SYork Sun 			((dimm_params->dq_mapping[14] & 0x3F) << 14) |
198934e026f9SYork Sun 			((dimm_params->dq_mapping[15] & 0x3F) << 8) |
199034e026f9SYork Sun 			((dimm_params->dq_mapping[16] & 0x3F) << 2);
199134e026f9SYork Sun 
1992f80d6472SYork Sun 	/* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */
199334e026f9SYork Sun 	ddr->dq_map_3 = ((dimm_params->dq_mapping[17] & 0x3F) << 26) |
199434e026f9SYork Sun 			((dimm_params->dq_mapping[8] & 0x3F) << 20) |
1995f80d6472SYork Sun 			(acc_ecc_en ? 0 :
1996f80d6472SYork Sun 			 (dimm_params->dq_mapping[9] & 0x3F) << 14) |
199734e026f9SYork Sun 			dimm_params->dq_mapping_ors;
199834e026f9SYork Sun 
199934e026f9SYork Sun 	debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0);
200034e026f9SYork Sun 	debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1);
200134e026f9SYork Sun 	debug("FSLDDR: dq_map_2 = 0x%08x\n", ddr->dq_map_2);
200234e026f9SYork Sun 	debug("FSLDDR: dq_map_3 = 0x%08x\n", ddr->dq_map_3);
200334e026f9SYork Sun }
200434e026f9SYork Sun static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr,
200534e026f9SYork Sun 			       const memctl_options_t *popts)
200634e026f9SYork Sun {
200734e026f9SYork Sun 	int rd_pre;
200834e026f9SYork Sun 
200934e026f9SYork Sun 	rd_pre = popts->quad_rank_present ? 1 : 0;
201034e026f9SYork Sun 
201134e026f9SYork Sun 	ddr->ddr_sdram_cfg_3 = (rd_pre & 0x1) << 16;
201234e026f9SYork Sun 
201334e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3);
201434e026f9SYork Sun }
201534e026f9SYork Sun #endif	/* CONFIG_SYS_FSL_DDR4 */
201634e026f9SYork Sun 
20175614e71bSYork Sun /* DDR ZQ Calibration Control (DDR_ZQ_CNTL) */
20185614e71bSYork Sun static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en)
20195614e71bSYork Sun {
20205614e71bSYork Sun 	unsigned int zqinit = 0;/* POR ZQ Calibration Time (tZQinit) */
20215614e71bSYork Sun 	/* Normal Operation Full Calibration Time (tZQoper) */
20225614e71bSYork Sun 	unsigned int zqoper = 0;
20235614e71bSYork Sun 	/* Normal Operation Short Calibration Time (tZQCS) */
20245614e71bSYork Sun 	unsigned int zqcs = 0;
202534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
202634e026f9SYork Sun 	unsigned int zqcs_init;
202734e026f9SYork Sun #endif
20285614e71bSYork Sun 
20295614e71bSYork Sun 	if (zq_en) {
203034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
203134e026f9SYork Sun 		zqinit = 10;	/* 1024 clocks */
203234e026f9SYork Sun 		zqoper = 9;	/* 512 clocks */
203334e026f9SYork Sun 		zqcs = 7;	/* 128 clocks */
203434e026f9SYork Sun 		zqcs_init = 5;	/* 1024 refresh sequences */
203534e026f9SYork Sun #else
20365614e71bSYork Sun 		zqinit = 9;	/* 512 clocks */
20375614e71bSYork Sun 		zqoper = 8;	/* 256 clocks */
20385614e71bSYork Sun 		zqcs = 6;	/* 64 clocks */
203934e026f9SYork Sun #endif
20405614e71bSYork Sun 	}
20415614e71bSYork Sun 
20425614e71bSYork Sun 	ddr->ddr_zq_cntl = (0
20435614e71bSYork Sun 			    | ((zq_en & 0x1) << 31)
20445614e71bSYork Sun 			    | ((zqinit & 0xF) << 24)
20455614e71bSYork Sun 			    | ((zqoper & 0xF) << 16)
20465614e71bSYork Sun 			    | ((zqcs & 0xF) << 8)
204734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
204834e026f9SYork Sun 			    | ((zqcs_init & 0xF) << 0)
204934e026f9SYork Sun #endif
20505614e71bSYork Sun 			    );
20515614e71bSYork Sun 	debug("FSLDDR: zq_cntl = 0x%08x\n", ddr->ddr_zq_cntl);
20525614e71bSYork Sun }
20535614e71bSYork Sun 
20545614e71bSYork Sun /* DDR Write Leveling Control (DDR_WRLVL_CNTL) */
20555614e71bSYork Sun static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en,
20565614e71bSYork Sun 				const memctl_options_t *popts)
20575614e71bSYork Sun {
20585614e71bSYork Sun 	/*
20595614e71bSYork Sun 	 * First DQS pulse rising edge after margining mode
20605614e71bSYork Sun 	 * is programmed (tWL_MRD)
20615614e71bSYork Sun 	 */
20625614e71bSYork Sun 	unsigned int wrlvl_mrd = 0;
20635614e71bSYork Sun 	/* ODT delay after margining mode is programmed (tWL_ODTEN) */
20645614e71bSYork Sun 	unsigned int wrlvl_odten = 0;
20655614e71bSYork Sun 	/* DQS/DQS_ delay after margining mode is programmed (tWL_DQSEN) */
20665614e71bSYork Sun 	unsigned int wrlvl_dqsen = 0;
20675614e71bSYork Sun 	/* WRLVL_SMPL: Write leveling sample time */
20685614e71bSYork Sun 	unsigned int wrlvl_smpl = 0;
20695614e71bSYork Sun 	/* WRLVL_WLR: Write leveling repeition time */
20705614e71bSYork Sun 	unsigned int wrlvl_wlr = 0;
20715614e71bSYork Sun 	/* WRLVL_START: Write leveling start time */
20725614e71bSYork Sun 	unsigned int wrlvl_start = 0;
20735614e71bSYork Sun 
20745614e71bSYork Sun 	/* suggest enable write leveling for DDR3 due to fly-by topology */
20755614e71bSYork Sun 	if (wrlvl_en) {
20765614e71bSYork Sun 		/* tWL_MRD min = 40 nCK, we set it 64 */
20775614e71bSYork Sun 		wrlvl_mrd = 0x6;
20785614e71bSYork Sun 		/* tWL_ODTEN 128 */
20795614e71bSYork Sun 		wrlvl_odten = 0x7;
20805614e71bSYork Sun 		/* tWL_DQSEN min = 25 nCK, we set it 32 */
20815614e71bSYork Sun 		wrlvl_dqsen = 0x5;
20825614e71bSYork Sun 		/*
20835614e71bSYork Sun 		 * Write leveling sample time at least need 6 clocks
20845614e71bSYork Sun 		 * higher than tWLO to allow enough time for progagation
20855614e71bSYork Sun 		 * delay and sampling the prime data bits.
20865614e71bSYork Sun 		 */
20875614e71bSYork Sun 		wrlvl_smpl = 0xf;
20885614e71bSYork Sun 		/*
20895614e71bSYork Sun 		 * Write leveling repetition time
20905614e71bSYork Sun 		 * at least tWLO + 6 clocks clocks
20915614e71bSYork Sun 		 * we set it 64
20925614e71bSYork Sun 		 */
20935614e71bSYork Sun 		wrlvl_wlr = 0x6;
20945614e71bSYork Sun 		/*
20955614e71bSYork Sun 		 * Write leveling start time
20965614e71bSYork Sun 		 * The value use for the DQS_ADJUST for the first sample
20975614e71bSYork Sun 		 * when write leveling is enabled. It probably needs to be
20985614e71bSYork Sun 		 * overriden per platform.
20995614e71bSYork Sun 		 */
21005614e71bSYork Sun 		wrlvl_start = 0x8;
21015614e71bSYork Sun 		/*
21025614e71bSYork Sun 		 * Override the write leveling sample and start time
21035614e71bSYork Sun 		 * according to specific board
21045614e71bSYork Sun 		 */
21055614e71bSYork Sun 		if (popts->wrlvl_override) {
21065614e71bSYork Sun 			wrlvl_smpl = popts->wrlvl_sample;
21075614e71bSYork Sun 			wrlvl_start = popts->wrlvl_start;
21085614e71bSYork Sun 		}
21095614e71bSYork Sun 	}
21105614e71bSYork Sun 
21115614e71bSYork Sun 	ddr->ddr_wrlvl_cntl = (0
21125614e71bSYork Sun 			       | ((wrlvl_en & 0x1) << 31)
21135614e71bSYork Sun 			       | ((wrlvl_mrd & 0x7) << 24)
21145614e71bSYork Sun 			       | ((wrlvl_odten & 0x7) << 20)
21155614e71bSYork Sun 			       | ((wrlvl_dqsen & 0x7) << 16)
21165614e71bSYork Sun 			       | ((wrlvl_smpl & 0xf) << 12)
21175614e71bSYork Sun 			       | ((wrlvl_wlr & 0x7) << 8)
21185614e71bSYork Sun 			       | ((wrlvl_start & 0x1F) << 0)
21195614e71bSYork Sun 			       );
21205614e71bSYork Sun 	debug("FSLDDR: wrlvl_cntl = 0x%08x\n", ddr->ddr_wrlvl_cntl);
21215614e71bSYork Sun 	ddr->ddr_wrlvl_cntl_2 = popts->wrlvl_ctl_2;
21225614e71bSYork Sun 	debug("FSLDDR: wrlvl_cntl_2 = 0x%08x\n", ddr->ddr_wrlvl_cntl_2);
21235614e71bSYork Sun 	ddr->ddr_wrlvl_cntl_3 = popts->wrlvl_ctl_3;
21245614e71bSYork Sun 	debug("FSLDDR: wrlvl_cntl_3 = 0x%08x\n", ddr->ddr_wrlvl_cntl_3);
21255614e71bSYork Sun 
21265614e71bSYork Sun }
21275614e71bSYork Sun 
21285614e71bSYork Sun /* DDR Self Refresh Counter (DDR_SR_CNTR) */
21295614e71bSYork Sun static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it)
21305614e71bSYork Sun {
21315614e71bSYork Sun 	/* Self Refresh Idle Threshold */
21325614e71bSYork Sun 	ddr->ddr_sr_cntr = (sr_it & 0xF) << 16;
21335614e71bSYork Sun }
21345614e71bSYork Sun 
21355614e71bSYork Sun static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
21365614e71bSYork Sun {
21375614e71bSYork Sun 	if (popts->addr_hash) {
21385614e71bSYork Sun 		ddr->ddr_eor = 0x40000000;	/* address hash enable */
21395614e71bSYork Sun 		puts("Address hashing enabled.\n");
21405614e71bSYork Sun 	}
21415614e71bSYork Sun }
21425614e71bSYork Sun 
21435614e71bSYork Sun static void set_ddr_cdr1(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
21445614e71bSYork Sun {
21455614e71bSYork Sun 	ddr->ddr_cdr1 = popts->ddr_cdr1;
21465614e71bSYork Sun 	debug("FSLDDR: ddr_cdr1 = 0x%08x\n", ddr->ddr_cdr1);
21475614e71bSYork Sun }
21485614e71bSYork Sun 
21495614e71bSYork Sun static void set_ddr_cdr2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
21505614e71bSYork Sun {
21515614e71bSYork Sun 	ddr->ddr_cdr2 = popts->ddr_cdr2;
21525614e71bSYork Sun 	debug("FSLDDR: ddr_cdr2 = 0x%08x\n", ddr->ddr_cdr2);
21535614e71bSYork Sun }
21545614e71bSYork Sun 
21555614e71bSYork Sun unsigned int
21565614e71bSYork Sun check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
21575614e71bSYork Sun {
21585614e71bSYork Sun 	unsigned int res = 0;
21595614e71bSYork Sun 
21605614e71bSYork Sun 	/*
21615614e71bSYork Sun 	 * Check that DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] are
21625614e71bSYork Sun 	 * not set at the same time.
21635614e71bSYork Sun 	 */
21645614e71bSYork Sun 	if (ddr->ddr_sdram_cfg & 0x10000000
21655614e71bSYork Sun 	    && ddr->ddr_sdram_cfg & 0x00008000) {
21665614e71bSYork Sun 		printf("Error: DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] "
21675614e71bSYork Sun 				" should not be set at the same time.\n");
21685614e71bSYork Sun 		res++;
21695614e71bSYork Sun 	}
21705614e71bSYork Sun 
21715614e71bSYork Sun 	return res;
21725614e71bSYork Sun }
21735614e71bSYork Sun 
21745614e71bSYork Sun unsigned int
217503e664d8SYork Sun compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
217603e664d8SYork Sun 			       const memctl_options_t *popts,
21775614e71bSYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
21785614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
21795614e71bSYork Sun 			       const dimm_params_t *dimm_params,
21805614e71bSYork Sun 			       unsigned int dbw_cap_adj,
21815614e71bSYork Sun 			       unsigned int size_only)
21825614e71bSYork Sun {
21835614e71bSYork Sun 	unsigned int i;
21845614e71bSYork Sun 	unsigned int cas_latency;
21855614e71bSYork Sun 	unsigned int additive_latency;
21865614e71bSYork Sun 	unsigned int sr_it;
21875614e71bSYork Sun 	unsigned int zq_en;
21885614e71bSYork Sun 	unsigned int wrlvl_en;
21895614e71bSYork Sun 	unsigned int ip_rev = 0;
21905614e71bSYork Sun 	unsigned int unq_mrs_en = 0;
21915614e71bSYork Sun 	int cs_en = 1;
21925614e71bSYork Sun 
21935614e71bSYork Sun 	memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t));
21945614e71bSYork Sun 
21955614e71bSYork Sun 	if (common_dimm == NULL) {
21965614e71bSYork Sun 		printf("Error: subset DIMM params struct null pointer\n");
21975614e71bSYork Sun 		return 1;
21985614e71bSYork Sun 	}
21995614e71bSYork Sun 
22005614e71bSYork Sun 	/*
22015614e71bSYork Sun 	 * Process overrides first.
22025614e71bSYork Sun 	 *
22035614e71bSYork Sun 	 * FIXME: somehow add dereated caslat to this
22045614e71bSYork Sun 	 */
22055614e71bSYork Sun 	cas_latency = (popts->cas_latency_override)
22065614e71bSYork Sun 		? popts->cas_latency_override_value
220734e026f9SYork Sun 		: common_dimm->lowest_common_spd_caslat;
22085614e71bSYork Sun 
22095614e71bSYork Sun 	additive_latency = (popts->additive_latency_override)
22105614e71bSYork Sun 		? popts->additive_latency_override_value
22115614e71bSYork Sun 		: common_dimm->additive_latency;
22125614e71bSYork Sun 
22135614e71bSYork Sun 	sr_it = (popts->auto_self_refresh_en)
22145614e71bSYork Sun 		? popts->sr_it
22155614e71bSYork Sun 		: 0;
22165614e71bSYork Sun 	/* ZQ calibration */
22175614e71bSYork Sun 	zq_en = (popts->zq_en) ? 1 : 0;
22185614e71bSYork Sun 	/* write leveling */
22195614e71bSYork Sun 	wrlvl_en = (popts->wrlvl_en) ? 1 : 0;
22205614e71bSYork Sun 
22215614e71bSYork Sun 	/* Chip Select Memory Bounds (CSn_BNDS) */
22225614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
22235614e71bSYork Sun 		unsigned long long ea, sa;
22245614e71bSYork Sun 		unsigned int cs_per_dimm
22255614e71bSYork Sun 			= CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR;
22265614e71bSYork Sun 		unsigned int dimm_number
22275614e71bSYork Sun 			= i / cs_per_dimm;
22285614e71bSYork Sun 		unsigned long long rank_density
22295614e71bSYork Sun 			= dimm_params[dimm_number].rank_density >> dbw_cap_adj;
22305614e71bSYork Sun 
22315614e71bSYork Sun 		if (dimm_params[dimm_number].n_ranks == 0) {
22325614e71bSYork Sun 			debug("Skipping setup of CS%u "
22335614e71bSYork Sun 				"because n_ranks on DIMM %u is 0\n", i, dimm_number);
22345614e71bSYork Sun 			continue;
22355614e71bSYork Sun 		}
22365614e71bSYork Sun 		if (popts->memctl_interleaving) {
22375614e71bSYork Sun 			switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
22385614e71bSYork Sun 			case FSL_DDR_CS0_CS1_CS2_CS3:
22395614e71bSYork Sun 				break;
22405614e71bSYork Sun 			case FSL_DDR_CS0_CS1:
22415614e71bSYork Sun 			case FSL_DDR_CS0_CS1_AND_CS2_CS3:
22425614e71bSYork Sun 				if (i > 1)
22435614e71bSYork Sun 					cs_en = 0;
22445614e71bSYork Sun 				break;
22455614e71bSYork Sun 			case FSL_DDR_CS2_CS3:
22465614e71bSYork Sun 			default:
22475614e71bSYork Sun 				if (i > 0)
22485614e71bSYork Sun 					cs_en = 0;
22495614e71bSYork Sun 				break;
22505614e71bSYork Sun 			}
22515614e71bSYork Sun 			sa = common_dimm->base_address;
22525614e71bSYork Sun 			ea = sa + common_dimm->total_mem - 1;
22535614e71bSYork Sun 		} else if (!popts->memctl_interleaving) {
22545614e71bSYork Sun 			/*
22555614e71bSYork Sun 			 * If memory interleaving between controllers is NOT
22565614e71bSYork Sun 			 * enabled, the starting address for each memory
22575614e71bSYork Sun 			 * controller is distinct.  However, because rank
22585614e71bSYork Sun 			 * interleaving is enabled, the starting and ending
22595614e71bSYork Sun 			 * addresses of the total memory on that memory
22605614e71bSYork Sun 			 * controller needs to be programmed into its
22615614e71bSYork Sun 			 * respective CS0_BNDS.
22625614e71bSYork Sun 			 */
22635614e71bSYork Sun 			switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
22645614e71bSYork Sun 			case FSL_DDR_CS0_CS1_CS2_CS3:
22655614e71bSYork Sun 				sa = common_dimm->base_address;
22665614e71bSYork Sun 				ea = sa + common_dimm->total_mem - 1;
22675614e71bSYork Sun 				break;
22685614e71bSYork Sun 			case FSL_DDR_CS0_CS1_AND_CS2_CS3:
22695614e71bSYork Sun 				if ((i >= 2) && (dimm_number == 0)) {
22705614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address +
22715614e71bSYork Sun 					      2 * rank_density;
22725614e71bSYork Sun 					ea = sa + 2 * rank_density - 1;
22735614e71bSYork Sun 				} else {
22745614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address;
22755614e71bSYork Sun 					ea = sa + 2 * rank_density - 1;
22765614e71bSYork Sun 				}
22775614e71bSYork Sun 				break;
22785614e71bSYork Sun 			case FSL_DDR_CS0_CS1:
22795614e71bSYork Sun 				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
22805614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address;
22815614e71bSYork Sun 					ea = sa + rank_density - 1;
22825614e71bSYork Sun 					if (i != 1)
22835614e71bSYork Sun 						sa += (i % cs_per_dimm) * rank_density;
22845614e71bSYork Sun 					ea += (i % cs_per_dimm) * rank_density;
22855614e71bSYork Sun 				} else {
22865614e71bSYork Sun 					sa = 0;
22875614e71bSYork Sun 					ea = 0;
22885614e71bSYork Sun 				}
22895614e71bSYork Sun 				if (i == 0)
22905614e71bSYork Sun 					ea += rank_density;
22915614e71bSYork Sun 				break;
22925614e71bSYork Sun 			case FSL_DDR_CS2_CS3:
22935614e71bSYork Sun 				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
22945614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address;
22955614e71bSYork Sun 					ea = sa + rank_density - 1;
22965614e71bSYork Sun 					if (i != 3)
22975614e71bSYork Sun 						sa += (i % cs_per_dimm) * rank_density;
22985614e71bSYork Sun 					ea += (i % cs_per_dimm) * rank_density;
22995614e71bSYork Sun 				} else {
23005614e71bSYork Sun 					sa = 0;
23015614e71bSYork Sun 					ea = 0;
23025614e71bSYork Sun 				}
23035614e71bSYork Sun 				if (i == 2)
23045614e71bSYork Sun 					ea += (rank_density >> dbw_cap_adj);
23055614e71bSYork Sun 				break;
23065614e71bSYork Sun 			default:  /* No bank(chip-select) interleaving */
23075614e71bSYork Sun 				sa = dimm_params[dimm_number].base_address;
23085614e71bSYork Sun 				ea = sa + rank_density - 1;
23095614e71bSYork Sun 				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
23105614e71bSYork Sun 					sa += (i % cs_per_dimm) * rank_density;
23115614e71bSYork Sun 					ea += (i % cs_per_dimm) * rank_density;
23125614e71bSYork Sun 				} else {
23135614e71bSYork Sun 					sa = 0;
23145614e71bSYork Sun 					ea = 0;
23155614e71bSYork Sun 				}
23165614e71bSYork Sun 				break;
23175614e71bSYork Sun 			}
23185614e71bSYork Sun 		}
23195614e71bSYork Sun 
23205614e71bSYork Sun 		sa >>= 24;
23215614e71bSYork Sun 		ea >>= 24;
23225614e71bSYork Sun 
23235614e71bSYork Sun 		if (cs_en) {
23245614e71bSYork Sun 			ddr->cs[i].bnds = (0
2325d4263b8aSYork Sun 				| ((sa & 0xffff) << 16) /* starting address */
2326d4263b8aSYork Sun 				| ((ea & 0xffff) << 0)	/* ending address */
23275614e71bSYork Sun 				);
23285614e71bSYork Sun 		} else {
23295614e71bSYork Sun 			/* setting bnds to 0xffffffff for inactive CS */
23305614e71bSYork Sun 			ddr->cs[i].bnds = 0xffffffff;
23315614e71bSYork Sun 		}
23325614e71bSYork Sun 
23335614e71bSYork Sun 		debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds);
23345614e71bSYork Sun 		set_csn_config(dimm_number, i, ddr, popts, dimm_params);
23355614e71bSYork Sun 		set_csn_config_2(i, ddr);
23365614e71bSYork Sun 	}
23375614e71bSYork Sun 
23385614e71bSYork Sun 	/*
23395614e71bSYork Sun 	 * In the case we only need to compute the ddr sdram size, we only need
23405614e71bSYork Sun 	 * to set csn registers, so return from here.
23415614e71bSYork Sun 	 */
23425614e71bSYork Sun 	if (size_only)
23435614e71bSYork Sun 		return 0;
23445614e71bSYork Sun 
23455614e71bSYork Sun 	set_ddr_eor(ddr, popts);
23465614e71bSYork Sun 
23475614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1)
234803e664d8SYork Sun 	set_timing_cfg_0(ctrl_num, ddr, popts, dimm_params);
23495614e71bSYork Sun #endif
23505614e71bSYork Sun 
235103e664d8SYork Sun 	set_timing_cfg_3(ctrl_num, ddr, popts, common_dimm, cas_latency,
2352d4263b8aSYork Sun 			 additive_latency);
235303e664d8SYork Sun 	set_timing_cfg_1(ctrl_num, ddr, popts, common_dimm, cas_latency);
235403e664d8SYork Sun 	set_timing_cfg_2(ctrl_num, ddr, popts, common_dimm,
23555614e71bSYork Sun 			 cas_latency, additive_latency);
23565614e71bSYork Sun 
23575614e71bSYork Sun 	set_ddr_cdr1(ddr, popts);
23585614e71bSYork Sun 	set_ddr_cdr2(ddr, popts);
23595614e71bSYork Sun 	set_ddr_sdram_cfg(ddr, popts, common_dimm);
23605614e71bSYork Sun 	ip_rev = fsl_ddr_get_version();
23615614e71bSYork Sun 	if (ip_rev > 0x40400)
23625614e71bSYork Sun 		unq_mrs_en = 1;
23635614e71bSYork Sun 
2364f80d6472SYork Sun 	if ((ip_rev > 0x40700) && (popts->cswl_override != 0))
2365ef87cab6SYork Sun 		ddr->debug[18] = popts->cswl_override;
2366ef87cab6SYork Sun 
236703e664d8SYork Sun 	set_ddr_sdram_cfg_2(ctrl_num, ddr, popts, unq_mrs_en);
236803e664d8SYork Sun 	set_ddr_sdram_mode(ctrl_num, ddr, popts, common_dimm,
23695614e71bSYork Sun 			   cas_latency, additive_latency, unq_mrs_en);
237003e664d8SYork Sun 	set_ddr_sdram_mode_2(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
237134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
237234e026f9SYork Sun 	set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en);
237303e664d8SYork Sun 	set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
237434e026f9SYork Sun #endif
237503e664d8SYork Sun 	set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm);
23765614e71bSYork Sun 	set_ddr_data_init(ddr);
23775614e71bSYork Sun 	set_ddr_sdram_clk_cntl(ddr, popts);
23785614e71bSYork Sun 	set_ddr_init_addr(ddr);
23795614e71bSYork Sun 	set_ddr_init_ext_addr(ddr);
23805614e71bSYork Sun 	set_timing_cfg_4(ddr, popts);
23815614e71bSYork Sun 	set_timing_cfg_5(ddr, cas_latency);
238234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
238334e026f9SYork Sun 	set_ddr_sdram_cfg_3(ddr, popts);
238434e026f9SYork Sun 	set_timing_cfg_6(ddr);
238503e664d8SYork Sun 	set_timing_cfg_7(ctrl_num, ddr, common_dimm);
238603e664d8SYork Sun 	set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency);
238734e026f9SYork Sun 	set_timing_cfg_9(ddr);
238834e026f9SYork Sun 	set_ddr_dq_mapping(ddr, dimm_params);
238934e026f9SYork Sun #endif
23905614e71bSYork Sun 
23915614e71bSYork Sun 	set_ddr_zq_cntl(ddr, zq_en);
23925614e71bSYork Sun 	set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts);
23935614e71bSYork Sun 
23945614e71bSYork Sun 	set_ddr_sr_cntr(ddr, sr_it);
23955614e71bSYork Sun 
23965614e71bSYork Sun 	set_ddr_sdram_rcw(ddr, popts, common_dimm);
23975614e71bSYork Sun 
23985614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR_EMU
23995614e71bSYork Sun 	/* disble DDR training for emulator */
24005614e71bSYork Sun 	ddr->debug[2] = 0x00000400;
24011f3402e7SYork Sun 	ddr->debug[4] = 0xff800800;
24021f3402e7SYork Sun 	ddr->debug[5] = 0x08000800;
24031f3402e7SYork Sun 	ddr->debug[6] = 0x08000800;
24041f3402e7SYork Sun 	ddr->debug[7] = 0x08000800;
24051f3402e7SYork Sun 	ddr->debug[8] = 0x08000800;
24065614e71bSYork Sun #endif
24079855b3beSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_A004508
24089855b3beSYork Sun 	if ((ip_rev >= 0x40000) && (ip_rev < 0x40400))
24099855b3beSYork Sun 		ddr->debug[2] |= 0x00000200;	/* set bit 22 */
24109855b3beSYork Sun #endif
24119855b3beSYork Sun 
24125614e71bSYork Sun 	return check_fsl_memctl_config_regs(ddr);
24135614e71bSYork Sun }
2414