Make DDR interleaving mode work correctly
PATCH 1/6 Make DDR interleaving mode work correctly
Fix some bugs:
1. Correctly set intlv_ctl in cs_config.
2. Correctly set sa, ea in cs_bnds when bank interleaving mode is enabled.
3. Set base_address and total memory for each ddr controller in memory controller interleaving mode.
--- cpu/mpc8xxx/ddr/ctrl_regs.c | 61 +++++++++++++++++++++++++++++++------- cpu/mpc8xxx/ddr/main.c | 5 +++ include/asm-ppc/fsl_ddr_sdram.h | 12 +++++++ 3 files changed, 66 insertions(+), 12 deletions(-)
cpu/mpc8xxx/ddr/ctrl_regs.c +49 -12
@@ -95,16 +95,10 @@ static void set_csn_config(int i, fsl_ddr_cfg_regs_t *ddr, col_bits_cs_n = dimm_params[i/2 ].n_col_addr -8 ; } -/* FIXME: intlv_en, intlv_ctl only on CS0_CONFIG */ -if (i !=0 ) { - intlv_en =0 ; - intlv_ctl =0 ; - } - ddr->cs[i].config = (0 | ((cs_n_en &0x1 ) <<31 ) | ((intlv_en &0x3 ) <<29 ) - | ((intlv_en &0xf ) <<24 ) + | ((intlv_ctl &0xf ) <<24 ) | ((ap_n_en &0x1 ) <<23 ) /* XXX: some implementation only have 1 bit starting@left */
@@ -874,8 +868,13 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,for (i =0 ; i <CONFIG_CHIP_SELECTS_PER_CTRL ; i++) {phys_size_t sa =0 ;phys_size_t ea =0 ; -if (popts->ba_intlv_ctl && i >0 ) { -/* Don't set up boundaries if bank interleaving */ + +if (popts->ba_intlv_ctl && (i >0 ) && + ((popts->ba_intlv_ctl &0x60 ) !=FSL_DDR_CS2_CS3 )) { +/* Don't set up boundaries for other CS +* other than CS0, if bank interleaving +* is enabled and not CS2+CS3 interleaved. +*/ break ; }
@@ -894,7 +893,9 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,* on each controller is twice the amount present on * each controller. */ - ea = (2 * common_dimm->total_mem >> dbw_cap_adj) -1 ; +unsigned long long rank_density + = dimm_params[0 ].capacity; + ea = (2 * (rank_density >> dbw_cap_adj)) -1 ; }else if (!popts->memctl_interleaving && popts->ba_intlv_ctl) {/*
@@ -906,8 +907,44 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,* controller needs to be programmed into its * respective CS0_BNDS. */ - sa = common_dimm->base_address; - ea = sa + (common_dimm->total_mem >> dbw_cap_adj) -1 ; +unsigned long long rank_density + = dimm_params[i/2 ].rank_density; +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 ; +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&1 )) { + sa = dimm_params[i/2 ].base_address; + ea = sa + (i * (rank_density >> + dbw_cap_adj)) -1 ; + } +break ; +case FSL_DDR_CS0_CS1 : +/* CS0+CS1 interleaving, CS0_CNDS needs +* to be set +*/ + sa = common_dimm->base_address; + ea = sa + (2 * (rank_density >> dbw_cap_adj))-1 ; +break ; +case FSL_DDR_CS2_CS3 : +/* CS2+CS3 interleaving*/ +if (i ==2 ) { + sa = dimm_params[i/2 ].base_address; + ea = sa + (2 * (rank_density >> + dbw_cap_adj)) -1 ; + } +break ; +default :/* No bank(chip-select) interleaving */ +break ; + } }else if (popts->memctl_interleaving && !popts->ba_intlv_ctl) {/*
cpu/mpc8xxx/ddr/main.c +5 -0
@@ -179,6 +179,7 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,if (*memctl_interleaving) {phys_addr_t addr; +phys_size_t total_mem_per_ctlr =0 ;/* * If interleaving between memory controllers,
@@ -197,14 +198,18 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,for (i =0 ; i <CONFIG_NUM_DDR_CONTROLLERS ; i++) { addr =0 ; + pinfo->common_timing_params[i].base_address = + (phys_addr_t )addr;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 += (phys_addr_t)(cap >> dbw_cap_adj[i]); + total_mem_per_ctlr += cap >> dbw_cap_adj[i]; } } + pinfo->common_timing_params[0 ].total_mem = total_mem_per_ctlr; }else {/* * Simple linear assignment if memory
include/asm-ppc/fsl_ddr_sdram.h +12 -0
@@ -36,6 +36,18 @@ typedef ddr2_spd_eeprom_t generic_spd_eeprom_t;typedef ddr3_spd_eeprom_t generic_spd_eeprom_t ;#endif +/* define bank(chip select) interleaving mode */ +#define FSL_DDR_CS0_CS1 0x40 +#define FSL_DDR_CS2_CS3 0x20 +#define FSL_DDR_CS0_CS1_AND_CS2_CS3 (FSL_DDR_CS0_CS1 | FSL_DDR_CS2_CS3) +#define FSL_DDR_CS0_CS1_CS2_CS3 (FSL_DDR_CS0_CS1_AND_CS2_CS3 | 0x04) + +/* define memory controller interleaving mode */ +#define FSL_DDR_CACHE_LINE_INTERLEAVING 0x0 +#define FSL_DDR_PAGE_INTERLEAVING 0x1 +#define FSL_DDR_BANK_INTERLEAVING 0x2 +#define FSL_DDR_SUPERBANK_INTERLEAVING 0x3 +/* Record of register values computed */ typedef struct fsl_ddr_cfg_regs_s { struct {
Signature · 1 line
1.6.0.2
PATCH 1/6 Make DDR interleaving mode work correctly
If Kim and Jon approve, I'll pull these 6 patches into my 85xx-next branch.
Quoted 171 lines · Haiying Wang
Fix some bugs:
1. Correctly setintlv_ctlincs_config.
2. Correctly set sa, ea incs_bndswhen bank interleaving mode is enabled.
3. Setbase_addressand total memory for each ddr controller in memory controller interleaving mode.Signed-off-by Haiying Wang <[email protected]>--- cpu/mpc8xxx/ddr/ctrl_regs.c | 61 +++++++++++++++++++++++++++++++------- cpu/mpc8xxx/ddr/main.c | 5 +++ include/asm-ppc/fsl_ddr_sdram.h | 12 +++++++ 3 files changed, 66 insertions(+), 12 deletions(-)cpu/mpc8xxx/ddr/ctrl_regs.c +49
-12@@ -95,16 +95,10 @@ static void set_csn_config(int i, fsl_ddr_cfg_regs_t *ddr, col_bits_cs_n = dimm_params[i/2 ].n_col_addr -8 ; } -/* FIXME: intlv_en, intlv_ctl only on CS0_CONFIG */ -if (i !=0 ) { - intlv_en =0 ; - intlv_ctl =0 ; - } - ddr->cs[i].config = (0 | ((cs_n_en &0x1 ) <<31 ) | ((intlv_en &0x3 ) <<29 ) - | ((intlv_en &0xf ) <<24 ) + | ((intlv_ctl &0xf ) <<24 ) | ((ap_n_en &0x1 ) <<23 ) /* XXX: some implementation only have 1 bit starting at left */@@ -874,8 +868,13 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,for (i =0 ; i <CONFIG_CHIP_SELECTS_PER_CTRL ; i++) {phys_size_t sa =0 ;phys_size_t ea =0 ; -if (popts->ba_intlv_ctl && i >0 ) { -/* Don't set up boundaries if bank interleaving */ + +if (popts->ba_intlv_ctl && (i >0 ) && + ((popts->ba_intlv_ctl &0x60 ) !=FSL_DDR_CS2_CS3 )) { +/* Don't set up boundaries for other CS +* other than CS0, if bank interleaving +* is enabled and not CS2+CS3 interleaved. +*/ break ; }@@ -894,7 +893,9 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,* on each controller is twice the amount present on * each controller. */ - ea = (2 * common_dimm->total_mem >> dbw_cap_adj) -1 ; +unsigned long long rank_density + = dimm_params[0 ].capacity; + ea = (2 * (rank_density >> dbw_cap_adj)) -1 ; }else if (!popts->memctl_interleaving && popts->ba_intlv_ctl) {/* @@ -906,8 +907,44 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,* controller needs to be programmed into its * respective CS0_BNDS. */ - sa = common_dimm->base_address; - ea = sa + (common_dimm->total_mem >> dbw_cap_adj) -1 ; +unsigned long long rank_density + = dimm_params[i/2 ].rank_density; +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 ; +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&1 )) { + sa = dimm_params[i/2 ].base_address; + ea = sa + (i * (rank_density >> + dbw_cap_adj)) -1 ; + } +break ; +case FSL_DDR_CS0_CS1 : +/* CS0+CS1 interleaving, CS0_CNDS needs +* to be set +*/ + sa = common_dimm->base_address; + ea = sa + (2 * (rank_density >> dbw_cap_adj))-1 ; +break ; +case FSL_DDR_CS2_CS3 : +/* CS2+CS3 interleaving*/ +if (i ==2 ) { + sa = dimm_params[i/2 ].base_address; + ea = sa + (2 * (rank_density >> + dbw_cap_adj)) -1 ; + } +break ; +default :/* No bank(chip-select) interleaving */ +break ; + } }else if (popts->memctl_interleaving && !popts->ba_intlv_ctl) {/* cpu/mpc8xxx/ddr/main.c +5
-0@@ -179,6 +179,7 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,if (*memctl_interleaving) {phys_addr_t addr; +phys_size_t total_mem_per_ctlr =0 ;/* * If interleaving between memory controllers, @@ -197,14 +198,18 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,for (i =0 ; i <CONFIG_NUM_DDR_CONTROLLERS ; i++) { addr =0 ; + pinfo->common_timing_params[i].base_address = + (phys_addr_t )addr;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 += (phys_addr_t)(cap >> dbw_cap_adj[i]); + total_mem_per_ctlr += cap >> dbw_cap_adj[i]; } } + pinfo->common_timing_params[0 ].total_mem = total_mem_per_ctlr; }else {/* * Simple linear assignment if memory include/asm-ppc/fsl_ddr_sdram.h +12
-1@@ -36,6 +36,18 @@ typedef ddr2_spd_eeprom_t generic_spd_eeprom_t;typedef ddr3_spd_eeprom_t generic_spd_eeprom_t ;#endif +/* define bank(chip select) interleaving mode */ +#define FSL_DDR_CS0_CS1 0x40 +#define FSL_DDR_CS2_CS3 0x20 +#define FSL_DDR_CS0_CS1_AND_CS2_CS3 (FSL_DDR_CS0_CS1 | FSL_DDR_CS2_CS3) +#define FSL_DDR_CS0_CS1_CS2_CS3 (FSL_DDR_CS0_CS1_AND_CS2_CS3 | 0x04) + +/* define memory controller interleaving mode */ +#define FSL_DDR_CACHE_LINE_INTERLEAVING 0x0 +#define FSL_DDR_PAGE_INTERLEAVING 0x1 +#define FSL_DDR_BANK_INTERLEAVING 0x2 +#define FSL_DDR_SUPERBANK_INTERLEAVING 0x3 +/* Record of register values computed */ typedef struct fsl_ddr_cfg_regs_s { struct { --1.6.0.2
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
PATCH 1/6 Make DDR interleaving mode work correctly
Quoted 11 lines · Andy Fleming
If Kim and Jon approve, I'll pull these 6 patches into my 85xx-next branch.
Quoted 7 lines · Haiying Wang
Fix some bugs:
1. Correctly setintlv_ctlincs_config.
2. Correctly set sa, ea incs_bndswhen bank interleaving mode is enabled.
3. Setbase_addressand total memory for each ddr controller in memory controller interleaving mode.Signed-off-by Haiying Wang <[email protected]>
Sounds good by me.
ACK.
jdl
PATCH 1/6 Make DDR interleaving mode work correctly
In reply to Andy FlemingQuoted 2 lines · Andy Fleming
If Kim and Jon approve, I'll pull these 6 patches into my 85xx-next branch.
The code doesn't impact 83xx and thus not sure why you need Kim's ack.
- k
Quoted 10 lines
Quoted 7 lines · Haiying Wang
Fix some bugs:
1. Correctly setintlv_ctlincs_config.
2. Correctly set sa, ea incs_bndswhen bank interleaving mode is enabled.
3. Setbase_addressand total memory for each ddr controller in memory
controller interleaving mode.
PATCH 1/6 Make DDR interleaving mode work correctly
Quoted 7 lines · On Wed, 8 Oct 2008 00:39:38 -0500 Kumar Gala <[email protected]> wrote:
Quoted 2 lines · Andy Fleming
If Kim and Jon approve, I'll pull these 6 patches into my 85xx-next branch.
The code doesn't impact 83xx and thus not sure why you need Kim's ack.
ack
on Kumar's comment, that is :)
Kim
PATCH 1/6 Make DDR interleaving mode work correctly
In reply to Haiying WangQuoted 7 lines · Haiying Wang
Fix some bugs:
1. Correctly setintlv_ctlincs_config.
2. Correctly set sa, ea incs_bndswhen bank interleaving mode is enabled.
3. Setbase_addressand total memory for each ddr controller in memory controller interleaving mode.Signed-off-by Haiying Wang <[email protected]>
Applied 1-6 to 85xx-next with some modifications from Kumar, thanks