All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving
@ 2010-07-14 15:14 Kumar Gala
  2010-07-14 15:14 ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
  2010-07-26 18:15 ` [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving Kumar Gala
  0 siblings, 2 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-14 15:14 UTC (permalink / raw)
  To: u-boot

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>
---
 arch/powerpc/cpu/mpc8xxx/ddr/options.c |   40 ++++++++++++++++++++------------
 doc/README.fsl-ddr                     |   25 +++++++++++--------
 2 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
index 46731c8..11281b7 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
@@ -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:
diff --git a/doc/README.fsl-ddr b/doc/README.fsl-ddr
index 9c2224f..6e4f6e9 100644
--- a/doc/README.fsl-ddr
+++ b/doc/README.fsl-ddr
@@ -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"
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4
  2010-07-14 15:14 [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving Kumar Gala
@ 2010-07-14 15:14 ` Kumar Gala
  2010-07-14 15:14   ` [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs Kumar Gala
  2010-07-26 18:15   ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
  2010-07-26 18:15 ` [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving Kumar Gala
  1 sibling, 2 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-14 15:14 UTC (permalink / raw)
  To: u-boot

From: york <yorksun@freescale.com>

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 <yorksun@freescale.com>
---
 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(-)

diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index 4a282bc..69c1c7c 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -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;
 			}
 		}
 
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h b/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h
index f122075..98acb8d 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h
@@ -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);
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c
index faa1af9..6d582e9 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c
@@ -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,
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
index 11281b7..ebbdb69 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
@@ -212,10 +212,9 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 	 * Please refer to doc/README.fsl-ddr for the detail.
 	 *
 	 * If memory controller interleaving is enabled, then the data
-	 * bus widths must be programmed identically for the 2 memory
-	 * controllers.
+	 * bus widths must be programmed identically for all memory controllers.
 	 *
-	 * XXX: Attempt to set both controllers to the same chip select
+	 * XXX: Attempt to set all controllers to the same chip select
 	 * interleaving mode. It will do a best effort to get the
 	 * requested ranks interleaved together such that the result
 	 * should be a subset of the requested configuration.
@@ -223,15 +222,17 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 #if (CONFIG_NUM_DDR_CONTROLLERS > 1)
 	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"
+			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");
+				"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 */
+			/*
+			 * 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");
@@ -254,13 +255,12 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 		}
 	}
 #endif
-
 	if ((hwconfig_sub("fsl_ddr", "bank_intlv")) &&
 		(CONFIG_CHIP_SELECTS_PER_CTRL > 1)) {
 		/* 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");
+			debug("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 (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs2_cs3"))
@@ -270,30 +270,70 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 		else if (hwconfig_subarg_cmp("fsl_ddr", "bank_intlv", "cs0_cs1_cs2_cs3"))
 			popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3;
 		else
-			printf("hwconfig has unrecognized parameter for ba_intlv_ctl.\n");
-
+			printf("hwconfig has unrecognized parameter for bank_intlv.\n");
 		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) {
+				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)) {
+				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);
+			}
+			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);
+			}
+#endif
+			break;
 		case FSL_DDR_CS0_CS1:
 			if (pdimm[0].n_ranks != 2) {
 				popts->ba_intlv_ctl = 0;
 				printf("Not enough bank(chip-select) for "
-					"CS0+CS1, force non-interleaving!\n");
+					"CS0+CS1 on controller %d, "
+					"force non-interleaving!\n", ctrl_num);
 			}
 			break;
 		case FSL_DDR_CS2_CS3:
-			if (pdimm[1].n_ranks !=2){
+#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
+			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) {
 				popts->ba_intlv_ctl = 0;
-				printf("Not enough bank(CS) for CS2+CS3, "
-					"force non-interleaving!\n");
+				printf("Not enough bank(chip-select) for CS2+CS3 "
+					"on controller %d, force non-interleaving!\n", ctrl_num);
 			}
+#endif
 			break;
 		case FSL_DDR_CS0_CS1_AND_CS2_CS3:
+#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
+			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)) {
 				popts->ba_intlv_ctl = 0;
-				printf("Not enough bank(CS) for CS0+CS1 or "
-					"CS2+CS3, force non-interleaving!\n");
+				printf("Not enough bank(CS) for CS0+CS1 and "
+					"CS2+CS3 on controller %d, "
+					"force non-interleaving!\n", ctrl_num);
 			}
+#endif
 			break;
 		default:
 			popts->ba_intlv_ctl = 0;
@@ -305,3 +345,34 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 
 	return 0;
 }
+
+void check_interleaving_options(fsl_ddr_info_t *pinfo)
+{
+	int i, j, check_n_ranks, intlv_fixed = 0;
+	unsigned long long check_rank_density;
+	/*
+	 * Check if all controllers are configured for memory
+	 * controller interleaving. Identical dimms are recommended. At least
+	 * the size 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;
+	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)) {
+			j++;
+		}
+	}
+	if (j != CONFIG_NUM_DDR_CONTROLLERS) {
+		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
+			if (pinfo->memctl_opts[i].memctl_interleaving) {
+				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");
+	}
+}
diff --git a/board/freescale/mpc8641hpcn/mpc8641hpcn.c b/board/freescale/mpc8641hpcn/mpc8641hpcn.c
index d86ca12..fee310a 100644
--- a/board/freescale/mpc8641hpcn/mpc8641hpcn.c
+++ b/board/freescale/mpc8641hpcn/mpc8641hpcn.c
@@ -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)
diff --git a/doc/README.fsl-ddr b/doc/README.fsl-ddr
index 6e4f6e9..8c37bbe 100644
--- a/doc/README.fsl-ddr
+++ b/doc/README.fsl-ddr
@@ -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
diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h
index 0d1f779..974cb6b 100644
--- a/include/configs/MPC8641HPCN.h
+++ b/include/configs/MPC8641HPCN.h
@@ -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
  */
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs.
  2010-07-14 15:14 ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
