powerpc/8xxx: Enabled hwconfig for memory interleaving
PATCH 1/8 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--- arch/powerpc/cpu/mpc8xxx/ddr/options.c | 40 ++++++++++++++++++++------------ doc/README.fsl-ddr | 25 +++++++++++-------- 2 files changed, 39 insertions(+), 26 deletions(-)
arch/powerpc/cpu/mpc8xxx/ddr/options.c +25 -15
@@ -8,6 +8,7 @@*/ #include <common.h> +#include <hwconfig.h> #include <asm/fsl_ddr_sdram.h> #include "ddr.h"
@@ -23,7 +24,6 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, unsigned int ctrl_num) {unsigned int i; -const char *p;/* Chip select options. */
@@ -221,7 +221,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,* should be a subset of the requested configuration. */ #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 ) {printf ("There is no rank on CS0. Because only rank on " "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; }else { 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 =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 =FSL_DDR_PAGE_INTERLEAVING ; -else if (strcmp (p,"bank" ) ==0 ) +else if (hwconfig_subarg_cmp ("fsl_ddr" ,"ctlr_intlv" ,"bank" )) popts->memctl_interleaving_mode =FSL_DDR_BANK_INTERLEAVING ; -else if (strcmp (p,"superbank" ) ==0 ) +else if (hwconfig_subarg_cmp ("fsl_ddr" ,"ctlr_intlv" ,"superbank" )) popts->memctl_interleaving_mode =FSL_DDR_SUPERBANK_INTERLEAVING ; -else - popts->memctl_interleaving_mode = -simple_strtoul (p,NULL ,0 ); +else { + popts->memctl_interleaving =0 ; +printf ("hwconfig has unrecognized parameter for ctlr_intlv.\n" ); + } } }#endif -if ( ((p =getenv ("ba_intlv_ctl" )) !=NULL ) && +if ((hwconfig_sub ("fsl_ddr" ,"bank_intlv" )) && (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 ; -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 ; -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 ; -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 ;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 ) {case FSL_DDR_CS0_CS1_CS2_CS3 :
doc/README.fsl-ddr +14 -11
@@ -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 under "CONFIG_EXTRA_ENV_SETTINGS", like: #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. Either numerical or string value is accepted. # disable memory controller interleaving - setenv memctl_intlv_ctl + setenv hwconfig "fsl_ddr:ctlr_intlv=null" # cacheline interleaving - setenv memctl_intlv_ctl 0 or setenv memctl_intlv_ctl cacheline + setenv hwconfig "fsl_ddr:ctlr_intlv=cacheline" # page interleaving - setenv memctl_intlv_ctl 1 or setenv memctl_intlv_ctl page + setenv hwconfig "fsl_ddr:ctlr_intlv=page" # bank interleaving - setenv memctl_intlv_ctl 2 or setenv memctl_intlv_ctl bank + setenv hwconfig "fsl_ddr:ctlr_intlv=bank" # superbank - setenv memctl_intlv_ctl 3 or setenv memctl_intlv_ctl superbank + setenv hwconfig "fsl_ddr:ctlr_intlv=superbank" # disable bank (chip-select) interleaving - setenv ba_intlv_ctl + setenv hwconfig "fsl_ddr:bank_intlv=null" # 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 - 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) - 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) - 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"
Signature · 1 line
1.6.0.6
Kumar Gala
AppliedPATCH 1/8 powerpc/8xxx: Enabled hwconfig for memory interleaving
Quoted 17 lines · Kumar Gala
Replace environmental variables
memctl_intlv_ctlandba_intlv_ctlwith hwconfig parameters. The syntax issetenv hwconfig "fsl_ddr:ctlr_intlv=<mode>,bank_intlv=<mode>"
The mode values for memory controller interleaving are
cacheline
page
bank
superbankThe mode values for bank interleaving are
cs0_cs1
cs2_cs3
cs0_cs1_and_cs2_cs3
cs0_cs1_cs2_cs3
Quoted 5 lines
Signed-off-by York Sun <[email protected]>---
arch/powerpc/cpu/mpc8xxx/ddr/options.c | 40 ++++++++++++++++++++------------ doc/README.fsl-ddr | 25 +++++++++++-------- 2 files changed, 39 insertions(+), 26 deletions(-)
applied to 85xx
- k
PATCH 2/8 powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4
In reply to Kumar GalaFrom: york <[email protected]>
Verified on MPC8641HPCN with four DDR2 dimms. Each dimm has dual rank with 512MB each rank.
Also check dimm size and rank size for memory controller interleaving
--- arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 113 +++++++++++++++++++---------- arch/powerpc/cpu/mpc8xxx/ddr/ddr.h | 1 + arch/powerpc/cpu/mpc8xxx/ddr/main.c | 40 +++++----- arch/powerpc/cpu/mpc8xxx/ddr/options.c | 107 +++++++++++++++++++++++----- board/freescale/mpc8641hpcn/mpc8641hpcn.c | 2 + doc/README.fsl-ddr | 3 + include/configs/MPC8641HPCN.h | 2 + 7 files changed, 191 insertions(+), 77 deletions(-)
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +74 -39
@@ -1201,20 +1201,28 @@ 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 ; - -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. +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; + +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 (i, ddr, popts, dimm_params); -break ; +continue ; } - -if (dimm_params[i/2 ].n_ranks ==0 ) { +if (dimm_params[dimm_number].n_ranks ==0 ) {debug ("Skipping setup of CS%u " "because n_ranks on DIMM %u is 0\n" , i, i/2 );continue ;
@@ -1222,16 +1230,34 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,if (popts->memctl_interleaving && popts->ba_intlv_ctl) {/* * This works superbank 2CS -* There are 2 memory controllers configured +* 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. */ -unsigned long long rank_density - = dimm_params[0 ].capacity; - ea = (2 * (rank_density >> dbw_cap_adj)) -1 ; +unsigned long long ctlr_density =0 ; +switch (popts->ba_intlv_ctl &FSL_DDR_CS0_CS1_CS2_CS3 ) { +case FSL_DDR_CS0_CS1 : +case FSL_DDR_CS0_CS1_AND_CS2_CS3 : + ctlr_density = dimm_params[0 ].rank_density *2 ; +break ; +case FSL_DDR_CS2_CS3 : + ctlr_density = dimm_params[0 ].rank_density; +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) {/*
@@ -1243,8 +1269,6 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,* controller needs to be programmed into its * respective CS0_BNDS. */ -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
@@ -1257,9 +1281,13 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,/* 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 >> +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 ; + }else { + sa = dimm_params[dimm_number].base_address; + ea = sa + (2 * (rank_density >> dbw_cap_adj)) -1 ; }break ;
@@ -1267,16 +1295,31 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,/* CS0+CS1 interleaving, CS0_CNDS needs * to be set */ - sa = common_dimm->base_address; - ea = sa + (2 * (rank_density >> dbw_cap_adj))-1 ; +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); + }else { + sa =0 ; + ea =0 ; + } +if (i ==0 ) + ea += (rank_density >> dbw_cap_adj);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 ; +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); + }else { + sa =0 ; + ea =0 ; } +if (i ==2 ) + ea += (rank_density >> dbw_cap_adj);break ;default :/* No bank(chip-select) interleaving */ break ;
@@ -1292,8 +1335,6 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,* memory in the two CS0 ranks. */ if (i ==0 ) { -unsigned long long rank_density - = dimm_params[0 ].rank_density; ea = (2 * (rank_density >> dbw_cap_adj)) -1 ; }
@@ -1303,20 +1344,14 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,* No rank interleaving and no memory controller * interleaving. */ -unsigned long long rank_density - = dimm_params[i/2 ].rank_density; - sa = dimm_params[i/2 ].base_address; + sa = dimm_params[dimm_number].base_address; ea = sa + (rank_density >> dbw_cap_adj) -1 ; -if (i&1 ) { -if ((dimm_params[i/2 ].n_ranks ==1 )) { -/* Odd chip select, single-rank dimm */ - sa =0 ; - ea =0 ; - }else { -/* Odd chip select, dual-rank DIMM */ - sa += rank_density >> dbw_cap_adj; - ea += rank_density >> dbw_cap_adj; - } +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 ; } }
arch/powerpc/cpu/mpc8xxx/ddr/ddr.h +1 -0
@@ -73,6 +73,7 @@ extern unsigned int populate_memctl_options(int all_DIMMs_registered, memctl_options_t *popts, dimm_params_t *pdimm, unsigned int ctrl_num); +extern void check_interleaving_options (fsl_ddr_info_t *pinfo);extern unsigned int mclk_to_picos (unsigned int mclk);extern unsigned int get_memory_clk_period_ps (void );
arch/powerpc/cpu/mpc8xxx/ddr/main.c +20 -20
@@ -100,8 +100,8 @@ const char * step_to_string(unsigned int step) {int step_assign_addresses (fsl_ddr_info_t *pinfo,unsigned int dbw_cap_adj[], -unsigned int *memctl_interleaving, -unsigned int *rank_interleaving) +unsigned int *all_memctl_interleaving, +unsigned int *all_ctlr_rank_interleaving) {int i, j;
@@ -152,30 +152,30 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo, } } -/* -* Check if all controllers are configured for memory -* controller interleaving. -*/ j =0 ; -for (i =0 ; i <CONFIG_NUM_DDR_CONTROLLERS ; i++) { -if (pinfo->memctl_opts[i].memctl_interleaving) { +for (i =0 ; i <CONFIG_NUM_DDR_CONTROLLERS ; i++) +if (pinfo->memctl_opts[i].memctl_interleaving) j++; - } - } -if (j ==2 ) - *memctl_interleaving =1 ; +/* +* 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) { +for (i =0 ; i <CONFIG_NUM_DDR_CONTROLLERS ; i++) +if (pinfo->memctl_opts[i].ba_intlv_ctl) j++; - } - } -if (j ==2 ) - *rank_interleaving =1 ; +/* +* 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 (*memctl_interleaving) { +if (*all_memctl_interleaving) {unsigned long long addr, total_mem_per_ctlr =0 ;/* * If interleaving between memory controllers,
@@ -316,7 +316,7 @@ 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,
arch/powerpc/cpu/mpc8xxx/ddr/options.c +89 -18
160 lines not on this page · raw message
board/freescale/mpc8641hpcn/mpc8641hpcn.c +2 -0
@@ -60,6 +60,8 @@ int checkboard(void)return 0 ; } +const char *board_hwconfig ="foo:bar=baz" ; +const char *cpu_hwconfig ="foo:bar=baz" ;phys_size_t initdram (int board_type)
doc/README.fsl-ddr +3 -0
@@ -27,6 +27,9 @@ Table of interleaving modes supported in cpu/8xxx/ddr/ from each controller. {CS2+CS3} on each controller are only rank interleaved on that controller. + For memory controller interleaving, identical DIMMs are suggested. Software + doesn't check the size or organization of interleaved DIMMs. + The ways to configure the ddr interleaving mode ============================================== 1. In board header file(e.g.MPC8572DS.h), add default interleaving setting
include/configs/MPC8641HPCN.h +2 -0
@@ -122,6 +122,8 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);#define CONFIG_SYS_CCSRBAR_PHYS CONFIG_SYS_CCSRBAR_PHYS_LOW#endif +#define CONFIG_HWCONFIG /* use hwconfig to control memory interleaving */ +/* * DDR Setup */
Signature · 1 line
1.6.0.6
Kumar Gala
AppliedPATCH 2/8 powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4
Quoted 9 lines · Kumar Gala
From: york <[email protected]>
Verified on MPC8641HPCN with four DDR2 dimms. Each dimm has dual rank with 512MB each rank.
Also check dimm size and rank size for memory controller interleaving
Signed-off-by York Sun <[email protected]>---
Quoted 8 lines
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 113 +++++++++++++++++++---------- arch/powerpc/cpu/mpc8xxx/ddr/ddr.h | 1 + arch/powerpc/cpu/mpc8xxx/ddr/main.c | 40 +++++----- arch/powerpc/cpu/mpc8xxx/ddr/options.c | 107 +++++++++++++++++++++++----- board/freescale/mpc8641hpcn/mpc8641hpcn.c | 2 + doc/README.fsl-ddr | 3 + include/configs/MPC8641HPCN.h | 2 + 7 files changed, 191 insertions(+), 77 deletions(-)
applied to 85xx
- k
PATCH 3/8 powerpc/8xxx: Enable quad-rank DIMMs.
In reply to Kumar GalaFrom: york <[email protected]>
Previous code presumes each DIMM has up to two rank (chip select). Newer DDR controller supports up to four chip select on one DIMM.
--- arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 52 ++++++++++++++----- .../cpu/mpc8xxx/ddr/lc_common_dimm_params.c | 12 +++++ arch/powerpc/cpu/mpc8xxx/ddr/options.c | 17 ++++--- arch/powerpc/include/asm/fsl_ddr_sdram.h | 1 + 4 files changed, 61 insertions(+), 21 deletions(-)
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +38 -14
@@ -93,7 +93,7 @@ static inline unsigned int compute_cas_write_latency(void) }/* Chip Select Configuration (CSn_CONFIG) */ -static void set_csn_config (int i,fsl_ddr_cfg_regs_t *ddr, +static void set_csn_config (int dimm_number,int i,fsl_ddr_cfg_regs_t *ddr,const memctl_options_t *popts,const dimm_params_t *dimm_params) {
@@ -106,28 +106,49 @@ static void set_csn_config(int i, fsl_ddr_cfg_regs_t *ddr,unsigned int ba_bits_cs_n =0 ;/* Num of bank bits for SDRAM on CSn */ unsigned int row_bits_cs_n =0 ;/* Num of row bits for SDRAM on CSn */ unsigned int col_bits_cs_n =0 ;/* Num of ocl bits for SDRAM on CSn */ +int go_config =0 ;/* Compute CS_CONFIG only for existing ranks of each DIMM. */ -if ((((i&1 ) ==0 ) - && (dimm_params[i/2 ].n_ranks ==1 )) - || (dimm_params[i/2 ].n_ranks ==2 )) { -unsigned int n_banks_per_sdram_device; - cs_n_en =1 ; -if (i ==0 ) { +switch (i) { +case 0 : +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; } +break ; +case 1 : +if ((dimm_number ==0 && dimm_params[0 ].n_ranks >1 ) || \ + (dimm_number ==1 && dimm_params[1 ].n_ranks >0 )) + go_config =1 ; +break ; +case 2 : +if ((dimm_number ==0 && dimm_params[0 ].n_ranks >2 ) || \ + (dimm_number >1 && dimm_params[dimm_number].n_ranks >0 )) + go_config =1 ; +break ; +case 3 : +if ((dimm_number ==0 && dimm_params[0 ].n_ranks >3 ) || \ + (dimm_number ==1 && dimm_params[1 ].n_ranks >1 ) || \ + (dimm_number ==3 && dimm_params[3 ].n_ranks >0 )) + go_config =1 ; +break ; +default : +break ; + } +if (go_config) { +unsigned int n_banks_per_sdram_device; + cs_n_en =1 ; ap_n_en = popts->cs_local_opts[i].auto_precharge; odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg; odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg; n_banks_per_sdram_device - = dimm_params[i/2 ].n_banks_per_sdram_device; + = dimm_params[dimm_number].n_banks_per_sdram_device; ba_bits_cs_n =__ilog2 (n_banks_per_sdram_device) -2 ; - row_bits_cs_n = dimm_params[i/2 ].n_row_addr -12 ; - col_bits_cs_n = dimm_params[i/2 ].n_col_addr -8 ; + row_bits_cs_n = dimm_params[dimm_number].n_row_addr -12 ; + col_bits_cs_n = dimm_params[dimm_number].n_col_addr -8 ; } - ddr->cs[i].config = (0 | ((cs_n_en &0x1 ) <<31 ) | ((intlv_en & 0x3) << 29)
@@ -521,6 +542,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,unsigned int d_init;/* DRAM data initialization */ unsigned int rcw_en =0 ;/* Register Control Word Enable */ unsigned int md_en =0 ;/* Mirrored DIMM Enable */ +unsigned int qd_en =0 ;/* quad-rank DIMM Enable */ dll_rst_dis =1 ;/* Make this configurable */ dqs_cfg = popts->DQS_config;
@@ -562,6 +584,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,#if defined(CONFIG_FSL_DDR3 ) md_en = popts->mirrored_dimm;#endif + qd_en = popts->quad_rank_present ?1 :0 ; ddr->ddr_sdram_cfg_2 = (0 | ((frc_sr &0x1 ) <<31 ) | ((sr_ie & 0x1) << 30)
@@ -569,6 +592,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, | ((dqs_cfg & 0x3) << 26) | ((odt_cfg &0x3 ) <<21 ) | ((num_pr &0xf ) <<12 ) + | (qd_en <<9 ) | ((obc_cfg &0x1 ) <<6 ) | ((ap_en &0x1 ) <<5 ) | ((d_init &0x1 ) <<4 )
@@ -1219,12 +1243,12 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,* But we need to set the ODT_RD_CFG and * ODT_WR_CFG for CS1_CONFIG here. */ -set_csn_config (i, ddr, popts, dimm_params); +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, i/2 ); +"because n_ranks on DIMM %u is 0\n" , i, dimm_number);continue ; }if (popts->memctl_interleaving && popts->ba_intlv_ctl) {
@@ -1364,7 +1388,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, );debug ("FSLDDR: cs[%d]_bnds = 0x%08x\n" , i, ddr->cs[i].bnds); -set_csn_config (i, ddr, popts, dimm_params); +set_csn_config (dimm_number, i, ddr, popts, dimm_params);set_csn_config_2 (i, ddr); }
arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +12 -0
@@ -118,6 +118,18 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, temp1++;continue ; } +if (dimm_params[i].n_ranks ==4 && i !=0 ) { +printf ("Found Quad-rank DIMM in wrong bank, ignored." +" Software may not run as expected.\n" ); + temp1++; +continue ; + } +if (dimm_params[i].n_ranks ==4 && \ +CONFIG_CHIP_SELECTS_PER_CTRL /CONFIG_DIMM_SLOTS_PER_CTLR <4 ) { +printf ("Found Quad-rank DIMM, not able to support." ); + temp1++; +continue ; + }/* * Find minimum tCKmax_ps to find fastest slow speed,
arch/powerpc/cpu/mpc8xxx/ddr/options.c +10 -7
@@ -274,14 +274,14 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,switch (popts->ba_intlv_ctl &FSL_DDR_CS0_CS1_CS2_CS3 ) {case FSL_DDR_CS0_CS1_CS2_CS3 :#if (CONFIG_DIMM_SLOTS_PER_CTLR ==1 ) -if (pdimm[0 ].n_ranks !=4 ) { +if (pdimm[0 ].n_ranks <4 ) { 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); }#elif (CONFIG_DIMM_SLOTS_PER_CTLR ==2 ) -if ((pdimm[0 ].n_ranks !=2 ) && (pdimm[1 ].n_ranks !=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, "
@@ -296,7 +296,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,#endif break ;case FSL_DDR_CS0_CS1 : -if (pdimm[0 ].n_ranks !=2 ) { +if (pdimm[0 ].n_ranks <2 ) { popts->ba_intlv_ctl =0 ;printf ("Not enough bank(chip-select) for " "CS0+CS1 on controller %d, "
@@ -305,13 +305,13 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,break ;case FSL_DDR_CS2_CS3 :#if (CONFIG_DIMM_SLOTS_PER_CTLR ==1 ) -if (pdimm[0 ].n_ranks !=4 ) { +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); }#elif (CONFIG_DIMM_SLOTS_PER_CTLR ==2 ) -if (pdimm[1 ].n_ranks !=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);
@@ -320,14 +320,14 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,break ;case FSL_DDR_CS0_CS1_AND_CS2_CS3 :#if (CONFIG_DIMM_SLOTS_PER_CTLR ==1 ) -if (pdimm[0 ].n_ranks !=4 ) { +if (pdimm[0 ].n_ranks <4 ) { 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); }#elif (CONFIG_DIMM_SLOTS_PER_CTLR ==2 ) -if ((pdimm[0 ].n_ranks !=2 )||(pdimm[1 ].n_ranks !=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, "
@@ -341,6 +341,9 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, } } +if (pdimm[0 ].n_ranks ==4 ) + popts->quad_rank_present =1 ; +fsl_ddr_board_options (popts, pdimm, ctrl_num);return 0 ;
arch/powerpc/include/asm/fsl_ddr_sdram.h +1 -0
@@ -172,6 +172,7 @@ typedef struct memctl_options_s {unsigned int OTF_burst_chop_en;/* mirrior DIMMs for DDR3 */ unsigned int mirrored_dimm; +unsigned int quad_rank_present;/* Global Timing Parameters */ unsigned int cas_latency_override;
Signature · 1 line
1.6.0.6
Kumar Gala
AppliedPATCH 3/8 powerpc/8xxx: Enable quad-rank DIMMs.
Quoted 5 lines · Kumar Gala
From: york <[email protected]>
Previous code presumes each DIMM has up to two rank (chip select). Newer DDR controller supports up to four chip select on one DIMM.
Quoted 7 lines
Signed-off-by York Sun <[email protected]>---
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 52 ++++++++++++++----- .../cpu/mpc8xxx/ddr/lc_common_dimm_params.c | 12 +++++ arch/powerpc/cpu/mpc8xxx/ddr/options.c | 17 ++++--- arch/powerpc/include/asm/fsl_ddr_sdram.h | 1 + 4 files changed, 61 insertions(+), 21 deletions(-)
applied to 85xx
- k
PATCH 4/8 powerpc/8xxx: Enabled address hashing for 85xx
In reply to Kumar GalaFrom: york <[email protected]>
For 85xx silicon which supports address hashing, it can be activated by hwconfig.
--- arch/powerpc/cpu/mpc85xx/ddr-gen3.c | 2 ++ arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 10 ++++++++++ arch/powerpc/cpu/mpc8xxx/ddr/options.c | 7 +++++++ arch/powerpc/include/asm/fsl_ddr_sdram.h | 2 ++ doc/README.fsl-ddr | 15 +++++++++++++-- 5 files changed, 34 insertions(+), 2 deletions(-)
arch/powerpc/cpu/mpc85xx/ddr-gen3.c +2 -0
@@ -33,6 +33,8 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,return ; } +out_be32 (&ddr->eor, regs->ddr_eor); +for (i =0 ; i <CONFIG_CHIP_SELECTS_PER_CTRL ; i++) {if (i ==0 ) {out_be32 (&ddr->cs0_bnds, regs->cs[i].bnds);
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +10 -0
@@ -1161,6 +1161,14 @@ static void set_ddr_sdram_rcw_2(fsl_ddr_cfg_regs_t *ddr) ); } +static void set_ddr_eor (fsl_ddr_cfg_regs_t *ddr,const memctl_options_t *popts) +{ +if (popts->addr_hash) { + ddr->ddr_eor =0x40000000 ;/* address hash enable */ +puts ("Addess hashing enabled.\n" ); + } +} +unsigned int check_fsl_memctl_config_regs (const fsl_ddr_cfg_regs_t *ddr) {
@@ -1392,6 +1400,8 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,set_csn_config_2 (i, ddr); } +set_ddr_eor (ddr, popts); +#if !defined(CONFIG_FSL_DDR1 )set_timing_cfg_0 (ddr);#endif
arch/powerpc/cpu/mpc8xxx/ddr/options.c +7 -0
@@ -341,6 +341,13 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, } } +if (hwconfig_sub ("fsl_ddr" ,"addr_hash" )) { +if (hwconfig_subarg_cmp ("fsl_ddr" ,"addr_hash" ,"null" )) + popts->addr_hash =0 ; +else if (hwconfig_subarg_cmp ("fsl_ddr" ,"addr_hash" ,"true" )) + popts->addr_hash =1 ; + } +if (pdimm[0 ].n_ranks ==4 ) popts->quad_rank_present =1 ;
arch/powerpc/include/asm/fsl_ddr_sdram.h +2 -0
@@ -119,6 +119,7 @@ typedef struct fsl_ddr_cfg_regs_s {unsigned int ddr_sr_cntr;unsigned int ddr_sdram_rcw_1;unsigned int ddr_sdram_rcw_2; +unsigned int ddr_eor; } fsl_ddr_cfg_regs_t; typedef struct memctl_options_partial_s {
@@ -156,6 +157,7 @@ typedef struct memctl_options_s {unsigned int memctl_interleaving;unsigned int memctl_interleaving_mode;unsigned int ba_intlv_ctl; +unsigned int addr_hash;/* Operational mode parameters */ unsigned int ECC_mode;/* Use ECC? */
doc/README.fsl-ddr +13 -2
@@ -71,5 +71,16 @@ The ways to configure the ddr interleaving mode # bank(chip-select) interleaving (cs0+cs1+cs2+cs3) (4x1) 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" +Memory controller address hashing +================================== +If the DDR controller supports address hashing, it can be enabled by hwconfig. + +Syntax is: +hwconfig=fsl_ddr:addr_hash=true + +Combination of hwconfig +======================= +Hwconfig can be combined with multiple parameters, for example, on a supported +platform + +hwconfig=fsl_ddr:addr_hash=true,ctlr_intlv=cacheline,bank_intlv=cs0_cs1_cs2_cs3
Signature · 1 line
1.6.0.6
Kumar Gala
AppliedPATCH 4/8 powerpc/8xxx: Enabled address hashing for 85xx
Quoted 5 lines · Kumar Gala
From: york <[email protected]>
For 85xx silicon which supports address hashing, it can be activated by hwconfig.
Quoted 8 lines
Signed-off-by York Sun <[email protected]>---
arch/powerpc/cpu/mpc85xx/ddr-gen3.c | 2 ++ arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 10 ++++++++++ arch/powerpc/cpu/mpc8xxx/ddr/options.c | 7 +++++++ arch/powerpc/include/asm/fsl_ddr_sdram.h | 2 ++ doc/README.fsl-ddr | 15 +++++++++++++-- 5 files changed, 34 insertions(+), 2 deletions(-)
applied to 85xx
- k
PATCH 5/8 powerpc/8xxx: Enable DDR3 RDIMM support
In reply to Kumar GalaFrom: york <[email protected]>
Enabled registered DIMMs using data from SPD. RDIMMs have registers which need to be configured before using. The register configuration words are stored in SPD byte 60~116 (JEDEC standard No.21-C). Software should read those RCWs and put into DDR controller before initialization.
--- .../powerpc/cpu/mpc8xxx/ddr/common_timing_params.h | 3 + arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 81 ++++++++------------ arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c | 6 +- .../cpu/mpc8xxx/ddr/lc_common_dimm_params.c | 18 ++++- arch/powerpc/include/asm/fsl_ddr_dimm_params.h | 3 + include/ddr_spd.h | 14 ++++ 6 files changed, 72 insertions(+), 53 deletions(-)
arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h +3 -0
@@ -48,6 +48,9 @@ typedef struct {unsigned long long total_mem;unsigned long long base_address; + +/* DDR3 RDIMM */ + unsigned char rcw[16]; /* Register Control Word 0-15 */ } common_timing_params_t;#endif
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +31 -50
105 lines not on this page · raw message
arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c +5 -1
@@ -90,6 +90,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, {unsigned int retval;unsigned int mtb_ps; +int i;if (spd->mem_type) {if (spd->mem_type !=SPD_MEMTYPE_DDR3 ) {
@@ -131,8 +132,11 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,case 0x01 :/* RDIMM */ case 0x05 :/* Mini-RDIMM */ pdimm->registered_dimm =1 ;/* register buffered */ +for (i =0 ; i <16 ; i +=2 ) { + pdimm->rcw[i] = spd->mod_section.registered.rcw[i/2 ] &0x0F ; + pdimm->rcw[i+1 ] = (spd->mod_section.registered.rcw[i/2 ] >>4 ) &0x0F ; + }break ; -case 0x02 :/* UDIMM */ case 0x03 :/* SO-DIMM */ case 0x04 :/* Micro-DIMM */
arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +16 -2
@@ -76,7 +76,7 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,common_timing_params_t *outpdimm, unsigned int number_of_dimms) { - unsigned int i; + unsigned int i, j;unsigned int tCKmin_X_ps =0 ;unsigned int tCKmax_ps =0xFFFFFFFF ;
@@ -98,7 +98,7 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,unsigned int tDQSQ_max_ps =0 ;unsigned int tQHS_ps =0 ; -unsigned int temp1, temp2; +unsigned int temp1, temp2, temp3;unsigned int additive_latency =0 ;#if !defined(CONFIG_FSL_DDR3 )const unsigned int mclk_ps =get_memory_clk_period_ps ();
@@ -231,6 +231,20 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, "DIMMs detected!\n"); } + temp1 =0 ; +if (outpdimm->all_DIMMs_registered) +for (j =0 ; j <16 ; j++) { + outpdimm->rcw[j] = dimm_params[0 ].rcw[j]; +for (i =1 ; i < number_of_dimms; i++) +if (dimm_params[i].rcw[j] != dimm_params[0 ].rcw[j]) { + temp3 =1 ; +break ; + } + } + +if (temp1 !=0 ) +printf ("ERROR: Mix different RDIMM detected!\n" ); +#if defined(CONFIG_FSL_DDR3 )if (compute_cas_latency_ddr3 (dimm_params, outpdimm, number_of_dimms))return 1 ;
arch/powerpc/include/asm/fsl_ddr_dimm_params.h +3 -0
@@ -81,6 +81,9 @@ typedef struct dimm_params_s {unsigned int tRTP_ps;/* byte 38, spd->trtp */ unsigned int tDQSQ_max_ps;/* byte 44, spd->tdqsq */ unsigned int tQHS_ps;/* byte 45, spd->tqhs */ + +/* DDR3 RDIMM */ +unsigned char rcw[16 ];/* Register Control Word 0-15 */ } dimm_params_t; extern unsigned int ddr_compute_dimm_parameters(
include/ddr_spd.h +14 -0
@@ -243,6 +243,20 @@ typedef struct ddr3_spd_eeprom_s {unsigned char mod_thickness;/* 62 (Registered) Reference Raw Card Used */ unsigned char ref_raw_card; +/* 63 DIMM Module Attributes */ +unsigned char modu_attr; +/* 64 RDIMM Thermal Heat Spreader Solution */ +unsigned char thermal; +/* 65 Register Manufacturer ID Code, Least Significant Byte */ +unsigned char reg_id_lo; +/* 66 Register Manufacturer ID Code, Most Significant Byte */ +unsigned char reg_id_hi; +/* 67 Register Revision Number */ +unsigned char reg_rev; +/* 68 Register Type */ +unsigned char reg_type; +/* 69-76 RC1,3,5...15 (MS Nibble) / RC0,2,4...14 (LS Nibble) */ +unsigned char rcw[8 ]; } registered;unsigned char uc[57 ];/* 60-116 Module-Specific Section */ } mod_section;
Signature · 1 line
1.6.0.6
Kumar Gala
AppliedPATCH 5/8 powerpc/8xxx: Enable DDR3 RDIMM support
Quoted 8 lines · Kumar Gala
From: york <[email protected]>
Enabled registered DIMMs using data from SPD. RDIMMs have registers which need to be configured before using. The register configuration words are stored in SPD byte 60~116 (JEDEC standard No.21-C). Software should read those RCWs and put into DDR controller before initialization.
Signed-off-by York Sun <[email protected]>
Quoted 8 lines
---
.../powerpc/cpu/mpc8xxx/ddr/common_timing_params.h | 3 + arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 81 ++++++++------------ arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c | 6 +- .../cpu/mpc8xxx/ddr/lc_common_dimm_params.c | 18 ++++- arch/powerpc/include/asm/fsl_ddr_dimm_params.h | 3 + include/ddr_spd.h | 14 ++++ 6 files changed, 72 insertions(+), 53 deletions(-)
applied to 85xx
- k
PATCH 6/8 powerpc/8xxx: Improvement to DDR parameters
In reply to Kumar GalaFrom: york <[email protected]>
Changes for P2020DS DDR applies to other 8xxx platform
--- arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 14 +++++++------- arch/powerpc/cpu/mpc8xxx/ddr/options.c | 1 + 2 files changed, 8 insertions(+), 7 deletions(-)
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +7 -7
@@ -199,7 +199,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr)unsigned char act_pd_exit_mclk;/* Precharge powerdown exit timing (tXP). */ unsigned char pre_pd_exit_mclk; -/* Precharge powerdown exit timing (tAXPD). */ +/* ODT powerdown exit timing (tAXPD). */ unsigned char taxpd_mclk;/* Mode register set cycle time (tMRD). */ unsigned char tmrd_mclk;
@@ -211,13 +211,13 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr)* we use the tXP instead of it. * tXP=max(3nCK, 7.5ns) for DDR3. * spec has not the tAXPD, we use -* tAXPD=8, need design to confirm. +* tAXPD=1, need design to confirm. */ int tXP =max ((get_memory_clk_period_ps () *3 ),7500 );/* unit=ps */ act_pd_exit_mclk =picos_to_mclk (tXP);/* Mode register MR0[A12] is '1' - fast exit */ pre_pd_exit_mclk = act_pd_exit_mclk; - taxpd_mclk =8 ; + taxpd_mclk =1 ; tmrd_mclk =4 ;/* set the turnaround time */ trwt_mclk =1 ;
@@ -1031,9 +1031,9 @@ static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr)unsigned int wodt_off =0 ;/* Write to ODT off */ #if defined(CONFIG_FSL_DDR3 ) - rodt_on =3 ;/* 2 clocks */ + rodt_on =2 ;/* 2 clocks */ rodt_off =4 ;/* 4 clocks */ - wodt_on =2 ;/* 1 clocks */ + wodt_on =1 ;/* 1 clocks */ wodt_off =4 ;/* 4 clocks */ #endif
@@ -1106,9 +1106,9 @@ static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en,/* * Write leveling repetition time * at least tWLO + 6 clocks clocks -* we set it 32 +* we set it 64 */ - wrlvl_wlr =0x5 ; + wrlvl_wlr =0x6 ;/* * Write leveling start time * The value use for the DQS_ADJUST for the first sample
arch/powerpc/cpu/mpc8xxx/ddr/options.c +1 -0
@@ -204,6 +204,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,* meet the tQDSS under different loading. */ popts->wrlvl_en =1 ; + popts->zq_en =1 ; popts->wrlvl_override =0 ;#endif
Signature · 1 line
1.6.0.6
Kumar Gala
AppliedPATCH 6/8 powerpc/8xxx: Improvement to DDR parameters
Quoted 9 lines · Kumar Gala
From: york <[email protected]>
Changes for P2020DS DDR applies to other 8xxx platform
Signed-off-by York Sun <[email protected]>---
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c| 14 +++++++-------arch/powerpc/cpu/mpc8xxx/ddr/options.c| 1 +2 files changed, 8 insertions(+), 7 deletions(-)
applied to 85xx
- k
PATCH 7/8 powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig
In reply to Kumar GalaFrom: york <[email protected]>
Enabled SPD
Enabled DDR2
Enabled hwconfig
--- Makefile | 1 + board/freescale/p2020ds/ddr.c | 56 ++++++++++++++++++------------------- board/freescale/p2020ds/p2020ds.c | 7 +++- include/configs/P2020DS.h | 6 ++++ 4 files changed, 39 insertions(+), 31 deletions(-)
Makefile +1 -0
@@ -1781,6 +1781,7 @@ P2010RDB_config \ P2010RDB_NAND_config \ P2010RDB_SDCARD_config \ P2010RDB_SPIFLASH_config \ +P2020DS_DDR2_config \ P2020RDB_config \ P2020RDB_NAND_config \ P2020RDB_SDCARD_config \
board/freescale/p2020ds/ddr.c +27 -29
90 lines not on this page · raw message
board/freescale/p2020ds/p2020ds.c +5 -2
@@ -69,13 +69,16 @@ int checkboard(void)return 0 ; } +const char *board_hwconfig ="foo:bar=baz" ; +const char *cpu_hwconfig ="foo:bar=baz" ; +phys_size_t initdram (int board_type) {phys_size_t dram_size =0 ;puts ("Initializing...." ); -#ifdef CONFIG_SPD_EEPROM +#ifdef CONFIG_DDR_SPD dram_size =fsl_ddr_sdram ();#else dram_size =fixed_sdram ();
@@ -94,7 +97,7 @@ phys_size_t initdram(int board_type)return dram_size; } -#if !defined(CONFIG_SPD_EEPROM ) +#if !defined(CONFIG_DDR_SPD )/* * Fixed sdram init -- doesn't use serial presence detect. */
include/configs/P2020DS.h +6 -0
@@ -92,7 +92,11 @@/* DDR Setup */ #define CONFIG_VERY_BIG_RAM +#ifdef CONFIG_MK_DDR2 +#define CONFIG_FSL_DDR2 +#else #define CONFIG_FSL_DDR3 1 +#endif #undef CONFIG_FSL_DDR_INTERACTIVE/* ECC will be enabled based on perf_mode environment variable */
@@ -109,6 +113,7 @@#define CONFIG_CHIP_SELECTS_PER_CTRL 2/* I2C addresses of SPD EEPROMs */ +#define CONFIG_DDR_SPD #define CONFIG_SYS_SPD_BUS_NUM 0/* SPD EEPROM located on I2C bus 0 */ #define SPD_EEPROM_ADDRESS1 0x51/* CTLR 0 DIMM 0 */
@@ -228,6 +233,7 @@#define CONFIG_BOARD_EARLY_INIT_R /* call board_early_init_r function */ +#define CONFIG_HWCONFIG /* enable hwconfig */ #define CONFIG_FSL_NGPIXIS /* use common ngPIXIS code */ #ifdef CONFIG_FSL_NGPIXIS
Signature · 1 line
1.6.0.6
Kumar Gala
AppliedPATCH 7/8 powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig
Quoted 6 lines · Kumar Gala
From: york <[email protected]>
Enabled SPD
Enabled DDR2
Enabled hwconfig
Quoted 7 lines
Signed-off-by York Sun <[email protected]>---
Makefile | 1 + board/freescale/p2020ds/ddr.c | 56 ++++++++++++++++++------------------- board/freescale/p2020ds/p2020ds.c | 7 +++- include/configs/P2020DS.h | 6 ++++ 4 files changed, 39 insertions(+), 31 deletions(-)
applied to 85xx
- k
PATCH 8/8 powerpc/85xx: Add memory test feature for mpc85xx.
In reply to Kumar GalaFrom: york <[email protected]>
If enabled in config file and hwconfig, the memory test is performed after DDR initialization when U-boot stills runs in flash and cache. Whole memory is testable. However, only the low 2GB space is mapped for DDR. The testing is conducted in the 2GB window and uses TLBs to map the higher physical address into the 2GB window if the total memory is more than 2GB. After the testing, DDR is remapped with up to 2GB memory from the lowest address.
Memory testing has different patterns which may be improved later.
If memory test fails, DDR DIMM SPD and DDR controller registers are dumped. All zero values are omitted for better viewing.
A worker function __setup_ddr_tlbs() is introduced to implemente more control on physical address mapping.
--- arch/powerpc/cpu/mpc85xx/Makefile | 2 + arch/powerpc/cpu/mpc85xx/memtest.c | 369 ++++++++++++++++++++++++++++++++++++ arch/powerpc/cpu/mpc85xx/tlb.c | 16 +- doc/README.fsl-ddr | 39 ++++ 4 files changed, 420 insertions(+), 6 deletions(-) create mode 100644 arch/powerpc/cpu/mpc85xx/memtest.c
arch/powerpc/cpu/mpc85xx/Makefile +2 -0
@@ -60,6 +60,8 @@ COBJS-$(CONFIG_P2010) += ddr-gen3.o COBJS-$(CONFIG_P2020) += ddr-gen3.o COBJS-$(CONFIG_PPC_P4080) += ddr-gen3.o +COBJS-${CONFIG_SYS_DRAM_TEST} += memtest.o + COBJS-$(CONFIG_CPM2) += ether_fcc.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o COBJS-$(CONFIG_MP) += mp.o
arch/powerpc/cpu/mpc85xx/memtest.c new file +369 -0
369 lines not on this page · raw message
arch/powerpc/cpu/mpc85xx/tlb.c +10 -6
@@ -245,7 +245,8 @@ void init_addr_map(void) }#endif -unsigned int setup_ddr_tlbs (unsigned int memsize_in_meg) +unsigned int +__setup_ddr_tlbs (phys_addr_t p_addr,unsigned int memsize_in_meg) {int i;unsigned int tlb_size;
@@ -275,21 +276,24 @@ unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg) tlb_size = (camsize -10 ) /2 ; -set_tlb (1 , ram_tlb_address, ram_tlb_address, +set_tlb (1 , ram_tlb_address, p_addr,MAS3_SX |MAS3_SW |MAS3_SR ,0 ,0 , ram_tlb_index, tlb_size,1 ); size -=1ULL << camsize; memsize -=1ULL << camsize; ram_tlb_address +=1UL << camsize; + p_addr += 1UL << camsize; }if (memsize)print_size (memsize," left unmapped\n" ); - -/* -* Confirm that the requested amount of memory was mapped. -*/ return memsize_in_meg; } + +unsigned int setup_ddr_tlbs (unsigned int memsize_in_meg) +{ +return +__setup_ddr_tlbs (CONFIG_SYS_DDR_SDRAM_BASE , memsize_in_meg); +}#endif /* !CONFIG_NAND_SPL */
doc/README.fsl-ddr +39 -0
@@ -78,6 +78,45 @@ If the DDR controller supports address hashing, it can be enabled by hwconfig. Syntax is: hwconfig=fsl_ddr:addr_hash=true + +Memory testing options for mpc85xx +================================== +1. Memory test can be done one U-boot prompt comes up using mtest, or +2. Memory test can be done with a built-in function, activated at compile time + and by hwconfig. + In order to enable the built-in memory test, CONFIG_SYS_DRAM_TEST needs to be + defined in board configuraiton header file. Hwconfig is also required. To test + memory bigger than 2GB, 36BIT support is needed. Memory is tested within a 2GB + window. TLBs are used to map the virtual 2GB window to physical address so that + all physical memory can be tested. + + Syntax of hwconfig + hwconfig=memtest:true or + hwconfig=memtest:simple + + The "simple" test uses one pattern and "true" uses more patterns. The testing + patterns include moving inversions and modulo-16. + +Moving inversions +================= +Moving inversions test takes a pattern (eg. 0x00000000) and fills the memory with +the pattern for the first round. The software then takes the second round to check +each address against the pattern, if matched the complement data is written back +and software moves on to next address, all the way to the end. In the third round, +software checks the complement of pattern of each address. + +Modulo-16 +========= +Modulo-16 is a test for selected address. In the first round, software fills the +memory with a pattern and the complement of the pattern every 16-sizeof(int). In +the second round, software checks the complement of the pattern@selected address. + +Patterns +======== +Built-in patterns are 0x00000000, 0xAAAAAAAA, 0x55555555, 0xFFFFFFFF and Address +Marching (i.e. the address of the cell). + + Combination of hwconfig ======================= Hwconfig can be combined with multiple parameters, for example, on a supported
Signature · 1 line
1.6.0.6
Wolfgang Denk
NAKPATCH 8/8 powerpc/85xx: Add memory test feature for mpc85xx.
Dear Kumar Gala,
Quoted 15 lines · In message <[email protected]> you…
From: york <[email protected]>
If enabled in config file and hwconfig, the memory test is performed after DDR initialization when U-boot stills runs in flash and cache. Whole memory is testable. However, only the low 2GB space is mapped for DDR. The testing is conducted in the 2GB window and uses TLBs to map the higher physical address into the 2GB window if the total memory is more than 2GB. After the testing, DDR is remapped with up to 2GB memory from the lowest address.
Memory testing has different patterns which may be improved later.
If memory test fails, DDR DIMM SPD and DDR controller registers are dumped. All zero values are omitted for better viewing.
Quoted 7 lines
A worker function
__setup_ddr_tlbs()is introduced to implemente more control on physical address mapping.Signed-off-by York Sun <[email protected]>--- arch/powerpc/cpu/mpc85xx/Makefile | 2 + arch/powerpc/cpu/mpc85xx/memtest.c | 369 ++++++++++++++++++++++++++++++++++++
NAK.
Please do not reinvent the wheel and add yet another meory test. Use one of the existing memory tests we already have - post/drivers/memory.c comes to mind.
Best regards,
Wolfgang Denk
Signature · 4 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de "A dirty mind is a joy forever." - Randy Kunkee
PATCH 8/8 powerpc/85xx: Add memory test feature for mpc85xx.
Quoted 5 lines · Wolfgang Denk
NAK.
Please do not reinvent the wheel and add yet another meory test. Use one of the existing memory tests we already have -
post/drivers/memory.ccomes to mind.
That code is not capable of testing more than 2GB of RAM. It assumes that memory has already been initialized, but on PowerPC parts, we only ever map 2GB of DDR. We need a memory test that covers all of DDR, but that requries PowerPC-specific code to create sliding TLB windows during the memory test.
Signature · 2 lines
Timur Tabi Linux kernel developer at Freescale
PATCH 8/8 powerpc/85xx: Add memory test feature for mpc85xx.
Dear Timur Tabi,
Quoted 7 lines · In message <[email protected]> you…
Quoted 6 lines
NAK.
Please do not reinvent the wheel and add yet another meory test. Use one of the existing memory tests we already have -
post/drivers/memory.ccomes to mind.
Quoted 5 lines
That code is not capable of testing more than 2GB of RAM. It assumes that memory has already been initialized, but on PowerPC parts, we only ever map 2GB of DDR. We need a memory test that covers all of DDR, but that requries PowerPC-specific code to create sliding TLB windows during the memory test.
Then please extend the existing code and add the missing features.
We already have too many different implementations of a memory test in U-Boot, and I will not accept adding yet another one.
Best regards,
Wolfgang Denk
Signature · 6 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Programmer's Lament: (Shakespeare, Macbeth, Act I, Scene vii)
"That we but teach bloody instructions,
which, being taught, return to plague the inventor..."PATCH 8/8 powerpc/85xx: Add memory test feature for mpc85xx.
Wolfgang,
Quoted 16 lines · Wolfgang Denk
Dear Timur Tabi,
Quoted 7 lines · In message <[email protected]> you…
Quoted 6 lines
NAK.
Please do not reinvent the wheel and add yet another meory test. Use one of the existing memory tests we already have -
post/drivers/memory.ccomes to mind.Quoted 5 lines
That code is not capable of testing more than 2GB of RAM. It assumes that memory has already been initialized, but on PowerPC parts, we only ever map 2GB of DDR. We need a memory test that covers all of DDR, but that requries PowerPC-specific code to create sliding TLB windows during the memory test.
Quoted 5 lines
Then please extend the existing code and add the missing features.
We already have too many different implementations of a memory test in U-Boot, and I will not accept adding yet another one.
I can reuse your testing code but have to move the desired code out of memory.c file to avoid the need for CONFIG_POST and CONFIG_SYS_POST_MEMORY. I also add a progress indicator. My testing target is 2GB at a time, up to physically memory size which is easily over 8GB. Without progress indicator, it feels hung when it is actually running.
Please take a look at the patch below.
Regards,
York
Wolfgang Denk
NAKPATCH 8/8 powerpc/85xx: Add memory test feature for mpc85xx.
Dear York Sun,
Quoted 7 lines · In message <1280351179.8571.63.camel@oslab-l1> you wrote:
Quoted 4 lines
We already have too many different implementations of a memory test in U-Boot, and I will not accept adding yet another one.
I can reuse your testing code but have to move the desired code out of
memory.cfile to avoid the need forCONFIG_POSTandCONFIG_SYS_POST_MEMORY. I also add a progress indicator. My testing
NAK, and NAK.
Please integrate your code into the existing POST framework instead, as a number of other boards already did.
A progress indicator may be a nice little toy, but how does it integrate into the POST framework?
Quoted 3 lines
target is 2GB at a time, up to physically memory size which is easily over 8GB. Without progress indicator, it feels hung when it is actually running.
Yes, memory testing takes time. In the context of a power-on self test (and this is what you are doing, right?) we should take care to fit it into the existing framework, though.
Quoted 1 line
Please take a look at the patch below.
Instead of integrating your needs into an existing framework you invent yet another one. I don't want to have this, sorry.
Best regards,
Wolfgang Denk
Signature · 4 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de How can you tell when sour cream goes bad?