15614e71bSYork Sun /* 234e026f9SYork Sun * Copyright 2008-2014 Freescale Semiconductor, Inc. 35614e71bSYork Sun * 45614e71bSYork Sun * SPDX-License-Identifier: GPL-2.0+ 55614e71bSYork Sun */ 65614e71bSYork Sun 75614e71bSYork Sun /* 85614e71bSYork Sun * Generic driver for Freescale DDR/DDR2/DDR3 memory controller. 95614e71bSYork Sun * Based on code from spd_sdram.c 105614e71bSYork Sun * Author: James Yang [at freescale.com] 115614e71bSYork Sun */ 125614e71bSYork Sun 135614e71bSYork Sun #include <common.h> 145614e71bSYork Sun #include <fsl_ddr_sdram.h> 155614e71bSYork Sun 165614e71bSYork Sun #include <fsl_ddr.h> 179a17eb5bSYork Sun #include <fsl_immap.h> 185614e71bSYork Sun #include <asm/io.h> 195614e71bSYork Sun 205614e71bSYork Sun unsigned int picos_to_mclk(unsigned int picos); 215614e71bSYork Sun 225614e71bSYork Sun /* 235614e71bSYork Sun * Determine Rtt value. 245614e71bSYork Sun * 255614e71bSYork Sun * This should likely be either board or controller specific. 265614e71bSYork Sun * 275614e71bSYork Sun * Rtt(nominal) - DDR2: 285614e71bSYork Sun * 0 = Rtt disabled 295614e71bSYork Sun * 1 = 75 ohm 305614e71bSYork Sun * 2 = 150 ohm 315614e71bSYork Sun * 3 = 50 ohm 325614e71bSYork Sun * Rtt(nominal) - DDR3: 335614e71bSYork Sun * 0 = Rtt disabled 345614e71bSYork Sun * 1 = 60 ohm 355614e71bSYork Sun * 2 = 120 ohm 365614e71bSYork Sun * 3 = 40 ohm 375614e71bSYork Sun * 4 = 20 ohm 385614e71bSYork Sun * 5 = 30 ohm 395614e71bSYork Sun * 405614e71bSYork Sun * FIXME: Apparently 8641 needs a value of 2 415614e71bSYork Sun * FIXME: Old code seys if 667 MHz or higher, use 3 on 8572 425614e71bSYork Sun * 435614e71bSYork Sun * FIXME: There was some effort down this line earlier: 445614e71bSYork Sun * 455614e71bSYork Sun * unsigned int i; 465614e71bSYork Sun * for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL/2; i++) { 475614e71bSYork Sun * if (popts->dimmslot[i].num_valid_cs 485614e71bSYork Sun * && (popts->cs_local_opts[2*i].odt_rd_cfg 495614e71bSYork Sun * || popts->cs_local_opts[2*i].odt_wr_cfg)) { 505614e71bSYork Sun * rtt = 2; 515614e71bSYork Sun * break; 525614e71bSYork Sun * } 535614e71bSYork Sun * } 545614e71bSYork Sun */ 555614e71bSYork Sun static inline int fsl_ddr_get_rtt(void) 565614e71bSYork Sun { 575614e71bSYork Sun int rtt; 585614e71bSYork Sun 595614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 605614e71bSYork Sun rtt = 0; 615614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 625614e71bSYork Sun rtt = 3; 635614e71bSYork Sun #else 645614e71bSYork Sun rtt = 0; 655614e71bSYork Sun #endif 665614e71bSYork Sun 675614e71bSYork Sun return rtt; 685614e71bSYork Sun } 695614e71bSYork Sun 7034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 7134e026f9SYork Sun /* 7234e026f9SYork Sun * compute CAS write latency according to DDR4 spec 7334e026f9SYork Sun * CWL = 9 for <= 1600MT/s 7434e026f9SYork Sun * 10 for <= 1866MT/s 7534e026f9SYork Sun * 11 for <= 2133MT/s 7634e026f9SYork Sun * 12 for <= 2400MT/s 7734e026f9SYork Sun * 14 for <= 2667MT/s 7834e026f9SYork Sun * 16 for <= 2933MT/s 7934e026f9SYork Sun * 18 for higher 8034e026f9SYork Sun */ 8134e026f9SYork Sun static inline unsigned int compute_cas_write_latency(void) 8234e026f9SYork Sun { 8334e026f9SYork Sun unsigned int cwl; 8434e026f9SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(); 8534e026f9SYork Sun if (mclk_ps >= 1250) 8634e026f9SYork Sun cwl = 9; 8734e026f9SYork Sun else if (mclk_ps >= 1070) 8834e026f9SYork Sun cwl = 10; 8934e026f9SYork Sun else if (mclk_ps >= 935) 9034e026f9SYork Sun cwl = 11; 9134e026f9SYork Sun else if (mclk_ps >= 833) 9234e026f9SYork Sun cwl = 12; 9334e026f9SYork Sun else if (mclk_ps >= 750) 9434e026f9SYork Sun cwl = 14; 9534e026f9SYork Sun else if (mclk_ps >= 681) 9634e026f9SYork Sun cwl = 16; 9734e026f9SYork Sun else 9834e026f9SYork Sun cwl = 18; 9934e026f9SYork Sun 10034e026f9SYork Sun return cwl; 10134e026f9SYork Sun } 10234e026f9SYork Sun #else 1035614e71bSYork Sun /* 1045614e71bSYork Sun * compute the CAS write latency according to DDR3 spec 1055614e71bSYork Sun * CWL = 5 if tCK >= 2.5ns 1065614e71bSYork Sun * 6 if 2.5ns > tCK >= 1.875ns 1075614e71bSYork Sun * 7 if 1.875ns > tCK >= 1.5ns 1085614e71bSYork Sun * 8 if 1.5ns > tCK >= 1.25ns 1095614e71bSYork Sun * 9 if 1.25ns > tCK >= 1.07ns 1105614e71bSYork Sun * 10 if 1.07ns > tCK >= 0.935ns 1115614e71bSYork Sun * 11 if 0.935ns > tCK >= 0.833ns 1125614e71bSYork Sun * 12 if 0.833ns > tCK >= 0.75ns 1135614e71bSYork Sun */ 1145614e71bSYork Sun static inline unsigned int compute_cas_write_latency(void) 1155614e71bSYork Sun { 1165614e71bSYork Sun unsigned int cwl; 1175614e71bSYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(); 1185614e71bSYork Sun 1195614e71bSYork Sun if (mclk_ps >= 2500) 1205614e71bSYork Sun cwl = 5; 1215614e71bSYork Sun else if (mclk_ps >= 1875) 1225614e71bSYork Sun cwl = 6; 1235614e71bSYork Sun else if (mclk_ps >= 1500) 1245614e71bSYork Sun cwl = 7; 1255614e71bSYork Sun else if (mclk_ps >= 1250) 1265614e71bSYork Sun cwl = 8; 1275614e71bSYork Sun else if (mclk_ps >= 1070) 1285614e71bSYork Sun cwl = 9; 1295614e71bSYork Sun else if (mclk_ps >= 935) 1305614e71bSYork Sun cwl = 10; 1315614e71bSYork Sun else if (mclk_ps >= 833) 1325614e71bSYork Sun cwl = 11; 1335614e71bSYork Sun else if (mclk_ps >= 750) 1345614e71bSYork Sun cwl = 12; 1355614e71bSYork Sun else { 1365614e71bSYork Sun cwl = 12; 1375614e71bSYork Sun printf("Warning: CWL is out of range\n"); 1385614e71bSYork Sun } 1395614e71bSYork Sun return cwl; 1405614e71bSYork Sun } 14134e026f9SYork Sun #endif 1425614e71bSYork Sun 1435614e71bSYork Sun /* Chip Select Configuration (CSn_CONFIG) */ 1445614e71bSYork Sun static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, 1455614e71bSYork Sun const memctl_options_t *popts, 1465614e71bSYork Sun const dimm_params_t *dimm_params) 1475614e71bSYork Sun { 1485614e71bSYork Sun unsigned int cs_n_en = 0; /* Chip Select enable */ 1495614e71bSYork Sun unsigned int intlv_en = 0; /* Memory controller interleave enable */ 1505614e71bSYork Sun unsigned int intlv_ctl = 0; /* Interleaving control */ 1515614e71bSYork Sun unsigned int ap_n_en = 0; /* Chip select n auto-precharge enable */ 1525614e71bSYork Sun unsigned int odt_rd_cfg = 0; /* ODT for reads configuration */ 1535614e71bSYork Sun unsigned int odt_wr_cfg = 0; /* ODT for writes configuration */ 1545614e71bSYork Sun unsigned int ba_bits_cs_n = 0; /* Num of bank bits for SDRAM on CSn */ 1555614e71bSYork Sun unsigned int row_bits_cs_n = 0; /* Num of row bits for SDRAM on CSn */ 1565614e71bSYork Sun unsigned int col_bits_cs_n = 0; /* Num of ocl bits for SDRAM on CSn */ 1575614e71bSYork Sun int go_config = 0; 15834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 15934e026f9SYork Sun unsigned int bg_bits_cs_n = 0; /* Num of bank group bits */ 16034e026f9SYork Sun #else 16134e026f9SYork Sun unsigned int n_banks_per_sdram_device; 16234e026f9SYork Sun #endif 1635614e71bSYork Sun 1645614e71bSYork Sun /* Compute CS_CONFIG only for existing ranks of each DIMM. */ 1655614e71bSYork Sun switch (i) { 1665614e71bSYork Sun case 0: 1675614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > 0) { 1685614e71bSYork Sun go_config = 1; 1695614e71bSYork Sun /* These fields only available in CS0_CONFIG */ 1705614e71bSYork Sun if (!popts->memctl_interleaving) 1715614e71bSYork Sun break; 1725614e71bSYork Sun switch (popts->memctl_interleaving_mode) { 1736b1e1254SYork Sun case FSL_DDR_256B_INTERLEAVING: 1745614e71bSYork Sun case FSL_DDR_CACHE_LINE_INTERLEAVING: 1755614e71bSYork Sun case FSL_DDR_PAGE_INTERLEAVING: 1765614e71bSYork Sun case FSL_DDR_BANK_INTERLEAVING: 1775614e71bSYork Sun case FSL_DDR_SUPERBANK_INTERLEAVING: 1785614e71bSYork Sun intlv_en = popts->memctl_interleaving; 1795614e71bSYork Sun intlv_ctl = popts->memctl_interleaving_mode; 1805614e71bSYork Sun break; 1815614e71bSYork Sun default: 1825614e71bSYork Sun break; 1835614e71bSYork Sun } 1845614e71bSYork Sun } 1855614e71bSYork Sun break; 1865614e71bSYork Sun case 1: 1875614e71bSYork Sun if ((dimm_number == 0 && dimm_params[0].n_ranks > 1) || \ 1885614e71bSYork Sun (dimm_number == 1 && dimm_params[1].n_ranks > 0)) 1895614e71bSYork Sun go_config = 1; 1905614e71bSYork Sun break; 1915614e71bSYork Sun case 2: 1925614e71bSYork Sun if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \ 1935614e71bSYork Sun (dimm_number >= 1 && dimm_params[dimm_number].n_ranks > 0)) 1945614e71bSYork Sun go_config = 1; 1955614e71bSYork Sun break; 1965614e71bSYork Sun case 3: 1975614e71bSYork Sun if ((dimm_number == 0 && dimm_params[0].n_ranks > 3) || \ 1985614e71bSYork Sun (dimm_number == 1 && dimm_params[1].n_ranks > 1) || \ 1995614e71bSYork Sun (dimm_number == 3 && dimm_params[3].n_ranks > 0)) 2005614e71bSYork Sun go_config = 1; 2015614e71bSYork Sun break; 2025614e71bSYork Sun default: 2035614e71bSYork Sun break; 2045614e71bSYork Sun } 2055614e71bSYork Sun if (go_config) { 2065614e71bSYork Sun cs_n_en = 1; 2075614e71bSYork Sun ap_n_en = popts->cs_local_opts[i].auto_precharge; 2085614e71bSYork Sun odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg; 2095614e71bSYork Sun odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg; 21034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 21134e026f9SYork Sun ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits; 21234e026f9SYork Sun bg_bits_cs_n = dimm_params[dimm_number].bank_group_bits; 21334e026f9SYork Sun #else 2145614e71bSYork Sun n_banks_per_sdram_device 2155614e71bSYork Sun = dimm_params[dimm_number].n_banks_per_sdram_device; 2165614e71bSYork Sun ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2; 21734e026f9SYork Sun #endif 2185614e71bSYork Sun row_bits_cs_n = dimm_params[dimm_number].n_row_addr - 12; 2195614e71bSYork Sun col_bits_cs_n = dimm_params[dimm_number].n_col_addr - 8; 2205614e71bSYork Sun } 2215614e71bSYork Sun ddr->cs[i].config = (0 2225614e71bSYork Sun | ((cs_n_en & 0x1) << 31) 2235614e71bSYork Sun | ((intlv_en & 0x3) << 29) 2245614e71bSYork Sun | ((intlv_ctl & 0xf) << 24) 2255614e71bSYork Sun | ((ap_n_en & 0x1) << 23) 2265614e71bSYork Sun 2275614e71bSYork Sun /* XXX: some implementation only have 1 bit starting at left */ 2285614e71bSYork Sun | ((odt_rd_cfg & 0x7) << 20) 2295614e71bSYork Sun 2305614e71bSYork Sun /* XXX: Some implementation only have 1 bit starting at left */ 2315614e71bSYork Sun | ((odt_wr_cfg & 0x7) << 16) 2325614e71bSYork Sun 2335614e71bSYork Sun | ((ba_bits_cs_n & 0x3) << 14) 2345614e71bSYork Sun | ((row_bits_cs_n & 0x7) << 8) 23534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 23634e026f9SYork Sun | ((bg_bits_cs_n & 0x3) << 4) 23734e026f9SYork Sun #endif 2385614e71bSYork Sun | ((col_bits_cs_n & 0x7) << 0) 2395614e71bSYork Sun ); 2405614e71bSYork Sun debug("FSLDDR: cs[%d]_config = 0x%08x\n", i,ddr->cs[i].config); 2415614e71bSYork Sun } 2425614e71bSYork Sun 2435614e71bSYork Sun /* Chip Select Configuration 2 (CSn_CONFIG_2) */ 2445614e71bSYork Sun /* FIXME: 8572 */ 2455614e71bSYork Sun static void set_csn_config_2(int i, fsl_ddr_cfg_regs_t *ddr) 2465614e71bSYork Sun { 2475614e71bSYork Sun unsigned int pasr_cfg = 0; /* Partial array self refresh config */ 2485614e71bSYork Sun 2495614e71bSYork Sun ddr->cs[i].config_2 = ((pasr_cfg & 7) << 24); 2505614e71bSYork Sun debug("FSLDDR: cs[%d]_config_2 = 0x%08x\n", i, ddr->cs[i].config_2); 2515614e71bSYork Sun } 2525614e71bSYork Sun 2535614e71bSYork Sun /* -3E = 667 CL5, -25 = CL6 800, -25E = CL5 800 */ 2545614e71bSYork Sun 2555614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1) 2565614e71bSYork Sun static inline int avoid_odt_overlap(const dimm_params_t *dimm_params) 2575614e71bSYork Sun { 2585614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 1 2595614e71bSYork Sun if (dimm_params[0].n_ranks == 4) 2605614e71bSYork Sun return 1; 2615614e71bSYork Sun #endif 2625614e71bSYork Sun 2635614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 2 2645614e71bSYork Sun if ((dimm_params[0].n_ranks == 2) && 2655614e71bSYork Sun (dimm_params[1].n_ranks == 2)) 2665614e71bSYork Sun return 1; 2675614e71bSYork Sun 2685614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE 2695614e71bSYork Sun if (dimm_params[0].n_ranks == 4) 2705614e71bSYork Sun return 1; 2715614e71bSYork Sun #endif 2725614e71bSYork Sun #endif 2735614e71bSYork Sun return 0; 2745614e71bSYork Sun } 2755614e71bSYork Sun 2765614e71bSYork Sun /* 2775614e71bSYork Sun * DDR SDRAM Timing Configuration 0 (TIMING_CFG_0) 2785614e71bSYork Sun * 2795614e71bSYork Sun * Avoid writing for DDR I. The new PQ38 DDR controller 2805614e71bSYork Sun * dreams up non-zero default values to be backwards compatible. 2815614e71bSYork Sun */ 2825614e71bSYork Sun static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, 2835614e71bSYork Sun const memctl_options_t *popts, 2845614e71bSYork Sun const dimm_params_t *dimm_params) 2855614e71bSYork Sun { 2865614e71bSYork Sun unsigned char trwt_mclk = 0; /* Read-to-write turnaround */ 2875614e71bSYork Sun unsigned char twrt_mclk = 0; /* Write-to-read turnaround */ 2885614e71bSYork Sun /* 7.5 ns on -3E; 0 means WL - CL + BL/2 + 1 */ 2895614e71bSYork Sun unsigned char trrt_mclk = 0; /* Read-to-read turnaround */ 2905614e71bSYork Sun unsigned char twwt_mclk = 0; /* Write-to-write turnaround */ 2915614e71bSYork Sun 2925614e71bSYork Sun /* Active powerdown exit timing (tXARD and tXARDS). */ 2935614e71bSYork Sun unsigned char act_pd_exit_mclk; 2945614e71bSYork Sun /* Precharge powerdown exit timing (tXP). */ 2955614e71bSYork Sun unsigned char pre_pd_exit_mclk; 2965614e71bSYork Sun /* ODT powerdown exit timing (tAXPD). */ 29734e026f9SYork Sun unsigned char taxpd_mclk = 0; 2985614e71bSYork Sun /* Mode register set cycle time (tMRD). */ 2995614e71bSYork Sun unsigned char tmrd_mclk; 300bb578322SYork Sun #if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3) 301bb578322SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(); 302bb578322SYork Sun #endif 3035614e71bSYork Sun 30434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 30534e026f9SYork Sun /* tXP=max(4nCK, 6ns) */ 306bb578322SYork Sun int txp = max(mclk_ps * 4, 6000); /* unit=ps */ 30734e026f9SYork Sun trwt_mclk = 2; 30834e026f9SYork Sun twrt_mclk = 1; 30934e026f9SYork Sun act_pd_exit_mclk = picos_to_mclk(txp); 31034e026f9SYork Sun pre_pd_exit_mclk = act_pd_exit_mclk; 31134e026f9SYork Sun /* 31234e026f9SYork Sun * MRS_CYC = max(tMRD, tMOD) 31334e026f9SYork Sun * tMRD = 8nCK, tMOD = max(24nCK, 15ns) 31434e026f9SYork Sun */ 31534e026f9SYork Sun tmrd_mclk = max(24, picos_to_mclk(15000)); 31634e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 317bb578322SYork Sun unsigned int data_rate = get_ddr_freq(0); 318bb578322SYork Sun int txp; 3195614e71bSYork Sun /* 3205614e71bSYork Sun * (tXARD and tXARDS). Empirical? 3215614e71bSYork Sun * The DDR3 spec has not tXARD, 3225614e71bSYork Sun * we use the tXP instead of it. 323bb578322SYork Sun * tXP=max(3nCK, 7.5ns) for DDR3-800, 1066 324bb578322SYork Sun * max(3nCK, 6ns) for DDR3-1333, 1600, 1866, 2133 3255614e71bSYork Sun * spec has not the tAXPD, we use 3265614e71bSYork Sun * tAXPD=1, need design to confirm. 3275614e71bSYork Sun */ 328bb578322SYork Sun txp = max(mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000)); 329bb578322SYork Sun 3305614e71bSYork Sun tmrd_mclk = 4; 3315614e71bSYork Sun /* set the turnaround time */ 3325614e71bSYork Sun 3335614e71bSYork Sun /* 3345614e71bSYork Sun * for single quad-rank DIMM and two dual-rank DIMMs 3355614e71bSYork Sun * to avoid ODT overlap 3365614e71bSYork Sun */ 3375614e71bSYork Sun if (avoid_odt_overlap(dimm_params)) { 3385614e71bSYork Sun twwt_mclk = 2; 3395614e71bSYork Sun trrt_mclk = 1; 3405614e71bSYork Sun } 3415614e71bSYork Sun /* for faster clock, need more time for data setup */ 3425614e71bSYork Sun trwt_mclk = (data_rate/1000000 > 1800) ? 2 : 1; 3435614e71bSYork Sun 3445614e71bSYork Sun if ((data_rate/1000000 > 1150) || (popts->memctl_interleaving)) 3455614e71bSYork Sun twrt_mclk = 1; 3465614e71bSYork Sun 3475614e71bSYork Sun if (popts->dynamic_power == 0) { /* powerdown is not used */ 3485614e71bSYork Sun act_pd_exit_mclk = 1; 3495614e71bSYork Sun pre_pd_exit_mclk = 1; 3505614e71bSYork Sun taxpd_mclk = 1; 3515614e71bSYork Sun } else { 3525614e71bSYork Sun /* act_pd_exit_mclk = tXARD, see above */ 35334e026f9SYork Sun act_pd_exit_mclk = picos_to_mclk(txp); 3545614e71bSYork Sun /* Mode register MR0[A12] is '1' - fast exit */ 3555614e71bSYork Sun pre_pd_exit_mclk = act_pd_exit_mclk; 3565614e71bSYork Sun taxpd_mclk = 1; 3575614e71bSYork Sun } 3585614e71bSYork Sun #else /* CONFIG_SYS_FSL_DDR2 */ 3595614e71bSYork Sun /* 3605614e71bSYork Sun * (tXARD and tXARDS). Empirical? 3615614e71bSYork Sun * tXARD = 2 for DDR2 3625614e71bSYork Sun * tXP=2 3635614e71bSYork Sun * tAXPD=8 3645614e71bSYork Sun */ 3655614e71bSYork Sun act_pd_exit_mclk = 2; 3665614e71bSYork Sun pre_pd_exit_mclk = 2; 3675614e71bSYork Sun taxpd_mclk = 8; 3685614e71bSYork Sun tmrd_mclk = 2; 3695614e71bSYork Sun #endif 3705614e71bSYork Sun 3715614e71bSYork Sun if (popts->trwt_override) 3725614e71bSYork Sun trwt_mclk = popts->trwt; 3735614e71bSYork Sun 3745614e71bSYork Sun ddr->timing_cfg_0 = (0 3755614e71bSYork Sun | ((trwt_mclk & 0x3) << 30) /* RWT */ 3765614e71bSYork Sun | ((twrt_mclk & 0x3) << 28) /* WRT */ 3775614e71bSYork Sun | ((trrt_mclk & 0x3) << 26) /* RRT */ 3785614e71bSYork Sun | ((twwt_mclk & 0x3) << 24) /* WWT */ 379d4263b8aSYork Sun | ((act_pd_exit_mclk & 0xf) << 20) /* ACT_PD_EXIT */ 3805614e71bSYork Sun | ((pre_pd_exit_mclk & 0xF) << 16) /* PRE_PD_EXIT */ 3815614e71bSYork Sun | ((taxpd_mclk & 0xf) << 8) /* ODT_PD_EXIT */ 382d4263b8aSYork Sun | ((tmrd_mclk & 0x1f) << 0) /* MRS_CYC */ 3835614e71bSYork Sun ); 3845614e71bSYork Sun debug("FSLDDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0); 3855614e71bSYork Sun } 3865614e71bSYork Sun #endif /* defined(CONFIG_SYS_FSL_DDR2) */ 3875614e71bSYork Sun 3885614e71bSYork Sun /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ 3895614e71bSYork Sun static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr, 3905614e71bSYork Sun const memctl_options_t *popts, 3915614e71bSYork Sun const common_timing_params_t *common_dimm, 392d4263b8aSYork Sun unsigned int cas_latency, 393d4263b8aSYork Sun unsigned int additive_latency) 3945614e71bSYork Sun { 3955614e71bSYork Sun /* Extended precharge to activate interval (tRP) */ 3965614e71bSYork Sun unsigned int ext_pretoact = 0; 3975614e71bSYork Sun /* Extended Activate to precharge interval (tRAS) */ 3985614e71bSYork Sun unsigned int ext_acttopre = 0; 3995614e71bSYork Sun /* Extended activate to read/write interval (tRCD) */ 4005614e71bSYork Sun unsigned int ext_acttorw = 0; 4015614e71bSYork Sun /* Extended refresh recovery time (tRFC) */ 4025614e71bSYork Sun unsigned int ext_refrec; 4035614e71bSYork Sun /* Extended MCAS latency from READ cmd */ 4045614e71bSYork Sun unsigned int ext_caslat = 0; 405d4263b8aSYork Sun /* Extended additive latency */ 406d4263b8aSYork Sun unsigned int ext_add_lat = 0; 4075614e71bSYork Sun /* Extended last data to precharge interval (tWR) */ 4085614e71bSYork Sun unsigned int ext_wrrec = 0; 4095614e71bSYork Sun /* Control Adjust */ 4105614e71bSYork Sun unsigned int cntl_adj = 0; 4115614e71bSYork Sun 4125614e71bSYork Sun ext_pretoact = picos_to_mclk(common_dimm->trp_ps) >> 4; 4135614e71bSYork Sun ext_acttopre = picos_to_mclk(common_dimm->tras_ps) >> 4; 4145614e71bSYork Sun ext_acttorw = picos_to_mclk(common_dimm->trcd_ps) >> 4; 4155614e71bSYork Sun ext_caslat = (2 * cas_latency - 1) >> 4; 416d4263b8aSYork Sun ext_add_lat = additive_latency >> 4; 41734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 41834e026f9SYork Sun ext_refrec = (picos_to_mclk(common_dimm->trfc1_ps) - 8) >> 4; 41934e026f9SYork Sun #else 4205614e71bSYork Sun ext_refrec = (picos_to_mclk(common_dimm->trfc_ps) - 8) >> 4; 4215614e71bSYork Sun /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ 42234e026f9SYork Sun #endif 4235614e71bSYork Sun ext_wrrec = (picos_to_mclk(common_dimm->twr_ps) + 4245614e71bSYork Sun (popts->otf_burst_chop_en ? 2 : 0)) >> 4; 4255614e71bSYork Sun 4265614e71bSYork Sun ddr->timing_cfg_3 = (0 4275614e71bSYork Sun | ((ext_pretoact & 0x1) << 28) 4285614e71bSYork Sun | ((ext_acttopre & 0x3) << 24) 4295614e71bSYork Sun | ((ext_acttorw & 0x1) << 22) 4305614e71bSYork Sun | ((ext_refrec & 0x1F) << 16) 4315614e71bSYork Sun | ((ext_caslat & 0x3) << 12) 432d4263b8aSYork Sun | ((ext_add_lat & 0x1) << 10) 4335614e71bSYork Sun | ((ext_wrrec & 0x1) << 8) 4345614e71bSYork Sun | ((cntl_adj & 0x7) << 0) 4355614e71bSYork Sun ); 4365614e71bSYork Sun debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3); 4375614e71bSYork Sun } 4385614e71bSYork Sun 4395614e71bSYork Sun /* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */ 4405614e71bSYork Sun static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, 4415614e71bSYork Sun const memctl_options_t *popts, 4425614e71bSYork Sun const common_timing_params_t *common_dimm, 4435614e71bSYork Sun unsigned int cas_latency) 4445614e71bSYork Sun { 4455614e71bSYork Sun /* Precharge-to-activate interval (tRP) */ 4465614e71bSYork Sun unsigned char pretoact_mclk; 4475614e71bSYork Sun /* Activate to precharge interval (tRAS) */ 4485614e71bSYork Sun unsigned char acttopre_mclk; 4495614e71bSYork Sun /* Activate to read/write interval (tRCD) */ 4505614e71bSYork Sun unsigned char acttorw_mclk; 4515614e71bSYork Sun /* CASLAT */ 4525614e71bSYork Sun unsigned char caslat_ctrl; 4535614e71bSYork Sun /* Refresh recovery time (tRFC) ; trfc_low */ 4545614e71bSYork Sun unsigned char refrec_ctrl; 4555614e71bSYork Sun /* Last data to precharge minimum interval (tWR) */ 4565614e71bSYork Sun unsigned char wrrec_mclk; 4575614e71bSYork Sun /* Activate-to-activate interval (tRRD) */ 4585614e71bSYork Sun unsigned char acttoact_mclk; 4595614e71bSYork Sun /* Last write data pair to read command issue interval (tWTR) */ 4605614e71bSYork Sun unsigned char wrtord_mclk; 46134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 46234e026f9SYork Sun /* DDR4 supports 10, 12, 14, 16, 18, 20, 24 */ 46334e026f9SYork Sun static const u8 wrrec_table[] = { 46434e026f9SYork Sun 10, 10, 10, 10, 10, 46534e026f9SYork Sun 10, 10, 10, 10, 10, 46634e026f9SYork Sun 12, 12, 14, 14, 16, 46734e026f9SYork Sun 16, 18, 18, 20, 20, 46834e026f9SYork Sun 24, 24, 24, 24}; 46934e026f9SYork Sun #else 4705614e71bSYork Sun /* DDR_SDRAM_MODE doesn't support 9,11,13,15 */ 4715614e71bSYork Sun static const u8 wrrec_table[] = { 4725614e71bSYork Sun 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0}; 47334e026f9SYork Sun #endif 4745614e71bSYork Sun 4755614e71bSYork Sun pretoact_mclk = picos_to_mclk(common_dimm->trp_ps); 4765614e71bSYork Sun acttopre_mclk = picos_to_mclk(common_dimm->tras_ps); 4775614e71bSYork Sun acttorw_mclk = picos_to_mclk(common_dimm->trcd_ps); 4785614e71bSYork Sun 4795614e71bSYork Sun /* 4805614e71bSYork Sun * Translate CAS Latency to a DDR controller field value: 4815614e71bSYork Sun * 4825614e71bSYork Sun * CAS Lat DDR I DDR II Ctrl 4835614e71bSYork Sun * Clocks SPD Bit SPD Bit Value 4845614e71bSYork Sun * ------- ------- ------- ----- 4855614e71bSYork Sun * 1.0 0 0001 4865614e71bSYork Sun * 1.5 1 0010 4875614e71bSYork Sun * 2.0 2 2 0011 4885614e71bSYork Sun * 2.5 3 0100 4895614e71bSYork Sun * 3.0 4 3 0101 4905614e71bSYork Sun * 3.5 5 0110 4915614e71bSYork Sun * 4.0 4 0111 4925614e71bSYork Sun * 4.5 1000 4935614e71bSYork Sun * 5.0 5 1001 4945614e71bSYork Sun */ 4955614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 4965614e71bSYork Sun caslat_ctrl = (cas_latency + 1) & 0x07; 4975614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 4985614e71bSYork Sun caslat_ctrl = 2 * cas_latency - 1; 4995614e71bSYork Sun #else 5005614e71bSYork Sun /* 5015614e71bSYork Sun * if the CAS latency more than 8 cycle, 5025614e71bSYork Sun * we need set extend bit for it at 5035614e71bSYork Sun * TIMING_CFG_3[EXT_CASLAT] 5045614e71bSYork Sun */ 50534e026f9SYork Sun if (fsl_ddr_get_version() <= 0x40400) 5065614e71bSYork Sun caslat_ctrl = 2 * cas_latency - 1; 50734e026f9SYork Sun else 50834e026f9SYork Sun caslat_ctrl = (cas_latency - 1) << 1; 5095614e71bSYork Sun #endif 5105614e71bSYork Sun 51134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 51234e026f9SYork Sun refrec_ctrl = picos_to_mclk(common_dimm->trfc1_ps) - 8; 51334e026f9SYork Sun wrrec_mclk = picos_to_mclk(common_dimm->twr_ps); 51434e026f9SYork Sun acttoact_mclk = max(picos_to_mclk(common_dimm->trrds_ps), 4); 51534e026f9SYork Sun wrtord_mclk = max(2, picos_to_mclk(2500)); 516349689b8SYork Sun if ((wrrec_mclk < 1) || (wrrec_mclk > 24)) 517349689b8SYork Sun printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); 51834e026f9SYork Sun else 51934e026f9SYork Sun wrrec_mclk = wrrec_table[wrrec_mclk - 1]; 52034e026f9SYork Sun #else 5215614e71bSYork Sun refrec_ctrl = picos_to_mclk(common_dimm->trfc_ps) - 8; 5225614e71bSYork Sun wrrec_mclk = picos_to_mclk(common_dimm->twr_ps); 52334e026f9SYork Sun acttoact_mclk = picos_to_mclk(common_dimm->trrd_ps); 52434e026f9SYork Sun wrtord_mclk = picos_to_mclk(common_dimm->twtr_ps); 525349689b8SYork Sun if ((wrrec_mclk < 1) || (wrrec_mclk > 16)) 526349689b8SYork Sun printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); 5275614e71bSYork Sun else 5285614e71bSYork Sun wrrec_mclk = wrrec_table[wrrec_mclk - 1]; 52934e026f9SYork Sun #endif 5305614e71bSYork Sun if (popts->otf_burst_chop_en) 5315614e71bSYork Sun wrrec_mclk += 2; 5325614e71bSYork Sun 5335614e71bSYork Sun /* 5345614e71bSYork Sun * JEDEC has min requirement for tRRD 5355614e71bSYork Sun */ 5365614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR3) 5375614e71bSYork Sun if (acttoact_mclk < 4) 5385614e71bSYork Sun acttoact_mclk = 4; 5395614e71bSYork Sun #endif 5405614e71bSYork Sun /* 5415614e71bSYork Sun * JEDEC has some min requirements for tWTR 5425614e71bSYork Sun */ 5435614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2) 5445614e71bSYork Sun if (wrtord_mclk < 2) 5455614e71bSYork Sun wrtord_mclk = 2; 5465614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 5475614e71bSYork Sun if (wrtord_mclk < 4) 5485614e71bSYork Sun wrtord_mclk = 4; 5495614e71bSYork Sun #endif 5505614e71bSYork Sun if (popts->otf_burst_chop_en) 5515614e71bSYork Sun wrtord_mclk += 2; 5525614e71bSYork Sun 5535614e71bSYork Sun ddr->timing_cfg_1 = (0 5545614e71bSYork Sun | ((pretoact_mclk & 0x0F) << 28) 5555614e71bSYork Sun | ((acttopre_mclk & 0x0F) << 24) 5565614e71bSYork Sun | ((acttorw_mclk & 0xF) << 20) 5575614e71bSYork Sun | ((caslat_ctrl & 0xF) << 16) 5585614e71bSYork Sun | ((refrec_ctrl & 0xF) << 12) 5595614e71bSYork Sun | ((wrrec_mclk & 0x0F) << 8) 5605614e71bSYork Sun | ((acttoact_mclk & 0x0F) << 4) 5615614e71bSYork Sun | ((wrtord_mclk & 0x0F) << 0) 5625614e71bSYork Sun ); 5635614e71bSYork Sun debug("FSLDDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1); 5645614e71bSYork Sun } 5655614e71bSYork Sun 5665614e71bSYork Sun /* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */ 5675614e71bSYork Sun static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr, 5685614e71bSYork Sun const memctl_options_t *popts, 5695614e71bSYork Sun const common_timing_params_t *common_dimm, 5705614e71bSYork Sun unsigned int cas_latency, 5715614e71bSYork Sun unsigned int additive_latency) 5725614e71bSYork Sun { 5735614e71bSYork Sun /* Additive latency */ 5745614e71bSYork Sun unsigned char add_lat_mclk; 5755614e71bSYork Sun /* CAS-to-preamble override */ 5765614e71bSYork Sun unsigned short cpo; 5775614e71bSYork Sun /* Write latency */ 5785614e71bSYork Sun unsigned char wr_lat; 5795614e71bSYork Sun /* Read to precharge (tRTP) */ 5805614e71bSYork Sun unsigned char rd_to_pre; 5815614e71bSYork Sun /* Write command to write data strobe timing adjustment */ 5825614e71bSYork Sun unsigned char wr_data_delay; 5835614e71bSYork Sun /* Minimum CKE pulse width (tCKE) */ 5845614e71bSYork Sun unsigned char cke_pls; 5855614e71bSYork Sun /* Window for four activates (tFAW) */ 5865614e71bSYork Sun unsigned short four_act; 587bb578322SYork Sun #ifdef CONFIG_SYS_FSL_DDR3 588bb578322SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(); 589bb578322SYork Sun #endif 5905614e71bSYork Sun 5915614e71bSYork Sun /* FIXME add check that this must be less than acttorw_mclk */ 5925614e71bSYork Sun add_lat_mclk = additive_latency; 5935614e71bSYork Sun cpo = popts->cpo_override; 5945614e71bSYork Sun 5955614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 5965614e71bSYork Sun /* 5975614e71bSYork Sun * This is a lie. It should really be 1, but if it is 5985614e71bSYork Sun * set to 1, bits overlap into the old controller's 5995614e71bSYork Sun * otherwise unused ACSM field. If we leave it 0, then 6005614e71bSYork Sun * the HW will magically treat it as 1 for DDR 1. Oh Yea. 6015614e71bSYork Sun */ 6025614e71bSYork Sun wr_lat = 0; 6035614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 6045614e71bSYork Sun wr_lat = cas_latency - 1; 6055614e71bSYork Sun #else 6065614e71bSYork Sun wr_lat = compute_cas_write_latency(); 6075614e71bSYork Sun #endif 6085614e71bSYork Sun 60934e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 61034e026f9SYork Sun rd_to_pre = picos_to_mclk(7500); 61134e026f9SYork Sun #else 6125614e71bSYork Sun rd_to_pre = picos_to_mclk(common_dimm->trtp_ps); 61334e026f9SYork Sun #endif 6145614e71bSYork Sun /* 6155614e71bSYork Sun * JEDEC has some min requirements for tRTP 6165614e71bSYork Sun */ 6175614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2) 6185614e71bSYork Sun if (rd_to_pre < 2) 6195614e71bSYork Sun rd_to_pre = 2; 62034e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 6215614e71bSYork Sun if (rd_to_pre < 4) 6225614e71bSYork Sun rd_to_pre = 4; 6235614e71bSYork Sun #endif 6245614e71bSYork Sun if (popts->otf_burst_chop_en) 6255614e71bSYork Sun rd_to_pre += 2; /* according to UM */ 6265614e71bSYork Sun 6275614e71bSYork Sun wr_data_delay = popts->write_data_delay; 62834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 62934e026f9SYork Sun cpo = 0; 63034e026f9SYork Sun cke_pls = max(3, picos_to_mclk(5000)); 631bb578322SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 632bb578322SYork Sun /* 633bb578322SYork Sun * cke pulse = max(3nCK, 7.5ns) for DDR3-800 634bb578322SYork Sun * max(3nCK, 5.625ns) for DDR3-1066, 1333 635bb578322SYork Sun * max(3nCK, 5ns) for DDR3-1600, 1866, 2133 636bb578322SYork Sun */ 637bb578322SYork Sun cke_pls = max(3, picos_to_mclk(mclk_ps > 1870 ? 7500 : 638bb578322SYork Sun (mclk_ps > 1245 ? 5625 : 5000))); 63934e026f9SYork Sun #else 640bb578322SYork Sun cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR; 64134e026f9SYork Sun #endif 6425614e71bSYork Sun four_act = picos_to_mclk(popts->tfaw_window_four_activates_ps); 6435614e71bSYork Sun 6445614e71bSYork Sun ddr->timing_cfg_2 = (0 6455614e71bSYork Sun | ((add_lat_mclk & 0xf) << 28) 6465614e71bSYork Sun | ((cpo & 0x1f) << 23) 6475614e71bSYork Sun | ((wr_lat & 0xf) << 19) 64834e026f9SYork Sun | ((wr_lat & 0x10) << 14) 6495614e71bSYork Sun | ((rd_to_pre & RD_TO_PRE_MASK) << RD_TO_PRE_SHIFT) 6505614e71bSYork Sun | ((wr_data_delay & WR_DATA_DELAY_MASK) << WR_DATA_DELAY_SHIFT) 6515614e71bSYork Sun | ((cke_pls & 0x7) << 6) 6525614e71bSYork Sun | ((four_act & 0x3f) << 0) 6535614e71bSYork Sun ); 6545614e71bSYork Sun debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2); 6555614e71bSYork Sun } 6565614e71bSYork Sun 6575614e71bSYork Sun /* DDR SDRAM Register Control Word */ 6585614e71bSYork Sun static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, 6595614e71bSYork Sun const memctl_options_t *popts, 6605614e71bSYork Sun const common_timing_params_t *common_dimm) 6615614e71bSYork Sun { 6625614e71bSYork Sun if (common_dimm->all_dimms_registered && 6635614e71bSYork Sun !common_dimm->all_dimms_unbuffered) { 6645614e71bSYork Sun if (popts->rcw_override) { 6655614e71bSYork Sun ddr->ddr_sdram_rcw_1 = popts->rcw_1; 6665614e71bSYork Sun ddr->ddr_sdram_rcw_2 = popts->rcw_2; 6675614e71bSYork Sun } else { 6685614e71bSYork Sun ddr->ddr_sdram_rcw_1 = 6695614e71bSYork Sun common_dimm->rcw[0] << 28 | \ 6705614e71bSYork Sun common_dimm->rcw[1] << 24 | \ 6715614e71bSYork Sun common_dimm->rcw[2] << 20 | \ 6725614e71bSYork Sun common_dimm->rcw[3] << 16 | \ 6735614e71bSYork Sun common_dimm->rcw[4] << 12 | \ 6745614e71bSYork Sun common_dimm->rcw[5] << 8 | \ 6755614e71bSYork Sun common_dimm->rcw[6] << 4 | \ 6765614e71bSYork Sun common_dimm->rcw[7]; 6775614e71bSYork Sun ddr->ddr_sdram_rcw_2 = 6785614e71bSYork Sun common_dimm->rcw[8] << 28 | \ 6795614e71bSYork Sun common_dimm->rcw[9] << 24 | \ 6805614e71bSYork Sun common_dimm->rcw[10] << 20 | \ 6815614e71bSYork Sun common_dimm->rcw[11] << 16 | \ 6825614e71bSYork Sun common_dimm->rcw[12] << 12 | \ 6835614e71bSYork Sun common_dimm->rcw[13] << 8 | \ 6845614e71bSYork Sun common_dimm->rcw[14] << 4 | \ 6855614e71bSYork Sun common_dimm->rcw[15]; 6865614e71bSYork Sun } 6875614e71bSYork Sun debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1); 6885614e71bSYork Sun debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2); 6895614e71bSYork Sun } 6905614e71bSYork Sun } 6915614e71bSYork Sun 6925614e71bSYork Sun /* DDR SDRAM control configuration (DDR_SDRAM_CFG) */ 6935614e71bSYork Sun static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, 6945614e71bSYork Sun const memctl_options_t *popts, 6955614e71bSYork Sun const common_timing_params_t *common_dimm) 6965614e71bSYork Sun { 6975614e71bSYork Sun unsigned int mem_en; /* DDR SDRAM interface logic enable */ 6985614e71bSYork Sun unsigned int sren; /* Self refresh enable (during sleep) */ 6995614e71bSYork Sun unsigned int ecc_en; /* ECC enable. */ 7005614e71bSYork Sun unsigned int rd_en; /* Registered DIMM enable */ 7015614e71bSYork Sun unsigned int sdram_type; /* Type of SDRAM */ 7025614e71bSYork Sun unsigned int dyn_pwr; /* Dynamic power management mode */ 7035614e71bSYork Sun unsigned int dbw; /* DRAM dta bus width */ 7045614e71bSYork Sun unsigned int eight_be = 0; /* 8-beat burst enable, DDR2 is zero */ 7055614e71bSYork Sun unsigned int ncap = 0; /* Non-concurrent auto-precharge */ 7065614e71bSYork Sun unsigned int threet_en; /* Enable 3T timing */ 7075614e71bSYork Sun unsigned int twot_en; /* Enable 2T timing */ 7085614e71bSYork Sun unsigned int ba_intlv_ctl; /* Bank (CS) interleaving control */ 7095614e71bSYork Sun unsigned int x32_en = 0; /* x32 enable */ 7105614e71bSYork Sun unsigned int pchb8 = 0; /* precharge bit 8 enable */ 7115614e71bSYork Sun unsigned int hse; /* Global half strength override */ 712d28cb671SYork Sun unsigned int acc_ecc_en = 0; /* Accumulated ECC enable */ 7135614e71bSYork Sun unsigned int mem_halt = 0; /* memory controller halt */ 7145614e71bSYork Sun unsigned int bi = 0; /* Bypass initialization */ 7155614e71bSYork Sun 7165614e71bSYork Sun mem_en = 1; 7175614e71bSYork Sun sren = popts->self_refresh_in_sleep; 7185614e71bSYork Sun if (common_dimm->all_dimms_ecc_capable) { 7195614e71bSYork Sun /* Allow setting of ECC only if all DIMMs are ECC. */ 7205614e71bSYork Sun ecc_en = popts->ecc_mode; 7215614e71bSYork Sun } else { 7225614e71bSYork Sun ecc_en = 0; 7235614e71bSYork Sun } 7245614e71bSYork Sun 7255614e71bSYork Sun if (common_dimm->all_dimms_registered && 7265614e71bSYork Sun !common_dimm->all_dimms_unbuffered) { 7275614e71bSYork Sun rd_en = 1; 7285614e71bSYork Sun twot_en = 0; 7295614e71bSYork Sun } else { 7305614e71bSYork Sun rd_en = 0; 7315614e71bSYork Sun twot_en = popts->twot_en; 7325614e71bSYork Sun } 7335614e71bSYork Sun 7345614e71bSYork Sun sdram_type = CONFIG_FSL_SDRAM_TYPE; 7355614e71bSYork Sun 7365614e71bSYork Sun dyn_pwr = popts->dynamic_power; 7375614e71bSYork Sun dbw = popts->data_bus_width; 7385614e71bSYork Sun /* 8-beat burst enable DDR-III case 7395614e71bSYork Sun * we must clear it when use the on-the-fly mode, 7405614e71bSYork Sun * must set it when use the 32-bits bus mode. 7415614e71bSYork Sun */ 74234e026f9SYork Sun if ((sdram_type == SDRAM_TYPE_DDR3) || 74334e026f9SYork Sun (sdram_type == SDRAM_TYPE_DDR4)) { 7445614e71bSYork Sun if (popts->burst_length == DDR_BL8) 7455614e71bSYork Sun eight_be = 1; 7465614e71bSYork Sun if (popts->burst_length == DDR_OTF) 7475614e71bSYork Sun eight_be = 0; 7485614e71bSYork Sun if (dbw == 0x1) 7495614e71bSYork Sun eight_be = 1; 7505614e71bSYork Sun } 7515614e71bSYork Sun 7525614e71bSYork Sun threet_en = popts->threet_en; 7535614e71bSYork Sun ba_intlv_ctl = popts->ba_intlv_ctl; 7545614e71bSYork Sun hse = popts->half_strength_driver_enable; 7555614e71bSYork Sun 756d28cb671SYork Sun /* set when ddr bus width < 64 */ 757d28cb671SYork Sun acc_ecc_en = (dbw != 0 && ecc_en == 1) ? 1 : 0; 758d28cb671SYork Sun 7595614e71bSYork Sun ddr->ddr_sdram_cfg = (0 7605614e71bSYork Sun | ((mem_en & 0x1) << 31) 7615614e71bSYork Sun | ((sren & 0x1) << 30) 7625614e71bSYork Sun | ((ecc_en & 0x1) << 29) 7635614e71bSYork Sun | ((rd_en & 0x1) << 28) 7645614e71bSYork Sun | ((sdram_type & 0x7) << 24) 7655614e71bSYork Sun | ((dyn_pwr & 0x1) << 21) 7665614e71bSYork Sun | ((dbw & 0x3) << 19) 7675614e71bSYork Sun | ((eight_be & 0x1) << 18) 7685614e71bSYork Sun | ((ncap & 0x1) << 17) 7695614e71bSYork Sun | ((threet_en & 0x1) << 16) 7705614e71bSYork Sun | ((twot_en & 0x1) << 15) 7715614e71bSYork Sun | ((ba_intlv_ctl & 0x7F) << 8) 7725614e71bSYork Sun | ((x32_en & 0x1) << 5) 7735614e71bSYork Sun | ((pchb8 & 0x1) << 4) 7745614e71bSYork Sun | ((hse & 0x1) << 3) 775d28cb671SYork Sun | ((acc_ecc_en & 0x1) << 2) 7765614e71bSYork Sun | ((mem_halt & 0x1) << 1) 7775614e71bSYork Sun | ((bi & 0x1) << 0) 7785614e71bSYork Sun ); 7795614e71bSYork Sun debug("FSLDDR: ddr_sdram_cfg = 0x%08x\n", ddr->ddr_sdram_cfg); 7805614e71bSYork Sun } 7815614e71bSYork Sun 7825614e71bSYork Sun /* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */ 7835614e71bSYork Sun static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, 7845614e71bSYork Sun const memctl_options_t *popts, 7855614e71bSYork Sun const unsigned int unq_mrs_en) 7865614e71bSYork Sun { 7875614e71bSYork Sun unsigned int frc_sr = 0; /* Force self refresh */ 7885614e71bSYork Sun unsigned int sr_ie = 0; /* Self-refresh interrupt enable */ 7895614e71bSYork Sun unsigned int odt_cfg = 0; /* ODT configuration */ 7905614e71bSYork Sun unsigned int num_pr; /* Number of posted refreshes */ 7915614e71bSYork Sun unsigned int slow = 0; /* DDR will be run less than 1250 */ 7925614e71bSYork Sun unsigned int x4_en = 0; /* x4 DRAM enable */ 7935614e71bSYork Sun unsigned int obc_cfg; /* On-The-Fly Burst Chop Cfg */ 7945614e71bSYork Sun unsigned int ap_en; /* Address Parity Enable */ 7955614e71bSYork Sun unsigned int d_init; /* DRAM data initialization */ 7965614e71bSYork Sun unsigned int rcw_en = 0; /* Register Control Word Enable */ 7975614e71bSYork Sun unsigned int md_en = 0; /* Mirrored DIMM Enable */ 7985614e71bSYork Sun unsigned int qd_en = 0; /* quad-rank DIMM Enable */ 7995614e71bSYork Sun int i; 80034e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4 80134e026f9SYork Sun unsigned int dll_rst_dis = 1; /* DLL reset disable */ 80234e026f9SYork Sun unsigned int dqs_cfg; /* DQS configuration */ 8035614e71bSYork Sun 8045614e71bSYork Sun dqs_cfg = popts->dqs_config; 80534e026f9SYork Sun #endif 8065614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 8075614e71bSYork Sun if (popts->cs_local_opts[i].odt_rd_cfg 8085614e71bSYork Sun || popts->cs_local_opts[i].odt_wr_cfg) { 8095614e71bSYork Sun odt_cfg = SDRAM_CFG2_ODT_ONLY_READ; 8105614e71bSYork Sun break; 8115614e71bSYork Sun } 8125614e71bSYork Sun } 8135614e71bSYork Sun 8145614e71bSYork Sun num_pr = 1; /* Make this configurable */ 8155614e71bSYork Sun 8165614e71bSYork Sun /* 8175614e71bSYork Sun * 8572 manual says 8185614e71bSYork Sun * {TIMING_CFG_1[PRETOACT] 8195614e71bSYork Sun * + [DDR_SDRAM_CFG_2[NUM_PR] 8205614e71bSYork Sun * * ({EXT_REFREC || REFREC} + 8 + 2)]} 8215614e71bSYork Sun * << DDR_SDRAM_INTERVAL[REFINT] 8225614e71bSYork Sun */ 82334e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 8245614e71bSYork Sun obc_cfg = popts->otf_burst_chop_en; 8255614e71bSYork Sun #else 8265614e71bSYork Sun obc_cfg = 0; 8275614e71bSYork Sun #endif 8285614e71bSYork Sun 8295614e71bSYork Sun #if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7) 8305614e71bSYork Sun slow = get_ddr_freq(0) < 1249000000; 8315614e71bSYork Sun #endif 8325614e71bSYork Sun 8335614e71bSYork Sun if (popts->registered_dimm_en) { 8345614e71bSYork Sun rcw_en = 1; 8355614e71bSYork Sun ap_en = popts->ap_en; 8365614e71bSYork Sun } else { 8375614e71bSYork Sun ap_en = 0; 8385614e71bSYork Sun } 8395614e71bSYork Sun 8405614e71bSYork Sun x4_en = popts->x4_en ? 1 : 0; 8415614e71bSYork Sun 8425614e71bSYork Sun #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) 8435614e71bSYork Sun /* Use the DDR controller to auto initialize memory. */ 8445614e71bSYork Sun d_init = popts->ecc_init_using_memctl; 8455614e71bSYork Sun ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE; 8465614e71bSYork Sun debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init); 8475614e71bSYork Sun #else 8485614e71bSYork Sun /* Memory will be initialized via DMA, or not at all. */ 8495614e71bSYork Sun d_init = 0; 8505614e71bSYork Sun #endif 8515614e71bSYork Sun 85234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 8535614e71bSYork Sun md_en = popts->mirrored_dimm; 8545614e71bSYork Sun #endif 8555614e71bSYork Sun qd_en = popts->quad_rank_present ? 1 : 0; 8565614e71bSYork Sun ddr->ddr_sdram_cfg_2 = (0 8575614e71bSYork Sun | ((frc_sr & 0x1) << 31) 8585614e71bSYork Sun | ((sr_ie & 0x1) << 30) 85934e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4 8605614e71bSYork Sun | ((dll_rst_dis & 0x1) << 29) 8615614e71bSYork Sun | ((dqs_cfg & 0x3) << 26) 86234e026f9SYork Sun #endif 8635614e71bSYork Sun | ((odt_cfg & 0x3) << 21) 8645614e71bSYork Sun | ((num_pr & 0xf) << 12) 8655614e71bSYork Sun | ((slow & 1) << 11) 8665614e71bSYork Sun | (x4_en << 10) 8675614e71bSYork Sun | (qd_en << 9) 8685614e71bSYork Sun | (unq_mrs_en << 8) 8695614e71bSYork Sun | ((obc_cfg & 0x1) << 6) 8705614e71bSYork Sun | ((ap_en & 0x1) << 5) 8715614e71bSYork Sun | ((d_init & 0x1) << 4) 8725614e71bSYork Sun | ((rcw_en & 0x1) << 2) 8735614e71bSYork Sun | ((md_en & 0x1) << 0) 8745614e71bSYork Sun ); 8755614e71bSYork Sun debug("FSLDDR: ddr_sdram_cfg_2 = 0x%08x\n", ddr->ddr_sdram_cfg_2); 8765614e71bSYork Sun } 8775614e71bSYork Sun 87834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 8795614e71bSYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 8805614e71bSYork Sun static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, 8815614e71bSYork Sun const memctl_options_t *popts, 8825614e71bSYork Sun const common_timing_params_t *common_dimm, 8835614e71bSYork Sun const unsigned int unq_mrs_en) 8845614e71bSYork Sun { 8855614e71bSYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 8865614e71bSYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 8875614e71bSYork Sun int i; 88834e026f9SYork Sun unsigned int wr_crc = 0; /* Disable */ 8895614e71bSYork Sun unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ 8905614e71bSYork Sun unsigned int srt = 0; /* self-refresh temerature, normal range */ 89134e026f9SYork Sun unsigned int cwl = compute_cas_write_latency() - 9; 89234e026f9SYork Sun unsigned int mpr = 0; /* serial */ 89334e026f9SYork Sun unsigned int wc_lat; 89434e026f9SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(); 8955614e71bSYork Sun 8965614e71bSYork Sun if (popts->rtt_override) 8975614e71bSYork Sun rtt_wr = popts->rtt_wr_override_value; 8985614e71bSYork Sun else 8995614e71bSYork Sun rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; 9005614e71bSYork Sun 9015614e71bSYork Sun if (common_dimm->extended_op_srt) 9025614e71bSYork Sun srt = common_dimm->extended_op_srt; 9035614e71bSYork Sun 9045614e71bSYork Sun esdmode2 = (0 90534e026f9SYork Sun | ((wr_crc & 0x1) << 12) 9065614e71bSYork Sun | ((rtt_wr & 0x3) << 9) 90734e026f9SYork Sun | ((srt & 0x3) << 6) 90834e026f9SYork Sun | ((cwl & 0x7) << 3)); 90934e026f9SYork Sun 91034e026f9SYork Sun if (mclk_ps >= 1250) 91134e026f9SYork Sun wc_lat = 0; 91234e026f9SYork Sun else if (mclk_ps >= 833) 91334e026f9SYork Sun wc_lat = 1; 91434e026f9SYork Sun else 91534e026f9SYork Sun wc_lat = 2; 91634e026f9SYork Sun 91734e026f9SYork Sun esdmode3 = (0 91834e026f9SYork Sun | ((mpr & 0x3) << 11) 91934e026f9SYork Sun | ((wc_lat & 0x3) << 9)); 92034e026f9SYork Sun 9215614e71bSYork Sun ddr->ddr_sdram_mode_2 = (0 9225614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 9235614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 9245614e71bSYork Sun ); 9255614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 9265614e71bSYork Sun 9275614e71bSYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 9285614e71bSYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 9295614e71bSYork Sun if (popts->rtt_override) 9305614e71bSYork Sun rtt_wr = popts->rtt_wr_override_value; 9315614e71bSYork Sun else 9325614e71bSYork Sun rtt_wr = popts->cs_local_opts[i].odt_rtt_wr; 9335614e71bSYork Sun 9345614e71bSYork Sun esdmode2 &= 0xF9FF; /* clear bit 10, 9 */ 9355614e71bSYork Sun esdmode2 |= (rtt_wr & 0x3) << 9; 9365614e71bSYork Sun switch (i) { 9375614e71bSYork Sun case 1: 9385614e71bSYork Sun ddr->ddr_sdram_mode_4 = (0 9395614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 9405614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 9415614e71bSYork Sun ); 9425614e71bSYork Sun break; 9435614e71bSYork Sun case 2: 9445614e71bSYork Sun ddr->ddr_sdram_mode_6 = (0 9455614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 9465614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 9475614e71bSYork Sun ); 9485614e71bSYork Sun break; 9495614e71bSYork Sun case 3: 9505614e71bSYork Sun ddr->ddr_sdram_mode_8 = (0 9515614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 9525614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 9535614e71bSYork Sun ); 9545614e71bSYork Sun break; 9555614e71bSYork Sun } 9565614e71bSYork Sun } 9575614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", 9585614e71bSYork Sun ddr->ddr_sdram_mode_4); 9595614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", 9605614e71bSYork Sun ddr->ddr_sdram_mode_6); 9615614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", 9625614e71bSYork Sun ddr->ddr_sdram_mode_8); 9635614e71bSYork Sun } 9645614e71bSYork Sun } 96534e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 96634e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 96734e026f9SYork Sun static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, 96834e026f9SYork Sun const memctl_options_t *popts, 96934e026f9SYork Sun const common_timing_params_t *common_dimm, 97034e026f9SYork Sun const unsigned int unq_mrs_en) 97134e026f9SYork Sun { 97234e026f9SYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 97334e026f9SYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 97434e026f9SYork Sun int i; 97534e026f9SYork Sun unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ 97634e026f9SYork Sun unsigned int srt = 0; /* self-refresh temerature, normal range */ 97734e026f9SYork Sun unsigned int asr = 0; /* auto self-refresh disable */ 97834e026f9SYork Sun unsigned int cwl = compute_cas_write_latency() - 5; 97934e026f9SYork Sun unsigned int pasr = 0; /* partial array self refresh disable */ 98034e026f9SYork Sun 98134e026f9SYork Sun if (popts->rtt_override) 98234e026f9SYork Sun rtt_wr = popts->rtt_wr_override_value; 98334e026f9SYork Sun else 98434e026f9SYork Sun rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; 98534e026f9SYork Sun 98634e026f9SYork Sun if (common_dimm->extended_op_srt) 98734e026f9SYork Sun srt = common_dimm->extended_op_srt; 98834e026f9SYork Sun 98934e026f9SYork Sun esdmode2 = (0 99034e026f9SYork Sun | ((rtt_wr & 0x3) << 9) 99134e026f9SYork Sun | ((srt & 0x1) << 7) 99234e026f9SYork Sun | ((asr & 0x1) << 6) 99334e026f9SYork Sun | ((cwl & 0x7) << 3) 99434e026f9SYork Sun | ((pasr & 0x7) << 0)); 99534e026f9SYork Sun ddr->ddr_sdram_mode_2 = (0 99634e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 99734e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 99834e026f9SYork Sun ); 99934e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 100034e026f9SYork Sun 100134e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 100234e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 100334e026f9SYork Sun if (popts->rtt_override) 100434e026f9SYork Sun rtt_wr = popts->rtt_wr_override_value; 100534e026f9SYork Sun else 100634e026f9SYork Sun rtt_wr = popts->cs_local_opts[i].odt_rtt_wr; 100734e026f9SYork Sun 100834e026f9SYork Sun esdmode2 &= 0xF9FF; /* clear bit 10, 9 */ 100934e026f9SYork Sun esdmode2 |= (rtt_wr & 0x3) << 9; 101034e026f9SYork Sun switch (i) { 101134e026f9SYork Sun case 1: 101234e026f9SYork Sun ddr->ddr_sdram_mode_4 = (0 101334e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 101434e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 101534e026f9SYork Sun ); 101634e026f9SYork Sun break; 101734e026f9SYork Sun case 2: 101834e026f9SYork Sun ddr->ddr_sdram_mode_6 = (0 101934e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 102034e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 102134e026f9SYork Sun ); 102234e026f9SYork Sun break; 102334e026f9SYork Sun case 3: 102434e026f9SYork Sun ddr->ddr_sdram_mode_8 = (0 102534e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 102634e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 102734e026f9SYork Sun ); 102834e026f9SYork Sun break; 102934e026f9SYork Sun } 103034e026f9SYork Sun } 103134e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", 103234e026f9SYork Sun ddr->ddr_sdram_mode_4); 103334e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", 103434e026f9SYork Sun ddr->ddr_sdram_mode_6); 103534e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", 103634e026f9SYork Sun ddr->ddr_sdram_mode_8); 103734e026f9SYork Sun } 103834e026f9SYork Sun } 103934e026f9SYork Sun 104034e026f9SYork Sun #else /* for DDR2 and DDR1 */ 104134e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 104234e026f9SYork Sun static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, 104334e026f9SYork Sun const memctl_options_t *popts, 104434e026f9SYork Sun const common_timing_params_t *common_dimm, 104534e026f9SYork Sun const unsigned int unq_mrs_en) 104634e026f9SYork Sun { 104734e026f9SYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 104834e026f9SYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 104934e026f9SYork Sun 105034e026f9SYork Sun ddr->ddr_sdram_mode_2 = (0 105134e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 105234e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 105334e026f9SYork Sun ); 105434e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 105534e026f9SYork Sun } 105634e026f9SYork Sun #endif 105734e026f9SYork Sun 105834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 105934e026f9SYork Sun /* DDR SDRAM Mode configuration 9 (DDR_SDRAM_MODE_9) */ 106034e026f9SYork Sun static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, 106134e026f9SYork Sun const memctl_options_t *popts, 106234e026f9SYork Sun const common_timing_params_t *common_dimm, 106334e026f9SYork Sun const unsigned int unq_mrs_en) 106434e026f9SYork Sun { 106534e026f9SYork Sun int i; 106634e026f9SYork Sun unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */ 106734e026f9SYork Sun unsigned short esdmode5; /* Extended SDRAM mode 5 */ 106834e026f9SYork Sun 106934e026f9SYork Sun esdmode5 = 0x00000400; /* Data mask enabled */ 107034e026f9SYork Sun 107134e026f9SYork Sun ddr->ddr_sdram_mode_9 = (0 107234e026f9SYork Sun | ((esdmode4 & 0xffff) << 16) 107334e026f9SYork Sun | ((esdmode5 & 0xffff) << 0) 107434e026f9SYork Sun ); 107534e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9); 107634e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 107734e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 107834e026f9SYork Sun switch (i) { 107934e026f9SYork Sun case 1: 108034e026f9SYork Sun ddr->ddr_sdram_mode_11 = (0 108134e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 108234e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 108334e026f9SYork Sun ); 108434e026f9SYork Sun break; 108534e026f9SYork Sun case 2: 108634e026f9SYork Sun ddr->ddr_sdram_mode_13 = (0 108734e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 108834e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 108934e026f9SYork Sun ); 109034e026f9SYork Sun break; 109134e026f9SYork Sun case 3: 109234e026f9SYork Sun ddr->ddr_sdram_mode_15 = (0 109334e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 109434e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 109534e026f9SYork Sun ); 109634e026f9SYork Sun break; 109734e026f9SYork Sun } 109834e026f9SYork Sun } 109934e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_11 = 0x%08x\n", 110034e026f9SYork Sun ddr->ddr_sdram_mode_11); 110134e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_13 = 0x%08x\n", 110234e026f9SYork Sun ddr->ddr_sdram_mode_13); 110334e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_15 = 0x%08x\n", 110434e026f9SYork Sun ddr->ddr_sdram_mode_15); 110534e026f9SYork Sun } 110634e026f9SYork Sun } 110734e026f9SYork Sun 110834e026f9SYork Sun /* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */ 110934e026f9SYork Sun static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr, 111034e026f9SYork Sun const memctl_options_t *popts, 111134e026f9SYork Sun const common_timing_params_t *common_dimm, 111234e026f9SYork Sun const unsigned int unq_mrs_en) 111334e026f9SYork Sun { 111434e026f9SYork Sun int i; 111534e026f9SYork Sun unsigned short esdmode6 = 0; /* Extended SDRAM mode 6 */ 111634e026f9SYork Sun unsigned short esdmode7 = 0; /* Extended SDRAM mode 7 */ 111734e026f9SYork Sun unsigned int tccdl_min = picos_to_mclk(common_dimm->tccdl_ps); 111834e026f9SYork Sun 111934e026f9SYork Sun esdmode6 = ((tccdl_min - 4) & 0x7) << 10; 112034e026f9SYork Sun 112134e026f9SYork Sun ddr->ddr_sdram_mode_10 = (0 112234e026f9SYork Sun | ((esdmode6 & 0xffff) << 16) 112334e026f9SYork Sun | ((esdmode7 & 0xffff) << 0) 112434e026f9SYork Sun ); 112534e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_10) = 0x%08x\n", ddr->ddr_sdram_mode_10); 112634e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 112734e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 112834e026f9SYork Sun switch (i) { 112934e026f9SYork Sun case 1: 113034e026f9SYork Sun ddr->ddr_sdram_mode_12 = (0 113134e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 113234e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 113334e026f9SYork Sun ); 113434e026f9SYork Sun break; 113534e026f9SYork Sun case 2: 113634e026f9SYork Sun ddr->ddr_sdram_mode_14 = (0 113734e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 113834e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 113934e026f9SYork Sun ); 114034e026f9SYork Sun break; 114134e026f9SYork Sun case 3: 114234e026f9SYork Sun ddr->ddr_sdram_mode_16 = (0 114334e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 114434e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 114534e026f9SYork Sun ); 114634e026f9SYork Sun break; 114734e026f9SYork Sun } 114834e026f9SYork Sun } 114934e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_12 = 0x%08x\n", 115034e026f9SYork Sun ddr->ddr_sdram_mode_12); 115134e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_14 = 0x%08x\n", 115234e026f9SYork Sun ddr->ddr_sdram_mode_14); 115334e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_16 = 0x%08x\n", 115434e026f9SYork Sun ddr->ddr_sdram_mode_16); 115534e026f9SYork Sun } 115634e026f9SYork Sun } 115734e026f9SYork Sun 115834e026f9SYork Sun #endif 11595614e71bSYork Sun 11605614e71bSYork Sun /* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */ 11615614e71bSYork Sun static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr, 11625614e71bSYork Sun const memctl_options_t *popts, 11635614e71bSYork Sun const common_timing_params_t *common_dimm) 11645614e71bSYork Sun { 11655614e71bSYork Sun unsigned int refint; /* Refresh interval */ 11665614e71bSYork Sun unsigned int bstopre; /* Precharge interval */ 11675614e71bSYork Sun 11685614e71bSYork Sun refint = picos_to_mclk(common_dimm->refresh_rate_ps); 11695614e71bSYork Sun 11705614e71bSYork Sun bstopre = popts->bstopre; 11715614e71bSYork Sun 11725614e71bSYork Sun /* refint field used 0x3FFF in earlier controllers */ 11735614e71bSYork Sun ddr->ddr_sdram_interval = (0 11745614e71bSYork Sun | ((refint & 0xFFFF) << 16) 11755614e71bSYork Sun | ((bstopre & 0x3FFF) << 0) 11765614e71bSYork Sun ); 11775614e71bSYork Sun debug("FSLDDR: ddr_sdram_interval = 0x%08x\n", ddr->ddr_sdram_interval); 11785614e71bSYork Sun } 11795614e71bSYork Sun 118034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 11815614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 11825614e71bSYork Sun static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, 11835614e71bSYork Sun const memctl_options_t *popts, 11845614e71bSYork Sun const common_timing_params_t *common_dimm, 11855614e71bSYork Sun unsigned int cas_latency, 11865614e71bSYork Sun unsigned int additive_latency, 11875614e71bSYork Sun const unsigned int unq_mrs_en) 11885614e71bSYork Sun { 118934e026f9SYork Sun int i; 119034e026f9SYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 119134e026f9SYork Sun unsigned short sdmode; /* SDRAM mode */ 119234e026f9SYork Sun 119334e026f9SYork Sun /* Mode Register - MR1 */ 119434e026f9SYork Sun unsigned int qoff = 0; /* Output buffer enable 0=yes, 1=no */ 119534e026f9SYork Sun unsigned int tdqs_en = 0; /* TDQS Enable: 0=no, 1=yes */ 119634e026f9SYork Sun unsigned int rtt; 119734e026f9SYork Sun unsigned int wrlvl_en = 0; /* Write level enable: 0=no, 1=yes */ 119834e026f9SYork Sun unsigned int al = 0; /* Posted CAS# additive latency (AL) */ 119934e026f9SYork Sun unsigned int dic = 0; /* Output driver impedance, 40ohm */ 120034e026f9SYork Sun unsigned int dll_en = 1; /* DLL Enable 1=Enable (Normal), 120134e026f9SYork Sun 0=Disable (Test/Debug) */ 120234e026f9SYork Sun 120334e026f9SYork Sun /* Mode Register - MR0 */ 120434e026f9SYork Sun unsigned int wr = 0; /* Write Recovery */ 120534e026f9SYork Sun unsigned int dll_rst; /* DLL Reset */ 120634e026f9SYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 120734e026f9SYork Sun unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ 120834e026f9SYork Sun /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ 120934e026f9SYork Sun unsigned int bt; 121034e026f9SYork Sun unsigned int bl; /* BL: Burst Length */ 121134e026f9SYork Sun 121234e026f9SYork Sun unsigned int wr_mclk; 121334e026f9SYork Sun /* DDR4 support WR 10, 12, 14, 16, 18, 20, 24 */ 121434e026f9SYork Sun static const u8 wr_table[] = { 121534e026f9SYork Sun 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6}; 121634e026f9SYork Sun /* DDR4 support CAS 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24 */ 121734e026f9SYork Sun static const u8 cas_latency_table[] = { 121834e026f9SYork Sun 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 121934e026f9SYork Sun 9, 9, 10, 10, 11, 11}; 122034e026f9SYork Sun 122134e026f9SYork Sun if (popts->rtt_override) 122234e026f9SYork Sun rtt = popts->rtt_override_value; 122334e026f9SYork Sun else 122434e026f9SYork Sun rtt = popts->cs_local_opts[0].odt_rtt_norm; 122534e026f9SYork Sun 122634e026f9SYork Sun if (additive_latency == (cas_latency - 1)) 122734e026f9SYork Sun al = 1; 122834e026f9SYork Sun if (additive_latency == (cas_latency - 2)) 122934e026f9SYork Sun al = 2; 123034e026f9SYork Sun 123134e026f9SYork Sun if (popts->quad_rank_present) 123234e026f9SYork Sun dic = 1; /* output driver impedance 240/7 ohm */ 123334e026f9SYork Sun 123434e026f9SYork Sun /* 123534e026f9SYork Sun * The esdmode value will also be used for writing 123634e026f9SYork Sun * MR1 during write leveling for DDR3, although the 123734e026f9SYork Sun * bits specifically related to the write leveling 123834e026f9SYork Sun * scheme will be handled automatically by the DDR 123934e026f9SYork Sun * controller. so we set the wrlvl_en = 0 here. 124034e026f9SYork Sun */ 124134e026f9SYork Sun esdmode = (0 124234e026f9SYork Sun | ((qoff & 0x1) << 12) 124334e026f9SYork Sun | ((tdqs_en & 0x1) << 11) 124434e026f9SYork Sun | ((rtt & 0x7) << 8) 124534e026f9SYork Sun | ((wrlvl_en & 0x1) << 7) 124634e026f9SYork Sun | ((al & 0x3) << 3) 124734e026f9SYork Sun | ((dic & 0x3) << 1) /* DIC field is split */ 124834e026f9SYork Sun | ((dll_en & 0x1) << 0) 124934e026f9SYork Sun ); 125034e026f9SYork Sun 125134e026f9SYork Sun /* 125234e026f9SYork Sun * DLL control for precharge PD 125334e026f9SYork Sun * 0=slow exit DLL off (tXPDLL) 125434e026f9SYork Sun * 1=fast exit DLL on (tXP) 125534e026f9SYork Sun */ 125634e026f9SYork Sun 125734e026f9SYork Sun wr_mclk = picos_to_mclk(common_dimm->twr_ps); 125834e026f9SYork Sun if (wr_mclk <= 24) { 125934e026f9SYork Sun wr = wr_table[wr_mclk - 10]; 126034e026f9SYork Sun } else { 126134e026f9SYork Sun printf("Error: unsupported write recovery for mode register wr_mclk = %d\n", 126234e026f9SYork Sun wr_mclk); 126334e026f9SYork Sun } 126434e026f9SYork Sun 126534e026f9SYork Sun dll_rst = 0; /* dll no reset */ 126634e026f9SYork Sun mode = 0; /* normal mode */ 126734e026f9SYork Sun 126834e026f9SYork Sun /* look up table to get the cas latency bits */ 126934e026f9SYork Sun if (cas_latency >= 9 && cas_latency <= 24) 127034e026f9SYork Sun caslat = cas_latency_table[cas_latency - 9]; 127134e026f9SYork Sun else 127234e026f9SYork Sun printf("Error: unsupported cas latency for mode register\n"); 127334e026f9SYork Sun 127434e026f9SYork Sun bt = 0; /* Nibble sequential */ 127534e026f9SYork Sun 127634e026f9SYork Sun switch (popts->burst_length) { 127734e026f9SYork Sun case DDR_BL8: 127834e026f9SYork Sun bl = 0; 127934e026f9SYork Sun break; 128034e026f9SYork Sun case DDR_OTF: 128134e026f9SYork Sun bl = 1; 128234e026f9SYork Sun break; 128334e026f9SYork Sun case DDR_BC4: 128434e026f9SYork Sun bl = 2; 128534e026f9SYork Sun break; 128634e026f9SYork Sun default: 128734e026f9SYork Sun printf("Error: invalid burst length of %u specified. ", 128834e026f9SYork Sun popts->burst_length); 128934e026f9SYork Sun puts("Defaulting to on-the-fly BC4 or BL8 beats.\n"); 129034e026f9SYork Sun bl = 1; 129134e026f9SYork Sun break; 129234e026f9SYork Sun } 129334e026f9SYork Sun 129434e026f9SYork Sun sdmode = (0 129534e026f9SYork Sun | ((wr & 0x7) << 9) 129634e026f9SYork Sun | ((dll_rst & 0x1) << 8) 129734e026f9SYork Sun | ((mode & 0x1) << 7) 129834e026f9SYork Sun | (((caslat >> 1) & 0x7) << 4) 129934e026f9SYork Sun | ((bt & 0x1) << 3) 130034e026f9SYork Sun | ((caslat & 1) << 2) 130134e026f9SYork Sun | ((bl & 0x3) << 0) 130234e026f9SYork Sun ); 130334e026f9SYork Sun 130434e026f9SYork Sun ddr->ddr_sdram_mode = (0 130534e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 130634e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 130734e026f9SYork Sun ); 130834e026f9SYork Sun 130934e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 131034e026f9SYork Sun 131134e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 131234e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 131334e026f9SYork Sun if (popts->rtt_override) 131434e026f9SYork Sun rtt = popts->rtt_override_value; 131534e026f9SYork Sun else 131634e026f9SYork Sun rtt = popts->cs_local_opts[i].odt_rtt_norm; 131734e026f9SYork Sun 131834e026f9SYork Sun esdmode &= 0xF8FF; /* clear bit 10,9,8 for rtt */ 131934e026f9SYork Sun esdmode |= (rtt & 0x7) << 8; 132034e026f9SYork Sun switch (i) { 132134e026f9SYork Sun case 1: 132234e026f9SYork Sun ddr->ddr_sdram_mode_3 = (0 132334e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 132434e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 132534e026f9SYork Sun ); 132634e026f9SYork Sun break; 132734e026f9SYork Sun case 2: 132834e026f9SYork Sun ddr->ddr_sdram_mode_5 = (0 132934e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 133034e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 133134e026f9SYork Sun ); 133234e026f9SYork Sun break; 133334e026f9SYork Sun case 3: 133434e026f9SYork Sun ddr->ddr_sdram_mode_7 = (0 133534e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 133634e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 133734e026f9SYork Sun ); 133834e026f9SYork Sun break; 133934e026f9SYork Sun } 134034e026f9SYork Sun } 134134e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", 134234e026f9SYork Sun ddr->ddr_sdram_mode_3); 134334e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 134434e026f9SYork Sun ddr->ddr_sdram_mode_5); 134534e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 134634e026f9SYork Sun ddr->ddr_sdram_mode_5); 134734e026f9SYork Sun } 134834e026f9SYork Sun } 134934e026f9SYork Sun 135034e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 135134e026f9SYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 135234e026f9SYork Sun static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, 135334e026f9SYork Sun const memctl_options_t *popts, 135434e026f9SYork Sun const common_timing_params_t *common_dimm, 135534e026f9SYork Sun unsigned int cas_latency, 135634e026f9SYork Sun unsigned int additive_latency, 135734e026f9SYork Sun const unsigned int unq_mrs_en) 135834e026f9SYork Sun { 135934e026f9SYork Sun int i; 13605614e71bSYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 13615614e71bSYork Sun unsigned short sdmode; /* SDRAM mode */ 13625614e71bSYork Sun 13635614e71bSYork Sun /* Mode Register - MR1 */ 13645614e71bSYork Sun unsigned int qoff = 0; /* Output buffer enable 0=yes, 1=no */ 13655614e71bSYork Sun unsigned int tdqs_en = 0; /* TDQS Enable: 0=no, 1=yes */ 13665614e71bSYork Sun unsigned int rtt; 13675614e71bSYork Sun unsigned int wrlvl_en = 0; /* Write level enable: 0=no, 1=yes */ 13685614e71bSYork Sun unsigned int al = 0; /* Posted CAS# additive latency (AL) */ 13695614e71bSYork Sun unsigned int dic = 0; /* Output driver impedance, 40ohm */ 13705614e71bSYork Sun unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), 13715614e71bSYork Sun 1=Disable (Test/Debug) */ 13725614e71bSYork Sun 13735614e71bSYork Sun /* Mode Register - MR0 */ 13745614e71bSYork Sun unsigned int dll_on; /* DLL control for precharge PD, 0=off, 1=on */ 13755614e71bSYork Sun unsigned int wr = 0; /* Write Recovery */ 13765614e71bSYork Sun unsigned int dll_rst; /* DLL Reset */ 13775614e71bSYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 13785614e71bSYork Sun unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ 13795614e71bSYork Sun /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ 13805614e71bSYork Sun unsigned int bt; 13815614e71bSYork Sun unsigned int bl; /* BL: Burst Length */ 13825614e71bSYork Sun 13835614e71bSYork Sun unsigned int wr_mclk; 13845614e71bSYork Sun /* 13855614e71bSYork Sun * DDR_SDRAM_MODE doesn't support 9,11,13,15 13865614e71bSYork Sun * Please refer JEDEC Standard No. 79-3E for Mode Register MR0 13875614e71bSYork Sun * for this table 13885614e71bSYork Sun */ 13895614e71bSYork Sun static const u8 wr_table[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0}; 13905614e71bSYork Sun 13915614e71bSYork Sun if (popts->rtt_override) 13925614e71bSYork Sun rtt = popts->rtt_override_value; 13935614e71bSYork Sun else 13945614e71bSYork Sun rtt = popts->cs_local_opts[0].odt_rtt_norm; 13955614e71bSYork Sun 13965614e71bSYork Sun if (additive_latency == (cas_latency - 1)) 13975614e71bSYork Sun al = 1; 13985614e71bSYork Sun if (additive_latency == (cas_latency - 2)) 13995614e71bSYork Sun al = 2; 14005614e71bSYork Sun 14015614e71bSYork Sun if (popts->quad_rank_present) 14025614e71bSYork Sun dic = 1; /* output driver impedance 240/7 ohm */ 14035614e71bSYork Sun 14045614e71bSYork Sun /* 14055614e71bSYork Sun * The esdmode value will also be used for writing 14065614e71bSYork Sun * MR1 during write leveling for DDR3, although the 14075614e71bSYork Sun * bits specifically related to the write leveling 14085614e71bSYork Sun * scheme will be handled automatically by the DDR 14095614e71bSYork Sun * controller. so we set the wrlvl_en = 0 here. 14105614e71bSYork Sun */ 14115614e71bSYork Sun esdmode = (0 14125614e71bSYork Sun | ((qoff & 0x1) << 12) 14135614e71bSYork Sun | ((tdqs_en & 0x1) << 11) 14145614e71bSYork Sun | ((rtt & 0x4) << 7) /* rtt field is split */ 14155614e71bSYork Sun | ((wrlvl_en & 0x1) << 7) 14165614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 14175614e71bSYork Sun | ((dic & 0x2) << 4) /* DIC field is split */ 14185614e71bSYork Sun | ((al & 0x3) << 3) 14195614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 14205614e71bSYork Sun | ((dic & 0x1) << 1) /* DIC field is split */ 14215614e71bSYork Sun | ((dll_en & 0x1) << 0) 14225614e71bSYork Sun ); 14235614e71bSYork Sun 14245614e71bSYork Sun /* 14255614e71bSYork Sun * DLL control for precharge PD 14265614e71bSYork Sun * 0=slow exit DLL off (tXPDLL) 14275614e71bSYork Sun * 1=fast exit DLL on (tXP) 14285614e71bSYork Sun */ 14295614e71bSYork Sun dll_on = 1; 14305614e71bSYork Sun 143134e026f9SYork Sun wr_mclk = picos_to_mclk(common_dimm->twr_ps); 14325614e71bSYork Sun if (wr_mclk <= 16) { 14335614e71bSYork Sun wr = wr_table[wr_mclk - 5]; 14345614e71bSYork Sun } else { 14355614e71bSYork Sun printf("Error: unsupported write recovery for mode register " 14365614e71bSYork Sun "wr_mclk = %d\n", wr_mclk); 14375614e71bSYork Sun } 14385614e71bSYork Sun 14395614e71bSYork Sun dll_rst = 0; /* dll no reset */ 14405614e71bSYork Sun mode = 0; /* normal mode */ 14415614e71bSYork Sun 14425614e71bSYork Sun /* look up table to get the cas latency bits */ 14435614e71bSYork Sun if (cas_latency >= 5 && cas_latency <= 16) { 14445614e71bSYork Sun unsigned char cas_latency_table[] = { 14455614e71bSYork Sun 0x2, /* 5 clocks */ 14465614e71bSYork Sun 0x4, /* 6 clocks */ 14475614e71bSYork Sun 0x6, /* 7 clocks */ 14485614e71bSYork Sun 0x8, /* 8 clocks */ 14495614e71bSYork Sun 0xa, /* 9 clocks */ 14505614e71bSYork Sun 0xc, /* 10 clocks */ 14515614e71bSYork Sun 0xe, /* 11 clocks */ 14525614e71bSYork Sun 0x1, /* 12 clocks */ 14535614e71bSYork Sun 0x3, /* 13 clocks */ 14545614e71bSYork Sun 0x5, /* 14 clocks */ 14555614e71bSYork Sun 0x7, /* 15 clocks */ 14565614e71bSYork Sun 0x9, /* 16 clocks */ 14575614e71bSYork Sun }; 14585614e71bSYork Sun caslat = cas_latency_table[cas_latency - 5]; 14595614e71bSYork Sun } else { 14605614e71bSYork Sun printf("Error: unsupported cas latency for mode register\n"); 14615614e71bSYork Sun } 14625614e71bSYork Sun 14635614e71bSYork Sun bt = 0; /* Nibble sequential */ 14645614e71bSYork Sun 14655614e71bSYork Sun switch (popts->burst_length) { 14665614e71bSYork Sun case DDR_BL8: 14675614e71bSYork Sun bl = 0; 14685614e71bSYork Sun break; 14695614e71bSYork Sun case DDR_OTF: 14705614e71bSYork Sun bl = 1; 14715614e71bSYork Sun break; 14725614e71bSYork Sun case DDR_BC4: 14735614e71bSYork Sun bl = 2; 14745614e71bSYork Sun break; 14755614e71bSYork Sun default: 14765614e71bSYork Sun printf("Error: invalid burst length of %u specified. " 14775614e71bSYork Sun " Defaulting to on-the-fly BC4 or BL8 beats.\n", 14785614e71bSYork Sun popts->burst_length); 14795614e71bSYork Sun bl = 1; 14805614e71bSYork Sun break; 14815614e71bSYork Sun } 14825614e71bSYork Sun 14835614e71bSYork Sun sdmode = (0 14845614e71bSYork Sun | ((dll_on & 0x1) << 12) 14855614e71bSYork Sun | ((wr & 0x7) << 9) 14865614e71bSYork Sun | ((dll_rst & 0x1) << 8) 14875614e71bSYork Sun | ((mode & 0x1) << 7) 14885614e71bSYork Sun | (((caslat >> 1) & 0x7) << 4) 14895614e71bSYork Sun | ((bt & 0x1) << 3) 14905614e71bSYork Sun | ((caslat & 1) << 2) 14915614e71bSYork Sun | ((bl & 0x3) << 0) 14925614e71bSYork Sun ); 14935614e71bSYork Sun 14945614e71bSYork Sun ddr->ddr_sdram_mode = (0 14955614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 14965614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 14975614e71bSYork Sun ); 14985614e71bSYork Sun 14995614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 15005614e71bSYork Sun 15015614e71bSYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 15025614e71bSYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 15035614e71bSYork Sun if (popts->rtt_override) 15045614e71bSYork Sun rtt = popts->rtt_override_value; 15055614e71bSYork Sun else 15065614e71bSYork Sun rtt = popts->cs_local_opts[i].odt_rtt_norm; 15075614e71bSYork Sun 15085614e71bSYork Sun esdmode &= 0xFDBB; /* clear bit 9,6,2 */ 15095614e71bSYork Sun esdmode |= (0 15105614e71bSYork Sun | ((rtt & 0x4) << 7) /* rtt field is split */ 15115614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 15125614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 15135614e71bSYork Sun ); 15145614e71bSYork Sun switch (i) { 15155614e71bSYork Sun case 1: 15165614e71bSYork Sun ddr->ddr_sdram_mode_3 = (0 15175614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 15185614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 15195614e71bSYork Sun ); 15205614e71bSYork Sun break; 15215614e71bSYork Sun case 2: 15225614e71bSYork Sun ddr->ddr_sdram_mode_5 = (0 15235614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 15245614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 15255614e71bSYork Sun ); 15265614e71bSYork Sun break; 15275614e71bSYork Sun case 3: 15285614e71bSYork Sun ddr->ddr_sdram_mode_7 = (0 15295614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 15305614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 15315614e71bSYork Sun ); 15325614e71bSYork Sun break; 15335614e71bSYork Sun } 15345614e71bSYork Sun } 15355614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", 15365614e71bSYork Sun ddr->ddr_sdram_mode_3); 15375614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 15385614e71bSYork Sun ddr->ddr_sdram_mode_5); 15395614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 15405614e71bSYork Sun ddr->ddr_sdram_mode_5); 15415614e71bSYork Sun } 15425614e71bSYork Sun } 15435614e71bSYork Sun 15445614e71bSYork Sun #else /* !CONFIG_SYS_FSL_DDR3 */ 15455614e71bSYork Sun 15465614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 15475614e71bSYork Sun static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, 15485614e71bSYork Sun const memctl_options_t *popts, 15495614e71bSYork Sun const common_timing_params_t *common_dimm, 15505614e71bSYork Sun unsigned int cas_latency, 15515614e71bSYork Sun unsigned int additive_latency, 15525614e71bSYork Sun const unsigned int unq_mrs_en) 15535614e71bSYork Sun { 15545614e71bSYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 15555614e71bSYork Sun unsigned short sdmode; /* SDRAM mode */ 15565614e71bSYork Sun 15575614e71bSYork Sun /* 15585614e71bSYork Sun * FIXME: This ought to be pre-calculated in a 15595614e71bSYork Sun * technology-specific routine, 15605614e71bSYork Sun * e.g. compute_DDR2_mode_register(), and then the 15615614e71bSYork Sun * sdmode and esdmode passed in as part of common_dimm. 15625614e71bSYork Sun */ 15635614e71bSYork Sun 15645614e71bSYork Sun /* Extended Mode Register */ 15655614e71bSYork Sun unsigned int mrs = 0; /* Mode Register Set */ 15665614e71bSYork Sun unsigned int outputs = 0; /* 0=Enabled, 1=Disabled */ 15675614e71bSYork Sun unsigned int rdqs_en = 0; /* RDQS Enable: 0=no, 1=yes */ 15685614e71bSYork Sun unsigned int dqs_en = 0; /* DQS# Enable: 0=enable, 1=disable */ 15695614e71bSYork Sun unsigned int ocd = 0; /* 0x0=OCD not supported, 15705614e71bSYork Sun 0x7=OCD default state */ 15715614e71bSYork Sun unsigned int rtt; 15725614e71bSYork Sun unsigned int al; /* Posted CAS# additive latency (AL) */ 15735614e71bSYork Sun unsigned int ods = 0; /* Output Drive Strength: 15745614e71bSYork Sun 0 = Full strength (18ohm) 15755614e71bSYork Sun 1 = Reduced strength (4ohm) */ 15765614e71bSYork Sun unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), 15775614e71bSYork Sun 1=Disable (Test/Debug) */ 15785614e71bSYork Sun 15795614e71bSYork Sun /* Mode Register (MR) */ 15805614e71bSYork Sun unsigned int mr; /* Mode Register Definition */ 15815614e71bSYork Sun unsigned int pd; /* Power-Down Mode */ 15825614e71bSYork Sun unsigned int wr; /* Write Recovery */ 15835614e71bSYork Sun unsigned int dll_res; /* DLL Reset */ 15845614e71bSYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 15855614e71bSYork Sun unsigned int caslat = 0;/* CAS# latency */ 15865614e71bSYork Sun /* BT: Burst Type (0=Sequential, 1=Interleaved) */ 15875614e71bSYork Sun unsigned int bt; 15885614e71bSYork Sun unsigned int bl; /* BL: Burst Length */ 15895614e71bSYork Sun 15905614e71bSYork Sun dqs_en = !popts->dqs_config; 15915614e71bSYork Sun rtt = fsl_ddr_get_rtt(); 15925614e71bSYork Sun 15935614e71bSYork Sun al = additive_latency; 15945614e71bSYork Sun 15955614e71bSYork Sun esdmode = (0 15965614e71bSYork Sun | ((mrs & 0x3) << 14) 15975614e71bSYork Sun | ((outputs & 0x1) << 12) 15985614e71bSYork Sun | ((rdqs_en & 0x1) << 11) 15995614e71bSYork Sun | ((dqs_en & 0x1) << 10) 16005614e71bSYork Sun | ((ocd & 0x7) << 7) 16015614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 16025614e71bSYork Sun | ((al & 0x7) << 3) 16035614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 16045614e71bSYork Sun | ((ods & 0x1) << 1) 16055614e71bSYork Sun | ((dll_en & 0x1) << 0) 16065614e71bSYork Sun ); 16075614e71bSYork Sun 16085614e71bSYork Sun mr = 0; /* FIXME: CHECKME */ 16095614e71bSYork Sun 16105614e71bSYork Sun /* 16115614e71bSYork Sun * 0 = Fast Exit (Normal) 16125614e71bSYork Sun * 1 = Slow Exit (Low Power) 16135614e71bSYork Sun */ 16145614e71bSYork Sun pd = 0; 16155614e71bSYork Sun 16165614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 16175614e71bSYork Sun wr = 0; /* Historical */ 16185614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 161934e026f9SYork Sun wr = picos_to_mclk(common_dimm->twr_ps); 16205614e71bSYork Sun #endif 16215614e71bSYork Sun dll_res = 0; 16225614e71bSYork Sun mode = 0; 16235614e71bSYork Sun 16245614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 16255614e71bSYork Sun if (1 <= cas_latency && cas_latency <= 4) { 16265614e71bSYork Sun unsigned char mode_caslat_table[4] = { 16275614e71bSYork Sun 0x5, /* 1.5 clocks */ 16285614e71bSYork Sun 0x2, /* 2.0 clocks */ 16295614e71bSYork Sun 0x6, /* 2.5 clocks */ 16305614e71bSYork Sun 0x3 /* 3.0 clocks */ 16315614e71bSYork Sun }; 16325614e71bSYork Sun caslat = mode_caslat_table[cas_latency - 1]; 16335614e71bSYork Sun } else { 16345614e71bSYork Sun printf("Warning: unknown cas_latency %d\n", cas_latency); 16355614e71bSYork Sun } 16365614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 16375614e71bSYork Sun caslat = cas_latency; 16385614e71bSYork Sun #endif 16395614e71bSYork Sun bt = 0; 16405614e71bSYork Sun 16415614e71bSYork Sun switch (popts->burst_length) { 16425614e71bSYork Sun case DDR_BL4: 16435614e71bSYork Sun bl = 2; 16445614e71bSYork Sun break; 16455614e71bSYork Sun case DDR_BL8: 16465614e71bSYork Sun bl = 3; 16475614e71bSYork Sun break; 16485614e71bSYork Sun default: 16495614e71bSYork Sun printf("Error: invalid burst length of %u specified. " 16505614e71bSYork Sun " Defaulting to 4 beats.\n", 16515614e71bSYork Sun popts->burst_length); 16525614e71bSYork Sun bl = 2; 16535614e71bSYork Sun break; 16545614e71bSYork Sun } 16555614e71bSYork Sun 16565614e71bSYork Sun sdmode = (0 16575614e71bSYork Sun | ((mr & 0x3) << 14) 16585614e71bSYork Sun | ((pd & 0x1) << 12) 16595614e71bSYork Sun | ((wr & 0x7) << 9) 16605614e71bSYork Sun | ((dll_res & 0x1) << 8) 16615614e71bSYork Sun | ((mode & 0x1) << 7) 16625614e71bSYork Sun | ((caslat & 0x7) << 4) 16635614e71bSYork Sun | ((bt & 0x1) << 3) 16645614e71bSYork Sun | ((bl & 0x7) << 0) 16655614e71bSYork Sun ); 16665614e71bSYork Sun 16675614e71bSYork Sun ddr->ddr_sdram_mode = (0 16685614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16695614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16705614e71bSYork Sun ); 16715614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 16725614e71bSYork Sun } 16735614e71bSYork Sun #endif 16745614e71bSYork Sun 16755614e71bSYork Sun /* DDR SDRAM Data Initialization (DDR_DATA_INIT) */ 16765614e71bSYork Sun static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr) 16775614e71bSYork Sun { 16785614e71bSYork Sun unsigned int init_value; /* Initialization value */ 16795614e71bSYork Sun 16805614e71bSYork Sun #ifdef CONFIG_MEM_INIT_VALUE 16815614e71bSYork Sun init_value = CONFIG_MEM_INIT_VALUE; 16825614e71bSYork Sun #else 16835614e71bSYork Sun init_value = 0xDEADBEEF; 16845614e71bSYork Sun #endif 16855614e71bSYork Sun ddr->ddr_data_init = init_value; 16865614e71bSYork Sun } 16875614e71bSYork Sun 16885614e71bSYork Sun /* 16895614e71bSYork Sun * DDR SDRAM Clock Control (DDR_SDRAM_CLK_CNTL) 16905614e71bSYork Sun * The old controller on the 8540/60 doesn't have this register. 16915614e71bSYork Sun * Hope it's OK to set it (to 0) anyway. 16925614e71bSYork Sun */ 16935614e71bSYork Sun static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr, 16945614e71bSYork Sun const memctl_options_t *popts) 16955614e71bSYork Sun { 16965614e71bSYork Sun unsigned int clk_adjust; /* Clock adjust */ 16975614e71bSYork Sun 16985614e71bSYork Sun clk_adjust = popts->clk_adjust; 16995614e71bSYork Sun ddr->ddr_sdram_clk_cntl = (clk_adjust & 0xF) << 23; 17005614e71bSYork Sun debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl); 17015614e71bSYork Sun } 17025614e71bSYork Sun 17035614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_ADDR) */ 17045614e71bSYork Sun static void set_ddr_init_addr(fsl_ddr_cfg_regs_t *ddr) 17055614e71bSYork Sun { 17065614e71bSYork Sun unsigned int init_addr = 0; /* Initialization address */ 17075614e71bSYork Sun 17085614e71bSYork Sun ddr->ddr_init_addr = init_addr; 17095614e71bSYork Sun } 17105614e71bSYork Sun 17115614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_EXT_ADDR) */ 17125614e71bSYork Sun static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr) 17135614e71bSYork Sun { 17145614e71bSYork Sun unsigned int uia = 0; /* Use initialization address */ 17155614e71bSYork Sun unsigned int init_ext_addr = 0; /* Initialization address */ 17165614e71bSYork Sun 17175614e71bSYork Sun ddr->ddr_init_ext_addr = (0 17185614e71bSYork Sun | ((uia & 0x1) << 31) 17195614e71bSYork Sun | (init_ext_addr & 0xF) 17205614e71bSYork Sun ); 17215614e71bSYork Sun } 17225614e71bSYork Sun 17235614e71bSYork Sun /* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */ 17245614e71bSYork Sun static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr, 17255614e71bSYork Sun const memctl_options_t *popts) 17265614e71bSYork Sun { 17275614e71bSYork Sun unsigned int rwt = 0; /* Read-to-write turnaround for same CS */ 17285614e71bSYork Sun unsigned int wrt = 0; /* Write-to-read turnaround for same CS */ 17295614e71bSYork Sun unsigned int rrt = 0; /* Read-to-read turnaround for same CS */ 17305614e71bSYork Sun unsigned int wwt = 0; /* Write-to-write turnaround for same CS */ 17315614e71bSYork Sun unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */ 17325614e71bSYork Sun 173334e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 17345614e71bSYork Sun if (popts->burst_length == DDR_BL8) { 17355614e71bSYork Sun /* We set BL/2 for fixed BL8 */ 17365614e71bSYork Sun rrt = 0; /* BL/2 clocks */ 17375614e71bSYork Sun wwt = 0; /* BL/2 clocks */ 17385614e71bSYork Sun } else { 17395614e71bSYork Sun /* We need to set BL/2 + 2 to BC4 and OTF */ 17405614e71bSYork Sun rrt = 2; /* BL/2 + 2 clocks */ 17415614e71bSYork Sun wwt = 2; /* BL/2 + 2 clocks */ 17425614e71bSYork Sun } 174334e026f9SYork Sun #endif 174434e026f9SYork Sun 174534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 174634e026f9SYork Sun dll_lock = 2; /* tDLLK = 1024 clocks */ 174734e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 17485614e71bSYork Sun dll_lock = 1; /* tDLLK = 512 clocks from spec */ 17495614e71bSYork Sun #endif 17505614e71bSYork Sun ddr->timing_cfg_4 = (0 17515614e71bSYork Sun | ((rwt & 0xf) << 28) 17525614e71bSYork Sun | ((wrt & 0xf) << 24) 17535614e71bSYork Sun | ((rrt & 0xf) << 20) 17545614e71bSYork Sun | ((wwt & 0xf) << 16) 17555614e71bSYork Sun | (dll_lock & 0x3) 17565614e71bSYork Sun ); 17575614e71bSYork Sun debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4); 17585614e71bSYork Sun } 17595614e71bSYork Sun 17605614e71bSYork Sun /* DDR SDRAM Timing Configuration 5 (TIMING_CFG_5) */ 17615614e71bSYork Sun static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr, unsigned int cas_latency) 17625614e71bSYork Sun { 17635614e71bSYork Sun unsigned int rodt_on = 0; /* Read to ODT on */ 17645614e71bSYork Sun unsigned int rodt_off = 0; /* Read to ODT off */ 17655614e71bSYork Sun unsigned int wodt_on = 0; /* Write to ODT on */ 17665614e71bSYork Sun unsigned int wodt_off = 0; /* Write to ODT off */ 17675614e71bSYork Sun 176834e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 176934e026f9SYork Sun unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 177034e026f9SYork Sun ((ddr->timing_cfg_2 & 0x00040000) >> 14); 17715614e71bSYork Sun /* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */ 177234e026f9SYork Sun if (cas_latency >= wr_lat) 177334e026f9SYork Sun rodt_on = cas_latency - wr_lat + 1; 17745614e71bSYork Sun rodt_off = 4; /* 4 clocks */ 17755614e71bSYork Sun wodt_on = 1; /* 1 clocks */ 17765614e71bSYork Sun wodt_off = 4; /* 4 clocks */ 17775614e71bSYork Sun #endif 17785614e71bSYork Sun 17795614e71bSYork Sun ddr->timing_cfg_5 = (0 17805614e71bSYork Sun | ((rodt_on & 0x1f) << 24) 17815614e71bSYork Sun | ((rodt_off & 0x7) << 20) 17825614e71bSYork Sun | ((wodt_on & 0x1f) << 12) 17835614e71bSYork Sun | ((wodt_off & 0x7) << 8) 17845614e71bSYork Sun ); 17855614e71bSYork Sun debug("FSLDDR: timing_cfg_5 = 0x%08x\n", ddr->timing_cfg_5); 17865614e71bSYork Sun } 17875614e71bSYork Sun 178834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 178934e026f9SYork Sun static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr) 179034e026f9SYork Sun { 179134e026f9SYork Sun unsigned int hs_caslat = 0; 179234e026f9SYork Sun unsigned int hs_wrlat = 0; 179334e026f9SYork Sun unsigned int hs_wrrec = 0; 179434e026f9SYork Sun unsigned int hs_clkadj = 0; 179534e026f9SYork Sun unsigned int hs_wrlvl_start = 0; 179634e026f9SYork Sun 179734e026f9SYork Sun ddr->timing_cfg_6 = (0 179834e026f9SYork Sun | ((hs_caslat & 0x1f) << 24) 179934e026f9SYork Sun | ((hs_wrlat & 0x1f) << 19) 180034e026f9SYork Sun | ((hs_wrrec & 0x1f) << 12) 180134e026f9SYork Sun | ((hs_clkadj & 0x1f) << 6) 180234e026f9SYork Sun | ((hs_wrlvl_start & 0x1f) << 0) 180334e026f9SYork Sun ); 180434e026f9SYork Sun debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6); 180534e026f9SYork Sun } 180634e026f9SYork Sun 180734e026f9SYork Sun static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr, 180834e026f9SYork Sun const common_timing_params_t *common_dimm) 180934e026f9SYork Sun { 181034e026f9SYork Sun unsigned int txpr, tcksre, tcksrx; 181134e026f9SYork Sun unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd; 181234e026f9SYork Sun 181334e026f9SYork Sun txpr = max(5, picos_to_mclk(common_dimm->trfc1_ps + 10000)); 181434e026f9SYork Sun tcksre = max(5, picos_to_mclk(10000)); 181534e026f9SYork Sun tcksrx = max(5, picos_to_mclk(10000)); 181634e026f9SYork Sun par_lat = 0; 181734e026f9SYork Sun cs_to_cmd = 0; 181834e026f9SYork Sun 181934e026f9SYork Sun if (txpr <= 200) 182034e026f9SYork Sun cke_rst = 0; 182134e026f9SYork Sun else if (txpr <= 256) 182234e026f9SYork Sun cke_rst = 1; 182334e026f9SYork Sun else if (txpr <= 512) 182434e026f9SYork Sun cke_rst = 2; 182534e026f9SYork Sun else 182634e026f9SYork Sun cke_rst = 3; 182734e026f9SYork Sun 182834e026f9SYork Sun if (tcksre <= 19) 182934e026f9SYork Sun cksre = tcksre - 5; 183034e026f9SYork Sun else 183134e026f9SYork Sun cksre = 15; 183234e026f9SYork Sun 183334e026f9SYork Sun if (tcksrx <= 19) 183434e026f9SYork Sun cksrx = tcksrx - 5; 183534e026f9SYork Sun else 183634e026f9SYork Sun cksrx = 15; 183734e026f9SYork Sun 183834e026f9SYork Sun ddr->timing_cfg_7 = (0 183934e026f9SYork Sun | ((cke_rst & 0x3) << 28) 184034e026f9SYork Sun | ((cksre & 0xf) << 24) 184134e026f9SYork Sun | ((cksrx & 0xf) << 20) 184234e026f9SYork Sun | ((par_lat & 0xf) << 16) 184334e026f9SYork Sun | ((cs_to_cmd & 0xf) << 4) 184434e026f9SYork Sun ); 184534e026f9SYork Sun debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7); 184634e026f9SYork Sun } 184734e026f9SYork Sun 184834e026f9SYork Sun static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr, 184934e026f9SYork Sun const memctl_options_t *popts, 185034e026f9SYork Sun const common_timing_params_t *common_dimm, 185134e026f9SYork Sun unsigned int cas_latency) 185234e026f9SYork Sun { 185334e026f9SYork Sun unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg; 185434e026f9SYork Sun unsigned int acttoact_bg, wrtord_bg, pre_all_rec; 185534e026f9SYork Sun unsigned int tccdl = picos_to_mclk(common_dimm->tccdl_ps); 185634e026f9SYork Sun unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 185734e026f9SYork Sun ((ddr->timing_cfg_2 & 0x00040000) >> 14); 185834e026f9SYork Sun 185934e026f9SYork Sun rwt_bg = cas_latency + 2 + 4 - wr_lat; 186034e026f9SYork Sun if (rwt_bg < tccdl) 186134e026f9SYork Sun rwt_bg = tccdl - rwt_bg; 186234e026f9SYork Sun else 186334e026f9SYork Sun rwt_bg = 0; 186434e026f9SYork Sun 186534e026f9SYork Sun wrt_bg = wr_lat + 4 + 1 - cas_latency; 186634e026f9SYork Sun if (wrt_bg < tccdl) 186734e026f9SYork Sun wrt_bg = tccdl - wrt_bg; 186834e026f9SYork Sun else 186934e026f9SYork Sun wrt_bg = 0; 187034e026f9SYork Sun 187134e026f9SYork Sun if (popts->burst_length == DDR_BL8) { 187234e026f9SYork Sun rrt_bg = tccdl - 4; 187334e026f9SYork Sun wwt_bg = tccdl - 4; 187434e026f9SYork Sun } else { 187534e026f9SYork Sun rrt_bg = tccdl - 2; 187634e026f9SYork Sun wwt_bg = tccdl - 4; 187734e026f9SYork Sun } 187834e026f9SYork Sun 187934e026f9SYork Sun acttoact_bg = picos_to_mclk(common_dimm->trrdl_ps); 188034e026f9SYork Sun wrtord_bg = max(4, picos_to_mclk(7500)); 18813d75ec95SYork Sun if (popts->otf_burst_chop_en) 18823d75ec95SYork Sun wrtord_bg += 2; 18833d75ec95SYork Sun 188434e026f9SYork Sun pre_all_rec = 0; 188534e026f9SYork Sun 188634e026f9SYork Sun ddr->timing_cfg_8 = (0 188734e026f9SYork Sun | ((rwt_bg & 0xf) << 28) 188834e026f9SYork Sun | ((wrt_bg & 0xf) << 24) 188934e026f9SYork Sun | ((rrt_bg & 0xf) << 20) 189034e026f9SYork Sun | ((wwt_bg & 0xf) << 16) 189134e026f9SYork Sun | ((acttoact_bg & 0xf) << 12) 189234e026f9SYork Sun | ((wrtord_bg & 0xf) << 8) 189334e026f9SYork Sun | ((pre_all_rec & 0x1f) << 0) 189434e026f9SYork Sun ); 189534e026f9SYork Sun 189634e026f9SYork Sun debug("FSLDDR: timing_cfg_8 = 0x%08x\n", ddr->timing_cfg_8); 189734e026f9SYork Sun } 189834e026f9SYork Sun 189934e026f9SYork Sun static void set_timing_cfg_9(fsl_ddr_cfg_regs_t *ddr) 190034e026f9SYork Sun { 190134e026f9SYork Sun ddr->timing_cfg_9 = 0; 190234e026f9SYork Sun debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9); 190334e026f9SYork Sun } 190434e026f9SYork Sun 1905*f80d6472SYork Sun /* This function needs to be called after set_ddr_sdram_cfg() is called */ 190634e026f9SYork Sun static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr, 190734e026f9SYork Sun const dimm_params_t *dimm_params) 190834e026f9SYork Sun { 1909*f80d6472SYork Sun unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1; 1910*f80d6472SYork Sun 191134e026f9SYork Sun ddr->dq_map_0 = ((dimm_params->dq_mapping[0] & 0x3F) << 26) | 191234e026f9SYork Sun ((dimm_params->dq_mapping[1] & 0x3F) << 20) | 191334e026f9SYork Sun ((dimm_params->dq_mapping[2] & 0x3F) << 14) | 191434e026f9SYork Sun ((dimm_params->dq_mapping[3] & 0x3F) << 8) | 191534e026f9SYork Sun ((dimm_params->dq_mapping[4] & 0x3F) << 2); 191634e026f9SYork Sun 191734e026f9SYork Sun ddr->dq_map_1 = ((dimm_params->dq_mapping[5] & 0x3F) << 26) | 191834e026f9SYork Sun ((dimm_params->dq_mapping[6] & 0x3F) << 20) | 191934e026f9SYork Sun ((dimm_params->dq_mapping[7] & 0x3F) << 14) | 192034e026f9SYork Sun ((dimm_params->dq_mapping[10] & 0x3F) << 8) | 192134e026f9SYork Sun ((dimm_params->dq_mapping[11] & 0x3F) << 2); 192234e026f9SYork Sun 192334e026f9SYork Sun ddr->dq_map_2 = ((dimm_params->dq_mapping[12] & 0x3F) << 26) | 192434e026f9SYork Sun ((dimm_params->dq_mapping[13] & 0x3F) << 20) | 192534e026f9SYork Sun ((dimm_params->dq_mapping[14] & 0x3F) << 14) | 192634e026f9SYork Sun ((dimm_params->dq_mapping[15] & 0x3F) << 8) | 192734e026f9SYork Sun ((dimm_params->dq_mapping[16] & 0x3F) << 2); 192834e026f9SYork Sun 1929*f80d6472SYork Sun /* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */ 193034e026f9SYork Sun ddr->dq_map_3 = ((dimm_params->dq_mapping[17] & 0x3F) << 26) | 193134e026f9SYork Sun ((dimm_params->dq_mapping[8] & 0x3F) << 20) | 1932*f80d6472SYork Sun (acc_ecc_en ? 0 : 1933*f80d6472SYork Sun (dimm_params->dq_mapping[9] & 0x3F) << 14) | 193434e026f9SYork Sun dimm_params->dq_mapping_ors; 193534e026f9SYork Sun 193634e026f9SYork Sun debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0); 193734e026f9SYork Sun debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1); 193834e026f9SYork Sun debug("FSLDDR: dq_map_2 = 0x%08x\n", ddr->dq_map_2); 193934e026f9SYork Sun debug("FSLDDR: dq_map_3 = 0x%08x\n", ddr->dq_map_3); 194034e026f9SYork Sun } 194134e026f9SYork Sun static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr, 194234e026f9SYork Sun const memctl_options_t *popts) 194334e026f9SYork Sun { 194434e026f9SYork Sun int rd_pre; 194534e026f9SYork Sun 194634e026f9SYork Sun rd_pre = popts->quad_rank_present ? 1 : 0; 194734e026f9SYork Sun 194834e026f9SYork Sun ddr->ddr_sdram_cfg_3 = (rd_pre & 0x1) << 16; 194934e026f9SYork Sun 195034e026f9SYork Sun debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3); 195134e026f9SYork Sun } 195234e026f9SYork Sun #endif /* CONFIG_SYS_FSL_DDR4 */ 195334e026f9SYork Sun 19545614e71bSYork Sun /* DDR ZQ Calibration Control (DDR_ZQ_CNTL) */ 19555614e71bSYork Sun static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en) 19565614e71bSYork Sun { 19575614e71bSYork Sun unsigned int zqinit = 0;/* POR ZQ Calibration Time (tZQinit) */ 19585614e71bSYork Sun /* Normal Operation Full Calibration Time (tZQoper) */ 19595614e71bSYork Sun unsigned int zqoper = 0; 19605614e71bSYork Sun /* Normal Operation Short Calibration Time (tZQCS) */ 19615614e71bSYork Sun unsigned int zqcs = 0; 196234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 196334e026f9SYork Sun unsigned int zqcs_init; 196434e026f9SYork Sun #endif 19655614e71bSYork Sun 19665614e71bSYork Sun if (zq_en) { 196734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 196834e026f9SYork Sun zqinit = 10; /* 1024 clocks */ 196934e026f9SYork Sun zqoper = 9; /* 512 clocks */ 197034e026f9SYork Sun zqcs = 7; /* 128 clocks */ 197134e026f9SYork Sun zqcs_init = 5; /* 1024 refresh sequences */ 197234e026f9SYork Sun #else 19735614e71bSYork Sun zqinit = 9; /* 512 clocks */ 19745614e71bSYork Sun zqoper = 8; /* 256 clocks */ 19755614e71bSYork Sun zqcs = 6; /* 64 clocks */ 197634e026f9SYork Sun #endif 19775614e71bSYork Sun } 19785614e71bSYork Sun 19795614e71bSYork Sun ddr->ddr_zq_cntl = (0 19805614e71bSYork Sun | ((zq_en & 0x1) << 31) 19815614e71bSYork Sun | ((zqinit & 0xF) << 24) 19825614e71bSYork Sun | ((zqoper & 0xF) << 16) 19835614e71bSYork Sun | ((zqcs & 0xF) << 8) 198434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 198534e026f9SYork Sun | ((zqcs_init & 0xF) << 0) 198634e026f9SYork Sun #endif 19875614e71bSYork Sun ); 19885614e71bSYork Sun debug("FSLDDR: zq_cntl = 0x%08x\n", ddr->ddr_zq_cntl); 19895614e71bSYork Sun } 19905614e71bSYork Sun 19915614e71bSYork Sun /* DDR Write Leveling Control (DDR_WRLVL_CNTL) */ 19925614e71bSYork Sun static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en, 19935614e71bSYork Sun const memctl_options_t *popts) 19945614e71bSYork Sun { 19955614e71bSYork Sun /* 19965614e71bSYork Sun * First DQS pulse rising edge after margining mode 19975614e71bSYork Sun * is programmed (tWL_MRD) 19985614e71bSYork Sun */ 19995614e71bSYork Sun unsigned int wrlvl_mrd = 0; 20005614e71bSYork Sun /* ODT delay after margining mode is programmed (tWL_ODTEN) */ 20015614e71bSYork Sun unsigned int wrlvl_odten = 0; 20025614e71bSYork Sun /* DQS/DQS_ delay after margining mode is programmed (tWL_DQSEN) */ 20035614e71bSYork Sun unsigned int wrlvl_dqsen = 0; 20045614e71bSYork Sun /* WRLVL_SMPL: Write leveling sample time */ 20055614e71bSYork Sun unsigned int wrlvl_smpl = 0; 20065614e71bSYork Sun /* WRLVL_WLR: Write leveling repeition time */ 20075614e71bSYork Sun unsigned int wrlvl_wlr = 0; 20085614e71bSYork Sun /* WRLVL_START: Write leveling start time */ 20095614e71bSYork Sun unsigned int wrlvl_start = 0; 20105614e71bSYork Sun 20115614e71bSYork Sun /* suggest enable write leveling for DDR3 due to fly-by topology */ 20125614e71bSYork Sun if (wrlvl_en) { 20135614e71bSYork Sun /* tWL_MRD min = 40 nCK, we set it 64 */ 20145614e71bSYork Sun wrlvl_mrd = 0x6; 20155614e71bSYork Sun /* tWL_ODTEN 128 */ 20165614e71bSYork Sun wrlvl_odten = 0x7; 20175614e71bSYork Sun /* tWL_DQSEN min = 25 nCK, we set it 32 */ 20185614e71bSYork Sun wrlvl_dqsen = 0x5; 20195614e71bSYork Sun /* 20205614e71bSYork Sun * Write leveling sample time at least need 6 clocks 20215614e71bSYork Sun * higher than tWLO to allow enough time for progagation 20225614e71bSYork Sun * delay and sampling the prime data bits. 20235614e71bSYork Sun */ 20245614e71bSYork Sun wrlvl_smpl = 0xf; 20255614e71bSYork Sun /* 20265614e71bSYork Sun * Write leveling repetition time 20275614e71bSYork Sun * at least tWLO + 6 clocks clocks 20285614e71bSYork Sun * we set it 64 20295614e71bSYork Sun */ 20305614e71bSYork Sun wrlvl_wlr = 0x6; 20315614e71bSYork Sun /* 20325614e71bSYork Sun * Write leveling start time 20335614e71bSYork Sun * The value use for the DQS_ADJUST for the first sample 20345614e71bSYork Sun * when write leveling is enabled. It probably needs to be 20355614e71bSYork Sun * overriden per platform. 20365614e71bSYork Sun */ 20375614e71bSYork Sun wrlvl_start = 0x8; 20385614e71bSYork Sun /* 20395614e71bSYork Sun * Override the write leveling sample and start time 20405614e71bSYork Sun * according to specific board 20415614e71bSYork Sun */ 20425614e71bSYork Sun if (popts->wrlvl_override) { 20435614e71bSYork Sun wrlvl_smpl = popts->wrlvl_sample; 20445614e71bSYork Sun wrlvl_start = popts->wrlvl_start; 20455614e71bSYork Sun } 20465614e71bSYork Sun } 20475614e71bSYork Sun 20485614e71bSYork Sun ddr->ddr_wrlvl_cntl = (0 20495614e71bSYork Sun | ((wrlvl_en & 0x1) << 31) 20505614e71bSYork Sun | ((wrlvl_mrd & 0x7) << 24) 20515614e71bSYork Sun | ((wrlvl_odten & 0x7) << 20) 20525614e71bSYork Sun | ((wrlvl_dqsen & 0x7) << 16) 20535614e71bSYork Sun | ((wrlvl_smpl & 0xf) << 12) 20545614e71bSYork Sun | ((wrlvl_wlr & 0x7) << 8) 20555614e71bSYork Sun | ((wrlvl_start & 0x1F) << 0) 20565614e71bSYork Sun ); 20575614e71bSYork Sun debug("FSLDDR: wrlvl_cntl = 0x%08x\n", ddr->ddr_wrlvl_cntl); 20585614e71bSYork Sun ddr->ddr_wrlvl_cntl_2 = popts->wrlvl_ctl_2; 20595614e71bSYork Sun debug("FSLDDR: wrlvl_cntl_2 = 0x%08x\n", ddr->ddr_wrlvl_cntl_2); 20605614e71bSYork Sun ddr->ddr_wrlvl_cntl_3 = popts->wrlvl_ctl_3; 20615614e71bSYork Sun debug("FSLDDR: wrlvl_cntl_3 = 0x%08x\n", ddr->ddr_wrlvl_cntl_3); 20625614e71bSYork Sun 20635614e71bSYork Sun } 20645614e71bSYork Sun 20655614e71bSYork Sun /* DDR Self Refresh Counter (DDR_SR_CNTR) */ 20665614e71bSYork Sun static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it) 20675614e71bSYork Sun { 20685614e71bSYork Sun /* Self Refresh Idle Threshold */ 20695614e71bSYork Sun ddr->ddr_sr_cntr = (sr_it & 0xF) << 16; 20705614e71bSYork Sun } 20715614e71bSYork Sun 20725614e71bSYork Sun static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 20735614e71bSYork Sun { 20745614e71bSYork Sun if (popts->addr_hash) { 20755614e71bSYork Sun ddr->ddr_eor = 0x40000000; /* address hash enable */ 20765614e71bSYork Sun puts("Address hashing enabled.\n"); 20775614e71bSYork Sun } 20785614e71bSYork Sun } 20795614e71bSYork Sun 20805614e71bSYork Sun static void set_ddr_cdr1(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 20815614e71bSYork Sun { 20825614e71bSYork Sun ddr->ddr_cdr1 = popts->ddr_cdr1; 20835614e71bSYork Sun debug("FSLDDR: ddr_cdr1 = 0x%08x\n", ddr->ddr_cdr1); 20845614e71bSYork Sun } 20855614e71bSYork Sun 20865614e71bSYork Sun static void set_ddr_cdr2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 20875614e71bSYork Sun { 20885614e71bSYork Sun ddr->ddr_cdr2 = popts->ddr_cdr2; 20895614e71bSYork Sun debug("FSLDDR: ddr_cdr2 = 0x%08x\n", ddr->ddr_cdr2); 20905614e71bSYork Sun } 20915614e71bSYork Sun 20925614e71bSYork Sun unsigned int 20935614e71bSYork Sun check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) 20945614e71bSYork Sun { 20955614e71bSYork Sun unsigned int res = 0; 20965614e71bSYork Sun 20975614e71bSYork Sun /* 20985614e71bSYork Sun * Check that DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] are 20995614e71bSYork Sun * not set at the same time. 21005614e71bSYork Sun */ 21015614e71bSYork Sun if (ddr->ddr_sdram_cfg & 0x10000000 21025614e71bSYork Sun && ddr->ddr_sdram_cfg & 0x00008000) { 21035614e71bSYork Sun printf("Error: DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] " 21045614e71bSYork Sun " should not be set at the same time.\n"); 21055614e71bSYork Sun res++; 21065614e71bSYork Sun } 21075614e71bSYork Sun 21085614e71bSYork Sun return res; 21095614e71bSYork Sun } 21105614e71bSYork Sun 21115614e71bSYork Sun unsigned int 21125614e71bSYork Sun compute_fsl_memctl_config_regs(const memctl_options_t *popts, 21135614e71bSYork Sun fsl_ddr_cfg_regs_t *ddr, 21145614e71bSYork Sun const common_timing_params_t *common_dimm, 21155614e71bSYork Sun const dimm_params_t *dimm_params, 21165614e71bSYork Sun unsigned int dbw_cap_adj, 21175614e71bSYork Sun unsigned int size_only) 21185614e71bSYork Sun { 21195614e71bSYork Sun unsigned int i; 21205614e71bSYork Sun unsigned int cas_latency; 21215614e71bSYork Sun unsigned int additive_latency; 21225614e71bSYork Sun unsigned int sr_it; 21235614e71bSYork Sun unsigned int zq_en; 21245614e71bSYork Sun unsigned int wrlvl_en; 21255614e71bSYork Sun unsigned int ip_rev = 0; 21265614e71bSYork Sun unsigned int unq_mrs_en = 0; 21275614e71bSYork Sun int cs_en = 1; 21285614e71bSYork Sun 21295614e71bSYork Sun memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t)); 21305614e71bSYork Sun 21315614e71bSYork Sun if (common_dimm == NULL) { 21325614e71bSYork Sun printf("Error: subset DIMM params struct null pointer\n"); 21335614e71bSYork Sun return 1; 21345614e71bSYork Sun } 21355614e71bSYork Sun 21365614e71bSYork Sun /* 21375614e71bSYork Sun * Process overrides first. 21385614e71bSYork Sun * 21395614e71bSYork Sun * FIXME: somehow add dereated caslat to this 21405614e71bSYork Sun */ 21415614e71bSYork Sun cas_latency = (popts->cas_latency_override) 21425614e71bSYork Sun ? popts->cas_latency_override_value 214334e026f9SYork Sun : common_dimm->lowest_common_spd_caslat; 21445614e71bSYork Sun 21455614e71bSYork Sun additive_latency = (popts->additive_latency_override) 21465614e71bSYork Sun ? popts->additive_latency_override_value 21475614e71bSYork Sun : common_dimm->additive_latency; 21485614e71bSYork Sun 21495614e71bSYork Sun sr_it = (popts->auto_self_refresh_en) 21505614e71bSYork Sun ? popts->sr_it 21515614e71bSYork Sun : 0; 21525614e71bSYork Sun /* ZQ calibration */ 21535614e71bSYork Sun zq_en = (popts->zq_en) ? 1 : 0; 21545614e71bSYork Sun /* write leveling */ 21555614e71bSYork Sun wrlvl_en = (popts->wrlvl_en) ? 1 : 0; 21565614e71bSYork Sun 21575614e71bSYork Sun /* Chip Select Memory Bounds (CSn_BNDS) */ 21585614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 21595614e71bSYork Sun unsigned long long ea, sa; 21605614e71bSYork Sun unsigned int cs_per_dimm 21615614e71bSYork Sun = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; 21625614e71bSYork Sun unsigned int dimm_number 21635614e71bSYork Sun = i / cs_per_dimm; 21645614e71bSYork Sun unsigned long long rank_density 21655614e71bSYork Sun = dimm_params[dimm_number].rank_density >> dbw_cap_adj; 21665614e71bSYork Sun 21675614e71bSYork Sun if (dimm_params[dimm_number].n_ranks == 0) { 21685614e71bSYork Sun debug("Skipping setup of CS%u " 21695614e71bSYork Sun "because n_ranks on DIMM %u is 0\n", i, dimm_number); 21705614e71bSYork Sun continue; 21715614e71bSYork Sun } 21725614e71bSYork Sun if (popts->memctl_interleaving) { 21735614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 21745614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 21755614e71bSYork Sun break; 21765614e71bSYork Sun case FSL_DDR_CS0_CS1: 21775614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 21785614e71bSYork Sun if (i > 1) 21795614e71bSYork Sun cs_en = 0; 21805614e71bSYork Sun break; 21815614e71bSYork Sun case FSL_DDR_CS2_CS3: 21825614e71bSYork Sun default: 21835614e71bSYork Sun if (i > 0) 21845614e71bSYork Sun cs_en = 0; 21855614e71bSYork Sun break; 21865614e71bSYork Sun } 21875614e71bSYork Sun sa = common_dimm->base_address; 21885614e71bSYork Sun ea = sa + common_dimm->total_mem - 1; 21895614e71bSYork Sun } else if (!popts->memctl_interleaving) { 21905614e71bSYork Sun /* 21915614e71bSYork Sun * If memory interleaving between controllers is NOT 21925614e71bSYork Sun * enabled, the starting address for each memory 21935614e71bSYork Sun * controller is distinct. However, because rank 21945614e71bSYork Sun * interleaving is enabled, the starting and ending 21955614e71bSYork Sun * addresses of the total memory on that memory 21965614e71bSYork Sun * controller needs to be programmed into its 21975614e71bSYork Sun * respective CS0_BNDS. 21985614e71bSYork Sun */ 21995614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 22005614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 22015614e71bSYork Sun sa = common_dimm->base_address; 22025614e71bSYork Sun ea = sa + common_dimm->total_mem - 1; 22035614e71bSYork Sun break; 22045614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 22055614e71bSYork Sun if ((i >= 2) && (dimm_number == 0)) { 22065614e71bSYork Sun sa = dimm_params[dimm_number].base_address + 22075614e71bSYork Sun 2 * rank_density; 22085614e71bSYork Sun ea = sa + 2 * rank_density - 1; 22095614e71bSYork Sun } else { 22105614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 22115614e71bSYork Sun ea = sa + 2 * rank_density - 1; 22125614e71bSYork Sun } 22135614e71bSYork Sun break; 22145614e71bSYork Sun case FSL_DDR_CS0_CS1: 22155614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 22165614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 22175614e71bSYork Sun ea = sa + rank_density - 1; 22185614e71bSYork Sun if (i != 1) 22195614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 22205614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 22215614e71bSYork Sun } else { 22225614e71bSYork Sun sa = 0; 22235614e71bSYork Sun ea = 0; 22245614e71bSYork Sun } 22255614e71bSYork Sun if (i == 0) 22265614e71bSYork Sun ea += rank_density; 22275614e71bSYork Sun break; 22285614e71bSYork Sun case FSL_DDR_CS2_CS3: 22295614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 22305614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 22315614e71bSYork Sun ea = sa + rank_density - 1; 22325614e71bSYork Sun if (i != 3) 22335614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 22345614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 22355614e71bSYork Sun } else { 22365614e71bSYork Sun sa = 0; 22375614e71bSYork Sun ea = 0; 22385614e71bSYork Sun } 22395614e71bSYork Sun if (i == 2) 22405614e71bSYork Sun ea += (rank_density >> dbw_cap_adj); 22415614e71bSYork Sun break; 22425614e71bSYork Sun default: /* No bank(chip-select) interleaving */ 22435614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 22445614e71bSYork Sun ea = sa + rank_density - 1; 22455614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 22465614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 22475614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 22485614e71bSYork Sun } else { 22495614e71bSYork Sun sa = 0; 22505614e71bSYork Sun ea = 0; 22515614e71bSYork Sun } 22525614e71bSYork Sun break; 22535614e71bSYork Sun } 22545614e71bSYork Sun } 22555614e71bSYork Sun 22565614e71bSYork Sun sa >>= 24; 22575614e71bSYork Sun ea >>= 24; 22585614e71bSYork Sun 22595614e71bSYork Sun if (cs_en) { 22605614e71bSYork Sun ddr->cs[i].bnds = (0 2261d4263b8aSYork Sun | ((sa & 0xffff) << 16) /* starting address */ 2262d4263b8aSYork Sun | ((ea & 0xffff) << 0) /* ending address */ 22635614e71bSYork Sun ); 22645614e71bSYork Sun } else { 22655614e71bSYork Sun /* setting bnds to 0xffffffff for inactive CS */ 22665614e71bSYork Sun ddr->cs[i].bnds = 0xffffffff; 22675614e71bSYork Sun } 22685614e71bSYork Sun 22695614e71bSYork Sun debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds); 22705614e71bSYork Sun set_csn_config(dimm_number, i, ddr, popts, dimm_params); 22715614e71bSYork Sun set_csn_config_2(i, ddr); 22725614e71bSYork Sun } 22735614e71bSYork Sun 22745614e71bSYork Sun /* 22755614e71bSYork Sun * In the case we only need to compute the ddr sdram size, we only need 22765614e71bSYork Sun * to set csn registers, so return from here. 22775614e71bSYork Sun */ 22785614e71bSYork Sun if (size_only) 22795614e71bSYork Sun return 0; 22805614e71bSYork Sun 22815614e71bSYork Sun set_ddr_eor(ddr, popts); 22825614e71bSYork Sun 22835614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1) 22845614e71bSYork Sun set_timing_cfg_0(ddr, popts, dimm_params); 22855614e71bSYork Sun #endif 22865614e71bSYork Sun 2287d4263b8aSYork Sun set_timing_cfg_3(ddr, popts, common_dimm, cas_latency, 2288d4263b8aSYork Sun additive_latency); 22895614e71bSYork Sun set_timing_cfg_1(ddr, popts, common_dimm, cas_latency); 22905614e71bSYork Sun set_timing_cfg_2(ddr, popts, common_dimm, 22915614e71bSYork Sun cas_latency, additive_latency); 22925614e71bSYork Sun 22935614e71bSYork Sun set_ddr_cdr1(ddr, popts); 22945614e71bSYork Sun set_ddr_cdr2(ddr, popts); 22955614e71bSYork Sun set_ddr_sdram_cfg(ddr, popts, common_dimm); 22965614e71bSYork Sun ip_rev = fsl_ddr_get_version(); 22975614e71bSYork Sun if (ip_rev > 0x40400) 22985614e71bSYork Sun unq_mrs_en = 1; 22995614e71bSYork Sun 2300*f80d6472SYork Sun if ((ip_rev > 0x40700) && (popts->cswl_override != 0)) 2301ef87cab6SYork Sun ddr->debug[18] = popts->cswl_override; 2302ef87cab6SYork Sun 23035614e71bSYork Sun set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en); 23045614e71bSYork Sun set_ddr_sdram_mode(ddr, popts, common_dimm, 23055614e71bSYork Sun cas_latency, additive_latency, unq_mrs_en); 23065614e71bSYork Sun set_ddr_sdram_mode_2(ddr, popts, common_dimm, unq_mrs_en); 230734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 230834e026f9SYork Sun set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en); 230934e026f9SYork Sun set_ddr_sdram_mode_10(ddr, popts, common_dimm, unq_mrs_en); 231034e026f9SYork Sun #endif 23115614e71bSYork Sun set_ddr_sdram_interval(ddr, popts, common_dimm); 23125614e71bSYork Sun set_ddr_data_init(ddr); 23135614e71bSYork Sun set_ddr_sdram_clk_cntl(ddr, popts); 23145614e71bSYork Sun set_ddr_init_addr(ddr); 23155614e71bSYork Sun set_ddr_init_ext_addr(ddr); 23165614e71bSYork Sun set_timing_cfg_4(ddr, popts); 23175614e71bSYork Sun set_timing_cfg_5(ddr, cas_latency); 231834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 231934e026f9SYork Sun set_ddr_sdram_cfg_3(ddr, popts); 232034e026f9SYork Sun set_timing_cfg_6(ddr); 232134e026f9SYork Sun set_timing_cfg_7(ddr, common_dimm); 232234e026f9SYork Sun set_timing_cfg_8(ddr, popts, common_dimm, cas_latency); 232334e026f9SYork Sun set_timing_cfg_9(ddr); 232434e026f9SYork Sun set_ddr_dq_mapping(ddr, dimm_params); 232534e026f9SYork Sun #endif 23265614e71bSYork Sun 23275614e71bSYork Sun set_ddr_zq_cntl(ddr, zq_en); 23285614e71bSYork Sun set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts); 23295614e71bSYork Sun 23305614e71bSYork Sun set_ddr_sr_cntr(ddr, sr_it); 23315614e71bSYork Sun 23325614e71bSYork Sun set_ddr_sdram_rcw(ddr, popts, common_dimm); 23335614e71bSYork Sun 23345614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR_EMU 23355614e71bSYork Sun /* disble DDR training for emulator */ 23365614e71bSYork Sun ddr->debug[2] = 0x00000400; 23375614e71bSYork Sun ddr->debug[4] = 0xff800000; 23385614e71bSYork Sun #endif 23399855b3beSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_A004508 23409855b3beSYork Sun if ((ip_rev >= 0x40000) && (ip_rev < 0x40400)) 23419855b3beSYork Sun ddr->debug[2] |= 0x00000200; /* set bit 22 */ 23429855b3beSYork Sun #endif 23439855b3beSYork Sun 23445614e71bSYork Sun return check_fsl_memctl_config_regs(ddr); 23455614e71bSYork Sun } 2346