@ 2010-07-14 15:14   ` Kumar Gala
  2010-07-14 15:14     ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
  2010-07-26 18:15     ` [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs Kumar Gala
  2010-07-26 18:15   ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
  1 sibling, 2 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-14 15:14 UTC (permalink / raw)
  To: u-boot

From: york <yorksun@freescale.com>

Previous code presumes each DIMM has up to two rank (chip select). Newer
DDR controller supports up to four chip select on one DIMM.

Signed-off-by: York Sun <yorksun@freescale.com>
---
 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(-)

diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index 69c1c7c..6e73b1d 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -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);
 	}
 
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
index e888e3e..ce6c148 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
@@ -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,
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
index ebbdb69..1d5f3e2 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
@@ -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;
diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h
index 02920db..431327e 100644
--- a/arch/powerpc/include/asm/fsl_ddr_sdram.h
+++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h
@@ -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;
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx
  2010-07-14 15:14   ` [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs Kumar Gala
@ 2010-07-14 15:14     ` Kumar Gala
  2010-07-14 15:14       ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
  2010-07-26 18:15       ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
  2010-07-26 18:15     ` [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs Kumar Gala
  1 sibling, 2 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-14 15:14 UTC (permalink / raw)
  To: u-boot

From: york <yorksun@freescale.com>

For 85xx silicon which supports address hashing, it can be activated by
hwconfig.

Signed-off-by: York Sun <yorksun@freescale.com>
---
 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(-)

diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
index 0691ca4..e46dcb7 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
@@ -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);
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index 6e73b1d..ff0ddd1 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -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
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
index 1d5f3e2..e4805d3 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
@@ -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;
 
diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h
index 431327e..d576eb8 100644
--- a/arch/powerpc/include/asm/fsl_ddr_sdram.h
+++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h
@@ -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? */
diff --git a/doc/README.fsl-ddr b/doc/README.fsl-ddr
index 8c37bbe..e108a0d 100644
--- a/doc/README.fsl-ddr
+++ b/doc/README.fsl-ddr
@@ -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
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support
  2010-07-14 15:14     ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
@ 2010-07-14 15:14       ` Kumar Gala
  2010-07-14 15:15         ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
  2010-07-26 18:15         ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
  2010-07-26 18:15       ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
  1 sibling, 2 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-14 15:14 UTC (permalink / raw)
  To: u-boot

From: york <yorksun@freescale.com>

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 <yorksun@freescale.com>
---
 .../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(-)

diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h b/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h
index 5aea517..06706ed 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h
@@ -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
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index ff0ddd1..b2962d2 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -448,6 +448,35 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
 	debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2);
 }
 
+/* DDR SDRAM Register Control Word */
+static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr,
+			       const common_timing_params_t *common_dimm)
+{
+	if (common_dimm->all_DIMMs_registered
+		&& !common_dimm->all_DIMMs_unbuffered) {
+		ddr->ddr_sdram_rcw_1 =
+			common_dimm->rcw[0] << 28 | \
+			common_dimm->rcw[1] << 24 | \
+			common_dimm->rcw[2] << 20 | \
+			common_dimm->rcw[3] << 16 | \
+			common_dimm->rcw[4] << 12 | \
+			common_dimm->rcw[5] << 8 | \
+			common_dimm->rcw[6] << 4 | \
+			common_dimm->rcw[7];
+		ddr->ddr_sdram_rcw_2 =
+			common_dimm->rcw[8] << 28 | \
+			common_dimm->rcw[9] << 24 | \
+			common_dimm->rcw[10] << 20 | \
+			common_dimm->rcw[11] << 16 | \
+			common_dimm->rcw[12] << 12 | \
+			common_dimm->rcw[13] << 8 | \
+			common_dimm->rcw[14] << 4 | \
+			common_dimm->rcw[15];
+		debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1);
+		debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2);
+	}
+}
+
 /* DDR SDRAM control configuration (DDR_SDRAM_CFG) */
 static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
 			       const memctl_options_t *popts,
@@ -938,6 +967,7 @@ static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr,
 
 	clk_adjust = popts->clk_adjust;
 	ddr->ddr_sdram_clk_cntl = (clk_adjust & 0xF) << 23;
+	debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl);
 }
 
 /* DDR Initialization Address (DDR_INIT_ADDR) */
@@ -1113,54 +1143,6 @@ static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it)
 	ddr->ddr_sr_cntr = (sr_it & 0xF) << 16;
 }
 
