All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] ARM: at91/pm: add ULP1 support
@ 2015-10-15  3:41 ` Wenyou Yang
  0 siblings, 0 replies; 14+ messages in thread
From: Wenyou Yang @ 2015-10-15  3:41 UTC (permalink / raw)
  To: Nicolas Ferre, Alexandre Belloni, Jean-Christophe Plagniol-Villard
  Cc: Russell King, Stephen Boyd, Michael Turquette, linux-arm-kernel,
	linux-kernel, linux-clk, Wenyou Yang

This patch series is to add the ultra Low-power mode 1(ULP1) mode
support.

The ULP1 mode is introduced by SAMA5D2. In ULP1 mode, the system can
achieve the lowest power consumption, and it can be woken up more
quickly, about 30uS.


Wenyou Yang (2):
  ARM: at91/pm: move enter sleep code to a procedure
  ARM: at91/pm: add ultra Low-power mode 1(ULP1) support

 arch/arm/mach-at91/pm.c         |   29 +++++
 arch/arm/mach-at91/pm.h         |    7 ++
 arch/arm/mach-at91/pm_suspend.S |  239 +++++++++++++++++++++++++++++----------
 include/linux/clk/at91_pmc.h    |   36 ++++++
 4 files changed, 249 insertions(+), 62 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 0/2] ARM: at91/pm: add ULP1 support
@ 2015-10-15  3:41 ` Wenyou Yang
  0 siblings, 0 replies; 14+ messages in thread
From: Wenyou Yang @ 2015-10-15  3:41 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series is to add the ultra Low-power mode 1(ULP1) mode
support.

The ULP1 mode is introduced by SAMA5D2. In ULP1 mode, the system can
achieve the lowest power consumption, and it can be woken up more
quickly, about 30uS.


Wenyou Yang (2):
  ARM: at91/pm: move enter sleep code to a procedure
  ARM: at91/pm: add ultra Low-power mode 1(ULP1) support

 arch/arm/mach-at91/pm.c         |   29 +++++
 arch/arm/mach-at91/pm.h         |    7 ++
 arch/arm/mach-at91/pm_suspend.S |  239 +++++++++++++++++++++++++++++----------
 include/linux/clk/at91_pmc.h    |   36 ++++++
 4 files changed, 249 insertions(+), 62 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/2] ARM: at91/pm: move enter sleep code to a procedure
  2015-10-15  3:41 ` Wenyou Yang
@ 2015-10-15  3:41   ` Wenyou Yang
  -1 siblings, 0 replies; 14+ messages in thread
From: Wenyou Yang @ 2015-10-15  3:41 UTC (permalink / raw)
  To: Nicolas Ferre, Alexandre Belloni, Jean-Christophe Plagniol-Villard
  Cc: Russell King, Stephen Boyd, Michael Turquette, linux-arm-kernel,
	linux-kernel, linux-clk, Wenyou Yang

To make the code more legible and to prepare for the ULP1 support
in the future, move the Master clock, PLLA, MOR handling code and
the sleep code to a separate procedure.

Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---

 arch/arm/mach-at91/pm_suspend.S |  132 ++++++++++++++++++++-------------------
 1 file changed, 68 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 0d95f48..825347b 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -105,77 +105,19 @@ ENTRY(at91_pm_suspend_in_sram)
 
 	ldr	r0, .pm_mode
 	tst	r0, #AT91_PM_SLOW_CLOCK
-	beq	skip_disable_main_clock
+	beq	standby_mode
 
-	ldr	pmc, .pmc_base
-
-	/* Save Master clock setting */
-	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
-	str	tmp1, .saved_mckr
+ulp0_mode:
+	bl	at91_pm_ulp0_mode
+	b	pm_exit
 
