xref: /rk3399_rockchip-uboot/drivers/ddr/fsl/mpc85xx_ddr_gen3.c (revision 51370d561842ae7438337e77a93177e13796ac45)
15614e71bSYork Sun /*
25614e71bSYork Sun  * Copyright 2008-2012 Freescale Semiconductor, Inc.
35614e71bSYork Sun  *
45b8031ccSTom Rini  * SPDX-License-Identifier:	GPL-2.0
55614e71bSYork Sun  */
65614e71bSYork Sun 
75614e71bSYork Sun #include <common.h>
85614e71bSYork Sun #include <asm/io.h>
95614e71bSYork Sun #include <fsl_ddr_sdram.h>
105614e71bSYork Sun #include <asm/processor.h>
115614e71bSYork Sun 
125614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
135614e71bSYork Sun #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
145614e71bSYork Sun #endif
155614e71bSYork Sun 
165614e71bSYork Sun /*
175614e71bSYork Sun  * regs has the to-be-set values for DDR controller registers
185614e71bSYork Sun  * ctrl_num is the DDR controller number
195614e71bSYork Sun  * step: 0 goes through the initialization in one pass
205614e71bSYork Sun  *       1 sets registers and returns before enabling controller
215614e71bSYork Sun  *       2 resumes from step 1 and continues to initialize
225614e71bSYork Sun  * Dividing the initialization to two steps to deassert DDR reset signal
235614e71bSYork Sun  * to comply with JEDEC specs for RDIMMs.
245614e71bSYork Sun  */
fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t * regs,unsigned int ctrl_num,int step)255614e71bSYork Sun void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
265614e71bSYork Sun 			     unsigned int ctrl_num, int step)
275614e71bSYork Sun {
285614e71bSYork Sun 	unsigned int i, bus_width;
299a17eb5bSYork Sun 	struct ccsr_ddr __iomem *ddr;
305614e71bSYork Sun 	u32 temp_sdram_cfg;
315614e71bSYork Sun 	u32 total_gb_size_per_controller;
325614e71bSYork Sun 	int timeout;
335614e71bSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
345614e71bSYork Sun 	int timeout_save;
355614e71bSYork Sun 	volatile ccsr_local_ecm_t *ecm = (void *)CONFIG_SYS_MPC85xx_ECM_ADDR;
365614e71bSYork Sun 	unsigned int csn_bnds_backup = 0, cs_sa, cs_ea, *csn_bnds_t;
375614e71bSYork Sun 	int csn = -1;
385614e71bSYork Sun #endif
3976356eb5SYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003
4076356eb5SYork Sun 	u32 save1, save2;
4176356eb5SYork Sun #endif
425614e71bSYork Sun 
435614e71bSYork Sun 	switch (ctrl_num) {
445614e71bSYork Sun 	case 0:
455614e71bSYork Sun 		ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
465614e71bSYork Sun 		break;
47*51370d56SYork Sun #if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1)
485614e71bSYork Sun 	case 1:
495614e71bSYork Sun 		ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
505614e71bSYork Sun 		break;
515614e71bSYork Sun #endif
52*51370d56SYork Sun #if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2)
535614e71bSYork Sun 	case 2:
545614e71bSYork Sun 		ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
555614e71bSYork Sun 		break;
565614e71bSYork Sun #endif
57*51370d56SYork Sun #if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3)
585614e71bSYork Sun 	case 3:
595614e71bSYork Sun 		ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
605614e71bSYork Sun 		break;
615614e71bSYork Sun #endif
625614e71bSYork Sun 	default:
635614e71bSYork Sun 		printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
645614e71bSYork Sun 		return;
655614e71bSYork Sun 	}
665614e71bSYork Sun 
675614e71bSYork Sun 	if (step == 2)
685614e71bSYork Sun 		goto step2;
695614e71bSYork Sun 
705614e71bSYork Sun 	if (regs->ddr_eor)
715614e71bSYork Sun 		out_be32(&ddr->eor, regs->ddr_eor);
725614e71bSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
735614e71bSYork Sun 	debug("Workaround for ERRATUM_DDR111_DDR134\n");
745614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
755614e71bSYork Sun 		cs_sa = (regs->cs[i].bnds >> 16) & 0xfff;
765614e71bSYork Sun 		cs_ea = regs->cs[i].bnds & 0xfff;
775614e71bSYork Sun 		if ((cs_sa <= 0xff) && (cs_ea >= 0xff)) {
785614e71bSYork Sun 			csn = i;
795614e71bSYork Sun 			csn_bnds_backup = regs->cs[i].bnds;
805614e71bSYork Sun 			csn_bnds_t = (unsigned int *) &regs->cs[i].bnds;
815614e71bSYork Sun 			if (cs_ea > 0xeff)
825614e71bSYork Sun 				*csn_bnds_t = regs->cs[i].bnds + 0x01000000;
835614e71bSYork Sun 			else
845614e71bSYork Sun 				*csn_bnds_t = regs->cs[i].bnds + 0x01000100;
855614e71bSYork Sun 			debug("Found cs%d_bns (0x%08x) covering 0xff000000, "
865614e71bSYork Sun 				"change it to 0x%x\n",
875614e71bSYork Sun 				csn, csn_bnds_backup, regs->cs[i].bnds);
885614e71bSYork Sun 			break;
895614e71bSYork Sun 		}
905614e71bSYork Sun 	}
915614e71bSYork Sun #endif
925614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
935614e71bSYork Sun 		if (i == 0) {
945614e71bSYork Sun 			out_be32(&ddr->cs0_bnds, regs->cs[i].bnds);
955614e71bSYork Sun 			out_be32(&ddr->cs0_config, regs->cs[i].config);
965614e71bSYork Sun 			out_be32(&ddr->cs0_config_2, regs->cs[i].config_2);
975614e71bSYork Sun 
985614e71bSYork Sun 		} else if (i == 1) {
995614e71bSYork Sun 			out_be32(&ddr->cs1_bnds, regs->cs[i].bnds);
1005614e71bSYork Sun 			out_be32(&ddr->cs1_config, regs->cs[i].config);
1015614e71bSYork Sun 			out_be32(&ddr->cs1_config_2, regs->cs[i].config_2);
1025614e71bSYork Sun 
1035614e71bSYork Sun 		} else if (i == 2) {
1045614e71bSYork Sun 			out_be32(&ddr->cs2_bnds, regs->cs[i].bnds);
1055614e71bSYork Sun 			out_be32(&ddr->cs2_config, regs->cs[i].config);
1065614e71bSYork Sun 			out_be32(&ddr->cs2_config_2, regs->cs[i].config_2);
1075614e71bSYork Sun 
1085614e71bSYork Sun 		} else if (i == 3) {
1095614e71bSYork Sun 			out_be32(&ddr->cs3_bnds, regs->cs[i].bnds);
1105614e71bSYork Sun 			out_be32(&ddr->cs3_config, regs->cs[i].config);
1115614e71bSYork Sun 			out_be32(&ddr->cs3_config_2, regs->cs[i].config_2);
1125614e71bSYork Sun 		}
1135614e71bSYork Sun 	}
1145614e71bSYork Sun 
1155614e71bSYork Sun 	out_be32(&ddr->timing_cfg_3, regs->timing_cfg_3);
1165614e71bSYork Sun 	out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0);
1175614e71bSYork Sun 	out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
1185614e71bSYork Sun 	out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
1195614e71bSYork Sun 	out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
1205614e71bSYork Sun 	out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
1215614e71bSYork Sun 	out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
1225614e71bSYork Sun 	out_be32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4);
1235614e71bSYork Sun 	out_be32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5);
1245614e71bSYork Sun 	out_be32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6);
1255614e71bSYork Sun 	out_be32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7);
1265614e71bSYork Sun 	out_be32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8);
1275614e71bSYork Sun 	out_be32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
1285614e71bSYork Sun 	out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
1295614e71bSYork Sun 	out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
1305614e71bSYork Sun 	out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
1315614e71bSYork Sun 	out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4);
1325614e71bSYork Sun 	out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);
1335614e71bSYork Sun 	out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
1345614e71bSYork Sun 	out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
1355614e71bSYork Sun #ifndef CONFIG_SYS_FSL_DDR_EMU
1365614e71bSYork Sun 	/*
1375614e71bSYork Sun 	 * Skip these two registers if running on emulator
1385614e71bSYork Sun 	 * because emulator doesn't have skew between bytes.
1395614e71bSYork Sun 	 */
1405614e71bSYork Sun 
1415614e71bSYork Sun 	if (regs->ddr_wrlvl_cntl_2)
1425614e71bSYork Sun 		out_be32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2);
1435614e71bSYork Sun 	if (regs->ddr_wrlvl_cntl_3)
1445614e71bSYork Sun 		out_be32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3);
1455614e71bSYork Sun #endif
1465614e71bSYork Sun 
1475614e71bSYork Sun 	out_be32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);
1485614e71bSYork Sun 	out_be32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
1495614e71bSYork Sun 	out_be32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
1505614e71bSYork Sun 	out_be32(&ddr->ddr_cdr1, regs->ddr_cdr1);
151a7787b78STang Yuantian #ifdef CONFIG_DEEP_SLEEP
152a7787b78STang Yuantian 	if (is_warm_boot()) {
153a7787b78STang Yuantian 		out_be32(&ddr->sdram_cfg_2,
154a7787b78STang Yuantian 			 regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
155a7787b78STang Yuantian 		out_be32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE);
156a7787b78STang Yuantian 		out_be32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA);
157a7787b78STang Yuantian 
158a7787b78STang Yuantian 		/* DRAM VRef will not be trained */
159a7787b78STang Yuantian 		out_be32(&ddr->ddr_cdr2,
160a7787b78STang Yuantian 			 regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN);
161a7787b78STang Yuantian 	} else
162a7787b78STang Yuantian #endif
163a7787b78STang Yuantian 	{
164a7787b78STang Yuantian 		out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
165a7787b78STang Yuantian 		out_be32(&ddr->init_addr, regs->ddr_init_addr);
166a7787b78STang Yuantian 		out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
1675614e71bSYork Sun 		out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2);
168a7787b78STang Yuantian 	}
1695614e71bSYork Sun 	out_be32(&ddr->err_disable, regs->err_disable);
1705614e71bSYork Sun 	out_be32(&ddr->err_int_en, regs->err_int_en);
1715614e71bSYork Sun 	for (i = 0; i < 32; i++) {
1725614e71bSYork Sun 		if (regs->debug[i]) {
1735614e71bSYork Sun 			debug("Write to debug_%d as %08x\n", i+1, regs->debug[i]);
1745614e71bSYork Sun 			out_be32(&ddr->debug[i], regs->debug[i]);
1755614e71bSYork Sun 		}
1765614e71bSYork Sun 	}
1775614e71bSYork Sun 
1785614e71bSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003474
1795614e71bSYork Sun 	out_be32(&ddr->debug[12], 0x00000015);
1805614e71bSYork Sun 	out_be32(&ddr->debug[21], 0x24000000);
1815614e71bSYork Sun #endif /* CONFIG_SYS_FSL_ERRATUM_DDR_A003474 */
1825614e71bSYork Sun 
1835614e71bSYork Sun 	/*
1845614e71bSYork Sun 	 * For RDIMMs, JEDEC spec requires clocks to be stable before reset is
1855614e71bSYork Sun 	 * deasserted. Clocks start when any chip select is enabled and clock
1865614e71bSYork Sun 	 * control register is set. Because all DDR components are connected to
1875614e71bSYork Sun 	 * one reset signal, this needs to be done in two steps. Step 1 is to
1885614e71bSYork Sun 	 * get the clocks started. Step 2 resumes after reset signal is
1895614e71bSYork Sun 	 * deasserted.
1905614e71bSYork Sun 	 */
1915614e71bSYork Sun 	if (step == 1) {
1925614e71bSYork Sun 		udelay(200);
1935614e71bSYork Sun 		return;
1945614e71bSYork Sun 	}
1955614e71bSYork Sun 
1965614e71bSYork Sun step2:
1975614e71bSYork Sun 	/* Set, but do not enable the memory */
1985614e71bSYork Sun 	temp_sdram_cfg = regs->ddr_sdram_cfg;
1995614e71bSYork Sun 	temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
2005614e71bSYork Sun 	out_be32(&ddr->sdram_cfg, temp_sdram_cfg);
2015614e71bSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003
2025614e71bSYork Sun 	debug("Workaround for ERRATUM_DDR_A003\n");
2035614e71bSYork Sun 	if (regs->ddr_sdram_rcw_2 & 0x00f00000) {
2045614e71bSYork Sun 		out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2 & 0xf07fffff);
2055614e71bSYork Sun 		out_be32(&ddr->debug[2], 0x00000400);
2065614e71bSYork Sun 		out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl & 0x7fffffff);
2075614e71bSYork Sun 		out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl & 0x7fffffff);
2085614e71bSYork Sun 		out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2 & 0xffffffeb);
2095614e71bSYork Sun 		out_be32(&ddr->mtcr, 0);
21076356eb5SYork Sun 		save1 = in_be32(&ddr->debug[12]);
21176356eb5SYork Sun 		save2 = in_be32(&ddr->debug[21]);
2125614e71bSYork Sun 		out_be32(&ddr->debug[12], 0x00000015);
2135614e71bSYork Sun 		out_be32(&ddr->debug[21], 0x24000000);
2145614e71bSYork Sun 		out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval & 0xffff);
2155614e71bSYork Sun 		out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_BI | SDRAM_CFG_MEM_EN);
2165614e71bSYork Sun 
2175614e71bSYork Sun 		asm volatile("sync;isync");
2185614e71bSYork Sun 		while (!(in_be32(&ddr->debug[1]) & 0x2))
2195614e71bSYork Sun 			;
2205614e71bSYork Sun 
2215614e71bSYork Sun 		switch (regs->ddr_sdram_rcw_2 & 0x00f00000) {
2225614e71bSYork Sun 		case 0x00000000:
2235614e71bSYork Sun 			out_be32(&ddr->sdram_md_cntl,
2245614e71bSYork Sun 				MD_CNTL_MD_EN		|
2255614e71bSYork Sun 				MD_CNTL_CS_SEL_CS0_CS1	|
2265614e71bSYork Sun 				0x04000000		|
2275614e71bSYork Sun 				MD_CNTL_WRCW		|
2285614e71bSYork Sun 				MD_CNTL_MD_VALUE(0x02));
22976356eb5SYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
23076356eb5SYork Sun 			if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
23176356eb5SYork Sun 				break;
23276356eb5SYork Sun 			while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
23376356eb5SYork Sun 				;
23476356eb5SYork Sun 			out_be32(&ddr->sdram_md_cntl,
23576356eb5SYork Sun 				 MD_CNTL_MD_EN		|
23676356eb5SYork Sun 				 MD_CNTL_CS_SEL_CS2_CS3	|
23776356eb5SYork Sun 				 0x04000000		|
23876356eb5SYork Sun 				 MD_CNTL_WRCW		|
23976356eb5SYork Sun 				 MD_CNTL_MD_VALUE(0x02));
24076356eb5SYork Sun #endif
2415614e71bSYork Sun 			break;
2425614e71bSYork Sun 		case 0x00100000:
2435614e71bSYork Sun 			out_be32(&ddr->sdram_md_cntl,
2445614e71bSYork Sun 				MD_CNTL_MD_EN		|
2455614e71bSYork Sun 				MD_CNTL_CS_SEL_CS0_CS1	|
2465614e71bSYork Sun 				0x04000000		|
2475614e71bSYork Sun 				MD_CNTL_WRCW		|
2485614e71bSYork Sun 				MD_CNTL_MD_VALUE(0x0a));
24976356eb5SYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
25076356eb5SYork Sun 			if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
25176356eb5SYork Sun 				break;
25276356eb5SYork Sun 			while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
25376356eb5SYork Sun 				;
25476356eb5SYork Sun 			out_be32(&ddr->sdram_md_cntl,
25576356eb5SYork Sun 				 MD_CNTL_MD_EN		|
25676356eb5SYork Sun 				 MD_CNTL_CS_SEL_CS2_CS3	|
25776356eb5SYork Sun 				 0x04000000		|
25876356eb5SYork Sun 				 MD_CNTL_WRCW		|
25976356eb5SYork Sun 				 MD_CNTL_MD_VALUE(0x0a));
26076356eb5SYork Sun #endif
2615614e71bSYork Sun 			break;
2625614e71bSYork Sun 		case 0x00200000:
2635614e71bSYork Sun 			out_be32(&ddr->sdram_md_cntl,
2645614e71bSYork Sun 				MD_CNTL_MD_EN		|
2655614e71bSYork Sun 				MD_CNTL_CS_SEL_CS0_CS1	|
2665614e71bSYork Sun 				0x04000000		|
2675614e71bSYork Sun 				MD_CNTL_WRCW		|
2685614e71bSYork Sun 				MD_CNTL_MD_VALUE(0x12));
26976356eb5SYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
27076356eb5SYork Sun 			if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
27176356eb5SYork Sun 				break;
27276356eb5SYork Sun 			while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
27376356eb5SYork Sun 				;
27476356eb5SYork Sun 			out_be32(&ddr->sdram_md_cntl,
27576356eb5SYork Sun 				 MD_CNTL_MD_EN		|
27676356eb5SYork Sun 				 MD_CNTL_CS_SEL_CS2_CS3	|
27776356eb5SYork Sun 				 0x04000000		|
27876356eb5SYork Sun 				 MD_CNTL_WRCW		|
27976356eb5SYork Sun 				 MD_CNTL_MD_VALUE(0x12));
28076356eb5SYork Sun #endif
2815614e71bSYork Sun 			break;
2825614e71bSYork Sun 		case 0x00300000:
2835614e71bSYork Sun 			out_be32(&ddr->sdram_md_cntl,
2845614e71bSYork Sun 				MD_CNTL_MD_EN		|
2855614e71bSYork Sun 				MD_CNTL_CS_SEL_CS0_CS1	|
2865614e71bSYork Sun 				0x04000000		|
2875614e71bSYork Sun 				MD_CNTL_WRCW		|
2885614e71bSYork Sun 				MD_CNTL_MD_VALUE(0x1a));
28976356eb5SYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
29076356eb5SYork Sun 			if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
29176356eb5SYork Sun 				break;
29276356eb5SYork Sun 			while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
29376356eb5SYork Sun 				;
29476356eb5SYork Sun 			out_be32(&ddr->sdram_md_cntl,
29576356eb5SYork Sun 				 MD_CNTL_MD_EN		|
29676356eb5SYork Sun 				 MD_CNTL_CS_SEL_CS2_CS3	|
29776356eb5SYork Sun 				 0x04000000		|
29876356eb5SYork Sun 				 MD_CNTL_WRCW		|
29976356eb5SYork Sun 				 MD_CNTL_MD_VALUE(0x1a));
30076356eb5SYork Sun #endif
3015614e71bSYork Sun 			break;
3025614e71bSYork Sun 		default:
3035614e71bSYork Sun 			out_be32(&ddr->sdram_md_cntl,
3045614e71bSYork Sun 				MD_CNTL_MD_EN		|
3055614e71bSYork Sun 				MD_CNTL_CS_SEL_CS0_CS1	|
3065614e71bSYork Sun 				0x04000000		|
3075614e71bSYork Sun 				MD_CNTL_WRCW		|
3085614e71bSYork Sun 				MD_CNTL_MD_VALUE(0x02));
30976356eb5SYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
31076356eb5SYork Sun 			if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
31176356eb5SYork Sun 				break;
31276356eb5SYork Sun 			while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
31376356eb5SYork Sun 				;
31476356eb5SYork Sun 			out_be32(&ddr->sdram_md_cntl,
31576356eb5SYork Sun 				 MD_CNTL_MD_EN		|
31676356eb5SYork Sun 				 MD_CNTL_CS_SEL_CS2_CS3	|
31776356eb5SYork Sun 				 0x04000000		|
31876356eb5SYork Sun 				 MD_CNTL_WRCW		|
31976356eb5SYork Sun 				 MD_CNTL_MD_VALUE(0x02));
32076356eb5SYork Sun #endif
3215614e71bSYork Sun 			printf("Unsupported RC10\n");
3225614e71bSYork Sun 			break;
3235614e71bSYork Sun 		}
3245614e71bSYork Sun 
3255614e71bSYork Sun 		while (in_be32(&ddr->sdram_md_cntl) & 0x80000000)
3265614e71bSYork Sun 			;
3275614e71bSYork Sun 		udelay(6);
3285614e71bSYork Sun 		out_be32(&ddr->sdram_cfg, temp_sdram_cfg);
3295614e71bSYork Sun 		out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
3305614e71bSYork Sun 		out_be32(&ddr->debug[2], 0x0);
3315614e71bSYork Sun 		out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
3325614e71bSYork Sun 		out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
3335614e71bSYork Sun 		out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
33476356eb5SYork Sun 		out_be32(&ddr->debug[12], save1);
33576356eb5SYork Sun 		out_be32(&ddr->debug[21], save2);
3365614e71bSYork Sun 		out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
3375614e71bSYork Sun 
3385614e71bSYork Sun 	}
3395614e71bSYork Sun #endif
3405614e71bSYork Sun 	/*
3415614e71bSYork Sun 	 * For 8572 DDR1 erratum - DDR controller may enter illegal state
3425614e71bSYork Sun 	 * when operatiing in 32-bit bus mode with 4-beat bursts,
3435614e71bSYork Sun 	 * This erratum does not affect DDR3 mode, only for DDR2 mode.
3445614e71bSYork Sun 	 */
3455614e71bSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_115
3465614e71bSYork Sun 	debug("Workaround for ERRATUM_DDR_115\n");
3475614e71bSYork Sun 	if ((((in_be32(&ddr->sdram_cfg) >> 24) & 0x7) == SDRAM_TYPE_DDR2)
3485614e71bSYork Sun 	    && in_be32(&ddr->sdram_cfg) & 0x80000) {
3495614e71bSYork Sun 		/* set DEBUG_1[31] */
3505614e71bSYork Sun 		setbits_be32(&ddr->debug[0], 1);
3515614e71bSYork Sun 	}
3525614e71bSYork Sun #endif
3535614e71bSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
3545614e71bSYork Sun 	debug("Workaround for ERRATUM_DDR111_DDR134\n");
3555614e71bSYork Sun 	/*
3565614e71bSYork Sun 	 * This is the combined workaround for DDR111 and DDR134
3575614e71bSYork Sun 	 * following the published errata for MPC8572
3585614e71bSYork Sun 	 */
3595614e71bSYork Sun 
3605614e71bSYork Sun 	/* 1. Set EEBACR[3] */
3615614e71bSYork Sun 	setbits_be32(&ecm->eebacr, 0x10000000);
3625614e71bSYork Sun 	debug("Setting EEBACR[3] to 0x%08x\n", in_be32(&ecm->eebacr));
3635614e71bSYork Sun 
3645614e71bSYork Sun 	/* 2. Set DINIT in SDRAM_CFG_2*/
3655614e71bSYork Sun 	setbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_D_INIT);
3665614e71bSYork Sun 	debug("Setting sdram_cfg_2[D_INIT] to 0x%08x\n",
3675614e71bSYork Sun 		in_be32(&ddr->sdram_cfg_2));
3685614e71bSYork Sun 
3695614e71bSYork Sun 	/* 3. Set DEBUG_3[21] */
3705614e71bSYork Sun 	setbits_be32(&ddr->debug[2], 0x400);
3715614e71bSYork Sun 	debug("Setting DEBUG_3[21] to 0x%08x\n", in_be32(&ddr->debug[2]));
3725614e71bSYork Sun 
3735614e71bSYork Sun #endif	/* part 1 of the workaound */
3745614e71bSYork Sun 
3755614e71bSYork Sun 	/*
3765614e71bSYork Sun 	 * 500 painful micro-seconds must elapse between
3775614e71bSYork Sun 	 * the DDR clock setup and the DDR config enable.
3785614e71bSYork Sun 	 * DDR2 need 200 us, and DDR3 need 500 us from spec,
3795614e71bSYork Sun 	 * we choose the max, that is 500 us for all of case.
3805614e71bSYork Sun 	 */
3815614e71bSYork Sun 	udelay(500);
3825614e71bSYork Sun 	asm volatile("sync;isync");
3835614e71bSYork Sun 
384aade2004STang Yuantian #ifdef CONFIG_DEEP_SLEEP
385a7787b78STang Yuantian 	if (is_warm_boot()) {
386aade2004STang Yuantian 		/* enter self-refresh */
387a7787b78STang Yuantian 		setbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR);
388aade2004STang Yuantian 		/* do board specific memory setup */
389aade2004STang Yuantian 		board_mem_sleep_setup();
390aade2004STang Yuantian 		temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
391a7787b78STang Yuantian 	} else
392aade2004STang Yuantian #endif
393aade2004STang Yuantian 		temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI);
394a7787b78STang Yuantian 
395a7787b78STang Yuantian 	/* Let the controller go */
3965614e71bSYork Sun 	out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
3975614e71bSYork Sun 	asm volatile("sync;isync");
3985614e71bSYork Sun 
3995614e71bSYork Sun 	total_gb_size_per_controller = 0;
4005614e71bSYork Sun 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
4015614e71bSYork Sun 		if (!(regs->cs[i].config & 0x80000000))
4025614e71bSYork Sun 			continue;
4035614e71bSYork Sun 		total_gb_size_per_controller += 1 << (
4045614e71bSYork Sun 			((regs->cs[i].config >> 14) & 0x3) + 2 +
4055614e71bSYork Sun 			((regs->cs[i].config >> 8) & 0x7) + 12 +
4065614e71bSYork Sun 			((regs->cs[i].config >> 0) & 0x7) + 8 +
4075614e71bSYork Sun 			3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) -
4085614e71bSYork Sun 			26);			/* minus 26 (count of 64M) */
4095614e71bSYork Sun 	}
4105614e71bSYork Sun 	if (fsl_ddr_get_intl3r() & 0x80000000)	/* 3-way interleaving */
4115614e71bSYork Sun 		total_gb_size_per_controller *= 3;
4125614e71bSYork Sun 	else if (regs->cs[0].config & 0x20000000) /* 2-way interleaving */
4135614e71bSYork Sun 		total_gb_size_per_controller <<= 1;
4145614e71bSYork Sun 	/*
4155614e71bSYork Sun 	 * total memory / bus width = transactions needed
4165614e71bSYork Sun 	 * transactions needed / data rate = seconds
4175614e71bSYork Sun 	 * to add plenty of buffer, double the time
4185614e71bSYork Sun 	 * For example, 2GB on 666MT/s 64-bit bus takes about 402ms
4195614e71bSYork Sun 	 * Let's wait for 800ms
4205614e71bSYork Sun 	 */
4215614e71bSYork Sun 	bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
4225614e71bSYork Sun 			>> SDRAM_CFG_DBW_SHIFT);
4235614e71bSYork Sun 	timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
42403e664d8SYork Sun 		(get_ddr_freq(ctrl_num) >> 20)) << 1;
4255614e71bSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
4265614e71bSYork Sun 	timeout_save = timeout;
4275614e71bSYork Sun #endif
4285614e71bSYork Sun 	total_gb_size_per_controller >>= 4;	/* shift down to gb size */
4295614e71bSYork Sun 	debug("total %d GB\n", total_gb_size_per_controller);
4305614e71bSYork Sun 	debug("Need to wait up to %d * 10ms\n", timeout);
4315614e71bSYork Sun 
4325614e71bSYork Sun 	/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done.  */
4335614e71bSYork Sun 	while ((in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
4345614e71bSYork Sun 		(timeout >= 0)) {
4355614e71bSYork Sun 		udelay(10000);		/* throttle polling rate */
4365614e71bSYork Sun 		timeout--;
4375614e71bSYork Sun 	}
4385614e71bSYork Sun 
4395614e71bSYork Sun 	if (timeout <= 0)
4405614e71bSYork Sun 		printf("Waiting for D_INIT timeout. Memory may not work.\n");
4415614e71bSYork Sun 
4425614e71bSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
4435614e71bSYork Sun 	/* continue this workaround */
4445614e71bSYork Sun 
4455614e71bSYork Sun 	/* 4. Clear DEBUG3[21] */
4465614e71bSYork Sun 	clrbits_be32(&ddr->debug[2], 0x400);
4475614e71bSYork Sun 	debug("Clearing D3[21] to 0x%08x\n", in_be32(&ddr->debug[2]));
4485614e71bSYork Sun 
4495614e71bSYork Sun 	/* DDR134 workaround starts */
4505614e71bSYork Sun 	/* A: Clear sdram_cfg_2[odt_cfg] */
4515614e71bSYork Sun 	clrbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_ODT_CFG_MASK);
4525614e71bSYork Sun 	debug("Clearing SDRAM_CFG2[ODT_CFG] to 0x%08x\n",
4535614e71bSYork Sun 		in_be32(&ddr->sdram_cfg_2));
4545614e71bSYork Sun 
4555614e71bSYork Sun 	/* B: Set DEBUG1[15] */
4565614e71bSYork Sun 	setbits_be32(&ddr->debug[0], 0x10000);
4575614e71bSYork Sun 	debug("Setting D1[15] to 0x%08x\n", in_be32(&ddr->debug[0]));
4585614e71bSYork Sun 
4595614e71bSYork Sun 	/* C: Set timing_cfg_2[cpo] to 0b11111 */
4605614e71bSYork Sun 	setbits_be32(&ddr->timing_cfg_2, TIMING_CFG_2_CPO_MASK);
4615614e71bSYork Sun 	debug("Setting TMING_CFG_2[CPO] to 0x%08x\n",
4625614e71bSYork Sun 		in_be32(&ddr->timing_cfg_2));
4635614e71bSYork Sun 
4645614e71bSYork Sun 	/* D: Set D6 to 0x9f9f9f9f */
4655614e71bSYork Sun 	out_be32(&ddr->debug[5], 0x9f9f9f9f);
4665614e71bSYork Sun 	debug("Setting D6 to 0x%08x\n", in_be32(&ddr->debug[5]));
4675614e71bSYork Sun 
4685614e71bSYork Sun 	/* E: Set D7 to 0x9f9f9f9f */
4695614e71bSYork Sun 	out_be32(&ddr->debug[6], 0x9f9f9f9f);
4705614e71bSYork Sun 	debug("Setting D7 to 0x%08x\n", in_be32(&ddr->debug[6]));
4715614e71bSYork Sun 
4725614e71bSYork Sun 	/* F: Set D2[20] */
4735614e71bSYork Sun 	setbits_be32(&ddr->debug[1], 0x800);
4745614e71bSYork Sun 	debug("Setting D2[20] to 0x%08x\n", in_be32(&ddr->debug[1]));
4755614e71bSYork Sun 
4765614e71bSYork Sun 	/* G: Poll on D2[20] until cleared */
4775614e71bSYork Sun 	while (in_be32(&ddr->debug[1]) & 0x800)
4785614e71bSYork Sun 		udelay(10000);          /* throttle polling rate */
4795614e71bSYork Sun 
4805614e71bSYork Sun 	/* H: Clear D1[15] */
4815614e71bSYork Sun 	clrbits_be32(&ddr->debug[0], 0x10000);
4825614e71bSYork Sun 	debug("Setting D1[15] to 0x%08x\n", in_be32(&ddr->debug[0]));
4835614e71bSYork Sun 
4845614e71bSYork Sun 	/* I: Set sdram_cfg_2[odt_cfg] */
4855614e71bSYork Sun 	setbits_be32(&ddr->sdram_cfg_2,
4865614e71bSYork Sun 		regs->ddr_sdram_cfg_2 & SDRAM_CFG2_ODT_CFG_MASK);
4875614e71bSYork Sun 	debug("Setting sdram_cfg_2 to 0x%08x\n", in_be32(&ddr->sdram_cfg_2));
4885614e71bSYork Sun 
4895614e71bSYork Sun 	/* Continuing with the DDR111 workaround */
4905614e71bSYork Sun 	/* 5. Set D2[21] */
4915614e71bSYork Sun 	setbits_be32(&ddr->debug[1], 0x400);
4925614e71bSYork Sun 	debug("Setting D2[21] to 0x%08x\n", in_be32(&ddr->debug[1]));
4935614e71bSYork Sun 
4945614e71bSYork Sun 	/* 6. Poll D2[21] until its cleared */
4955614e71bSYork Sun 	while (in_be32(&ddr->debug[1]) & 0x400)
4965614e71bSYork Sun 		udelay(10000);          /* throttle polling rate */
4975614e71bSYork Sun 
4985614e71bSYork Sun 	/* 7. Wait for state machine 2nd run, roughly 400ms/GB */
4995614e71bSYork Sun 	debug("Wait for %d * 10ms\n", timeout_save);
5005614e71bSYork Sun 	udelay(timeout_save * 10000);
5015614e71bSYork Sun 
5025614e71bSYork Sun 	/* 8. Set sdram_cfg_2[dinit] if options requires */
5035614e71bSYork Sun 	setbits_be32(&ddr->sdram_cfg_2,
5045614e71bSYork Sun 		regs->ddr_sdram_cfg_2 & SDRAM_CFG2_D_INIT);
5055614e71bSYork Sun 	debug("Setting sdram_cfg_2 to 0x%08x\n", in_be32(&ddr->sdram_cfg_2));
5065614e71bSYork Sun 
5075614e71bSYork Sun 	/* 9. Poll until dinit is cleared */
5085614e71bSYork Sun 	timeout = timeout_save;
5095614e71bSYork Sun 	debug("Need to wait up to %d * 10ms\n", timeout);
5105614e71bSYork Sun 	while ((in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
5115614e71bSYork Sun 		(timeout >= 0)) {
5125614e71bSYork Sun 		udelay(10000);		/* throttle polling rate */
5135614e71bSYork Sun 		timeout--;
5145614e71bSYork Sun 	}
5155614e71bSYork Sun 
5165614e71bSYork Sun 	if (timeout <= 0)
5175614e71bSYork Sun 		printf("Waiting for D_INIT timeout. Memory may not work.\n");
5185614e71bSYork Sun 
5195614e71bSYork Sun 	/* 10. Clear EEBACR[3] */
5205614e71bSYork Sun 	clrbits_be32(&ecm->eebacr, 10000000);
5215614e71bSYork Sun 	debug("Clearing EEBACR[3] to 0x%08x\n", in_be32(&ecm->eebacr));
5225614e71bSYork Sun 
5235614e71bSYork Sun 	if (csn != -1) {
5245614e71bSYork Sun 		csn_bnds_t = (unsigned int *) &regs->cs[csn].bnds;
5255614e71bSYork Sun 		*csn_bnds_t = csn_bnds_backup;
5265614e71bSYork Sun 		debug("Change cs%d_bnds back to 0x%08x\n",
5275614e71bSYork Sun 			csn, regs->cs[csn].bnds);
5285614e71bSYork Sun 		setbits_be32(&ddr->sdram_cfg, 0x2);	/* MEM_HALT */
5295614e71bSYork Sun 		switch (csn) {
5305614e71bSYork Sun 		case 0:
5315614e71bSYork Sun 			out_be32(&ddr->cs0_bnds, regs->cs[csn].bnds);
5325614e71bSYork Sun 			break;
5335614e71bSYork Sun 		case 1:
5345614e71bSYork Sun 			out_be32(&ddr->cs1_bnds, regs->cs[csn].bnds);
5355614e71bSYork Sun 			break;
53603e664d8SYork Sun #if CONFIG_CHIP_SELECTS_PER_CTRL > 2
5375614e71bSYork Sun 		case 2:
5385614e71bSYork Sun 			out_be32(&ddr->cs2_bnds, regs->cs[csn].bnds);
5395614e71bSYork Sun 			break;
5405614e71bSYork Sun 		case 3:
5415614e71bSYork Sun 			out_be32(&ddr->cs3_bnds, regs->cs[csn].bnds);
5425614e71bSYork Sun 			break;
54303e664d8SYork Sun #endif
5445614e71bSYork Sun 		}
5455614e71bSYork Sun 		clrbits_be32(&ddr->sdram_cfg, 0x2);
5465614e71bSYork Sun 	}
5475614e71bSYork Sun #endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */
548aade2004STang Yuantian #ifdef CONFIG_DEEP_SLEEP
549a7787b78STang Yuantian 	if (is_warm_boot())
550aade2004STang Yuantian 		/* exit self-refresh */
551a7787b78STang Yuantian 		clrbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR);
552aade2004STang Yuantian #endif
5535614e71bSYork Sun }
554