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; 3206c6e006aSYork Sun 3216c6e006aSYork Sun /* 3226c6e006aSYork Sun * for single quad-rank DIMM and two-slot DIMMs 3236c6e006aSYork Sun * to avoid ODT overlap 3246c6e006aSYork Sun */ 3256c6e006aSYork Sun switch (avoid_odt_overlap(dimm_params)) { 3266c6e006aSYork Sun case 2: 3276c6e006aSYork Sun twrt_mclk = 2; 3286c6e006aSYork Sun twwt_mclk = 2; 3296c6e006aSYork Sun trrt_mclk = 2; 3306c6e006aSYork Sun break; 3316c6e006aSYork Sun default: 33234e026f9SYork Sun twrt_mclk = 1; 3336c6e006aSYork Sun twwt_mclk = 1; 3346c6e006aSYork Sun trrt_mclk = 0; 3356c6e006aSYork Sun break; 3366c6e006aSYork Sun } 3376c6e006aSYork Sun 33803e664d8SYork Sun act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); 33934e026f9SYork Sun pre_pd_exit_mclk = act_pd_exit_mclk; 34034e026f9SYork Sun /* 34134e026f9SYork Sun * MRS_CYC = max(tMRD, tMOD) 34234e026f9SYork Sun * tMRD = 8nCK, tMOD = max(24nCK, 15ns) 34334e026f9SYork Sun */ 34403e664d8SYork Sun tmrd_mclk = max(24U, picos_to_mclk(ctrl_num, 15000)); 34534e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 34603e664d8SYork Sun unsigned int data_rate = get_ddr_freq(ctrl_num); 347bb578322SYork Sun int txp; 348938bbb60SYork Sun unsigned int ip_rev; 34984baed2aSYork Sun int odt_overlap; 3505614e71bSYork Sun /* 3515614e71bSYork Sun * (tXARD and tXARDS). Empirical? 3525614e71bSYork Sun * The DDR3 spec has not tXARD, 3535614e71bSYork Sun * we use the tXP instead of it. 354bb578322SYork Sun * tXP=max(3nCK, 7.5ns) for DDR3-800, 1066 355bb578322SYork Sun * max(3nCK, 6ns) for DDR3-1333, 1600, 1866, 2133 3565614e71bSYork Sun * spec has not the tAXPD, we use 3575614e71bSYork Sun * tAXPD=1, need design to confirm. 3585614e71bSYork Sun */ 359b4141195SMasahiro Yamada txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000)); 360bb578322SYork Sun 36166869f95SYork Sun ip_rev = fsl_ddr_get_version(ctrl_num); 362938bbb60SYork Sun if (ip_rev >= 0x40700) { 363938bbb60SYork Sun /* 364938bbb60SYork Sun * MRS_CYC = max(tMRD, tMOD) 365938bbb60SYork Sun * tMRD = 4nCK (8nCK for RDIMM) 366938bbb60SYork Sun * tMOD = max(12nCK, 15ns) 367938bbb60SYork Sun */ 36803e664d8SYork Sun tmrd_mclk = max((unsigned int)12, 36903e664d8SYork Sun picos_to_mclk(ctrl_num, 15000)); 370938bbb60SYork Sun } else { 371938bbb60SYork Sun /* 372938bbb60SYork Sun * MRS_CYC = tMRD 373938bbb60SYork Sun * tMRD = 4nCK (8nCK for RDIMM) 374938bbb60SYork Sun */ 375938bbb60SYork Sun if (popts->registered_dimm_en) 376938bbb60SYork Sun tmrd_mclk = 8; 377938bbb60SYork Sun else 3785614e71bSYork Sun tmrd_mclk = 4; 379938bbb60SYork Sun } 380938bbb60SYork Sun 3815614e71bSYork Sun /* set the turnaround time */ 3825614e71bSYork Sun 3835614e71bSYork Sun /* 38484baed2aSYork Sun * for single quad-rank DIMM and two-slot DIMMs 3855614e71bSYork Sun * to avoid ODT overlap 3865614e71bSYork Sun */ 38784baed2aSYork Sun odt_overlap = avoid_odt_overlap(dimm_params); 38884baed2aSYork Sun switch (odt_overlap) { 38984baed2aSYork Sun case 2: 3905614e71bSYork Sun twwt_mclk = 2; 3915614e71bSYork Sun trrt_mclk = 1; 39284baed2aSYork Sun break; 39384baed2aSYork Sun case 1: 39484baed2aSYork Sun twwt_mclk = 1; 39584baed2aSYork Sun trrt_mclk = 0; 39684baed2aSYork Sun break; 39784baed2aSYork Sun default: 39884baed2aSYork Sun break; 3995614e71bSYork Sun } 40084baed2aSYork Sun 4015614e71bSYork Sun /* for faster clock, need more time for data setup */ 4025614e71bSYork Sun trwt_mclk = (data_rate/1000000 > 1800) ? 2 : 1; 4035614e71bSYork Sun 4045614e71bSYork Sun if ((data_rate/1000000 > 1150) || (popts->memctl_interleaving)) 4055614e71bSYork Sun twrt_mclk = 1; 4065614e71bSYork Sun 4075614e71bSYork Sun if (popts->dynamic_power == 0) { /* powerdown is not used */ 4085614e71bSYork Sun act_pd_exit_mclk = 1; 4095614e71bSYork Sun pre_pd_exit_mclk = 1; 4105614e71bSYork Sun taxpd_mclk = 1; 4115614e71bSYork Sun } else { 4125614e71bSYork Sun /* act_pd_exit_mclk = tXARD, see above */ 41303e664d8SYork Sun act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); 4145614e71bSYork Sun /* Mode register MR0[A12] is '1' - fast exit */ 4155614e71bSYork Sun pre_pd_exit_mclk = act_pd_exit_mclk; 4165614e71bSYork Sun taxpd_mclk = 1; 4175614e71bSYork Sun } 4185614e71bSYork Sun #else /* CONFIG_SYS_FSL_DDR2 */ 4195614e71bSYork Sun /* 4205614e71bSYork Sun * (tXARD and tXARDS). Empirical? 4215614e71bSYork Sun * tXARD = 2 for DDR2 4225614e71bSYork Sun * tXP=2 4235614e71bSYork Sun * tAXPD=8 4245614e71bSYork Sun */ 4255614e71bSYork Sun act_pd_exit_mclk = 2; 4265614e71bSYork Sun pre_pd_exit_mclk = 2; 4275614e71bSYork Sun taxpd_mclk = 8; 4285614e71bSYork Sun tmrd_mclk = 2; 4295614e71bSYork Sun #endif 4305614e71bSYork Sun 4315614e71bSYork Sun if (popts->trwt_override) 4325614e71bSYork Sun trwt_mclk = popts->trwt; 4335614e71bSYork Sun 4345614e71bSYork Sun ddr->timing_cfg_0 = (0 4355614e71bSYork Sun | ((trwt_mclk & 0x3) << 30) /* RWT */ 4365614e71bSYork Sun | ((twrt_mclk & 0x3) << 28) /* WRT */ 4375614e71bSYork Sun | ((trrt_mclk & 0x3) << 26) /* RRT */ 4385614e71bSYork Sun | ((twwt_mclk & 0x3) << 24) /* WWT */ 439d4263b8aSYork Sun | ((act_pd_exit_mclk & 0xf) << 20) /* ACT_PD_EXIT */ 4405614e71bSYork Sun | ((pre_pd_exit_mclk & 0xF) << 16) /* PRE_PD_EXIT */ 4415614e71bSYork Sun | ((taxpd_mclk & 0xf) << 8) /* ODT_PD_EXIT */ 442d4263b8aSYork Sun | ((tmrd_mclk & 0x1f) << 0) /* MRS_CYC */ 4435614e71bSYork Sun ); 4445614e71bSYork Sun debug("FSLDDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0); 4455614e71bSYork Sun } 44684baed2aSYork Sun #endif /* !defined(CONFIG_SYS_FSL_DDR1) */ 4475614e71bSYork Sun 4485614e71bSYork Sun /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ 44903e664d8SYork Sun static void set_timing_cfg_3(const unsigned int ctrl_num, 45003e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 4515614e71bSYork Sun const memctl_options_t *popts, 4525614e71bSYork Sun const common_timing_params_t *common_dimm, 453d4263b8aSYork Sun unsigned int cas_latency, 454d4263b8aSYork Sun unsigned int additive_latency) 4555614e71bSYork Sun { 4565614e71bSYork Sun /* Extended precharge to activate interval (tRP) */ 4575614e71bSYork Sun unsigned int ext_pretoact = 0; 4585614e71bSYork Sun /* Extended Activate to precharge interval (tRAS) */ 4595614e71bSYork Sun unsigned int ext_acttopre = 0; 4605614e71bSYork Sun /* Extended activate to read/write interval (tRCD) */ 4615614e71bSYork Sun unsigned int ext_acttorw = 0; 4625614e71bSYork Sun /* Extended refresh recovery time (tRFC) */ 4635614e71bSYork Sun unsigned int ext_refrec; 4645614e71bSYork Sun /* Extended MCAS latency from READ cmd */ 4655614e71bSYork Sun unsigned int ext_caslat = 0; 466d4263b8aSYork Sun /* Extended additive latency */ 467d4263b8aSYork Sun unsigned int ext_add_lat = 0; 4685614e71bSYork Sun /* Extended last data to precharge interval (tWR) */ 4695614e71bSYork Sun unsigned int ext_wrrec = 0; 4705614e71bSYork Sun /* Control Adjust */ 4715614e71bSYork Sun unsigned int cntl_adj = 0; 4725614e71bSYork Sun 47303e664d8SYork Sun ext_pretoact = picos_to_mclk(ctrl_num, common_dimm->trp_ps) >> 4; 47403e664d8SYork Sun ext_acttopre = picos_to_mclk(ctrl_num, common_dimm->tras_ps) >> 4; 47503e664d8SYork Sun ext_acttorw = picos_to_mclk(ctrl_num, common_dimm->trcd_ps) >> 4; 4765614e71bSYork Sun ext_caslat = (2 * cas_latency - 1) >> 4; 477d4263b8aSYork Sun ext_add_lat = additive_latency >> 4; 47834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 47903e664d8SYork Sun ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8) >> 4; 48034e026f9SYork Sun #else 48103e664d8SYork Sun ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8) >> 4; 4825614e71bSYork Sun /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ 48334e026f9SYork Sun #endif 48403e664d8SYork Sun ext_wrrec = (picos_to_mclk(ctrl_num, common_dimm->twr_ps) + 4855614e71bSYork Sun (popts->otf_burst_chop_en ? 2 : 0)) >> 4; 4865614e71bSYork Sun 4875614e71bSYork Sun ddr->timing_cfg_3 = (0 4885614e71bSYork Sun | ((ext_pretoact & 0x1) << 28) 4895614e71bSYork Sun | ((ext_acttopre & 0x3) << 24) 4905614e71bSYork Sun | ((ext_acttorw & 0x1) << 22) 4915614e71bSYork Sun | ((ext_refrec & 0x1F) << 16) 4925614e71bSYork Sun | ((ext_caslat & 0x3) << 12) 493d4263b8aSYork Sun | ((ext_add_lat & 0x1) << 10) 4945614e71bSYork Sun | ((ext_wrrec & 0x1) << 8) 4955614e71bSYork Sun | ((cntl_adj & 0x7) << 0) 4965614e71bSYork Sun ); 4975614e71bSYork Sun debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3); 4985614e71bSYork Sun } 4995614e71bSYork Sun 5005614e71bSYork Sun /* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */ 50103e664d8SYork Sun static void set_timing_cfg_1(const unsigned int ctrl_num, 50203e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 5035614e71bSYork Sun const memctl_options_t *popts, 5045614e71bSYork Sun const common_timing_params_t *common_dimm, 5055614e71bSYork Sun unsigned int cas_latency) 5065614e71bSYork Sun { 5075614e71bSYork Sun /* Precharge-to-activate interval (tRP) */ 5085614e71bSYork Sun unsigned char pretoact_mclk; 5095614e71bSYork Sun /* Activate to precharge interval (tRAS) */ 5105614e71bSYork Sun unsigned char acttopre_mclk; 5115614e71bSYork Sun /* Activate to read/write interval (tRCD) */ 5125614e71bSYork Sun unsigned char acttorw_mclk; 5135614e71bSYork Sun /* CASLAT */ 5145614e71bSYork Sun unsigned char caslat_ctrl; 5155614e71bSYork Sun /* Refresh recovery time (tRFC) ; trfc_low */ 5165614e71bSYork Sun unsigned char refrec_ctrl; 5175614e71bSYork Sun /* Last data to precharge minimum interval (tWR) */ 5185614e71bSYork Sun unsigned char wrrec_mclk; 5195614e71bSYork Sun /* Activate-to-activate interval (tRRD) */ 5205614e71bSYork Sun unsigned char acttoact_mclk; 5215614e71bSYork Sun /* Last write data pair to read command issue interval (tWTR) */ 5225614e71bSYork Sun unsigned char wrtord_mclk; 52334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 52434e026f9SYork Sun /* DDR4 supports 10, 12, 14, 16, 18, 20, 24 */ 52534e026f9SYork Sun static const u8 wrrec_table[] = { 52634e026f9SYork Sun 10, 10, 10, 10, 10, 52734e026f9SYork Sun 10, 10, 10, 10, 10, 52834e026f9SYork Sun 12, 12, 14, 14, 16, 52934e026f9SYork Sun 16, 18, 18, 20, 20, 53034e026f9SYork Sun 24, 24, 24, 24}; 53134e026f9SYork Sun #else 5325614e71bSYork Sun /* DDR_SDRAM_MODE doesn't support 9,11,13,15 */ 5335614e71bSYork Sun static const u8 wrrec_table[] = { 5345614e71bSYork Sun 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0}; 53534e026f9SYork Sun #endif 5365614e71bSYork Sun 53703e664d8SYork Sun pretoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trp_ps); 53803e664d8SYork Sun acttopre_mclk = picos_to_mclk(ctrl_num, common_dimm->tras_ps); 53903e664d8SYork Sun acttorw_mclk = picos_to_mclk(ctrl_num, common_dimm->trcd_ps); 5405614e71bSYork Sun 5415614e71bSYork Sun /* 5425614e71bSYork Sun * Translate CAS Latency to a DDR controller field value: 5435614e71bSYork Sun * 5445614e71bSYork Sun * CAS Lat DDR I DDR II Ctrl 5455614e71bSYork Sun * Clocks SPD Bit SPD Bit Value 5465614e71bSYork Sun * ------- ------- ------- ----- 5475614e71bSYork Sun * 1.0 0 0001 5485614e71bSYork Sun * 1.5 1 0010 5495614e71bSYork Sun * 2.0 2 2 0011 5505614e71bSYork Sun * 2.5 3 0100 5515614e71bSYork Sun * 3.0 4 3 0101 5525614e71bSYork Sun * 3.5 5 0110 5535614e71bSYork Sun * 4.0 4 0111 5545614e71bSYork Sun * 4.5 1000 5555614e71bSYork Sun * 5.0 5 1001 5565614e71bSYork Sun */ 5575614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 5585614e71bSYork Sun caslat_ctrl = (cas_latency + 1) & 0x07; 5595614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 5605614e71bSYork Sun caslat_ctrl = 2 * cas_latency - 1; 5615614e71bSYork Sun #else 5625614e71bSYork Sun /* 5635614e71bSYork Sun * if the CAS latency more than 8 cycle, 5645614e71bSYork Sun * we need set extend bit for it at 5655614e71bSYork Sun * TIMING_CFG_3[EXT_CASLAT] 5665614e71bSYork Sun */ 56766869f95SYork Sun if (fsl_ddr_get_version(ctrl_num) <= 0x40400) 5685614e71bSYork Sun caslat_ctrl = 2 * cas_latency - 1; 56934e026f9SYork Sun else 57034e026f9SYork Sun caslat_ctrl = (cas_latency - 1) << 1; 5715614e71bSYork Sun #endif 5725614e71bSYork Sun 57334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 57403e664d8SYork Sun refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8; 57503e664d8SYork Sun wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 57603e664d8SYork Sun acttoact_mclk = max(picos_to_mclk(ctrl_num, common_dimm->trrds_ps), 4U); 57703e664d8SYork Sun wrtord_mclk = max(2U, picos_to_mclk(ctrl_num, 2500)); 578349689b8SYork Sun if ((wrrec_mclk < 1) || (wrrec_mclk > 24)) 579349689b8SYork Sun printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); 58034e026f9SYork Sun else 58134e026f9SYork Sun wrrec_mclk = wrrec_table[wrrec_mclk - 1]; 58234e026f9SYork Sun #else 58303e664d8SYork Sun refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8; 58403e664d8SYork Sun wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 58503e664d8SYork Sun acttoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trrd_ps); 58603e664d8SYork Sun wrtord_mclk = picos_to_mclk(ctrl_num, common_dimm->twtr_ps); 587349689b8SYork Sun if ((wrrec_mclk < 1) || (wrrec_mclk > 16)) 588349689b8SYork Sun printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); 5895614e71bSYork Sun else 5905614e71bSYork Sun wrrec_mclk = wrrec_table[wrrec_mclk - 1]; 59134e026f9SYork Sun #endif 5925614e71bSYork Sun if (popts->otf_burst_chop_en) 5935614e71bSYork Sun wrrec_mclk += 2; 5945614e71bSYork Sun 5955614e71bSYork Sun /* 5965614e71bSYork Sun * JEDEC has min requirement for tRRD 5975614e71bSYork Sun */ 5985614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR3) 5995614e71bSYork Sun if (acttoact_mclk < 4) 6005614e71bSYork Sun acttoact_mclk = 4; 6015614e71bSYork Sun #endif 6025614e71bSYork Sun /* 6035614e71bSYork Sun * JEDEC has some min requirements for tWTR 6045614e71bSYork Sun */ 6055614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2) 6065614e71bSYork Sun if (wrtord_mclk < 2) 6075614e71bSYork Sun wrtord_mclk = 2; 6085614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 6095614e71bSYork Sun if (wrtord_mclk < 4) 6105614e71bSYork Sun wrtord_mclk = 4; 6115614e71bSYork Sun #endif 6125614e71bSYork Sun if (popts->otf_burst_chop_en) 6135614e71bSYork Sun wrtord_mclk += 2; 6145614e71bSYork Sun 6155614e71bSYork Sun ddr->timing_cfg_1 = (0 6165614e71bSYork Sun | ((pretoact_mclk & 0x0F) << 28) 6175614e71bSYork Sun | ((acttopre_mclk & 0x0F) << 24) 6185614e71bSYork Sun | ((acttorw_mclk & 0xF) << 20) 6195614e71bSYork Sun | ((caslat_ctrl & 0xF) << 16) 6205614e71bSYork Sun | ((refrec_ctrl & 0xF) << 12) 6215614e71bSYork Sun | ((wrrec_mclk & 0x0F) << 8) 6225614e71bSYork Sun | ((acttoact_mclk & 0x0F) << 4) 6235614e71bSYork Sun | ((wrtord_mclk & 0x0F) << 0) 6245614e71bSYork Sun ); 6255614e71bSYork Sun debug("FSLDDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1); 6265614e71bSYork Sun } 6275614e71bSYork Sun 6285614e71bSYork Sun /* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */ 62903e664d8SYork Sun static void set_timing_cfg_2(const unsigned int ctrl_num, 63003e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 6315614e71bSYork Sun const memctl_options_t *popts, 6325614e71bSYork Sun const common_timing_params_t *common_dimm, 6335614e71bSYork Sun unsigned int cas_latency, 6345614e71bSYork Sun unsigned int additive_latency) 6355614e71bSYork Sun { 6365614e71bSYork Sun /* Additive latency */ 6375614e71bSYork Sun unsigned char add_lat_mclk; 6385614e71bSYork Sun /* CAS-to-preamble override */ 6395614e71bSYork Sun unsigned short cpo; 6405614e71bSYork Sun /* Write latency */ 6415614e71bSYork Sun unsigned char wr_lat; 6425614e71bSYork Sun /* Read to precharge (tRTP) */ 6435614e71bSYork Sun unsigned char rd_to_pre; 6445614e71bSYork Sun /* Write command to write data strobe timing adjustment */ 6455614e71bSYork Sun unsigned char wr_data_delay; 6465614e71bSYork Sun /* Minimum CKE pulse width (tCKE) */ 6475614e71bSYork Sun unsigned char cke_pls; 6485614e71bSYork Sun /* Window for four activates (tFAW) */ 6495614e71bSYork Sun unsigned short four_act; 650bb578322SYork Sun #ifdef CONFIG_SYS_FSL_DDR3 65103e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 652bb578322SYork Sun #endif 6535614e71bSYork Sun 6545614e71bSYork Sun /* FIXME add check that this must be less than acttorw_mclk */ 6555614e71bSYork Sun add_lat_mclk = additive_latency; 6565614e71bSYork Sun cpo = popts->cpo_override; 6575614e71bSYork Sun 6585614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 6595614e71bSYork Sun /* 6605614e71bSYork Sun * This is a lie. It should really be 1, but if it is 6615614e71bSYork Sun * set to 1, bits overlap into the old controller's 6625614e71bSYork Sun * otherwise unused ACSM field. If we leave it 0, then 6635614e71bSYork Sun * the HW will magically treat it as 1 for DDR 1. Oh Yea. 6645614e71bSYork Sun */ 6655614e71bSYork Sun wr_lat = 0; 6665614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 6675614e71bSYork Sun wr_lat = cas_latency - 1; 6685614e71bSYork Sun #else 66903e664d8SYork Sun wr_lat = compute_cas_write_latency(ctrl_num); 6705614e71bSYork Sun #endif 6715614e71bSYork Sun 67234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 67303e664d8SYork Sun rd_to_pre = picos_to_mclk(ctrl_num, 7500); 67434e026f9SYork Sun #else 67503e664d8SYork Sun rd_to_pre = picos_to_mclk(ctrl_num, common_dimm->trtp_ps); 67634e026f9SYork Sun #endif 6775614e71bSYork Sun /* 6785614e71bSYork Sun * JEDEC has some min requirements for tRTP 6795614e71bSYork Sun */ 6805614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2) 6815614e71bSYork Sun if (rd_to_pre < 2) 6825614e71bSYork Sun rd_to_pre = 2; 68334e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 6845614e71bSYork Sun if (rd_to_pre < 4) 6855614e71bSYork Sun rd_to_pre = 4; 6865614e71bSYork Sun #endif 6875614e71bSYork Sun if (popts->otf_burst_chop_en) 6885614e71bSYork Sun rd_to_pre += 2; /* according to UM */ 6895614e71bSYork Sun 6905614e71bSYork Sun wr_data_delay = popts->write_data_delay; 69134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 69234e026f9SYork Sun cpo = 0; 69303e664d8SYork Sun cke_pls = max(3U, picos_to_mclk(ctrl_num, 5000)); 694bb578322SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 695bb578322SYork Sun /* 696bb578322SYork Sun * cke pulse = max(3nCK, 7.5ns) for DDR3-800 697bb578322SYork Sun * max(3nCK, 5.625ns) for DDR3-1066, 1333 698bb578322SYork Sun * max(3nCK, 5ns) for DDR3-1600, 1866, 2133 699bb578322SYork Sun */ 70003e664d8SYork Sun cke_pls = max(3U, picos_to_mclk(ctrl_num, mclk_ps > 1870 ? 7500 : 701bb578322SYork Sun (mclk_ps > 1245 ? 5625 : 5000))); 70234e026f9SYork Sun #else 703bb578322SYork Sun cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR; 70434e026f9SYork Sun #endif 70503e664d8SYork Sun four_act = picos_to_mclk(ctrl_num, 70603e664d8SYork Sun popts->tfaw_window_four_activates_ps); 7075614e71bSYork Sun 7085614e71bSYork Sun ddr->timing_cfg_2 = (0 7095614e71bSYork Sun | ((add_lat_mclk & 0xf) << 28) 7105614e71bSYork Sun | ((cpo & 0x1f) << 23) 7115614e71bSYork Sun | ((wr_lat & 0xf) << 19) 7128936691bSYork Sun | (((wr_lat & 0x10) >> 4) << 18) 7135614e71bSYork Sun | ((rd_to_pre & RD_TO_PRE_MASK) << RD_TO_PRE_SHIFT) 7145614e71bSYork Sun | ((wr_data_delay & WR_DATA_DELAY_MASK) << WR_DATA_DELAY_SHIFT) 7155614e71bSYork Sun | ((cke_pls & 0x7) << 6) 7165614e71bSYork Sun | ((four_act & 0x3f) << 0) 7175614e71bSYork Sun ); 7185614e71bSYork Sun debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2); 7195614e71bSYork Sun } 7205614e71bSYork Sun 7215614e71bSYork Sun /* DDR SDRAM Register Control Word */ 7225614e71bSYork Sun static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, 7235614e71bSYork Sun const memctl_options_t *popts, 7245614e71bSYork Sun const common_timing_params_t *common_dimm) 7255614e71bSYork Sun { 7265614e71bSYork Sun if (common_dimm->all_dimms_registered && 7275614e71bSYork Sun !common_dimm->all_dimms_unbuffered) { 7285614e71bSYork Sun if (popts->rcw_override) { 7295614e71bSYork Sun ddr->ddr_sdram_rcw_1 = popts->rcw_1; 7305614e71bSYork Sun ddr->ddr_sdram_rcw_2 = popts->rcw_2; 7315614e71bSYork Sun } else { 7325614e71bSYork Sun ddr->ddr_sdram_rcw_1 = 7335614e71bSYork Sun common_dimm->rcw[0] << 28 | \ 7345614e71bSYork Sun common_dimm->rcw[1] << 24 | \ 7355614e71bSYork Sun common_dimm->rcw[2] << 20 | \ 7365614e71bSYork Sun common_dimm->rcw[3] << 16 | \ 7375614e71bSYork Sun common_dimm->rcw[4] << 12 | \ 7385614e71bSYork Sun common_dimm->rcw[5] << 8 | \ 7395614e71bSYork Sun common_dimm->rcw[6] << 4 | \ 7405614e71bSYork Sun common_dimm->rcw[7]; 7415614e71bSYork Sun ddr->ddr_sdram_rcw_2 = 7425614e71bSYork Sun common_dimm->rcw[8] << 28 | \ 7435614e71bSYork Sun common_dimm->rcw[9] << 24 | \ 7445614e71bSYork Sun common_dimm->rcw[10] << 20 | \ 7455614e71bSYork Sun common_dimm->rcw[11] << 16 | \ 7465614e71bSYork Sun common_dimm->rcw[12] << 12 | \ 7475614e71bSYork Sun common_dimm->rcw[13] << 8 | \ 7485614e71bSYork Sun common_dimm->rcw[14] << 4 | \ 7495614e71bSYork Sun common_dimm->rcw[15]; 7505614e71bSYork Sun } 7515614e71bSYork Sun debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1); 7525614e71bSYork Sun debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2); 7535614e71bSYork Sun } 7545614e71bSYork Sun } 7555614e71bSYork Sun 7565614e71bSYork Sun /* DDR SDRAM control configuration (DDR_SDRAM_CFG) */ 7575614e71bSYork Sun static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, 7585614e71bSYork Sun const memctl_options_t *popts, 7595614e71bSYork Sun const common_timing_params_t *common_dimm) 7605614e71bSYork Sun { 7615614e71bSYork Sun unsigned int mem_en; /* DDR SDRAM interface logic enable */ 7625614e71bSYork Sun unsigned int sren; /* Self refresh enable (during sleep) */ 7635614e71bSYork Sun unsigned int ecc_en; /* ECC enable. */ 7645614e71bSYork Sun unsigned int rd_en; /* Registered DIMM enable */ 7655614e71bSYork Sun unsigned int sdram_type; /* Type of SDRAM */ 7665614e71bSYork Sun unsigned int dyn_pwr; /* Dynamic power management mode */ 7675614e71bSYork Sun unsigned int dbw; /* DRAM dta bus width */ 7685614e71bSYork Sun unsigned int eight_be = 0; /* 8-beat burst enable, DDR2 is zero */ 7695614e71bSYork Sun unsigned int ncap = 0; /* Non-concurrent auto-precharge */ 7705614e71bSYork Sun unsigned int threet_en; /* Enable 3T timing */ 7715614e71bSYork Sun unsigned int twot_en; /* Enable 2T timing */ 7725614e71bSYork Sun unsigned int ba_intlv_ctl; /* Bank (CS) interleaving control */ 7735614e71bSYork Sun unsigned int x32_en = 0; /* x32 enable */ 7745614e71bSYork Sun unsigned int pchb8 = 0; /* precharge bit 8 enable */ 7755614e71bSYork Sun unsigned int hse; /* Global half strength override */ 776d28cb671SYork Sun unsigned int acc_ecc_en = 0; /* Accumulated ECC enable */ 7775614e71bSYork Sun unsigned int mem_halt = 0; /* memory controller halt */ 7785614e71bSYork Sun unsigned int bi = 0; /* Bypass initialization */ 7795614e71bSYork Sun 7805614e71bSYork Sun mem_en = 1; 7815614e71bSYork Sun sren = popts->self_refresh_in_sleep; 7825614e71bSYork Sun if (common_dimm->all_dimms_ecc_capable) { 7835614e71bSYork Sun /* Allow setting of ECC only if all DIMMs are ECC. */ 7845614e71bSYork Sun ecc_en = popts->ecc_mode; 7855614e71bSYork Sun } else { 7865614e71bSYork Sun ecc_en = 0; 7875614e71bSYork Sun } 7885614e71bSYork Sun 7895614e71bSYork Sun if (common_dimm->all_dimms_registered && 7905614e71bSYork Sun !common_dimm->all_dimms_unbuffered) { 7915614e71bSYork Sun rd_en = 1; 7925614e71bSYork Sun twot_en = 0; 7935614e71bSYork Sun } else { 7945614e71bSYork Sun rd_en = 0; 7955614e71bSYork Sun twot_en = popts->twot_en; 7965614e71bSYork Sun } 7975614e71bSYork Sun 7985614e71bSYork Sun sdram_type = CONFIG_FSL_SDRAM_TYPE; 7995614e71bSYork Sun 8005614e71bSYork Sun dyn_pwr = popts->dynamic_power; 8015614e71bSYork Sun dbw = popts->data_bus_width; 8025614e71bSYork Sun /* 8-beat burst enable DDR-III case 8035614e71bSYork Sun * we must clear it when use the on-the-fly mode, 8045614e71bSYork Sun * must set it when use the 32-bits bus mode. 8055614e71bSYork Sun */ 80634e026f9SYork Sun if ((sdram_type == SDRAM_TYPE_DDR3) || 80734e026f9SYork Sun (sdram_type == SDRAM_TYPE_DDR4)) { 8085614e71bSYork Sun if (popts->burst_length == DDR_BL8) 8095614e71bSYork Sun eight_be = 1; 8105614e71bSYork Sun if (popts->burst_length == DDR_OTF) 8115614e71bSYork Sun eight_be = 0; 8125614e71bSYork Sun if (dbw == 0x1) 8135614e71bSYork Sun eight_be = 1; 8145614e71bSYork Sun } 8155614e71bSYork Sun 8165614e71bSYork Sun threet_en = popts->threet_en; 8175614e71bSYork Sun ba_intlv_ctl = popts->ba_intlv_ctl; 8185614e71bSYork Sun hse = popts->half_strength_driver_enable; 8195614e71bSYork Sun 820d28cb671SYork Sun /* set when ddr bus width < 64 */ 821d28cb671SYork Sun acc_ecc_en = (dbw != 0 && ecc_en == 1) ? 1 : 0; 822d28cb671SYork Sun 8235614e71bSYork Sun ddr->ddr_sdram_cfg = (0 8245614e71bSYork Sun | ((mem_en & 0x1) << 31) 8255614e71bSYork Sun | ((sren & 0x1) << 30) 8265614e71bSYork Sun | ((ecc_en & 0x1) << 29) 8275614e71bSYork Sun | ((rd_en & 0x1) << 28) 8285614e71bSYork Sun | ((sdram_type & 0x7) << 24) 8295614e71bSYork Sun | ((dyn_pwr & 0x1) << 21) 8305614e71bSYork Sun | ((dbw & 0x3) << 19) 8315614e71bSYork Sun | ((eight_be & 0x1) << 18) 8325614e71bSYork Sun | ((ncap & 0x1) << 17) 8335614e71bSYork Sun | ((threet_en & 0x1) << 16) 8345614e71bSYork Sun | ((twot_en & 0x1) << 15) 8355614e71bSYork Sun | ((ba_intlv_ctl & 0x7F) << 8) 8365614e71bSYork Sun | ((x32_en & 0x1) << 5) 8375614e71bSYork Sun | ((pchb8 & 0x1) << 4) 8385614e71bSYork Sun | ((hse & 0x1) << 3) 839d28cb671SYork Sun | ((acc_ecc_en & 0x1) << 2) 8405614e71bSYork Sun | ((mem_halt & 0x1) << 1) 8415614e71bSYork Sun | ((bi & 0x1) << 0) 8425614e71bSYork Sun ); 8435614e71bSYork Sun debug("FSLDDR: ddr_sdram_cfg = 0x%08x\n", ddr->ddr_sdram_cfg); 8445614e71bSYork Sun } 8455614e71bSYork Sun 8465614e71bSYork Sun /* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */ 84703e664d8SYork Sun static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num, 84803e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 8495614e71bSYork Sun const memctl_options_t *popts, 8505614e71bSYork Sun const unsigned int unq_mrs_en) 8515614e71bSYork Sun { 8525614e71bSYork Sun unsigned int frc_sr = 0; /* Force self refresh */ 8535614e71bSYork Sun unsigned int sr_ie = 0; /* Self-refresh interrupt enable */ 8545614e71bSYork Sun unsigned int odt_cfg = 0; /* ODT configuration */ 8555614e71bSYork Sun unsigned int num_pr; /* Number of posted refreshes */ 8565614e71bSYork Sun unsigned int slow = 0; /* DDR will be run less than 1250 */ 8575614e71bSYork Sun unsigned int x4_en = 0; /* x4 DRAM enable */ 8585614e71bSYork Sun unsigned int obc_cfg; /* On-The-Fly Burst Chop Cfg */ 8595614e71bSYork Sun unsigned int ap_en; /* Address Parity Enable */ 8605614e71bSYork Sun unsigned int d_init; /* DRAM data initialization */ 8615614e71bSYork Sun unsigned int rcw_en = 0; /* Register Control Word Enable */ 8625614e71bSYork Sun unsigned int md_en = 0; /* Mirrored DIMM Enable */ 8635614e71bSYork Sun unsigned int qd_en = 0; /* quad-rank DIMM Enable */ 8645614e71bSYork Sun int i; 86534e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4 86634e026f9SYork Sun unsigned int dll_rst_dis = 1; /* DLL reset disable */ 86734e026f9SYork Sun unsigned int dqs_cfg; /* DQS configuration */ 8685614e71bSYork Sun 8695614e71bSYork Sun dqs_cfg = popts->dqs_config; 87034e026f9SYork Sun #endif 8715614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 8725614e71bSYork Sun if (popts->cs_local_opts[i].odt_rd_cfg 8735614e71bSYork Sun || popts->cs_local_opts[i].odt_wr_cfg) { 8745614e71bSYork Sun odt_cfg = SDRAM_CFG2_ODT_ONLY_READ; 8755614e71bSYork Sun break; 8765614e71bSYork Sun } 8775614e71bSYork Sun } 878e368c206SJoakim Tjernlund sr_ie = popts->self_refresh_interrupt_en; 8795614e71bSYork Sun num_pr = 1; /* Make this configurable */ 8805614e71bSYork Sun 8815614e71bSYork Sun /* 8825614e71bSYork Sun * 8572 manual says 8835614e71bSYork Sun * {TIMING_CFG_1[PRETOACT] 8845614e71bSYork Sun * + [DDR_SDRAM_CFG_2[NUM_PR] 8855614e71bSYork Sun * * ({EXT_REFREC || REFREC} + 8 + 2)]} 8865614e71bSYork Sun * << DDR_SDRAM_INTERVAL[REFINT] 8875614e71bSYork Sun */ 88834e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 8895614e71bSYork Sun obc_cfg = popts->otf_burst_chop_en; 8905614e71bSYork Sun #else 8915614e71bSYork Sun obc_cfg = 0; 8925614e71bSYork Sun #endif 8935614e71bSYork Sun 8945614e71bSYork Sun #if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7) 89503e664d8SYork Sun slow = get_ddr_freq(ctrl_num) < 1249000000; 8965614e71bSYork Sun #endif 8975614e71bSYork Sun 898eb118807SShengzhou Liu if (popts->registered_dimm_en) 8995614e71bSYork Sun rcw_en = 1; 900eb118807SShengzhou Liu 901eb118807SShengzhou Liu /* DDR4 can have address parity for UDIMM and discrete */ 902eb118807SShengzhou Liu if ((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) && 903eb118807SShengzhou Liu (!popts->registered_dimm_en)) { 9045614e71bSYork Sun ap_en = 0; 905eb118807SShengzhou Liu } else { 906eb118807SShengzhou Liu ap_en = popts->ap_en; 9075614e71bSYork Sun } 9085614e71bSYork Sun 9095614e71bSYork Sun x4_en = popts->x4_en ? 1 : 0; 9105614e71bSYork Sun 9115614e71bSYork Sun #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) 9125614e71bSYork Sun /* Use the DDR controller to auto initialize memory. */ 9135614e71bSYork Sun d_init = popts->ecc_init_using_memctl; 9145614e71bSYork Sun ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE; 9155614e71bSYork Sun debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init); 9165614e71bSYork Sun #else 9175614e71bSYork Sun /* Memory will be initialized via DMA, or not at all. */ 9185614e71bSYork Sun d_init = 0; 9195614e71bSYork Sun #endif 9205614e71bSYork Sun 92134e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 9225614e71bSYork Sun md_en = popts->mirrored_dimm; 9235614e71bSYork Sun #endif 9245614e71bSYork Sun qd_en = popts->quad_rank_present ? 1 : 0; 9255614e71bSYork Sun ddr->ddr_sdram_cfg_2 = (0 9265614e71bSYork Sun | ((frc_sr & 0x1) << 31) 9275614e71bSYork Sun | ((sr_ie & 0x1) << 30) 92834e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4 9295614e71bSYork Sun | ((dll_rst_dis & 0x1) << 29) 9305614e71bSYork Sun | ((dqs_cfg & 0x3) << 26) 93134e026f9SYork Sun #endif 9325614e71bSYork Sun | ((odt_cfg & 0x3) << 21) 9335614e71bSYork Sun | ((num_pr & 0xf) << 12) 9345614e71bSYork Sun | ((slow & 1) << 11) 9355614e71bSYork Sun | (x4_en << 10) 9365614e71bSYork Sun | (qd_en << 9) 9375614e71bSYork Sun | (unq_mrs_en << 8) 9385614e71bSYork Sun | ((obc_cfg & 0x1) << 6) 9395614e71bSYork Sun | ((ap_en & 0x1) << 5) 9405614e71bSYork Sun | ((d_init & 0x1) << 4) 9415614e71bSYork Sun | ((rcw_en & 0x1) << 2) 9425614e71bSYork Sun | ((md_en & 0x1) << 0) 9435614e71bSYork Sun ); 9445614e71bSYork Sun debug("FSLDDR: ddr_sdram_cfg_2 = 0x%08x\n", ddr->ddr_sdram_cfg_2); 9455614e71bSYork Sun } 9465614e71bSYork Sun 94734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 9485614e71bSYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 94903e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, 95003e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 9515614e71bSYork Sun const memctl_options_t *popts, 9525614e71bSYork Sun const common_timing_params_t *common_dimm, 9535614e71bSYork Sun const unsigned int unq_mrs_en) 9545614e71bSYork Sun { 9555614e71bSYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 9565614e71bSYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 9575614e71bSYork Sun int i; 95834e026f9SYork Sun unsigned int wr_crc = 0; /* Disable */ 9595614e71bSYork Sun unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ 9605614e71bSYork Sun unsigned int srt = 0; /* self-refresh temerature, normal range */ 96103e664d8SYork Sun unsigned int cwl = compute_cas_write_latency(ctrl_num) - 9; 96234e026f9SYork Sun unsigned int mpr = 0; /* serial */ 96334e026f9SYork Sun unsigned int wc_lat; 96403e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 9655614e71bSYork Sun 9665614e71bSYork Sun if (popts->rtt_override) 9675614e71bSYork Sun rtt_wr = popts->rtt_wr_override_value; 9685614e71bSYork Sun else 9695614e71bSYork Sun rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; 9705614e71bSYork Sun 9715614e71bSYork Sun if (common_dimm->extended_op_srt) 9725614e71bSYork Sun srt = common_dimm->extended_op_srt; 9735614e71bSYork Sun 9745614e71bSYork Sun esdmode2 = (0 97534e026f9SYork Sun | ((wr_crc & 0x1) << 12) 9765614e71bSYork Sun | ((rtt_wr & 0x3) << 9) 97734e026f9SYork Sun | ((srt & 0x3) << 6) 97834e026f9SYork Sun | ((cwl & 0x7) << 3)); 97934e026f9SYork Sun 98034e026f9SYork Sun if (mclk_ps >= 1250) 98134e026f9SYork Sun wc_lat = 0; 98234e026f9SYork Sun else if (mclk_ps >= 833) 98334e026f9SYork Sun wc_lat = 1; 98434e026f9SYork Sun else 98534e026f9SYork Sun wc_lat = 2; 98634e026f9SYork Sun 98734e026f9SYork Sun esdmode3 = (0 98834e026f9SYork Sun | ((mpr & 0x3) << 11) 98934e026f9SYork Sun | ((wc_lat & 0x3) << 9)); 99034e026f9SYork Sun 9915614e71bSYork Sun ddr->ddr_sdram_mode_2 = (0 9925614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 9935614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 9945614e71bSYork Sun ); 9955614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 9965614e71bSYork Sun 9975614e71bSYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 9985614e71bSYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 9995614e71bSYork Sun if (popts->rtt_override) 10005614e71bSYork Sun rtt_wr = popts->rtt_wr_override_value; 10015614e71bSYork Sun else 10025614e71bSYork Sun rtt_wr = popts->cs_local_opts[i].odt_rtt_wr; 10035614e71bSYork Sun 10045614e71bSYork Sun esdmode2 &= 0xF9FF; /* clear bit 10, 9 */ 10055614e71bSYork Sun esdmode2 |= (rtt_wr & 0x3) << 9; 10065614e71bSYork Sun switch (i) { 10075614e71bSYork Sun case 1: 10085614e71bSYork Sun ddr->ddr_sdram_mode_4 = (0 10095614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 10105614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 10115614e71bSYork Sun ); 10125614e71bSYork Sun break; 10135614e71bSYork Sun case 2: 10145614e71bSYork Sun ddr->ddr_sdram_mode_6 = (0 10155614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 10165614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 10175614e71bSYork Sun ); 10185614e71bSYork Sun break; 10195614e71bSYork Sun case 3: 10205614e71bSYork Sun ddr->ddr_sdram_mode_8 = (0 10215614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 10225614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 10235614e71bSYork Sun ); 10245614e71bSYork Sun break; 10255614e71bSYork Sun } 10265614e71bSYork Sun } 10275614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", 10285614e71bSYork Sun ddr->ddr_sdram_mode_4); 10295614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", 10305614e71bSYork Sun ddr->ddr_sdram_mode_6); 10315614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", 10325614e71bSYork Sun ddr->ddr_sdram_mode_8); 10335614e71bSYork Sun } 10345614e71bSYork Sun } 103534e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 103634e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 103703e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, 103803e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 103934e026f9SYork Sun const memctl_options_t *popts, 104034e026f9SYork Sun const common_timing_params_t *common_dimm, 104134e026f9SYork Sun const unsigned int unq_mrs_en) 104234e026f9SYork Sun { 104334e026f9SYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 104434e026f9SYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 104534e026f9SYork Sun int i; 104634e026f9SYork Sun unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ 104734e026f9SYork Sun unsigned int srt = 0; /* self-refresh temerature, normal range */ 104834e026f9SYork Sun unsigned int asr = 0; /* auto self-refresh disable */ 104903e664d8SYork Sun unsigned int cwl = compute_cas_write_latency(ctrl_num) - 5; 105034e026f9SYork Sun unsigned int pasr = 0; /* partial array self refresh disable */ 105134e026f9SYork Sun 105234e026f9SYork Sun if (popts->rtt_override) 105334e026f9SYork Sun rtt_wr = popts->rtt_wr_override_value; 105434e026f9SYork Sun else 105534e026f9SYork Sun rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; 105634e026f9SYork Sun 105734e026f9SYork Sun if (common_dimm->extended_op_srt) 105834e026f9SYork Sun srt = common_dimm->extended_op_srt; 105934e026f9SYork Sun 106034e026f9SYork Sun esdmode2 = (0 106134e026f9SYork Sun | ((rtt_wr & 0x3) << 9) 106234e026f9SYork Sun | ((srt & 0x1) << 7) 106334e026f9SYork Sun | ((asr & 0x1) << 6) 106434e026f9SYork Sun | ((cwl & 0x7) << 3) 106534e026f9SYork Sun | ((pasr & 0x7) << 0)); 106634e026f9SYork Sun ddr->ddr_sdram_mode_2 = (0 106734e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 106834e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 106934e026f9SYork Sun ); 107034e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 107134e026f9SYork Sun 107234e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 107334e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 107434e026f9SYork Sun if (popts->rtt_override) 107534e026f9SYork Sun rtt_wr = popts->rtt_wr_override_value; 107634e026f9SYork Sun else 107734e026f9SYork Sun rtt_wr = popts->cs_local_opts[i].odt_rtt_wr; 107834e026f9SYork Sun 107934e026f9SYork Sun esdmode2 &= 0xF9FF; /* clear bit 10, 9 */ 108034e026f9SYork Sun esdmode2 |= (rtt_wr & 0x3) << 9; 108134e026f9SYork Sun switch (i) { 108234e026f9SYork Sun case 1: 108334e026f9SYork Sun ddr->ddr_sdram_mode_4 = (0 108434e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 108534e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 108634e026f9SYork Sun ); 108734e026f9SYork Sun break; 108834e026f9SYork Sun case 2: 108934e026f9SYork Sun ddr->ddr_sdram_mode_6 = (0 109034e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 109134e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 109234e026f9SYork Sun ); 109334e026f9SYork Sun break; 109434e026f9SYork Sun case 3: 109534e026f9SYork Sun ddr->ddr_sdram_mode_8 = (0 109634e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 109734e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 109834e026f9SYork Sun ); 109934e026f9SYork Sun break; 110034e026f9SYork Sun } 110134e026f9SYork Sun } 110234e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", 110334e026f9SYork Sun ddr->ddr_sdram_mode_4); 110434e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", 110534e026f9SYork Sun ddr->ddr_sdram_mode_6); 110634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", 110734e026f9SYork Sun ddr->ddr_sdram_mode_8); 110834e026f9SYork Sun } 110934e026f9SYork Sun } 111034e026f9SYork Sun 111134e026f9SYork Sun #else /* for DDR2 and DDR1 */ 111234e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 111303e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, 111403e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 111534e026f9SYork Sun const memctl_options_t *popts, 111634e026f9SYork Sun const common_timing_params_t *common_dimm, 111734e026f9SYork Sun const unsigned int unq_mrs_en) 111834e026f9SYork Sun { 111934e026f9SYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 112034e026f9SYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 112134e026f9SYork Sun 112234e026f9SYork Sun ddr->ddr_sdram_mode_2 = (0 112334e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 112434e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 112534e026f9SYork Sun ); 112634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 112734e026f9SYork Sun } 112834e026f9SYork Sun #endif 112934e026f9SYork Sun 113034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 113134e026f9SYork Sun /* DDR SDRAM Mode configuration 9 (DDR_SDRAM_MODE_9) */ 113234e026f9SYork Sun static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, 113334e026f9SYork Sun const memctl_options_t *popts, 113434e026f9SYork Sun const common_timing_params_t *common_dimm, 113534e026f9SYork Sun const unsigned int unq_mrs_en) 113634e026f9SYork Sun { 113734e026f9SYork Sun int i; 113834e026f9SYork Sun unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */ 113934e026f9SYork Sun unsigned short esdmode5; /* Extended SDRAM mode 5 */ 11406b95be22SYork Sun int rtt_park = 0; 11418a51429eSYork Sun bool four_cs = false; 1142eb118807SShengzhou Liu const unsigned int mclk_ps = get_memory_clk_period_ps(0); 114334e026f9SYork Sun 11448a51429eSYork Sun #if CONFIG_CHIP_SELECTS_PER_CTRL == 4 11458a51429eSYork Sun if ((ddr->cs[0].config & SDRAM_CS_CONFIG_EN) && 11468a51429eSYork Sun (ddr->cs[1].config & SDRAM_CS_CONFIG_EN) && 11478a51429eSYork Sun (ddr->cs[2].config & SDRAM_CS_CONFIG_EN) && 11488a51429eSYork Sun (ddr->cs[3].config & SDRAM_CS_CONFIG_EN)) 11498a51429eSYork Sun four_cs = true; 11508a51429eSYork Sun #endif 11516b95be22SYork Sun if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) { 11526b95be22SYork Sun esdmode5 = 0x00000500; /* Data mask enable, RTT_PARK CS0 */ 11538a51429eSYork Sun rtt_park = four_cs ? 0 : 1; 11546b95be22SYork Sun } else { 11556b95be22SYork Sun esdmode5 = 0x00000400; /* Data mask enabled */ 11566b95be22SYork Sun } 115734e026f9SYork Sun 1158eb118807SShengzhou Liu /* set command/address parity latency */ 1159eb118807SShengzhou Liu if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { 1160eb118807SShengzhou Liu if (mclk_ps >= 935) { 1161eb118807SShengzhou Liu /* for DDR4-1600/1866/2133 */ 1162eb118807SShengzhou Liu esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK; 1163eb118807SShengzhou Liu } else if (mclk_ps >= 833) { 1164eb118807SShengzhou Liu /* for DDR4-2400 */ 1165eb118807SShengzhou Liu esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK; 1166eb118807SShengzhou Liu } else { 1167eb118807SShengzhou Liu printf("parity: mclk_ps = %d not supported\n", mclk_ps); 1168eb118807SShengzhou Liu } 1169eb118807SShengzhou Liu } 1170eb118807SShengzhou Liu 117134e026f9SYork Sun ddr->ddr_sdram_mode_9 = (0 117234e026f9SYork Sun | ((esdmode4 & 0xffff) << 16) 117334e026f9SYork Sun | ((esdmode5 & 0xffff) << 0) 117434e026f9SYork Sun ); 117566869f95SYork Sun 11768a51429eSYork Sun /* Normally only the first enabled CS use 0x500, others use 0x400 11778a51429eSYork Sun * But when four chip-selects are all enabled, all mode registers 11788a51429eSYork Sun * need 0x500 to park. 11798a51429eSYork Sun */ 118066869f95SYork Sun 118134e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9); 118234e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 118334e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 11846b95be22SYork Sun if (!rtt_park && 11856b95be22SYork Sun (ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) { 11866b95be22SYork Sun esdmode5 |= 0x00000500; /* RTT_PARK */ 11878a51429eSYork Sun rtt_park = four_cs ? 0 : 1; 11886b95be22SYork Sun } else { 11896b95be22SYork Sun esdmode5 = 0x00000400; 11906b95be22SYork Sun } 1191eb118807SShengzhou Liu 1192eb118807SShengzhou Liu if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { 1193eb118807SShengzhou Liu if (mclk_ps >= 935) { 1194eb118807SShengzhou Liu /* for DDR4-1600/1866/2133 */ 1195eb118807SShengzhou Liu esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK; 1196eb118807SShengzhou Liu } else if (mclk_ps >= 833) { 1197eb118807SShengzhou Liu /* for DDR4-2400 */ 1198eb118807SShengzhou Liu esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK; 1199eb118807SShengzhou Liu } else { 1200eb118807SShengzhou Liu printf("parity: mclk_ps = %d not supported\n", 1201eb118807SShengzhou Liu mclk_ps); 1202eb118807SShengzhou Liu } 1203eb118807SShengzhou Liu } 1204eb118807SShengzhou Liu 120534e026f9SYork Sun switch (i) { 120634e026f9SYork Sun case 1: 120734e026f9SYork Sun ddr->ddr_sdram_mode_11 = (0 120834e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 120934e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 121034e026f9SYork Sun ); 121134e026f9SYork Sun break; 121234e026f9SYork Sun case 2: 121334e026f9SYork Sun ddr->ddr_sdram_mode_13 = (0 121434e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 121534e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 121634e026f9SYork Sun ); 121734e026f9SYork Sun break; 121834e026f9SYork Sun case 3: 121934e026f9SYork Sun ddr->ddr_sdram_mode_15 = (0 122034e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 122134e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 122234e026f9SYork Sun ); 122334e026f9SYork Sun break; 122434e026f9SYork Sun } 122534e026f9SYork Sun } 122634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_11 = 0x%08x\n", 122734e026f9SYork Sun ddr->ddr_sdram_mode_11); 122834e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_13 = 0x%08x\n", 122934e026f9SYork Sun ddr->ddr_sdram_mode_13); 123034e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_15 = 0x%08x\n", 123134e026f9SYork Sun ddr->ddr_sdram_mode_15); 123234e026f9SYork Sun } 123334e026f9SYork Sun } 123434e026f9SYork Sun 123534e026f9SYork Sun /* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */ 123603e664d8SYork Sun static void set_ddr_sdram_mode_10(const unsigned int ctrl_num, 123703e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 123834e026f9SYork Sun const memctl_options_t *popts, 123934e026f9SYork Sun const common_timing_params_t *common_dimm, 124034e026f9SYork Sun const unsigned int unq_mrs_en) 124134e026f9SYork Sun { 124234e026f9SYork Sun int i; 124334e026f9SYork Sun unsigned short esdmode6 = 0; /* Extended SDRAM mode 6 */ 124434e026f9SYork Sun unsigned short esdmode7 = 0; /* Extended SDRAM mode 7 */ 124503e664d8SYork Sun unsigned int tccdl_min = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); 124634e026f9SYork Sun 124734e026f9SYork Sun esdmode6 = ((tccdl_min - 4) & 0x7) << 10; 124834e026f9SYork Sun 12490fb71974SYork Sun if (popts->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2) 12500fb71974SYork Sun esdmode6 |= 1 << 6; /* Range 2 */ 12510fb71974SYork Sun 125234e026f9SYork Sun ddr->ddr_sdram_mode_10 = (0 125334e026f9SYork Sun | ((esdmode6 & 0xffff) << 16) 125434e026f9SYork Sun | ((esdmode7 & 0xffff) << 0) 125534e026f9SYork Sun ); 125634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_10) = 0x%08x\n", ddr->ddr_sdram_mode_10); 125734e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 125834e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 125934e026f9SYork Sun switch (i) { 126034e026f9SYork Sun case 1: 126134e026f9SYork Sun ddr->ddr_sdram_mode_12 = (0 126234e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 126334e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 126434e026f9SYork Sun ); 126534e026f9SYork Sun break; 126634e026f9SYork Sun case 2: 126734e026f9SYork Sun ddr->ddr_sdram_mode_14 = (0 126834e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 126934e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 127034e026f9SYork Sun ); 127134e026f9SYork Sun break; 127234e026f9SYork Sun case 3: 127334e026f9SYork Sun ddr->ddr_sdram_mode_16 = (0 127434e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 127534e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 127634e026f9SYork Sun ); 127734e026f9SYork Sun break; 127834e026f9SYork Sun } 127934e026f9SYork Sun } 128034e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_12 = 0x%08x\n", 128134e026f9SYork Sun ddr->ddr_sdram_mode_12); 128234e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_14 = 0x%08x\n", 128334e026f9SYork Sun ddr->ddr_sdram_mode_14); 128434e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_16 = 0x%08x\n", 128534e026f9SYork Sun ddr->ddr_sdram_mode_16); 128634e026f9SYork Sun } 128734e026f9SYork Sun } 128834e026f9SYork Sun 128934e026f9SYork Sun #endif 12905614e71bSYork Sun 12915614e71bSYork Sun /* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */ 129203e664d8SYork Sun static void set_ddr_sdram_interval(const unsigned int ctrl_num, 129303e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 12945614e71bSYork Sun const memctl_options_t *popts, 12955614e71bSYork Sun const common_timing_params_t *common_dimm) 12965614e71bSYork Sun { 12975614e71bSYork Sun unsigned int refint; /* Refresh interval */ 12985614e71bSYork Sun unsigned int bstopre; /* Precharge interval */ 12995614e71bSYork Sun 130003e664d8SYork Sun refint = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps); 13015614e71bSYork Sun 13025614e71bSYork Sun bstopre = popts->bstopre; 13035614e71bSYork Sun 13045614e71bSYork Sun /* refint field used 0x3FFF in earlier controllers */ 13055614e71bSYork Sun ddr->ddr_sdram_interval = (0 13065614e71bSYork Sun | ((refint & 0xFFFF) << 16) 13075614e71bSYork Sun | ((bstopre & 0x3FFF) << 0) 13085614e71bSYork Sun ); 13095614e71bSYork Sun debug("FSLDDR: ddr_sdram_interval = 0x%08x\n", ddr->ddr_sdram_interval); 13105614e71bSYork Sun } 13115614e71bSYork Sun 131234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 13135614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 131403e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num, 131503e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 13165614e71bSYork Sun const memctl_options_t *popts, 13175614e71bSYork Sun const common_timing_params_t *common_dimm, 13185614e71bSYork Sun unsigned int cas_latency, 13195614e71bSYork Sun unsigned int additive_latency, 13205614e71bSYork Sun const unsigned int unq_mrs_en) 13215614e71bSYork Sun { 132234e026f9SYork Sun int i; 132334e026f9SYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 132434e026f9SYork Sun unsigned short sdmode; /* SDRAM mode */ 132534e026f9SYork Sun 132634e026f9SYork Sun /* Mode Register - MR1 */ 132734e026f9SYork Sun unsigned int qoff = 0; /* Output buffer enable 0=yes, 1=no */ 132834e026f9SYork Sun unsigned int tdqs_en = 0; /* TDQS Enable: 0=no, 1=yes */ 132934e026f9SYork Sun unsigned int rtt; 133034e026f9SYork Sun unsigned int wrlvl_en = 0; /* Write level enable: 0=no, 1=yes */ 133134e026f9SYork Sun unsigned int al = 0; /* Posted CAS# additive latency (AL) */ 133234e026f9SYork Sun unsigned int dic = 0; /* Output driver impedance, 40ohm */ 133334e026f9SYork Sun unsigned int dll_en = 1; /* DLL Enable 1=Enable (Normal), 133434e026f9SYork Sun 0=Disable (Test/Debug) */ 133534e026f9SYork Sun 133634e026f9SYork Sun /* Mode Register - MR0 */ 133734e026f9SYork Sun unsigned int wr = 0; /* Write Recovery */ 133834e026f9SYork Sun unsigned int dll_rst; /* DLL Reset */ 133934e026f9SYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 134034e026f9SYork Sun unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ 134134e026f9SYork Sun /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ 134234e026f9SYork Sun unsigned int bt; 134334e026f9SYork Sun unsigned int bl; /* BL: Burst Length */ 134434e026f9SYork Sun 134534e026f9SYork Sun unsigned int wr_mclk; 134634e026f9SYork Sun /* DDR4 support WR 10, 12, 14, 16, 18, 20, 24 */ 134734e026f9SYork Sun static const u8 wr_table[] = { 134834e026f9SYork Sun 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6}; 134934e026f9SYork Sun /* DDR4 support CAS 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24 */ 135034e026f9SYork Sun static const u8 cas_latency_table[] = { 135134e026f9SYork Sun 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 135234e026f9SYork Sun 9, 9, 10, 10, 11, 11}; 135334e026f9SYork Sun 135434e026f9SYork Sun if (popts->rtt_override) 135534e026f9SYork Sun rtt = popts->rtt_override_value; 135634e026f9SYork Sun else 135734e026f9SYork Sun rtt = popts->cs_local_opts[0].odt_rtt_norm; 135834e026f9SYork Sun 135934e026f9SYork Sun if (additive_latency == (cas_latency - 1)) 136034e026f9SYork Sun al = 1; 136134e026f9SYork Sun if (additive_latency == (cas_latency - 2)) 136234e026f9SYork Sun al = 2; 136334e026f9SYork Sun 136434e026f9SYork Sun if (popts->quad_rank_present) 136534e026f9SYork Sun dic = 1; /* output driver impedance 240/7 ohm */ 136634e026f9SYork Sun 136734e026f9SYork Sun /* 136834e026f9SYork Sun * The esdmode value will also be used for writing 136934e026f9SYork Sun * MR1 during write leveling for DDR3, although the 137034e026f9SYork Sun * bits specifically related to the write leveling 137134e026f9SYork Sun * scheme will be handled automatically by the DDR 137234e026f9SYork Sun * controller. so we set the wrlvl_en = 0 here. 137334e026f9SYork Sun */ 137434e026f9SYork Sun esdmode = (0 137534e026f9SYork Sun | ((qoff & 0x1) << 12) 137634e026f9SYork Sun | ((tdqs_en & 0x1) << 11) 137734e026f9SYork Sun | ((rtt & 0x7) << 8) 137834e026f9SYork Sun | ((wrlvl_en & 0x1) << 7) 137934e026f9SYork Sun | ((al & 0x3) << 3) 138034e026f9SYork Sun | ((dic & 0x3) << 1) /* DIC field is split */ 138134e026f9SYork Sun | ((dll_en & 0x1) << 0) 138234e026f9SYork Sun ); 138334e026f9SYork Sun 138434e026f9SYork Sun /* 138534e026f9SYork Sun * DLL control for precharge PD 138634e026f9SYork Sun * 0=slow exit DLL off (tXPDLL) 138734e026f9SYork Sun * 1=fast exit DLL on (tXP) 138834e026f9SYork Sun */ 138934e026f9SYork Sun 139003e664d8SYork Sun wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 139134e026f9SYork Sun if (wr_mclk <= 24) { 139234e026f9SYork Sun wr = wr_table[wr_mclk - 10]; 139334e026f9SYork Sun } else { 139434e026f9SYork Sun printf("Error: unsupported write recovery for mode register wr_mclk = %d\n", 139534e026f9SYork Sun wr_mclk); 139634e026f9SYork Sun } 139734e026f9SYork Sun 139834e026f9SYork Sun dll_rst = 0; /* dll no reset */ 139934e026f9SYork Sun mode = 0; /* normal mode */ 140034e026f9SYork Sun 140134e026f9SYork Sun /* look up table to get the cas latency bits */ 140234e026f9SYork Sun if (cas_latency >= 9 && cas_latency <= 24) 140334e026f9SYork Sun caslat = cas_latency_table[cas_latency - 9]; 140434e026f9SYork Sun else 140534e026f9SYork Sun printf("Error: unsupported cas latency for mode register\n"); 140634e026f9SYork Sun 140734e026f9SYork Sun bt = 0; /* Nibble sequential */ 140834e026f9SYork Sun 140934e026f9SYork Sun switch (popts->burst_length) { 141034e026f9SYork Sun case DDR_BL8: 141134e026f9SYork Sun bl = 0; 141234e026f9SYork Sun break; 141334e026f9SYork Sun case DDR_OTF: 141434e026f9SYork Sun bl = 1; 141534e026f9SYork Sun break; 141634e026f9SYork Sun case DDR_BC4: 141734e026f9SYork Sun bl = 2; 141834e026f9SYork Sun break; 141934e026f9SYork Sun default: 142034e026f9SYork Sun printf("Error: invalid burst length of %u specified. ", 142134e026f9SYork Sun popts->burst_length); 142234e026f9SYork Sun puts("Defaulting to on-the-fly BC4 or BL8 beats.\n"); 142334e026f9SYork Sun bl = 1; 142434e026f9SYork Sun break; 142534e026f9SYork Sun } 142634e026f9SYork Sun 142734e026f9SYork Sun sdmode = (0 142834e026f9SYork Sun | ((wr & 0x7) << 9) 142934e026f9SYork Sun | ((dll_rst & 0x1) << 8) 143034e026f9SYork Sun | ((mode & 0x1) << 7) 143134e026f9SYork Sun | (((caslat >> 1) & 0x7) << 4) 143234e026f9SYork Sun | ((bt & 0x1) << 3) 143334e026f9SYork Sun | ((caslat & 1) << 2) 143434e026f9SYork Sun | ((bl & 0x3) << 0) 143534e026f9SYork Sun ); 143634e026f9SYork Sun 143734e026f9SYork Sun ddr->ddr_sdram_mode = (0 143834e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 143934e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 144034e026f9SYork Sun ); 144134e026f9SYork Sun 144234e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 144334e026f9SYork Sun 144434e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 144534e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 144634e026f9SYork Sun if (popts->rtt_override) 144734e026f9SYork Sun rtt = popts->rtt_override_value; 144834e026f9SYork Sun else 144934e026f9SYork Sun rtt = popts->cs_local_opts[i].odt_rtt_norm; 145034e026f9SYork Sun 145134e026f9SYork Sun esdmode &= 0xF8FF; /* clear bit 10,9,8 for rtt */ 145234e026f9SYork Sun esdmode |= (rtt & 0x7) << 8; 145334e026f9SYork Sun switch (i) { 145434e026f9SYork Sun case 1: 145534e026f9SYork Sun ddr->ddr_sdram_mode_3 = (0 145634e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 145734e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 145834e026f9SYork Sun ); 145934e026f9SYork Sun break; 146034e026f9SYork Sun case 2: 146134e026f9SYork Sun ddr->ddr_sdram_mode_5 = (0 146234e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 146334e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 146434e026f9SYork Sun ); 146534e026f9SYork Sun break; 146634e026f9SYork Sun case 3: 146734e026f9SYork Sun ddr->ddr_sdram_mode_7 = (0 146834e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 146934e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 147034e026f9SYork Sun ); 147134e026f9SYork Sun break; 147234e026f9SYork Sun } 147334e026f9SYork Sun } 147434e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", 147534e026f9SYork Sun ddr->ddr_sdram_mode_3); 147634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 147734e026f9SYork Sun ddr->ddr_sdram_mode_5); 147834e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 147934e026f9SYork Sun ddr->ddr_sdram_mode_5); 148034e026f9SYork Sun } 148134e026f9SYork Sun } 148234e026f9SYork Sun 148334e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 148434e026f9SYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 148503e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num, 148603e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 148734e026f9SYork Sun const memctl_options_t *popts, 148834e026f9SYork Sun const common_timing_params_t *common_dimm, 148934e026f9SYork Sun unsigned int cas_latency, 149034e026f9SYork Sun unsigned int additive_latency, 149134e026f9SYork Sun const unsigned int unq_mrs_en) 149234e026f9SYork Sun { 149334e026f9SYork Sun int i; 14945614e71bSYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 14955614e71bSYork Sun unsigned short sdmode; /* SDRAM mode */ 14965614e71bSYork Sun 14975614e71bSYork Sun /* Mode Register - MR1 */ 14985614e71bSYork Sun unsigned int qoff = 0; /* Output buffer enable 0=yes, 1=no */ 14995614e71bSYork Sun unsigned int tdqs_en = 0; /* TDQS Enable: 0=no, 1=yes */ 15005614e71bSYork Sun unsigned int rtt; 15015614e71bSYork Sun unsigned int wrlvl_en = 0; /* Write level enable: 0=no, 1=yes */ 15025614e71bSYork Sun unsigned int al = 0; /* Posted CAS# additive latency (AL) */ 15035614e71bSYork Sun unsigned int dic = 0; /* Output driver impedance, 40ohm */ 15045614e71bSYork Sun unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), 15055614e71bSYork Sun 1=Disable (Test/Debug) */ 15065614e71bSYork Sun 15075614e71bSYork Sun /* Mode Register - MR0 */ 15085614e71bSYork Sun unsigned int dll_on; /* DLL control for precharge PD, 0=off, 1=on */ 15095614e71bSYork Sun unsigned int wr = 0; /* Write Recovery */ 15105614e71bSYork Sun unsigned int dll_rst; /* DLL Reset */ 15115614e71bSYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 15125614e71bSYork Sun unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ 15135614e71bSYork Sun /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ 15145614e71bSYork Sun unsigned int bt; 15155614e71bSYork Sun unsigned int bl; /* BL: Burst Length */ 15165614e71bSYork Sun 15175614e71bSYork Sun unsigned int wr_mclk; 15185614e71bSYork Sun /* 15195614e71bSYork Sun * DDR_SDRAM_MODE doesn't support 9,11,13,15 15205614e71bSYork Sun * Please refer JEDEC Standard No. 79-3E for Mode Register MR0 15215614e71bSYork Sun * for this table 15225614e71bSYork Sun */ 15235614e71bSYork Sun static const u8 wr_table[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0}; 15245614e71bSYork Sun 15255614e71bSYork Sun if (popts->rtt_override) 15265614e71bSYork Sun rtt = popts->rtt_override_value; 15275614e71bSYork Sun else 15285614e71bSYork Sun rtt = popts->cs_local_opts[0].odt_rtt_norm; 15295614e71bSYork Sun 15305614e71bSYork Sun if (additive_latency == (cas_latency - 1)) 15315614e71bSYork Sun al = 1; 15325614e71bSYork Sun if (additive_latency == (cas_latency - 2)) 15335614e71bSYork Sun al = 2; 15345614e71bSYork Sun 15355614e71bSYork Sun if (popts->quad_rank_present) 15365614e71bSYork Sun dic = 1; /* output driver impedance 240/7 ohm */ 15375614e71bSYork Sun 15385614e71bSYork Sun /* 15395614e71bSYork Sun * The esdmode value will also be used for writing 15405614e71bSYork Sun * MR1 during write leveling for DDR3, although the 15415614e71bSYork Sun * bits specifically related to the write leveling 15425614e71bSYork Sun * scheme will be handled automatically by the DDR 15435614e71bSYork Sun * controller. so we set the wrlvl_en = 0 here. 15445614e71bSYork Sun */ 15455614e71bSYork Sun esdmode = (0 15465614e71bSYork Sun | ((qoff & 0x1) << 12) 15475614e71bSYork Sun | ((tdqs_en & 0x1) << 11) 15485614e71bSYork Sun | ((rtt & 0x4) << 7) /* rtt field is split */ 15495614e71bSYork Sun | ((wrlvl_en & 0x1) << 7) 15505614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 15515614e71bSYork Sun | ((dic & 0x2) << 4) /* DIC field is split */ 15525614e71bSYork Sun | ((al & 0x3) << 3) 15535614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 15545614e71bSYork Sun | ((dic & 0x1) << 1) /* DIC field is split */ 15555614e71bSYork Sun | ((dll_en & 0x1) << 0) 15565614e71bSYork Sun ); 15575614e71bSYork Sun 15585614e71bSYork Sun /* 15595614e71bSYork Sun * DLL control for precharge PD 15605614e71bSYork Sun * 0=slow exit DLL off (tXPDLL) 15615614e71bSYork Sun * 1=fast exit DLL on (tXP) 15625614e71bSYork Sun */ 15635614e71bSYork Sun dll_on = 1; 15645614e71bSYork Sun 156503e664d8SYork Sun wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 15665614e71bSYork Sun if (wr_mclk <= 16) { 15675614e71bSYork Sun wr = wr_table[wr_mclk - 5]; 15685614e71bSYork Sun } else { 15695614e71bSYork Sun printf("Error: unsupported write recovery for mode register " 15705614e71bSYork Sun "wr_mclk = %d\n", wr_mclk); 15715614e71bSYork Sun } 15725614e71bSYork Sun 15735614e71bSYork Sun dll_rst = 0; /* dll no reset */ 15745614e71bSYork Sun mode = 0; /* normal mode */ 15755614e71bSYork Sun 15765614e71bSYork Sun /* look up table to get the cas latency bits */ 15775614e71bSYork Sun if (cas_latency >= 5 && cas_latency <= 16) { 15785614e71bSYork Sun unsigned char cas_latency_table[] = { 15795614e71bSYork Sun 0x2, /* 5 clocks */ 15805614e71bSYork Sun 0x4, /* 6 clocks */ 15815614e71bSYork Sun 0x6, /* 7 clocks */ 15825614e71bSYork Sun 0x8, /* 8 clocks */ 15835614e71bSYork Sun 0xa, /* 9 clocks */ 15845614e71bSYork Sun 0xc, /* 10 clocks */ 15855614e71bSYork Sun 0xe, /* 11 clocks */ 15865614e71bSYork Sun 0x1, /* 12 clocks */ 15875614e71bSYork Sun 0x3, /* 13 clocks */ 15885614e71bSYork Sun 0x5, /* 14 clocks */ 15895614e71bSYork Sun 0x7, /* 15 clocks */ 15905614e71bSYork Sun 0x9, /* 16 clocks */ 15915614e71bSYork Sun }; 15925614e71bSYork Sun caslat = cas_latency_table[cas_latency - 5]; 15935614e71bSYork Sun } else { 15945614e71bSYork Sun printf("Error: unsupported cas latency for mode register\n"); 15955614e71bSYork Sun } 15965614e71bSYork Sun 15975614e71bSYork Sun bt = 0; /* Nibble sequential */ 15985614e71bSYork Sun 15995614e71bSYork Sun switch (popts->burst_length) { 16005614e71bSYork Sun case DDR_BL8: 16015614e71bSYork Sun bl = 0; 16025614e71bSYork Sun break; 16035614e71bSYork Sun case DDR_OTF: 16045614e71bSYork Sun bl = 1; 16055614e71bSYork Sun break; 16065614e71bSYork Sun case DDR_BC4: 16075614e71bSYork Sun bl = 2; 16085614e71bSYork Sun break; 16095614e71bSYork Sun default: 16105614e71bSYork Sun printf("Error: invalid burst length of %u specified. " 16115614e71bSYork Sun " Defaulting to on-the-fly BC4 or BL8 beats.\n", 16125614e71bSYork Sun popts->burst_length); 16135614e71bSYork Sun bl = 1; 16145614e71bSYork Sun break; 16155614e71bSYork Sun } 16165614e71bSYork Sun 16175614e71bSYork Sun sdmode = (0 16185614e71bSYork Sun | ((dll_on & 0x1) << 12) 16195614e71bSYork Sun | ((wr & 0x7) << 9) 16205614e71bSYork Sun | ((dll_rst & 0x1) << 8) 16215614e71bSYork Sun | ((mode & 0x1) << 7) 16225614e71bSYork Sun | (((caslat >> 1) & 0x7) << 4) 16235614e71bSYork Sun | ((bt & 0x1) << 3) 16245614e71bSYork Sun | ((caslat & 1) << 2) 16255614e71bSYork Sun | ((bl & 0x3) << 0) 16265614e71bSYork Sun ); 16275614e71bSYork Sun 16285614e71bSYork Sun ddr->ddr_sdram_mode = (0 16295614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16305614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16315614e71bSYork Sun ); 16325614e71bSYork Sun 16335614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 16345614e71bSYork Sun 16355614e71bSYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 16365614e71bSYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 16375614e71bSYork Sun if (popts->rtt_override) 16385614e71bSYork Sun rtt = popts->rtt_override_value; 16395614e71bSYork Sun else 16405614e71bSYork Sun rtt = popts->cs_local_opts[i].odt_rtt_norm; 16415614e71bSYork Sun 16425614e71bSYork Sun esdmode &= 0xFDBB; /* clear bit 9,6,2 */ 16435614e71bSYork Sun esdmode |= (0 16445614e71bSYork Sun | ((rtt & 0x4) << 7) /* rtt field is split */ 16455614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 16465614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 16475614e71bSYork Sun ); 16485614e71bSYork Sun switch (i) { 16495614e71bSYork Sun case 1: 16505614e71bSYork Sun ddr->ddr_sdram_mode_3 = (0 16515614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16525614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16535614e71bSYork Sun ); 16545614e71bSYork Sun break; 16555614e71bSYork Sun case 2: 16565614e71bSYork Sun ddr->ddr_sdram_mode_5 = (0 16575614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16585614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16595614e71bSYork Sun ); 16605614e71bSYork Sun break; 16615614e71bSYork Sun case 3: 16625614e71bSYork Sun ddr->ddr_sdram_mode_7 = (0 16635614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16645614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16655614e71bSYork Sun ); 16665614e71bSYork Sun break; 16675614e71bSYork Sun } 16685614e71bSYork Sun } 16695614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", 16705614e71bSYork Sun ddr->ddr_sdram_mode_3); 16715614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 16725614e71bSYork Sun ddr->ddr_sdram_mode_5); 16735614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 16745614e71bSYork Sun ddr->ddr_sdram_mode_5); 16755614e71bSYork Sun } 16765614e71bSYork Sun } 16775614e71bSYork Sun 16785614e71bSYork Sun #else /* !CONFIG_SYS_FSL_DDR3 */ 16795614e71bSYork Sun 16805614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 168103e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num, 168203e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 16835614e71bSYork Sun const memctl_options_t *popts, 16845614e71bSYork Sun const common_timing_params_t *common_dimm, 16855614e71bSYork Sun unsigned int cas_latency, 16865614e71bSYork Sun unsigned int additive_latency, 16875614e71bSYork Sun const unsigned int unq_mrs_en) 16885614e71bSYork Sun { 16895614e71bSYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 16905614e71bSYork Sun unsigned short sdmode; /* SDRAM mode */ 16915614e71bSYork Sun 16925614e71bSYork Sun /* 16935614e71bSYork Sun * FIXME: This ought to be pre-calculated in a 16945614e71bSYork Sun * technology-specific routine, 16955614e71bSYork Sun * e.g. compute_DDR2_mode_register(), and then the 16965614e71bSYork Sun * sdmode and esdmode passed in as part of common_dimm. 16975614e71bSYork Sun */ 16985614e71bSYork Sun 16995614e71bSYork Sun /* Extended Mode Register */ 17005614e71bSYork Sun unsigned int mrs = 0; /* Mode Register Set */ 17015614e71bSYork Sun unsigned int outputs = 0; /* 0=Enabled, 1=Disabled */ 17025614e71bSYork Sun unsigned int rdqs_en = 0; /* RDQS Enable: 0=no, 1=yes */ 17035614e71bSYork Sun unsigned int dqs_en = 0; /* DQS# Enable: 0=enable, 1=disable */ 17045614e71bSYork Sun unsigned int ocd = 0; /* 0x0=OCD not supported, 17055614e71bSYork Sun 0x7=OCD default state */ 17065614e71bSYork Sun unsigned int rtt; 17075614e71bSYork Sun unsigned int al; /* Posted CAS# additive latency (AL) */ 17085614e71bSYork Sun unsigned int ods = 0; /* Output Drive Strength: 17095614e71bSYork Sun 0 = Full strength (18ohm) 17105614e71bSYork Sun 1 = Reduced strength (4ohm) */ 17115614e71bSYork Sun unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), 17125614e71bSYork Sun 1=Disable (Test/Debug) */ 17135614e71bSYork Sun 17145614e71bSYork Sun /* Mode Register (MR) */ 17155614e71bSYork Sun unsigned int mr; /* Mode Register Definition */ 17165614e71bSYork Sun unsigned int pd; /* Power-Down Mode */ 17175614e71bSYork Sun unsigned int wr; /* Write Recovery */ 17185614e71bSYork Sun unsigned int dll_res; /* DLL Reset */ 17195614e71bSYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 17205614e71bSYork Sun unsigned int caslat = 0;/* CAS# latency */ 17215614e71bSYork Sun /* BT: Burst Type (0=Sequential, 1=Interleaved) */ 17225614e71bSYork Sun unsigned int bt; 17235614e71bSYork Sun unsigned int bl; /* BL: Burst Length */ 17245614e71bSYork Sun 17255614e71bSYork Sun dqs_en = !popts->dqs_config; 17265614e71bSYork Sun rtt = fsl_ddr_get_rtt(); 17275614e71bSYork Sun 17285614e71bSYork Sun al = additive_latency; 17295614e71bSYork Sun 17305614e71bSYork Sun esdmode = (0 17315614e71bSYork Sun | ((mrs & 0x3) << 14) 17325614e71bSYork Sun | ((outputs & 0x1) << 12) 17335614e71bSYork Sun | ((rdqs_en & 0x1) << 11) 17345614e71bSYork Sun | ((dqs_en & 0x1) << 10) 17355614e71bSYork Sun | ((ocd & 0x7) << 7) 17365614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 17375614e71bSYork Sun | ((al & 0x7) << 3) 17385614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 17395614e71bSYork Sun | ((ods & 0x1) << 1) 17405614e71bSYork Sun | ((dll_en & 0x1) << 0) 17415614e71bSYork Sun ); 17425614e71bSYork Sun 17435614e71bSYork Sun mr = 0; /* FIXME: CHECKME */ 17445614e71bSYork Sun 17455614e71bSYork Sun /* 17465614e71bSYork Sun * 0 = Fast Exit (Normal) 17475614e71bSYork Sun * 1 = Slow Exit (Low Power) 17485614e71bSYork Sun */ 17495614e71bSYork Sun pd = 0; 17505614e71bSYork Sun 17515614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 17525614e71bSYork Sun wr = 0; /* Historical */ 17535614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 175403e664d8SYork Sun wr = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 17555614e71bSYork Sun #endif 17565614e71bSYork Sun dll_res = 0; 17575614e71bSYork Sun mode = 0; 17585614e71bSYork Sun 17595614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 17605614e71bSYork Sun if (1 <= cas_latency && cas_latency <= 4) { 17615614e71bSYork Sun unsigned char mode_caslat_table[4] = { 17625614e71bSYork Sun 0x5, /* 1.5 clocks */ 17635614e71bSYork Sun 0x2, /* 2.0 clocks */ 17645614e71bSYork Sun 0x6, /* 2.5 clocks */ 17655614e71bSYork Sun 0x3 /* 3.0 clocks */ 17665614e71bSYork Sun }; 17675614e71bSYork Sun caslat = mode_caslat_table[cas_latency - 1]; 17685614e71bSYork Sun } else { 17695614e71bSYork Sun printf("Warning: unknown cas_latency %d\n", cas_latency); 17705614e71bSYork Sun } 17715614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 17725614e71bSYork Sun caslat = cas_latency; 17735614e71bSYork Sun #endif 17745614e71bSYork Sun bt = 0; 17755614e71bSYork Sun 17765614e71bSYork Sun switch (popts->burst_length) { 17775614e71bSYork Sun case DDR_BL4: 17785614e71bSYork Sun bl = 2; 17795614e71bSYork Sun break; 17805614e71bSYork Sun case DDR_BL8: 17815614e71bSYork Sun bl = 3; 17825614e71bSYork Sun break; 17835614e71bSYork Sun default: 17845614e71bSYork Sun printf("Error: invalid burst length of %u specified. " 17855614e71bSYork Sun " Defaulting to 4 beats.\n", 17865614e71bSYork Sun popts->burst_length); 17875614e71bSYork Sun bl = 2; 17885614e71bSYork Sun break; 17895614e71bSYork Sun } 17905614e71bSYork Sun 17915614e71bSYork Sun sdmode = (0 17925614e71bSYork Sun | ((mr & 0x3) << 14) 17935614e71bSYork Sun | ((pd & 0x1) << 12) 17945614e71bSYork Sun | ((wr & 0x7) << 9) 17955614e71bSYork Sun | ((dll_res & 0x1) << 8) 17965614e71bSYork Sun | ((mode & 0x1) << 7) 17975614e71bSYork Sun | ((caslat & 0x7) << 4) 17985614e71bSYork Sun | ((bt & 0x1) << 3) 17995614e71bSYork Sun | ((bl & 0x7) << 0) 18005614e71bSYork Sun ); 18015614e71bSYork Sun 18025614e71bSYork Sun ddr->ddr_sdram_mode = (0 18035614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 18045614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 18055614e71bSYork Sun ); 18065614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 18075614e71bSYork Sun } 18085614e71bSYork Sun #endif 18095614e71bSYork Sun 18105614e71bSYork Sun /* DDR SDRAM Data Initialization (DDR_DATA_INIT) */ 18115614e71bSYork Sun static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr) 18125614e71bSYork Sun { 18135614e71bSYork Sun unsigned int init_value; /* Initialization value */ 18145614e71bSYork Sun 18155614e71bSYork Sun #ifdef CONFIG_MEM_INIT_VALUE 18165614e71bSYork Sun init_value = CONFIG_MEM_INIT_VALUE; 18175614e71bSYork Sun #else 18185614e71bSYork Sun init_value = 0xDEADBEEF; 18195614e71bSYork Sun #endif 18205614e71bSYork Sun ddr->ddr_data_init = init_value; 18215614e71bSYork Sun } 18225614e71bSYork Sun 18235614e71bSYork Sun /* 18245614e71bSYork Sun * DDR SDRAM Clock Control (DDR_SDRAM_CLK_CNTL) 18255614e71bSYork Sun * The old controller on the 8540/60 doesn't have this register. 18265614e71bSYork Sun * Hope it's OK to set it (to 0) anyway. 18275614e71bSYork Sun */ 18285614e71bSYork Sun static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr, 18295614e71bSYork Sun const memctl_options_t *popts) 18305614e71bSYork Sun { 18315614e71bSYork Sun unsigned int clk_adjust; /* Clock adjust */ 1832d7c865bdSCurt Brune unsigned int ss_en = 0; /* Source synchronous enable */ 18335614e71bSYork Sun 1834*3c3d8ab5SYork Sun #if defined(CONFIG_ARCH_MPC8541) || defined(CONFIG_ARCH_MPC8555) 1835d7c865bdSCurt Brune /* Per FSL Application Note: AN2805 */ 1836d7c865bdSCurt Brune ss_en = 1; 1837d7c865bdSCurt Brune #endif 1838d8e5163aSShengzhou Liu if (fsl_ddr_get_version(0) >= 0x40701) { 1839d8e5163aSShengzhou Liu /* clk_adjust in 5-bits on T-series and LS-series */ 1840d8e5163aSShengzhou Liu clk_adjust = (popts->clk_adjust & 0x1F) << 22; 1841d8e5163aSShengzhou Liu } else { 1842d8e5163aSShengzhou Liu /* clk_adjust in 4-bits on earlier MPC85xx and P-series */ 1843d8e5163aSShengzhou Liu clk_adjust = (popts->clk_adjust & 0xF) << 23; 1844d8e5163aSShengzhou Liu } 1845d8e5163aSShengzhou Liu 1846d7c865bdSCurt Brune ddr->ddr_sdram_clk_cntl = (0 1847d7c865bdSCurt Brune | ((ss_en & 0x1) << 31) 1848d8e5163aSShengzhou Liu | clk_adjust 1849d7c865bdSCurt Brune ); 18505614e71bSYork Sun debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl); 18515614e71bSYork Sun } 18525614e71bSYork Sun 18535614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_ADDR) */ 18545614e71bSYork Sun static void set_ddr_init_addr(fsl_ddr_cfg_regs_t *ddr) 18555614e71bSYork Sun { 18565614e71bSYork Sun unsigned int init_addr = 0; /* Initialization address */ 18575614e71bSYork Sun 18585614e71bSYork Sun ddr->ddr_init_addr = init_addr; 18595614e71bSYork Sun } 18605614e71bSYork Sun 18615614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_EXT_ADDR) */ 18625614e71bSYork Sun static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr) 18635614e71bSYork Sun { 18645614e71bSYork Sun unsigned int uia = 0; /* Use initialization address */ 18655614e71bSYork Sun unsigned int init_ext_addr = 0; /* Initialization address */ 18665614e71bSYork Sun 18675614e71bSYork Sun ddr->ddr_init_ext_addr = (0 18685614e71bSYork Sun | ((uia & 0x1) << 31) 18695614e71bSYork Sun | (init_ext_addr & 0xF) 18705614e71bSYork Sun ); 18715614e71bSYork Sun } 18725614e71bSYork Sun 18735614e71bSYork Sun /* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */ 18745614e71bSYork Sun static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr, 18755614e71bSYork Sun const memctl_options_t *popts) 18765614e71bSYork Sun { 18775614e71bSYork Sun unsigned int rwt = 0; /* Read-to-write turnaround for same CS */ 18785614e71bSYork Sun unsigned int wrt = 0; /* Write-to-read turnaround for same CS */ 18795614e71bSYork Sun unsigned int rrt = 0; /* Read-to-read turnaround for same CS */ 18805614e71bSYork Sun unsigned int wwt = 0; /* Write-to-write turnaround for same CS */ 18816c6e006aSYork Sun unsigned int trwt_mclk = 0; /* ext_rwt */ 18825614e71bSYork Sun unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */ 18835614e71bSYork Sun 188434e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 18855614e71bSYork Sun if (popts->burst_length == DDR_BL8) { 18865614e71bSYork Sun /* We set BL/2 for fixed BL8 */ 18875614e71bSYork Sun rrt = 0; /* BL/2 clocks */ 18885614e71bSYork Sun wwt = 0; /* BL/2 clocks */ 18895614e71bSYork Sun } else { 18905614e71bSYork Sun /* We need to set BL/2 + 2 to BC4 and OTF */ 18915614e71bSYork Sun rrt = 2; /* BL/2 + 2 clocks */ 18925614e71bSYork Sun wwt = 2; /* BL/2 + 2 clocks */ 18935614e71bSYork Sun } 189434e026f9SYork Sun #endif 189534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 189634e026f9SYork Sun dll_lock = 2; /* tDLLK = 1024 clocks */ 189734e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 18985614e71bSYork Sun dll_lock = 1; /* tDLLK = 512 clocks from spec */ 18995614e71bSYork Sun #endif 19006c6e006aSYork Sun 19016c6e006aSYork Sun if (popts->trwt_override) 19026c6e006aSYork Sun trwt_mclk = popts->trwt; 19036c6e006aSYork Sun 19045614e71bSYork Sun ddr->timing_cfg_4 = (0 19055614e71bSYork Sun | ((rwt & 0xf) << 28) 19065614e71bSYork Sun | ((wrt & 0xf) << 24) 19075614e71bSYork Sun | ((rrt & 0xf) << 20) 19085614e71bSYork Sun | ((wwt & 0xf) << 16) 19096c6e006aSYork Sun | ((trwt_mclk & 0xc) << 12) 19105614e71bSYork Sun | (dll_lock & 0x3) 19115614e71bSYork Sun ); 19125614e71bSYork Sun debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4); 19135614e71bSYork Sun } 19145614e71bSYork Sun 19155614e71bSYork Sun /* DDR SDRAM Timing Configuration 5 (TIMING_CFG_5) */ 19165614e71bSYork Sun static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr, unsigned int cas_latency) 19175614e71bSYork Sun { 19185614e71bSYork Sun unsigned int rodt_on = 0; /* Read to ODT on */ 19195614e71bSYork Sun unsigned int rodt_off = 0; /* Read to ODT off */ 19205614e71bSYork Sun unsigned int wodt_on = 0; /* Write to ODT on */ 19215614e71bSYork Sun unsigned int wodt_off = 0; /* Write to ODT off */ 19225614e71bSYork Sun 192334e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 192434e026f9SYork Sun unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 192534e026f9SYork Sun ((ddr->timing_cfg_2 & 0x00040000) >> 14); 19265614e71bSYork Sun /* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */ 192734e026f9SYork Sun if (cas_latency >= wr_lat) 192834e026f9SYork Sun rodt_on = cas_latency - wr_lat + 1; 19295614e71bSYork Sun rodt_off = 4; /* 4 clocks */ 19305614e71bSYork Sun wodt_on = 1; /* 1 clocks */ 19315614e71bSYork Sun wodt_off = 4; /* 4 clocks */ 19325614e71bSYork Sun #endif 19335614e71bSYork Sun 19345614e71bSYork Sun ddr->timing_cfg_5 = (0 19355614e71bSYork Sun | ((rodt_on & 0x1f) << 24) 19365614e71bSYork Sun | ((rodt_off & 0x7) << 20) 19375614e71bSYork Sun | ((wodt_on & 0x1f) << 12) 19385614e71bSYork Sun | ((wodt_off & 0x7) << 8) 19395614e71bSYork Sun ); 19405614e71bSYork Sun debug("FSLDDR: timing_cfg_5 = 0x%08x\n", ddr->timing_cfg_5); 19415614e71bSYork Sun } 19425614e71bSYork Sun 194334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 194434e026f9SYork Sun static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr) 194534e026f9SYork Sun { 194634e026f9SYork Sun unsigned int hs_caslat = 0; 194734e026f9SYork Sun unsigned int hs_wrlat = 0; 194834e026f9SYork Sun unsigned int hs_wrrec = 0; 194934e026f9SYork Sun unsigned int hs_clkadj = 0; 195034e026f9SYork Sun unsigned int hs_wrlvl_start = 0; 195134e026f9SYork Sun 195234e026f9SYork Sun ddr->timing_cfg_6 = (0 195334e026f9SYork Sun | ((hs_caslat & 0x1f) << 24) 195434e026f9SYork Sun | ((hs_wrlat & 0x1f) << 19) 195534e026f9SYork Sun | ((hs_wrrec & 0x1f) << 12) 195634e026f9SYork Sun | ((hs_clkadj & 0x1f) << 6) 195734e026f9SYork Sun | ((hs_wrlvl_start & 0x1f) << 0) 195834e026f9SYork Sun ); 195934e026f9SYork Sun debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6); 196034e026f9SYork Sun } 196134e026f9SYork Sun 196203e664d8SYork Sun static void set_timing_cfg_7(const unsigned int ctrl_num, 196303e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 196434e026f9SYork Sun const common_timing_params_t *common_dimm) 196534e026f9SYork Sun { 196634e026f9SYork Sun unsigned int txpr, tcksre, tcksrx; 1967eb118807SShengzhou Liu unsigned int cke_rst, cksre, cksrx, par_lat = 0, cs_to_cmd; 1968eb118807SShengzhou Liu const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 196934e026f9SYork Sun 197003e664d8SYork Sun txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000)); 197103e664d8SYork Sun tcksre = max(5U, picos_to_mclk(ctrl_num, 10000)); 197203e664d8SYork Sun tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000)); 1973eb118807SShengzhou Liu 1974eb118807SShengzhou Liu if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { 1975eb118807SShengzhou Liu if (mclk_ps >= 935) { 1976eb118807SShengzhou Liu /* parity latency 4 clocks in case of 1600/1866/2133 */ 1977eb118807SShengzhou Liu par_lat = 4; 1978eb118807SShengzhou Liu } else if (mclk_ps >= 833) { 1979eb118807SShengzhou Liu /* parity latency 5 clocks for DDR4-2400 */ 1980eb118807SShengzhou Liu par_lat = 5; 1981eb118807SShengzhou Liu } else { 1982eb118807SShengzhou Liu printf("parity: mclk_ps = %d not supported\n", mclk_ps); 1983eb118807SShengzhou Liu } 1984eb118807SShengzhou Liu } 1985eb118807SShengzhou Liu 198634e026f9SYork Sun cs_to_cmd = 0; 198734e026f9SYork Sun 198834e026f9SYork Sun if (txpr <= 200) 198934e026f9SYork Sun cke_rst = 0; 199034e026f9SYork Sun else if (txpr <= 256) 199134e026f9SYork Sun cke_rst = 1; 199234e026f9SYork Sun else if (txpr <= 512) 199334e026f9SYork Sun cke_rst = 2; 199434e026f9SYork Sun else 199534e026f9SYork Sun cke_rst = 3; 199634e026f9SYork Sun 199734e026f9SYork Sun if (tcksre <= 19) 199834e026f9SYork Sun cksre = tcksre - 5; 199934e026f9SYork Sun else 200034e026f9SYork Sun cksre = 15; 200134e026f9SYork Sun 200234e026f9SYork Sun if (tcksrx <= 19) 200334e026f9SYork Sun cksrx = tcksrx - 5; 200434e026f9SYork Sun else 200534e026f9SYork Sun cksrx = 15; 200634e026f9SYork Sun 200734e026f9SYork Sun ddr->timing_cfg_7 = (0 200834e026f9SYork Sun | ((cke_rst & 0x3) << 28) 200934e026f9SYork Sun | ((cksre & 0xf) << 24) 201034e026f9SYork Sun | ((cksrx & 0xf) << 20) 201134e026f9SYork Sun | ((par_lat & 0xf) << 16) 201234e026f9SYork Sun | ((cs_to_cmd & 0xf) << 4) 201334e026f9SYork Sun ); 201434e026f9SYork Sun debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7); 201534e026f9SYork Sun } 201634e026f9SYork Sun 201703e664d8SYork Sun static void set_timing_cfg_8(const unsigned int ctrl_num, 201803e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 201934e026f9SYork Sun const memctl_options_t *popts, 202034e026f9SYork Sun const common_timing_params_t *common_dimm, 202134e026f9SYork Sun unsigned int cas_latency) 202234e026f9SYork Sun { 202334e026f9SYork Sun unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg; 202434e026f9SYork Sun unsigned int acttoact_bg, wrtord_bg, pre_all_rec; 202503e664d8SYork Sun unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); 202634e026f9SYork Sun unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 202734e026f9SYork Sun ((ddr->timing_cfg_2 & 0x00040000) >> 14); 202834e026f9SYork Sun 202934e026f9SYork Sun rwt_bg = cas_latency + 2 + 4 - wr_lat; 203034e026f9SYork Sun if (rwt_bg < tccdl) 203134e026f9SYork Sun rwt_bg = tccdl - rwt_bg; 203234e026f9SYork Sun else 203334e026f9SYork Sun rwt_bg = 0; 203434e026f9SYork Sun 203534e026f9SYork Sun wrt_bg = wr_lat + 4 + 1 - cas_latency; 203634e026f9SYork Sun if (wrt_bg < tccdl) 203734e026f9SYork Sun wrt_bg = tccdl - wrt_bg; 203834e026f9SYork Sun else 203934e026f9SYork Sun wrt_bg = 0; 204034e026f9SYork Sun 204134e026f9SYork Sun if (popts->burst_length == DDR_BL8) { 204234e026f9SYork Sun rrt_bg = tccdl - 4; 204334e026f9SYork Sun wwt_bg = tccdl - 4; 204434e026f9SYork Sun } else { 204534e026f9SYork Sun rrt_bg = tccdl - 2; 2046dc1437afSYork Sun wwt_bg = tccdl - 2; 204734e026f9SYork Sun } 204834e026f9SYork Sun 204903e664d8SYork Sun acttoact_bg = picos_to_mclk(ctrl_num, common_dimm->trrdl_ps); 205003e664d8SYork Sun wrtord_bg = max(4U, picos_to_mclk(ctrl_num, 7500)); 20513d75ec95SYork Sun if (popts->otf_burst_chop_en) 20523d75ec95SYork Sun wrtord_bg += 2; 20533d75ec95SYork Sun 205434e026f9SYork Sun pre_all_rec = 0; 205534e026f9SYork Sun 205634e026f9SYork Sun ddr->timing_cfg_8 = (0 205734e026f9SYork Sun | ((rwt_bg & 0xf) << 28) 205834e026f9SYork Sun | ((wrt_bg & 0xf) << 24) 205934e026f9SYork Sun | ((rrt_bg & 0xf) << 20) 206034e026f9SYork Sun | ((wwt_bg & 0xf) << 16) 206134e026f9SYork Sun | ((acttoact_bg & 0xf) << 12) 206234e026f9SYork Sun | ((wrtord_bg & 0xf) << 8) 206334e026f9SYork Sun | ((pre_all_rec & 0x1f) << 0) 206434e026f9SYork Sun ); 206534e026f9SYork Sun 206634e026f9SYork Sun debug("FSLDDR: timing_cfg_8 = 0x%08x\n", ddr->timing_cfg_8); 206734e026f9SYork Sun } 206834e026f9SYork Sun 206934e026f9SYork Sun static void set_timing_cfg_9(fsl_ddr_cfg_regs_t *ddr) 207034e026f9SYork Sun { 207134e026f9SYork Sun ddr->timing_cfg_9 = 0; 207234e026f9SYork Sun debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9); 207334e026f9SYork Sun } 207434e026f9SYork Sun 2075f80d6472SYork Sun /* This function needs to be called after set_ddr_sdram_cfg() is called */ 207634e026f9SYork Sun static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr, 207734e026f9SYork Sun const dimm_params_t *dimm_params) 207834e026f9SYork Sun { 2079f80d6472SYork Sun unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1; 20806b95be22SYork Sun int i; 2081f80d6472SYork Sun 20826b95be22SYork Sun for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { 20836b95be22SYork Sun if (dimm_params[i].n_ranks) 20846b95be22SYork Sun break; 20856b95be22SYork Sun } 20866b95be22SYork Sun if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) { 20876b95be22SYork Sun puts("DDR error: no DIMM found!\n"); 20886b95be22SYork Sun return; 20896b95be22SYork Sun } 209034e026f9SYork Sun 20916b95be22SYork Sun ddr->dq_map_0 = ((dimm_params[i].dq_mapping[0] & 0x3F) << 26) | 20926b95be22SYork Sun ((dimm_params[i].dq_mapping[1] & 0x3F) << 20) | 20936b95be22SYork Sun ((dimm_params[i].dq_mapping[2] & 0x3F) << 14) | 20946b95be22SYork Sun ((dimm_params[i].dq_mapping[3] & 0x3F) << 8) | 20956b95be22SYork Sun ((dimm_params[i].dq_mapping[4] & 0x3F) << 2); 209634e026f9SYork Sun 20976b95be22SYork Sun ddr->dq_map_1 = ((dimm_params[i].dq_mapping[5] & 0x3F) << 26) | 20986b95be22SYork Sun ((dimm_params[i].dq_mapping[6] & 0x3F) << 20) | 20996b95be22SYork Sun ((dimm_params[i].dq_mapping[7] & 0x3F) << 14) | 21006b95be22SYork Sun ((dimm_params[i].dq_mapping[10] & 0x3F) << 8) | 21016b95be22SYork Sun ((dimm_params[i].dq_mapping[11] & 0x3F) << 2); 21026b95be22SYork Sun 21036b95be22SYork Sun ddr->dq_map_2 = ((dimm_params[i].dq_mapping[12] & 0x3F) << 26) | 21046b95be22SYork Sun ((dimm_params[i].dq_mapping[13] & 0x3F) << 20) | 21056b95be22SYork Sun ((dimm_params[i].dq_mapping[14] & 0x3F) << 14) | 21066b95be22SYork Sun ((dimm_params[i].dq_mapping[15] & 0x3F) << 8) | 21076b95be22SYork Sun ((dimm_params[i].dq_mapping[16] & 0x3F) << 2); 210834e026f9SYork Sun 2109f80d6472SYork Sun /* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */ 21106b95be22SYork Sun ddr->dq_map_3 = ((dimm_params[i].dq_mapping[17] & 0x3F) << 26) | 21116b95be22SYork Sun ((dimm_params[i].dq_mapping[8] & 0x3F) << 20) | 2112f80d6472SYork Sun (acc_ecc_en ? 0 : 21136b95be22SYork Sun (dimm_params[i].dq_mapping[9] & 0x3F) << 14) | 21146b95be22SYork Sun dimm_params[i].dq_mapping_ors; 211534e026f9SYork Sun 211634e026f9SYork Sun debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0); 211734e026f9SYork Sun debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1); 211834e026f9SYork Sun debug("FSLDDR: dq_map_2 = 0x%08x\n", ddr->dq_map_2); 211934e026f9SYork Sun debug("FSLDDR: dq_map_3 = 0x%08x\n", ddr->dq_map_3); 212034e026f9SYork Sun } 212134e026f9SYork Sun static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr, 212234e026f9SYork Sun const memctl_options_t *popts) 212334e026f9SYork Sun { 212434e026f9SYork Sun int rd_pre; 212534e026f9SYork Sun 212634e026f9SYork Sun rd_pre = popts->quad_rank_present ? 1 : 0; 212734e026f9SYork Sun 212834e026f9SYork Sun ddr->ddr_sdram_cfg_3 = (rd_pre & 0x1) << 16; 212934e026f9SYork Sun 213034e026f9SYork Sun debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3); 213134e026f9SYork Sun } 213234e026f9SYork Sun #endif /* CONFIG_SYS_FSL_DDR4 */ 213334e026f9SYork Sun 21345614e71bSYork Sun /* DDR ZQ Calibration Control (DDR_ZQ_CNTL) */ 21355614e71bSYork Sun static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en) 21365614e71bSYork Sun { 21375614e71bSYork Sun unsigned int zqinit = 0;/* POR ZQ Calibration Time (tZQinit) */ 21385614e71bSYork Sun /* Normal Operation Full Calibration Time (tZQoper) */ 21395614e71bSYork Sun unsigned int zqoper = 0; 21405614e71bSYork Sun /* Normal Operation Short Calibration Time (tZQCS) */ 21415614e71bSYork Sun unsigned int zqcs = 0; 214234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 214334e026f9SYork Sun unsigned int zqcs_init; 214434e026f9SYork Sun #endif 21455614e71bSYork Sun 21465614e71bSYork Sun if (zq_en) { 214734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 214834e026f9SYork Sun zqinit = 10; /* 1024 clocks */ 214934e026f9SYork Sun zqoper = 9; /* 512 clocks */ 215034e026f9SYork Sun zqcs = 7; /* 128 clocks */ 215134e026f9SYork Sun zqcs_init = 5; /* 1024 refresh sequences */ 215234e026f9SYork Sun #else 21535614e71bSYork Sun zqinit = 9; /* 512 clocks */ 21545614e71bSYork Sun zqoper = 8; /* 256 clocks */ 21555614e71bSYork Sun zqcs = 6; /* 64 clocks */ 215634e026f9SYork Sun #endif 21575614e71bSYork Sun } 21585614e71bSYork Sun 21595614e71bSYork Sun ddr->ddr_zq_cntl = (0 21605614e71bSYork Sun | ((zq_en & 0x1) << 31) 21615614e71bSYork Sun | ((zqinit & 0xF) << 24) 21625614e71bSYork Sun | ((zqoper & 0xF) << 16) 21635614e71bSYork Sun | ((zqcs & 0xF) << 8) 216434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 216534e026f9SYork Sun | ((zqcs_init & 0xF) << 0) 216634e026f9SYork Sun #endif 21675614e71bSYork Sun ); 21685614e71bSYork Sun debug("FSLDDR: zq_cntl = 0x%08x\n", ddr->ddr_zq_cntl); 21695614e71bSYork Sun } 21705614e71bSYork Sun 21715614e71bSYork Sun /* DDR Write Leveling Control (DDR_WRLVL_CNTL) */ 21725614e71bSYork Sun static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en, 21735614e71bSYork Sun const memctl_options_t *popts) 21745614e71bSYork Sun { 21755614e71bSYork Sun /* 21765614e71bSYork Sun * First DQS pulse rising edge after margining mode 21775614e71bSYork Sun * is programmed (tWL_MRD) 21785614e71bSYork Sun */ 21795614e71bSYork Sun unsigned int wrlvl_mrd = 0; 21805614e71bSYork Sun /* ODT delay after margining mode is programmed (tWL_ODTEN) */ 21815614e71bSYork Sun unsigned int wrlvl_odten = 0; 21825614e71bSYork Sun /* DQS/DQS_ delay after margining mode is programmed (tWL_DQSEN) */ 21835614e71bSYork Sun unsigned int wrlvl_dqsen = 0; 21845614e71bSYork Sun /* WRLVL_SMPL: Write leveling sample time */ 21855614e71bSYork Sun unsigned int wrlvl_smpl = 0; 21865614e71bSYork Sun /* WRLVL_WLR: Write leveling repeition time */ 21875614e71bSYork Sun unsigned int wrlvl_wlr = 0; 21885614e71bSYork Sun /* WRLVL_START: Write leveling start time */ 21895614e71bSYork Sun unsigned int wrlvl_start = 0; 21905614e71bSYork Sun 21915614e71bSYork Sun /* suggest enable write leveling for DDR3 due to fly-by topology */ 21925614e71bSYork Sun if (wrlvl_en) { 21935614e71bSYork Sun /* tWL_MRD min = 40 nCK, we set it 64 */ 21945614e71bSYork Sun wrlvl_mrd = 0x6; 21955614e71bSYork Sun /* tWL_ODTEN 128 */ 21965614e71bSYork Sun wrlvl_odten = 0x7; 21975614e71bSYork Sun /* tWL_DQSEN min = 25 nCK, we set it 32 */ 21985614e71bSYork Sun wrlvl_dqsen = 0x5; 21995614e71bSYork Sun /* 22005614e71bSYork Sun * Write leveling sample time at least need 6 clocks 22015614e71bSYork Sun * higher than tWLO to allow enough time for progagation 22025614e71bSYork Sun * delay and sampling the prime data bits. 22035614e71bSYork Sun */ 22045614e71bSYork Sun wrlvl_smpl = 0xf; 22055614e71bSYork Sun /* 22065614e71bSYork Sun * Write leveling repetition time 22075614e71bSYork Sun * at least tWLO + 6 clocks clocks 22085614e71bSYork Sun * we set it 64 22095614e71bSYork Sun */ 22105614e71bSYork Sun wrlvl_wlr = 0x6; 22115614e71bSYork Sun /* 22125614e71bSYork Sun * Write leveling start time 22135614e71bSYork Sun * The value use for the DQS_ADJUST for the first sample 22145614e71bSYork Sun * when write leveling is enabled. It probably needs to be 221562a3b7ddSRobert P. J. Day * overridden per platform. 22165614e71bSYork Sun */ 22175614e71bSYork Sun wrlvl_start = 0x8; 22185614e71bSYork Sun /* 22195614e71bSYork Sun * Override the write leveling sample and start time 22205614e71bSYork Sun * according to specific board 22215614e71bSYork Sun */ 22225614e71bSYork Sun if (popts->wrlvl_override) { 22235614e71bSYork Sun wrlvl_smpl = popts->wrlvl_sample; 22245614e71bSYork Sun wrlvl_start = popts->wrlvl_start; 22255614e71bSYork Sun } 22265614e71bSYork Sun } 22275614e71bSYork Sun 22285614e71bSYork Sun ddr->ddr_wrlvl_cntl = (0 22295614e71bSYork Sun | ((wrlvl_en & 0x1) << 31) 22305614e71bSYork Sun | ((wrlvl_mrd & 0x7) << 24) 22315614e71bSYork Sun | ((wrlvl_odten & 0x7) << 20) 22325614e71bSYork Sun | ((wrlvl_dqsen & 0x7) << 16) 22335614e71bSYork Sun | ((wrlvl_smpl & 0xf) << 12) 22345614e71bSYork Sun | ((wrlvl_wlr & 0x7) << 8) 22355614e71bSYork Sun | ((wrlvl_start & 0x1F) << 0) 22365614e71bSYork Sun ); 22375614e71bSYork Sun debug("FSLDDR: wrlvl_cntl = 0x%08x\n", ddr->ddr_wrlvl_cntl); 22385614e71bSYork Sun ddr->ddr_wrlvl_cntl_2 = popts->wrlvl_ctl_2; 22395614e71bSYork Sun debug("FSLDDR: wrlvl_cntl_2 = 0x%08x\n", ddr->ddr_wrlvl_cntl_2); 22405614e71bSYork Sun ddr->ddr_wrlvl_cntl_3 = popts->wrlvl_ctl_3; 22415614e71bSYork Sun debug("FSLDDR: wrlvl_cntl_3 = 0x%08x\n", ddr->ddr_wrlvl_cntl_3); 22425614e71bSYork Sun 22435614e71bSYork Sun } 22445614e71bSYork Sun 22455614e71bSYork Sun /* DDR Self Refresh Counter (DDR_SR_CNTR) */ 22465614e71bSYork Sun static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it) 22475614e71bSYork Sun { 22485614e71bSYork Sun /* Self Refresh Idle Threshold */ 22495614e71bSYork Sun ddr->ddr_sr_cntr = (sr_it & 0xF) << 16; 22505614e71bSYork Sun } 22515614e71bSYork Sun 22525614e71bSYork Sun static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 22535614e71bSYork Sun { 22545614e71bSYork Sun if (popts->addr_hash) { 22555614e71bSYork Sun ddr->ddr_eor = 0x40000000; /* address hash enable */ 22565614e71bSYork Sun puts("Address hashing enabled.\n"); 22575614e71bSYork Sun } 22585614e71bSYork Sun } 22595614e71bSYork Sun 22605614e71bSYork Sun static void set_ddr_cdr1(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 22615614e71bSYork Sun { 22625614e71bSYork Sun ddr->ddr_cdr1 = popts->ddr_cdr1; 22635614e71bSYork Sun debug("FSLDDR: ddr_cdr1 = 0x%08x\n", ddr->ddr_cdr1); 22645614e71bSYork Sun } 22655614e71bSYork Sun 22665614e71bSYork Sun static void set_ddr_cdr2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 22675614e71bSYork Sun { 22685614e71bSYork Sun ddr->ddr_cdr2 = popts->ddr_cdr2; 22695614e71bSYork Sun debug("FSLDDR: ddr_cdr2 = 0x%08x\n", ddr->ddr_cdr2); 22705614e71bSYork Sun } 22715614e71bSYork Sun 22725614e71bSYork Sun unsigned int 22735614e71bSYork Sun check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) 22745614e71bSYork Sun { 22755614e71bSYork Sun unsigned int res = 0; 22765614e71bSYork Sun 22775614e71bSYork Sun /* 22785614e71bSYork Sun * Check that DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] are 22795614e71bSYork Sun * not set at the same time. 22805614e71bSYork Sun */ 22815614e71bSYork Sun if (ddr->ddr_sdram_cfg & 0x10000000 22825614e71bSYork Sun && ddr->ddr_sdram_cfg & 0x00008000) { 22835614e71bSYork Sun printf("Error: DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] " 22845614e71bSYork Sun " should not be set at the same time.\n"); 22855614e71bSYork Sun res++; 22865614e71bSYork Sun } 22875614e71bSYork Sun 22885614e71bSYork Sun return res; 22895614e71bSYork Sun } 22905614e71bSYork Sun 22915614e71bSYork Sun unsigned int 229203e664d8SYork Sun compute_fsl_memctl_config_regs(const unsigned int ctrl_num, 229303e664d8SYork Sun const memctl_options_t *popts, 22945614e71bSYork Sun fsl_ddr_cfg_regs_t *ddr, 22955614e71bSYork Sun const common_timing_params_t *common_dimm, 22965614e71bSYork Sun const dimm_params_t *dimm_params, 22975614e71bSYork Sun unsigned int dbw_cap_adj, 22985614e71bSYork Sun unsigned int size_only) 22995614e71bSYork Sun { 23005614e71bSYork Sun unsigned int i; 23015614e71bSYork Sun unsigned int cas_latency; 23025614e71bSYork Sun unsigned int additive_latency; 23035614e71bSYork Sun unsigned int sr_it; 23045614e71bSYork Sun unsigned int zq_en; 23055614e71bSYork Sun unsigned int wrlvl_en; 23065614e71bSYork Sun unsigned int ip_rev = 0; 23075614e71bSYork Sun unsigned int unq_mrs_en = 0; 23085614e71bSYork Sun int cs_en = 1; 23095614e71bSYork Sun 23105614e71bSYork Sun memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t)); 23115614e71bSYork Sun 23125614e71bSYork Sun if (common_dimm == NULL) { 23135614e71bSYork Sun printf("Error: subset DIMM params struct null pointer\n"); 23145614e71bSYork Sun return 1; 23155614e71bSYork Sun } 23165614e71bSYork Sun 23175614e71bSYork Sun /* 23185614e71bSYork Sun * Process overrides first. 23195614e71bSYork Sun * 23205614e71bSYork Sun * FIXME: somehow add dereated caslat to this 23215614e71bSYork Sun */ 23225614e71bSYork Sun cas_latency = (popts->cas_latency_override) 23235614e71bSYork Sun ? popts->cas_latency_override_value 232434e026f9SYork Sun : common_dimm->lowest_common_spd_caslat; 23255614e71bSYork Sun 23265614e71bSYork Sun additive_latency = (popts->additive_latency_override) 23275614e71bSYork Sun ? popts->additive_latency_override_value 23285614e71bSYork Sun : common_dimm->additive_latency; 23295614e71bSYork Sun 23305614e71bSYork Sun sr_it = (popts->auto_self_refresh_en) 23315614e71bSYork Sun ? popts->sr_it 23325614e71bSYork Sun : 0; 23335614e71bSYork Sun /* ZQ calibration */ 23345614e71bSYork Sun zq_en = (popts->zq_en) ? 1 : 0; 23355614e71bSYork Sun /* write leveling */ 23365614e71bSYork Sun wrlvl_en = (popts->wrlvl_en) ? 1 : 0; 23375614e71bSYork Sun 23385614e71bSYork Sun /* Chip Select Memory Bounds (CSn_BNDS) */ 23395614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 23405614e71bSYork Sun unsigned long long ea, sa; 23415614e71bSYork Sun unsigned int cs_per_dimm 23425614e71bSYork Sun = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; 23435614e71bSYork Sun unsigned int dimm_number 23445614e71bSYork Sun = i / cs_per_dimm; 23455614e71bSYork Sun unsigned long long rank_density 23465614e71bSYork Sun = dimm_params[dimm_number].rank_density >> dbw_cap_adj; 23475614e71bSYork Sun 23485614e71bSYork Sun if (dimm_params[dimm_number].n_ranks == 0) { 23495614e71bSYork Sun debug("Skipping setup of CS%u " 23505614e71bSYork Sun "because n_ranks on DIMM %u is 0\n", i, dimm_number); 23515614e71bSYork Sun continue; 23525614e71bSYork Sun } 23535614e71bSYork Sun if (popts->memctl_interleaving) { 23545614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 23555614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 23565614e71bSYork Sun break; 23575614e71bSYork Sun case FSL_DDR_CS0_CS1: 23585614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 23595614e71bSYork Sun if (i > 1) 23605614e71bSYork Sun cs_en = 0; 23615614e71bSYork Sun break; 23625614e71bSYork Sun case FSL_DDR_CS2_CS3: 23635614e71bSYork Sun default: 23645614e71bSYork Sun if (i > 0) 23655614e71bSYork Sun cs_en = 0; 23665614e71bSYork Sun break; 23675614e71bSYork Sun } 23685614e71bSYork Sun sa = common_dimm->base_address; 23695614e71bSYork Sun ea = sa + common_dimm->total_mem - 1; 23705614e71bSYork Sun } else if (!popts->memctl_interleaving) { 23715614e71bSYork Sun /* 23725614e71bSYork Sun * If memory interleaving between controllers is NOT 23735614e71bSYork Sun * enabled, the starting address for each memory 23745614e71bSYork Sun * controller is distinct. However, because rank 23755614e71bSYork Sun * interleaving is enabled, the starting and ending 23765614e71bSYork Sun * addresses of the total memory on that memory 23775614e71bSYork Sun * controller needs to be programmed into its 23785614e71bSYork Sun * respective CS0_BNDS. 23795614e71bSYork Sun */ 23805614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 23815614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 23825614e71bSYork Sun sa = common_dimm->base_address; 23835614e71bSYork Sun ea = sa + common_dimm->total_mem - 1; 23845614e71bSYork Sun break; 23855614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 23865614e71bSYork Sun if ((i >= 2) && (dimm_number == 0)) { 23875614e71bSYork Sun sa = dimm_params[dimm_number].base_address + 23885614e71bSYork Sun 2 * rank_density; 23895614e71bSYork Sun ea = sa + 2 * rank_density - 1; 23905614e71bSYork Sun } else { 23915614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 23925614e71bSYork Sun ea = sa + 2 * rank_density - 1; 23935614e71bSYork Sun } 23945614e71bSYork Sun break; 23955614e71bSYork Sun case FSL_DDR_CS0_CS1: 23965614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 23975614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 23985614e71bSYork Sun ea = sa + rank_density - 1; 23995614e71bSYork Sun if (i != 1) 24005614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 24015614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 24025614e71bSYork Sun } else { 24035614e71bSYork Sun sa = 0; 24045614e71bSYork Sun ea = 0; 24055614e71bSYork Sun } 24065614e71bSYork Sun if (i == 0) 24075614e71bSYork Sun ea += rank_density; 24085614e71bSYork Sun break; 24095614e71bSYork Sun case FSL_DDR_CS2_CS3: 24105614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 24115614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 24125614e71bSYork Sun ea = sa + rank_density - 1; 24135614e71bSYork Sun if (i != 3) 24145614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 24155614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 24165614e71bSYork Sun } else { 24175614e71bSYork Sun sa = 0; 24185614e71bSYork Sun ea = 0; 24195614e71bSYork Sun } 24205614e71bSYork Sun if (i == 2) 24215614e71bSYork Sun ea += (rank_density >> dbw_cap_adj); 24225614e71bSYork Sun break; 24235614e71bSYork Sun default: /* No bank(chip-select) interleaving */ 24245614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 24255614e71bSYork Sun ea = sa + rank_density - 1; 24265614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 24275614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 24285614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 24295614e71bSYork Sun } else { 24305614e71bSYork Sun sa = 0; 24315614e71bSYork Sun ea = 0; 24325614e71bSYork Sun } 24335614e71bSYork Sun break; 24345614e71bSYork Sun } 24355614e71bSYork Sun } 24365614e71bSYork Sun 24375614e71bSYork Sun sa >>= 24; 24385614e71bSYork Sun ea >>= 24; 24395614e71bSYork Sun 24405614e71bSYork Sun if (cs_en) { 24415614e71bSYork Sun ddr->cs[i].bnds = (0 2442d4263b8aSYork Sun | ((sa & 0xffff) << 16) /* starting address */ 2443d4263b8aSYork Sun | ((ea & 0xffff) << 0) /* ending address */ 24445614e71bSYork Sun ); 24455614e71bSYork Sun } else { 24465614e71bSYork Sun /* setting bnds to 0xffffffff for inactive CS */ 24475614e71bSYork Sun ddr->cs[i].bnds = 0xffffffff; 24485614e71bSYork Sun } 24495614e71bSYork Sun 24505614e71bSYork Sun debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds); 24515614e71bSYork Sun set_csn_config(dimm_number, i, ddr, popts, dimm_params); 24525614e71bSYork Sun set_csn_config_2(i, ddr); 24535614e71bSYork Sun } 24545614e71bSYork Sun 24555614e71bSYork Sun /* 24565614e71bSYork Sun * In the case we only need to compute the ddr sdram size, we only need 24575614e71bSYork Sun * to set csn registers, so return from here. 24585614e71bSYork Sun */ 24595614e71bSYork Sun if (size_only) 24605614e71bSYork Sun return 0; 24615614e71bSYork Sun 24625614e71bSYork Sun set_ddr_eor(ddr, popts); 24635614e71bSYork Sun 24645614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1) 246503e664d8SYork Sun set_timing_cfg_0(ctrl_num, ddr, popts, dimm_params); 24665614e71bSYork Sun #endif 24675614e71bSYork Sun 246803e664d8SYork Sun set_timing_cfg_3(ctrl_num, ddr, popts, common_dimm, cas_latency, 2469d4263b8aSYork Sun additive_latency); 247003e664d8SYork Sun set_timing_cfg_1(ctrl_num, ddr, popts, common_dimm, cas_latency); 247103e664d8SYork Sun set_timing_cfg_2(ctrl_num, ddr, popts, common_dimm, 24725614e71bSYork Sun cas_latency, additive_latency); 24735614e71bSYork Sun 24745614e71bSYork Sun set_ddr_cdr1(ddr, popts); 24755614e71bSYork Sun set_ddr_cdr2(ddr, popts); 24765614e71bSYork Sun set_ddr_sdram_cfg(ddr, popts, common_dimm); 247766869f95SYork Sun ip_rev = fsl_ddr_get_version(ctrl_num); 24785614e71bSYork Sun if (ip_rev > 0x40400) 24795614e71bSYork Sun unq_mrs_en = 1; 24805614e71bSYork Sun 2481f80d6472SYork Sun if ((ip_rev > 0x40700) && (popts->cswl_override != 0)) 2482ef87cab6SYork Sun ddr->debug[18] = popts->cswl_override; 2483ef87cab6SYork Sun 248403e664d8SYork Sun set_ddr_sdram_cfg_2(ctrl_num, ddr, popts, unq_mrs_en); 248503e664d8SYork Sun set_ddr_sdram_mode(ctrl_num, ddr, popts, common_dimm, 24865614e71bSYork Sun cas_latency, additive_latency, unq_mrs_en); 248703e664d8SYork Sun set_ddr_sdram_mode_2(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); 248834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 248934e026f9SYork Sun set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en); 249003e664d8SYork Sun set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); 249134e026f9SYork Sun #endif 249203e664d8SYork Sun set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm); 24935614e71bSYork Sun set_ddr_data_init(ddr); 24945614e71bSYork Sun set_ddr_sdram_clk_cntl(ddr, popts); 24955614e71bSYork Sun set_ddr_init_addr(ddr); 24965614e71bSYork Sun set_ddr_init_ext_addr(ddr); 24975614e71bSYork Sun set_timing_cfg_4(ddr, popts); 24985614e71bSYork Sun set_timing_cfg_5(ddr, cas_latency); 249934e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 250034e026f9SYork Sun set_ddr_sdram_cfg_3(ddr, popts); 250134e026f9SYork Sun set_timing_cfg_6(ddr); 250203e664d8SYork Sun set_timing_cfg_7(ctrl_num, ddr, common_dimm); 250303e664d8SYork Sun set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency); 250434e026f9SYork Sun set_timing_cfg_9(ddr); 250534e026f9SYork Sun set_ddr_dq_mapping(ddr, dimm_params); 250634e026f9SYork Sun #endif 25075614e71bSYork Sun 25085614e71bSYork Sun set_ddr_zq_cntl(ddr, zq_en); 25095614e71bSYork Sun set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts); 25105614e71bSYork Sun 25115614e71bSYork Sun set_ddr_sr_cntr(ddr, sr_it); 25125614e71bSYork Sun 25135614e71bSYork Sun set_ddr_sdram_rcw(ddr, popts, common_dimm); 25145614e71bSYork Sun 25155614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR_EMU 25165614e71bSYork Sun /* disble DDR training for emulator */ 25175614e71bSYork Sun ddr->debug[2] = 0x00000400; 25181f3402e7SYork Sun ddr->debug[4] = 0xff800800; 25191f3402e7SYork Sun ddr->debug[5] = 0x08000800; 25201f3402e7SYork Sun ddr->debug[6] = 0x08000800; 25211f3402e7SYork Sun ddr->debug[7] = 0x08000800; 25221f3402e7SYork Sun ddr->debug[8] = 0x08000800; 25235614e71bSYork Sun #endif 25249855b3beSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_A004508 25259855b3beSYork Sun if ((ip_rev >= 0x40000) && (ip_rev < 0x40400)) 25269855b3beSYork Sun ddr->debug[2] |= 0x00000200; /* set bit 22 */ 25279855b3beSYork Sun #endif 25289855b3beSYork Sun 25295614e71bSYork Sun return check_fsl_memctl_config_regs(ddr); 25305614e71bSYork Sun } 2531