[PATCH 3/3] pm: at91: Workaround DDRSDRC self-refresh bug with LPDDR1 memories.
Nicolas Ferre
nicolas.ferre at atmel.com
Tue Mar 3 10:41:57 PST 2015
Le 05/02/2015 07:02, Wenyou Yang a écrit :
> From: Peter Rosin <peda at axentia.se>
>
> The DDRSDR controller fails miserably to put LPDDR1 memories in
> self-refresh. Force the controller to think it has DDR2 memories
> during the self-refresh period, as the DDR2 self-refresh spec is
> equivalent to LPDDR1, and is correctly implemented in the
> controller.
>
> Assume that the second controller has the same fault, but that is
> untested.
>
> Signed-off-by: Peter Rosin <peda at axentia.se>
> Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
Stacked in at91-4.0-fixes.
Bye,
> ---
> arch/arm/mach-at91/pm_slowclock.S | 43 +++++++++++++++++++++++++++++++-----
> include/soc/at91/at91sam9_ddrsdr.h | 2 +-
> 2 files changed, 39 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
> index 75d8b19..487ae1e 100644
> --- a/arch/arm/mach-at91/pm_slowclock.S
> +++ b/arch/arm/mach-at91/pm_slowclock.S
> @@ -109,6 +109,16 @@ ddr_sr_enable:
> cmp memctrl, #AT91_MEMCTRL_DDRSDR
> bne sdr_sr_enable
>
> + /* LPDDR1 --> force DDR2 mode during self-refresh */
> + ldr tmp1, [sdramc, #AT91_DDRSDRC_MDR]
> + str tmp1, .saved_sam9_mdr
> + bic tmp1, tmp1, #~AT91_DDRSDRC_MD
> + cmp tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR
> + ldreq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
> + biceq tmp1, tmp1, #AT91_DDRSDRC_MD
> + orreq tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2
> + streq tmp1, [sdramc, #AT91_DDRSDRC_MDR]
> +
> /* prepare for DDRAM self-refresh mode */
> ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
> str tmp1, .saved_sam9_lpr
> @@ -117,14 +127,26 @@ ddr_sr_enable:
>
> /* figure out if we use the second ram controller */
> cmp ramc1, #0
> - ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
> - strne tmp2, .saved_sam9_lpr1
> - bicne tmp2, #AT91_DDRSDRC_LPCB
> - orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
> + beq ddr_no_2nd_ctrl
> +
> + ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR]
> + str tmp2, .saved_sam9_mdr1
> + bic tmp2, tmp2, #~AT91_DDRSDRC_MD
> + cmp tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR
> + ldreq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
> + biceq tmp2, tmp2, #AT91_DDRSDRC_MD
> + orreq tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2
> + streq tmp2, [ramc1, #AT91_DDRSDRC_MDR]
> +
> + ldr tmp2, [ramc1, #AT91_DDRSDRC_LPR]
> + str tmp2, .saved_sam9_lpr1
> + bic tmp2, #AT91_DDRSDRC_LPCB
> + orr tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
>
> /* Enable DDRAM self-refresh mode */
> + str tmp2, [ramc1, #AT91_DDRSDRC_LPR]
> +ddr_no_2nd_ctrl:
> str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
> - strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
>
> b sdr_sr_done
>
> @@ -236,12 +258,17 @@ sdr_sr_done:
> */
> cmp memctrl, #AT91_MEMCTRL_DDRSDR
> bne sdr_en_restore
> + /* Restore MDR in case of LPDDR1 */
> + ldr tmp1, .saved_sam9_mdr
> + str tmp1, [sdramc, #AT91_DDRSDRC_MDR]
> /* Restore LPR on AT91 with DDRAM */
> ldr tmp1, .saved_sam9_lpr
> str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
>
> /* if we use the second ram controller */
> cmp ramc1, #0
> + ldrne tmp2, .saved_sam9_mdr1
> + strne tmp2, [ramc1, #AT91_DDRSDRC_MDR]
> ldrne tmp2, .saved_sam9_lpr1
> strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
>
> @@ -272,5 +299,11 @@ ram_restored:
> .saved_sam9_lpr1:
> .word 0
>
> +.saved_sam9_mdr:
> + .word 0
> +
> +.saved_sam9_mdr1:
> + .word 0
> +
> ENTRY(at91_slow_clock_sz)
> .word .-at91_slow_clock
> diff --git a/include/soc/at91/at91sam9_ddrsdr.h b/include/soc/at91/at91sam9_ddrsdr.h
> index 0210797..dc10c52 100644
> --- a/include/soc/at91/at91sam9_ddrsdr.h
> +++ b/include/soc/at91/at91sam9_ddrsdr.h
> @@ -92,7 +92,7 @@
> #define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */
>
> #define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */
> -#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */
> +#define AT91_DDRSDRC_MD (7 << 0) /* Memory Device Type */
> #define AT91_DDRSDRC_MD_SDR 0
> #define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
> #define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
>
--
Nicolas Ferre
More information about the linux-arm-kernel
mailing list