[PATCH] PowerPC: 440EPx/GRx Sequoia/Rainier U-Boot incorrect chipselect number workaround

Valentine Barshak vbarshak at ru.mvista.com
Fri Apr 24 03:12:22 EST 2009


Some U-Boot versions incorrectly set the number of chipselects to two
for Sequoia/Rainier boards while they only have one chipselect hardwired.
This patch adds a workaround for this, hardcoding the number of chipselects
to one for sequioa/rainer board models and reading the actual value from
the memory controller register DDR0_10 otherwise.

Signed-off-by: Valentine Barshak <vbarshak at ru.mvista.com>
---
 arch/powerpc/boot/4xx.c |   52 +++++++++++++++++++++++++++++++++++++----------
 1 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index 5c87843..6196067 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -158,21 +158,33 @@ void ibm440spe_fixup_memsize(void)
 
 #define DDR_GET_VAL(val, mask, shift)	(((val) >> (shift)) & (mask))
 
-void ibm4xx_denali_fixup_memsize(void)
+/*
+ * Some U-Boot versions set the number of chipselects to two
+ * for Sequoia/Rainier boards while they only have one chipselect
+ * hardwired. Hardcode the number of chipselects to one 
+ * for sequioa/rainer board models or read the actual value
+ * from the memory controller register DDR0_10 otherwise.
+ */
+static inline u32 ibm4xx_denali_get_cs(void)
 {
-	u32 val, max_cs, max_col, max_row;
-	u32 cs, col, row, bank, dpath;
-	unsigned long memsize;
+	void *devp;
+	char model[64];
+	u32 val, cs;
 
-	val = SDRAM0_READ(DDR0_02);
-	if (!DDR_GET_VAL(val, DDR_START, DDR_START_SHIFT))
-		fatal("DDR controller is not initialized\n");
+	devp = finddevice("/");
+	if (!devp)
+		goto read_cs;
 
-	/* get maximum cs col and row values */
-	max_cs  = DDR_GET_VAL(val, DDR_MAX_CS_REG, DDR_MAX_CS_REG_SHIFT);
-	max_col = DDR_GET_VAL(val, DDR_MAX_COL_REG, DDR_MAX_COL_REG_SHIFT);
-	max_row = DDR_GET_VAL(val, DDR_MAX_ROW_REG, DDR_MAX_ROW_REG_SHIFT);
+	if (getprop(devp, "model", model, sizeof(model)) <= 0)
+		goto read_cs;
 
+	model[sizeof(model)-1] = 0;
+
+	if (!strcmp(model, "amcc,sequoia") ||
+	    !strcmp(model, "amcc,rainier"))
+		return 1;
+
+read_cs:
 	/* get CS value */
 	val = SDRAM0_READ(DDR0_10);
 
@@ -183,7 +195,25 @@ void ibm4xx_denali_fixup_memsize(void)
 			cs++;
 		val = val >> 1;
 	}
+	return cs;
+}
+
+void ibm4xx_denali_fixup_memsize(void)
+{
+	u32 val, max_cs, max_col, max_row;
+	u32 cs, col, row, bank, dpath;
+	unsigned long memsize;
+
+	val = SDRAM0_READ(DDR0_02);
+	if (!DDR_GET_VAL(val, DDR_START, DDR_START_SHIFT))
+		fatal("DDR controller is not initialized\n");
+
+	/* get maximum cs col and row values */
+	max_cs  = DDR_GET_VAL(val, DDR_MAX_CS_REG, DDR_MAX_CS_REG_SHIFT);
+	max_col = DDR_GET_VAL(val, DDR_MAX_COL_REG, DDR_MAX_COL_REG_SHIFT);
+	max_row = DDR_GET_VAL(val, DDR_MAX_ROW_REG, DDR_MAX_ROW_REG_SHIFT);
 
+	cs = ibm4xx_denali_get_cs();
 	if (!cs)
 		fatal("No memory installed\n");
 	if (cs > max_cs)



More information about the Linuxppc-dev mailing list