15614e71bSYork Sun /* 2*c0c32af0SYork Sun * Copyright 2008-2016 Freescale Semiconductor, Inc. 3*c0c32af0SYork Sun * Copyright 2017-2018 NXP Semiconductor 45614e71bSYork Sun * 55614e71bSYork Sun * SPDX-License-Identifier: GPL-2.0+ 65614e71bSYork Sun */ 75614e71bSYork Sun 85614e71bSYork Sun /* 902fb2761SShengzhou Liu * Generic driver for Freescale DDR/DDR2/DDR3/DDR4 memory controller. 105614e71bSYork Sun * Based on code from spd_sdram.c 115614e71bSYork Sun * Author: James Yang [at freescale.com] 125614e71bSYork Sun */ 135614e71bSYork Sun 145614e71bSYork Sun #include <common.h> 155614e71bSYork Sun #include <fsl_ddr_sdram.h> 1602fb2761SShengzhou Liu #include <fsl_errata.h> 175614e71bSYork Sun #include <fsl_ddr.h> 189a17eb5bSYork Sun #include <fsl_immap.h> 195614e71bSYork Sun #include <asm/io.h> 20457e51cfSSimon Glass #if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \ 21457e51cfSSimon Glass defined(CONFIG_ARM) 226e2941d7SSimon Glass #include <asm/arch/clock.h> 236e2941d7SSimon Glass #endif 245614e71bSYork Sun 255614e71bSYork Sun /* 265614e71bSYork Sun * Determine Rtt value. 275614e71bSYork Sun * 285614e71bSYork Sun * This should likely be either board or controller specific. 295614e71bSYork Sun * 305614e71bSYork Sun * Rtt(nominal) - DDR2: 315614e71bSYork Sun * 0 = Rtt disabled 325614e71bSYork Sun * 1 = 75 ohm 335614e71bSYork Sun * 2 = 150 ohm 345614e71bSYork Sun * 3 = 50 ohm 355614e71bSYork Sun * Rtt(nominal) - DDR3: 365614e71bSYork Sun * 0 = Rtt disabled 375614e71bSYork Sun * 1 = 60 ohm 385614e71bSYork Sun * 2 = 120 ohm 395614e71bSYork Sun * 3 = 40 ohm 405614e71bSYork Sun * 4 = 20 ohm 415614e71bSYork Sun * 5 = 30 ohm 425614e71bSYork Sun * 435614e71bSYork Sun * FIXME: Apparently 8641 needs a value of 2 445614e71bSYork Sun * FIXME: Old code seys if 667 MHz or higher, use 3 on 8572 455614e71bSYork Sun * 465614e71bSYork Sun * FIXME: There was some effort down this line earlier: 475614e71bSYork Sun * 485614e71bSYork Sun * unsigned int i; 495614e71bSYork Sun * for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL/2; i++) { 505614e71bSYork Sun * if (popts->dimmslot[i].num_valid_cs 515614e71bSYork Sun * && (popts->cs_local_opts[2*i].odt_rd_cfg 525614e71bSYork Sun * || popts->cs_local_opts[2*i].odt_wr_cfg)) { 535614e71bSYork Sun * rtt = 2; 545614e71bSYork Sun * break; 555614e71bSYork Sun * } 565614e71bSYork Sun * } 575614e71bSYork Sun */ 585614e71bSYork Sun static inline int fsl_ddr_get_rtt(void) 595614e71bSYork Sun { 605614e71bSYork Sun int rtt; 615614e71bSYork Sun 625614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 635614e71bSYork Sun rtt = 0; 645614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 655614e71bSYork Sun rtt = 3; 665614e71bSYork Sun #else 675614e71bSYork Sun rtt = 0; 685614e71bSYork Sun #endif 695614e71bSYork Sun 705614e71bSYork Sun return rtt; 715614e71bSYork Sun } 725614e71bSYork Sun 7334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 7434e026f9SYork Sun /* 7534e026f9SYork Sun * compute CAS write latency according to DDR4 spec 7634e026f9SYork Sun * CWL = 9 for <= 1600MT/s 7734e026f9SYork Sun * 10 for <= 1866MT/s 7834e026f9SYork Sun * 11 for <= 2133MT/s 7934e026f9SYork Sun * 12 for <= 2400MT/s 8034e026f9SYork Sun * 14 for <= 2667MT/s 8134e026f9SYork Sun * 16 for <= 2933MT/s 8234e026f9SYork Sun * 18 for higher 8334e026f9SYork Sun */ 8403e664d8SYork Sun static inline unsigned int compute_cas_write_latency( 8503e664d8SYork Sun const unsigned int ctrl_num) 8634e026f9SYork Sun { 8734e026f9SYork Sun unsigned int cwl; 8803e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 8934e026f9SYork Sun if (mclk_ps >= 1250) 9034e026f9SYork Sun cwl = 9; 9134e026f9SYork Sun else if (mclk_ps >= 1070) 9234e026f9SYork Sun cwl = 10; 9334e026f9SYork Sun else if (mclk_ps >= 935) 9434e026f9SYork Sun cwl = 11; 9534e026f9SYork Sun else if (mclk_ps >= 833) 9634e026f9SYork Sun cwl = 12; 9734e026f9SYork Sun else if (mclk_ps >= 750) 9834e026f9SYork Sun cwl = 14; 9934e026f9SYork Sun else if (mclk_ps >= 681) 10034e026f9SYork Sun cwl = 16; 10134e026f9SYork Sun else 10234e026f9SYork Sun cwl = 18; 10334e026f9SYork Sun 10434e026f9SYork Sun return cwl; 10534e026f9SYork Sun } 10634e026f9SYork Sun #else 1075614e71bSYork Sun /* 1085614e71bSYork Sun * compute the CAS write latency according to DDR3 spec 1095614e71bSYork Sun * CWL = 5 if tCK >= 2.5ns 1105614e71bSYork Sun * 6 if 2.5ns > tCK >= 1.875ns 1115614e71bSYork Sun * 7 if 1.875ns > tCK >= 1.5ns 1125614e71bSYork Sun * 8 if 1.5ns > tCK >= 1.25ns 1135614e71bSYork Sun * 9 if 1.25ns > tCK >= 1.07ns 1145614e71bSYork Sun * 10 if 1.07ns > tCK >= 0.935ns 1155614e71bSYork Sun * 11 if 0.935ns > tCK >= 0.833ns 1165614e71bSYork Sun * 12 if 0.833ns > tCK >= 0.75ns 1175614e71bSYork Sun */ 11803e664d8SYork Sun static inline unsigned int compute_cas_write_latency( 11903e664d8SYork Sun const unsigned int ctrl_num) 1205614e71bSYork Sun { 1215614e71bSYork Sun unsigned int cwl; 12203e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 1235614e71bSYork Sun 1245614e71bSYork Sun if (mclk_ps >= 2500) 1255614e71bSYork Sun cwl = 5; 1265614e71bSYork Sun else if (mclk_ps >= 1875) 1275614e71bSYork Sun cwl = 6; 1285614e71bSYork Sun else if (mclk_ps >= 1500) 1295614e71bSYork Sun cwl = 7; 1305614e71bSYork Sun else if (mclk_ps >= 1250) 1315614e71bSYork Sun cwl = 8; 1325614e71bSYork Sun else if (mclk_ps >= 1070) 1335614e71bSYork Sun cwl = 9; 1345614e71bSYork Sun else if (mclk_ps >= 935) 1355614e71bSYork Sun cwl = 10; 1365614e71bSYork Sun else if (mclk_ps >= 833) 1375614e71bSYork Sun cwl = 11; 1385614e71bSYork Sun else if (mclk_ps >= 750) 1395614e71bSYork Sun cwl = 12; 1405614e71bSYork Sun else { 1415614e71bSYork Sun cwl = 12; 1425614e71bSYork Sun printf("Warning: CWL is out of range\n"); 1435614e71bSYork Sun } 1445614e71bSYork Sun return cwl; 1455614e71bSYork Sun } 14634e026f9SYork Sun #endif 1475614e71bSYork Sun 1485614e71bSYork Sun /* Chip Select Configuration (CSn_CONFIG) */ 1495614e71bSYork Sun static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, 1505614e71bSYork Sun const memctl_options_t *popts, 1515614e71bSYork Sun const dimm_params_t *dimm_params) 1525614e71bSYork Sun { 1535614e71bSYork Sun unsigned int cs_n_en = 0; /* Chip Select enable */ 1545614e71bSYork Sun unsigned int intlv_en = 0; /* Memory controller interleave enable */ 1555614e71bSYork Sun unsigned int intlv_ctl = 0; /* Interleaving control */ 1565614e71bSYork Sun unsigned int ap_n_en = 0; /* Chip select n auto-precharge enable */ 1575614e71bSYork Sun unsigned int odt_rd_cfg = 0; /* ODT for reads configuration */ 1585614e71bSYork Sun unsigned int odt_wr_cfg = 0; /* ODT for writes configuration */ 1595614e71bSYork Sun unsigned int ba_bits_cs_n = 0; /* Num of bank bits for SDRAM on CSn */ 1605614e71bSYork Sun unsigned int row_bits_cs_n = 0; /* Num of row bits for SDRAM on CSn */ 1615614e71bSYork Sun unsigned int col_bits_cs_n = 0; /* Num of ocl bits for SDRAM on CSn */ 1625614e71bSYork Sun int go_config = 0; 16334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 16434e026f9SYork Sun unsigned int bg_bits_cs_n = 0; /* Num of bank group bits */ 16534e026f9SYork Sun #else 16634e026f9SYork Sun unsigned int n_banks_per_sdram_device; 16734e026f9SYork Sun #endif 1685614e71bSYork Sun 1695614e71bSYork Sun /* Compute CS_CONFIG only for existing ranks of each DIMM. */ 1705614e71bSYork Sun switch (i) { 1715614e71bSYork Sun case 0: 1725614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > 0) { 1735614e71bSYork Sun go_config = 1; 1745614e71bSYork Sun /* These fields only available in CS0_CONFIG */ 1755614e71bSYork Sun if (!popts->memctl_interleaving) 1765614e71bSYork Sun break; 1775614e71bSYork Sun switch (popts->memctl_interleaving_mode) { 1786b1e1254SYork Sun case FSL_DDR_256B_INTERLEAVING: 1795614e71bSYork Sun case FSL_DDR_CACHE_LINE_INTERLEAVING: 1805614e71bSYork Sun case FSL_DDR_PAGE_INTERLEAVING: 1815614e71bSYork Sun case FSL_DDR_BANK_INTERLEAVING: 1825614e71bSYork Sun case FSL_DDR_SUPERBANK_INTERLEAVING: 1835614e71bSYork Sun intlv_en = popts->memctl_interleaving; 1845614e71bSYork Sun intlv_ctl = popts->memctl_interleaving_mode; 1855614e71bSYork Sun break; 1865614e71bSYork Sun default: 1875614e71bSYork Sun break; 1885614e71bSYork Sun } 1895614e71bSYork Sun } 1905614e71bSYork Sun break; 1915614e71bSYork Sun case 1: 1925614e71bSYork Sun if ((dimm_number == 0 && dimm_params[0].n_ranks > 1) || \ 1935614e71bSYork Sun (dimm_number == 1 && dimm_params[1].n_ranks > 0)) 1945614e71bSYork Sun go_config = 1; 1955614e71bSYork Sun break; 1965614e71bSYork Sun case 2: 1975614e71bSYork Sun if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \ 1985614e71bSYork Sun (dimm_number >= 1 && dimm_params[dimm_number].n_ranks > 0)) 1995614e71bSYork Sun go_config = 1; 2005614e71bSYork Sun break; 2015614e71bSYork Sun case 3: 2025614e71bSYork Sun if ((dimm_number == 0 && dimm_params[0].n_ranks > 3) || \ 2035614e71bSYork Sun (dimm_number == 1 && dimm_params[1].n_ranks > 1) || \ 2045614e71bSYork Sun (dimm_number == 3 && dimm_params[3].n_ranks > 0)) 2055614e71bSYork Sun go_config = 1; 2065614e71bSYork Sun break; 2075614e71bSYork Sun default: 2085614e71bSYork Sun break; 2095614e71bSYork Sun } 2105614e71bSYork Sun if (go_config) { 2115614e71bSYork Sun cs_n_en = 1; 2125614e71bSYork Sun ap_n_en = popts->cs_local_opts[i].auto_precharge; 2135614e71bSYork Sun odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg; 2145614e71bSYork Sun odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg; 21534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 21634e026f9SYork Sun ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits; 21734e026f9SYork Sun bg_bits_cs_n = dimm_params[dimm_number].bank_group_bits; 21834e026f9SYork Sun #else 2195614e71bSYork Sun n_banks_per_sdram_device 2205614e71bSYork Sun = dimm_params[dimm_number].n_banks_per_sdram_device; 2215614e71bSYork Sun ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2; 22234e026f9SYork Sun #endif 2235614e71bSYork Sun row_bits_cs_n = dimm_params[dimm_number].n_row_addr - 12; 2245614e71bSYork Sun col_bits_cs_n = dimm_params[dimm_number].n_col_addr - 8; 2255614e71bSYork Sun } 2265614e71bSYork Sun ddr->cs[i].config = (0 2275614e71bSYork Sun | ((cs_n_en & 0x1) << 31) 2285614e71bSYork Sun | ((intlv_en & 0x3) << 29) 2295614e71bSYork Sun | ((intlv_ctl & 0xf) << 24) 2305614e71bSYork Sun | ((ap_n_en & 0x1) << 23) 2315614e71bSYork Sun 2325614e71bSYork Sun /* XXX: some implementation only have 1 bit starting at left */ 2335614e71bSYork Sun | ((odt_rd_cfg & 0x7) << 20) 2345614e71bSYork Sun 2355614e71bSYork Sun /* XXX: Some implementation only have 1 bit starting at left */ 2365614e71bSYork Sun | ((odt_wr_cfg & 0x7) << 16) 2375614e71bSYork Sun 2385614e71bSYork Sun | ((ba_bits_cs_n & 0x3) << 14) 2395614e71bSYork Sun | ((row_bits_cs_n & 0x7) << 8) 24034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 24134e026f9SYork Sun | ((bg_bits_cs_n & 0x3) << 4) 24234e026f9SYork Sun #endif 2435614e71bSYork Sun | ((col_bits_cs_n & 0x7) << 0) 2445614e71bSYork Sun ); 2455614e71bSYork Sun debug("FSLDDR: cs[%d]_config = 0x%08x\n", i,ddr->cs[i].config); 2465614e71bSYork Sun } 2475614e71bSYork Sun 2485614e71bSYork Sun /* Chip Select Configuration 2 (CSn_CONFIG_2) */ 2495614e71bSYork Sun /* FIXME: 8572 */ 2505614e71bSYork Sun static void set_csn_config_2(int i, fsl_ddr_cfg_regs_t *ddr) 2515614e71bSYork Sun { 2525614e71bSYork Sun unsigned int pasr_cfg = 0; /* Partial array self refresh config */ 2535614e71bSYork Sun 2545614e71bSYork Sun ddr->cs[i].config_2 = ((pasr_cfg & 7) << 24); 2555614e71bSYork Sun debug("FSLDDR: cs[%d]_config_2 = 0x%08x\n", i, ddr->cs[i].config_2); 2565614e71bSYork Sun } 2575614e71bSYork Sun 2585614e71bSYork Sun /* -3E = 667 CL5, -25 = CL6 800, -25E = CL5 800 */ 2595614e71bSYork Sun 2605614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1) 26184baed2aSYork Sun /* 26284baed2aSYork Sun * Check DIMM configuration, return 2 if quad-rank or two dual-rank 26384baed2aSYork Sun * Return 1 if other two slots configuration. Return 0 if single slot. 26484baed2aSYork Sun */ 2655614e71bSYork Sun static inline int avoid_odt_overlap(const dimm_params_t *dimm_params) 2665614e71bSYork Sun { 2675614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 1 2685614e71bSYork Sun if (dimm_params[0].n_ranks == 4) 26984baed2aSYork Sun return 2; 2705614e71bSYork Sun #endif 2715614e71bSYork Sun 2725614e71bSYork Sun #if CONFIG_DIMM_SLOTS_PER_CTLR == 2 2735614e71bSYork Sun if ((dimm_params[0].n_ranks == 2) && 2745614e71bSYork Sun (dimm_params[1].n_ranks == 2)) 27584baed2aSYork Sun return 2; 2765614e71bSYork Sun 2775614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE 2785614e71bSYork Sun if (dimm_params[0].n_ranks == 4) 27984baed2aSYork Sun return 2; 2805614e71bSYork Sun #endif 28184baed2aSYork Sun 28284baed2aSYork Sun if ((dimm_params[0].n_ranks != 0) && 28384baed2aSYork Sun (dimm_params[2].n_ranks != 0)) 28484baed2aSYork Sun return 1; 2855614e71bSYork Sun #endif 2865614e71bSYork Sun return 0; 2875614e71bSYork Sun } 2885614e71bSYork Sun 2895614e71bSYork Sun /* 2905614e71bSYork Sun * DDR SDRAM Timing Configuration 0 (TIMING_CFG_0) 2915614e71bSYork Sun * 2925614e71bSYork Sun * Avoid writing for DDR I. The new PQ38 DDR controller 2935614e71bSYork Sun * dreams up non-zero default values to be backwards compatible. 2945614e71bSYork Sun */ 29503e664d8SYork Sun static void set_timing_cfg_0(const unsigned int ctrl_num, 29603e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 2975614e71bSYork Sun const memctl_options_t *popts, 2985614e71bSYork Sun const dimm_params_t *dimm_params) 2995614e71bSYork Sun { 3005614e71bSYork Sun unsigned char trwt_mclk = 0; /* Read-to-write turnaround */ 3015614e71bSYork Sun unsigned char twrt_mclk = 0; /* Write-to-read turnaround */ 3025614e71bSYork Sun /* 7.5 ns on -3E; 0 means WL - CL + BL/2 + 1 */ 3035614e71bSYork Sun unsigned char trrt_mclk = 0; /* Read-to-read turnaround */ 3045614e71bSYork Sun unsigned char twwt_mclk = 0; /* Write-to-write turnaround */ 3055614e71bSYork Sun 3065614e71bSYork Sun /* Active powerdown exit timing (tXARD and tXARDS). */ 3075614e71bSYork Sun unsigned char act_pd_exit_mclk; 3085614e71bSYork Sun /* Precharge powerdown exit timing (tXP). */ 3095614e71bSYork Sun unsigned char pre_pd_exit_mclk; 3105614e71bSYork Sun /* ODT powerdown exit timing (tAXPD). */ 31134e026f9SYork Sun unsigned char taxpd_mclk = 0; 3125614e71bSYork Sun /* Mode register set cycle time (tMRD). */ 3135614e71bSYork Sun unsigned char tmrd_mclk; 314bb578322SYork Sun #if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3) 31503e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 316bb578322SYork Sun #endif 3175614e71bSYork Sun 31834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 31934e026f9SYork Sun /* tXP=max(4nCK, 6ns) */ 320b4141195SMasahiro Yamada int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */ 32166869f95SYork Sun unsigned int data_rate = get_ddr_freq(ctrl_num); 32266869f95SYork Sun 32366869f95SYork Sun /* for faster clock, need more time for data setup */ 32466869f95SYork Sun trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2; 3256c6e006aSYork Sun 3266c6e006aSYork Sun /* 3276c6e006aSYork Sun * for single quad-rank DIMM and two-slot DIMMs 3286c6e006aSYork Sun * to avoid ODT overlap 3296c6e006aSYork Sun */ 3306c6e006aSYork Sun switch (avoid_odt_overlap(dimm_params)) { 3316c6e006aSYork Sun case 2: 3326c6e006aSYork Sun twrt_mclk = 2; 3336c6e006aSYork Sun twwt_mclk = 2; 3346c6e006aSYork Sun trrt_mclk = 2; 3356c6e006aSYork Sun break; 3366c6e006aSYork Sun default: 33734e026f9SYork Sun twrt_mclk = 1; 3386c6e006aSYork Sun twwt_mclk = 1; 3396c6e006aSYork Sun trrt_mclk = 0; 3406c6e006aSYork Sun break; 3416c6e006aSYork Sun } 3426c6e006aSYork Sun 34303e664d8SYork Sun act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); 34434e026f9SYork Sun pre_pd_exit_mclk = act_pd_exit_mclk; 34534e026f9SYork Sun /* 34634e026f9SYork Sun * MRS_CYC = max(tMRD, tMOD) 34734e026f9SYork Sun * tMRD = 8nCK, tMOD = max(24nCK, 15ns) 34834e026f9SYork Sun */ 34903e664d8SYork Sun tmrd_mclk = max(24U, picos_to_mclk(ctrl_num, 15000)); 35034e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 35103e664d8SYork Sun unsigned int data_rate = get_ddr_freq(ctrl_num); 352bb578322SYork Sun int txp; 353938bbb60SYork Sun unsigned int ip_rev; 35484baed2aSYork Sun int odt_overlap; 3555614e71bSYork Sun /* 3565614e71bSYork Sun * (tXARD and tXARDS). Empirical? 3575614e71bSYork Sun * The DDR3 spec has not tXARD, 3585614e71bSYork Sun * we use the tXP instead of it. 359bb578322SYork Sun * tXP=max(3nCK, 7.5ns) for DDR3-800, 1066 360bb578322SYork Sun * max(3nCK, 6ns) for DDR3-1333, 1600, 1866, 2133 3615614e71bSYork Sun * spec has not the tAXPD, we use 3625614e71bSYork Sun * tAXPD=1, need design to confirm. 3635614e71bSYork Sun */ 364b4141195SMasahiro Yamada txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000)); 365bb578322SYork Sun 36666869f95SYork Sun ip_rev = fsl_ddr_get_version(ctrl_num); 367938bbb60SYork Sun if (ip_rev >= 0x40700) { 368938bbb60SYork Sun /* 369938bbb60SYork Sun * MRS_CYC = max(tMRD, tMOD) 370938bbb60SYork Sun * tMRD = 4nCK (8nCK for RDIMM) 371938bbb60SYork Sun * tMOD = max(12nCK, 15ns) 372938bbb60SYork Sun */ 37303e664d8SYork Sun tmrd_mclk = max((unsigned int)12, 37403e664d8SYork Sun picos_to_mclk(ctrl_num, 15000)); 375938bbb60SYork Sun } else { 376938bbb60SYork Sun /* 377938bbb60SYork Sun * MRS_CYC = tMRD 378938bbb60SYork Sun * tMRD = 4nCK (8nCK for RDIMM) 379938bbb60SYork Sun */ 380938bbb60SYork Sun if (popts->registered_dimm_en) 381938bbb60SYork Sun tmrd_mclk = 8; 382938bbb60SYork Sun else 3835614e71bSYork Sun tmrd_mclk = 4; 384938bbb60SYork Sun } 385938bbb60SYork Sun 3865614e71bSYork Sun /* set the turnaround time */ 3875614e71bSYork Sun 3885614e71bSYork Sun /* 38984baed2aSYork Sun * for single quad-rank DIMM and two-slot DIMMs 3905614e71bSYork Sun * to avoid ODT overlap 3915614e71bSYork Sun */ 39284baed2aSYork Sun odt_overlap = avoid_odt_overlap(dimm_params); 39384baed2aSYork Sun switch (odt_overlap) { 39484baed2aSYork Sun case 2: 3955614e71bSYork Sun twwt_mclk = 2; 3965614e71bSYork Sun trrt_mclk = 1; 39784baed2aSYork Sun break; 39884baed2aSYork Sun case 1: 39984baed2aSYork Sun twwt_mclk = 1; 40084baed2aSYork Sun trrt_mclk = 0; 40184baed2aSYork Sun break; 40284baed2aSYork Sun default: 40384baed2aSYork Sun break; 4045614e71bSYork Sun } 40584baed2aSYork Sun 4065614e71bSYork Sun /* for faster clock, need more time for data setup */ 4075614e71bSYork Sun trwt_mclk = (data_rate/1000000 > 1800) ? 2 : 1; 4085614e71bSYork Sun 4095614e71bSYork Sun if ((data_rate/1000000 > 1150) || (popts->memctl_interleaving)) 4105614e71bSYork Sun twrt_mclk = 1; 4115614e71bSYork Sun 4125614e71bSYork Sun if (popts->dynamic_power == 0) { /* powerdown is not used */ 4135614e71bSYork Sun act_pd_exit_mclk = 1; 4145614e71bSYork Sun pre_pd_exit_mclk = 1; 4155614e71bSYork Sun taxpd_mclk = 1; 4165614e71bSYork Sun } else { 4175614e71bSYork Sun /* act_pd_exit_mclk = tXARD, see above */ 41803e664d8SYork Sun act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); 4195614e71bSYork Sun /* Mode register MR0[A12] is '1' - fast exit */ 4205614e71bSYork Sun pre_pd_exit_mclk = act_pd_exit_mclk; 4215614e71bSYork Sun taxpd_mclk = 1; 4225614e71bSYork Sun } 4235614e71bSYork Sun #else /* CONFIG_SYS_FSL_DDR2 */ 4245614e71bSYork Sun /* 4255614e71bSYork Sun * (tXARD and tXARDS). Empirical? 4265614e71bSYork Sun * tXARD = 2 for DDR2 4275614e71bSYork Sun * tXP=2 4285614e71bSYork Sun * tAXPD=8 4295614e71bSYork Sun */ 4305614e71bSYork Sun act_pd_exit_mclk = 2; 4315614e71bSYork Sun pre_pd_exit_mclk = 2; 4325614e71bSYork Sun taxpd_mclk = 8; 4335614e71bSYork Sun tmrd_mclk = 2; 4345614e71bSYork Sun #endif 4355614e71bSYork Sun 4365614e71bSYork Sun if (popts->trwt_override) 4375614e71bSYork Sun trwt_mclk = popts->trwt; 4385614e71bSYork Sun 4395614e71bSYork Sun ddr->timing_cfg_0 = (0 4405614e71bSYork Sun | ((trwt_mclk & 0x3) << 30) /* RWT */ 4415614e71bSYork Sun | ((twrt_mclk & 0x3) << 28) /* WRT */ 4425614e71bSYork Sun | ((trrt_mclk & 0x3) << 26) /* RRT */ 4435614e71bSYork Sun | ((twwt_mclk & 0x3) << 24) /* WWT */ 444d4263b8aSYork Sun | ((act_pd_exit_mclk & 0xf) << 20) /* ACT_PD_EXIT */ 4455614e71bSYork Sun | ((pre_pd_exit_mclk & 0xF) << 16) /* PRE_PD_EXIT */ 4465614e71bSYork Sun | ((taxpd_mclk & 0xf) << 8) /* ODT_PD_EXIT */ 447d4263b8aSYork Sun | ((tmrd_mclk & 0x1f) << 0) /* MRS_CYC */ 4485614e71bSYork Sun ); 4495614e71bSYork Sun debug("FSLDDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0); 4505614e71bSYork Sun } 45184baed2aSYork Sun #endif /* !defined(CONFIG_SYS_FSL_DDR1) */ 4525614e71bSYork Sun 4535614e71bSYork Sun /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ 45403e664d8SYork Sun static void set_timing_cfg_3(const unsigned int ctrl_num, 45503e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 4565614e71bSYork Sun const memctl_options_t *popts, 4575614e71bSYork Sun const common_timing_params_t *common_dimm, 458d4263b8aSYork Sun unsigned int cas_latency, 459d4263b8aSYork Sun unsigned int additive_latency) 4605614e71bSYork Sun { 4615614e71bSYork Sun /* Extended precharge to activate interval (tRP) */ 4625614e71bSYork Sun unsigned int ext_pretoact = 0; 4635614e71bSYork Sun /* Extended Activate to precharge interval (tRAS) */ 4645614e71bSYork Sun unsigned int ext_acttopre = 0; 4655614e71bSYork Sun /* Extended activate to read/write interval (tRCD) */ 4665614e71bSYork Sun unsigned int ext_acttorw = 0; 4675614e71bSYork Sun /* Extended refresh recovery time (tRFC) */ 4685614e71bSYork Sun unsigned int ext_refrec; 4695614e71bSYork Sun /* Extended MCAS latency from READ cmd */ 4705614e71bSYork Sun unsigned int ext_caslat = 0; 471d4263b8aSYork Sun /* Extended additive latency */ 472d4263b8aSYork Sun unsigned int ext_add_lat = 0; 4735614e71bSYork Sun /* Extended last data to precharge interval (tWR) */ 4745614e71bSYork Sun unsigned int ext_wrrec = 0; 4755614e71bSYork Sun /* Control Adjust */ 4765614e71bSYork Sun unsigned int cntl_adj = 0; 4775614e71bSYork Sun 47803e664d8SYork Sun ext_pretoact = picos_to_mclk(ctrl_num, common_dimm->trp_ps) >> 4; 47903e664d8SYork Sun ext_acttopre = picos_to_mclk(ctrl_num, common_dimm->tras_ps) >> 4; 48003e664d8SYork Sun ext_acttorw = picos_to_mclk(ctrl_num, common_dimm->trcd_ps) >> 4; 4815614e71bSYork Sun ext_caslat = (2 * cas_latency - 1) >> 4; 482d4263b8aSYork Sun ext_add_lat = additive_latency >> 4; 48334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 48403e664d8SYork Sun ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8) >> 4; 48534e026f9SYork Sun #else 48603e664d8SYork Sun ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8) >> 4; 4875614e71bSYork Sun /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ 48834e026f9SYork Sun #endif 48903e664d8SYork Sun ext_wrrec = (picos_to_mclk(ctrl_num, common_dimm->twr_ps) + 4905614e71bSYork Sun (popts->otf_burst_chop_en ? 2 : 0)) >> 4; 4915614e71bSYork Sun 4925614e71bSYork Sun ddr->timing_cfg_3 = (0 4935614e71bSYork Sun | ((ext_pretoact & 0x1) << 28) 4945614e71bSYork Sun | ((ext_acttopre & 0x3) << 24) 4955614e71bSYork Sun | ((ext_acttorw & 0x1) << 22) 496*c0c32af0SYork Sun | ((ext_refrec & 0x3F) << 16) 4975614e71bSYork Sun | ((ext_caslat & 0x3) << 12) 498d4263b8aSYork Sun | ((ext_add_lat & 0x1) << 10) 4995614e71bSYork Sun | ((ext_wrrec & 0x1) << 8) 5005614e71bSYork Sun | ((cntl_adj & 0x7) << 0) 5015614e71bSYork Sun ); 5025614e71bSYork Sun debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3); 5035614e71bSYork Sun } 5045614e71bSYork Sun 5055614e71bSYork Sun /* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */ 50603e664d8SYork Sun static void set_timing_cfg_1(const unsigned int ctrl_num, 50703e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 5085614e71bSYork Sun const memctl_options_t *popts, 5095614e71bSYork Sun const common_timing_params_t *common_dimm, 5105614e71bSYork Sun unsigned int cas_latency) 5115614e71bSYork Sun { 5125614e71bSYork Sun /* Precharge-to-activate interval (tRP) */ 5135614e71bSYork Sun unsigned char pretoact_mclk; 5145614e71bSYork Sun /* Activate to precharge interval (tRAS) */ 5155614e71bSYork Sun unsigned char acttopre_mclk; 5165614e71bSYork Sun /* Activate to read/write interval (tRCD) */ 5175614e71bSYork Sun unsigned char acttorw_mclk; 5185614e71bSYork Sun /* CASLAT */ 5195614e71bSYork Sun unsigned char caslat_ctrl; 5205614e71bSYork Sun /* Refresh recovery time (tRFC) ; trfc_low */ 5215614e71bSYork Sun unsigned char refrec_ctrl; 5225614e71bSYork Sun /* Last data to precharge minimum interval (tWR) */ 5235614e71bSYork Sun unsigned char wrrec_mclk; 5245614e71bSYork Sun /* Activate-to-activate interval (tRRD) */ 5255614e71bSYork Sun unsigned char acttoact_mclk; 5265614e71bSYork Sun /* Last write data pair to read command issue interval (tWTR) */ 5275614e71bSYork Sun unsigned char wrtord_mclk; 52834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 52934e026f9SYork Sun /* DDR4 supports 10, 12, 14, 16, 18, 20, 24 */ 53034e026f9SYork Sun static const u8 wrrec_table[] = { 53134e026f9SYork Sun 10, 10, 10, 10, 10, 53234e026f9SYork Sun 10, 10, 10, 10, 10, 53334e026f9SYork Sun 12, 12, 14, 14, 16, 53434e026f9SYork Sun 16, 18, 18, 20, 20, 53534e026f9SYork Sun 24, 24, 24, 24}; 53634e026f9SYork Sun #else 5375614e71bSYork Sun /* DDR_SDRAM_MODE doesn't support 9,11,13,15 */ 5385614e71bSYork Sun static const u8 wrrec_table[] = { 5395614e71bSYork Sun 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0}; 54034e026f9SYork Sun #endif 5415614e71bSYork Sun 54203e664d8SYork Sun pretoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trp_ps); 54303e664d8SYork Sun acttopre_mclk = picos_to_mclk(ctrl_num, common_dimm->tras_ps); 54403e664d8SYork Sun acttorw_mclk = picos_to_mclk(ctrl_num, common_dimm->trcd_ps); 5455614e71bSYork Sun 5465614e71bSYork Sun /* 5475614e71bSYork Sun * Translate CAS Latency to a DDR controller field value: 5485614e71bSYork Sun * 5495614e71bSYork Sun * CAS Lat DDR I DDR II Ctrl 5505614e71bSYork Sun * Clocks SPD Bit SPD Bit Value 5515614e71bSYork Sun * ------- ------- ------- ----- 5525614e71bSYork Sun * 1.0 0 0001 5535614e71bSYork Sun * 1.5 1 0010 5545614e71bSYork Sun * 2.0 2 2 0011 5555614e71bSYork Sun * 2.5 3 0100 5565614e71bSYork Sun * 3.0 4 3 0101 5575614e71bSYork Sun * 3.5 5 0110 5585614e71bSYork Sun * 4.0 4 0111 5595614e71bSYork Sun * 4.5 1000 5605614e71bSYork Sun * 5.0 5 1001 5615614e71bSYork Sun */ 5625614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 5635614e71bSYork Sun caslat_ctrl = (cas_latency + 1) & 0x07; 5645614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 5655614e71bSYork Sun caslat_ctrl = 2 * cas_latency - 1; 5665614e71bSYork Sun #else 5675614e71bSYork Sun /* 5685614e71bSYork Sun * if the CAS latency more than 8 cycle, 5695614e71bSYork Sun * we need set extend bit for it at 5705614e71bSYork Sun * TIMING_CFG_3[EXT_CASLAT] 5715614e71bSYork Sun */ 57266869f95SYork Sun if (fsl_ddr_get_version(ctrl_num) <= 0x40400) 5735614e71bSYork Sun caslat_ctrl = 2 * cas_latency - 1; 57434e026f9SYork Sun else 57534e026f9SYork Sun caslat_ctrl = (cas_latency - 1) << 1; 5765614e71bSYork Sun #endif 5775614e71bSYork Sun 57834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 57903e664d8SYork Sun refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8; 58003e664d8SYork Sun wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 58103e664d8SYork Sun acttoact_mclk = max(picos_to_mclk(ctrl_num, common_dimm->trrds_ps), 4U); 58203e664d8SYork Sun wrtord_mclk = max(2U, picos_to_mclk(ctrl_num, 2500)); 583349689b8SYork Sun if ((wrrec_mclk < 1) || (wrrec_mclk > 24)) 584349689b8SYork Sun printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); 58534e026f9SYork Sun else 58634e026f9SYork Sun wrrec_mclk = wrrec_table[wrrec_mclk - 1]; 58734e026f9SYork Sun #else 58803e664d8SYork Sun refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8; 58903e664d8SYork Sun wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 59003e664d8SYork Sun acttoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trrd_ps); 59103e664d8SYork Sun wrtord_mclk = picos_to_mclk(ctrl_num, common_dimm->twtr_ps); 592349689b8SYork Sun if ((wrrec_mclk < 1) || (wrrec_mclk > 16)) 593349689b8SYork Sun printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); 5945614e71bSYork Sun else 5955614e71bSYork Sun wrrec_mclk = wrrec_table[wrrec_mclk - 1]; 59634e026f9SYork Sun #endif 5975614e71bSYork Sun if (popts->otf_burst_chop_en) 5985614e71bSYork Sun wrrec_mclk += 2; 5995614e71bSYork Sun 6005614e71bSYork Sun /* 6015614e71bSYork Sun * JEDEC has min requirement for tRRD 6025614e71bSYork Sun */ 6035614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR3) 6045614e71bSYork Sun if (acttoact_mclk < 4) 6055614e71bSYork Sun acttoact_mclk = 4; 6065614e71bSYork Sun #endif 6075614e71bSYork Sun /* 6085614e71bSYork Sun * JEDEC has some min requirements for tWTR 6095614e71bSYork Sun */ 6105614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2) 6115614e71bSYork Sun if (wrtord_mclk < 2) 6125614e71bSYork Sun wrtord_mclk = 2; 6135614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 6145614e71bSYork Sun if (wrtord_mclk < 4) 6155614e71bSYork Sun wrtord_mclk = 4; 6165614e71bSYork Sun #endif 6175614e71bSYork Sun if (popts->otf_burst_chop_en) 6185614e71bSYork Sun wrtord_mclk += 2; 6195614e71bSYork Sun 6205614e71bSYork Sun ddr->timing_cfg_1 = (0 6215614e71bSYork Sun | ((pretoact_mclk & 0x0F) << 28) 6225614e71bSYork Sun | ((acttopre_mclk & 0x0F) << 24) 6235614e71bSYork Sun | ((acttorw_mclk & 0xF) << 20) 6245614e71bSYork Sun | ((caslat_ctrl & 0xF) << 16) 6255614e71bSYork Sun | ((refrec_ctrl & 0xF) << 12) 6265614e71bSYork Sun | ((wrrec_mclk & 0x0F) << 8) 6275614e71bSYork Sun | ((acttoact_mclk & 0x0F) << 4) 6285614e71bSYork Sun | ((wrtord_mclk & 0x0F) << 0) 6295614e71bSYork Sun ); 6305614e71bSYork Sun debug("FSLDDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1); 6315614e71bSYork Sun } 6325614e71bSYork Sun 6335614e71bSYork Sun /* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */ 63403e664d8SYork Sun static void set_timing_cfg_2(const unsigned int ctrl_num, 63503e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 6365614e71bSYork Sun const memctl_options_t *popts, 6375614e71bSYork Sun const common_timing_params_t *common_dimm, 6385614e71bSYork Sun unsigned int cas_latency, 6395614e71bSYork Sun unsigned int additive_latency) 6405614e71bSYork Sun { 6415614e71bSYork Sun /* Additive latency */ 6425614e71bSYork Sun unsigned char add_lat_mclk; 6435614e71bSYork Sun /* CAS-to-preamble override */ 6445614e71bSYork Sun unsigned short cpo; 6455614e71bSYork Sun /* Write latency */ 6465614e71bSYork Sun unsigned char wr_lat; 6475614e71bSYork Sun /* Read to precharge (tRTP) */ 6485614e71bSYork Sun unsigned char rd_to_pre; 6495614e71bSYork Sun /* Write command to write data strobe timing adjustment */ 6505614e71bSYork Sun unsigned char wr_data_delay; 6515614e71bSYork Sun /* Minimum CKE pulse width (tCKE) */ 6525614e71bSYork Sun unsigned char cke_pls; 6535614e71bSYork Sun /* Window for four activates (tFAW) */ 6545614e71bSYork Sun unsigned short four_act; 655bb578322SYork Sun #ifdef CONFIG_SYS_FSL_DDR3 65603e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 657bb578322SYork Sun #endif 6585614e71bSYork Sun 6595614e71bSYork Sun /* FIXME add check that this must be less than acttorw_mclk */ 6605614e71bSYork Sun add_lat_mclk = additive_latency; 6615614e71bSYork Sun cpo = popts->cpo_override; 6625614e71bSYork Sun 6635614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 6645614e71bSYork Sun /* 6655614e71bSYork Sun * This is a lie. It should really be 1, but if it is 6665614e71bSYork Sun * set to 1, bits overlap into the old controller's 6675614e71bSYork Sun * otherwise unused ACSM field. If we leave it 0, then 6685614e71bSYork Sun * the HW will magically treat it as 1 for DDR 1. Oh Yea. 6695614e71bSYork Sun */ 6705614e71bSYork Sun wr_lat = 0; 6715614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 6725614e71bSYork Sun wr_lat = cas_latency - 1; 6735614e71bSYork Sun #else 67403e664d8SYork Sun wr_lat = compute_cas_write_latency(ctrl_num); 6755614e71bSYork Sun #endif 6765614e71bSYork Sun 67734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 67803e664d8SYork Sun rd_to_pre = picos_to_mclk(ctrl_num, 7500); 67934e026f9SYork Sun #else 68003e664d8SYork Sun rd_to_pre = picos_to_mclk(ctrl_num, common_dimm->trtp_ps); 68134e026f9SYork Sun #endif 6825614e71bSYork Sun /* 6835614e71bSYork Sun * JEDEC has some min requirements for tRTP 6845614e71bSYork Sun */ 6855614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR2) 6865614e71bSYork Sun if (rd_to_pre < 2) 6875614e71bSYork Sun rd_to_pre = 2; 68834e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 6895614e71bSYork Sun if (rd_to_pre < 4) 6905614e71bSYork Sun rd_to_pre = 4; 6915614e71bSYork Sun #endif 6925614e71bSYork Sun if (popts->otf_burst_chop_en) 6935614e71bSYork Sun rd_to_pre += 2; /* according to UM */ 6945614e71bSYork Sun 6955614e71bSYork Sun wr_data_delay = popts->write_data_delay; 69634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 69734e026f9SYork Sun cpo = 0; 69803e664d8SYork Sun cke_pls = max(3U, picos_to_mclk(ctrl_num, 5000)); 699bb578322SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 700bb578322SYork Sun /* 701bb578322SYork Sun * cke pulse = max(3nCK, 7.5ns) for DDR3-800 702bb578322SYork Sun * max(3nCK, 5.625ns) for DDR3-1066, 1333 703bb578322SYork Sun * max(3nCK, 5ns) for DDR3-1600, 1866, 2133 704bb578322SYork Sun */ 70503e664d8SYork Sun cke_pls = max(3U, picos_to_mclk(ctrl_num, mclk_ps > 1870 ? 7500 : 706bb578322SYork Sun (mclk_ps > 1245 ? 5625 : 5000))); 70734e026f9SYork Sun #else 708bb578322SYork Sun cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR; 70934e026f9SYork Sun #endif 71003e664d8SYork Sun four_act = picos_to_mclk(ctrl_num, 71103e664d8SYork Sun popts->tfaw_window_four_activates_ps); 7125614e71bSYork Sun 7135614e71bSYork Sun ddr->timing_cfg_2 = (0 7145614e71bSYork Sun | ((add_lat_mclk & 0xf) << 28) 7155614e71bSYork Sun | ((cpo & 0x1f) << 23) 7165614e71bSYork Sun | ((wr_lat & 0xf) << 19) 7178936691bSYork Sun | (((wr_lat & 0x10) >> 4) << 18) 7185614e71bSYork Sun | ((rd_to_pre & RD_TO_PRE_MASK) << RD_TO_PRE_SHIFT) 7195614e71bSYork Sun | ((wr_data_delay & WR_DATA_DELAY_MASK) << WR_DATA_DELAY_SHIFT) 7205614e71bSYork Sun | ((cke_pls & 0x7) << 6) 7215614e71bSYork Sun | ((four_act & 0x3f) << 0) 7225614e71bSYork Sun ); 7235614e71bSYork Sun debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2); 7245614e71bSYork Sun } 7255614e71bSYork Sun 7265614e71bSYork Sun /* DDR SDRAM Register Control Word */ 7275614e71bSYork Sun static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, 7285614e71bSYork Sun const memctl_options_t *popts, 7295614e71bSYork Sun const common_timing_params_t *common_dimm) 7305614e71bSYork Sun { 7315614e71bSYork Sun if (common_dimm->all_dimms_registered && 7325614e71bSYork Sun !common_dimm->all_dimms_unbuffered) { 7335614e71bSYork Sun if (popts->rcw_override) { 7345614e71bSYork Sun ddr->ddr_sdram_rcw_1 = popts->rcw_1; 7355614e71bSYork Sun ddr->ddr_sdram_rcw_2 = popts->rcw_2; 736426230a6SYork Sun ddr->ddr_sdram_rcw_3 = popts->rcw_3; 7375614e71bSYork Sun } else { 7385614e71bSYork Sun ddr->ddr_sdram_rcw_1 = 7395614e71bSYork Sun common_dimm->rcw[0] << 28 | \ 7405614e71bSYork Sun common_dimm->rcw[1] << 24 | \ 7415614e71bSYork Sun common_dimm->rcw[2] << 20 | \ 7425614e71bSYork Sun common_dimm->rcw[3] << 16 | \ 7435614e71bSYork Sun common_dimm->rcw[4] << 12 | \ 7445614e71bSYork Sun common_dimm->rcw[5] << 8 | \ 7455614e71bSYork Sun common_dimm->rcw[6] << 4 | \ 7465614e71bSYork Sun common_dimm->rcw[7]; 7475614e71bSYork Sun ddr->ddr_sdram_rcw_2 = 7485614e71bSYork Sun common_dimm->rcw[8] << 28 | \ 7495614e71bSYork Sun common_dimm->rcw[9] << 24 | \ 7505614e71bSYork Sun common_dimm->rcw[10] << 20 | \ 7515614e71bSYork Sun common_dimm->rcw[11] << 16 | \ 7525614e71bSYork Sun common_dimm->rcw[12] << 12 | \ 7535614e71bSYork Sun common_dimm->rcw[13] << 8 | \ 7545614e71bSYork Sun common_dimm->rcw[14] << 4 | \ 7555614e71bSYork Sun common_dimm->rcw[15]; 7565614e71bSYork Sun } 757426230a6SYork Sun debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", 758426230a6SYork Sun ddr->ddr_sdram_rcw_1); 759426230a6SYork Sun debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", 760426230a6SYork Sun ddr->ddr_sdram_rcw_2); 761426230a6SYork Sun debug("FSLDDR: ddr_sdram_rcw_3 = 0x%08x\n", 762426230a6SYork Sun ddr->ddr_sdram_rcw_3); 7635614e71bSYork Sun } 7645614e71bSYork Sun } 7655614e71bSYork Sun 7665614e71bSYork Sun /* DDR SDRAM control configuration (DDR_SDRAM_CFG) */ 7675614e71bSYork Sun static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, 7685614e71bSYork Sun const memctl_options_t *popts, 7695614e71bSYork Sun const common_timing_params_t *common_dimm) 7705614e71bSYork Sun { 7715614e71bSYork Sun unsigned int mem_en; /* DDR SDRAM interface logic enable */ 7725614e71bSYork Sun unsigned int sren; /* Self refresh enable (during sleep) */ 7735614e71bSYork Sun unsigned int ecc_en; /* ECC enable. */ 7745614e71bSYork Sun unsigned int rd_en; /* Registered DIMM enable */ 7755614e71bSYork Sun unsigned int sdram_type; /* Type of SDRAM */ 7765614e71bSYork Sun unsigned int dyn_pwr; /* Dynamic power management mode */ 7775614e71bSYork Sun unsigned int dbw; /* DRAM dta bus width */ 7785614e71bSYork Sun unsigned int eight_be = 0; /* 8-beat burst enable, DDR2 is zero */ 7795614e71bSYork Sun unsigned int ncap = 0; /* Non-concurrent auto-precharge */ 7805614e71bSYork Sun unsigned int threet_en; /* Enable 3T timing */ 7815614e71bSYork Sun unsigned int twot_en; /* Enable 2T timing */ 7825614e71bSYork Sun unsigned int ba_intlv_ctl; /* Bank (CS) interleaving control */ 7835614e71bSYork Sun unsigned int x32_en = 0; /* x32 enable */ 7845614e71bSYork Sun unsigned int pchb8 = 0; /* precharge bit 8 enable */ 7855614e71bSYork Sun unsigned int hse; /* Global half strength override */ 786d28cb671SYork Sun unsigned int acc_ecc_en = 0; /* Accumulated ECC enable */ 7875614e71bSYork Sun unsigned int mem_halt = 0; /* memory controller halt */ 7885614e71bSYork Sun unsigned int bi = 0; /* Bypass initialization */ 7895614e71bSYork Sun 7905614e71bSYork Sun mem_en = 1; 7915614e71bSYork Sun sren = popts->self_refresh_in_sleep; 7925614e71bSYork Sun if (common_dimm->all_dimms_ecc_capable) { 7935614e71bSYork Sun /* Allow setting of ECC only if all DIMMs are ECC. */ 7945614e71bSYork Sun ecc_en = popts->ecc_mode; 7955614e71bSYork Sun } else { 7965614e71bSYork Sun ecc_en = 0; 7975614e71bSYork Sun } 7985614e71bSYork Sun 7995614e71bSYork Sun if (common_dimm->all_dimms_registered && 8005614e71bSYork Sun !common_dimm->all_dimms_unbuffered) { 8015614e71bSYork Sun rd_en = 1; 8025614e71bSYork Sun twot_en = 0; 8035614e71bSYork Sun } else { 8045614e71bSYork Sun rd_en = 0; 8055614e71bSYork Sun twot_en = popts->twot_en; 8065614e71bSYork Sun } 8075614e71bSYork Sun 8085614e71bSYork Sun sdram_type = CONFIG_FSL_SDRAM_TYPE; 8095614e71bSYork Sun 8105614e71bSYork Sun dyn_pwr = popts->dynamic_power; 8115614e71bSYork Sun dbw = popts->data_bus_width; 8125614e71bSYork Sun /* 8-beat burst enable DDR-III case 8135614e71bSYork Sun * we must clear it when use the on-the-fly mode, 8145614e71bSYork Sun * must set it when use the 32-bits bus mode. 8155614e71bSYork Sun */ 81634e026f9SYork Sun if ((sdram_type == SDRAM_TYPE_DDR3) || 81734e026f9SYork Sun (sdram_type == SDRAM_TYPE_DDR4)) { 8185614e71bSYork Sun if (popts->burst_length == DDR_BL8) 8195614e71bSYork Sun eight_be = 1; 8205614e71bSYork Sun if (popts->burst_length == DDR_OTF) 8215614e71bSYork Sun eight_be = 0; 8225614e71bSYork Sun if (dbw == 0x1) 8235614e71bSYork Sun eight_be = 1; 8245614e71bSYork Sun } 8255614e71bSYork Sun 8265614e71bSYork Sun threet_en = popts->threet_en; 8275614e71bSYork Sun ba_intlv_ctl = popts->ba_intlv_ctl; 8285614e71bSYork Sun hse = popts->half_strength_driver_enable; 8295614e71bSYork Sun 830d28cb671SYork Sun /* set when ddr bus width < 64 */ 831d28cb671SYork Sun acc_ecc_en = (dbw != 0 && ecc_en == 1) ? 1 : 0; 832d28cb671SYork Sun 8335614e71bSYork Sun ddr->ddr_sdram_cfg = (0 8345614e71bSYork Sun | ((mem_en & 0x1) << 31) 8355614e71bSYork Sun | ((sren & 0x1) << 30) 8365614e71bSYork Sun | ((ecc_en & 0x1) << 29) 8375614e71bSYork Sun | ((rd_en & 0x1) << 28) 8385614e71bSYork Sun | ((sdram_type & 0x7) << 24) 8395614e71bSYork Sun | ((dyn_pwr & 0x1) << 21) 8405614e71bSYork Sun | ((dbw & 0x3) << 19) 8415614e71bSYork Sun | ((eight_be & 0x1) << 18) 8425614e71bSYork Sun | ((ncap & 0x1) << 17) 8435614e71bSYork Sun | ((threet_en & 0x1) << 16) 8445614e71bSYork Sun | ((twot_en & 0x1) << 15) 8455614e71bSYork Sun | ((ba_intlv_ctl & 0x7F) << 8) 8465614e71bSYork Sun | ((x32_en & 0x1) << 5) 8475614e71bSYork Sun | ((pchb8 & 0x1) << 4) 8485614e71bSYork Sun | ((hse & 0x1) << 3) 849d28cb671SYork Sun | ((acc_ecc_en & 0x1) << 2) 8505614e71bSYork Sun | ((mem_halt & 0x1) << 1) 8515614e71bSYork Sun | ((bi & 0x1) << 0) 8525614e71bSYork Sun ); 8535614e71bSYork Sun debug("FSLDDR: ddr_sdram_cfg = 0x%08x\n", ddr->ddr_sdram_cfg); 8545614e71bSYork Sun } 8555614e71bSYork Sun 8565614e71bSYork Sun /* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */ 85703e664d8SYork Sun static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num, 85803e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 8595614e71bSYork Sun const memctl_options_t *popts, 8605614e71bSYork Sun const unsigned int unq_mrs_en) 8615614e71bSYork Sun { 8625614e71bSYork Sun unsigned int frc_sr = 0; /* Force self refresh */ 8635614e71bSYork Sun unsigned int sr_ie = 0; /* Self-refresh interrupt enable */ 8645614e71bSYork Sun unsigned int odt_cfg = 0; /* ODT configuration */ 8655614e71bSYork Sun unsigned int num_pr; /* Number of posted refreshes */ 8665614e71bSYork Sun unsigned int slow = 0; /* DDR will be run less than 1250 */ 8675614e71bSYork Sun unsigned int x4_en = 0; /* x4 DRAM enable */ 8685614e71bSYork Sun unsigned int obc_cfg; /* On-The-Fly Burst Chop Cfg */ 8695614e71bSYork Sun unsigned int ap_en; /* Address Parity Enable */ 8705614e71bSYork Sun unsigned int d_init; /* DRAM data initialization */ 8715614e71bSYork Sun unsigned int rcw_en = 0; /* Register Control Word Enable */ 8725614e71bSYork Sun unsigned int md_en = 0; /* Mirrored DIMM Enable */ 8735614e71bSYork Sun unsigned int qd_en = 0; /* quad-rank DIMM Enable */ 8745614e71bSYork Sun int i; 87534e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4 87634e026f9SYork Sun unsigned int dll_rst_dis = 1; /* DLL reset disable */ 87734e026f9SYork Sun unsigned int dqs_cfg; /* DQS configuration */ 8785614e71bSYork Sun 8795614e71bSYork Sun dqs_cfg = popts->dqs_config; 88034e026f9SYork Sun #endif 8815614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 8825614e71bSYork Sun if (popts->cs_local_opts[i].odt_rd_cfg 8835614e71bSYork Sun || popts->cs_local_opts[i].odt_wr_cfg) { 8845614e71bSYork Sun odt_cfg = SDRAM_CFG2_ODT_ONLY_READ; 8855614e71bSYork Sun break; 8865614e71bSYork Sun } 8875614e71bSYork Sun } 888e368c206SJoakim Tjernlund sr_ie = popts->self_refresh_interrupt_en; 889*c0c32af0SYork Sun num_pr = popts->package_3ds + 1; 8905614e71bSYork Sun 8915614e71bSYork Sun /* 8925614e71bSYork Sun * 8572 manual says 8935614e71bSYork Sun * {TIMING_CFG_1[PRETOACT] 8945614e71bSYork Sun * + [DDR_SDRAM_CFG_2[NUM_PR] 8955614e71bSYork Sun * * ({EXT_REFREC || REFREC} + 8 + 2)]} 8965614e71bSYork Sun * << DDR_SDRAM_INTERVAL[REFINT] 8975614e71bSYork Sun */ 89834e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 8995614e71bSYork Sun obc_cfg = popts->otf_burst_chop_en; 9005614e71bSYork Sun #else 9015614e71bSYork Sun obc_cfg = 0; 9025614e71bSYork Sun #endif 9035614e71bSYork Sun 9045614e71bSYork Sun #if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7) 90503e664d8SYork Sun slow = get_ddr_freq(ctrl_num) < 1249000000; 9065614e71bSYork Sun #endif 9075614e71bSYork Sun 908eb118807SShengzhou Liu if (popts->registered_dimm_en) 9095614e71bSYork Sun rcw_en = 1; 910eb118807SShengzhou Liu 911eb118807SShengzhou Liu /* DDR4 can have address parity for UDIMM and discrete */ 912eb118807SShengzhou Liu if ((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) && 913eb118807SShengzhou Liu (!popts->registered_dimm_en)) { 9145614e71bSYork Sun ap_en = 0; 915eb118807SShengzhou Liu } else { 916eb118807SShengzhou Liu ap_en = popts->ap_en; 9175614e71bSYork Sun } 9185614e71bSYork Sun 9195614e71bSYork Sun x4_en = popts->x4_en ? 1 : 0; 9205614e71bSYork Sun 9215614e71bSYork Sun #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) 9225614e71bSYork Sun /* Use the DDR controller to auto initialize memory. */ 9235614e71bSYork Sun d_init = popts->ecc_init_using_memctl; 9245614e71bSYork Sun ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE; 9255614e71bSYork Sun debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init); 9265614e71bSYork Sun #else 9275614e71bSYork Sun /* Memory will be initialized via DMA, or not at all. */ 9285614e71bSYork Sun d_init = 0; 9295614e71bSYork Sun #endif 9305614e71bSYork Sun 93134e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 9325614e71bSYork Sun md_en = popts->mirrored_dimm; 9335614e71bSYork Sun #endif 9345614e71bSYork Sun qd_en = popts->quad_rank_present ? 1 : 0; 9355614e71bSYork Sun ddr->ddr_sdram_cfg_2 = (0 9365614e71bSYork Sun | ((frc_sr & 0x1) << 31) 9375614e71bSYork Sun | ((sr_ie & 0x1) << 30) 93834e026f9SYork Sun #ifndef CONFIG_SYS_FSL_DDR4 9395614e71bSYork Sun | ((dll_rst_dis & 0x1) << 29) 9405614e71bSYork Sun | ((dqs_cfg & 0x3) << 26) 94134e026f9SYork Sun #endif 9425614e71bSYork Sun | ((odt_cfg & 0x3) << 21) 9435614e71bSYork Sun | ((num_pr & 0xf) << 12) 9445614e71bSYork Sun | ((slow & 1) << 11) 9455614e71bSYork Sun | (x4_en << 10) 9465614e71bSYork Sun | (qd_en << 9) 9475614e71bSYork Sun | (unq_mrs_en << 8) 9485614e71bSYork Sun | ((obc_cfg & 0x1) << 6) 9495614e71bSYork Sun | ((ap_en & 0x1) << 5) 9505614e71bSYork Sun | ((d_init & 0x1) << 4) 9515614e71bSYork Sun | ((rcw_en & 0x1) << 2) 9525614e71bSYork Sun | ((md_en & 0x1) << 0) 9535614e71bSYork Sun ); 9545614e71bSYork Sun debug("FSLDDR: ddr_sdram_cfg_2 = 0x%08x\n", ddr->ddr_sdram_cfg_2); 9555614e71bSYork Sun } 9565614e71bSYork Sun 95734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 9585614e71bSYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 95903e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, 96003e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 9615614e71bSYork Sun const memctl_options_t *popts, 9625614e71bSYork Sun const common_timing_params_t *common_dimm, 9635614e71bSYork Sun const unsigned int unq_mrs_en) 9645614e71bSYork Sun { 9655614e71bSYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 9665614e71bSYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 9675614e71bSYork Sun int i; 96834e026f9SYork Sun unsigned int wr_crc = 0; /* Disable */ 9695614e71bSYork Sun unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ 9705614e71bSYork Sun unsigned int srt = 0; /* self-refresh temerature, normal range */ 97103e664d8SYork Sun unsigned int cwl = compute_cas_write_latency(ctrl_num) - 9; 97234e026f9SYork Sun unsigned int mpr = 0; /* serial */ 97334e026f9SYork Sun unsigned int wc_lat; 97403e664d8SYork Sun const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 9755614e71bSYork Sun 9765614e71bSYork Sun if (popts->rtt_override) 9775614e71bSYork Sun rtt_wr = popts->rtt_wr_override_value; 9785614e71bSYork Sun else 9795614e71bSYork Sun rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; 9805614e71bSYork Sun 9815614e71bSYork Sun if (common_dimm->extended_op_srt) 9825614e71bSYork Sun srt = common_dimm->extended_op_srt; 9835614e71bSYork Sun 9845614e71bSYork Sun esdmode2 = (0 98534e026f9SYork Sun | ((wr_crc & 0x1) << 12) 9865614e71bSYork Sun | ((rtt_wr & 0x3) << 9) 98734e026f9SYork Sun | ((srt & 0x3) << 6) 98834e026f9SYork Sun | ((cwl & 0x7) << 3)); 98934e026f9SYork Sun 99034e026f9SYork Sun if (mclk_ps >= 1250) 99134e026f9SYork Sun wc_lat = 0; 99234e026f9SYork Sun else if (mclk_ps >= 833) 99334e026f9SYork Sun wc_lat = 1; 99434e026f9SYork Sun else 99534e026f9SYork Sun wc_lat = 2; 99634e026f9SYork Sun 99734e026f9SYork Sun esdmode3 = (0 99834e026f9SYork Sun | ((mpr & 0x3) << 11) 99934e026f9SYork Sun | ((wc_lat & 0x3) << 9)); 100034e026f9SYork Sun 10015614e71bSYork Sun ddr->ddr_sdram_mode_2 = (0 10025614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 10035614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 10045614e71bSYork Sun ); 10055614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 10065614e71bSYork Sun 10075614e71bSYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 10085614e71bSYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 10095614e71bSYork Sun if (popts->rtt_override) 10105614e71bSYork Sun rtt_wr = popts->rtt_wr_override_value; 10115614e71bSYork Sun else 10125614e71bSYork Sun rtt_wr = popts->cs_local_opts[i].odt_rtt_wr; 10135614e71bSYork Sun 10145614e71bSYork Sun esdmode2 &= 0xF9FF; /* clear bit 10, 9 */ 10155614e71bSYork Sun esdmode2 |= (rtt_wr & 0x3) << 9; 10165614e71bSYork Sun switch (i) { 10175614e71bSYork Sun case 1: 10185614e71bSYork Sun ddr->ddr_sdram_mode_4 = (0 10195614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 10205614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 10215614e71bSYork Sun ); 10225614e71bSYork Sun break; 10235614e71bSYork Sun case 2: 10245614e71bSYork Sun ddr->ddr_sdram_mode_6 = (0 10255614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 10265614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 10275614e71bSYork Sun ); 10285614e71bSYork Sun break; 10295614e71bSYork Sun case 3: 10305614e71bSYork Sun ddr->ddr_sdram_mode_8 = (0 10315614e71bSYork Sun | ((esdmode2 & 0xFFFF) << 16) 10325614e71bSYork Sun | ((esdmode3 & 0xFFFF) << 0) 10335614e71bSYork Sun ); 10345614e71bSYork Sun break; 10355614e71bSYork Sun } 10365614e71bSYork Sun } 10375614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", 10385614e71bSYork Sun ddr->ddr_sdram_mode_4); 10395614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", 10405614e71bSYork Sun ddr->ddr_sdram_mode_6); 10415614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", 10425614e71bSYork Sun ddr->ddr_sdram_mode_8); 10435614e71bSYork Sun } 10445614e71bSYork Sun } 104534e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 104634e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 104703e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, 104803e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 104934e026f9SYork Sun const memctl_options_t *popts, 105034e026f9SYork Sun const common_timing_params_t *common_dimm, 105134e026f9SYork Sun const unsigned int unq_mrs_en) 105234e026f9SYork Sun { 105334e026f9SYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 105434e026f9SYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 105534e026f9SYork Sun int i; 105634e026f9SYork Sun unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ 105734e026f9SYork Sun unsigned int srt = 0; /* self-refresh temerature, normal range */ 105834e026f9SYork Sun unsigned int asr = 0; /* auto self-refresh disable */ 105903e664d8SYork Sun unsigned int cwl = compute_cas_write_latency(ctrl_num) - 5; 106034e026f9SYork Sun unsigned int pasr = 0; /* partial array self refresh disable */ 106134e026f9SYork Sun 106234e026f9SYork Sun if (popts->rtt_override) 106334e026f9SYork Sun rtt_wr = popts->rtt_wr_override_value; 106434e026f9SYork Sun else 106534e026f9SYork Sun rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; 106634e026f9SYork Sun 106734e026f9SYork Sun if (common_dimm->extended_op_srt) 106834e026f9SYork Sun srt = common_dimm->extended_op_srt; 106934e026f9SYork Sun 107034e026f9SYork Sun esdmode2 = (0 107134e026f9SYork Sun | ((rtt_wr & 0x3) << 9) 107234e026f9SYork Sun | ((srt & 0x1) << 7) 107334e026f9SYork Sun | ((asr & 0x1) << 6) 107434e026f9SYork Sun | ((cwl & 0x7) << 3) 107534e026f9SYork Sun | ((pasr & 0x7) << 0)); 107634e026f9SYork Sun ddr->ddr_sdram_mode_2 = (0 107734e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 107834e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 107934e026f9SYork Sun ); 108034e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 108134e026f9SYork Sun 108234e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 108334e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 108434e026f9SYork Sun if (popts->rtt_override) 108534e026f9SYork Sun rtt_wr = popts->rtt_wr_override_value; 108634e026f9SYork Sun else 108734e026f9SYork Sun rtt_wr = popts->cs_local_opts[i].odt_rtt_wr; 108834e026f9SYork Sun 108934e026f9SYork Sun esdmode2 &= 0xF9FF; /* clear bit 10, 9 */ 109034e026f9SYork Sun esdmode2 |= (rtt_wr & 0x3) << 9; 109134e026f9SYork Sun switch (i) { 109234e026f9SYork Sun case 1: 109334e026f9SYork Sun ddr->ddr_sdram_mode_4 = (0 109434e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 109534e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 109634e026f9SYork Sun ); 109734e026f9SYork Sun break; 109834e026f9SYork Sun case 2: 109934e026f9SYork Sun ddr->ddr_sdram_mode_6 = (0 110034e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 110134e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 110234e026f9SYork Sun ); 110334e026f9SYork Sun break; 110434e026f9SYork Sun case 3: 110534e026f9SYork Sun ddr->ddr_sdram_mode_8 = (0 110634e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 110734e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 110834e026f9SYork Sun ); 110934e026f9SYork Sun break; 111034e026f9SYork Sun } 111134e026f9SYork Sun } 111234e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", 111334e026f9SYork Sun ddr->ddr_sdram_mode_4); 111434e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", 111534e026f9SYork Sun ddr->ddr_sdram_mode_6); 111634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", 111734e026f9SYork Sun ddr->ddr_sdram_mode_8); 111834e026f9SYork Sun } 111934e026f9SYork Sun } 112034e026f9SYork Sun 112134e026f9SYork Sun #else /* for DDR2 and DDR1 */ 112234e026f9SYork Sun /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ 112303e664d8SYork Sun static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, 112403e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 112534e026f9SYork Sun const memctl_options_t *popts, 112634e026f9SYork Sun const common_timing_params_t *common_dimm, 112734e026f9SYork Sun const unsigned int unq_mrs_en) 112834e026f9SYork Sun { 112934e026f9SYork Sun unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ 113034e026f9SYork Sun unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ 113134e026f9SYork Sun 113234e026f9SYork Sun ddr->ddr_sdram_mode_2 = (0 113334e026f9SYork Sun | ((esdmode2 & 0xFFFF) << 16) 113434e026f9SYork Sun | ((esdmode3 & 0xFFFF) << 0) 113534e026f9SYork Sun ); 113634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); 113734e026f9SYork Sun } 113834e026f9SYork Sun #endif 113934e026f9SYork Sun 114034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 114134e026f9SYork Sun /* DDR SDRAM Mode configuration 9 (DDR_SDRAM_MODE_9) */ 114234e026f9SYork Sun static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, 114334e026f9SYork Sun const memctl_options_t *popts, 114434e026f9SYork Sun const common_timing_params_t *common_dimm, 114534e026f9SYork Sun const unsigned int unq_mrs_en) 114634e026f9SYork Sun { 114734e026f9SYork Sun int i; 114834e026f9SYork Sun unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */ 114934e026f9SYork Sun unsigned short esdmode5; /* Extended SDRAM mode 5 */ 11506b95be22SYork Sun int rtt_park = 0; 11518a51429eSYork Sun bool four_cs = false; 1152eb118807SShengzhou Liu const unsigned int mclk_ps = get_memory_clk_period_ps(0); 115334e026f9SYork Sun 11548a51429eSYork Sun #if CONFIG_CHIP_SELECTS_PER_CTRL == 4 11558a51429eSYork Sun if ((ddr->cs[0].config & SDRAM_CS_CONFIG_EN) && 11568a51429eSYork Sun (ddr->cs[1].config & SDRAM_CS_CONFIG_EN) && 11578a51429eSYork Sun (ddr->cs[2].config & SDRAM_CS_CONFIG_EN) && 11588a51429eSYork Sun (ddr->cs[3].config & SDRAM_CS_CONFIG_EN)) 11598a51429eSYork Sun four_cs = true; 11608a51429eSYork Sun #endif 11616b95be22SYork Sun if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) { 11626b95be22SYork Sun esdmode5 = 0x00000500; /* Data mask enable, RTT_PARK CS0 */ 11638a51429eSYork Sun rtt_park = four_cs ? 0 : 1; 11646b95be22SYork Sun } else { 11656b95be22SYork Sun esdmode5 = 0x00000400; /* Data mask enabled */ 11666b95be22SYork Sun } 116734e026f9SYork Sun 1168426230a6SYork Sun /* 1169426230a6SYork Sun * For DDR3, set C/A latency if address parity is enabled. 1170426230a6SYork Sun * For DDR4, set C/A latency for UDIMM only. For RDIMM the delay is 1171426230a6SYork Sun * handled by register chip and RCW settings. 1172426230a6SYork Sun */ 1173426230a6SYork Sun if ((ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) && 1174426230a6SYork Sun ((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) || 1175426230a6SYork Sun !popts->registered_dimm_en)) { 1176eb118807SShengzhou Liu if (mclk_ps >= 935) { 1177eb118807SShengzhou Liu /* for DDR4-1600/1866/2133 */ 1178eb118807SShengzhou Liu esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK; 1179eb118807SShengzhou Liu } else if (mclk_ps >= 833) { 1180eb118807SShengzhou Liu /* for DDR4-2400 */ 1181eb118807SShengzhou Liu esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK; 1182eb118807SShengzhou Liu } else { 1183eb118807SShengzhou Liu printf("parity: mclk_ps = %d not supported\n", mclk_ps); 1184eb118807SShengzhou Liu } 1185eb118807SShengzhou Liu } 1186eb118807SShengzhou Liu 118734e026f9SYork Sun ddr->ddr_sdram_mode_9 = (0 118834e026f9SYork Sun | ((esdmode4 & 0xffff) << 16) 118934e026f9SYork Sun | ((esdmode5 & 0xffff) << 0) 119034e026f9SYork Sun ); 119166869f95SYork Sun 11928a51429eSYork Sun /* Normally only the first enabled CS use 0x500, others use 0x400 11938a51429eSYork Sun * But when four chip-selects are all enabled, all mode registers 11948a51429eSYork Sun * need 0x500 to park. 11958a51429eSYork Sun */ 119666869f95SYork Sun 1197*c0c32af0SYork Sun debug("FSLDDR: ddr_sdram_mode_9 = 0x%08x\n", ddr->ddr_sdram_mode_9); 119834e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 119934e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 12006b95be22SYork Sun if (!rtt_park && 12016b95be22SYork Sun (ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) { 12026b95be22SYork Sun esdmode5 |= 0x00000500; /* RTT_PARK */ 12038a51429eSYork Sun rtt_park = four_cs ? 0 : 1; 12046b95be22SYork Sun } else { 12056b95be22SYork Sun esdmode5 = 0x00000400; 12066b95be22SYork Sun } 1207eb118807SShengzhou Liu 1208426230a6SYork Sun if ((ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) && 1209426230a6SYork Sun ((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) || 1210426230a6SYork Sun !popts->registered_dimm_en)) { 1211eb118807SShengzhou Liu if (mclk_ps >= 935) { 1212eb118807SShengzhou Liu /* for DDR4-1600/1866/2133 */ 1213eb118807SShengzhou Liu esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK; 1214eb118807SShengzhou Liu } else if (mclk_ps >= 833) { 1215eb118807SShengzhou Liu /* for DDR4-2400 */ 1216eb118807SShengzhou Liu esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK; 1217eb118807SShengzhou Liu } else { 1218eb118807SShengzhou Liu printf("parity: mclk_ps = %d not supported\n", 1219eb118807SShengzhou Liu mclk_ps); 1220eb118807SShengzhou Liu } 1221eb118807SShengzhou Liu } 1222eb118807SShengzhou Liu 122334e026f9SYork Sun switch (i) { 122434e026f9SYork Sun case 1: 122534e026f9SYork Sun ddr->ddr_sdram_mode_11 = (0 122634e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 122734e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 122834e026f9SYork Sun ); 122934e026f9SYork Sun break; 123034e026f9SYork Sun case 2: 123134e026f9SYork Sun ddr->ddr_sdram_mode_13 = (0 123234e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 123334e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 123434e026f9SYork Sun ); 123534e026f9SYork Sun break; 123634e026f9SYork Sun case 3: 123734e026f9SYork Sun ddr->ddr_sdram_mode_15 = (0 123834e026f9SYork Sun | ((esdmode4 & 0xFFFF) << 16) 123934e026f9SYork Sun | ((esdmode5 & 0xFFFF) << 0) 124034e026f9SYork Sun ); 124134e026f9SYork Sun break; 124234e026f9SYork Sun } 124334e026f9SYork Sun } 124434e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_11 = 0x%08x\n", 124534e026f9SYork Sun ddr->ddr_sdram_mode_11); 124634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_13 = 0x%08x\n", 124734e026f9SYork Sun ddr->ddr_sdram_mode_13); 124834e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_15 = 0x%08x\n", 124934e026f9SYork Sun ddr->ddr_sdram_mode_15); 125034e026f9SYork Sun } 125134e026f9SYork Sun } 125234e026f9SYork Sun 125334e026f9SYork Sun /* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */ 125403e664d8SYork Sun static void set_ddr_sdram_mode_10(const unsigned int ctrl_num, 125503e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 125634e026f9SYork Sun const memctl_options_t *popts, 125734e026f9SYork Sun const common_timing_params_t *common_dimm, 125834e026f9SYork Sun const unsigned int unq_mrs_en) 125934e026f9SYork Sun { 126034e026f9SYork Sun int i; 126134e026f9SYork Sun unsigned short esdmode6 = 0; /* Extended SDRAM mode 6 */ 126234e026f9SYork Sun unsigned short esdmode7 = 0; /* Extended SDRAM mode 7 */ 126303e664d8SYork Sun unsigned int tccdl_min = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); 126434e026f9SYork Sun 126534e026f9SYork Sun esdmode6 = ((tccdl_min - 4) & 0x7) << 10; 126634e026f9SYork Sun 12670fb71974SYork Sun if (popts->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2) 12680fb71974SYork Sun esdmode6 |= 1 << 6; /* Range 2 */ 12690fb71974SYork Sun 127034e026f9SYork Sun ddr->ddr_sdram_mode_10 = (0 127134e026f9SYork Sun | ((esdmode6 & 0xffff) << 16) 127234e026f9SYork Sun | ((esdmode7 & 0xffff) << 0) 127334e026f9SYork Sun ); 1274*c0c32af0SYork Sun debug("FSLDDR: ddr_sdram_mode_10 = 0x%08x\n", ddr->ddr_sdram_mode_10); 127534e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 127634e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 127734e026f9SYork Sun switch (i) { 127834e026f9SYork Sun case 1: 127934e026f9SYork Sun ddr->ddr_sdram_mode_12 = (0 128034e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 128134e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 128234e026f9SYork Sun ); 128334e026f9SYork Sun break; 128434e026f9SYork Sun case 2: 128534e026f9SYork Sun ddr->ddr_sdram_mode_14 = (0 128634e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 128734e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 128834e026f9SYork Sun ); 128934e026f9SYork Sun break; 129034e026f9SYork Sun case 3: 129134e026f9SYork Sun ddr->ddr_sdram_mode_16 = (0 129234e026f9SYork Sun | ((esdmode6 & 0xFFFF) << 16) 129334e026f9SYork Sun | ((esdmode7 & 0xFFFF) << 0) 129434e026f9SYork Sun ); 129534e026f9SYork Sun break; 129634e026f9SYork Sun } 129734e026f9SYork Sun } 129834e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_12 = 0x%08x\n", 129934e026f9SYork Sun ddr->ddr_sdram_mode_12); 130034e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_14 = 0x%08x\n", 130134e026f9SYork Sun ddr->ddr_sdram_mode_14); 130234e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_16 = 0x%08x\n", 130334e026f9SYork Sun ddr->ddr_sdram_mode_16); 130434e026f9SYork Sun } 130534e026f9SYork Sun } 130634e026f9SYork Sun 130734e026f9SYork Sun #endif 13085614e71bSYork Sun 13095614e71bSYork Sun /* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */ 131003e664d8SYork Sun static void set_ddr_sdram_interval(const unsigned int ctrl_num, 131103e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 13125614e71bSYork Sun const memctl_options_t *popts, 13135614e71bSYork Sun const common_timing_params_t *common_dimm) 13145614e71bSYork Sun { 13155614e71bSYork Sun unsigned int refint; /* Refresh interval */ 13165614e71bSYork Sun unsigned int bstopre; /* Precharge interval */ 13175614e71bSYork Sun 131803e664d8SYork Sun refint = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps); 13195614e71bSYork Sun 13205614e71bSYork Sun bstopre = popts->bstopre; 13215614e71bSYork Sun 13225614e71bSYork Sun /* refint field used 0x3FFF in earlier controllers */ 13235614e71bSYork Sun ddr->ddr_sdram_interval = (0 13245614e71bSYork Sun | ((refint & 0xFFFF) << 16) 13255614e71bSYork Sun | ((bstopre & 0x3FFF) << 0) 13265614e71bSYork Sun ); 13275614e71bSYork Sun debug("FSLDDR: ddr_sdram_interval = 0x%08x\n", ddr->ddr_sdram_interval); 13285614e71bSYork Sun } 13295614e71bSYork Sun 133034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 13315614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 133203e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num, 133303e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 13345614e71bSYork Sun const memctl_options_t *popts, 13355614e71bSYork Sun const common_timing_params_t *common_dimm, 13365614e71bSYork Sun unsigned int cas_latency, 13375614e71bSYork Sun unsigned int additive_latency, 13385614e71bSYork Sun const unsigned int unq_mrs_en) 13395614e71bSYork Sun { 134034e026f9SYork Sun int i; 134134e026f9SYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 134234e026f9SYork Sun unsigned short sdmode; /* SDRAM mode */ 134334e026f9SYork Sun 134434e026f9SYork Sun /* Mode Register - MR1 */ 134534e026f9SYork Sun unsigned int qoff = 0; /* Output buffer enable 0=yes, 1=no */ 134634e026f9SYork Sun unsigned int tdqs_en = 0; /* TDQS Enable: 0=no, 1=yes */ 134734e026f9SYork Sun unsigned int rtt; 134834e026f9SYork Sun unsigned int wrlvl_en = 0; /* Write level enable: 0=no, 1=yes */ 134934e026f9SYork Sun unsigned int al = 0; /* Posted CAS# additive latency (AL) */ 135034e026f9SYork Sun unsigned int dic = 0; /* Output driver impedance, 40ohm */ 135134e026f9SYork Sun unsigned int dll_en = 1; /* DLL Enable 1=Enable (Normal), 135234e026f9SYork Sun 0=Disable (Test/Debug) */ 135334e026f9SYork Sun 135434e026f9SYork Sun /* Mode Register - MR0 */ 135534e026f9SYork Sun unsigned int wr = 0; /* Write Recovery */ 135634e026f9SYork Sun unsigned int dll_rst; /* DLL Reset */ 135734e026f9SYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 135834e026f9SYork Sun unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ 135934e026f9SYork Sun /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ 136034e026f9SYork Sun unsigned int bt; 136134e026f9SYork Sun unsigned int bl; /* BL: Burst Length */ 136234e026f9SYork Sun 136334e026f9SYork Sun unsigned int wr_mclk; 136434e026f9SYork Sun /* DDR4 support WR 10, 12, 14, 16, 18, 20, 24 */ 136534e026f9SYork Sun static const u8 wr_table[] = { 136634e026f9SYork Sun 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6}; 136734e026f9SYork Sun /* DDR4 support CAS 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24 */ 136834e026f9SYork Sun static const u8 cas_latency_table[] = { 136934e026f9SYork Sun 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 137034e026f9SYork Sun 9, 9, 10, 10, 11, 11}; 137134e026f9SYork Sun 137234e026f9SYork Sun if (popts->rtt_override) 137334e026f9SYork Sun rtt = popts->rtt_override_value; 137434e026f9SYork Sun else 137534e026f9SYork Sun rtt = popts->cs_local_opts[0].odt_rtt_norm; 137634e026f9SYork Sun 137734e026f9SYork Sun if (additive_latency == (cas_latency - 1)) 137834e026f9SYork Sun al = 1; 137934e026f9SYork Sun if (additive_latency == (cas_latency - 2)) 138034e026f9SYork Sun al = 2; 138134e026f9SYork Sun 138234e026f9SYork Sun if (popts->quad_rank_present) 138334e026f9SYork Sun dic = 1; /* output driver impedance 240/7 ohm */ 138434e026f9SYork Sun 138534e026f9SYork Sun /* 138634e026f9SYork Sun * The esdmode value will also be used for writing 138734e026f9SYork Sun * MR1 during write leveling for DDR3, although the 138834e026f9SYork Sun * bits specifically related to the write leveling 138934e026f9SYork Sun * scheme will be handled automatically by the DDR 139034e026f9SYork Sun * controller. so we set the wrlvl_en = 0 here. 139134e026f9SYork Sun */ 139234e026f9SYork Sun esdmode = (0 139334e026f9SYork Sun | ((qoff & 0x1) << 12) 139434e026f9SYork Sun | ((tdqs_en & 0x1) << 11) 139534e026f9SYork Sun | ((rtt & 0x7) << 8) 139634e026f9SYork Sun | ((wrlvl_en & 0x1) << 7) 139734e026f9SYork Sun | ((al & 0x3) << 3) 139834e026f9SYork Sun | ((dic & 0x3) << 1) /* DIC field is split */ 139934e026f9SYork Sun | ((dll_en & 0x1) << 0) 140034e026f9SYork Sun ); 140134e026f9SYork Sun 140234e026f9SYork Sun /* 140334e026f9SYork Sun * DLL control for precharge PD 140434e026f9SYork Sun * 0=slow exit DLL off (tXPDLL) 140534e026f9SYork Sun * 1=fast exit DLL on (tXP) 140634e026f9SYork Sun */ 140734e026f9SYork Sun 140803e664d8SYork Sun wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 140934e026f9SYork Sun if (wr_mclk <= 24) { 141034e026f9SYork Sun wr = wr_table[wr_mclk - 10]; 141134e026f9SYork Sun } else { 141234e026f9SYork Sun printf("Error: unsupported write recovery for mode register wr_mclk = %d\n", 141334e026f9SYork Sun wr_mclk); 141434e026f9SYork Sun } 141534e026f9SYork Sun 141634e026f9SYork Sun dll_rst = 0; /* dll no reset */ 141734e026f9SYork Sun mode = 0; /* normal mode */ 141834e026f9SYork Sun 141934e026f9SYork Sun /* look up table to get the cas latency bits */ 142034e026f9SYork Sun if (cas_latency >= 9 && cas_latency <= 24) 142134e026f9SYork Sun caslat = cas_latency_table[cas_latency - 9]; 142234e026f9SYork Sun else 142334e026f9SYork Sun printf("Error: unsupported cas latency for mode register\n"); 142434e026f9SYork Sun 142534e026f9SYork Sun bt = 0; /* Nibble sequential */ 142634e026f9SYork Sun 142734e026f9SYork Sun switch (popts->burst_length) { 142834e026f9SYork Sun case DDR_BL8: 142934e026f9SYork Sun bl = 0; 143034e026f9SYork Sun break; 143134e026f9SYork Sun case DDR_OTF: 143234e026f9SYork Sun bl = 1; 143334e026f9SYork Sun break; 143434e026f9SYork Sun case DDR_BC4: 143534e026f9SYork Sun bl = 2; 143634e026f9SYork Sun break; 143734e026f9SYork Sun default: 143834e026f9SYork Sun printf("Error: invalid burst length of %u specified. ", 143934e026f9SYork Sun popts->burst_length); 144034e026f9SYork Sun puts("Defaulting to on-the-fly BC4 or BL8 beats.\n"); 144134e026f9SYork Sun bl = 1; 144234e026f9SYork Sun break; 144334e026f9SYork Sun } 144434e026f9SYork Sun 144534e026f9SYork Sun sdmode = (0 144634e026f9SYork Sun | ((wr & 0x7) << 9) 144734e026f9SYork Sun | ((dll_rst & 0x1) << 8) 144834e026f9SYork Sun | ((mode & 0x1) << 7) 144934e026f9SYork Sun | (((caslat >> 1) & 0x7) << 4) 145034e026f9SYork Sun | ((bt & 0x1) << 3) 145134e026f9SYork Sun | ((caslat & 1) << 2) 145234e026f9SYork Sun | ((bl & 0x3) << 0) 145334e026f9SYork Sun ); 145434e026f9SYork Sun 145534e026f9SYork Sun ddr->ddr_sdram_mode = (0 145634e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 145734e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 145834e026f9SYork Sun ); 145934e026f9SYork Sun 146034e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 146134e026f9SYork Sun 146234e026f9SYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 146334e026f9SYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 146434e026f9SYork Sun if (popts->rtt_override) 146534e026f9SYork Sun rtt = popts->rtt_override_value; 146634e026f9SYork Sun else 146734e026f9SYork Sun rtt = popts->cs_local_opts[i].odt_rtt_norm; 146834e026f9SYork Sun 146934e026f9SYork Sun esdmode &= 0xF8FF; /* clear bit 10,9,8 for rtt */ 147034e026f9SYork Sun esdmode |= (rtt & 0x7) << 8; 147134e026f9SYork Sun switch (i) { 147234e026f9SYork Sun case 1: 147334e026f9SYork Sun ddr->ddr_sdram_mode_3 = (0 147434e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 147534e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 147634e026f9SYork Sun ); 147734e026f9SYork Sun break; 147834e026f9SYork Sun case 2: 147934e026f9SYork Sun ddr->ddr_sdram_mode_5 = (0 148034e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 148134e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 148234e026f9SYork Sun ); 148334e026f9SYork Sun break; 148434e026f9SYork Sun case 3: 148534e026f9SYork Sun ddr->ddr_sdram_mode_7 = (0 148634e026f9SYork Sun | ((esdmode & 0xFFFF) << 16) 148734e026f9SYork Sun | ((sdmode & 0xFFFF) << 0) 148834e026f9SYork Sun ); 148934e026f9SYork Sun break; 149034e026f9SYork Sun } 149134e026f9SYork Sun } 149234e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", 149334e026f9SYork Sun ddr->ddr_sdram_mode_3); 149434e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 149534e026f9SYork Sun ddr->ddr_sdram_mode_5); 149634e026f9SYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 149734e026f9SYork Sun ddr->ddr_sdram_mode_5); 149834e026f9SYork Sun } 149934e026f9SYork Sun } 150034e026f9SYork Sun 150134e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 150234e026f9SYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 150303e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num, 150403e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 150534e026f9SYork Sun const memctl_options_t *popts, 150634e026f9SYork Sun const common_timing_params_t *common_dimm, 150734e026f9SYork Sun unsigned int cas_latency, 150834e026f9SYork Sun unsigned int additive_latency, 150934e026f9SYork Sun const unsigned int unq_mrs_en) 151034e026f9SYork Sun { 151134e026f9SYork Sun int i; 15125614e71bSYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 15135614e71bSYork Sun unsigned short sdmode; /* SDRAM mode */ 15145614e71bSYork Sun 15155614e71bSYork Sun /* Mode Register - MR1 */ 15165614e71bSYork Sun unsigned int qoff = 0; /* Output buffer enable 0=yes, 1=no */ 15175614e71bSYork Sun unsigned int tdqs_en = 0; /* TDQS Enable: 0=no, 1=yes */ 15185614e71bSYork Sun unsigned int rtt; 15195614e71bSYork Sun unsigned int wrlvl_en = 0; /* Write level enable: 0=no, 1=yes */ 15205614e71bSYork Sun unsigned int al = 0; /* Posted CAS# additive latency (AL) */ 15215614e71bSYork Sun unsigned int dic = 0; /* Output driver impedance, 40ohm */ 15225614e71bSYork Sun unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), 15235614e71bSYork Sun 1=Disable (Test/Debug) */ 15245614e71bSYork Sun 15255614e71bSYork Sun /* Mode Register - MR0 */ 15265614e71bSYork Sun unsigned int dll_on; /* DLL control for precharge PD, 0=off, 1=on */ 15275614e71bSYork Sun unsigned int wr = 0; /* Write Recovery */ 15285614e71bSYork Sun unsigned int dll_rst; /* DLL Reset */ 15295614e71bSYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 15305614e71bSYork Sun unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ 15315614e71bSYork Sun /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ 15325614e71bSYork Sun unsigned int bt; 15335614e71bSYork Sun unsigned int bl; /* BL: Burst Length */ 15345614e71bSYork Sun 15355614e71bSYork Sun unsigned int wr_mclk; 15365614e71bSYork Sun /* 15375614e71bSYork Sun * DDR_SDRAM_MODE doesn't support 9,11,13,15 15385614e71bSYork Sun * Please refer JEDEC Standard No. 79-3E for Mode Register MR0 15395614e71bSYork Sun * for this table 15405614e71bSYork Sun */ 15415614e71bSYork Sun static const u8 wr_table[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0}; 15425614e71bSYork Sun 15435614e71bSYork Sun if (popts->rtt_override) 15445614e71bSYork Sun rtt = popts->rtt_override_value; 15455614e71bSYork Sun else 15465614e71bSYork Sun rtt = popts->cs_local_opts[0].odt_rtt_norm; 15475614e71bSYork Sun 15485614e71bSYork Sun if (additive_latency == (cas_latency - 1)) 15495614e71bSYork Sun al = 1; 15505614e71bSYork Sun if (additive_latency == (cas_latency - 2)) 15515614e71bSYork Sun al = 2; 15525614e71bSYork Sun 15535614e71bSYork Sun if (popts->quad_rank_present) 15545614e71bSYork Sun dic = 1; /* output driver impedance 240/7 ohm */ 15555614e71bSYork Sun 15565614e71bSYork Sun /* 15575614e71bSYork Sun * The esdmode value will also be used for writing 15585614e71bSYork Sun * MR1 during write leveling for DDR3, although the 15595614e71bSYork Sun * bits specifically related to the write leveling 15605614e71bSYork Sun * scheme will be handled automatically by the DDR 15615614e71bSYork Sun * controller. so we set the wrlvl_en = 0 here. 15625614e71bSYork Sun */ 15635614e71bSYork Sun esdmode = (0 15645614e71bSYork Sun | ((qoff & 0x1) << 12) 15655614e71bSYork Sun | ((tdqs_en & 0x1) << 11) 15665614e71bSYork Sun | ((rtt & 0x4) << 7) /* rtt field is split */ 15675614e71bSYork Sun | ((wrlvl_en & 0x1) << 7) 15685614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 15695614e71bSYork Sun | ((dic & 0x2) << 4) /* DIC field is split */ 15705614e71bSYork Sun | ((al & 0x3) << 3) 15715614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 15725614e71bSYork Sun | ((dic & 0x1) << 1) /* DIC field is split */ 15735614e71bSYork Sun | ((dll_en & 0x1) << 0) 15745614e71bSYork Sun ); 15755614e71bSYork Sun 15765614e71bSYork Sun /* 15775614e71bSYork Sun * DLL control for precharge PD 15785614e71bSYork Sun * 0=slow exit DLL off (tXPDLL) 15795614e71bSYork Sun * 1=fast exit DLL on (tXP) 15805614e71bSYork Sun */ 15815614e71bSYork Sun dll_on = 1; 15825614e71bSYork Sun 158303e664d8SYork Sun wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 15845614e71bSYork Sun if (wr_mclk <= 16) { 15855614e71bSYork Sun wr = wr_table[wr_mclk - 5]; 15865614e71bSYork Sun } else { 15875614e71bSYork Sun printf("Error: unsupported write recovery for mode register " 15885614e71bSYork Sun "wr_mclk = %d\n", wr_mclk); 15895614e71bSYork Sun } 15905614e71bSYork Sun 15915614e71bSYork Sun dll_rst = 0; /* dll no reset */ 15925614e71bSYork Sun mode = 0; /* normal mode */ 15935614e71bSYork Sun 15945614e71bSYork Sun /* look up table to get the cas latency bits */ 15955614e71bSYork Sun if (cas_latency >= 5 && cas_latency <= 16) { 15965614e71bSYork Sun unsigned char cas_latency_table[] = { 15975614e71bSYork Sun 0x2, /* 5 clocks */ 15985614e71bSYork Sun 0x4, /* 6 clocks */ 15995614e71bSYork Sun 0x6, /* 7 clocks */ 16005614e71bSYork Sun 0x8, /* 8 clocks */ 16015614e71bSYork Sun 0xa, /* 9 clocks */ 16025614e71bSYork Sun 0xc, /* 10 clocks */ 16035614e71bSYork Sun 0xe, /* 11 clocks */ 16045614e71bSYork Sun 0x1, /* 12 clocks */ 16055614e71bSYork Sun 0x3, /* 13 clocks */ 16065614e71bSYork Sun 0x5, /* 14 clocks */ 16075614e71bSYork Sun 0x7, /* 15 clocks */ 16085614e71bSYork Sun 0x9, /* 16 clocks */ 16095614e71bSYork Sun }; 16105614e71bSYork Sun caslat = cas_latency_table[cas_latency - 5]; 16115614e71bSYork Sun } else { 16125614e71bSYork Sun printf("Error: unsupported cas latency for mode register\n"); 16135614e71bSYork Sun } 16145614e71bSYork Sun 16155614e71bSYork Sun bt = 0; /* Nibble sequential */ 16165614e71bSYork Sun 16175614e71bSYork Sun switch (popts->burst_length) { 16185614e71bSYork Sun case DDR_BL8: 16195614e71bSYork Sun bl = 0; 16205614e71bSYork Sun break; 16215614e71bSYork Sun case DDR_OTF: 16225614e71bSYork Sun bl = 1; 16235614e71bSYork Sun break; 16245614e71bSYork Sun case DDR_BC4: 16255614e71bSYork Sun bl = 2; 16265614e71bSYork Sun break; 16275614e71bSYork Sun default: 16285614e71bSYork Sun printf("Error: invalid burst length of %u specified. " 16295614e71bSYork Sun " Defaulting to on-the-fly BC4 or BL8 beats.\n", 16305614e71bSYork Sun popts->burst_length); 16315614e71bSYork Sun bl = 1; 16325614e71bSYork Sun break; 16335614e71bSYork Sun } 16345614e71bSYork Sun 16355614e71bSYork Sun sdmode = (0 16365614e71bSYork Sun | ((dll_on & 0x1) << 12) 16375614e71bSYork Sun | ((wr & 0x7) << 9) 16385614e71bSYork Sun | ((dll_rst & 0x1) << 8) 16395614e71bSYork Sun | ((mode & 0x1) << 7) 16405614e71bSYork Sun | (((caslat >> 1) & 0x7) << 4) 16415614e71bSYork Sun | ((bt & 0x1) << 3) 16425614e71bSYork Sun | ((caslat & 1) << 2) 16435614e71bSYork Sun | ((bl & 0x3) << 0) 16445614e71bSYork Sun ); 16455614e71bSYork Sun 16465614e71bSYork Sun ddr->ddr_sdram_mode = (0 16475614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16485614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16495614e71bSYork Sun ); 16505614e71bSYork Sun 16515614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 16525614e71bSYork Sun 16535614e71bSYork Sun if (unq_mrs_en) { /* unique mode registers are supported */ 16545614e71bSYork Sun for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 16555614e71bSYork Sun if (popts->rtt_override) 16565614e71bSYork Sun rtt = popts->rtt_override_value; 16575614e71bSYork Sun else 16585614e71bSYork Sun rtt = popts->cs_local_opts[i].odt_rtt_norm; 16595614e71bSYork Sun 16605614e71bSYork Sun esdmode &= 0xFDBB; /* clear bit 9,6,2 */ 16615614e71bSYork Sun esdmode |= (0 16625614e71bSYork Sun | ((rtt & 0x4) << 7) /* rtt field is split */ 16635614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 16645614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 16655614e71bSYork Sun ); 16665614e71bSYork Sun switch (i) { 16675614e71bSYork Sun case 1: 16685614e71bSYork Sun ddr->ddr_sdram_mode_3 = (0 16695614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16705614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16715614e71bSYork Sun ); 16725614e71bSYork Sun break; 16735614e71bSYork Sun case 2: 16745614e71bSYork Sun ddr->ddr_sdram_mode_5 = (0 16755614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16765614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16775614e71bSYork Sun ); 16785614e71bSYork Sun break; 16795614e71bSYork Sun case 3: 16805614e71bSYork Sun ddr->ddr_sdram_mode_7 = (0 16815614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 16825614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 16835614e71bSYork Sun ); 16845614e71bSYork Sun break; 16855614e71bSYork Sun } 16865614e71bSYork Sun } 16875614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", 16885614e71bSYork Sun ddr->ddr_sdram_mode_3); 16895614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 16905614e71bSYork Sun ddr->ddr_sdram_mode_5); 16915614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", 16925614e71bSYork Sun ddr->ddr_sdram_mode_5); 16935614e71bSYork Sun } 16945614e71bSYork Sun } 16955614e71bSYork Sun 16965614e71bSYork Sun #else /* !CONFIG_SYS_FSL_DDR3 */ 16975614e71bSYork Sun 16985614e71bSYork Sun /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ 169903e664d8SYork Sun static void set_ddr_sdram_mode(const unsigned int ctrl_num, 170003e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 17015614e71bSYork Sun const memctl_options_t *popts, 17025614e71bSYork Sun const common_timing_params_t *common_dimm, 17035614e71bSYork Sun unsigned int cas_latency, 17045614e71bSYork Sun unsigned int additive_latency, 17055614e71bSYork Sun const unsigned int unq_mrs_en) 17065614e71bSYork Sun { 17075614e71bSYork Sun unsigned short esdmode; /* Extended SDRAM mode */ 17085614e71bSYork Sun unsigned short sdmode; /* SDRAM mode */ 17095614e71bSYork Sun 17105614e71bSYork Sun /* 17115614e71bSYork Sun * FIXME: This ought to be pre-calculated in a 17125614e71bSYork Sun * technology-specific routine, 17135614e71bSYork Sun * e.g. compute_DDR2_mode_register(), and then the 17145614e71bSYork Sun * sdmode and esdmode passed in as part of common_dimm. 17155614e71bSYork Sun */ 17165614e71bSYork Sun 17175614e71bSYork Sun /* Extended Mode Register */ 17185614e71bSYork Sun unsigned int mrs = 0; /* Mode Register Set */ 17195614e71bSYork Sun unsigned int outputs = 0; /* 0=Enabled, 1=Disabled */ 17205614e71bSYork Sun unsigned int rdqs_en = 0; /* RDQS Enable: 0=no, 1=yes */ 17215614e71bSYork Sun unsigned int dqs_en = 0; /* DQS# Enable: 0=enable, 1=disable */ 17225614e71bSYork Sun unsigned int ocd = 0; /* 0x0=OCD not supported, 17235614e71bSYork Sun 0x7=OCD default state */ 17245614e71bSYork Sun unsigned int rtt; 17255614e71bSYork Sun unsigned int al; /* Posted CAS# additive latency (AL) */ 17265614e71bSYork Sun unsigned int ods = 0; /* Output Drive Strength: 17275614e71bSYork Sun 0 = Full strength (18ohm) 17285614e71bSYork Sun 1 = Reduced strength (4ohm) */ 17295614e71bSYork Sun unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), 17305614e71bSYork Sun 1=Disable (Test/Debug) */ 17315614e71bSYork Sun 17325614e71bSYork Sun /* Mode Register (MR) */ 17335614e71bSYork Sun unsigned int mr; /* Mode Register Definition */ 17345614e71bSYork Sun unsigned int pd; /* Power-Down Mode */ 17355614e71bSYork Sun unsigned int wr; /* Write Recovery */ 17365614e71bSYork Sun unsigned int dll_res; /* DLL Reset */ 17375614e71bSYork Sun unsigned int mode; /* Normal=0 or Test=1 */ 17385614e71bSYork Sun unsigned int caslat = 0;/* CAS# latency */ 17395614e71bSYork Sun /* BT: Burst Type (0=Sequential, 1=Interleaved) */ 17405614e71bSYork Sun unsigned int bt; 17415614e71bSYork Sun unsigned int bl; /* BL: Burst Length */ 17425614e71bSYork Sun 17435614e71bSYork Sun dqs_en = !popts->dqs_config; 17445614e71bSYork Sun rtt = fsl_ddr_get_rtt(); 17455614e71bSYork Sun 17465614e71bSYork Sun al = additive_latency; 17475614e71bSYork Sun 17485614e71bSYork Sun esdmode = (0 17495614e71bSYork Sun | ((mrs & 0x3) << 14) 17505614e71bSYork Sun | ((outputs & 0x1) << 12) 17515614e71bSYork Sun | ((rdqs_en & 0x1) << 11) 17525614e71bSYork Sun | ((dqs_en & 0x1) << 10) 17535614e71bSYork Sun | ((ocd & 0x7) << 7) 17545614e71bSYork Sun | ((rtt & 0x2) << 5) /* rtt field is split */ 17555614e71bSYork Sun | ((al & 0x7) << 3) 17565614e71bSYork Sun | ((rtt & 0x1) << 2) /* rtt field is split */ 17575614e71bSYork Sun | ((ods & 0x1) << 1) 17585614e71bSYork Sun | ((dll_en & 0x1) << 0) 17595614e71bSYork Sun ); 17605614e71bSYork Sun 17615614e71bSYork Sun mr = 0; /* FIXME: CHECKME */ 17625614e71bSYork Sun 17635614e71bSYork Sun /* 17645614e71bSYork Sun * 0 = Fast Exit (Normal) 17655614e71bSYork Sun * 1 = Slow Exit (Low Power) 17665614e71bSYork Sun */ 17675614e71bSYork Sun pd = 0; 17685614e71bSYork Sun 17695614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 17705614e71bSYork Sun wr = 0; /* Historical */ 17715614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 177203e664d8SYork Sun wr = picos_to_mclk(ctrl_num, common_dimm->twr_ps); 17735614e71bSYork Sun #endif 17745614e71bSYork Sun dll_res = 0; 17755614e71bSYork Sun mode = 0; 17765614e71bSYork Sun 17775614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 17785614e71bSYork Sun if (1 <= cas_latency && cas_latency <= 4) { 17795614e71bSYork Sun unsigned char mode_caslat_table[4] = { 17805614e71bSYork Sun 0x5, /* 1.5 clocks */ 17815614e71bSYork Sun 0x2, /* 2.0 clocks */ 17825614e71bSYork Sun 0x6, /* 2.5 clocks */ 17835614e71bSYork Sun 0x3 /* 3.0 clocks */ 17845614e71bSYork Sun }; 17855614e71bSYork Sun caslat = mode_caslat_table[cas_latency - 1]; 17865614e71bSYork Sun } else { 17875614e71bSYork Sun printf("Warning: unknown cas_latency %d\n", cas_latency); 17885614e71bSYork Sun } 17895614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 17905614e71bSYork Sun caslat = cas_latency; 17915614e71bSYork Sun #endif 17925614e71bSYork Sun bt = 0; 17935614e71bSYork Sun 17945614e71bSYork Sun switch (popts->burst_length) { 17955614e71bSYork Sun case DDR_BL4: 17965614e71bSYork Sun bl = 2; 17975614e71bSYork Sun break; 17985614e71bSYork Sun case DDR_BL8: 17995614e71bSYork Sun bl = 3; 18005614e71bSYork Sun break; 18015614e71bSYork Sun default: 18025614e71bSYork Sun printf("Error: invalid burst length of %u specified. " 18035614e71bSYork Sun " Defaulting to 4 beats.\n", 18045614e71bSYork Sun popts->burst_length); 18055614e71bSYork Sun bl = 2; 18065614e71bSYork Sun break; 18075614e71bSYork Sun } 18085614e71bSYork Sun 18095614e71bSYork Sun sdmode = (0 18105614e71bSYork Sun | ((mr & 0x3) << 14) 18115614e71bSYork Sun | ((pd & 0x1) << 12) 18125614e71bSYork Sun | ((wr & 0x7) << 9) 18135614e71bSYork Sun | ((dll_res & 0x1) << 8) 18145614e71bSYork Sun | ((mode & 0x1) << 7) 18155614e71bSYork Sun | ((caslat & 0x7) << 4) 18165614e71bSYork Sun | ((bt & 0x1) << 3) 18175614e71bSYork Sun | ((bl & 0x7) << 0) 18185614e71bSYork Sun ); 18195614e71bSYork Sun 18205614e71bSYork Sun ddr->ddr_sdram_mode = (0 18215614e71bSYork Sun | ((esdmode & 0xFFFF) << 16) 18225614e71bSYork Sun | ((sdmode & 0xFFFF) << 0) 18235614e71bSYork Sun ); 18245614e71bSYork Sun debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); 18255614e71bSYork Sun } 18265614e71bSYork Sun #endif 18275614e71bSYork Sun 18285614e71bSYork Sun /* DDR SDRAM Data Initialization (DDR_DATA_INIT) */ 18295614e71bSYork Sun static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr) 18305614e71bSYork Sun { 18315614e71bSYork Sun unsigned int init_value; /* Initialization value */ 18325614e71bSYork Sun 18335614e71bSYork Sun #ifdef CONFIG_MEM_INIT_VALUE 18345614e71bSYork Sun init_value = CONFIG_MEM_INIT_VALUE; 18355614e71bSYork Sun #else 18365614e71bSYork Sun init_value = 0xDEADBEEF; 18375614e71bSYork Sun #endif 18385614e71bSYork Sun ddr->ddr_data_init = init_value; 18395614e71bSYork Sun } 18405614e71bSYork Sun 18415614e71bSYork Sun /* 18425614e71bSYork Sun * DDR SDRAM Clock Control (DDR_SDRAM_CLK_CNTL) 18435614e71bSYork Sun * The old controller on the 8540/60 doesn't have this register. 18445614e71bSYork Sun * Hope it's OK to set it (to 0) anyway. 18455614e71bSYork Sun */ 18465614e71bSYork Sun static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr, 18475614e71bSYork Sun const memctl_options_t *popts) 18485614e71bSYork Sun { 18495614e71bSYork Sun unsigned int clk_adjust; /* Clock adjust */ 1850d7c865bdSCurt Brune unsigned int ss_en = 0; /* Source synchronous enable */ 18515614e71bSYork Sun 18523c3d8ab5SYork Sun #if defined(CONFIG_ARCH_MPC8541) || defined(CONFIG_ARCH_MPC8555) 1853d7c865bdSCurt Brune /* Per FSL Application Note: AN2805 */ 1854d7c865bdSCurt Brune ss_en = 1; 1855d7c865bdSCurt Brune #endif 1856d8e5163aSShengzhou Liu if (fsl_ddr_get_version(0) >= 0x40701) { 1857d8e5163aSShengzhou Liu /* clk_adjust in 5-bits on T-series and LS-series */ 1858d8e5163aSShengzhou Liu clk_adjust = (popts->clk_adjust & 0x1F) << 22; 1859d8e5163aSShengzhou Liu } else { 1860d8e5163aSShengzhou Liu /* clk_adjust in 4-bits on earlier MPC85xx and P-series */ 1861d8e5163aSShengzhou Liu clk_adjust = (popts->clk_adjust & 0xF) << 23; 1862d8e5163aSShengzhou Liu } 1863d8e5163aSShengzhou Liu 1864d7c865bdSCurt Brune ddr->ddr_sdram_clk_cntl = (0 1865d7c865bdSCurt Brune | ((ss_en & 0x1) << 31) 1866d8e5163aSShengzhou Liu | clk_adjust 1867d7c865bdSCurt Brune ); 18685614e71bSYork Sun debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl); 18695614e71bSYork Sun } 18705614e71bSYork Sun 18715614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_ADDR) */ 18725614e71bSYork Sun static void set_ddr_init_addr(fsl_ddr_cfg_regs_t *ddr) 18735614e71bSYork Sun { 18745614e71bSYork Sun unsigned int init_addr = 0; /* Initialization address */ 18755614e71bSYork Sun 18765614e71bSYork Sun ddr->ddr_init_addr = init_addr; 18775614e71bSYork Sun } 18785614e71bSYork Sun 18795614e71bSYork Sun /* DDR Initialization Address (DDR_INIT_EXT_ADDR) */ 18805614e71bSYork Sun static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr) 18815614e71bSYork Sun { 18825614e71bSYork Sun unsigned int uia = 0; /* Use initialization address */ 18835614e71bSYork Sun unsigned int init_ext_addr = 0; /* Initialization address */ 18845614e71bSYork Sun 18855614e71bSYork Sun ddr->ddr_init_ext_addr = (0 18865614e71bSYork Sun | ((uia & 0x1) << 31) 18875614e71bSYork Sun | (init_ext_addr & 0xF) 18885614e71bSYork Sun ); 18895614e71bSYork Sun } 18905614e71bSYork Sun 18915614e71bSYork Sun /* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */ 18925614e71bSYork Sun static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr, 18935614e71bSYork Sun const memctl_options_t *popts) 18945614e71bSYork Sun { 18955614e71bSYork Sun unsigned int rwt = 0; /* Read-to-write turnaround for same CS */ 18965614e71bSYork Sun unsigned int wrt = 0; /* Write-to-read turnaround for same CS */ 18975614e71bSYork Sun unsigned int rrt = 0; /* Read-to-read turnaround for same CS */ 18985614e71bSYork Sun unsigned int wwt = 0; /* Write-to-write turnaround for same CS */ 18996c6e006aSYork Sun unsigned int trwt_mclk = 0; /* ext_rwt */ 19005614e71bSYork Sun unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */ 19015614e71bSYork Sun 190234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 19035614e71bSYork Sun if (popts->burst_length == DDR_BL8) { 19045614e71bSYork Sun /* We set BL/2 for fixed BL8 */ 19055614e71bSYork Sun rrt = 0; /* BL/2 clocks */ 19065614e71bSYork Sun wwt = 0; /* BL/2 clocks */ 19075614e71bSYork Sun } else { 19085614e71bSYork Sun /* We need to set BL/2 + 2 to BC4 and OTF */ 19095614e71bSYork Sun rrt = 2; /* BL/2 + 2 clocks */ 19105614e71bSYork Sun wwt = 2; /* BL/2 + 2 clocks */ 19115614e71bSYork Sun } 191234e026f9SYork Sun #endif 191334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 191434e026f9SYork Sun dll_lock = 2; /* tDLLK = 1024 clocks */ 191534e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 19165614e71bSYork Sun dll_lock = 1; /* tDLLK = 512 clocks from spec */ 19175614e71bSYork Sun #endif 19186c6e006aSYork Sun 19196c6e006aSYork Sun if (popts->trwt_override) 19206c6e006aSYork Sun trwt_mclk = popts->trwt; 19216c6e006aSYork Sun 19225614e71bSYork Sun ddr->timing_cfg_4 = (0 19235614e71bSYork Sun | ((rwt & 0xf) << 28) 19245614e71bSYork Sun | ((wrt & 0xf) << 24) 19255614e71bSYork Sun | ((rrt & 0xf) << 20) 19265614e71bSYork Sun | ((wwt & 0xf) << 16) 19276c6e006aSYork Sun | ((trwt_mclk & 0xc) << 12) 19285614e71bSYork Sun | (dll_lock & 0x3) 19295614e71bSYork Sun ); 19305614e71bSYork Sun debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4); 19315614e71bSYork Sun } 19325614e71bSYork Sun 19335614e71bSYork Sun /* DDR SDRAM Timing Configuration 5 (TIMING_CFG_5) */ 19345614e71bSYork Sun static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr, unsigned int cas_latency) 19355614e71bSYork Sun { 19365614e71bSYork Sun unsigned int rodt_on = 0; /* Read to ODT on */ 19375614e71bSYork Sun unsigned int rodt_off = 0; /* Read to ODT off */ 19385614e71bSYork Sun unsigned int wodt_on = 0; /* Write to ODT on */ 19395614e71bSYork Sun unsigned int wodt_off = 0; /* Write to ODT off */ 19405614e71bSYork Sun 194134e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 194234e026f9SYork Sun unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 194334e026f9SYork Sun ((ddr->timing_cfg_2 & 0x00040000) >> 14); 19445614e71bSYork Sun /* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */ 194534e026f9SYork Sun if (cas_latency >= wr_lat) 194634e026f9SYork Sun rodt_on = cas_latency - wr_lat + 1; 19475614e71bSYork Sun rodt_off = 4; /* 4 clocks */ 19485614e71bSYork Sun wodt_on = 1; /* 1 clocks */ 19495614e71bSYork Sun wodt_off = 4; /* 4 clocks */ 19505614e71bSYork Sun #endif 19515614e71bSYork Sun 19525614e71bSYork Sun ddr->timing_cfg_5 = (0 19535614e71bSYork Sun | ((rodt_on & 0x1f) << 24) 19545614e71bSYork Sun | ((rodt_off & 0x7) << 20) 19555614e71bSYork Sun | ((wodt_on & 0x1f) << 12) 19565614e71bSYork Sun | ((wodt_off & 0x7) << 8) 19575614e71bSYork Sun ); 19585614e71bSYork Sun debug("FSLDDR: timing_cfg_5 = 0x%08x\n", ddr->timing_cfg_5); 19595614e71bSYork Sun } 19605614e71bSYork Sun 196134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 196234e026f9SYork Sun static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr) 196334e026f9SYork Sun { 196434e026f9SYork Sun unsigned int hs_caslat = 0; 196534e026f9SYork Sun unsigned int hs_wrlat = 0; 196634e026f9SYork Sun unsigned int hs_wrrec = 0; 196734e026f9SYork Sun unsigned int hs_clkadj = 0; 196834e026f9SYork Sun unsigned int hs_wrlvl_start = 0; 196934e026f9SYork Sun 197034e026f9SYork Sun ddr->timing_cfg_6 = (0 197134e026f9SYork Sun | ((hs_caslat & 0x1f) << 24) 197234e026f9SYork Sun | ((hs_wrlat & 0x1f) << 19) 197334e026f9SYork Sun | ((hs_wrrec & 0x1f) << 12) 197434e026f9SYork Sun | ((hs_clkadj & 0x1f) << 6) 197534e026f9SYork Sun | ((hs_wrlvl_start & 0x1f) << 0) 197634e026f9SYork Sun ); 197734e026f9SYork Sun debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6); 197834e026f9SYork Sun } 197934e026f9SYork Sun 198003e664d8SYork Sun static void set_timing_cfg_7(const unsigned int ctrl_num, 198103e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 1982426230a6SYork Sun const memctl_options_t *popts, 198334e026f9SYork Sun const common_timing_params_t *common_dimm) 198434e026f9SYork Sun { 198534e026f9SYork Sun unsigned int txpr, tcksre, tcksrx; 1986eb118807SShengzhou Liu unsigned int cke_rst, cksre, cksrx, par_lat = 0, cs_to_cmd; 1987eb118807SShengzhou Liu const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); 198834e026f9SYork Sun 198903e664d8SYork Sun txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000)); 199003e664d8SYork Sun tcksre = max(5U, picos_to_mclk(ctrl_num, 10000)); 199103e664d8SYork Sun tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000)); 1992eb118807SShengzhou Liu 1993426230a6SYork Sun if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN && 1994426230a6SYork Sun CONFIG_FSL_SDRAM_TYPE == SDRAM_TYPE_DDR4) { 1995426230a6SYork Sun /* for DDR4 only */ 1996*c0c32af0SYork Sun par_lat = (ddr->ddr_sdram_rcw_2 & 0xf) + 1; 1997426230a6SYork Sun debug("PAR_LAT = %u for mclk_ps = %d\n", par_lat, mclk_ps); 1998eb118807SShengzhou Liu } 1999eb118807SShengzhou Liu 200034e026f9SYork Sun cs_to_cmd = 0; 200134e026f9SYork Sun 200234e026f9SYork Sun if (txpr <= 200) 200334e026f9SYork Sun cke_rst = 0; 200434e026f9SYork Sun else if (txpr <= 256) 200534e026f9SYork Sun cke_rst = 1; 200634e026f9SYork Sun else if (txpr <= 512) 200734e026f9SYork Sun cke_rst = 2; 200834e026f9SYork Sun else 200934e026f9SYork Sun cke_rst = 3; 201034e026f9SYork Sun 201134e026f9SYork Sun if (tcksre <= 19) 201234e026f9SYork Sun cksre = tcksre - 5; 201334e026f9SYork Sun else 201434e026f9SYork Sun cksre = 15; 201534e026f9SYork Sun 201634e026f9SYork Sun if (tcksrx <= 19) 201734e026f9SYork Sun cksrx = tcksrx - 5; 201834e026f9SYork Sun else 201934e026f9SYork Sun cksrx = 15; 202034e026f9SYork Sun 202134e026f9SYork Sun ddr->timing_cfg_7 = (0 202234e026f9SYork Sun | ((cke_rst & 0x3) << 28) 202334e026f9SYork Sun | ((cksre & 0xf) << 24) 202434e026f9SYork Sun | ((cksrx & 0xf) << 20) 202534e026f9SYork Sun | ((par_lat & 0xf) << 16) 202634e026f9SYork Sun | ((cs_to_cmd & 0xf) << 4) 202734e026f9SYork Sun ); 202834e026f9SYork Sun debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7); 202934e026f9SYork Sun } 203034e026f9SYork Sun 203103e664d8SYork Sun static void set_timing_cfg_8(const unsigned int ctrl_num, 203203e664d8SYork Sun fsl_ddr_cfg_regs_t *ddr, 203334e026f9SYork Sun const memctl_options_t *popts, 203434e026f9SYork Sun const common_timing_params_t *common_dimm, 203534e026f9SYork Sun unsigned int cas_latency) 203634e026f9SYork Sun { 2037426230a6SYork Sun int rwt_bg, wrt_bg, rrt_bg, wwt_bg; 203834e026f9SYork Sun unsigned int acttoact_bg, wrtord_bg, pre_all_rec; 2039426230a6SYork Sun int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); 2040426230a6SYork Sun int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 204134e026f9SYork Sun ((ddr->timing_cfg_2 & 0x00040000) >> 14); 204234e026f9SYork Sun 204334e026f9SYork Sun rwt_bg = cas_latency + 2 + 4 - wr_lat; 204434e026f9SYork Sun if (rwt_bg < tccdl) 204534e026f9SYork Sun rwt_bg = tccdl - rwt_bg; 204634e026f9SYork Sun else 204734e026f9SYork Sun rwt_bg = 0; 204834e026f9SYork Sun 204934e026f9SYork Sun wrt_bg = wr_lat + 4 + 1 - cas_latency; 205034e026f9SYork Sun if (wrt_bg < tccdl) 205134e026f9SYork Sun wrt_bg = tccdl - wrt_bg; 205234e026f9SYork Sun else 205334e026f9SYork Sun wrt_bg = 0; 205434e026f9SYork Sun 205534e026f9SYork Sun if (popts->burst_length == DDR_BL8) { 205634e026f9SYork Sun rrt_bg = tccdl - 4; 205734e026f9SYork Sun wwt_bg = tccdl - 4; 205834e026f9SYork Sun } else { 205934e026f9SYork Sun rrt_bg = tccdl - 2; 2060dc1437afSYork Sun wwt_bg = tccdl - 2; 206134e026f9SYork Sun } 206234e026f9SYork Sun 206303e664d8SYork Sun acttoact_bg = picos_to_mclk(ctrl_num, common_dimm->trrdl_ps); 206403e664d8SYork Sun wrtord_bg = max(4U, picos_to_mclk(ctrl_num, 7500)); 20653d75ec95SYork Sun if (popts->otf_burst_chop_en) 20663d75ec95SYork Sun wrtord_bg += 2; 20673d75ec95SYork Sun 206834e026f9SYork Sun pre_all_rec = 0; 206934e026f9SYork Sun 207034e026f9SYork Sun ddr->timing_cfg_8 = (0 207134e026f9SYork Sun | ((rwt_bg & 0xf) << 28) 207234e026f9SYork Sun | ((wrt_bg & 0xf) << 24) 207334e026f9SYork Sun | ((rrt_bg & 0xf) << 20) 207434e026f9SYork Sun | ((wwt_bg & 0xf) << 16) 207534e026f9SYork Sun | ((acttoact_bg & 0xf) << 12) 207634e026f9SYork Sun | ((wrtord_bg & 0xf) << 8) 207734e026f9SYork Sun | ((pre_all_rec & 0x1f) << 0) 207834e026f9SYork Sun ); 207934e026f9SYork Sun 208034e026f9SYork Sun debug("FSLDDR: timing_cfg_8 = 0x%08x\n", ddr->timing_cfg_8); 208134e026f9SYork Sun } 208234e026f9SYork Sun 2083*c0c32af0SYork Sun static void set_timing_cfg_9(const unsigned int ctrl_num, 2084*c0c32af0SYork Sun fsl_ddr_cfg_regs_t *ddr, 2085*c0c32af0SYork Sun const memctl_options_t *popts, 2086*c0c32af0SYork Sun const common_timing_params_t *common_dimm) 208734e026f9SYork Sun { 2088*c0c32af0SYork Sun unsigned int refrec_cid_mclk = 0; 2089*c0c32af0SYork Sun unsigned int acttoact_cid_mclk = 0; 2090*c0c32af0SYork Sun 2091*c0c32af0SYork Sun if (popts->package_3ds) { 2092*c0c32af0SYork Sun refrec_cid_mclk = 2093*c0c32af0SYork Sun picos_to_mclk(ctrl_num, common_dimm->trfc_slr_ps); 2094*c0c32af0SYork Sun acttoact_cid_mclk = 4U; /* tRRDS_slr */ 2095*c0c32af0SYork Sun } 2096*c0c32af0SYork Sun 2097*c0c32af0SYork Sun ddr->timing_cfg_9 = (refrec_cid_mclk & 0x3ff) << 16 | 2098*c0c32af0SYork Sun (acttoact_cid_mclk & 0xf) << 8; 2099*c0c32af0SYork Sun 210034e026f9SYork Sun debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9); 210134e026f9SYork Sun } 210234e026f9SYork Sun 2103f80d6472SYork Sun /* This function needs to be called after set_ddr_sdram_cfg() is called */ 210434e026f9SYork Sun static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr, 210534e026f9SYork Sun const dimm_params_t *dimm_params) 210634e026f9SYork Sun { 2107f80d6472SYork Sun unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1; 21086b95be22SYork Sun int i; 2109f80d6472SYork Sun 21106b95be22SYork Sun for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { 21116b95be22SYork Sun if (dimm_params[i].n_ranks) 21126b95be22SYork Sun break; 21136b95be22SYork Sun } 21146b95be22SYork Sun if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) { 21156b95be22SYork Sun puts("DDR error: no DIMM found!\n"); 21166b95be22SYork Sun return; 21176b95be22SYork Sun } 211834e026f9SYork Sun 21196b95be22SYork Sun ddr->dq_map_0 = ((dimm_params[i].dq_mapping[0] & 0x3F) << 26) | 21206b95be22SYork Sun ((dimm_params[i].dq_mapping[1] & 0x3F) << 20) | 21216b95be22SYork Sun ((dimm_params[i].dq_mapping[2] & 0x3F) << 14) | 21226b95be22SYork Sun ((dimm_params[i].dq_mapping[3] & 0x3F) << 8) | 21236b95be22SYork Sun ((dimm_params[i].dq_mapping[4] & 0x3F) << 2); 212434e026f9SYork Sun 21256b95be22SYork Sun ddr->dq_map_1 = ((dimm_params[i].dq_mapping[5] & 0x3F) << 26) | 21266b95be22SYork Sun ((dimm_params[i].dq_mapping[6] & 0x3F) << 20) | 21276b95be22SYork Sun ((dimm_params[i].dq_mapping[7] & 0x3F) << 14) | 21286b95be22SYork Sun ((dimm_params[i].dq_mapping[10] & 0x3F) << 8) | 21296b95be22SYork Sun ((dimm_params[i].dq_mapping[11] & 0x3F) << 2); 21306b95be22SYork Sun 21316b95be22SYork Sun ddr->dq_map_2 = ((dimm_params[i].dq_mapping[12] & 0x3F) << 26) | 21326b95be22SYork Sun ((dimm_params[i].dq_mapping[13] & 0x3F) << 20) | 21336b95be22SYork Sun ((dimm_params[i].dq_mapping[14] & 0x3F) << 14) | 21346b95be22SYork Sun ((dimm_params[i].dq_mapping[15] & 0x3F) << 8) | 21356b95be22SYork Sun ((dimm_params[i].dq_mapping[16] & 0x3F) << 2); 213634e026f9SYork Sun 2137f80d6472SYork Sun /* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */ 21386b95be22SYork Sun ddr->dq_map_3 = ((dimm_params[i].dq_mapping[17] & 0x3F) << 26) | 21396b95be22SYork Sun ((dimm_params[i].dq_mapping[8] & 0x3F) << 20) | 2140f80d6472SYork Sun (acc_ecc_en ? 0 : 21416b95be22SYork Sun (dimm_params[i].dq_mapping[9] & 0x3F) << 14) | 21426b95be22SYork Sun dimm_params[i].dq_mapping_ors; 214334e026f9SYork Sun 214434e026f9SYork Sun debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0); 214534e026f9SYork Sun debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1); 214634e026f9SYork Sun debug("FSLDDR: dq_map_2 = 0x%08x\n", ddr->dq_map_2); 214734e026f9SYork Sun debug("FSLDDR: dq_map_3 = 0x%08x\n", ddr->dq_map_3); 214834e026f9SYork Sun } 214934e026f9SYork Sun static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr, 215034e026f9SYork Sun const memctl_options_t *popts) 215134e026f9SYork Sun { 215234e026f9SYork Sun int rd_pre; 215334e026f9SYork Sun 215434e026f9SYork Sun rd_pre = popts->quad_rank_present ? 1 : 0; 215534e026f9SYork Sun 215634e026f9SYork Sun ddr->ddr_sdram_cfg_3 = (rd_pre & 0x1) << 16; 2157426230a6SYork Sun /* Disable MRS on parity error for RDIMMs */ 2158426230a6SYork Sun ddr->ddr_sdram_cfg_3 |= popts->registered_dimm_en ? 1 : 0; 215934e026f9SYork Sun 2160*c0c32af0SYork Sun if (popts->package_3ds) { /* only 2,4,8 are supported */ 2161*c0c32af0SYork Sun if ((popts->package_3ds + 1) & 0x1) { 2162*c0c32af0SYork Sun printf("Error: Unsupported 3DS DIMM with %d die\n", 2163*c0c32af0SYork Sun popts->package_3ds + 1); 2164*c0c32af0SYork Sun } else { 2165*c0c32af0SYork Sun ddr->ddr_sdram_cfg_3 |= ((popts->package_3ds + 1) >> 1) 2166*c0c32af0SYork Sun << 4; 2167*c0c32af0SYork Sun } 2168*c0c32af0SYork Sun } 2169*c0c32af0SYork Sun 217034e026f9SYork Sun debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3); 217134e026f9SYork Sun } 217234e026f9SYork Sun #endif /* CONFIG_SYS_FSL_DDR4 */ 217334e026f9SYork Sun 21745614e71bSYork Sun /* DDR ZQ Calibration Control (DDR_ZQ_CNTL) */ 21755614e71bSYork Sun static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en) 21765614e71bSYork Sun { 21775614e71bSYork Sun unsigned int zqinit = 0;/* POR ZQ Calibration Time (tZQinit) */ 21785614e71bSYork Sun /* Normal Operation Full Calibration Time (tZQoper) */ 21795614e71bSYork Sun unsigned int zqoper = 0; 21805614e71bSYork Sun /* Normal Operation Short Calibration Time (tZQCS) */ 21815614e71bSYork Sun unsigned int zqcs = 0; 218234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 218334e026f9SYork Sun unsigned int zqcs_init; 218434e026f9SYork Sun #endif 21855614e71bSYork Sun 21865614e71bSYork Sun if (zq_en) { 218734e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 218834e026f9SYork Sun zqinit = 10; /* 1024 clocks */ 218934e026f9SYork Sun zqoper = 9; /* 512 clocks */ 219034e026f9SYork Sun zqcs = 7; /* 128 clocks */ 219134e026f9SYork Sun zqcs_init = 5; /* 1024 refresh sequences */ 219234e026f9SYork Sun #else 21935614e71bSYork Sun zqinit = 9; /* 512 clocks */ 21945614e71bSYork Sun zqoper = 8; /* 256 clocks */ 21955614e71bSYork Sun zqcs = 6; /* 64 clocks */ 219634e026f9SYork Sun #endif 21975614e71bSYork Sun } 21985614e71bSYork Sun 21995614e71bSYork Sun ddr->ddr_zq_cntl = (0 22005614e71bSYork Sun | ((zq_en & 0x1) << 31) 22015614e71bSYork Sun | ((zqinit & 0xF) << 24) 22025614e71bSYork Sun | ((zqoper & 0xF) << 16) 22035614e71bSYork Sun | ((zqcs & 0xF) << 8) 220434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 220534e026f9SYork Sun | ((zqcs_init & 0xF) << 0) 220634e026f9SYork Sun #endif 22075614e71bSYork Sun ); 22085614e71bSYork Sun debug("FSLDDR: zq_cntl = 0x%08x\n", ddr->ddr_zq_cntl); 22095614e71bSYork Sun } 22105614e71bSYork Sun 22115614e71bSYork Sun /* DDR Write Leveling Control (DDR_WRLVL_CNTL) */ 22125614e71bSYork Sun static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en, 22135614e71bSYork Sun const memctl_options_t *popts) 22145614e71bSYork Sun { 22155614e71bSYork Sun /* 22165614e71bSYork Sun * First DQS pulse rising edge after margining mode 22175614e71bSYork Sun * is programmed (tWL_MRD) 22185614e71bSYork Sun */ 22195614e71bSYork Sun unsigned int wrlvl_mrd = 0; 22205614e71bSYork Sun /* ODT delay after margining mode is programmed (tWL_ODTEN) */ 22215614e71bSYork Sun unsigned int wrlvl_odten = 0; 22225614e71bSYork Sun /* DQS/DQS_ delay after margining mode is programmed (tWL_DQSEN) */ 22235614e71bSYork Sun unsigned int wrlvl_dqsen = 0; 22245614e71bSYork Sun /* WRLVL_SMPL: Write leveling sample time */ 22255614e71bSYork Sun unsigned int wrlvl_smpl = 0; 22265614e71bSYork Sun /* WRLVL_WLR: Write leveling repeition time */ 22275614e71bSYork Sun unsigned int wrlvl_wlr = 0; 22285614e71bSYork Sun /* WRLVL_START: Write leveling start time */ 22295614e71bSYork Sun unsigned int wrlvl_start = 0; 22305614e71bSYork Sun 22315614e71bSYork Sun /* suggest enable write leveling for DDR3 due to fly-by topology */ 22325614e71bSYork Sun if (wrlvl_en) { 22335614e71bSYork Sun /* tWL_MRD min = 40 nCK, we set it 64 */ 22345614e71bSYork Sun wrlvl_mrd = 0x6; 22355614e71bSYork Sun /* tWL_ODTEN 128 */ 22365614e71bSYork Sun wrlvl_odten = 0x7; 22375614e71bSYork Sun /* tWL_DQSEN min = 25 nCK, we set it 32 */ 22385614e71bSYork Sun wrlvl_dqsen = 0x5; 22395614e71bSYork Sun /* 22405614e71bSYork Sun * Write leveling sample time at least need 6 clocks 22415614e71bSYork Sun * higher than tWLO to allow enough time for progagation 22425614e71bSYork Sun * delay and sampling the prime data bits. 22435614e71bSYork Sun */ 22445614e71bSYork Sun wrlvl_smpl = 0xf; 22455614e71bSYork Sun /* 22465614e71bSYork Sun * Write leveling repetition time 22475614e71bSYork Sun * at least tWLO + 6 clocks clocks 22485614e71bSYork Sun * we set it 64 22495614e71bSYork Sun */ 22505614e71bSYork Sun wrlvl_wlr = 0x6; 22515614e71bSYork Sun /* 22525614e71bSYork Sun * Write leveling start time 22535614e71bSYork Sun * The value use for the DQS_ADJUST for the first sample 22545614e71bSYork Sun * when write leveling is enabled. It probably needs to be 225562a3b7ddSRobert P. J. Day * overridden per platform. 22565614e71bSYork Sun */ 22575614e71bSYork Sun wrlvl_start = 0x8; 22585614e71bSYork Sun /* 22595614e71bSYork Sun * Override the write leveling sample and start time 22605614e71bSYork Sun * according to specific board 22615614e71bSYork Sun */ 22625614e71bSYork Sun if (popts->wrlvl_override) { 22635614e71bSYork Sun wrlvl_smpl = popts->wrlvl_sample; 22645614e71bSYork Sun wrlvl_start = popts->wrlvl_start; 22655614e71bSYork Sun } 22665614e71bSYork Sun } 22675614e71bSYork Sun 22685614e71bSYork Sun ddr->ddr_wrlvl_cntl = (0 22695614e71bSYork Sun | ((wrlvl_en & 0x1) << 31) 22705614e71bSYork Sun | ((wrlvl_mrd & 0x7) << 24) 22715614e71bSYork Sun | ((wrlvl_odten & 0x7) << 20) 22725614e71bSYork Sun | ((wrlvl_dqsen & 0x7) << 16) 22735614e71bSYork Sun | ((wrlvl_smpl & 0xf) << 12) 22745614e71bSYork Sun | ((wrlvl_wlr & 0x7) << 8) 22755614e71bSYork Sun | ((wrlvl_start & 0x1F) << 0) 22765614e71bSYork Sun ); 22775614e71bSYork Sun debug("FSLDDR: wrlvl_cntl = 0x%08x\n", ddr->ddr_wrlvl_cntl); 22785614e71bSYork Sun ddr->ddr_wrlvl_cntl_2 = popts->wrlvl_ctl_2; 22795614e71bSYork Sun debug("FSLDDR: wrlvl_cntl_2 = 0x%08x\n", ddr->ddr_wrlvl_cntl_2); 22805614e71bSYork Sun ddr->ddr_wrlvl_cntl_3 = popts->wrlvl_ctl_3; 22815614e71bSYork Sun debug("FSLDDR: wrlvl_cntl_3 = 0x%08x\n", ddr->ddr_wrlvl_cntl_3); 22825614e71bSYork Sun 22835614e71bSYork Sun } 22845614e71bSYork Sun 22855614e71bSYork Sun /* DDR Self Refresh Counter (DDR_SR_CNTR) */ 22865614e71bSYork Sun static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it) 22875614e71bSYork Sun { 22885614e71bSYork Sun /* Self Refresh Idle Threshold */ 22895614e71bSYork Sun ddr->ddr_sr_cntr = (sr_it & 0xF) << 16; 22905614e71bSYork Sun } 22915614e71bSYork Sun 22925614e71bSYork Sun static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 22935614e71bSYork Sun { 22945614e71bSYork Sun if (popts->addr_hash) { 22955614e71bSYork Sun ddr->ddr_eor = 0x40000000; /* address hash enable */ 22965614e71bSYork Sun puts("Address hashing enabled.\n"); 22975614e71bSYork Sun } 22985614e71bSYork Sun } 22995614e71bSYork Sun 23005614e71bSYork Sun static void set_ddr_cdr1(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 23015614e71bSYork Sun { 23025614e71bSYork Sun ddr->ddr_cdr1 = popts->ddr_cdr1; 23035614e71bSYork Sun debug("FSLDDR: ddr_cdr1 = 0x%08x\n", ddr->ddr_cdr1); 23045614e71bSYork Sun } 23055614e71bSYork Sun 23065614e71bSYork Sun static void set_ddr_cdr2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) 23075614e71bSYork Sun { 23085614e71bSYork Sun ddr->ddr_cdr2 = popts->ddr_cdr2; 23095614e71bSYork Sun debug("FSLDDR: ddr_cdr2 = 0x%08x\n", ddr->ddr_cdr2); 23105614e71bSYork Sun } 23115614e71bSYork Sun 23125614e71bSYork Sun unsigned int 23135614e71bSYork Sun check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) 23145614e71bSYork Sun { 23155614e71bSYork Sun unsigned int res = 0; 23165614e71bSYork Sun 23175614e71bSYork Sun /* 23185614e71bSYork Sun * Check that DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] are 23195614e71bSYork Sun * not set at the same time. 23205614e71bSYork Sun */ 23215614e71bSYork Sun if (ddr->ddr_sdram_cfg & 0x10000000 23225614e71bSYork Sun && ddr->ddr_sdram_cfg & 0x00008000) { 23235614e71bSYork Sun printf("Error: DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] " 23245614e71bSYork Sun " should not be set at the same time.\n"); 23255614e71bSYork Sun res++; 23265614e71bSYork Sun } 23275614e71bSYork Sun 23285614e71bSYork Sun return res; 23295614e71bSYork Sun } 23305614e71bSYork Sun 23315614e71bSYork Sun unsigned int 233203e664d8SYork Sun compute_fsl_memctl_config_regs(const unsigned int ctrl_num, 233303e664d8SYork Sun const memctl_options_t *popts, 23345614e71bSYork Sun fsl_ddr_cfg_regs_t *ddr, 23355614e71bSYork Sun const common_timing_params_t *common_dimm, 23365614e71bSYork Sun const dimm_params_t *dimm_params, 23375614e71bSYork Sun unsigned int dbw_cap_adj, 23385614e71bSYork Sun unsigned int size_only) 23395614e71bSYork Sun { 23405614e71bSYork Sun unsigned int i; 23415614e71bSYork Sun unsigned int cas_latency; 23425614e71bSYork Sun unsigned int additive_latency; 23435614e71bSYork Sun unsigned int sr_it; 23445614e71bSYork Sun unsigned int zq_en; 23455614e71bSYork Sun unsigned int wrlvl_en; 23465614e71bSYork Sun unsigned int ip_rev = 0; 23475614e71bSYork Sun unsigned int unq_mrs_en = 0; 23485614e71bSYork Sun int cs_en = 1; 234902fb2761SShengzhou Liu #ifdef CONFIG_SYS_FSL_ERRATUM_A009942 235002fb2761SShengzhou Liu unsigned int ddr_freq; 235102fb2761SShengzhou Liu #endif 235202fb2761SShengzhou Liu #if (defined(CONFIG_SYS_FSL_ERRATUM_A008378) && \ 235302fb2761SShengzhou Liu defined(CONFIG_SYS_FSL_DDRC_GEN4)) || \ 235402fb2761SShengzhou Liu defined(CONFIG_SYS_FSL_ERRATUM_A009942) 235502fb2761SShengzhou Liu struct ccsr_ddr __iomem *ddrc; 235602fb2761SShengzhou Liu 235702fb2761SShengzhou Liu switch (ctrl_num) { 235802fb2761SShengzhou Liu case 0: 235902fb2761SShengzhou Liu ddrc = (void *)CONFIG_SYS_FSL_DDR_ADDR; 236002fb2761SShengzhou Liu break; 236151370d56SYork Sun #if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1) 236202fb2761SShengzhou Liu case 1: 236302fb2761SShengzhou Liu ddrc = (void *)CONFIG_SYS_FSL_DDR2_ADDR; 236402fb2761SShengzhou Liu break; 236502fb2761SShengzhou Liu #endif 236651370d56SYork Sun #if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2) 236702fb2761SShengzhou Liu case 2: 236802fb2761SShengzhou Liu ddrc = (void *)CONFIG_SYS_FSL_DDR3_ADDR; 236902fb2761SShengzhou Liu break; 237002fb2761SShengzhou Liu #endif 237151370d56SYork Sun #if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3) 237202fb2761SShengzhou Liu case 3: 237302fb2761SShengzhou Liu ddrc = (void *)CONFIG_SYS_FSL_DDR4_ADDR; 237402fb2761SShengzhou Liu break; 237502fb2761SShengzhou Liu #endif 237602fb2761SShengzhou Liu default: 237702fb2761SShengzhou Liu printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num); 237802fb2761SShengzhou Liu return 1; 237902fb2761SShengzhou Liu } 238002fb2761SShengzhou Liu #endif 23815614e71bSYork Sun 23825614e71bSYork Sun memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t)); 23835614e71bSYork Sun 23845614e71bSYork Sun if (common_dimm == NULL) { 23855614e71bSYork Sun printf("Error: subset DIMM params struct null pointer\n"); 23865614e71bSYork Sun return 1; 23875614e71bSYork Sun } 23885614e71bSYork Sun 23895614e71bSYork Sun /* 23905614e71bSYork Sun * Process overrides first. 23915614e71bSYork Sun * 23925614e71bSYork Sun * FIXME: somehow add dereated caslat to this 23935614e71bSYork Sun */ 23945614e71bSYork Sun cas_latency = (popts->cas_latency_override) 23955614e71bSYork Sun ? popts->cas_latency_override_value 239634e026f9SYork Sun : common_dimm->lowest_common_spd_caslat; 23975614e71bSYork Sun 23985614e71bSYork Sun additive_latency = (popts->additive_latency_override) 23995614e71bSYork Sun ? popts->additive_latency_override_value 24005614e71bSYork Sun : common_dimm->additive_latency; 24015614e71bSYork Sun 24025614e71bSYork Sun sr_it = (popts->auto_self_refresh_en) 24035614e71bSYork Sun ? popts->sr_it 24045614e71bSYork Sun : 0; 24055614e71bSYork Sun /* ZQ calibration */ 24065614e71bSYork Sun zq_en = (popts->zq_en) ? 1 : 0; 24075614e71bSYork Sun /* write leveling */ 24085614e71bSYork Sun wrlvl_en = (popts->wrlvl_en) ? 1 : 0; 24095614e71bSYork Sun 24105614e71bSYork Sun /* Chip Select Memory Bounds (CSn_BNDS) */ 24115614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 24125614e71bSYork Sun unsigned long long ea, sa; 24135614e71bSYork Sun unsigned int cs_per_dimm 24145614e71bSYork Sun = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; 24155614e71bSYork Sun unsigned int dimm_number 24165614e71bSYork Sun = i / cs_per_dimm; 24175614e71bSYork Sun unsigned long long rank_density 24185614e71bSYork Sun = dimm_params[dimm_number].rank_density >> dbw_cap_adj; 24195614e71bSYork Sun 24205614e71bSYork Sun if (dimm_params[dimm_number].n_ranks == 0) { 24215614e71bSYork Sun debug("Skipping setup of CS%u " 24225614e71bSYork Sun "because n_ranks on DIMM %u is 0\n", i, dimm_number); 24235614e71bSYork Sun continue; 24245614e71bSYork Sun } 24255614e71bSYork Sun if (popts->memctl_interleaving) { 24265614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 24275614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 24285614e71bSYork Sun break; 24295614e71bSYork Sun case FSL_DDR_CS0_CS1: 24305614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 24315614e71bSYork Sun if (i > 1) 24325614e71bSYork Sun cs_en = 0; 24335614e71bSYork Sun break; 24345614e71bSYork Sun case FSL_DDR_CS2_CS3: 24355614e71bSYork Sun default: 24365614e71bSYork Sun if (i > 0) 24375614e71bSYork Sun cs_en = 0; 24385614e71bSYork Sun break; 24395614e71bSYork Sun } 24405614e71bSYork Sun sa = common_dimm->base_address; 24415614e71bSYork Sun ea = sa + common_dimm->total_mem - 1; 24425614e71bSYork Sun } else if (!popts->memctl_interleaving) { 24435614e71bSYork Sun /* 24445614e71bSYork Sun * If memory interleaving between controllers is NOT 24455614e71bSYork Sun * enabled, the starting address for each memory 24465614e71bSYork Sun * controller is distinct. However, because rank 24475614e71bSYork Sun * interleaving is enabled, the starting and ending 24485614e71bSYork Sun * addresses of the total memory on that memory 24495614e71bSYork Sun * controller needs to be programmed into its 24505614e71bSYork Sun * respective CS0_BNDS. 24515614e71bSYork Sun */ 24525614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 24535614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 24545614e71bSYork Sun sa = common_dimm->base_address; 24555614e71bSYork Sun ea = sa + common_dimm->total_mem - 1; 24565614e71bSYork Sun break; 24575614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 24585614e71bSYork Sun if ((i >= 2) && (dimm_number == 0)) { 24595614e71bSYork Sun sa = dimm_params[dimm_number].base_address + 24605614e71bSYork Sun 2 * rank_density; 24615614e71bSYork Sun ea = sa + 2 * rank_density - 1; 24625614e71bSYork Sun } else { 24635614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 24645614e71bSYork Sun ea = sa + 2 * rank_density - 1; 24655614e71bSYork Sun } 24665614e71bSYork Sun break; 24675614e71bSYork Sun case FSL_DDR_CS0_CS1: 24685614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 24695614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 24705614e71bSYork Sun ea = sa + rank_density - 1; 24715614e71bSYork Sun if (i != 1) 24725614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 24735614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 24745614e71bSYork Sun } else { 24755614e71bSYork Sun sa = 0; 24765614e71bSYork Sun ea = 0; 24775614e71bSYork Sun } 24785614e71bSYork Sun if (i == 0) 24795614e71bSYork Sun ea += rank_density; 24805614e71bSYork Sun break; 24815614e71bSYork Sun case FSL_DDR_CS2_CS3: 24825614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 24835614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 24845614e71bSYork Sun ea = sa + rank_density - 1; 24855614e71bSYork Sun if (i != 3) 24865614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 24875614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 24885614e71bSYork Sun } else { 24895614e71bSYork Sun sa = 0; 24905614e71bSYork Sun ea = 0; 24915614e71bSYork Sun } 24925614e71bSYork Sun if (i == 2) 24935614e71bSYork Sun ea += (rank_density >> dbw_cap_adj); 24945614e71bSYork Sun break; 24955614e71bSYork Sun default: /* No bank(chip-select) interleaving */ 24965614e71bSYork Sun sa = dimm_params[dimm_number].base_address; 24975614e71bSYork Sun ea = sa + rank_density - 1; 24985614e71bSYork Sun if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { 24995614e71bSYork Sun sa += (i % cs_per_dimm) * rank_density; 25005614e71bSYork Sun ea += (i % cs_per_dimm) * rank_density; 25015614e71bSYork Sun } else { 25025614e71bSYork Sun sa = 0; 25035614e71bSYork Sun ea = 0; 25045614e71bSYork Sun } 25055614e71bSYork Sun break; 25065614e71bSYork Sun } 25075614e71bSYork Sun } 25085614e71bSYork Sun 25095614e71bSYork Sun sa >>= 24; 25105614e71bSYork Sun ea >>= 24; 25115614e71bSYork Sun 25125614e71bSYork Sun if (cs_en) { 25135614e71bSYork Sun ddr->cs[i].bnds = (0 2514d4263b8aSYork Sun | ((sa & 0xffff) << 16) /* starting address */ 2515d4263b8aSYork Sun | ((ea & 0xffff) << 0) /* ending address */ 25165614e71bSYork Sun ); 25175614e71bSYork Sun } else { 25185614e71bSYork Sun /* setting bnds to 0xffffffff for inactive CS */ 25195614e71bSYork Sun ddr->cs[i].bnds = 0xffffffff; 25205614e71bSYork Sun } 25215614e71bSYork Sun 25225614e71bSYork Sun debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds); 25235614e71bSYork Sun set_csn_config(dimm_number, i, ddr, popts, dimm_params); 25245614e71bSYork Sun set_csn_config_2(i, ddr); 25255614e71bSYork Sun } 25265614e71bSYork Sun 25275614e71bSYork Sun /* 25285614e71bSYork Sun * In the case we only need to compute the ddr sdram size, we only need 25295614e71bSYork Sun * to set csn registers, so return from here. 25305614e71bSYork Sun */ 25315614e71bSYork Sun if (size_only) 25325614e71bSYork Sun return 0; 25335614e71bSYork Sun 25345614e71bSYork Sun set_ddr_eor(ddr, popts); 25355614e71bSYork Sun 25365614e71bSYork Sun #if !defined(CONFIG_SYS_FSL_DDR1) 253703e664d8SYork Sun set_timing_cfg_0(ctrl_num, ddr, popts, dimm_params); 25385614e71bSYork Sun #endif 25395614e71bSYork Sun 254003e664d8SYork Sun set_timing_cfg_3(ctrl_num, ddr, popts, common_dimm, cas_latency, 2541d4263b8aSYork Sun additive_latency); 254203e664d8SYork Sun set_timing_cfg_1(ctrl_num, ddr, popts, common_dimm, cas_latency); 254303e664d8SYork Sun set_timing_cfg_2(ctrl_num, ddr, popts, common_dimm, 25445614e71bSYork Sun cas_latency, additive_latency); 25455614e71bSYork Sun 25465614e71bSYork Sun set_ddr_cdr1(ddr, popts); 25475614e71bSYork Sun set_ddr_cdr2(ddr, popts); 25485614e71bSYork Sun set_ddr_sdram_cfg(ddr, popts, common_dimm); 254966869f95SYork Sun ip_rev = fsl_ddr_get_version(ctrl_num); 25505614e71bSYork Sun if (ip_rev > 0x40400) 25515614e71bSYork Sun unq_mrs_en = 1; 25525614e71bSYork Sun 2553f80d6472SYork Sun if ((ip_rev > 0x40700) && (popts->cswl_override != 0)) 2554ef87cab6SYork Sun ddr->debug[18] = popts->cswl_override; 2555ef87cab6SYork Sun 255603e664d8SYork Sun set_ddr_sdram_cfg_2(ctrl_num, ddr, popts, unq_mrs_en); 255703e664d8SYork Sun set_ddr_sdram_mode(ctrl_num, ddr, popts, common_dimm, 25585614e71bSYork Sun cas_latency, additive_latency, unq_mrs_en); 255903e664d8SYork Sun set_ddr_sdram_mode_2(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); 256034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 256134e026f9SYork Sun set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en); 256203e664d8SYork Sun set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); 256334e026f9SYork Sun #endif 256403e664d8SYork Sun set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm); 25655614e71bSYork Sun set_ddr_data_init(ddr); 25665614e71bSYork Sun set_ddr_sdram_clk_cntl(ddr, popts); 25675614e71bSYork Sun set_ddr_init_addr(ddr); 25685614e71bSYork Sun set_ddr_init_ext_addr(ddr); 25695614e71bSYork Sun set_timing_cfg_4(ddr, popts); 25705614e71bSYork Sun set_timing_cfg_5(ddr, cas_latency); 257134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 257234e026f9SYork Sun set_ddr_sdram_cfg_3(ddr, popts); 257334e026f9SYork Sun set_timing_cfg_6(ddr); 2574426230a6SYork Sun set_timing_cfg_7(ctrl_num, ddr, popts, common_dimm); 257503e664d8SYork Sun set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency); 2576*c0c32af0SYork Sun set_timing_cfg_9(ctrl_num, ddr, popts, common_dimm); 257734e026f9SYork Sun set_ddr_dq_mapping(ddr, dimm_params); 257834e026f9SYork Sun #endif 25795614e71bSYork Sun 25805614e71bSYork Sun set_ddr_zq_cntl(ddr, zq_en); 25815614e71bSYork Sun set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts); 25825614e71bSYork Sun 25835614e71bSYork Sun set_ddr_sr_cntr(ddr, sr_it); 25845614e71bSYork Sun 25855614e71bSYork Sun set_ddr_sdram_rcw(ddr, popts, common_dimm); 25865614e71bSYork Sun 25875614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR_EMU 25885614e71bSYork Sun /* disble DDR training for emulator */ 25895614e71bSYork Sun ddr->debug[2] = 0x00000400; 25901f3402e7SYork Sun ddr->debug[4] = 0xff800800; 25911f3402e7SYork Sun ddr->debug[5] = 0x08000800; 25921f3402e7SYork Sun ddr->debug[6] = 0x08000800; 25931f3402e7SYork Sun ddr->debug[7] = 0x08000800; 25941f3402e7SYork Sun ddr->debug[8] = 0x08000800; 25955614e71bSYork Sun #endif 25969855b3beSYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_A004508 25979855b3beSYork Sun if ((ip_rev >= 0x40000) && (ip_rev < 0x40400)) 25989855b3beSYork Sun ddr->debug[2] |= 0x00000200; /* set bit 22 */ 25999855b3beSYork Sun #endif 26009855b3beSYork Sun 260102fb2761SShengzhou Liu #if defined(CONFIG_SYS_FSL_ERRATUM_A008378) && defined(CONFIG_SYS_FSL_DDRC_GEN4) 260202fb2761SShengzhou Liu /* Erratum applies when accumulated ECC is used, or DBI is enabled */ 260302fb2761SShengzhou Liu #define IS_ACC_ECC_EN(v) ((v) & 0x4) 260402fb2761SShengzhou Liu #define IS_DBI(v) ((((v) >> 12) & 0x3) == 0x2) 260502fb2761SShengzhou Liu if (has_erratum_a008378()) { 260602fb2761SShengzhou Liu if (IS_ACC_ECC_EN(ddr->ddr_sdram_cfg) || 260702fb2761SShengzhou Liu IS_DBI(ddr->ddr_sdram_cfg_3)) { 260802fb2761SShengzhou Liu ddr->debug[28] = ddr_in32(&ddrc->debug[28]); 260902fb2761SShengzhou Liu ddr->debug[28] |= (0x9 << 20); 261002fb2761SShengzhou Liu } 261102fb2761SShengzhou Liu } 261202fb2761SShengzhou Liu #endif 261302fb2761SShengzhou Liu 261402fb2761SShengzhou Liu #ifdef CONFIG_SYS_FSL_ERRATUM_A009942 261502fb2761SShengzhou Liu ddr_freq = get_ddr_freq(ctrl_num) / 1000000; 261602fb2761SShengzhou Liu ddr->debug[28] |= ddr_in32(&ddrc->debug[28]); 261702fb2761SShengzhou Liu ddr->debug[28] &= 0xff0fff00; 261802fb2761SShengzhou Liu if (ddr_freq <= 1333) 261902fb2761SShengzhou Liu ddr->debug[28] |= 0x0080006a; 262002fb2761SShengzhou Liu else if (ddr_freq <= 1600) 262102fb2761SShengzhou Liu ddr->debug[28] |= 0x0070006f; 262202fb2761SShengzhou Liu else if (ddr_freq <= 1867) 262302fb2761SShengzhou Liu ddr->debug[28] |= 0x00700076; 262402fb2761SShengzhou Liu else if (ddr_freq <= 2133) 262502fb2761SShengzhou Liu ddr->debug[28] |= 0x0060007b; 262602fb2761SShengzhou Liu if (popts->cpo_sample) 262702fb2761SShengzhou Liu ddr->debug[28] = (ddr->debug[28] & 0xffffff00) | 262802fb2761SShengzhou Liu popts->cpo_sample; 262902fb2761SShengzhou Liu #endif 263002fb2761SShengzhou Liu 26315614e71bSYork Sun return check_fsl_memctl_config_regs(ddr); 26325614e71bSYork Sun } 263302fb2761SShengzhou Liu 263402fb2761SShengzhou Liu #ifdef CONFIG_SYS_FSL_ERRATUM_A009942 263502fb2761SShengzhou Liu /* 263602fb2761SShengzhou Liu * This additional workaround of A009942 checks the condition to determine if 263702fb2761SShengzhou Liu * the CPO value set by the existing A009942 workaround needs to be updated. 263802fb2761SShengzhou Liu * If need, print a warning to prompt user reconfigure DDR debug_29[24:31] with 263902fb2761SShengzhou Liu * expected optimal value, the optimal value is highly board dependent. 264002fb2761SShengzhou Liu */ 264102fb2761SShengzhou Liu void erratum_a009942_check_cpo(void) 264202fb2761SShengzhou Liu { 264302fb2761SShengzhou Liu struct ccsr_ddr __iomem *ddr = 264402fb2761SShengzhou Liu (struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_DDR_ADDR); 264502fb2761SShengzhou Liu u32 cpo, cpo_e, cpo_o, cpo_target, cpo_optimal; 264602fb2761SShengzhou Liu u32 cpo_min = ddr_in32(&ddr->debug[9]) >> 24; 264702fb2761SShengzhou Liu u32 cpo_max = cpo_min; 264802fb2761SShengzhou Liu u32 sdram_cfg, i, tmp, lanes, ddr_type; 264902fb2761SShengzhou Liu bool update_cpo = false, has_ecc = false; 265002fb2761SShengzhou Liu 265102fb2761SShengzhou Liu sdram_cfg = ddr_in32(&ddr->sdram_cfg); 265202fb2761SShengzhou Liu if (sdram_cfg & SDRAM_CFG_32_BE) 265302fb2761SShengzhou Liu lanes = 4; 265402fb2761SShengzhou Liu else if (sdram_cfg & SDRAM_CFG_16_BE) 265502fb2761SShengzhou Liu lanes = 2; 265602fb2761SShengzhou Liu else 265702fb2761SShengzhou Liu lanes = 8; 265802fb2761SShengzhou Liu 265902fb2761SShengzhou Liu if (sdram_cfg & SDRAM_CFG_ECC_EN) 266002fb2761SShengzhou Liu has_ecc = true; 266102fb2761SShengzhou Liu 266202fb2761SShengzhou Liu /* determine the maximum and minimum CPO values */ 266302fb2761SShengzhou Liu for (i = 9; i < 9 + lanes / 2; i++) { 266402fb2761SShengzhou Liu cpo = ddr_in32(&ddr->debug[i]); 266502fb2761SShengzhou Liu cpo_e = cpo >> 24; 266602fb2761SShengzhou Liu cpo_o = (cpo >> 8) & 0xff; 266702fb2761SShengzhou Liu tmp = min(cpo_e, cpo_o); 266802fb2761SShengzhou Liu if (tmp < cpo_min) 266902fb2761SShengzhou Liu cpo_min = tmp; 267002fb2761SShengzhou Liu tmp = max(cpo_e, cpo_o); 267102fb2761SShengzhou Liu if (tmp > cpo_max) 267202fb2761SShengzhou Liu cpo_max = tmp; 267302fb2761SShengzhou Liu } 267402fb2761SShengzhou Liu 267502fb2761SShengzhou Liu if (has_ecc) { 267602fb2761SShengzhou Liu cpo = ddr_in32(&ddr->debug[13]); 267702fb2761SShengzhou Liu cpo = cpo >> 24; 267802fb2761SShengzhou Liu if (cpo < cpo_min) 267902fb2761SShengzhou Liu cpo_min = cpo; 268002fb2761SShengzhou Liu if (cpo > cpo_max) 268102fb2761SShengzhou Liu cpo_max = cpo; 268202fb2761SShengzhou Liu } 268302fb2761SShengzhou Liu 268402fb2761SShengzhou Liu cpo_target = ddr_in32(&ddr->debug[28]) & 0xff; 268502fb2761SShengzhou Liu cpo_optimal = ((cpo_max + cpo_min) >> 1) + 0x27; 268602fb2761SShengzhou Liu debug("cpo_optimal = 0x%x, cpo_target = 0x%x\n", cpo_optimal, 268702fb2761SShengzhou Liu cpo_target); 268802fb2761SShengzhou Liu debug("cpo_max = 0x%x, cpo_min = 0x%x\n", cpo_max, cpo_min); 268902fb2761SShengzhou Liu 269002fb2761SShengzhou Liu ddr_type = (sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >> 269102fb2761SShengzhou Liu SDRAM_CFG_SDRAM_TYPE_SHIFT; 269202fb2761SShengzhou Liu if (ddr_type == SDRAM_TYPE_DDR4) 269302fb2761SShengzhou Liu update_cpo = (cpo_min + 0x3b) < cpo_target ? true : false; 269402fb2761SShengzhou Liu else if (ddr_type == SDRAM_TYPE_DDR3) 269502fb2761SShengzhou Liu update_cpo = (cpo_min + 0x3f) < cpo_target ? true : false; 269602fb2761SShengzhou Liu 269702fb2761SShengzhou Liu if (update_cpo) { 269802fb2761SShengzhou Liu printf("WARN: pls set popts->cpo_sample = 0x%x ", cpo_optimal); 269902fb2761SShengzhou Liu printf("in <board>/ddr.c to optimize cpo\n"); 270002fb2761SShengzhou Liu } 270102fb2761SShengzhou Liu } 270202fb2761SShengzhou Liu #endif 2703