powerpc/mpc8xxx: Enable 3-way and 4-way DDR interleaving

Restructure DDR interleaving option to support 3 and 4 DDR controllers
for 2-, 3- and 4-way interleaving.

Signed-off-by: York Sun <yorksun@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
master
York Sun 12 years ago committed by Andy Fleming
parent fcea30688f
commit a4c66509f1
  1. 12
      arch/powerpc/cpu/mpc85xx/cpu.c
  2. 12
      arch/powerpc/cpu/mpc85xx/ddr-gen3.c
  3. 144
      arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
  4. 305
      arch/powerpc/cpu/mpc8xxx/ddr/main.c
  5. 211
      arch/powerpc/cpu/mpc8xxx/ddr/options.c
  6. 67
      arch/powerpc/cpu/mpc8xxx/ddr/util.c
  7. 7
      arch/powerpc/include/asm/fsl_ddr_sdram.h
  8. 12
      arch/powerpc/include/asm/fsl_law.h
  9. 3
      arch/powerpc/include/asm/immap_85xx.h
  10. 36
      doc/README.fsl-ddr

@ -430,11 +430,21 @@ static void dump_spd_ddr_reg(void)
case 0:
ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
break;
#ifdef CONFIG_SYS_MPC85xx_DDR2_ADDR
#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
break;
#endif
#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
break;
#endif
#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR;
break;
#endif
default:
printf("%s unexpected controller number = %u\n",
__func__, i);

@ -32,9 +32,21 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
case 0:
ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
break;
#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
break;
#endif
#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
break;
#endif
#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR;
break;
#endif
default:
printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
return;

@ -151,8 +151,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:
@ -1413,73 +1424,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 = 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 +1466,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 = 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,38 +1508,18 @@ 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;

