X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=arch%2Fpowerpc%2Fcpu%2Fmpc8xxx%2Fddr%2Fctrl_regs.c;h=dcfc48aa957f6774c488b34b8eb00a2bd645626c;hb=509dca7a11aad394d781a9d31a7bfa6692562741;hp=a8b2132f9032481fd76bfa4eba6203824a02089c;hpb=fcea30688fd8c47d54473ffd0f551a5e6efc74a0;p=u-boot diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index a8b2132f90..dcfc48aa95 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -1,10 +1,7 @@ /* * Copyright 2008-2012 Freescale Semiconductor, Inc. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. + * SPDX-License-Identifier: GPL-2.0+ */ /* @@ -18,17 +15,9 @@ #include "ddr.h" -#ifdef CONFIG_MPC83xx - #define _DDR_ADDR CONFIG_SYS_MPC83xx_DDR_ADDR -#elif defined(CONFIG_MPC85xx) - #define _DDR_ADDR CONFIG_SYS_MPC85xx_DDR_ADDR -#elif defined(CONFIG_MPC86xx) - #define _DDR_ADDR CONFIG_SYS_MPC86xx_DDR_ADDR -#else - #error "Undefined _DDR_ADDR" -#endif +#define _DDR_ADDR CONFIG_SYS_MPC8xxx_DDR_ADDR -u32 fsl_ddr_get_version(void) +static u32 fsl_ddr_get_version(void) { ccsr_ddr_t *ddr; u32 ver_major_minor_errata; @@ -151,8 +140,19 @@ static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, if (dimm_params[dimm_number].n_ranks > 0) { go_config = 1; /* These fields only available in CS0_CONFIG */ - intlv_en = popts->memctl_interleaving; - intlv_ctl = popts->memctl_interleaving_mode; + if (!popts->memctl_interleaving) + break; + switch (popts->memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + intlv_en = popts->memctl_interleaving; + intlv_ctl = popts->memctl_interleaving_mode; + break; + default: + break; + } } break; case 1: @@ -218,6 +218,26 @@ static void set_csn_config_2(int i, fsl_ddr_cfg_regs_t *ddr) /* -3E = 667 CL5, -25 = CL6 800, -25E = CL5 800 */ #if !defined(CONFIG_FSL_DDR1) +static inline int avoid_odt_overlap(const dimm_params_t *dimm_params) +{ +#if CONFIG_DIMM_SLOTS_PER_CTLR == 1 + if (dimm_params[0].n_ranks == 4) + return 1; +#endif + +#if CONFIG_DIMM_SLOTS_PER_CTLR == 2 + if ((dimm_params[0].n_ranks == 2) && + (dimm_params[1].n_ranks == 2)) + return 1; + +#ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE + if (dimm_params[0].n_ranks == 4) + return 1; +#endif +#endif + return 0; +} + /* * DDR SDRAM Timing Configuration 0 (TIMING_CFG_0) * @@ -225,7 +245,8 @@ static void set_csn_config_2(int i, fsl_ddr_cfg_regs_t *ddr) * dreams up non-zero default values to be backwards compatible. */ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts) + const memctl_options_t *popts, + const dimm_params_t *dimm_params) { unsigned char trwt_mclk = 0; /* Read-to-write turnaround */ unsigned char twrt_mclk = 0; /* Write-to-read turnaround */ @@ -255,7 +276,18 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, unsigned int data_rate = get_ddr_freq(0); tmrd_mclk = 4; /* set the turnaround time */ - trwt_mclk = 1; + + /* + * for single quad-rank DIMM and two dual-rank DIMMs + * to avoid ODT overlap + */ + if (avoid_odt_overlap(dimm_params)) { + twwt_mclk = 2; + trrt_mclk = 1; + } + /* for faster clock, need more time for data setup */ + trwt_mclk = (data_rate/1000000 > 1800) ? 2 : 1; + if ((data_rate/1000000 > 1150) || (popts->memctl_interleaving)) twrt_mclk = 1; @@ -302,29 +334,41 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, const common_timing_params_t *common_dimm, unsigned int cas_latency) { + /* Extended precharge to activate interval (tRP) */ + unsigned int ext_pretoact = 0; /* Extended Activate to precharge interval (tRAS) */ unsigned int ext_acttopre = 0; - unsigned int ext_refrec; /* Extended refresh recovery time (tRFC) */ - unsigned int ext_caslat = 0; /* Extended MCAS latency from READ cmd */ - unsigned int cntl_adj = 0; /* Control Adjust */ - - /* If the tRAS > 19 MCLK, we use the ext mode */ - if (picos_to_mclk(common_dimm->tRAS_ps) > 0x13) - ext_acttopre = 1; - - ext_refrec = (picos_to_mclk(common_dimm->tRFC_ps) - 8) >> 4; - - /* If the CAS latency more than 8, use the ext mode */ - if (cas_latency > 8) - ext_caslat = 1; + /* Extended activate to read/write interval (tRCD) */ + unsigned int ext_acttorw = 0; + /* Extended refresh recovery time (tRFC) */ + unsigned int ext_refrec; + /* Extended MCAS latency from READ cmd */ + unsigned int ext_caslat = 0; + /* Extended last data to precharge interval (tWR) */ + unsigned int ext_wrrec = 0; + /* Control Adjust */ + unsigned int cntl_adj = 0; + + ext_pretoact = picos_to_mclk(common_dimm->trp_ps) >> 4; + ext_acttopre = picos_to_mclk(common_dimm->tras_ps) >> 4; + ext_acttorw = picos_to_mclk(common_dimm->trcd_ps) >> 4; + ext_caslat = (2 * cas_latency - 1) >> 4; + ext_refrec = (picos_to_mclk(common_dimm->trfc_ps) - 8) >> 4; + /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ + ext_wrrec = (picos_to_mclk(common_dimm->twr_ps) + + (popts->otf_burst_chop_en ? 2 : 0)) >> 4; ddr->timing_cfg_3 = (0 - | ((ext_acttopre & 0x1) << 24) - | ((ext_refrec & 0xF) << 16) - | ((ext_caslat & 0x1) << 12) + | ((ext_pretoact & 0x1) << 28) + | ((ext_acttopre & 0x3) << 24) + | ((ext_acttorw & 0x1) << 22) + | ((ext_refrec & 0x1F) << 16) + | ((ext_caslat & 0x3) << 12) + | ((ext_wrrec & 0x1) << 8) | ((cntl_adj & 0x7) << 0) ); debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3); @@ -356,9 +400,9 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, static const u8 wrrec_table[] = { 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0}; - pretoact_mclk = picos_to_mclk(common_dimm->tRP_ps); - acttopre_mclk = picos_to_mclk(common_dimm->tRAS_ps); - acttorw_mclk = picos_to_mclk(common_dimm->tRCD_ps); + pretoact_mclk = picos_to_mclk(common_dimm->trp_ps); + acttopre_mclk = picos_to_mclk(common_dimm->tras_ps); + acttorw_mclk = picos_to_mclk(common_dimm->trcd_ps); /* * Translate CAS Latency to a DDR controller field value: @@ -386,19 +430,20 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, * we need set extend bit for it at * TIMING_CFG_3[EXT_CASLAT] */ - if (cas_latency > 8) - cas_latency -= 8; caslat_ctrl = 2 * cas_latency - 1; #endif - refrec_ctrl = picos_to_mclk(common_dimm->tRFC_ps) - 8; - wrrec_mclk = picos_to_mclk(common_dimm->tWR_ps); + refrec_ctrl = picos_to_mclk(common_dimm->trfc_ps) - 8; + wrrec_mclk = picos_to_mclk(common_dimm->twr_ps); - wrrec_mclk = wrrec_table[wrrec_mclk - 1]; - if (popts->OTF_burst_chop_en) + if (wrrec_mclk > 16) + printf("Error: WRREC doesn't support more than 16 clocks\n"); + else + wrrec_mclk = wrrec_table[wrrec_mclk - 1]; + if (popts->otf_burst_chop_en) wrrec_mclk += 2; - acttoact_mclk = picos_to_mclk(common_dimm->tRRD_ps); + acttoact_mclk = picos_to_mclk(common_dimm->trrd_ps); /* * JEDEC has min requirement for tRRD */ @@ -406,7 +451,7 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, if (acttoact_mclk < 4) acttoact_mclk = 4; #endif - wrtord_mclk = picos_to_mclk(common_dimm->tWTR_ps); + wrtord_mclk = picos_to_mclk(common_dimm->twtr_ps); /* * JEDEC has some min requirements for tWTR */ @@ -417,7 +462,7 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, if (wrtord_mclk < 4) wrtord_mclk = 4; #endif - if (popts->OTF_burst_chop_en) + if (popts->otf_burst_chop_en) wrtord_mclk += 2; ddr->timing_cfg_1 = (0 @@ -427,8 +472,8 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, | ((caslat_ctrl & 0xF) << 16) | ((refrec_ctrl & 0xF) << 12) | ((wrrec_mclk & 0x0F) << 8) - | ((acttoact_mclk & 0x07) << 4) - | ((wrtord_mclk & 0x07) << 0) + | ((acttoact_mclk & 0x0F) << 4) + | ((wrtord_mclk & 0x0F) << 0) ); debug("FSLDDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1); } @@ -473,7 +518,7 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr, wr_lat = compute_cas_write_latency(); #endif - rd_to_pre = picos_to_mclk(common_dimm->tRTP_ps); + rd_to_pre = picos_to_mclk(common_dimm->trtp_ps); /* * JEDEC has some min requirements for tRTP */ @@ -486,12 +531,12 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr, #endif if (additive_latency) rd_to_pre += additive_latency; - if (popts->OTF_burst_chop_en) + if (popts->otf_burst_chop_en) rd_to_pre += 2; /* according to UM */ wr_data_delay = popts->write_data_delay; - cke_pls = picos_to_mclk(popts->tCKE_clock_pulse_width_ps); - four_act = picos_to_mclk(popts->tFAW_window_four_activates_ps); + cke_pls = picos_to_mclk(popts->tcke_clock_pulse_width_ps); + four_act = picos_to_mclk(popts->tfaw_window_four_activates_ps); ddr->timing_cfg_2 = (0 | ((add_lat_mclk & 0xf) << 28) @@ -510,8 +555,8 @@ static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const common_timing_params_t *common_dimm) { - if (common_dimm->all_DIMMs_registered - && !common_dimm->all_DIMMs_unbuffered) { + if (common_dimm->all_dimms_registered && + !common_dimm->all_dimms_unbuffered) { if (popts->rcw_override) { ddr->ddr_sdram_rcw_1 = popts->rcw_1; ddr->ddr_sdram_rcw_2 = popts->rcw_2; @@ -554,8 +599,8 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, unsigned int dbw; /* DRAM dta bus width */ unsigned int eight_be = 0; /* 8-beat burst enable, DDR2 is zero */ unsigned int ncap = 0; /* Non-concurrent auto-precharge */ - unsigned int threeT_en; /* Enable 3T timing */ - unsigned int twoT_en; /* Enable 2T timing */ + unsigned int threet_en; /* Enable 3T timing */ + unsigned int twot_en; /* Enable 2T timing */ unsigned int ba_intlv_ctl; /* Bank (CS) interleaving control */ unsigned int x32_en = 0; /* x32 enable */ unsigned int pchb8 = 0; /* precharge bit 8 enable */ @@ -565,20 +610,20 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, mem_en = 1; sren = popts->self_refresh_in_sleep; - if (common_dimm->all_DIMMs_ECC_capable) { + if (common_dimm->all_dimms_ecc_capable) { /* Allow setting of ECC only if all DIMMs are ECC. */ - ecc_en = popts->ECC_mode; + ecc_en = popts->ecc_mode; } else { ecc_en = 0; } - if (common_dimm->all_DIMMs_registered - && !common_dimm->all_DIMMs_unbuffered) { + if (common_dimm->all_dimms_registered && + !common_dimm->all_dimms_unbuffered) { rd_en = 1; - twoT_en = 0; + twot_en = 0; } else { rd_en = 0; - twoT_en = popts->twoT_en; + twot_en = popts->twot_en; } sdram_type = CONFIG_FSL_SDRAM_TYPE; @@ -598,7 +643,7 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, eight_be = 1; } - threeT_en = popts->threeT_en; + threet_en = popts->threet_en; ba_intlv_ctl = popts->ba_intlv_ctl; hse = popts->half_strength_driver_enable; @@ -612,8 +657,8 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, | ((dbw & 0x3) << 19) | ((eight_be & 0x1) << 18) | ((ncap & 0x1) << 17) - | ((threeT_en & 0x1) << 16) - | ((twoT_en & 0x1) << 15) + | ((threet_en & 0x1) << 16) + | ((twot_en & 0x1) << 15) | ((ba_intlv_ctl & 0x7F) << 8) | ((x32_en & 0x1) << 5) | ((pchb8 & 0x1) << 4) @@ -635,6 +680,8 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, unsigned int dqs_cfg; /* DQS configuration */ unsigned int odt_cfg = 0; /* ODT configuration */ unsigned int num_pr; /* Number of posted refreshes */ + unsigned int slow = 0; /* DDR will be run less than 1250 */ + unsigned int x4_en = 0; /* x4 DRAM enable */ unsigned int obc_cfg; /* On-The-Fly Burst Chop Cfg */ unsigned int ap_en; /* Address Parity Enable */ unsigned int d_init; /* DRAM data initialization */ @@ -644,7 +691,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, int i; dll_rst_dis = 1; /* Make this configurable */ - dqs_cfg = popts->DQS_config; + dqs_cfg = popts->dqs_config; for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { if (popts->cs_local_opts[i].odt_rd_cfg || popts->cs_local_opts[i].odt_wr_cfg) { @@ -663,11 +710,15 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, * << DDR_SDRAM_INTERVAL[REFINT] */ #if defined(CONFIG_FSL_DDR3) - obc_cfg = popts->OTF_burst_chop_en; + obc_cfg = popts->otf_burst_chop_en; #else obc_cfg = 0; #endif +#if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7) + slow = get_ddr_freq(0) < 1249000000; +#endif + if (popts->registered_dimm_en) { rcw_en = 1; ap_en = popts->ap_en; @@ -675,9 +726,11 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, ap_en = 0; } + x4_en = popts->x4_en ? 1 : 0; + #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) /* Use the DDR controller to auto initialize memory. */ - d_init = popts->ECC_init_using_memctl; + d_init = popts->ecc_init_using_memctl; ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE; debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init); #else @@ -696,6 +749,8 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, | ((dqs_cfg & 0x3) << 26) | ((odt_cfg & 0x3) << 21) | ((num_pr & 0xf) << 12) + | ((slow & 1) << 11) + | (x4_en << 10) | (qd_en << 9) | (unq_mrs_en << 8) | ((obc_cfg & 0x1) << 6) @@ -710,6 +765,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, + const common_timing_params_t *common_dimm, const unsigned int unq_mrs_en) { unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ @@ -727,6 +783,10 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, rtt_wr = popts->rtt_wr_override_value; else rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; + + if (common_dimm->extended_op_srt) + srt = common_dimm->extended_op_srt; + esdmode2 = (0 | ((rtt_wr & 0x3) << 9) | ((srt & 0x1) << 7) @@ -884,7 +944,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, */ dll_on = 1; - wr_mclk = (common_dimm->tWR_ps + mclk_ps - 1) / mclk_ps; + wr_mclk = (common_dimm->twr_ps + mclk_ps - 1) / mclk_ps; if (wr_mclk <= 16) { wr = wr_table[wr_mclk - 5]; } else { @@ -1046,7 +1106,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, #if defined(CONFIG_FSL_DDR2) const unsigned int mclk_ps = get_memory_clk_period_ps(); #endif - dqs_en = !popts->DQS_config; + dqs_en = !popts->dqs_config; rtt = fsl_ddr_get_rtt(); al = additive_latency; @@ -1075,7 +1135,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, #if defined(CONFIG_FSL_DDR1) wr = 0; /* Historical */ #elif defined(CONFIG_FSL_DDR2) - wr = (common_dimm->tWR_ps + mclk_ps - 1) / mclk_ps - 1; + wr = (common_dimm->twr_ps + mclk_ps - 1) / mclk_ps - 1; #endif dll_res = 0; mode = 0; @@ -1136,7 +1196,11 @@ static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr) { unsigned int init_value; /* Initialization value */ +#ifdef CONFIG_MEM_INIT_VALUE + init_value = CONFIG_MEM_INIT_VALUE; +#else init_value = 0xDEADBEEF; +#endif ddr->ddr_data_init = init_value; } @@ -1323,6 +1387,11 @@ static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en, | ((wrlvl_start & 0x1F) << 0) ); debug("FSLDDR: wrlvl_cntl = 0x%08x\n", ddr->ddr_wrlvl_cntl); + ddr->ddr_wrlvl_cntl_2 = popts->wrlvl_ctl_2; + debug("FSLDDR: wrlvl_cntl_2 = 0x%08x\n", ddr->ddr_wrlvl_cntl_2); + ddr->ddr_wrlvl_cntl_3 = popts->wrlvl_ctl_3; + debug("FSLDDR: wrlvl_cntl_3 = 0x%08x\n", ddr->ddr_wrlvl_cntl_3); + } /* DDR Self Refresh Counter (DDR_SR_CNTR) */ @@ -1346,6 +1415,12 @@ static void set_ddr_cdr1(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) debug("FSLDDR: ddr_cdr1 = 0x%08x\n", ddr->ddr_cdr1); } +static void set_ddr_cdr2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) +{ + ddr->ddr_cdr2 = popts->ddr_cdr2; + debug("FSLDDR: ddr_cdr2 = 0x%08x\n", ddr->ddr_cdr2); +} + unsigned int check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) { @@ -1413,73 +1488,37 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, /* Chip Select Memory Bounds (CSn_BNDS) */ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { - unsigned long long ea = 0, sa = 0; + unsigned long long ea, sa; unsigned int cs_per_dimm = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; unsigned int dimm_number = i / cs_per_dimm; unsigned long long rank_density - = dimm_params[dimm_number].rank_density; + = dimm_params[dimm_number].rank_density >> dbw_cap_adj; - if (((i == 1) && (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1)) || - ((i == 2) && (popts->ba_intlv_ctl & 0x04)) || - ((i == 3) && (popts->ba_intlv_ctl & FSL_DDR_CS2_CS3))) { - /* - * Don't set up boundaries for unused CS - * cs1 for cs0_cs1, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3 - * cs2 for cs0_cs1_cs2_cs3 - * cs3 for cs2_cs3, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3 - * But we need to set the ODT_RD_CFG and - * ODT_WR_CFG for CS1_CONFIG here. - */ - set_csn_config(dimm_number, i, ddr, popts, dimm_params); - continue; - } if (dimm_params[dimm_number].n_ranks == 0) { debug("Skipping setup of CS%u " "because n_ranks on DIMM %u is 0\n", i, dimm_number); continue; } - if (popts->memctl_interleaving && popts->ba_intlv_ctl) { - /* - * This works superbank 2CS - * There are 2 or more memory controllers configured - * identically, memory is interleaved between them, - * and each controller uses rank interleaving within - * itself. Therefore the starting and ending address - * on each controller is twice the amount present on - * each controller. If any CS is not included in the - * interleaving, the memory on that CS is not accssible - * and the total memory size is reduced. The CS is also - * disabled. - */ - unsigned long long ctlr_density = 0; + if (popts->memctl_interleaving) { switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { + case FSL_DDR_CS0_CS1_CS2_CS3: + break; case FSL_DDR_CS0_CS1: case FSL_DDR_CS0_CS1_AND_CS2_CS3: - ctlr_density = dimm_params[0].rank_density * 2; if (i > 1) cs_en = 0; break; case FSL_DDR_CS2_CS3: - ctlr_density = dimm_params[0].rank_density; + default: if (i > 0) cs_en = 0; break; - case FSL_DDR_CS0_CS1_CS2_CS3: - /* - * The four CS interleaving should have been verified by - * populate_memctl_options() - */ - ctlr_density = dimm_params[0].rank_density * 4; - break; - default: - break; } - ea = (CONFIG_NUM_DDR_CONTROLLERS * - (ctlr_density >> dbw_cap_adj)) - 1; - } - else if (!popts->memctl_interleaving && popts->ba_intlv_ctl) { + sa = common_dimm->base_address; + ea = sa + common_dimm->total_mem - 1; + } else if (!popts->memctl_interleaving) { /* * If memory interleaving between controllers is NOT * enabled, the starting address for each memory @@ -1491,49 +1530,40 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, */ switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { case FSL_DDR_CS0_CS1_CS2_CS3: - /* CS0+CS1+CS2+CS3 interleaving, only CS0_CNDS - * needs to be set. - */ sa = common_dimm->base_address; - ea = sa + (4 * (rank_density >> dbw_cap_adj))-1; + ea = sa + common_dimm->total_mem - 1; break; case FSL_DDR_CS0_CS1_AND_CS2_CS3: - /* CS0+CS1 and CS2+CS3 interleaving, CS0_CNDS - * and CS2_CNDS need to be set. - */ - if ((i == 2) && (dimm_number == 0)) { + if ((i >= 2) && (dimm_number == 0)) { sa = dimm_params[dimm_number].base_address + - 2 * (rank_density >> dbw_cap_adj); - ea = sa + 2 * (rank_density >> dbw_cap_adj) - 1; + 2 * rank_density; + ea = sa + 2 * rank_density - 1; } else { sa = dimm_params[dimm_number].base_address; - ea = sa + (2 * (rank_density >> - dbw_cap_adj)) - 1; + ea = sa + 2 * rank_density - 1; } break; case FSL_DDR_CS0_CS1: - /* CS0+CS1 interleaving, CS0_CNDS needs - * to be set - */ if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); + ea = sa + rank_density - 1; + if (i != 1) + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; } else { sa = 0; ea = 0; } if (i == 0) - ea += (rank_density >> dbw_cap_adj); + ea += rank_density; break; case FSL_DDR_CS2_CS3: - /* CS2+CS3 interleaving*/ if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); + ea = sa + rank_density - 1; + if (i != 3) + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; } else { sa = 0; ea = 0; @@ -1542,53 +1572,35 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, ea += (rank_density >> dbw_cap_adj); break; default: /* No bank(chip-select) interleaving */ + sa = dimm_params[dimm_number].base_address; + ea = sa + rank_density - 1; + if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; + } else { + sa = 0; + ea = 0; + } break; } } - else if (popts->memctl_interleaving && !popts->ba_intlv_ctl) { - /* - * Only the rank on CS0 of each memory controller may - * be used if memory controller interleaving is used - * without rank interleaving within each memory - * controller. However, the ending address programmed - * into each CS0 must be the sum of the amount of - * memory in the two CS0 ranks. - */ - if (i == 0) { - ea = (2 * (rank_density >> dbw_cap_adj)) - 1; - } - - } - else if (!popts->memctl_interleaving && !popts->ba_intlv_ctl) { - /* - * No rank interleaving and no memory controller - * interleaving. - */ - sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - } else { - sa = 0; - ea = 0; - } - } sa >>= 24; ea >>= 24; - ddr->cs[i].bnds = (0 - | ((sa & 0xFFF) << 16) /* starting address MSB */ - | ((ea & 0xFFF) << 0) /* ending address MSB */ - ); + if (cs_en) { + ddr->cs[i].bnds = (0 + | ((sa & 0xFFF) << 16)/* starting address MSB */ + | ((ea & 0xFFF) << 0) /* ending address MSB */ + ); + } else { + /* setting bnds to 0xffffffff for inactive CS */ + ddr->cs[i].bnds = 0xffffffff; + } debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds); - if (cs_en) { - set_csn_config(dimm_number, i, ddr, popts, dimm_params); - set_csn_config_2(i, ddr); - } else - debug("CS%d is disabled.\n", i); + set_csn_config(dimm_number, i, ddr, popts, dimm_params); + set_csn_config_2(i, ddr); } /* @@ -1601,15 +1613,16 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_ddr_eor(ddr, popts); #if !defined(CONFIG_FSL_DDR1) - set_timing_cfg_0(ddr, popts); + set_timing_cfg_0(ddr, popts, dimm_params); #endif - set_timing_cfg_3(ddr, common_dimm, cas_latency); + set_timing_cfg_3(ddr, popts, common_dimm, cas_latency); set_timing_cfg_1(ddr, popts, common_dimm, cas_latency); set_timing_cfg_2(ddr, popts, common_dimm, cas_latency, additive_latency); set_ddr_cdr1(ddr, popts); + set_ddr_cdr2(ddr, popts); set_ddr_sdram_cfg(ddr, popts, common_dimm); ip_rev = fsl_ddr_get_version(); if (ip_rev > 0x40400) @@ -1618,7 +1631,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en); set_ddr_sdram_mode(ddr, popts, common_dimm, cas_latency, additive_latency, unq_mrs_en); - set_ddr_sdram_mode_2(ddr, popts, unq_mrs_en); + set_ddr_sdram_mode_2(ddr, popts, common_dimm, unq_mrs_en); set_ddr_sdram_interval(ddr, popts, common_dimm); set_ddr_data_init(ddr); set_ddr_sdram_clk_cntl(ddr, popts); @@ -1634,5 +1647,10 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_ddr_sdram_rcw(ddr, popts, common_dimm); +#ifdef CONFIG_SYS_FSL_DDR_EMU + /* disble DDR training for emulator */ + ddr->debug[2] = 0x00000400; + ddr->debug[4] = 0xff800000; +#endif return check_fsl_memctl_config_regs(ddr); }