]> git.itanic.dy.fi Git - linux-stable/commitdiff
ARM: at91: pm: fix self-refresh for sama7g5
authorClaudiu Beznea <claudiu.beznea@microchip.com>
Fri, 26 Aug 2022 08:39:20 +0000 (11:39 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Sep 2022 09:30:04 +0000 (11:30 +0200)
[ Upstream commit a02875c4cbd6f3d2f33d70cc158a19ef02d4b84f ]

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: f0bbf17958e8 ("ARM: at91: pm: add self-refresh support for sama7g5")
Suggested-by: Frederic Schumacher <frederic.schumacher@microchip.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Tested-by: Cristian Birsan <cristian.birsan@microchip.com>
Link: https://lore.kernel.org/r/20220826083927.3107272-3-claudiu.beznea@microchip.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/arm/mach-at91/pm_suspend.S
include/soc/at91/sama7-ddr.h

index fdb4f63ecde4bc6a2d523c7ee3d41ff7a60b287c..65cfcc19a936c3997a12ff9c9b5e4c34f61827ce 100644 (file)
@@ -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
index f6542584ca13920fc028eb1fe7fca471678017e2..f47a933df82eac895351323bb188aec7c8e269d1 100644 (file)
 
 #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 */