ARM: tegra3: Cluster Switch and LP0 require PM_SLEEP
[linux-2.6.git] / arch / arm / mach-tegra / pm-t3.c
1 /*
2  * arch/arm/mach-tegra/pm-t3.c
3  *
4  * Tegra3 SOC-specific power and cluster management
5  *
6  * Copyright (c) 2009-2011, NVIDIA Corporation.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/io.h>
22 #include <linux/smp.h>
23 #include <linux/interrupt.h>
24 #include <linux/clk.h>
25
26 #include <mach/gpio.h>
27 #include <mach/iomap.h>
28 #include <mach/irqs.h>
29 #include <asm/hardware/gic.h>
30
31 #include "clock.h"
32 #include "gpio-names.h"
33 #include "pm.h"
34 #include "tegra3_emc.h"
35
36 #define CAR_CCLK_BURST_POLICY \
37         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x20)
38
39 #define CAR_SUPER_CCLK_DIVIDER \
40         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x24)
41
42 #define CAR_CCLKG_BURST_POLICY \
43         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x368)
44
45 #define CAR_SUPER_CCLKG_DIVIDER \
46         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x36C)
47
48 #define CAR_CCLKLP_BURST_POLICY \
49         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x370)
50 #define PLLX_DIV2_BYPASS_LP     (1<<16)
51
52 #define CAR_SUPER_CCLKLP_DIVIDER \
53         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x374)
54
55 #define CAR_BOND_OUT_V \
56         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x390)
57 #define CAR_BOND_OUT_V_CPU_G    (1<<0)
58 #define CAR_BOND_OUT_V_CPU_LP   (1<<1)
59
60 #define CAR_CLK_ENB_V_SET \
61         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x440)
62 #define CAR_CLK_ENB_V_CPU_G     (1<<0)
63 #define CAR_CLK_ENB_V_CPU_LP    (1<<1)
64
65 #define CAR_RST_CPUG_CMPLX_SET \
66         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x450)
67
68 #define CAR_RST_CPUG_CMPLX_CLR \
69         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x454)
70
71 #define CAR_RST_CPULP_CMPLX_SET \
72         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x458)
73
74 #define CAR_RST_CPULP_CMPLX_CLR \
75         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x45C)
76
77 #define CAR_CLK_CPUG_CMPLX_SET \
78         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x460)
79
80 #define CAR_CLK_CPUG_CMPLX_CLR \
81         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x464)
82
83 #define CAR_CLK_CPULP_CMPLX_SET \
84         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x468)
85
86 #define CAR_CLK_CPULP_CMPLX_CLR \
87         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x46C)
88
89 #define CPU_CLOCK(cpu)  (0x1<<(8+cpu))
90 #define CPU_RESET(cpu)  (0x1111ul<<(cpu))
91
92 #ifdef CONFIG_PM_SLEEP
93 static int cluster_switch_prolog_clock(unsigned int flags)
94 {
95         u32 reg;
96         u32 CclkBurstPolicy;
97         u32 SuperCclkDivier;
98
99         /* Read the bond out register containing the G and LP CPUs. */
100         reg = readl(CAR_BOND_OUT_V);
101
102         /* Sync G-PLLX divider bypass with LP (no effect on G, just to prevent
103            LP settings overwrite by save/restore code */
104         CclkBurstPolicy = ~PLLX_DIV2_BYPASS_LP & readl(CAR_CCLKG_BURST_POLICY);
105         CclkBurstPolicy |= PLLX_DIV2_BYPASS_LP & readl(CAR_CCLKLP_BURST_POLICY);
106         writel(CclkBurstPolicy, CAR_CCLKG_BURST_POLICY);
107
108         /* Switching to G? */
109         if (flags & TEGRA_POWER_CLUSTER_G) {
110                 /* Do the G CPUs exist? */
111                 if (reg & CAR_BOND_OUT_V_CPU_G)
112                         return -ENXIO;
113
114                 /* Keep G CPU clock policy set by upper laayer, with the
115                    exception of the transition via LP1 */
116                 if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
117                         /* In LP1 power mode come up on CLKM (oscillator) */
118                         CclkBurstPolicy = readl(CAR_CCLKG_BURST_POLICY);
119                         CclkBurstPolicy |= ~0xF;
120                         SuperCclkDivier = 0;
121
122                         writel(CclkBurstPolicy, CAR_CCLKG_BURST_POLICY);
123                         writel(SuperCclkDivier, CAR_SUPER_CCLKG_DIVIDER);
124                 }
125
126                 /* Hold G CPUs 1-3 in reset after the switch */
127                 reg = CPU_RESET(1) | CPU_RESET(2) | CPU_RESET(3);
128                 writel(reg, CAR_RST_CPUG_CMPLX_SET);
129
130                 /* Take G CPU 0 out of reset after the switch */
131                 reg = CPU_RESET(0);
132                 writel(reg, CAR_RST_CPUG_CMPLX_CLR);
133
134                 /* Disable the clocks on G CPUs 1-3 after the switch */
135                 reg = CPU_CLOCK(1) | CPU_CLOCK(2) | CPU_CLOCK(3);
136                 writel(reg, CAR_CLK_CPUG_CMPLX_SET);
137
138                 /* Enable the clock on G CPU 0 after the switch */
139                 reg = CPU_CLOCK(0);
140                 writel(reg, CAR_CLK_CPUG_CMPLX_CLR);
141
142                 /* Enable the G CPU complex clock after the switch */
143                 reg = CAR_CLK_ENB_V_CPU_G;
144                 writel(reg, CAR_CLK_ENB_V_SET);
145         }
146         /* Switching to LP? */
147         else if (flags & TEGRA_POWER_CLUSTER_LP) {
148                 /* Does the LP CPU exist? */
149                 if (reg & CAR_BOND_OUT_V_CPU_LP)
150                         return -ENXIO;
151
152                 /* Keep LP CPU clock policy set by upper layer, with the
153                    exception of the transition via LP1 */
154                 if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
155                         /* In LP1 power mode come up on CLKM (oscillator) */
156                         CclkBurstPolicy = readl(CAR_CCLKLP_BURST_POLICY);
157                         CclkBurstPolicy |= ~0xF;
158                         SuperCclkDivier = 0;
159
160                         writel(CclkBurstPolicy, CAR_CCLKLP_BURST_POLICY);
161                         writel(SuperCclkDivier, CAR_SUPER_CCLKLP_DIVIDER);
162                 }
163
164                 /* Take the LP CPU ut of reset after the switch */
165                 reg = CPU_RESET(0);
166                 writel(reg, CAR_RST_CPULP_CMPLX_CLR);
167
168                 /* Enable the clock on the LP CPU after the switch */
169                 reg = CPU_CLOCK(0);
170                 writel(reg, CAR_CLK_CPULP_CMPLX_CLR);
171
172                 /* Enable the LP CPU complex clock after the switch */
173                 reg = CAR_CLK_ENB_V_CPU_LP;
174                 writel(reg, CAR_CLK_ENB_V_SET);
175         }
176
177         return 0;
178 }
179
180 void tegra_cluster_switch_prolog(unsigned int flags)
181 {
182         unsigned int target_cluster = flags & TEGRA_POWER_CLUSTER_MASK;
183         unsigned int current_cluster = is_lp_cluster()
184                                         ? TEGRA_POWER_CLUSTER_LP
185                                         : TEGRA_POWER_CLUSTER_G;
186         u32 reg;
187
188         /* Read the flow controler CSR register and clear the CPU switch
189            and immediate flags. If an actual CPU switch is to be performed,
190            re-write the CSR register with the desired values. */
191         reg = readl(FLOW_CTRL_CPU_CSR(0));
192         reg &= ~(FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE |
193                  FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER);
194
195         /* Program flow controller for immediate wake if requested */
196         if (flags & TEGRA_POWER_CLUSTER_IMMEDIATE)
197                 reg |= FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE;
198
199         /* Do nothing if no switch actions requested */
200         if (!target_cluster)
201                 goto done;
202
203         if ((current_cluster != target_cluster) ||
204                 (flags & TEGRA_POWER_CLUSTER_FORCE)) {
205                 if (current_cluster != target_cluster) {
206                         // Set up the clocks for the target CPU.
207                         if (cluster_switch_prolog_clock(flags)) {
208                                 /* The target CPU does not exist */
209                                 goto done;
210                         }
211
212                         /* Set up the flow controller to switch CPUs. */
213                         reg |= FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER;
214                 }
215         }
216
217 done:
218         writel(reg, FLOW_CTRL_CPU_CSR(0));
219 }
220
221 static void cluster_switch_epilog_gic(void)
222 {
223         unsigned int max_irq, i;
224         void __iomem *gic_base = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
225
226         /* Nothing to do if currently running on the LP CPU. */
227         if (is_lp_cluster())
228                 return;
229
230         /* Reprogram the interrupt affinity because the on the LP CPU,
231            the interrupt distributor affinity regsiters are stubbed out
232            by ARM (reads as zero, writes ignored). So when the LP CPU
233            context save code runs, the affinity registers will read
234            as all zero. This causes all interrupts to be effectively
235            disabled when back on the G CPU because they aren't routable
236            to any CPU. See bug 667720 for details. */
237
238         max_irq = readl(gic_base + GIC_DIST_CTR) & 0x1f;
239         max_irq = (max_irq + 1) * 32;
240
241         for (i = 32; i < max_irq; i += 4)
242                 writel(0x01010101, gic_base + GIC_DIST_TARGET + i * 4 / 4);
243 }
244
245 void tegra_cluster_switch_epilog(unsigned int flags)
246 {
247         u32 reg;
248
249         /* Make sure the switch and immediate flags are cleared in
250            the flow controller to prevent undesirable side-effects
251            for future users of the flow controller. */
252         reg = readl(FLOW_CTRL_CPU_CSR(0));
253         reg &= ~(FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE |
254                  FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER);
255         writel(reg, FLOW_CTRL_CPU_CSR(0));
256
257         /* Perform post-switch clean-up of the interrupt distributor */
258         cluster_switch_epilog_gic();
259
260         #if DEBUG_CLUSTER_SWITCH
261         {
262                 /* FIXME: clock functions below are taking mutex */
263                 struct clk *c = tegra_get_clock_by_name(
264                         is_lp_cluster() ? "cpu_lp" : "cpu_g");
265                 DEBUG_CLUSTER(("%s: %s freq %lu\r\n", __func__,
266                         is_lp_cluster() ? "LP" : "G", clk_get_rate(c)));
267         }
268         #endif
269 }
270
271 int tegra_cluster_control(unsigned int us, unsigned int flags)
272 {
273         unsigned int target_cluster = flags & TEGRA_POWER_CLUSTER_MASK;
274         unsigned int current_cluster = is_lp_cluster()
275                                         ? TEGRA_POWER_CLUSTER_LP
276                                         : TEGRA_POWER_CLUSTER_G;
277
278         if ((target_cluster == TEGRA_POWER_CLUSTER_MASK) || !target_cluster)
279                 return -EINVAL;
280
281         if (num_online_cpus() > 1)
282                 return -EBUSY;
283
284         if ((current_cluster == target_cluster)
285         && !(flags & TEGRA_POWER_CLUSTER_FORCE))
286                 return -EEXIST;
287
288         if (target_cluster == TEGRA_POWER_CLUSTER_G)
289                 if (!is_g_cluster_present())
290                         return -EPERM;
291
292         if (flags & TEGRA_POWER_CLUSTER_IMMEDIATE)
293                 us = 0;
294
295         DEBUG_CLUSTER(("%s(LP%d): %s->%s %s %s %d\r\n", __func__,
296                 (flags & TEGRA_POWER_SDRAM_SELFREFRESH) ? 1 : 2,
297                 is_lp_cluster() ? "LP" : "G",
298                 (target_cluster == TEGRA_POWER_CLUSTER_G) ? "G" : "LP",
299                 (flags & TEGRA_POWER_CLUSTER_IMMEDIATE) ? "immediate" : "",
300                 (flags & TEGRA_POWER_CLUSTER_FORCE) ? "force" : "",
301                 us));
302
303         local_irq_disable();
304         if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
305                 if (us)
306                         tegra_lp2_set_trigger(us);
307
308                 tegra_suspend_dram(TEGRA_SUSPEND_LP1);
309
310                 if (us)
311                         tegra_lp2_set_trigger(0);
312         } else
313                 tegra_idle_lp2_last(0, flags);
314         local_irq_enable();
315
316         DEBUG_CLUSTER(("%s: %s\r\n", __func__, is_lp_cluster() ? "LP" : "G"));
317
318         return 0;
319 }
320
321 static u32 mc_reserved_rsv;
322 static u32 mc_emem_arb_override;
323
324 void tegra_lp0_suspend_mc(void)
325 {
326         void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
327         mc_reserved_rsv = readl(mc + MC_RESERVED_RSV);
328         mc_emem_arb_override = readl(mc + MC_EMEM_ARB_OVERRIDE);
329 }
330
331 void tegra_lp0_resume_mc(void)
332 {
333         void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
334         writel(mc_reserved_rsv, mc + MC_RESERVED_RSV);
335         writel(mc_emem_arb_override, mc + MC_EMEM_ARB_OVERRIDE);
336 }
337 #endif