Branch data Line data Source code
1 : : /*
2 : : * arch/arm/mach-vexpress/tc2_pm.c - TC2 power management support
3 : : *
4 : : * Created by: Nicolas Pitre, October 2012
5 : : * Copyright: (C) 2012-2013 Linaro Limited
6 : : *
7 : : * Some portions of this file were originally written by Achin Gupta
8 : : * Copyright: (C) 2012 ARM Limited
9 : : *
10 : : * This program is free software; you can redistribute it and/or modify
11 : : * it under the terms of the GNU General Public License version 2 as
12 : : * published by the Free Software Foundation.
13 : : */
14 : :
15 : : #include <linux/delay.h>
16 : : #include <linux/init.h>
17 : : #include <linux/io.h>
18 : : #include <linux/kernel.h>
19 : : #include <linux/of_address.h>
20 : : #include <linux/of_irq.h>
21 : : #include <linux/spinlock.h>
22 : : #include <linux/errno.h>
23 : : #include <linux/irqchip/arm-gic.h>
24 : :
25 : : #include <asm/mcpm.h>
26 : : #include <asm/proc-fns.h>
27 : : #include <asm/cacheflush.h>
28 : : #include <asm/cputype.h>
29 : : #include <asm/cp15.h>
30 : : #include <asm/psci.h>
31 : :
32 : : #include <linux/arm-cci.h>
33 : :
34 : : #include "spc.h"
35 : :
36 : : /* SCC conf registers */
37 : : #define RESET_CTRL 0x018
38 : : #define RESET_A15_NCORERESET(cpu) (1 << (2 + (cpu)))
39 : : #define RESET_A7_NCORERESET(cpu) (1 << (16 + (cpu)))
40 : :
41 : : #define A15_CONF 0x400
42 : : #define A7_CONF 0x500
43 : : #define SYS_INFO 0x700
44 : : #define SPC_BASE 0xb00
45 : :
46 : : static void __iomem *scc;
47 : :
48 : : /*
49 : : * We can't use regular spinlocks. In the switcher case, it is possible
50 : : * for an outbound CPU to call power_down() after its inbound counterpart
51 : : * is already live using the same logical CPU number which trips lockdep
52 : : * debugging.
53 : : */
54 : : static arch_spinlock_t tc2_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
55 : :
56 : : #define TC2_CLUSTERS 2
57 : : #define TC2_MAX_CPUS_PER_CLUSTER 3
58 : :
59 : : static unsigned int tc2_nr_cpus[TC2_CLUSTERS];
60 : :
61 : : /* Keep per-cpu usage count to cope with unordered up/down requests */
62 : : static int tc2_pm_use_count[TC2_MAX_CPUS_PER_CLUSTER][TC2_CLUSTERS];
63 : :
64 : : #define tc2_cluster_unused(cluster) \
65 : : (!tc2_pm_use_count[0][cluster] && \
66 : : !tc2_pm_use_count[1][cluster] && \
67 : : !tc2_pm_use_count[2][cluster])
68 : :
69 : 0 : static int tc2_pm_power_up(unsigned int cpu, unsigned int cluster)
70 : : {
71 : : pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
72 [ + + ][ + ]: 4877 : if (cluster >= TC2_CLUSTERS || cpu >= tc2_nr_cpus[cluster])
73 : : return -EINVAL;
74 : :
75 : : /*
76 : : * Since this is called with IRQs enabled, and no arch_spin_lock_irq
77 : : * variant exists, we need to disable IRQs manually here.
78 : : */
79 : : local_irq_disable();
80 : : arch_spin_lock(&tc2_pm_lock);
81 : :
82 [ + + ][ + + ]: 4878 : if (tc2_cluster_unused(cluster))
[ + - ]
83 : 3678 : ve_spc_powerdown(cluster, false);
84 : :
85 : 4878 : tc2_pm_use_count[cpu][cluster]++;
86 [ + - ]: 4878 : if (tc2_pm_use_count[cpu][cluster] == 1) {
87 : 4878 : ve_spc_set_resume_addr(cluster, cpu,
88 : : virt_to_phys(mcpm_entry_point));
89 : 4878 : ve_spc_cpu_wakeup_irq(cluster, cpu, true);
90 [ # # ]: 0 : } else if (tc2_pm_use_count[cpu][cluster] != 2) {
91 : : /*
92 : : * The only possible values are:
93 : : * 0 = CPU down
94 : : * 1 = CPU (still) up
95 : : * 2 = CPU requested to be up before it had a chance
96 : : * to actually make itself down.
97 : : * Any other value is a bug.
98 : : */
99 : 0 : BUG();
100 : : }
101 : :
102 : : arch_spin_unlock(&tc2_pm_lock);
103 : : local_irq_enable();
104 : :
105 : 4878 : return 0;
106 : : }
107 : :
108 : 0 : static void tc2_pm_down(u64 residency)
109 : : {
110 : : unsigned int mpidr, cpu, cluster;
111 : : bool last_man = false, skip_wfi = false;
112 : :
113 : : mpidr = read_cpuid_mpidr();
114 : 1200195 : cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
115 : 1200195 : cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
116 : :
117 : : pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
118 [ - + ]: 1200195 : BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
119 : :
120 : 1200195 : __mcpm_cpu_going_down(cpu, cluster);
121 : :
122 : : arch_spin_lock(&tc2_pm_lock);
123 [ - + ]: 1200197 : BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP);
124 : 1200197 : tc2_pm_use_count[cpu][cluster]--;
125 [ + - ]: 1200197 : if (tc2_pm_use_count[cpu][cluster] == 0) {
126 : 1200197 : ve_spc_cpu_wakeup_irq(cluster, cpu, true);
127 [ + + ][ + + ]: 1200197 : if (tc2_cluster_unused(cluster)) {
[ + - ]
128 : 767476 : ve_spc_powerdown(cluster, true);
129 : 767476 : ve_spc_global_wakeup_irq(true);
130 : : last_man = true;
131 : : }
132 [ # # ]: 0 : } else if (tc2_pm_use_count[cpu][cluster] == 1) {
133 : : /*
134 : : * A power_up request went ahead of us.
135 : : * Even if we do not want to shut this CPU down,
136 : : * the caller expects a certain state as if the WFI
137 : : * was aborted. So let's continue with cache cleaning.
138 : : */
139 : : skip_wfi = true;
140 : : } else
141 : 0 : BUG();
142 : :
143 : : /*
144 : : * If the CPU is committed to power down, make sure
145 : : * the power controller will be in charge of waking it
146 : : * up upon IRQ, ie IRQ lines are cut from GIC CPU IF
147 : : * to the CPU by disabling the GIC CPU IF to prevent wfi
148 : : * from completing execution behind power controller back
149 : : */
150 [ + - ]: 2400392 : if (!skip_wfi)
151 : 1200197 : gic_cpu_if_down();
152 : :
153 [ + + ][ + + ]: 1200197 : if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) {
154 : : arch_spin_unlock(&tc2_pm_lock);
155 : :
156 [ + + ]: 764228 : if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A15) {
157 : : /*
158 : : * On the Cortex-A15 we need to disable
159 : : * L2 prefetching before flushing the cache.
160 : : */
161 : 152996 : asm volatile(
162 : : "mcr p15, 1, %0, c15, c0, 3 \n\t"
163 : : "isb \n\t"
164 : : "dsb "
165 : : : : "r" (0x400) );
166 : : }
167 : :
168 : 764228 : v7_exit_coherency_flush(all);
169 : :
170 : 764226 : cci_disable_port_by_cpu(mpidr);
171 : :
172 : 764224 : __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN);
173 : : } else {
174 : : /*
175 : : * If last man then undo any setup done previously.
176 : : */
177 [ + + ]: 435969 : if (last_man) {
178 : 3248 : ve_spc_powerdown(cluster, false);
179 : 3248 : ve_spc_global_wakeup_irq(false);
180 : : }
181 : :
182 : : arch_spin_unlock(&tc2_pm_lock);
183 : :
184 : 435969 : v7_exit_coherency_flush(louis);
185 : : }
186 : :
187 : 1200193 : __mcpm_cpu_down(cpu, cluster);
188 : :
189 : : /* Now we are prepared for power-down, do it: */
190 [ + + ]: 1200193 : if (!skip_wfi)
191 : 1200191 : wfi();
192 : :
193 : : /* Not dead at this point? Let our caller cope. */
194 : 2 : }
195 : :
196 : 0 : static void tc2_pm_power_down(void)
197 : : {
198 : 4878 : tc2_pm_down(0);
199 : 0 : }
200 : :
201 : : static int tc2_core_in_reset(unsigned int cpu, unsigned int cluster)
202 : : {
203 [ # # ]: 0 : u32 mask = cluster ?
204 : 0 : RESET_A7_NCORERESET(cpu)
205 : 0 : : RESET_A15_NCORERESET(cpu);
206 : :
207 : 0 : return !(readl_relaxed(scc + RESET_CTRL) & mask);
208 : : }
209 : :
210 : : #define POLL_MSEC 10
211 : : #define TIMEOUT_MSEC 1000
212 : :
213 : 0 : static int tc2_pm_power_down_finish(unsigned int cpu, unsigned int cluster)
214 : : {
215 : : unsigned tries;
216 : :
217 : : pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
218 [ # # ]: 0 : BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
219 : :
220 [ # # ]: 0 : for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; ++tries) {
221 : : /*
222 : : * Only examine the hardware state if the target CPU has
223 : : * caught up at least as far as tc2_pm_down():
224 : : */
225 [ # # ]: 0 : if (ACCESS_ONCE(tc2_pm_use_count[cpu][cluster]) == 0) {
226 : 0 : pr_debug("%s(cpu=%u, cluster=%u): RESET_CTRL = 0x%08X\n",
227 : : __func__, cpu, cluster,
228 : : readl_relaxed(scc + RESET_CTRL));
229 : :
230 : : /*
231 : : * We need the CPU to reach WFI, but the power
232 : : * controller may put the cluster in reset and
233 : : * power it off as soon as that happens, before
234 : : * we have a chance to see STANDBYWFI.
235 : : *
236 : : * So we need to check for both conditions:
237 : : */
238 [ # # # # ]: 0 : if (tc2_core_in_reset(cpu, cluster) ||
239 : 0 : ve_spc_cpu_in_wfi(cpu, cluster))
240 : : return 0; /* success: the CPU is halted */
241 : : }
242 : :
243 : : /* Otherwise, wait and retry: */
244 : 0 : msleep(POLL_MSEC);
245 : : }
246 : :
247 : : return -ETIMEDOUT; /* timeout */
248 : : }
249 : :
250 : 0 : static void tc2_pm_suspend(u64 residency)
251 : : {
252 : : unsigned int mpidr, cpu, cluster;
253 : :
254 : : mpidr = read_cpuid_mpidr();
255 : 1195312 : cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
256 : 1195312 : cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
257 : 1195312 : ve_spc_set_resume_addr(cluster, cpu, virt_to_phys(mcpm_entry_point));
258 : 1195300 : tc2_pm_down(residency);
259 : 0 : }
260 : :
261 : 0 : static void tc2_pm_powered_up(void)
262 : : {
263 : : unsigned int mpidr, cpu, cluster;
264 : : unsigned long flags;
265 : :
266 : : mpidr = read_cpuid_mpidr();
267 : 1196993 : cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
268 : 1196993 : cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
269 : :
270 : : pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
271 [ - + ]: 1196993 : BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
272 : :
273 : : local_irq_save(flags);
274 : : arch_spin_lock(&tc2_pm_lock);
275 : :
276 [ + + ][ + + ]: 1200196 : if (tc2_cluster_unused(cluster)) {
[ + - ]
277 : 763797 : ve_spc_powerdown(cluster, false);
278 : 763797 : ve_spc_global_wakeup_irq(false);
279 : : }
280 : :
281 [ + + ]: 2397189 : if (!tc2_pm_use_count[cpu][cluster])
282 : 1195318 : tc2_pm_use_count[cpu][cluster] = 1;
283 : :
284 : 1200196 : ve_spc_cpu_wakeup_irq(cluster, cpu, false);
285 : 1200196 : ve_spc_set_resume_addr(cluster, cpu, 0);
286 : :
287 : : arch_spin_unlock(&tc2_pm_lock);
288 [ + - ]: 1200196 : local_irq_restore(flags);
289 : 1200196 : }
290 : :
291 : : static const struct mcpm_platform_ops tc2_pm_power_ops = {
292 : : .power_up = tc2_pm_power_up,
293 : : .power_down = tc2_pm_power_down,
294 : : .power_down_finish = tc2_pm_power_down_finish,
295 : : .suspend = tc2_pm_suspend,
296 : : .powered_up = tc2_pm_powered_up,
297 : : };
298 : :
299 : 0 : static bool __init tc2_pm_usage_count_init(void)
300 : : {
301 : : unsigned int mpidr, cpu, cluster;
302 : :
303 : : mpidr = read_cpuid_mpidr();
304 : 0 : cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
305 : 0 : cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
306 : :
307 : : pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
308 [ # # ][ # # ]: 0 : if (cluster >= TC2_CLUSTERS || cpu >= tc2_nr_cpus[cluster]) {
309 : 0 : pr_err("%s: boot CPU is out of bound!\n", __func__);
310 : 0 : return false;
311 : : }
312 : 0 : tc2_pm_use_count[cpu][cluster] = 1;
313 : 0 : return true;
314 : : }
315 : :
316 : : /*
317 : : * Enable cluster-level coherency, in preparation for turning on the MMU.
318 : : */
319 : 0 : static void __naked tc2_pm_power_up_setup(unsigned int affinity_level)
320 : : {
321 : 0 : asm volatile (" \n"
322 : : " cmp r0, #1 \n"
323 : : " bxne lr \n"
324 : : " b cci_enable_port_for_self ");
325 : 0 : }
326 : :
327 : 0 : static int __init tc2_pm_init(void)
328 : : {
329 : : int ret, irq;
330 : : u32 a15_cluster_id, a7_cluster_id, sys_info;
331 : : struct device_node *np;
332 : :
333 : 0 : ret = psci_probe();
334 [ # # ]: 0 : if (!ret) {
335 : : pr_debug("psci found. Aborting native init\n");
336 : : return -ENODEV;
337 : : }
338 : :
339 : : /*
340 : : * The power management-related features are hidden behind
341 : : * SCC registers. We need to extract runtime information like
342 : : * cluster ids and number of CPUs really available in clusters.
343 : : */
344 : 0 : np = of_find_compatible_node(NULL, NULL,
345 : : "arm,vexpress-scc,v2p-ca15_a7");
346 : 0 : scc = of_iomap(np, 0);
347 [ # # ]: 0 : if (!scc)
348 : : return -ENODEV;
349 : :
350 : 0 : a15_cluster_id = readl_relaxed(scc + A15_CONF) & 0xf;
351 : 0 : a7_cluster_id = readl_relaxed(scc + A7_CONF) & 0xf;
352 [ # # ]: 0 : if (a15_cluster_id >= TC2_CLUSTERS || a7_cluster_id >= TC2_CLUSTERS)
353 : : return -EINVAL;
354 : :
355 : 0 : sys_info = readl_relaxed(scc + SYS_INFO);
356 : 0 : tc2_nr_cpus[a15_cluster_id] = (sys_info >> 16) & 0xf;
357 : 0 : tc2_nr_cpus[a7_cluster_id] = (sys_info >> 20) & 0xf;
358 : :
359 : 0 : irq = irq_of_parse_and_map(np, 0);
360 : :
361 : : /*
362 : : * A subset of the SCC registers is also used to communicate
363 : : * with the SPC (power controller). We need to be able to
364 : : * drive it very early in the boot process to power up
365 : : * processors, so we initialize the SPC driver here.
366 : : */
367 : 0 : ret = ve_spc_init(scc + SPC_BASE, a15_cluster_id, irq);
368 [ # # ]: 0 : if (ret)
369 : : return ret;
370 : :
371 [ # # ]: 0 : if (!cci_probed())
372 : : return -ENODEV;
373 : :
374 [ # # ]: 0 : if (!tc2_pm_usage_count_init())
375 : : return -EINVAL;
376 : :
377 : 0 : ret = mcpm_platform_register(&tc2_pm_power_ops);
378 [ # # ]: 0 : if (!ret) {
379 : 0 : mcpm_sync_init(tc2_pm_power_up_setup);
380 : 0 : pr_info("TC2 power management initialized\n");
381 : : }
382 : 0 : return ret;
383 : : }
384 : :
385 : : early_initcall(tc2_pm_init);
|