[U-Boot] [PATCH 2/2] Update Kilauea board support to use PPC4xx DDR autocalibration routines.

Adam Graham agraham at amcc.com
Wed Sep 3 21:26:59 CEST 2008


Signed-off-by: Adam Graham <agraham at amcc.com>
---
 cpu/ppc4xx/44x_spd_ddr2.c      |  158 ++++++++++++++++++++++++----------------
 cpu/ppc4xx/Makefile            |    3 +
 include/asm-ppc/ppc4xx-sdram.h |    3 +-
 include/common.h               |   21 +++++
 include/configs/kilauea.h      |   19 +++++
 include/ppc440.h               |   13 ---
 include/ppc4xx.h               |   13 +++
 7 files changed, 153 insertions(+), 77 deletions(-)

diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 15250d4..f1d7684 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -60,8 +60,6 @@
 		       "SDRAM_" #mnemonic, SDRAM_##mnemonic, data);	\
 	} while (0)
 
-static inline void ppc4xx_ibm_ddr2_register_dump(void);
-
 #if defined(CONFIG_SPD_EEPROM)
 
 /*-----------------------------------------------------------------------------+
@@ -260,62 +258,19 @@ static void program_ecc_addr(unsigned long start_address,
 			     unsigned long num_bytes,
 			     unsigned long tlb_word2_i_value);
 #endif
+#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
 static void program_DQS_calibration(unsigned long *dimm_populated,
-				    unsigned char *iic0_dimm_addr,
-				    unsigned long num_dimm_banks);
+				unsigned char *iic0_dimm_addr,
+				unsigned long num_dimm_banks);
 #ifdef HARD_CODED_DQS /* calibration test with hardvalues */
 static void	test(void);
 #else
 static void	DQS_calibration_process(void);
 #endif
+#endif
 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 void dcbz_area(u32 start_address, u32 num_bytes);
 
-static u32 mfdcr_any(u32 dcr)
-{
-	u32 val;
-
-	switch (dcr) {
-	case SDRAM_R0BAS + 0:
-		val = mfdcr(SDRAM_R0BAS + 0);
-		break;
-	case SDRAM_R0BAS + 1:
-		val = mfdcr(SDRAM_R0BAS + 1);
-		break;
-	case SDRAM_R0BAS + 2:
-		val = mfdcr(SDRAM_R0BAS + 2);
-		break;
-	case SDRAM_R0BAS + 3:
-		val = mfdcr(SDRAM_R0BAS + 3);
-		break;
-	default:
-		printf("DCR %d not defined in case statement!!!\n", dcr);
-		val = 0; /* just to satisfy the compiler */
-	}
-
-	return val;
-}
-
-static void mtdcr_any(u32 dcr, u32 val)
-{
-	switch (dcr) {
-	case SDRAM_R0BAS + 0:
-		mtdcr(SDRAM_R0BAS + 0, val);
-		break;
-	case SDRAM_R0BAS + 1:
-		mtdcr(SDRAM_R0BAS + 1, val);
-		break;
-	case SDRAM_R0BAS + 2:
-		mtdcr(SDRAM_R0BAS + 2, val);
-		break;
-	case SDRAM_R0BAS + 3:
-		mtdcr(SDRAM_R0BAS + 3, val);
-		break;
-	default:
-		printf("DCR %d not defined in case statement!!!\n", dcr);
-	}
-}
-
 static unsigned char spd_read(uchar chip, uint addr)
 {
 	unsigned char data[2];
@@ -609,7 +564,11 @@ phys_size_t initdram(int board_type)
 	/*------------------------------------------------------------------
 	 * DQS calibration.
 	 *-----------------------------------------------------------------*/
+#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
+	DQS_autocalibration();
+#else
 	program_DQS_calibration(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+#endif
 
 #ifdef CONFIG_DDR_ECC
 	/*------------------------------------------------------------------
@@ -2329,18 +2288,6 @@ static unsigned long is_ecc_enabled(void)
 	return ecc;
 }
 
-static void blank_string(int size)
-{
-	int i;
-
-	for (i=0; i<size; i++)
-		putc('\b');
-	for (i=0; i<size; i++)
-		putc(' ');
-	for (i=0; i<size; i++)
-		putc('\b');
-}
-
 #ifdef CONFIG_DDR_ECC
 /*-----------------------------------------------------------------------------+
  * program_ecc.
@@ -2468,6 +2415,7 @@ static void program_ecc_addr(unsigned long start_address,
 }
 #endif
 
+#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
 /*-----------------------------------------------------------------------------+
  * program_DQS_calibration.
  *-----------------------------------------------------------------------------*/
@@ -3001,7 +2949,8 @@ static void test(void)
 		(ppcMfdcr_sdram(SDRAM_MCOPT1) & ~SDRAM_MCOPT1_MCHK_MASK)
 		| ecc_temp);
 }
-#endif
+#endif /* !HARD_CODED_DQS */
+#endif /* !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION) */
 
 #else /* CONFIG_SPD_EEPROM */
 
