diff options
-rw-r--r-- | README | 6 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/cpu.c | 4 | ||||
-rw-r--r-- | drivers/ddr/fsl/ddr4_dimm_params.c | 12 | ||||
-rw-r--r-- | drivers/ddr/fsl/main.c | 244 | ||||
-rw-r--r-- | drivers/ddr/fsl/options.c | 23 | ||||
-rw-r--r-- | drivers/ddr/fsl/util.c | 26 | ||||
-rw-r--r-- | include/fsl_ddr.h | 15 | ||||
-rw-r--r-- | include/fsl_ddr_sdram.h | 16 |
8 files changed, 238 insertions, 108 deletions
@@ -538,6 +538,12 @@ The following options need to be configured: interleaving mode, handled by Dickens for Freescale layerscape SoCs with ARM core. + CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS + Number of controllers used as main memory. + + CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS + Number of controllers used for other than main memory. + - Intel Monahans options: CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 6274f92..3d6ec84 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -441,7 +441,7 @@ phys_size_t initdram(int board_type) /* Board-specific functions defined in each board's ddr.c */ void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, - unsigned int ctrl_num); + unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl); void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn, phys_addr_t *rpn); unsigned int @@ -459,7 +459,7 @@ static void dump_spd_ddr_reg(void) spd[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR]; for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - fsl_ddr_get_spd(spd[i], i); + fsl_ddr_get_spd(spd[i], i, CONFIG_DIMM_SLOTS_PER_CTLR); puts("SPD data of all dimms (zero vaule is omitted)...\n"); puts("Byte (hex) "); diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 4745b7f..2418dca 100644 --- a/drivers/ddr/fsl/ddr4_dimm_params.c +++ b/drivers/ddr/fsl/ddr4_dimm_params.c @@ -113,7 +113,7 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd) #define spd_to_ps(mtb, ftb) \ (mtb * pdimm->mtb_ps + (ftb * pdimm->ftb_10th_ps) / 10) /* - * ddr_compute_dimm_parameters for DDR3 SPD + * ddr_compute_dimm_parameters for DDR4 SPD * * Compute DIMM parameters based upon the SPD information in spd. * Writes the results to the dimm_params_t structure pointed by pdimm. @@ -165,17 +165,17 @@ ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd, + pdimm->ec_sdram_width; pdimm->device_width = 1 << ((spd->organization & 0x7) + 2); - /* These are the types defined by the JEDEC DDR3 SPD spec */ + /* These are the types defined by the JEDEC SPD spec */ pdimm->mirrored_dimm = 0; pdimm->registered_dimm = 0; - switch (spd->module_type & DDR3_SPD_MODULETYPE_MASK) { - case DDR3_SPD_MODULETYPE_RDIMM: + switch (spd->module_type & DDR4_SPD_MODULETYPE_MASK) { + case DDR4_SPD_MODULETYPE_RDIMM: /* Registered/buffered DIMMs */ pdimm->registered_dimm = 1; break; - case DDR3_SPD_MODULETYPE_UDIMM: - case DDR3_SPD_MODULETYPE_SO_DIMM: + case DDR4_SPD_MODULETYPE_UDIMM: + case DDR4_SPD_MODULETYPE_SO_DIMM: /* Unbuffered DIMMs */ if (spd->mod_section.unbuffered.addr_mapping & 0x1) pdimm->mirrored_dimm = 1; diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index 5e001fc..b43b669 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -135,7 +135,7 @@ __attribute__((weak, alias("__get_spd"))) void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address); void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, - unsigned int ctrl_num) + unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl) { unsigned int i; unsigned int i2c_address = 0; @@ -145,14 +145,14 @@ void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, return; } - for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { + for (i = 0; i < dimm_slots_per_ctrl; i++) { i2c_address = spd_i2c_addr[ctrl_num][i]; get_spd(&(ctrl_dimms_spd[i]), i2c_address); } } #else void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, - unsigned int ctrl_num) + unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl) { } #endif /* SPD_EEPROM_ADDRESSx */ @@ -231,9 +231,11 @@ const char * step_to_string(unsigned int step) { static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo, unsigned int dbw_cap_adj[]) { - int i, j; + unsigned int i, j; unsigned long long total_mem, current_mem_base, total_ctlr_mem; unsigned long long rank_density, ctlr_density = 0; + unsigned int first_ctrl = pinfo->first_ctrl; + unsigned int last_ctrl = first_ctrl + pinfo->num_ctrls - 1; /* * If a reduced data width is requested, but the SPD @@ -241,7 +243,7 @@ static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo, * computed dimm capacities accordingly before * assigning addresses. */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { unsigned int found = 0; switch (pinfo->memctl_opts[i].data_bus_width) { @@ -295,12 +297,12 @@ static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo, debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]); } - current_mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY; + current_mem_base = pinfo->mem_base; total_mem = 0; - if (pinfo->memctl_opts[0].memctl_interleaving) { - rank_density = pinfo->dimm_params[0][0].rank_density >> - dbw_cap_adj[0]; - switch (pinfo->memctl_opts[0].ba_intlv_ctl & + if (pinfo->memctl_opts[first_ctrl].memctl_interleaving) { + rank_density = pinfo->dimm_params[first_ctrl][0].rank_density >> + dbw_cap_adj[first_ctrl]; + switch (pinfo->memctl_opts[first_ctrl].ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { case FSL_DDR_CS0_CS1_CS2_CS3: ctlr_density = 4 * rank_density; @@ -316,7 +318,7 @@ static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo, } debug("rank density is 0x%llx, ctlr density is 0x%llx\n", rank_density, ctlr_density); - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { if (pinfo->memctl_opts[i].memctl_interleaving) { switch (pinfo->memctl_opts[i].memctl_interleaving_mode) { case FSL_DDR_256B_INTERLEAVING: @@ -372,7 +374,7 @@ static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo, * Simple linear assignment if memory * controllers are not interleaved. */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { total_ctlr_mem = 0; pinfo->common_timing_params[i].base_address = current_mem_base; @@ -408,18 +410,23 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, { unsigned int i, j; unsigned long long total_mem = 0; - int assert_reset; + int assert_reset = 0; + unsigned int first_ctrl = pinfo->first_ctrl; + unsigned int last_ctrl = first_ctrl + pinfo->num_ctrls - 1; + __maybe_unused int retval; + __maybe_unused bool goodspd = false; + __maybe_unused int dimm_slots_per_ctrl = pinfo->dimm_slots_per_ctrl; fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg; common_timing_params_t *timing_params = pinfo->common_timing_params; - assert_reset = board_need_mem_reset(); + if (pinfo->board_need_mem_reset) + assert_reset = pinfo->board_need_mem_reset(); /* data bus width capacity adjust shift amount */ unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS]; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) dbw_capacity_adjust[i] = 0; - } debug("starting at step %u (%s)\n", start_step, step_to_string(start_step)); @@ -428,28 +435,28 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, case STEP_GET_SPD: #if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM) /* STEP 1: Gather all DIMM SPD data */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i); + for (i = first_ctrl; i <= last_ctrl; i++) { + fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i, + dimm_slots_per_ctrl); } case STEP_COMPUTE_DIMM_PARMS: /* STEP 2: Compute DIMM parameters from SPD data */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned int retval; generic_spd_eeprom_t *spd = &(pinfo->spd_installed_dimms[i][j]); dimm_params_t *pdimm = &(pinfo->dimm_params[i][j]); - retval = compute_dimm_parameters(spd, pdimm, i); #ifdef CONFIG_SYS_DDR_RAW_TIMING if (!i && !j && retval) { printf("SPD error on controller %d! " "Trying fallback to raw timing " "calculation\n", i); - fsl_ddr_get_dimm_params(pdimm, i, j); + retval = fsl_ddr_get_dimm_params(pdimm, + i, j); } #else if (retval == 2) { @@ -463,13 +470,26 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, debug("Warning: compute_dimm_parameters" " non-zero return value for memctl=%u " "dimm=%u\n", i, j); + } else { + goodspd = true; } } } + if (!goodspd) { + /* + * No valid SPD found + * Throw an error if this is for main memory, i.e. + * first_ctrl == 0. Otherwise, siliently return 0 + * as the memory size. + */ + if (first_ctrl == 0) + printf("Error: No valid SPD detected.\n"); + return 0; + } #elif defined(CONFIG_SYS_DDR_RAW_TIMING) case STEP_COMPUTE_DIMM_PARMS: - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { dimm_params_t *pdimm = &(pinfo->dimm_params[i][j]); @@ -483,7 +503,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, * STEP 3: Compute a common set of timing parameters * suitable for all of the DIMMs on each memory controller */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { debug("Computing lowest common DIMM" " parameters for memctl=%u\n", i); compute_lowest_common_dimm_parameters( @@ -494,7 +514,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, case STEP_GATHER_OPTS: /* STEP 4: Gather configuration requirements from user */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { debug("Reloading memory controller " "configuration options for memctl=%u\n", i); /* @@ -516,9 +536,13 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, if (timing_params[i].all_dimms_registered) assert_reset = 1; } - if (assert_reset) { - debug("Asserting mem reset\n"); - board_assert_mem_reset(); + if (assert_reset && !size_only) { + if (pinfo->board_mem_reset) { + debug("Asserting mem reset\n"); + pinfo->board_mem_reset(); + } else { + debug("Asserting mem reset missing\n"); + } } case STEP_ASSIGN_ADDRESSES: @@ -530,7 +554,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, case STEP_COMPUTE_REGS: /* STEP 6: compute controller register values */ debug("FSL Memory ctrl register computation\n"); - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { if (timing_params[i].ndimms_present == 0) { memset(&ddr_reg[i], 0, sizeof(fsl_ddr_cfg_regs_t)); @@ -558,7 +582,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, */ unsigned int max_end = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { for (j = 0; j < CONFIG_CHIP_SELECTS_PER_CTRL; j++) { fsl_ddr_cfg_regs_t *reg = &ddr_reg[i]; if (reg->cs[j].config & 0x80000000) { @@ -578,53 +602,45 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, } total_mem = 1 + (((unsigned long long)max_end << 24ULL) | - 0xFFFFFFULL) - CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY; + 0xFFFFFFULL) - pinfo->mem_base; } return total_mem; } -/* - * fsl_ddr_sdram() -- this is the main function to be called by - * initdram() in the board file. - * - * It returns amount of memory configured in bytes. - */ -phys_size_t fsl_ddr_sdram(void) +phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo) { - unsigned int i; + unsigned int i, first_ctrl, last_ctrl; #ifdef CONFIG_PPC unsigned int law_memctl = LAW_TRGT_IF_DDR_1; #endif unsigned long long total_memory; - fsl_ddr_info_t info; - int deassert_reset; + int deassert_reset = 0; - /* Reset info structure. */ - memset(&info, 0, sizeof(fsl_ddr_info_t)); + first_ctrl = pinfo->first_ctrl; + last_ctrl = first_ctrl + pinfo->num_ctrls - 1; /* Compute it once normally. */ #ifdef CONFIG_FSL_DDR_INTERACTIVE if (tstc() && (getc() == 'd')) { /* we got a key press of 'd' */ - total_memory = fsl_ddr_interactive(&info, 0); + total_memory = fsl_ddr_interactive(pinfo, 0); } else if (fsl_ddr_interactive_env_var_exists()) { - total_memory = fsl_ddr_interactive(&info, 1); + total_memory = fsl_ddr_interactive(pinfo, 1); } else #endif - total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0); + total_memory = fsl_ddr_compute(pinfo, STEP_GET_SPD, 0); /* setup 3-way interleaving before enabling DDRC */ - if (info.memctl_opts[0].memctl_interleaving) { - switch (info.memctl_opts[0].memctl_interleaving_mode) { - case FSL_DDR_3WAY_1KB_INTERLEAVING: - case FSL_DDR_3WAY_4KB_INTERLEAVING: - case FSL_DDR_3WAY_8KB_INTERLEAVING: - fsl_ddr_set_intl3r( - info.memctl_opts[0].memctl_interleaving_mode); - break; - default: - break; - } + switch (pinfo->memctl_opts[first_ctrl].memctl_interleaving_mode) { + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + fsl_ddr_set_intl3r( + pinfo->memctl_opts[first_ctrl]. + memctl_interleaving_mode); + break; + default: + break; } /* @@ -637,14 +653,15 @@ phys_size_t fsl_ddr_sdram(void) * For non-registered DIMMs, initialization can go through but it is * also OK to follow the same flow. */ - deassert_reset = board_need_mem_reset(); - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (info.common_timing_params[i].all_dimms_registered) + if (pinfo->board_need_mem_reset) + deassert_reset = pinfo->board_need_mem_reset(); + for (i = first_ctrl; i <= last_ctrl; i++) { + if (pinfo->common_timing_params[i].all_dimms_registered) deassert_reset = 1; } - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = first_ctrl; i <= last_ctrl; i++) { debug("Programming controller %u\n", i); - if (info.common_timing_params[i].ndimms_present == 0) { + if (pinfo->common_timing_params[i].ndimms_present == 0) { debug("No dimms present on controller %u; " "skipping programming\n", i); continue; @@ -653,45 +670,58 @@ phys_size_t fsl_ddr_sdram(void) * The following call with step = 1 returns before enabling * the controller. It has to finish with step = 2 later. */ - fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i, + fsl_ddr_set_memctl_regs(&(pinfo->fsl_ddr_config_reg[i]), i, deassert_reset ? 1 : 0); } if (deassert_reset) { /* Use board FPGA or GPIO to deassert reset signal */ - debug("Deasserting mem reset\n"); - board_deassert_mem_reset(); - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + if (pinfo->board_mem_de_reset) { + debug("Deasserting mem reset\n"); + pinfo->board_mem_de_reset(); + } else { + debug("Deasserting mem reset missing\n"); + } + for (i = first_ctrl; i <= last_ctrl; i++) { /* Call with step = 2 to continue initialization */ - fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), + fsl_ddr_set_memctl_regs(&(pinfo->fsl_ddr_config_reg[i]), i, 2); } } #ifdef CONFIG_PPC /* program LAWs */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (info.memctl_opts[i].memctl_interleaving) { - switch (info.memctl_opts[i].memctl_interleaving_mode) { + for (i = first_ctrl; i <= last_ctrl; i++) { + if (pinfo->memctl_opts[i].memctl_interleaving) { + switch (pinfo->memctl_opts[i]. + memctl_interleaving_mode) { case FSL_DDR_CACHE_LINE_INTERLEAVING: case FSL_DDR_PAGE_INTERLEAVING: case FSL_DDR_BANK_INTERLEAVING: case FSL_DDR_SUPERBANK_INTERLEAVING: + if (i % 2) + break; if (i == 0) { law_memctl = LAW_TRGT_IF_DDR_INTRLV; - fsl_ddr_set_lawbar(&info.common_timing_params[i], + fsl_ddr_set_lawbar( + &pinfo->common_timing_params[i], law_memctl, i); - } else if (i == 2) { + } +#if CONFIG_NUM_DDR_CONTROLLERS > 3 + else if (i == 2) { law_memctl = LAW_TRGT_IF_DDR_INTLV_34; - fsl_ddr_set_lawbar(&info.common_timing_params[i], + fsl_ddr_set_lawbar( + &pinfo->common_timing_params[i], law_memctl, i); } +#endif break; case FSL_DDR_3WAY_1KB_INTERLEAVING: case FSL_DDR_3WAY_4KB_INTERLEAVING: case FSL_DDR_3WAY_8KB_INTERLEAVING: law_memctl = LAW_TRGT_IF_DDR_INTLV_123; if (i == 0) { - fsl_ddr_set_lawbar(&info.common_timing_params[i], + fsl_ddr_set_lawbar( + &pinfo->common_timing_params[i], law_memctl, i); } break; @@ -700,7 +730,8 @@ phys_size_t fsl_ddr_sdram(void) case FSL_DDR_4WAY_8KB_INTERLEAVING: law_memctl = LAW_TRGT_IF_DDR_INTLV_1234; if (i == 0) - fsl_ddr_set_lawbar(&info.common_timing_params[i], + fsl_ddr_set_lawbar( + &pinfo->common_timing_params[i], law_memctl, i); /* place holder for future 4-way interleaving */ break; @@ -724,8 +755,8 @@ phys_size_t fsl_ddr_sdram(void) default: break; } - fsl_ddr_set_lawbar(&info.common_timing_params[i], - law_memctl, i); + fsl_ddr_set_lawbar(&pinfo->common_timing_params[i], + law_memctl, i); } } #endif @@ -734,7 +765,7 @@ phys_size_t fsl_ddr_sdram(void) #if !defined(CONFIG_PHYS_64BIT) /* Check for 4G or more. Bad. */ - if (total_memory >= (1ull << 32)) { + if ((first_ctrl == 0) && (total_memory >= (1ull << 32))) { puts("Detected "); print_size(total_memory, " of memory\n"); printf(" This U-Boot only supports < 4G of DDR\n"); @@ -748,8 +779,56 @@ phys_size_t fsl_ddr_sdram(void) } /* - * fsl_ddr_sdram_size() - This function only returns the size of the total - * memory without setting ddr control registers. + * fsl_ddr_sdram(void) -- this is the main function to be + * called by initdram() in the board file. + * + * It returns amount of memory configured in bytes. + */ +phys_size_t fsl_ddr_sdram(void) +{ + fsl_ddr_info_t info; + + /* Reset info structure. */ + memset(&info, 0, sizeof(fsl_ddr_info_t)); + info.mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY; + info.first_ctrl = 0; + info.num_ctrls = CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS; + info.dimm_slots_per_ctrl = CONFIG_DIMM_SLOTS_PER_CTLR; + info.board_need_mem_reset = board_need_mem_reset; + info.board_mem_reset = board_assert_mem_reset; + info.board_mem_de_reset = board_deassert_mem_reset; + + return __fsl_ddr_sdram(&info); +} + +#ifdef CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS +phys_size_t fsl_other_ddr_sdram(unsigned long long base, + unsigned int first_ctrl, + unsigned int num_ctrls, + unsigned int dimm_slots_per_ctrl, + int (*board_need_reset)(void), + void (*board_reset)(void), + void (*board_de_reset)(void)) +{ + fsl_ddr_info_t info; + + /* Reset info structure. */ + memset(&info, 0, sizeof(fsl_ddr_info_t)); + info.mem_base = base; + info.first_ctrl = first_ctrl; + info.num_ctrls = num_ctrls; + info.dimm_slots_per_ctrl = dimm_slots_per_ctrl; + info.board_need_mem_reset = board_need_reset; + info.board_mem_reset = board_reset; + info.board_mem_de_reset = board_de_reset; + + return __fsl_ddr_sdram(&info); +} +#endif + +/* + * fsl_ddr_sdram_size(first_ctrl, last_intlv) - This function only returns the + * size of the total memory without setting ddr control registers. */ phys_size_t fsl_ddr_sdram_size(void) @@ -758,6 +837,11 @@ fsl_ddr_sdram_size(void) unsigned long long total_memory = 0; memset(&info, 0 , sizeof(fsl_ddr_info_t)); + info.mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY; + info.first_ctrl = 0; + info.num_ctrls = CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS; + info.dimm_slots_per_ctrl = CONFIG_DIMM_SLOTS_PER_CTLR; + info.board_need_mem_reset = NULL; /* Compute it once normally. */ total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1); diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index 5986e1a..31cc2bf 100644 --- a/drivers/ddr/fsl/options.c +++ b/drivers/ddr/fsl/options.c @@ -1065,18 +1065,21 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo) unsigned int check_intlv, check_n_row_addr, check_n_col_addr; unsigned long long check_rank_density; struct dimm_params_s *dimm; + int first_ctrl = pinfo->first_ctrl; + int last_ctrl = first_ctrl + pinfo->num_ctrls - 1; + /* * Check if all controllers are configured for memory * controller interleaving. Identical dimms are recommended. At least * the size, row and col address should be checked. */ j = 0; - check_n_ranks = pinfo->dimm_params[0][0].n_ranks; - check_rank_density = pinfo->dimm_params[0][0].rank_density; - check_n_row_addr = pinfo->dimm_params[0][0].n_row_addr; - check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr; - check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + check_n_ranks = pinfo->dimm_params[first_ctrl][0].n_ranks; + check_rank_density = pinfo->dimm_params[first_ctrl][0].rank_density; + check_n_row_addr = pinfo->dimm_params[first_ctrl][0].n_row_addr; + check_n_col_addr = pinfo->dimm_params[first_ctrl][0].n_col_addr; + check_intlv = pinfo->memctl_opts[first_ctrl].memctl_interleaving_mode; + for (i = first_ctrl; i <= last_ctrl; i++) { dimm = &pinfo->dimm_params[i][0]; if (!pinfo->memctl_opts[i].memctl_interleaving) { continue; @@ -1094,7 +1097,7 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo) } if (intlv_invalid) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) + for (i = first_ctrl; i <= last_ctrl; i++) pinfo->memctl_opts[i].memctl_interleaving = 0; printf("Not all DIMMs are identical. " "Memory controller interleaving disabled.\n"); @@ -1123,10 +1126,10 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo) } debug("%d of %d controllers are interleaving.\n", j, k); if (j && (j != k)) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) + for (i = first_ctrl; i <= last_ctrl; i++) pinfo->memctl_opts[i].memctl_interleaving = 0; - printf("Not all controllers have compatible " - "interleaving mode. All disabled.\n"); + if ((last_ctrl - first_ctrl) > 1) + puts("Not all controllers have compatible interleaving mode. All disabled.\n"); } } debug("Checking interleaving options completed\n"); diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c index 7a22aa3..58b519b 100644 --- a/drivers/ddr/fsl/util.c +++ b/drivers/ddr/fsl/util.c @@ -149,7 +149,7 @@ u32 fsl_ddr_get_intl3r(void) return val; } -void board_add_ram_info(int use_default) +void print_ddr_info(unsigned int start_ctrl) { struct ccsr_ddr __iomem *ddr = (struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_DDR_ADDR); @@ -164,17 +164,25 @@ void board_add_ram_info(int use_default) int cas_lat; #if CONFIG_NUM_DDR_CONTROLLERS >= 2 - if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) { + if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) || + (start_ctrl == 1)) { ddr = (void __iomem *)CONFIG_SYS_FSL_DDR2_ADDR; sdram_cfg = ddr_in32(&ddr->sdram_cfg); } #endif #if CONFIG_NUM_DDR_CONTROLLERS >= 3 - if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) { + if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) || + (start_ctrl == 2)) { ddr = (void __iomem *)CONFIG_SYS_FSL_DDR3_ADDR; sdram_cfg = ddr_in32(&ddr->sdram_cfg); } #endif + + if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) { + puts(" (DDR not enabled)\n"); + return; + } + puts(" (DDR"); switch ((sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >> SDRAM_CFG_SDRAM_TYPE_SHIFT) { @@ -241,7 +249,7 @@ void board_add_ram_info(int use_default) #endif #endif #if (CONFIG_NUM_DDR_CONTROLLERS >= 2) - if (cs0_config & 0x20000000) { + if ((cs0_config & 0x20000000) && (start_ctrl == 0)) { puts("\n"); puts(" DDR Controller Interleaving Mode: "); @@ -290,3 +298,13 @@ void board_add_ram_info(int use_default) } } } + +void __weak detail_board_ddr_info(void) +{ + print_ddr_info(0); +} + +void board_add_ram_info(int use_default) +{ + detail_board_ddr_info(); +} diff --git a/include/fsl_ddr.h b/include/fsl_ddr.h index 5c49b22..675557a 100644 --- a/include/fsl_ddr.h +++ b/include/fsl_ddr.h @@ -15,6 +15,11 @@ #include <common_timing_params.h> +#ifndef CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS +/* All controllers are for main memory */ +#define CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS CONFIG_NUM_DDR_CONTROLLERS +#endif + #ifdef CONFIG_SYS_FSL_DDR_LE #define ddr_in32(a) in_le32(a) #define ddr_out32(a, v) out_le32(a, v) @@ -57,6 +62,13 @@ typedef struct { memctl_options_t memctl_opts[CONFIG_SYS_NUM_DDR_CTLRS]; common_timing_params_t common_timing_params[CONFIG_SYS_NUM_DDR_CTLRS]; fsl_ddr_cfg_regs_t fsl_ddr_config_reg[CONFIG_SYS_NUM_DDR_CTLRS]; + unsigned int first_ctrl; + unsigned int num_ctrls; + unsigned long long mem_base; + unsigned int dimm_slots_per_ctrl; + int (*board_need_mem_reset)(void); + void (*board_mem_reset)(void); + void (*board_mem_de_reset)(void); } fsl_ddr_info_t; /* Compute steps */ @@ -72,7 +84,6 @@ typedef struct { unsigned long long fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, unsigned int size_only); - const char *step_to_string(unsigned int step); unsigned int compute_fsl_memctl_config_regs(const memctl_options_t *popts, @@ -102,7 +113,7 @@ void fsl_ddr_set_lawbar( int fsl_ddr_interactive_env_var_exists(void); unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set); void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, - unsigned int ctrl_num); + unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl); int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); unsigned int check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr); diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h index 987119b..d03901f 100644 --- a/include/fsl_ddr_sdram.h +++ b/include/fsl_ddr_sdram.h @@ -379,12 +379,20 @@ typedef struct memctl_options_s { unsigned int trwt; /* read-to-write turnaround */ } memctl_options_t; -extern phys_size_t fsl_ddr_sdram(void); -extern phys_size_t fsl_ddr_sdram_size(void); +phys_size_t fsl_ddr_sdram(void); +phys_size_t fsl_ddr_sdram_size(void); +phys_size_t fsl_other_ddr_sdram(unsigned long long base, + unsigned int first_ctrl, + unsigned int num_ctrls, + unsigned int dimm_slots_per_ctrl, + int (*board_need_reset)(void), + void (*board_reset)(void), + void (*board_de_reset)(void)); extern int fsl_use_spd(void); -extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, - unsigned int ctrl_num, int step); +void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, + unsigned int ctrl_num, int step); u32 fsl_ddr_get_intl3r(void); +void print_ddr_info(unsigned int start_ctrl); static void __board_assert_mem_reset(void) { |