powerpc/mpc8xxx: Add memory reset control

JEDEC spec requires the clocks to be stable before deasserting reset
signal for RDIMMs. Clocks start when any chip select is enabled and
clock control register is set. This patch also adds the interface to
toggle memory reset signal if needed by the boards.

Signed-off-by: York Sun <yorksun@freescale.com>
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen1.c b/arch/powerpc/cpu/mpc85xx/ddr-gen1.c
index 8a86819..4dd8c0b 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen1.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen1.c
@@ -15,7 +15,7 @@
 #endif
 
 void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
-			     unsigned int ctrl_num)
+			     unsigned int ctrl_num, int step)
 {
 	unsigned int i;
 	volatile ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c
index a705862..542bc84 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c
@@ -16,7 +16,7 @@
 #endif
 
 void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
-			     unsigned int ctrl_num)
+			     unsigned int ctrl_num, int step)
 {
 	unsigned int i;
 	ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
index 3e7a564..1be51d3 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
@@ -15,8 +15,18 @@
 #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
 #endif
 
+
+/*
+ * regs has the to-be-set values for DDR controller registers
+ * ctrl_num is the DDR controller number
+ * step: 0 goes through the initialization in one pass
+ *       1 sets registers and returns before enabling controller
+ *       2 resumes from step 1 and continues to initialize
+ * Dividing the initialization to two steps to deassert DDR reset signal
+ * to comply with JEDEC specs for RDIMMs.
+ */
 void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
-			     unsigned int ctrl_num)
+			     unsigned int ctrl_num, int step)
 {
 	unsigned int i, bus_width;
 	volatile ccsr_ddr_t *ddr;
@@ -54,6 +64,9 @@
 		return;
 	}
 
+	if (step == 2)
+		goto step2;
+
 	if (regs->ddr_eor)
 		out_be32(&ddr->eor, regs->ddr_eor);
 #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
@@ -157,6 +170,20 @@
 	out_be32(&ddr->debug[21], 0x24000000);
 #endif /* CONFIG_SYS_FSL_ERRATUM_DDR_A003474 */
 
+	/*
+	 * For RDIMMs, JEDEC spec requires clocks to be stable before reset is
+	 * deasserted. Clocks start when any chip select is enabled and clock
+	 * control register is set. Because all DDR components are connected to
+	 * one reset signal, this needs to be done in two steps. Step 1 is to
+	 * get the clocks started. Step 2 resumes after reset signal is
+	 * deasserted.
+	 */
+	if (step == 1) {
+		udelay(200);
+		return;
+	}
+
+step2:
 	/* Set, but do not enable the memory */
 	temp_sdram_cfg = regs->ddr_sdram_cfg;
 	temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);