@@ -3104,9 +3053,12 @@ phys_size_t initdram(int board_type)
 	/* Set Delay Control Registers */
 
 	mtsdram(SDRAM_DLCR, CFG_SDRAM0_DLCR);
+
+#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
 	mtsdram(SDRAM_RDCC, CFG_SDRAM0_RDCC);
 	mtsdram(SDRAM_RQDC, CFG_SDRAM0_RQDC);
 	mtsdram(SDRAM_RFDC, CFG_SDRAM0_RFDC);
+#endif /* !CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
 
 	/*
 	 * Enable Controller by SDRAM0_MCOPT2[DCEN] = 1:
@@ -3115,18 +3067,98 @@ phys_size_t initdram(int board_type)
 	mfsdram(SDRAM_MCOPT2, val);
 	mtsdram(SDRAM_MCOPT2, val | SDRAM_MCOPT2_DCEN_ENABLE);
 
+#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
+#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+	/*------------------------------------------------------------------
+	 | DQS calibration.
+	 +-----------------------------------------------------------------*/
+	DQS_autocalibration();
+#endif /* !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) */
+#endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
+
 #if defined(CONFIG_DDR_ECC)
 	ecc_init(CFG_SDRAM_BASE, CFG_MBYTES_SDRAM << 20);
 #endif /* defined(CONFIG_DDR_ECC) */
 
 	ppc4xx_ibm_ddr2_register_dump();
+
+#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
+	/*
+	 * Clear potential errors resulting from auto-calibration.
+	 * If not done, then we could get an interrupt later on when
+	 * exceptions are enabled.
+	 */
+	set_mcsr(get_mcsr());
+#endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
+
 #endif /* !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) */
 
 	return (CFG_MBYTES_SDRAM << 20);
 }
 #endif /* CONFIG_SPD_EEPROM */
 
