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 *) ®s->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 *) ®s->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