-	/*
-	 * Set the Master clock source to slow clock
-	 */
-	bic	tmp1, tmp1, #AT91_PMC_CSS
-	str	tmp1, [pmc, #AT91_PMC_MCKR]
-
-	wait_mckrdy
-
-	/* Save PLLA setting and disable it */
-	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
-	str	tmp1, .saved_pllar
-
-	mov	tmp1, #AT91_PMC_PLLCOUNT
-	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
-	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
-
-	/* Turn off the main oscillator */
-	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
-	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
-	orr	tmp1, tmp1, #AT91_PMC_KEY
-	str	tmp1, [pmc, #AT91_CKGR_MOR]
-
-skip_disable_main_clock:
+standby_mode:
 	ldr	pmc, .pmc_base
 
 	/* Wait for interrupt */
 	at91_cpu_idle
 
-	ldr	r0, .pm_mode
-	tst	r0, #AT91_PM_SLOW_CLOCK
-	beq	skip_enable_main_clock
-
-	ldr	pmc, .pmc_base
-
-	/* Turn on the main oscillator */
-	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
-	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
-	orr	tmp1, tmp1, #AT91_PMC_KEY
-	str	tmp1, [pmc, #AT91_CKGR_MOR]
-
-	wait_moscrdy
-
-	/* Restore PLLA setting */
-	ldr	tmp1, .saved_pllar
-	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
-
-	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
-	bne	3f
-	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
-	beq	4f
-3:
-	wait_pllalock
-4:
-
-	/*
-	 * Restore master clock setting
-	 */
-	ldr	tmp1, .saved_mckr
-	str	tmp1, [pmc, #AT91_PMC_MCKR]
-
-	wait_mckrdy
-
-skip_enable_main_clock:
+pm_exit:
 	/* Exit the self-refresh mode */
 	mov	r0, #SRAMC_SELF_FRESH_EXIT
 	bl	at91_sramc_self_refresh
@@ -309,6 +251,68 @@ exit_sramc_sf:
 	mov	pc, lr
 ENDPROC(at91_sramc_self_refresh)
 
+/*
+ * void at91_pm_ulp0_mode(void)
+ */
+ENTRY(at91_pm_ulp0_mode)
+	ldr	pmc, .pmc_base
+
+	/* Save PMC_MCKR config */
+	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
+	str	tmp1, .saved_mckr
+
+	/* Switch master clock source to slow clock */
+	bic	tmp1, tmp1, #AT91_PMC_CSS
+	str	tmp1, [pmc, #AT91_PMC_MCKR]
+
+	wait_mckrdy
+
+	/* Save PLLA config, then and disable PLLA */
+	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
+	str	tmp1, .saved_pllar
+
+	mov	tmp1, #AT91_PMC_PLLCOUNT
+	orr	tmp1, tmp1, #(1 << 29)
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	/* Turn off the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	/* Wait for interrupt */
+	at91_cpu_idle
+
+	/* Turn on the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_moscrdy
+
+	/* Restore PLLA config */
+	ldr	tmp1, .saved_pllar
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
+	bne	1f
+	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
+	beq	2f
+1:
+	wait_pllalock
+2:
+
+	/* Restore PMC_MCKR config */
+	ldr	tmp1, .saved_mckr
+	str	tmp1, [pmc, #AT91_PMC_MCKR]
+
+	wait_mckrdy
+
+	mov	pc, lr
+ENDPROC(at91_pm_ulp0_mode)
+
 .pmc_base:
 	.word 0
 .sramc_base:
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 1/2] ARM: at91/pm: move enter sleep code to a procedure
@ 2015-10-15  3:41   ` Wenyou Yang
  0 siblings, 0 replies; 14+ messages in thread
From: Wenyou Yang @ 2015-10-15  3:41 UTC (permalink / raw)
  To: linux-arm-kernel

To make the code more legible and to prepare for the ULP1 support
in the future, move the Master clock, PLLA, MOR handling code and
the sleep code to a separate procedure.

Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---

 arch/arm/mach-at91/pm_suspend.S |  132 ++++++++++++++++++++-------------------
 1 file changed, 68 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 0d95f48..825347b 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -105,77 +105,19 @@ ENTRY(at91_pm_suspend_in_sram)
 
 	ldr	r0, .pm_mode
 	tst	r0, #AT91_PM_SLOW_CLOCK
-	beq	skip_disable_main_clock
+	beq	standby_mode
 
-	ldr	pmc, .pmc_base
-
-	/* Save Master clock setting */
-	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
-	str	tmp1, .saved_mckr
+ulp0_mode:
+	bl	at91_pm_ulp0_mode
+	b	pm_exit
 
-	/*
-	 * Set the Master clock source to slow clock
-	 */
-	bic	tmp1, tmp1, #AT91_PMC_CSS
-	str	tmp1, [pmc, #AT91_PMC_MCKR]
-
-	wait_mckrdy
-
-	/* Save PLLA setting and disable it */
-	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
-	str	tmp1, .saved_pllar
-
-	mov	tmp1, #AT91_PMC_PLLCOUNT
-	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
-	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
-
-	/* Turn off the main oscillator */
-	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
-	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
-	orr	tmp1, tmp1, #AT91_PMC_KEY
-	str	tmp1, [pmc, #AT91_CKGR_MOR]
-
-skip_disable_main_clock:
+standby_mode:
 	ldr	pmc, .pmc_base
 
 	/* Wait for interrupt */
 	at91_cpu_idle
 
-	ldr	r0, .pm_mode
-	tst	r0, #AT91_PM_SLOW_CLOCK
-	beq	skip_enable_main_clock
-
-	ldr	pmc, .pmc_base
-
-	/* Turn on the main oscillator */
-	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
-	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
-	orr	tmp1, tmp1, #AT91_PMC_KEY
-	str	tmp1, [pmc, #AT91_CKGR_MOR]
-
-	wait_moscrdy
-
-	/* Restore PLLA setting */
-	ldr	tmp1, .saved_pllar
-	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
-
-	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
-	bne	3f
-	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
-	beq	4f
-3:
-	wait_pllalock
-4:
-
-	/*
-	 * Restore master clock setting
-	 */
-	ldr	tmp1, .saved_mckr
-	str	tmp1, [pmc, #AT91_PMC_MCKR]
-
-	wait_mckrdy
-
-skip_enable_main_clock:
+pm_exit:
 	/* Exit the self-refresh mode */
 	mov	r0, #SRAMC_SELF_FRESH_EXIT
 	bl	at91_sramc_self_refresh
@@ -309,6 +251,68 @@ exit_sramc_sf:
 	mov	pc, lr
 ENDPROC(at91_sramc_self_refresh)
 
+/*
+ * void at91_pm_ulp0_mode(void)
+ */
+ENTRY(at91_pm_ulp0_mode)
+	ldr	pmc, .pmc_base
+
+	/* Save PMC_MCKR config */
+	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
+	str	tmp1, .saved_mckr
+
+	/* Switch master clock source to slow clock */
+	bic	tmp1, tmp1, #AT91_PMC_CSS
+	str	tmp1, [pmc, #AT91_PMC_MCKR]
+
+	wait_mckrdy
+
+	/* Save PLLA config, then and disable PLLA */
+	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
+	str	tmp1, .saved_pllar
+
+	mov	tmp1, #AT91_PMC_PLLCOUNT
+	orr	tmp1, tmp1, #(1 << 29)
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	/* Turn off the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	/* Wait for interrupt */
+	at91_cpu_idle
+
+	/* Turn on the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_moscrdy
+
+	/* Restore PLLA config */
+	ldr	tmp1, .saved_pllar
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
+	bne	1f
+	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
+	beq	2f
+1:
+	wait_pllalock
+2:
+
+	/* Restore PMC_MCKR config */
+	ldr	tmp1, .saved_mckr
+	str	tmp1, [pmc, #AT91_PMC_MCKR]
+
+	wait_mckrdy
+
+	mov	pc, lr
+ENDPROC(at91_pm_ulp0_mode)
+
 .pmc_base:
 	.word 0
 .sramc_base:
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
  2015-10-15  3:41 ` Wenyou Yang
@ 2015-10-15  3:41   ` Wenyou Yang
  -1 siblings, 0 replies; 14+ messages in thread
From: Wenyou Yang @ 2015-10-15  3:41 UTC (permalink / raw)
  To: Nicolas Ferre, Alexandre Belloni, Jean-Christophe Plagniol-Villard
  Cc: Russell King, Stephen Boyd, Michael Turquette, linux-arm-kernel,
	linux-kernel, linux-clk, Wenyou Yang

The Ultra Low-power mode 1(ULP1) is introduced by SAMA5D2.

In the ULP1 mode, all the clocks are shut off, inclusive the embedded
12MHz RC oscillator, so as to achieve the lowest power consumption
with the system in retention mode and able to resume on the wake up
events. As soon as the wake up event is asserted, the embedded 12MHz
RC oscillator restarts automatically.

The number of wake up sources for the ULP1 mode is limited, the wake
up sources should be configured via the PMC_FSMR and PMC_FSPR
registers.

In this patch, the following wake up sources are enabled,
 - WKUP0 pin
 - WKUP1 pin to WKUP8 pin (shared with PIOBU0 to PIOBU7)
 - RTC alarm

Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---

 arch/arm/mach-at91/pm.c         |   29 ++++++++++
 arch/arm/mach-at91/pm.h         |    7 +++
 arch/arm/mach-at91/pm_suspend.S |  111 +++++++++++++++++++++++++++++++++++++++
 include/linux/clk/at91_pmc.h    |   36 +++++++++++++
 4 files changed, 183 insertions(+)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 80e277c..49443d9 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -35,6 +35,11 @@
 #include "generic.h"
 #include "pm.h"
 
+#define ULP0_MODE	0x00
+#define ULP1_MODE	0x11
+
+#define SAMA5D2_PMC_VERSION	0x20540
+
 /*
  * FIXME: this is needed to communicate between the pinctrl driver and
  * the PM implementation in the machine. Possibly part of the PM
@@ -64,6 +69,23 @@ static int at91_pm_valid_state(suspend_state_t state)
 	}
 }
 
+static void at91_config_ulp1_wkup_source(void)
+{
+	if (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION) {
+		at91_pmc_write(AT91_PMC_FSMR, AT91_PMC_RTCAL |
+					      AT91_PMC_FSTT9 |
+					      AT91_PMC_FSTT8 |
+					      AT91_PMC_FSTT7 |
+					      AT91_PMC_FSTT6 |
+					      AT91_PMC_FSTT5 |
+					      AT91_PMC_FSTT4 |
+					      AT91_PMC_FSTT3 |
+					      AT91_PMC_FSTT2 |
+					      AT91_PMC_FSTT0);
+
+		at91_pmc_write(AT91_PMC_FSPR, 0);
+	}
+}
 
 static suspend_state_t target_state;
 
@@ -73,6 +95,9 @@ static suspend_state_t target_state;
 static int at91_pm_begin(suspend_state_t state)
 {
 	target_state = state;
+
+	at91_config_ulp1_wkup_source();
+
 	return 0;
 }
 
@@ -140,6 +165,10 @@ static void at91_pm_suspend(suspend_state_t state)
 	pm_data |= (state == PM_SUSPEND_MEM) ?
 				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
 
+	pm_data |= ((state == PM_SUSPEND_MEM) &&
+		    (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION)) ?
+		    AT91_PM_ULP(AT91_PM_ULP1_MODE) : 0;
+
 	flush_cache_all();
 	outer_disable();
 
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 3fcf881..2e76745 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -39,4 +39,11 @@ extern void __iomem *at91_ramc_base[];
 
 #define	AT91_PM_SLOW_CLOCK	0x01
 
+#define AT91_PM_ULP_OFFSET	5
+#define AT91_PM_ULP_MASK	0x03
+#define AT91_PM_ULP(x)		(((x) & AT91_PM_ULP_MASK) << AT91_PM_ULP_OFFSET)
+
+#define AT91_PM_ULP0_MODE	0x00
+#define AT91_PM_ULP1_MODE	0x01
+
 #endif
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 825347b..543c430 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -41,6 +41,15 @@ tmp2	.req	r5
 	.endm
 
 /*
+ * Wait for main oscillator selection is done
+ */
+	.macro wait_moscsels
+1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
+	tst	tmp1, #AT91_PMC_MOSCSELS
+	beq	1b
+	.endm
+
+/*
  * Wait until PLLA has locked.
  */
 	.macro wait_pllalock
@@ -99,6 +108,10 @@ ENTRY(at91_pm_suspend_in_sram)
 	and	r0, r0, #AT91_PM_MODE_MASK
 	str	r0, .pm_mode
 
+	lsr	r0, r3, #AT91_PM_ULP_OFFSET
+	and	r0, r0, #AT91_PM_ULP_MASK
+	str	r0, .ulp_mode
+
 	/* Active the self-refresh mode */
 	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
 	bl	at91_sramc_self_refresh
@@ -107,6 +120,14 @@ ENTRY(at91_pm_suspend_in_sram)
 	tst	r0, #AT91_PM_SLOW_CLOCK
 	beq	standby_mode
 
+	ldr	r0, .ulp_mode
+	tst	r0, #AT91_PM_ULP1_MODE
+	beq	ulp0_mode
+
+ulp1_mode:
+	bl	at91_pm_ulp1_mode
+	b	pm_exit
+
 ulp0_mode:
 	bl	at91_pm_ulp0_mode
 	b	pm_exit
@@ -313,6 +334,94 @@ ENTRY(at91_pm_ulp0_mode)
 	mov	pc, lr
 ENDPROC(at91_pm_ulp0_mode)
 
+/*
+ * void at91_pm_ulp1_mode(void)
+ *
+ */
+ENTRY(at91_pm_ulp1_mode)
+	ldr	pmc, .pmc_base
+
+	/* Save PMC_MCKR config */
+	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
+	str	tmp1, .saved_mckr
+
+	/* Switch the master clock source to main clock */
+	bic	tmp1, tmp1, #AT91_PMC_CSS
+	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
+	str	tmp1, [pmc, #AT91_PMC_MCKR]
+
+	wait_mckrdy
+
+	/* Save PLLA config, then and disable PLLA */
+	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
+	str	tmp1, .saved_pllar
+
+	bic	tmp1, tmp1, #AT91_PMC3_MUL
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	/* Switch main clock to 12-MHz RC oscillator */
+	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
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_moscsels
+
+	/* Disable the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
+	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	/* Enter the ULP1 mode by setting WAITMODE bit in CKGR_MOR */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
+	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_mckrdy
+
+	/* Enable the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
+	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_moscrdy
+
+	/* Switch main clock to the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
+	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_moscsels
+
+	/* Restore PLLA config */
+	ldr	tmp1, .saved_pllar
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	wait_pllalock
+
+	/* Restore PMC_MCKR config */
+	ldr	tmp1, .saved_mckr
+	str	tmp1, [pmc, #AT91_PMC_MCKR]
+
+	wait_mckrdy
+
+	mov	pc, lr
+ENDPROC(at91_pm_ulp1_mode)
+
 .pmc_base:
 	.word 0
 .sramc_base:
@@ -323,6 +432,8 @@ ENDPROC(at91_pm_ulp0_mode)
 	.word 0
 .pm_mode:
 	.word 0
+.ulp_mode:
+	.word 0
 .saved_mckr:
 	.word 0
 .saved_pllar:
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 7669f76..3dc4e60 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -59,8 +59,10 @@ extern void __iomem *at91_pmc_base;
 #define	AT91_CKGR_MOR		0x20			/* Main Oscillator Register [not on SAM9RL] */
 #define		AT91_PMC_MOSCEN		(1    <<  0)		/* Main Oscillator Enable */
 #define		AT91_PMC_OSCBYPASS	(1    <<  1)		/* Oscillator Bypass */
+#define		AT91_PMC_WAITMODE	(1    <<  2)		/* Wait Mode Command */
 #define		AT91_PMC_MOSCRCEN	(1    <<  3)		/* Main On-Chip RC Oscillator Enable [some SAM9] */
 #define		AT91_PMC_OSCOUNT	(0xff <<  8)		/* Main Oscillator Start-up Time */
+#define		AT91_PMC_KEY_MASK	(0xff << 16)
 #define		AT91_PMC_KEY		(0x37 << 16)		/* MOR Writing Key */
 #define		AT91_PMC_MOSCSEL	(1    << 24)		/* Main Oscillator Selection [some SAM9] */
 #define		AT91_PMC_CFDEN		(1    << 25)		/* Clock Failure Detector Enable [some SAM9] */
@@ -166,6 +168,38 @@ extern void __iomem *at91_pmc_base;
 #define		AT91_PMC_CFDEV		(1 << 18)		/* Clock Failure Detector Event [some SAM9] */
 #define	AT91_PMC_IMR		0x6c			/* Interrupt Mask Register */
 
+#define AT91_PMC_FSMR		0x70			/* Fast Startup Mode Register */
+#define		AT91_PMC_FSTT0		(1 << 0)		/* Fast Startup from WKUP Pin Enable */
+#define		AT91_PMC_FSTT1		(1 << 1)		/* Fast Startup from Security Module Enable */
+#define		AT91_PMC_FSTT2		(1 << 2)		/* Fast Startup from PIOBU0 Input Enable */
+#define		AT91_PMC_FSTT3		(1 << 3)		/* Fast Startup from PIOBU1 Input Enable */
+#define		AT91_PMC_FSTT4		(1 << 4)		/* Fast Startup from PIOBU2 Input Enable */
+#define		AT91_PMC_FSTT5		(1 << 5)		/* Fast Startup from PIOBU3 Input Enable */
+#define		AT91_PMC_FSTT6		(1 << 6)		/* Fast Startup from PIOBU4 Input Enable */
+#define		AT91_PMC_FSTT7		(1 << 7)		/* Fast Startup from PIOBU5 Input Enable */
+#define		AT91_PMC_FSTT8		(1 << 8)		/* Fast Startup from PIOBU6 Input Enable */
+#define		AT91_PMC_FSTT9		(1 << 9)		/* Fast Startup from PIOBU7 Input Enable */
+#define		AT91_PMC_FSTT10		(1 << 10)		/* Fast Startup from GMAC Wake-up On LAN Enable */
+#define		AT91_PMC_RTCAL		(1 << 17)		/* Fast Startup from RTC Alarm Enable */
+#define		AT91_PMC_USBAL		(1 << 18)		/* Fast Startup from USB Resume Enable */
+#define		AT91_PMC_SDMMC_CD	(1 << 19)		/* Fast Startup from SDMMC Card Detect Enable */
+#define		AT91_PMC_LPM		(1 << 20)		/* Low-power Mode */
+#define		AT91_PMC_RXLP_MCE	(1 << 24)		/* Fast Startup from Backup UART Receive Match Condition Enable */
+#define		AT91_PMC_ACC_CE		(1 << 25)		/* Fast Startup from Analog Comparator Controller Comparison Enable*/
+
+#define AT91_PMC_FSPR		0x74			/* Fast Startup Polarity Register */
+#define		AT91_PMC_FSTP0		(1 << 0)		/* WKUP Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP1		(1 << 1)		/* Security Module Polarity for Fast Startup */
+#define		AT91_PMC_FSTP2		(1 << 2)		/* PIOBU0 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP3		(1 << 3)		/* PIOBU1 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP4		(1 << 4)		/* PIOBU2 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP5		(1 << 5)		/* PIOBU3 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP6		(1 << 6)		/* PIOBU4 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP7		(1 << 7)		/* PIOBU5 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP8		(1 << 8)		/* PIOBU6 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP9		(1 << 9)		/* PIOBU7 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP10		(1 << 10)		/* GMAC Wake-up On LAN Polarity for Fast Startup */
+
 #define AT91_PMC_PLLICPR	0x80			/* PLL Charge Pump Current Register */
 
 #define AT91_PMC_PROT		0xe4			/* Write Protect Mode Register [some SAM9] */
@@ -177,6 +211,8 @@ extern void __iomem *at91_pmc_base;
 #define		AT91_PMC_WPVS		(0x1  <<  0)		/* Write Protect Violation Status */
 #define		AT91_PMC_WPVSRC		(0xffff  <<  8)		/* Write Protect Violation Source */
 
+#define AT91_PMC_VERSION	0xfc
+
 #define AT91_PMC_PCER1		0x100			/* Peripheral Clock Enable Register 1 [SAMA5 only]*/
 #define AT91_PMC_PCDR1		0x104			/* Peripheral Clock Enable Register 1 */
 #define AT91_PMC_PCSR1		0x108			/* Peripheral Clock Enable Register 1 */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
@ 2015-10-15  3:41   ` Wenyou Yang
  0 siblings, 0 replies; 14+ messages in thread
From: Wenyou Yang @ 2015-10-15  3:41 UTC (permalink / raw)
  To: linux-arm-kernel

The Ultra Low-power mode 1(ULP1) is introduced by SAMA5D2.

In the ULP1 mode, all the clocks are shut off, inclusive the embedded
12MHz RC oscillator, so as to achieve the lowest power consumption
with the system in retention mode and able to resume on the wake up
events. As soon as the wake up event is asserted, the embedded 12MHz
RC oscillator restarts automatically.

The number of wake up sources for the ULP1 mode is limited, the wake
up sources should be configured via the PMC_FSMR and PMC_FSPR
registers.

In this patch, the following wake up sources are enabled,
 - WKUP0 pin
 - WKUP1 pin to WKUP8 pin (shared with PIOBU0 to PIOBU7)
 - RTC alarm

Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---

 arch/arm/mach-at91/pm.c         |   29 ++++++++++
 arch/arm/mach-at91/pm.h         |    7 +++
 arch/arm/mach-at91/pm_suspend.S |  111 +++++++++++++++++++++++++++++++++++++++
 include/linux/clk/at91_pmc.h    |   36 +++++++++++++
 4 files changed, 183 insertions(+)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 80e277c..49443d9 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -35,6 +35,11 @@
 #include "generic.h"
 #include "pm.h"
 
+#define ULP0_MODE	0x00
+#define ULP1_MODE	0x11
+
+#define SAMA5D2_PMC_VERSION	0x20540
+
 /*
  * FIXME: this is needed to communicate between the pinctrl driver and
  * the PM implementation in the machine. Possibly part of the PM
@@ -64,6 +69,23 @@ static int at91_pm_valid_state(suspend_state_t state)
 	}
 }
 
+static void at91_config_ulp1_wkup_source(void)
+{
+	if (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION) {
+		at91_pmc_write(AT91_PMC_FSMR, AT91_PMC_RTCAL |
+					      AT91_PMC_FSTT9 |
+					      AT91_PMC_FSTT8 |
+					      AT91_PMC_FSTT7 |
+					      AT91_PMC_FSTT6 |
+					      AT91_PMC_FSTT5 |
+					      AT91_PMC_FSTT4 |
+					      AT91_PMC_FSTT3 |
+					      AT91_PMC_FSTT2 |
+					      AT91_PMC_FSTT0);
+
+		at91_pmc_write(AT91_PMC_FSPR, 0);
+	}
+}
 
 static suspend_state_t target_state;
 
@@ -73,6 +95,9 @@ static suspend_state_t target_state;
 static int at91_pm_begin(suspend_state_t state)
 {
 	target_state = state;
+
+	at91_config_ulp1_wkup_source();
+
 	return 0;
 }
 
@@ -140,6 +165,10 @@ static void at91_pm_suspend(suspend_state_t state)
 	pm_data |= (state == PM_SUSPEND_MEM) ?
 				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
 
+	pm_data |= ((state == PM_SUSPEND_MEM) &&
+		    (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION)) ?
+		    AT91_PM_ULP(AT91_PM_ULP1_MODE) : 0;
+
 	flush_cache_all();
 	outer_disable();
 
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 3fcf881..2e76745 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -39,4 +39,11 @@ extern void __iomem *at91_ramc_base[];
 
 #define	AT91_PM_SLOW_CLOCK	0x01
 
+#define AT91_PM_ULP_OFFSET	5
+#define AT91_PM_ULP_MASK	0x03
+#define AT91_PM_ULP(x)		(((x) & AT91_PM_ULP_MASK) << AT91_PM_ULP_OFFSET)
+
+#define AT91_PM_ULP0_MODE	0x00
+#define AT91_PM_ULP1_MODE	0x01
+
 #endif
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 825347b..543c430 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -41,6 +41,15 @@ tmp2	.req	r5
 	.endm
 
 /*
+ * Wait for main oscillator selection is done
+ */
+	.macro wait_moscsels
+1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
+	tst	tmp1, #AT91_PMC_MOSCSELS
+	beq	1b
+	.endm
+
+/*
  * Wait until PLLA has locked.
  */
 	.macro wait_pllalock
@@ -99,6 +108,10 @@ ENTRY(at91_pm_suspend_in_sram)
 	and	r0, r0, #AT91_PM_MODE_MASK
 	str	r0, .pm_mode
 
+	lsr	r0, r3, #AT91_PM_ULP_OFFSET
+	and	r0, r0, #AT91_PM_ULP_MASK
+	str	r0, .ulp_mode
+
 	/* Active the self-refresh mode */
 	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
 	bl	at91_sramc_self_refresh
@@ -107,6 +120,14 @@ ENTRY(at91_pm_suspend_in_sram)
 	tst	r0, #AT91_PM_SLOW_CLOCK
 	beq	standby_mode
 
+	ldr	r0, .ulp_mode
+	tst	r0, #AT91_PM_ULP1_MODE
+	beq	ulp0_mode
+
+ulp1_mode:
+	bl	at91_pm_ulp1_mode
+	b	pm_exit
+
 ulp0_mode:
 	bl	at91_pm_ulp0_mode
 	b	pm_exit
@@ -313,6 +334,94 @@ ENTRY(at91_pm_ulp0_mode)
 	mov	pc, lr
 ENDPROC(at91_pm_ulp0_mode)
 
+/*
+ * void at91_pm_ulp1_mode(void)
+ *
+ */
+ENTRY(at91_pm_ulp1_mode)
+	ldr	pmc, .pmc_base
+
+	/* Save PMC_MCKR config */
+	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
+	str	tmp1, .saved_mckr
+
+	/* Switch the master clock source to main clock */
+	bic	tmp1, tmp1, #AT91_PMC_CSS
+	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
+	str	tmp1, [pmc, #AT91_PMC_MCKR]
+
+	wait_mckrdy
+
+	/* Save PLLA config, then and disable PLLA */
+	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
+	str	tmp1, .saved_pllar
+
+	bic	tmp1, tmp1, #AT91_PMC3_MUL
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	/* Switch main clock to 12-MHz RC oscillator */
+	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
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_moscsels
+
+	/* Disable the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
+	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	/* Enter the ULP1 mode by setting WAITMODE bit in CKGR_MOR */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
+	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_mckrdy
+
+	/* Enable the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
+	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_moscrdy
+
+	/* Switch main clock to the main oscillator */
+	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
+	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
+	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
+	orr	tmp1, tmp1, #AT91_PMC_KEY
+	bic	tmp1, tmp1, #(7 << 4)
+	str	tmp1, [pmc, #AT91_CKGR_MOR]
+
+	wait_moscsels
+
+	/* Restore PLLA config */
+	ldr	tmp1, .saved_pllar
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	wait_pllalock
+
+	/* Restore PMC_MCKR config */
+	ldr	tmp1, .saved_mckr
+	str	tmp1, [pmc, #AT91_PMC_MCKR]
+
+	wait_mckrdy
+
+	mov	pc, lr
+ENDPROC(at91_pm_ulp1_mode)
+
 .pmc_base:
 	.word 0
 .sramc_base:
@@ -323,6 +432,8 @@ ENDPROC(at91_pm_ulp0_mode)
 	.word 0
 .pm_mode:
 	.word 0
+.ulp_mode:
+	.word 0
 .saved_mckr:
 	.word 0
 .saved_pllar:
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 7669f76..3dc4e60 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -59,8 +59,10 @@ extern void __iomem *at91_pmc_base;
 #define	AT91_CKGR_MOR		0x20			/* Main Oscillator Register [not on SAM9RL] */
 #define		AT91_PMC_MOSCEN		(1    <<  0)		/* Main Oscillator Enable */
 #define		AT91_PMC_OSCBYPASS	(1    <<  1)		/* Oscillator Bypass */
+#define		AT91_PMC_WAITMODE	(1    <<  2)		/* Wait Mode Command */
 #define		AT91_PMC_MOSCRCEN	(1    <<  3)		/* Main On-Chip RC Oscillator Enable [some SAM9] */
 #define		AT91_PMC_OSCOUNT	(0xff <<  8)		/* Main Oscillator Start-up Time */
+#define		AT91_PMC_KEY_MASK	(0xff << 16)
 #define		AT91_PMC_KEY		(0x37 << 16)		/* MOR Writing Key */
 #define		AT91_PMC_MOSCSEL	(1    << 24)		/* Main Oscillator Selection [some SAM9] */
 #define		AT91_PMC_CFDEN		(1    << 25)		/* Clock Failure Detector Enable [some SAM9] */
@@ -166,6 +168,38 @@ extern void __iomem *at91_pmc_base;
 #define		AT91_PMC_CFDEV		(1 << 18)		/* Clock Failure Detector Event [some SAM9] */
 #define	AT91_PMC_IMR		0x6c			/* Interrupt Mask Register */
 
+#define AT91_PMC_FSMR		0x70			/* Fast Startup Mode Register */
+#define		AT91_PMC_FSTT0		(1 << 0)		/* Fast Startup from WKUP Pin Enable */
+#define		AT91_PMC_FSTT1		(1 << 1)		/* Fast Startup from Security Module Enable */
+#define		AT91_PMC_FSTT2		(1 << 2)		/* Fast Startup from PIOBU0 Input Enable */
+#define		AT91_PMC_FSTT3		(1 << 3)		/* Fast Startup from PIOBU1 Input Enable */
+#define		AT91_PMC_FSTT4		(1 << 4)		/* Fast Startup from PIOBU2 Input Enable */
+#define		AT91_PMC_FSTT5		(1 << 5)		/* Fast Startup from PIOBU3 Input Enable */
+#define		AT91_PMC_FSTT6		(1 << 6)		/* Fast Startup from PIOBU4 Input Enable */
+#define		AT91_PMC_FSTT7		(1 << 7)		/* Fast Startup from PIOBU5 Input Enable */
+#define		AT91_PMC_FSTT8		(1 << 8)		/* Fast Startup from PIOBU6 Input Enable */
+#define		AT91_PMC_FSTT9		(1 << 9)		/* Fast Startup from PIOBU7 Input Enable */
+#define		AT91_PMC_FSTT10		(1 << 10)		/* Fast Startup from GMAC Wake-up On LAN Enable */
+#define		AT91_PMC_RTCAL		(1 << 17)		/* Fast Startup from RTC Alarm Enable */
+#define		AT91_PMC_USBAL		(1 << 18)		/* Fast Startup from USB Resume Enable */
+#define		AT91_PMC_SDMMC_CD	(1 << 19)		/* Fast Startup from SDMMC Card Detect Enable */
+#define		AT91_PMC_LPM		(1 << 20)		/* Low-power Mode */
+#define		AT91_PMC_RXLP_MCE	(1 << 24)		/* Fast Startup from Backup UART Receive Match Condition Enable */
+#define		AT91_PMC_ACC_CE		(1 << 25)		/* Fast Startup from Analog Comparator Controller Comparison Enable*/
+
+#define AT91_PMC_FSPR		0x74			/* Fast Startup Polarity Register */
+#define		AT91_PMC_FSTP0		(1 << 0)		/* WKUP Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP1		(1 << 1)		/* Security Module Polarity for Fast Startup */
+#define		AT91_PMC_FSTP2		(1 << 2)		/* PIOBU0 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP3		(1 << 3)		/* PIOBU1 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP4		(1 << 4)		/* PIOBU2 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP5		(1 << 5)		/* PIOBU3 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP6		(1 << 6)		/* PIOBU4 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP7		(1 << 7)		/* PIOBU5 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP8		(1 << 8)		/* PIOBU6 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP9		(1 << 9)		/* PIOBU7 Pin Polarity for Fast Startup */
+#define		AT91_PMC_FSTP10		(1 << 10)		/* GMAC Wake-up On LAN Polarity for Fast Startup */
+
 #define AT91_PMC_PLLICPR	0x80			/* PLL Charge Pump Current Register */
 
 #define AT91_PMC_PROT		0xe4			/* Write Protect Mode Register [some SAM9] */
@@ -177,6 +211,8 @@ extern void __iomem *at91_pmc_base;
 #define		AT91_PMC_WPVS		(0x1  <<  0)		/* Write Protect Violation Status */
 #define		AT91_PMC_WPVSRC		(0xffff  <<  8)		/* Write Protect Violation Source */
 
+#define AT91_PMC_VERSION	0xfc
+
 #define AT91_PMC_PCER1		0x100			/* Peripheral Clock Enable Register 1 [SAMA5 only]*/
 #define AT91_PMC_PCDR1		0x104			/* Peripheral Clock Enable Register 1 */
 #define AT91_PMC_PCSR1		0x108			/* Peripheral Clock Enable Register 1 */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
  2015-10-15  3:41   ` Wenyou Yang
  (?)
@ 2015-10-15  9:31     ` Michael Turquette
  -1 siblings, 0 replies; 14+ messages in thread
From: Michael Turquette @ 2015-10-15  9:31 UTC (permalink / raw)
  To: Wenyou Yang, Nicolas Ferre, Alexandre Belloni,
	Jean-Christophe Plagniol-Villard
  Cc: Russell King, Stephen Boyd, linux-arm-kernel, linux-kernel,
	linux-clk, Wenyou Yang

Quoting Wenyou Yang (2015-10-14 20:41:07)
> The Ultra Low-power mode 1(ULP1) is introduced by SAMA5D2.
> 
> In the ULP1 mode, all the clocks are shut off, inclusive the embedded
> 12MHz RC oscillator, so as to achieve the lowest power consumption
> with the system in retention mode and able to resume on the wake up
> events. As soon as the wake up event is asserted, the embedded 12MHz
> RC oscillator restarts automatically.
> 
> The number of wake up sources for the ULP1 mode is limited, the wake
> up sources should be configured via the PMC_FSMR and PMC_FSPR
> registers.
> 
> In this patch, the following wake up sources are enabled,
>  - WKUP0 pin
>  - WKUP1 pin to WKUP8 pin (shared with PIOBU0 to PIOBU7)
>  - RTC alarm
> 
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>

For the changes to the clk header:

Acked-by: Michael Turquette <mturquette@baylibre.com>

> ---
> 
>  arch/arm/mach-at91/pm.c         |   29 ++++++++++
>  arch/arm/mach-at91/pm.h         |    7 +++
>  arch/arm/mach-at91/pm_suspend.S |  111 +++++++++++++++++++++++++++++++++++++++
>  include/linux/clk/at91_pmc.h    |   36 +++++++++++++
>  4 files changed, 183 insertions(+)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
> index 80e277c..49443d9 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -35,6 +35,11 @@
>  #include "generic.h"
>  #include "pm.h"
>  
> +#define ULP0_MODE      0x00
> +#define ULP1_MODE      0x11
> +
> +#define SAMA5D2_PMC_VERSION    0x20540
> +
>  /*
>   * FIXME: this is needed to communicate between the pinctrl driver and
>   * the PM implementation in the machine. Possibly part of the PM
> @@ -64,6 +69,23 @@ static int at91_pm_valid_state(suspend_state_t state)
>         }
>  }
>  
> +static void at91_config_ulp1_wkup_source(void)
> +{
> +       if (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION) {
> +               at91_pmc_write(AT91_PMC_FSMR, AT91_PMC_RTCAL |
> +                                             AT91_PMC_FSTT9 |
> +                                             AT91_PMC_FSTT8 |
> +                                             AT91_PMC_FSTT7 |
> +                                             AT91_PMC_FSTT6 |
> +                                             AT91_PMC_FSTT5 |
> +                                             AT91_PMC_FSTT4 |
> +                                             AT91_PMC_FSTT3 |
> +                                             AT91_PMC_FSTT2 |
> +                                             AT91_PMC_FSTT0);
> +
> +               at91_pmc_write(AT91_PMC_FSPR, 0);
> +       }
> +}
>  
>  static suspend_state_t target_state;
>  
> @@ -73,6 +95,9 @@ static suspend_state_t target_state;
>  static int at91_pm_begin(suspend_state_t state)
>  {
>         target_state = state;
> +
> +       at91_config_ulp1_wkup_source();
> +
>         return 0;
>  }
>  
> @@ -140,6 +165,10 @@ static void at91_pm_suspend(suspend_state_t state)
>         pm_data |= (state == PM_SUSPEND_MEM) ?
>                                 AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
>  
> +       pm_data |= ((state == PM_SUSPEND_MEM) &&
> +                   (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION)) ?
> +                   AT91_PM_ULP(AT91_PM_ULP1_MODE) : 0;
> +
>         flush_cache_all();
>         outer_disable();
>  
> diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
> index 3fcf881..2e76745 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -39,4 +39,11 @@ extern void __iomem *at91_ramc_base[];
>  
>  #define        AT91_PM_SLOW_CLOCK      0x01
>  
> +#define AT91_PM_ULP_OFFSET     5
> +#define AT91_PM_ULP_MASK       0x03
> +#define AT91_PM_ULP(x)         (((x) & AT91_PM_ULP_MASK) << AT91_PM_ULP_OFFSET)
> +
> +#define AT91_PM_ULP0_MODE      0x00
> +#define AT91_PM_ULP1_MODE      0x01
> +
>  #endif
> diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
> index 825347b..543c430 100644
> --- a/arch/arm/mach-at91/pm_suspend.S
> +++ b/arch/arm/mach-at91/pm_suspend.S
> @@ -41,6 +41,15 @@ tmp2 .req    r5
>         .endm
>  
>  /*
> + * Wait for main oscillator selection is done
> + */
> +       .macro wait_moscsels
> +1:     ldr     tmp1, [pmc, #AT91_PMC_SR]
> +       tst     tmp1, #AT91_PMC_MOSCSELS
> +       beq     1b
> +       .endm
> +
> +/*
>   * Wait until PLLA has locked.
>   */
>         .macro wait_pllalock
> @@ -99,6 +108,10 @@ ENTRY(at91_pm_suspend_in_sram)
>         and     r0, r0, #AT91_PM_MODE_MASK
>         str     r0, .pm_mode
>  
> +       lsr     r0, r3, #AT91_PM_ULP_OFFSET
> +       and     r0, r0, #AT91_PM_ULP_MASK
> +       str     r0, .ulp_mode
> +
>         /* Active the self-refresh mode */
>         mov     r0, #SRAMC_SELF_FRESH_ACTIVE
>         bl      at91_sramc_self_refresh
> @@ -107,6 +120,14 @@ ENTRY(at91_pm_suspend_in_sram)
>         tst     r0, #AT91_PM_SLOW_CLOCK
>         beq     standby_mode
>  
> +       ldr     r0, .ulp_mode
> +       tst     r0, #AT91_PM_ULP1_MODE
> +       beq     ulp0_mode
> +
> +ulp1_mode:
> +       bl      at91_pm_ulp1_mode
> +       b       pm_exit
> +
>  ulp0_mode:
>         bl      at91_pm_ulp0_mode
>         b       pm_exit
> @@ -313,6 +334,94 @@ ENTRY(at91_pm_ulp0_mode)
>         mov     pc, lr
>  ENDPROC(at91_pm_ulp0_mode)
>  
> +/*
> + * void at91_pm_ulp1_mode(void)
> + *
> + */
> +ENTRY(at91_pm_ulp1_mode)
> +       ldr     pmc, .pmc_base
> +
> +       /* Save PMC_MCKR config */
> +       ldr     tmp1, [pmc, #AT91_PMC_MCKR]
> +       str     tmp1, .saved_mckr
> +
> +       /* Switch the master clock source to main clock */
> +       bic     tmp1, tmp1, #AT91_PMC_CSS
> +       orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
> +       str     tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +       wait_mckrdy
> +
> +       /* Save PLLA config, then and disable PLLA */
> +       ldr     tmp1, [pmc, #AT91_CKGR_PLLAR]
> +       str     tmp1, .saved_pllar
> +
> +       bic     tmp1, tmp1, #AT91_PMC3_MUL
> +       str     tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +       /* Switch main clock to 12-MHz RC oscillator */
> +       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
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_moscsels
> +
> +       /* Disable the main oscillator */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       bic     tmp1, tmp1, #AT91_PMC_MOSCEN
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       /* Enter the ULP1 mode by setting WAITMODE bit in CKGR_MOR */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       orr     tmp1, tmp1, #AT91_PMC_WAITMODE
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_mckrdy
> +
> +       /* Enable the main oscillator */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       orr     tmp1, tmp1, #AT91_PMC_MOSCEN
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_moscrdy
> +
> +       /* Switch main clock to the main oscillator */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       orr     tmp1, tmp1, #AT91_PMC_MOSCSEL
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_moscsels
> +
> +       /* Restore PLLA config */
> +       ldr     tmp1, .saved_pllar
> +       str     tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +       wait_pllalock
> +
> +       /* Restore PMC_MCKR config */
> +       ldr     tmp1, .saved_mckr
> +       str     tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +       wait_mckrdy
> +
> +       mov     pc, lr
> +ENDPROC(at91_pm_ulp1_mode)
> +
>  .pmc_base:
>         .word 0
>  .sramc_base:
> @@ -323,6 +432,8 @@ ENDPROC(at91_pm_ulp0_mode)
>         .word 0
>  .pm_mode:
>         .word 0
> +.ulp_mode:
> +       .word 0
>  .saved_mckr:
>         .word 0
>  .saved_pllar:
> diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
> index 7669f76..3dc4e60 100644
> --- a/include/linux/clk/at91_pmc.h
> +++ b/include/linux/clk/at91_pmc.h
> @@ -59,8 +59,10 @@ extern void __iomem *at91_pmc_base;
>  #define        AT91_CKGR_MOR           0x20                    /* Main Oscillator Register [not on SAM9RL] */
>  #define                AT91_PMC_MOSCEN         (1    <<  0)            /* Main Oscillator Enable */
>  #define                AT91_PMC_OSCBYPASS      (1    <<  1)            /* Oscillator Bypass */
> +#define                AT91_PMC_WAITMODE       (1    <<  2)            /* Wait Mode Command */
>  #define                AT91_PMC_MOSCRCEN       (1    <<  3)            /* Main On-Chip RC Oscillator Enable [some SAM9] */
>  #define                AT91_PMC_OSCOUNT        (0xff <<  8)            /* Main Oscillator Start-up Time */
> +#define                AT91_PMC_KEY_MASK       (0xff << 16)
>  #define                AT91_PMC_KEY            (0x37 << 16)            /* MOR Writing Key */
>  #define                AT91_PMC_MOSCSEL        (1    << 24)            /* Main Oscillator Selection [some SAM9] */
>  #define                AT91_PMC_CFDEN          (1    << 25)            /* Clock Failure Detector Enable [some SAM9] */
> @@ -166,6 +168,38 @@ extern void __iomem *at91_pmc_base;
>  #define                AT91_PMC_CFDEV          (1 << 18)               /* Clock Failure Detector Event [some SAM9] */
>  #define        AT91_PMC_IMR            0x6c                    /* Interrupt Mask Register */
>  
> +#define AT91_PMC_FSMR          0x70                    /* Fast Startup Mode Register */
> +#define                AT91_PMC_FSTT0          (1 << 0)                /* Fast Startup from WKUP Pin Enable */
> +#define                AT91_PMC_FSTT1          (1 << 1)                /* Fast Startup from Security Module Enable */
> +#define                AT91_PMC_FSTT2          (1 << 2)                /* Fast Startup from PIOBU0 Input Enable */
> +#define                AT91_PMC_FSTT3          (1 << 3)                /* Fast Startup from PIOBU1 Input Enable */
> +#define                AT91_PMC_FSTT4          (1 << 4)                /* Fast Startup from PIOBU2 Input Enable */
> +#define                AT91_PMC_FSTT5          (1 << 5)                /* Fast Startup from PIOBU3 Input Enable */
> +#define                AT91_PMC_FSTT6          (1 << 6)                /* Fast Startup from PIOBU4 Input Enable */
> +#define                AT91_PMC_FSTT7          (1 << 7)                /* Fast Startup from PIOBU5 Input Enable */
> +#define                AT91_PMC_FSTT8          (1 << 8)                /* Fast Startup from PIOBU6 Input Enable */
> +#define                AT91_PMC_FSTT9          (1 << 9)                /* Fast Startup from PIOBU7 Input Enable */
> +#define                AT91_PMC_FSTT10         (1 << 10)               /* Fast Startup from GMAC Wake-up On LAN Enable */
> +#define                AT91_PMC_RTCAL          (1 << 17)               /* Fast Startup from RTC Alarm Enable */
> +#define                AT91_PMC_USBAL          (1 << 18)               /* Fast Startup from USB Resume Enable */
> +#define                AT91_PMC_SDMMC_CD       (1 << 19)               /* Fast Startup from SDMMC Card Detect Enable */
> +#define                AT91_PMC_LPM            (1 << 20)               /* Low-power Mode */
> +#define                AT91_PMC_RXLP_MCE       (1 << 24)               /* Fast Startup from Backup UART Receive Match Condition Enable */
> +#define                AT91_PMC_ACC_CE         (1 << 25)               /* Fast Startup from Analog Comparator Controller Comparison Enable*/
> +
> +#define AT91_PMC_FSPR          0x74                    /* Fast Startup Polarity Register */
> +#define                AT91_PMC_FSTP0          (1 << 0)                /* WKUP Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP1          (1 << 1)                /* Security Module Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP2          (1 << 2)                /* PIOBU0 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP3          (1 << 3)                /* PIOBU1 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP4          (1 << 4)                /* PIOBU2 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP5          (1 << 5)                /* PIOBU3 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP6          (1 << 6)                /* PIOBU4 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP7          (1 << 7)                /* PIOBU5 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP8          (1 << 8)                /* PIOBU6 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP9          (1 << 9)                /* PIOBU7 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP10         (1 << 10)               /* GMAC Wake-up On LAN Polarity for Fast Startup */
> +
>  #define AT91_PMC_PLLICPR       0x80                    /* PLL Charge Pump Current Register */
>  
>  #define AT91_PMC_PROT          0xe4                    /* Write Protect Mode Register [some SAM9] */
> @@ -177,6 +211,8 @@ extern void __iomem *at91_pmc_base;
>  #define                AT91_PMC_WPVS           (0x1  <<  0)            /* Write Protect Violation Status */
>  #define                AT91_PMC_WPVSRC         (0xffff  <<  8)         /* Write Protect Violation Source */
>  
> +#define AT91_PMC_VERSION       0xfc
> +
>  #define AT91_PMC_PCER1         0x100                   /* Peripheral Clock Enable Register 1 [SAMA5 only]*/
>  #define AT91_PMC_PCDR1         0x104                   /* Peripheral Clock Enable Register 1 */
>  #define AT91_PMC_PCSR1         0x108                   /* Peripheral Clock Enable Register 1 */
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
@ 2015-10-15  9:31     ` Michael Turquette
  0 siblings, 0 replies; 14+ messages in thread
From: Michael Turquette @ 2015-10-15  9:31 UTC (permalink / raw)
  To: Wenyou Yang, Nicolas Ferre, Alexandre Belloni,
	Jean-Christophe Plagniol-Villard
  Cc: Russell King, Stephen Boyd, linux-arm-kernel, linux-kernel,
	linux-clk, Wenyou Yang

Quoting Wenyou Yang (2015-10-14 20:41:07)
> The Ultra Low-power mode 1(ULP1) is introduced by SAMA5D2.
> =

> In the ULP1 mode, all the clocks are shut off, inclusive the embedded
> 12MHz RC oscillator, so as to achieve the lowest power consumption
> with the system in retention mode and able to resume on the wake up
> events. As soon as the wake up event is asserted, the embedded 12MHz
> RC oscillator restarts automatically.
> =

> The number of wake up sources for the ULP1 mode is limited, the wake
> up sources should be configured via the PMC_FSMR and PMC_FSPR
> registers.
> =

> In this patch, the following wake up sources are enabled,
>  - WKUP0 pin
>  - WKUP1 pin to WKUP8 pin (shared with PIOBU0 to PIOBU7)
>  - RTC alarm
> =

> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>

For the changes to the clk header:

Acked-by: Michael Turquette <mturquette@baylibre.com>

> ---
> =

>  arch/arm/mach-at91/pm.c         |   29 ++++++++++
>  arch/arm/mach-at91/pm.h         |    7 +++
>  arch/arm/mach-at91/pm_suspend.S |  111 +++++++++++++++++++++++++++++++++=
++++++
>  include/linux/clk/at91_pmc.h    |   36 +++++++++++++
>  4 files changed, 183 insertions(+)
> =

> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
> index 80e277c..49443d9 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -35,6 +35,11 @@
>  #include "generic.h"
>  #include "pm.h"
>  =

> +#define ULP0_MODE      0x00
> +#define ULP1_MODE      0x11
> +
> +#define SAMA5D2_PMC_VERSION    0x20540
> +
>  /*
>   * FIXME: this is needed to communicate between the pinctrl driver and
>   * the PM implementation in the machine. Possibly part of the PM
> @@ -64,6 +69,23 @@ static int at91_pm_valid_state(suspend_state_t state)
>         }
>  }
>  =

> +static void at91_config_ulp1_wkup_source(void)
> +{
> +       if (at91_pmc_read(AT91_PMC_VERSION) >=3D SAMA5D2_PMC_VERSION) {
> +               at91_pmc_write(AT91_PMC_FSMR, AT91_PMC_RTCAL |
> +                                             AT91_PMC_FSTT9 |
> +                                             AT91_PMC_FSTT8 |
> +                                             AT91_PMC_FSTT7 |
> +                                             AT91_PMC_FSTT6 |
> +                                             AT91_PMC_FSTT5 |
> +                                             AT91_PMC_FSTT4 |
> +                                             AT91_PMC_FSTT3 |
> +                                             AT91_PMC_FSTT2 |
> +                                             AT91_PMC_FSTT0);
> +
> +               at91_pmc_write(AT91_PMC_FSPR, 0);
> +       }
> +}
>  =

>  static suspend_state_t target_state;
>  =

> @@ -73,6 +95,9 @@ static suspend_state_t target_state;
>  static int at91_pm_begin(suspend_state_t state)
>  {
>         target_state =3D state;
> +
> +       at91_config_ulp1_wkup_source();
> +
>         return 0;
>  }
>  =

> @@ -140,6 +165,10 @@ static void at91_pm_suspend(suspend_state_t state)
>         pm_data |=3D (state =3D=3D PM_SUSPEND_MEM) ?
>                                 AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
>  =

> +       pm_data |=3D ((state =3D=3D PM_SUSPEND_MEM) &&
> +                   (at91_pmc_read(AT91_PMC_VERSION) >=3D SAMA5D2_PMC_VER=
SION)) ?
> +                   AT91_PM_ULP(AT91_PM_ULP1_MODE) : 0;
> +
>         flush_cache_all();
>         outer_disable();
>  =

> diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
> index 3fcf881..2e76745 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -39,4 +39,11 @@ extern void __iomem *at91_ramc_base[];
>  =

>  #define        AT91_PM_SLOW_CLOCK      0x01
>  =

> +#define AT91_PM_ULP_OFFSET     5
> +#define AT91_PM_ULP_MASK       0x03
> +#define AT91_PM_ULP(x)         (((x) & AT91_PM_ULP_MASK) << AT91_PM_ULP_=
OFFSET)
> +
> +#define AT91_PM_ULP0_MODE      0x00
> +#define AT91_PM_ULP1_MODE      0x01
> +
>  #endif
> diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_susp=
end.S
> index 825347b..543c430 100644
> --- a/arch/arm/mach-at91/pm_suspend.S
> +++ b/arch/arm/mach-at91/pm_suspend.S
> @@ -41,6 +41,15 @@ tmp2 .req    r5
>         .endm
>  =

>  /*
> + * Wait for main oscillator selection is done
> + */
> +       .macro wait_moscsels
> +1:     ldr     tmp1, [pmc, #AT91_PMC_SR]
> +       tst     tmp1, #AT91_PMC_MOSCSELS
> +       beq     1b
> +       .endm
> +
> +/*
>   * Wait until PLLA has locked.
>   */
>         .macro wait_pllalock
> @@ -99,6 +108,10 @@ ENTRY(at91_pm_suspend_in_sram)
>         and     r0, r0, #AT91_PM_MODE_MASK
>         str     r0, .pm_mode
>  =

> +       lsr     r0, r3, #AT91_PM_ULP_OFFSET
> +       and     r0, r0, #AT91_PM_ULP_MASK
> +       str     r0, .ulp_mode
> +
>         /* Active the self-refresh mode */
>         mov     r0, #SRAMC_SELF_FRESH_ACTIVE
>         bl      at91_sramc_self_refresh
> @@ -107,6 +120,14 @@ ENTRY(at91_pm_suspend_in_sram)
>         tst     r0, #AT91_PM_SLOW_CLOCK
>         beq     standby_mode
>  =

> +       ldr     r0, .ulp_mode
> +       tst     r0, #AT91_PM_ULP1_MODE
> +       beq     ulp0_mode
> +
> +ulp1_mode:
> +       bl      at91_pm_ulp1_mode
> +       b       pm_exit
> +
>  ulp0_mode:
>         bl      at91_pm_ulp0_mode
>         b       pm_exit
> @@ -313,6 +334,94 @@ ENTRY(at91_pm_ulp0_mode)
>         mov     pc, lr
>  ENDPROC(at91_pm_ulp0_mode)
>  =

> +/*
> + * void at91_pm_ulp1_mode(void)
> + *
> + */
> +ENTRY(at91_pm_ulp1_mode)
> +       ldr     pmc, .pmc_base
> +
> +       /* Save PMC_MCKR config */
> +       ldr     tmp1, [pmc, #AT91_PMC_MCKR]
> +       str     tmp1, .saved_mckr
> +
> +       /* Switch the master clock source to main clock */
> +       bic     tmp1, tmp1, #AT91_PMC_CSS
> +       orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
> +       str     tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +       wait_mckrdy
> +
> +       /* Save PLLA config, then and disable PLLA */
> +       ldr     tmp1, [pmc, #AT91_CKGR_PLLAR]
> +       str     tmp1, .saved_pllar
> +
> +       bic     tmp1, tmp1, #AT91_PMC3_MUL
> +       str     tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +       /* Switch main clock to 12-MHz RC oscillator */
> +       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
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_moscsels
> +
> +       /* Disable the main oscillator */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       bic     tmp1, tmp1, #AT91_PMC_MOSCEN
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       /* Enter the ULP1 mode by setting WAITMODE bit in CKGR_MOR */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       orr     tmp1, tmp1, #AT91_PMC_WAITMODE
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_mckrdy
> +
> +       /* Enable the main oscillator */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       orr     tmp1, tmp1, #AT91_PMC_MOSCEN
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_moscrdy
> +
> +       /* Switch main clock to the main oscillator */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       orr     tmp1, tmp1, #AT91_PMC_MOSCSEL
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_moscsels
> +
> +       /* Restore PLLA config */
> +       ldr     tmp1, .saved_pllar
> +       str     tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +       wait_pllalock
> +
> +       /* Restore PMC_MCKR config */
> +       ldr     tmp1, .saved_mckr
> +       str     tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +       wait_mckrdy
> +
> +       mov     pc, lr
> +ENDPROC(at91_pm_ulp1_mode)
> +
>  .pmc_base:
>         .word 0
>  .sramc_base:
> @@ -323,6 +432,8 @@ ENDPROC(at91_pm_ulp0_mode)
>         .word 0
>  .pm_mode:
>         .word 0
> +.ulp_mode:
> +       .word 0
>  .saved_mckr:
>         .word 0
>  .saved_pllar:
> diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
> index 7669f76..3dc4e60 100644
> --- a/include/linux/clk/at91_pmc.h
> +++ b/include/linux/clk/at91_pmc.h
> @@ -59,8 +59,10 @@ extern void __iomem *at91_pmc_base;
>  #define        AT91_CKGR_MOR           0x20                    /* Main O=
scillator Register [not on SAM9RL] */
>  #define                AT91_PMC_MOSCEN         (1    <<  0)            /=
* Main Oscillator Enable */
>  #define                AT91_PMC_OSCBYPASS      (1    <<  1)            /=
* Oscillator Bypass */
> +#define                AT91_PMC_WAITMODE       (1    <<  2)            /=
* Wait Mode Command */
>  #define                AT91_PMC_MOSCRCEN       (1    <<  3)            /=
* Main On-Chip RC Oscillator Enable [some SAM9] */
>  #define                AT91_PMC_OSCOUNT        (0xff <<  8)            /=
* Main Oscillator Start-up Time */
> +#define                AT91_PMC_KEY_MASK       (0xff << 16)
>  #define                AT91_PMC_KEY            (0x37 << 16)            /=
* MOR Writing Key */
>  #define                AT91_PMC_MOSCSEL        (1    << 24)            /=
* Main Oscillator Selection [some SAM9] */
>  #define                AT91_PMC_CFDEN          (1    << 25)            /=
* Clock Failure Detector Enable [some SAM9] */
> @@ -166,6 +168,38 @@ extern void __iomem *at91_pmc_base;
>  #define                AT91_PMC_CFDEV          (1 << 18)               /=
* Clock Failure Detector Event [some SAM9] */
>  #define        AT91_PMC_IMR            0x6c                    /* Interr=
upt Mask Register */
>  =

> +#define AT91_PMC_FSMR          0x70                    /* Fast Startup M=
ode Register */
> +#define                AT91_PMC_FSTT0          (1 << 0)                /=
* Fast Startup from WKUP Pin Enable */
> +#define                AT91_PMC_FSTT1          (1 << 1)                /=
* Fast Startup from Security Module Enable */
> +#define                AT91_PMC_FSTT2          (1 << 2)                /=
* Fast Startup from PIOBU0 Input Enable */
> +#define                AT91_PMC_FSTT3          (1 << 3)                /=
* Fast Startup from PIOBU1 Input Enable */
> +#define                AT91_PMC_FSTT4          (1 << 4)                /=
* Fast Startup from PIOBU2 Input Enable */
> +#define                AT91_PMC_FSTT5          (1 << 5)                /=
* Fast Startup from PIOBU3 Input Enable */
> +#define                AT91_PMC_FSTT6          (1 << 6)                /=
* Fast Startup from PIOBU4 Input Enable */
> +#define                AT91_PMC_FSTT7          (1 << 7)                /=
* Fast Startup from PIOBU5 Input Enable */
> +#define                AT91_PMC_FSTT8          (1 << 8)                /=
* Fast Startup from PIOBU6 Input Enable */
> +#define                AT91_PMC_FSTT9          (1 << 9)                /=
* Fast Startup from PIOBU7 Input Enable */
> +#define                AT91_PMC_FSTT10         (1 << 10)               /=
* Fast Startup from GMAC Wake-up On LAN Enable */
> +#define                AT91_PMC_RTCAL          (1 << 17)               /=
* Fast Startup from RTC Alarm Enable */
> +#define                AT91_PMC_USBAL          (1 << 18)               /=
* Fast Startup from USB Resume Enable */
> +#define                AT91_PMC_SDMMC_CD       (1 << 19)               /=
* Fast Startup from SDMMC Card Detect Enable */
> +#define                AT91_PMC_LPM            (1 << 20)               /=
* Low-power Mode */
> +#define                AT91_PMC_RXLP_MCE       (1 << 24)               /=
* Fast Startup from Backup UART Receive Match Condition Enable */
> +#define                AT91_PMC_ACC_CE         (1 << 25)               /=
* Fast Startup from Analog Comparator Controller Comparison Enable*/
> +
> +#define AT91_PMC_FSPR          0x74                    /* Fast Startup P=
olarity Register */
> +#define                AT91_PMC_FSTP0          (1 << 0)                /=
* WKUP Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP1          (1 << 1)                /=
* Security Module Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP2          (1 << 2)                /=
* PIOBU0 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP3          (1 << 3)                /=
* PIOBU1 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP4          (1 << 4)                /=
* PIOBU2 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP5          (1 << 5)                /=
* PIOBU3 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP6          (1 << 6)                /=
* PIOBU4 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP7          (1 << 7)                /=
* PIOBU5 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP8          (1 << 8)                /=
* PIOBU6 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP9          (1 << 9)                /=
* PIOBU7 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP10         (1 << 10)               /=
* GMAC Wake-up On LAN Polarity for Fast Startup */
> +
>  #define AT91_PMC_PLLICPR       0x80                    /* PLL Charge Pum=
p Current Register */
>  =

>  #define AT91_PMC_PROT          0xe4                    /* Write Protect =
Mode Register [some SAM9] */
> @@ -177,6 +211,8 @@ extern void __iomem *at91_pmc_base;
>  #define                AT91_PMC_WPVS           (0x1  <<  0)            /=
* Write Protect Violation Status */
>  #define                AT91_PMC_WPVSRC         (0xffff  <<  8)         /=
* Write Protect Violation Source */
>  =

> +#define AT91_PMC_VERSION       0xfc
> +
>  #define AT91_PMC_PCER1         0x100                   /* Peripheral Clo=
ck Enable Register 1 [SAMA5 only]*/
>  #define AT91_PMC_PCDR1         0x104                   /* Peripheral Clo=
ck Enable Register 1 */
>  #define AT91_PMC_PCSR1         0x108                   /* Peripheral Clo=
ck Enable Register 1 */
> -- =

> 1.7.9.5
>=20

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
@ 2015-10-15  9:31     ` Michael Turquette
  0 siblings, 0 replies; 14+ messages in thread
From: Michael Turquette @ 2015-10-15  9:31 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Wenyou Yang (2015-10-14 20:41:07)
> The Ultra Low-power mode 1(ULP1) is introduced by SAMA5D2.
> 
> In the ULP1 mode, all the clocks are shut off, inclusive the embedded
> 12MHz RC oscillator, so as to achieve the lowest power consumption
> with the system in retention mode and able to resume on the wake up
> events. As soon as the wake up event is asserted, the embedded 12MHz
> RC oscillator restarts automatically.
> 
> The number of wake up sources for the ULP1 mode is limited, the wake
> up sources should be configured via the PMC_FSMR and PMC_FSPR
> registers.
> 
> In this patch, the following wake up sources are enabled,
>  - WKUP0 pin
>  - WKUP1 pin to WKUP8 pin (shared with PIOBU0 to PIOBU7)
>  - RTC alarm
> 
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>

For the changes to the clk header:

Acked-by: Michael Turquette <mturquette@baylibre.com>

> ---
> 
>  arch/arm/mach-at91/pm.c         |   29 ++++++++++
>  arch/arm/mach-at91/pm.h         |    7 +++
>  arch/arm/mach-at91/pm_suspend.S |  111 +++++++++++++++++++++++++++++++++++++++
>  include/linux/clk/at91_pmc.h    |   36 +++++++++++++
>  4 files changed, 183 insertions(+)
> 
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
> index 80e277c..49443d9 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -35,6 +35,11 @@
>  #include "generic.h"
>  #include "pm.h"
>  
> +#define ULP0_MODE      0x00
> +#define ULP1_MODE      0x11
> +
> +#define SAMA5D2_PMC_VERSION    0x20540
> +
>  /*
>   * FIXME: this is needed to communicate between the pinctrl driver and
>   * the PM implementation in the machine. Possibly part of the PM
> @@ -64,6 +69,23 @@ static int at91_pm_valid_state(suspend_state_t state)
>         }
>  }
>  
> +static void at91_config_ulp1_wkup_source(void)
> +{
> +       if (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION) {
> +               at91_pmc_write(AT91_PMC_FSMR, AT91_PMC_RTCAL |
> +                                             AT91_PMC_FSTT9 |
> +                                             AT91_PMC_FSTT8 |
> +                                             AT91_PMC_FSTT7 |
> +                                             AT91_PMC_FSTT6 |
> +                                             AT91_PMC_FSTT5 |
> +                                             AT91_PMC_FSTT4 |
> +                                             AT91_PMC_FSTT3 |
> +                                             AT91_PMC_FSTT2 |
> +                                             AT91_PMC_FSTT0);
> +
> +               at91_pmc_write(AT91_PMC_FSPR, 0);
> +       }
> +}
>  
>  static suspend_state_t target_state;
>  
> @@ -73,6 +95,9 @@ static suspend_state_t target_state;
>  static int at91_pm_begin(suspend_state_t state)
>  {
>         target_state = state;
> +
> +       at91_config_ulp1_wkup_source();
> +
>         return 0;
>  }
>  
> @@ -140,6 +165,10 @@ static void at91_pm_suspend(suspend_state_t state)
>         pm_data |= (state == PM_SUSPEND_MEM) ?
>                                 AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
>  
> +       pm_data |= ((state == PM_SUSPEND_MEM) &&
> +                   (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION)) ?
> +                   AT91_PM_ULP(AT91_PM_ULP1_MODE) : 0;
> +
>         flush_cache_all();
>         outer_disable();
>  
> diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
> index 3fcf881..2e76745 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -39,4 +39,11 @@ extern void __iomem *at91_ramc_base[];
>  
>  #define        AT91_PM_SLOW_CLOCK      0x01
>  
> +#define AT91_PM_ULP_OFFSET     5
> +#define AT91_PM_ULP_MASK       0x03
> +#define AT91_PM_ULP(x)         (((x) & AT91_PM_ULP_MASK) << AT91_PM_ULP_OFFSET)
> +
> +#define AT91_PM_ULP0_MODE      0x00
> +#define AT91_PM_ULP1_MODE      0x01
> +
>  #endif
> diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
> index 825347b..543c430 100644
> --- a/arch/arm/mach-at91/pm_suspend.S
> +++ b/arch/arm/mach-at91/pm_suspend.S
> @@ -41,6 +41,15 @@ tmp2 .req    r5
>         .endm
>  
>  /*
> + * Wait for main oscillator selection is done
> + */
> +       .macro wait_moscsels
> +1:     ldr     tmp1, [pmc, #AT91_PMC_SR]
> +       tst     tmp1, #AT91_PMC_MOSCSELS
> +       beq     1b
> +       .endm
> +
> +/*
>   * Wait until PLLA has locked.
>   */
>         .macro wait_pllalock
> @@ -99,6 +108,10 @@ ENTRY(at91_pm_suspend_in_sram)
>         and     r0, r0, #AT91_PM_MODE_MASK
>         str     r0, .pm_mode
>  
> +       lsr     r0, r3, #AT91_PM_ULP_OFFSET
> +       and     r0, r0, #AT91_PM_ULP_MASK
> +       str     r0, .ulp_mode
> +
>         /* Active the self-refresh mode */
>         mov     r0, #SRAMC_SELF_FRESH_ACTIVE
>         bl      at91_sramc_self_refresh
> @@ -107,6 +120,14 @@ ENTRY(at91_pm_suspend_in_sram)
>         tst     r0, #AT91_PM_SLOW_CLOCK
>         beq     standby_mode
>  
> +       ldr     r0, .ulp_mode
> +       tst     r0, #AT91_PM_ULP1_MODE
> +       beq     ulp0_mode
> +
> +ulp1_mode:
> +       bl      at91_pm_ulp1_mode
> +       b       pm_exit
> +
>  ulp0_mode:
>         bl      at91_pm_ulp0_mode
>         b       pm_exit
> @@ -313,6 +334,94 @@ ENTRY(at91_pm_ulp0_mode)
>         mov     pc, lr
>  ENDPROC(at91_pm_ulp0_mode)
>  
> +/*
> + * void at91_pm_ulp1_mode(void)
> + *
> + */
> +ENTRY(at91_pm_ulp1_mode)
> +       ldr     pmc, .pmc_base
> +
> +       /* Save PMC_MCKR config */
> +       ldr     tmp1, [pmc, #AT91_PMC_MCKR]
> +       str     tmp1, .saved_mckr
> +
> +       /* Switch the master clock source to main clock */
> +       bic     tmp1, tmp1, #AT91_PMC_CSS
> +       orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
> +       str     tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +       wait_mckrdy
> +
> +       /* Save PLLA config, then and disable PLLA */
> +       ldr     tmp1, [pmc, #AT91_CKGR_PLLAR]
> +       str     tmp1, .saved_pllar
> +
> +       bic     tmp1, tmp1, #AT91_PMC3_MUL
> +       str     tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +       /* Switch main clock to 12-MHz RC oscillator */
> +       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
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_moscsels
> +
> +       /* Disable the main oscillator */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       bic     tmp1, tmp1, #AT91_PMC_MOSCEN
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       /* Enter the ULP1 mode by setting WAITMODE bit in CKGR_MOR */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       orr     tmp1, tmp1, #AT91_PMC_WAITMODE
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_mckrdy
> +
> +       /* Enable the main oscillator */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       orr     tmp1, tmp1, #AT91_PMC_MOSCEN
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_moscrdy
> +
> +       /* Switch main clock to the main oscillator */
> +       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
> +       orr     tmp1, tmp1, #AT91_PMC_MOSCSEL
> +       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
> +       orr     tmp1, tmp1, #AT91_PMC_KEY
> +       bic     tmp1, tmp1, #(7 << 4)
> +       str     tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +       wait_moscsels
> +
> +       /* Restore PLLA config */
> +       ldr     tmp1, .saved_pllar
> +       str     tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +       wait_pllalock
> +
> +       /* Restore PMC_MCKR config */
> +       ldr     tmp1, .saved_mckr
> +       str     tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +       wait_mckrdy
> +
> +       mov     pc, lr
> +ENDPROC(at91_pm_ulp1_mode)
> +
>  .pmc_base:
>         .word 0
>  .sramc_base:
> @@ -323,6 +432,8 @@ ENDPROC(at91_pm_ulp0_mode)
>         .word 0
>  .pm_mode:
>         .word 0
> +.ulp_mode:
> +       .word 0
>  .saved_mckr:
>         .word 0
>  .saved_pllar:
> diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
> index 7669f76..3dc4e60 100644
> --- a/include/linux/clk/at91_pmc.h
> +++ b/include/linux/clk/at91_pmc.h
> @@ -59,8 +59,10 @@ extern void __iomem *at91_pmc_base;
>  #define        AT91_CKGR_MOR           0x20                    /* Main Oscillator Register [not on SAM9RL] */
>  #define                AT91_PMC_MOSCEN         (1    <<  0)            /* Main Oscillator Enable */
>  #define                AT91_PMC_OSCBYPASS      (1    <<  1)            /* Oscillator Bypass */
> +#define                AT91_PMC_WAITMODE       (1    <<  2)            /* Wait Mode Command */
>  #define                AT91_PMC_MOSCRCEN       (1    <<  3)            /* Main On-Chip RC Oscillator Enable [some SAM9] */
>  #define                AT91_PMC_OSCOUNT        (0xff <<  8)            /* Main Oscillator Start-up Time */
> +#define                AT91_PMC_KEY_MASK       (0xff << 16)
>  #define                AT91_PMC_KEY            (0x37 << 16)            /* MOR Writing Key */
>  #define                AT91_PMC_MOSCSEL        (1    << 24)            /* Main Oscillator Selection [some SAM9] */
>  #define                AT91_PMC_CFDEN          (1    << 25)            /* Clock Failure Detector Enable [some SAM9] */
> @@ -166,6 +168,38 @@ extern void __iomem *at91_pmc_base;
>  #define                AT91_PMC_CFDEV          (1 << 18)               /* Clock Failure Detector Event [some SAM9] */
>  #define        AT91_PMC_IMR            0x6c                    /* Interrupt Mask Register */
>  
> +#define AT91_PMC_FSMR          0x70                    /* Fast Startup Mode Register */
> +#define                AT91_PMC_FSTT0          (1 << 0)                /* Fast Startup from WKUP Pin Enable */
> +#define                AT91_PMC_FSTT1          (1 << 1)                /* Fast Startup from Security Module Enable */
> +#define                AT91_PMC_FSTT2          (1 << 2)                /* Fast Startup from PIOBU0 Input Enable */
> +#define                AT91_PMC_FSTT3          (1 << 3)                /* Fast Startup from PIOBU1 Input Enable */
> +#define                AT91_PMC_FSTT4          (1 << 4)                /* Fast Startup from PIOBU2 Input Enable */
> +#define                AT91_PMC_FSTT5          (1 << 5)                /* Fast Startup from PIOBU3 Input Enable */
> +#define                AT91_PMC_FSTT6          (1 << 6)                /* Fast Startup from PIOBU4 Input Enable */
> +#define                AT91_PMC_FSTT7          (1 << 7)                /* Fast Startup from PIOBU5 Input Enable */
> +#define                AT91_PMC_FSTT8          (1 << 8)                /* Fast Startup from PIOBU6 Input Enable */
> +#define                AT91_PMC_FSTT9          (1 << 9)                /* Fast Startup from PIOBU7 Input Enable */
> +#define                AT91_PMC_FSTT10         (1 << 10)               /* Fast Startup from GMAC Wake-up On LAN Enable */
> +#define                AT91_PMC_RTCAL          (1 << 17)               /* Fast Startup from RTC Alarm Enable */
> +#define                AT91_PMC_USBAL          (1 << 18)               /* Fast Startup from USB Resume Enable */
> +#define                AT91_PMC_SDMMC_CD       (1 << 19)               /* Fast Startup from SDMMC Card Detect Enable */
> +#define                AT91_PMC_LPM            (1 << 20)               /* Low-power Mode */
> +#define                AT91_PMC_RXLP_MCE       (1 << 24)               /* Fast Startup from Backup UART Receive Match Condition Enable */
> +#define                AT91_PMC_ACC_CE         (1 << 25)               /* Fast Startup from Analog Comparator Controller Comparison Enable*/
> +
> +#define AT91_PMC_FSPR          0x74                    /* Fast Startup Polarity Register */
> +#define                AT91_PMC_FSTP0          (1 << 0)                /* WKUP Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP1          (1 << 1)                /* Security Module Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP2          (1 << 2)                /* PIOBU0 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP3          (1 << 3)                /* PIOBU1 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP4          (1 << 4)                /* PIOBU2 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP5          (1 << 5)                /* PIOBU3 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP6          (1 << 6)                /* PIOBU4 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP7          (1 << 7)                /* PIOBU5 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP8          (1 << 8)                /* PIOBU6 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP9          (1 << 9)                /* PIOBU7 Pin Polarity for Fast Startup */
> +#define                AT91_PMC_FSTP10         (1 << 10)               /* GMAC Wake-up On LAN Polarity for Fast Startup */
> +
>  #define AT91_PMC_PLLICPR       0x80                    /* PLL Charge Pump Current Register */
>  
>  #define AT91_PMC_PROT          0xe4                    /* Write Protect Mode Register [some SAM9] */
> @@ -177,6 +211,8 @@ extern void __iomem *at91_pmc_base;
>  #define                AT91_PMC_WPVS           (0x1  <<  0)            /* Write Protect Violation Status */
>  #define                AT91_PMC_WPVSRC         (0xffff  <<  8)         /* Write Protect Violation Source */
>  
> +#define AT91_PMC_VERSION       0xfc
> +
>  #define AT91_PMC_PCER1         0x100                   /* Peripheral Clock Enable Register 1 [SAMA5 only]*/
>  #define AT91_PMC_PCDR1         0x104                   /* Peripheral Clock Enable Register 1 */
>  #define AT91_PMC_PCSR1         0x108                   /* Peripheral Clock Enable Register 1 */
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
  2015-10-15  3:41   ` Wenyou Yang
@ 2015-10-15 13:22     ` Alexandre Belloni
  -1 siblings, 0 replies; 14+ messages in thread
From: Alexandre Belloni @ 2015-10-15 13:22 UTC (permalink / raw)
  To: Wenyou Yang
  Cc: Nicolas Ferre, Jean-Christophe Plagniol-Villard, Russell King,
	Stephen Boyd, Michael Turquette, linux-arm-kernel, linux-kernel,
	linux-clk

Hello Wenyou,

On 15/10/2015 at 11:41:07 +0800, Wenyou Yang wrote :
> +#define ULP0_MODE      0x00
> +#define ULP1_MODE      0x11

Those are not used.

> +static void at91_config_ulp1_wkup_source(void)
> +{
> +	if (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION) {
> +		at91_pmc_write(AT91_PMC_FSMR, AT91_PMC_RTCAL |
> +					      AT91_PMC_FSTT9 |
> +					      AT91_PMC_FSTT8 |
> +					      AT91_PMC_FSTT7 |
> +					      AT91_PMC_FSTT6 |
> +					      AT91_PMC_FSTT5 |
> +					      AT91_PMC_FSTT4 |
> +					      AT91_PMC_FSTT3 |
> +					      AT91_PMC_FSTT2 |
> +					      AT91_PMC_FSTT0);
> +
> +		at91_pmc_write(AT91_PMC_FSPR, 0);

Shouldn't those be configured from irq_set_wake() in the aic driver
instead of activating all the wakeup sources?
I think you need to get the PMC syscon from the aic5 driver and
implement a new irq_set_wake function when you can find the sam5d2 pmc.

The PMC syscon is introduced with that series:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/376493.html

> @@ -140,6 +165,10 @@ static void at91_pm_suspend(suspend_state_t state)
>  	pm_data |= (state == PM_SUSPEND_MEM) ?
>  				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
>  
> +	pm_data |= ((state == PM_SUSPEND_MEM) &&
> +		    (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION)) ?
> +		    AT91_PM_ULP(AT91_PM_ULP1_MODE) : 0;
> +

I would prefer not relying on the AT91_PMC_VERSION. Also, you probably
shouldn't read the register each time you go to suspend.
Finally, this could be better written by testing state only once.


>  	flush_cache_all();
>  	outer_disable();
>  
> diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
> index 3fcf881..2e76745 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -39,4 +39,11 @@ extern void __iomem *at91_ramc_base[];
>  
>  #define	AT91_PM_SLOW_CLOCK	0x01
>  
> +#define AT91_PM_ULP_OFFSET	5
> +#define AT91_PM_ULP_MASK	0x03
> +#define AT91_PM_ULP(x)		(((x) & AT91_PM_ULP_MASK) << AT91_PM_ULP_OFFSET)
> +
> +#define AT91_PM_ULP0_MODE	0x00
> +#define AT91_PM_ULP1_MODE	0x01
> +
>  #endif
> diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
> index 825347b..543c430 100644
> --- a/arch/arm/mach-at91/pm_suspend.S
> +++ b/arch/arm/mach-at91/pm_suspend.S
> @@ -41,6 +41,15 @@ tmp2	.req	r5
>  	.endm
>  
>  /*
> + * Wait for main oscillator selection is done
> + */
> +	.macro wait_moscsels
> +1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
> +	tst	tmp1, #AT91_PMC_MOSCSELS
> +	beq	1b
> +	.endm
> +
> +/*
>   * Wait until PLLA has locked.
>   */
>  	.macro wait_pllalock
> @@ -99,6 +108,10 @@ ENTRY(at91_pm_suspend_in_sram)
>  	and	r0, r0, #AT91_PM_MODE_MASK
>  	str	r0, .pm_mode
>  
> +	lsr	r0, r3, #AT91_PM_ULP_OFFSET
> +	and	r0, r0, #AT91_PM_ULP_MASK
> +	str	r0, .ulp_mode
> +
>  	/* Active the self-refresh mode */
>  	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
>  	bl	at91_sramc_self_refresh
> @@ -107,6 +120,14 @@ ENTRY(at91_pm_suspend_in_sram)
>  	tst	r0, #AT91_PM_SLOW_CLOCK
>  	beq	standby_mode
>  
> +	ldr	r0, .ulp_mode
> +	tst	r0, #AT91_PM_ULP1_MODE
> +	beq	ulp0_mode
> +
> +ulp1_mode:
> +	bl	at91_pm_ulp1_mode
> +	b	pm_exit
> +
>  ulp0_mode:
>  	bl	at91_pm_ulp0_mode
>  	b	pm_exit
> @@ -313,6 +334,94 @@ ENTRY(at91_pm_ulp0_mode)
>  	mov	pc, lr
>  ENDPROC(at91_pm_ulp0_mode)
>  
> +/*
> + * void at91_pm_ulp1_mode(void)
> + *
> + */
> +ENTRY(at91_pm_ulp1_mode)
> +	ldr	pmc, .pmc_base
> +
> +	/* Save PMC_MCKR config */
> +	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
> +	str	tmp1, .saved_mckr
> +
> +	/* Switch the master clock source to main clock */
> +	bic	tmp1, tmp1, #AT91_PMC_CSS
> +	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
> +	str	tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +	wait_mckrdy
> +
> +	/* Save PLLA config, then and disable PLLA */
> +	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
> +	str	tmp1, .saved_pllar
> +
> +	bic	tmp1, tmp1, #AT91_PMC3_MUL
> +	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +	/* Switch main clock to 12-MHz RC oscillator */
> +	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
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	wait_moscsels
> +
> +	/* Disable the main oscillator */
> +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> +	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
> +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> +	orr	tmp1, tmp1, #AT91_PMC_KEY
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	/* Enter the ULP1 mode by setting WAITMODE bit in CKGR_MOR */
> +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> +	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
> +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> +	orr	tmp1, tmp1, #AT91_PMC_KEY
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	wait_mckrdy
> +
> +	/* Enable the main oscillator */
> +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> +	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
> +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> +	orr	tmp1, tmp1, #AT91_PMC_KEY
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	wait_moscrdy
> +
> +	/* Switch main clock to the main oscillator */
> +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> +	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
> +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> +	orr	tmp1, tmp1, #AT91_PMC_KEY
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	wait_moscsels
> +
> +	/* Restore PLLA config */
> +	ldr	tmp1, .saved_pllar
> +	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +	wait_pllalock
> +
> +	/* Restore PMC_MCKR config */
> +	ldr	tmp1, .saved_mckr
> +	str	tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +	wait_mckrdy
> +
> +	mov	pc, lr
> +ENDPROC(at91_pm_ulp1_mode)
> +

This makes a lot of duplication anyway, why not having separate code for
ULP0 and ULP1 that would be copied in SRAM? This would avoid the test on .ulp_mode

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
@ 2015-10-15 13:22     ` Alexandre Belloni
  0 siblings, 0 replies; 14+ messages in thread
From: Alexandre Belloni @ 2015-10-15 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Wenyou,

On 15/10/2015 at 11:41:07 +0800, Wenyou Yang wrote :
> +#define ULP0_MODE      0x00
> +#define ULP1_MODE      0x11

Those are not used.

> +static void at91_config_ulp1_wkup_source(void)
> +{
> +	if (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION) {
> +		at91_pmc_write(AT91_PMC_FSMR, AT91_PMC_RTCAL |
> +					      AT91_PMC_FSTT9 |
> +					      AT91_PMC_FSTT8 |
> +					      AT91_PMC_FSTT7 |
> +					      AT91_PMC_FSTT6 |
> +					      AT91_PMC_FSTT5 |
> +					      AT91_PMC_FSTT4 |
> +					      AT91_PMC_FSTT3 |
> +					      AT91_PMC_FSTT2 |
> +					      AT91_PMC_FSTT0);
> +
> +		at91_pmc_write(AT91_PMC_FSPR, 0);

Shouldn't those be configured from irq_set_wake() in the aic driver
instead of activating all the wakeup sources?
I think you need to get the PMC syscon from the aic5 driver and
implement a new irq_set_wake function when you can find the sam5d2 pmc.

The PMC syscon is introduced with that series:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/376493.html

> @@ -140,6 +165,10 @@ static void at91_pm_suspend(suspend_state_t state)
>  	pm_data |= (state == PM_SUSPEND_MEM) ?
>  				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
>  
> +	pm_data |= ((state == PM_SUSPEND_MEM) &&
> +		    (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION)) ?
> +		    AT91_PM_ULP(AT91_PM_ULP1_MODE) : 0;
> +

I would prefer not relying on the AT91_PMC_VERSION. Also, you probably
shouldn't read the register each time you go to suspend.
Finally, this could be better written by testing state only once.


>  	flush_cache_all();
>  	outer_disable();
>  
> diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
> index 3fcf881..2e76745 100644
> --- a/arch/arm/mach-at91/pm.h
> +++ b/arch/arm/mach-at91/pm.h
> @@ -39,4 +39,11 @@ extern void __iomem *at91_ramc_base[];
>  
>  #define	AT91_PM_SLOW_CLOCK	0x01
>  
> +#define AT91_PM_ULP_OFFSET	5
> +#define AT91_PM_ULP_MASK	0x03
> +#define AT91_PM_ULP(x)		(((x) & AT91_PM_ULP_MASK) << AT91_PM_ULP_OFFSET)
> +
> +#define AT91_PM_ULP0_MODE	0x00
> +#define AT91_PM_ULP1_MODE	0x01
> +
>  #endif
> diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
> index 825347b..543c430 100644
> --- a/arch/arm/mach-at91/pm_suspend.S
> +++ b/arch/arm/mach-at91/pm_suspend.S
> @@ -41,6 +41,15 @@ tmp2	.req	r5
>  	.endm
>  
>  /*
> + * Wait for main oscillator selection is done
> + */
> +	.macro wait_moscsels
> +1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
> +	tst	tmp1, #AT91_PMC_MOSCSELS
> +	beq	1b
> +	.endm
> +
> +/*
>   * Wait until PLLA has locked.
>   */
>  	.macro wait_pllalock
> @@ -99,6 +108,10 @@ ENTRY(at91_pm_suspend_in_sram)
>  	and	r0, r0, #AT91_PM_MODE_MASK
>  	str	r0, .pm_mode
>  
> +	lsr	r0, r3, #AT91_PM_ULP_OFFSET
> +	and	r0, r0, #AT91_PM_ULP_MASK
> +	str	r0, .ulp_mode
> +
>  	/* Active the self-refresh mode */
>  	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
>  	bl	at91_sramc_self_refresh
> @@ -107,6 +120,14 @@ ENTRY(at91_pm_suspend_in_sram)
>  	tst	r0, #AT91_PM_SLOW_CLOCK
>  	beq	standby_mode
>  
> +	ldr	r0, .ulp_mode
> +	tst	r0, #AT91_PM_ULP1_MODE
> +	beq	ulp0_mode
> +
> +ulp1_mode:
> +	bl	at91_pm_ulp1_mode
> +	b	pm_exit
> +
>  ulp0_mode:
>  	bl	at91_pm_ulp0_mode
>  	b	pm_exit
> @@ -313,6 +334,94 @@ ENTRY(at91_pm_ulp0_mode)
>  	mov	pc, lr
>  ENDPROC(at91_pm_ulp0_mode)
>  
> +/*
> + * void at91_pm_ulp1_mode(void)
> + *
> + */
> +ENTRY(at91_pm_ulp1_mode)
> +	ldr	pmc, .pmc_base
> +
> +	/* Save PMC_MCKR config */
> +	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
> +	str	tmp1, .saved_mckr
> +
> +	/* Switch the master clock source to main clock */
> +	bic	tmp1, tmp1, #AT91_PMC_CSS
> +	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
> +	str	tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +	wait_mckrdy
> +
> +	/* Save PLLA config, then and disable PLLA */
> +	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
> +	str	tmp1, .saved_pllar
> +
> +	bic	tmp1, tmp1, #AT91_PMC3_MUL
> +	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +	/* Switch main clock to 12-MHz RC oscillator */
> +	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
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	wait_moscsels
> +
> +	/* Disable the main oscillator */
> +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> +	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
> +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> +	orr	tmp1, tmp1, #AT91_PMC_KEY
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	/* Enter the ULP1 mode by setting WAITMODE bit in CKGR_MOR */
> +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> +	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
> +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> +	orr	tmp1, tmp1, #AT91_PMC_KEY
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	wait_mckrdy
> +
> +	/* Enable the main oscillator */
> +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> +	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
> +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> +	orr	tmp1, tmp1, #AT91_PMC_KEY
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	wait_moscrdy
> +
> +	/* Switch main clock to the main oscillator */
> +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> +	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
> +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> +	orr	tmp1, tmp1, #AT91_PMC_KEY
> +	bic	tmp1, tmp1, #(7 << 4)
> +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> +
> +	wait_moscsels
> +
> +	/* Restore PLLA config */
> +	ldr	tmp1, .saved_pllar
> +	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
> +
> +	wait_pllalock
> +
> +	/* Restore PMC_MCKR config */
> +	ldr	tmp1, .saved_mckr
> +	str	tmp1, [pmc, #AT91_PMC_MCKR]
> +
> +	wait_mckrdy
> +
> +	mov	pc, lr
> +ENDPROC(at91_pm_ulp1_mode)
> +

This makes a lot of duplication anyway, why not having separate code for
ULP0 and ULP1 that would be copied in SRAM? This would avoid the test on .ulp_mode

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
  2015-10-15 13:22     ` Alexandre Belloni
  (?)
@ 2015-10-23  1:53       ` Yang, Wenyou
  -1 siblings, 0 replies; 14+ messages in thread
From: Yang, Wenyou @ 2015-10-23  1:53 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Ferre, Nicolas, Jean-Christophe Plagniol-Villard, Russell King,
	Stephen Boyd, Michael Turquette, linux-arm-kernel, linux-kernel,
	linux-clk

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb2312", Size: 7389 bytes --]

Hi Alexandre,

Sorry for late answer.

> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni@free-electrons.com]
> Sent: 2015Äê10ÔÂ15ÈÕ 21:22
> To: Yang, Wenyou
> Cc: Ferre, Nicolas; Jean-Christophe Plagniol-Villard; Russell King; Stephen Boyd;
> Michael Turquette; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; linux-clk@vger.kernel.org
> Subject: Re: [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1)
> support
> 
> Hello Wenyou,
> 
> On 15/10/2015 at 11:41:07 +0800, Wenyou Yang wrote :
> > +#define ULP0_MODE      0x00
> > +#define ULP1_MODE      0x11
> 
> Those are not used.
> 
> > +static void at91_config_ulp1_wkup_source(void)
> > +{
> > +	if (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION)
> {
> > +		at91_pmc_write(AT91_PMC_FSMR, AT91_PMC_RTCAL |
> > +					      AT91_PMC_FSTT9 |
> > +					      AT91_PMC_FSTT8 |
> > +					      AT91_PMC_FSTT7 |
> > +					      AT91_PMC_FSTT6 |
> > +					      AT91_PMC_FSTT5 |
> > +					      AT91_PMC_FSTT4 |
> > +					      AT91_PMC_FSTT3 |
> > +					      AT91_PMC_FSTT2 |
> > +					      AT91_PMC_FSTT0);
> > +
> > +		at91_pmc_write(AT91_PMC_FSPR, 0);
> 
> Shouldn't those be configured from irq_set_wake() in the aic driver instead of
> activating all the wakeup sources?
> I think you need to get the PMC syscon from the aic5 driver and implement a new
> irq_set_wake function when you can find the sam5d2 pmc.
I understand these code should not be here,  but I don't think those should be configured from irq_set_wake().
As said in datasheet, those configuration is to trigger a fast restart signal to the PMC. I think they should not be related to irq. 
 
> 
> The PMC syscon is introduced with that series:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/376493.html
> 
> > @@ -140,6 +165,10 @@ static void at91_pm_suspend(suspend_state_t state)
> >  	pm_data |= (state == PM_SUSPEND_MEM) ?
> >  				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
> >
> > +	pm_data |= ((state == PM_SUSPEND_MEM) &&
> > +		    (at91_pmc_read(AT91_PMC_VERSION) >=
> SAMA5D2_PMC_VERSION)) ?
> > +		    AT91_PM_ULP(AT91_PM_ULP1_MODE) : 0;
> > +
> 
> I would prefer not relying on the AT91_PMC_VERSION. Also, you probably
> shouldn't read the register each time you go to suspend.
> Finally, this could be better written by testing state only once.
Yes, it is not good.
> 
> 
> >  	flush_cache_all();
> >  	outer_disable();
> >
> > diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index
> > 3fcf881..2e76745 100644
> > --- a/arch/arm/mach-at91/pm.h
> > +++ b/arch/arm/mach-at91/pm.h
> > @@ -39,4 +39,11 @@ extern void __iomem *at91_ramc_base[];
> >
> >  #define	AT91_PM_SLOW_CLOCK	0x01
> >
> > +#define AT91_PM_ULP_OFFSET	5
> > +#define AT91_PM_ULP_MASK	0x03
> > +#define AT91_PM_ULP(x)		(((x) & AT91_PM_ULP_MASK) <<
> AT91_PM_ULP_OFFSET)
> > +
> > +#define AT91_PM_ULP0_MODE	0x00
> > +#define AT91_PM_ULP1_MODE	0x01
> > +
> >  #endif
> > diff --git a/arch/arm/mach-at91/pm_suspend.S
> > b/arch/arm/mach-at91/pm_suspend.S index 825347b..543c430 100644
> > --- a/arch/arm/mach-at91/pm_suspend.S
> > +++ b/arch/arm/mach-at91/pm_suspend.S
> > @@ -41,6 +41,15 @@ tmp2	.req	r5
> >  	.endm
> >
> >  /*
> > + * Wait for main oscillator selection is done  */
> > +	.macro wait_moscsels
> > +1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
> > +	tst	tmp1, #AT91_PMC_MOSCSELS
> > +	beq	1b
> > +	.endm
> > +
> > +/*
> >   * Wait until PLLA has locked.
> >   */
> >  	.macro wait_pllalock
> > @@ -99,6 +108,10 @@ ENTRY(at91_pm_suspend_in_sram)
> >  	and	r0, r0, #AT91_PM_MODE_MASK
> >  	str	r0, .pm_mode
> >
> > +	lsr	r0, r3, #AT91_PM_ULP_OFFSET
> > +	and	r0, r0, #AT91_PM_ULP_MASK
> > +	str	r0, .ulp_mode
> > +
> >  	/* Active the self-refresh mode */
> >  	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
> >  	bl	at91_sramc_self_refresh
> > @@ -107,6 +120,14 @@ ENTRY(at91_pm_suspend_in_sram)
> >  	tst	r0, #AT91_PM_SLOW_CLOCK
> >  	beq	standby_mode
> >
> > +	ldr	r0, .ulp_mode
> > +	tst	r0, #AT91_PM_ULP1_MODE
> > +	beq	ulp0_mode
> > +
> > +ulp1_mode:
> > +	bl	at91_pm_ulp1_mode
> > +	b	pm_exit
> > +
> >  ulp0_mode:
> >  	bl	at91_pm_ulp0_mode
> >  	b	pm_exit
> > @@ -313,6 +334,94 @@ ENTRY(at91_pm_ulp0_mode)
> >  	mov	pc, lr
> >  ENDPROC(at91_pm_ulp0_mode)
> >
> > +/*
> > + * void at91_pm_ulp1_mode(void)
> > + *
> > + */
> > +ENTRY(at91_pm_ulp1_mode)
> > +	ldr	pmc, .pmc_base
> > +
> > +	/* Save PMC_MCKR config */
> > +	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
> > +	str	tmp1, .saved_mckr
> > +
> > +	/* Switch the master clock source to main clock */
> > +	bic	tmp1, tmp1, #AT91_PMC_CSS
> > +	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
> > +	str	tmp1, [pmc, #AT91_PMC_MCKR]
> > +
> > +	wait_mckrdy
> > +
> > +	/* Save PLLA config, then and disable PLLA */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
> > +	str	tmp1, .saved_pllar
> > +
> > +	bic	tmp1, tmp1, #AT91_PMC3_MUL
> > +	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
> > +
> > +	/* Switch main clock to 12-MHz RC oscillator */
> > +	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
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	wait_moscsels
> > +
> > +	/* Disable the main oscillator */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> > +	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
> > +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> > +	orr	tmp1, tmp1, #AT91_PMC_KEY
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	/* Enter the ULP1 mode by setting WAITMODE bit in CKGR_MOR */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> > +	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
> > +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> > +	orr	tmp1, tmp1, #AT91_PMC_KEY
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	wait_mckrdy
> > +
> > +	/* Enable the main oscillator */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> > +	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
> > +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> > +	orr	tmp1, tmp1, #AT91_PMC_KEY
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	wait_moscrdy
> > +
> > +	/* Switch main clock to the main oscillator */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> > +	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
> > +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> > +	orr	tmp1, tmp1, #AT91_PMC_KEY
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	wait_moscsels
> > +
> > +	/* Restore PLLA config */
> > +	ldr	tmp1, .saved_pllar
> > +	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
> > +
> > +	wait_pllalock
> > +
> > +	/* Restore PMC_MCKR config */
> > +	ldr	tmp1, .saved_mckr
> > +	str	tmp1, [pmc, #AT91_PMC_MCKR]
> > +
> > +	wait_mckrdy
> > +
> > +	mov	pc, lr
> > +ENDPROC(at91_pm_ulp1_mode)
> > +
> 
> This makes a lot of duplication anyway, why not having separate code for
> ULP0 and ULP1 that would be copied in SRAM? This would avoid the test
> on .ulp_mode
Thank you for your suggestion. I agree to have separate code for ULP0 and ULP1 code.
But I still think there are a lot a duplication even so. 
Anyway, I will prepare a patch as your suggestion.

> 
> --
> Alexandre Belloni, Free Electrons
> Embedded Linux, Kernel and Android engineering http://free-electrons.com

Best Regards,
Wenyou Yang
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
@ 2015-10-23  1:53       ` Yang, Wenyou
  0 siblings, 0 replies; 14+ messages in thread
From: Yang, Wenyou @ 2015-10-23  1:53 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Ferre, Nicolas, Jean-Christophe Plagniol-Villard, Russell King,
	Stephen Boyd, Michael Turquette, linux-arm-kernel, linux-kernel,
	linux-clk

SGkgQWxleGFuZHJlLA0KDQpTb3JyeSBmb3IgbGF0ZSBhbnN3ZXIuDQoNCj4gLS0tLS1PcmlnaW5h
bCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogQWxleGFuZHJlIEJlbGxvbmkgW21haWx0bzphbGV4YW5k
cmUuYmVsbG9uaUBmcmVlLWVsZWN0cm9ucy5jb21dDQo+IFNlbnQ6IDIwMTXE6jEw1MIxNcjVIDIx
OjIyDQo+IFRvOiBZYW5nLCBXZW55b3UNCj4gQ2M6IEZlcnJlLCBOaWNvbGFzOyBKZWFuLUNocmlz
dG9waGUgUGxhZ25pb2wtVmlsbGFyZDsgUnVzc2VsbCBLaW5nOyBTdGVwaGVuIEJveWQ7DQo+IE1p
Y2hhZWwgVHVycXVldHRlOyBsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmc7IGxp
bnV4LQ0KPiBrZXJuZWxAdmdlci5rZXJuZWwub3JnOyBsaW51eC1jbGtAdmdlci5rZXJuZWwub3Jn
DQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggMi8yXSBBUk06IGF0OTEvcG06IGFkZCB1bHRyYSBMb3ct
cG93ZXIgbW9kZSAxKFVMUDEpDQo+IHN1cHBvcnQNCj4gDQo+IEhlbGxvIFdlbnlvdSwNCj4gDQo+
IE9uIDE1LzEwLzIwMTUgYXQgMTE6NDE6MDcgKzA4MDAsIFdlbnlvdSBZYW5nIHdyb3RlIDoNCj4g
PiArI2RlZmluZSBVTFAwX01PREUgICAgICAweDAwDQo+ID4gKyNkZWZpbmUgVUxQMV9NT0RFICAg
ICAgMHgxMQ0KPiANCj4gVGhvc2UgYXJlIG5vdCB1c2VkLg0KPiANCj4gPiArc3RhdGljIHZvaWQg
YXQ5MV9jb25maWdfdWxwMV93a3VwX3NvdXJjZSh2b2lkKQ0KPiA+ICt7DQo+ID4gKwlpZiAoYXQ5
MV9wbWNfcmVhZChBVDkxX1BNQ19WRVJTSU9OKSA+PSBTQU1BNUQyX1BNQ19WRVJTSU9OKQ0KPiB7
DQo+ID4gKwkJYXQ5MV9wbWNfd3JpdGUoQVQ5MV9QTUNfRlNNUiwgQVQ5MV9QTUNfUlRDQUwgfA0K
PiA+ICsJCQkJCSAgICAgIEFUOTFfUE1DX0ZTVFQ5IHwNCj4gPiArCQkJCQkgICAgICBBVDkxX1BN
Q19GU1RUOCB8DQo+ID4gKwkJCQkJICAgICAgQVQ5MV9QTUNfRlNUVDcgfA0KPiA+ICsJCQkJCSAg
ICAgIEFUOTFfUE1DX0ZTVFQ2IHwNCj4gPiArCQkJCQkgICAgICBBVDkxX1BNQ19GU1RUNSB8DQo+
ID4gKwkJCQkJICAgICAgQVQ5MV9QTUNfRlNUVDQgfA0KPiA+ICsJCQkJCSAgICAgIEFUOTFfUE1D
X0ZTVFQzIHwNCj4gPiArCQkJCQkgICAgICBBVDkxX1BNQ19GU1RUMiB8DQo+ID4gKwkJCQkJICAg
ICAgQVQ5MV9QTUNfRlNUVDApOw0KPiA+ICsNCj4gPiArCQlhdDkxX3BtY193cml0ZShBVDkxX1BN
Q19GU1BSLCAwKTsNCj4gDQo+IFNob3VsZG4ndCB0aG9zZSBiZSBjb25maWd1cmVkIGZyb20gaXJx
X3NldF93YWtlKCkgaW4gdGhlIGFpYyBkcml2ZXIgaW5zdGVhZCBvZg0KPiBhY3RpdmF0aW5nIGFs
bCB0aGUgd2FrZXVwIHNvdXJjZXM/DQo+IEkgdGhpbmsgeW91IG5lZWQgdG8gZ2V0IHRoZSBQTUMg
c3lzY29uIGZyb20gdGhlIGFpYzUgZHJpdmVyIGFuZCBpbXBsZW1lbnQgYSBuZXcNCj4gaXJxX3Nl
dF93YWtlIGZ1bmN0aW9uIHdoZW4geW91IGNhbiBmaW5kIHRoZSBzYW01ZDIgcG1jLg0KSSB1bmRl
cnN0YW5kIHRoZXNlIGNvZGUgc2hvdWxkIG5vdCBiZSBoZXJlLCAgYnV0IEkgZG9uJ3QgdGhpbmsg
dGhvc2Ugc2hvdWxkIGJlIGNvbmZpZ3VyZWQgZnJvbSBpcnFfc2V0X3dha2UoKS4NCkFzIHNhaWQg
aW4gZGF0YXNoZWV0LCB0aG9zZSBjb25maWd1cmF0aW9uIGlzIHRvIHRyaWdnZXIgYSBmYXN0IHJl
c3RhcnQgc2lnbmFsIHRvIHRoZSBQTUMuIEkgdGhpbmsgdGhleSBzaG91bGQgbm90IGJlIHJlbGF0
ZWQgdG8gaXJxLiANCiANCj4gDQo+IFRoZSBQTUMgc3lzY29uIGlzIGludHJvZHVjZWQgd2l0aCB0
aGF0IHNlcmllczoNCj4gaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvcGlwZXJtYWlsL2xpbnV4
LWFybS1rZXJuZWwvMjAxNS1PY3RvYmVyLzM3NjQ5My5odG1sDQo+IA0KPiA+IEBAIC0xNDAsNiAr
MTY1LDEwIEBAIHN0YXRpYyB2b2lkIGF0OTFfcG1fc3VzcGVuZChzdXNwZW5kX3N0YXRlX3Qgc3Rh
dGUpDQo+ID4gIAlwbV9kYXRhIHw9IChzdGF0ZSA9PSBQTV9TVVNQRU5EX01FTSkgPw0KPiA+ICAJ
CQkJQVQ5MV9QTV9NT0RFKEFUOTFfUE1fU0xPV19DTE9DSykgOiAwOw0KPiA+DQo+ID4gKwlwbV9k
YXRhIHw9ICgoc3RhdGUgPT0gUE1fU1VTUEVORF9NRU0pICYmDQo+ID4gKwkJICAgIChhdDkxX3Bt
Y19yZWFkKEFUOTFfUE1DX1ZFUlNJT04pID49DQo+IFNBTUE1RDJfUE1DX1ZFUlNJT04pKSA/DQo+
ID4gKwkJICAgIEFUOTFfUE1fVUxQKEFUOTFfUE1fVUxQMV9NT0RFKSA6IDA7DQo+ID4gKw0KPiAN
Cj4gSSB3b3VsZCBwcmVmZXIgbm90IHJlbHlpbmcgb24gdGhlIEFUOTFfUE1DX1ZFUlNJT04uIEFs
c28sIHlvdSBwcm9iYWJseQ0KPiBzaG91bGRuJ3QgcmVhZCB0aGUgcmVnaXN0ZXIgZWFjaCB0aW1l
IHlvdSBnbyB0byBzdXNwZW5kLg0KPiBGaW5hbGx5LCB0aGlzIGNvdWxkIGJlIGJldHRlciB3cml0
dGVuIGJ5IHRlc3Rpbmcgc3RhdGUgb25seSBvbmNlLg0KWWVzLCBpdCBpcyBub3QgZ29vZC4NCj4g
DQo+IA0KPiA+ICAJZmx1c2hfY2FjaGVfYWxsKCk7DQo+ID4gIAlvdXRlcl9kaXNhYmxlKCk7DQo+
ID4NCj4gPiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm0vbWFjaC1hdDkxL3BtLmggYi9hcmNoL2FybS9t
YWNoLWF0OTEvcG0uaCBpbmRleA0KPiA+IDNmY2Y4ODEuLjJlNzY3NDUgMTAwNjQ0DQo+ID4gLS0t
IGEvYXJjaC9hcm0vbWFjaC1hdDkxL3BtLmgNCj4gPiArKysgYi9hcmNoL2FybS9tYWNoLWF0OTEv
cG0uaA0KPiA+IEBAIC0zOSw0ICszOSwxMSBAQCBleHRlcm4gdm9pZCBfX2lvbWVtICphdDkxX3Jh
bWNfYmFzZVtdOw0KPiA+DQo+ID4gICNkZWZpbmUJQVQ5MV9QTV9TTE9XX0NMT0NLCTB4MDENCj4g
Pg0KPiA+ICsjZGVmaW5lIEFUOTFfUE1fVUxQX09GRlNFVAk1DQo+ID4gKyNkZWZpbmUgQVQ5MV9Q
TV9VTFBfTUFTSwkweDAzDQo+ID4gKyNkZWZpbmUgQVQ5MV9QTV9VTFAoeCkJCSgoKHgpICYgQVQ5
MV9QTV9VTFBfTUFTSykgPDwNCj4gQVQ5MV9QTV9VTFBfT0ZGU0VUKQ0KPiA+ICsNCj4gPiArI2Rl
ZmluZSBBVDkxX1BNX1VMUDBfTU9ERQkweDAwDQo+ID4gKyNkZWZpbmUgQVQ5MV9QTV9VTFAxX01P
REUJMHgwMQ0KPiA+ICsNCj4gPiAgI2VuZGlmDQo+ID4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtL21h
Y2gtYXQ5MS9wbV9zdXNwZW5kLlMNCj4gPiBiL2FyY2gvYXJtL21hY2gtYXQ5MS9wbV9zdXNwZW5k
LlMgaW5kZXggODI1MzQ3Yi4uNTQzYzQzMCAxMDA2NDQNCj4gPiAtLS0gYS9hcmNoL2FybS9tYWNo
LWF0OTEvcG1fc3VzcGVuZC5TDQo+ID4gKysrIGIvYXJjaC9hcm0vbWFjaC1hdDkxL3BtX3N1c3Bl
bmQuUw0KPiA+IEBAIC00MSw2ICs0MSwxNSBAQCB0bXAyCS5yZXEJcjUNCj4gPiAgCS5lbmRtDQo+
ID4NCj4gPiAgLyoNCj4gPiArICogV2FpdCBmb3IgbWFpbiBvc2NpbGxhdG9yIHNlbGVjdGlvbiBp
cyBkb25lICAqLw0KPiA+ICsJLm1hY3JvIHdhaXRfbW9zY3NlbHMNCj4gPiArMToJbGRyCXRtcDEs
IFtwbWMsICNBVDkxX1BNQ19TUl0NCj4gPiArCXRzdAl0bXAxLCAjQVQ5MV9QTUNfTU9TQ1NFTFMN
Cj4gPiArCWJlcQkxYg0KPiA+ICsJLmVuZG0NCj4gPiArDQo+ID4gKy8qDQo+ID4gICAqIFdhaXQg
dW50aWwgUExMQSBoYXMgbG9ja2VkLg0KPiA+ICAgKi8NCj4gPiAgCS5tYWNybyB3YWl0X3BsbGFs
b2NrDQo+ID4gQEAgLTk5LDYgKzEwOCwxMCBAQCBFTlRSWShhdDkxX3BtX3N1c3BlbmRfaW5fc3Jh
bSkNCj4gPiAgCWFuZAlyMCwgcjAsICNBVDkxX1BNX01PREVfTUFTSw0KPiA+ICAJc3RyCXIwLCAu
cG1fbW9kZQ0KPiA+DQo+ID4gKwlsc3IJcjAsIHIzLCAjQVQ5MV9QTV9VTFBfT0ZGU0VUDQo+ID4g
KwlhbmQJcjAsIHIwLCAjQVQ5MV9QTV9VTFBfTUFTSw0KPiA+ICsJc3RyCXIwLCAudWxwX21vZGUN
Cj4gPiArDQo+ID4gIAkvKiBBY3RpdmUgdGhlIHNlbGYtcmVmcmVzaCBtb2RlICovDQo+ID4gIAlt
b3YJcjAsICNTUkFNQ19TRUxGX0ZSRVNIX0FDVElWRQ0KPiA+ICAJYmwJYXQ5MV9zcmFtY19zZWxm
X3JlZnJlc2gNCj4gPiBAQCAtMTA3LDYgKzEyMCwxNCBAQCBFTlRSWShhdDkxX3BtX3N1c3BlbmRf
aW5fc3JhbSkNCj4gPiAgCXRzdAlyMCwgI0FUOTFfUE1fU0xPV19DTE9DSw0KPiA+ICAJYmVxCXN0
YW5kYnlfbW9kZQ0KPiA+DQo+ID4gKwlsZHIJcjAsIC51bHBfbW9kZQ0KPiA+ICsJdHN0CXIwLCAj
QVQ5MV9QTV9VTFAxX01PREUNCj4gPiArCWJlcQl1bHAwX21vZGUNCj4gPiArDQo+ID4gK3VscDFf
bW9kZToNCj4gPiArCWJsCWF0OTFfcG1fdWxwMV9tb2RlDQo+ID4gKwliCXBtX2V4aXQNCj4gPiAr
DQo+ID4gIHVscDBfbW9kZToNCj4gPiAgCWJsCWF0OTFfcG1fdWxwMF9tb2RlDQo+ID4gIAliCXBt
X2V4aXQNCj4gPiBAQCAtMzEzLDYgKzMzNCw5NCBAQCBFTlRSWShhdDkxX3BtX3VscDBfbW9kZSkN
Cj4gPiAgCW1vdglwYywgbHINCj4gPiAgRU5EUFJPQyhhdDkxX3BtX3VscDBfbW9kZSkNCj4gPg0K
PiA+ICsvKg0KPiA+ICsgKiB2b2lkIGF0OTFfcG1fdWxwMV9tb2RlKHZvaWQpDQo+ID4gKyAqDQo+
ID4gKyAqLw0KPiA+ICtFTlRSWShhdDkxX3BtX3VscDFfbW9kZSkNCj4gPiArCWxkcglwbWMsIC5w
bWNfYmFzZQ0KPiA+ICsNCj4gPiArCS8qIFNhdmUgUE1DX01DS1IgY29uZmlnICovDQo+ID4gKwls
ZHIJdG1wMSwgW3BtYywgI0FUOTFfUE1DX01DS1JdDQo+ID4gKwlzdHIJdG1wMSwgLnNhdmVkX21j
a3INCj4gPiArDQo+ID4gKwkvKiBTd2l0Y2ggdGhlIG1hc3RlciBjbG9jayBzb3VyY2UgdG8gbWFp
biBjbG9jayAqLw0KPiA+ICsJYmljCXRtcDEsIHRtcDEsICNBVDkxX1BNQ19DU1MNCj4gPiArCW9y
cgl0bXAxLCB0bXAxLCAjQVQ5MV9QTUNfQ1NTX01BSU4NCj4gPiArCXN0cgl0bXAxLCBbcG1jLCAj
QVQ5MV9QTUNfTUNLUl0NCj4gPiArDQo+ID4gKwl3YWl0X21ja3JkeQ0KPiA+ICsNCj4gPiArCS8q
IFNhdmUgUExMQSBjb25maWcsIHRoZW4gYW5kIGRpc2FibGUgUExMQSAqLw0KPiA+ICsJbGRyCXRt
cDEsIFtwbWMsICNBVDkxX0NLR1JfUExMQVJdDQo+ID4gKwlzdHIJdG1wMSwgLnNhdmVkX3BsbGFy
DQo+ID4gKw0KPiA+ICsJYmljCXRtcDEsIHRtcDEsICNBVDkxX1BNQzNfTVVMDQo+ID4gKwlzdHIJ
dG1wMSwgW3BtYywgI0FUOTFfQ0tHUl9QTExBUl0NCj4gPiArDQo+ID4gKwkvKiBTd2l0Y2ggbWFp
biBjbG9jayB0byAxMi1NSHogUkMgb3NjaWxsYXRvciAqLw0KPiA+ICsJbGRyCXRtcDEsIFtwbWMs
ICNBVDkxX0NLR1JfTU9SXQ0KPiA+ICsJYmljCXRtcDEsIHRtcDEsICNBVDkxX1BNQ19NT1NDU0VM
DQo+ID4gKwliaWMJdG1wMSwgdG1wMSwgI0FUOTFfUE1DX0tFWV9NQVNLDQo+ID4gKwlvcnIJdG1w
MSwgdG1wMSwgI0FUOTFfUE1DX0tFWQ0KPiA+ICsJYmljCXRtcDEsIHRtcDEsICMoNyA8PCA0KQ0K
PiA+ICsJc3RyCXRtcDEsIFtwbWMsICNBVDkxX0NLR1JfTU9SXQ0KPiA+ICsNCj4gPiArCXdhaXRf
bW9zY3NlbHMNCj4gPiArDQo+ID4gKwkvKiBEaXNhYmxlIHRoZSBtYWluIG9zY2lsbGF0b3IgKi8N
Cj4gPiArCWxkcgl0bXAxLCBbcG1jLCAjQVQ5MV9DS0dSX01PUl0NCj4gPiArCWJpYwl0bXAxLCB0
bXAxLCAjQVQ5MV9QTUNfTU9TQ0VODQo+ID4gKwliaWMJdG1wMSwgdG1wMSwgI0FUOTFfUE1DX0tF
WV9NQVNLDQo+ID4gKwlvcnIJdG1wMSwgdG1wMSwgI0FUOTFfUE1DX0tFWQ0KPiA+ICsJYmljCXRt
cDEsIHRtcDEsICMoNyA8PCA0KQ0KPiA+ICsJc3RyCXRtcDEsIFtwbWMsICNBVDkxX0NLR1JfTU9S
XQ0KPiA+ICsNCj4gPiArCS8qIEVudGVyIHRoZSBVTFAxIG1vZGUgYnkgc2V0dGluZyBXQUlUTU9E
RSBiaXQgaW4gQ0tHUl9NT1IgKi8NCj4gPiArCWxkcgl0bXAxLCBbcG1jLCAjQVQ5MV9DS0dSX01P
Ul0NCj4gPiArCW9ycgl0bXAxLCB0bXAxLCAjQVQ5MV9QTUNfV0FJVE1PREUNCj4gPiArCWJpYwl0
bXAxLCB0bXAxLCAjQVQ5MV9QTUNfS0VZX01BU0sNCj4gPiArCW9ycgl0bXAxLCB0bXAxLCAjQVQ5
MV9QTUNfS0VZDQo+ID4gKwliaWMJdG1wMSwgdG1wMSwgIyg3IDw8IDQpDQo+ID4gKwlzdHIJdG1w
MSwgW3BtYywgI0FUOTFfQ0tHUl9NT1JdDQo+ID4gKw0KPiA+ICsJd2FpdF9tY2tyZHkNCj4gPiAr
DQo+ID4gKwkvKiBFbmFibGUgdGhlIG1haW4gb3NjaWxsYXRvciAqLw0KPiA+ICsJbGRyCXRtcDEs
IFtwbWMsICNBVDkxX0NLR1JfTU9SXQ0KPiA+ICsJb3JyCXRtcDEsIHRtcDEsICNBVDkxX1BNQ19N
T1NDRU4NCj4gPiArCWJpYwl0bXAxLCB0bXAxLCAjQVQ5MV9QTUNfS0VZX01BU0sNCj4gPiArCW9y
cgl0bXAxLCB0bXAxLCAjQVQ5MV9QTUNfS0VZDQo+ID4gKwliaWMJdG1wMSwgdG1wMSwgIyg3IDw8
IDQpDQo+ID4gKwlzdHIJdG1wMSwgW3BtYywgI0FUOTFfQ0tHUl9NT1JdDQo+ID4gKw0KPiA+ICsJ
d2FpdF9tb3NjcmR5DQo+ID4gKw0KPiA+ICsJLyogU3dpdGNoIG1haW4gY2xvY2sgdG8gdGhlIG1h
aW4gb3NjaWxsYXRvciAqLw0KPiA+ICsJbGRyCXRtcDEsIFtwbWMsICNBVDkxX0NLR1JfTU9SXQ0K
PiA+ICsJb3JyCXRtcDEsIHRtcDEsICNBVDkxX1BNQ19NT1NDU0VMDQo+ID4gKwliaWMJdG1wMSwg
dG1wMSwgI0FUOTFfUE1DX0tFWV9NQVNLDQo+ID4gKwlvcnIJdG1wMSwgdG1wMSwgI0FUOTFfUE1D
X0tFWQ0KPiA+ICsJYmljCXRtcDEsIHRtcDEsICMoNyA8PCA0KQ0KPiA+ICsJc3RyCXRtcDEsIFtw
bWMsICNBVDkxX0NLR1JfTU9SXQ0KPiA+ICsNCj4gPiArCXdhaXRfbW9zY3NlbHMNCj4gPiArDQo+
ID4gKwkvKiBSZXN0b3JlIFBMTEEgY29uZmlnICovDQo+ID4gKwlsZHIJdG1wMSwgLnNhdmVkX3Bs
bGFyDQo+ID4gKwlzdHIJdG1wMSwgW3BtYywgI0FUOTFfQ0tHUl9QTExBUl0NCj4gPiArDQo+ID4g
Kwl3YWl0X3BsbGFsb2NrDQo+ID4gKw0KPiA+ICsJLyogUmVzdG9yZSBQTUNfTUNLUiBjb25maWcg
Ki8NCj4gPiArCWxkcgl0bXAxLCAuc2F2ZWRfbWNrcg0KPiA+ICsJc3RyCXRtcDEsIFtwbWMsICNB
VDkxX1BNQ19NQ0tSXQ0KPiA+ICsNCj4gPiArCXdhaXRfbWNrcmR5DQo+ID4gKw0KPiA+ICsJbW92
CXBjLCBscg0KPiA+ICtFTkRQUk9DKGF0OTFfcG1fdWxwMV9tb2RlKQ0KPiA+ICsNCj4gDQo+IFRo
aXMgbWFrZXMgYSBsb3Qgb2YgZHVwbGljYXRpb24gYW55d2F5LCB3aHkgbm90IGhhdmluZyBzZXBh
cmF0ZSBjb2RlIGZvcg0KPiBVTFAwIGFuZCBVTFAxIHRoYXQgd291bGQgYmUgY29waWVkIGluIFNS
QU0/IFRoaXMgd291bGQgYXZvaWQgdGhlIHRlc3QNCj4gb24gLnVscF9tb2RlDQpUaGFuayB5b3Ug
Zm9yIHlvdXIgc3VnZ2VzdGlvbi4gSSBhZ3JlZSB0byBoYXZlIHNlcGFyYXRlIGNvZGUgZm9yIFVM
UDAgYW5kIFVMUDEgY29kZS4NCkJ1dCBJIHN0aWxsIHRoaW5rIHRoZXJlIGFyZSBhIGxvdCBhIGR1
cGxpY2F0aW9uIGV2ZW4gc28uIA0KQW55d2F5LCBJIHdpbGwgcHJlcGFyZSBhIHBhdGNoIGFzIHlv
dXIgc3VnZ2VzdGlvbi4NCg0KPiANCj4gLS0NCj4gQWxleGFuZHJlIEJlbGxvbmksIEZyZWUgRWxl
Y3Ryb25zDQo+IEVtYmVkZGVkIExpbnV4LCBLZXJuZWwgYW5kIEFuZHJvaWQgZW5naW5lZXJpbmcg
aHR0cDovL2ZyZWUtZWxlY3Ryb25zLmNvbQ0KDQpCZXN0IFJlZ2FyZHMsDQpXZW55b3UgWWFuZw0K

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support
@ 2015-10-23  1:53       ` Yang, Wenyou
  0 siblings, 0 replies; 14+ messages in thread
From: Yang, Wenyou @ 2015-10-23  1:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Alexandre,

Sorry for late answer.

> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2015?10?15? 21:22
> To: Yang, Wenyou
> Cc: Ferre, Nicolas; Jean-Christophe Plagniol-Villard; Russell King; Stephen Boyd;
> Michael Turquette; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; linux-clk at vger.kernel.org
> Subject: Re: [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1)
> support
> 
> Hello Wenyou,
> 
> On 15/10/2015 at 11:41:07 +0800, Wenyou Yang wrote :
> > +#define ULP0_MODE      0x00
> > +#define ULP1_MODE      0x11
> 
> Those are not used.
> 
> > +static void at91_config_ulp1_wkup_source(void)
> > +{
> > +	if (at91_pmc_read(AT91_PMC_VERSION) >= SAMA5D2_PMC_VERSION)
> {
> > +		at91_pmc_write(AT91_PMC_FSMR, AT91_PMC_RTCAL |
> > +					      AT91_PMC_FSTT9 |
> > +					      AT91_PMC_FSTT8 |
> > +					      AT91_PMC_FSTT7 |
> > +					      AT91_PMC_FSTT6 |
> > +					      AT91_PMC_FSTT5 |
> > +					      AT91_PMC_FSTT4 |
> > +					      AT91_PMC_FSTT3 |
> > +					      AT91_PMC_FSTT2 |
> > +					      AT91_PMC_FSTT0);
> > +
> > +		at91_pmc_write(AT91_PMC_FSPR, 0);
> 
> Shouldn't those be configured from irq_set_wake() in the aic driver instead of
> activating all the wakeup sources?
> I think you need to get the PMC syscon from the aic5 driver and implement a new
> irq_set_wake function when you can find the sam5d2 pmc.
I understand these code should not be here,  but I don't think those should be configured from irq_set_wake().
As said in datasheet, those configuration is to trigger a fast restart signal to the PMC. I think they should not be related to irq. 
 
> 
> The PMC syscon is introduced with that series:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/376493.html
> 
> > @@ -140,6 +165,10 @@ static void at91_pm_suspend(suspend_state_t state)
> >  	pm_data |= (state == PM_SUSPEND_MEM) ?
> >  				AT91_PM_MODE(AT91_PM_SLOW_CLOCK) : 0;
> >
> > +	pm_data |= ((state == PM_SUSPEND_MEM) &&
> > +		    (at91_pmc_read(AT91_PMC_VERSION) >=
> SAMA5D2_PMC_VERSION)) ?
> > +		    AT91_PM_ULP(AT91_PM_ULP1_MODE) : 0;
> > +
> 
> I would prefer not relying on the AT91_PMC_VERSION. Also, you probably
> shouldn't read the register each time you go to suspend.
> Finally, this could be better written by testing state only once.
Yes, it is not good.
> 
> 
> >  	flush_cache_all();
> >  	outer_disable();
> >
> > diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index
> > 3fcf881..2e76745 100644
> > --- a/arch/arm/mach-at91/pm.h
> > +++ b/arch/arm/mach-at91/pm.h
> > @@ -39,4 +39,11 @@ extern void __iomem *at91_ramc_base[];
> >
> >  #define	AT91_PM_SLOW_CLOCK	0x01
> >
> > +#define AT91_PM_ULP_OFFSET	5
> > +#define AT91_PM_ULP_MASK	0x03
> > +#define AT91_PM_ULP(x)		(((x) & AT91_PM_ULP_MASK) <<
> AT91_PM_ULP_OFFSET)
> > +
> > +#define AT91_PM_ULP0_MODE	0x00
> > +#define AT91_PM_ULP1_MODE	0x01
> > +
> >  #endif
> > diff --git a/arch/arm/mach-at91/pm_suspend.S
> > b/arch/arm/mach-at91/pm_suspend.S index 825347b..543c430 100644
> > --- a/arch/arm/mach-at91/pm_suspend.S
> > +++ b/arch/arm/mach-at91/pm_suspend.S
> > @@ -41,6 +41,15 @@ tmp2	.req	r5
> >  	.endm
> >
> >  /*
> > + * Wait for main oscillator selection is done  */
> > +	.macro wait_moscsels
> > +1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
> > +	tst	tmp1, #AT91_PMC_MOSCSELS
> > +	beq	1b
> > +	.endm
> > +
> > +/*
> >   * Wait until PLLA has locked.
> >   */
> >  	.macro wait_pllalock
> > @@ -99,6 +108,10 @@ ENTRY(at91_pm_suspend_in_sram)
> >  	and	r0, r0, #AT91_PM_MODE_MASK
> >  	str	r0, .pm_mode
> >
> > +	lsr	r0, r3, #AT91_PM_ULP_OFFSET
> > +	and	r0, r0, #AT91_PM_ULP_MASK
> > +	str	r0, .ulp_mode
> > +
> >  	/* Active the self-refresh mode */
> >  	mov	r0, #SRAMC_SELF_FRESH_ACTIVE
> >  	bl	at91_sramc_self_refresh
> > @@ -107,6 +120,14 @@ ENTRY(at91_pm_suspend_in_sram)
> >  	tst	r0, #AT91_PM_SLOW_CLOCK
> >  	beq	standby_mode
> >
> > +	ldr	r0, .ulp_mode
> > +	tst	r0, #AT91_PM_ULP1_MODE
> > +	beq	ulp0_mode
> > +
> > +ulp1_mode:
> > +	bl	at91_pm_ulp1_mode
> > +	b	pm_exit
> > +
> >  ulp0_mode:
> >  	bl	at91_pm_ulp0_mode
> >  	b	pm_exit
> > @@ -313,6 +334,94 @@ ENTRY(at91_pm_ulp0_mode)
> >  	mov	pc, lr
> >  ENDPROC(at91_pm_ulp0_mode)
> >
> > +/*
> > + * void at91_pm_ulp1_mode(void)
> > + *
> > + */
> > +ENTRY(at91_pm_ulp1_mode)
> > +	ldr	pmc, .pmc_base
> > +
> > +	/* Save PMC_MCKR config */
> > +	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
> > +	str	tmp1, .saved_mckr
> > +
> > +	/* Switch the master clock source to main clock */
> > +	bic	tmp1, tmp1, #AT91_PMC_CSS
> > +	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
> > +	str	tmp1, [pmc, #AT91_PMC_MCKR]
> > +
> > +	wait_mckrdy
> > +
> > +	/* Save PLLA config, then and disable PLLA */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
> > +	str	tmp1, .saved_pllar
> > +
> > +	bic	tmp1, tmp1, #AT91_PMC3_MUL
> > +	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
> > +
> > +	/* Switch main clock to 12-MHz RC oscillator */
> > +	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
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	wait_moscsels
> > +
> > +	/* Disable the main oscillator */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> > +	bic	tmp1, tmp1, #AT91_PMC_MOSCEN
> > +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> > +	orr	tmp1, tmp1, #AT91_PMC_KEY
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	/* Enter the ULP1 mode by setting WAITMODE bit in CKGR_MOR */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> > +	orr	tmp1, tmp1, #AT91_PMC_WAITMODE
> > +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> > +	orr	tmp1, tmp1, #AT91_PMC_KEY
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	wait_mckrdy
> > +
> > +	/* Enable the main oscillator */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> > +	orr	tmp1, tmp1, #AT91_PMC_MOSCEN
> > +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> > +	orr	tmp1, tmp1, #AT91_PMC_KEY
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	wait_moscrdy
> > +
> > +	/* Switch main clock to the main oscillator */
> > +	ldr	tmp1, [pmc, #AT91_CKGR_MOR]
> > +	orr	tmp1, tmp1, #AT91_PMC_MOSCSEL
> > +	bic	tmp1, tmp1, #AT91_PMC_KEY_MASK
> > +	orr	tmp1, tmp1, #AT91_PMC_KEY
> > +	bic	tmp1, tmp1, #(7 << 4)
> > +	str	tmp1, [pmc, #AT91_CKGR_MOR]
> > +
> > +	wait_moscsels
> > +
> > +	/* Restore PLLA config */
> > +	ldr	tmp1, .saved_pllar
> > +	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
> > +
> > +	wait_pllalock
> > +
> > +	/* Restore PMC_MCKR config */
> > +	ldr	tmp1, .saved_mckr
> > +	str	tmp1, [pmc, #AT91_PMC_MCKR]
> > +
> > +	wait_mckrdy
> > +
> > +	mov	pc, lr
> > +ENDPROC(at91_pm_ulp1_mode)
> > +
> 
> This makes a lot of duplication anyway, why not having separate code for
> ULP0 and ULP1 that would be copied in SRAM? This would avoid the test
> on .ulp_mode
Thank you for your suggestion. I agree to have separate code for ULP0 and ULP1 code.
But I still think there are a lot a duplication even so. 
Anyway, I will prepare a patch as your suggestion.

> 
> --
> Alexandre Belloni, Free Electrons
> Embedded Linux, Kernel and Android engineering http://free-electrons.com

Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2015-10-23  1:54 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-15  3:41 [PATCH 0/2] ARM: at91/pm: add ULP1 support Wenyou Yang
2015-10-15  3:41 ` Wenyou Yang
2015-10-15  3:41 ` [PATCH 1/2] ARM: at91/pm: move enter sleep code to a procedure Wenyou Yang
2015-10-15  3:41   ` Wenyou Yang
2015-10-15  3:41 ` [PATCH 2/2] ARM: at91/pm: add ultra Low-power mode 1(ULP1) support Wenyou Yang
2015-10-15  3:41   ` Wenyou Yang
2015-10-15  9:31   ` Michael Turquette
2015-10-15  9:31     ` Michael Turquette
2015-10-15  9:31     ` Michael Turquette
2015-10-15 13:22   ` Alexandre Belloni
2015-10-15 13:22     ` Alexandre Belloni
2015-10-23  1:53     ` Yang, Wenyou
2015-10-23  1:53       ` Yang, Wenyou
2015-10-23  1:53       ` Yang, Wenyou

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.