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