powerpc/8xxx: Enabled hwconfig for memory interleaving

Replace environmental variables memctl_intlv_ctl and ba_intlv_ctl with
hwconfig parameters. The syntax is

    setenv hwconfig "fsl_ddr:ctlr_intlv=<mode>,bank_intlv=<mode>"

The mode values for memory controller interleaving are
    cacheline
    page
    bank
    superbank

The mode values for bank interleaving are
    cs0_cs1
    cs2_cs3
    cs0_cs1_and_cs2_cs3
    cs0_cs1_cs2_cs3

Signed-off-by: York Sun <yorksun@freescale.com>
This commit is contained in:
Kumar Gala 2010-07-14 10:04:21 -05:00
parent fd3c9befa8
commit 79e4e6480b
2 changed files with 39 additions and 26 deletions

View File

@ -8,6 +8,7 @@
*/ */
#include <common.h> #include <common.h>
#include <hwconfig.h>
#include <asm/fsl_ddr_sdram.h> #include <asm/fsl_ddr_sdram.h>
#include "ddr.h" #include "ddr.h"
@ -23,7 +24,6 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
unsigned int ctrl_num) unsigned int ctrl_num)
{ {
unsigned int i; unsigned int i;
const char *p;
/* Chip select options. */ /* Chip select options. */
@ -221,7 +221,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
* should be a subset of the requested configuration. * should be a subset of the requested configuration.
*/ */
#if (CONFIG_NUM_DDR_CONTROLLERS > 1) #if (CONFIG_NUM_DDR_CONTROLLERS > 1)
if ((p = getenv("memctl_intlv_ctl")) != NULL) { if (hwconfig_sub("fsl_ddr", "ctlr_intlv")) {
if (pdimm[0].n_ranks == 0) { if (pdimm[0].n_ranks == 0) {
printf("There is no rank on CS0. Because only rank on " printf("There is no rank on CS0. Because only rank on "
"CS0 and ranks chip-select interleaved with CS0" "CS0 and ranks chip-select interleaved with CS0"
@ -230,37 +230,47 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
popts->memctl_interleaving = 0; popts->memctl_interleaving = 0;
} else { } else {
popts->memctl_interleaving = 1; popts->memctl_interleaving = 1;
if (strcmp(p, "cacheline") == 0) /* test null first. if CONFIG_HWCONFIG is not defined
* hwconfig_arg_cmp returns non-zero */
if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "null")) {
popts->memctl_interleaving = 0;
debug("memory controller interleaving disabled.\n");
} else if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "cacheline"))
popts->memctl_interleaving_mode = popts->memctl_interleaving_mode =
FSL_DDR_CACHE_LINE_INTERLEAVING; FSL_DDR_CACHE_LINE_INTERLEAVING;
else if (strcmp(p, "page") == 0) else if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "page"))
popts->memctl_interleaving_mode = popts->memctl_interleaving_mode =
FSL_DDR_PAGE_INTERLEAVING; FSL_DDR_PAGE_INTERLEAVING;
else if (strcmp(p, "bank") == 0) else if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "bank"))
popts->memctl_interleaving_mode = popts->memctl_interleaving_mode =
FSL_DDR_BANK_INTERLEAVING; FSL_DDR_BANK_INTERLEAVING;
else if (strcmp(p, "superbank") == 0) else if (hwconfig_subarg_cmp("fsl_ddr", "ctlr_intlv", "superbank"))
popts->memctl_interleaving_mode = popts->memctl_interleaving_mode =
FSL_DDR_SUPERBANK_INTERLEAVING; FSL_DDR_SUPERBANK_INTERLEAVING;
else else {
popts->memctl_interleaving_mode = popts->memctl_interleaving = 0;
simple_strtoul(p, NULL, 0); printf("hwconfig has unrecognized parameter for ctlr_intlv.\n");
}
} }
} }
#endif #endif
if( ((p = getenv("ba_intlv_ctl")) != NULL) && if ((hwconfig_sub("fsl_ddr", "bank_intlv")) &&
(CONFIG_CHIP_SELECTS_PER_CTRL > 1)) { (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) {
if (strcmp(p, "cs0_cs1") == 0) /* test null first. if CONFIG_HWCONFIG is not defined,
* hwconfig_arg_cmp returns non-zero */
if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "null"))
printf("bank interleaving disabled.\n");
else if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs0_cs1"))
popts->ba_intlv_ctl = FSL_DDR_CS0_CS1; popts->ba_intlv_ctl = FSL_DDR_CS0_CS1;
else if (strcmp(p, "cs2_cs3") == 0) else if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs2_cs3"))
popts->ba_intlv_ctl = FSL_DDR_CS2_CS3; popts->ba_intlv_ctl = FSL_DDR_CS2_CS3;
else if (strcmp(p, "cs0_cs1_and_cs2_cs3") == 0) else if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs0_cs1_and_cs2_cs3"))
popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_AND_CS2_CS3; popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_AND_CS2_CS3;
else if (strcmp(p, "cs0_cs1_cs2_cs3") == 0) else if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs0_cs1_cs2_cs3"))
popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3; popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3;
else else
popts->ba_intlv_ctl = simple_strtoul(p, NULL, 0); printf("hwconfig has unrecognized parameter for ba_intlv_ctl.\n");
switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
case FSL_DDR_CS0_CS1_CS2_CS3: case FSL_DDR_CS0_CS1_CS2_CS3:

View File

@ -32,38 +32,41 @@ The ways to configure the ddr interleaving mode
1. In board header file(e.g.MPC8572DS.h), add default interleaving setting 1. In board header file(e.g.MPC8572DS.h), add default interleaving setting
under "CONFIG_EXTRA_ENV_SETTINGS", like: under "CONFIG_EXTRA_ENV_SETTINGS", like:
#define CONFIG_EXTRA_ENV_SETTINGS \ #define CONFIG_EXTRA_ENV_SETTINGS \
"memctl_intlv_ctl=2\0" \ "hwconfig=fsl_ddr:ctlr_intlv=bank" \
...... ......
2. Run u-boot "setenv" command to configure the memory interleaving mode. 2. Run u-boot "setenv" command to configure the memory interleaving mode.
Either numerical or string value is accepted. Either numerical or string value is accepted.
# disable memory controller interleaving # disable memory controller interleaving
setenv memctl_intlv_ctl setenv hwconfig "fsl_ddr:ctlr_intlv=null"
# cacheline interleaving # cacheline interleaving
setenv memctl_intlv_ctl 0 or setenv memctl_intlv_ctl cacheline setenv hwconfig "fsl_ddr:ctlr_intlv=cacheline"
# page interleaving # page interleaving
setenv memctl_intlv_ctl 1 or setenv memctl_intlv_ctl page setenv hwconfig "fsl_ddr:ctlr_intlv=page"
# bank interleaving # bank interleaving
setenv memctl_intlv_ctl 2 or setenv memctl_intlv_ctl bank setenv hwconfig "fsl_ddr:ctlr_intlv=bank"
# superbank # superbank
setenv memctl_intlv_ctl 3 or setenv memctl_intlv_ctl superbank setenv hwconfig "fsl_ddr:ctlr_intlv=superbank"
# disable bank (chip-select) interleaving # disable bank (chip-select) interleaving
setenv ba_intlv_ctl setenv hwconfig "fsl_ddr:bank_intlv=null"
# bank(chip-select) interleaving cs0+cs1 # bank(chip-select) interleaving cs0+cs1
setenv ba_intlv_ctl 0x40 or setenv ba_intlv_ctl cs0_cs1 setenv hwconfig "fsl_ddr:bank_intlv=cs0_cs1"
# bank(chip-select) interleaving cs2+cs3 # bank(chip-select) interleaving cs2+cs3
setenv ba_intlv_ctl 0x20 or setenv ba_intlv_ctl cs2_cs3 setenv hwconfig "fsl_ddr:bank_intlv=cs2_cs3"
# bank(chip-select) interleaving (cs0+cs1) and (cs2+cs3) (2x2) # bank(chip-select) interleaving (cs0+cs1) and (cs2+cs3) (2x2)
setenv ba_intlv_ctl 0x60 or setenv ba_intlv_ctl cs0_cs1_and_cs2_cs3 setenv hwconfig "fsl_ddr:bank_intlv=cs0_cs1_and_cs2_cs3"
# bank(chip-select) interleaving (cs0+cs1+cs2+cs3) (4x1) # bank(chip-select) interleaving (cs0+cs1+cs2+cs3) (4x1)
setenv ba_intlv_ctl 0x04 or setenv ba_intlv_ctl cs0_cs1_cs2_cs3 setenv hwconfig "fsl_ddr:bank_intlv=cs0_cs1_cs2_cs3"
The above memory controller interleaving and bank interleaving can be mixed. The syntax is
setenv hwconfig "fsl_ddr:ctlr_intlv=cacheline,bank_intlv=cs0_cs1"