aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-kirkwood
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel.garcia@free-electrons.com>2013-08-22 11:49:07 -0400
committerJason Cooper <jason@lakedaemon.net>2013-10-08 11:41:52 -0400
commite1cb367de27ca5c186b0f120c3c10a4a0e8edd2e (patch)
treeaed853fb2fa315698ca5ff56a932dfbe7389b4f6 /arch/arm/mach-kirkwood
parent272b98c6455f00884f0350f775c5342358ebb73f (diff)
ARM: kirkwood: Add standby support
Implements standby support for Kirkwood SoC. When the SoC enters standby state the memory PM units are disabled, the DDR is set in self-refresh mode, and the CPU is set in WFI. At this point there's no clock gating, as that is considered each driver's task. Signed-off-by: Simon Guinot <sguinot@lacie.com> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'arch/arm/mach-kirkwood')
-rw-r--r--arch/arm/mach-kirkwood/Makefile2
-rw-r--r--arch/arm/mach-kirkwood/board-dt.c1
-rw-r--r--arch/arm/mach-kirkwood/common.c1
-rw-r--r--arch/arm/mach-kirkwood/common.h6
-rw-r--r--arch/arm/mach-kirkwood/include/mach/bridge-regs.h2
-rw-r--r--arch/arm/mach-kirkwood/pm.c73
6 files changed, 85 insertions, 0 deletions
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index d1f8e3d0793b..144b51102939 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -1,5 +1,7 @@
1obj-y += common.o pcie.o 1obj-y += common.o pcie.o
2obj-$(CONFIG_KIRKWOOD_LEGACY) += irq.o mpp.o 2obj-$(CONFIG_KIRKWOOD_LEGACY) += irq.o mpp.o
3obj-$(CONFIG_PM) += pm.o
4
3obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o 5obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o
4obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o 6obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
5obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o 7obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 82d3ad8e87cf..cdde73a07c1b 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -101,6 +101,7 @@ static void __init kirkwood_dt_init(void)
101 /* Setup clocks for legacy devices */ 101 /* Setup clocks for legacy devices */
102 kirkwood_legacy_clk_init(); 102 kirkwood_legacy_clk_init();
103 103
104 kirkwood_pm_init();
104 kirkwood_cpuidle_init(); 105 kirkwood_cpuidle_init();
105 106
106#ifdef CONFIG_KEXEC 107#ifdef CONFIG_KEXEC
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 176761134a66..f3407a5db216 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -721,6 +721,7 @@ void __init kirkwood_init(void)
721 kirkwood_xor1_init(); 721 kirkwood_xor1_init();
722 kirkwood_crypto_init(); 722 kirkwood_crypto_init();
723 723
724 kirkwood_pm_init();
724 kirkwood_cpuidle_init(); 725 kirkwood_cpuidle_init();
725#ifdef CONFIG_KEXEC 726#ifdef CONFIG_KEXEC
726 kexec_reinit = kirkwood_enable_pcie; 727 kexec_reinit = kirkwood_enable_pcie;
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 1296de94febf..05fd648df543 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -58,6 +58,12 @@ void kirkwood_cpufreq_init(void);
58void kirkwood_restart(enum reboot_mode, const char *); 58void kirkwood_restart(enum reboot_mode, const char *);
59void kirkwood_clk_init(void); 59void kirkwood_clk_init(void);
60 60
61#ifdef CONFIG_PM
62void kirkwood_pm_init(void);
63#else
64static inline void kirkwood_pm_init(void) {};
65#endif
66
61/* board init functions for boards not fully converted to fdt */ 67/* board init functions for boards not fully converted to fdt */
62#ifdef CONFIG_MACH_MV88F6281GTW_GE_DT 68#ifdef CONFIG_MACH_MV88F6281GTW_GE_DT
63void mv88f6281gtw_ge_init(void); 69void mv88f6281gtw_ge_init(void);
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
index 91242c944d7a..8b9d1c9ff199 100644
--- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -78,4 +78,6 @@
78#define CGC_TDM (1 << 20) 78#define CGC_TDM (1 << 20)
79#define CGC_RESERVED (0x6 << 21) 79#define CGC_RESERVED (0x6 << 21)
80 80
81#define MEMORY_PM_CTRL (BRIDGE_VIRT_BASE + 0x118)
82
81#endif 83#endif
diff --git a/arch/arm/mach-kirkwood/pm.c b/arch/arm/mach-kirkwood/pm.c
new file mode 100644
index 000000000000..8783a7184e73
--- /dev/null
+++ b/arch/arm/mach-kirkwood/pm.c
@@ -0,0 +1,73 @@
1/*
2 * Power Management driver for Marvell Kirkwood SoCs
3 *
4 * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
5 * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License,
9 * version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/kernel.h>
18#include <linux/suspend.h>
19#include <linux/io.h>
20#include <mach/bridge-regs.h>
21
22static void __iomem *ddr_operation_base;
23
24static void kirkwood_low_power(void)
25{
26 u32 mem_pm_ctrl;
27
28 mem_pm_ctrl = readl(MEMORY_PM_CTRL);
29
30 /* Set peripherals to low-power mode */
31 writel_relaxed(~0, MEMORY_PM_CTRL);
32
33 /* Set DDR in self-refresh */
34 writel_relaxed(0x7, ddr_operation_base);
35
36 /*
37 * Set CPU in wait-for-interrupt state.
38 * This disables the CPU core clocks,
39 * the array clocks, and also the L2 controller.
40 */
41 cpu_do_idle();
42
43 writel_relaxed(mem_pm_ctrl, MEMORY_PM_CTRL);
44}
45
46static int kirkwood_suspend_enter(suspend_state_t state)
47{
48 switch (state) {
49 case PM_SUSPEND_STANDBY:
50 kirkwood_low_power();
51 break;
52 default:
53 return -EINVAL;
54 }
55 return 0;
56}
57
58static int kirkwood_pm_valid_standby(suspend_state_t state)
59{
60 return state == PM_SUSPEND_STANDBY;
61}
62
63static const struct platform_suspend_ops kirkwood_suspend_ops = {
64 .enter = kirkwood_suspend_enter,
65 .valid = kirkwood_pm_valid_standby,
66};
67
68int __init kirkwood_pm_init(void)
69{
70 ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
71 suspend_set_ops(&kirkwood_suspend_ops);
72 return 0;
73}