Re: [PATCH 6/8] ARM: at91: pm: add ULP1 support for SAM9X60

2019-02-15 Thread Stephen Boyd
Quoting claudiu.bez...@microchip.com (2019-02-14 07:54:57)
> From: Claudiu Beznea 
> 
> Add ULP1 support for SAM9X60. In pm_suspend.S enable RC oscillator in
> PMC if it is not enabled. At resume the state before suspend is
> restored.
> 
> Signed-off-by: Claudiu Beznea 
> ---
>  include/linux/clk/at91_pmc.h|  1 +

Acked-by: Stephen Boyd 



[PATCH 6/8] ARM: at91: pm: add ULP1 support for SAM9X60

2019-02-14 Thread Claudiu.Beznea
From: Claudiu Beznea 

Add ULP1 support for SAM9X60. In pm_suspend.S enable RC oscillator in
PMC if it is not enabled. At resume the state before suspend is
restored.

Signed-off-by: Claudiu Beznea 
---
 arch/arm/mach-at91/pm.c | 24 
 arch/arm/mach-at91/pm_suspend.S | 41 -
 include/linux/clk/at91_pmc.h|  1 +
 3 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 27264caa4ec6..5571658b3c46 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -100,6 +100,8 @@ static const struct wakeup_source_info ws_info[] = {
{ .pmc_fsmr_bit = AT91_PMC_RTCAL,   .shdwc_mr_bit = BIT(17) },
{ .pmc_fsmr_bit = AT91_PMC_USBAL },
{ .pmc_fsmr_bit = AT91_PMC_SDMMC_CD },
+   { .pmc_fsmr_bit = AT91_PMC_RTTAL },
+   { .pmc_fsmr_bit = AT91_PMC_RXLP_MCE },
 };
 
 static const struct of_device_id sama5d2_ws_ids[] = {
@@ -114,6 +116,17 @@ static const struct of_device_id sama5d2_ws_ids[] = {
{ /* sentinel */ }
 };
 
+static const struct of_device_id sam9x60_ws_ids[] = {
+   { .compatible = "atmel,at91sam9x5-rtc", .data = _info[1] },
+   { .compatible = "atmel,at91rm9200-ohci",.data = _info[2] },
+   { .compatible = "usb-ohci", .data = _info[2] },
+   { .compatible = "atmel,at91sam9g45-ehci",   .data = _info[2] },
+   { .compatible = "usb-ehci", .data = _info[2] },
+   { .compatible = "atmel,at91sam9260-rtt",.data = _info[4] },
+   { .compatible = "cdns,sam9x60-macb",.data = _info[5] },
+   { /* sentinel */ }
+};
+
 static int at91_pm_config_ws(unsigned int pm_mode, bool set)
 {
const struct wakeup_source_info *wsi;
@@ -192,6 +205,13 @@ static int at91_sama5d2_config_pmc_ws(void __iomem *pmc, 
u32 mode, u32 polarity)
return 0;
 }
 
+static int at91_sam9x60_config_pmc_ws(void __iomem *pmc, u32 mode, u32 
polarity)
+{
+   writel(mode, pmc + AT91_PMC_FSMR);
+
+   return 0;
+}
+
 /*
  * Called after processes are frozen, but before we shutdown devices.
  */
@@ -789,8 +809,12 @@ void __init sam9x60_pm_init(void)
if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
return;
 
+   at91_pm_modes_init();
at91_dt_ramc();
at91_pm_init(at91sam9x60_idle);
+
+   soc_pm.ws_ids = sam9x60_ws_ids;
+   soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
 }
 
 void __init at91sam9_pm_init(void)
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index bfe1c4d06901..8b18cad1dcf5 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -197,8 +197,26 @@ ENDPROC(at91_backup_mode)
 .macro at91_pm_ulp1_mode
ldr pmc, .pmc_base
 
-   /* Switch the main clock source to 12-MHz RC oscillator */
+   /* Save RC oscillator state and check if it is enabled. */
+   ldr tmp1, [pmc, #AT91_PMC_SR]
+   str tmp1, .saved_osc_status
+   tst tmp1, #AT91_PMC_MOSCRCS
+   bne 2f
+
+   /* Enable RC oscillator */
ldr tmp1, [pmc, #AT91_CKGR_MOR]
+   orr tmp1, tmp1, #AT91_PMC_MOSCRCEN
+   bic tmp1, tmp1, #AT91_PMC_KEY_MASK
+   orr tmp1, tmp1, #AT91_PMC_KEY
+   str tmp1, [pmc, #AT91_CKGR_MOR]
+
+   /* Wait main RC stabilization */
+1: ldr tmp1, [pmc, #AT91_PMC_SR]
+   tst tmp1, #AT91_PMC_MOSCRCS
+   beq 1b
+
+   /* Switch the main clock source to 12-MHz RC oscillator */
+2: ldr tmp1, [pmc, #AT91_CKGR_MOR]
bic tmp1, tmp1, #AT91_PMC_MOSCSEL
bic tmp1, tmp1, #AT91_PMC_KEY_MASK
orr tmp1, tmp1, #AT91_PMC_KEY
@@ -262,6 +280,25 @@ ENDPROC(at91_backup_mode)
str tmp1, [pmc, #AT91_PMC_MCKR]
 
wait_mckrdy
+
+   /* Restore RC oscillator state */
+   ldr tmp1, .saved_osc_status
+   tst tmp1, #AT91_PMC_MOSCRCS
+   bne 3f
+
+   /* Disable RC oscillator */
+   ldr tmp1, [pmc, #AT91_CKGR_MOR]
+   bic tmp1, tmp1, #AT91_PMC_MOSCRCEN
+   bic tmp1, tmp1, #AT91_PMC_KEY_MASK
+   orr tmp1, tmp1, #AT91_PMC_KEY
+   str tmp1, [pmc, #AT91_CKGR_MOR]
+
+   /* Wait RC oscillator disable done */
+4: ldr tmp1, [pmc, #AT91_PMC_SR]
+   tst tmp1, #AT91_PMC_MOSCRCS
+   bne 4b
+
+3:
 .endm
 
 ENTRY(at91_ulp_mode)
@@ -475,6 +512,8 @@ ENDPROC(at91_sramc_self_refresh)
.word 0
 .saved_sam9_mdr1:
.word 0
+.saved_osc_status:
+   .word 0
 
 ENTRY(at91_pm_suspend_in_sram_sz)
.word .-at91_pm_suspend_in_sram
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 931ab05f771d..bd3a65c0bad3 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -159,6 +159,7 @@
 
 #define AT91_PMC_FSMR  0x70/* Fast Startup Mode Register */
 #define