@ -1,5 +1,5 @@
/*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
* 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
@ -15,13 +15,15 @@
#include <common.h>
#include <i2c.h>
#include <asm/fsl_ddr_sdram.h>
#include <asm/fsl_law.h>
#include "ddr.h"
extern void fsl_ddr_set_lawbar(
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);
/* processor specific function */
extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
@ -51,6 +53,22 @@ u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
[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)
@ -156,12 +174,12 @@ const char * step_to_string(unsigned int step) {
return step_string_tbl[s];
}
int step_assign_addresses(fsl_ddr_info_t *pinfo,
unsigned int dbw_cap_adj[],
unsigned int *all_memctl_interleaving,
unsigned int *all_ctlr_rank_interleaving)
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
@ -220,86 +238,108 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,
"specified controller %u\n", i);
return 1;
}
debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]);
}
j = 0;
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
if (pinfo->memctl_opts[i].memctl_interleaving)
j++;
/*
* Not support less than all memory controllers interleaving
* if more than two controllers
*/
if (j == CONFIG_NUM_DDR_CONTROLLERS)
*all_memctl_interleaving = 1;
/* Check that all controllers are rank interleaving. */
j = 0;
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
if (pinfo->memctl_opts[i].ba_intlv_ctl)
j++;
/*
* All memory controllers must be populated to qualify for
* all controller rank interleaving
*/
if (j == CONFIG_NUM_DDR_CONTROLLERS)
*all_ctlr_rank_interleaving = 1;
if (*all_memctl_interleaving) {
unsigned long long addr, total_mem_per_ctlr = 0;
/*
* If interleaving between memory controllers,
* make each controller start at a base address
* of 0.
*
* Also, if bank interleaving (chip select
* interleaving) is enabled on each memory
* controller, CS0 needs to be programmed to
* cover the entire memory range on that memory
* controller
*
* Bank interleaving also implies that each
* addressed chip select is identical in size.
*/
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++) {
addr = 0;
pinfo->common_timing_params[i].base_address = 0ull;
for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
unsigned long long cap
= pinfo->dimm_params[i][j].capacity;
pinfo->dimm_params[i][j].base_address = addr;
addr += cap >> dbw_cap_adj[i];
total_mem_per_ctlr += cap >> dbw_cap_adj[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;
}
}
pinfo->common_timing_params[0].total_mem = total_mem_per_ctlr;
} else {
/*
* Simple linear assignment if memory
* controllers are not interleaved.
*/
unsigned long long cur_memsize = 0;
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
u64 total_mem_per_ctlr = 0;
total_ctlr_mem = 0;
pinfo->common_timing_params[i].base_address =
cur_memsize;
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;
pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i];
pinfo->dimm_params[i][j].base_address =
cur_memsize;
cur_memsize += cap >> dbw_cap_adj[i];
total_mem_per_ctlr += cap >> dbw_cap_adj[i];
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_mem_per_ctlr;
total_ctlr_mem;
total_mem += total_ctlr_mem;
}
}
debug("Total mem by %s is 0x%llx\n", __func__, total_mem);
return 0;
return total_mem;
}
unsigned long long
@ -307,8 +347,6 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
unsigned int size_only)
{
unsigned int i, j;
unsigned int all_controllers_memctl_interleaving = 0;
unsigned int all_controllers_rank_interleaving = 0;
unsigned long long total_mem = 0;
fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
@ -346,8 +384,9 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
retval = compute_dimm_parameters(spd, pdimm, i);
#ifdef CONFIG_SYS_DDR_RAW_TIMING
if (retval != 0) {
printf("SPD error! Trying fallback to "
"raw timing calculation\n");
printf("SPD error on controller %d! "
"Trying fallback to raw timing "
"calculation\n", i);
fsl_ddr_get_dimm_params(pdimm, i, j);
}
#else
@ -407,17 +446,14 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
&pinfo->memctl_opts[i],
pinfo->dimm_params[i], i);
}
check_interleaving_options(pinfo);
case STEP_ASSIGN_ADDRESSES:
/* STEP 5: Assign addresses to chip selects */
step_assign_addresses(pinfo,
dbw_capacity_adjust,
&all_controllers_memctl_interleaving,
&all_controllers_rank_interleaving);
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 cg register computation\n");
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,
@ -437,21 +473,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
break;
}
/* Compute the total amount of memory. */
/*
* If bank interleaving but NOT memory controller interleaving
* CS_BNDS describe the quantity of memory on each memory
* controller, so the total is the sum across.
*/
if (!all_controllers_memctl_interleaving
&& all_controllers_rank_interleaving) {
total_mem = 0;
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
total_mem += timing_params[i].total_mem;
}
} else {
{
/*
* Compute the amount of memory available just by
* looking for the highest valid CSn_BNDS value.
@ -489,7 +511,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
phys_size_t fsl_ddr_sdram(void)
{
unsigned int i;
unsigned int memctl_interleaved;
unsigned int law_memctl = LAW_TRGT_IF_DDR_1;
unsigned long long total_memory;
fsl_ddr_info_t info;
@ -504,34 +526,6 @@ phys_size_t fsl_ddr_sdram(void)
#endif
total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0);
/* Check for memory controller interleaving. */
memctl_interleaved = 0;
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
memctl_interleaved +=
info.memctl_opts[i].memctl_interleaving;
}
if (memctl_interleaved) {
if (memctl_interleaved == CONFIG_NUM_DDR_CONTROLLERS) {
debug("memctl interleaving\n");
/*
* Change the meaning of memctl_interleaved
* to be "boolean".
*/
memctl_interleaved = 1;
} else {
printf("Warning: memctl interleaving not "
"properly configured on all controllers\n");
memctl_interleaved = 0;
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
info.memctl_opts[i].memctl_interleaving = 0;
debug("Recomputing with memctl_interleaving off.\n");
total_memory = fsl_ddr_compute(&info,
STEP_ASSIGN_ADDRESSES,
0);
}
}
/* Program configuration registers. */
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
debug("Programming controller %u\n", i);
@ -544,24 +538,69 @@ phys_size_t fsl_ddr_sdram(void)
fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i);
}
if (memctl_interleaved) {
const unsigned int ctrl_num = 0;
/* Only set LAWBAR1 if memory controller interleaving is on. */
fsl_ddr_set_lawbar(&info.common_timing_params[0],
memctl_interleaved, ctrl_num);
} else {
/*
* Memory controller interleaving is NOT on;
* set each lawbar individually.
*/
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
/* 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_intl3r(info.memctl_opts[i].memctl_interleaving_mode);
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],
0, i);
law_memctl, i);
}
}
debug("total_memory = %llu\n", total_memory);
debug("total_memory by %s = %llu\n", __func__, total_memory);
#if !defined(CONFIG_PHYS_64BIT)
/* Check for 4G or more. Bad. */

@ -1,5 +1,5 @@
/*
* Copyright 2008, 2010-2011 Freescale Semiconductor, Inc.
* Copyright 2008, 2010-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
@ -790,46 +790,97 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
* should be a subset of the requested configuration.
*/
#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
if (hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) {
if (pdimm[0].n_ranks == 0) {
printf("There is no rank on CS0 for controller %d. Because only"
" rank on CS0 and ranks chip-select interleaved with CS0"
" are controller interleaved, force non memory "
"controller interleaving\n", ctrl_num);
popts->memctl_interleaving = 0;
} else {
popts->memctl_interleaving = 1;
/*
* test null first. if CONFIG_HWCONFIG is not defined
* hwconfig_arg_cmp returns non-zero
*/
if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
"null", buf)) {
popts->memctl_interleaving = 0;
debug("memory controller interleaving disabled.\n");
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"cacheline", buf))
popts->memctl_interleaving_mode =
FSL_DDR_CACHE_LINE_INTERLEAVING;
else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
"page", buf))
popts->memctl_interleaving_mode =
FSL_DDR_PAGE_INTERLEAVING;
else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
"bank", buf))
popts->memctl_interleaving_mode =
FSL_DDR_BANK_INTERLEAVING;
else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
"superbank", buf))
popts->memctl_interleaving_mode =
FSL_DDR_SUPERBANK_INTERLEAVING;
else {
popts->memctl_interleaving = 0;
printf("hwconfig has unrecognized parameter for ctlr_intlv.\n");
}
}
if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf))
goto done;
if (pdimm[0].n_ranks == 0) {
printf("There is no rank on CS0 for controller %d.\n", ctrl_num);
popts->memctl_interleaving = 0;
goto done;
}
popts->memctl_interleaving = 1;
/*
* test null first. if CONFIG_HWCONFIG is not defined
* hwconfig_arg_cmp returns non-zero
*/
if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
"null", buf)) {
popts->memctl_interleaving = 0;
debug("memory controller interleaving disabled.\n");
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"cacheline", buf)) {
popts->memctl_interleaving_mode =
((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
0 : FSL_DDR_CACHE_LINE_INTERLEAVING;
popts->memctl_interleaving =
((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
0 : 1;
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"page", buf)) {
popts->memctl_interleaving_mode =
((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
0 : FSL_DDR_PAGE_INTERLEAVING;
popts->memctl_interleaving =
((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
0 : 1;
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"bank", buf)) {
popts->memctl_interleaving_mode =
((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
0 : FSL_DDR_BANK_INTERLEAVING;
popts->memctl_interleaving =
((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
0 : 1;
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"superbank", buf)) {
popts->memctl_interleaving_mode =
((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
0 : FSL_DDR_SUPERBANK_INTERLEAVING;
popts->memctl_interleaving =
((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
0 : 1;
#if (CONFIG_NUM_DDR_CONTROLLERS == 3)
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"3way_1KB", buf)) {
popts->memctl_interleaving_mode =
FSL_DDR_3WAY_1KB_INTERLEAVING;
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"3way_4KB", buf)) {
popts->memctl_interleaving_mode =
FSL_DDR_3WAY_4KB_INTERLEAVING;
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"3way_8KB", buf)) {
popts->memctl_interleaving_mode =
FSL_DDR_3WAY_8KB_INTERLEAVING;
#elif (CONFIG_NUM_DDR_CONTROLLERS == 4)
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"4way_1KB", buf)) {
popts->memctl_interleaving_mode =
FSL_DDR_4WAY_1KB_INTERLEAVING;
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"4way_4KB", buf)) {
popts->memctl_interleaving_mode =
FSL_DDR_4WAY_4KB_INTERLEAVING;
} else if (hwconfig_subarg_cmp_f("fsl_ddr",
"ctlr_intlv",
"4way_8KB", buf)) {
popts->memctl_interleaving_mode =
FSL_DDR_4WAY_8KB_INTERLEAVING;
#endif
} else {
popts->memctl_interleaving = 0;
printf("hwconfig has unrecognized parameter for ctlr_intlv.\n");
}
done:
#endif
if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) &&
(CONFIG_CHIP_SELECTS_PER_CTRL > 1)) {
@ -859,20 +910,20 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
popts->ba_intlv_ctl = 0;
printf("Not enough bank(chip-select) for "
"CS0+CS1+CS2+CS3 on controller %d, "
"force non-interleaving!\n", ctrl_num);
"interleaving disabled!\n", ctrl_num);
}
#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) {
popts->ba_intlv_ctl = 0;
printf("Not enough bank(chip-select) for "
"CS0+CS1+CS2+CS3 on controller %d, "
"force non-interleaving!\n", ctrl_num);
"interleaving disabled!\n", ctrl_num);
}
if (pdimm[0].capacity != pdimm[1].capacity) {
popts->ba_intlv_ctl = 0;
printf("Not identical DIMM size for "
"CS0+CS1+CS2+CS3 on controller %d, "
"force non-interleaving!\n", ctrl_num);
"interleaving disabled!\n", ctrl_num);
}
#endif
break;
@ -881,7 +932,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
popts->ba_intlv_ctl = 0;
printf("Not enough bank(chip-select) for "
"CS0+CS1 on controller %d, "
"force non-interleaving!\n", ctrl_num);
"interleaving disabled!\n", ctrl_num);
}
break;
case FSL_DDR_CS2_CS3:
@ -889,13 +940,13 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
if (pdimm[0].n_ranks < 4) {
popts->ba_intlv_ctl = 0;
printf("Not enough bank(chip-select) for CS2+CS3 "
"on controller %d, force non-interleaving!\n", ctrl_num);
"on controller %d, interleaving disabled!\n", ctrl_num);
}
#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if (pdimm[1].n_ranks < 2) {
popts->ba_intlv_ctl = 0;
printf("Not enough bank(chip-select) for CS2+CS3 "
"on controller %d, force non-interleaving!\n", ctrl_num);
"on controller %d, interleaving disabled!\n", ctrl_num);
}
#endif
break;
@ -905,14 +956,14 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
popts->ba_intlv_ctl = 0;
printf("Not enough bank(CS) for CS0+CS1 and "
"CS2+CS3 on controller %d, "
"force non-interleaving!\n", ctrl_num);
"interleaving disabled!\n", ctrl_num);
}
#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) {
popts->ba_intlv_ctl = 0;
printf("Not enough bank(CS) for CS0+CS1 and "
"CS2+CS3 on controller %d, "
"force non-interleaving!\n", ctrl_num);
"interleaving disabled!\n", ctrl_num);
}
#endif
break;
@ -954,33 +1005,73 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
void check_interleaving_options(fsl_ddr_info_t *pinfo)
{
int i, j, check_n_ranks, intlv_fixed = 0;
int i, j, k, check_n_ranks, intlv_invalid = 0;
unsigned int check_intlv, check_n_row_addr, check_n_col_addr;
unsigned long long check_rank_density;
struct dimm_params_s *dimm;
/*
* Check if all controllers are configured for memory
* controller interleaving. Identical dimms are recommended. At least
* the size should be checked.
* 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++) {
if ((pinfo->memctl_opts[i].memctl_interleaving) && \
(check_rank_density == pinfo->dimm_params[i][0].rank_density) && \
(check_n_ranks == pinfo->dimm_params[i][0].n_ranks)) {
dimm = &pinfo->dimm_params[i][0];
if (!pinfo->memctl_opts[i].memctl_interleaving) {
continue;
} else if (((check_rank_density != dimm->rank_density) ||
(check_n_ranks != dimm->n_ranks) ||
(check_n_row_addr != dimm->n_row_addr) ||
(check_n_col_addr != dimm->n_col_addr) ||
(check_intlv !=
pinfo->memctl_opts[i].memctl_interleaving_mode))){
intlv_invalid = 1;
break;
} else {
j++;
}
}
if (j != CONFIG_NUM_DDR_CONTROLLERS) {
if (intlv_invalid) {
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
if (pinfo->memctl_opts[i].memctl_interleaving) {
pinfo->memctl_opts[i].memctl_interleaving = 0;
printf("Not all DIMMs are identical. "
"Memory controller interleaving disabled.\n");
} else {
switch (check_intlv) {
case FSL_DDR_CACHE_LINE_INTERLEAVING:
case FSL_DDR_PAGE_INTERLEAVING:
case FSL_DDR_BANK_INTERLEAVING:
case FSL_DDR_SUPERBANK_INTERLEAVING:
if (3 == CONFIG_NUM_DDR_CONTROLLERS)
k = 2;
else
k = CONFIG_NUM_DDR_CONTROLLERS;
break;
case FSL_DDR_3WAY_1KB_INTERLEAVING:
case FSL_DDR_3WAY_4KB_INTERLEAVING:
case FSL_DDR_3WAY_8KB_INTERLEAVING:
case FSL_DDR_4WAY_1KB_INTERLEAVING:
case FSL_DDR_4WAY_4KB_INTERLEAVING:
case FSL_DDR_4WAY_8KB_INTERLEAVING:
default:
k = CONFIG_NUM_DDR_CONTROLLERS;
break;
}
debug("%d of %d controllers are interleaving.\n", j, k);
if (j != k) {
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
pinfo->memctl_opts[i].memctl_interleaving = 0;
intlv_fixed = 1;
}
if (intlv_fixed)
printf("Not all DIMMs are identical in size. "
"Memory controller interleaving disabled.\n");
printf("Not all controllers have compatible "
"interleaving mode. All disabled.\n");
}
}
debug("Checking interleaving options completed\n");
}
int fsl_use_spd(void)

@ -1,5 +1,5 @@
/*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
* 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
@ -79,7 +79,7 @@ unsigned int mclk_to_picos(unsigned int mclk)
void
__fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
unsigned int memctl_interleaved,
unsigned int law_memctl,
unsigned int ctrl_num)
{
unsigned long long base = memctl_common_params->base_address;
@ -98,28 +98,13 @@ __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
if ((base + size) >= CONFIG_MAX_MEM_MAPPED)
size = CONFIG_MAX_MEM_MAPPED - base;
#endif
if (ctrl_num == 0) {
/*
* Set up LAW for DDR controller 1 space.
*/
unsigned int lawbar1_target_id = memctl_interleaved
? LAW_TRGT_IF_DDR_INTRLV : LAW_TRGT_IF_DDR_1;
if (set_ddr_laws(base, size, lawbar1_target_id) < 0) {
printf("%s: ERROR (ctrl #0, intrlv=%d)\n", __func__,
memctl_interleaved);
return ;
}
} else if (ctrl_num == 1) {
if (set_ddr_laws(base, size, LAW_TRGT_IF_DDR_2) < 0) {
printf("%s: ERROR (ctrl #1)\n", __func__);
return ;
}
} else {
printf("%s: unexpected DDR controller number (%u)\n", __func__,
ctrl_num);
if (set_ddr_laws(base, size, law_memctl) < 0) {
printf("%s: ERROR (ctrl #%d, TRGT ID=%x)\n", __func__, ctrl_num,
law_memctl);
return ;
}
debug("setup ddr law base = 0x%llx, size 0x%llx, TRGT_ID 0x%x\n",
base, size, law_memctl);
}
__attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void
@ -127,6 +112,15 @@ 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)
{
#ifdef CONFIG_E6500
u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
*mcintl3r = 0x80000000 | (granule_size & 0x1f);
debug("Enable MCINTL3R with granule size 0x%x\n", granule_size);
#endif
}
void board_add_ram_info(int use_default)
{
#if defined(CONFIG_MPC83xx)
@ -137,6 +131,9 @@ void board_add_ram_info(int use_default)
#elif defined(CONFIG_MPC86xx)
ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR);
#endif
#if defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3)
u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
#endif
#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
uint32_t cs0_config = in_be32(&ddr->cs0_config);
#endif
@ -180,7 +177,29 @@ void board_add_ram_info(int use_default)
else
puts(", ECC off)");
#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
#if (CONFIG_NUM_DDR_CONTROLLERS == 3)
#ifdef CONFIG_E6500
if (*mcintl3r & 0x80000000) {
puts("\n");
puts(" DDR Controller Interleaving Mode: ");
switch (*mcintl3r & 0x1f) {
case FSL_DDR_3WAY_1KB_INTERLEAVING:
puts("3-way 1KB");
break;
case FSL_DDR_3WAY_4KB_INTERLEAVING:
puts("3-way 4KB");
break;
case FSL_DDR_3WAY_8KB_INTERLEAVING:
puts("3-way 8KB");
break;
default:
puts("3-way UNKNOWN");
break;
}
}
#endif
#endif
#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
if (cs0_config & 0x20000000) {
puts("\n");
puts(" DDR Controller Interleaving Mode: ");

@ -76,6 +76,13 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
#define FSL_DDR_PAGE_INTERLEAVING 0x1
#define FSL_DDR_BANK_INTERLEAVING 0x2
#define FSL_DDR_SUPERBANK_INTERLEAVING 0x3
#define FSL_DDR_3WAY_1KB_INTERLEAVING 0xA
#define FSL_DDR_3WAY_4KB_INTERLEAVING 0xC
#define FSL_DDR_3WAY_8KB_INTERLEAVING 0xD
/* placeholder for 4-way interleaving */
#define FSL_DDR_4WAY_1KB_INTERLEAVING 0x1A
#define FSL_DDR_4WAY_4KB_INTERLEAVING 0x1C
#define FSL_DDR_4WAY_8KB_INTERLEAVING 0x1D
/* DDR_SDRAM_CFG - DDR SDRAM Control Configuration
*/

@ -60,8 +60,12 @@ enum law_trgt_if {
LAW_TRGT_IF_DDR_1 = 0x10,
LAW_TRGT_IF_DDR_2 = 0x11, /* 2nd controller */
LAW_TRGT_IF_DDR_3 = 0x12,
LAW_TRGT_IF_DDR_4 = 0x13,
LAW_TRGT_IF_DDR_INTRLV = 0x14,
LAW_TRGT_IF_DDR_INTLV_34 = 0x15,
LAW_TRGT_IF_DDR_INTLV_123 = 0x17,
LAW_TRGT_IF_DDR_INTLV_1234 = 0x16,
LAW_TRGT_IF_BMAN = 0x18,
LAW_TRGT_IF_DCSR = 0x1d,
LAW_TRGT_IF_LBC = 0x1f,
@ -87,6 +91,12 @@ enum law_trgt_if {
LAW_TRGT_IF_DPAA_SWP_SRAM = 0x0e,
LAW_TRGT_IF_DDR = 0x0f,
LAW_TRGT_IF_DDR_2 = 0x16, /* 2nd controller */
/* place holder for 3-way and 4-way interleaving */
LAW_TRGT_IF_DDR_3,
LAW_TRGT_IF_DDR_4,
LAW_TRGT_IF_DDR_INTLV_34,
LAW_TRGT_IF_DDR_INTLV_123,
LAW_TRGT_IF_DDR_INTLV_1234,
};
#define LAW_TRGT_IF_DDR_1 LAW_TRGT_IF_DDR
#define LAW_TRGT_IF_PCI_1 LAW_TRGT_IF_PCI

@ -2621,6 +2621,7 @@ struct ccsr_rman {
#define CONFIG_SYS_FSL_CORENET_CCM_OFFSET 0x0000
#define CONFIG_SYS_MPC85xx_DDR_OFFSET 0x8000
#define CONFIG_SYS_MPC85xx_DDR2_OFFSET 0x9000
#define CONFIG_SYS_MPC85xx_DDR3_OFFSET 0xA000
#define CONFIG_SYS_FSL_CORENET_CLK_OFFSET 0xE1000
#define CONFIG_SYS_FSL_CORENET_RCPM_OFFSET 0xE2000
#define CONFIG_SYS_FSL_CORENET_SERDES_OFFSET 0xEA000
@ -2740,6 +2741,8 @@ struct ccsr_rman {
(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR_OFFSET)
#define CONFIG_SYS_MPC85xx_DDR2_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR2_OFFSET)
#define CONFIG_SYS_MPC85xx_DDR3_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR3_OFFSET)
#define CONFIG_SYS_LBC_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_LBC_OFFSET)
#define CONFIG_SYS_IFC_ADDR \

@ -1,5 +1,28 @@
Table of interleaving modes supported in cpu/8xxx/ddr/
Table of interleaving 2-4 controllers
=====================================
+--------------+-----------------------------------------------------------+
|Configuration | Memory Controller |
| | 1 2 3 4 |
|--------------+--------------+--------------+-----------------------------+
| Two memory | Not Intlv'ed | Not Intlv'ed | |
| complexes +--------------+--------------+ |
| | 2-way Intlv'ed | |
|--------------+--------------+--------------+--------------+ |
| | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | |
| Three memory +--------------+--------------+--------------+ |
| complexes | 2-way Intlv'ed | Not Intlv'ed | |
| +-----------------------------+--------------+ |
| | 3-way Intlv'ed | |
+--------------+--------------+--------------+--------------+--------------+
| | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed |
| Four memory +--------------+--------------+--------------+--------------+
| complexes | 2-way Intlv'ed | 2-way Intlv'ed |
| +-----------------------------+-----------------------------+
| | 4-way Intlv'ed |
+--------------+-----------------------------------------------------------+
Table of 2-way interleaving modes supported in cpu/8xxx/ddr/
======================================================
+-------------+---------------------------------------------------------+
| | Rank Interleaving |
@ -56,6 +79,15 @@ The ways to configure the ddr interleaving mode
# superbank
setenv hwconfig "fsl_ddr:ctlr_intlv=superbank"
# 1KB 3-way interleaving
setenv hwconfig "fsl_ddr:ctlr_intlv=3way_1KB"
# 4KB 3-way interleaving
setenv hwconfig "fsl_ddr:ctlr_intlv=3way_4KB"
# 8KB 3-way interleaving
setenv hwconfig "fsl_ddr:ctlr_intlv=3way_8KB"
# disable bank (chip-select) interleaving
setenv hwconfig "fsl_ddr:bank_intlv=null"

Loading…
Cancel
Save