[U-Boot] [PATCH 1/6] Make DDR interleaving mode work correctly

Andy Fleming afleming at gmail.com
Tue Oct 7 23:38:57 CEST 2008


If Kim and Jon approve, I'll pull these 6 patches into my 85xx-next branch.

On Fri, Oct 3, 2008 at 11:36 AM, Haiying Wang
<Haiying.Wang at freescale.com> wrote:
> 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.
>
> Signed-off-by: Haiying Wang <Haiying.Wang at freescale.com>
> ---
>  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(-)
>
> diff --git a/cpu/mpc8xxx/ddr/ctrl_regs.c b/cpu/mpc8xxx/ddr/ctrl_regs.c
> index e6c2a5c..6297141 100644
> --- a/cpu/mpc8xxx/ddr/ctrl_regs.c
> +++ b/cpu/mpc8xxx/ddr/ctrl_regs.c
> @@ -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) {
>                        /*
> diff --git a/cpu/mpc8xxx/ddr/main.c b/cpu/mpc8xxx/ddr/main.c
> index c340d56..d26c5c5 100644
> --- a/cpu/mpc8xxx/ddr/main.c
> +++ b/cpu/mpc8xxx/ddr/main.c
> @@ -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
> diff --git a/include/asm-ppc/fsl_ddr_sdram.h b/include/asm-ppc/fsl_ddr_sdram.h
> index 8adde34..c1ea7cd 100644
> --- a/include/asm-ppc/fsl_ddr_sdram.h
> +++ b/include/asm-ppc/fsl_ddr_sdram.h
> @@ -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
>


More information about the U-Boot mailing list