Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02f513a0 authored by Peter Rosin's avatar Peter Rosin Committed by Nicolas Ferre
Browse files

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: default avatarPeter Rosin <peda@axentia.se>
Acked-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
parent ad4a38d2
Loading
Loading
Loading
Loading
+38 −5
Original line number Diff line number Diff line
@@ -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

@@ -255,12 +277,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]

@@ -294,5 +321,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
+1 −1
Original line number Diff line number Diff line
@@ -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