提交 02f513a0 编写于 作者: P Peter Rosin 提交者: Nicolas Ferre

pm: at91: Workaround DDRSDRC self-refresh bug with LPDDR1 memories.

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: NPeter Rosin <peda@axentia.se>
Acked-by: NNicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: NNicolas Ferre <nicolas.ferre@atmel.com>
上级 ad4a38d2
...@@ -109,6 +109,16 @@ ddr_sr_enable: ...@@ -109,6 +109,16 @@ ddr_sr_enable:
cmp memctrl, #AT91_MEMCTRL_DDRSDR cmp memctrl, #AT91_MEMCTRL_DDRSDR
bne sdr_sr_enable 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 */ /* prepare for DDRAM self-refresh mode */
ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
str tmp1, .saved_sam9_lpr str tmp1, .saved_sam9_lpr
...@@ -117,14 +127,26 @@ ddr_sr_enable: ...@@ -117,14 +127,26 @@ ddr_sr_enable:
/* figure out if we use the second ram controller */ /* figure out if we use the second ram controller */
cmp ramc1, #0 cmp ramc1, #0
ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR] beq ddr_no_2nd_ctrl
strne tmp2, .saved_sam9_lpr1
bicne tmp2, #AT91_DDRSDRC_LPCB ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR]
orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH 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 */ /* Enable DDRAM self-refresh mode */
str tmp2, [ramc1, #AT91_DDRSDRC_LPR]
ddr_no_2nd_ctrl:
str tmp1, [sdramc, #AT91_DDRSDRC_LPR] str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
b sdr_sr_done b sdr_sr_done
...@@ -255,12 +277,17 @@ sdr_sr_done: ...@@ -255,12 +277,17 @@ sdr_sr_done:
*/ */
cmp memctrl, #AT91_MEMCTRL_DDRSDR cmp memctrl, #AT91_MEMCTRL_DDRSDR
bne sdr_en_restore 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 */ /* Restore LPR on AT91 with DDRAM */
ldr tmp1, .saved_sam9_lpr ldr tmp1, .saved_sam9_lpr
str tmp1, [sdramc, #AT91_DDRSDRC_LPR] str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
/* if we use the second ram controller */ /* if we use the second ram controller */
cmp ramc1, #0 cmp ramc1, #0
ldrne tmp2, .saved_sam9_mdr1
strne tmp2, [ramc1, #AT91_DDRSDRC_MDR]
ldrne tmp2, .saved_sam9_lpr1 ldrne tmp2, .saved_sam9_lpr1
strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
...@@ -294,5 +321,11 @@ ram_restored: ...@@ -294,5 +321,11 @@ ram_restored:
.saved_sam9_lpr1: .saved_sam9_lpr1:
.word 0 .word 0
.saved_sam9_mdr:
.word 0
.saved_sam9_mdr1:
.word 0
ENTRY(at91_slow_clock_sz) ENTRY(at91_slow_clock_sz)
.word .-at91_slow_clock .word .-at91_slow_clock
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
#define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */ #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_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_SDR 0
#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 #define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 #define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册