]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ARM: at91: pm: add support for ULP0 fast wakeup
authorClaudiu Beznea <claudiu.beznea@microchip.com>
Wed, 5 Aug 2020 08:36:48 +0000 (11:36 +0300)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Mon, 17 Aug 2020 09:18:17 +0000 (11:18 +0200)
ULP0 fast improves suspend/resume time with few milliseconds the drawback
being the power consumption. The mean values measured for suspend/resume
time are as follows (measured on SAMA5D2 Xplained board), ULP0 compared
with fast ULP0:
- ulp0 fast: suspend time: 169 ms, resume time: 216 ms
- ulp0     : suspend time: 197 ms, resume time: 258 ms

Current consumption while suspended (measured on SAMA5D2 Xplained board):
- ulp0 fast: 730uA
- ulp0     : 270uA

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/1596616610-15460-2-git-send-email-claudiu.beznea@microchip.com
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm.h
arch/arm/mach-at91/pm_suspend.S

index 2aab043441e8fb1afd16276e2e1f25e7fecfc2cb..a6336af1f449df2fa6c66b9f5b39d993656e97e6 100644 (file)
@@ -51,10 +51,11 @@ static struct at91_soc_pm soc_pm = {
 };
 
 static const match_table_t pm_modes __initconst = {
-       { AT91_PM_STANDBY, "standby" },
-       { AT91_PM_ULP0, "ulp0" },
-       { AT91_PM_ULP1, "ulp1" },
-       { AT91_PM_BACKUP, "backup" },
+       { AT91_PM_STANDBY,      "standby" },
+       { AT91_PM_ULP0,         "ulp0" },
+       { AT91_PM_ULP0_FAST,    "ulp0-fast" },
+       { AT91_PM_ULP1,         "ulp1" },
+       { AT91_PM_BACKUP,       "backup" },
        { -1, NULL },
 };
 
index 218e8d1a30fb5d4b768b7f7d019f98126d5cdc3d..bfb260be371e2ede9ff5213fef403c9c793b0d90 100644 (file)
@@ -19,8 +19,9 @@
 
 #define        AT91_PM_STANDBY         0x00
 #define AT91_PM_ULP0           0x01
-#define AT91_PM_ULP1           0x02
-#define        AT91_PM_BACKUP          0x03
+#define AT91_PM_ULP0_FAST      0x02
+#define AT91_PM_ULP1           0x03
+#define        AT91_PM_BACKUP          0x04
 
 #ifndef __ASSEMBLY__
 struct at91_pm_data {
index be9764e8d3fa13b78b4e0cdb4e2e82f0ab4c1862..0184de05c1be1879a9f4c62d1c4135e94d6cad38 100644 (file)
@@ -164,7 +164,22 @@ ENDPROC(at91_backup_mode)
 
 .macro at91_pm_ulp0_mode
        ldr     pmc, .pmc_base
+       ldr     tmp2, .pm_mode
+       ldr     tmp3, .mckr_offset
+
+       /* Check if ULP0 fast variant has been requested. */
+       cmp     tmp2, #AT91_PM_ULP0_FAST
+       bne     0f
+
+       /* Set highest prescaler for power saving */
+       ldr     tmp1, [pmc, tmp3]
+       bic     tmp1, tmp1, #AT91_PMC_PRES
+       orr     tmp1, tmp1, #AT91_PMC_PRES_64
+       str     tmp1, [pmc, tmp3]
+       wait_mckrdy
+       b       1f
 
+0:
        /* Turn off the crystal oscillator */
        ldr     tmp1, [pmc, #AT91_CKGR_MOR]
        bic     tmp1, tmp1, #AT91_PMC_MOSCEN
@@ -192,7 +207,18 @@ ENDPROC(at91_backup_mode)
        /* Wait for interrupt */
 1:     at91_cpu_idle
 
-       /* Restore RC oscillator state */
+       /* Check if ULP0 fast variant has been requested. */
+       cmp     tmp2, #AT91_PM_ULP0_FAST
+       bne     5f
+
+       /* Set lowest prescaler for fast resume. */
+       ldr     tmp1, [pmc, tmp3]
+       bic     tmp1, tmp1, #AT91_PMC_PRES
+       str     tmp1, [pmc, tmp3]
+       wait_mckrdy
+       b       6f
+
+5:     /* Restore RC oscillator state */
        ldr     tmp1, .saved_osc_status
        tst     tmp1, #AT91_PMC_MOSCRCS
        beq     4f
@@ -216,6 +242,7 @@ ENDPROC(at91_backup_mode)
        str     tmp1, [pmc, #AT91_CKGR_MOR]
 
        wait_moscrdy
+6:
 .endm
 
 /**
@@ -473,23 +500,29 @@ ENDPROC(at91_backup_mode)
 ENTRY(at91_ulp_mode)
        ldr     pmc, .pmc_base
        ldr     tmp2, .mckr_offset
+       ldr     tmp3, .pm_mode
 
        /* Save Master clock setting */
        ldr     tmp1, [pmc, tmp2]
        str     tmp1, .saved_mckr
 
        /*
-        * Set the Master clock source to slow clock
+        * Set master clock source to:
+        * - MAINCK if using ULP0 fast variant
+        * - slow clock, otherwise
         */
        bic     tmp1, tmp1, #AT91_PMC_CSS
+       cmp     tmp3, #AT91_PM_ULP0_FAST
+       bne     save_mck
+       orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
+save_mck:
        str     tmp1, [pmc, tmp2]
 
        wait_mckrdy
 
        at91_plla_disable
 
-       ldr     r0, .pm_mode
-       cmp     r0, #AT91_PM_ULP1
+       cmp     tmp3, #AT91_PM_ULP1
        beq     ulp1_mode
 
        at91_pm_ulp0_mode