-static inline void ppc4xx_ibm_ddr2_register_dump(void)
+#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+#if defined(CONFIG_440)
+u32 mfdcr_any(u32 dcr)
+{
+	u32 val;
+
+	switch (dcr) {
+	case SDRAM_R0BAS + 0:
+		val = mfdcr(SDRAM_R0BAS + 0);
+		break;
+	case SDRAM_R0BAS + 1:
+		val = mfdcr(SDRAM_R0BAS + 1);
+		break;
+	case SDRAM_R0BAS + 2:
+		val = mfdcr(SDRAM_R0BAS + 2);
+		break;
+	case SDRAM_R0BAS + 3:
+		val = mfdcr(SDRAM_R0BAS + 3);
+		break;
+	default:
+		printf("DCR %d not defined in case statement!!!\n", dcr);
+		val = 0; /* just to satisfy the compiler */
+	}
+
+	return val;
+}
+
+void mtdcr_any(u32 dcr, u32 val)
+{
+	switch (dcr) {
+	case SDRAM_R0BAS + 0:
+		mtdcr(SDRAM_R0BAS + 0, val);
+		break;
+	case SDRAM_R0BAS + 1:
+		mtdcr(SDRAM_R0BAS + 1, val);
+		break;
+	case SDRAM_R0BAS + 2:
+		mtdcr(SDRAM_R0BAS + 2, val);
+		break;
+	case SDRAM_R0BAS + 3:
+		mtdcr(SDRAM_R0BAS + 3, val);
+		break;
+	default:
+		printf("DCR %d not defined in case statement!!!\n", dcr);
+	}
+}
+#endif /* defined(CONFIG_440) */
+
+void blank_string(int size)
+{
+	int i;
+
+	for (i = 0; i < size; i++)
+		putc('\b');
+	for (i = 0; i < size; i++)
+		putc(' ');
+	for (i = 0; i < size; i++)
+		putc('\b');
+}
+#endif /* !defined(CONFIG_NAND_U_BOOT) &&  !defined(CONFIG_NAND_SPL) */
+
+inline void ppc4xx_ibm_ddr2_register_dump(void)
 {
 #if defined(DEBUG)
 	printf("\nPPC4xx IBM DDR2 Register Dump:\n");
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index c773400..75f3e49 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -35,6 +35,9 @@ SOBJS	+= kgdb.o
 COBJS	:= 40x_spd_sdram.o
 COBJS	+= 44x_spd_ddr.o
 COBJS	+= 44x_spd_ddr2.o
+ifdef CONFIG_PPC4xx_DDR_AUTOCALIBRATION 
+COBJS	+= 4xx_ibm_ddr2_autocalib.o 
+endif
 COBJS	+= 4xx_pci.o
 COBJS	+= 4xx_pcie.o
 COBJS	+= bedbug_405.o
diff --git a/include/asm-ppc/ppc4xx-sdram.h b/include/asm-ppc/ppc4xx-sdram.h
index 0174d62..a1ef029 100644
--- a/include/asm-ppc/ppc4xx-sdram.h
+++ b/include/asm-ppc/ppc4xx-sdram.h
@@ -29,6 +29,7 @@
 /*
  * SDRAM Controller
  */
+
 /*
  * XXX - ToDo: Revisit file to change all these lower case defines into
  * upper case. Also needs to be done in the controller setup code too
@@ -256,6 +257,7 @@
 #define SDRAM_DLYCAL_DLCV_ENCODE(x)	(((x)<<2) & SDRAM_DLYCAL_DLCV_MASK)
 #define SDRAM_DLYCAL_DLCV_DECODE(x)	(((x) & SDRAM_DLYCAL_DLCV_MASK)>>2)
 
+#if !defined(CONFIG_405EX)
 /*
  * Memory queue defines
  */
@@ -293,7 +295,6 @@
 
 #define SDRAM_PLBADDUHB		(SDRAMQ_DCR_BASE+0x10)  /* PLB base address upper 32 LL */
 
-#if !defined(CONFIG_405EX)
 /*
  * Memory Bank 0-7 configuration
  */
diff --git a/include/common.h b/include/common.h
index a394988..2516bfd 100644
--- a/include/common.h
+++ b/include/common.h
@@ -287,6 +287,27 @@ void	pciinfo	      (int, int);
 #endif
 #endif
 
+/*
+ * Prototypes
+ */
+#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
+void blank_string(int);
+inline void ppc4xx_ibm_ddr2_register_dump(void);
+#if defined(CONFIG_440)
+u32 mfdcr_any(u32);
+void mtdcr_any(u32, u32);
+#endif
+#if defined(CONFIG_SPD_EEPROM)
+u32 ddr_wrdtr(u32);
+u32 ddr_clktr(u32);
+void spd_ddr_init_hang(void);
+#endif
+#endif /* defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2) */
+
+#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
+u32 DQS_autocalibration(void);
+#endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
+
 int	misc_init_f   (void);
 int	misc_init_r   (void);
 
diff --git a/include/configs/kilauea.h b/include/configs/kilauea.h
index a475f97..f9eaa77 100644
--- a/include/configs/kilauea.h
+++ b/include/configs/kilauea.h
@@ -223,6 +223,22 @@
  *----------------------------------------------------------------------*/
 #define CFG_MBYTES_SDRAM        (256)		/* 256MB			*/
 
+/*
+ * CONFIG_PPC4xx_DDR_AUTOCALIBRATION
+ *
+ * Note: DDR Autocalibration Method_A scans the full range of possible PPC4xx
+ *       SDRAM Controller DDR autocalibration values and takes a lot longer
+ *       to run than Method_B.
+ * (See the Method_A and Method_B algorithm discription in the file:
+ *	cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c)
+ * Define CONFIG_PPC4xx_DDR_METHOD_A to use DDR autocalibration Method_A
+ *
+ * DDR Autocalibration Method_B is the default.
+ */
+#define	CONFIG_PPC4xx_DDR_AUTOCALIBRATION	/* IBM DDR autocalibration */
+#define	DEBUG_PPC4xx_DDR_AUTOCALIBRATION	/* dynamic DDR autocal debug */
+#undef	CONFIG_PPC4xx_DDR_METHOD_A
+
 #define	CFG_SDRAM0_MB0CF_BASE	((  0 << 20) + CFG_SDRAM_BASE)
 
 /* DDR1/2 SDRAM Device Control Register Data Values */
@@ -386,6 +402,9 @@
 #define CONFIG_HAS_ETH1		1	/* add support for "eth1addr"   */
 #define CONFIG_PHY1_ADDR	2
 
+/* Debug messages for the DDR autocalibration */
+#define CONFIG_AUTOCALIB		"silent\0"  /* default is non-verbose */
+
 /*
  * Default environment variables
  */
diff --git a/include/ppc440.h b/include/ppc440.h
index 3584fd2..be8d3ff 100644
--- a/include/ppc440.h
+++ b/include/ppc440.h
@@ -2064,19 +2064,6 @@
 
 #ifndef __ASSEMBLY__
 
-static inline u32 get_mcsr(void)
-{
-	u32 val;
-
-	asm volatile("mfspr %0, 0x23c" : "=r" (val) :);
-	return val;
-}
-
-static inline void set_mcsr(u32 val)
-{
-	asm volatile("mtspr 0x23c, %0" : "=r" (val) :);
-}
-
 #endif	/* _ASMLANGUAGE */
 
 #endif	/* __PPC440_H__ */
diff --git a/include/ppc4xx.h b/include/ppc4xx.h
index 59a3b06..e216663 100644
--- a/include/ppc4xx.h
+++ b/include/ppc4xx.h
@@ -203,6 +203,19 @@ typedef struct
 	unsigned long pllPlbDiv;
 } PPC4xx_SYS_INFO;
 
+static inline u32 get_mcsr(void)
+{
+	u32 val;
+
+	asm volatile("mfspr %0, 0x23c" : "=r" (val) :);
+	return val;
+}
+
+static inline void set_mcsr(u32 val)
+{
+	asm volatile("mtspr 0x23c, %0" : "=r" (val) :);
+}
+
 #endif	/* __ASSEMBLY__ */
 
 #endif	/* __PPC4XX_H__ */
-- 
1.5.5



More information about the U-Boot mailing list