diff options
Diffstat (limited to 'arch/powerpc/cpu/mpc85xx/ddr-gen3.c')
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/ddr-gen3.c | 36 | 
1 files changed, 35 insertions, 1 deletions
| diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c index c5b47200e..1be51d330 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 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,  		return;  	} +	if (step == 2) +		goto step2; +  	if (regs->ddr_eor)  		out_be32(&ddr->eor, regs->ddr_eor);  #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 @@ -123,10 +136,17 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,  	out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);  	out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);  	out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl); +#ifndef CONFIG_SYS_FSL_DDR_EMU +	/* +	 * Skip these two registers if running on emulator +	 * because emulator doesn't have skew between bytes. +	 */ +  	if (regs->ddr_wrlvl_cntl_2)  		out_be32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2);  	if (regs->ddr_wrlvl_cntl_3)  		out_be32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3); +#endif  	out_be32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);  	out_be32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1); @@ -150,6 +170,20 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,  	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); |