* [PATCH 1/3] ARM: CSR: PM: save/restore timer status in suspend cycles
2011-09-13 10:06 [PATCH 0/3] ARCH: CSR: basic PM suspend/resume support Barry Song
@ 2011-09-13 10:06 ` Barry Song
2011-09-13 10:06 ` [PATCH 2/3] ARM: CSR: PM: save/restore irq " Barry Song
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Barry Song @ 2011-09-13 10:06 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
arch/arm/mach-prima2/timer.c | 34 ++++++++++++++++++++++++++++++++++
1 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
index ed7ec48..3b15961 100644
--- a/arch/arm/mach-prima2/timer.c
+++ b/arch/arm/mach-prima2/timer.c
@@ -40,6 +40,17 @@
#define SIRFSOC_TIMER_LATCH_BIT BIT(0)
+#define SIRFSOC_TIMER_REG_CNT 11
+
+static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
+ SIRFSOC_TIMER_MATCH_0, SIRFSOC_TIMER_MATCH_1, SIRFSOC_TIMER_MATCH_2,
+ SIRFSOC_TIMER_MATCH_3, SIRFSOC_TIMER_MATCH_4, SIRFSOC_TIMER_MATCH_5,
+ SIRFSOC_TIMER_INT_EN, SIRFSOC_TIMER_WATCHDOG_EN, SIRFSOC_TIMER_DIV,
+ SIRFSOC_TIMER_LATCHED_LO, SIRFSOC_TIMER_LATCHED_HI,
+};
+
+static u32 sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT];
+
static void __iomem *sirfsoc_timer_base;
static void __init sirfsoc_of_timer_map(void);
@@ -106,6 +117,27 @@ static void sirfsoc_timer_set_mode(enum clock_event_mode mode,
}
}
+static void sirfsoc_clocksource_suspend(struct clocksource *cs)
+{
+ int i;
+
+ writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
+
+ for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++)
+ sirfsoc_timer_reg_val[i] = readl_relaxed(sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
+}
+
+static void sirfsoc_clocksource_resume(struct clocksource *cs)
+{
+ int i;
+
+ for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++)
+ writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
+
+ writel_relaxed(sirfsoc_timer_reg_val[i - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
+ writel_relaxed(sirfsoc_timer_reg_val[i - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
+}
+
static struct clock_event_device sirfsoc_clockevent = {
.name = "sirfsoc_clockevent",
.rating = 200,
@@ -120,6 +152,8 @@ static struct clocksource sirfsoc_clocksource = {
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
.read = sirfsoc_timer_read,
+ .suspend = sirfsoc_clocksource_suspend,
+ .resume = sirfsoc_clocksource_resume,
};
static struct irqaction sirfsoc_timer_irq = {
--
1.7.1
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog@www.csr.com/blog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/3] ARM: CSR: PM: save/restore irq status in suspend cycles
2011-09-13 10:06 [PATCH 0/3] ARCH: CSR: basic PM suspend/resume support Barry Song
2011-09-13 10:06 ` [PATCH 1/3] ARM: CSR: PM: save/restore timer status in suspend cycles Barry Song
@ 2011-09-13 10:06 ` Barry Song
2011-09-13 10:06 ` [PATCH 3/3] ARM: CSR: PM: add sleep entry for SiRFprimaII Barry Song
2011-09-13 16:11 ` [PATCH 0/3] ARCH: CSR: basic PM suspend/resume support Arnd Bergmann
3 siblings, 0 replies; 6+ messages in thread
From: Barry Song @ 2011-09-13 10:06 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
arch/arm/mach-prima2/irq.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c
index cf80a72..d93ceef 100644
--- a/arch/arm/mach-prima2/irq.c
+++ b/arch/arm/mach-prima2/irq.c
@@ -14,6 +14,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/irqdomain.h>
+#include <linux/syscore_ops.h>
#define SIRFSOC_INT_RISC_MASK0 0x0018
#define SIRFSOC_INT_RISC_MASK1 0x001C
@@ -73,3 +74,42 @@ void __init sirfsoc_of_irq_init(void)
sirfsoc_irq_init();
}
+
+struct sirfsoc_irq_status {
+ u32 mask0;
+ u32 mask1;
+ u32 level0;
+ u32 level1;
+};
+
+static struct sirfsoc_irq_status sirfsoc_irq_st;
+
+static int sirfsoc_irq_suspend(void)
+{
+ sirfsoc_irq_st.mask0 = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK0);
+ sirfsoc_irq_st.mask1 = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1);
+ sirfsoc_irq_st.level0 = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0);
+ sirfsoc_irq_st.level1 = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1);
+
+ return 0;
+}
+
+static void sirfsoc_irq_resume(void)
+{
+ writel_relaxed(sirfsoc_irq_st.mask0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK0);
+ writel_relaxed(sirfsoc_irq_st.mask1, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1);
+ writel_relaxed(sirfsoc_irq_st.level0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0);
+ writel_relaxed(sirfsoc_irq_st.level1, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1);
+}
+
+static struct syscore_ops sirfsoc_irq_syscore_ops = {
+ .suspend = sirfsoc_irq_suspend,
+ .resume = sirfsoc_irq_resume,
+};
+
+static int __init sirfsoc_irq_pm_init(void)
+{
+ register_syscore_ops(&sirfsoc_irq_syscore_ops);
+ return 0;
+}
+device_initcall(sirfsoc_irq_pm_init);
--
1.7.1
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/3] ARM: CSR: PM: add sleep entry for SiRFprimaII
2011-09-13 10:06 [PATCH 0/3] ARCH: CSR: basic PM suspend/resume support Barry Song
2011-09-13 10:06 ` [PATCH 1/3] ARM: CSR: PM: save/restore timer status in suspend cycles Barry Song
2011-09-13 10:06 ` [PATCH 2/3] ARM: CSR: PM: save/restore irq " Barry Song
@ 2011-09-13 10:06 ` Barry Song
2011-09-13 16:11 ` [PATCH 0/3] ARCH: CSR: basic PM suspend/resume support Arnd Bergmann
3 siblings, 0 replies; 6+ messages in thread
From: Barry Song @ 2011-09-13 10:06 UTC (permalink / raw)
To: linux-arm-kernel
From: Rongjun Ying <rongjun.ying@csr.com>
Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
Due to L2 cache will lose power and data in suspend cycle, prima2 actually requires
the whole l2 cache flushed while suspending and re-initilized after resuming just
like code boot.
So the "ARM: CSR: PM: add sleep entry for SiRFprimaII" depends on:
Shawn Guo <shawn.guo@linaro.org>'s
[PATCH v2 1/2] ARM: cache-l2x0: remove __init annotation from initialization functions
http://www.spinics.net/lists/arm-kernel/msg139198.html
arch/arm/mach-prima2/Makefile | 1 +
arch/arm/mach-prima2/pm.c | 150 +++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-prima2/pm.h | 31 +++++++++
arch/arm/mach-prima2/sleep.S | 64 +++++++++++++++++
4 files changed, 246 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-prima2/pm.c
create mode 100644 arch/arm/mach-prima2/pm.h
create mode 100644 arch/arm/mach-prima2/sleep.S
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
index f49d70b..13dd160 100644
--- a/arch/arm/mach-prima2/Makefile
+++ b/arch/arm/mach-prima2/Makefile
@@ -6,3 +6,4 @@ obj-y += prima2.o
obj-y += rtciobrg.o
obj-$(CONFIG_DEBUG_LL) += lluart.o
obj-$(CONFIG_CACHE_L2X0) += l2x0.o
+obj-$(CONFIG_SUSPEND) += pm.o sleep.o
diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c
new file mode 100644
index 0000000..0109729
--- /dev/null
+++ b/arch/arm/mach-prima2/pm.c
@@ -0,0 +1,150 @@
+/*
+ * power management entry for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/rtc/sirfsoc_rtciobrg.h>
+#include <asm/suspend.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "pm.h"
+
+/*
+ * suspend asm codes will access these to make DRAM become self-refresh and
+ * system sleep
+ */
+u32 sirfsoc_pwrc_base;
+void __iomem *sirfsoc_memc_base;
+
+static void sirfsoc_set_wakeup_source(void)
+{
+ u32 pwr_trigger_en_reg;
+ pwr_trigger_en_reg = sirfsoc_rtc_iobrg_readl(sirfsoc_pwrc_base +
+ SIRFSOC_PWRC_TRIGGER_EN);
+#define X_ON_KEY_B (1 << 0)
+ sirfsoc_rtc_iobrg_writel(pwr_trigger_en_reg | X_ON_KEY_B,
+ sirfsoc_pwrc_base + SIRFSOC_PWRC_TRIGGER_EN);
+}
+
+static void sirfsoc_set_sleep_mode(u32 mode)
+{
+ u32 sleep_mode = sirfsoc_rtc_iobrg_readl(sirfsoc_pwrc_base +
+ SIRFSOC_PWRC_PDN_CTRL);
+ sleep_mode &= ~(SIRFSOC_SLEEP_MODE_MASK << 1);
+ sleep_mode |= mode << 1;
+ sirfsoc_rtc_iobrg_writel(sleep_mode, sirfsoc_pwrc_base +
+ SIRFSOC_PWRC_PDN_CTRL);
+}
+
+static int sirfsoc_pre_suspend_power_off(void)
+{
+ u32 wakeup_entry = virt_to_phys(cpu_resume);
+
+ sirfsoc_rtc_iobrg_writel(wakeup_entry, sirfsoc_pwrc_base +
+ SIRFSOC_PWRC_SCRATCH_PAD1);
+
+ sirfsoc_set_wakeup_source();
+
+ sirfsoc_set_sleep_mode(SIRFSOC_DEEP_SLEEP_MODE);
+
+ return 0;
+}
+
+static int sirfsoc_pm_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ sirfsoc_pre_suspend_power_off();
+
+ outer_flush_all();
+ outer_disable();
+ /* go zzz */
+ cpu_suspend(0, sirfsoc_finish_suspend);
+ l2x0_of_init(0x40000, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const struct platform_suspend_ops sirfsoc_pm_ops = {
+ .enter = sirfsoc_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init sirfsoc_pm_init(void)
+{
+ suspend_set_ops(&sirfsoc_pm_ops);
+ return 0;
+}
+late_initcall(sirfsoc_pm_init);
+
+static const struct of_device_id pwrc_ids[] = {
+ { .compatible = "sirf,prima2-pwrc" },
+ {}
+};
+
+static int __init sirfsoc_of_pwrc_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, pwrc_ids);
+ if (!np)
+ panic("unable to find compatible pwrc node in dtb\n");
+
+ /*
+ * pwrc behind rtciobrg is not located in memory space
+ * though the property is named reg. reg only means base
+ * offset for pwrc. then of_iomap is not suitable here.
+ */
+ if (of_property_read_u32(np, "reg", &sirfsoc_pwrc_base))
+ panic("unable to find base address of pwrc node in dtb\n");
+
+ of_node_put(np);
+
+ return 0;
+}
+postcore_initcall(sirfsoc_of_pwrc_init);
+
+static const struct of_device_id memc_ids[] = {
+ { .compatible = "sirf,prima2-memc" },
+ {}
+};
+
+static int __devinit sirfsoc_memc_probe(struct platform_device *op)
+{
+ struct device_node *np = op->dev.of_node;
+
+ sirfsoc_memc_base = of_iomap(np, 0);
+ if (!sirfsoc_memc_base)
+ panic("unable to map memc registers\n");
+
+ return 0;
+}
+
+static struct platform_driver sirfsoc_memc_driver = {
+ .probe = sirfsoc_memc_probe,
+ .driver = {
+ .name = "sirfsoc-memc",
+ .owner = THIS_MODULE,
+ .of_match_table = memc_ids,
+ },
+};
+
+static int __init sirfsoc_memc_init(void)
+{
+ return platform_driver_register(&sirfsoc_memc_driver);
+}
+postcore_initcall(sirfsoc_memc_init);
diff --git a/arch/arm/mach-prima2/pm.h b/arch/arm/mach-prima2/pm.h
new file mode 100644
index 0000000..aa2b428
--- /dev/null
+++ b/arch/arm/mach-prima2/pm.h
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-prima2/pm.h
+ *
+ * Copyright (C) 2011 CSR
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef _MACH_PRIMA2_PM_H_
+#define _MACH_PRIMA2_PM_H_
+
+#define SIRFSOC_PWR_SLEEPFORCE 0x01
+
+#define SIRFSOC_SLEEP_MODE_MASK 0x3
+#define SIRFSOC_DEEP_SLEEP_MODE 0x1
+
+#define SIRFSOC_PWRC_PDN_CTRL 0x0
+#define SIRFSOC_PWRC_PON_OFF 0x4
+#define SIRFSOC_PWRC_TRIGGER_EN 0x8
+#define SIRFSOC_PWRC_PIN_STATUS 0x14
+#define SIRFSOC_PWRC_SCRATCH_PAD1 0x18
+#define SIRFSOC_PWRC_SCRATCH_PAD2 0x1C
+
+#ifndef __ASSEMBLY__
+extern int sirfsoc_finish_suspend(unsigned long);
+#endif
+
+#endif
+
diff --git a/arch/arm/mach-prima2/sleep.S b/arch/arm/mach-prima2/sleep.S
new file mode 100644
index 0000000..0745abc
--- /dev/null
+++ b/arch/arm/mach-prima2/sleep.S
@@ -0,0 +1,64 @@
+/*
+ * sleep mode for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/assembler.h>
+
+#include "pm.h"
+
+#define DENALI_CTL_22_OFF 0x58
+#define DENALI_CTL_112_OFF 0x1c0
+
+ .text
+
+ENTRY(sirfsoc_finish_suspend)
+ @ r5: mem controller
+ ldr r0, =sirfsoc_memc_base
+ ldr r5, [r0]
+ @ r6: pwrc base offset
+ ldr r0, =sirfsoc_pwrc_base
+ ldr r6, [r0]
+ @ r7: rtc iobrg controller
+ ldr r0, =sirfsoc_rtciobrg_base
+ ldr r7, [r0]
+
+ @ Read the power control register and set the
+ @ sleep force bit.
+ add r0, r6, #SIRFSOC_PWRC_PDN_CTRL
+ bl __sirfsoc_rtc_iobrg_readl
+ orr r0,r0,#SIRFSOC_PWR_SLEEPFORCE
+ add r1, r6, #SIRFSOC_PWRC_PDN_CTRL
+ bl sirfsoc_rtc_iobrg_pre_writel
+ mov r1, #0x1
+
+ @ read the MEM ctl register and set the self
+ @ refresh bit
+
+ ldr r2, [r5, #DENALI_CTL_22_OFF]
+ orr r2, r2, #0x1
+
+ @ Following code has to run from cache since
+ @ the RAM is going to self refresh mode
+ .align 5
+ str r2, [r5, #DENALI_CTL_22_OFF]
+
+1:
+ ldr r4, [r5, #DENALI_CTL_112_OFF]
+ tst r4, #0x1
+ bne 1b
+
+ @ write SLEEPFORCE through rtc iobridge
+
+ str r1, [r7]
+ @ wait rtc io bridge sync
+1:
+ ldr r3, [r7]
+ tst r3, #0x01
+ bne 1b
+ b .
--
1.7.1
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 0/3] ARCH: CSR: basic PM suspend/resume support
2011-09-13 10:06 [PATCH 0/3] ARCH: CSR: basic PM suspend/resume support Barry Song
` (2 preceding siblings ...)
2011-09-13 10:06 ` [PATCH 3/3] ARM: CSR: PM: add sleep entry for SiRFprimaII Barry Song
@ 2011-09-13 16:11 ` Arnd Bergmann
2011-09-14 1:37 ` Barry Song
3 siblings, 1 reply; 6+ messages in thread
From: Arnd Bergmann @ 2011-09-13 16:11 UTC (permalink / raw)
To: linux-arm-kernel
On Tuesday 13 September 2011, Barry Song wrote:
>
> it was in thread "ARM: CSR: add rtciobrg and PM support" before. See:
> http://www.spinics.net/lists/arm-kernel/msg137375.html
>
> Arnd has pulled rtciobrg into arm-soc next branch. PM should be another
> series.
Looks good to me, feel free to add my Acked-by to the patches, but
please add a meaningful changelog text to each patch first.
You can use some of the text that you put in the introductory mail.
In general, I expect even trivial patches to have a changelog of
one sentence and more text if the patch touches more code.
If nobody has other comments on the code, please send me a pull
request once that is done.
Arnd
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 0/3] ARCH: CSR: basic PM suspend/resume support
2011-09-13 16:11 ` [PATCH 0/3] ARCH: CSR: basic PM suspend/resume support Arnd Bergmann
@ 2011-09-14 1:37 ` Barry Song
0 siblings, 0 replies; 6+ messages in thread
From: Barry Song @ 2011-09-14 1:37 UTC (permalink / raw)
To: linux-arm-kernel
Hi Arnd,
Thanks!
2011/9/14 Arnd Bergmann <arnd@arndb.de>:
> On Tuesday 13 September 2011, Barry Song wrote:
>>
>> it was in thread "ARM: CSR: add rtciobrg and PM support" before. See:
>> http://www.spinics.net/lists/arm-kernel/msg137375.html
>>
>> Arnd has pulled rtciobrg into arm-soc next branch. PM should be another
>> series.
>
> Looks good to me, feel free to add my Acked-by to the patches, but
> please add a meaningful changelog text to each patch first.
> You can use some of the text that you put in the introductory mail.
>
ok. i will. and thanks.
> In general, I expect even trivial patches to have a changelog of
> one sentence and more text if the patch touches more code.
make sense.
>
> If nobody has other comments on the code, please send me a pull
> request once that is done.
a problem is patch 3/3 depends on Shawn Guo <shawn.guo@linaro.org>'s
[PATCH v2 1/2] ARM: cache-l2x0: remove __init annotation from
initialization functions
http://www.spinics.net/lists/arm-kernel/msg139198.html
it seems Russell hasn't given feedback yet. i am not sure Russell's
opinion about how to suspend/resume l2 for SoCs whose l2 cache will
lose in suspend cycle. in my opinion, a complete re-init is simplest.
For imx6q and omap who will not lose l2 in suspend cycle, Russell sent
a patchset about suspend and required l2 re-enabled before cpu_resume
by omap/imx6q platform-specific codes.
>
> ? ? ? ?Arnd
Thanks
barry
^ permalink raw reply [flat|nested] 6+ messages in thread