diff options
author | Ezequiel Garcia <ezequiel.garcia@free-electrons.com> | 2013-08-22 11:49:07 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2013-10-08 11:41:52 -0400 |
commit | e1cb367de27ca5c186b0f120c3c10a4a0e8edd2e (patch) | |
tree | aed853fb2fa315698ca5ff56a932dfbe7389b4f6 /arch/arm/mach-kirkwood | |
parent | 272b98c6455f00884f0350f775c5342358ebb73f (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/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/board-dt.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/common.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/common.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/pm.c | 73 |
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 @@ | |||
1 | obj-y += common.o pcie.o | 1 | obj-y += common.o pcie.o |
2 | obj-$(CONFIG_KIRKWOOD_LEGACY) += irq.o mpp.o | 2 | obj-$(CONFIG_KIRKWOOD_LEGACY) += irq.o mpp.o |
3 | obj-$(CONFIG_PM) += pm.o | ||
4 | |||
3 | obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o | 5 | obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o |
4 | obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o | 6 | obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o |
5 | obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o | 7 | obj-$(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); | |||
58 | void kirkwood_restart(enum reboot_mode, const char *); | 58 | void kirkwood_restart(enum reboot_mode, const char *); |
59 | void kirkwood_clk_init(void); | 59 | void kirkwood_clk_init(void); |
60 | 60 | ||
61 | #ifdef CONFIG_PM | ||
62 | void kirkwood_pm_init(void); | ||
63 | #else | ||
64 | static 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 |
63 | void mv88f6281gtw_ge_init(void); | 69 | void 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 | |||
22 | static void __iomem *ddr_operation_base; | ||
23 | |||
24 | static 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 | |||
46 | static 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 | |||
58 | static int kirkwood_pm_valid_standby(suspend_state_t state) | ||
59 | { | ||
60 | return state == PM_SUSPEND_STANDBY; | ||
61 | } | ||
62 | |||
63 | static const struct platform_suspend_ops kirkwood_suspend_ops = { | ||
64 | .enter = kirkwood_suspend_enter, | ||
65 | .valid = kirkwood_pm_valid_standby, | ||
66 | }; | ||
67 | |||
68 | int __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 | } | ||