xref: /openbmc/u-boot/drivers/ddr/fsl/ctrl_regs.c (revision 84baed2a2bdde3b2bf876d36cc966bd41ac67a6d)
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 unsigned int picos_to_mclk(unsigned int picos);
215614e71bSYork Sun 
225614e71bSYork Sun /*
235614e71bSYork Sun  * Determine Rtt value.
245614e71bSYork Sun  *
255614e71bSYork Sun  * This should likely be either board or controller specific.
265614e71bSYork Sun  *
275614e71bSYork Sun  * Rtt(nominal) - DDR2:
285614e71bSYork Sun  *	0 = Rtt disabled
295614e71bSYork Sun  *	1 = 75 ohm
305614e71bSYork Sun  *	2 = 150 ohm
315614e71bSYork Sun  *	3 = 50 ohm
325614e71bSYork Sun  * Rtt(nominal) - DDR3:
335614e71bSYork Sun  *	0 = Rtt disabled
345614e71bSYork Sun  *	1 = 60 ohm
355614e71bSYork Sun  *	2 = 120 ohm
365614e71bSYork Sun  *	3 = 40 ohm
375614e71bSYork Sun  *	4 = 20 ohm
385614e71bSYork Sun  *	5 = 30 ohm
395614e71bSYork Sun  *
405614e71bSYork Sun  * FIXME: Apparently 8641 needs a value of 2
415614e71bSYork Sun  * FIXME: Old code seys if 667 MHz or higher, use 3 on 8572
425614e71bSYork Sun  *
435614e71bSYork Sun  * FIXME: There was some effort down this line earlier:
445614e71bSYork Sun  *
455614e71bSYork Sun  *	unsigned int i;
465614e71bSYork Sun  *	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL/2; i++) {
475614e71bSYork Sun  *		if (popts->dimmslot[i].num_valid_cs
485614e71bSYork Sun  *		    && (popts->cs_local_opts[2*i].odt_rd_cfg
495614e71bSYork Sun  *			|| popts->cs_local_opts[2*i].odt_wr_cfg)) {
505614e71bSYork Sun  *			rtt = 2;
515614e71bSYork Sun  *			break;
525614e71bSYork Sun  *		}
535614e71bSYork Sun  *	}
545614e71bSYork Sun  */
555614e71bSYork Sun static inline int fsl_ddr_get_rtt(void)
565614e71bSYork Sun {
575614e71bSYork Sun 	int rtt;
585614e71bSYork Sun 
595614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
605614e71bSYork Sun 	rtt = 0;
615614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
625614e71bSYork Sun 	rtt = 3;
635614e71bSYork Sun #else
645614e71bSYork Sun 	rtt = 0;
655614e71bSYork Sun #endif
665614e71bSYork Sun 
675614e71bSYork Sun 	return rtt;
685614e71bSYork Sun }
695614e71bSYork Sun 
7034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
7134e026f9SYork Sun /*
7234e026f9SYork Sun  * compute CAS write latency according to DDR4 spec
7334e026f9SYork Sun  * CWL = 9 for <= 1600MT/s
7434e026f9SYork Sun  *       10 for <= 1866MT/s
7534e026f9SYork Sun  *       11 for <= 2133MT/s
7634e026f9SYork Sun  *       12 for <= 2400MT/s
7734e026f9SYork Sun  *       14 for <= 2667MT/s
7834e026f9SYork Sun  *       16 for <= 2933MT/s
7934e026f9SYork Sun  *       18 for higher
8034e026f9SYork Sun  */
8134e026f9SYork Sun static inline unsigned int compute_cas_write_latency(void)
8234e026f9SYork Sun {
8334e026f9SYork Sun 	unsigned int cwl;
8434e026f9SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps();
8534e026f9SYork Sun 	if (mclk_ps >= 1250)
8634e026f9SYork Sun 		cwl = 9;
8734e026f9SYork Sun 	else if (mclk_ps >= 1070)
8834e026f9SYork Sun 		cwl = 10;
8934e026f9SYork Sun 	else if (mclk_ps >= 935)
9034e026f9SYork Sun 		cwl = 11;
9134e026f9SYork Sun 	else if (mclk_ps >= 833)
9234e026f9SYork Sun 		cwl = 12;
9334e026f9SYork Sun 	else if (mclk_ps >= 750)
9434e026f9SYork Sun 		cwl = 14;
9534e026f9SYork Sun 	else if (mclk_ps >= 681)
9634e026f9SYork Sun 		cwl = 16;
9734e026f9SYork Sun 	else
9834e026f9SYork Sun 		cwl = 18;
9934e026f9SYork Sun 
10034e026f9SYork Sun 	return cwl;
10134e026f9SYork Sun }
10234e026f9SYork Sun #else
1035614e71bSYork Sun /*
1045614e71bSYork Sun  * compute the CAS write latency according to DDR3 spec
1055614e71bSYork Sun  * CWL = 5 if tCK >= 2.5ns
1065614e71bSYork Sun  *       6 if 2.5ns > tCK >= 1.875ns
1075614e71bSYork Sun  *       7 if 1.875ns > tCK >= 1.5ns
1085614e71bSYork Sun  *       8 if 1.5ns > tCK >= 1.25ns
1095614e71bSYork Sun  *       9 if 1.25ns > tCK >= 1.07ns
1105614e71bSYork Sun  *       10 if 1.07ns > tCK >= 0.935ns
1115614e71bSYork Sun  *       11 if 0.935ns > tCK >= 0.833ns
1125614e71bSYork Sun  *       12 if 0.833ns > tCK >= 0.75ns
1135614e71bSYork Sun  */
1145614e71bSYork Sun static inline unsigned int compute_cas_write_latency(void)
1155614e71bSYork Sun {
1165614e71bSYork Sun 	unsigned int cwl;
1175614e71bSYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps();
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)
256*84baed2aSYork Sun /*
257*84baed2aSYork Sun  * Check DIMM configuration, return 2 if quad-rank or two dual-rank
258*84baed2aSYork Sun  * Return 1 if other two slots configuration. Return 0 if single slot.
259*84baed2aSYork 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)
264*84baed2aSYork 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))
270*84baed2aSYork Sun 		return 2;
2715614e71bSYork Sun 
2725614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
2735614e71bSYork Sun 	if (dimm_params[0].n_ranks == 4)
274*84baed2aSYork Sun 		return 2;
2755614e71bSYork Sun #endif
276*84baed2aSYork Sun 
277*84baed2aSYork Sun 	if ((dimm_params[0].n_ranks != 0) &&
278*84baed2aSYork Sun 	    (dimm_params[2].n_ranks != 0))
279*84baed2aSYork 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  */
2905614e71bSYork Sun static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
2915614e71bSYork Sun 				const memctl_options_t *popts,
2925614e71bSYork Sun 				const dimm_params_t *dimm_params)
2935614e71bSYork Sun {
2945614e71bSYork Sun 	unsigned char trwt_mclk = 0;   /* Read-to-write turnaround */
2955614e71bSYork Sun 	unsigned char twrt_mclk = 0;   /* Write-to-read turnaround */
2965614e71bSYork Sun 	/* 7.5 ns on -3E; 0 means WL - CL + BL/2 + 1 */
2975614e71bSYork Sun 	unsigned char trrt_mclk = 0;   /* Read-to-read turnaround */
2985614e71bSYork Sun 	unsigned char twwt_mclk = 0;   /* Write-to-write turnaround */
2995614e71bSYork Sun 
3005614e71bSYork Sun 	/* Active powerdown exit timing (tXARD and tXARDS). */
3015614e71bSYork Sun 	unsigned char act_pd_exit_mclk;
3025614e71bSYork Sun 	/* Precharge powerdown exit timing (tXP). */
3035614e71bSYork Sun 	unsigned char pre_pd_exit_mclk;
3045614e71bSYork Sun 	/* ODT powerdown exit timing (tAXPD). */
30534e026f9SYork Sun 	unsigned char taxpd_mclk = 0;
3065614e71bSYork Sun 	/* Mode register set cycle time (tMRD). */
3075614e71bSYork Sun 	unsigned char tmrd_mclk;
308bb578322SYork Sun #if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
309bb578322SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps();
310bb578322SYork Sun #endif
3115614e71bSYork Sun 
31234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
31334e026f9SYork Sun 	/* tXP=max(4nCK, 6ns) */
314b4141195SMasahiro Yamada 	int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
31534e026f9SYork Sun 	trwt_mclk = 2;
31634e026f9SYork Sun 	twrt_mclk = 1;
31734e026f9SYork Sun 	act_pd_exit_mclk = picos_to_mclk(txp);
31834e026f9SYork Sun 	pre_pd_exit_mclk = act_pd_exit_mclk;
31934e026f9SYork Sun 	/*
32034e026f9SYork Sun 	 * MRS_CYC = max(tMRD, tMOD)
32134e026f9SYork Sun 	 * tMRD = 8nCK, tMOD = max(24nCK, 15ns)
32234e026f9SYork Sun 	 */
323b4141195SMasahiro Yamada 	tmrd_mclk = max(24U, picos_to_mclk(15000));
32434e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
325bb578322SYork Sun 	unsigned int data_rate = get_ddr_freq(0);
326bb578322SYork Sun 	int txp;
327*84baed2aSYork Sun 	int odt_overlap;
3285614e71bSYork Sun 	/*
3295614e71bSYork Sun 	 * (tXARD and tXARDS). Empirical?
3305614e71bSYork Sun 	 * The DDR3 spec has not tXARD,
3315614e71bSYork Sun 	 * we use the tXP instead of it.
332bb578322SYork Sun 	 * tXP=max(3nCK, 7.5ns) for DDR3-800, 1066
333bb578322SYork Sun 	 *     max(3nCK, 6ns) for DDR3-1333, 1600, 1866, 2133
3345614e71bSYork Sun 	 * spec has not the tAXPD, we use
3355614e71bSYork Sun 	 * tAXPD=1, need design to confirm.
3365614e71bSYork Sun 	 */
337b4141195SMasahiro Yamada 	txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000));
338bb578322SYork Sun 
3395614e71bSYork Sun 	tmrd_mclk = 4;
3405614e71bSYork Sun 	/* set the turnaround time */
3415614e71bSYork Sun 
3425614e71bSYork Sun 	/*
343*84baed2aSYork Sun 	 * for single quad-rank DIMM and two-slot DIMMs
3445614e71bSYork Sun 	 * to avoid ODT overlap
3455614e71bSYork Sun 	 */
346*84baed2aSYork Sun 	odt_overlap = avoid_odt_overlap(dimm_params);
347*84baed2aSYork Sun 	switch (odt_overlap) {
348*84baed2aSYork Sun 	case 2:
3495614e71bSYork Sun 		twwt_mclk = 2;
3505614e71bSYork Sun 		trrt_mclk = 1;
351*84baed2aSYork Sun 		break;
352*84baed2aSYork Sun 	case 1:
353*84baed2aSYork Sun 		twwt_mclk = 1;
354*84baed2aSYork Sun 		trrt_mclk = 0;
355*84baed2aSYork Sun 		break;
356*84baed2aSYork Sun 	default:
357*84baed2aSYork Sun 		break;
3585614e71bSYork Sun 	}
359*84baed2aSYork Sun 
3605614e71bSYork Sun 	/* for faster clock, need more time for data setup */
3615614e71bSYork Sun 	trwt_mclk = (data_rate/1000000 > 1800) ? 2 : 1;
3625614e71bSYork Sun 
3635614e71bSYork Sun 	if ((data_rate/1000000 > 1150) || (popts->memctl_interleaving))
3645614e71bSYork Sun 		twrt_mclk = 1;
3655614e71bSYork Sun 
3665614e71bSYork Sun 	if (popts->dynamic_power == 0) {	/* powerdown is not used */
3675614e71bSYork Sun 		act_pd_exit_mclk = 1;
3685614e71bSYork Sun 		pre_pd_exit_mclk = 1;
3695614e71bSYork Sun 		taxpd_mclk = 1;
3705614e71bSYork Sun 	} else {
3715614e71bSYork Sun 		/* act_pd_exit_mclk = tXARD, see above */
37234e026f9SYork Sun 		act_pd_exit_mclk = picos_to_mclk(txp);
3735614e71bSYork Sun 		/* Mode register MR0[A12] is '1' - fast exit */
3745614e71bSYork Sun 		pre_pd_exit_mclk = act_pd_exit_mclk;
3755614e71bSYork Sun 		taxpd_mclk = 1;
3765614e71bSYork Sun 	}
3775614e71bSYork Sun #else /* CONFIG_SYS_FSL_DDR2 */
3785614e71bSYork Sun 	/*
3795614e71bSYork Sun 	 * (tXARD and tXARDS). Empirical?
3805614e71bSYork Sun 	 * tXARD = 2 for DDR2
3815614e71bSYork Sun 	 * tXP=2
3825614e71bSYork Sun 	 * tAXPD=8
3835614e71bSYork Sun 	 */
3845614e71bSYork Sun 	act_pd_exit_mclk = 2;
3855614e71bSYork Sun 	pre_pd_exit_mclk = 2;
3865614e71bSYork Sun 	taxpd_mclk = 8;
3875614e71bSYork Sun 	tmrd_mclk = 2;
3885614e71bSYork Sun #endif
3895614e71bSYork Sun 
3905614e71bSYork Sun 	if (popts->trwt_override)
3915614e71bSYork Sun 		trwt_mclk = popts->trwt;
3925614e71bSYork Sun 
3935614e71bSYork Sun 	ddr->timing_cfg_0 = (0
3945614e71bSYork Sun 		| ((trwt_mclk & 0x3) << 30)	/* RWT */
3955614e71bSYork Sun 		| ((twrt_mclk & 0x3) << 28)	/* WRT */
3965614e71bSYork Sun 		| ((trrt_mclk & 0x3) << 26)	/* RRT */
3975614e71bSYork Sun 		| ((twwt_mclk & 0x3) << 24)	/* WWT */
398d4263b8aSYork Sun 		| ((act_pd_exit_mclk & 0xf) << 20)  /* ACT_PD_EXIT */
3995614e71bSYork Sun 		| ((pre_pd_exit_mclk & 0xF) << 16)  /* PRE_PD_EXIT */
4005614e71bSYork Sun 		| ((taxpd_mclk & 0xf) << 8)	/* ODT_PD_EXIT */
401d4263b8aSYork Sun 		| ((tmrd_mclk & 0x1f) << 0)	/* MRS_CYC */
4025614e71bSYork Sun 		);
4035614e71bSYork Sun 	debug("FSLDDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
4045614e71bSYork Sun }
405*84baed2aSYork Sun #endif	/* !defined(CONFIG_SYS_FSL_DDR1) */
4065614e71bSYork Sun 
4075614e71bSYork Sun /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */
4085614e71bSYork Sun static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
4095614e71bSYork Sun 			       const memctl_options_t *popts,
4105614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
411d4263b8aSYork Sun 			       unsigned int cas_latency,
412d4263b8aSYork Sun 			       unsigned int additive_latency)
4135614e71bSYork Sun {
4145614e71bSYork Sun 	/* Extended precharge to activate interval (tRP) */
4155614e71bSYork Sun 	unsigned int ext_pretoact = 0;
4165614e71bSYork Sun 	/* Extended Activate to precharge interval (tRAS) */
4175614e71bSYork Sun 	unsigned int ext_acttopre = 0;
4185614e71bSYork Sun 	/* Extended activate to read/write interval (tRCD) */
4195614e71bSYork Sun 	unsigned int ext_acttorw = 0;
4205614e71bSYork Sun 	/* Extended refresh recovery time (tRFC) */
4215614e71bSYork Sun 	unsigned int ext_refrec;
4225614e71bSYork Sun 	/* Extended MCAS latency from READ cmd */
4235614e71bSYork Sun 	unsigned int ext_caslat = 0;
424d4263b8aSYork Sun 	/* Extended additive latency */
425d4263b8aSYork Sun 	unsigned int ext_add_lat = 0;
4265614e71bSYork Sun 	/* Extended last data to precharge interval (tWR) */
4275614e71bSYork Sun 	unsigned int ext_wrrec = 0;
4285614e71bSYork Sun 	/* Control Adjust */
4295614e71bSYork Sun 	unsigned int cntl_adj = 0;
4305614e71bSYork Sun 
4315614e71bSYork Sun 	ext_pretoact = picos_to_mclk(common_dimm->trp_ps) >> 4;
4325614e71bSYork Sun 	ext_acttopre = picos_to_mclk(common_dimm->tras_ps) >> 4;
4335614e71bSYork Sun 	ext_acttorw = picos_to_mclk(common_dimm->trcd_ps) >> 4;
4345614e71bSYork Sun 	ext_caslat = (2 * cas_latency - 1) >> 4;
435d4263b8aSYork Sun 	ext_add_lat = additive_latency >> 4;
43634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
43734e026f9SYork Sun 	ext_refrec = (picos_to_mclk(common_dimm->trfc1_ps) - 8) >> 4;
43834e026f9SYork Sun #else
4395614e71bSYork Sun 	ext_refrec = (picos_to_mclk(common_dimm->trfc_ps) - 8) >> 4;
4405614e71bSYork Sun 	/* ext_wrrec only deals with 16 clock and above, or 14 with OTF */
44134e026f9SYork Sun #endif
4425614e71bSYork Sun 	ext_wrrec = (picos_to_mclk(common_dimm->twr_ps) +
4435614e71bSYork Sun 		(popts->otf_burst_chop_en ? 2 : 0)) >> 4;
4445614e71bSYork Sun 
4455614e71bSYork Sun 	ddr->timing_cfg_3 = (0
4465614e71bSYork Sun 		| ((ext_pretoact & 0x1) << 28)
4475614e71bSYork Sun 		| ((ext_acttopre & 0x3) << 24)
4485614e71bSYork Sun 		| ((ext_acttorw & 0x1) << 22)
4495614e71bSYork Sun 		| ((ext_refrec & 0x1F) << 16)
4505614e71bSYork Sun 		| ((ext_caslat & 0x3) << 12)
451d4263b8aSYork Sun 		| ((ext_add_lat & 0x1) << 10)
4525614e71bSYork Sun 		| ((ext_wrrec & 0x1) << 8)
4535614e71bSYork Sun 		| ((cntl_adj & 0x7) << 0)
4545614e71bSYork Sun 		);
4555614e71bSYork Sun 	debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3);
4565614e71bSYork Sun }
4575614e71bSYork Sun 
4585614e71bSYork Sun /* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */
4595614e71bSYork Sun static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
4605614e71bSYork Sun 			       const memctl_options_t *popts,
4615614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
4625614e71bSYork Sun 			       unsigned int cas_latency)
4635614e71bSYork Sun {
4645614e71bSYork Sun 	/* Precharge-to-activate interval (tRP) */
4655614e71bSYork Sun 	unsigned char pretoact_mclk;
4665614e71bSYork Sun 	/* Activate to precharge interval (tRAS) */
4675614e71bSYork Sun 	unsigned char acttopre_mclk;
4685614e71bSYork Sun 	/*  Activate to read/write interval (tRCD) */
4695614e71bSYork Sun 	unsigned char acttorw_mclk;
4705614e71bSYork Sun 	/* CASLAT */
4715614e71bSYork Sun 	unsigned char caslat_ctrl;
4725614e71bSYork Sun 	/*  Refresh recovery time (tRFC) ; trfc_low */
4735614e71bSYork Sun 	unsigned char refrec_ctrl;
4745614e71bSYork Sun 	/* Last data to precharge minimum interval (tWR) */
4755614e71bSYork Sun 	unsigned char wrrec_mclk;
4765614e71bSYork Sun 	/* Activate-to-activate interval (tRRD) */
4775614e71bSYork Sun 	unsigned char acttoact_mclk;
4785614e71bSYork Sun 	/* Last write data pair to read command issue interval (tWTR) */
4795614e71bSYork Sun 	unsigned char wrtord_mclk;
48034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
48134e026f9SYork Sun 	/* DDR4 supports 10, 12, 14, 16, 18, 20, 24 */
48234e026f9SYork Sun 	static const u8 wrrec_table[] = {
48334e026f9SYork Sun 		10, 10, 10, 10, 10,
48434e026f9SYork Sun 		10, 10, 10, 10, 10,
48534e026f9SYork Sun 		12, 12, 14, 14, 16,
48634e026f9SYork Sun 		16, 18, 18, 20, 20,
48734e026f9SYork Sun 		24, 24, 24, 24};
48834e026f9SYork Sun #else
4895614e71bSYork Sun 	/* DDR_SDRAM_MODE doesn't support 9,11,13,15 */
4905614e71bSYork Sun 	static const u8 wrrec_table[] = {
4915614e71bSYork Sun 		1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0};
49234e026f9SYork Sun #endif
4935614e71bSYork Sun 
4945614e71bSYork Sun 	pretoact_mclk = picos_to_mclk(common_dimm->trp_ps);
4955614e71bSYork Sun 	acttopre_mclk = picos_to_mclk(common_dimm->tras_ps);
4965614e71bSYork Sun 	acttorw_mclk = picos_to_mclk(common_dimm->trcd_ps);
4975614e71bSYork Sun 
4985614e71bSYork Sun 	/*
4995614e71bSYork Sun 	 * Translate CAS Latency to a DDR controller field value:
5005614e71bSYork Sun 	 *
5015614e71bSYork Sun 	 *      CAS Lat DDR I   DDR II  Ctrl
5025614e71bSYork Sun 	 *      Clocks  SPD Bit SPD Bit Value
5035614e71bSYork Sun 	 *      ------- ------- ------- -----
5045614e71bSYork Sun 	 *      1.0     0               0001
5055614e71bSYork Sun 	 *      1.5     1               0010
5065614e71bSYork Sun 	 *      2.0     2       2       0011
5075614e71bSYork Sun 	 *      2.5     3               0100
5085614e71bSYork Sun 	 *      3.0     4       3       0101
5095614e71bSYork Sun 	 *      3.5     5               0110
5105614e71bSYork Sun 	 *      4.0             4       0111
5115614e71bSYork Sun 	 *      4.5                     1000
5125614e71bSYork Sun 	 *      5.0             5       1001
5135614e71bSYork Sun 	 */
5145614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
5155614e71bSYork Sun 	caslat_ctrl = (cas_latency + 1) & 0x07;
5165614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
5175614e71bSYork Sun 	caslat_ctrl = 2 * cas_latency - 1;
5185614e71bSYork Sun #else
5195614e71bSYork Sun 	/*
5205614e71bSYork Sun 	 * if the CAS latency more than 8 cycle,
5215614e71bSYork Sun 	 * we need set extend bit for it at
5225614e71bSYork Sun 	 * TIMING_CFG_3[EXT_CASLAT]
5235614e71bSYork Sun 	 */
52434e026f9SYork Sun 	if (fsl_ddr_get_version() <= 0x40400)
5255614e71bSYork Sun 		caslat_ctrl = 2 * cas_latency - 1;
52634e026f9SYork Sun 	else
52734e026f9SYork Sun 		caslat_ctrl = (cas_latency - 1) << 1;
5285614e71bSYork Sun #endif
5295614e71bSYork Sun 
53034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
53134e026f9SYork Sun 	refrec_ctrl = picos_to_mclk(common_dimm->trfc1_ps) - 8;
53234e026f9SYork Sun 	wrrec_mclk = picos_to_mclk(common_dimm->twr_ps);
533b4141195SMasahiro Yamada 	acttoact_mclk = max(picos_to_mclk(common_dimm->trrds_ps), 4U);
534b4141195SMasahiro Yamada 	wrtord_mclk = max(2U, picos_to_mclk(2500));
535349689b8SYork Sun 	if ((wrrec_mclk < 1) || (wrrec_mclk > 24))
536349689b8SYork Sun 		printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
53734e026f9SYork Sun 	else
53834e026f9SYork Sun 		wrrec_mclk = wrrec_table[wrrec_mclk - 1];
53934e026f9SYork Sun #else
5405614e71bSYork Sun 	refrec_ctrl = picos_to_mclk(common_dimm->trfc_ps) - 8;
5415614e71bSYork Sun 	wrrec_mclk = picos_to_mclk(common_dimm->twr_ps);
54234e026f9SYork Sun 	acttoact_mclk = picos_to_mclk(common_dimm->trrd_ps);
54334e026f9SYork Sun 	wrtord_mclk = picos_to_mclk(common_dimm->twtr_ps);
544349689b8SYork Sun 	if ((wrrec_mclk < 1) || (wrrec_mclk > 16))
545349689b8SYork Sun 		printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
5465614e71bSYork Sun 	else
5475614e71bSYork Sun 		wrrec_mclk = wrrec_table[wrrec_mclk - 1];
54834e026f9SYork Sun #endif
5495614e71bSYork Sun 	if (popts->otf_burst_chop_en)
5505614e71bSYork Sun 		wrrec_mclk += 2;
5515614e71bSYork Sun 
5525614e71bSYork Sun 	/*
5535614e71bSYork Sun 	 * JEDEC has min requirement for tRRD
5545614e71bSYork Sun 	 */
5555614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR3)
5565614e71bSYork Sun 	if (acttoact_mclk < 4)
5575614e71bSYork Sun 		acttoact_mclk = 4;
5585614e71bSYork Sun #endif
5595614e71bSYork Sun 	/*
5605614e71bSYork Sun 	 * JEDEC has some min requirements for tWTR
5615614e71bSYork Sun 	 */
5625614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2)
5635614e71bSYork Sun 	if (wrtord_mclk < 2)
5645614e71bSYork Sun 		wrtord_mclk = 2;
5655614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
5665614e71bSYork Sun 	if (wrtord_mclk < 4)
5675614e71bSYork Sun 		wrtord_mclk = 4;
5685614e71bSYork Sun #endif
5695614e71bSYork Sun 	if (popts->otf_burst_chop_en)
5705614e71bSYork Sun 		wrtord_mclk += 2;
5715614e71bSYork Sun 
5725614e71bSYork Sun 	ddr->timing_cfg_1 = (0
5735614e71bSYork Sun 		| ((pretoact_mclk & 0x0F) << 28)
5745614e71bSYork Sun 		| ((acttopre_mclk & 0x0F) << 24)
5755614e71bSYork Sun 		| ((acttorw_mclk & 0xF) << 20)
5765614e71bSYork Sun 		| ((caslat_ctrl & 0xF) << 16)
5775614e71bSYork Sun 		| ((refrec_ctrl & 0xF) << 12)
5785614e71bSYork Sun 		| ((wrrec_mclk & 0x0F) << 8)
5795614e71bSYork Sun 		| ((acttoact_mclk & 0x0F) << 4)
5805614e71bSYork Sun 		| ((wrtord_mclk & 0x0F) << 0)
5815614e71bSYork Sun 		);
5825614e71bSYork Sun 	debug("FSLDDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1);
5835614e71bSYork Sun }
5845614e71bSYork Sun 
5855614e71bSYork Sun /* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */
5865614e71bSYork Sun static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
5875614e71bSYork Sun 			       const memctl_options_t *popts,
5885614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
5895614e71bSYork Sun 			       unsigned int cas_latency,
5905614e71bSYork Sun 			       unsigned int additive_latency)
5915614e71bSYork Sun {
5925614e71bSYork Sun 	/* Additive latency */
5935614e71bSYork Sun 	unsigned char add_lat_mclk;
5945614e71bSYork Sun 	/* CAS-to-preamble override */
5955614e71bSYork Sun 	unsigned short cpo;
5965614e71bSYork Sun 	/* Write latency */
5975614e71bSYork Sun 	unsigned char wr_lat;
5985614e71bSYork Sun 	/*  Read to precharge (tRTP) */
5995614e71bSYork Sun 	unsigned char rd_to_pre;
6005614e71bSYork Sun 	/* Write command to write data strobe timing adjustment */
6015614e71bSYork Sun 	unsigned char wr_data_delay;
6025614e71bSYork Sun 	/* Minimum CKE pulse width (tCKE) */
6035614e71bSYork Sun 	unsigned char cke_pls;
6045614e71bSYork Sun 	/* Window for four activates (tFAW) */
6055614e71bSYork Sun 	unsigned short four_act;
606bb578322SYork Sun #ifdef CONFIG_SYS_FSL_DDR3
607bb578322SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps();
608bb578322SYork Sun #endif
6095614e71bSYork Sun 
6105614e71bSYork Sun 	/* FIXME add check that this must be less than acttorw_mclk */
6115614e71bSYork Sun 	add_lat_mclk = additive_latency;
6125614e71bSYork Sun 	cpo = popts->cpo_override;
6135614e71bSYork Sun 
6145614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
6155614e71bSYork Sun 	/*
6165614e71bSYork Sun 	 * This is a lie.  It should really be 1, but if it is
6175614e71bSYork Sun 	 * set to 1, bits overlap into the old controller's
6185614e71bSYork Sun 	 * otherwise unused ACSM field.  If we leave it 0, then
6195614e71bSYork Sun 	 * the HW will magically treat it as 1 for DDR 1.  Oh Yea.
6205614e71bSYork Sun 	 */
6215614e71bSYork Sun 	wr_lat = 0;
6225614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
6235614e71bSYork Sun 	wr_lat = cas_latency - 1;
6245614e71bSYork Sun #else
6255614e71bSYork Sun 	wr_lat = compute_cas_write_latency();
6265614e71bSYork Sun #endif
6275614e71bSYork Sun 
62834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
62934e026f9SYork Sun 	rd_to_pre = picos_to_mclk(7500);
63034e026f9SYork Sun #else
6315614e71bSYork Sun 	rd_to_pre = picos_to_mclk(common_dimm->trtp_ps);
63234e026f9SYork Sun #endif
6335614e71bSYork Sun 	/*
6345614e71bSYork Sun 	 * JEDEC has some min requirements for tRTP
6355614e71bSYork Sun 	 */
6365614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2)
6375614e71bSYork Sun 	if (rd_to_pre  < 2)
6385614e71bSYork Sun 		rd_to_pre  = 2;
63934e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
6405614e71bSYork Sun 	if (rd_to_pre < 4)
6415614e71bSYork Sun 		rd_to_pre = 4;
6425614e71bSYork Sun #endif
6435614e71bSYork Sun 	if (popts->otf_burst_chop_en)
6445614e71bSYork Sun 		rd_to_pre += 2; /* according to UM */
6455614e71bSYork Sun 
6465614e71bSYork Sun 	wr_data_delay = popts->write_data_delay;
64734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
64834e026f9SYork Sun 	cpo = 0;
649b4141195SMasahiro Yamada 	cke_pls = max(3U, picos_to_mclk(5000));
650bb578322SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
651bb578322SYork Sun 	/*
652bb578322SYork Sun 	 * cke pulse = max(3nCK, 7.5ns) for DDR3-800
653bb578322SYork Sun 	 *             max(3nCK, 5.625ns) for DDR3-1066, 1333
654bb578322SYork Sun 	 *             max(3nCK, 5ns) for DDR3-1600, 1866, 2133
655bb578322SYork Sun 	 */
656b4141195SMasahiro Yamada 	cke_pls = max(3U, picos_to_mclk(mclk_ps > 1870 ? 7500 :
657bb578322SYork Sun 				       (mclk_ps > 1245 ? 5625 : 5000)));
65834e026f9SYork Sun #else
659bb578322SYork Sun 	cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR;
66034e026f9SYork Sun #endif
6615614e71bSYork Sun 	four_act = picos_to_mclk(popts->tfaw_window_four_activates_ps);
6625614e71bSYork Sun 
6635614e71bSYork Sun 	ddr->timing_cfg_2 = (0
6645614e71bSYork Sun 		| ((add_lat_mclk & 0xf) << 28)
6655614e71bSYork Sun 		| ((cpo & 0x1f) << 23)
6665614e71bSYork Sun 		| ((wr_lat & 0xf) << 19)
66734e026f9SYork Sun 		| ((wr_lat & 0x10) << 14)
6685614e71bSYork Sun 		| ((rd_to_pre & RD_TO_PRE_MASK) << RD_TO_PRE_SHIFT)
6695614e71bSYork Sun 		| ((wr_data_delay & WR_DATA_DELAY_MASK) << WR_DATA_DELAY_SHIFT)
6705614e71bSYork Sun 		| ((cke_pls & 0x7) << 6)
6715614e71bSYork Sun 		| ((four_act & 0x3f) << 0)
6725614e71bSYork Sun 		);
6735614e71bSYork Sun 	debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2);
6745614e71bSYork Sun }
6755614e71bSYork Sun 
6765614e71bSYork Sun /* DDR SDRAM Register Control Word */
6775614e71bSYork Sun static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr,
6785614e71bSYork Sun 			       const memctl_options_t *popts,
6795614e71bSYork Sun 			       const common_timing_params_t *common_dimm)
6805614e71bSYork Sun {
6815614e71bSYork Sun 	if (common_dimm->all_dimms_registered &&
6825614e71bSYork Sun 	    !common_dimm->all_dimms_unbuffered)	{
6835614e71bSYork Sun 		if (popts->rcw_override) {
6845614e71bSYork Sun 			ddr->ddr_sdram_rcw_1 = popts->rcw_1;
6855614e71bSYork Sun 			ddr->ddr_sdram_rcw_2 = popts->rcw_2;
6865614e71bSYork Sun 		} else {
6875614e71bSYork Sun 			ddr->ddr_sdram_rcw_1 =
6885614e71bSYork Sun 				common_dimm->rcw[0] << 28 | \
6895614e71bSYork Sun 				common_dimm->rcw[1] << 24 | \
6905614e71bSYork Sun 				common_dimm->rcw[2] << 20 | \
6915614e71bSYork Sun 				common_dimm->rcw[3] << 16 | \
6925614e71bSYork Sun 				common_dimm->rcw[4] << 12 | \
6935614e71bSYork Sun 				common_dimm->rcw[5] << 8 | \
6945614e71bSYork Sun 				common_dimm->rcw[6] << 4 | \
6955614e71bSYork Sun 				common_dimm->rcw[7];
6965614e71bSYork Sun 			ddr->ddr_sdram_rcw_2 =
6975614e71bSYork Sun 				common_dimm->rcw[8] << 28 | \
6985614e71bSYork Sun 				common_dimm->rcw[9] << 24 | \
6995614e71bSYork Sun 				common_dimm->rcw[10] << 20 | \
7005614e71bSYork Sun 				common_dimm->rcw[11] << 16 | \
7015614e71bSYork Sun 				common_dimm->rcw[12] << 12 | \
7025614e71bSYork Sun 				common_dimm->rcw[13] << 8 | \
7035614e71bSYork Sun 				common_dimm->rcw[14] << 4 | \
7045614e71bSYork Sun 				common_dimm->rcw[15];
7055614e71bSYork Sun 		}
7065614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1);
7075614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2);
7085614e71bSYork Sun 	}
7095614e71bSYork Sun }
7105614e71bSYork Sun 
7115614e71bSYork Sun /* DDR SDRAM control configuration (DDR_SDRAM_CFG) */
7125614e71bSYork Sun static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
7135614e71bSYork Sun 			       const memctl_options_t *popts,
7145614e71bSYork Sun 			       const common_timing_params_t *common_dimm)
7155614e71bSYork Sun {
7165614e71bSYork Sun 	unsigned int mem_en;		/* DDR SDRAM interface logic enable */
7175614e71bSYork Sun 	unsigned int sren;		/* Self refresh enable (during sleep) */
7185614e71bSYork Sun 	unsigned int ecc_en;		/* ECC enable. */
7195614e71bSYork Sun 	unsigned int rd_en;		/* Registered DIMM enable */
7205614e71bSYork Sun 	unsigned int sdram_type;	/* Type of SDRAM */
7215614e71bSYork Sun 	unsigned int dyn_pwr;		/* Dynamic power management mode */
7225614e71bSYork Sun 	unsigned int dbw;		/* DRAM dta bus width */
7235614e71bSYork Sun 	unsigned int eight_be = 0;	/* 8-beat burst enable, DDR2 is zero */
7245614e71bSYork Sun 	unsigned int ncap = 0;		/* Non-concurrent auto-precharge */
7255614e71bSYork Sun 	unsigned int threet_en;		/* Enable 3T timing */
7265614e71bSYork Sun 	unsigned int twot_en;		/* Enable 2T timing */
7275614e71bSYork Sun 	unsigned int ba_intlv_ctl;	/* Bank (CS) interleaving control */
7285614e71bSYork Sun 	unsigned int x32_en = 0;	/* x32 enable */
7295614e71bSYork Sun 	unsigned int pchb8 = 0;		/* precharge bit 8 enable */
7305614e71bSYork Sun 	unsigned int hse;		/* Global half strength override */
731d28cb671SYork Sun 	unsigned int acc_ecc_en = 0;	/* Accumulated ECC enable */
7325614e71bSYork Sun 	unsigned int mem_halt = 0;	/* memory controller halt */
7335614e71bSYork Sun 	unsigned int bi = 0;		/* Bypass initialization */
7345614e71bSYork Sun 
7355614e71bSYork Sun 	mem_en = 1;
7365614e71bSYork Sun 	sren = popts->self_refresh_in_sleep;
7375614e71bSYork Sun 	if (common_dimm->all_dimms_ecc_capable) {
7385614e71bSYork Sun 		/* Allow setting of ECC only if all DIMMs are ECC. */
7395614e71bSYork Sun 		ecc_en = popts->ecc_mode;
7405614e71bSYork Sun 	} else {
7415614e71bSYork Sun 		ecc_en = 0;
7425614e71bSYork Sun 	}
7435614e71bSYork Sun 
7445614e71bSYork Sun 	if (common_dimm->all_dimms_registered &&
7455614e71bSYork Sun 	    !common_dimm->all_dimms_unbuffered)	{
7465614e71bSYork Sun 		rd_en = 1;
7475614e71bSYork Sun 		twot_en = 0;
7485614e71bSYork Sun 	} else {
7495614e71bSYork Sun 		rd_en = 0;
7505614e71bSYork Sun 		twot_en = popts->twot_en;
7515614e71bSYork Sun 	}
7525614e71bSYork Sun 
7535614e71bSYork Sun 	sdram_type = CONFIG_FSL_SDRAM_TYPE;
7545614e71bSYork Sun 
7555614e71bSYork Sun 	dyn_pwr = popts->dynamic_power;
7565614e71bSYork Sun 	dbw = popts->data_bus_width;
7575614e71bSYork Sun 	/* 8-beat burst enable DDR-III case
7585614e71bSYork Sun 	 * we must clear it when use the on-the-fly mode,
7595614e71bSYork Sun 	 * must set it when use the 32-bits bus mode.
7605614e71bSYork Sun 	 */
76134e026f9SYork Sun 	if ((sdram_type == SDRAM_TYPE_DDR3) ||
76234e026f9SYork Sun 	    (sdram_type == SDRAM_TYPE_DDR4)) {
7635614e71bSYork Sun 		if (popts->burst_length == DDR_BL8)
7645614e71bSYork Sun 			eight_be = 1;
7655614e71bSYork Sun 		if (popts->burst_length == DDR_OTF)
7665614e71bSYork Sun 			eight_be = 0;
7675614e71bSYork Sun 		if (dbw == 0x1)
7685614e71bSYork Sun 			eight_be = 1;
7695614e71bSYork Sun 	}
7705614e71bSYork Sun 
7715614e71bSYork Sun 	threet_en = popts->threet_en;
7725614e71bSYork Sun 	ba_intlv_ctl = popts->ba_intlv_ctl;
7735614e71bSYork Sun 	hse = popts->half_strength_driver_enable;
7745614e71bSYork Sun 
775d28cb671SYork Sun 	/* set when ddr bus width < 64 */
776d28cb671SYork Sun 	acc_ecc_en = (dbw != 0 && ecc_en == 1) ? 1 : 0;
777d28cb671SYork Sun 
7785614e71bSYork Sun 	ddr->ddr_sdram_cfg = (0
7795614e71bSYork Sun 			| ((mem_en & 0x1) << 31)
7805614e71bSYork Sun 			| ((sren & 0x1) << 30)
7815614e71bSYork Sun 			| ((ecc_en & 0x1) << 29)
7825614e71bSYork Sun 			| ((rd_en & 0x1) << 28)
7835614e71bSYork Sun 			| ((sdram_type & 0x7) << 24)
7845614e71bSYork Sun 			| ((dyn_pwr & 0x1) << 21)
7855614e71bSYork Sun 			| ((dbw & 0x3) << 19)
7865614e71bSYork Sun 			| ((eight_be & 0x1) << 18)
7875614e71bSYork Sun 			| ((ncap & 0x1) << 17)
7885614e71bSYork Sun 			| ((threet_en & 0x1) << 16)
7895614e71bSYork Sun 			| ((twot_en & 0x1) << 15)
7905614e71bSYork Sun 			| ((ba_intlv_ctl & 0x7F) << 8)
7915614e71bSYork Sun 			| ((x32_en & 0x1) << 5)
7925614e71bSYork Sun 			| ((pchb8 & 0x1) << 4)
7935614e71bSYork Sun 			| ((hse & 0x1) << 3)
794d28cb671SYork Sun 			| ((acc_ecc_en & 0x1) << 2)
7955614e71bSYork Sun 			| ((mem_halt & 0x1) << 1)
7965614e71bSYork Sun 			| ((bi & 0x1) << 0)
7975614e71bSYork Sun 			);
7985614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_cfg = 0x%08x\n", ddr->ddr_sdram_cfg);
7995614e71bSYork Sun }
8005614e71bSYork Sun 
8015614e71bSYork Sun /* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */
8025614e71bSYork Sun static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
8035614e71bSYork Sun 			       const memctl_options_t *popts,
8045614e71bSYork Sun 			       const unsigned int unq_mrs_en)
8055614e71bSYork Sun {
8065614e71bSYork Sun 	unsigned int frc_sr = 0;	/* Force self refresh */
8075614e71bSYork Sun 	unsigned int sr_ie = 0;		/* Self-refresh interrupt enable */
8085614e71bSYork Sun 	unsigned int odt_cfg = 0;	/* ODT configuration */
8095614e71bSYork Sun 	unsigned int num_pr;		/* Number of posted refreshes */
8105614e71bSYork Sun 	unsigned int slow = 0;		/* DDR will be run less than 1250 */
8115614e71bSYork Sun 	unsigned int x4_en = 0;		/* x4 DRAM enable */
8125614e71bSYork Sun 	unsigned int obc_cfg;		/* On-The-Fly Burst Chop Cfg */
8135614e71bSYork Sun 	unsigned int ap_en;		/* Address Parity Enable */
8145614e71bSYork Sun 	unsigned int d_init;		/* DRAM data initialization */
8155614e71bSYork Sun 	unsigned int rcw_en = 0;	/* Register Control Word Enable */
8165614e71bSYork Sun 	unsigned int md_en = 0;		/* Mirrored DIMM Enable */
8175614e71bSYork Sun 	unsigned int qd_en = 0;		/* quad-rank DIMM Enable */
8185614e71bSYork Sun 	int i;
81934e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4
82034e026f9SYork Sun 	unsigned int dll_rst_dis = 1;	/* DLL reset disable */
82134e026f9SYork Sun 	unsigned int dqs_cfg;		/* DQS configuration */
8225614e71bSYork Sun 
8235614e71bSYork Sun 	dqs_cfg = popts->dqs_config;
82434e026f9SYork Sun #endif
8255614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
8265614e71bSYork Sun 		if (popts->cs_local_opts[i].odt_rd_cfg
8275614e71bSYork Sun 			|| popts->cs_local_opts[i].odt_wr_cfg) {
8285614e71bSYork Sun 			odt_cfg = SDRAM_CFG2_ODT_ONLY_READ;
8295614e71bSYork Sun 			break;
8305614e71bSYork Sun 		}
8315614e71bSYork Sun 	}
8325614e71bSYork Sun 
8335614e71bSYork Sun 	num_pr = 1;	/* Make this configurable */
8345614e71bSYork Sun 
8355614e71bSYork Sun 	/*
8365614e71bSYork Sun 	 * 8572 manual says
8375614e71bSYork Sun 	 *     {TIMING_CFG_1[PRETOACT]
8385614e71bSYork Sun 	 *      + [DDR_SDRAM_CFG_2[NUM_PR]
8395614e71bSYork Sun 	 *        * ({EXT_REFREC || REFREC} + 8 + 2)]}
8405614e71bSYork Sun 	 *      << DDR_SDRAM_INTERVAL[REFINT]
8415614e71bSYork Sun 	 */
84234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
8435614e71bSYork Sun 	obc_cfg = popts->otf_burst_chop_en;
8445614e71bSYork Sun #else
8455614e71bSYork Sun 	obc_cfg = 0;
8465614e71bSYork Sun #endif
8475614e71bSYork Sun 
8485614e71bSYork Sun #if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)
8495614e71bSYork Sun 	slow = get_ddr_freq(0) < 1249000000;
8505614e71bSYork Sun #endif
8515614e71bSYork Sun 
8525614e71bSYork Sun 	if (popts->registered_dimm_en) {
8535614e71bSYork Sun 		rcw_en = 1;
8545614e71bSYork Sun 		ap_en = popts->ap_en;
8555614e71bSYork Sun 	} else {
8565614e71bSYork Sun 		ap_en = 0;
8575614e71bSYork Sun 	}
8585614e71bSYork Sun 
8595614e71bSYork Sun 	x4_en = popts->x4_en ? 1 : 0;
8605614e71bSYork Sun 
8615614e71bSYork Sun #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
8625614e71bSYork Sun 	/* Use the DDR controller to auto initialize memory. */
8635614e71bSYork Sun 	d_init = popts->ecc_init_using_memctl;
8645614e71bSYork Sun 	ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE;
8655614e71bSYork Sun 	debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init);
8665614e71bSYork Sun #else
8675614e71bSYork Sun 	/* Memory will be initialized via DMA, or not at all. */
8685614e71bSYork Sun 	d_init = 0;
8695614e71bSYork Sun #endif
8705614e71bSYork Sun 
87134e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
8725614e71bSYork Sun 	md_en = popts->mirrored_dimm;
8735614e71bSYork Sun #endif
8745614e71bSYork Sun 	qd_en = popts->quad_rank_present ? 1 : 0;
8755614e71bSYork Sun 	ddr->ddr_sdram_cfg_2 = (0
8765614e71bSYork Sun 		| ((frc_sr & 0x1) << 31)
8775614e71bSYork Sun 		| ((sr_ie & 0x1) << 30)
87834e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4
8795614e71bSYork Sun 		| ((dll_rst_dis & 0x1) << 29)
8805614e71bSYork Sun 		| ((dqs_cfg & 0x3) << 26)
88134e026f9SYork Sun #endif
8825614e71bSYork Sun 		| ((odt_cfg & 0x3) << 21)
8835614e71bSYork Sun 		| ((num_pr & 0xf) << 12)
8845614e71bSYork Sun 		| ((slow & 1) << 11)
8855614e71bSYork Sun 		| (x4_en << 10)
8865614e71bSYork Sun 		| (qd_en << 9)
8875614e71bSYork Sun 		| (unq_mrs_en << 8)
8885614e71bSYork Sun 		| ((obc_cfg & 0x1) << 6)
8895614e71bSYork Sun 		| ((ap_en & 0x1) << 5)
8905614e71bSYork Sun 		| ((d_init & 0x1) << 4)
8915614e71bSYork Sun 		| ((rcw_en & 0x1) << 2)
8925614e71bSYork Sun 		| ((md_en & 0x1) << 0)
8935614e71bSYork Sun 		);
8945614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_cfg_2 = 0x%08x\n", ddr->ddr_sdram_cfg_2);
8955614e71bSYork Sun }
8965614e71bSYork Sun 
89734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
8985614e71bSYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
8995614e71bSYork Sun static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
9005614e71bSYork Sun 				const memctl_options_t *popts,
9015614e71bSYork Sun 				const common_timing_params_t *common_dimm,
9025614e71bSYork Sun 				const unsigned int unq_mrs_en)
9035614e71bSYork Sun {
9045614e71bSYork Sun 	unsigned short esdmode2 = 0;	/* Extended SDRAM mode 2 */
9055614e71bSYork Sun 	unsigned short esdmode3 = 0;	/* Extended SDRAM mode 3 */
9065614e71bSYork Sun 	int i;
90734e026f9SYork Sun 	unsigned int wr_crc = 0;	/* Disable */
9085614e71bSYork Sun 	unsigned int rtt_wr = 0;	/* Rtt_WR - dynamic ODT off */
9095614e71bSYork Sun 	unsigned int srt = 0;	/* self-refresh temerature, normal range */
91034e026f9SYork Sun 	unsigned int cwl = compute_cas_write_latency() - 9;
91134e026f9SYork Sun 	unsigned int mpr = 0;	/* serial */
91234e026f9SYork Sun 	unsigned int wc_lat;
91334e026f9SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps();
9145614e71bSYork Sun 
9155614e71bSYork Sun 	if (popts->rtt_override)
9165614e71bSYork Sun 		rtt_wr = popts->rtt_wr_override_value;
9175614e71bSYork Sun 	else
9185614e71bSYork Sun 		rtt_wr = popts->cs_local_opts[0].odt_rtt_wr;
9195614e71bSYork Sun 
9205614e71bSYork Sun 	if (common_dimm->extended_op_srt)
9215614e71bSYork Sun 		srt = common_dimm->extended_op_srt;
9225614e71bSYork Sun 
9235614e71bSYork Sun 	esdmode2 = (0
92434e026f9SYork Sun 		| ((wr_crc & 0x1) << 12)
9255614e71bSYork Sun 		| ((rtt_wr & 0x3) << 9)
92634e026f9SYork Sun 		| ((srt & 0x3) << 6)
92734e026f9SYork Sun 		| ((cwl & 0x7) << 3));
92834e026f9SYork Sun 
92934e026f9SYork Sun 	if (mclk_ps >= 1250)
93034e026f9SYork Sun 		wc_lat = 0;
93134e026f9SYork Sun 	else if (mclk_ps >= 833)
93234e026f9SYork Sun 		wc_lat = 1;
93334e026f9SYork Sun 	else
93434e026f9SYork Sun 		wc_lat = 2;
93534e026f9SYork Sun 
93634e026f9SYork Sun 	esdmode3 = (0
93734e026f9SYork Sun 		| ((mpr & 0x3) << 11)
93834e026f9SYork Sun 		| ((wc_lat & 0x3) << 9));
93934e026f9SYork Sun 
9405614e71bSYork Sun 	ddr->ddr_sdram_mode_2 = (0
9415614e71bSYork Sun 				 | ((esdmode2 & 0xFFFF) << 16)
9425614e71bSYork Sun 				 | ((esdmode3 & 0xFFFF) << 0)
9435614e71bSYork Sun 				 );
9445614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2);
9455614e71bSYork Sun 
9465614e71bSYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
9475614e71bSYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
9485614e71bSYork Sun 			if (popts->rtt_override)
9495614e71bSYork Sun 				rtt_wr = popts->rtt_wr_override_value;
9505614e71bSYork Sun 			else
9515614e71bSYork Sun 				rtt_wr = popts->cs_local_opts[i].odt_rtt_wr;
9525614e71bSYork Sun 
9535614e71bSYork Sun 			esdmode2 &= 0xF9FF;	/* clear bit 10, 9 */
9545614e71bSYork Sun 			esdmode2 |= (rtt_wr & 0x3) << 9;
9555614e71bSYork Sun 			switch (i) {
9565614e71bSYork Sun 			case 1:
9575614e71bSYork Sun 				ddr->ddr_sdram_mode_4 = (0
9585614e71bSYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
9595614e71bSYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
9605614e71bSYork Sun 					);
9615614e71bSYork Sun 				break;
9625614e71bSYork Sun 			case 2:
9635614e71bSYork Sun 				ddr->ddr_sdram_mode_6 = (0
9645614e71bSYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
9655614e71bSYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
9665614e71bSYork Sun 					);
9675614e71bSYork Sun 				break;
9685614e71bSYork Sun 			case 3:
9695614e71bSYork Sun 				ddr->ddr_sdram_mode_8 = (0
9705614e71bSYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
9715614e71bSYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
9725614e71bSYork Sun 					);
9735614e71bSYork Sun 				break;
9745614e71bSYork Sun 			}
9755614e71bSYork Sun 		}
9765614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n",
9775614e71bSYork Sun 		      ddr->ddr_sdram_mode_4);
9785614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n",
9795614e71bSYork Sun 		      ddr->ddr_sdram_mode_6);
9805614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n",
9815614e71bSYork Sun 		      ddr->ddr_sdram_mode_8);
9825614e71bSYork Sun 	}
9835614e71bSYork Sun }
98434e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
98534e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
98634e026f9SYork Sun static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
98734e026f9SYork Sun 				const memctl_options_t *popts,
98834e026f9SYork Sun 				const common_timing_params_t *common_dimm,
98934e026f9SYork Sun 				const unsigned int unq_mrs_en)
99034e026f9SYork Sun {
99134e026f9SYork Sun 	unsigned short esdmode2 = 0;	/* Extended SDRAM mode 2 */
99234e026f9SYork Sun 	unsigned short esdmode3 = 0;	/* Extended SDRAM mode 3 */
99334e026f9SYork Sun 	int i;
99434e026f9SYork Sun 	unsigned int rtt_wr = 0;	/* Rtt_WR - dynamic ODT off */
99534e026f9SYork Sun 	unsigned int srt = 0;	/* self-refresh temerature, normal range */
99634e026f9SYork Sun 	unsigned int asr = 0;	/* auto self-refresh disable */
99734e026f9SYork Sun 	unsigned int cwl = compute_cas_write_latency() - 5;
99834e026f9SYork Sun 	unsigned int pasr = 0;	/* partial array self refresh disable */
99934e026f9SYork Sun 
100034e026f9SYork Sun 	if (popts->rtt_override)
100134e026f9SYork Sun 		rtt_wr = popts->rtt_wr_override_value;
100234e026f9SYork Sun 	else
100334e026f9SYork Sun 		rtt_wr = popts->cs_local_opts[0].odt_rtt_wr;
100434e026f9SYork Sun 
100534e026f9SYork Sun 	if (common_dimm->extended_op_srt)
100634e026f9SYork Sun 		srt = common_dimm->extended_op_srt;
100734e026f9SYork Sun 
100834e026f9SYork Sun 	esdmode2 = (0
100934e026f9SYork Sun 		| ((rtt_wr & 0x3) << 9)
101034e026f9SYork Sun 		| ((srt & 0x1) << 7)
101134e026f9SYork Sun 		| ((asr & 0x1) << 6)
101234e026f9SYork Sun 		| ((cwl & 0x7) << 3)
101334e026f9SYork Sun 		| ((pasr & 0x7) << 0));
101434e026f9SYork Sun 	ddr->ddr_sdram_mode_2 = (0
101534e026f9SYork Sun 				 | ((esdmode2 & 0xFFFF) << 16)
101634e026f9SYork Sun 				 | ((esdmode3 & 0xFFFF) << 0)
101734e026f9SYork Sun 				 );
101834e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2);
101934e026f9SYork Sun 
102034e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
102134e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
102234e026f9SYork Sun 			if (popts->rtt_override)
102334e026f9SYork Sun 				rtt_wr = popts->rtt_wr_override_value;
102434e026f9SYork Sun 			else
102534e026f9SYork Sun 				rtt_wr = popts->cs_local_opts[i].odt_rtt_wr;
102634e026f9SYork Sun 
102734e026f9SYork Sun 			esdmode2 &= 0xF9FF;	/* clear bit 10, 9 */
102834e026f9SYork Sun 			esdmode2 |= (rtt_wr & 0x3) << 9;
102934e026f9SYork Sun 			switch (i) {
103034e026f9SYork Sun 			case 1:
103134e026f9SYork Sun 				ddr->ddr_sdram_mode_4 = (0
103234e026f9SYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
103334e026f9SYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
103434e026f9SYork Sun 					);
103534e026f9SYork Sun 				break;
103634e026f9SYork Sun 			case 2:
103734e026f9SYork Sun 				ddr->ddr_sdram_mode_6 = (0
103834e026f9SYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
103934e026f9SYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
104034e026f9SYork Sun 					);
104134e026f9SYork Sun 				break;
104234e026f9SYork Sun 			case 3:
104334e026f9SYork Sun 				ddr->ddr_sdram_mode_8 = (0
104434e026f9SYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
104534e026f9SYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
104634e026f9SYork Sun 					);
104734e026f9SYork Sun 				break;
104834e026f9SYork Sun 			}
104934e026f9SYork Sun 		}
105034e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n",
105134e026f9SYork Sun 			ddr->ddr_sdram_mode_4);
105234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n",
105334e026f9SYork Sun 			ddr->ddr_sdram_mode_6);
105434e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n",
105534e026f9SYork Sun 			ddr->ddr_sdram_mode_8);
105634e026f9SYork Sun 	}
105734e026f9SYork Sun }
105834e026f9SYork Sun 
105934e026f9SYork Sun #else /* for DDR2 and DDR1 */
106034e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
106134e026f9SYork Sun static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
106234e026f9SYork Sun 				const memctl_options_t *popts,
106334e026f9SYork Sun 				const common_timing_params_t *common_dimm,
106434e026f9SYork Sun 				const unsigned int unq_mrs_en)
106534e026f9SYork Sun {
106634e026f9SYork Sun 	unsigned short esdmode2 = 0;	/* Extended SDRAM mode 2 */
106734e026f9SYork Sun 	unsigned short esdmode3 = 0;	/* Extended SDRAM mode 3 */
106834e026f9SYork Sun 
106934e026f9SYork Sun 	ddr->ddr_sdram_mode_2 = (0
107034e026f9SYork Sun 				 | ((esdmode2 & 0xFFFF) << 16)
107134e026f9SYork Sun 				 | ((esdmode3 & 0xFFFF) << 0)
107234e026f9SYork Sun 				 );
107334e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2);
107434e026f9SYork Sun }
107534e026f9SYork Sun #endif
107634e026f9SYork Sun 
107734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
107834e026f9SYork Sun /* DDR SDRAM Mode configuration 9 (DDR_SDRAM_MODE_9) */
107934e026f9SYork Sun static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
108034e026f9SYork Sun 				const memctl_options_t *popts,
108134e026f9SYork Sun 				const common_timing_params_t *common_dimm,
108234e026f9SYork Sun 				const unsigned int unq_mrs_en)
108334e026f9SYork Sun {
108434e026f9SYork Sun 	int i;
108534e026f9SYork Sun 	unsigned short esdmode4 = 0;	/* Extended SDRAM mode 4 */
108634e026f9SYork Sun 	unsigned short esdmode5;	/* Extended SDRAM mode 5 */
108734e026f9SYork Sun 
108834e026f9SYork Sun 	esdmode5 = 0x00000400;		/* Data mask enabled */
108934e026f9SYork Sun 
109034e026f9SYork Sun 	ddr->ddr_sdram_mode_9 = (0
109134e026f9SYork Sun 				 | ((esdmode4 & 0xffff) << 16)
109234e026f9SYork Sun 				 | ((esdmode5 & 0xffff) << 0)
109334e026f9SYork Sun 				);
109434e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9);
109534e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
109634e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
109734e026f9SYork Sun 			switch (i) {
109834e026f9SYork Sun 			case 1:
109934e026f9SYork Sun 				ddr->ddr_sdram_mode_11 = (0
110034e026f9SYork Sun 					| ((esdmode4 & 0xFFFF) << 16)
110134e026f9SYork Sun 					| ((esdmode5 & 0xFFFF) << 0)
110234e026f9SYork Sun 					);
110334e026f9SYork Sun 				break;
110434e026f9SYork Sun 			case 2:
110534e026f9SYork Sun 				ddr->ddr_sdram_mode_13 = (0
110634e026f9SYork Sun 					| ((esdmode4 & 0xFFFF) << 16)
110734e026f9SYork Sun 					| ((esdmode5 & 0xFFFF) << 0)
110834e026f9SYork Sun 					);
110934e026f9SYork Sun 				break;
111034e026f9SYork Sun 			case 3:
111134e026f9SYork Sun 				ddr->ddr_sdram_mode_15 = (0
111234e026f9SYork Sun 					| ((esdmode4 & 0xFFFF) << 16)
111334e026f9SYork Sun 					| ((esdmode5 & 0xFFFF) << 0)
111434e026f9SYork Sun 					);
111534e026f9SYork Sun 				break;
111634e026f9SYork Sun 			}
111734e026f9SYork Sun 		}
111834e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_11 = 0x%08x\n",
111934e026f9SYork Sun 		      ddr->ddr_sdram_mode_11);
112034e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_13 = 0x%08x\n",
112134e026f9SYork Sun 		      ddr->ddr_sdram_mode_13);
112234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_15 = 0x%08x\n",
112334e026f9SYork Sun 		      ddr->ddr_sdram_mode_15);
112434e026f9SYork Sun 	}
112534e026f9SYork Sun }
112634e026f9SYork Sun 
112734e026f9SYork Sun /* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */
112834e026f9SYork Sun static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
112934e026f9SYork Sun 				const memctl_options_t *popts,
113034e026f9SYork Sun 				const common_timing_params_t *common_dimm,
113134e026f9SYork Sun 				const unsigned int unq_mrs_en)
113234e026f9SYork Sun {
113334e026f9SYork Sun 	int i;
113434e026f9SYork Sun 	unsigned short esdmode6 = 0;	/* Extended SDRAM mode 6 */
113534e026f9SYork Sun 	unsigned short esdmode7 = 0;	/* Extended SDRAM mode 7 */
113634e026f9SYork Sun 	unsigned int tccdl_min = picos_to_mclk(common_dimm->tccdl_ps);
113734e026f9SYork Sun 
113834e026f9SYork Sun 	esdmode6 = ((tccdl_min - 4) & 0x7) << 10;
113934e026f9SYork Sun 
114034e026f9SYork Sun 	ddr->ddr_sdram_mode_10 = (0
114134e026f9SYork Sun 				 | ((esdmode6 & 0xffff) << 16)
114234e026f9SYork Sun 				 | ((esdmode7 & 0xffff) << 0)
114334e026f9SYork Sun 				);
114434e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_10) = 0x%08x\n", ddr->ddr_sdram_mode_10);
114534e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
114634e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
114734e026f9SYork Sun 			switch (i) {
114834e026f9SYork Sun 			case 1:
114934e026f9SYork Sun 				ddr->ddr_sdram_mode_12 = (0
115034e026f9SYork Sun 					| ((esdmode6 & 0xFFFF) << 16)
115134e026f9SYork Sun 					| ((esdmode7 & 0xFFFF) << 0)
115234e026f9SYork Sun 					);
115334e026f9SYork Sun 				break;
115434e026f9SYork Sun 			case 2:
115534e026f9SYork Sun 				ddr->ddr_sdram_mode_14 = (0
115634e026f9SYork Sun 					| ((esdmode6 & 0xFFFF) << 16)
115734e026f9SYork Sun 					| ((esdmode7 & 0xFFFF) << 0)
115834e026f9SYork Sun 					);
115934e026f9SYork Sun 				break;
116034e026f9SYork Sun 			case 3:
116134e026f9SYork Sun 				ddr->ddr_sdram_mode_16 = (0
116234e026f9SYork Sun 					| ((esdmode6 & 0xFFFF) << 16)
116334e026f9SYork Sun 					| ((esdmode7 & 0xFFFF) << 0)
116434e026f9SYork Sun 					);
116534e026f9SYork Sun 				break;
116634e026f9SYork Sun 			}
116734e026f9SYork Sun 		}
116834e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_12 = 0x%08x\n",
116934e026f9SYork Sun 		      ddr->ddr_sdram_mode_12);
117034e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_14 = 0x%08x\n",
117134e026f9SYork Sun 		      ddr->ddr_sdram_mode_14);
117234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_16 = 0x%08x\n",
117334e026f9SYork Sun 		      ddr->ddr_sdram_mode_16);
117434e026f9SYork Sun 	}
117534e026f9SYork Sun }
117634e026f9SYork Sun 
117734e026f9SYork Sun #endif
11785614e71bSYork Sun 
11795614e71bSYork Sun /* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */
11805614e71bSYork Sun static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr,
11815614e71bSYork Sun 			       const memctl_options_t *popts,
11825614e71bSYork Sun 			       const common_timing_params_t *common_dimm)
11835614e71bSYork Sun {
11845614e71bSYork Sun 	unsigned int refint;	/* Refresh interval */
11855614e71bSYork Sun 	unsigned int bstopre;	/* Precharge interval */
11865614e71bSYork Sun 
11875614e71bSYork Sun 	refint = picos_to_mclk(common_dimm->refresh_rate_ps);
11885614e71bSYork Sun 
11895614e71bSYork Sun 	bstopre = popts->bstopre;
11905614e71bSYork Sun 
11915614e71bSYork Sun 	/* refint field used 0x3FFF in earlier controllers */
11925614e71bSYork Sun 	ddr->ddr_sdram_interval = (0
11935614e71bSYork Sun 				   | ((refint & 0xFFFF) << 16)
11945614e71bSYork Sun 				   | ((bstopre & 0x3FFF) << 0)
11955614e71bSYork Sun 				   );
11965614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_interval = 0x%08x\n", ddr->ddr_sdram_interval);
11975614e71bSYork Sun }
11985614e71bSYork Sun 
119934e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
12005614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
12015614e71bSYork Sun static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
12025614e71bSYork Sun 			       const memctl_options_t *popts,
12035614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
12045614e71bSYork Sun 			       unsigned int cas_latency,
12055614e71bSYork Sun 			       unsigned int additive_latency,
12065614e71bSYork Sun 			       const unsigned int unq_mrs_en)
12075614e71bSYork Sun {
120834e026f9SYork Sun 	int i;
120934e026f9SYork Sun 	unsigned short esdmode;		/* Extended SDRAM mode */
121034e026f9SYork Sun 	unsigned short sdmode;		/* SDRAM mode */
121134e026f9SYork Sun 
121234e026f9SYork Sun 	/* Mode Register - MR1 */
121334e026f9SYork Sun 	unsigned int qoff = 0;		/* Output buffer enable 0=yes, 1=no */
121434e026f9SYork Sun 	unsigned int tdqs_en = 0;	/* TDQS Enable: 0=no, 1=yes */
121534e026f9SYork Sun 	unsigned int rtt;
121634e026f9SYork Sun 	unsigned int wrlvl_en = 0;	/* Write level enable: 0=no, 1=yes */
121734e026f9SYork Sun 	unsigned int al = 0;		/* Posted CAS# additive latency (AL) */
121834e026f9SYork Sun 	unsigned int dic = 0;		/* Output driver impedance, 40ohm */
121934e026f9SYork Sun 	unsigned int dll_en = 1;	/* DLL Enable  1=Enable (Normal),
122034e026f9SYork Sun 						       0=Disable (Test/Debug) */
122134e026f9SYork Sun 
122234e026f9SYork Sun 	/* Mode Register - MR0 */
122334e026f9SYork Sun 	unsigned int wr = 0;	/* Write Recovery */
122434e026f9SYork Sun 	unsigned int dll_rst;	/* DLL Reset */
122534e026f9SYork Sun 	unsigned int mode;	/* Normal=0 or Test=1 */
122634e026f9SYork Sun 	unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */
122734e026f9SYork Sun 	/* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */
122834e026f9SYork Sun 	unsigned int bt;
122934e026f9SYork Sun 	unsigned int bl;	/* BL: Burst Length */
123034e026f9SYork Sun 
123134e026f9SYork Sun 	unsigned int wr_mclk;
123234e026f9SYork Sun 	/* DDR4 support WR 10, 12, 14, 16, 18, 20, 24 */
123334e026f9SYork Sun 	static const u8 wr_table[] = {
123434e026f9SYork Sun 		0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6};
123534e026f9SYork Sun 	/* DDR4 support CAS 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24 */
123634e026f9SYork Sun 	static const u8 cas_latency_table[] = {
123734e026f9SYork Sun 		0, 1, 2, 3, 4, 5, 6, 7, 8, 8,
123834e026f9SYork Sun 		9, 9, 10, 10, 11, 11};
123934e026f9SYork Sun 
124034e026f9SYork Sun 	if (popts->rtt_override)
124134e026f9SYork Sun 		rtt = popts->rtt_override_value;
124234e026f9SYork Sun 	else
124334e026f9SYork Sun 		rtt = popts->cs_local_opts[0].odt_rtt_norm;
124434e026f9SYork Sun 
124534e026f9SYork Sun 	if (additive_latency == (cas_latency - 1))
124634e026f9SYork Sun 		al = 1;
124734e026f9SYork Sun 	if (additive_latency == (cas_latency - 2))
124834e026f9SYork Sun 		al = 2;
124934e026f9SYork Sun 
125034e026f9SYork Sun 	if (popts->quad_rank_present)
125134e026f9SYork Sun 		dic = 1;	/* output driver impedance 240/7 ohm */
125234e026f9SYork Sun 
125334e026f9SYork Sun 	/*
125434e026f9SYork Sun 	 * The esdmode value will also be used for writing
125534e026f9SYork Sun 	 * MR1 during write leveling for DDR3, although the
125634e026f9SYork Sun 	 * bits specifically related to the write leveling
125734e026f9SYork Sun 	 * scheme will be handled automatically by the DDR
125834e026f9SYork Sun 	 * controller. so we set the wrlvl_en = 0 here.
125934e026f9SYork Sun 	 */
126034e026f9SYork Sun 	esdmode = (0
126134e026f9SYork Sun 		| ((qoff & 0x1) << 12)
126234e026f9SYork Sun 		| ((tdqs_en & 0x1) << 11)
126334e026f9SYork Sun 		| ((rtt & 0x7) << 8)
126434e026f9SYork Sun 		| ((wrlvl_en & 0x1) << 7)
126534e026f9SYork Sun 		| ((al & 0x3) << 3)
126634e026f9SYork Sun 		| ((dic & 0x3) << 1)   /* DIC field is split */
126734e026f9SYork Sun 		| ((dll_en & 0x1) << 0)
126834e026f9SYork Sun 		);
126934e026f9SYork Sun 
127034e026f9SYork Sun 	/*
127134e026f9SYork Sun 	 * DLL control for precharge PD
127234e026f9SYork Sun 	 * 0=slow exit DLL off (tXPDLL)
127334e026f9SYork Sun 	 * 1=fast exit DLL on (tXP)
127434e026f9SYork Sun 	 */
127534e026f9SYork Sun 
127634e026f9SYork Sun 	wr_mclk = picos_to_mclk(common_dimm->twr_ps);
127734e026f9SYork Sun 	if (wr_mclk <= 24) {
127834e026f9SYork Sun 		wr = wr_table[wr_mclk - 10];
127934e026f9SYork Sun 	} else {
128034e026f9SYork Sun 		printf("Error: unsupported write recovery for mode register wr_mclk = %d\n",
128134e026f9SYork Sun 		       wr_mclk);
128234e026f9SYork Sun 	}
128334e026f9SYork Sun 
128434e026f9SYork Sun 	dll_rst = 0;	/* dll no reset */
128534e026f9SYork Sun 	mode = 0;	/* normal mode */
128634e026f9SYork Sun 
128734e026f9SYork Sun 	/* look up table to get the cas latency bits */
128834e026f9SYork Sun 	if (cas_latency >= 9 && cas_latency <= 24)
128934e026f9SYork Sun 		caslat = cas_latency_table[cas_latency - 9];
129034e026f9SYork Sun 	else
129134e026f9SYork Sun 		printf("Error: unsupported cas latency for mode register\n");
129234e026f9SYork Sun 
129334e026f9SYork Sun 	bt = 0;	/* Nibble sequential */
129434e026f9SYork Sun 
129534e026f9SYork Sun 	switch (popts->burst_length) {
129634e026f9SYork Sun 	case DDR_BL8:
129734e026f9SYork Sun 		bl = 0;
129834e026f9SYork Sun 		break;
129934e026f9SYork Sun 	case DDR_OTF:
130034e026f9SYork Sun 		bl = 1;
130134e026f9SYork Sun 		break;
130234e026f9SYork Sun 	case DDR_BC4:
130334e026f9SYork Sun 		bl = 2;
130434e026f9SYork Sun 		break;
130534e026f9SYork Sun 	default:
130634e026f9SYork Sun 		printf("Error: invalid burst length of %u specified. ",
130734e026f9SYork Sun 		       popts->burst_length);
130834e026f9SYork Sun 		puts("Defaulting to on-the-fly BC4 or BL8 beats.\n");
130934e026f9SYork Sun 		bl = 1;
131034e026f9SYork Sun 		break;
131134e026f9SYork Sun 	}
131234e026f9SYork Sun 
131334e026f9SYork Sun 	sdmode = (0
131434e026f9SYork Sun 		  | ((wr & 0x7) << 9)
131534e026f9SYork Sun 		  | ((dll_rst & 0x1) << 8)
131634e026f9SYork Sun 		  | ((mode & 0x1) << 7)
131734e026f9SYork Sun 		  | (((caslat >> 1) & 0x7) << 4)
131834e026f9SYork Sun 		  | ((bt & 0x1) << 3)
131934e026f9SYork Sun 		  | ((caslat & 1) << 2)
132034e026f9SYork Sun 		  | ((bl & 0x3) << 0)
132134e026f9SYork Sun 		  );
132234e026f9SYork Sun 
132334e026f9SYork Sun 	ddr->ddr_sdram_mode = (0
132434e026f9SYork Sun 			       | ((esdmode & 0xFFFF) << 16)
132534e026f9SYork Sun 			       | ((sdmode & 0xFFFF) << 0)
132634e026f9SYork Sun 			       );
132734e026f9SYork Sun 
132834e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode);
132934e026f9SYork Sun 
133034e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
133134e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
133234e026f9SYork Sun 			if (popts->rtt_override)
133334e026f9SYork Sun 				rtt = popts->rtt_override_value;
133434e026f9SYork Sun 			else
133534e026f9SYork Sun 				rtt = popts->cs_local_opts[i].odt_rtt_norm;
133634e026f9SYork Sun 
133734e026f9SYork Sun 			esdmode &= 0xF8FF;	/* clear bit 10,9,8 for rtt */
133834e026f9SYork Sun 			esdmode |= (rtt & 0x7) << 8;
133934e026f9SYork Sun 			switch (i) {
134034e026f9SYork Sun 			case 1:
134134e026f9SYork Sun 				ddr->ddr_sdram_mode_3 = (0
134234e026f9SYork Sun 				       | ((esdmode & 0xFFFF) << 16)
134334e026f9SYork Sun 				       | ((sdmode & 0xFFFF) << 0)
134434e026f9SYork Sun 				       );
134534e026f9SYork Sun 				break;
134634e026f9SYork Sun 			case 2:
134734e026f9SYork Sun 				ddr->ddr_sdram_mode_5 = (0
134834e026f9SYork Sun 				       | ((esdmode & 0xFFFF) << 16)
134934e026f9SYork Sun 				       | ((sdmode & 0xFFFF) << 0)
135034e026f9SYork Sun 				       );
135134e026f9SYork Sun 				break;
135234e026f9SYork Sun 			case 3:
135334e026f9SYork Sun 				ddr->ddr_sdram_mode_7 = (0
135434e026f9SYork Sun 				       | ((esdmode & 0xFFFF) << 16)
135534e026f9SYork Sun 				       | ((sdmode & 0xFFFF) << 0)
135634e026f9SYork Sun 				       );
135734e026f9SYork Sun 				break;
135834e026f9SYork Sun 			}
135934e026f9SYork Sun 		}
136034e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n",
136134e026f9SYork Sun 		      ddr->ddr_sdram_mode_3);
136234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
136334e026f9SYork Sun 		      ddr->ddr_sdram_mode_5);
136434e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
136534e026f9SYork Sun 		      ddr->ddr_sdram_mode_5);
136634e026f9SYork Sun 	}
136734e026f9SYork Sun }
136834e026f9SYork Sun 
136934e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
137034e026f9SYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
137134e026f9SYork Sun static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
137234e026f9SYork Sun 			       const memctl_options_t *popts,
137334e026f9SYork Sun 			       const common_timing_params_t *common_dimm,
137434e026f9SYork Sun 			       unsigned int cas_latency,
137534e026f9SYork Sun 			       unsigned int additive_latency,
137634e026f9SYork Sun 			       const unsigned int unq_mrs_en)
137734e026f9SYork Sun {
137834e026f9SYork Sun 	int i;
13795614e71bSYork Sun 	unsigned short esdmode;		/* Extended SDRAM mode */
13805614e71bSYork Sun 	unsigned short sdmode;		/* SDRAM mode */
13815614e71bSYork Sun 
13825614e71bSYork Sun 	/* Mode Register - MR1 */
13835614e71bSYork Sun 	unsigned int qoff = 0;		/* Output buffer enable 0=yes, 1=no */
13845614e71bSYork Sun 	unsigned int tdqs_en = 0;	/* TDQS Enable: 0=no, 1=yes */
13855614e71bSYork Sun 	unsigned int rtt;
13865614e71bSYork Sun 	unsigned int wrlvl_en = 0;	/* Write level enable: 0=no, 1=yes */
13875614e71bSYork Sun 	unsigned int al = 0;		/* Posted CAS# additive latency (AL) */
13885614e71bSYork Sun 	unsigned int dic = 0;		/* Output driver impedance, 40ohm */
13895614e71bSYork Sun 	unsigned int dll_en = 0;	/* DLL Enable  0=Enable (Normal),
13905614e71bSYork Sun 						       1=Disable (Test/Debug) */
13915614e71bSYork Sun 
13925614e71bSYork Sun 	/* Mode Register - MR0 */
13935614e71bSYork Sun 	unsigned int dll_on;	/* DLL control for precharge PD, 0=off, 1=on */
13945614e71bSYork Sun 	unsigned int wr = 0;	/* Write Recovery */
13955614e71bSYork Sun 	unsigned int dll_rst;	/* DLL Reset */
13965614e71bSYork Sun 	unsigned int mode;	/* Normal=0 or Test=1 */
13975614e71bSYork Sun 	unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */
13985614e71bSYork Sun 	/* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */
13995614e71bSYork Sun 	unsigned int bt;
14005614e71bSYork Sun 	unsigned int bl;	/* BL: Burst Length */
14015614e71bSYork Sun 
14025614e71bSYork Sun 	unsigned int wr_mclk;
14035614e71bSYork Sun 	/*
14045614e71bSYork Sun 	 * DDR_SDRAM_MODE doesn't support 9,11,13,15
14055614e71bSYork Sun 	 * Please refer JEDEC Standard No. 79-3E for Mode Register MR0
14065614e71bSYork Sun 	 * for this table
14075614e71bSYork Sun 	 */
14085614e71bSYork Sun 	static const u8 wr_table[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0};
14095614e71bSYork Sun 
14105614e71bSYork Sun 	if (popts->rtt_override)
14115614e71bSYork Sun 		rtt = popts->rtt_override_value;
14125614e71bSYork Sun 	else
14135614e71bSYork Sun 		rtt = popts->cs_local_opts[0].odt_rtt_norm;
14145614e71bSYork Sun 
14155614e71bSYork Sun 	if (additive_latency == (cas_latency - 1))
14165614e71bSYork Sun 		al = 1;
14175614e71bSYork Sun 	if (additive_latency == (cas_latency - 2))
14185614e71bSYork Sun 		al = 2;
14195614e71bSYork Sun 
14205614e71bSYork Sun 	if (popts->quad_rank_present)
14215614e71bSYork Sun 		dic = 1;	/* output driver impedance 240/7 ohm */
14225614e71bSYork Sun 
14235614e71bSYork Sun 	/*
14245614e71bSYork Sun 	 * The esdmode value will also be used for writing
14255614e71bSYork Sun 	 * MR1 during write leveling for DDR3, although the
14265614e71bSYork Sun 	 * bits specifically related to the write leveling
14275614e71bSYork Sun 	 * scheme will be handled automatically by the DDR
14285614e71bSYork Sun 	 * controller. so we set the wrlvl_en = 0 here.
14295614e71bSYork Sun 	 */
14305614e71bSYork Sun 	esdmode = (0
14315614e71bSYork Sun 		| ((qoff & 0x1) << 12)
14325614e71bSYork Sun 		| ((tdqs_en & 0x1) << 11)
14335614e71bSYork Sun 		| ((rtt & 0x4) << 7)   /* rtt field is split */
14345614e71bSYork Sun 		| ((wrlvl_en & 0x1) << 7)
14355614e71bSYork Sun 		| ((rtt & 0x2) << 5)   /* rtt field is split */
14365614e71bSYork Sun 		| ((dic & 0x2) << 4)   /* DIC field is split */
14375614e71bSYork Sun 		| ((al & 0x3) << 3)
14385614e71bSYork Sun 		| ((rtt & 0x1) << 2)  /* rtt field is split */
14395614e71bSYork Sun 		| ((dic & 0x1) << 1)   /* DIC field is split */
14405614e71bSYork Sun 		| ((dll_en & 0x1) << 0)
14415614e71bSYork Sun 		);
14425614e71bSYork Sun 
14435614e71bSYork Sun 	/*
14445614e71bSYork Sun 	 * DLL control for precharge PD
14455614e71bSYork Sun 	 * 0=slow exit DLL off (tXPDLL)
14465614e71bSYork Sun 	 * 1=fast exit DLL on (tXP)
14475614e71bSYork Sun 	 */
14485614e71bSYork Sun 	dll_on = 1;
14495614e71bSYork Sun 
145034e026f9SYork Sun 	wr_mclk = picos_to_mclk(common_dimm->twr_ps);
14515614e71bSYork Sun 	if (wr_mclk <= 16) {
14525614e71bSYork Sun 		wr = wr_table[wr_mclk - 5];
14535614e71bSYork Sun 	} else {
14545614e71bSYork Sun 		printf("Error: unsupported write recovery for mode register "
14555614e71bSYork Sun 		       "wr_mclk = %d\n", wr_mclk);
14565614e71bSYork Sun 	}
14575614e71bSYork Sun 
14585614e71bSYork Sun 	dll_rst = 0;	/* dll no reset */
14595614e71bSYork Sun 	mode = 0;	/* normal mode */
14605614e71bSYork Sun 
14615614e71bSYork Sun 	/* look up table to get the cas latency bits */
14625614e71bSYork Sun 	if (cas_latency >= 5 && cas_latency <= 16) {
14635614e71bSYork Sun 		unsigned char cas_latency_table[] = {
14645614e71bSYork Sun 			0x2,	/* 5 clocks */
14655614e71bSYork Sun 			0x4,	/* 6 clocks */
14665614e71bSYork Sun 			0x6,	/* 7 clocks */
14675614e71bSYork Sun 			0x8,	/* 8 clocks */
14685614e71bSYork Sun 			0xa,	/* 9 clocks */
14695614e71bSYork Sun 			0xc,	/* 10 clocks */
14705614e71bSYork Sun 			0xe,	/* 11 clocks */
14715614e71bSYork Sun 			0x1,	/* 12 clocks */
14725614e71bSYork Sun 			0x3,	/* 13 clocks */
14735614e71bSYork Sun 			0x5,	/* 14 clocks */
14745614e71bSYork Sun 			0x7,	/* 15 clocks */
14755614e71bSYork Sun 			0x9,	/* 16 clocks */
14765614e71bSYork Sun 		};
14775614e71bSYork Sun 		caslat = cas_latency_table[cas_latency - 5];
14785614e71bSYork Sun 	} else {
14795614e71bSYork Sun 		printf("Error: unsupported cas latency for mode register\n");
14805614e71bSYork Sun 	}
14815614e71bSYork Sun 
14825614e71bSYork Sun 	bt = 0;	/* Nibble sequential */
14835614e71bSYork Sun 
14845614e71bSYork Sun 	switch (popts->burst_length) {
14855614e71bSYork Sun 	case DDR_BL8:
14865614e71bSYork Sun 		bl = 0;
14875614e71bSYork Sun 		break;
14885614e71bSYork Sun 	case DDR_OTF:
14895614e71bSYork Sun 		bl = 1;
14905614e71bSYork Sun 		break;
14915614e71bSYork Sun 	case DDR_BC4:
14925614e71bSYork Sun 		bl = 2;
14935614e71bSYork Sun 		break;
14945614e71bSYork Sun 	default:
14955614e71bSYork Sun 		printf("Error: invalid burst length of %u specified. "
14965614e71bSYork Sun 			" Defaulting to on-the-fly BC4 or BL8 beats.\n",
14975614e71bSYork Sun 			popts->burst_length);
14985614e71bSYork Sun 		bl = 1;
14995614e71bSYork Sun 		break;
15005614e71bSYork Sun 	}
15015614e71bSYork Sun 
15025614e71bSYork Sun 	sdmode = (0
15035614e71bSYork Sun 		  | ((dll_on & 0x1) << 12)
15045614e71bSYork Sun 		  | ((wr & 0x7) << 9)
15055614e71bSYork Sun 		  | ((dll_rst & 0x1) << 8)
15065614e71bSYork Sun 		  | ((mode & 0x1) << 7)
15075614e71bSYork Sun 		  | (((caslat >> 1) & 0x7) << 4)
15085614e71bSYork Sun 		  | ((bt & 0x1) << 3)
15095614e71bSYork Sun 		  | ((caslat & 1) << 2)
15105614e71bSYork Sun 		  | ((bl & 0x3) << 0)
15115614e71bSYork Sun 		  );
15125614e71bSYork Sun 
15135614e71bSYork Sun 	ddr->ddr_sdram_mode = (0
15145614e71bSYork Sun 			       | ((esdmode & 0xFFFF) << 16)
15155614e71bSYork Sun 			       | ((sdmode & 0xFFFF) << 0)
15165614e71bSYork Sun 			       );
15175614e71bSYork Sun 
15185614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode);
15195614e71bSYork Sun 
15205614e71bSYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
15215614e71bSYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
15225614e71bSYork Sun 			if (popts->rtt_override)
15235614e71bSYork Sun 				rtt = popts->rtt_override_value;
15245614e71bSYork Sun 			else
15255614e71bSYork Sun 				rtt = popts->cs_local_opts[i].odt_rtt_norm;
15265614e71bSYork Sun 
15275614e71bSYork Sun 			esdmode &= 0xFDBB;	/* clear bit 9,6,2 */
15285614e71bSYork Sun 			esdmode |= (0
15295614e71bSYork Sun 				| ((rtt & 0x4) << 7)   /* rtt field is split */
15305614e71bSYork Sun 				| ((rtt & 0x2) << 5)   /* rtt field is split */
15315614e71bSYork Sun 				| ((rtt & 0x1) << 2)  /* rtt field is split */
15325614e71bSYork Sun 				);
15335614e71bSYork Sun 			switch (i) {
15345614e71bSYork Sun 			case 1:
15355614e71bSYork Sun 				ddr->ddr_sdram_mode_3 = (0
15365614e71bSYork Sun 				       | ((esdmode & 0xFFFF) << 16)
15375614e71bSYork Sun 				       | ((sdmode & 0xFFFF) << 0)
15385614e71bSYork Sun 				       );
15395614e71bSYork Sun 				break;
15405614e71bSYork Sun 			case 2:
15415614e71bSYork Sun 				ddr->ddr_sdram_mode_5 = (0
15425614e71bSYork Sun 				       | ((esdmode & 0xFFFF) << 16)
15435614e71bSYork Sun 				       | ((sdmode & 0xFFFF) << 0)
15445614e71bSYork Sun 				       );
15455614e71bSYork Sun 				break;
15465614e71bSYork Sun 			case 3:
15475614e71bSYork Sun 				ddr->ddr_sdram_mode_7 = (0
15485614e71bSYork Sun 				       | ((esdmode & 0xFFFF) << 16)
15495614e71bSYork Sun 				       | ((sdmode & 0xFFFF) << 0)
15505614e71bSYork Sun 				       );
15515614e71bSYork Sun 				break;
15525614e71bSYork Sun 			}
15535614e71bSYork Sun 		}
15545614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n",
15555614e71bSYork Sun 			ddr->ddr_sdram_mode_3);
15565614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
15575614e71bSYork Sun 			ddr->ddr_sdram_mode_5);
15585614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
15595614e71bSYork Sun 			ddr->ddr_sdram_mode_5);
15605614e71bSYork Sun 	}
15615614e71bSYork Sun }
15625614e71bSYork Sun 
15635614e71bSYork Sun #else /* !CONFIG_SYS_FSL_DDR3 */
15645614e71bSYork Sun 
15655614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
15665614e71bSYork Sun static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
15675614e71bSYork Sun 			       const memctl_options_t *popts,
15685614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
15695614e71bSYork Sun 			       unsigned int cas_latency,
15705614e71bSYork Sun 			       unsigned int additive_latency,
15715614e71bSYork Sun 			       const unsigned int unq_mrs_en)
15725614e71bSYork Sun {
15735614e71bSYork Sun 	unsigned short esdmode;		/* Extended SDRAM mode */
15745614e71bSYork Sun 	unsigned short sdmode;		/* SDRAM mode */
15755614e71bSYork Sun 
15765614e71bSYork Sun 	/*
15775614e71bSYork Sun 	 * FIXME: This ought to be pre-calculated in a
15785614e71bSYork Sun 	 * technology-specific routine,
15795614e71bSYork Sun 	 * e.g. compute_DDR2_mode_register(), and then the
15805614e71bSYork Sun 	 * sdmode and esdmode passed in as part of common_dimm.
15815614e71bSYork Sun 	 */
15825614e71bSYork Sun 
15835614e71bSYork Sun 	/* Extended Mode Register */
15845614e71bSYork Sun 	unsigned int mrs = 0;		/* Mode Register Set */
15855614e71bSYork Sun 	unsigned int outputs = 0;	/* 0=Enabled, 1=Disabled */
15865614e71bSYork Sun 	unsigned int rdqs_en = 0;	/* RDQS Enable: 0=no, 1=yes */
15875614e71bSYork Sun 	unsigned int dqs_en = 0;	/* DQS# Enable: 0=enable, 1=disable */
15885614e71bSYork Sun 	unsigned int ocd = 0;		/* 0x0=OCD not supported,
15895614e71bSYork Sun 					   0x7=OCD default state */
15905614e71bSYork Sun 	unsigned int rtt;
15915614e71bSYork Sun 	unsigned int al;		/* Posted CAS# additive latency (AL) */
15925614e71bSYork Sun 	unsigned int ods = 0;		/* Output Drive Strength:
15935614e71bSYork Sun 						0 = Full strength (18ohm)
15945614e71bSYork Sun 						1 = Reduced strength (4ohm) */
15955614e71bSYork Sun 	unsigned int dll_en = 0;	/* DLL Enable  0=Enable (Normal),
15965614e71bSYork Sun 						       1=Disable (Test/Debug) */
15975614e71bSYork Sun 
15985614e71bSYork Sun 	/* Mode Register (MR) */
15995614e71bSYork Sun 	unsigned int mr;	/* Mode Register Definition */
16005614e71bSYork Sun 	unsigned int pd;	/* Power-Down Mode */
16015614e71bSYork Sun 	unsigned int wr;	/* Write Recovery */
16025614e71bSYork Sun 	unsigned int dll_res;	/* DLL Reset */
16035614e71bSYork Sun 	unsigned int mode;	/* Normal=0 or Test=1 */
16045614e71bSYork Sun 	unsigned int caslat = 0;/* CAS# latency */
16055614e71bSYork Sun 	/* BT: Burst Type (0=Sequential, 1=Interleaved) */
16065614e71bSYork Sun 	unsigned int bt;
16075614e71bSYork Sun 	unsigned int bl;	/* BL: Burst Length */
16085614e71bSYork Sun 
16095614e71bSYork Sun 	dqs_en = !popts->dqs_config;
16105614e71bSYork Sun 	rtt = fsl_ddr_get_rtt();
16115614e71bSYork Sun 
16125614e71bSYork Sun 	al = additive_latency;
16135614e71bSYork Sun 
16145614e71bSYork Sun 	esdmode = (0
16155614e71bSYork Sun 		| ((mrs & 0x3) << 14)
16165614e71bSYork Sun 		| ((outputs & 0x1) << 12)
16175614e71bSYork Sun 		| ((rdqs_en & 0x1) << 11)
16185614e71bSYork Sun 		| ((dqs_en & 0x1) << 10)
16195614e71bSYork Sun 		| ((ocd & 0x7) << 7)
16205614e71bSYork Sun 		| ((rtt & 0x2) << 5)   /* rtt field is split */
16215614e71bSYork Sun 		| ((al & 0x7) << 3)
16225614e71bSYork Sun 		| ((rtt & 0x1) << 2)   /* rtt field is split */
16235614e71bSYork Sun 		| ((ods & 0x1) << 1)
16245614e71bSYork Sun 		| ((dll_en & 0x1) << 0)
16255614e71bSYork Sun 		);
16265614e71bSYork Sun 
16275614e71bSYork Sun 	mr = 0;		 /* FIXME: CHECKME */
16285614e71bSYork Sun 
16295614e71bSYork Sun 	/*
16305614e71bSYork Sun 	 * 0 = Fast Exit (Normal)
16315614e71bSYork Sun 	 * 1 = Slow Exit (Low Power)
16325614e71bSYork Sun 	 */
16335614e71bSYork Sun 	pd = 0;
16345614e71bSYork Sun 
16355614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
16365614e71bSYork Sun 	wr = 0;       /* Historical */
16375614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
163834e026f9SYork Sun 	wr = picos_to_mclk(common_dimm->twr_ps);
16395614e71bSYork Sun #endif
16405614e71bSYork Sun 	dll_res = 0;
16415614e71bSYork Sun 	mode = 0;
16425614e71bSYork Sun 
16435614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
16445614e71bSYork Sun 	if (1 <= cas_latency && cas_latency <= 4) {
16455614e71bSYork Sun 		unsigned char mode_caslat_table[4] = {
16465614e71bSYork Sun 			0x5,	/* 1.5 clocks */
16475614e71bSYork Sun 			0x2,	/* 2.0 clocks */
16485614e71bSYork Sun 			0x6,	/* 2.5 clocks */
16495614e71bSYork Sun 			0x3	/* 3.0 clocks */
16505614e71bSYork Sun 		};
16515614e71bSYork Sun 		caslat = mode_caslat_table[cas_latency - 1];
16525614e71bSYork Sun 	} else {
16535614e71bSYork Sun 		printf("Warning: unknown cas_latency %d\n", cas_latency);
16545614e71bSYork Sun 	}
16555614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
16565614e71bSYork Sun 	caslat = cas_latency;
16575614e71bSYork Sun #endif
16585614e71bSYork Sun 	bt = 0;
16595614e71bSYork Sun 
16605614e71bSYork Sun 	switch (popts->burst_length) {
16615614e71bSYork Sun 	case DDR_BL4:
16625614e71bSYork Sun 		bl = 2;
16635614e71bSYork Sun 		break;
16645614e71bSYork Sun 	case DDR_BL8:
16655614e71bSYork Sun 		bl = 3;
16665614e71bSYork Sun 		break;
16675614e71bSYork Sun 	default:
16685614e71bSYork Sun 		printf("Error: invalid burst length of %u specified. "
16695614e71bSYork Sun 			" Defaulting to 4 beats.\n",
16705614e71bSYork Sun 			popts->burst_length);
16715614e71bSYork Sun 		bl = 2;
16725614e71bSYork Sun 		break;
16735614e71bSYork Sun 	}
16745614e71bSYork Sun 
16755614e71bSYork Sun 	sdmode = (0
16765614e71bSYork Sun 		  | ((mr & 0x3) << 14)
16775614e71bSYork Sun 		  | ((pd & 0x1) << 12)
16785614e71bSYork Sun 		  | ((wr & 0x7) << 9)
16795614e71bSYork Sun 		  | ((dll_res & 0x1) << 8)
16805614e71bSYork Sun 		  | ((mode & 0x1) << 7)
16815614e71bSYork Sun 		  | ((caslat & 0x7) << 4)
16825614e71bSYork Sun 		  | ((bt & 0x1) << 3)
16835614e71bSYork Sun 		  | ((bl & 0x7) << 0)
16845614e71bSYork Sun 		  );
16855614e71bSYork Sun 
16865614e71bSYork Sun 	ddr->ddr_sdram_mode = (0
16875614e71bSYork Sun 			       | ((esdmode & 0xFFFF) << 16)
16885614e71bSYork Sun 			       | ((sdmode & 0xFFFF) << 0)
16895614e71bSYork Sun 			       );
16905614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode);
16915614e71bSYork Sun }
16925614e71bSYork Sun #endif
16935614e71bSYork Sun 
16945614e71bSYork Sun /* DDR SDRAM Data Initialization (DDR_DATA_INIT) */
16955614e71bSYork Sun static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr)
16965614e71bSYork Sun {
16975614e71bSYork Sun 	unsigned int init_value;	/* Initialization value */
16985614e71bSYork Sun 
16995614e71bSYork Sun #ifdef CONFIG_MEM_INIT_VALUE
17005614e71bSYork Sun 	init_value = CONFIG_MEM_INIT_VALUE;
17015614e71bSYork Sun #else
17025614e71bSYork Sun 	init_value = 0xDEADBEEF;
17035614e71bSYork Sun #endif
17045614e71bSYork Sun 	ddr->ddr_data_init = init_value;
17055614e71bSYork Sun }
17065614e71bSYork Sun 
17075614e71bSYork Sun /*
17085614e71bSYork Sun  * DDR SDRAM Clock Control (DDR_SDRAM_CLK_CNTL)
17095614e71bSYork Sun  * The old controller on the 8540/60 doesn't have this register.
17105614e71bSYork Sun  * Hope it's OK to set it (to 0) anyway.
17115614e71bSYork Sun  */
17125614e71bSYork Sun static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr,
17135614e71bSYork Sun 					 const memctl_options_t *popts)
17145614e71bSYork Sun {
17155614e71bSYork Sun 	unsigned int clk_adjust;	/* Clock adjust */
17165614e71bSYork Sun 
17175614e71bSYork Sun 	clk_adjust = popts->clk_adjust;
17185614e71bSYork Sun 	ddr->ddr_sdram_clk_cntl = (clk_adjust & 0xF) << 23;
17195614e71bSYork Sun 	debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl);
17205614e71bSYork Sun }
17215614e71bSYork Sun 
17225614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_ADDR) */
17235614e71bSYork Sun static void set_ddr_init_addr(fsl_ddr_cfg_regs_t *ddr)
17245614e71bSYork Sun {
17255614e71bSYork Sun 	unsigned int init_addr = 0;	/* Initialization address */
17265614e71bSYork Sun 
17275614e71bSYork Sun 	ddr->ddr_init_addr = init_addr;
17285614e71bSYork Sun }
17295614e71bSYork Sun 
17305614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_EXT_ADDR) */
17315614e71bSYork Sun static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr)
17325614e71bSYork Sun {
17335614e71bSYork Sun 	unsigned int uia = 0;	/* Use initialization address */
17345614e71bSYork Sun 	unsigned int init_ext_addr = 0;	/* Initialization address */
17355614e71bSYork Sun 
17365614e71bSYork Sun 	ddr->ddr_init_ext_addr = (0
17375614e71bSYork Sun 				  | ((uia & 0x1) << 31)
17385614e71bSYork Sun 				  | (init_ext_addr & 0xF)
17395614e71bSYork Sun 				  );
17405614e71bSYork Sun }
17415614e71bSYork Sun 
17425614e71bSYork Sun /* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */
17435614e71bSYork Sun static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr,
17445614e71bSYork Sun 				const memctl_options_t *popts)
17455614e71bSYork Sun {
17465614e71bSYork Sun 	unsigned int rwt = 0; /* Read-to-write turnaround for same CS */
17475614e71bSYork Sun 	unsigned int wrt = 0; /* Write-to-read turnaround for same CS */
17485614e71bSYork Sun 	unsigned int rrt = 0; /* Read-to-read turnaround for same CS */
17495614e71bSYork Sun 	unsigned int wwt = 0; /* Write-to-write turnaround for same CS */
17505614e71bSYork Sun 	unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */
17515614e71bSYork Sun 
175234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
17535614e71bSYork Sun 	if (popts->burst_length == DDR_BL8) {
17545614e71bSYork Sun 		/* We set BL/2 for fixed BL8 */
17555614e71bSYork Sun 		rrt = 0;	/* BL/2 clocks */
17565614e71bSYork Sun 		wwt = 0;	/* BL/2 clocks */
17575614e71bSYork Sun 	} else {
17585614e71bSYork Sun 		/* We need to set BL/2 + 2 to BC4 and OTF */
17595614e71bSYork Sun 		rrt = 2;	/* BL/2 + 2 clocks */
17605614e71bSYork Sun 		wwt = 2;	/* BL/2 + 2 clocks */
17615614e71bSYork Sun 	}
176234e026f9SYork Sun #endif
176334e026f9SYork Sun 
176434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
176534e026f9SYork Sun 	dll_lock = 2;	/* tDLLK = 1024 clocks */
176634e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
17675614e71bSYork Sun 	dll_lock = 1;	/* tDLLK = 512 clocks from spec */
17685614e71bSYork Sun #endif
17695614e71bSYork Sun 	ddr->timing_cfg_4 = (0
17705614e71bSYork Sun 			     | ((rwt & 0xf) << 28)
17715614e71bSYork Sun 			     | ((wrt & 0xf) << 24)
17725614e71bSYork Sun 			     | ((rrt & 0xf) << 20)
17735614e71bSYork Sun 			     | ((wwt & 0xf) << 16)
17745614e71bSYork Sun 			     | (dll_lock & 0x3)
17755614e71bSYork Sun 			     );
17765614e71bSYork Sun 	debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4);
17775614e71bSYork Sun }
17785614e71bSYork Sun 
17795614e71bSYork Sun /* DDR SDRAM Timing Configuration 5 (TIMING_CFG_5) */
17805614e71bSYork Sun static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr, unsigned int cas_latency)
17815614e71bSYork Sun {
17825614e71bSYork Sun 	unsigned int rodt_on = 0;	/* Read to ODT on */
17835614e71bSYork Sun 	unsigned int rodt_off = 0;	/* Read to ODT off */
17845614e71bSYork Sun 	unsigned int wodt_on = 0;	/* Write to ODT on */
17855614e71bSYork Sun 	unsigned int wodt_off = 0;	/* Write to ODT off */
17865614e71bSYork Sun 
178734e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
178834e026f9SYork Sun 	unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
178934e026f9SYork Sun 			      ((ddr->timing_cfg_2 & 0x00040000) >> 14);
17905614e71bSYork Sun 	/* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */
179134e026f9SYork Sun 	if (cas_latency >= wr_lat)
179234e026f9SYork Sun 		rodt_on = cas_latency - wr_lat + 1;
17935614e71bSYork Sun 	rodt_off = 4;	/*  4 clocks */
17945614e71bSYork Sun 	wodt_on = 1;	/*  1 clocks */
17955614e71bSYork Sun 	wodt_off = 4;	/*  4 clocks */
17965614e71bSYork Sun #endif
17975614e71bSYork Sun 
17985614e71bSYork Sun 	ddr->timing_cfg_5 = (0
17995614e71bSYork Sun 			     | ((rodt_on & 0x1f) << 24)
18005614e71bSYork Sun 			     | ((rodt_off & 0x7) << 20)
18015614e71bSYork Sun 			     | ((wodt_on & 0x1f) << 12)
18025614e71bSYork Sun 			     | ((wodt_off & 0x7) << 8)
18035614e71bSYork Sun 			     );
18045614e71bSYork Sun 	debug("FSLDDR: timing_cfg_5 = 0x%08x\n", ddr->timing_cfg_5);
18055614e71bSYork Sun }
18065614e71bSYork Sun 
180734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
180834e026f9SYork Sun static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr)
180934e026f9SYork Sun {
181034e026f9SYork Sun 	unsigned int hs_caslat = 0;
181134e026f9SYork Sun 	unsigned int hs_wrlat = 0;
181234e026f9SYork Sun 	unsigned int hs_wrrec = 0;
181334e026f9SYork Sun 	unsigned int hs_clkadj = 0;
181434e026f9SYork Sun 	unsigned int hs_wrlvl_start = 0;
181534e026f9SYork Sun 
181634e026f9SYork Sun 	ddr->timing_cfg_6 = (0
181734e026f9SYork Sun 			     | ((hs_caslat & 0x1f) << 24)
181834e026f9SYork Sun 			     | ((hs_wrlat & 0x1f) << 19)
181934e026f9SYork Sun 			     | ((hs_wrrec & 0x1f) << 12)
182034e026f9SYork Sun 			     | ((hs_clkadj & 0x1f) << 6)
182134e026f9SYork Sun 			     | ((hs_wrlvl_start & 0x1f) << 0)
182234e026f9SYork Sun 			    );
182334e026f9SYork Sun 	debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6);
182434e026f9SYork Sun }
182534e026f9SYork Sun 
182634e026f9SYork Sun static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr,
182734e026f9SYork Sun 			const common_timing_params_t *common_dimm)
182834e026f9SYork Sun {
182934e026f9SYork Sun 	unsigned int txpr, tcksre, tcksrx;
183034e026f9SYork Sun 	unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd;
183134e026f9SYork Sun 
1832b4141195SMasahiro Yamada 	txpr = max(5U, picos_to_mclk(common_dimm->trfc1_ps + 10000));
1833b4141195SMasahiro Yamada 	tcksre = max(5U, picos_to_mclk(10000));
1834b4141195SMasahiro Yamada 	tcksrx = max(5U, picos_to_mclk(10000));
183534e026f9SYork Sun 	par_lat = 0;
183634e026f9SYork Sun 	cs_to_cmd = 0;
183734e026f9SYork Sun 
183834e026f9SYork Sun 	if (txpr <= 200)
183934e026f9SYork Sun 		cke_rst = 0;
184034e026f9SYork Sun 	else if (txpr <= 256)
184134e026f9SYork Sun 		cke_rst = 1;
184234e026f9SYork Sun 	else if (txpr <= 512)
184334e026f9SYork Sun 		cke_rst = 2;
184434e026f9SYork Sun 	else
184534e026f9SYork Sun 		cke_rst = 3;
184634e026f9SYork Sun 
184734e026f9SYork Sun 	if (tcksre <= 19)
184834e026f9SYork Sun 		cksre = tcksre - 5;
184934e026f9SYork Sun 	else
185034e026f9SYork Sun 		cksre = 15;
185134e026f9SYork Sun 
185234e026f9SYork Sun 	if (tcksrx <= 19)
185334e026f9SYork Sun 		cksrx = tcksrx - 5;
185434e026f9SYork Sun 	else
185534e026f9SYork Sun 		cksrx = 15;
185634e026f9SYork Sun 
185734e026f9SYork Sun 	ddr->timing_cfg_7 = (0
185834e026f9SYork Sun 			     | ((cke_rst & 0x3) << 28)
185934e026f9SYork Sun 			     | ((cksre & 0xf) << 24)
186034e026f9SYork Sun 			     | ((cksrx & 0xf) << 20)
186134e026f9SYork Sun 			     | ((par_lat & 0xf) << 16)
186234e026f9SYork Sun 			     | ((cs_to_cmd & 0xf) << 4)
186334e026f9SYork Sun 			    );
186434e026f9SYork Sun 	debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7);
186534e026f9SYork Sun }
186634e026f9SYork Sun 
186734e026f9SYork Sun static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr,
186834e026f9SYork Sun 			     const memctl_options_t *popts,
186934e026f9SYork Sun 			     const common_timing_params_t *common_dimm,
187034e026f9SYork Sun 			     unsigned int cas_latency)
187134e026f9SYork Sun {
187234e026f9SYork Sun 	unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg;
187334e026f9SYork Sun 	unsigned int acttoact_bg, wrtord_bg, pre_all_rec;
187434e026f9SYork Sun 	unsigned int tccdl = picos_to_mclk(common_dimm->tccdl_ps);
187534e026f9SYork Sun 	unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
187634e026f9SYork Sun 			      ((ddr->timing_cfg_2 & 0x00040000) >> 14);
187734e026f9SYork Sun 
187834e026f9SYork Sun 	rwt_bg = cas_latency + 2 + 4 - wr_lat;
187934e026f9SYork Sun 	if (rwt_bg < tccdl)
188034e026f9SYork Sun 		rwt_bg = tccdl - rwt_bg;
188134e026f9SYork Sun 	else
188234e026f9SYork Sun 		rwt_bg = 0;
188334e026f9SYork Sun 
188434e026f9SYork Sun 	wrt_bg = wr_lat + 4 + 1 - cas_latency;
188534e026f9SYork Sun 	if (wrt_bg < tccdl)
188634e026f9SYork Sun 		wrt_bg = tccdl - wrt_bg;
188734e026f9SYork Sun 	else
188834e026f9SYork Sun 		wrt_bg = 0;
188934e026f9SYork Sun 
189034e026f9SYork Sun 	if (popts->burst_length == DDR_BL8) {
189134e026f9SYork Sun 		rrt_bg = tccdl - 4;
189234e026f9SYork Sun 		wwt_bg = tccdl - 4;
189334e026f9SYork Sun 	} else {
189434e026f9SYork Sun 		rrt_bg = tccdl - 2;
189534e026f9SYork Sun 		wwt_bg = tccdl - 4;
189634e026f9SYork Sun 	}
189734e026f9SYork Sun 
189834e026f9SYork Sun 	acttoact_bg = picos_to_mclk(common_dimm->trrdl_ps);
1899b4141195SMasahiro Yamada 	wrtord_bg = max(4U, picos_to_mclk(7500));
19003d75ec95SYork Sun 	if (popts->otf_burst_chop_en)
19013d75ec95SYork Sun 		wrtord_bg += 2;
19023d75ec95SYork Sun 
190334e026f9SYork Sun 	pre_all_rec = 0;
190434e026f9SYork Sun 
190534e026f9SYork Sun 	ddr->timing_cfg_8 = (0
190634e026f9SYork Sun 			     | ((rwt_bg & 0xf) << 28)
190734e026f9SYork Sun 			     | ((wrt_bg & 0xf) << 24)
190834e026f9SYork Sun 			     | ((rrt_bg & 0xf) << 20)
190934e026f9SYork Sun 			     | ((wwt_bg & 0xf) << 16)
191034e026f9SYork Sun 			     | ((acttoact_bg & 0xf) << 12)
191134e026f9SYork Sun 			     | ((wrtord_bg & 0xf) << 8)
191234e026f9SYork Sun 			     | ((pre_all_rec & 0x1f) << 0)
191334e026f9SYork Sun 			    );
191434e026f9SYork Sun 
191534e026f9SYork Sun 	debug("FSLDDR: timing_cfg_8 = 0x%08x\n", ddr->timing_cfg_8);
191634e026f9SYork Sun }
191734e026f9SYork Sun 
191834e026f9SYork Sun static void set_timing_cfg_9(fsl_ddr_cfg_regs_t *ddr)
191934e026f9SYork Sun {
192034e026f9SYork Sun 	ddr->timing_cfg_9 = 0;
192134e026f9SYork Sun 	debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9);
192234e026f9SYork Sun }
192334e026f9SYork Sun 
1924f80d6472SYork Sun /* This function needs to be called after set_ddr_sdram_cfg() is called */
192534e026f9SYork Sun static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr,
192634e026f9SYork Sun 			       const dimm_params_t *dimm_params)
192734e026f9SYork Sun {
1928f80d6472SYork Sun 	unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1;
1929f80d6472SYork Sun 
193034e026f9SYork Sun 	ddr->dq_map_0 = ((dimm_params->dq_mapping[0] & 0x3F) << 26) |
193134e026f9SYork Sun 			((dimm_params->dq_mapping[1] & 0x3F) << 20) |
193234e026f9SYork Sun 			((dimm_params->dq_mapping[2] & 0x3F) << 14) |
193334e026f9SYork Sun 			((dimm_params->dq_mapping[3] & 0x3F) << 8) |
193434e026f9SYork Sun 			((dimm_params->dq_mapping[4] & 0x3F) << 2);
193534e026f9SYork Sun 
193634e026f9SYork Sun 	ddr->dq_map_1 = ((dimm_params->dq_mapping[5] & 0x3F) << 26) |
193734e026f9SYork Sun 			((dimm_params->dq_mapping[6] & 0x3F) << 20) |
193834e026f9SYork Sun 			((dimm_params->dq_mapping[7] & 0x3F) << 14) |
193934e026f9SYork Sun 			((dimm_params->dq_mapping[10] & 0x3F) << 8) |
194034e026f9SYork Sun 			((dimm_params->dq_mapping[11] & 0x3F) << 2);
194134e026f9SYork Sun 
194234e026f9SYork Sun 	ddr->dq_map_2 = ((dimm_params->dq_mapping[12] & 0x3F) << 26) |
194334e026f9SYork Sun 			((dimm_params->dq_mapping[13] & 0x3F) << 20) |
194434e026f9SYork Sun 			((dimm_params->dq_mapping[14] & 0x3F) << 14) |
194534e026f9SYork Sun 			((dimm_params->dq_mapping[15] & 0x3F) << 8) |
194634e026f9SYork Sun 			((dimm_params->dq_mapping[16] & 0x3F) << 2);
194734e026f9SYork Sun 
1948f80d6472SYork Sun 	/* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */
194934e026f9SYork Sun 	ddr->dq_map_3 = ((dimm_params->dq_mapping[17] & 0x3F) << 26) |
195034e026f9SYork Sun 			((dimm_params->dq_mapping[8] & 0x3F) << 20) |
1951f80d6472SYork Sun 			(acc_ecc_en ? 0 :
1952f80d6472SYork Sun 			 (dimm_params->dq_mapping[9] & 0x3F) << 14) |
195334e026f9SYork Sun 			dimm_params->dq_mapping_ors;
195434e026f9SYork Sun 
195534e026f9SYork Sun 	debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0);
195634e026f9SYork Sun 	debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1);
195734e026f9SYork Sun 	debug("FSLDDR: dq_map_2 = 0x%08x\n", ddr->dq_map_2);
195834e026f9SYork Sun 	debug("FSLDDR: dq_map_3 = 0x%08x\n", ddr->dq_map_3);
195934e026f9SYork Sun }
196034e026f9SYork Sun static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr,
196134e026f9SYork Sun 			       const memctl_options_t *popts)
196234e026f9SYork Sun {
196334e026f9SYork Sun 	int rd_pre;
196434e026f9SYork Sun 
196534e026f9SYork Sun 	rd_pre = popts->quad_rank_present ? 1 : 0;
196634e026f9SYork Sun 
196734e026f9SYork Sun 	ddr->ddr_sdram_cfg_3 = (rd_pre & 0x1) << 16;
196834e026f9SYork Sun 
196934e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3);
197034e026f9SYork Sun }
197134e026f9SYork Sun #endif	/* CONFIG_SYS_FSL_DDR4 */
197234e026f9SYork Sun 
19735614e71bSYork Sun /* DDR ZQ Calibration Control (DDR_ZQ_CNTL) */
19745614e71bSYork Sun static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en)
19755614e71bSYork Sun {
19765614e71bSYork Sun 	unsigned int zqinit = 0;/* POR ZQ Calibration Time (tZQinit) */
19775614e71bSYork Sun 	/* Normal Operation Full Calibration Time (tZQoper) */
19785614e71bSYork Sun 	unsigned int zqoper = 0;
19795614e71bSYork Sun 	/* Normal Operation Short Calibration Time (tZQCS) */
19805614e71bSYork Sun 	unsigned int zqcs = 0;
198134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
198234e026f9SYork Sun 	unsigned int zqcs_init;
198334e026f9SYork Sun #endif
19845614e71bSYork Sun 
19855614e71bSYork Sun 	if (zq_en) {
198634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
198734e026f9SYork Sun 		zqinit = 10;	/* 1024 clocks */
198834e026f9SYork Sun 		zqoper = 9;	/* 512 clocks */
198934e026f9SYork Sun 		zqcs = 7;	/* 128 clocks */
199034e026f9SYork Sun 		zqcs_init = 5;	/* 1024 refresh sequences */
199134e026f9SYork Sun #else
19925614e71bSYork Sun 		zqinit = 9;	/* 512 clocks */
19935614e71bSYork Sun 		zqoper = 8;	/* 256 clocks */
19945614e71bSYork Sun 		zqcs = 6;	/* 64 clocks */
199534e026f9SYork Sun #endif
19965614e71bSYork Sun 	}
19975614e71bSYork Sun 
19985614e71bSYork Sun 	ddr->ddr_zq_cntl = (0
19995614e71bSYork Sun 			    | ((zq_en & 0x1) << 31)
20005614e71bSYork Sun 			    | ((zqinit & 0xF) << 24)
20015614e71bSYork Sun 			    | ((zqoper & 0xF) << 16)
20025614e71bSYork Sun 			    | ((zqcs & 0xF) << 8)
200334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
200434e026f9SYork Sun 			    | ((zqcs_init & 0xF) << 0)
200534e026f9SYork Sun #endif
20065614e71bSYork Sun 			    );
20075614e71bSYork Sun 	debug("FSLDDR: zq_cntl = 0x%08x\n", ddr->ddr_zq_cntl);
20085614e71bSYork Sun }
20095614e71bSYork Sun 
20105614e71bSYork Sun /* DDR Write Leveling Control (DDR_WRLVL_CNTL) */
20115614e71bSYork Sun static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en,
20125614e71bSYork Sun 				const memctl_options_t *popts)
20135614e71bSYork Sun {
20145614e71bSYork Sun 	/*
20155614e71bSYork Sun 	 * First DQS pulse rising edge after margining mode
20165614e71bSYork Sun 	 * is programmed (tWL_MRD)
20175614e71bSYork Sun 	 */
20185614e71bSYork Sun 	unsigned int wrlvl_mrd = 0;
20195614e71bSYork Sun 	/* ODT delay after margining mode is programmed (tWL_ODTEN) */
20205614e71bSYork Sun 	unsigned int wrlvl_odten = 0;
20215614e71bSYork Sun 	/* DQS/DQS_ delay after margining mode is programmed (tWL_DQSEN) */
20225614e71bSYork Sun 	unsigned int wrlvl_dqsen = 0;
20235614e71bSYork Sun 	/* WRLVL_SMPL: Write leveling sample time */
20245614e71bSYork Sun 	unsigned int wrlvl_smpl = 0;
20255614e71bSYork Sun 	/* WRLVL_WLR: Write leveling repeition time */
20265614e71bSYork Sun 	unsigned int wrlvl_wlr = 0;
20275614e71bSYork Sun 	/* WRLVL_START: Write leveling start time */
20285614e71bSYork Sun 	unsigned int wrlvl_start = 0;
20295614e71bSYork Sun 
20305614e71bSYork Sun 	/* suggest enable write leveling for DDR3 due to fly-by topology */
20315614e71bSYork Sun 	if (wrlvl_en) {
20325614e71bSYork Sun 		/* tWL_MRD min = 40 nCK, we set it 64 */
20335614e71bSYork Sun 		wrlvl_mrd = 0x6;
20345614e71bSYork Sun 		/* tWL_ODTEN 128 */
20355614e71bSYork Sun 		wrlvl_odten = 0x7;
20365614e71bSYork Sun 		/* tWL_DQSEN min = 25 nCK, we set it 32 */
20375614e71bSYork Sun 		wrlvl_dqsen = 0x5;
20385614e71bSYork Sun 		/*
20395614e71bSYork Sun 		 * Write leveling sample time at least need 6 clocks
20405614e71bSYork Sun 		 * higher than tWLO to allow enough time for progagation
20415614e71bSYork Sun 		 * delay and sampling the prime data bits.
20425614e71bSYork Sun 		 */
20435614e71bSYork Sun 		wrlvl_smpl = 0xf;
20445614e71bSYork Sun 		/*
20455614e71bSYork Sun 		 * Write leveling repetition time
20465614e71bSYork Sun 		 * at least tWLO + 6 clocks clocks
20475614e71bSYork Sun 		 * we set it 64
20485614e71bSYork Sun 		 */
20495614e71bSYork Sun 		wrlvl_wlr = 0x6;
20505614e71bSYork Sun 		/*
20515614e71bSYork Sun 		 * Write leveling start time
20525614e71bSYork Sun 		 * The value use for the DQS_ADJUST for the first sample
20535614e71bSYork Sun 		 * when write leveling is enabled. It probably needs to be
20545614e71bSYork Sun 		 * overriden per platform.
20555614e71bSYork Sun 		 */
20565614e71bSYork Sun 		wrlvl_start = 0x8;
20575614e71bSYork Sun 		/*
20585614e71bSYork Sun 		 * Override the write leveling sample and start time
20595614e71bSYork Sun 		 * according to specific board
20605614e71bSYork Sun 		 */
20615614e71bSYork Sun 		if (popts->wrlvl_override) {
20625614e71bSYork Sun 			wrlvl_smpl = popts->wrlvl_sample;
20635614e71bSYork Sun 			wrlvl_start = popts->wrlvl_start;
20645614e71bSYork Sun 		}
20655614e71bSYork Sun 	}
20665614e71bSYork Sun 
20675614e71bSYork Sun 	ddr->ddr_wrlvl_cntl = (0
20685614e71bSYork Sun 			       | ((wrlvl_en & 0x1) << 31)
20695614e71bSYork Sun 			       | ((wrlvl_mrd & 0x7) << 24)
20705614e71bSYork Sun 			       | ((wrlvl_odten & 0x7) << 20)
20715614e71bSYork Sun 			       | ((wrlvl_dqsen & 0x7) << 16)
20725614e71bSYork Sun 			       | ((wrlvl_smpl & 0xf) << 12)
20735614e71bSYork Sun 			       | ((wrlvl_wlr & 0x7) << 8)
20745614e71bSYork Sun 			       | ((wrlvl_start & 0x1F) << 0)
20755614e71bSYork Sun 			       );
20765614e71bSYork Sun 	debug("FSLDDR: wrlvl_cntl = 0x%08x\n", ddr->ddr_wrlvl_cntl);
20775614e71bSYork Sun 	ddr->ddr_wrlvl_cntl_2 = popts->wrlvl_ctl_2;
20785614e71bSYork Sun 	debug("FSLDDR: wrlvl_cntl_2 = 0x%08x\n", ddr->ddr_wrlvl_cntl_2);
20795614e71bSYork Sun 	ddr->ddr_wrlvl_cntl_3 = popts->wrlvl_ctl_3;
20805614e71bSYork Sun 	debug("FSLDDR: wrlvl_cntl_3 = 0x%08x\n", ddr->ddr_wrlvl_cntl_3);
20815614e71bSYork Sun 
20825614e71bSYork Sun }
20835614e71bSYork Sun 
20845614e71bSYork Sun /* DDR Self Refresh Counter (DDR_SR_CNTR) */
20855614e71bSYork Sun static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it)
20865614e71bSYork Sun {
20875614e71bSYork Sun 	/* Self Refresh Idle Threshold */
20885614e71bSYork Sun 	ddr->ddr_sr_cntr = (sr_it & 0xF) << 16;
20895614e71bSYork Sun }
20905614e71bSYork Sun 
20915614e71bSYork Sun static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
20925614e71bSYork Sun {
20935614e71bSYork Sun 	if (popts->addr_hash) {
20945614e71bSYork Sun 		ddr->ddr_eor = 0x40000000;	/* address hash enable */
20955614e71bSYork Sun 		puts("Address hashing enabled.\n");
20965614e71bSYork Sun 	}
20975614e71bSYork Sun }
20985614e71bSYork Sun 
20995614e71bSYork Sun static void set_ddr_cdr1(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
21005614e71bSYork Sun {
21015614e71bSYork Sun 	ddr->ddr_cdr1 = popts->ddr_cdr1;
21025614e71bSYork Sun 	debug("FSLDDR: ddr_cdr1 = 0x%08x\n", ddr->ddr_cdr1);
21035614e71bSYork Sun }
21045614e71bSYork Sun 
21055614e71bSYork Sun static void set_ddr_cdr2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
21065614e71bSYork Sun {
21075614e71bSYork Sun 	ddr->ddr_cdr2 = popts->ddr_cdr2;
21085614e71bSYork Sun 	debug("FSLDDR: ddr_cdr2 = 0x%08x\n", ddr->ddr_cdr2);
21095614e71bSYork Sun }
21105614e71bSYork Sun 
21115614e71bSYork Sun unsigned int
21125614e71bSYork Sun check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
21135614e71bSYork Sun {
21145614e71bSYork Sun 	unsigned int res = 0;
21155614e71bSYork Sun 
21165614e71bSYork Sun 	/*
21175614e71bSYork Sun 	 * Check that DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] are
21185614e71bSYork Sun 	 * not set at the same time.
21195614e71bSYork Sun 	 */
21205614e71bSYork Sun 	if (ddr->ddr_sdram_cfg & 0x10000000
21215614e71bSYork Sun 	    && ddr->ddr_sdram_cfg & 0x00008000) {
21225614e71bSYork Sun 		printf("Error: DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] "
21235614e71bSYork Sun 				" should not be set at the same time.\n");
21245614e71bSYork Sun 		res++;
21255614e71bSYork Sun 	}
21265614e71bSYork Sun 
21275614e71bSYork Sun 	return res;
21285614e71bSYork Sun }
21295614e71bSYork Sun 
21305614e71bSYork Sun unsigned int
21315614e71bSYork Sun compute_fsl_memctl_config_regs(const memctl_options_t *popts,
21325614e71bSYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
21335614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
21345614e71bSYork Sun 			       const dimm_params_t *dimm_params,
21355614e71bSYork Sun 			       unsigned int dbw_cap_adj,
21365614e71bSYork Sun 			       unsigned int size_only)
21375614e71bSYork Sun {
21385614e71bSYork Sun 	unsigned int i;
21395614e71bSYork Sun 	unsigned int cas_latency;
21405614e71bSYork Sun 	unsigned int additive_latency;
21415614e71bSYork Sun 	unsigned int sr_it;
21425614e71bSYork Sun 	unsigned int zq_en;
21435614e71bSYork Sun 	unsigned int wrlvl_en;
21445614e71bSYork Sun 	unsigned int ip_rev = 0;
21455614e71bSYork Sun 	unsigned int unq_mrs_en = 0;
21465614e71bSYork Sun 	int cs_en = 1;
21475614e71bSYork Sun 
21485614e71bSYork Sun 	memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t));
21495614e71bSYork Sun 
21505614e71bSYork Sun 	if (common_dimm == NULL) {
21515614e71bSYork Sun 		printf("Error: subset DIMM params struct null pointer\n");
21525614e71bSYork Sun 		return 1;
21535614e71bSYork Sun 	}
21545614e71bSYork Sun 
21555614e71bSYork Sun 	/*
21565614e71bSYork Sun 	 * Process overrides first.
21575614e71bSYork Sun 	 *
21585614e71bSYork Sun 	 * FIXME: somehow add dereated caslat to this
21595614e71bSYork Sun 	 */
21605614e71bSYork Sun 	cas_latency = (popts->cas_latency_override)
21615614e71bSYork Sun 		? popts->cas_latency_override_value
216234e026f9SYork Sun 		: common_dimm->lowest_common_spd_caslat;
21635614e71bSYork Sun 
21645614e71bSYork Sun 	additive_latency = (popts->additive_latency_override)
21655614e71bSYork Sun 		? popts->additive_latency_override_value
21665614e71bSYork Sun 		: common_dimm->additive_latency;
21675614e71bSYork Sun 
21685614e71bSYork Sun 	sr_it = (popts->auto_self_refresh_en)
21695614e71bSYork Sun 		? popts->sr_it
21705614e71bSYork Sun 		: 0;
21715614e71bSYork Sun 	/* ZQ calibration */
21725614e71bSYork Sun 	zq_en = (popts->zq_en) ? 1 : 0;
21735614e71bSYork Sun 	/* write leveling */
21745614e71bSYork Sun 	wrlvl_en = (popts->wrlvl_en) ? 1 : 0;
21755614e71bSYork Sun 
21765614e71bSYork Sun 	/* Chip Select Memory Bounds (CSn_BNDS) */
21775614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
21785614e71bSYork Sun 		unsigned long long ea, sa;
21795614e71bSYork Sun 		unsigned int cs_per_dimm
21805614e71bSYork Sun 			= CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR;
21815614e71bSYork Sun 		unsigned int dimm_number
21825614e71bSYork Sun 			= i / cs_per_dimm;
21835614e71bSYork Sun 		unsigned long long rank_density
21845614e71bSYork Sun 			= dimm_params[dimm_number].rank_density >> dbw_cap_adj;
21855614e71bSYork Sun 
21865614e71bSYork Sun 		if (dimm_params[dimm_number].n_ranks == 0) {
21875614e71bSYork Sun 			debug("Skipping setup of CS%u "
21885614e71bSYork Sun 				"because n_ranks on DIMM %u is 0\n", i, dimm_number);
21895614e71bSYork Sun 			continue;
21905614e71bSYork Sun 		}
21915614e71bSYork Sun 		if (popts->memctl_interleaving) {
21925614e71bSYork Sun 			switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
21935614e71bSYork Sun 			case FSL_DDR_CS0_CS1_CS2_CS3:
21945614e71bSYork Sun 				break;
21955614e71bSYork Sun 			case FSL_DDR_CS0_CS1:
21965614e71bSYork Sun 			case FSL_DDR_CS0_CS1_AND_CS2_CS3:
21975614e71bSYork Sun 				if (i > 1)
21985614e71bSYork Sun 					cs_en = 0;
21995614e71bSYork Sun 				break;
22005614e71bSYork Sun 			case FSL_DDR_CS2_CS3:
22015614e71bSYork Sun 			default:
22025614e71bSYork Sun 				if (i > 0)
22035614e71bSYork Sun 					cs_en = 0;
22045614e71bSYork Sun 				break;
22055614e71bSYork Sun 			}
22065614e71bSYork Sun 			sa = common_dimm->base_address;
22075614e71bSYork Sun 			ea = sa + common_dimm->total_mem - 1;
22085614e71bSYork Sun 		} else if (!popts->memctl_interleaving) {
22095614e71bSYork Sun 			/*
22105614e71bSYork Sun 			 * If memory interleaving between controllers is NOT
22115614e71bSYork Sun 			 * enabled, the starting address for each memory
22125614e71bSYork Sun 			 * controller is distinct.  However, because rank
22135614e71bSYork Sun 			 * interleaving is enabled, the starting and ending
22145614e71bSYork Sun 			 * addresses of the total memory on that memory
22155614e71bSYork Sun 			 * controller needs to be programmed into its
22165614e71bSYork Sun 			 * respective CS0_BNDS.
22175614e71bSYork Sun 			 */
22185614e71bSYork Sun 			switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
22195614e71bSYork Sun 			case FSL_DDR_CS0_CS1_CS2_CS3:
22205614e71bSYork Sun 				sa = common_dimm->base_address;
22215614e71bSYork Sun 				ea = sa + common_dimm->total_mem - 1;
22225614e71bSYork Sun 				break;
22235614e71bSYork Sun 			case FSL_DDR_CS0_CS1_AND_CS2_CS3:
22245614e71bSYork Sun 				if ((i >= 2) && (dimm_number == 0)) {
22255614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address +
22265614e71bSYork Sun 					      2 * rank_density;
22275614e71bSYork Sun 					ea = sa + 2 * rank_density - 1;
22285614e71bSYork Sun 				} else {
22295614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address;
22305614e71bSYork Sun 					ea = sa + 2 * rank_density - 1;
22315614e71bSYork Sun 				}
22325614e71bSYork Sun 				break;
22335614e71bSYork Sun 			case FSL_DDR_CS0_CS1:
22345614e71bSYork Sun 				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
22355614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address;
22365614e71bSYork Sun 					ea = sa + rank_density - 1;
22375614e71bSYork Sun 					if (i != 1)
22385614e71bSYork Sun 						sa += (i % cs_per_dimm) * rank_density;
22395614e71bSYork Sun 					ea += (i % cs_per_dimm) * rank_density;
22405614e71bSYork Sun 				} else {
22415614e71bSYork Sun 					sa = 0;
22425614e71bSYork Sun 					ea = 0;
22435614e71bSYork Sun 				}
22445614e71bSYork Sun 				if (i == 0)
22455614e71bSYork Sun 					ea += rank_density;
22465614e71bSYork Sun 				break;
22475614e71bSYork Sun 			case FSL_DDR_CS2_CS3:
22485614e71bSYork Sun 				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
22495614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address;
22505614e71bSYork Sun 					ea = sa + rank_density - 1;
22515614e71bSYork Sun 					if (i != 3)
22525614e71bSYork Sun 						sa += (i % cs_per_dimm) * rank_density;
22535614e71bSYork Sun 					ea += (i % cs_per_dimm) * rank_density;
22545614e71bSYork Sun 				} else {
22555614e71bSYork Sun 					sa = 0;
22565614e71bSYork Sun 					ea = 0;
22575614e71bSYork Sun 				}
22585614e71bSYork Sun 				if (i == 2)
22595614e71bSYork Sun 					ea += (rank_density >> dbw_cap_adj);
22605614e71bSYork Sun 				break;
22615614e71bSYork Sun 			default:  /* No bank(chip-select) interleaving */
22625614e71bSYork Sun 				sa = dimm_params[dimm_number].base_address;
22635614e71bSYork Sun 				ea = sa + rank_density - 1;
22645614e71bSYork Sun 				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
22655614e71bSYork Sun 					sa += (i % cs_per_dimm) * rank_density;
22665614e71bSYork Sun 					ea += (i % cs_per_dimm) * rank_density;
22675614e71bSYork Sun 				} else {
22685614e71bSYork Sun 					sa = 0;
22695614e71bSYork Sun 					ea = 0;
22705614e71bSYork Sun 				}
22715614e71bSYork Sun 				break;
22725614e71bSYork Sun 			}
22735614e71bSYork Sun 		}
22745614e71bSYork Sun 
22755614e71bSYork Sun 		sa >>= 24;
22765614e71bSYork Sun 		ea >>= 24;
22775614e71bSYork Sun 
22785614e71bSYork Sun 		if (cs_en) {
22795614e71bSYork Sun 			ddr->cs[i].bnds = (0
2280d4263b8aSYork Sun 				| ((sa & 0xffff) << 16) /* starting address */
2281d4263b8aSYork Sun 				| ((ea & 0xffff) << 0)	/* ending address */
22825614e71bSYork Sun 				);
22835614e71bSYork Sun 		} else {
22845614e71bSYork Sun 			/* setting bnds to 0xffffffff for inactive CS */
22855614e71bSYork Sun 			ddr->cs[i].bnds = 0xffffffff;
22865614e71bSYork Sun 		}
22875614e71bSYork Sun 
22885614e71bSYork Sun 		debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds);
22895614e71bSYork Sun 		set_csn_config(dimm_number, i, ddr, popts, dimm_params);
22905614e71bSYork Sun 		set_csn_config_2(i, ddr);
22915614e71bSYork Sun 	}
22925614e71bSYork Sun 
22935614e71bSYork Sun 	/*
22945614e71bSYork Sun 	 * In the case we only need to compute the ddr sdram size, we only need
22955614e71bSYork Sun 	 * to set csn registers, so return from here.
22965614e71bSYork Sun 	 */
22975614e71bSYork Sun 	if (size_only)
22985614e71bSYork Sun 		return 0;
22995614e71bSYork Sun 
23005614e71bSYork Sun 	set_ddr_eor(ddr, popts);
23015614e71bSYork Sun 
23025614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1)
23035614e71bSYork Sun 	set_timing_cfg_0(ddr, popts, dimm_params);
23045614e71bSYork Sun #endif
23055614e71bSYork Sun 
2306d4263b8aSYork Sun 	set_timing_cfg_3(ddr, popts, common_dimm, cas_latency,
2307d4263b8aSYork Sun 			 additive_latency);
23085614e71bSYork Sun 	set_timing_cfg_1(ddr, popts, common_dimm, cas_latency);
23095614e71bSYork Sun 	set_timing_cfg_2(ddr, popts, common_dimm,
23105614e71bSYork Sun 				cas_latency, additive_latency);
23115614e71bSYork Sun 
23125614e71bSYork Sun 	set_ddr_cdr1(ddr, popts);
23135614e71bSYork Sun 	set_ddr_cdr2(ddr, popts);
23145614e71bSYork Sun 	set_ddr_sdram_cfg(ddr, popts, common_dimm);
23155614e71bSYork Sun 	ip_rev = fsl_ddr_get_version();
23165614e71bSYork Sun 	if (ip_rev > 0x40400)
23175614e71bSYork Sun 		unq_mrs_en = 1;
23185614e71bSYork Sun 
2319f80d6472SYork Sun 	if ((ip_rev > 0x40700) && (popts->cswl_override != 0))
2320ef87cab6SYork Sun 		ddr->debug[18] = popts->cswl_override;
2321ef87cab6SYork Sun 
23225614e71bSYork Sun 	set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en);
23235614e71bSYork Sun 	set_ddr_sdram_mode(ddr, popts, common_dimm,
23245614e71bSYork Sun 				cas_latency, additive_latency, unq_mrs_en);
23255614e71bSYork Sun 	set_ddr_sdram_mode_2(ddr, popts, common_dimm, unq_mrs_en);
232634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
232734e026f9SYork Sun 	set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en);
232834e026f9SYork Sun 	set_ddr_sdram_mode_10(ddr, popts, common_dimm, unq_mrs_en);
232934e026f9SYork Sun #endif
23305614e71bSYork Sun 	set_ddr_sdram_interval(ddr, popts, common_dimm);
23315614e71bSYork Sun 	set_ddr_data_init(ddr);
23325614e71bSYork Sun 	set_ddr_sdram_clk_cntl(ddr, popts);
23335614e71bSYork Sun 	set_ddr_init_addr(ddr);
23345614e71bSYork Sun 	set_ddr_init_ext_addr(ddr);
23355614e71bSYork Sun 	set_timing_cfg_4(ddr, popts);
23365614e71bSYork Sun 	set_timing_cfg_5(ddr, cas_latency);
233734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
233834e026f9SYork Sun 	set_ddr_sdram_cfg_3(ddr, popts);
233934e026f9SYork Sun 	set_timing_cfg_6(ddr);
234034e026f9SYork Sun 	set_timing_cfg_7(ddr, common_dimm);
234134e026f9SYork Sun 	set_timing_cfg_8(ddr, popts, common_dimm, cas_latency);
234234e026f9SYork Sun 	set_timing_cfg_9(ddr);
234334e026f9SYork Sun 	set_ddr_dq_mapping(ddr, dimm_params);
234434e026f9SYork Sun #endif
23455614e71bSYork Sun 
23465614e71bSYork Sun 	set_ddr_zq_cntl(ddr, zq_en);
23475614e71bSYork Sun 	set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts);
23485614e71bSYork Sun 
23495614e71bSYork Sun 	set_ddr_sr_cntr(ddr, sr_it);
23505614e71bSYork Sun 
23515614e71bSYork Sun 	set_ddr_sdram_rcw(ddr, popts, common_dimm);
23525614e71bSYork Sun 
23535614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR_EMU
23545614e71bSYork Sun 	/* disble DDR training for emulator */
23555614e71bSYork Sun 	ddr->debug[2] = 0x00000400;
23565614e71bSYork Sun 	ddr->debug[4] = 0xff800000;
23575614e71bSYork Sun #endif
23589855b3beSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_A004508
23599855b3beSYork Sun 	if ((ip_rev >= 0x40000) && (ip_rev < 0x40400))
23609855b3beSYork Sun 		ddr->debug[2] |= 0x00000200;	/* set bit 22 */
23619855b3beSYork Sun #endif
23629855b3beSYork Sun 
23635614e71bSYork Sun 	return check_fsl_memctl_config_regs(ddr);
23645614e71bSYork Sun }
2365