15614e71bSYork Sun /* 234e026f9SYork Sun * Copyright 2008-2014 Freescale Semiconductor, Inc. 35614e71bSYork Sun * 45614e71bSYork Sun * SPDX-License-Identifier: GPL-2.0+ 55614e71bSYork Sun */ 65614e71bSYork Sun 75614e71bSYork Sun /* 85614e71bSYork Sun * Generic driver for Freescale DDR/DDR2/DDR3 memory controller. 95614e71bSYork Sun * Based on code from spd_sdram.c 105614e71bSYork Sun * Author: James Yang [at freescale.com] 115614e71bSYork Sun */ 125614e71bSYork Sun 135614e71bSYork Sun #include <common.h> 145614e71bSYork Sun #include <fsl_ddr_sdram.h> 155614e71bSYork Sun 165614e71bSYork Sun #include <fsl_ddr.h> 179a17eb5bSYork Sun #include <fsl_immap.h> 185614e71bSYork Sun #include <asm/io.h> 195614e71bSYork Sun 205614e71bSYork Sun /* 215614e71bSYork Sun * Determine Rtt value. 225614e71bSYork Sun * 235614e71bSYork Sun * This should likely be either board or controller specific. 245614e71bSYork Sun * 255614e71bSYork Sun * Rtt(nominal) - DDR2: 265614e71bSYork Sun * 0 = Rtt disabled 275614e71bSYork Sun * 1 = 75 ohm 285614e71bSYork Sun * 2 = 150 ohm 295614e71bSYork Sun * 3 = 50 ohm 305614e71bSYork Sun * Rtt(nominal) - DDR3: 315614e71bSYork Sun * 0 = Rtt disabled 325614e71bSYork Sun * 1 = 60 ohm 335614e71bSYork Sun * 2 = 120 ohm 345614e71bSYork Sun * 3 = 40 ohm 355614e71bSYork Sun * 4 = 20 ohm 365614e71bSYork Sun * 5 = 30 ohm 375614e71bSYork Sun * 385614e71bSYork Sun * FIXME: Apparently 8641 needs a value of 2 395614e71bSYork Sun * FIXME: Old code seys if 667 MHz or higher, use 3 on 8572 405614e71bSYork Sun * 415614e71bSYork Sun * FIXME: There was some effort down this line earlier: 425614e71bSYork Sun * 435614e71bSYork Sun * unsigned int i; 445614e71bSYork Sun * for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL/2; i++) { 455614e71bSYork Sun * if (popts->dimmslot[i].num_valid_cs 465614e71bSYork Sun * && (popts->cs_local_opts[2*i].odt_rd_cfg 475614e71bSYork Sun * || popts->cs_local_opts[2*i].odt_wr_cfg)) { 485614e71bSYork Sun * rtt = 2; 495614e71bSYork Sun * break; 505614e71bSYork Sun * } 515614e71bSYork Sun * } 525614e71bSYork Sun */ 535614e71bSYork Sun static inline int fsl_ddr_get_rtt(void) 545614e71bSYork Sun { 555614e71bSYork Sun int rtt; 565614e71bSYork Sun 575614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 585614e71bSYork Sun rtt = 0; 595614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 605614e71bSYork Sun rtt = 3; 615614e71bSYork Sun #else 625614e71bSYork Sun rtt = 0; 635614e71bSYork Sun #endif 645614e71bSYork Sun 655614e71bSYork Sun return rtt; 665614e71bSYork Sun } 675614e71bSYork Sun 6834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 6934e026f9SYork Sun /* 7034e026f9SYork Sun * compute CAS write latency according to DDR4 spec 7134e026f9SYork Sun * CWL = 9 for <= 1600MT/s 7234e026f9SYork Sun * 10 for <= 1866MT/s 7334e026f9SYork Sun * 11 for <= 2133MT/s 7434e026f9SYork Sun * 12 for <= 2400MT/s 7534e026f9SYork Sun * 14 for <= 2667MT/s 7634e026f9SYork Sun * 16 for <= 2933MT/s 7734e026f9SYork Sun * 18 for higher 7834e026f9SYork Sun */ 7903e664d8SYork Sun static inline unsigned int compute_cas_write_latency( 8003e664d8SYork Sun const unsigned int ctrl_num) 8134e026f9SYork Sun { 8234e026f9SYork Sun unsigned int cwl; 8303e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 8434e026f9SYork Sun if (mclk_ps >= 1250) 8534e026f9SYork Sun cwl = 9; 8634e026f9SYork Sun else if (mclk_ps >= 1070) 8734e026f9SYork Sun cwl = 10; 8834e026f9SYork Sun else if (mclk_ps >= 935) 8934e026f9SYork Sun cwl = 11; 9034e026f9SYork Sun else if (mclk_ps >= 833) 9134e026f9SYork Sun cwl = 12; 9234e026f9SYork Sun else if (mclk_ps >= 750) 9334e026f9SYork Sun cwl = 14; 9434e026f9SYork Sun else if (mclk_ps >= 681) 9534e026f9SYork Sun cwl = 16; 9634e026f9SYork Sun else 9734e026f9SYork Sun cwl = 18; 9834e026f9SYork Sun 9934e026f9SYork Sun return cwl; 10034e026f9SYork Sun } 10134e026f9SYork Sun #else 1025614e71bSYork Sun /* 1035614e71bSYork Sun * compute the CAS write latency according to DDR3 spec 1045614e71bSYork Sun * CWL = 5 if tCK >= 2.5ns 1055614e71bSYork Sun * 6 if 2.5ns > tCK >= 1.875ns 1065614e71bSYork Sun * 7 if 1.875ns > tCK >= 1.5ns 1075614e71bSYork Sun * 8 if 1.5ns > tCK >= 1.25ns 1085614e71bSYork Sun * 9 if 1.25ns > tCK >= 1.07ns 1095614e71bSYork Sun * 10 if 1.07ns > tCK >= 0.935ns 1105614e71bSYork Sun * 11 if 0.935ns > tCK >= 0.833ns 1115614e71bSYork Sun * 12 if 0.833ns > tCK >= 0.75ns 1125614e71bSYork Sun */ 11303e664d8SYork Sun static inline unsigned int compute_cas_write_latency( 11403e664d8SYork Sun const unsigned int ctrl_num) 1155614e71bSYork Sun { 1165614e71bSYork Sun unsigned int cwl; 11703e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 1185614e71bSYork Sun 1195614e71bSYork Sun if (mclk_ps >= 2500) 1205614e71bSYork Sun cwl = 5; 1215614e71bSYork Sun else if (mclk_ps >= 1875) 1225614e71bSYork Sun cwl = 6; 1235614e71bSYork Sun else if (mclk_ps >= 1500) 1245614e71bSYork Sun cwl = 7; 1255614e71bSYork Sun else if (mclk_ps >= 1250) 1265614e71bSYork Sun cwl = 8; 1275614e71bSYork Sun else if (mclk_ps >= 1070) 1285614e71bSYork Sun cwl = 9; 1295614e71bSYork Sun else if (mclk_ps >= 935) 1305614e71bSYork Sun cwl = 10; 1315614e71bSYork Sun else if (mclk_ps >= 833) 1325614e71bSYork Sun cwl = 11; 1335614e71bSYork Sun else if (mclk_ps >= 750) 1345614e71bSYork Sun cwl = 12; 1355614e71bSYork Sun else { 1365614e71bSYork Sun cwl = 12; 1375614e71bSYork Sun printf("Warning: CWL is out of range\n"); 1385614e71bSYork Sun } 1395614e71bSYork Sun return cwl; 1405614e71bSYork Sun } 14134e026f9SYork Sun #endif 1425614e71bSYork Sun 1435614e71bSYork Sun /* Chip Select Configuration (CSn_CONFIG) */ 1445614e71bSYork Sun static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, 1455614e71bSYork Sun const memctl_options_t *popts, 1465614e71bSYork Sun const dimm_params_t *dimm_params) 1475614e71bSYork Sun { 1485614e71bSYork Sun unsigned int cs_n_en = 0; /* Chip Select enable */ 1495614e71bSYork Sun unsigned int intlv_en = 0; /* Memory controller interleave enable */ 1505614e71bSYork Sun unsigned int intlv_ctl = 0; /* Interleaving control */ 1515614e71bSYork Sun unsigned int ap_n_en = 0; /* Chip select n auto-precharge enable */ 1525614e71bSYork Sun unsigned int odt_rd_cfg = 0; /* ODT for reads configuration */ 1535614e71bSYork Sun unsigned int odt_wr_cfg = 0; /* ODT for writes configuration */ 1545614e71bSYork Sun unsigned int ba_bits_cs_n = 0; /* Num of bank bits for SDRAM on CSn */ 1555614e71bSYork Sun unsigned int row_bits_cs_n = 0; /* Num of row bits for SDRAM on CSn */ 1565614e71bSYork Sun unsigned int col_bits_cs_n = 0; /* Num of ocl bits for SDRAM on CSn */ 1575614e71bSYork Sun int go_config = 0; 15834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 15934e026f9SYork Sun unsigned int bg_bits_cs_n = 0; /* Num of bank group bits */ 16034e026f9SYork Sun #else 16134e026f9SYork Sun unsigned int n_banks_per_sdram_device; 16234e026f9SYork Sun #endif 1635614e71bSYork Sun 1645614e71bSYork Sun /* Compute CS_CONFIG only for existing ranks of each DIMM. */ 1655614e71bSYork Sun switch (i) { 1665614e71bSYork Sun case 0: 1675614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > 0) { 1685614e71bSYork Sun go_config = 1; 1695614e71bSYork Sun /* These fields only available in CS0_CONFIG */ 1705614e71bSYork Sun if (!popts->memctl_interleaving) 1715614e71bSYork Sun break; 1725614e71bSYork Sun switch (popts->memctl_interleaving_mode) { 1736b1e1254SYork Sun case FSL_DDR_256B_INTERLEAVING: 1745614e71bSYork Sun case FSL_DDR_CACHE_LINE_INTERLEAVING: 1755614e71bSYork Sun case FSL_DDR_PAGE_INTERLEAVING: 1765614e71bSYork Sun case FSL_DDR_BANK_INTERLEAVING: 1775614e71bSYork Sun case FSL_DDR_SUPERBANK_INTERLEAVING: 1785614e71bSYork Sun intlv_en = popts->memctl_interleaving; 1795614e71bSYork Sun intlv_ctl = popts->memctl_interleaving_mode; 1805614e71bSYork Sun break; 1815614e71bSYork Sun default: 1825614e71bSYork Sun break; 1835614e71bSYork Sun } 1845614e71bSYork Sun } 1855614e71bSYork Sun break; 1865614e71bSYork Sun case 1: 1875614e71bSYork Sun if ((dimm_number == 0 && dimm_params[0].n_ranks > 1) || \ 1885614e71bSYork Sun (dimm_number == 1 && dimm_params[1].n_ranks > 0)) 1895614e71bSYork Sun go_config = 1; 1905614e71bSYork Sun break; 1915614e71bSYork Sun case 2: 1925614e71bSYork Sun if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \ 1935614e71bSYork Sun (dimm_number >= 1 && dimm_params[dimm_number].n_ranks > 0)) 1945614e71bSYork Sun go_config = 1; 1955614e71bSYork Sun break; 1965614e71bSYork Sun case 3: 1975614e71bSYork Sun if ((dimm_number == 0 && dimm_params[0].n_ranks > 3) || \ 1985614e71bSYork Sun (dimm_number == 1 && dimm_params[1].n_ranks > 1) || \ 1995614e71bSYork Sun (dimm_number == 3 && dimm_params[3].n_ranks > 0)) 2005614e71bSYork Sun go_config = 1; 2015614e71bSYork Sun break; 2025614e71bSYork Sun default: 2035614e71bSYork Sun break; 2045614e71bSYork Sun } 2055614e71bSYork Sun if (go_config) { 2065614e71bSYork Sun cs_n_en = 1; 2075614e71bSYork Sun ap_n_en = popts->cs_local_opts[i].auto_precharge; 2085614e71bSYork Sun odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg; 2095614e71bSYork Sun odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg; 21034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 21134e026f9SYork Sun ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits; 21234e026f9SYork Sun bg_bits_cs_n = dimm_params[dimm_number].bank_group_bits; 21334e026f9SYork Sun #else 2145614e71bSYork Sun n_banks_per_sdram_device 2155614e71bSYork Sun = dimm_params[dimm_number].n_banks_per_sdram_device; 2165614e71bSYork Sun ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2; 21734e026f9SYork Sun #endif 2185614e71bSYork Sun row_bits_cs_n = dimm_params[dimm_number].n_row_addr - 12; 2195614e71bSYork Sun col_bits_cs_n = dimm_params[dimm_number].n_col_addr - 8; 2205614e71bSYork Sun } 2215614e71bSYork Sun ddr->cs[i].config = (0 2225614e71bSYork Sun | ((cs_n_en & 0x1) << 31) 2235614e71bSYork Sun | ((intlv_en & 0x3) << 29) 2245614e71bSYork Sun | ((intlv_ctl & 0xf) << 24) 2255614e71bSYork Sun | ((ap_n_en & 0x1) << 23) 2265614e71bSYork Sun 2275614e71bSYork Sun /* XXX: some implementation only have 1 bit starting at left */ 2285614e71bSYork Sun | ((odt_rd_cfg & 0x7) << 20) 2295614e71bSYork Sun 2305614e71bSYork Sun /* XXX: Some implementation only have 1 bit starting at left */ 2315614e71bSYork Sun | ((odt_wr_cfg & 0x7) << 16) 2325614e71bSYork Sun 2335614e71bSYork Sun | ((ba_bits_cs_n & 0x3) << 14) 2345614e71bSYork Sun | ((row_bits_cs_n & 0x7) << 8) 23534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 23634e026f9SYork Sun | ((bg_bits_cs_n & 0x3) << 4) 23734e026f9SYork Sun #endif 2385614e71bSYork Sun | ((col_bits_cs_n & 0x7) << 0) 2395614e71bSYork Sun ); 2405614e71bSYork Sun debug("FSLDDR: cs[%d]_config = 0x%08x\n", i,ddr->cs[i].config); 2415614e71bSYork Sun } 2425614e71bSYork Sun 2435614e71bSYork Sun /* Chip Select Configuration 2 (CSn_CONFIG_2) */ 2445614e71bSYork Sun /* FIXME: 8572 */ 2455614e71bSYork Sun static void set_csn_config_2(int i, fsl_ddr_cfg_regs_t *ddr) 2465614e71bSYork Sun { 2475614e71bSYork Sun unsigned int pasr_cfg = 0; /* Partial array self refresh config */ 2485614e71bSYork Sun 2495614e71bSYork Sun ddr->cs[i].config_2 = ((pasr_cfg & 7) << 24); 2505614e71bSYork Sun debug("FSLDDR: cs[%d]_config_2 = 0x%08x\n", i, ddr->cs[i].config_2); 2515614e71bSYork Sun } 2525614e71bSYork Sun 2535614e71bSYork Sun /* -3E = 667 CL5, -25 = CL6 800, -25E = CL5 800 */ 2545614e71bSYork Sun 2555614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1) 25684baed2aSYork Sun /* 25784baed2aSYork Sun * Check DIMM configuration, return 2 if quad-rank or two dual-rank 25884baed2aSYork Sun * Return 1 if other two slots configuration. Return 0 if single slot. 25984baed2aSYork Sun */ 2605614e71bSYork Sun static inline int avoid_odt_overlap(const dimm_params_t *dimm_params) 2615614e71bSYork Sun { 2625614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 1 2635614e71bSYork Sun if (dimm_params[0].n_ranks == 4) 26484baed2aSYork Sun return 2; 2655614e71bSYork Sun #endif 2665614e71bSYork Sun 2675614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 2 2685614e71bSYork Sun if ((dimm_params[0].n_ranks == 2) && 2695614e71bSYork Sun (dimm_params[1].n_ranks == 2)) 27084baed2aSYork Sun return 2; 2715614e71bSYork Sun 2725614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE 2735614e71bSYork Sun if (dimm_params[0].n_ranks == 4) 27484baed2aSYork Sun return 2; 2755614e71bSYork Sun #endif 27684baed2aSYork Sun 27784baed2aSYork Sun if ((dimm_params[0].n_ranks != 0) && 27884baed2aSYork Sun (dimm_params[2].n_ranks != 0)) 27984baed2aSYork Sun return 1; 2805614e71bSYork Sun #endif 2815614e71bSYork Sun return 0; 2825614e71bSYork Sun } 2835614e71bSYork Sun 2845614e71bSYork Sun /* 2855614e71bSYork Sun * DDR SDRAM Timing Configuration 0 (TIMING_CFG_0) 2865614e71bSYork Sun * 2875614e71bSYork Sun * Avoid writing for DDR I. The new PQ38 DDR controller 2885614e71bSYork Sun * dreams up non-zero default values to be backwards compatible. 2895614e71bSYork Sun */ 29003e664d8SYork Sun static void set_timing_cfg_0(const unsigned int ctrl_num, 29103e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 2925614e71bSYork Sun const memctl_options_t *popts, 2935614e71bSYork Sun const dimm_params_t *dimm_params) 2945614e71bSYork Sun { 2955614e71bSYork Sun unsigned char trwt_mclk = 0; /* Read-to-write turnaround */ 2965614e71bSYork Sun unsigned char twrt_mclk = 0; /* Write-to-read turnaround */ 2975614e71bSYork Sun /* 7.5 ns on -3E; 0 means WL - CL + BL/2 + 1 */ 2985614e71bSYork Sun unsigned char trrt_mclk = 0; /* Read-to-read turnaround */ 2995614e71bSYork Sun unsigned char twwt_mclk = 0; /* Write-to-write turnaround */ 3005614e71bSYork Sun 3015614e71bSYork Sun /* Active powerdown exit timing (tXARD and tXARDS). */ 3025614e71bSYork Sun unsigned char act_pd_exit_mclk; 3035614e71bSYork Sun /* Precharge powerdown exit timing (tXP). */ 3045614e71bSYork Sun unsigned char pre_pd_exit_mclk; 3055614e71bSYork Sun /* ODT powerdown exit timing (tAXPD). */ 30634e026f9SYork Sun unsigned char taxpd_mclk = 0; 3075614e71bSYork Sun /* Mode register set cycle time (tMRD). */ 3085614e71bSYork Sun unsigned char tmrd_mclk; 309bb578322SYork Sun #if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3) 31003e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 311bb578322SYork Sun #endif 3125614e71bSYork Sun 31334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 31434e026f9SYork Sun /* tXP=max(4nCK, 6ns) */ 315b4141195SMasahiro Yamada int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */ 31666869f95SYork Sun unsigned int data_rate = get_ddr_freq(ctrl_num); 31766869f95SYork Sun 31866869f95SYork Sun /* for faster clock, need more time for data setup */ 31966869f95SYork Sun trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2; 32034e026f9SYork Sun twrt_mclk = 1; 32103e664d8SYork Sun act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); 32234e026f9SYork Sun pre_pd_exit_mclk = act_pd_exit_mclk; 32334e026f9SYork Sun /* 32434e026f9SYork Sun * MRS_CYC = max(tMRD, tMOD) 32534e026f9SYork Sun * tMRD = 8nCK, tMOD = max(24nCK, 15ns) 32634e026f9SYork Sun */ 32703e664d8SYork Sun tmrd_mclk = max(24U, picos_to_mclk(ctrl_num, 15000)); 32834e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 32903e664d8SYork Sun unsigned int data_rate = get_ddr_freq(ctrl_num); 330bb578322SYork Sun int txp; 331938bbb60SYork Sun unsigned int ip_rev; 33284baed2aSYork Sun int odt_overlap; 3335614e71bSYork Sun /* 3345614e71bSYork Sun * (tXARD and tXARDS). Empirical? 3355614e71bSYork Sun * The DDR3 spec has not tXARD, 3365614e71bSYork Sun * we use the tXP instead of it. 337bb578322SYork Sun * tXP=max(3nCK, 7.5ns) for DDR3-800, 1066 338bb578322SYork Sun * max(3nCK, 6ns) for DDR3-1333, 1600, 1866, 2133 3395614e71bSYork Sun * spec has not the tAXPD, we use 3405614e71bSYork Sun * tAXPD=1, need design to confirm. 3415614e71bSYork Sun */ 342b4141195SMasahiro Yamada txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000)); 343bb578322SYork Sun 34466869f95SYork Sun ip_rev = fsl_ddr_get_version(ctrl_num); 345938bbb60SYork Sun if (ip_rev >= 0x40700) { 346938bbb60SYork Sun /* 347938bbb60SYork Sun * MRS_CYC = max(tMRD, tMOD) 348938bbb60SYork Sun * tMRD = 4nCK (8nCK for RDIMM) 349938bbb60SYork Sun * tMOD = max(12nCK, 15ns) 350938bbb60SYork Sun */ 35103e664d8SYork Sun tmrd_mclk = max((unsigned int)12, 35203e664d8SYork Sun picos_to_mclk(ctrl_num, 15000)); 353938bbb60SYork Sun } else { 354938bbb60SYork Sun /* 355938bbb60SYork Sun * MRS_CYC = tMRD 356938bbb60SYork Sun * tMRD = 4nCK (8nCK for RDIMM) 357938bbb60SYork Sun */ 358938bbb60SYork Sun if (popts->registered_dimm_en) 359938bbb60SYork Sun tmrd_mclk = 8; 360938bbb60SYork Sun else 3615614e71bSYork Sun tmrd_mclk = 4; 362938bbb60SYork Sun } 363938bbb60SYork Sun 3645614e71bSYork Sun /* set the turnaround time */ 3655614e71bSYork Sun 3665614e71bSYork Sun /* 36784baed2aSYork Sun * for single quad-rank DIMM and two-slot DIMMs 3685614e71bSYork Sun * to avoid ODT overlap 3695614e71bSYork Sun */ 37084baed2aSYork Sun odt_overlap = avoid_odt_overlap(dimm_params); 37184baed2aSYork Sun switch (odt_overlap) { 37284baed2aSYork Sun case 2: 3735614e71bSYork Sun twwt_mclk = 2; 3745614e71bSYork Sun trrt_mclk = 1; 37584baed2aSYork Sun break; 37684baed2aSYork Sun case 1: 37784baed2aSYork Sun twwt_mclk = 1; 37884baed2aSYork Sun trrt_mclk = 0; 37984baed2aSYork Sun break; 38084baed2aSYork Sun default: 38184baed2aSYork Sun break; 3825614e71bSYork Sun } 38384baed2aSYork Sun 3845614e71bSYork Sun /* for faster clock, need more time for data setup */ 3855614e71bSYork Sun trwt_mclk = (data_rate/1000000 > 1800) ? 2 : 1; 3865614e71bSYork Sun 3875614e71bSYork Sun if ((data_rate/1000000 > 1150) || (popts->memctl_interleaving)) 3885614e71bSYork Sun twrt_mclk = 1; 3895614e71bSYork Sun 3905614e71bSYork Sun if (popts->dynamic_power == 0) { /* powerdown is not used */ 3915614e71bSYork Sun act_pd_exit_mclk = 1; 3925614e71bSYork Sun pre_pd_exit_mclk = 1; 3935614e71bSYork Sun taxpd_mclk = 1; 3945614e71bSYork Sun } else { 3955614e71bSYork Sun /* act_pd_exit_mclk = tXARD, see above */ 39603e664d8SYork Sun act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); 3975614e71bSYork Sun /* Mode register MR0[A12] is '1' - fast exit */ 3985614e71bSYork Sun pre_pd_exit_mclk = act_pd_exit_mclk; 3995614e71bSYork Sun taxpd_mclk = 1; 4005614e71bSYork Sun } 4015614e71bSYork Sun #else /* CONFIG_SYS_FSL_DDR2 */ 4025614e71bSYork Sun /* 4035614e71bSYork Sun * (tXARD and tXARDS). Empirical? 4045614e71bSYork Sun * tXARD = 2 for DDR2 4055614e71bSYork Sun * tXP=2 4065614e71bSYork Sun * tAXPD=8 4075614e71bSYork Sun */ 4085614e71bSYork Sun act_pd_exit_mclk = 2; 4095614e71bSYork Sun pre_pd_exit_mclk = 2; 4105614e71bSYork Sun taxpd_mclk = 8; 4115614e71bSYork Sun tmrd_mclk = 2; 4125614e71bSYork Sun #endif 4135614e71bSYork Sun 4145614e71bSYork Sun if (popts->trwt_override) 4155614e71bSYork Sun trwt_mclk = popts->trwt; 4165614e71bSYork Sun 4175614e71bSYork Sun ddr->timing_cfg_0 = (0 4185614e71bSYork Sun | ((trwt_mclk & 0x3) << 30) /* RWT */ 4195614e71bSYork Sun | ((twrt_mclk & 0x3) << 28) /* WRT */ 4205614e71bSYork Sun | ((trrt_mclk & 0x3) << 26) /* RRT */ 4215614e71bSYork Sun | ((twwt_mclk & 0x3) << 24) /* WWT */ 422d4263b8aSYork Sun | ((act_pd_exit_mclk & 0xf) << 20) /* ACT_PD_EXIT */ 4235614e71bSYork Sun | ((pre_pd_exit_mclk & 0xF) << 16) /* PRE_PD_EXIT */ 4245614e71bSYork Sun | ((taxpd_mclk & 0xf) << 8) /* ODT_PD_EXIT */ 425d4263b8aSYork Sun | ((tmrd_mclk & 0x1f) << 0) /* MRS_CYC */ 4265614e71bSYork Sun ); 4275614e71bSYork Sun debug("FSLDDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0); 4285614e71bSYork Sun } 42984baed2aSYork Sun #endif /* !defined(CONFIG_SYS_FSL_DDR1) */ 4305614e71bSYork Sun 4315614e71bSYork Sun /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ 43203e664d8SYork Sun static void set_timing_cfg_3(const unsigned int ctrl_num, 43303e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 4345614e71bSYork Sun const memctl_options_t *popts, 4355614e71bSYork Sun const common_timing_params_t *common_dimm, 436d4263b8aSYork Sun unsigned int cas_latency, 437d4263b8aSYork Sun unsigned int additive_latency) 4385614e71bSYork Sun { 4395614e71bSYork Sun /* Extended precharge to activate interval (tRP) */ 4405614e71bSYork Sun unsigned int ext_pretoact = 0; 4415614e71bSYork Sun /* Extended Activate to precharge interval (tRAS) */ 4425614e71bSYork Sun unsigned int ext_acttopre = 0; 4435614e71bSYork Sun /* Extended activate to read/write interval (tRCD) */ 4445614e71bSYork Sun unsigned int ext_acttorw = 0; 4455614e71bSYork Sun /* Extended refresh recovery time (tRFC) */ 4465614e71bSYork Sun unsigned int ext_refrec; 4475614e71bSYork Sun /* Extended MCAS latency from READ cmd */ 4485614e71bSYork Sun unsigned int ext_caslat = 0; 449d4263b8aSYork Sun /* Extended additive latency */ 450d4263b8aSYork Sun unsigned int ext_add_lat = 0; 4515614e71bSYork Sun /* Extended last data to precharge interval (tWR) */ 4525614e71bSYork Sun unsigned int ext_wrrec = 0; 4535614e71bSYork Sun /* Control Adjust */ 4545614e71bSYork Sun unsigned int cntl_adj = 0; 4555614e71bSYork Sun 45603e664d8SYork Sun ext_pretoact = picos_to_mclk(ctrl_num, common_dimm->trp_ps) >> 4; 45703e664d8SYork Sun ext_acttopre = picos_to_mclk(ctrl_num, common_dimm->tras_ps) >> 4; 45803e664d8SYork Sun ext_acttorw = picos_to_mclk(ctrl_num, common_dimm->trcd_ps) >> 4; 4595614e71bSYork Sun ext_caslat = (2 * cas_latency - 1) >> 4; 460d4263b8aSYork Sun ext_add_lat = additive_latency >> 4; 46134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 46203e664d8SYork Sun ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8) >> 4; 46334e026f9SYork Sun #else 46403e664d8SYork Sun ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8) >> 4; 4655614e71bSYork Sun /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ 46634e026f9SYork Sun #endif 46703e664d8SYork Sun ext_wrrec = (picos_to_mclk(ctrl_num, common_dimm->twr_ps) + 4685614e71bSYork Sun (popts->otf_burst_chop_en ? 2 : 0)) >> 4; 4695614e71bSYork Sun 4705614e71bSYork Sun ddr->timing_cfg_3 = (0 4715614e71bSYork Sun | ((ext_pretoact & 0x1) << 28) 4725614e71bSYork Sun | ((ext_acttopre & 0x3) << 24) 4735614e71bSYork Sun | ((ext_acttorw & 0x1) << 22) 4745614e71bSYork Sun | ((ext_refrec & 0x1F) << 16) 4755614e71bSYork Sun | ((ext_caslat & 0x3) << 12) 476d4263b8aSYork Sun | ((ext_add_lat & 0x1) << 10) 4775614e71bSYork Sun | ((ext_wrrec & 0x1) << 8) 4785614e71bSYork Sun | ((cntl_adj & 0x7) << 0) 4795614e71bSYork Sun ); 4805614e71bSYork Sun debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3); 4815614e71bSYork Sun } 4825614e71bSYork Sun 4835614e71bSYork Sun /* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */ 48403e664d8SYork Sun static void set_timing_cfg_1(const unsigned int ctrl_num, 48503e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 4865614e71bSYork Sun const memctl_options_t *popts, 4875614e71bSYork Sun const common_timing_params_t *common_dimm, 4885614e71bSYork Sun unsigned int cas_latency) 4895614e71bSYork Sun { 4905614e71bSYork Sun /* Precharge-to-activate interval (tRP) */ 4915614e71bSYork Sun unsigned char pretoact_mclk; 4925614e71bSYork Sun /* Activate to precharge interval (tRAS) */ 4935614e71bSYork Sun unsigned char acttopre_mclk; 4945614e71bSYork Sun /* Activate to read/write interval (tRCD) */ 4955614e71bSYork Sun unsigned char acttorw_mclk; 4965614e71bSYork Sun /* CASLAT */ 4975614e71bSYork Sun unsigned char caslat_ctrl; 4985614e71bSYork Sun /* Refresh recovery time (tRFC) ; trfc_low */ 4995614e71bSYork Sun unsigned char refrec_ctrl; 5005614e71bSYork Sun /* Last data to precharge minimum interval (tWR) */ 5015614e71bSYork Sun unsigned char wrrec_mclk; 5025614e71bSYork Sun /* Activate-to-activate interval (tRRD) */ 5035614e71bSYork Sun unsigned char acttoact_mclk; 5045614e71bSYork Sun /* Last write data pair to read command issue interval (tWTR) */ 5055614e71bSYork Sun unsigned char wrtord_mclk; 50634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 50734e026f9SYork Sun /* DDR4 supports 10, 12, 14, 16, 18, 20, 24 */ 50834e026f9SYork Sun static const u8 wrrec_table[] = { 50934e026f9SYork Sun 10, 10, 10, 10, 10, 51034e026f9SYork Sun 10, 10, 10, 10, 10, 51134e026f9SYork Sun 12, 12, 14, 14, 16, 51234e026f9SYork Sun 16, 18, 18, 20, 20, 51334e026f9SYork Sun 24, 24, 24, 24}; 51434e026f9SYork Sun #else 5155614e71bSYork Sun /* DDR_SDRAM_MODE doesn't support 9,11,13,15 */ 5165614e71bSYork Sun static const u8 wrrec_table[] = { 5175614e71bSYork Sun 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0}; 51834e026f9SYork Sun #endif 5195614e71bSYork Sun 52003e664d8SYork Sun pretoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trp_ps); 52103e664d8SYork Sun acttopre_mclk = picos_to_mclk(ctrl_num, common_dimm->tras_ps); 52203e664d8SYork Sun acttorw_mclk = picos_to_mclk(ctrl_num, common_dimm->trcd_ps); 5235614e71bSYork Sun 5245614e71bSYork Sun /* 5255614e71bSYork Sun * Translate CAS Latency to a DDR controller field value: 5265614e71bSYork Sun * 5275614e71bSYork Sun * CAS Lat DDR I DDR II Ctrl 5285614e71bSYork Sun * Clocks SPD Bit SPD Bit Value 5295614e71bSYork Sun * ------- ------- ------- ----- 5305614e71bSYork Sun * 1.0 0 0001 5315614e71bSYork Sun * 1.5 1 0010 5325614e71bSYork Sun * 2.0 2 2 0011 5335614e71bSYork Sun * 2.5 3 0100 5345614e71bSYork Sun * 3.0 4 3 0101 5355614e71bSYork Sun * 3.5 5 0110 5365614e71bSYork Sun * 4.0 4 0111 5375614e71bSYork Sun * 4.5 1000 5385614e71bSYork Sun * 5.0 5 1001 5395614e71bSYork Sun */ 5405614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 5415614e71bSYork Sun caslat_ctrl = (cas_latency + 1) & 0x07; 5425614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 5435614e71bSYork Sun caslat_ctrl = 2 * cas_latency - 1; 5445614e71bSYork Sun #else 5455614e71bSYork Sun /* 5465614e71bSYork Sun * if the CAS latency more than 8 cycle, 5475614e71bSYork Sun * we need set extend bit for it at 5485614e71bSYork Sun * TIMING_CFG_3[EXT_CASLAT] 5495614e71bSYork Sun */ 55066869f95SYork Sun if (fsl_ddr_get_version(ctrl_num) <= 0x40400) 5515614e71bSYork Sun caslat_ctrl = 2 * cas_latency - 1; 55234e026f9SYork Sun else 55334e026f9SYork Sun caslat_ctrl = (cas_latency - 1) << 1; 5545614e71bSYork Sun #endif 5555614e71bSYork Sun 55634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 55703e664d8SYork Sun refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8; 55803e664d8SYork Sun wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 55903e664d8SYork Sun acttoact_mclk = max(picos_to_mclk(ctrl_num, common_dimm->trrds_ps), 4U); 56003e664d8SYork Sun wrtord_mclk = max(2U, picos_to_mclk(ctrl_num, 2500)); 561349689b8SYork Sun if ((wrrec_mclk < 1) || (wrrec_mclk > 24)) 562349689b8SYork Sun printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); 56334e026f9SYork Sun else 56434e026f9SYork Sun wrrec_mclk = wrrec_table[wrrec_mclk - 1]; 56534e026f9SYork Sun #else 56603e664d8SYork Sun refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8; 56703e664d8SYork Sun wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 56803e664d8SYork Sun acttoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trrd_ps); 56903e664d8SYork Sun wrtord_mclk = picos_to_mclk(ctrl_num, common_dimm->twtr_ps); 570349689b8SYork Sun if ((wrrec_mclk < 1) || (wrrec_mclk > 16)) 571349689b8SYork Sun printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); 5725614e71bSYork Sun else 5735614e71bSYork Sun wrrec_mclk = wrrec_table[wrrec_mclk - 1]; 57434e026f9SYork Sun #endif 5755614e71bSYork Sun if (popts->otf_burst_chop_en) 5765614e71bSYork Sun wrrec_mclk += 2; 5775614e71bSYork Sun 5785614e71bSYork Sun /* 5795614e71bSYork Sun * JEDEC has min requirement for tRRD 5805614e71bSYork Sun */ 5815614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR3) 5825614e71bSYork Sun if (acttoact_mclk < 4) 5835614e71bSYork Sun acttoact_mclk = 4; 5845614e71bSYork Sun #endif 5855614e71bSYork Sun /* 5865614e71bSYork Sun * JEDEC has some min requirements for tWTR 5875614e71bSYork Sun */ 5885614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2) 5895614e71bSYork Sun if (wrtord_mclk < 2) 5905614e71bSYork Sun wrtord_mclk = 2; 5915614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 5925614e71bSYork Sun if (wrtord_mclk < 4) 5935614e71bSYork Sun wrtord_mclk = 4; 5945614e71bSYork Sun #endif 5955614e71bSYork Sun if (popts->otf_burst_chop_en) 5965614e71bSYork Sun wrtord_mclk += 2; 5975614e71bSYork Sun 5985614e71bSYork Sun ddr->timing_cfg_1 = (0 5995614e71bSYork Sun | ((pretoact_mclk & 0x0F) << 28) 6005614e71bSYork Sun | ((acttopre_mclk & 0x0F) << 24) 6015614e71bSYork Sun | ((acttorw_mclk & 0xF) << 20) 6025614e71bSYork Sun | ((caslat_ctrl & 0xF) << 16) 6035614e71bSYork Sun | ((refrec_ctrl & 0xF) << 12) 6045614e71bSYork Sun | ((wrrec_mclk & 0x0F) << 8) 6055614e71bSYork Sun | ((acttoact_mclk & 0x0F) << 4) 6065614e71bSYork Sun | ((wrtord_mclk & 0x0F) << 0) 6075614e71bSYork Sun ); 6085614e71bSYork Sun debug("FSLDDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1); 6095614e71bSYork Sun } 6105614e71bSYork Sun 6115614e71bSYork Sun /* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */ 61203e664d8SYork Sun static void set_timing_cfg_2(const unsigned int ctrl_num, 61303e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 6145614e71bSYork Sun const memctl_options_t *popts, 6155614e71bSYork Sun const common_timing_params_t *common_dimm, 6165614e71bSYork Sun unsigned int cas_latency, 6175614e71bSYork Sun unsigned int additive_latency) 6185614e71bSYork Sun { 6195614e71bSYork Sun /* Additive latency */ 6205614e71bSYork Sun unsigned char add_lat_mclk; 6215614e71bSYork Sun /* CAS-to-preamble override */ 6225614e71bSYork Sun unsigned short cpo; 6235614e71bSYork Sun /* Write latency */ 6245614e71bSYork Sun unsigned char wr_lat; 6255614e71bSYork Sun /* Read to precharge (tRTP) */ 6265614e71bSYork Sun unsigned char rd_to_pre; 6275614e71bSYork Sun /* Write command to write data strobe timing adjustment */ 6285614e71bSYork Sun unsigned char wr_data_delay; 6295614e71bSYork Sun /* Minimum CKE pulse width (tCKE) */ 6305614e71bSYork Sun unsigned char cke_pls; 6315614e71bSYork Sun /* Window for four activates (tFAW) */ 6325614e71bSYork Sun unsigned short four_act; 633bb578322SYork Sun #ifdef CONFIG_SYS_FSL_DDR3 63403e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 635bb578322SYork Sun #endif 6365614e71bSYork Sun 6375614e71bSYork Sun /* FIXME add check that this must be less than acttorw_mclk */ 6385614e71bSYork Sun add_lat_mclk = additive_latency; 6395614e71bSYork Sun cpo = popts->cpo_override; 6405614e71bSYork Sun 6415614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 6425614e71bSYork Sun /* 6435614e71bSYork Sun * This is a lie. It should really be 1, but if it is 6445614e71bSYork Sun * set to 1, bits overlap into the old controller's 6455614e71bSYork Sun * otherwise unused ACSM field. If we leave it 0, then 6465614e71bSYork Sun * the HW will magically treat it as 1 for DDR 1. Oh Yea. 6475614e71bSYork Sun */ 6485614e71bSYork Sun wr_lat = 0; 6495614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 6505614e71bSYork Sun wr_lat = cas_latency - 1; 6515614e71bSYork Sun #else 65203e664d8SYork Sun wr_lat = compute_cas_write_latency(ctrl_num); 6535614e71bSYork Sun #endif 6545614e71bSYork Sun 65534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 65603e664d8SYork Sun rd_to_pre = picos_to_mclk(ctrl_num, 7500); 65734e026f9SYork Sun #else 65803e664d8SYork Sun rd_to_pre = picos_to_mclk(ctrl_num, common_dimm->trtp_ps); 65934e026f9SYork Sun #endif 6605614e71bSYork Sun /* 6615614e71bSYork Sun * JEDEC has some min requirements for tRTP 6625614e71bSYork Sun */ 6635614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2) 6645614e71bSYork Sun if (rd_to_pre < 2) 6655614e71bSYork Sun rd_to_pre = 2; 66634e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 6675614e71bSYork Sun if (rd_to_pre < 4) 6685614e71bSYork Sun rd_to_pre = 4; 6695614e71bSYork Sun #endif 6705614e71bSYork Sun if (popts->otf_burst_chop_en) 6715614e71bSYork Sun rd_to_pre += 2; /* according to UM */ 6725614e71bSYork Sun 6735614e71bSYork Sun wr_data_delay = popts->write_data_delay; 67434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 67534e026f9SYork Sun cpo = 0; 67603e664d8SYork Sun cke_pls = max(3U, picos_to_mclk(ctrl_num, 5000)); 677bb578322SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 678bb578322SYork Sun /* 679bb578322SYork Sun * cke pulse = max(3nCK, 7.5ns) for DDR3-800 680bb578322SYork Sun * max(3nCK, 5.625ns) for DDR3-1066, 1333 681bb578322SYork Sun * max(3nCK, 5ns) for DDR3-1600, 1866, 2133 682bb578322SYork Sun */ 68303e664d8SYork Sun cke_pls = max(3U, picos_to_mclk(ctrl_num, mclk_ps > 1870 ? 7500 : 684bb578322SYork Sun (mclk_ps > 1245 ? 5625 : 5000))); 68534e026f9SYork Sun #else 686bb578322SYork Sun cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR; 68734e026f9SYork Sun #endif 68803e664d8SYork Sun four_act = picos_to_mclk(ctrl_num, 68903e664d8SYork Sun popts->tfaw_window_four_activates_ps); 6905614e71bSYork Sun 6915614e71bSYork Sun ddr->timing_cfg_2 = (0 6925614e71bSYork Sun | ((add_lat_mclk & 0xf) << 28) 6935614e71bSYork Sun | ((cpo & 0x1f) << 23) 6945614e71bSYork Sun | ((wr_lat & 0xf) << 19) 69534e026f9SYork Sun | ((wr_lat & 0x10) << 14) 6965614e71bSYork Sun | ((rd_to_pre & RD_TO_PRE_MASK) << RD_TO_PRE_SHIFT) 6975614e71bSYork Sun | ((wr_data_delay & WR_DATA_DELAY_MASK) << WR_DATA_DELAY_SHIFT) 6985614e71bSYork Sun | ((cke_pls & 0x7) << 6) 6995614e71bSYork Sun | ((four_act & 0x3f) << 0) 7005614e71bSYork Sun ); 7015614e71bSYork Sun debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2); 7025614e71bSYork Sun } 7035614e71bSYork Sun 7045614e71bSYork Sun /* DDR SDRAM Register Control Word */ 7055614e71bSYork Sun static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, 7065614e71bSYork Sun const memctl_options_t *popts, 7075614e71bSYork Sun const common_timing_params_t *common_dimm) 7085614e71bSYork Sun { 7095614e71bSYork Sun if (common_dimm->all_dimms_registered && 7105614e71bSYork Sun !common_dimm->all_dimms_unbuffered) { 7115614e71bSYork Sun if (popts->rcw_override) { 7125614e71bSYork Sun ddr->ddr_sdram_rcw_1 = popts->rcw_1; 7135614e71bSYork Sun ddr->ddr_sdram_rcw_2 = popts->rcw_2; 7145614e71bSYork Sun } else { 7155614e71bSYork Sun ddr->ddr_sdram_rcw_1 = 7165614e71bSYork Sun common_dimm->rcw[0] << 28 | \ 7175614e71bSYork Sun common_dimm->rcw[1] << 24 | \ 7185614e71bSYork Sun common_dimm->rcw[2] << 20 | \ 7195614e71bSYork Sun common_dimm->rcw[3] << 16 | \ 7205614e71bSYork Sun common_dimm->rcw[4] << 12 | \ 7215614e71bSYork Sun common_dimm->rcw[5] << 8 | \ 7225614e71bSYork Sun common_dimm->rcw[6] << 4 | \ 7235614e71bSYork Sun common_dimm->rcw[7]; 7245614e71bSYork Sun ddr->ddr_sdram_rcw_2 = 7255614e71bSYork Sun common_dimm->rcw[8] << 28 | \ 7265614e71bSYork Sun common_dimm->rcw[9] << 24 | \ 7275614e71bSYork Sun common_dimm->rcw[10] << 20 | \ 7285614e71bSYork Sun common_dimm->rcw[11] << 16 | \ 7295614e71bSYork Sun common_dimm->rcw[12] << 12 | \ 7305614e71bSYork Sun common_dimm->rcw[13] << 8 | \ 7315614e71bSYork Sun common_dimm->rcw[14] << 4 | \ 7325614e71bSYork Sun common_dimm->rcw[15]; 7335614e71bSYork Sun } 7345614e71bSYork Sun debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1); 7355614e71bSYork Sun debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2); 7365614e71bSYork Sun } 7375614e71bSYork Sun } 7385614e71bSYork Sun 7395614e71bSYork Sun /* DDR SDRAM control configuration (DDR_SDRAM_CFG) */ 7405614e71bSYork Sun static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, 7415614e71bSYork Sun const memctl_options_t *popts, 7425614e71bSYork Sun const common_timing_params_t *common_dimm) 7435614e71bSYork Sun { 7445614e71bSYork Sun unsigned int mem_en; /* DDR SDRAM interface logic enable */ 7455614e71bSYork Sun unsigned int sren; /* Self refresh enable (during sleep) */ 7465614e71bSYork Sun unsigned int ecc_en; /* ECC enable. */ 7475614e71bSYork Sun unsigned int rd_en; /* Registered DIMM enable */ 7485614e71bSYork Sun unsigned int sdram_type; /* Type of SDRAM */ 7495614e71bSYork Sun unsigned int dyn_pwr; /* Dynamic power management mode */ 7505614e71bSYork Sun unsigned int dbw; /* DRAM dta bus width */ 7515614e71bSYork Sun unsigned int eight_be = 0; /* 8-beat burst enable, DDR2 is zero */ 7525614e71bSYork Sun unsigned int ncap = 0; /* Non-concurrent auto-precharge */ 7535614e71bSYork Sun unsigned int threet_en; /* Enable 3T timing */ 7545614e71bSYork Sun unsigned int twot_en; /* Enable 2T timing */ 7555614e71bSYork Sun unsigned int ba_intlv_ctl; /* Bank (CS) interleaving control */ 7565614e71bSYork Sun unsigned int x32_en = 0; /* x32 enable */ 7575614e71bSYork Sun unsigned int pchb8 = 0; /* precharge bit 8 enable */ 7585614e71bSYork Sun unsigned int hse; /* Global half strength override */ 759d28cb671SYork Sun unsigned int acc_ecc_en = 0; /* Accumulated ECC enable */ 7605614e71bSYork Sun unsigned int mem_halt = 0; /* memory controller halt */ 7615614e71bSYork Sun unsigned int bi = 0; /* Bypass initialization */ 7625614e71bSYork Sun 7635614e71bSYork Sun mem_en = 1; 7645614e71bSYork Sun sren = popts->self_refresh_in_sleep; 7655614e71bSYork Sun if (common_dimm->all_dimms_ecc_capable) { 7665614e71bSYork Sun /* Allow setting of ECC only if all DIMMs are ECC. */ 7675614e71bSYork Sun ecc_en = popts->ecc_mode; 7685614e71bSYork Sun } else { 7695614e71bSYork Sun ecc_en = 0; 7705614e71bSYork Sun } 7715614e71bSYork Sun 7725614e71bSYork Sun if (common_dimm->all_dimms_registered && 7735614e71bSYork Sun !common_dimm->all_dimms_unbuffered) { 7745614e71bSYork Sun rd_en = 1; 7755614e71bSYork Sun twot_en = 0; 7765614e71bSYork Sun } else { 7775614e71bSYork Sun rd_en = 0; 7785614e71bSYork Sun twot_en = popts->twot_en; 7795614e71bSYork Sun } 7805614e71bSYork Sun 7815614e71bSYork Sun sdram_type = CONFIG_FSL_SDRAM_TYPE; 7825614e71bSYork Sun 7835614e71bSYork Sun dyn_pwr = popts->dynamic_power; 7845614e71bSYork Sun dbw = popts->data_bus_width; 7855614e71bSYork Sun /* 8-beat burst enable DDR-III case 7865614e71bSYork Sun * we must clear it when use the on-the-fly mode, 7875614e71bSYork Sun * must set it when use the 32-bits bus mode. 7885614e71bSYork Sun */ 78934e026f9SYork Sun if ((sdram_type == SDRAM_TYPE_DDR3) || 79034e026f9SYork Sun (sdram_type == SDRAM_TYPE_DDR4)) { 7915614e71bSYork Sun if (popts->burst_length == DDR_BL8) 7925614e71bSYork Sun eight_be = 1; 7935614e71bSYork Sun if (popts->burst_length == DDR_OTF) 7945614e71bSYork Sun eight_be = 0; 7955614e71bSYork Sun if (dbw == 0x1) 7965614e71bSYork Sun eight_be = 1; 7975614e71bSYork Sun } 7985614e71bSYork Sun 7995614e71bSYork Sun threet_en = popts->threet_en; 8005614e71bSYork Sun ba_intlv_ctl = popts->ba_intlv_ctl; 8015614e71bSYork Sun hse = popts->half_strength_driver_enable; 8025614e71bSYork Sun 803d28cb671SYork Sun /* set when ddr bus width < 64 */ 804d28cb671SYork Sun acc_ecc_en = (dbw != 0 && ecc_en == 1) ? 1 : 0; 805d28cb671SYork Sun 8065614e71bSYork Sun ddr->ddr_sdram_cfg = (0 8075614e71bSYork Sun | ((mem_en & 0x1) << 31) 8085614e71bSYork Sun | ((sren & 0x1) << 30) 8095614e71bSYork Sun | ((ecc_en & 0x1) << 29) 8105614e71bSYork Sun | ((rd_en & 0x1) << 28) 8115614e71bSYork Sun | ((sdram_type & 0x7) << 24) 8125614e71bSYork Sun | ((dyn_pwr & 0x1) << 21) 8135614e71bSYork Sun | ((dbw & 0x3) << 19) 8145614e71bSYork Sun | ((eight_be & 0x1) << 18) 8155614e71bSYork Sun | ((ncap & 0x1) << 17) 8165614e71bSYork Sun | ((threet_en & 0x1) << 16) 8175614e71bSYork Sun | ((twot_en & 0x1) << 15) 8185614e71bSYork Sun | ((ba_intlv_ctl & 0x7F) << 8) 8195614e71bSYork Sun | ((x32_en & 0x1) << 5) 8205614e71bSYork Sun | ((pchb8 & 0x1) << 4) 8215614e71bSYork Sun | ((hse & 0x1) << 3) 822d28cb671SYork Sun | ((acc_ecc_en & 0x1) << 2) 8235614e71bSYork Sun | ((mem_halt & 0x1) << 1) 8245614e71bSYork Sun | ((bi & 0x1) << 0) 8255614e71bSYork Sun ); 8265614e71bSYork Sun debug("FSLDDR: ddr_sdram_cfg = 0x%08x\n", ddr->ddr_sdram_cfg); 8275614e71bSYork Sun } 8285614e71bSYork Sun 8295614e71bSYork Sun /* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */ 83003e664d8SYork Sun static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num, 83103e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 8325614e71bSYork Sun const memctl_options_t *popts, 8335614e71bSYork Sun const unsigned int unq_mrs_en) 8345614e71bSYork Sun { 8355614e71bSYork Sun unsigned int frc_sr = 0; /* Force self refresh */ 8365614e71bSYork Sun unsigned int sr_ie = 0; /* Self-refresh interrupt enable */ 8375614e71bSYork Sun unsigned int odt_cfg = 0; /* ODT configuration */ 8385614e71bSYork Sun unsigned int num_pr; /* Number of posted refreshes */ 8395614e71bSYork Sun unsigned int slow = 0; /* DDR will be run less than 1250 */ 8405614e71bSYork Sun unsigned int x4_en = 0; /* x4 DRAM enable */ 8415614e71bSYork Sun unsigned int obc_cfg; /* On-The-Fly Burst Chop Cfg */ 8425614e71bSYork Sun unsigned int ap_en; /* Address Parity Enable */ 8435614e71bSYork Sun unsigned int d_init; /* DRAM data initialization */ 8445614e71bSYork Sun unsigned int rcw_en = 0; /* Register Control Word Enable */ 8455614e71bSYork Sun unsigned int md_en = 0; /* Mirrored DIMM Enable */ 8465614e71bSYork Sun unsigned int qd_en = 0; /* quad-rank DIMM Enable */ 8475614e71bSYork Sun int i; 84834e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4 84934e026f9SYork Sun unsigned int dll_rst_dis = 1; /* DLL reset disable */ 85034e026f9SYork Sun unsigned int dqs_cfg; /* DQS configuration */ 8515614e71bSYork Sun 8525614e71bSYork Sun dqs_cfg = popts->dqs_config; 85334e026f9SYork Sun #endif 8545614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 8555614e71bSYork Sun if (popts->cs_local_opts[i].odt_rd_cfg 8565614e71bSYork Sun || popts->cs_local_opts[i].odt_wr_cfg) { 8575614e71bSYork Sun odt_cfg = SDRAM_CFG2_ODT_ONLY_READ; 8585614e71bSYork Sun break; 8595614e71bSYork Sun } 8605614e71bSYork Sun } 861e368c206SJoakim Tjernlund sr_ie = popts->self_refresh_interrupt_en; 8625614e71bSYork Sun num_pr = 1; /* Make this configurable */ 8635614e71bSYork Sun 8645614e71bSYork Sun /* 8655614e71bSYork Sun * 8572 manual says 8665614e71bSYork Sun * {TIMING_CFG_1[PRETOACT] 8675614e71bSYork Sun * + [DDR_SDRAM_CFG_2[NUM_PR] 8685614e71bSYork Sun * * ({EXT_REFREC || REFREC} + 8 + 2)]} 8695614e71bSYork Sun * << DDR_SDRAM_INTERVAL[REFINT] 8705614e71bSYork Sun */ 87134e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 8725614e71bSYork Sun obc_cfg = popts->otf_burst_chop_en; 8735614e71bSYork Sun #else 8745614e71bSYork Sun obc_cfg = 0; 8755614e71bSYork Sun #endif 8765614e71bSYork Sun 8775614e71bSYork Sun #if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7) 87803e664d8SYork Sun slow = get_ddr_freq(ctrl_num) < 1249000000; 8795614e71bSYork Sun #endif 8805614e71bSYork Sun 8815614e71bSYork Sun if (popts->registered_dimm_en) { 8825614e71bSYork Sun rcw_en = 1; 8835614e71bSYork Sun ap_en = popts->ap_en; 8845614e71bSYork Sun } else { 8855614e71bSYork Sun ap_en = 0; 8865614e71bSYork Sun } 8875614e71bSYork Sun 8885614e71bSYork Sun x4_en = popts->x4_en ? 1 : 0; 8895614e71bSYork Sun 8905614e71bSYork Sun #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) 8915614e71bSYork Sun /* Use the DDR controller to auto initialize memory. */ 8925614e71bSYork Sun d_init = popts->ecc_init_using_memctl; 8935614e71bSYork Sun ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE; 8945614e71bSYork Sun debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init); 8955614e71bSYork Sun #else 8965614e71bSYork Sun /* Memory will be initialized via DMA, or not at all. */ 8975614e71bSYork Sun d_init = 0; 8985614e71bSYork Sun #endif 8995614e71bSYork Sun 90034e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 9015614e71bSYork Sun md_en = popts->mirrored_dimm; 9025614e71bSYork Sun #endif 9035614e71bSYork Sun qd_en = popts->quad_rank_present ? 1 : 0; 9045614e71bSYork Sun ddr->ddr_sdram_cfg_2 = (0 9055614e71bSYork Sun | ((frc_sr & 0x1) << 31) 9065614e71bSYork Sun | ((sr_ie & 0x1) << 30) 90734e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4 9085614e71bSYork Sun | ((dll_rst_dis & 0x1) << 29) 9095614e71bSYork Sun | ((dqs_cfg & 0x3) << 26) 91034e026f9SYork Sun #endif 9115614e71bSYork Sun | ((odt_cfg & 0x3) << 21) 9125614e71bSYork Sun | ((num_pr & 0xf) << 12) 9135614e71bSYork Sun | ((slow & 1) << 11) 9145614e71bSYork Sun | (x4_en << 10) 9155614e71bSYork Sun | (qd_en << 9) 9165614e71bSYork Sun | (unq_mrs_en << 8) 9175614e71bSYork Sun | ((obc_cfg & 0x1) << 6) 9185614e71bSYork Sun | ((ap_en & 0x1) << 5) 9195614e71bSYork Sun | ((d_init & 0x1) << 4) 9205614e71bSYork Sun | ((rcw_en & 0x1) << 2) 9215614e71bSYork Sun | ((md_en & 0x1) << 0) 9225614e71bSYork Sun ); 9235614e71bSYork Sun debug("FSLDDR: ddr_sdram_cfg_2 = 0x%08x\n", ddr->ddr_sdram_cfg_2); 9245614e71bSYork Sun } 9255614e71bSYork Sun 92634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 9275614e71bSYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 92803e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, 92903e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 9305614e71bSYork Sun const memctl_options_t *popts, 9315614e71bSYork Sun const common_timing_params_t *common_dimm, 9325614e71bSYork Sun const unsigned int unq_mrs_en) 9335614e71bSYork Sun { 9345614e71bSYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 9355614e71bSYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 9365614e71bSYork Sun int i; 93734e026f9SYork Sun unsigned int wr_crc = 0; /* Disable */ 9385614e71bSYork Sun unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ 9395614e71bSYork Sun unsigned int srt = 0; /* self-refresh temerature, normal range */ 94003e664d8SYork Sun unsigned int cwl = compute_cas_write_latency(ctrl_num) - 9; 94134e026f9SYork Sun unsigned int mpr = 0; /* serial */ 94234e026f9SYork Sun unsigned int wc_lat; 94303e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 9445614e71bSYork Sun 9455614e71bSYork Sun if (popts->rtt_override) 9465614e71bSYork Sun rtt_wr = popts->rtt_wr_override_value; 9475614e71bSYork Sun else 9485614e71bSYork Sun rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; 9495614e71bSYork Sun 9505614e71bSYork Sun if (common_dimm->extended_op_srt) 9515614e71bSYork Sun srt = common_dimm->extended_op_srt; 9525614e71bSYork Sun 9535614e71bSYork Sun esdmode2 = (0 95434e026f9SYork Sun | ((wr_crc & 0x1) << 12) 9555614e71bSYork Sun | ((rtt_wr & 0x3) << 9) 95634e026f9SYork Sun | ((srt & 0x3) << 6) 95734e026f9SYork Sun | ((cwl & 0x7) << 3)); 95834e026f9SYork Sun 95934e026f9SYork Sun if (mclk_ps >= 1250) 96034e026f9SYork Sun wc_lat = 0; 96134e026f9SYork Sun else if (mclk_ps >= 833) 96234e026f9SYork Sun wc_lat = 1; 96334e026f9SYork Sun else 96434e026f9SYork Sun wc_lat = 2; 96534e026f9SYork Sun 96634e026f9SYork Sun esdmode3 = (0 96734e026f9SYork Sun | ((mpr & 0x3) << 11) 96834e026f9SYork Sun | ((wc_lat & 0x3) << 9)); 96934e026f9SYork Sun 9705614e71bSYork Sun ddr->ddr_sdram_mode_2 = (0 9715614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 9725614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 9735614e71bSYork Sun ); 9745614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 9755614e71bSYork Sun 9765614e71bSYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 9775614e71bSYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 9785614e71bSYork Sun if (popts->rtt_override) 9795614e71bSYork Sun rtt_wr = popts->rtt_wr_override_value; 9805614e71bSYork Sun else 9815614e71bSYork Sun rtt_wr = popts->cs_local_opts[i].odt_rtt_wr; 9825614e71bSYork Sun 9835614e71bSYork Sun esdmode2 &= 0xF9FF; /* clear bit 10, 9 */ 9845614e71bSYork Sun esdmode2 |= (rtt_wr & 0x3) << 9; 9855614e71bSYork Sun switch (i) { 9865614e71bSYork Sun case 1: 9875614e71bSYork Sun ddr->ddr_sdram_mode_4 = (0 9885614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 9895614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 9905614e71bSYork Sun ); 9915614e71bSYork Sun break; 9925614e71bSYork Sun case 2: 9935614e71bSYork Sun ddr->ddr_sdram_mode_6 = (0 9945614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 9955614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 9965614e71bSYork Sun ); 9975614e71bSYork Sun break; 9985614e71bSYork Sun case 3: 9995614e71bSYork Sun ddr->ddr_sdram_mode_8 = (0 10005614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 10015614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 10025614e71bSYork Sun ); 10035614e71bSYork Sun break; 10045614e71bSYork Sun } 10055614e71bSYork Sun } 10065614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", 10075614e71bSYork Sun ddr->ddr_sdram_mode_4); 10085614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", 10095614e71bSYork Sun ddr->ddr_sdram_mode_6); 10105614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", 10115614e71bSYork Sun ddr->ddr_sdram_mode_8); 10125614e71bSYork Sun } 10135614e71bSYork Sun } 101434e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 101534e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 101603e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, 101703e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 101834e026f9SYork Sun const memctl_options_t *popts, 101934e026f9SYork Sun const common_timing_params_t *common_dimm, 102034e026f9SYork Sun const unsigned int unq_mrs_en) 102134e026f9SYork Sun { 102234e026f9SYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 102334e026f9SYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 102434e026f9SYork Sun int i; 102534e026f9SYork Sun unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ 102634e026f9SYork Sun unsigned int srt = 0; /* self-refresh temerature, normal range */ 102734e026f9SYork Sun unsigned int asr = 0; /* auto self-refresh disable */ 102803e664d8SYork Sun unsigned int cwl = compute_cas_write_latency(ctrl_num) - 5; 102934e026f9SYork Sun unsigned int pasr = 0; /* partial array self refresh disable */ 103034e026f9SYork Sun 103134e026f9SYork Sun if (popts->rtt_override) 103234e026f9SYork Sun rtt_wr = popts->rtt_wr_override_value; 103334e026f9SYork Sun else 103434e026f9SYork Sun rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; 103534e026f9SYork Sun 103634e026f9SYork Sun if (common_dimm->extended_op_srt) 103734e026f9SYork Sun srt = common_dimm->extended_op_srt; 103834e026f9SYork Sun 103934e026f9SYork Sun esdmode2 = (0 104034e026f9SYork Sun | ((rtt_wr & 0x3) << 9) 104134e026f9SYork Sun | ((srt & 0x1) << 7) 104234e026f9SYork Sun | ((asr & 0x1) << 6) 104334e026f9SYork Sun | ((cwl & 0x7) << 3) 104434e026f9SYork Sun | ((pasr & 0x7) << 0)); 104534e026f9SYork Sun ddr->ddr_sdram_mode_2 = (0 104634e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 104734e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 104834e026f9SYork Sun ); 104934e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 105034e026f9SYork Sun 105134e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 105234e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 105334e026f9SYork Sun if (popts->rtt_override) 105434e026f9SYork Sun rtt_wr = popts->rtt_wr_override_value; 105534e026f9SYork Sun else 105634e026f9SYork Sun rtt_wr = popts->cs_local_opts[i].odt_rtt_wr; 105734e026f9SYork Sun 105834e026f9SYork Sun esdmode2 &= 0xF9FF; /* clear bit 10, 9 */ 105934e026f9SYork Sun esdmode2 |= (rtt_wr & 0x3) << 9; 106034e026f9SYork Sun switch (i) { 106134e026f9SYork Sun case 1: 106234e026f9SYork Sun ddr->ddr_sdram_mode_4 = (0 106334e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 106434e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 106534e026f9SYork Sun ); 106634e026f9SYork Sun break; 106734e026f9SYork Sun case 2: 106834e026f9SYork Sun ddr->ddr_sdram_mode_6 = (0 106934e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 107034e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 107134e026f9SYork Sun ); 107234e026f9SYork Sun break; 107334e026f9SYork Sun case 3: 107434e026f9SYork Sun ddr->ddr_sdram_mode_8 = (0 107534e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 107634e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 107734e026f9SYork Sun ); 107834e026f9SYork Sun break; 107934e026f9SYork Sun } 108034e026f9SYork Sun } 108134e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", 108234e026f9SYork Sun ddr->ddr_sdram_mode_4); 108334e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", 108434e026f9SYork Sun ddr->ddr_sdram_mode_6); 108534e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", 108634e026f9SYork Sun ddr->ddr_sdram_mode_8); 108734e026f9SYork Sun } 108834e026f9SYork Sun } 108934e026f9SYork Sun 109034e026f9SYork Sun #else /* for DDR2 and DDR1 */ 109134e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 109203e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, 109303e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 109434e026f9SYork Sun const memctl_options_t *popts, 109534e026f9SYork Sun const common_timing_params_t *common_dimm, 109634e026f9SYork Sun const unsigned int unq_mrs_en) 109734e026f9SYork Sun { 109834e026f9SYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 109934e026f9SYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 110034e026f9SYork Sun 110134e026f9SYork Sun ddr->ddr_sdram_mode_2 = (0 110234e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 110334e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 110434e026f9SYork Sun ); 110534e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 110634e026f9SYork Sun } 110734e026f9SYork Sun #endif 110834e026f9SYork Sun 110934e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 111034e026f9SYork Sun /* DDR SDRAM Mode configuration 9 (DDR_SDRAM_MODE_9) */ 111134e026f9SYork Sun static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, 111234e026f9SYork Sun const memctl_options_t *popts, 111334e026f9SYork Sun const common_timing_params_t *common_dimm, 111434e026f9SYork Sun const unsigned int unq_mrs_en) 111534e026f9SYork Sun { 111634e026f9SYork Sun int i; 111734e026f9SYork Sun unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */ 111834e026f9SYork Sun unsigned short esdmode5; /* Extended SDRAM mode 5 */ 11196b95be22SYork Sun int rtt_park = 0; 112034e026f9SYork Sun 11216b95be22SYork Sun if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) { 11226b95be22SYork Sun esdmode5 = 0x00000500; /* Data mask enable, RTT_PARK CS0 */ 11236b95be22SYork Sun rtt_park = 1; 11246b95be22SYork Sun } else { 11256b95be22SYork Sun esdmode5 = 0x00000400; /* Data mask enabled */ 11266b95be22SYork Sun } 112734e026f9SYork Sun 112834e026f9SYork Sun ddr->ddr_sdram_mode_9 = (0 112934e026f9SYork Sun | ((esdmode4 & 0xffff) << 16) 113034e026f9SYork Sun | ((esdmode5 & 0xffff) << 0) 113134e026f9SYork Sun ); 113266869f95SYork Sun 113366869f95SYork Sun /* only mode_9 use 0x500, others use 0x400 */ 113466869f95SYork Sun 113534e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9); 113634e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 113734e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 11386b95be22SYork Sun if (!rtt_park && 11396b95be22SYork Sun (ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) { 11406b95be22SYork Sun esdmode5 |= 0x00000500; /* RTT_PARK */ 11416b95be22SYork Sun rtt_park = 1; 11426b95be22SYork Sun } else { 11436b95be22SYork Sun esdmode5 = 0x00000400; 11446b95be22SYork Sun } 114534e026f9SYork Sun switch (i) { 114634e026f9SYork Sun case 1: 114734e026f9SYork Sun ddr->ddr_sdram_mode_11 = (0 114834e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 114934e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 115034e026f9SYork Sun ); 115134e026f9SYork Sun break; 115234e026f9SYork Sun case 2: 115334e026f9SYork Sun ddr->ddr_sdram_mode_13 = (0 115434e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 115534e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 115634e026f9SYork Sun ); 115734e026f9SYork Sun break; 115834e026f9SYork Sun case 3: 115934e026f9SYork Sun ddr->ddr_sdram_mode_15 = (0 116034e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 116134e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 116234e026f9SYork Sun ); 116334e026f9SYork Sun break; 116434e026f9SYork Sun } 116534e026f9SYork Sun } 116634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_11 = 0x%08x\n", 116734e026f9SYork Sun ddr->ddr_sdram_mode_11); 116834e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_13 = 0x%08x\n", 116934e026f9SYork Sun ddr->ddr_sdram_mode_13); 117034e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_15 = 0x%08x\n", 117134e026f9SYork Sun ddr->ddr_sdram_mode_15); 117234e026f9SYork Sun } 117334e026f9SYork Sun } 117434e026f9SYork Sun 117534e026f9SYork Sun /* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */ 117603e664d8SYork Sun static void set_ddr_sdram_mode_10(const unsigned int ctrl_num, 117703e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 117834e026f9SYork Sun const memctl_options_t *popts, 117934e026f9SYork Sun const common_timing_params_t *common_dimm, 118034e026f9SYork Sun const unsigned int unq_mrs_en) 118134e026f9SYork Sun { 118234e026f9SYork Sun int i; 118334e026f9SYork Sun unsigned short esdmode6 = 0; /* Extended SDRAM mode 6 */ 118434e026f9SYork Sun unsigned short esdmode7 = 0; /* Extended SDRAM mode 7 */ 118503e664d8SYork Sun unsigned int tccdl_min = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); 118634e026f9SYork Sun 118734e026f9SYork Sun esdmode6 = ((tccdl_min - 4) & 0x7) << 10; 118834e026f9SYork Sun 1189*0fb71974SYork Sun if (popts->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2) 1190*0fb71974SYork Sun esdmode6 |= 1 << 6; /* Range 2 */ 1191*0fb71974SYork Sun 119234e026f9SYork Sun ddr->ddr_sdram_mode_10 = (0 119334e026f9SYork Sun | ((esdmode6 & 0xffff) << 16) 119434e026f9SYork Sun | ((esdmode7 & 0xffff) << 0) 119534e026f9SYork Sun ); 119634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_10) = 0x%08x\n", ddr->ddr_sdram_mode_10); 119734e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 119834e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 119934e026f9SYork Sun switch (i) { 120034e026f9SYork Sun case 1: 120134e026f9SYork Sun ddr->ddr_sdram_mode_12 = (0 120234e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 120334e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 120434e026f9SYork Sun ); 120534e026f9SYork Sun break; 120634e026f9SYork Sun case 2: 120734e026f9SYork Sun ddr->ddr_sdram_mode_14 = (0 120834e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 120934e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 121034e026f9SYork Sun ); 121134e026f9SYork Sun break; 121234e026f9SYork Sun case 3: 121334e026f9SYork Sun ddr->ddr_sdram_mode_16 = (0 121434e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 121534e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 121634e026f9SYork Sun ); 121734e026f9SYork Sun break; 121834e026f9SYork Sun } 121934e026f9SYork Sun } 122034e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_12 = 0x%08x\n", 122134e026f9SYork Sun ddr->ddr_sdram_mode_12); 122234e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_14 = 0x%08x\n", 122334e026f9SYork Sun ddr->ddr_sdram_mode_14); 122434e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_16 = 0x%08x\n", 122534e026f9SYork Sun ddr->ddr_sdram_mode_16); 122634e026f9SYork Sun } 122734e026f9SYork Sun } 122834e026f9SYork Sun 122934e026f9SYork Sun #endif 12305614e71bSYork Sun 12315614e71bSYork Sun /* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */ 123203e664d8SYork Sun static void set_ddr_sdram_interval(const unsigned int ctrl_num, 123303e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 12345614e71bSYork Sun const memctl_options_t *popts, 12355614e71bSYork Sun const common_timing_params_t *common_dimm) 12365614e71bSYork Sun { 12375614e71bSYork Sun unsigned int refint; /* Refresh interval */ 12385614e71bSYork Sun unsigned int bstopre; /* Precharge interval */ 12395614e71bSYork Sun 124003e664d8SYork Sun refint = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps); 12415614e71bSYork Sun 12425614e71bSYork Sun bstopre = popts->bstopre; 12435614e71bSYork Sun 12445614e71bSYork Sun /* refint field used 0x3FFF in earlier controllers */ 12455614e71bSYork Sun ddr->ddr_sdram_interval = (0 12465614e71bSYork Sun | ((refint & 0xFFFF) << 16) 12475614e71bSYork Sun | ((bstopre & 0x3FFF) << 0) 12485614e71bSYork Sun ); 12495614e71bSYork Sun debug("FSLDDR: ddr_sdram_interval = 0x%08x\n", ddr->ddr_sdram_interval); 12505614e71bSYork Sun } 12515614e71bSYork Sun 125234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 12535614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 125403e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num, 125503e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 12565614e71bSYork Sun const memctl_options_t *popts, 12575614e71bSYork Sun const common_timing_params_t *common_dimm, 12585614e71bSYork Sun unsigned int cas_latency, 12595614e71bSYork Sun unsigned int additive_latency, 12605614e71bSYork Sun const unsigned int unq_mrs_en) 12615614e71bSYork Sun { 126234e026f9SYork Sun int i; 126334e026f9SYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 126434e026f9SYork Sun unsigned short sdmode; /* SDRAM mode */ 126534e026f9SYork Sun 126634e026f9SYork Sun /* Mode Register - MR1 */ 126734e026f9SYork Sun unsigned int qoff = 0; /* Output buffer enable 0=yes, 1=no */ 126834e026f9SYork Sun unsigned int tdqs_en = 0; /* TDQS Enable: 0=no, 1=yes */ 126934e026f9SYork Sun unsigned int rtt; 127034e026f9SYork Sun unsigned int wrlvl_en = 0; /* Write level enable: 0=no, 1=yes */ 127134e026f9SYork Sun unsigned int al = 0; /* Posted CAS# additive latency (AL) */ 127234e026f9SYork Sun unsigned int dic = 0; /* Output driver impedance, 40ohm */ 127334e026f9SYork Sun unsigned int dll_en = 1; /* DLL Enable 1=Enable (Normal), 127434e026f9SYork Sun 0=Disable (Test/Debug) */ 127534e026f9SYork Sun 127634e026f9SYork Sun /* Mode Register - MR0 */ 127734e026f9SYork Sun unsigned int wr = 0; /* Write Recovery */ 127834e026f9SYork Sun unsigned int dll_rst; /* DLL Reset */ 127934e026f9SYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 128034e026f9SYork Sun unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ 128134e026f9SYork Sun /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ 128234e026f9SYork Sun unsigned int bt; 128334e026f9SYork Sun unsigned int bl; /* BL: Burst Length */ 128434e026f9SYork Sun 128534e026f9SYork Sun unsigned int wr_mclk; 128634e026f9SYork Sun /* DDR4 support WR 10, 12, 14, 16, 18, 20, 24 */ 128734e026f9SYork Sun static const u8 wr_table[] = { 128834e026f9SYork Sun 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6}; 128934e026f9SYork Sun /* DDR4 support CAS 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24 */ 129034e026f9SYork Sun static const u8 cas_latency_table[] = { 129134e026f9SYork Sun 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 129234e026f9SYork Sun 9, 9, 10, 10, 11, 11}; 129334e026f9SYork Sun 129434e026f9SYork Sun if (popts->rtt_override) 129534e026f9SYork Sun rtt = popts->rtt_override_value; 129634e026f9SYork Sun else 129734e026f9SYork Sun rtt = popts->cs_local_opts[0].odt_rtt_norm; 129834e026f9SYork Sun 129934e026f9SYork Sun if (additive_latency == (cas_latency - 1)) 130034e026f9SYork Sun al = 1; 130134e026f9SYork Sun if (additive_latency == (cas_latency - 2)) 130234e026f9SYork Sun al = 2; 130334e026f9SYork Sun 130434e026f9SYork Sun if (popts->quad_rank_present) 130534e026f9SYork Sun dic = 1; /* output driver impedance 240/7 ohm */ 130634e026f9SYork Sun 130734e026f9SYork Sun /* 130834e026f9SYork Sun * The esdmode value will also be used for writing 130934e026f9SYork Sun * MR1 during write leveling for DDR3, although the 131034e026f9SYork Sun * bits specifically related to the write leveling 131134e026f9SYork Sun * scheme will be handled automatically by the DDR 131234e026f9SYork Sun * controller. so we set the wrlvl_en = 0 here. 131334e026f9SYork Sun */ 131434e026f9SYork Sun esdmode = (0 131534e026f9SYork Sun | ((qoff & 0x1) << 12) 131634e026f9SYork Sun | ((tdqs_en & 0x1) << 11) 131734e026f9SYork Sun | ((rtt & 0x7) << 8) 131834e026f9SYork Sun | ((wrlvl_en & 0x1) << 7) 131934e026f9SYork Sun | ((al & 0x3) << 3) 132034e026f9SYork Sun | ((dic & 0x3) << 1) /* DIC field is split */ 132134e026f9SYork Sun | ((dll_en & 0x1) << 0) 132234e026f9SYork Sun ); 132334e026f9SYork Sun 132434e026f9SYork Sun /* 132534e026f9SYork Sun * DLL control for precharge PD 132634e026f9SYork Sun * 0=slow exit DLL off (tXPDLL) 132734e026f9SYork Sun * 1=fast exit DLL on (tXP) 132834e026f9SYork Sun */ 132934e026f9SYork Sun 133003e664d8SYork Sun wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 133134e026f9SYork Sun if (wr_mclk <= 24) { 133234e026f9SYork Sun wr = wr_table[wr_mclk - 10]; 133334e026f9SYork Sun } else { 133434e026f9SYork Sun printf("Error: unsupported write recovery for mode register wr_mclk = %d\n", 133534e026f9SYork Sun wr_mclk); 133634e026f9SYork Sun } 133734e026f9SYork Sun 133834e026f9SYork Sun dll_rst = 0; /* dll no reset */ 133934e026f9SYork Sun mode = 0; /* normal mode */ 134034e026f9SYork Sun 134134e026f9SYork Sun /* look up table to get the cas latency bits */ 134234e026f9SYork Sun if (cas_latency >= 9 && cas_latency <= 24) 134334e026f9SYork Sun caslat = cas_latency_table[cas_latency - 9]; 134434e026f9SYork Sun else 134534e026f9SYork Sun printf("Error: unsupported cas latency for mode register\n"); 134634e026f9SYork Sun 134734e026f9SYork Sun bt = 0; /* Nibble sequential */ 134834e026f9SYork Sun 134934e026f9SYork Sun switch (popts->burst_length) { 135034e026f9SYork Sun case DDR_BL8: 135134e026f9SYork Sun bl = 0; 135234e026f9SYork Sun break; 135334e026f9SYork Sun case DDR_OTF: 135434e026f9SYork Sun bl = 1; 135534e026f9SYork Sun break; 135634e026f9SYork Sun case DDR_BC4: 135734e026f9SYork Sun bl = 2; 135834e026f9SYork Sun break; 135934e026f9SYork Sun default: 136034e026f9SYork Sun printf("Error: invalid burst length of %u specified. ", 136134e026f9SYork Sun popts->burst_length); 136234e026f9SYork Sun puts("Defaulting to on-the-fly BC4 or BL8 beats.\n"); 136334e026f9SYork Sun bl = 1; 136434e026f9SYork Sun break; 136534e026f9SYork Sun } 136634e026f9SYork Sun 136734e026f9SYork Sun sdmode = (0 136834e026f9SYork Sun | ((wr & 0x7) << 9) 136934e026f9SYork Sun | ((dll_rst & 0x1) << 8) 137034e026f9SYork Sun | ((mode & 0x1) << 7) 137134e026f9SYork Sun | (((caslat >> 1) & 0x7) << 4) 137234e026f9SYork Sun | ((bt & 0x1) << 3) 137334e026f9SYork Sun | ((caslat & 1) << 2) 137434e026f9SYork Sun | ((bl & 0x3) << 0) 137534e026f9SYork Sun ); 137634e026f9SYork Sun 137734e026f9SYork Sun ddr->ddr_sdram_mode = (0 137834e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 137934e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 138034e026f9SYork Sun ); 138134e026f9SYork Sun 138234e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 138334e026f9SYork Sun 138434e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 138534e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 138634e026f9SYork Sun if (popts->rtt_override) 138734e026f9SYork Sun rtt = popts->rtt_override_value; 138834e026f9SYork Sun else 138934e026f9SYork Sun rtt = popts->cs_local_opts[i].odt_rtt_norm; 139034e026f9SYork Sun 139134e026f9SYork Sun esdmode &= 0xF8FF; /* clear bit 10,9,8 for rtt */ 139234e026f9SYork Sun esdmode |= (rtt & 0x7) << 8; 139334e026f9SYork Sun switch (i) { 139434e026f9SYork Sun case 1: 139534e026f9SYork Sun ddr->ddr_sdram_mode_3 = (0 139634e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 139734e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 139834e026f9SYork Sun ); 139934e026f9SYork Sun break; 140034e026f9SYork Sun case 2: 140134e026f9SYork Sun ddr->ddr_sdram_mode_5 = (0 140234e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 140334e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 140434e026f9SYork Sun ); 140534e026f9SYork Sun break; 140634e026f9SYork Sun case 3: 140734e026f9SYork Sun ddr->ddr_sdram_mode_7 = (0 140834e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 140934e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 141034e026f9SYork Sun ); 141134e026f9SYork Sun break; 141234e026f9SYork Sun } 141334e026f9SYork Sun } 141434e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", 141534e026f9SYork Sun ddr->ddr_sdram_mode_3); 141634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 141734e026f9SYork Sun ddr->ddr_sdram_mode_5); 141834e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 141934e026f9SYork Sun ddr->ddr_sdram_mode_5); 142034e026f9SYork Sun } 142134e026f9SYork Sun } 142234e026f9SYork Sun 142334e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 142434e026f9SYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 142503e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num, 142603e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 142734e026f9SYork Sun const memctl_options_t *popts, 142834e026f9SYork Sun const common_timing_params_t *common_dimm, 142934e026f9SYork Sun unsigned int cas_latency, 143034e026f9SYork Sun unsigned int additive_latency, 143134e026f9SYork Sun const unsigned int unq_mrs_en) 143234e026f9SYork Sun { 143334e026f9SYork Sun int i; 14345614e71bSYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 14355614e71bSYork Sun unsigned short sdmode; /* SDRAM mode */ 14365614e71bSYork Sun 14375614e71bSYork Sun /* Mode Register - MR1 */ 14385614e71bSYork Sun unsigned int qoff = 0; /* Output buffer enable 0=yes, 1=no */ 14395614e71bSYork Sun unsigned int tdqs_en = 0; /* TDQS Enable: 0=no, 1=yes */ 14405614e71bSYork Sun unsigned int rtt; 14415614e71bSYork Sun unsigned int wrlvl_en = 0; /* Write level enable: 0=no, 1=yes */ 14425614e71bSYork Sun unsigned int al = 0; /* Posted CAS# additive latency (AL) */ 14435614e71bSYork Sun unsigned int dic = 0; /* Output driver impedance, 40ohm */ 14445614e71bSYork Sun unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), 14455614e71bSYork Sun 1=Disable (Test/Debug) */ 14465614e71bSYork Sun 14475614e71bSYork Sun /* Mode Register - MR0 */ 14485614e71bSYork Sun unsigned int dll_on; /* DLL control for precharge PD, 0=off, 1=on */ 14495614e71bSYork Sun unsigned int wr = 0; /* Write Recovery */ 14505614e71bSYork Sun unsigned int dll_rst; /* DLL Reset */ 14515614e71bSYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 14525614e71bSYork Sun unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ 14535614e71bSYork Sun /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ 14545614e71bSYork Sun unsigned int bt; 14555614e71bSYork Sun unsigned int bl; /* BL: Burst Length */ 14565614e71bSYork Sun 14575614e71bSYork Sun unsigned int wr_mclk; 14585614e71bSYork Sun /* 14595614e71bSYork Sun * DDR_SDRAM_MODE doesn't support 9,11,13,15 14605614e71bSYork Sun * Please refer JEDEC Standard No. 79-3E for Mode Register MR0 14615614e71bSYork Sun * for this table 14625614e71bSYork Sun */ 14635614e71bSYork Sun static const u8 wr_table[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0}; 14645614e71bSYork Sun 14655614e71bSYork Sun if (popts->rtt_override) 14665614e71bSYork Sun rtt = popts->rtt_override_value; 14675614e71bSYork Sun else 14685614e71bSYork Sun rtt = popts->cs_local_opts[0].odt_rtt_norm; 14695614e71bSYork Sun 14705614e71bSYork Sun if (additive_latency == (cas_latency - 1)) 14715614e71bSYork Sun al = 1; 14725614e71bSYork Sun if (additive_latency == (cas_latency - 2)) 14735614e71bSYork Sun al = 2; 14745614e71bSYork Sun 14755614e71bSYork Sun if (popts->quad_rank_present) 14765614e71bSYork Sun dic = 1; /* output driver impedance 240/7 ohm */ 14775614e71bSYork Sun 14785614e71bSYork Sun /* 14795614e71bSYork Sun * The esdmode value will also be used for writing 14805614e71bSYork Sun * MR1 during write leveling for DDR3, although the 14815614e71bSYork Sun * bits specifically related to the write leveling 14825614e71bSYork Sun * scheme will be handled automatically by the DDR 14835614e71bSYork Sun * controller. so we set the wrlvl_en = 0 here. 14845614e71bSYork Sun */ 14855614e71bSYork Sun esdmode = (0 14865614e71bSYork Sun | ((qoff & 0x1) << 12) 14875614e71bSYork Sun | ((tdqs_en & 0x1) << 11) 14885614e71bSYork Sun | ((rtt & 0x4) << 7) /* rtt field is split */ 14895614e71bSYork Sun | ((wrlvl_en & 0x1) << 7) 14905614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 14915614e71bSYork Sun | ((dic & 0x2) << 4) /* DIC field is split */ 14925614e71bSYork Sun | ((al & 0x3) << 3) 14935614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 14945614e71bSYork Sun | ((dic & 0x1) << 1) /* DIC field is split */ 14955614e71bSYork Sun | ((dll_en & 0x1) << 0) 14965614e71bSYork Sun ); 14975614e71bSYork Sun 14985614e71bSYork Sun /* 14995614e71bSYork Sun * DLL control for precharge PD 15005614e71bSYork Sun * 0=slow exit DLL off (tXPDLL) 15015614e71bSYork Sun * 1=fast exit DLL on (tXP) 15025614e71bSYork Sun */ 15035614e71bSYork Sun dll_on = 1; 15045614e71bSYork Sun 150503e664d8SYork Sun wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 15065614e71bSYork Sun if (wr_mclk <= 16) { 15075614e71bSYork Sun wr = wr_table[wr_mclk - 5]; 15085614e71bSYork Sun } else { 15095614e71bSYork Sun printf("Error: unsupported write recovery for mode register " 15105614e71bSYork Sun "wr_mclk = %d\n", wr_mclk); 15115614e71bSYork Sun } 15125614e71bSYork Sun 15135614e71bSYork Sun dll_rst = 0; /* dll no reset */ 15145614e71bSYork Sun mode = 0; /* normal mode */ 15155614e71bSYork Sun 15165614e71bSYork Sun /* look up table to get the cas latency bits */ 15175614e71bSYork Sun if (cas_latency >= 5 && cas_latency <= 16) { 15185614e71bSYork Sun unsigned char cas_latency_table[] = { 15195614e71bSYork Sun 0x2, /* 5 clocks */ 15205614e71bSYork Sun 0x4, /* 6 clocks */ 15215614e71bSYork Sun 0x6, /* 7 clocks */ 15225614e71bSYork Sun 0x8, /* 8 clocks */ 15235614e71bSYork Sun 0xa, /* 9 clocks */ 15245614e71bSYork Sun 0xc, /* 10 clocks */ 15255614e71bSYork Sun 0xe, /* 11 clocks */ 15265614e71bSYork Sun 0x1, /* 12 clocks */ 15275614e71bSYork Sun 0x3, /* 13 clocks */ 15285614e71bSYork Sun 0x5, /* 14 clocks */ 15295614e71bSYork Sun 0x7, /* 15 clocks */ 15305614e71bSYork Sun 0x9, /* 16 clocks */ 15315614e71bSYork Sun }; 15325614e71bSYork Sun caslat = cas_latency_table[cas_latency - 5]; 15335614e71bSYork Sun } else { 15345614e71bSYork Sun printf("Error: unsupported cas latency for mode register\n"); 15355614e71bSYork Sun } 15365614e71bSYork Sun 15375614e71bSYork Sun bt = 0; /* Nibble sequential */ 15385614e71bSYork Sun 15395614e71bSYork Sun switch (popts->burst_length) { 15405614e71bSYork Sun case DDR_BL8: 15415614e71bSYork Sun bl = 0; 15425614e71bSYork Sun break; 15435614e71bSYork Sun case DDR_OTF: 15445614e71bSYork Sun bl = 1; 15455614e71bSYork Sun break; 15465614e71bSYork Sun case DDR_BC4: 15475614e71bSYork Sun bl = 2; 15485614e71bSYork Sun break; 15495614e71bSYork Sun default: 15505614e71bSYork Sun printf("Error: invalid burst length of %u specified. " 15515614e71bSYork Sun " Defaulting to on-the-fly BC4 or BL8 beats.\n", 15525614e71bSYork Sun popts->burst_length); 15535614e71bSYork Sun bl = 1; 15545614e71bSYork Sun break; 15555614e71bSYork Sun } 15565614e71bSYork Sun 15575614e71bSYork Sun sdmode = (0 15585614e71bSYork Sun | ((dll_on & 0x1) << 12) 15595614e71bSYork Sun | ((wr & 0x7) << 9) 15605614e71bSYork Sun | ((dll_rst & 0x1) << 8) 15615614e71bSYork Sun | ((mode & 0x1) << 7) 15625614e71bSYork Sun | (((caslat >> 1) & 0x7) << 4) 15635614e71bSYork Sun | ((bt & 0x1) << 3) 15645614e71bSYork Sun | ((caslat & 1) << 2) 15655614e71bSYork Sun | ((bl & 0x3) << 0) 15665614e71bSYork Sun ); 15675614e71bSYork Sun 15685614e71bSYork Sun ddr->ddr_sdram_mode = (0 15695614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 15705614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 15715614e71bSYork Sun ); 15725614e71bSYork Sun 15735614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 15745614e71bSYork Sun 15755614e71bSYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 15765614e71bSYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 15775614e71bSYork Sun if (popts->rtt_override) 15785614e71bSYork Sun rtt = popts->rtt_override_value; 15795614e71bSYork Sun else 15805614e71bSYork Sun rtt = popts->cs_local_opts[i].odt_rtt_norm; 15815614e71bSYork Sun 15825614e71bSYork Sun esdmode &= 0xFDBB; /* clear bit 9,6,2 */ 15835614e71bSYork Sun esdmode |= (0 15845614e71bSYork Sun | ((rtt & 0x4) << 7) /* rtt field is split */ 15855614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 15865614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 15875614e71bSYork Sun ); 15885614e71bSYork Sun switch (i) { 15895614e71bSYork Sun case 1: 15905614e71bSYork Sun ddr->ddr_sdram_mode_3 = (0 15915614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 15925614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 15935614e71bSYork Sun ); 15945614e71bSYork Sun break; 15955614e71bSYork Sun case 2: 15965614e71bSYork Sun ddr->ddr_sdram_mode_5 = (0 15975614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 15985614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 15995614e71bSYork Sun ); 16005614e71bSYork Sun break; 16015614e71bSYork Sun case 3: 16025614e71bSYork Sun ddr->ddr_sdram_mode_7 = (0 16035614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16045614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16055614e71bSYork Sun ); 16065614e71bSYork Sun break; 16075614e71bSYork Sun } 16085614e71bSYork Sun } 16095614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", 16105614e71bSYork Sun ddr->ddr_sdram_mode_3); 16115614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 16125614e71bSYork Sun ddr->ddr_sdram_mode_5); 16135614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 16145614e71bSYork Sun ddr->ddr_sdram_mode_5); 16155614e71bSYork Sun } 16165614e71bSYork Sun } 16175614e71bSYork Sun 16185614e71bSYork Sun #else /* !CONFIG_SYS_FSL_DDR3 */ 16195614e71bSYork Sun 16205614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 162103e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num, 162203e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 16235614e71bSYork Sun const memctl_options_t *popts, 16245614e71bSYork Sun const common_timing_params_t *common_dimm, 16255614e71bSYork Sun unsigned int cas_latency, 16265614e71bSYork Sun unsigned int additive_latency, 16275614e71bSYork Sun const unsigned int unq_mrs_en) 16285614e71bSYork Sun { 16295614e71bSYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 16305614e71bSYork Sun unsigned short sdmode; /* SDRAM mode */ 16315614e71bSYork Sun 16325614e71bSYork Sun /* 16335614e71bSYork Sun * FIXME: This ought to be pre-calculated in a 16345614e71bSYork Sun * technology-specific routine, 16355614e71bSYork Sun * e.g. compute_DDR2_mode_register(), and then the 16365614e71bSYork Sun * sdmode and esdmode passed in as part of common_dimm. 16375614e71bSYork Sun */ 16385614e71bSYork Sun 16395614e71bSYork Sun /* Extended Mode Register */ 16405614e71bSYork Sun unsigned int mrs = 0; /* Mode Register Set */ 16415614e71bSYork Sun unsigned int outputs = 0; /* 0=Enabled, 1=Disabled */ 16425614e71bSYork Sun unsigned int rdqs_en = 0; /* RDQS Enable: 0=no, 1=yes */ 16435614e71bSYork Sun unsigned int dqs_en = 0; /* DQS# Enable: 0=enable, 1=disable */ 16445614e71bSYork Sun unsigned int ocd = 0; /* 0x0=OCD not supported, 16455614e71bSYork Sun 0x7=OCD default state */ 16465614e71bSYork Sun unsigned int rtt; 16475614e71bSYork Sun unsigned int al; /* Posted CAS# additive latency (AL) */ 16485614e71bSYork Sun unsigned int ods = 0; /* Output Drive Strength: 16495614e71bSYork Sun 0 = Full strength (18ohm) 16505614e71bSYork Sun 1 = Reduced strength (4ohm) */ 16515614e71bSYork Sun unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), 16525614e71bSYork Sun 1=Disable (Test/Debug) */ 16535614e71bSYork Sun 16545614e71bSYork Sun /* Mode Register (MR) */ 16555614e71bSYork Sun unsigned int mr; /* Mode Register Definition */ 16565614e71bSYork Sun unsigned int pd; /* Power-Down Mode */ 16575614e71bSYork Sun unsigned int wr; /* Write Recovery */ 16585614e71bSYork Sun unsigned int dll_res; /* DLL Reset */ 16595614e71bSYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 16605614e71bSYork Sun unsigned int caslat = 0;/* CAS# latency */ 16615614e71bSYork Sun /* BT: Burst Type (0=Sequential, 1=Interleaved) */ 16625614e71bSYork Sun unsigned int bt; 16635614e71bSYork Sun unsigned int bl; /* BL: Burst Length */ 16645614e71bSYork Sun 16655614e71bSYork Sun dqs_en = !popts->dqs_config; 16665614e71bSYork Sun rtt = fsl_ddr_get_rtt(); 16675614e71bSYork Sun 16685614e71bSYork Sun al = additive_latency; 16695614e71bSYork Sun 16705614e71bSYork Sun esdmode = (0 16715614e71bSYork Sun | ((mrs & 0x3) << 14) 16725614e71bSYork Sun | ((outputs & 0x1) << 12) 16735614e71bSYork Sun | ((rdqs_en & 0x1) << 11) 16745614e71bSYork Sun | ((dqs_en & 0x1) << 10) 16755614e71bSYork Sun | ((ocd & 0x7) << 7) 16765614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 16775614e71bSYork Sun | ((al & 0x7) << 3) 16785614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 16795614e71bSYork Sun | ((ods & 0x1) << 1) 16805614e71bSYork Sun | ((dll_en & 0x1) << 0) 16815614e71bSYork Sun ); 16825614e71bSYork Sun 16835614e71bSYork Sun mr = 0; /* FIXME: CHECKME */ 16845614e71bSYork Sun 16855614e71bSYork Sun /* 16865614e71bSYork Sun * 0 = Fast Exit (Normal) 16875614e71bSYork Sun * 1 = Slow Exit (Low Power) 16885614e71bSYork Sun */ 16895614e71bSYork Sun pd = 0; 16905614e71bSYork Sun 16915614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 16925614e71bSYork Sun wr = 0; /* Historical */ 16935614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 169403e664d8SYork Sun wr = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 16955614e71bSYork Sun #endif 16965614e71bSYork Sun dll_res = 0; 16975614e71bSYork Sun mode = 0; 16985614e71bSYork Sun 16995614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 17005614e71bSYork Sun if (1 <= cas_latency && cas_latency <= 4) { 17015614e71bSYork Sun unsigned char mode_caslat_table[4] = { 17025614e71bSYork Sun 0x5, /* 1.5 clocks */ 17035614e71bSYork Sun 0x2, /* 2.0 clocks */ 17045614e71bSYork Sun 0x6, /* 2.5 clocks */ 17055614e71bSYork Sun 0x3 /* 3.0 clocks */ 17065614e71bSYork Sun }; 17075614e71bSYork Sun caslat = mode_caslat_table[cas_latency - 1]; 17085614e71bSYork Sun } else { 17095614e71bSYork Sun printf("Warning: unknown cas_latency %d\n", cas_latency); 17105614e71bSYork Sun } 17115614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 17125614e71bSYork Sun caslat = cas_latency; 17135614e71bSYork Sun #endif 17145614e71bSYork Sun bt = 0; 17155614e71bSYork Sun 17165614e71bSYork Sun switch (popts->burst_length) { 17175614e71bSYork Sun case DDR_BL4: 17185614e71bSYork Sun bl = 2; 17195614e71bSYork Sun break; 17205614e71bSYork Sun case DDR_BL8: 17215614e71bSYork Sun bl = 3; 17225614e71bSYork Sun break; 17235614e71bSYork Sun default: 17245614e71bSYork Sun printf("Error: invalid burst length of %u specified. " 17255614e71bSYork Sun " Defaulting to 4 beats.\n", 17265614e71bSYork Sun popts->burst_length); 17275614e71bSYork Sun bl = 2; 17285614e71bSYork Sun break; 17295614e71bSYork Sun } 17305614e71bSYork Sun 17315614e71bSYork Sun sdmode = (0 17325614e71bSYork Sun | ((mr & 0x3) << 14) 17335614e71bSYork Sun | ((pd & 0x1) << 12) 17345614e71bSYork Sun | ((wr & 0x7) << 9) 17355614e71bSYork Sun | ((dll_res & 0x1) << 8) 17365614e71bSYork Sun | ((mode & 0x1) << 7) 17375614e71bSYork Sun | ((caslat & 0x7) << 4) 17385614e71bSYork Sun | ((bt & 0x1) << 3) 17395614e71bSYork Sun | ((bl & 0x7) << 0) 17405614e71bSYork Sun ); 17415614e71bSYork Sun 17425614e71bSYork Sun ddr->ddr_sdram_mode = (0 17435614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 17445614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 17455614e71bSYork Sun ); 17465614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 17475614e71bSYork Sun } 17485614e71bSYork Sun #endif 17495614e71bSYork Sun 17505614e71bSYork Sun /* DDR SDRAM Data Initialization (DDR_DATA_INIT) */ 17515614e71bSYork Sun static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr) 17525614e71bSYork Sun { 17535614e71bSYork Sun unsigned int init_value; /* Initialization value */ 17545614e71bSYork Sun 17555614e71bSYork Sun #ifdef CONFIG_MEM_INIT_VALUE 17565614e71bSYork Sun init_value = CONFIG_MEM_INIT_VALUE; 17575614e71bSYork Sun #else 17585614e71bSYork Sun init_value = 0xDEADBEEF; 17595614e71bSYork Sun #endif 17605614e71bSYork Sun ddr->ddr_data_init = init_value; 17615614e71bSYork Sun } 17625614e71bSYork Sun 17635614e71bSYork Sun /* 17645614e71bSYork Sun * DDR SDRAM Clock Control (DDR_SDRAM_CLK_CNTL) 17655614e71bSYork Sun * The old controller on the 8540/60 doesn't have this register. 17665614e71bSYork Sun * Hope it's OK to set it (to 0) anyway. 17675614e71bSYork Sun */ 17685614e71bSYork Sun static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr, 17695614e71bSYork Sun const memctl_options_t *popts) 17705614e71bSYork Sun { 17715614e71bSYork Sun unsigned int clk_adjust; /* Clock adjust */ 1772d7c865bdSCurt Brune unsigned int ss_en = 0; /* Source synchronous enable */ 17735614e71bSYork Sun 1774d7c865bdSCurt Brune #if defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) 1775d7c865bdSCurt Brune /* Per FSL Application Note: AN2805 */ 1776d7c865bdSCurt Brune ss_en = 1; 1777d7c865bdSCurt Brune #endif 17785614e71bSYork Sun clk_adjust = popts->clk_adjust; 1779d7c865bdSCurt Brune ddr->ddr_sdram_clk_cntl = (0 1780d7c865bdSCurt Brune | ((ss_en & 0x1) << 31) 1781d7c865bdSCurt Brune | ((clk_adjust & 0xF) << 23) 1782d7c865bdSCurt Brune ); 17835614e71bSYork Sun debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl); 17845614e71bSYork Sun } 17855614e71bSYork Sun 17865614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_ADDR) */ 17875614e71bSYork Sun static void set_ddr_init_addr(fsl_ddr_cfg_regs_t *ddr) 17885614e71bSYork Sun { 17895614e71bSYork Sun unsigned int init_addr = 0; /* Initialization address */ 17905614e71bSYork Sun 17915614e71bSYork Sun ddr->ddr_init_addr = init_addr; 17925614e71bSYork Sun } 17935614e71bSYork Sun 17945614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_EXT_ADDR) */ 17955614e71bSYork Sun static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr) 17965614e71bSYork Sun { 17975614e71bSYork Sun unsigned int uia = 0; /* Use initialization address */ 17985614e71bSYork Sun unsigned int init_ext_addr = 0; /* Initialization address */ 17995614e71bSYork Sun 18005614e71bSYork Sun ddr->ddr_init_ext_addr = (0 18015614e71bSYork Sun | ((uia & 0x1) << 31) 18025614e71bSYork Sun | (init_ext_addr & 0xF) 18035614e71bSYork Sun ); 18045614e71bSYork Sun } 18055614e71bSYork Sun 18065614e71bSYork Sun /* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */ 18075614e71bSYork Sun static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr, 18085614e71bSYork Sun const memctl_options_t *popts) 18095614e71bSYork Sun { 18105614e71bSYork Sun unsigned int rwt = 0; /* Read-to-write turnaround for same CS */ 18115614e71bSYork Sun unsigned int wrt = 0; /* Write-to-read turnaround for same CS */ 18125614e71bSYork Sun unsigned int rrt = 0; /* Read-to-read turnaround for same CS */ 18135614e71bSYork Sun unsigned int wwt = 0; /* Write-to-write turnaround for same CS */ 18145614e71bSYork Sun unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */ 18155614e71bSYork Sun 181634e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 18175614e71bSYork Sun if (popts->burst_length == DDR_BL8) { 18185614e71bSYork Sun /* We set BL/2 for fixed BL8 */ 18195614e71bSYork Sun rrt = 0; /* BL/2 clocks */ 18205614e71bSYork Sun wwt = 0; /* BL/2 clocks */ 18215614e71bSYork Sun } else { 18225614e71bSYork Sun /* We need to set BL/2 + 2 to BC4 and OTF */ 18235614e71bSYork Sun rrt = 2; /* BL/2 + 2 clocks */ 18245614e71bSYork Sun wwt = 2; /* BL/2 + 2 clocks */ 18255614e71bSYork Sun } 182634e026f9SYork Sun #endif 182734e026f9SYork Sun 182834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 182934e026f9SYork Sun dll_lock = 2; /* tDLLK = 1024 clocks */ 183034e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 18315614e71bSYork Sun dll_lock = 1; /* tDLLK = 512 clocks from spec */ 18325614e71bSYork Sun #endif 18335614e71bSYork Sun ddr->timing_cfg_4 = (0 18345614e71bSYork Sun | ((rwt & 0xf) << 28) 18355614e71bSYork Sun | ((wrt & 0xf) << 24) 18365614e71bSYork Sun | ((rrt & 0xf) << 20) 18375614e71bSYork Sun | ((wwt & 0xf) << 16) 18385614e71bSYork Sun | (dll_lock & 0x3) 18395614e71bSYork Sun ); 18405614e71bSYork Sun debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4); 18415614e71bSYork Sun } 18425614e71bSYork Sun 18435614e71bSYork Sun /* DDR SDRAM Timing Configuration 5 (TIMING_CFG_5) */ 18445614e71bSYork Sun static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr, unsigned int cas_latency) 18455614e71bSYork Sun { 18465614e71bSYork Sun unsigned int rodt_on = 0; /* Read to ODT on */ 18475614e71bSYork Sun unsigned int rodt_off = 0; /* Read to ODT off */ 18485614e71bSYork Sun unsigned int wodt_on = 0; /* Write to ODT on */ 18495614e71bSYork Sun unsigned int wodt_off = 0; /* Write to ODT off */ 18505614e71bSYork Sun 185134e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 185234e026f9SYork Sun unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 185334e026f9SYork Sun ((ddr->timing_cfg_2 & 0x00040000) >> 14); 18545614e71bSYork Sun /* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */ 185534e026f9SYork Sun if (cas_latency >= wr_lat) 185634e026f9SYork Sun rodt_on = cas_latency - wr_lat + 1; 18575614e71bSYork Sun rodt_off = 4; /* 4 clocks */ 18585614e71bSYork Sun wodt_on = 1; /* 1 clocks */ 18595614e71bSYork Sun wodt_off = 4; /* 4 clocks */ 18605614e71bSYork Sun #endif 18615614e71bSYork Sun 18625614e71bSYork Sun ddr->timing_cfg_5 = (0 18635614e71bSYork Sun | ((rodt_on & 0x1f) << 24) 18645614e71bSYork Sun | ((rodt_off & 0x7) << 20) 18655614e71bSYork Sun | ((wodt_on & 0x1f) << 12) 18665614e71bSYork Sun | ((wodt_off & 0x7) << 8) 18675614e71bSYork Sun ); 18685614e71bSYork Sun debug("FSLDDR: timing_cfg_5 = 0x%08x\n", ddr->timing_cfg_5); 18695614e71bSYork Sun } 18705614e71bSYork Sun 187134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 187234e026f9SYork Sun static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr) 187334e026f9SYork Sun { 187434e026f9SYork Sun unsigned int hs_caslat = 0; 187534e026f9SYork Sun unsigned int hs_wrlat = 0; 187634e026f9SYork Sun unsigned int hs_wrrec = 0; 187734e026f9SYork Sun unsigned int hs_clkadj = 0; 187834e026f9SYork Sun unsigned int hs_wrlvl_start = 0; 187934e026f9SYork Sun 188034e026f9SYork Sun ddr->timing_cfg_6 = (0 188134e026f9SYork Sun | ((hs_caslat & 0x1f) << 24) 188234e026f9SYork Sun | ((hs_wrlat & 0x1f) << 19) 188334e026f9SYork Sun | ((hs_wrrec & 0x1f) << 12) 188434e026f9SYork Sun | ((hs_clkadj & 0x1f) << 6) 188534e026f9SYork Sun | ((hs_wrlvl_start & 0x1f) << 0) 188634e026f9SYork Sun ); 188734e026f9SYork Sun debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6); 188834e026f9SYork Sun } 188934e026f9SYork Sun 189003e664d8SYork Sun static void set_timing_cfg_7(const unsigned int ctrl_num, 189103e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 189234e026f9SYork Sun const common_timing_params_t *common_dimm) 189334e026f9SYork Sun { 189434e026f9SYork Sun unsigned int txpr, tcksre, tcksrx; 189534e026f9SYork Sun unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd; 189634e026f9SYork Sun 189703e664d8SYork Sun txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000)); 189803e664d8SYork Sun tcksre = max(5U, picos_to_mclk(ctrl_num, 10000)); 189903e664d8SYork Sun tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000)); 190034e026f9SYork Sun par_lat = 0; 190134e026f9SYork Sun cs_to_cmd = 0; 190234e026f9SYork Sun 190334e026f9SYork Sun if (txpr <= 200) 190434e026f9SYork Sun cke_rst = 0; 190534e026f9SYork Sun else if (txpr <= 256) 190634e026f9SYork Sun cke_rst = 1; 190734e026f9SYork Sun else if (txpr <= 512) 190834e026f9SYork Sun cke_rst = 2; 190934e026f9SYork Sun else 191034e026f9SYork Sun cke_rst = 3; 191134e026f9SYork Sun 191234e026f9SYork Sun if (tcksre <= 19) 191334e026f9SYork Sun cksre = tcksre - 5; 191434e026f9SYork Sun else 191534e026f9SYork Sun cksre = 15; 191634e026f9SYork Sun 191734e026f9SYork Sun if (tcksrx <= 19) 191834e026f9SYork Sun cksrx = tcksrx - 5; 191934e026f9SYork Sun else 192034e026f9SYork Sun cksrx = 15; 192134e026f9SYork Sun 192234e026f9SYork Sun ddr->timing_cfg_7 = (0 192334e026f9SYork Sun | ((cke_rst & 0x3) << 28) 192434e026f9SYork Sun | ((cksre & 0xf) << 24) 192534e026f9SYork Sun | ((cksrx & 0xf) << 20) 192634e026f9SYork Sun | ((par_lat & 0xf) << 16) 192734e026f9SYork Sun | ((cs_to_cmd & 0xf) << 4) 192834e026f9SYork Sun ); 192934e026f9SYork Sun debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7); 193034e026f9SYork Sun } 193134e026f9SYork Sun 193203e664d8SYork Sun static void set_timing_cfg_8(const unsigned int ctrl_num, 193303e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 193434e026f9SYork Sun const memctl_options_t *popts, 193534e026f9SYork Sun const common_timing_params_t *common_dimm, 193634e026f9SYork Sun unsigned int cas_latency) 193734e026f9SYork Sun { 193834e026f9SYork Sun unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg; 193934e026f9SYork Sun unsigned int acttoact_bg, wrtord_bg, pre_all_rec; 194003e664d8SYork Sun unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); 194134e026f9SYork Sun unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 194234e026f9SYork Sun ((ddr->timing_cfg_2 & 0x00040000) >> 14); 194334e026f9SYork Sun 194434e026f9SYork Sun rwt_bg = cas_latency + 2 + 4 - wr_lat; 194534e026f9SYork Sun if (rwt_bg < tccdl) 194634e026f9SYork Sun rwt_bg = tccdl - rwt_bg; 194734e026f9SYork Sun else 194834e026f9SYork Sun rwt_bg = 0; 194934e026f9SYork Sun 195034e026f9SYork Sun wrt_bg = wr_lat + 4 + 1 - cas_latency; 195134e026f9SYork Sun if (wrt_bg < tccdl) 195234e026f9SYork Sun wrt_bg = tccdl - wrt_bg; 195334e026f9SYork Sun else 195434e026f9SYork Sun wrt_bg = 0; 195534e026f9SYork Sun 195634e026f9SYork Sun if (popts->burst_length == DDR_BL8) { 195734e026f9SYork Sun rrt_bg = tccdl - 4; 195834e026f9SYork Sun wwt_bg = tccdl - 4; 195934e026f9SYork Sun } else { 196034e026f9SYork Sun rrt_bg = tccdl - 2; 1961dc1437afSYork Sun wwt_bg = tccdl - 2; 196234e026f9SYork Sun } 196334e026f9SYork Sun 196403e664d8SYork Sun acttoact_bg = picos_to_mclk(ctrl_num, common_dimm->trrdl_ps); 196503e664d8SYork Sun wrtord_bg = max(4U, picos_to_mclk(ctrl_num, 7500)); 19663d75ec95SYork Sun if (popts->otf_burst_chop_en) 19673d75ec95SYork Sun wrtord_bg += 2; 19683d75ec95SYork Sun 196934e026f9SYork Sun pre_all_rec = 0; 197034e026f9SYork Sun 197134e026f9SYork Sun ddr->timing_cfg_8 = (0 197234e026f9SYork Sun | ((rwt_bg & 0xf) << 28) 197334e026f9SYork Sun | ((wrt_bg & 0xf) << 24) 197434e026f9SYork Sun | ((rrt_bg & 0xf) << 20) 197534e026f9SYork Sun | ((wwt_bg & 0xf) << 16) 197634e026f9SYork Sun | ((acttoact_bg & 0xf) << 12) 197734e026f9SYork Sun | ((wrtord_bg & 0xf) << 8) 197834e026f9SYork Sun | ((pre_all_rec & 0x1f) << 0) 197934e026f9SYork Sun ); 198034e026f9SYork Sun 198134e026f9SYork Sun debug("FSLDDR: timing_cfg_8 = 0x%08x\n", ddr->timing_cfg_8); 198234e026f9SYork Sun } 198334e026f9SYork Sun 198434e026f9SYork Sun static void set_timing_cfg_9(fsl_ddr_cfg_regs_t *ddr) 198534e026f9SYork Sun { 198634e026f9SYork Sun ddr->timing_cfg_9 = 0; 198734e026f9SYork Sun debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9); 198834e026f9SYork Sun } 198934e026f9SYork Sun 1990f80d6472SYork Sun /* This function needs to be called after set_ddr_sdram_cfg() is called */ 199134e026f9SYork Sun static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr, 199234e026f9SYork Sun const dimm_params_t *dimm_params) 199334e026f9SYork Sun { 1994f80d6472SYork Sun unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1; 19956b95be22SYork Sun int i; 1996f80d6472SYork Sun 19976b95be22SYork Sun for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { 19986b95be22SYork Sun if (dimm_params[i].n_ranks) 19996b95be22SYork Sun break; 20006b95be22SYork Sun } 20016b95be22SYork Sun if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) { 20026b95be22SYork Sun puts("DDR error: no DIMM found!\n"); 20036b95be22SYork Sun return; 20046b95be22SYork Sun } 200534e026f9SYork Sun 20066b95be22SYork Sun ddr->dq_map_0 = ((dimm_params[i].dq_mapping[0] & 0x3F) << 26) | 20076b95be22SYork Sun ((dimm_params[i].dq_mapping[1] & 0x3F) << 20) | 20086b95be22SYork Sun ((dimm_params[i].dq_mapping[2] & 0x3F) << 14) | 20096b95be22SYork Sun ((dimm_params[i].dq_mapping[3] & 0x3F) << 8) | 20106b95be22SYork Sun ((dimm_params[i].dq_mapping[4] & 0x3F) << 2); 201134e026f9SYork Sun 20126b95be22SYork Sun ddr->dq_map_1 = ((dimm_params[i].dq_mapping[5] & 0x3F) << 26) | 20136b95be22SYork Sun ((dimm_params[i].dq_mapping[6] & 0x3F) << 20) | 20146b95be22SYork Sun ((dimm_params[i].dq_mapping[7] & 0x3F) << 14) | 20156b95be22SYork Sun ((dimm_params[i].dq_mapping[10] & 0x3F) << 8) | 20166b95be22SYork Sun ((dimm_params[i].dq_mapping[11] & 0x3F) << 2); 20176b95be22SYork Sun 20186b95be22SYork Sun ddr->dq_map_2 = ((dimm_params[i].dq_mapping[12] & 0x3F) << 26) | 20196b95be22SYork Sun ((dimm_params[i].dq_mapping[13] & 0x3F) << 20) | 20206b95be22SYork Sun ((dimm_params[i].dq_mapping[14] & 0x3F) << 14) | 20216b95be22SYork Sun ((dimm_params[i].dq_mapping[15] & 0x3F) << 8) | 20226b95be22SYork Sun ((dimm_params[i].dq_mapping[16] & 0x3F) << 2); 202334e026f9SYork Sun 2024f80d6472SYork Sun /* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */ 20256b95be22SYork Sun ddr->dq_map_3 = ((dimm_params[i].dq_mapping[17] & 0x3F) << 26) | 20266b95be22SYork Sun ((dimm_params[i].dq_mapping[8] & 0x3F) << 20) | 2027f80d6472SYork Sun (acc_ecc_en ? 0 : 20286b95be22SYork Sun (dimm_params[i].dq_mapping[9] & 0x3F) << 14) | 20296b95be22SYork Sun dimm_params[i].dq_mapping_ors; 203034e026f9SYork Sun 203134e026f9SYork Sun debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0); 203234e026f9SYork Sun debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1); 203334e026f9SYork Sun debug("FSLDDR: dq_map_2 = 0x%08x\n", ddr->dq_map_2); 203434e026f9SYork Sun debug("FSLDDR: dq_map_3 = 0x%08x\n", ddr->dq_map_3); 203534e026f9SYork Sun } 203634e026f9SYork Sun static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr, 203734e026f9SYork Sun const memctl_options_t *popts) 203834e026f9SYork Sun { 203934e026f9SYork Sun int rd_pre; 204034e026f9SYork Sun 204134e026f9SYork Sun rd_pre = popts->quad_rank_present ? 1 : 0; 204234e026f9SYork Sun 204334e026f9SYork Sun ddr->ddr_sdram_cfg_3 = (rd_pre & 0x1) << 16; 204434e026f9SYork Sun 204534e026f9SYork Sun debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3); 204634e026f9SYork Sun } 204734e026f9SYork Sun #endif /* CONFIG_SYS_FSL_DDR4 */ 204834e026f9SYork Sun 20495614e71bSYork Sun /* DDR ZQ Calibration Control (DDR_ZQ_CNTL) */ 20505614e71bSYork Sun static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en) 20515614e71bSYork Sun { 20525614e71bSYork Sun unsigned int zqinit = 0;/* POR ZQ Calibration Time (tZQinit) */ 20535614e71bSYork Sun /* Normal Operation Full Calibration Time (tZQoper) */ 20545614e71bSYork Sun unsigned int zqoper = 0; 20555614e71bSYork Sun /* Normal Operation Short Calibration Time (tZQCS) */ 20565614e71bSYork Sun unsigned int zqcs = 0; 205734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 205834e026f9SYork Sun unsigned int zqcs_init; 205934e026f9SYork Sun #endif 20605614e71bSYork Sun 20615614e71bSYork Sun if (zq_en) { 206234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 206334e026f9SYork Sun zqinit = 10; /* 1024 clocks */ 206434e026f9SYork Sun zqoper = 9; /* 512 clocks */ 206534e026f9SYork Sun zqcs = 7; /* 128 clocks */ 206634e026f9SYork Sun zqcs_init = 5; /* 1024 refresh sequences */ 206734e026f9SYork Sun #else 20685614e71bSYork Sun zqinit = 9; /* 512 clocks */ 20695614e71bSYork Sun zqoper = 8; /* 256 clocks */ 20705614e71bSYork Sun zqcs = 6; /* 64 clocks */ 207134e026f9SYork Sun #endif 20725614e71bSYork Sun } 20735614e71bSYork Sun 20745614e71bSYork Sun ddr->ddr_zq_cntl = (0 20755614e71bSYork Sun | ((zq_en & 0x1) << 31) 20765614e71bSYork Sun | ((zqinit & 0xF) << 24) 20775614e71bSYork Sun | ((zqoper & 0xF) << 16) 20785614e71bSYork Sun | ((zqcs & 0xF) << 8) 207934e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 208034e026f9SYork Sun | ((zqcs_init & 0xF) << 0) 208134e026f9SYork Sun #endif 20825614e71bSYork Sun ); 20835614e71bSYork Sun debug("FSLDDR: zq_cntl = 0x%08x\n", ddr->ddr_zq_cntl); 20845614e71bSYork Sun } 20855614e71bSYork Sun 20865614e71bSYork Sun /* DDR Write Leveling Control (DDR_WRLVL_CNTL) */ 20875614e71bSYork Sun static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en, 20885614e71bSYork Sun const memctl_options_t *popts) 20895614e71bSYork Sun { 20905614e71bSYork Sun /* 20915614e71bSYork Sun * First DQS pulse rising edge after margining mode 20925614e71bSYork Sun * is programmed (tWL_MRD) 20935614e71bSYork Sun */ 20945614e71bSYork Sun unsigned int wrlvl_mrd = 0; 20955614e71bSYork Sun /* ODT delay after margining mode is programmed (tWL_ODTEN) */ 20965614e71bSYork Sun unsigned int wrlvl_odten = 0; 20975614e71bSYork Sun /* DQS/DQS_ delay after margining mode is programmed (tWL_DQSEN) */ 20985614e71bSYork Sun unsigned int wrlvl_dqsen = 0; 20995614e71bSYork Sun /* WRLVL_SMPL: Write leveling sample time */ 21005614e71bSYork Sun unsigned int wrlvl_smpl = 0; 21015614e71bSYork Sun /* WRLVL_WLR: Write leveling repeition time */ 21025614e71bSYork Sun unsigned int wrlvl_wlr = 0; 21035614e71bSYork Sun /* WRLVL_START: Write leveling start time */ 21045614e71bSYork Sun unsigned int wrlvl_start = 0; 21055614e71bSYork Sun 21065614e71bSYork Sun /* suggest enable write leveling for DDR3 due to fly-by topology */ 21075614e71bSYork Sun if (wrlvl_en) { 21085614e71bSYork Sun /* tWL_MRD min = 40 nCK, we set it 64 */ 21095614e71bSYork Sun wrlvl_mrd = 0x6; 21105614e71bSYork Sun /* tWL_ODTEN 128 */ 21115614e71bSYork Sun wrlvl_odten = 0x7; 21125614e71bSYork Sun /* tWL_DQSEN min = 25 nCK, we set it 32 */ 21135614e71bSYork Sun wrlvl_dqsen = 0x5; 21145614e71bSYork Sun /* 21155614e71bSYork Sun * Write leveling sample time at least need 6 clocks 21165614e71bSYork Sun * higher than tWLO to allow enough time for progagation 21175614e71bSYork Sun * delay and sampling the prime data bits. 21185614e71bSYork Sun */ 21195614e71bSYork Sun wrlvl_smpl = 0xf; 21205614e71bSYork Sun /* 21215614e71bSYork Sun * Write leveling repetition time 21225614e71bSYork Sun * at least tWLO + 6 clocks clocks 21235614e71bSYork Sun * we set it 64 21245614e71bSYork Sun */ 21255614e71bSYork Sun wrlvl_wlr = 0x6; 21265614e71bSYork Sun /* 21275614e71bSYork Sun * Write leveling start time 21285614e71bSYork Sun * The value use for the DQS_ADJUST for the first sample 21295614e71bSYork Sun * when write leveling is enabled. It probably needs to be 21305614e71bSYork Sun * overriden per platform. 21315614e71bSYork Sun */ 21325614e71bSYork Sun wrlvl_start = 0x8; 21335614e71bSYork Sun /* 21345614e71bSYork Sun * Override the write leveling sample and start time 21355614e71bSYork Sun * according to specific board 21365614e71bSYork Sun */ 21375614e71bSYork Sun if (popts->wrlvl_override) { 21385614e71bSYork Sun wrlvl_smpl = popts->wrlvl_sample; 21395614e71bSYork Sun wrlvl_start = popts->wrlvl_start; 21405614e71bSYork Sun } 21415614e71bSYork Sun } 21425614e71bSYork Sun 21435614e71bSYork Sun ddr->ddr_wrlvl_cntl = (0 21445614e71bSYork Sun | ((wrlvl_en & 0x1) << 31) 21455614e71bSYork Sun | ((wrlvl_mrd & 0x7) << 24) 21465614e71bSYork Sun | ((wrlvl_odten & 0x7) << 20) 21475614e71bSYork Sun | ((wrlvl_dqsen & 0x7) << 16) 21485614e71bSYork Sun | ((wrlvl_smpl & 0xf) << 12) 21495614e71bSYork Sun | ((wrlvl_wlr & 0x7) << 8) 21505614e71bSYork Sun | ((wrlvl_start & 0x1F) << 0) 21515614e71bSYork Sun ); 21525614e71bSYork Sun debug("FSLDDR: wrlvl_cntl = 0x%08x\n", ddr->ddr_wrlvl_cntl); 21535614e71bSYork Sun ddr->ddr_wrlvl_cntl_2 = popts->wrlvl_ctl_2; 21545614e71bSYork Sun debug("FSLDDR: wrlvl_cntl_2 = 0x%08x\n", ddr->ddr_wrlvl_cntl_2); 21555614e71bSYork Sun ddr->ddr_wrlvl_cntl_3 = popts->wrlvl_ctl_3; 21565614e71bSYork Sun debug("FSLDDR: wrlvl_cntl_3 = 0x%08x\n", ddr->ddr_wrlvl_cntl_3); 21575614e71bSYork Sun 21585614e71bSYork Sun } 21595614e71bSYork Sun 21605614e71bSYork Sun /* DDR Self Refresh Counter (DDR_SR_CNTR) */ 21615614e71bSYork Sun static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it) 21625614e71bSYork Sun { 21635614e71bSYork Sun /* Self Refresh Idle Threshold */ 21645614e71bSYork Sun ddr->ddr_sr_cntr = (sr_it & 0xF) << 16; 21655614e71bSYork Sun } 21665614e71bSYork Sun 21675614e71bSYork Sun static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 21685614e71bSYork Sun { 21695614e71bSYork Sun if (popts->addr_hash) { 21705614e71bSYork Sun ddr->ddr_eor = 0x40000000; /* address hash enable */ 21715614e71bSYork Sun puts("Address hashing enabled.\n"); 21725614e71bSYork Sun } 21735614e71bSYork Sun } 21745614e71bSYork Sun 21755614e71bSYork Sun static void set_ddr_cdr1(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 21765614e71bSYork Sun { 21775614e71bSYork Sun ddr->ddr_cdr1 = popts->ddr_cdr1; 21785614e71bSYork Sun debug("FSLDDR: ddr_cdr1 = 0x%08x\n", ddr->ddr_cdr1); 21795614e71bSYork Sun } 21805614e71bSYork Sun 21815614e71bSYork Sun static void set_ddr_cdr2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 21825614e71bSYork Sun { 21835614e71bSYork Sun ddr->ddr_cdr2 = popts->ddr_cdr2; 21845614e71bSYork Sun debug("FSLDDR: ddr_cdr2 = 0x%08x\n", ddr->ddr_cdr2); 21855614e71bSYork Sun } 21865614e71bSYork Sun 21875614e71bSYork Sun unsigned int 21885614e71bSYork Sun check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) 21895614e71bSYork Sun { 21905614e71bSYork Sun unsigned int res = 0; 21915614e71bSYork Sun 21925614e71bSYork Sun /* 21935614e71bSYork Sun * Check that DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] are 21945614e71bSYork Sun * not set at the same time. 21955614e71bSYork Sun */ 21965614e71bSYork Sun if (ddr->ddr_sdram_cfg & 0x10000000 21975614e71bSYork Sun && ddr->ddr_sdram_cfg & 0x00008000) { 21985614e71bSYork Sun printf("Error: DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] " 21995614e71bSYork Sun " should not be set at the same time.\n"); 22005614e71bSYork Sun res++; 22015614e71bSYork Sun } 22025614e71bSYork Sun 22035614e71bSYork Sun return res; 22045614e71bSYork Sun } 22055614e71bSYork Sun 22065614e71bSYork Sun unsigned int 220703e664d8SYork Sun compute_fsl_memctl_config_regs(const unsigned int ctrl_num, 220803e664d8SYork Sun const memctl_options_t *popts, 22095614e71bSYork Sun fsl_ddr_cfg_regs_t *ddr, 22105614e71bSYork Sun const common_timing_params_t *common_dimm, 22115614e71bSYork Sun const dimm_params_t *dimm_params, 22125614e71bSYork Sun unsigned int dbw_cap_adj, 22135614e71bSYork Sun unsigned int size_only) 22145614e71bSYork Sun { 22155614e71bSYork Sun unsigned int i; 22165614e71bSYork Sun unsigned int cas_latency; 22175614e71bSYork Sun unsigned int additive_latency; 22185614e71bSYork Sun unsigned int sr_it; 22195614e71bSYork Sun unsigned int zq_en; 22205614e71bSYork Sun unsigned int wrlvl_en; 22215614e71bSYork Sun unsigned int ip_rev = 0; 22225614e71bSYork Sun unsigned int unq_mrs_en = 0; 22235614e71bSYork Sun int cs_en = 1; 22245614e71bSYork Sun 22255614e71bSYork Sun memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t)); 22265614e71bSYork Sun 22275614e71bSYork Sun if (common_dimm == NULL) { 22285614e71bSYork Sun printf("Error: subset DIMM params struct null pointer\n"); 22295614e71bSYork Sun return 1; 22305614e71bSYork Sun } 22315614e71bSYork Sun 22325614e71bSYork Sun /* 22335614e71bSYork Sun * Process overrides first. 22345614e71bSYork Sun * 22355614e71bSYork Sun * FIXME: somehow add dereated caslat to this 22365614e71bSYork Sun */ 22375614e71bSYork Sun cas_latency = (popts->cas_latency_override) 22385614e71bSYork Sun ? popts->cas_latency_override_value 223934e026f9SYork Sun : common_dimm->lowest_common_spd_caslat; 22405614e71bSYork Sun 22415614e71bSYork Sun additive_latency = (popts->additive_latency_override) 22425614e71bSYork Sun ? popts->additive_latency_override_value 22435614e71bSYork Sun : common_dimm->additive_latency; 22445614e71bSYork Sun 22455614e71bSYork Sun sr_it = (popts->auto_self_refresh_en) 22465614e71bSYork Sun ? popts->sr_it 22475614e71bSYork Sun : 0; 22485614e71bSYork Sun /* ZQ calibration */ 22495614e71bSYork Sun zq_en = (popts->zq_en) ? 1 : 0; 22505614e71bSYork Sun /* write leveling */ 22515614e71bSYork Sun wrlvl_en = (popts->wrlvl_en) ? 1 : 0; 22525614e71bSYork Sun 22535614e71bSYork Sun /* Chip Select Memory Bounds (CSn_BNDS) */ 22545614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 22555614e71bSYork Sun unsigned long long ea, sa; 22565614e71bSYork Sun unsigned int cs_per_dimm 22575614e71bSYork Sun = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; 22585614e71bSYork Sun unsigned int dimm_number 22595614e71bSYork Sun = i / cs_per_dimm; 22605614e71bSYork Sun unsigned long long rank_density 22615614e71bSYork Sun = dimm_params[dimm_number].rank_density >> dbw_cap_adj; 22625614e71bSYork Sun 22635614e71bSYork Sun if (dimm_params[dimm_number].n_ranks == 0) { 22645614e71bSYork Sun debug("Skipping setup of CS%u " 22655614e71bSYork Sun "because n_ranks on DIMM %u is 0\n", i, dimm_number); 22665614e71bSYork Sun continue; 22675614e71bSYork Sun } 22685614e71bSYork Sun if (popts->memctl_interleaving) { 22695614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 22705614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 22715614e71bSYork Sun break; 22725614e71bSYork Sun case FSL_DDR_CS0_CS1: 22735614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 22745614e71bSYork Sun if (i > 1) 22755614e71bSYork Sun cs_en = 0; 22765614e71bSYork Sun break; 22775614e71bSYork Sun case FSL_DDR_CS2_CS3: 22785614e71bSYork Sun default: 22795614e71bSYork Sun if (i > 0) 22805614e71bSYork Sun cs_en = 0; 22815614e71bSYork Sun break; 22825614e71bSYork Sun } 22835614e71bSYork Sun sa = common_dimm->base_address; 22845614e71bSYork Sun ea = sa + common_dimm->total_mem - 1; 22855614e71bSYork Sun } else if (!popts->memctl_interleaving) { 22865614e71bSYork Sun /* 22875614e71bSYork Sun * If memory interleaving between controllers is NOT 22885614e71bSYork Sun * enabled, the starting address for each memory 22895614e71bSYork Sun * controller is distinct. However, because rank 22905614e71bSYork Sun * interleaving is enabled, the starting and ending 22915614e71bSYork Sun * addresses of the total memory on that memory 22925614e71bSYork Sun * controller needs to be programmed into its 22935614e71bSYork Sun * respective CS0_BNDS. 22945614e71bSYork Sun */ 22955614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 22965614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 22975614e71bSYork Sun sa = common_dimm->base_address; 22985614e71bSYork Sun ea = sa + common_dimm->total_mem - 1; 22995614e71bSYork Sun break; 23005614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 23015614e71bSYork Sun if ((i >= 2) && (dimm_number == 0)) { 23025614e71bSYork Sun sa = dimm_params[dimm_number].base_address + 23035614e71bSYork Sun 2 * rank_density; 23045614e71bSYork Sun ea = sa + 2 * rank_density - 1; 23055614e71bSYork Sun } else { 23065614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 23075614e71bSYork Sun ea = sa + 2 * rank_density - 1; 23085614e71bSYork Sun } 23095614e71bSYork Sun break; 23105614e71bSYork Sun case FSL_DDR_CS0_CS1: 23115614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 23125614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 23135614e71bSYork Sun ea = sa + rank_density - 1; 23145614e71bSYork Sun if (i != 1) 23155614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 23165614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 23175614e71bSYork Sun } else { 23185614e71bSYork Sun sa = 0; 23195614e71bSYork Sun ea = 0; 23205614e71bSYork Sun } 23215614e71bSYork Sun if (i == 0) 23225614e71bSYork Sun ea += rank_density; 23235614e71bSYork Sun break; 23245614e71bSYork Sun case FSL_DDR_CS2_CS3: 23255614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 23265614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 23275614e71bSYork Sun ea = sa + rank_density - 1; 23285614e71bSYork Sun if (i != 3) 23295614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 23305614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 23315614e71bSYork Sun } else { 23325614e71bSYork Sun sa = 0; 23335614e71bSYork Sun ea = 0; 23345614e71bSYork Sun } 23355614e71bSYork Sun if (i == 2) 23365614e71bSYork Sun ea += (rank_density >> dbw_cap_adj); 23375614e71bSYork Sun break; 23385614e71bSYork Sun default: /* No bank(chip-select) interleaving */ 23395614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 23405614e71bSYork Sun ea = sa + rank_density - 1; 23415614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 23425614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 23435614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 23445614e71bSYork Sun } else { 23455614e71bSYork Sun sa = 0; 23465614e71bSYork Sun ea = 0; 23475614e71bSYork Sun } 23485614e71bSYork Sun break; 23495614e71bSYork Sun } 23505614e71bSYork Sun } 23515614e71bSYork Sun 23525614e71bSYork Sun sa >>= 24; 23535614e71bSYork Sun ea >>= 24; 23545614e71bSYork Sun 23555614e71bSYork Sun if (cs_en) { 23565614e71bSYork Sun ddr->cs[i].bnds = (0 2357d4263b8aSYork Sun | ((sa & 0xffff) << 16) /* starting address */ 2358d4263b8aSYork Sun | ((ea & 0xffff) << 0) /* ending address */ 23595614e71bSYork Sun ); 23605614e71bSYork Sun } else { 23615614e71bSYork Sun /* setting bnds to 0xffffffff for inactive CS */ 23625614e71bSYork Sun ddr->cs[i].bnds = 0xffffffff; 23635614e71bSYork Sun } 23645614e71bSYork Sun 23655614e71bSYork Sun debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds); 23665614e71bSYork Sun set_csn_config(dimm_number, i, ddr, popts, dimm_params); 23675614e71bSYork Sun set_csn_config_2(i, ddr); 23685614e71bSYork Sun } 23695614e71bSYork Sun 23705614e71bSYork Sun /* 23715614e71bSYork Sun * In the case we only need to compute the ddr sdram size, we only need 23725614e71bSYork Sun * to set csn registers, so return from here. 23735614e71bSYork Sun */ 23745614e71bSYork Sun if (size_only) 23755614e71bSYork Sun return 0; 23765614e71bSYork Sun 23775614e71bSYork Sun set_ddr_eor(ddr, popts); 23785614e71bSYork Sun 23795614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1) 238003e664d8SYork Sun set_timing_cfg_0(ctrl_num, ddr, popts, dimm_params); 23815614e71bSYork Sun #endif 23825614e71bSYork Sun 238303e664d8SYork Sun set_timing_cfg_3(ctrl_num, ddr, popts, common_dimm, cas_latency, 2384d4263b8aSYork Sun additive_latency); 238503e664d8SYork Sun set_timing_cfg_1(ctrl_num, ddr, popts, common_dimm, cas_latency); 238603e664d8SYork Sun set_timing_cfg_2(ctrl_num, ddr, popts, common_dimm, 23875614e71bSYork Sun cas_latency, additive_latency); 23885614e71bSYork Sun 23895614e71bSYork Sun set_ddr_cdr1(ddr, popts); 23905614e71bSYork Sun set_ddr_cdr2(ddr, popts); 23915614e71bSYork Sun set_ddr_sdram_cfg(ddr, popts, common_dimm); 239266869f95SYork Sun ip_rev = fsl_ddr_get_version(ctrl_num); 23935614e71bSYork Sun if (ip_rev > 0x40400) 23945614e71bSYork Sun unq_mrs_en = 1; 23955614e71bSYork Sun 2396f80d6472SYork Sun if ((ip_rev > 0x40700) && (popts->cswl_override != 0)) 2397ef87cab6SYork Sun ddr->debug[18] = popts->cswl_override; 2398ef87cab6SYork Sun 239903e664d8SYork Sun set_ddr_sdram_cfg_2(ctrl_num, ddr, popts, unq_mrs_en); 240003e664d8SYork Sun set_ddr_sdram_mode(ctrl_num, ddr, popts, common_dimm, 24015614e71bSYork Sun cas_latency, additive_latency, unq_mrs_en); 240203e664d8SYork Sun set_ddr_sdram_mode_2(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); 240334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 240434e026f9SYork Sun set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en); 240503e664d8SYork Sun set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); 240634e026f9SYork Sun #endif 240703e664d8SYork Sun set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm); 24085614e71bSYork Sun set_ddr_data_init(ddr); 24095614e71bSYork Sun set_ddr_sdram_clk_cntl(ddr, popts); 24105614e71bSYork Sun set_ddr_init_addr(ddr); 24115614e71bSYork Sun set_ddr_init_ext_addr(ddr); 24125614e71bSYork Sun set_timing_cfg_4(ddr, popts); 24135614e71bSYork Sun set_timing_cfg_5(ddr, cas_latency); 241434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 241534e026f9SYork Sun set_ddr_sdram_cfg_3(ddr, popts); 241634e026f9SYork Sun set_timing_cfg_6(ddr); 241703e664d8SYork Sun set_timing_cfg_7(ctrl_num, ddr, common_dimm); 241803e664d8SYork Sun set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency); 241934e026f9SYork Sun set_timing_cfg_9(ddr); 242034e026f9SYork Sun set_ddr_dq_mapping(ddr, dimm_params); 242134e026f9SYork Sun #endif 24225614e71bSYork Sun 24235614e71bSYork Sun set_ddr_zq_cntl(ddr, zq_en); 24245614e71bSYork Sun set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts); 24255614e71bSYork Sun 24265614e71bSYork Sun set_ddr_sr_cntr(ddr, sr_it); 24275614e71bSYork Sun 24285614e71bSYork Sun set_ddr_sdram_rcw(ddr, popts, common_dimm); 24295614e71bSYork Sun 24305614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR_EMU 24315614e71bSYork Sun /* disble DDR training for emulator */ 24325614e71bSYork Sun ddr->debug[2] = 0x00000400; 24331f3402e7SYork Sun ddr->debug[4] = 0xff800800; 24341f3402e7SYork Sun ddr->debug[5] = 0x08000800; 24351f3402e7SYork Sun ddr->debug[6] = 0x08000800; 24361f3402e7SYork Sun ddr->debug[7] = 0x08000800; 24371f3402e7SYork Sun ddr->debug[8] = 0x08000800; 24385614e71bSYork Sun #endif 24399855b3beSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_A004508 24409855b3beSYork Sun if ((ip_rev >= 0x40000) && (ip_rev < 0x40400)) 24419855b3beSYork Sun ddr->debug[2] |= 0x00000200; /* set bit 22 */ 24429855b3beSYork Sun #endif 24439855b3beSYork Sun 24445614e71bSYork Sun return check_fsl_memctl_config_regs(ddr); 24455614e71bSYork Sun } 2446