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.bez...@microchip.com>
---
 arch/arm/mach-at91/pm.c         |  9 +++++----
 arch/arm/mach-at91/pm.h         |  5 +++--
 arch/arm/mach-at91/pm_suspend.S | 41 +++++++++++++++++++++++++++++++++++++----
 3 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 074bde64064e..04fdcbd57100 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -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 },
 };
 
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 218e8d1a30fb..bfb260be371e 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -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 {
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index be9764e8d3fa..0184de05c1be 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -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
-- 
2.7.4

Reply via email to