diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-shmobile/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/common.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/r8a7791.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/platsmp-apmu.c | 60 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pm-r8a7791.c | 47 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/rcar-gen2.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-r8a7790.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-r8a7791.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-rcar-gen2.c | 72 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/smp-r8a7790.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/smp-r8a7791.c | 3 |
12 files changed, 189 insertions, 4 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 5ec9c3855624..4508643cca32 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
@@ -12,6 +12,7 @@ menuconfig ARCH_SHMOBILE_MULTI | |||
12 | select NO_IOPORT_MAP | 12 | select NO_IOPORT_MAP |
13 | select PINCTRL | 13 | select PINCTRL |
14 | select ARCH_REQUIRE_GPIOLIB | 14 | select ARCH_REQUIRE_GPIOLIB |
15 | select ARCH_HAS_OPP | ||
15 | 16 | ||
16 | if ARCH_SHMOBILE_MULTI | 17 | if ARCH_SHMOBILE_MULTI |
17 | 18 | ||
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index d4fd9a98242e..ccb056327fd4 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile | |||
@@ -54,6 +54,7 @@ obj-$(CONFIG_ARCH_SH73A0) += pm-sh73a0.o | |||
54 | obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o pm-rmobile.o | 54 | obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o pm-rmobile.o |
55 | obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o pm-rcar.o | 55 | obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o pm-rcar.o |
56 | obj-$(CONFIG_ARCH_R8A7790) += pm-r8a7790.o pm-rcar.o | 56 | obj-$(CONFIG_ARCH_R8A7790) += pm-r8a7790.o pm-rcar.o |
57 | obj-$(CONFIG_ARCH_R8A7791) += pm-r8a7791.o pm-rcar.o | ||
57 | 58 | ||
58 | # Board objects | 59 | # Board objects |
59 | ifdef CONFIG_ARCH_SHMOBILE_MULTI | 60 | ifdef CONFIG_ARCH_SHMOBILE_MULTI |
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index 921a18ef4dfe..98056081f0da 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h | |||
@@ -35,8 +35,10 @@ extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv); | |||
35 | 35 | ||
36 | #ifdef CONFIG_SUSPEND | 36 | #ifdef CONFIG_SUSPEND |
37 | int shmobile_suspend_init(void); | 37 | int shmobile_suspend_init(void); |
38 | void shmobile_smp_apmu_suspend_init(void); | ||
38 | #else | 39 | #else |
39 | static inline int shmobile_suspend_init(void) { return 0; } | 40 | static inline int shmobile_suspend_init(void) { return 0; } |
41 | static inline void shmobile_smp_apmu_suspend_init(void) { } | ||
40 | #endif | 42 | #endif |
41 | 43 | ||
42 | #ifdef CONFIG_CPU_IDLE | 44 | #ifdef CONFIG_CPU_IDLE |
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h index 664274cc4b64..86eae7bceb6f 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7791.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h | |||
@@ -5,6 +5,7 @@ void r8a7791_add_standard_devices(void); | |||
5 | void r8a7791_add_dt_devices(void); | 5 | void r8a7791_add_dt_devices(void); |
6 | void r8a7791_clock_init(void); | 6 | void r8a7791_clock_init(void); |
7 | void r8a7791_pinmux_init(void); | 7 | void r8a7791_pinmux_init(void); |
8 | void r8a7791_pm_init(void); | ||
8 | extern struct smp_operations r8a7791_smp_ops; | 9 | extern struct smp_operations r8a7791_smp_ops; |
9 | 10 | ||
10 | #endif /* __ASM_R8A7791_H__ */ | 11 | #endif /* __ASM_R8A7791_H__ */ |
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c index fe648f5d8f06..590e35c22a60 100644 --- a/arch/arm/mach-shmobile/platsmp-apmu.c +++ b/arch/arm/mach-shmobile/platsmp-apmu.c | |||
@@ -7,15 +7,19 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/cpu_pm.h> | ||
10 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/io.h> | 13 | #include <linux/io.h> |
13 | #include <linux/ioport.h> | 14 | #include <linux/ioport.h> |
14 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
15 | #include <linux/smp.h> | 16 | #include <linux/smp.h> |
17 | #include <linux/suspend.h> | ||
16 | #include <asm/cacheflush.h> | 18 | #include <asm/cacheflush.h> |
17 | #include <asm/cp15.h> | 19 | #include <asm/cp15.h> |
20 | #include <asm/proc-fns.h> | ||
18 | #include <asm/smp_plat.h> | 21 | #include <asm/smp_plat.h> |
22 | #include <asm/suspend.h> | ||
19 | #include "common.h" | 23 | #include "common.h" |
20 | 24 | ||
21 | static struct { | 25 | static struct { |
@@ -141,7 +145,7 @@ int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
141 | return apmu_wrap(cpu, apmu_power_on); | 145 | return apmu_wrap(cpu, apmu_power_on); |
142 | } | 146 | } |
143 | 147 | ||
144 | #ifdef CONFIG_HOTPLUG_CPU | 148 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND) |
145 | /* nicked from arch/arm/mach-exynos/hotplug.c */ | 149 | /* nicked from arch/arm/mach-exynos/hotplug.c */ |
146 | static inline void cpu_enter_lowpower_a15(void) | 150 | static inline void cpu_enter_lowpower_a15(void) |
147 | { | 151 | { |
@@ -172,16 +176,40 @@ static inline void cpu_enter_lowpower_a15(void) | |||
172 | dsb(); | 176 | dsb(); |
173 | } | 177 | } |
174 | 178 | ||
175 | void shmobile_smp_apmu_cpu_die(unsigned int cpu) | 179 | void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu) |
176 | { | 180 | { |
177 | /* For this particular CPU deregister boot vector */ | ||
178 | shmobile_smp_hook(cpu, 0, 0); | ||
179 | 181 | ||
180 | /* Select next sleep mode using the APMU */ | 182 | /* Select next sleep mode using the APMU */ |
181 | apmu_wrap(cpu, apmu_power_off); | 183 | apmu_wrap(cpu, apmu_power_off); |
182 | 184 | ||
183 | /* Do ARM specific CPU shutdown */ | 185 | /* Do ARM specific CPU shutdown */ |
184 | cpu_enter_lowpower_a15(); | 186 | cpu_enter_lowpower_a15(); |
187 | } | ||
188 | |||
189 | static inline void cpu_leave_lowpower(void) | ||
190 | { | ||
191 | unsigned int v; | ||
192 | |||
193 | asm volatile("mrc p15, 0, %0, c1, c0, 0\n" | ||
194 | " orr %0, %0, %1\n" | ||
195 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
196 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
197 | " orr %0, %0, %2\n" | ||
198 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
199 | : "=&r" (v) | ||
200 | : "Ir" (CR_C), "Ir" (0x40) | ||
201 | : "cc"); | ||
202 | } | ||
203 | #endif | ||
204 | |||
205 | #if defined(CONFIG_HOTPLUG_CPU) | ||
206 | void shmobile_smp_apmu_cpu_die(unsigned int cpu) | ||
207 | { | ||
208 | /* For this particular CPU deregister boot vector */ | ||
209 | shmobile_smp_hook(cpu, 0, 0); | ||
210 | |||
211 | /* Shutdown CPU core */ | ||
212 | shmobile_smp_apmu_cpu_shutdown(cpu); | ||
185 | 213 | ||
186 | /* jump to shared mach-shmobile sleep / reset code */ | 214 | /* jump to shared mach-shmobile sleep / reset code */ |
187 | shmobile_smp_sleep(); | 215 | shmobile_smp_sleep(); |
@@ -192,3 +220,27 @@ int shmobile_smp_apmu_cpu_kill(unsigned int cpu) | |||
192 | return apmu_wrap(cpu, apmu_power_off_poll); | 220 | return apmu_wrap(cpu, apmu_power_off_poll); |
193 | } | 221 | } |
194 | #endif | 222 | #endif |
223 | |||
224 | #if defined(CONFIG_SUSPEND) | ||
225 | static int shmobile_smp_apmu_do_suspend(unsigned long cpu) | ||
226 | { | ||
227 | shmobile_smp_hook(cpu, virt_to_phys(cpu_resume), 0); | ||
228 | shmobile_smp_apmu_cpu_shutdown(cpu); | ||
229 | cpu_do_idle(); /* WFI selects Core Standby */ | ||
230 | return 1; | ||
231 | } | ||
232 | |||
233 | static int shmobile_smp_apmu_enter_suspend(suspend_state_t state) | ||
234 | { | ||
235 | cpu_suspend(smp_processor_id(), shmobile_smp_apmu_do_suspend); | ||
236 | cpu_leave_lowpower(); | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | void shmobile_smp_apmu_suspend_init(void) | ||
241 | { | ||
242 | shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend; | ||
243 | } | ||
244 | #else | ||
245 | void shmobile_smp_apmu_suspend_init(void) {} | ||
246 | #endif | ||
diff --git a/arch/arm/mach-shmobile/pm-r8a7791.c b/arch/arm/mach-shmobile/pm-r8a7791.c new file mode 100644 index 000000000000..15190875d507 --- /dev/null +++ b/arch/arm/mach-shmobile/pm-r8a7791.c | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * r8a7791 Power management support | ||
3 | * | ||
4 | * Copyright (C) 2014 Renesas Electronics Corporation | ||
5 | * Copyright (C) 2011 Renesas Solutions Corp. | ||
6 | * Copyright (C) 2011 Magnus Damm | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | |||
13 | #include <asm/io.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <mach/r8a7791.h> | ||
16 | #include "pm-rcar.h" | ||
17 | |||
18 | /* SYSC */ | ||
19 | #define SYSCIER 0x0c | ||
20 | #define SYSCIMR 0x10 | ||
21 | |||
22 | #if defined(CONFIG_SMP) | ||
23 | |||
24 | static void __init r8a7791_sysc_init(void) | ||
25 | { | ||
26 | void __iomem *base = rcar_sysc_init(0xe6180000); | ||
27 | |||
28 | /* enable all interrupt sources, but do not use interrupt handler */ | ||
29 | iowrite32(0x0131000e, base + SYSCIER); | ||
30 | iowrite32(0, base + SYSCIMR); | ||
31 | } | ||
32 | |||
33 | #else /* CONFIG_SMP */ | ||
34 | |||
35 | static inline void r8a7791_sysc_init(void) {} | ||
36 | |||
37 | #endif /* CONFIG_SMP */ | ||
38 | |||
39 | void __init r8a7791_pm_init(void) | ||
40 | { | ||
41 | static int once; | ||
42 | |||
43 | if (once++) | ||
44 | return; | ||
45 | |||
46 | r8a7791_sysc_init(); | ||
47 | } | ||
diff --git a/arch/arm/mach-shmobile/rcar-gen2.h b/arch/arm/mach-shmobile/rcar-gen2.h index 43f606eb2d82..ce53cb5f53a1 100644 --- a/arch/arm/mach-shmobile/rcar-gen2.h +++ b/arch/arm/mach-shmobile/rcar-gen2.h | |||
@@ -4,5 +4,6 @@ | |||
4 | void rcar_gen2_timer_init(void); | 4 | void rcar_gen2_timer_init(void); |
5 | #define MD(nr) BIT(nr) | 5 | #define MD(nr) BIT(nr) |
6 | u32 rcar_gen2_read_mode_pins(void); | 6 | u32 rcar_gen2_read_mode_pins(void); |
7 | void rcar_gen2_reserve(void); | ||
7 | 8 | ||
8 | #endif /* __ASM_RCAR_GEN2_H__ */ | 9 | #endif /* __ASM_RCAR_GEN2_H__ */ |
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 4212c8de987a..e1907686ace4 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c | |||
@@ -326,6 +326,8 @@ DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") | |||
326 | .smp = smp_ops(r8a7790_smp_ops), | 326 | .smp = smp_ops(r8a7790_smp_ops), |
327 | .init_early = r8a7790_init_early, | 327 | .init_early = r8a7790_init_early, |
328 | .init_time = rcar_gen2_timer_init, | 328 | .init_time = rcar_gen2_timer_init, |
329 | .init_late = shmobile_init_late, | ||
330 | .reserve = rcar_gen2_reserve, | ||
329 | .dt_compat = r8a7790_boards_compat_dt, | 331 | .dt_compat = r8a7790_boards_compat_dt, |
330 | MACHINE_END | 332 | MACHINE_END |
331 | #endif /* CONFIG_USE_OF */ | 333 | #endif /* CONFIG_USE_OF */ |
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c index f554cda4a96a..7e970d005f7f 100644 --- a/arch/arm/mach-shmobile/setup-r8a7791.c +++ b/arch/arm/mach-shmobile/setup-r8a7791.c | |||
@@ -217,6 +217,8 @@ DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") | |||
217 | .smp = smp_ops(r8a7791_smp_ops), | 217 | .smp = smp_ops(r8a7791_smp_ops), |
218 | .init_early = shmobile_init_delay, | 218 | .init_early = shmobile_init_delay, |
219 | .init_time = rcar_gen2_timer_init, | 219 | .init_time = rcar_gen2_timer_init, |
220 | .init_late = shmobile_init_late, | ||
221 | .reserve = rcar_gen2_reserve, | ||
220 | .dt_compat = r8a7791_boards_compat_dt, | 222 | .dt_compat = r8a7791_boards_compat_dt, |
221 | MACHINE_END | 223 | MACHINE_END |
222 | #endif /* CONFIG_USE_OF */ | 224 | #endif /* CONFIG_USE_OF */ |
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index fdc714ebc4cd..42d5b4308923 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c | |||
@@ -20,8 +20,11 @@ | |||
20 | 20 | ||
21 | #include <linux/clk/shmobile.h> | 21 | #include <linux/clk/shmobile.h> |
22 | #include <linux/clocksource.h> | 22 | #include <linux/clocksource.h> |
23 | #include <linux/device.h> | ||
24 | #include <linux/dma-contiguous.h> | ||
23 | #include <linux/io.h> | 25 | #include <linux/io.h> |
24 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/of_fdt.h> | ||
25 | #include <asm/mach/arch.h> | 28 | #include <asm/mach/arch.h> |
26 | #include "common.h" | 29 | #include "common.h" |
27 | #include "rcar-gen2.h" | 30 | #include "rcar-gen2.h" |
@@ -110,3 +113,72 @@ void __init rcar_gen2_timer_init(void) | |||
110 | #endif | 113 | #endif |
111 | clocksource_of_init(); | 114 | clocksource_of_init(); |
112 | } | 115 | } |
116 | |||
117 | struct memory_reserve_config { | ||
118 | u64 reserved; | ||
119 | u64 base, size; | ||
120 | }; | ||
121 | |||
122 | static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname, | ||
123 | int depth, void *data) | ||
124 | { | ||
125 | const char *type = of_get_flat_dt_prop(node, "device_type", NULL); | ||
126 | const __be32 *reg, *endp; | ||
127 | int l; | ||
128 | struct memory_reserve_config *mrc = data; | ||
129 | u64 lpae_start = 1ULL << 32; | ||
130 | |||
131 | /* We are scanning "memory" nodes only */ | ||
132 | if (type == NULL || strcmp(type, "memory")) | ||
133 | return 0; | ||
134 | |||
135 | reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); | ||
136 | if (reg == NULL) | ||
137 | reg = of_get_flat_dt_prop(node, "reg", &l); | ||
138 | if (reg == NULL) | ||
139 | return 0; | ||
140 | |||
141 | endp = reg + (l / sizeof(__be32)); | ||
142 | while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { | ||
143 | u64 base, size; | ||
144 | |||
145 | base = dt_mem_next_cell(dt_root_addr_cells, ®); | ||
146 | size = dt_mem_next_cell(dt_root_size_cells, ®); | ||
147 | |||
148 | if (base >= lpae_start) | ||
149 | continue; | ||
150 | |||
151 | if ((base + size) >= lpae_start) | ||
152 | size = lpae_start - base; | ||
153 | |||
154 | if (size < mrc->reserved) | ||
155 | continue; | ||
156 | |||
157 | if (base < mrc->base) | ||
158 | continue; | ||
159 | |||
160 | /* keep the area at top near the 32-bit legacy limit */ | ||
161 | mrc->base = base + size - mrc->reserved; | ||
162 | mrc->size = mrc->reserved; | ||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | struct cma *rcar_gen2_dma_contiguous; | ||
169 | |||
170 | void __init rcar_gen2_reserve(void) | ||
171 | { | ||
172 | struct memory_reserve_config mrc; | ||
173 | |||
174 | /* reserve 256 MiB at the top of the physical legacy 32-bit space */ | ||
175 | memset(&mrc, 0, sizeof(mrc)); | ||
176 | mrc.reserved = SZ_256M; | ||
177 | |||
178 | of_scan_flat_dt(rcar_gen2_scan_mem, &mrc); | ||
179 | #ifdef CONFIG_DMA_CMA | ||
180 | if (mrc.size) | ||
181 | dma_contiguous_reserve_area(mrc.size, mrc.base, 0, | ||
182 | &rcar_gen2_dma_contiguous, true); | ||
183 | #endif | ||
184 | } | ||
diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c index a8ace58c3dd2..7590e2b6e2fa 100644 --- a/arch/arm/mach-shmobile/smp-r8a7790.c +++ b/arch/arm/mach-shmobile/smp-r8a7790.c | |||
@@ -69,6 +69,7 @@ static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) | |||
69 | 69 | ||
70 | /* turn on power to SCU */ | 70 | /* turn on power to SCU */ |
71 | r8a7790_pm_init(); | 71 | r8a7790_pm_init(); |
72 | shmobile_smp_apmu_suspend_init(); | ||
72 | rcar_sysc_power_up(&r8a7790_ca15_scu); | 73 | rcar_sysc_power_up(&r8a7790_ca15_scu); |
73 | rcar_sysc_power_up(&r8a7790_ca7_scu); | 74 | rcar_sysc_power_up(&r8a7790_ca7_scu); |
74 | } | 75 | } |
diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c index 2648d68650e4..c6543b6ec759 100644 --- a/arch/arm/mach-shmobile/smp-r8a7791.c +++ b/arch/arm/mach-shmobile/smp-r8a7791.c | |||
@@ -50,6 +50,9 @@ static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) | |||
50 | writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, | 50 | writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, |
51 | p + CA15RESCNT); | 51 | p + CA15RESCNT); |
52 | iounmap(p); | 52 | iounmap(p); |
53 | |||
54 | r8a7791_pm_init(); | ||
55 | shmobile_smp_apmu_suspend_init(); | ||
53 | } | 56 | } |
54 | 57 | ||
55 | static int r8a7791_smp_boot_secondary(unsigned int cpu, | 58 | static int r8a7791_smp_boot_secondary(unsigned int cpu, |