diff options
Diffstat (limited to 'arch/powerpc/cpu/mpc8xxx/ddr/main.c')
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/main.c | 718 |
1 files changed, 0 insertions, 718 deletions
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c deleted file mode 100644 index 34d8bc3a..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - * 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 - * Version 2 as published by the Free Software Foundation. - */ - -/* - * Generic driver for Freescale DDR/DDR2/DDR3 memory controller. - * Based on code from spd_sdram.c - * Author: James Yang [at freescale.com] - */ - -#include <common.h> -#include <i2c.h> -#include <asm/fsl_ddr_sdram.h> -#include <asm/fsl_law.h> - -#include "ddr.h" - -void fsl_ddr_set_lawbar( - const common_timing_params_t *memctl_common_params, - unsigned int memctl_interleaved, - unsigned int ctrl_num); -void fsl_ddr_set_intl3r(const unsigned int granule_size); - -#if defined(SPD_EEPROM_ADDRESS) || \ - defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \ - defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4) -#if (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS, -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ - [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ - [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ - [2][0] = SPD_EEPROM_ADDRESS3, /* controller 3 */ -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ - [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ - [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ - [2][0] = SPD_EEPROM_ADDRESS5, /* controller 3 */ - [2][1] = SPD_EEPROM_ADDRESS6, /* controller 3 */ -}; - -#endif - -static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) -{ - int ret; - - i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM); - - ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, - sizeof(generic_spd_eeprom_t)); - - if (ret) { - if (i2c_address == -#ifdef SPD_EEPROM_ADDRESS - SPD_EEPROM_ADDRESS -#elif defined(SPD_EEPROM_ADDRESS1) - SPD_EEPROM_ADDRESS1 -#endif - ) { - printf("DDR: failed to read SPD from address %u\n", - i2c_address); - } else { - debug("DDR: failed to read SPD from address %u\n", - i2c_address); - } - memset(spd, 0, sizeof(generic_spd_eeprom_t)); - } -} - -__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 i; - unsigned int i2c_address = 0; - - if (ctrl_num >= CONFIG_NUM_DDR_CONTROLLERS) { - printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num); - return; - } - - for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; 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) -{ -} -#endif /* SPD_EEPROM_ADDRESSx */ - -/* - * ASSUMPTIONS: - * - Same number of CONFIG_DIMM_SLOTS_PER_CTLR on each controller - * - Same memory data bus width on all controllers - * - * NOTES: - * - * The memory controller and associated documentation use confusing - * terminology when referring to the orgranization of DRAM. - * - * Here is a terminology translation table: - * - * memory controller/documention |industry |this code |signals - * -------------------------------|-----------|-----------|----------------- - * physical bank/bank |rank |rank |chip select (CS) - * logical bank/sub-bank |bank |bank |bank address (BA) - * page/row |row |page |row address - * ??? |column |column |column address - * - * The naming confusion is further exacerbated by the descriptions of the - * memory controller interleaving feature, where accesses are interleaved - * _BETWEEN_ two seperate memory controllers. This is configured only in - * CS0_CONFIG[INTLV_CTL] of each memory controller. - * - * memory controller documentation | number of chip selects - * | per memory controller supported - * --------------------------------|----------------------------------------- - * cache line interleaving | 1 (CS0 only) - * page interleaving | 1 (CS0 only) - * bank interleaving | 1 (CS0 only) - * superbank interleraving | depends on bank (chip select) - * | interleraving [rank interleaving] - * | mode used on every memory controller - * - * Even further confusing is the existence of the interleaving feature - * _WITHIN_ each memory controller. The feature is referred to in - * documentation as chip select interleaving or bank interleaving, - * although it is configured in the DDR_SDRAM_CFG field. - * - * Name of field | documentation name | this code - * -----------------------------|-----------------------|------------------ - * DDR_SDRAM_CFG[BA_INTLV_CTL] | Bank (chip select) | rank interleaving - * | interleaving - */ - -const char *step_string_tbl[] = { - "STEP_GET_SPD", - "STEP_COMPUTE_DIMM_PARMS", - "STEP_COMPUTE_COMMON_PARMS", - "STEP_GATHER_OPTS", - "STEP_ASSIGN_ADDRESSES", - "STEP_COMPUTE_REGS", - "STEP_PROGRAM_REGS", - "STEP_ALL" -}; - -const char * step_to_string(unsigned int step) { - - unsigned int s = __ilog2(step); - - if ((1 << s) != step) - return step_string_tbl[7]; - - return step_string_tbl[s]; -} - -static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo, - unsigned int dbw_cap_adj[]) -{ - int i, j; - unsigned long long total_mem, current_mem_base, total_ctlr_mem; - unsigned long long rank_density, ctlr_density = 0; - - /* - * If a reduced data width is requested, but the SPD - * specifies a physically wider device, adjust the - * computed dimm capacities accordingly before - * assigning addresses. - */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - unsigned int found = 0; - - switch (pinfo->memctl_opts[i].data_bus_width) { - case 2: - /* 16-bit */ - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned int dw; - if (!pinfo->dimm_params[i][j].n_ranks) - continue; - dw = pinfo->dimm_params[i][j].primary_sdram_width; - if ((dw == 72 || dw == 64)) { - dbw_cap_adj[i] = 2; - break; - } else if ((dw == 40 || dw == 32)) { - dbw_cap_adj[i] = 1; - break; - } - } - break; - - case 1: - /* 32-bit */ - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned int dw; - dw = pinfo->dimm_params[i][j].data_width; - if (pinfo->dimm_params[i][j].n_ranks - && (dw == 72 || dw == 64)) { - /* - * FIXME: can't really do it - * like this because this just - * further reduces the memory - */ - found = 1; - break; - } - } - if (found) { - dbw_cap_adj[i] = 1; - } - break; - - case 0: - /* 64-bit */ - break; - - default: - printf("unexpected data bus width " - "specified controller %u\n", i); - return 1; - } - debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]); - } - - current_mem_base = 0ull; - 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 & - FSL_DDR_CS0_CS1_CS2_CS3) { - case FSL_DDR_CS0_CS1_CS2_CS3: - ctlr_density = 4 * rank_density; - break; - case FSL_DDR_CS0_CS1: - case FSL_DDR_CS0_CS1_AND_CS2_CS3: - ctlr_density = 2 * rank_density; - break; - case FSL_DDR_CS2_CS3: - default: - ctlr_density = rank_density; - break; - } - 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++) { - 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: - total_ctlr_mem = 2 * ctlr_density; - break; - case FSL_DDR_3WAY_1KB_INTERLEAVING: - case FSL_DDR_3WAY_4KB_INTERLEAVING: - case FSL_DDR_3WAY_8KB_INTERLEAVING: - total_ctlr_mem = 3 * ctlr_density; - break; - case FSL_DDR_4WAY_1KB_INTERLEAVING: - case FSL_DDR_4WAY_4KB_INTERLEAVING: - case FSL_DDR_4WAY_8KB_INTERLEAVING: - total_ctlr_mem = 4 * ctlr_density; - break; - default: - panic("Unknown interleaving mode"); - } - pinfo->common_timing_params[i].base_address = - current_mem_base; - pinfo->common_timing_params[i].total_mem = - total_ctlr_mem; - total_mem = current_mem_base + total_ctlr_mem; - debug("ctrl %d base 0x%llx\n", i, current_mem_base); - debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); - } else { - /* when 3rd controller not interleaved */ - current_mem_base = total_mem; - total_ctlr_mem = 0; - pinfo->common_timing_params[i].base_address = - current_mem_base; - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned long long cap = - pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; - pinfo->dimm_params[i][j].base_address = - current_mem_base; - debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); - current_mem_base += cap; - total_ctlr_mem += cap; - } - debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); - pinfo->common_timing_params[i].total_mem = - total_ctlr_mem; - total_mem += total_ctlr_mem; - } - } - } else { - /* - * Simple linear assignment if memory - * controllers are not interleaved. - */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - total_ctlr_mem = 0; - pinfo->common_timing_params[i].base_address = - current_mem_base; - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - /* Compute DIMM base addresses. */ - unsigned long long cap = - pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; - pinfo->dimm_params[i][j].base_address = - current_mem_base; - debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); - current_mem_base += cap; - total_ctlr_mem += cap; - } - debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); - pinfo->common_timing_params[i].total_mem = - total_ctlr_mem; - total_mem += total_ctlr_mem; - } - } - debug("Total mem by %s is 0x%llx\n", __func__, total_mem); - - return total_mem; -} - -/* Use weak function to allow board file to override the address assignment */ -__attribute__((weak, alias("__step_assign_addresses"))) -unsigned long long step_assign_addresses(fsl_ddr_info_t *pinfo, - unsigned int dbw_cap_adj[]); - -unsigned long long -fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, - unsigned int size_only) -{ - unsigned int i, j; - unsigned long long total_mem = 0; - int assert_reset; - - 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(); - - /* 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++) { - dbw_capacity_adjust[i] = 0; - } - - debug("starting at step %u (%s)\n", - start_step, step_to_string(start_step)); - - switch (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); - } - - case STEP_COMPUTE_DIMM_PARMS: - /* STEP 2: Compute DIMM parameters from SPD data */ - - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; 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); - } -#else - if (retval == 2) { - printf("Error: compute_dimm_parameters" - " non-zero returned FATAL value " - "for memctl=%u dimm=%u\n", i, j); - return 0; - } -#endif - if (retval) { - debug("Warning: compute_dimm_parameters" - " non-zero return value for memctl=%u " - "dimm=%u\n", i, j); - } - } - } - -#elif defined(CONFIG_SYS_DDR_RAW_TIMING) - case STEP_COMPUTE_DIMM_PARMS: - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - dimm_params_t *pdimm = - &(pinfo->dimm_params[i][j]); - fsl_ddr_get_dimm_params(pdimm, i, j); - } - } - debug("Filling dimm parameters from board specific file\n"); -#endif - case STEP_COMPUTE_COMMON_PARMS: - /* - * 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++) { - debug("Computing lowest common DIMM" - " parameters for memctl=%u\n", i); - compute_lowest_common_dimm_parameters( - pinfo->dimm_params[i], - &timing_params[i], - CONFIG_DIMM_SLOTS_PER_CTLR); - } - - case STEP_GATHER_OPTS: - /* STEP 4: Gather configuration requirements from user */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - debug("Reloading memory controller " - "configuration options for memctl=%u\n", i); - /* - * This "reloads" the memory controller options - * to defaults. If the user "edits" an option, - * next_step points to the step after this, - * which is currently STEP_ASSIGN_ADDRESSES. - */ - populate_memctl_options( - timing_params[i].all_dimms_registered, - &pinfo->memctl_opts[i], - pinfo->dimm_params[i], i); - /* - * For RDIMMs, JEDEC spec requires clocks to be stable - * before reset signal is deasserted. For the boards - * using fixed parameters, this function should be - * be called from board init file. - */ - if (timing_params[i].all_dimms_registered) - assert_reset = 1; - } - if (assert_reset) { - debug("Asserting mem reset\n"); - board_assert_mem_reset(); - } - - case STEP_ASSIGN_ADDRESSES: - /* STEP 5: Assign addresses to chip selects */ - check_interleaving_options(pinfo); - total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust); - - 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++) { - if (timing_params[i].ndimms_present == 0) { - memset(&ddr_reg[i], 0, - sizeof(fsl_ddr_cfg_regs_t)); - continue; - } - - compute_fsl_memctl_config_regs( - &pinfo->memctl_opts[i], - &ddr_reg[i], &timing_params[i], - pinfo->dimm_params[i], - dbw_capacity_adjust[i], - size_only); - } - - default: - break; - } - - { - /* - * Compute the amount of memory available just by - * looking for the highest valid CSn_BNDS value. - * This allows us to also experiment with using - * only CS0 when using dual-rank DIMMs. - */ - unsigned int max_end = 0; - - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; 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) { - unsigned int end; - /* - * 0xfffffff is a special value we put - * for unused bnds - */ - if (reg->cs[j].bnds == 0xffffffff) - continue; - end = reg->cs[j].bnds & 0xffff; - if (end > max_end) { - max_end = end; - } - } - } - } - - total_mem = 1 + (((unsigned long long)max_end << 24ULL) - | 0xFFFFFFULL); - } - - 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) -{ - unsigned int i; - unsigned int law_memctl = LAW_TRGT_IF_DDR_1; - unsigned long long total_memory; - fsl_ddr_info_t info; - int deassert_reset; - - /* Reset info structure. */ - memset(&info, 0, sizeof(fsl_ddr_info_t)); - - /* 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); - } else if (fsl_ddr_interactive_env_var_exists()) { - total_memory = fsl_ddr_interactive(&info, 1); - } else -#endif - total_memory = fsl_ddr_compute(&info, 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; - } - } - - /* - * Program configuration registers. - * JEDEC specs requires clocks to be stable before deasserting reset - * for RDIMMs. Clocks start after chip select is enabled and clock - * control register is set. During step 1, all controllers have their - * registers set but not enabled. Step 2 proceeds after deasserting - * reset through board FPGA or GPIO. - * 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) - deassert_reset = 1; - } - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - debug("Programming controller %u\n", i); - if (info.common_timing_params[i].ndimms_present == 0) { - debug("No dimms present on controller %u; " - "skipping programming\n", i); - continue; - } - /* - * 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, - 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++) { - /* Call with step = 2 to continue initialization */ - fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), - i, 2); - } - } - - /* 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) { - case FSL_DDR_CACHE_LINE_INTERLEAVING: - case FSL_DDR_PAGE_INTERLEAVING: - case FSL_DDR_BANK_INTERLEAVING: - case FSL_DDR_SUPERBANK_INTERLEAVING: - if (i == 0) { - law_memctl = LAW_TRGT_IF_DDR_INTRLV; - fsl_ddr_set_lawbar(&info.common_timing_params[i], - law_memctl, i); - } else if (i == 2) { - law_memctl = LAW_TRGT_IF_DDR_INTLV_34; - fsl_ddr_set_lawbar(&info.common_timing_params[i], - law_memctl, i); - } - 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], - law_memctl, i); - } - break; - case FSL_DDR_4WAY_1KB_INTERLEAVING: - case FSL_DDR_4WAY_4KB_INTERLEAVING: - 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], - law_memctl, i); - /* place holder for future 4-way interleaving */ - break; - default: - break; - } - } else { - switch (i) { - case 0: - law_memctl = LAW_TRGT_IF_DDR_1; - break; - case 1: - law_memctl = LAW_TRGT_IF_DDR_2; - break; - case 2: - law_memctl = LAW_TRGT_IF_DDR_3; - break; - case 3: - law_memctl = LAW_TRGT_IF_DDR_4; - break; - default: - break; - } - fsl_ddr_set_lawbar(&info.common_timing_params[i], - law_memctl, i); - } - } - - debug("total_memory by %s = %llu\n", __func__, total_memory); - -#if !defined(CONFIG_PHYS_64BIT) - /* Check for 4G or more. Bad. */ - if (total_memory >= (1ull << 32)) { - puts("Detected "); - print_size(total_memory, " of memory\n"); - printf(" This U-Boot only supports < 4G of DDR\n"); - printf(" You could rebuild it with CONFIG_PHYS_64BIT\n"); - printf(" "); /* re-align to match init_func_ram print */ - total_memory = CONFIG_MAX_MEM_MAPPED; - } -#endif - - return total_memory; -} - -/* - * fsl_ddr_sdram_size() - This function only returns the size of the total - * memory without setting ddr control registers. - */ -phys_size_t -fsl_ddr_sdram_size(void) -{ - fsl_ddr_info_t info; - unsigned long long total_memory = 0; - - memset(&info, 0 , sizeof(fsl_ddr_info_t)); - - /* Compute it once normally. */ - total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1); - - return total_memory; -} |