ARM: tegra: Trivial changes
[linux-2.6.git] / arch / arm / mach-tegra / platsmp.c
1 /*
2  *  linux/arch/arm/mach-tegra/platsmp.c
3  *
4  *  Copyright (C) 2002 ARM Ltd.
5  *  All Rights Reserved
6  *
7  *  Copyright (C) 2009 Palm
8  *  All Rights Reserved
9  *
10  *  Copyright (C) 2010 NVIDIA Corporation
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/io.h>
20 #include <linux/smp.h>
21 #include <linux/delay.h>
22 #include <linux/clk.h>
23
24 #include <asm/hardware/gic.h>
25 #include <asm/smp_scu.h>
26
27 #include <mach/iomap.h>
28 #include <mach/powergate.h>
29
30 #include "pm.h"
31 #include "clock.h"
32 #include "sleep.h"
33
34 #define EVP_CPU_RESET_VECTOR \
35         (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
36 #define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \
37         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c)
38 #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET \
39         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x340)
40 #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \
41         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344)
42
43 #define CPU_CLOCK(cpu)  (0x1<<(8+cpu))
44 #define CPU_RESET(cpu)  (0x1111ul<<(cpu))
45
46 static unsigned int available_cpus(void);
47 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
48 static inline int is_g_cluster_available(unsigned int cpu)
49 { return -EPERM; }
50 static inline bool is_cpu_powered(unsigned int cpu)
51 { return true; }
52 static inline int power_up_cpu(unsigned int cpu)
53 { return 0; }
54
55 /* For Tegra2 use the software-written value of the reset regsiter for status.*/
56 #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET
57
58 #else
59 static int is_g_cluster_available(unsigned int cpu);
60 static bool is_cpu_powered(unsigned int cpu);
61 static int power_up_cpu(unsigned int cpu);
62
63 #define CAR_BOND_OUT_V \
64         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x390)
65 #define CAR_BOND_OUT_V_CPU_G    (1<<0)
66 #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS \
67         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x470)
68
69 #endif
70
71 extern void tegra_secondary_startup(void);
72
73 static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
74
75 void __cpuinit platform_secondary_init(unsigned int cpu)
76 {
77         gic_secondary_init(0);
78 }
79
80 int boot_secondary(unsigned int cpu, struct task_struct *idle)
81 {
82         int status;
83
84         if (is_lp_cluster()) {
85                 struct clk *cpu_clk, *cpu_g_clk;
86
87                 /* The G CPU may not be available for a variety of reasons. */
88                 status = is_g_cluster_available(cpu);
89                 if (status)
90                         goto done;
91
92                 cpu_clk = tegra_get_clock_by_name("cpu");
93                 cpu_g_clk = tegra_get_clock_by_name("cpu_g");
94
95                 /* Switch to G CPU before continuing. */
96                 if (!cpu_clk || !cpu_g_clk) {
97                         /* Early boot, clock infrastructure is not initialized
98                            - CPU mode switch is not allowed */
99                         status = -EINVAL;
100                 } else
101                         status = clk_set_parent(cpu_clk, cpu_g_clk);
102
103                 if (status)
104                         goto done;
105         }
106
107         smp_wmb();
108
109         /* set the reset vector to point to the secondary_startup routine */
110         writel(virt_to_phys(tegra_secondary_startup), EVP_CPU_RESET_VECTOR);
111
112         /* Force the CPU into reset. The CPU must remain in reset when the
113            flow controller state is cleared (which will cause the flow
114            controller to stop driving reset if the CPU has been power-gated
115            via the flow controller). This will have no effect on first boot
116            of the CPU since it should already be in reset. */
117         writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
118         dmb();
119
120         /* Unhalt the CPU. If the flow controller was used to power-gate the
121            CPU this will cause the flow controller to stop driving reset.
122            The CPU will remain in reset because the clock and reset block
123            is now driving reset. */
124         flowctrl_writel(0, FLOW_CTRL_HALT_CPU(cpu));
125
126 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
127         {
128                 /* enable cpu clock on cpu */
129                 u32 reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
130                 writel(reg & ~CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
131                 dmb();
132         }
133 #endif
134         status = power_up_cpu(cpu);
135         if (status)
136                 goto done;
137
138         dmb();
139         udelay(10);     /* power up delay */
140         writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
141
142 done:
143         return status;
144 }
145
146 /*
147  * Initialise the CPU possible map early - this describes the CPUs
148  * which may be present or become present in the system.
149  */
150 void __init smp_init_cpus(void)
151 {
152         unsigned int ncores = available_cpus();
153         unsigned int i;
154
155         if (ncores > nr_cpu_ids) {
156                 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
157                         ncores, nr_cpu_ids);
158                 ncores = nr_cpu_ids;
159         }
160
161         for (i = 0; i < ncores; i++)
162                 set_cpu_possible(i, true);
163
164         set_smp_cross_call(gic_raise_softirq);
165 }
166
167 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
168 {
169
170         scu_enable(scu_base);
171 }
172
173 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
174
175 static bool is_cpu_powered(unsigned int cpu)
176 {
177         if (is_lp_cluster())
178                 return true;
179         else
180                 return tegra_powergate_is_powered(TEGRA_CPU_POWERGATE_ID(cpu));
181 }
182
183 static int power_up_cpu(unsigned int cpu)
184 {
185         int ret;
186         u32 reg;
187         unsigned long timeout;
188
189         BUG_ON(cpu == smp_processor_id());
190         BUG_ON(is_lp_cluster());
191
192         /* If this cpu has booted this function is entered after
193          * CPU has been already un-gated by flow controller. Wait
194          * for confirmation that cpu is powered and remove clamps.
195          * On first boot entry do not wait - go to direct ungate.
196          */
197 #if 0 /* FIXME! */
198         if (cpu_isset(cpu,*(cpumask_t*)&tegra_cpu_init_map))
199         {
200                 timeout = jiffies + HZ;
201                 do {
202                         if (is_cpu_powered(cpu))
203                                 goto remove_clamps;
204                         udelay(10);
205                 } while (time_before(jiffies, timeout));
206         }
207 #endif
208         /* 1'st boot or Flow controller did not work as expected - try directly toggle
209            power gates. Bail out if direct power on also failed */
210         if (!is_cpu_powered(cpu))
211         {
212                 ret = tegra_powergate_power_on(TEGRA_CPU_POWERGATE_ID(cpu));
213                 if (ret)
214                         goto fail;
215
216                 /* Wait for the power to come up. */
217                 timeout = jiffies + 10*HZ;
218
219                 do {
220                         if (is_cpu_powered(cpu))
221                                 goto remove_clamps;
222                         udelay(10);
223                 } while (time_before(jiffies, timeout));
224                 ret = -ETIMEDOUT;
225                 goto fail;
226         }
227
228 remove_clamps:
229         /* now CPU is up: enable clock, propagate reset, and remove clamps */
230         reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
231         writel(reg & ~CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
232         barrier();
233         reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
234
235         udelay(10);
236         ret = tegra_powergate_remove_clamping(TEGRA_CPU_POWERGATE_ID(cpu));
237 fail:
238         return ret;
239 }
240
241 static int is_g_cluster_available(unsigned int cpu)
242 {
243         u32 fuse_sku = readl(FUSE_SKU_DIRECT_CONFIG);
244         u32 bond_out = readl(CAR_BOND_OUT_V);
245
246         /* Does the G CPU complex exist at all? */
247         if ((fuse_sku & FUSE_SKU_DISABLE_ALL_CPUS) ||
248             (bond_out & CAR_BOND_OUT_V_CPU_G))
249                 return -EPERM;
250
251         if (cpu >= available_cpus())
252                 return -EPERM;
253
254         /* FIXME: The G CPU can be unavailable for a number of reasons
255          *        (e.g., low battery, over temperature, etc.). Add checks for
256          *        these conditions. */
257
258         return 0;
259 }
260 #endif
261
262 static unsigned int available_cpus(void)
263 {
264         static unsigned int ncores = 0;
265
266         if (ncores == 0) {
267                 ncores = scu_get_core_count(scu_base);
268 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
269                 if (ncores > 1) {
270                         u32 fuse_sku = readl(FUSE_SKU_DIRECT_CONFIG);
271                         ncores -= FUSE_SKU_NUM_DISABLED_CPUS(fuse_sku);
272                         BUG_ON((int)ncores <= 0);
273                 }
274 #endif
275         }
276         return ncores;
277 }