xref: /openbmc/u-boot/drivers/ddr/fsl/ctrl_regs.c (revision 6c6e006a2083f2da7b4f66c6bb82ce8b3fb713a3)
15614e71bSYork Sun /*
234e026f9SYork Sun  * Copyright 2008-2014 Freescale Semiconductor, Inc.
35614e71bSYork Sun  *
45614e71bSYork Sun  * SPDX-License-Identifier:	GPL-2.0+
55614e71bSYork Sun  */
65614e71bSYork Sun 
75614e71bSYork Sun /*
85614e71bSYork Sun  * Generic driver for Freescale DDR/DDR2/DDR3 memory controller.
95614e71bSYork Sun  * Based on code from spd_sdram.c
105614e71bSYork Sun  * Author: James Yang [at freescale.com]
115614e71bSYork Sun  */
125614e71bSYork Sun 
135614e71bSYork Sun #include <common.h>
145614e71bSYork Sun #include <fsl_ddr_sdram.h>
155614e71bSYork Sun 
165614e71bSYork Sun #include <fsl_ddr.h>
179a17eb5bSYork Sun #include <fsl_immap.h>
185614e71bSYork Sun #include <asm/io.h>
195614e71bSYork Sun 
205614e71bSYork Sun /*
215614e71bSYork Sun  * Determine Rtt value.
225614e71bSYork Sun  *
235614e71bSYork Sun  * This should likely be either board or controller specific.
245614e71bSYork Sun  *
255614e71bSYork Sun  * Rtt(nominal) - DDR2:
265614e71bSYork Sun  *	0 = Rtt disabled
275614e71bSYork Sun  *	1 = 75 ohm
285614e71bSYork Sun  *	2 = 150 ohm
295614e71bSYork Sun  *	3 = 50 ohm
305614e71bSYork Sun  * Rtt(nominal) - DDR3:
315614e71bSYork Sun  *	0 = Rtt disabled
325614e71bSYork Sun  *	1 = 60 ohm
335614e71bSYork Sun  *	2 = 120 ohm
345614e71bSYork Sun  *	3 = 40 ohm
355614e71bSYork Sun  *	4 = 20 ohm
365614e71bSYork Sun  *	5 = 30 ohm
375614e71bSYork Sun  *
385614e71bSYork Sun  * FIXME: Apparently 8641 needs a value of 2
395614e71bSYork Sun  * FIXME: Old code seys if 667 MHz or higher, use 3 on 8572
405614e71bSYork Sun  *
415614e71bSYork Sun  * FIXME: There was some effort down this line earlier:
425614e71bSYork Sun  *
435614e71bSYork Sun  *	unsigned int i;
445614e71bSYork Sun  *	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL/2; i++) {
455614e71bSYork Sun  *		if (popts->dimmslot[i].num_valid_cs
465614e71bSYork Sun  *		    && (popts->cs_local_opts[2*i].odt_rd_cfg
475614e71bSYork Sun  *			|| popts->cs_local_opts[2*i].odt_wr_cfg)) {
485614e71bSYork Sun  *			rtt = 2;
495614e71bSYork Sun  *			break;
505614e71bSYork Sun  *		}
515614e71bSYork Sun  *	}
525614e71bSYork Sun  */
535614e71bSYork Sun static inline int fsl_ddr_get_rtt(void)
545614e71bSYork Sun {
555614e71bSYork Sun 	int rtt;
565614e71bSYork Sun 
575614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
585614e71bSYork Sun 	rtt = 0;
595614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
605614e71bSYork Sun 	rtt = 3;
615614e71bSYork Sun #else
625614e71bSYork Sun 	rtt = 0;
635614e71bSYork Sun #endif
645614e71bSYork Sun 
655614e71bSYork Sun 	return rtt;
665614e71bSYork Sun }
675614e71bSYork Sun 
6834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
6934e026f9SYork Sun /*
7034e026f9SYork Sun  * compute CAS write latency according to DDR4 spec
7134e026f9SYork Sun  * CWL = 9 for <= 1600MT/s
7234e026f9SYork Sun  *       10 for <= 1866MT/s
7334e026f9SYork Sun  *       11 for <= 2133MT/s
7434e026f9SYork Sun  *       12 for <= 2400MT/s
7534e026f9SYork Sun  *       14 for <= 2667MT/s
7634e026f9SYork Sun  *       16 for <= 2933MT/s
7734e026f9SYork Sun  *       18 for higher
7834e026f9SYork Sun  */
7903e664d8SYork Sun static inline unsigned int compute_cas_write_latency(
8003e664d8SYork Sun 				const unsigned int ctrl_num)
8134e026f9SYork Sun {
8234e026f9SYork Sun 	unsigned int cwl;
8303e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
8434e026f9SYork Sun 	if (mclk_ps >= 1250)
8534e026f9SYork Sun 		cwl = 9;
8634e026f9SYork Sun 	else if (mclk_ps >= 1070)
8734e026f9SYork Sun 		cwl = 10;
8834e026f9SYork Sun 	else if (mclk_ps >= 935)
8934e026f9SYork Sun 		cwl = 11;
9034e026f9SYork Sun 	else if (mclk_ps >= 833)
9134e026f9SYork Sun 		cwl = 12;
9234e026f9SYork Sun 	else if (mclk_ps >= 750)
9334e026f9SYork Sun 		cwl = 14;
9434e026f9SYork Sun 	else if (mclk_ps >= 681)
9534e026f9SYork Sun 		cwl = 16;
9634e026f9SYork Sun 	else
9734e026f9SYork Sun 		cwl = 18;
9834e026f9SYork Sun 
9934e026f9SYork Sun 	return cwl;
10034e026f9SYork Sun }
10134e026f9SYork Sun #else
1025614e71bSYork Sun /*
1035614e71bSYork Sun  * compute the CAS write latency according to DDR3 spec
1045614e71bSYork Sun  * CWL = 5 if tCK >= 2.5ns
1055614e71bSYork Sun  *       6 if 2.5ns > tCK >= 1.875ns
1065614e71bSYork Sun  *       7 if 1.875ns > tCK >= 1.5ns
1075614e71bSYork Sun  *       8 if 1.5ns > tCK >= 1.25ns
1085614e71bSYork Sun  *       9 if 1.25ns > tCK >= 1.07ns
1095614e71bSYork Sun  *       10 if 1.07ns > tCK >= 0.935ns
1105614e71bSYork Sun  *       11 if 0.935ns > tCK >= 0.833ns
1115614e71bSYork Sun  *       12 if 0.833ns > tCK >= 0.75ns
1125614e71bSYork Sun  */
11303e664d8SYork Sun static inline unsigned int compute_cas_write_latency(
11403e664d8SYork Sun 				const unsigned int ctrl_num)
1155614e71bSYork Sun {
1165614e71bSYork Sun 	unsigned int cwl;
11703e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
1185614e71bSYork Sun 
1195614e71bSYork Sun 	if (mclk_ps >= 2500)
1205614e71bSYork Sun 		cwl = 5;
1215614e71bSYork Sun 	else if (mclk_ps >= 1875)
1225614e71bSYork Sun 		cwl = 6;
1235614e71bSYork Sun 	else if (mclk_ps >= 1500)
1245614e71bSYork Sun 		cwl = 7;
1255614e71bSYork Sun 	else if (mclk_ps >= 1250)
1265614e71bSYork Sun 		cwl = 8;
1275614e71bSYork Sun 	else if (mclk_ps >= 1070)
1285614e71bSYork Sun 		cwl = 9;
1295614e71bSYork Sun 	else if (mclk_ps >= 935)
1305614e71bSYork Sun 		cwl = 10;
1315614e71bSYork Sun 	else if (mclk_ps >= 833)
1325614e71bSYork Sun 		cwl = 11;
1335614e71bSYork Sun 	else if (mclk_ps >= 750)
1345614e71bSYork Sun 		cwl = 12;
1355614e71bSYork Sun 	else {
1365614e71bSYork Sun 		cwl = 12;
1375614e71bSYork Sun 		printf("Warning: CWL is out of range\n");
1385614e71bSYork Sun 	}
1395614e71bSYork Sun 	return cwl;
1405614e71bSYork Sun }
14134e026f9SYork Sun #endif
1425614e71bSYork Sun 
1435614e71bSYork Sun /* Chip Select Configuration (CSn_CONFIG) */
1445614e71bSYork Sun static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr,
1455614e71bSYork Sun 			       const memctl_options_t *popts,
1465614e71bSYork Sun 			       const dimm_params_t *dimm_params)
1475614e71bSYork Sun {
1485614e71bSYork Sun 	unsigned int cs_n_en = 0; /* Chip Select enable */
1495614e71bSYork Sun 	unsigned int intlv_en = 0; /* Memory controller interleave enable */
1505614e71bSYork Sun 	unsigned int intlv_ctl = 0; /* Interleaving control */
1515614e71bSYork Sun 	unsigned int ap_n_en = 0; /* Chip select n auto-precharge enable */
1525614e71bSYork Sun 	unsigned int odt_rd_cfg = 0; /* ODT for reads configuration */
1535614e71bSYork Sun 	unsigned int odt_wr_cfg = 0; /* ODT for writes configuration */
1545614e71bSYork Sun 	unsigned int ba_bits_cs_n = 0; /* Num of bank bits for SDRAM on CSn */
1555614e71bSYork Sun 	unsigned int row_bits_cs_n = 0; /* Num of row bits for SDRAM on CSn */
1565614e71bSYork Sun 	unsigned int col_bits_cs_n = 0; /* Num of ocl bits for SDRAM on CSn */
1575614e71bSYork Sun 	int go_config = 0;
15834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
15934e026f9SYork Sun 	unsigned int bg_bits_cs_n = 0; /* Num of bank group bits */
16034e026f9SYork Sun #else
16134e026f9SYork Sun 	unsigned int n_banks_per_sdram_device;
16234e026f9SYork Sun #endif
1635614e71bSYork Sun 
1645614e71bSYork Sun 	/* Compute CS_CONFIG only for existing ranks of each DIMM.  */
1655614e71bSYork Sun 	switch (i) {
1665614e71bSYork Sun 	case 0:
1675614e71bSYork Sun 		if (dimm_params[dimm_number].n_ranks > 0) {
1685614e71bSYork Sun 			go_config = 1;
1695614e71bSYork Sun 			/* These fields only available in CS0_CONFIG */
1705614e71bSYork Sun 			if (!popts->memctl_interleaving)
1715614e71bSYork Sun 				break;
1725614e71bSYork Sun 			switch (popts->memctl_interleaving_mode) {
1736b1e1254SYork Sun 			case FSL_DDR_256B_INTERLEAVING:
1745614e71bSYork Sun 			case FSL_DDR_CACHE_LINE_INTERLEAVING:
1755614e71bSYork Sun 			case FSL_DDR_PAGE_INTERLEAVING:
1765614e71bSYork Sun 			case FSL_DDR_BANK_INTERLEAVING:
1775614e71bSYork Sun 			case FSL_DDR_SUPERBANK_INTERLEAVING:
1785614e71bSYork Sun 				intlv_en = popts->memctl_interleaving;
1795614e71bSYork Sun 				intlv_ctl = popts->memctl_interleaving_mode;
1805614e71bSYork Sun 				break;
1815614e71bSYork Sun 			default:
1825614e71bSYork Sun 				break;
1835614e71bSYork Sun 			}
1845614e71bSYork Sun 		}
1855614e71bSYork Sun 		break;
1865614e71bSYork Sun 	case 1:
1875614e71bSYork Sun 		if ((dimm_number == 0 && dimm_params[0].n_ranks > 1) || \
1885614e71bSYork Sun 		    (dimm_number == 1 && dimm_params[1].n_ranks > 0))
1895614e71bSYork Sun 			go_config = 1;
1905614e71bSYork Sun 		break;
1915614e71bSYork Sun 	case 2:
1925614e71bSYork Sun 		if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \
1935614e71bSYork Sun 		   (dimm_number >= 1 && dimm_params[dimm_number].n_ranks > 0))
1945614e71bSYork Sun 			go_config = 1;
1955614e71bSYork Sun 		break;
1965614e71bSYork Sun 	case 3:
1975614e71bSYork Sun 		if ((dimm_number == 0 && dimm_params[0].n_ranks > 3) || \
1985614e71bSYork Sun 		    (dimm_number == 1 && dimm_params[1].n_ranks > 1) || \
1995614e71bSYork Sun 		    (dimm_number == 3 && dimm_params[3].n_ranks > 0))
2005614e71bSYork Sun 			go_config = 1;
2015614e71bSYork Sun 		break;
2025614e71bSYork Sun 	default:
2035614e71bSYork Sun 		break;
2045614e71bSYork Sun 	}
2055614e71bSYork Sun 	if (go_config) {
2065614e71bSYork Sun 		cs_n_en = 1;
2075614e71bSYork Sun 		ap_n_en = popts->cs_local_opts[i].auto_precharge;
2085614e71bSYork Sun 		odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg;
2095614e71bSYork Sun 		odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg;
21034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
21134e026f9SYork Sun 		ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits;
21234e026f9SYork Sun 		bg_bits_cs_n = dimm_params[dimm_number].bank_group_bits;
21334e026f9SYork Sun #else
2145614e71bSYork Sun 		n_banks_per_sdram_device
2155614e71bSYork Sun 			= dimm_params[dimm_number].n_banks_per_sdram_device;
2165614e71bSYork Sun 		ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2;
21734e026f9SYork Sun #endif
2185614e71bSYork Sun 		row_bits_cs_n = dimm_params[dimm_number].n_row_addr - 12;
2195614e71bSYork Sun 		col_bits_cs_n = dimm_params[dimm_number].n_col_addr - 8;
2205614e71bSYork Sun 	}
2215614e71bSYork Sun 	ddr->cs[i].config = (0
2225614e71bSYork Sun 		| ((cs_n_en & 0x1) << 31)
2235614e71bSYork Sun 		| ((intlv_en & 0x3) << 29)
2245614e71bSYork Sun 		| ((intlv_ctl & 0xf) << 24)
2255614e71bSYork Sun 		| ((ap_n_en & 0x1) << 23)
2265614e71bSYork Sun 
2275614e71bSYork Sun 		/* XXX: some implementation only have 1 bit starting at left */
2285614e71bSYork Sun 		| ((odt_rd_cfg & 0x7) << 20)
2295614e71bSYork Sun 
2305614e71bSYork Sun 		/* XXX: Some implementation only have 1 bit starting at left */
2315614e71bSYork Sun 		| ((odt_wr_cfg & 0x7) << 16)
2325614e71bSYork Sun 
2335614e71bSYork Sun 		| ((ba_bits_cs_n & 0x3) << 14)
2345614e71bSYork Sun 		| ((row_bits_cs_n & 0x7) << 8)
23534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
23634e026f9SYork Sun 		| ((bg_bits_cs_n & 0x3) << 4)
23734e026f9SYork Sun #endif
2385614e71bSYork Sun 		| ((col_bits_cs_n & 0x7) << 0)
2395614e71bSYork Sun 		);
2405614e71bSYork Sun 	debug("FSLDDR: cs[%d]_config = 0x%08x\n", i,ddr->cs[i].config);
2415614e71bSYork Sun }
2425614e71bSYork Sun 
2435614e71bSYork Sun /* Chip Select Configuration 2 (CSn_CONFIG_2) */
2445614e71bSYork Sun /* FIXME: 8572 */
2455614e71bSYork Sun static void set_csn_config_2(int i, fsl_ddr_cfg_regs_t *ddr)
2465614e71bSYork Sun {
2475614e71bSYork Sun 	unsigned int pasr_cfg = 0;	/* Partial array self refresh config */
2485614e71bSYork Sun 
2495614e71bSYork Sun 	ddr->cs[i].config_2 = ((pasr_cfg & 7) << 24);
2505614e71bSYork Sun 	debug("FSLDDR: cs[%d]_config_2 = 0x%08x\n", i, ddr->cs[i].config_2);
2515614e71bSYork Sun }
2525614e71bSYork Sun 
2535614e71bSYork Sun /* -3E = 667 CL5, -25 = CL6 800, -25E = CL5 800 */
2545614e71bSYork Sun 
2555614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1)
25684baed2aSYork Sun /*
25784baed2aSYork Sun  * Check DIMM configuration, return 2 if quad-rank or two dual-rank
25884baed2aSYork Sun  * Return 1 if other two slots configuration. Return 0 if single slot.
25984baed2aSYork Sun  */
2605614e71bSYork Sun static inline int avoid_odt_overlap(const dimm_params_t *dimm_params)
2615614e71bSYork Sun {
2625614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 1
2635614e71bSYork Sun 	if (dimm_params[0].n_ranks == 4)
26484baed2aSYork Sun 		return 2;
2655614e71bSYork Sun #endif
2665614e71bSYork Sun 
2675614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 2
2685614e71bSYork Sun 	if ((dimm_params[0].n_ranks == 2) &&
2695614e71bSYork Sun 		(dimm_params[1].n_ranks == 2))
27084baed2aSYork Sun 		return 2;
2715614e71bSYork Sun 
2725614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
2735614e71bSYork Sun 	if (dimm_params[0].n_ranks == 4)
27484baed2aSYork Sun 		return 2;
2755614e71bSYork Sun #endif
27684baed2aSYork Sun 
27784baed2aSYork Sun 	if ((dimm_params[0].n_ranks != 0) &&
27884baed2aSYork Sun 	    (dimm_params[2].n_ranks != 0))
27984baed2aSYork Sun 		return 1;
2805614e71bSYork Sun #endif
2815614e71bSYork Sun 	return 0;
2825614e71bSYork Sun }
2835614e71bSYork Sun 
2845614e71bSYork Sun /*
2855614e71bSYork Sun  * DDR SDRAM Timing Configuration 0 (TIMING_CFG_0)
2865614e71bSYork Sun  *
2875614e71bSYork Sun  * Avoid writing for DDR I.  The new PQ38 DDR controller
2885614e71bSYork Sun  * dreams up non-zero default values to be backwards compatible.
2895614e71bSYork Sun  */
29003e664d8SYork Sun static void set_timing_cfg_0(const unsigned int ctrl_num,
29103e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
2925614e71bSYork Sun 				const memctl_options_t *popts,
2935614e71bSYork Sun 				const dimm_params_t *dimm_params)
2945614e71bSYork Sun {
2955614e71bSYork Sun 	unsigned char trwt_mclk = 0;   /* Read-to-write turnaround */
2965614e71bSYork Sun 	unsigned char twrt_mclk = 0;   /* Write-to-read turnaround */
2975614e71bSYork Sun 	/* 7.5 ns on -3E; 0 means WL - CL + BL/2 + 1 */
2985614e71bSYork Sun 	unsigned char trrt_mclk = 0;   /* Read-to-read turnaround */
2995614e71bSYork Sun 	unsigned char twwt_mclk = 0;   /* Write-to-write turnaround */
3005614e71bSYork Sun 
3015614e71bSYork Sun 	/* Active powerdown exit timing (tXARD and tXARDS). */
3025614e71bSYork Sun 	unsigned char act_pd_exit_mclk;
3035614e71bSYork Sun 	/* Precharge powerdown exit timing (tXP). */
3045614e71bSYork Sun 	unsigned char pre_pd_exit_mclk;
3055614e71bSYork Sun 	/* ODT powerdown exit timing (tAXPD). */
30634e026f9SYork Sun 	unsigned char taxpd_mclk = 0;
3075614e71bSYork Sun 	/* Mode register set cycle time (tMRD). */
3085614e71bSYork Sun 	unsigned char tmrd_mclk;
309bb578322SYork Sun #if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
31003e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
311bb578322SYork Sun #endif
3125614e71bSYork Sun 
31334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
31434e026f9SYork Sun 	/* tXP=max(4nCK, 6ns) */
315b4141195SMasahiro Yamada 	int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
31666869f95SYork Sun 	unsigned int data_rate = get_ddr_freq(ctrl_num);
31766869f95SYork Sun 
31866869f95SYork Sun 	/* for faster clock, need more time for data setup */
31966869f95SYork Sun 	trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2;
320*6c6e006aSYork Sun 
321*6c6e006aSYork Sun 	/*
322*6c6e006aSYork Sun 	 * for single quad-rank DIMM and two-slot DIMMs
323*6c6e006aSYork Sun 	 * to avoid ODT overlap
324*6c6e006aSYork Sun 	 */
325*6c6e006aSYork Sun 	switch (avoid_odt_overlap(dimm_params)) {
326*6c6e006aSYork Sun 	case 2:
327*6c6e006aSYork Sun 		twrt_mclk = 2;
328*6c6e006aSYork Sun 		twwt_mclk = 2;
329*6c6e006aSYork Sun 		trrt_mclk = 2;
330*6c6e006aSYork Sun 		break;
331*6c6e006aSYork Sun 	default:
33234e026f9SYork Sun 		twrt_mclk = 1;
333*6c6e006aSYork Sun 		twwt_mclk = 1;
334*6c6e006aSYork Sun 		trrt_mclk = 0;
335*6c6e006aSYork Sun 		break;
336*6c6e006aSYork Sun 	}
337*6c6e006aSYork Sun 
33803e664d8SYork Sun 	act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
33934e026f9SYork Sun 	pre_pd_exit_mclk = act_pd_exit_mclk;
34034e026f9SYork Sun 	/*
34134e026f9SYork Sun 	 * MRS_CYC = max(tMRD, tMOD)
34234e026f9SYork Sun 	 * tMRD = 8nCK, tMOD = max(24nCK, 15ns)
34334e026f9SYork Sun 	 */
34403e664d8SYork Sun 	tmrd_mclk = max(24U, picos_to_mclk(ctrl_num, 15000));
34534e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
34603e664d8SYork Sun 	unsigned int data_rate = get_ddr_freq(ctrl_num);
347bb578322SYork Sun 	int txp;
348938bbb60SYork Sun 	unsigned int ip_rev;
34984baed2aSYork Sun 	int odt_overlap;
3505614e71bSYork Sun 	/*
3515614e71bSYork Sun 	 * (tXARD and tXARDS). Empirical?
3525614e71bSYork Sun 	 * The DDR3 spec has not tXARD,
3535614e71bSYork Sun 	 * we use the tXP instead of it.
354bb578322SYork Sun 	 * tXP=max(3nCK, 7.5ns) for DDR3-800, 1066
355bb578322SYork Sun 	 *     max(3nCK, 6ns) for DDR3-1333, 1600, 1866, 2133
3565614e71bSYork Sun 	 * spec has not the tAXPD, we use
3575614e71bSYork Sun 	 * tAXPD=1, need design to confirm.
3585614e71bSYork Sun 	 */
359b4141195SMasahiro Yamada 	txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000));
360bb578322SYork Sun 
36166869f95SYork Sun 	ip_rev = fsl_ddr_get_version(ctrl_num);
362938bbb60SYork Sun 	if (ip_rev >= 0x40700) {
363938bbb60SYork Sun 		/*
364938bbb60SYork Sun 		 * MRS_CYC = max(tMRD, tMOD)
365938bbb60SYork Sun 		 * tMRD = 4nCK (8nCK for RDIMM)
366938bbb60SYork Sun 		 * tMOD = max(12nCK, 15ns)
367938bbb60SYork Sun 		 */
36803e664d8SYork Sun 		tmrd_mclk = max((unsigned int)12,
36903e664d8SYork Sun 				picos_to_mclk(ctrl_num, 15000));
370938bbb60SYork Sun 	} else {
371938bbb60SYork Sun 		/*
372938bbb60SYork Sun 		 * MRS_CYC = tMRD
373938bbb60SYork Sun 		 * tMRD = 4nCK (8nCK for RDIMM)
374938bbb60SYork Sun 		 */
375938bbb60SYork Sun 		if (popts->registered_dimm_en)
376938bbb60SYork Sun 			tmrd_mclk = 8;
377938bbb60SYork Sun 		else
3785614e71bSYork Sun 			tmrd_mclk = 4;
379938bbb60SYork Sun 	}
380938bbb60SYork Sun 
3815614e71bSYork Sun 	/* set the turnaround time */
3825614e71bSYork Sun 
3835614e71bSYork Sun 	/*
38484baed2aSYork Sun 	 * for single quad-rank DIMM and two-slot DIMMs
3855614e71bSYork Sun 	 * to avoid ODT overlap
3865614e71bSYork Sun 	 */
38784baed2aSYork Sun 	odt_overlap = avoid_odt_overlap(dimm_params);
38884baed2aSYork Sun 	switch (odt_overlap) {
38984baed2aSYork Sun 	case 2:
3905614e71bSYork Sun 		twwt_mclk = 2;
3915614e71bSYork Sun 		trrt_mclk = 1;
39284baed2aSYork Sun 		break;
39384baed2aSYork Sun 	case 1:
39484baed2aSYork Sun 		twwt_mclk = 1;
39584baed2aSYork Sun 		trrt_mclk = 0;
39684baed2aSYork Sun 		break;
39784baed2aSYork Sun 	default:
39884baed2aSYork Sun 		break;
3995614e71bSYork Sun 	}
40084baed2aSYork Sun 
4015614e71bSYork Sun 	/* for faster clock, need more time for data setup */
4025614e71bSYork Sun 	trwt_mclk = (data_rate/1000000 > 1800) ? 2 : 1;
4035614e71bSYork Sun 
4045614e71bSYork Sun 	if ((data_rate/1000000 > 1150) || (popts->memctl_interleaving))
4055614e71bSYork Sun 		twrt_mclk = 1;
4065614e71bSYork Sun 
4075614e71bSYork Sun 	if (popts->dynamic_power == 0) {	/* powerdown is not used */
4085614e71bSYork Sun 		act_pd_exit_mclk = 1;
4095614e71bSYork Sun 		pre_pd_exit_mclk = 1;
4105614e71bSYork Sun 		taxpd_mclk = 1;
4115614e71bSYork Sun 	} else {
4125614e71bSYork Sun 		/* act_pd_exit_mclk = tXARD, see above */
41303e664d8SYork Sun 		act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
4145614e71bSYork Sun 		/* Mode register MR0[A12] is '1' - fast exit */
4155614e71bSYork Sun 		pre_pd_exit_mclk = act_pd_exit_mclk;
4165614e71bSYork Sun 		taxpd_mclk = 1;
4175614e71bSYork Sun 	}
4185614e71bSYork Sun #else /* CONFIG_SYS_FSL_DDR2 */
4195614e71bSYork Sun 	/*
4205614e71bSYork Sun 	 * (tXARD and tXARDS). Empirical?
4215614e71bSYork Sun 	 * tXARD = 2 for DDR2
4225614e71bSYork Sun 	 * tXP=2
4235614e71bSYork Sun 	 * tAXPD=8
4245614e71bSYork Sun 	 */
4255614e71bSYork Sun 	act_pd_exit_mclk = 2;
4265614e71bSYork Sun 	pre_pd_exit_mclk = 2;
4275614e71bSYork Sun 	taxpd_mclk = 8;
4285614e71bSYork Sun 	tmrd_mclk = 2;
4295614e71bSYork Sun #endif
4305614e71bSYork Sun 
4315614e71bSYork Sun 	if (popts->trwt_override)
4325614e71bSYork Sun 		trwt_mclk = popts->trwt;
4335614e71bSYork Sun 
4345614e71bSYork Sun 	ddr->timing_cfg_0 = (0
4355614e71bSYork Sun 		| ((trwt_mclk & 0x3) << 30)	/* RWT */
4365614e71bSYork Sun 		| ((twrt_mclk & 0x3) << 28)	/* WRT */
4375614e71bSYork Sun 		| ((trrt_mclk & 0x3) << 26)	/* RRT */
4385614e71bSYork Sun 		| ((twwt_mclk & 0x3) << 24)	/* WWT */
439d4263b8aSYork Sun 		| ((act_pd_exit_mclk & 0xf) << 20)  /* ACT_PD_EXIT */
4405614e71bSYork Sun 		| ((pre_pd_exit_mclk & 0xF) << 16)  /* PRE_PD_EXIT */
4415614e71bSYork Sun 		| ((taxpd_mclk & 0xf) << 8)	/* ODT_PD_EXIT */
442d4263b8aSYork Sun 		| ((tmrd_mclk & 0x1f) << 0)	/* MRS_CYC */
4435614e71bSYork Sun 		);
4445614e71bSYork Sun 	debug("FSLDDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
4455614e71bSYork Sun }
44684baed2aSYork Sun #endif	/* !defined(CONFIG_SYS_FSL_DDR1) */
4475614e71bSYork Sun 
4485614e71bSYork Sun /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */
44903e664d8SYork Sun static void set_timing_cfg_3(const unsigned int ctrl_num,
45003e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
4515614e71bSYork Sun 			     const memctl_options_t *popts,
4525614e71bSYork Sun 			     const common_timing_params_t *common_dimm,
453d4263b8aSYork Sun 			     unsigned int cas_latency,
454d4263b8aSYork Sun 			     unsigned int additive_latency)
4555614e71bSYork Sun {
4565614e71bSYork Sun 	/* Extended precharge to activate interval (tRP) */
4575614e71bSYork Sun 	unsigned int ext_pretoact = 0;
4585614e71bSYork Sun 	/* Extended Activate to precharge interval (tRAS) */
4595614e71bSYork Sun 	unsigned int ext_acttopre = 0;
4605614e71bSYork Sun 	/* Extended activate to read/write interval (tRCD) */
4615614e71bSYork Sun 	unsigned int ext_acttorw = 0;
4625614e71bSYork Sun 	/* Extended refresh recovery time (tRFC) */
4635614e71bSYork Sun 	unsigned int ext_refrec;
4645614e71bSYork Sun 	/* Extended MCAS latency from READ cmd */
4655614e71bSYork Sun 	unsigned int ext_caslat = 0;
466d4263b8aSYork Sun 	/* Extended additive latency */
467d4263b8aSYork Sun 	unsigned int ext_add_lat = 0;
4685614e71bSYork Sun 	/* Extended last data to precharge interval (tWR) */
4695614e71bSYork Sun 	unsigned int ext_wrrec = 0;
4705614e71bSYork Sun 	/* Control Adjust */
4715614e71bSYork Sun 	unsigned int cntl_adj = 0;
4725614e71bSYork Sun 
47303e664d8SYork Sun 	ext_pretoact = picos_to_mclk(ctrl_num, common_dimm->trp_ps) >> 4;
47403e664d8SYork Sun 	ext_acttopre = picos_to_mclk(ctrl_num, common_dimm->tras_ps) >> 4;
47503e664d8SYork Sun 	ext_acttorw = picos_to_mclk(ctrl_num, common_dimm->trcd_ps) >> 4;
4765614e71bSYork Sun 	ext_caslat = (2 * cas_latency - 1) >> 4;
477d4263b8aSYork Sun 	ext_add_lat = additive_latency >> 4;
47834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
47903e664d8SYork Sun 	ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8) >> 4;
48034e026f9SYork Sun #else
48103e664d8SYork Sun 	ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8) >> 4;
4825614e71bSYork Sun 	/* ext_wrrec only deals with 16 clock and above, or 14 with OTF */
48334e026f9SYork Sun #endif
48403e664d8SYork Sun 	ext_wrrec = (picos_to_mclk(ctrl_num, common_dimm->twr_ps) +
4855614e71bSYork Sun 		(popts->otf_burst_chop_en ? 2 : 0)) >> 4;
4865614e71bSYork Sun 
4875614e71bSYork Sun 	ddr->timing_cfg_3 = (0
4885614e71bSYork Sun 		| ((ext_pretoact & 0x1) << 28)
4895614e71bSYork Sun 		| ((ext_acttopre & 0x3) << 24)
4905614e71bSYork Sun 		| ((ext_acttorw & 0x1) << 22)
4915614e71bSYork Sun 		| ((ext_refrec & 0x1F) << 16)
4925614e71bSYork Sun 		| ((ext_caslat & 0x3) << 12)
493d4263b8aSYork Sun 		| ((ext_add_lat & 0x1) << 10)
4945614e71bSYork Sun 		| ((ext_wrrec & 0x1) << 8)
4955614e71bSYork Sun 		| ((cntl_adj & 0x7) << 0)
4965614e71bSYork Sun 		);
4975614e71bSYork Sun 	debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3);
4985614e71bSYork Sun }
4995614e71bSYork Sun 
5005614e71bSYork Sun /* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */
50103e664d8SYork Sun static void set_timing_cfg_1(const unsigned int ctrl_num,
50203e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
5035614e71bSYork Sun 			     const memctl_options_t *popts,
5045614e71bSYork Sun 			     const common_timing_params_t *common_dimm,
5055614e71bSYork Sun 			     unsigned int cas_latency)
5065614e71bSYork Sun {
5075614e71bSYork Sun 	/* Precharge-to-activate interval (tRP) */
5085614e71bSYork Sun 	unsigned char pretoact_mclk;
5095614e71bSYork Sun 	/* Activate to precharge interval (tRAS) */
5105614e71bSYork Sun 	unsigned char acttopre_mclk;
5115614e71bSYork Sun 	/*  Activate to read/write interval (tRCD) */
5125614e71bSYork Sun 	unsigned char acttorw_mclk;
5135614e71bSYork Sun 	/* CASLAT */
5145614e71bSYork Sun 	unsigned char caslat_ctrl;
5155614e71bSYork Sun 	/*  Refresh recovery time (tRFC) ; trfc_low */
5165614e71bSYork Sun 	unsigned char refrec_ctrl;
5175614e71bSYork Sun 	/* Last data to precharge minimum interval (tWR) */
5185614e71bSYork Sun 	unsigned char wrrec_mclk;
5195614e71bSYork Sun 	/* Activate-to-activate interval (tRRD) */
5205614e71bSYork Sun 	unsigned char acttoact_mclk;
5215614e71bSYork Sun 	/* Last write data pair to read command issue interval (tWTR) */
5225614e71bSYork Sun 	unsigned char wrtord_mclk;
52334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
52434e026f9SYork Sun 	/* DDR4 supports 10, 12, 14, 16, 18, 20, 24 */
52534e026f9SYork Sun 	static const u8 wrrec_table[] = {
52634e026f9SYork Sun 		10, 10, 10, 10, 10,
52734e026f9SYork Sun 		10, 10, 10, 10, 10,
52834e026f9SYork Sun 		12, 12, 14, 14, 16,
52934e026f9SYork Sun 		16, 18, 18, 20, 20,
53034e026f9SYork Sun 		24, 24, 24, 24};
53134e026f9SYork Sun #else
5325614e71bSYork Sun 	/* DDR_SDRAM_MODE doesn't support 9,11,13,15 */
5335614e71bSYork Sun 	static const u8 wrrec_table[] = {
5345614e71bSYork Sun 		1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0};
53534e026f9SYork Sun #endif
5365614e71bSYork Sun 
53703e664d8SYork Sun 	pretoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trp_ps);
53803e664d8SYork Sun 	acttopre_mclk = picos_to_mclk(ctrl_num, common_dimm->tras_ps);
53903e664d8SYork Sun 	acttorw_mclk = picos_to_mclk(ctrl_num, common_dimm->trcd_ps);
5405614e71bSYork Sun 
5415614e71bSYork Sun 	/*
5425614e71bSYork Sun 	 * Translate CAS Latency to a DDR controller field value:
5435614e71bSYork Sun 	 *
5445614e71bSYork Sun 	 *      CAS Lat DDR I   DDR II  Ctrl
5455614e71bSYork Sun 	 *      Clocks  SPD Bit SPD Bit Value
5465614e71bSYork Sun 	 *      ------- ------- ------- -----
5475614e71bSYork Sun 	 *      1.0     0               0001
5485614e71bSYork Sun 	 *      1.5     1               0010
5495614e71bSYork Sun 	 *      2.0     2       2       0011
5505614e71bSYork Sun 	 *      2.5     3               0100
5515614e71bSYork Sun 	 *      3.0     4       3       0101
5525614e71bSYork Sun 	 *      3.5     5               0110
5535614e71bSYork Sun 	 *      4.0             4       0111
5545614e71bSYork Sun 	 *      4.5                     1000
5555614e71bSYork Sun 	 *      5.0             5       1001
5565614e71bSYork Sun 	 */
5575614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
5585614e71bSYork Sun 	caslat_ctrl = (cas_latency + 1) & 0x07;
5595614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
5605614e71bSYork Sun 	caslat_ctrl = 2 * cas_latency - 1;
5615614e71bSYork Sun #else
5625614e71bSYork Sun 	/*
5635614e71bSYork Sun 	 * if the CAS latency more than 8 cycle,
5645614e71bSYork Sun 	 * we need set extend bit for it at
5655614e71bSYork Sun 	 * TIMING_CFG_3[EXT_CASLAT]
5665614e71bSYork Sun 	 */
56766869f95SYork Sun 	if (fsl_ddr_get_version(ctrl_num) <= 0x40400)
5685614e71bSYork Sun 		caslat_ctrl = 2 * cas_latency - 1;
56934e026f9SYork Sun 	else
57034e026f9SYork Sun 		caslat_ctrl = (cas_latency - 1) << 1;
5715614e71bSYork Sun #endif
5725614e71bSYork Sun 
57334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
57403e664d8SYork Sun 	refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8;
57503e664d8SYork Sun 	wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
57603e664d8SYork Sun 	acttoact_mclk = max(picos_to_mclk(ctrl_num, common_dimm->trrds_ps), 4U);
57703e664d8SYork Sun 	wrtord_mclk = max(2U, picos_to_mclk(ctrl_num, 2500));
578349689b8SYork Sun 	if ((wrrec_mclk < 1) || (wrrec_mclk > 24))
579349689b8SYork Sun 		printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
58034e026f9SYork Sun 	else
58134e026f9SYork Sun 		wrrec_mclk = wrrec_table[wrrec_mclk - 1];
58234e026f9SYork Sun #else
58303e664d8SYork Sun 	refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8;
58403e664d8SYork Sun 	wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
58503e664d8SYork Sun 	acttoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trrd_ps);
58603e664d8SYork Sun 	wrtord_mclk = picos_to_mclk(ctrl_num, common_dimm->twtr_ps);
587349689b8SYork Sun 	if ((wrrec_mclk < 1) || (wrrec_mclk > 16))
588349689b8SYork Sun 		printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
5895614e71bSYork Sun 	else
5905614e71bSYork Sun 		wrrec_mclk = wrrec_table[wrrec_mclk - 1];
59134e026f9SYork Sun #endif
5925614e71bSYork Sun 	if (popts->otf_burst_chop_en)
5935614e71bSYork Sun 		wrrec_mclk += 2;
5945614e71bSYork Sun 
5955614e71bSYork Sun 	/*
5965614e71bSYork Sun 	 * JEDEC has min requirement for tRRD
5975614e71bSYork Sun 	 */
5985614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR3)
5995614e71bSYork Sun 	if (acttoact_mclk < 4)
6005614e71bSYork Sun 		acttoact_mclk = 4;
6015614e71bSYork Sun #endif
6025614e71bSYork Sun 	/*
6035614e71bSYork Sun 	 * JEDEC has some min requirements for tWTR
6045614e71bSYork Sun 	 */
6055614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2)
6065614e71bSYork Sun 	if (wrtord_mclk < 2)
6075614e71bSYork Sun 		wrtord_mclk = 2;
6085614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
6095614e71bSYork Sun 	if (wrtord_mclk < 4)
6105614e71bSYork Sun 		wrtord_mclk = 4;
6115614e71bSYork Sun #endif
6125614e71bSYork Sun 	if (popts->otf_burst_chop_en)
6135614e71bSYork Sun 		wrtord_mclk += 2;
6145614e71bSYork Sun 
6155614e71bSYork Sun 	ddr->timing_cfg_1 = (0
6165614e71bSYork Sun 		| ((pretoact_mclk & 0x0F) << 28)
6175614e71bSYork Sun 		| ((acttopre_mclk & 0x0F) << 24)
6185614e71bSYork Sun 		| ((acttorw_mclk & 0xF) << 20)
6195614e71bSYork Sun 		| ((caslat_ctrl & 0xF) << 16)
6205614e71bSYork Sun 		| ((refrec_ctrl & 0xF) << 12)
6215614e71bSYork Sun 		| ((wrrec_mclk & 0x0F) << 8)
6225614e71bSYork Sun 		| ((acttoact_mclk & 0x0F) << 4)
6235614e71bSYork Sun 		| ((wrtord_mclk & 0x0F) << 0)
6245614e71bSYork Sun 		);
6255614e71bSYork Sun 	debug("FSLDDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1);
6265614e71bSYork Sun }
6275614e71bSYork Sun 
6285614e71bSYork Sun /* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */
62903e664d8SYork Sun static void set_timing_cfg_2(const unsigned int ctrl_num,
63003e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
6315614e71bSYork Sun 			     const memctl_options_t *popts,
6325614e71bSYork Sun 			     const common_timing_params_t *common_dimm,
6335614e71bSYork Sun 			     unsigned int cas_latency,
6345614e71bSYork Sun 			     unsigned int additive_latency)
6355614e71bSYork Sun {
6365614e71bSYork Sun 	/* Additive latency */
6375614e71bSYork Sun 	unsigned char add_lat_mclk;
6385614e71bSYork Sun 	/* CAS-to-preamble override */
6395614e71bSYork Sun 	unsigned short cpo;
6405614e71bSYork Sun 	/* Write latency */
6415614e71bSYork Sun 	unsigned char wr_lat;
6425614e71bSYork Sun 	/*  Read to precharge (tRTP) */
6435614e71bSYork Sun 	unsigned char rd_to_pre;
6445614e71bSYork Sun 	/* Write command to write data strobe timing adjustment */
6455614e71bSYork Sun 	unsigned char wr_data_delay;
6465614e71bSYork Sun 	/* Minimum CKE pulse width (tCKE) */
6475614e71bSYork Sun 	unsigned char cke_pls;
6485614e71bSYork Sun 	/* Window for four activates (tFAW) */
6495614e71bSYork Sun 	unsigned short four_act;
650bb578322SYork Sun #ifdef CONFIG_SYS_FSL_DDR3
65103e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
652bb578322SYork Sun #endif
6535614e71bSYork Sun 
6545614e71bSYork Sun 	/* FIXME add check that this must be less than acttorw_mclk */
6555614e71bSYork Sun 	add_lat_mclk = additive_latency;
6565614e71bSYork Sun 	cpo = popts->cpo_override;
6575614e71bSYork Sun 
6585614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
6595614e71bSYork Sun 	/*
6605614e71bSYork Sun 	 * This is a lie.  It should really be 1, but if it is
6615614e71bSYork Sun 	 * set to 1, bits overlap into the old controller's
6625614e71bSYork Sun 	 * otherwise unused ACSM field.  If we leave it 0, then
6635614e71bSYork Sun 	 * the HW will magically treat it as 1 for DDR 1.  Oh Yea.
6645614e71bSYork Sun 	 */
6655614e71bSYork Sun 	wr_lat = 0;
6665614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
6675614e71bSYork Sun 	wr_lat = cas_latency - 1;
6685614e71bSYork Sun #else
66903e664d8SYork Sun 	wr_lat = compute_cas_write_latency(ctrl_num);
6705614e71bSYork Sun #endif
6715614e71bSYork Sun 
67234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
67303e664d8SYork Sun 	rd_to_pre = picos_to_mclk(ctrl_num, 7500);
67434e026f9SYork Sun #else
67503e664d8SYork Sun 	rd_to_pre = picos_to_mclk(ctrl_num, common_dimm->trtp_ps);
67634e026f9SYork Sun #endif
6775614e71bSYork Sun 	/*
6785614e71bSYork Sun 	 * JEDEC has some min requirements for tRTP
6795614e71bSYork Sun 	 */
6805614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2)
6815614e71bSYork Sun 	if (rd_to_pre  < 2)
6825614e71bSYork Sun 		rd_to_pre  = 2;
68334e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
6845614e71bSYork Sun 	if (rd_to_pre < 4)
6855614e71bSYork Sun 		rd_to_pre = 4;
6865614e71bSYork Sun #endif
6875614e71bSYork Sun 	if (popts->otf_burst_chop_en)
6885614e71bSYork Sun 		rd_to_pre += 2; /* according to UM */
6895614e71bSYork Sun 
6905614e71bSYork Sun 	wr_data_delay = popts->write_data_delay;
69134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
69234e026f9SYork Sun 	cpo = 0;
69303e664d8SYork Sun 	cke_pls = max(3U, picos_to_mclk(ctrl_num, 5000));
694bb578322SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
695bb578322SYork Sun 	/*
696bb578322SYork Sun 	 * cke pulse = max(3nCK, 7.5ns) for DDR3-800
697bb578322SYork Sun 	 *             max(3nCK, 5.625ns) for DDR3-1066, 1333
698bb578322SYork Sun 	 *             max(3nCK, 5ns) for DDR3-1600, 1866, 2133
699bb578322SYork Sun 	 */
70003e664d8SYork Sun 	cke_pls = max(3U, picos_to_mclk(ctrl_num, mclk_ps > 1870 ? 7500 :
701bb578322SYork Sun 					(mclk_ps > 1245 ? 5625 : 5000)));
70234e026f9SYork Sun #else
703bb578322SYork Sun 	cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR;
70434e026f9SYork Sun #endif
70503e664d8SYork Sun 	four_act = picos_to_mclk(ctrl_num,
70603e664d8SYork Sun 				 popts->tfaw_window_four_activates_ps);
7075614e71bSYork Sun 
7085614e71bSYork Sun 	ddr->timing_cfg_2 = (0
7095614e71bSYork Sun 		| ((add_lat_mclk & 0xf) << 28)
7105614e71bSYork Sun 		| ((cpo & 0x1f) << 23)
7115614e71bSYork Sun 		| ((wr_lat & 0xf) << 19)
71234e026f9SYork Sun 		| ((wr_lat & 0x10) << 14)
7135614e71bSYork Sun 		| ((rd_to_pre & RD_TO_PRE_MASK) << RD_TO_PRE_SHIFT)
7145614e71bSYork Sun 		| ((wr_data_delay & WR_DATA_DELAY_MASK) << WR_DATA_DELAY_SHIFT)
7155614e71bSYork Sun 		| ((cke_pls & 0x7) << 6)
7165614e71bSYork Sun 		| ((four_act & 0x3f) << 0)
7175614e71bSYork Sun 		);
7185614e71bSYork Sun 	debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2);
7195614e71bSYork Sun }
7205614e71bSYork Sun 
7215614e71bSYork Sun /* DDR SDRAM Register Control Word */
7225614e71bSYork Sun static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr,
7235614e71bSYork Sun 			       const memctl_options_t *popts,
7245614e71bSYork Sun 			       const common_timing_params_t *common_dimm)
7255614e71bSYork Sun {
7265614e71bSYork Sun 	if (common_dimm->all_dimms_registered &&
7275614e71bSYork Sun 	    !common_dimm->all_dimms_unbuffered)	{
7285614e71bSYork Sun 		if (popts->rcw_override) {
7295614e71bSYork Sun 			ddr->ddr_sdram_rcw_1 = popts->rcw_1;
7305614e71bSYork Sun 			ddr->ddr_sdram_rcw_2 = popts->rcw_2;
7315614e71bSYork Sun 		} else {
7325614e71bSYork Sun 			ddr->ddr_sdram_rcw_1 =
7335614e71bSYork Sun 				common_dimm->rcw[0] << 28 | \
7345614e71bSYork Sun 				common_dimm->rcw[1] << 24 | \
7355614e71bSYork Sun 				common_dimm->rcw[2] << 20 | \
7365614e71bSYork Sun 				common_dimm->rcw[3] << 16 | \
7375614e71bSYork Sun 				common_dimm->rcw[4] << 12 | \
7385614e71bSYork Sun 				common_dimm->rcw[5] << 8 | \
7395614e71bSYork Sun 				common_dimm->rcw[6] << 4 | \
7405614e71bSYork Sun 				common_dimm->rcw[7];
7415614e71bSYork Sun 			ddr->ddr_sdram_rcw_2 =
7425614e71bSYork Sun 				common_dimm->rcw[8] << 28 | \
7435614e71bSYork Sun 				common_dimm->rcw[9] << 24 | \
7445614e71bSYork Sun 				common_dimm->rcw[10] << 20 | \
7455614e71bSYork Sun 				common_dimm->rcw[11] << 16 | \
7465614e71bSYork Sun 				common_dimm->rcw[12] << 12 | \
7475614e71bSYork Sun 				common_dimm->rcw[13] << 8 | \
7485614e71bSYork Sun 				common_dimm->rcw[14] << 4 | \
7495614e71bSYork Sun 				common_dimm->rcw[15];
7505614e71bSYork Sun 		}
7515614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1);
7525614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2);
7535614e71bSYork Sun 	}
7545614e71bSYork Sun }
7555614e71bSYork Sun 
7565614e71bSYork Sun /* DDR SDRAM control configuration (DDR_SDRAM_CFG) */
7575614e71bSYork Sun static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
7585614e71bSYork Sun 			       const memctl_options_t *popts,
7595614e71bSYork Sun 			       const common_timing_params_t *common_dimm)
7605614e71bSYork Sun {
7615614e71bSYork Sun 	unsigned int mem_en;		/* DDR SDRAM interface logic enable */
7625614e71bSYork Sun 	unsigned int sren;		/* Self refresh enable (during sleep) */
7635614e71bSYork Sun 	unsigned int ecc_en;		/* ECC enable. */
7645614e71bSYork Sun 	unsigned int rd_en;		/* Registered DIMM enable */
7655614e71bSYork Sun 	unsigned int sdram_type;	/* Type of SDRAM */
7665614e71bSYork Sun 	unsigned int dyn_pwr;		/* Dynamic power management mode */
7675614e71bSYork Sun 	unsigned int dbw;		/* DRAM dta bus width */
7685614e71bSYork Sun 	unsigned int eight_be = 0;	/* 8-beat burst enable, DDR2 is zero */
7695614e71bSYork Sun 	unsigned int ncap = 0;		/* Non-concurrent auto-precharge */
7705614e71bSYork Sun 	unsigned int threet_en;		/* Enable 3T timing */
7715614e71bSYork Sun 	unsigned int twot_en;		/* Enable 2T timing */
7725614e71bSYork Sun 	unsigned int ba_intlv_ctl;	/* Bank (CS) interleaving control */
7735614e71bSYork Sun 	unsigned int x32_en = 0;	/* x32 enable */
7745614e71bSYork Sun 	unsigned int pchb8 = 0;		/* precharge bit 8 enable */
7755614e71bSYork Sun 	unsigned int hse;		/* Global half strength override */
776d28cb671SYork Sun 	unsigned int acc_ecc_en = 0;	/* Accumulated ECC enable */
7775614e71bSYork Sun 	unsigned int mem_halt = 0;	/* memory controller halt */
7785614e71bSYork Sun 	unsigned int bi = 0;		/* Bypass initialization */
7795614e71bSYork Sun 
7805614e71bSYork Sun 	mem_en = 1;
7815614e71bSYork Sun 	sren = popts->self_refresh_in_sleep;
7825614e71bSYork Sun 	if (common_dimm->all_dimms_ecc_capable) {
7835614e71bSYork Sun 		/* Allow setting of ECC only if all DIMMs are ECC. */
7845614e71bSYork Sun 		ecc_en = popts->ecc_mode;
7855614e71bSYork Sun 	} else {
7865614e71bSYork Sun 		ecc_en = 0;
7875614e71bSYork Sun 	}
7885614e71bSYork Sun 
7895614e71bSYork Sun 	if (common_dimm->all_dimms_registered &&
7905614e71bSYork Sun 	    !common_dimm->all_dimms_unbuffered)	{
7915614e71bSYork Sun 		rd_en = 1;
7925614e71bSYork Sun 		twot_en = 0;
7935614e71bSYork Sun 	} else {
7945614e71bSYork Sun 		rd_en = 0;
7955614e71bSYork Sun 		twot_en = popts->twot_en;
7965614e71bSYork Sun 	}
7975614e71bSYork Sun 
7985614e71bSYork Sun 	sdram_type = CONFIG_FSL_SDRAM_TYPE;
7995614e71bSYork Sun 
8005614e71bSYork Sun 	dyn_pwr = popts->dynamic_power;
8015614e71bSYork Sun 	dbw = popts->data_bus_width;
8025614e71bSYork Sun 	/* 8-beat burst enable DDR-III case
8035614e71bSYork Sun 	 * we must clear it when use the on-the-fly mode,
8045614e71bSYork Sun 	 * must set it when use the 32-bits bus mode.
8055614e71bSYork Sun 	 */
80634e026f9SYork Sun 	if ((sdram_type == SDRAM_TYPE_DDR3) ||
80734e026f9SYork Sun 	    (sdram_type == SDRAM_TYPE_DDR4)) {
8085614e71bSYork Sun 		if (popts->burst_length == DDR_BL8)
8095614e71bSYork Sun 			eight_be = 1;
8105614e71bSYork Sun 		if (popts->burst_length == DDR_OTF)
8115614e71bSYork Sun 			eight_be = 0;
8125614e71bSYork Sun 		if (dbw == 0x1)
8135614e71bSYork Sun 			eight_be = 1;
8145614e71bSYork Sun 	}
8155614e71bSYork Sun 
8165614e71bSYork Sun 	threet_en = popts->threet_en;
8175614e71bSYork Sun 	ba_intlv_ctl = popts->ba_intlv_ctl;
8185614e71bSYork Sun 	hse = popts->half_strength_driver_enable;
8195614e71bSYork Sun 
820d28cb671SYork Sun 	/* set when ddr bus width < 64 */
821d28cb671SYork Sun 	acc_ecc_en = (dbw != 0 && ecc_en == 1) ? 1 : 0;
822d28cb671SYork Sun 
8235614e71bSYork Sun 	ddr->ddr_sdram_cfg = (0
8245614e71bSYork Sun 			| ((mem_en & 0x1) << 31)
8255614e71bSYork Sun 			| ((sren & 0x1) << 30)
8265614e71bSYork Sun 			| ((ecc_en & 0x1) << 29)
8275614e71bSYork Sun 			| ((rd_en & 0x1) << 28)
8285614e71bSYork Sun 			| ((sdram_type & 0x7) << 24)
8295614e71bSYork Sun 			| ((dyn_pwr & 0x1) << 21)
8305614e71bSYork Sun 			| ((dbw & 0x3) << 19)
8315614e71bSYork Sun 			| ((eight_be & 0x1) << 18)
8325614e71bSYork Sun 			| ((ncap & 0x1) << 17)
8335614e71bSYork Sun 			| ((threet_en & 0x1) << 16)
8345614e71bSYork Sun 			| ((twot_en & 0x1) << 15)
8355614e71bSYork Sun 			| ((ba_intlv_ctl & 0x7F) << 8)
8365614e71bSYork Sun 			| ((x32_en & 0x1) << 5)
8375614e71bSYork Sun 			| ((pchb8 & 0x1) << 4)
8385614e71bSYork Sun 			| ((hse & 0x1) << 3)
839d28cb671SYork Sun 			| ((acc_ecc_en & 0x1) << 2)
8405614e71bSYork Sun 			| ((mem_halt & 0x1) << 1)
8415614e71bSYork Sun 			| ((bi & 0x1) << 0)
8425614e71bSYork Sun 			);
8435614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_cfg = 0x%08x\n", ddr->ddr_sdram_cfg);
8445614e71bSYork Sun }
8455614e71bSYork Sun 
8465614e71bSYork Sun /* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */
84703e664d8SYork Sun static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num,
84803e664d8SYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
8495614e71bSYork Sun 			       const memctl_options_t *popts,
8505614e71bSYork Sun 			       const unsigned int unq_mrs_en)
8515614e71bSYork Sun {
8525614e71bSYork Sun 	unsigned int frc_sr = 0;	/* Force self refresh */
8535614e71bSYork Sun 	unsigned int sr_ie = 0;		/* Self-refresh interrupt enable */
8545614e71bSYork Sun 	unsigned int odt_cfg = 0;	/* ODT configuration */
8555614e71bSYork Sun 	unsigned int num_pr;		/* Number of posted refreshes */
8565614e71bSYork Sun 	unsigned int slow = 0;		/* DDR will be run less than 1250 */
8575614e71bSYork Sun 	unsigned int x4_en = 0;		/* x4 DRAM enable */
8585614e71bSYork Sun 	unsigned int obc_cfg;		/* On-The-Fly Burst Chop Cfg */
8595614e71bSYork Sun 	unsigned int ap_en;		/* Address Parity Enable */
8605614e71bSYork Sun 	unsigned int d_init;		/* DRAM data initialization */
8615614e71bSYork Sun 	unsigned int rcw_en = 0;	/* Register Control Word Enable */
8625614e71bSYork Sun 	unsigned int md_en = 0;		/* Mirrored DIMM Enable */
8635614e71bSYork Sun 	unsigned int qd_en = 0;		/* quad-rank DIMM Enable */
8645614e71bSYork Sun 	int i;
86534e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4
86634e026f9SYork Sun 	unsigned int dll_rst_dis = 1;	/* DLL reset disable */
86734e026f9SYork Sun 	unsigned int dqs_cfg;		/* DQS configuration */
8685614e71bSYork Sun 
8695614e71bSYork Sun 	dqs_cfg = popts->dqs_config;
87034e026f9SYork Sun #endif
8715614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
8725614e71bSYork Sun 		if (popts->cs_local_opts[i].odt_rd_cfg
8735614e71bSYork Sun 			|| popts->cs_local_opts[i].odt_wr_cfg) {
8745614e71bSYork Sun 			odt_cfg = SDRAM_CFG2_ODT_ONLY_READ;
8755614e71bSYork Sun 			break;
8765614e71bSYork Sun 		}
8775614e71bSYork Sun 	}
878e368c206SJoakim Tjernlund 	sr_ie = popts->self_refresh_interrupt_en;
8795614e71bSYork Sun 	num_pr = 1;	/* Make this configurable */
8805614e71bSYork Sun 
8815614e71bSYork Sun 	/*
8825614e71bSYork Sun 	 * 8572 manual says
8835614e71bSYork Sun 	 *     {TIMING_CFG_1[PRETOACT]
8845614e71bSYork Sun 	 *      + [DDR_SDRAM_CFG_2[NUM_PR]
8855614e71bSYork Sun 	 *        * ({EXT_REFREC || REFREC} + 8 + 2)]}
8865614e71bSYork Sun 	 *      << DDR_SDRAM_INTERVAL[REFINT]
8875614e71bSYork Sun 	 */
88834e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
8895614e71bSYork Sun 	obc_cfg = popts->otf_burst_chop_en;
8905614e71bSYork Sun #else
8915614e71bSYork Sun 	obc_cfg = 0;
8925614e71bSYork Sun #endif
8935614e71bSYork Sun 
8945614e71bSYork Sun #if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)
89503e664d8SYork Sun 	slow = get_ddr_freq(ctrl_num) < 1249000000;
8965614e71bSYork Sun #endif
8975614e71bSYork Sun 
8985614e71bSYork Sun 	if (popts->registered_dimm_en) {
8995614e71bSYork Sun 		rcw_en = 1;
9005614e71bSYork Sun 		ap_en = popts->ap_en;
9015614e71bSYork Sun 	} else {
9025614e71bSYork Sun 		ap_en = 0;
9035614e71bSYork Sun 	}
9045614e71bSYork Sun 
9055614e71bSYork Sun 	x4_en = popts->x4_en ? 1 : 0;
9065614e71bSYork Sun 
9075614e71bSYork Sun #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
9085614e71bSYork Sun 	/* Use the DDR controller to auto initialize memory. */
9095614e71bSYork Sun 	d_init = popts->ecc_init_using_memctl;
9105614e71bSYork Sun 	ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE;
9115614e71bSYork Sun 	debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init);
9125614e71bSYork Sun #else
9135614e71bSYork Sun 	/* Memory will be initialized via DMA, or not at all. */
9145614e71bSYork Sun 	d_init = 0;
9155614e71bSYork Sun #endif
9165614e71bSYork Sun 
91734e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
9185614e71bSYork Sun 	md_en = popts->mirrored_dimm;
9195614e71bSYork Sun #endif
9205614e71bSYork Sun 	qd_en = popts->quad_rank_present ? 1 : 0;
9215614e71bSYork Sun 	ddr->ddr_sdram_cfg_2 = (0
9225614e71bSYork Sun 		| ((frc_sr & 0x1) << 31)
9235614e71bSYork Sun 		| ((sr_ie & 0x1) << 30)
92434e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4
9255614e71bSYork Sun 		| ((dll_rst_dis & 0x1) << 29)
9265614e71bSYork Sun 		| ((dqs_cfg & 0x3) << 26)
92734e026f9SYork Sun #endif
9285614e71bSYork Sun 		| ((odt_cfg & 0x3) << 21)
9295614e71bSYork Sun 		| ((num_pr & 0xf) << 12)
9305614e71bSYork Sun 		| ((slow & 1) << 11)
9315614e71bSYork Sun 		| (x4_en << 10)
9325614e71bSYork Sun 		| (qd_en << 9)
9335614e71bSYork Sun 		| (unq_mrs_en << 8)
9345614e71bSYork Sun 		| ((obc_cfg & 0x1) << 6)
9355614e71bSYork Sun 		| ((ap_en & 0x1) << 5)
9365614e71bSYork Sun 		| ((d_init & 0x1) << 4)
9375614e71bSYork Sun 		| ((rcw_en & 0x1) << 2)
9385614e71bSYork Sun 		| ((md_en & 0x1) << 0)
9395614e71bSYork Sun 		);
9405614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_cfg_2 = 0x%08x\n", ddr->ddr_sdram_cfg_2);
9415614e71bSYork Sun }
9425614e71bSYork Sun 
94334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
9445614e71bSYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
94503e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
94603e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
9475614e71bSYork Sun 				const memctl_options_t *popts,
9485614e71bSYork Sun 				const common_timing_params_t *common_dimm,
9495614e71bSYork Sun 				const unsigned int unq_mrs_en)
9505614e71bSYork Sun {
9515614e71bSYork Sun 	unsigned short esdmode2 = 0;	/* Extended SDRAM mode 2 */
9525614e71bSYork Sun 	unsigned short esdmode3 = 0;	/* Extended SDRAM mode 3 */
9535614e71bSYork Sun 	int i;
95434e026f9SYork Sun 	unsigned int wr_crc = 0;	/* Disable */
9555614e71bSYork Sun 	unsigned int rtt_wr = 0;	/* Rtt_WR - dynamic ODT off */
9565614e71bSYork Sun 	unsigned int srt = 0;	/* self-refresh temerature, normal range */
95703e664d8SYork Sun 	unsigned int cwl = compute_cas_write_latency(ctrl_num) - 9;
95834e026f9SYork Sun 	unsigned int mpr = 0;	/* serial */
95934e026f9SYork Sun 	unsigned int wc_lat;
96003e664d8SYork Sun 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
9615614e71bSYork Sun 
9625614e71bSYork Sun 	if (popts->rtt_override)
9635614e71bSYork Sun 		rtt_wr = popts->rtt_wr_override_value;
9645614e71bSYork Sun 	else
9655614e71bSYork Sun 		rtt_wr = popts->cs_local_opts[0].odt_rtt_wr;
9665614e71bSYork Sun 
9675614e71bSYork Sun 	if (common_dimm->extended_op_srt)
9685614e71bSYork Sun 		srt = common_dimm->extended_op_srt;
9695614e71bSYork Sun 
9705614e71bSYork Sun 	esdmode2 = (0
97134e026f9SYork Sun 		| ((wr_crc & 0x1) << 12)
9725614e71bSYork Sun 		| ((rtt_wr & 0x3) << 9)
97334e026f9SYork Sun 		| ((srt & 0x3) << 6)
97434e026f9SYork Sun 		| ((cwl & 0x7) << 3));
97534e026f9SYork Sun 
97634e026f9SYork Sun 	if (mclk_ps >= 1250)
97734e026f9SYork Sun 		wc_lat = 0;
97834e026f9SYork Sun 	else if (mclk_ps >= 833)
97934e026f9SYork Sun 		wc_lat = 1;
98034e026f9SYork Sun 	else
98134e026f9SYork Sun 		wc_lat = 2;
98234e026f9SYork Sun 
98334e026f9SYork Sun 	esdmode3 = (0
98434e026f9SYork Sun 		| ((mpr & 0x3) << 11)
98534e026f9SYork Sun 		| ((wc_lat & 0x3) << 9));
98634e026f9SYork Sun 
9875614e71bSYork Sun 	ddr->ddr_sdram_mode_2 = (0
9885614e71bSYork Sun 				 | ((esdmode2 & 0xFFFF) << 16)
9895614e71bSYork Sun 				 | ((esdmode3 & 0xFFFF) << 0)
9905614e71bSYork Sun 				 );
9915614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2);
9925614e71bSYork Sun 
9935614e71bSYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
9945614e71bSYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
9955614e71bSYork Sun 			if (popts->rtt_override)
9965614e71bSYork Sun 				rtt_wr = popts->rtt_wr_override_value;
9975614e71bSYork Sun 			else
9985614e71bSYork Sun 				rtt_wr = popts->cs_local_opts[i].odt_rtt_wr;
9995614e71bSYork Sun 
10005614e71bSYork Sun 			esdmode2 &= 0xF9FF;	/* clear bit 10, 9 */
10015614e71bSYork Sun 			esdmode2 |= (rtt_wr & 0x3) << 9;
10025614e71bSYork Sun 			switch (i) {
10035614e71bSYork Sun 			case 1:
10045614e71bSYork Sun 				ddr->ddr_sdram_mode_4 = (0
10055614e71bSYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
10065614e71bSYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
10075614e71bSYork Sun 					);
10085614e71bSYork Sun 				break;
10095614e71bSYork Sun 			case 2:
10105614e71bSYork Sun 				ddr->ddr_sdram_mode_6 = (0
10115614e71bSYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
10125614e71bSYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
10135614e71bSYork Sun 					);
10145614e71bSYork Sun 				break;
10155614e71bSYork Sun 			case 3:
10165614e71bSYork Sun 				ddr->ddr_sdram_mode_8 = (0
10175614e71bSYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
10185614e71bSYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
10195614e71bSYork Sun 					);
10205614e71bSYork Sun 				break;
10215614e71bSYork Sun 			}
10225614e71bSYork Sun 		}
10235614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n",
10245614e71bSYork Sun 		      ddr->ddr_sdram_mode_4);
10255614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n",
10265614e71bSYork Sun 		      ddr->ddr_sdram_mode_6);
10275614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n",
10285614e71bSYork Sun 		      ddr->ddr_sdram_mode_8);
10295614e71bSYork Sun 	}
10305614e71bSYork Sun }
103134e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
103234e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
103303e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
103403e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
103534e026f9SYork Sun 				const memctl_options_t *popts,
103634e026f9SYork Sun 				const common_timing_params_t *common_dimm,
103734e026f9SYork Sun 				const unsigned int unq_mrs_en)
103834e026f9SYork Sun {
103934e026f9SYork Sun 	unsigned short esdmode2 = 0;	/* Extended SDRAM mode 2 */
104034e026f9SYork Sun 	unsigned short esdmode3 = 0;	/* Extended SDRAM mode 3 */
104134e026f9SYork Sun 	int i;
104234e026f9SYork Sun 	unsigned int rtt_wr = 0;	/* Rtt_WR - dynamic ODT off */
104334e026f9SYork Sun 	unsigned int srt = 0;	/* self-refresh temerature, normal range */
104434e026f9SYork Sun 	unsigned int asr = 0;	/* auto self-refresh disable */
104503e664d8SYork Sun 	unsigned int cwl = compute_cas_write_latency(ctrl_num) - 5;
104634e026f9SYork Sun 	unsigned int pasr = 0;	/* partial array self refresh disable */
104734e026f9SYork Sun 
104834e026f9SYork Sun 	if (popts->rtt_override)
104934e026f9SYork Sun 		rtt_wr = popts->rtt_wr_override_value;
105034e026f9SYork Sun 	else
105134e026f9SYork Sun 		rtt_wr = popts->cs_local_opts[0].odt_rtt_wr;
105234e026f9SYork Sun 
105334e026f9SYork Sun 	if (common_dimm->extended_op_srt)
105434e026f9SYork Sun 		srt = common_dimm->extended_op_srt;
105534e026f9SYork Sun 
105634e026f9SYork Sun 	esdmode2 = (0
105734e026f9SYork Sun 		| ((rtt_wr & 0x3) << 9)
105834e026f9SYork Sun 		| ((srt & 0x1) << 7)
105934e026f9SYork Sun 		| ((asr & 0x1) << 6)
106034e026f9SYork Sun 		| ((cwl & 0x7) << 3)
106134e026f9SYork Sun 		| ((pasr & 0x7) << 0));
106234e026f9SYork Sun 	ddr->ddr_sdram_mode_2 = (0
106334e026f9SYork Sun 				 | ((esdmode2 & 0xFFFF) << 16)
106434e026f9SYork Sun 				 | ((esdmode3 & 0xFFFF) << 0)
106534e026f9SYork Sun 				 );
106634e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2);
106734e026f9SYork Sun 
106834e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
106934e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
107034e026f9SYork Sun 			if (popts->rtt_override)
107134e026f9SYork Sun 				rtt_wr = popts->rtt_wr_override_value;
107234e026f9SYork Sun 			else
107334e026f9SYork Sun 				rtt_wr = popts->cs_local_opts[i].odt_rtt_wr;
107434e026f9SYork Sun 
107534e026f9SYork Sun 			esdmode2 &= 0xF9FF;	/* clear bit 10, 9 */
107634e026f9SYork Sun 			esdmode2 |= (rtt_wr & 0x3) << 9;
107734e026f9SYork Sun 			switch (i) {
107834e026f9SYork Sun 			case 1:
107934e026f9SYork Sun 				ddr->ddr_sdram_mode_4 = (0
108034e026f9SYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
108134e026f9SYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
108234e026f9SYork Sun 					);
108334e026f9SYork Sun 				break;
108434e026f9SYork Sun 			case 2:
108534e026f9SYork Sun 				ddr->ddr_sdram_mode_6 = (0
108634e026f9SYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
108734e026f9SYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
108834e026f9SYork Sun 					);
108934e026f9SYork Sun 				break;
109034e026f9SYork Sun 			case 3:
109134e026f9SYork Sun 				ddr->ddr_sdram_mode_8 = (0
109234e026f9SYork Sun 					| ((esdmode2 & 0xFFFF) << 16)
109334e026f9SYork Sun 					| ((esdmode3 & 0xFFFF) << 0)
109434e026f9SYork Sun 					);
109534e026f9SYork Sun 				break;
109634e026f9SYork Sun 			}
109734e026f9SYork Sun 		}
109834e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n",
109934e026f9SYork Sun 			ddr->ddr_sdram_mode_4);
110034e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n",
110134e026f9SYork Sun 			ddr->ddr_sdram_mode_6);
110234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n",
110334e026f9SYork Sun 			ddr->ddr_sdram_mode_8);
110434e026f9SYork Sun 	}
110534e026f9SYork Sun }
110634e026f9SYork Sun 
110734e026f9SYork Sun #else /* for DDR2 and DDR1 */
110834e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
110903e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
111003e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
111134e026f9SYork Sun 				const memctl_options_t *popts,
111234e026f9SYork Sun 				const common_timing_params_t *common_dimm,
111334e026f9SYork Sun 				const unsigned int unq_mrs_en)
111434e026f9SYork Sun {
111534e026f9SYork Sun 	unsigned short esdmode2 = 0;	/* Extended SDRAM mode 2 */
111634e026f9SYork Sun 	unsigned short esdmode3 = 0;	/* Extended SDRAM mode 3 */
111734e026f9SYork Sun 
111834e026f9SYork Sun 	ddr->ddr_sdram_mode_2 = (0
111934e026f9SYork Sun 				 | ((esdmode2 & 0xFFFF) << 16)
112034e026f9SYork Sun 				 | ((esdmode3 & 0xFFFF) << 0)
112134e026f9SYork Sun 				 );
112234e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2);
112334e026f9SYork Sun }
112434e026f9SYork Sun #endif
112534e026f9SYork Sun 
112634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
112734e026f9SYork Sun /* DDR SDRAM Mode configuration 9 (DDR_SDRAM_MODE_9) */
112834e026f9SYork Sun static void set_ddr_sdram_mode_9(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 esdmode4 = 0;	/* Extended SDRAM mode 4 */
113534e026f9SYork Sun 	unsigned short esdmode5;	/* Extended SDRAM mode 5 */
11366b95be22SYork Sun 	int rtt_park = 0;
11378a51429eSYork Sun 	bool four_cs = false;
113834e026f9SYork Sun 
11398a51429eSYork Sun #if CONFIG_CHIP_SELECTS_PER_CTRL == 4
11408a51429eSYork Sun 	if ((ddr->cs[0].config & SDRAM_CS_CONFIG_EN) &&
11418a51429eSYork Sun 	    (ddr->cs[1].config & SDRAM_CS_CONFIG_EN) &&
11428a51429eSYork Sun 	    (ddr->cs[2].config & SDRAM_CS_CONFIG_EN) &&
11438a51429eSYork Sun 	    (ddr->cs[3].config & SDRAM_CS_CONFIG_EN))
11448a51429eSYork Sun 		four_cs = true;
11458a51429eSYork Sun #endif
11466b95be22SYork Sun 	if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) {
11476b95be22SYork Sun 		esdmode5 = 0x00000500;	/* Data mask enable, RTT_PARK CS0 */
11488a51429eSYork Sun 		rtt_park = four_cs ? 0 : 1;
11496b95be22SYork Sun 	} else {
11506b95be22SYork Sun 		esdmode5 = 0x00000400;	/* Data mask enabled */
11516b95be22SYork Sun 	}
115234e026f9SYork Sun 
115334e026f9SYork Sun 	ddr->ddr_sdram_mode_9 = (0
115434e026f9SYork Sun 				 | ((esdmode4 & 0xffff) << 16)
115534e026f9SYork Sun 				 | ((esdmode5 & 0xffff) << 0)
115634e026f9SYork Sun 				);
115766869f95SYork Sun 
11588a51429eSYork Sun 	/* Normally only the first enabled CS use 0x500, others use 0x400
11598a51429eSYork Sun 	 * But when four chip-selects are all enabled, all mode registers
11608a51429eSYork Sun 	 * need 0x500 to park.
11618a51429eSYork Sun 	 */
116266869f95SYork Sun 
116334e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9);
116434e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
116534e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
11666b95be22SYork Sun 			if (!rtt_park &&
11676b95be22SYork Sun 			    (ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) {
11686b95be22SYork Sun 				esdmode5 |= 0x00000500;	/* RTT_PARK */
11698a51429eSYork Sun 				rtt_park = four_cs ? 0 : 1;
11706b95be22SYork Sun 			} else {
11716b95be22SYork Sun 				esdmode5 = 0x00000400;
11726b95be22SYork Sun 			}
117334e026f9SYork Sun 			switch (i) {
117434e026f9SYork Sun 			case 1:
117534e026f9SYork Sun 				ddr->ddr_sdram_mode_11 = (0
117634e026f9SYork Sun 					| ((esdmode4 & 0xFFFF) << 16)
117734e026f9SYork Sun 					| ((esdmode5 & 0xFFFF) << 0)
117834e026f9SYork Sun 					);
117934e026f9SYork Sun 				break;
118034e026f9SYork Sun 			case 2:
118134e026f9SYork Sun 				ddr->ddr_sdram_mode_13 = (0
118234e026f9SYork Sun 					| ((esdmode4 & 0xFFFF) << 16)
118334e026f9SYork Sun 					| ((esdmode5 & 0xFFFF) << 0)
118434e026f9SYork Sun 					);
118534e026f9SYork Sun 				break;
118634e026f9SYork Sun 			case 3:
118734e026f9SYork Sun 				ddr->ddr_sdram_mode_15 = (0
118834e026f9SYork Sun 					| ((esdmode4 & 0xFFFF) << 16)
118934e026f9SYork Sun 					| ((esdmode5 & 0xFFFF) << 0)
119034e026f9SYork Sun 					);
119134e026f9SYork Sun 				break;
119234e026f9SYork Sun 			}
119334e026f9SYork Sun 		}
119434e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_11 = 0x%08x\n",
119534e026f9SYork Sun 		      ddr->ddr_sdram_mode_11);
119634e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_13 = 0x%08x\n",
119734e026f9SYork Sun 		      ddr->ddr_sdram_mode_13);
119834e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_15 = 0x%08x\n",
119934e026f9SYork Sun 		      ddr->ddr_sdram_mode_15);
120034e026f9SYork Sun 	}
120134e026f9SYork Sun }
120234e026f9SYork Sun 
120334e026f9SYork Sun /* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */
120403e664d8SYork Sun static void set_ddr_sdram_mode_10(const unsigned int ctrl_num,
120503e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
120634e026f9SYork Sun 				const memctl_options_t *popts,
120734e026f9SYork Sun 				const common_timing_params_t *common_dimm,
120834e026f9SYork Sun 				const unsigned int unq_mrs_en)
120934e026f9SYork Sun {
121034e026f9SYork Sun 	int i;
121134e026f9SYork Sun 	unsigned short esdmode6 = 0;	/* Extended SDRAM mode 6 */
121234e026f9SYork Sun 	unsigned short esdmode7 = 0;	/* Extended SDRAM mode 7 */
121303e664d8SYork Sun 	unsigned int tccdl_min = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
121434e026f9SYork Sun 
121534e026f9SYork Sun 	esdmode6 = ((tccdl_min - 4) & 0x7) << 10;
121634e026f9SYork Sun 
12170fb71974SYork Sun 	if (popts->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2)
12180fb71974SYork Sun 		esdmode6 |= 1 << 6;	/* Range 2 */
12190fb71974SYork Sun 
122034e026f9SYork Sun 	ddr->ddr_sdram_mode_10 = (0
122134e026f9SYork Sun 				 | ((esdmode6 & 0xffff) << 16)
122234e026f9SYork Sun 				 | ((esdmode7 & 0xffff) << 0)
122334e026f9SYork Sun 				);
122434e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode_10) = 0x%08x\n", ddr->ddr_sdram_mode_10);
122534e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
122634e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
122734e026f9SYork Sun 			switch (i) {
122834e026f9SYork Sun 			case 1:
122934e026f9SYork Sun 				ddr->ddr_sdram_mode_12 = (0
123034e026f9SYork Sun 					| ((esdmode6 & 0xFFFF) << 16)
123134e026f9SYork Sun 					| ((esdmode7 & 0xFFFF) << 0)
123234e026f9SYork Sun 					);
123334e026f9SYork Sun 				break;
123434e026f9SYork Sun 			case 2:
123534e026f9SYork Sun 				ddr->ddr_sdram_mode_14 = (0
123634e026f9SYork Sun 					| ((esdmode6 & 0xFFFF) << 16)
123734e026f9SYork Sun 					| ((esdmode7 & 0xFFFF) << 0)
123834e026f9SYork Sun 					);
123934e026f9SYork Sun 				break;
124034e026f9SYork Sun 			case 3:
124134e026f9SYork Sun 				ddr->ddr_sdram_mode_16 = (0
124234e026f9SYork Sun 					| ((esdmode6 & 0xFFFF) << 16)
124334e026f9SYork Sun 					| ((esdmode7 & 0xFFFF) << 0)
124434e026f9SYork Sun 					);
124534e026f9SYork Sun 				break;
124634e026f9SYork Sun 			}
124734e026f9SYork Sun 		}
124834e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_12 = 0x%08x\n",
124934e026f9SYork Sun 		      ddr->ddr_sdram_mode_12);
125034e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_14 = 0x%08x\n",
125134e026f9SYork Sun 		      ddr->ddr_sdram_mode_14);
125234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_16 = 0x%08x\n",
125334e026f9SYork Sun 		      ddr->ddr_sdram_mode_16);
125434e026f9SYork Sun 	}
125534e026f9SYork Sun }
125634e026f9SYork Sun 
125734e026f9SYork Sun #endif
12585614e71bSYork Sun 
12595614e71bSYork Sun /* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */
126003e664d8SYork Sun static void set_ddr_sdram_interval(const unsigned int ctrl_num,
126103e664d8SYork Sun 				fsl_ddr_cfg_regs_t *ddr,
12625614e71bSYork Sun 				const memctl_options_t *popts,
12635614e71bSYork Sun 				const common_timing_params_t *common_dimm)
12645614e71bSYork Sun {
12655614e71bSYork Sun 	unsigned int refint;	/* Refresh interval */
12665614e71bSYork Sun 	unsigned int bstopre;	/* Precharge interval */
12675614e71bSYork Sun 
126803e664d8SYork Sun 	refint = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps);
12695614e71bSYork Sun 
12705614e71bSYork Sun 	bstopre = popts->bstopre;
12715614e71bSYork Sun 
12725614e71bSYork Sun 	/* refint field used 0x3FFF in earlier controllers */
12735614e71bSYork Sun 	ddr->ddr_sdram_interval = (0
12745614e71bSYork Sun 				   | ((refint & 0xFFFF) << 16)
12755614e71bSYork Sun 				   | ((bstopre & 0x3FFF) << 0)
12765614e71bSYork Sun 				   );
12775614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_interval = 0x%08x\n", ddr->ddr_sdram_interval);
12785614e71bSYork Sun }
12795614e71bSYork Sun 
128034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
12815614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
128203e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num,
128303e664d8SYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
12845614e71bSYork Sun 			       const memctl_options_t *popts,
12855614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
12865614e71bSYork Sun 			       unsigned int cas_latency,
12875614e71bSYork Sun 			       unsigned int additive_latency,
12885614e71bSYork Sun 			       const unsigned int unq_mrs_en)
12895614e71bSYork Sun {
129034e026f9SYork Sun 	int i;
129134e026f9SYork Sun 	unsigned short esdmode;		/* Extended SDRAM mode */
129234e026f9SYork Sun 	unsigned short sdmode;		/* SDRAM mode */
129334e026f9SYork Sun 
129434e026f9SYork Sun 	/* Mode Register - MR1 */
129534e026f9SYork Sun 	unsigned int qoff = 0;		/* Output buffer enable 0=yes, 1=no */
129634e026f9SYork Sun 	unsigned int tdqs_en = 0;	/* TDQS Enable: 0=no, 1=yes */
129734e026f9SYork Sun 	unsigned int rtt;
129834e026f9SYork Sun 	unsigned int wrlvl_en = 0;	/* Write level enable: 0=no, 1=yes */
129934e026f9SYork Sun 	unsigned int al = 0;		/* Posted CAS# additive latency (AL) */
130034e026f9SYork Sun 	unsigned int dic = 0;		/* Output driver impedance, 40ohm */
130134e026f9SYork Sun 	unsigned int dll_en = 1;	/* DLL Enable  1=Enable (Normal),
130234e026f9SYork Sun 						       0=Disable (Test/Debug) */
130334e026f9SYork Sun 
130434e026f9SYork Sun 	/* Mode Register - MR0 */
130534e026f9SYork Sun 	unsigned int wr = 0;	/* Write Recovery */
130634e026f9SYork Sun 	unsigned int dll_rst;	/* DLL Reset */
130734e026f9SYork Sun 	unsigned int mode;	/* Normal=0 or Test=1 */
130834e026f9SYork Sun 	unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */
130934e026f9SYork Sun 	/* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */
131034e026f9SYork Sun 	unsigned int bt;
131134e026f9SYork Sun 	unsigned int bl;	/* BL: Burst Length */
131234e026f9SYork Sun 
131334e026f9SYork Sun 	unsigned int wr_mclk;
131434e026f9SYork Sun 	/* DDR4 support WR 10, 12, 14, 16, 18, 20, 24 */
131534e026f9SYork Sun 	static const u8 wr_table[] = {
131634e026f9SYork Sun 		0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6};
131734e026f9SYork Sun 	/* DDR4 support CAS 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24 */
131834e026f9SYork Sun 	static const u8 cas_latency_table[] = {
131934e026f9SYork Sun 		0, 1, 2, 3, 4, 5, 6, 7, 8, 8,
132034e026f9SYork Sun 		9, 9, 10, 10, 11, 11};
132134e026f9SYork Sun 
132234e026f9SYork Sun 	if (popts->rtt_override)
132334e026f9SYork Sun 		rtt = popts->rtt_override_value;
132434e026f9SYork Sun 	else
132534e026f9SYork Sun 		rtt = popts->cs_local_opts[0].odt_rtt_norm;
132634e026f9SYork Sun 
132734e026f9SYork Sun 	if (additive_latency == (cas_latency - 1))
132834e026f9SYork Sun 		al = 1;
132934e026f9SYork Sun 	if (additive_latency == (cas_latency - 2))
133034e026f9SYork Sun 		al = 2;
133134e026f9SYork Sun 
133234e026f9SYork Sun 	if (popts->quad_rank_present)
133334e026f9SYork Sun 		dic = 1;	/* output driver impedance 240/7 ohm */
133434e026f9SYork Sun 
133534e026f9SYork Sun 	/*
133634e026f9SYork Sun 	 * The esdmode value will also be used for writing
133734e026f9SYork Sun 	 * MR1 during write leveling for DDR3, although the
133834e026f9SYork Sun 	 * bits specifically related to the write leveling
133934e026f9SYork Sun 	 * scheme will be handled automatically by the DDR
134034e026f9SYork Sun 	 * controller. so we set the wrlvl_en = 0 here.
134134e026f9SYork Sun 	 */
134234e026f9SYork Sun 	esdmode = (0
134334e026f9SYork Sun 		| ((qoff & 0x1) << 12)
134434e026f9SYork Sun 		| ((tdqs_en & 0x1) << 11)
134534e026f9SYork Sun 		| ((rtt & 0x7) << 8)
134634e026f9SYork Sun 		| ((wrlvl_en & 0x1) << 7)
134734e026f9SYork Sun 		| ((al & 0x3) << 3)
134834e026f9SYork Sun 		| ((dic & 0x3) << 1)   /* DIC field is split */
134934e026f9SYork Sun 		| ((dll_en & 0x1) << 0)
135034e026f9SYork Sun 		);
135134e026f9SYork Sun 
135234e026f9SYork Sun 	/*
135334e026f9SYork Sun 	 * DLL control for precharge PD
135434e026f9SYork Sun 	 * 0=slow exit DLL off (tXPDLL)
135534e026f9SYork Sun 	 * 1=fast exit DLL on (tXP)
135634e026f9SYork Sun 	 */
135734e026f9SYork Sun 
135803e664d8SYork Sun 	wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
135934e026f9SYork Sun 	if (wr_mclk <= 24) {
136034e026f9SYork Sun 		wr = wr_table[wr_mclk - 10];
136134e026f9SYork Sun 	} else {
136234e026f9SYork Sun 		printf("Error: unsupported write recovery for mode register wr_mclk = %d\n",
136334e026f9SYork Sun 		       wr_mclk);
136434e026f9SYork Sun 	}
136534e026f9SYork Sun 
136634e026f9SYork Sun 	dll_rst = 0;	/* dll no reset */
136734e026f9SYork Sun 	mode = 0;	/* normal mode */
136834e026f9SYork Sun 
136934e026f9SYork Sun 	/* look up table to get the cas latency bits */
137034e026f9SYork Sun 	if (cas_latency >= 9 && cas_latency <= 24)
137134e026f9SYork Sun 		caslat = cas_latency_table[cas_latency - 9];
137234e026f9SYork Sun 	else
137334e026f9SYork Sun 		printf("Error: unsupported cas latency for mode register\n");
137434e026f9SYork Sun 
137534e026f9SYork Sun 	bt = 0;	/* Nibble sequential */
137634e026f9SYork Sun 
137734e026f9SYork Sun 	switch (popts->burst_length) {
137834e026f9SYork Sun 	case DDR_BL8:
137934e026f9SYork Sun 		bl = 0;
138034e026f9SYork Sun 		break;
138134e026f9SYork Sun 	case DDR_OTF:
138234e026f9SYork Sun 		bl = 1;
138334e026f9SYork Sun 		break;
138434e026f9SYork Sun 	case DDR_BC4:
138534e026f9SYork Sun 		bl = 2;
138634e026f9SYork Sun 		break;
138734e026f9SYork Sun 	default:
138834e026f9SYork Sun 		printf("Error: invalid burst length of %u specified. ",
138934e026f9SYork Sun 		       popts->burst_length);
139034e026f9SYork Sun 		puts("Defaulting to on-the-fly BC4 or BL8 beats.\n");
139134e026f9SYork Sun 		bl = 1;
139234e026f9SYork Sun 		break;
139334e026f9SYork Sun 	}
139434e026f9SYork Sun 
139534e026f9SYork Sun 	sdmode = (0
139634e026f9SYork Sun 		  | ((wr & 0x7) << 9)
139734e026f9SYork Sun 		  | ((dll_rst & 0x1) << 8)
139834e026f9SYork Sun 		  | ((mode & 0x1) << 7)
139934e026f9SYork Sun 		  | (((caslat >> 1) & 0x7) << 4)
140034e026f9SYork Sun 		  | ((bt & 0x1) << 3)
140134e026f9SYork Sun 		  | ((caslat & 1) << 2)
140234e026f9SYork Sun 		  | ((bl & 0x3) << 0)
140334e026f9SYork Sun 		  );
140434e026f9SYork Sun 
140534e026f9SYork Sun 	ddr->ddr_sdram_mode = (0
140634e026f9SYork Sun 			       | ((esdmode & 0xFFFF) << 16)
140734e026f9SYork Sun 			       | ((sdmode & 0xFFFF) << 0)
140834e026f9SYork Sun 			       );
140934e026f9SYork Sun 
141034e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode);
141134e026f9SYork Sun 
141234e026f9SYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
141334e026f9SYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
141434e026f9SYork Sun 			if (popts->rtt_override)
141534e026f9SYork Sun 				rtt = popts->rtt_override_value;
141634e026f9SYork Sun 			else
141734e026f9SYork Sun 				rtt = popts->cs_local_opts[i].odt_rtt_norm;
141834e026f9SYork Sun 
141934e026f9SYork Sun 			esdmode &= 0xF8FF;	/* clear bit 10,9,8 for rtt */
142034e026f9SYork Sun 			esdmode |= (rtt & 0x7) << 8;
142134e026f9SYork Sun 			switch (i) {
142234e026f9SYork Sun 			case 1:
142334e026f9SYork Sun 				ddr->ddr_sdram_mode_3 = (0
142434e026f9SYork Sun 				       | ((esdmode & 0xFFFF) << 16)
142534e026f9SYork Sun 				       | ((sdmode & 0xFFFF) << 0)
142634e026f9SYork Sun 				       );
142734e026f9SYork Sun 				break;
142834e026f9SYork Sun 			case 2:
142934e026f9SYork Sun 				ddr->ddr_sdram_mode_5 = (0
143034e026f9SYork Sun 				       | ((esdmode & 0xFFFF) << 16)
143134e026f9SYork Sun 				       | ((sdmode & 0xFFFF) << 0)
143234e026f9SYork Sun 				       );
143334e026f9SYork Sun 				break;
143434e026f9SYork Sun 			case 3:
143534e026f9SYork Sun 				ddr->ddr_sdram_mode_7 = (0
143634e026f9SYork Sun 				       | ((esdmode & 0xFFFF) << 16)
143734e026f9SYork Sun 				       | ((sdmode & 0xFFFF) << 0)
143834e026f9SYork Sun 				       );
143934e026f9SYork Sun 				break;
144034e026f9SYork Sun 			}
144134e026f9SYork Sun 		}
144234e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n",
144334e026f9SYork Sun 		      ddr->ddr_sdram_mode_3);
144434e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
144534e026f9SYork Sun 		      ddr->ddr_sdram_mode_5);
144634e026f9SYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
144734e026f9SYork Sun 		      ddr->ddr_sdram_mode_5);
144834e026f9SYork Sun 	}
144934e026f9SYork Sun }
145034e026f9SYork Sun 
145134e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
145234e026f9SYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
145303e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num,
145403e664d8SYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
145534e026f9SYork Sun 			       const memctl_options_t *popts,
145634e026f9SYork Sun 			       const common_timing_params_t *common_dimm,
145734e026f9SYork Sun 			       unsigned int cas_latency,
145834e026f9SYork Sun 			       unsigned int additive_latency,
145934e026f9SYork Sun 			       const unsigned int unq_mrs_en)
146034e026f9SYork Sun {
146134e026f9SYork Sun 	int i;
14625614e71bSYork Sun 	unsigned short esdmode;		/* Extended SDRAM mode */
14635614e71bSYork Sun 	unsigned short sdmode;		/* SDRAM mode */
14645614e71bSYork Sun 
14655614e71bSYork Sun 	/* Mode Register - MR1 */
14665614e71bSYork Sun 	unsigned int qoff = 0;		/* Output buffer enable 0=yes, 1=no */
14675614e71bSYork Sun 	unsigned int tdqs_en = 0;	/* TDQS Enable: 0=no, 1=yes */
14685614e71bSYork Sun 	unsigned int rtt;
14695614e71bSYork Sun 	unsigned int wrlvl_en = 0;	/* Write level enable: 0=no, 1=yes */
14705614e71bSYork Sun 	unsigned int al = 0;		/* Posted CAS# additive latency (AL) */
14715614e71bSYork Sun 	unsigned int dic = 0;		/* Output driver impedance, 40ohm */
14725614e71bSYork Sun 	unsigned int dll_en = 0;	/* DLL Enable  0=Enable (Normal),
14735614e71bSYork Sun 						       1=Disable (Test/Debug) */
14745614e71bSYork Sun 
14755614e71bSYork Sun 	/* Mode Register - MR0 */
14765614e71bSYork Sun 	unsigned int dll_on;	/* DLL control for precharge PD, 0=off, 1=on */
14775614e71bSYork Sun 	unsigned int wr = 0;	/* Write Recovery */
14785614e71bSYork Sun 	unsigned int dll_rst;	/* DLL Reset */
14795614e71bSYork Sun 	unsigned int mode;	/* Normal=0 or Test=1 */
14805614e71bSYork Sun 	unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */
14815614e71bSYork Sun 	/* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */
14825614e71bSYork Sun 	unsigned int bt;
14835614e71bSYork Sun 	unsigned int bl;	/* BL: Burst Length */
14845614e71bSYork Sun 
14855614e71bSYork Sun 	unsigned int wr_mclk;
14865614e71bSYork Sun 	/*
14875614e71bSYork Sun 	 * DDR_SDRAM_MODE doesn't support 9,11,13,15
14885614e71bSYork Sun 	 * Please refer JEDEC Standard No. 79-3E for Mode Register MR0
14895614e71bSYork Sun 	 * for this table
14905614e71bSYork Sun 	 */
14915614e71bSYork Sun 	static const u8 wr_table[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0};
14925614e71bSYork Sun 
14935614e71bSYork Sun 	if (popts->rtt_override)
14945614e71bSYork Sun 		rtt = popts->rtt_override_value;
14955614e71bSYork Sun 	else
14965614e71bSYork Sun 		rtt = popts->cs_local_opts[0].odt_rtt_norm;
14975614e71bSYork Sun 
14985614e71bSYork Sun 	if (additive_latency == (cas_latency - 1))
14995614e71bSYork Sun 		al = 1;
15005614e71bSYork Sun 	if (additive_latency == (cas_latency - 2))
15015614e71bSYork Sun 		al = 2;
15025614e71bSYork Sun 
15035614e71bSYork Sun 	if (popts->quad_rank_present)
15045614e71bSYork Sun 		dic = 1;	/* output driver impedance 240/7 ohm */
15055614e71bSYork Sun 
15065614e71bSYork Sun 	/*
15075614e71bSYork Sun 	 * The esdmode value will also be used for writing
15085614e71bSYork Sun 	 * MR1 during write leveling for DDR3, although the
15095614e71bSYork Sun 	 * bits specifically related to the write leveling
15105614e71bSYork Sun 	 * scheme will be handled automatically by the DDR
15115614e71bSYork Sun 	 * controller. so we set the wrlvl_en = 0 here.
15125614e71bSYork Sun 	 */
15135614e71bSYork Sun 	esdmode = (0
15145614e71bSYork Sun 		| ((qoff & 0x1) << 12)
15155614e71bSYork Sun 		| ((tdqs_en & 0x1) << 11)
15165614e71bSYork Sun 		| ((rtt & 0x4) << 7)   /* rtt field is split */
15175614e71bSYork Sun 		| ((wrlvl_en & 0x1) << 7)
15185614e71bSYork Sun 		| ((rtt & 0x2) << 5)   /* rtt field is split */
15195614e71bSYork Sun 		| ((dic & 0x2) << 4)   /* DIC field is split */
15205614e71bSYork Sun 		| ((al & 0x3) << 3)
15215614e71bSYork Sun 		| ((rtt & 0x1) << 2)  /* rtt field is split */
15225614e71bSYork Sun 		| ((dic & 0x1) << 1)   /* DIC field is split */
15235614e71bSYork Sun 		| ((dll_en & 0x1) << 0)
15245614e71bSYork Sun 		);
15255614e71bSYork Sun 
15265614e71bSYork Sun 	/*
15275614e71bSYork Sun 	 * DLL control for precharge PD
15285614e71bSYork Sun 	 * 0=slow exit DLL off (tXPDLL)
15295614e71bSYork Sun 	 * 1=fast exit DLL on (tXP)
15305614e71bSYork Sun 	 */
15315614e71bSYork Sun 	dll_on = 1;
15325614e71bSYork Sun 
153303e664d8SYork Sun 	wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
15345614e71bSYork Sun 	if (wr_mclk <= 16) {
15355614e71bSYork Sun 		wr = wr_table[wr_mclk - 5];
15365614e71bSYork Sun 	} else {
15375614e71bSYork Sun 		printf("Error: unsupported write recovery for mode register "
15385614e71bSYork Sun 		       "wr_mclk = %d\n", wr_mclk);
15395614e71bSYork Sun 	}
15405614e71bSYork Sun 
15415614e71bSYork Sun 	dll_rst = 0;	/* dll no reset */
15425614e71bSYork Sun 	mode = 0;	/* normal mode */
15435614e71bSYork Sun 
15445614e71bSYork Sun 	/* look up table to get the cas latency bits */
15455614e71bSYork Sun 	if (cas_latency >= 5 && cas_latency <= 16) {
15465614e71bSYork Sun 		unsigned char cas_latency_table[] = {
15475614e71bSYork Sun 			0x2,	/* 5 clocks */
15485614e71bSYork Sun 			0x4,	/* 6 clocks */
15495614e71bSYork Sun 			0x6,	/* 7 clocks */
15505614e71bSYork Sun 			0x8,	/* 8 clocks */
15515614e71bSYork Sun 			0xa,	/* 9 clocks */
15525614e71bSYork Sun 			0xc,	/* 10 clocks */
15535614e71bSYork Sun 			0xe,	/* 11 clocks */
15545614e71bSYork Sun 			0x1,	/* 12 clocks */
15555614e71bSYork Sun 			0x3,	/* 13 clocks */
15565614e71bSYork Sun 			0x5,	/* 14 clocks */
15575614e71bSYork Sun 			0x7,	/* 15 clocks */
15585614e71bSYork Sun 			0x9,	/* 16 clocks */
15595614e71bSYork Sun 		};
15605614e71bSYork Sun 		caslat = cas_latency_table[cas_latency - 5];
15615614e71bSYork Sun 	} else {
15625614e71bSYork Sun 		printf("Error: unsupported cas latency for mode register\n");
15635614e71bSYork Sun 	}
15645614e71bSYork Sun 
15655614e71bSYork Sun 	bt = 0;	/* Nibble sequential */
15665614e71bSYork Sun 
15675614e71bSYork Sun 	switch (popts->burst_length) {
15685614e71bSYork Sun 	case DDR_BL8:
15695614e71bSYork Sun 		bl = 0;
15705614e71bSYork Sun 		break;
15715614e71bSYork Sun 	case DDR_OTF:
15725614e71bSYork Sun 		bl = 1;
15735614e71bSYork Sun 		break;
15745614e71bSYork Sun 	case DDR_BC4:
15755614e71bSYork Sun 		bl = 2;
15765614e71bSYork Sun 		break;
15775614e71bSYork Sun 	default:
15785614e71bSYork Sun 		printf("Error: invalid burst length of %u specified. "
15795614e71bSYork Sun 			" Defaulting to on-the-fly BC4 or BL8 beats.\n",
15805614e71bSYork Sun 			popts->burst_length);
15815614e71bSYork Sun 		bl = 1;
15825614e71bSYork Sun 		break;
15835614e71bSYork Sun 	}
15845614e71bSYork Sun 
15855614e71bSYork Sun 	sdmode = (0
15865614e71bSYork Sun 		  | ((dll_on & 0x1) << 12)
15875614e71bSYork Sun 		  | ((wr & 0x7) << 9)
15885614e71bSYork Sun 		  | ((dll_rst & 0x1) << 8)
15895614e71bSYork Sun 		  | ((mode & 0x1) << 7)
15905614e71bSYork Sun 		  | (((caslat >> 1) & 0x7) << 4)
15915614e71bSYork Sun 		  | ((bt & 0x1) << 3)
15925614e71bSYork Sun 		  | ((caslat & 1) << 2)
15935614e71bSYork Sun 		  | ((bl & 0x3) << 0)
15945614e71bSYork Sun 		  );
15955614e71bSYork Sun 
15965614e71bSYork Sun 	ddr->ddr_sdram_mode = (0
15975614e71bSYork Sun 			       | ((esdmode & 0xFFFF) << 16)
15985614e71bSYork Sun 			       | ((sdmode & 0xFFFF) << 0)
15995614e71bSYork Sun 			       );
16005614e71bSYork Sun 
16015614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode);
16025614e71bSYork Sun 
16035614e71bSYork Sun 	if (unq_mrs_en) {	/* unique mode registers are supported */
16045614e71bSYork Sun 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
16055614e71bSYork Sun 			if (popts->rtt_override)
16065614e71bSYork Sun 				rtt = popts->rtt_override_value;
16075614e71bSYork Sun 			else
16085614e71bSYork Sun 				rtt = popts->cs_local_opts[i].odt_rtt_norm;
16095614e71bSYork Sun 
16105614e71bSYork Sun 			esdmode &= 0xFDBB;	/* clear bit 9,6,2 */
16115614e71bSYork Sun 			esdmode |= (0
16125614e71bSYork Sun 				| ((rtt & 0x4) << 7)   /* rtt field is split */
16135614e71bSYork Sun 				| ((rtt & 0x2) << 5)   /* rtt field is split */
16145614e71bSYork Sun 				| ((rtt & 0x1) << 2)  /* rtt field is split */
16155614e71bSYork Sun 				);
16165614e71bSYork Sun 			switch (i) {
16175614e71bSYork Sun 			case 1:
16185614e71bSYork Sun 				ddr->ddr_sdram_mode_3 = (0
16195614e71bSYork Sun 				       | ((esdmode & 0xFFFF) << 16)
16205614e71bSYork Sun 				       | ((sdmode & 0xFFFF) << 0)
16215614e71bSYork Sun 				       );
16225614e71bSYork Sun 				break;
16235614e71bSYork Sun 			case 2:
16245614e71bSYork Sun 				ddr->ddr_sdram_mode_5 = (0
16255614e71bSYork Sun 				       | ((esdmode & 0xFFFF) << 16)
16265614e71bSYork Sun 				       | ((sdmode & 0xFFFF) << 0)
16275614e71bSYork Sun 				       );
16285614e71bSYork Sun 				break;
16295614e71bSYork Sun 			case 3:
16305614e71bSYork Sun 				ddr->ddr_sdram_mode_7 = (0
16315614e71bSYork Sun 				       | ((esdmode & 0xFFFF) << 16)
16325614e71bSYork Sun 				       | ((sdmode & 0xFFFF) << 0)
16335614e71bSYork Sun 				       );
16345614e71bSYork Sun 				break;
16355614e71bSYork Sun 			}
16365614e71bSYork Sun 		}
16375614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n",
16385614e71bSYork Sun 			ddr->ddr_sdram_mode_3);
16395614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
16405614e71bSYork Sun 			ddr->ddr_sdram_mode_5);
16415614e71bSYork Sun 		debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n",
16425614e71bSYork Sun 			ddr->ddr_sdram_mode_5);
16435614e71bSYork Sun 	}
16445614e71bSYork Sun }
16455614e71bSYork Sun 
16465614e71bSYork Sun #else /* !CONFIG_SYS_FSL_DDR3 */
16475614e71bSYork Sun 
16485614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
164903e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num,
165003e664d8SYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
16515614e71bSYork Sun 			       const memctl_options_t *popts,
16525614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
16535614e71bSYork Sun 			       unsigned int cas_latency,
16545614e71bSYork Sun 			       unsigned int additive_latency,
16555614e71bSYork Sun 			       const unsigned int unq_mrs_en)
16565614e71bSYork Sun {
16575614e71bSYork Sun 	unsigned short esdmode;		/* Extended SDRAM mode */
16585614e71bSYork Sun 	unsigned short sdmode;		/* SDRAM mode */
16595614e71bSYork Sun 
16605614e71bSYork Sun 	/*
16615614e71bSYork Sun 	 * FIXME: This ought to be pre-calculated in a
16625614e71bSYork Sun 	 * technology-specific routine,
16635614e71bSYork Sun 	 * e.g. compute_DDR2_mode_register(), and then the
16645614e71bSYork Sun 	 * sdmode and esdmode passed in as part of common_dimm.
16655614e71bSYork Sun 	 */
16665614e71bSYork Sun 
16675614e71bSYork Sun 	/* Extended Mode Register */
16685614e71bSYork Sun 	unsigned int mrs = 0;		/* Mode Register Set */
16695614e71bSYork Sun 	unsigned int outputs = 0;	/* 0=Enabled, 1=Disabled */
16705614e71bSYork Sun 	unsigned int rdqs_en = 0;	/* RDQS Enable: 0=no, 1=yes */
16715614e71bSYork Sun 	unsigned int dqs_en = 0;	/* DQS# Enable: 0=enable, 1=disable */
16725614e71bSYork Sun 	unsigned int ocd = 0;		/* 0x0=OCD not supported,
16735614e71bSYork Sun 					   0x7=OCD default state */
16745614e71bSYork Sun 	unsigned int rtt;
16755614e71bSYork Sun 	unsigned int al;		/* Posted CAS# additive latency (AL) */
16765614e71bSYork Sun 	unsigned int ods = 0;		/* Output Drive Strength:
16775614e71bSYork Sun 						0 = Full strength (18ohm)
16785614e71bSYork Sun 						1 = Reduced strength (4ohm) */
16795614e71bSYork Sun 	unsigned int dll_en = 0;	/* DLL Enable  0=Enable (Normal),
16805614e71bSYork Sun 						       1=Disable (Test/Debug) */
16815614e71bSYork Sun 
16825614e71bSYork Sun 	/* Mode Register (MR) */
16835614e71bSYork Sun 	unsigned int mr;	/* Mode Register Definition */
16845614e71bSYork Sun 	unsigned int pd;	/* Power-Down Mode */
16855614e71bSYork Sun 	unsigned int wr;	/* Write Recovery */
16865614e71bSYork Sun 	unsigned int dll_res;	/* DLL Reset */
16875614e71bSYork Sun 	unsigned int mode;	/* Normal=0 or Test=1 */
16885614e71bSYork Sun 	unsigned int caslat = 0;/* CAS# latency */
16895614e71bSYork Sun 	/* BT: Burst Type (0=Sequential, 1=Interleaved) */
16905614e71bSYork Sun 	unsigned int bt;
16915614e71bSYork Sun 	unsigned int bl;	/* BL: Burst Length */
16925614e71bSYork Sun 
16935614e71bSYork Sun 	dqs_en = !popts->dqs_config;
16945614e71bSYork Sun 	rtt = fsl_ddr_get_rtt();
16955614e71bSYork Sun 
16965614e71bSYork Sun 	al = additive_latency;
16975614e71bSYork Sun 
16985614e71bSYork Sun 	esdmode = (0
16995614e71bSYork Sun 		| ((mrs & 0x3) << 14)
17005614e71bSYork Sun 		| ((outputs & 0x1) << 12)
17015614e71bSYork Sun 		| ((rdqs_en & 0x1) << 11)
17025614e71bSYork Sun 		| ((dqs_en & 0x1) << 10)
17035614e71bSYork Sun 		| ((ocd & 0x7) << 7)
17045614e71bSYork Sun 		| ((rtt & 0x2) << 5)   /* rtt field is split */
17055614e71bSYork Sun 		| ((al & 0x7) << 3)
17065614e71bSYork Sun 		| ((rtt & 0x1) << 2)   /* rtt field is split */
17075614e71bSYork Sun 		| ((ods & 0x1) << 1)
17085614e71bSYork Sun 		| ((dll_en & 0x1) << 0)
17095614e71bSYork Sun 		);
17105614e71bSYork Sun 
17115614e71bSYork Sun 	mr = 0;		 /* FIXME: CHECKME */
17125614e71bSYork Sun 
17135614e71bSYork Sun 	/*
17145614e71bSYork Sun 	 * 0 = Fast Exit (Normal)
17155614e71bSYork Sun 	 * 1 = Slow Exit (Low Power)
17165614e71bSYork Sun 	 */
17175614e71bSYork Sun 	pd = 0;
17185614e71bSYork Sun 
17195614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
17205614e71bSYork Sun 	wr = 0;       /* Historical */
17215614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
172203e664d8SYork Sun 	wr = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
17235614e71bSYork Sun #endif
17245614e71bSYork Sun 	dll_res = 0;
17255614e71bSYork Sun 	mode = 0;
17265614e71bSYork Sun 
17275614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
17285614e71bSYork Sun 	if (1 <= cas_latency && cas_latency <= 4) {
17295614e71bSYork Sun 		unsigned char mode_caslat_table[4] = {
17305614e71bSYork Sun 			0x5,	/* 1.5 clocks */
17315614e71bSYork Sun 			0x2,	/* 2.0 clocks */
17325614e71bSYork Sun 			0x6,	/* 2.5 clocks */
17335614e71bSYork Sun 			0x3	/* 3.0 clocks */
17345614e71bSYork Sun 		};
17355614e71bSYork Sun 		caslat = mode_caslat_table[cas_latency - 1];
17365614e71bSYork Sun 	} else {
17375614e71bSYork Sun 		printf("Warning: unknown cas_latency %d\n", cas_latency);
17385614e71bSYork Sun 	}
17395614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
17405614e71bSYork Sun 	caslat = cas_latency;
17415614e71bSYork Sun #endif
17425614e71bSYork Sun 	bt = 0;
17435614e71bSYork Sun 
17445614e71bSYork Sun 	switch (popts->burst_length) {
17455614e71bSYork Sun 	case DDR_BL4:
17465614e71bSYork Sun 		bl = 2;
17475614e71bSYork Sun 		break;
17485614e71bSYork Sun 	case DDR_BL8:
17495614e71bSYork Sun 		bl = 3;
17505614e71bSYork Sun 		break;
17515614e71bSYork Sun 	default:
17525614e71bSYork Sun 		printf("Error: invalid burst length of %u specified. "
17535614e71bSYork Sun 			" Defaulting to 4 beats.\n",
17545614e71bSYork Sun 			popts->burst_length);
17555614e71bSYork Sun 		bl = 2;
17565614e71bSYork Sun 		break;
17575614e71bSYork Sun 	}
17585614e71bSYork Sun 
17595614e71bSYork Sun 	sdmode = (0
17605614e71bSYork Sun 		  | ((mr & 0x3) << 14)
17615614e71bSYork Sun 		  | ((pd & 0x1) << 12)
17625614e71bSYork Sun 		  | ((wr & 0x7) << 9)
17635614e71bSYork Sun 		  | ((dll_res & 0x1) << 8)
17645614e71bSYork Sun 		  | ((mode & 0x1) << 7)
17655614e71bSYork Sun 		  | ((caslat & 0x7) << 4)
17665614e71bSYork Sun 		  | ((bt & 0x1) << 3)
17675614e71bSYork Sun 		  | ((bl & 0x7) << 0)
17685614e71bSYork Sun 		  );
17695614e71bSYork Sun 
17705614e71bSYork Sun 	ddr->ddr_sdram_mode = (0
17715614e71bSYork Sun 			       | ((esdmode & 0xFFFF) << 16)
17725614e71bSYork Sun 			       | ((sdmode & 0xFFFF) << 0)
17735614e71bSYork Sun 			       );
17745614e71bSYork Sun 	debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode);
17755614e71bSYork Sun }
17765614e71bSYork Sun #endif
17775614e71bSYork Sun 
17785614e71bSYork Sun /* DDR SDRAM Data Initialization (DDR_DATA_INIT) */
17795614e71bSYork Sun static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr)
17805614e71bSYork Sun {
17815614e71bSYork Sun 	unsigned int init_value;	/* Initialization value */
17825614e71bSYork Sun 
17835614e71bSYork Sun #ifdef CONFIG_MEM_INIT_VALUE
17845614e71bSYork Sun 	init_value = CONFIG_MEM_INIT_VALUE;
17855614e71bSYork Sun #else
17865614e71bSYork Sun 	init_value = 0xDEADBEEF;
17875614e71bSYork Sun #endif
17885614e71bSYork Sun 	ddr->ddr_data_init = init_value;
17895614e71bSYork Sun }
17905614e71bSYork Sun 
17915614e71bSYork Sun /*
17925614e71bSYork Sun  * DDR SDRAM Clock Control (DDR_SDRAM_CLK_CNTL)
17935614e71bSYork Sun  * The old controller on the 8540/60 doesn't have this register.
17945614e71bSYork Sun  * Hope it's OK to set it (to 0) anyway.
17955614e71bSYork Sun  */
17965614e71bSYork Sun static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr,
17975614e71bSYork Sun 					 const memctl_options_t *popts)
17985614e71bSYork Sun {
17995614e71bSYork Sun 	unsigned int clk_adjust;	/* Clock adjust */
1800d7c865bdSCurt Brune 	unsigned int ss_en = 0;		/* Source synchronous enable */
18015614e71bSYork Sun 
1802d7c865bdSCurt Brune #if defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
1803d7c865bdSCurt Brune 	/* Per FSL Application Note: AN2805 */
1804d7c865bdSCurt Brune 	ss_en = 1;
1805d7c865bdSCurt Brune #endif
18065614e71bSYork Sun 	clk_adjust = popts->clk_adjust;
1807d7c865bdSCurt Brune 	ddr->ddr_sdram_clk_cntl = (0
1808d7c865bdSCurt Brune 				   | ((ss_en & 0x1) << 31)
1809d7c865bdSCurt Brune 				   | ((clk_adjust & 0xF) << 23)
1810d7c865bdSCurt Brune 				   );
18115614e71bSYork Sun 	debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl);
18125614e71bSYork Sun }
18135614e71bSYork Sun 
18145614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_ADDR) */
18155614e71bSYork Sun static void set_ddr_init_addr(fsl_ddr_cfg_regs_t *ddr)
18165614e71bSYork Sun {
18175614e71bSYork Sun 	unsigned int init_addr = 0;	/* Initialization address */
18185614e71bSYork Sun 
18195614e71bSYork Sun 	ddr->ddr_init_addr = init_addr;
18205614e71bSYork Sun }
18215614e71bSYork Sun 
18225614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_EXT_ADDR) */
18235614e71bSYork Sun static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr)
18245614e71bSYork Sun {
18255614e71bSYork Sun 	unsigned int uia = 0;	/* Use initialization address */
18265614e71bSYork Sun 	unsigned int init_ext_addr = 0;	/* Initialization address */
18275614e71bSYork Sun 
18285614e71bSYork Sun 	ddr->ddr_init_ext_addr = (0
18295614e71bSYork Sun 				  | ((uia & 0x1) << 31)
18305614e71bSYork Sun 				  | (init_ext_addr & 0xF)
18315614e71bSYork Sun 				  );
18325614e71bSYork Sun }
18335614e71bSYork Sun 
18345614e71bSYork Sun /* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */
18355614e71bSYork Sun static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr,
18365614e71bSYork Sun 				const memctl_options_t *popts)
18375614e71bSYork Sun {
18385614e71bSYork Sun 	unsigned int rwt = 0; /* Read-to-write turnaround for same CS */
18395614e71bSYork Sun 	unsigned int wrt = 0; /* Write-to-read turnaround for same CS */
18405614e71bSYork Sun 	unsigned int rrt = 0; /* Read-to-read turnaround for same CS */
18415614e71bSYork Sun 	unsigned int wwt = 0; /* Write-to-write turnaround for same CS */
1842*6c6e006aSYork Sun 	unsigned int trwt_mclk = 0;	/* ext_rwt */
18435614e71bSYork Sun 	unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */
18445614e71bSYork Sun 
184534e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
18465614e71bSYork Sun 	if (popts->burst_length == DDR_BL8) {
18475614e71bSYork Sun 		/* We set BL/2 for fixed BL8 */
18485614e71bSYork Sun 		rrt = 0;	/* BL/2 clocks */
18495614e71bSYork Sun 		wwt = 0;	/* BL/2 clocks */
18505614e71bSYork Sun 	} else {
18515614e71bSYork Sun 		/* We need to set BL/2 + 2 to BC4 and OTF */
18525614e71bSYork Sun 		rrt = 2;	/* BL/2 + 2 clocks */
18535614e71bSYork Sun 		wwt = 2;	/* BL/2 + 2 clocks */
18545614e71bSYork Sun 	}
185534e026f9SYork Sun #endif
185634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
185734e026f9SYork Sun 	dll_lock = 2;	/* tDLLK = 1024 clocks */
185834e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
18595614e71bSYork Sun 	dll_lock = 1;	/* tDLLK = 512 clocks from spec */
18605614e71bSYork Sun #endif
1861*6c6e006aSYork Sun 
1862*6c6e006aSYork Sun 	if (popts->trwt_override)
1863*6c6e006aSYork Sun 		trwt_mclk = popts->trwt;
1864*6c6e006aSYork Sun 
18655614e71bSYork Sun 	ddr->timing_cfg_4 = (0
18665614e71bSYork Sun 			     | ((rwt & 0xf) << 28)
18675614e71bSYork Sun 			     | ((wrt & 0xf) << 24)
18685614e71bSYork Sun 			     | ((rrt & 0xf) << 20)
18695614e71bSYork Sun 			     | ((wwt & 0xf) << 16)
1870*6c6e006aSYork Sun 			     | ((trwt_mclk & 0xc) << 12)
18715614e71bSYork Sun 			     | (dll_lock & 0x3)
18725614e71bSYork Sun 			     );
18735614e71bSYork Sun 	debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4);
18745614e71bSYork Sun }
18755614e71bSYork Sun 
18765614e71bSYork Sun /* DDR SDRAM Timing Configuration 5 (TIMING_CFG_5) */
18775614e71bSYork Sun static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr, unsigned int cas_latency)
18785614e71bSYork Sun {
18795614e71bSYork Sun 	unsigned int rodt_on = 0;	/* Read to ODT on */
18805614e71bSYork Sun 	unsigned int rodt_off = 0;	/* Read to ODT off */
18815614e71bSYork Sun 	unsigned int wodt_on = 0;	/* Write to ODT on */
18825614e71bSYork Sun 	unsigned int wodt_off = 0;	/* Write to ODT off */
18835614e71bSYork Sun 
188434e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
188534e026f9SYork Sun 	unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
188634e026f9SYork Sun 			      ((ddr->timing_cfg_2 & 0x00040000) >> 14);
18875614e71bSYork Sun 	/* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */
188834e026f9SYork Sun 	if (cas_latency >= wr_lat)
188934e026f9SYork Sun 		rodt_on = cas_latency - wr_lat + 1;
18905614e71bSYork Sun 	rodt_off = 4;	/*  4 clocks */
18915614e71bSYork Sun 	wodt_on = 1;	/*  1 clocks */
18925614e71bSYork Sun 	wodt_off = 4;	/*  4 clocks */
18935614e71bSYork Sun #endif
18945614e71bSYork Sun 
18955614e71bSYork Sun 	ddr->timing_cfg_5 = (0
18965614e71bSYork Sun 			     | ((rodt_on & 0x1f) << 24)
18975614e71bSYork Sun 			     | ((rodt_off & 0x7) << 20)
18985614e71bSYork Sun 			     | ((wodt_on & 0x1f) << 12)
18995614e71bSYork Sun 			     | ((wodt_off & 0x7) << 8)
19005614e71bSYork Sun 			     );
19015614e71bSYork Sun 	debug("FSLDDR: timing_cfg_5 = 0x%08x\n", ddr->timing_cfg_5);
19025614e71bSYork Sun }
19035614e71bSYork Sun 
190434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
190534e026f9SYork Sun static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr)
190634e026f9SYork Sun {
190734e026f9SYork Sun 	unsigned int hs_caslat = 0;
190834e026f9SYork Sun 	unsigned int hs_wrlat = 0;
190934e026f9SYork Sun 	unsigned int hs_wrrec = 0;
191034e026f9SYork Sun 	unsigned int hs_clkadj = 0;
191134e026f9SYork Sun 	unsigned int hs_wrlvl_start = 0;
191234e026f9SYork Sun 
191334e026f9SYork Sun 	ddr->timing_cfg_6 = (0
191434e026f9SYork Sun 			     | ((hs_caslat & 0x1f) << 24)
191534e026f9SYork Sun 			     | ((hs_wrlat & 0x1f) << 19)
191634e026f9SYork Sun 			     | ((hs_wrrec & 0x1f) << 12)
191734e026f9SYork Sun 			     | ((hs_clkadj & 0x1f) << 6)
191834e026f9SYork Sun 			     | ((hs_wrlvl_start & 0x1f) << 0)
191934e026f9SYork Sun 			    );
192034e026f9SYork Sun 	debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6);
192134e026f9SYork Sun }
192234e026f9SYork Sun 
192303e664d8SYork Sun static void set_timing_cfg_7(const unsigned int ctrl_num,
192403e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
192534e026f9SYork Sun 			     const common_timing_params_t *common_dimm)
192634e026f9SYork Sun {
192734e026f9SYork Sun 	unsigned int txpr, tcksre, tcksrx;
192834e026f9SYork Sun 	unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd;
192934e026f9SYork Sun 
193003e664d8SYork Sun 	txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000));
193103e664d8SYork Sun 	tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
193203e664d8SYork Sun 	tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
193334e026f9SYork Sun 	par_lat = 0;
193434e026f9SYork Sun 	cs_to_cmd = 0;
193534e026f9SYork Sun 
193634e026f9SYork Sun 	if (txpr <= 200)
193734e026f9SYork Sun 		cke_rst = 0;
193834e026f9SYork Sun 	else if (txpr <= 256)
193934e026f9SYork Sun 		cke_rst = 1;
194034e026f9SYork Sun 	else if (txpr <= 512)
194134e026f9SYork Sun 		cke_rst = 2;
194234e026f9SYork Sun 	else
194334e026f9SYork Sun 		cke_rst = 3;
194434e026f9SYork Sun 
194534e026f9SYork Sun 	if (tcksre <= 19)
194634e026f9SYork Sun 		cksre = tcksre - 5;
194734e026f9SYork Sun 	else
194834e026f9SYork Sun 		cksre = 15;
194934e026f9SYork Sun 
195034e026f9SYork Sun 	if (tcksrx <= 19)
195134e026f9SYork Sun 		cksrx = tcksrx - 5;
195234e026f9SYork Sun 	else
195334e026f9SYork Sun 		cksrx = 15;
195434e026f9SYork Sun 
195534e026f9SYork Sun 	ddr->timing_cfg_7 = (0
195634e026f9SYork Sun 			     | ((cke_rst & 0x3) << 28)
195734e026f9SYork Sun 			     | ((cksre & 0xf) << 24)
195834e026f9SYork Sun 			     | ((cksrx & 0xf) << 20)
195934e026f9SYork Sun 			     | ((par_lat & 0xf) << 16)
196034e026f9SYork Sun 			     | ((cs_to_cmd & 0xf) << 4)
196134e026f9SYork Sun 			    );
196234e026f9SYork Sun 	debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7);
196334e026f9SYork Sun }
196434e026f9SYork Sun 
196503e664d8SYork Sun static void set_timing_cfg_8(const unsigned int ctrl_num,
196603e664d8SYork Sun 			     fsl_ddr_cfg_regs_t *ddr,
196734e026f9SYork Sun 			     const memctl_options_t *popts,
196834e026f9SYork Sun 			     const common_timing_params_t *common_dimm,
196934e026f9SYork Sun 			     unsigned int cas_latency)
197034e026f9SYork Sun {
197134e026f9SYork Sun 	unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg;
197234e026f9SYork Sun 	unsigned int acttoact_bg, wrtord_bg, pre_all_rec;
197303e664d8SYork Sun 	unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
197434e026f9SYork Sun 	unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
197534e026f9SYork Sun 			      ((ddr->timing_cfg_2 & 0x00040000) >> 14);
197634e026f9SYork Sun 
197734e026f9SYork Sun 	rwt_bg = cas_latency + 2 + 4 - wr_lat;
197834e026f9SYork Sun 	if (rwt_bg < tccdl)
197934e026f9SYork Sun 		rwt_bg = tccdl - rwt_bg;
198034e026f9SYork Sun 	else
198134e026f9SYork Sun 		rwt_bg = 0;
198234e026f9SYork Sun 
198334e026f9SYork Sun 	wrt_bg = wr_lat + 4 + 1 - cas_latency;
198434e026f9SYork Sun 	if (wrt_bg < tccdl)
198534e026f9SYork Sun 		wrt_bg = tccdl - wrt_bg;
198634e026f9SYork Sun 	else
198734e026f9SYork Sun 		wrt_bg = 0;
198834e026f9SYork Sun 
198934e026f9SYork Sun 	if (popts->burst_length == DDR_BL8) {
199034e026f9SYork Sun 		rrt_bg = tccdl - 4;
199134e026f9SYork Sun 		wwt_bg = tccdl - 4;
199234e026f9SYork Sun 	} else {
199334e026f9SYork Sun 		rrt_bg = tccdl - 2;
1994dc1437afSYork Sun 		wwt_bg = tccdl - 2;
199534e026f9SYork Sun 	}
199634e026f9SYork Sun 
199703e664d8SYork Sun 	acttoact_bg = picos_to_mclk(ctrl_num, common_dimm->trrdl_ps);
199803e664d8SYork Sun 	wrtord_bg = max(4U, picos_to_mclk(ctrl_num, 7500));
19993d75ec95SYork Sun 	if (popts->otf_burst_chop_en)
20003d75ec95SYork Sun 		wrtord_bg += 2;
20013d75ec95SYork Sun 
200234e026f9SYork Sun 	pre_all_rec = 0;
200334e026f9SYork Sun 
200434e026f9SYork Sun 	ddr->timing_cfg_8 = (0
200534e026f9SYork Sun 			     | ((rwt_bg & 0xf) << 28)
200634e026f9SYork Sun 			     | ((wrt_bg & 0xf) << 24)
200734e026f9SYork Sun 			     | ((rrt_bg & 0xf) << 20)
200834e026f9SYork Sun 			     | ((wwt_bg & 0xf) << 16)
200934e026f9SYork Sun 			     | ((acttoact_bg & 0xf) << 12)
201034e026f9SYork Sun 			     | ((wrtord_bg & 0xf) << 8)
201134e026f9SYork Sun 			     | ((pre_all_rec & 0x1f) << 0)
201234e026f9SYork Sun 			    );
201334e026f9SYork Sun 
201434e026f9SYork Sun 	debug("FSLDDR: timing_cfg_8 = 0x%08x\n", ddr->timing_cfg_8);
201534e026f9SYork Sun }
201634e026f9SYork Sun 
201734e026f9SYork Sun static void set_timing_cfg_9(fsl_ddr_cfg_regs_t *ddr)
201834e026f9SYork Sun {
201934e026f9SYork Sun 	ddr->timing_cfg_9 = 0;
202034e026f9SYork Sun 	debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9);
202134e026f9SYork Sun }
202234e026f9SYork Sun 
2023f80d6472SYork Sun /* This function needs to be called after set_ddr_sdram_cfg() is called */
202434e026f9SYork Sun static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr,
202534e026f9SYork Sun 			       const dimm_params_t *dimm_params)
202634e026f9SYork Sun {
2027f80d6472SYork Sun 	unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1;
20286b95be22SYork Sun 	int i;
2029f80d6472SYork Sun 
20306b95be22SYork Sun 	for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
20316b95be22SYork Sun 		if (dimm_params[i].n_ranks)
20326b95be22SYork Sun 			break;
20336b95be22SYork Sun 	}
20346b95be22SYork Sun 	if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) {
20356b95be22SYork Sun 		puts("DDR error: no DIMM found!\n");
20366b95be22SYork Sun 		return;
20376b95be22SYork Sun 	}
203834e026f9SYork Sun 
20396b95be22SYork Sun 	ddr->dq_map_0 = ((dimm_params[i].dq_mapping[0] & 0x3F) << 26) |
20406b95be22SYork Sun 			((dimm_params[i].dq_mapping[1] & 0x3F) << 20) |
20416b95be22SYork Sun 			((dimm_params[i].dq_mapping[2] & 0x3F) << 14) |
20426b95be22SYork Sun 			((dimm_params[i].dq_mapping[3] & 0x3F) << 8) |
20436b95be22SYork Sun 			((dimm_params[i].dq_mapping[4] & 0x3F) << 2);
204434e026f9SYork Sun 
20456b95be22SYork Sun 	ddr->dq_map_1 = ((dimm_params[i].dq_mapping[5] & 0x3F) << 26) |
20466b95be22SYork Sun 			((dimm_params[i].dq_mapping[6] & 0x3F) << 20) |
20476b95be22SYork Sun 			((dimm_params[i].dq_mapping[7] & 0x3F) << 14) |
20486b95be22SYork Sun 			((dimm_params[i].dq_mapping[10] & 0x3F) << 8) |
20496b95be22SYork Sun 			((dimm_params[i].dq_mapping[11] & 0x3F) << 2);
20506b95be22SYork Sun 
20516b95be22SYork Sun 	ddr->dq_map_2 = ((dimm_params[i].dq_mapping[12] & 0x3F) << 26) |
20526b95be22SYork Sun 			((dimm_params[i].dq_mapping[13] & 0x3F) << 20) |
20536b95be22SYork Sun 			((dimm_params[i].dq_mapping[14] & 0x3F) << 14) |
20546b95be22SYork Sun 			((dimm_params[i].dq_mapping[15] & 0x3F) << 8) |
20556b95be22SYork Sun 			((dimm_params[i].dq_mapping[16] & 0x3F) << 2);
205634e026f9SYork Sun 
2057f80d6472SYork Sun 	/* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */
20586b95be22SYork Sun 	ddr->dq_map_3 = ((dimm_params[i].dq_mapping[17] & 0x3F) << 26) |
20596b95be22SYork Sun 			((dimm_params[i].dq_mapping[8] & 0x3F) << 20) |
2060f80d6472SYork Sun 			(acc_ecc_en ? 0 :
20616b95be22SYork Sun 			 (dimm_params[i].dq_mapping[9] & 0x3F) << 14) |
20626b95be22SYork Sun 			dimm_params[i].dq_mapping_ors;
206334e026f9SYork Sun 
206434e026f9SYork Sun 	debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0);
206534e026f9SYork Sun 	debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1);
206634e026f9SYork Sun 	debug("FSLDDR: dq_map_2 = 0x%08x\n", ddr->dq_map_2);
206734e026f9SYork Sun 	debug("FSLDDR: dq_map_3 = 0x%08x\n", ddr->dq_map_3);
206834e026f9SYork Sun }
206934e026f9SYork Sun static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr,
207034e026f9SYork Sun 			       const memctl_options_t *popts)
207134e026f9SYork Sun {
207234e026f9SYork Sun 	int rd_pre;
207334e026f9SYork Sun 
207434e026f9SYork Sun 	rd_pre = popts->quad_rank_present ? 1 : 0;
207534e026f9SYork Sun 
207634e026f9SYork Sun 	ddr->ddr_sdram_cfg_3 = (rd_pre & 0x1) << 16;
207734e026f9SYork Sun 
207834e026f9SYork Sun 	debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3);
207934e026f9SYork Sun }
208034e026f9SYork Sun #endif	/* CONFIG_SYS_FSL_DDR4 */
208134e026f9SYork Sun 
20825614e71bSYork Sun /* DDR ZQ Calibration Control (DDR_ZQ_CNTL) */
20835614e71bSYork Sun static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en)
20845614e71bSYork Sun {
20855614e71bSYork Sun 	unsigned int zqinit = 0;/* POR ZQ Calibration Time (tZQinit) */
20865614e71bSYork Sun 	/* Normal Operation Full Calibration Time (tZQoper) */
20875614e71bSYork Sun 	unsigned int zqoper = 0;
20885614e71bSYork Sun 	/* Normal Operation Short Calibration Time (tZQCS) */
20895614e71bSYork Sun 	unsigned int zqcs = 0;
209034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
209134e026f9SYork Sun 	unsigned int zqcs_init;
209234e026f9SYork Sun #endif
20935614e71bSYork Sun 
20945614e71bSYork Sun 	if (zq_en) {
209534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
209634e026f9SYork Sun 		zqinit = 10;	/* 1024 clocks */
209734e026f9SYork Sun 		zqoper = 9;	/* 512 clocks */
209834e026f9SYork Sun 		zqcs = 7;	/* 128 clocks */
209934e026f9SYork Sun 		zqcs_init = 5;	/* 1024 refresh sequences */
210034e026f9SYork Sun #else
21015614e71bSYork Sun 		zqinit = 9;	/* 512 clocks */
21025614e71bSYork Sun 		zqoper = 8;	/* 256 clocks */
21035614e71bSYork Sun 		zqcs = 6;	/* 64 clocks */
210434e026f9SYork Sun #endif
21055614e71bSYork Sun 	}
21065614e71bSYork Sun 
21075614e71bSYork Sun 	ddr->ddr_zq_cntl = (0
21085614e71bSYork Sun 			    | ((zq_en & 0x1) << 31)
21095614e71bSYork Sun 			    | ((zqinit & 0xF) << 24)
21105614e71bSYork Sun 			    | ((zqoper & 0xF) << 16)
21115614e71bSYork Sun 			    | ((zqcs & 0xF) << 8)
211234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
211334e026f9SYork Sun 			    | ((zqcs_init & 0xF) << 0)
211434e026f9SYork Sun #endif
21155614e71bSYork Sun 			    );
21165614e71bSYork Sun 	debug("FSLDDR: zq_cntl = 0x%08x\n", ddr->ddr_zq_cntl);
21175614e71bSYork Sun }
21185614e71bSYork Sun 
21195614e71bSYork Sun /* DDR Write Leveling Control (DDR_WRLVL_CNTL) */
21205614e71bSYork Sun static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en,
21215614e71bSYork Sun 				const memctl_options_t *popts)
21225614e71bSYork Sun {
21235614e71bSYork Sun 	/*
21245614e71bSYork Sun 	 * First DQS pulse rising edge after margining mode
21255614e71bSYork Sun 	 * is programmed (tWL_MRD)
21265614e71bSYork Sun 	 */
21275614e71bSYork Sun 	unsigned int wrlvl_mrd = 0;
21285614e71bSYork Sun 	/* ODT delay after margining mode is programmed (tWL_ODTEN) */
21295614e71bSYork Sun 	unsigned int wrlvl_odten = 0;
21305614e71bSYork Sun 	/* DQS/DQS_ delay after margining mode is programmed (tWL_DQSEN) */
21315614e71bSYork Sun 	unsigned int wrlvl_dqsen = 0;
21325614e71bSYork Sun 	/* WRLVL_SMPL: Write leveling sample time */
21335614e71bSYork Sun 	unsigned int wrlvl_smpl = 0;
21345614e71bSYork Sun 	/* WRLVL_WLR: Write leveling repeition time */
21355614e71bSYork Sun 	unsigned int wrlvl_wlr = 0;
21365614e71bSYork Sun 	/* WRLVL_START: Write leveling start time */
21375614e71bSYork Sun 	unsigned int wrlvl_start = 0;
21385614e71bSYork Sun 
21395614e71bSYork Sun 	/* suggest enable write leveling for DDR3 due to fly-by topology */
21405614e71bSYork Sun 	if (wrlvl_en) {
21415614e71bSYork Sun 		/* tWL_MRD min = 40 nCK, we set it 64 */
21425614e71bSYork Sun 		wrlvl_mrd = 0x6;
21435614e71bSYork Sun 		/* tWL_ODTEN 128 */
21445614e71bSYork Sun 		wrlvl_odten = 0x7;
21455614e71bSYork Sun 		/* tWL_DQSEN min = 25 nCK, we set it 32 */
21465614e71bSYork Sun 		wrlvl_dqsen = 0x5;
21475614e71bSYork Sun 		/*
21485614e71bSYork Sun 		 * Write leveling sample time at least need 6 clocks
21495614e71bSYork Sun 		 * higher than tWLO to allow enough time for progagation
21505614e71bSYork Sun 		 * delay and sampling the prime data bits.
21515614e71bSYork Sun 		 */
21525614e71bSYork Sun 		wrlvl_smpl = 0xf;
21535614e71bSYork Sun 		/*
21545614e71bSYork Sun 		 * Write leveling repetition time
21555614e71bSYork Sun 		 * at least tWLO + 6 clocks clocks
21565614e71bSYork Sun 		 * we set it 64
21575614e71bSYork Sun 		 */
21585614e71bSYork Sun 		wrlvl_wlr = 0x6;
21595614e71bSYork Sun 		/*
21605614e71bSYork Sun 		 * Write leveling start time
21615614e71bSYork Sun 		 * The value use for the DQS_ADJUST for the first sample
21625614e71bSYork Sun 		 * when write leveling is enabled. It probably needs to be
21635614e71bSYork Sun 		 * overriden per platform.
21645614e71bSYork Sun 		 */
21655614e71bSYork Sun 		wrlvl_start = 0x8;
21665614e71bSYork Sun 		/*
21675614e71bSYork Sun 		 * Override the write leveling sample and start time
21685614e71bSYork Sun 		 * according to specific board
21695614e71bSYork Sun 		 */
21705614e71bSYork Sun 		if (popts->wrlvl_override) {
21715614e71bSYork Sun 			wrlvl_smpl = popts->wrlvl_sample;
21725614e71bSYork Sun 			wrlvl_start = popts->wrlvl_start;
21735614e71bSYork Sun 		}
21745614e71bSYork Sun 	}
21755614e71bSYork Sun 
21765614e71bSYork Sun 	ddr->ddr_wrlvl_cntl = (0
21775614e71bSYork Sun 			       | ((wrlvl_en & 0x1) << 31)
21785614e71bSYork Sun 			       | ((wrlvl_mrd & 0x7) << 24)
21795614e71bSYork Sun 			       | ((wrlvl_odten & 0x7) << 20)
21805614e71bSYork Sun 			       | ((wrlvl_dqsen & 0x7) << 16)
21815614e71bSYork Sun 			       | ((wrlvl_smpl & 0xf) << 12)
21825614e71bSYork Sun 			       | ((wrlvl_wlr & 0x7) << 8)
21835614e71bSYork Sun 			       | ((wrlvl_start & 0x1F) << 0)
21845614e71bSYork Sun 			       );
21855614e71bSYork Sun 	debug("FSLDDR: wrlvl_cntl = 0x%08x\n", ddr->ddr_wrlvl_cntl);
21865614e71bSYork Sun 	ddr->ddr_wrlvl_cntl_2 = popts->wrlvl_ctl_2;
21875614e71bSYork Sun 	debug("FSLDDR: wrlvl_cntl_2 = 0x%08x\n", ddr->ddr_wrlvl_cntl_2);
21885614e71bSYork Sun 	ddr->ddr_wrlvl_cntl_3 = popts->wrlvl_ctl_3;
21895614e71bSYork Sun 	debug("FSLDDR: wrlvl_cntl_3 = 0x%08x\n", ddr->ddr_wrlvl_cntl_3);
21905614e71bSYork Sun 
21915614e71bSYork Sun }
21925614e71bSYork Sun 
21935614e71bSYork Sun /* DDR Self Refresh Counter (DDR_SR_CNTR) */
21945614e71bSYork Sun static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it)
21955614e71bSYork Sun {
21965614e71bSYork Sun 	/* Self Refresh Idle Threshold */
21975614e71bSYork Sun 	ddr->ddr_sr_cntr = (sr_it & 0xF) << 16;
21985614e71bSYork Sun }
21995614e71bSYork Sun 
22005614e71bSYork Sun static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
22015614e71bSYork Sun {
22025614e71bSYork Sun 	if (popts->addr_hash) {
22035614e71bSYork Sun 		ddr->ddr_eor = 0x40000000;	/* address hash enable */
22045614e71bSYork Sun 		puts("Address hashing enabled.\n");
22055614e71bSYork Sun 	}
22065614e71bSYork Sun }
22075614e71bSYork Sun 
22085614e71bSYork Sun static void set_ddr_cdr1(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
22095614e71bSYork Sun {
22105614e71bSYork Sun 	ddr->ddr_cdr1 = popts->ddr_cdr1;
22115614e71bSYork Sun 	debug("FSLDDR: ddr_cdr1 = 0x%08x\n", ddr->ddr_cdr1);
22125614e71bSYork Sun }
22135614e71bSYork Sun 
22145614e71bSYork Sun static void set_ddr_cdr2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
22155614e71bSYork Sun {
22165614e71bSYork Sun 	ddr->ddr_cdr2 = popts->ddr_cdr2;
22175614e71bSYork Sun 	debug("FSLDDR: ddr_cdr2 = 0x%08x\n", ddr->ddr_cdr2);
22185614e71bSYork Sun }
22195614e71bSYork Sun 
22205614e71bSYork Sun unsigned int
22215614e71bSYork Sun check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
22225614e71bSYork Sun {
22235614e71bSYork Sun 	unsigned int res = 0;
22245614e71bSYork Sun 
22255614e71bSYork Sun 	/*
22265614e71bSYork Sun 	 * Check that DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] are
22275614e71bSYork Sun 	 * not set at the same time.
22285614e71bSYork Sun 	 */
22295614e71bSYork Sun 	if (ddr->ddr_sdram_cfg & 0x10000000
22305614e71bSYork Sun 	    && ddr->ddr_sdram_cfg & 0x00008000) {
22315614e71bSYork Sun 		printf("Error: DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] "
22325614e71bSYork Sun 				" should not be set at the same time.\n");
22335614e71bSYork Sun 		res++;
22345614e71bSYork Sun 	}
22355614e71bSYork Sun 
22365614e71bSYork Sun 	return res;
22375614e71bSYork Sun }
22385614e71bSYork Sun 
22395614e71bSYork Sun unsigned int
224003e664d8SYork Sun compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
224103e664d8SYork Sun 			       const memctl_options_t *popts,
22425614e71bSYork Sun 			       fsl_ddr_cfg_regs_t *ddr,
22435614e71bSYork Sun 			       const common_timing_params_t *common_dimm,
22445614e71bSYork Sun 			       const dimm_params_t *dimm_params,
22455614e71bSYork Sun 			       unsigned int dbw_cap_adj,
22465614e71bSYork Sun 			       unsigned int size_only)
22475614e71bSYork Sun {
22485614e71bSYork Sun 	unsigned int i;
22495614e71bSYork Sun 	unsigned int cas_latency;
22505614e71bSYork Sun 	unsigned int additive_latency;
22515614e71bSYork Sun 	unsigned int sr_it;
22525614e71bSYork Sun 	unsigned int zq_en;
22535614e71bSYork Sun 	unsigned int wrlvl_en;
22545614e71bSYork Sun 	unsigned int ip_rev = 0;
22555614e71bSYork Sun 	unsigned int unq_mrs_en = 0;
22565614e71bSYork Sun 	int cs_en = 1;
22575614e71bSYork Sun 
22585614e71bSYork Sun 	memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t));
22595614e71bSYork Sun 
22605614e71bSYork Sun 	if (common_dimm == NULL) {
22615614e71bSYork Sun 		printf("Error: subset DIMM params struct null pointer\n");
22625614e71bSYork Sun 		return 1;
22635614e71bSYork Sun 	}
22645614e71bSYork Sun 
22655614e71bSYork Sun 	/*
22665614e71bSYork Sun 	 * Process overrides first.
22675614e71bSYork Sun 	 *
22685614e71bSYork Sun 	 * FIXME: somehow add dereated caslat to this
22695614e71bSYork Sun 	 */
22705614e71bSYork Sun 	cas_latency = (popts->cas_latency_override)
22715614e71bSYork Sun 		? popts->cas_latency_override_value
227234e026f9SYork Sun 		: common_dimm->lowest_common_spd_caslat;
22735614e71bSYork Sun 
22745614e71bSYork Sun 	additive_latency = (popts->additive_latency_override)
22755614e71bSYork Sun 		? popts->additive_latency_override_value
22765614e71bSYork Sun 		: common_dimm->additive_latency;
22775614e71bSYork Sun 
22785614e71bSYork Sun 	sr_it = (popts->auto_self_refresh_en)
22795614e71bSYork Sun 		? popts->sr_it
22805614e71bSYork Sun 		: 0;
22815614e71bSYork Sun 	/* ZQ calibration */
22825614e71bSYork Sun 	zq_en = (popts->zq_en) ? 1 : 0;
22835614e71bSYork Sun 	/* write leveling */
22845614e71bSYork Sun 	wrlvl_en = (popts->wrlvl_en) ? 1 : 0;
22855614e71bSYork Sun 
22865614e71bSYork Sun 	/* Chip Select Memory Bounds (CSn_BNDS) */
22875614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
22885614e71bSYork Sun 		unsigned long long ea, sa;
22895614e71bSYork Sun 		unsigned int cs_per_dimm
22905614e71bSYork Sun 			= CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR;
22915614e71bSYork Sun 		unsigned int dimm_number
22925614e71bSYork Sun 			= i / cs_per_dimm;
22935614e71bSYork Sun 		unsigned long long rank_density
22945614e71bSYork Sun 			= dimm_params[dimm_number].rank_density >> dbw_cap_adj;
22955614e71bSYork Sun 
22965614e71bSYork Sun 		if (dimm_params[dimm_number].n_ranks == 0) {
22975614e71bSYork Sun 			debug("Skipping setup of CS%u "
22985614e71bSYork Sun 				"because n_ranks on DIMM %u is 0\n", i, dimm_number);
22995614e71bSYork Sun 			continue;
23005614e71bSYork Sun 		}
23015614e71bSYork Sun 		if (popts->memctl_interleaving) {
23025614e71bSYork Sun 			switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
23035614e71bSYork Sun 			case FSL_DDR_CS0_CS1_CS2_CS3:
23045614e71bSYork Sun 				break;
23055614e71bSYork Sun 			case FSL_DDR_CS0_CS1:
23065614e71bSYork Sun 			case FSL_DDR_CS0_CS1_AND_CS2_CS3:
23075614e71bSYork Sun 				if (i > 1)
23085614e71bSYork Sun 					cs_en = 0;
23095614e71bSYork Sun 				break;
23105614e71bSYork Sun 			case FSL_DDR_CS2_CS3:
23115614e71bSYork Sun 			default:
23125614e71bSYork Sun 				if (i > 0)
23135614e71bSYork Sun 					cs_en = 0;
23145614e71bSYork Sun 				break;
23155614e71bSYork Sun 			}
23165614e71bSYork Sun 			sa = common_dimm->base_address;
23175614e71bSYork Sun 			ea = sa + common_dimm->total_mem - 1;
23185614e71bSYork Sun 		} else if (!popts->memctl_interleaving) {
23195614e71bSYork Sun 			/*
23205614e71bSYork Sun 			 * If memory interleaving between controllers is NOT
23215614e71bSYork Sun 			 * enabled, the starting address for each memory
23225614e71bSYork Sun 			 * controller is distinct.  However, because rank
23235614e71bSYork Sun 			 * interleaving is enabled, the starting and ending
23245614e71bSYork Sun 			 * addresses of the total memory on that memory
23255614e71bSYork Sun 			 * controller needs to be programmed into its
23265614e71bSYork Sun 			 * respective CS0_BNDS.
23275614e71bSYork Sun 			 */
23285614e71bSYork Sun 			switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
23295614e71bSYork Sun 			case FSL_DDR_CS0_CS1_CS2_CS3:
23305614e71bSYork Sun 				sa = common_dimm->base_address;
23315614e71bSYork Sun 				ea = sa + common_dimm->total_mem - 1;
23325614e71bSYork Sun 				break;
23335614e71bSYork Sun 			case FSL_DDR_CS0_CS1_AND_CS2_CS3:
23345614e71bSYork Sun 				if ((i >= 2) && (dimm_number == 0)) {
23355614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address +
23365614e71bSYork Sun 					      2 * rank_density;
23375614e71bSYork Sun 					ea = sa + 2 * rank_density - 1;
23385614e71bSYork Sun 				} else {
23395614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address;
23405614e71bSYork Sun 					ea = sa + 2 * rank_density - 1;
23415614e71bSYork Sun 				}
23425614e71bSYork Sun 				break;
23435614e71bSYork Sun 			case FSL_DDR_CS0_CS1:
23445614e71bSYork Sun 				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
23455614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address;
23465614e71bSYork Sun 					ea = sa + rank_density - 1;
23475614e71bSYork Sun 					if (i != 1)
23485614e71bSYork Sun 						sa += (i % cs_per_dimm) * rank_density;
23495614e71bSYork Sun 					ea += (i % cs_per_dimm) * rank_density;
23505614e71bSYork Sun 				} else {
23515614e71bSYork Sun 					sa = 0;
23525614e71bSYork Sun 					ea = 0;
23535614e71bSYork Sun 				}
23545614e71bSYork Sun 				if (i == 0)
23555614e71bSYork Sun 					ea += rank_density;
23565614e71bSYork Sun 				break;
23575614e71bSYork Sun 			case FSL_DDR_CS2_CS3:
23585614e71bSYork Sun 				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
23595614e71bSYork Sun 					sa = dimm_params[dimm_number].base_address;
23605614e71bSYork Sun 					ea = sa + rank_density - 1;
23615614e71bSYork Sun 					if (i != 3)
23625614e71bSYork Sun 						sa += (i % cs_per_dimm) * rank_density;
23635614e71bSYork Sun 					ea += (i % cs_per_dimm) * rank_density;
23645614e71bSYork Sun 				} else {
23655614e71bSYork Sun 					sa = 0;
23665614e71bSYork Sun 					ea = 0;
23675614e71bSYork Sun 				}
23685614e71bSYork Sun 				if (i == 2)
23695614e71bSYork Sun 					ea += (rank_density >> dbw_cap_adj);
23705614e71bSYork Sun 				break;
23715614e71bSYork Sun 			default:  /* No bank(chip-select) interleaving */
23725614e71bSYork Sun 				sa = dimm_params[dimm_number].base_address;
23735614e71bSYork Sun 				ea = sa + rank_density - 1;
23745614e71bSYork Sun 				if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) {
23755614e71bSYork Sun 					sa += (i % cs_per_dimm) * rank_density;
23765614e71bSYork Sun 					ea += (i % cs_per_dimm) * rank_density;
23775614e71bSYork Sun 				} else {
23785614e71bSYork Sun 					sa = 0;
23795614e71bSYork Sun 					ea = 0;
23805614e71bSYork Sun 				}
23815614e71bSYork Sun 				break;
23825614e71bSYork Sun 			}
23835614e71bSYork Sun 		}
23845614e71bSYork Sun 
23855614e71bSYork Sun 		sa >>= 24;
23865614e71bSYork Sun 		ea >>= 24;
23875614e71bSYork Sun 
23885614e71bSYork Sun 		if (cs_en) {
23895614e71bSYork Sun 			ddr->cs[i].bnds = (0
2390d4263b8aSYork Sun 				| ((sa & 0xffff) << 16) /* starting address */
2391d4263b8aSYork Sun 				| ((ea & 0xffff) << 0)	/* ending address */
23925614e71bSYork Sun 				);
23935614e71bSYork Sun 		} else {
23945614e71bSYork Sun 			/* setting bnds to 0xffffffff for inactive CS */
23955614e71bSYork Sun 			ddr->cs[i].bnds = 0xffffffff;
23965614e71bSYork Sun 		}
23975614e71bSYork Sun 
23985614e71bSYork Sun 		debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds);
23995614e71bSYork Sun 		set_csn_config(dimm_number, i, ddr, popts, dimm_params);
24005614e71bSYork Sun 		set_csn_config_2(i, ddr);
24015614e71bSYork Sun 	}
24025614e71bSYork Sun 
24035614e71bSYork Sun 	/*
24045614e71bSYork Sun 	 * In the case we only need to compute the ddr sdram size, we only need
24055614e71bSYork Sun 	 * to set csn registers, so return from here.
24065614e71bSYork Sun 	 */
24075614e71bSYork Sun 	if (size_only)
24085614e71bSYork Sun 		return 0;
24095614e71bSYork Sun 
24105614e71bSYork Sun 	set_ddr_eor(ddr, popts);
24115614e71bSYork Sun 
24125614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1)
241303e664d8SYork Sun 	set_timing_cfg_0(ctrl_num, ddr, popts, dimm_params);
24145614e71bSYork Sun #endif
24155614e71bSYork Sun 
241603e664d8SYork Sun 	set_timing_cfg_3(ctrl_num, ddr, popts, common_dimm, cas_latency,
2417d4263b8aSYork Sun 			 additive_latency);
241803e664d8SYork Sun 	set_timing_cfg_1(ctrl_num, ddr, popts, common_dimm, cas_latency);
241903e664d8SYork Sun 	set_timing_cfg_2(ctrl_num, ddr, popts, common_dimm,
24205614e71bSYork Sun 			 cas_latency, additive_latency);
24215614e71bSYork Sun 
24225614e71bSYork Sun 	set_ddr_cdr1(ddr, popts);
24235614e71bSYork Sun 	set_ddr_cdr2(ddr, popts);
24245614e71bSYork Sun 	set_ddr_sdram_cfg(ddr, popts, common_dimm);
242566869f95SYork Sun 	ip_rev = fsl_ddr_get_version(ctrl_num);
24265614e71bSYork Sun 	if (ip_rev > 0x40400)
24275614e71bSYork Sun 		unq_mrs_en = 1;
24285614e71bSYork Sun 
2429f80d6472SYork Sun 	if ((ip_rev > 0x40700) && (popts->cswl_override != 0))
2430ef87cab6SYork Sun 		ddr->debug[18] = popts->cswl_override;
2431ef87cab6SYork Sun 
243203e664d8SYork Sun 	set_ddr_sdram_cfg_2(ctrl_num, ddr, popts, unq_mrs_en);
243303e664d8SYork Sun 	set_ddr_sdram_mode(ctrl_num, ddr, popts, common_dimm,
24345614e71bSYork Sun 			   cas_latency, additive_latency, unq_mrs_en);
243503e664d8SYork Sun 	set_ddr_sdram_mode_2(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
243634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
243734e026f9SYork Sun 	set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en);
243803e664d8SYork Sun 	set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
243934e026f9SYork Sun #endif
244003e664d8SYork Sun 	set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm);
24415614e71bSYork Sun 	set_ddr_data_init(ddr);
24425614e71bSYork Sun 	set_ddr_sdram_clk_cntl(ddr, popts);
24435614e71bSYork Sun 	set_ddr_init_addr(ddr);
24445614e71bSYork Sun 	set_ddr_init_ext_addr(ddr);
24455614e71bSYork Sun 	set_timing_cfg_4(ddr, popts);
24465614e71bSYork Sun 	set_timing_cfg_5(ddr, cas_latency);
244734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
244834e026f9SYork Sun 	set_ddr_sdram_cfg_3(ddr, popts);
244934e026f9SYork Sun 	set_timing_cfg_6(ddr);
245003e664d8SYork Sun 	set_timing_cfg_7(ctrl_num, ddr, common_dimm);
245103e664d8SYork Sun 	set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency);
245234e026f9SYork Sun 	set_timing_cfg_9(ddr);
245334e026f9SYork Sun 	set_ddr_dq_mapping(ddr, dimm_params);
245434e026f9SYork Sun #endif
24555614e71bSYork Sun 
24565614e71bSYork Sun 	set_ddr_zq_cntl(ddr, zq_en);
24575614e71bSYork Sun 	set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts);
24585614e71bSYork Sun 
24595614e71bSYork Sun 	set_ddr_sr_cntr(ddr, sr_it);
24605614e71bSYork Sun 
24615614e71bSYork Sun 	set_ddr_sdram_rcw(ddr, popts, common_dimm);
24625614e71bSYork Sun 
24635614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR_EMU
24645614e71bSYork Sun 	/* disble DDR training for emulator */
24655614e71bSYork Sun 	ddr->debug[2] = 0x00000400;
24661f3402e7SYork Sun 	ddr->debug[4] = 0xff800800;
24671f3402e7SYork Sun 	ddr->debug[5] = 0x08000800;
24681f3402e7SYork Sun 	ddr->debug[6] = 0x08000800;
24691f3402e7SYork Sun 	ddr->debug[7] = 0x08000800;
24701f3402e7SYork Sun 	ddr->debug[8] = 0x08000800;
24715614e71bSYork Sun #endif
24729855b3beSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_A004508
24739855b3beSYork Sun 	if ((ip_rev >= 0x40000) && (ip_rev < 0x40400))
24749855b3beSYork Sun 		ddr->debug[2] |= 0x00000200;	/* set bit 22 */
24759855b3beSYork Sun #endif
24769855b3beSYork Sun 
24775614e71bSYork Sun 	return check_fsl_memctl_config_regs(ddr);
24785614e71bSYork Sun }
2479