ARM: tegra: clock: Re-factor Tegra3 cpu clocks
[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
33 #define EVP_CPU_RESET_VECTOR \
34         (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
35 #define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \
36         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c)
37 #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET \
38         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x340)
39 #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \
40         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344)
41
42 #define CPU_CLOCK(cpu)  (0x1<<(8+cpu))
43 #define CPU_RESET(cpu)  (0x1111ul<<(cpu))
44
45 static unsigned int available_cpus(void);
46 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
47 static inline int is_g_cluster_available(unsigned int cpu)
48 { return -EPERM; }
49 static inline bool is_cpu_powered(unsigned int cpu)
50 { return true; }
51 static inline int power_up_cpu(unsigned int cpu)
52 { return 0; }
53
54 /* For Tegra2 use the software-written value of the reset regsiter for status.*/
55 #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET
56
57 #else
58 static int is_g_cluster_available(unsigned int cpu);
59 static bool is_cpu_powered(unsigned int cpu);
60 static int power_up_cpu(unsigned int cpu);
61
62 #define CAR_BOND_OUT_V \
63         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x390)
64 #define CAR_BOND_OUT_V_CPU_G    (1<<0)
65 #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS \
66         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x470)
67
68 #endif
69
70 extern void tegra_secondary_startup(void);
71
72 static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
73
74 void __cpuinit platform_secondary_init(unsigned int cpu)
75 {
76         gic_secondary_init(0);
77 }
78
79 int boot_secondary(unsigned int cpu, struct task_struct *idle)
80 {
81         int status;
82
83         if (is_lp_cluster()) {
84                 struct clk *cpu_clk, *cpu_g_clk;
85
86                 /* The G CPU may not be available for a
87                    variety of reasons. */
88                 status = is_g_cluster_available(cpu);
89                 if (status)
90                         return status;
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                         return status;
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 i, ncores = available_cpus();
153
154         if (ncores > nr_cpu_ids) {
155                 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
156                         ncores, nr_cpu_ids);
157                 ncores = nr_cpu_ids;
158         }
159
160         for (i = 0; i < ncores; i++)
161                 set_cpu_possible(i, true);
162
163         set_smp_cross_call(gic_raise_softirq);
164 }
165
166 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
167 {
168
169         scu_enable(scu_base);
170 }
171
172 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
173
174 static bool is_cpu_powered(unsigned int cpu)
175 {
176         if (is_lp_cluster())
177                 return true;
178         else
179                 return tegra_powergate_is_powered(TEGRA_CPU_POWERGATE_ID(cpu));
180 }
181
182 static int power_up_cpu(unsigned int cpu)
183 {
184         int ret;
185         u32 reg;
186         unsigned long timeout;
187
188         BUG_ON(cpu == smp_processor_id());
189         BUG_ON(is_lp_cluster());
190
191         /* This function is entered after CPU has been already un-gated by
192            flow controller. Wait for confirmation that cpu is powered and
193            remove clamps. */
194         timeout = jiffies + HZ;
195         do {
196                 if (is_cpu_powered(cpu))
197                         goto remove_clamps;
198                 udelay(10);
199         } while (time_before(jiffies, timeout));
200
201         /* Flow controller did not work as expected - try directly toggle
202            power gates. Bail out if direct power on also failed */
203         if (!is_cpu_powered(cpu))
204         {
205                 ret = tegra_powergate_power_on(TEGRA_CPU_POWERGATE_ID(cpu));
206                 if (ret)
207                         goto fail;
208
209                 /* Wait for the power to come up. */
210                 timeout = jiffies + 10*HZ;
211
212                 do {
213                         if (is_cpu_powered(cpu))
214                                 goto remove_clamps;
215                         udelay(10);
216                 } while (time_before(jiffies, timeout));
217                 ret = -ETIMEDOUT;
218                 goto fail;
219         }
220
221 remove_clamps:
222         /* now CPU is up: enable clock, propagate reset, and remove clamps */
223         reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
224         writel(reg & ~CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
225         barrier();
226         reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
227
228         udelay(10);
229         ret = tegra_powergate_remove_clamping(TEGRA_CPU_POWERGATE_ID(cpu));
230 fail:
231         return ret;
232 }
233
234 static int is_g_cluster_available(unsigned int cpu)
235 {
236         u32 fuse_sku = readl(FUSE_SKU_DIRECT_CONFIG);
237         u32 bond_out = readl(CAR_BOND_OUT_V);
238
239         /* Does the G CPU complex exist at all? */
240         if ((fuse_sku & FUSE_SKU_DISABLE_ALL_CPUS) ||
241             (bond_out & CAR_BOND_OUT_V_CPU_G))
242                 return -EPERM;
243
244         if (cpu >= available_cpus())
245                 return -EPERM;
246
247         /* FIXME: The G CPU can be unavailable for a number of reasons
248          *        (e.g., low battery, over temperature, etc.). Add checks for
249          *        these conditions. */
250
251         return 0;
252 }
253 #endif
254
255 static unsigned int available_cpus(void)
256 {
257         static unsigned int ncores = 0;
258
259         if (ncores == 0) {
260                 ncores = scu_get_core_count(scu_base);
261 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
262                 if (ncores > 1) {
263                         u32 fuse_sku = readl(FUSE_SKU_DIRECT_CONFIG);
264                         ncores -= FUSE_SKU_NUM_DISABLED_CPUS(fuse_sku);
265                         BUG_ON((int)ncores <= 0);
266                 }
267 #endif
268         }
269         return ncores;
270 }