-/* DDR SDRAM Register Control Word 1 (DDR_SDRAM_RCW_1) */
-static void set_ddr_sdram_rcw_1(fsl_ddr_cfg_regs_t *ddr)
-{
-	unsigned int rcw0 = 0;	/* RCW0: Register Control Word 0 */
-	unsigned int rcw1 = 0;	/* RCW1: Register Control Word 1 */
-	unsigned int rcw2 = 0;	/* RCW2: Register Control Word 2 */
-	unsigned int rcw3 = 0;	/* RCW3: Register Control Word 3 */
-	unsigned int rcw4 = 0;	/* RCW4: Register Control Word 4 */
-	unsigned int rcw5 = 0;	/* RCW5: Register Control Word 5 */
-	unsigned int rcw6 = 0;	/* RCW6: Register Control Word 6 */
-	unsigned int rcw7 = 0;	/* RCW7: Register Control Word 7 */
-
-	ddr->ddr_sdram_rcw_1 = (0
-				| ((rcw0 & 0xF) << 28)
-				| ((rcw1 & 0xF) << 24)
-				| ((rcw2 & 0xF) << 20)
-				| ((rcw3 & 0xF) << 16)
-				| ((rcw4 & 0xF) << 12)
-				| ((rcw5 & 0xF) << 8)
-				| ((rcw6 & 0xF) << 4)
-				| ((rcw7 & 0xF) << 0)
-				);
-}
-
-/* DDR SDRAM Register Control Word 2 (DDR_SDRAM_RCW_2) */
-static void set_ddr_sdram_rcw_2(fsl_ddr_cfg_regs_t *ddr)
-{
-	unsigned int rcw8 = 0;	/* RCW0: Register Control Word 8 */
-	unsigned int rcw9 = 0;	/* RCW1: Register Control Word 9 */
-	unsigned int rcw10 = 0;	/* RCW2: Register Control Word 10 */
-	unsigned int rcw11 = 0;	/* RCW3: Register Control Word 11 */
-	unsigned int rcw12 = 0;	/* RCW4: Register Control Word 12 */
-	unsigned int rcw13 = 0;	/* RCW5: Register Control Word 13 */
-	unsigned int rcw14 = 0;	/* RCW6: Register Control Word 14 */
-	unsigned int rcw15 = 0;	/* RCW7: Register Control Word 15 */
-
-	ddr->ddr_sdram_rcw_2 = (0
-				| ((rcw8 & 0xF) << 28)
-				| ((rcw9 & 0xF) << 24)
-				| ((rcw10 & 0xF) << 20)
-				| ((rcw11 & 0xF) << 16)
-				| ((rcw12 & 0xF) << 12)
-				| ((rcw13 & 0xF) << 8)
-				| ((rcw14 & 0xF) << 4)
-				| ((rcw15 & 0xF) << 0)
-				);
-}
-
 static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts)
 {
 	if (popts->addr_hash) {
@@ -1430,8 +1412,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
 
 	set_ddr_sr_cntr(ddr, sr_it);
 
-	set_ddr_sdram_rcw_1(ddr);
-	set_ddr_sdram_rcw_2(ddr);
+	set_ddr_sdram_rcw(ddr, common_dimm);
 
 	return check_fsl_memctl_config_regs(ddr);
 }
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c
index d4199ba..29cea53 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c
@@ -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 */
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
index ce6c148..029e566 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
@@ -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;
diff --git a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h
index 55923e0..be82602 100644
--- a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h
+++ b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h
@@ -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(
diff --git a/include/ddr_spd.h b/include/ddr_spd.h
index 10402c5..710e528 100644
--- a/include/ddr_spd.h
+++ b/include/ddr_spd.h
@@ -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;
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters
  2010-07-14 15:14       ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
@ 2010-07-14 15:15         ` Kumar Gala
  2010-07-14 15:15           ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
  2010-07-26 18:15           ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
  2010-07-26 18:15         ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
  1 sibling, 2 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-14 15:15 UTC (permalink / raw)
  To: u-boot

From: york <yorksun@freescale.com>

Changes for P2020DS DDR applies to other 8xxx platform

Signed-off-by: York Sun <yorksun@freescale.com>
---
 arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c |   14 +++++++-------
 arch/powerpc/cpu/mpc8xxx/ddr/options.c   |    1 +
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index b2962d2..dccb7aa 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -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
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
index e4805d3..774c0e4 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
@@ -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
 
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig
  2010-07-14 15:15         ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
@ 2010-07-14 15:15           ` Kumar Gala
  2010-07-14 15:15             ` [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx Kumar Gala
  2010-07-26 18:16             ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
  2010-07-26 18:15           ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
  1 sibling, 2 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-14 15:15 UTC (permalink / raw)
  To: u-boot

From: york <yorksun@freescale.com>

Enabled SPD
Enabled DDR2
Enabled hwconfig

Signed-off-by: York Sun <yorksun@freescale.com>
---
 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(-)

diff --git a/Makefile b/Makefile
index 9cf58bd..82d2c25 100644
--- a/Makefile
+++ b/Makefile
@@ -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 \
diff --git a/board/freescale/p2020ds/ddr.c b/board/freescale/p2020ds/ddr.c
index b9c0cb2..30d640f 100644
--- a/board/freescale/p2020ds/ddr.c
+++ b/board/freescale/p2020ds/ddr.c
@@ -12,7 +12,7 @@
 #include <asm/fsl_ddr_sdram.h>
 #include <asm/fsl_ddr_dimm_params.h>
 
-static void get_spd(ddr3_spd_eeprom_t *spd, unsigned char i2c_address)
+static void get_spd(generic_spd_eeprom_t *spd, unsigned char i2c_address)
 {
 	i2c_read(i2c_address, 0, 1, (uchar *)spd, sizeof(ddr3_spd_eeprom_t));
 }
@@ -22,7 +22,7 @@ unsigned int fsl_ddr_get_mem_data_rate(void)
 	return get_ddr_freq(0);
 }
 
-void fsl_ddr_get_spd(ddr3_spd_eeprom_t *ctrl_dimms_spd,
+void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
 		      unsigned int ctrl_num)
 {
 	unsigned int i;
@@ -51,27 +51,26 @@ typedef struct {
  *  cpo 2-0x1E (30)
  */
 
-
-/* XXX: these values need to be checked for all interleaving modes.  */
-/* XXX: No reliable dual-rank 800 MHz setting has been found.  It may
- *      seem reliable, but errors will appear when memory intensive
- *      program is run. */
-/* XXX: Single rank at 800 MHz is OK.  */
 const board_specific_parameters_t board_specific_parameters[][20] = {
 	{
 	/* 	memory controller 0 			*/
 	/*	  lo|  hi|  num|  clk| cpo|wrdata|2T	*/
 	/*	 mhz| mhz|ranks|adjst|    | delay|	*/
-		{  0, 333,    2,    6,   7,    3,  0},
-		{334, 400,    2,    6,   9,    3,  0},
-		{401, 549,    2,    6,  11,    3,  0},
-		{550, 680,    2,    1,  10,    5,  0},
-		{681, 850,    2,    1,  12,    5,  1},
-		{  0, 333,    1,    6,   7,    3,  0},
-		{334, 400,    1,    6,   9,    3,  0},
-		{401, 549,    1,    6,  11,    3,  0},
-		{550, 680,    1,    1,  10,    5,  0},
-		{681, 850,    1,    1,  12,    5,  0}
+#ifdef CONFIG_FSL_DDR2
+		{  0, 333,    2,    4,   0x1f,    2,  0},
+		{334, 400,    2,    4,   0x1f,    2,  0},
+		{401, 549,    2,    4,   0x1f,    2,  0},
+		{550, 680,    2,    4,   0x1f,    3,  0},
+		{681, 850,    2,    4,   0x1f,    4,  0},
+		{  0, 333,    1,    4,   0x1f,    2,  0},
+		{334, 400,    1,    4,   0x1f,    2,  0},
+		{401, 549,    1,    4,   0x1f,    2,  0},
+		{550, 680,    1,    4,   0x1f,    3,  0},
+		{681, 850,    1,    4,   0x1f,    4,  0}
+#else
+		{  0, 850,    2,    4,   0x1f,    4,  0},
+		{  0, 850,    1,    4,   0x1f,    4,  0}
+#endif
 	},
 };
 
@@ -92,18 +91,8 @@ void fsl_ddr_board_options(memctl_options_t *popts,
 	 * odt_wr_cfg to 3 for the even CS, 0 for the odd CS.
 	 */
 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
-		if (i&1) {	/* odd CS */
 			popts->cs_local_opts[i].odt_rd_cfg = 0;
-			popts->cs_local_opts[i].odt_wr_cfg = 0;
-		} else {	/* even CS */
-			if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) {
-				popts->cs_local_opts[i].odt_rd_cfg = 0;
-				popts->cs_local_opts[i].odt_wr_cfg = 4;
-			} else if (CONFIG_DIMM_SLOTS_PER_CTLR == 2) {
-				popts->cs_local_opts[i].odt_rd_cfg = 3;
-				popts->cs_local_opts[i].odt_wr_cfg = 3;
-			}
-		}
+			popts->cs_local_opts[i].odt_wr_cfg = 1;
 	}
 
 	/* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
@@ -127,4 +116,13 @@ void fsl_ddr_board_options(memctl_options_t *popts,
 	 *	- number of DIMMs installed
 	 */
 	popts->half_strength_driver_enable = 0;
+	popts->wrlvl_en = 1;
+	/* Write leveling override */
+	popts->wrlvl_override = 1;
+	popts->wrlvl_sample = 0xa;
+	popts->wrlvl_start = 0x7;
+	/* Rtt and Rtt_WR override */
+	popts->rtt_override = 1;
+	popts->rtt_override_value = DDR3_RTT_120_OHM;
+	popts->rtt_wr_override_value = 0; /* Rtt_WR= dynamic ODT off */
 }
diff --git a/board/freescale/p2020ds/p2020ds.c b/board/freescale/p2020ds/p2020ds.c
index 3fd1b34..608ff91 100644
--- a/board/freescale/p2020ds/p2020ds.c
+++ b/board/freescale/p2020ds/p2020ds.c
@@ -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.
  */
diff --git a/include/configs/P2020DS.h b/include/configs/P2020DS.h
index e70c673..ee21d8b 100644
--- a/include/configs/P2020DS.h
+++ b/include/configs/P2020DS.h
@@ -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
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx.
  2010-07-14 15:15           ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
@ 2010-07-14 15:15             ` Kumar Gala
  2010-07-14 20:16               ` Wolfgang Denk
  2010-07-26 18:16             ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
  1 sibling, 1 reply; 20+ messages in thread
From: Kumar Gala @ 2010-07-14 15:15 UTC (permalink / raw)
  To: u-boot

From: york <yorksun@freescale.com>

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.

Signed-off-by: York Sun <yorksun@freescale.com>
---
 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

diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile
index 4ee0e9a..c0fc9ba 100644
--- a/arch/powerpc/cpu/mpc85xx/Makefile
+++ b/arch/powerpc/cpu/mpc85xx/Makefile
@@ -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
diff --git a/arch/powerpc/cpu/mpc85xx/memtest.c b/arch/powerpc/cpu/mpc85xx/memtest.c
new file mode 100644
index 0000000..7ad3326
--- /dev/null
+++ b/arch/powerpc/cpu/mpc85xx/memtest.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ * York Sun <yorksun@freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <hwconfig.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+#include <asm/fsl_ddr_sdram.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Board-specific functions defined in each board's ddr.c */
+void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
+	unsigned int ctrl_num);
+void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn,
+		       phys_addr_t *rpn);
+unsigned int __setup_ddr_tlbs(phys_addr_t p_addr, unsigned int memsize_in_meg);
+
+#define PATTERN(pattern, address) (pattern == 0x12345678 ? address : pattern)
+
+#define TOTAL_PROGRESS_DOTS 45
+#define TOTAL_PROGRESS_NUMBERS 9
+#define PROGRESS_DOTS_PER_NUMBER (TOTAL_PROGRESS_DOTS/TOTAL_PROGRESS_NUMBERS)
+#define TEST_SHOW_PROGRESS(scale, dots, digit, dots_sub) \
+{ \
+	dots -= (dots_sub); \
+	if ((scale > 0) && (dots <= 0)) { \
+		if ((digit % PROGRESS_DOTS_PER_NUMBER) == 0) \
+			printf("%d", digit / PROGRESS_DOTS_PER_NUMBER); \
+		else \
+			putc('.'); \
+		digit--; \
+		dots += (scale); \
+	} \
+}
+
+#if defined(CONFIG_SYS_DRAM_TEST)
+void dump_spd_ddr_reg(void)
+{
+	int i, j, k, m;
+	u8 *p_8;
+	u32 *p_32;
+	ccsr_ddr_t *ddr[CONFIG_NUM_DDR_CONTROLLERS];
+	generic_spd_eeprom_t
+	   spd[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR];
+
+	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+		fsl_ddr_get_spd(spd[i], i);
+	}
+	puts("SPD data of all dimms (zero vaule is omitted)...\n");
+	puts("Byte (hex)  ");
+	k = 1;
+	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
+		for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++)
+			printf("Dimm%d ", k++);
+	puts("\n");
+	for (k = 0; k < sizeof(generic_spd_eeprom_t); k++) {
+		m = 0;
+		printf("%3d (0x%02x)  ", k, k);
+		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
+				p_8 = (u8 *) &spd[i][j];
+				if (p_8[k]) {
+					printf("0x%02x  ", p_8[k]);
+					m++;
+				} else
+					puts("      ");
+			}
+		}
+		if (m)
+			puts("\n");
+		else
+			puts("\r");
+	}
+
+	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+		switch (i) {
+		case 0:
+			ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+			break;
+#ifdef CONFIG_SYS_MPC85xx_DDR2_ADDR
+		case 1:
+			ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
+			break;
+#endif
+		default:
+			printf("%s unexpected controller number = %u\n",
+				__FUNCTION__, i);
+			return;
+		}
+	}
+	printf("DDR registers dump for all controllers "
+		"(zero vaule is omitted)...\n");
+	puts("Offset (hex)   ");
+	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
+		printf("     Base + 0x%04x", (u32)ddr[i] & 0xFFFF);
+	puts("\n");
+	for (k = 0; k < sizeof(ccsr_ddr_t)/4; k++) {
+		m = 0;
+		printf("%6d (0x%04x)", k * 4, k * 4);
+		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+			p_32 = (u32 *) ddr[i];
+			if (p_32[k]) {
+				printf("        0x%08x", p_32[k]);
+				m++;
+			} else
+				puts("                  ");
+		}
+		if (m)
+			puts("\n");
+		else
+			puts("\r");
+	}
+	puts("\n");
+}
+
+#define MODULOMASK 0x3F
+#define MODULOX 16
+int pattern_test(u32 start_addr, u32 size, u32 pattern, u64 offset)
+{
+	const int MaxError = 10;
+	volatile u32 *p;
+	u32 ptr, buffer, end_addr = start_addr + size;
+	int error = 0;
+	int digit, dots;
+	int scale;
+
+	puts("Pattern: Moving Inversions ");
+	if (pattern == 0x12345678)
+		puts("Address March\n");
+	else
+		printf("0x%08x\n", pattern);
+
+	scale = (int)(((size >> 20) + TOTAL_PROGRESS_DOTS - 1) /
+		TOTAL_PROGRESS_DOTS);
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
+	for (p = (volatile u32 *)(start_addr & 0xfffffffc);
+		p < (volatile u32 *)(end_addr & 0xfffffffc); p++) {
+		*p = PATTERN(pattern, (u32)p);
+		if (((u32)p % (1 << 20)) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
+	}
+	puts("Filled with pattern.\n");
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
+	for (ptr = (start_addr & 0xfffffffc);
+		ptr < (end_addr & 0xfffffffc); ptr += sizeof(u32)) {
+		p = (volatile u32 *) ptr;
+		buffer = *p;
+		if (buffer != PATTERN(pattern, ptr)) {
+			error++;
+			printf("\nAddress 0x%08llx, Write 0x%08x, Read 0x%08x",
+			offset + ptr, PATTERN(pattern, ptr), buffer);
+			if (error > MaxError)
+				break;
+		}
+		*p = ~PATTERN(pattern, ptr);
+		if ((ptr % (1 << 20)) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
+	}
+	if (error == 0)
+		puts("Verified and written with complement.\n");
+	else {
+		puts("\nFailed!\n\n");
+		return error;
+	}
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
+	for (ptr = ((end_addr - 1) & 0xfffffffc);
+		ptr > (start_addr & 0xfffffffc); ptr -= sizeof(u32)) {
+		p = (volatile u32 *) ptr;
+		buffer = *p;
+		if (buffer != ~PATTERN(pattern, ptr)) {
+			error++;
+			printf("\nAddress 0x%08llx, Write 0x%08x, Read 0x%08x",
+			offset + ptr, ~PATTERN(pattern, ptr), buffer);
+			if (error > MaxError)
+				break;
+		}
+		*p = PATTERN(pattern, ptr);
+		if ((ptr % (1 << 20)) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
+	}
+	if (error == 0)
+		puts("Verified OK.\n\n");
+	else {
+		puts("\nFailed!\n\n");
+		return error;
+	}
+
+	printf("Pattern: Modulo-%d ", MODULOX);
+	if (pattern == 0x12345678)
+		puts("Address March\n");
+	else
+		printf(" 0x%08x\n", pattern);
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
+	for (ptr = (start_addr & 0xfffffffc);
+		ptr < (end_addr & 0xfffffffc); ptr += sizeof(u32)) {
+		p = (volatile u32 *) ptr;
+		if (ptr & MODULOMASK)
+			*p = PATTERN(pattern, ptr);
+		else
+			*p = ~PATTERN(pattern, ptr);
+		if (ptr % (1 << 20) == 0)
+			TEST_SHOW_PROGRESS(scale, dots, digit, 1);
+	}
+	puts("Filled with pattern.\n");
+	scale = (int)(((size / MODULOX / sizeof(u32)) + TOTAL_PROGRESS_DOTS - 1) /
+		TOTAL_PROGRESS_DOTS);
+	digit = TOTAL_PROGRESS_DOTS;
+	dots  = 0;
+	for (ptr = (start_addr & 0xfffffffc);
+		ptr < (end_addr & 0xfffffffc); ptr += sizeof(u32)) {
+		if (ptr & MODULOMASK)
+			break;
+	}
+	for (; ptr < (end_addr & 0xfffffffc); ptr += MODULOX * sizeof(u32)) {
+		p = (volatile u32 *) ptr;
+		buffer = *p;
+		if (buffer != PATTERN(pattern, ptr)) {
+			error++;
+			printf("\nAddress 0x%08llx, Write 0x%08x, Read 0x%08x",
+				ptr + offset, PATTERN(pattern, ptr), buffer);
+			if (error > MaxError)
+				break;
+		}
+		TEST_SHOW_PROGRESS(scale, dots, digit, 1);
+	}
+	if (error == 0)
+		puts("OK.\n\n");
+	else
+		puts("\nFailed!\n\n");
+	return error;
+}
+
+/*
+ * This funciton is called before U-boot relocates itself to RAM
+ * The L1 cache should be locked and L2 cache is not enabled yet
+ */
+int __testdram(phys_addr_t p_addr, u32 size, int simple_test)
+{
+
+	u32 vstart = CONFIG_SYS_DDR_SDRAM_BASE;
+	u32 vend = vstart + size;
+	int failed = 0;
+	unsigned long epn;
+	u32 tsize, valid, ptr;
+	phys_addr_t rpn = 0;
+	int ddr_esel;
+
+	puts("DDR memory testing...\n");
+	size = min(size, CONFIG_MAX_MEM_MAPPED);
+	ptr = vstart;
+	while (ptr < vend) {
+		ddr_esel = find_tlb_idx((void *)ptr, 1);
+		if (ddr_esel != -1) {
+			read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, &rpn);
+			disable_tlb(ddr_esel);
+		}
+		ptr += TSIZE_TO_BYTES(tsize);
+	}
+	/* Setup new tlb to cover the physical address */
+	__setup_ddr_tlbs(p_addr, size>>20);
+
+	ptr = vstart;
+	ddr_esel = find_tlb_idx((void *)ptr, 1);
+	if (ddr_esel != -1) {
+		read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, &rpn);
+	} else {
+		printf("TLB error in function %s\n", __FUNCTION__);
+		return -1;
+	}
+
+	printf("Testing 0x%08llx - 0x%08llx\n",
+		(u64)vstart + rpn, (u64)vstart + rpn + size - 1);
+
+	failed = pattern_test(vstart, size, 0, rpn);
+	if (!simple_test) {
+		if (failed == 0)
+			failed = pattern_test(vstart, size, 0xaaaaaaaa, rpn);
+		if (failed == 0)
+			pattern_test(vstart, size, 0x55555555, rpn);
+		if (failed == 0)
+			failed = pattern_test(vstart, size, 0xffffffff, rpn);
+		if (failed == 0)
+			failed = pattern_test(vstart, size, 0x12345678, rpn);
+	}
+	if (failed != 0)
+		dump_spd_ddr_reg();
+
+	/* disable the TLBs for this testing */
+	ptr = vstart;
+	while (ptr < vend) {
+		ddr_esel = find_tlb_idx((void *)ptr, 1);
+		if (ddr_esel != -1) {
+			read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, &rpn);
+			disable_tlb(ddr_esel);
+		}
+		ptr += TSIZE_TO_BYTES(tsize);
+	}
+
+	return failed;
+}
+
+int testdram(void)
+{
+	int simple_test, failed = 0;
+	phys_addr_t test_cap, p_addr = CONFIG_SYS_DDR_SDRAM_BASE;
+	phys_size_t p_size;
+	if (hwconfig("memtest")) {
+		if (hwconfig_arg_cmp("memtest", "null") || \
+			(!hwconfig_arg_cmp("memtest", "true") && \
+			!hwconfig_arg_cmp("memtest", "simple"))) {
+			puts("memtest is not enabled in hwconfig, skipped.\n");
+			return 0;
+		}
+		simple_test = hwconfig_arg_cmp("memtest", "simple");
+		p_size = min(gd->ram_size, CONFIG_MAX_MEM_MAPPED);
+#if !defined(CONFIG_PHYS_64BIT) || \
+    !defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS) || \
+	(CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull)
+		if (gd->ram_size > CONFIG_MAX_MEM_MAPPED) {
+			puts("Cannot test more than ");
+			print_size(CONFIG_MAX_MEM_MAPPED,
+				" without proper 36BIT support.\n");
+		}
+		test_cap = p_size;
+#else
+		test_cap = gd->ram_size;
+#endif
+		while (p_addr < test_cap - 1) {
+			if (__testdram(p_addr, (u32)p_size, simple_test) != 0)
+				failed++;
+			p_addr += p_size;
+			p_size = min(test_cap - p_addr, CONFIG_MAX_MEM_MAPPED);
+		}
+		if (failed)
+			printf("\nWarning: Memory test failed."
+				" Software may not run as expected.\n");
+		puts("Remap DDR ");
+		setup_ddr_tlbs(gd->ram_size>>20);
+		puts("\n");
+	} else
+		puts("memtest is not set in hwconfig, skipped.\n");
+	return 0;
+}
+#endif
diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c
index f2833a5..019fab7 100644
--- a/arch/powerpc/cpu/mpc85xx/tlb.c
+++ b/arch/powerpc/cpu/mpc85xx/tlb.c
@@ -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 */
diff --git a/doc/README.fsl-ddr b/doc/README.fsl-ddr
index e108a0d..f5deb4f 100644
--- a/doc/README.fsl-ddr
+++ b/doc/README.fsl-ddr
@@ -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
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx.
  2010-07-14 15:15             ` [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx Kumar Gala
@ 2010-07-14 20:16               ` Wolfgang Denk
  2010-07-14 22:13                 ` Timur Tabi
  0 siblings, 1 reply; 20+ messages in thread
From: Wolfgang Denk @ 2010-07-14 20:16 UTC (permalink / raw)
  To: u-boot

Dear Kumar Gala,

In message <1279120502-6289-8-git-send-email-galak@kernel.crashing.org> you wrote:
> From: york <yorksun@freescale.com>
> 
> 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.
> 
> Signed-off-by: York Sun <yorksun@freescale.com>
> ---
>  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

-- 
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

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx.
  2010-07-14 20:16               ` Wolfgang Denk
@ 2010-07-14 22:13                 ` Timur Tabi
  2010-07-15  9:07                   ` Wolfgang Denk
  0 siblings, 1 reply; 20+ messages in thread
From: Timur Tabi @ 2010-07-14 22:13 UTC (permalink / raw)
  To: u-boot

On Wed, Jul 14, 2010 at 3:16 PM, Wolfgang Denk <wd@denx.de> wrote:

> 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.

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.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx.
  2010-07-14 22:13                 ` Timur Tabi
@ 2010-07-15  9:07                   ` Wolfgang Denk
  2010-07-28 21:06                     ` York Sun
  0 siblings, 1 reply; 20+ messages in thread
From: Wolfgang Denk @ 2010-07-15  9:07 UTC (permalink / raw)
  To: u-boot

Dear Timur Tabi,

In message <AANLkTim6yjF6ORogtqE0vqiVqZqxu-EkkUhDTmJMgPqu@mail.gmail.com> you wrote:
> 
> > 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.
> 
> 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

-- 
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..."

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving
  2010-07-14 15:14 [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving Kumar Gala
  2010-07-14 15:14 ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
@ 2010-07-26 18:15 ` Kumar Gala
  1 sibling, 0 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-26 18:15 UTC (permalink / raw)
  To: u-boot


On Jul 14, 2010, at 10:14 AM, Kumar Gala wrote:

> 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>
> ---
> arch/powerpc/cpu/mpc8xxx/ddr/options.c |   40 ++++++++++++++++++++------------
> doc/README.fsl-ddr                     |   25 +++++++++++--------
> 2 files changed, 39 insertions(+), 26 deletions(-)

applied to 85xx

- k

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4
  2010-07-14 15:14 ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
  2010-07-14 15:14   ` [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs Kumar Gala
@ 2010-07-26 18:15   ` Kumar Gala
  1 sibling, 0 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-26 18:15 UTC (permalink / raw)
  To: u-boot


On Jul 14, 2010, at 10:14 AM, Kumar Gala wrote:

> From: york <yorksun@freescale.com>
> 
> 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 <yorksun@freescale.com>
> ---
> 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

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs.
  2010-07-14 15:14   ` [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs Kumar Gala
  2010-07-14 15:14     ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
@ 2010-07-26 18:15     ` Kumar Gala
  1 sibling, 0 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-26 18:15 UTC (permalink / raw)
  To: u-boot


On Jul 14, 2010, at 10:14 AM, Kumar Gala wrote:

> From: york <yorksun@freescale.com>
> 
> Previous code presumes each DIMM has up to two rank (chip select). Newer
> DDR controller supports up to four chip select on one DIMM.
> 
> Signed-off-by: York Sun <yorksun@freescale.com>
> ---
> 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

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx
  2010-07-14 15:14     ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
  2010-07-14 15:14       ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
@ 2010-07-26 18:15       ` Kumar Gala
  1 sibling, 0 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-26 18:15 UTC (permalink / raw)
  To: u-boot


On Jul 14, 2010, at 10:14 AM, Kumar Gala wrote:

> From: york <yorksun@freescale.com>
> 
> For 85xx silicon which supports address hashing, it can be activated by
> hwconfig.
> 
> Signed-off-by: York Sun <yorksun@freescale.com>
> ---
> 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

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support
  2010-07-14 15:14       ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
  2010-07-14 15:15         ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
@ 2010-07-26 18:15         ` Kumar Gala
  1 sibling, 0 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-26 18:15 UTC (permalink / raw)
  To: u-boot


On Jul 14, 2010, at 10:14 AM, Kumar Gala wrote:

> From: york <yorksun@freescale.com>
> 
> 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 <yorksun@freescale.com>
> ---
> .../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

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters
  2010-07-14 15:15         ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
  2010-07-14 15:15           ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
@ 2010-07-26 18:15           ` Kumar Gala
  1 sibling, 0 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-26 18:15 UTC (permalink / raw)
  To: u-boot


On Jul 14, 2010, at 10:15 AM, Kumar Gala wrote:

> From: york <yorksun@freescale.com>
> 
> Changes for P2020DS DDR applies to other 8xxx platform
> 
> Signed-off-by: York Sun <yorksun@freescale.com>
> ---
> 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

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig
  2010-07-14 15:15           ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
  2010-07-14 15:15             ` [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx Kumar Gala
@ 2010-07-26 18:16             ` Kumar Gala
  1 sibling, 0 replies; 20+ messages in thread
From: Kumar Gala @ 2010-07-26 18:16 UTC (permalink / raw)
  To: u-boot


On Jul 14, 2010, at 10:15 AM, Kumar Gala wrote:

> From: york <yorksun@freescale.com>
> 
> Enabled SPD
> Enabled DDR2
> Enabled hwconfig
> 
> Signed-off-by: York Sun <yorksun@freescale.com>
> ---
> 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

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx.
  2010-07-15  9:07                   ` Wolfgang Denk
@ 2010-07-28 21:06                     ` York Sun
  2010-07-28 21:50                       ` Wolfgang Denk
  0 siblings, 1 reply; 20+ messages in thread
From: York Sun @ 2010-07-28 21:06 UTC (permalink / raw)
  To: u-boot

Wolfgang,

On Thu, 2010-07-15 at 11:07 +0200, Wolfgang Denk wrote: 
> Dear Timur Tabi,
> 
> In message <AANLkTim6yjF6ORogtqE0vqiVqZqxu-EkkUhDTmJMgPqu@mail.gmail.com> you wrote:
> > 
> > > 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.
> > 
> > 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.
> 
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

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx.
  2010-07-28 21:06                     ` York Sun
@ 2010-07-28 21:50                       ` Wolfgang Denk
  0 siblings, 0 replies; 20+ messages in thread
From: Wolfgang Denk @ 2010-07-28 21:50 UTC (permalink / raw)
  To: u-boot

Dear York Sun,

In message <1280351179.8571.63.camel@oslab-l1> you wrote:
> 
> > 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

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?

> 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.

> 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

-- 
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?

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2010-07-28 21:50 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-14 15:14 [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving Kumar Gala
2010-07-14 15:14 ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
2010-07-14 15:14   ` [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs Kumar Gala
2010-07-14 15:14     ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
2010-07-14 15:14       ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
2010-07-14 15:15         ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
2010-07-14 15:15           ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
2010-07-14 15:15             ` [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx Kumar Gala
2010-07-14 20:16               ` Wolfgang Denk
2010-07-14 22:13                 ` Timur Tabi
2010-07-15  9:07                   ` Wolfgang Denk
2010-07-28 21:06                     ` York Sun
2010-07-28 21:50                       ` Wolfgang Denk
2010-07-26 18:16             ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
2010-07-26 18:15           ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
2010-07-26 18:15         ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
2010-07-26 18:15       ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
2010-07-26 18:15     ` [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs Kumar Gala
2010-07-26 18:15   ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
2010-07-26 18:15 ` [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving Kumar Gala

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.