Commit a02875c4 authored by Claudiu Beznea's avatar Claudiu Beznea
Browse files

ARM: at91: pm: fix self-refresh for sama7g5



It has been discovered that on some parts, from time to time, self-refresh
procedure doesn't work as expected. Debugging and investigating it proved
that disabling AC DLL introduce glitches in RAM controllers which
leads to unexpected behavior. This is confirmed as a hardware bug. DLL
bypass disables 3 DLLs: 2 DX DLLs and AC DLL. Thus, keep only DX DLLs
disabled. This introduce 6mA extra current consumption on VDDCORE when
switching to any ULP mode or standby mode but the self-refresh procedure
still works.

Fixes: f0bbf179 ("ARM: at91: pm: add self-refresh support for sama7g5")
Suggested-by: default avatarFrederic Schumacher <frederic.schumacher@microchip.com>
Signed-off-by: default avatarClaudiu Beznea <claudiu.beznea@microchip.com>
Tested-by: default avatarCristian Birsan <cristian.birsan@microchip.com>
Link: https://lore.kernel.org/r/20220826083927.3107272-3-claudiu.beznea@microchip.com
parent f04445fa
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -172,9 +172,15 @@ sr_ena_2:
	/* Put DDR PHY's DLL in bypass mode for non-backup modes. */
	cmp	r7, #AT91_PM_BACKUP
	beq	sr_ena_3
	ldr	tmp1, [r3, #DDR3PHY_PIR]
	orr	tmp1, tmp1, #DDR3PHY_PIR_DLLBYP
	str	tmp1, [r3, #DDR3PHY_PIR]

	/* Disable DX DLLs. */
	ldr	tmp1, [r3, #DDR3PHY_DX0DLLCR]
	orr	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
	str	tmp1, [r3, #DDR3PHY_DX0DLLCR]

	ldr	tmp1, [r3, #DDR3PHY_DX1DLLCR]
	orr	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
	str	tmp1, [r3, #DDR3PHY_DX1DLLCR]

sr_ena_3:
	/* Power down DDR PHY data receivers. */
@@ -221,10 +227,14 @@ sr_ena_3:
	bic	tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0
	str	tmp1, [r3, #DDR3PHY_DSGCR]

	/* Take DDR PHY's DLL out of bypass mode. */
	ldr	tmp1, [r3, #DDR3PHY_PIR]
	bic	tmp1, tmp1, #DDR3PHY_PIR_DLLBYP
	str	tmp1, [r3, #DDR3PHY_PIR]
	/* Enable DX DLLs. */
	ldr	tmp1, [r3, #DDR3PHY_DX0DLLCR]
	bic	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
	str	tmp1, [r3, #DDR3PHY_DX0DLLCR]

	ldr	tmp1, [r3, #DDR3PHY_DX1DLLCR]
	bic	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
	str	tmp1, [r3, #DDR3PHY_DX1DLLCR]

	/* Enable quasi-dynamic programming. */
	mov	tmp1, #0
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,10 @@

#define DDR3PHY_ZQ0SR0				(0x188)		/* ZQ status register 0 */

#define	DDR3PHY_DX0DLLCR			(0x1CC)		/* DDR3PHY DATX8 DLL Control Register */
#define	DDR3PHY_DX1DLLCR			(0x20C)		/* DDR3PHY DATX8 DLL Control Register */
#define		DDR3PHY_DXDLLCR_DLLDIS		(1 << 31)	/* DLL Disable */

/* UDDRC */
#define UDDRC_STAT				(0x04)		/* UDDRC Operating Mode Status Register */
#define		UDDRC_STAT_SELFREF_TYPE_DIS	(0x0 << 4)	/* SDRAM is not in Self-refresh */