diff options
author | Wang Long <long.wanglong@huawei.com> | 2014-12-23 22:10:02 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2015-01-21 17:33:39 -0500 |
commit | 7fda91e731554336c08a8157b886387d890a9676 (patch) | |
tree | 3cdf75fa716ec06d77f3ec95eccd34a9978db06c | |
parent | 29d189e1395a3f0924f7a442bb4b968c9e6de9c1 (diff) |
ARM: hisi: enable smp for HiP01
Enable smp for HiP01 board.
Signed-off-by: Wang Long <long.wanglong@huawei.com>
Signed-off-by: Wei Xu <xuwei5@hisilicon.com>
[olof: split off the dts change to a separate commit]
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | arch/arm/mach-hisi/core.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-hisi/hotplug.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-hisi/platsmp.c | 50 |
3 files changed, 84 insertions, 0 deletions
diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h index 75520b084b34..92a682d8e939 100644 --- a/arch/arm/mach-hisi/core.h +++ b/arch/arm/mach-hisi/core.h | |||
@@ -17,4 +17,7 @@ extern struct smp_operations hix5hd2_smp_ops; | |||
17 | extern void hix5hd2_set_cpu(int cpu, bool enable); | 17 | extern void hix5hd2_set_cpu(int cpu, bool enable); |
18 | extern void hix5hd2_cpu_die(unsigned int cpu); | 18 | extern void hix5hd2_cpu_die(unsigned int cpu); |
19 | 19 | ||
20 | extern struct smp_operations hip01_smp_ops; | ||
21 | extern void hip01_set_cpu(int cpu, bool enable); | ||
22 | extern void hip01_cpu_die(unsigned int cpu); | ||
20 | #endif | 23 | #endif |
diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c index 84e6919f68c7..a129aae72602 100644 --- a/arch/arm/mach-hisi/hotplug.c +++ b/arch/arm/mach-hisi/hotplug.c | |||
@@ -65,6 +65,9 @@ | |||
65 | #define PMC0_CPU1_PMC_ENABLE (1 << 7) | 65 | #define PMC0_CPU1_PMC_ENABLE (1 << 7) |
66 | #define PMC0_CPU1_POWERDOWN (1 << 3) | 66 | #define PMC0_CPU1_POWERDOWN (1 << 3) |
67 | 67 | ||
68 | #define HIP01_PERI9 0x50 | ||
69 | #define PERI9_CPU1_RESET (1 << 1) | ||
70 | |||
68 | enum { | 71 | enum { |
69 | HI3620_CTRL, | 72 | HI3620_CTRL, |
70 | ERROR_CTRL, | 73 | ERROR_CTRL, |
@@ -209,6 +212,34 @@ void hix5hd2_set_cpu(int cpu, bool enable) | |||
209 | } | 212 | } |
210 | } | 213 | } |
211 | 214 | ||
215 | void hip01_set_cpu(int cpu, bool enable) | ||
216 | { | ||
217 | unsigned int temp; | ||
218 | struct device_node *np; | ||
219 | |||
220 | if (!ctrl_base) { | ||
221 | np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl"); | ||
222 | if (np) | ||
223 | ctrl_base = of_iomap(np, 0); | ||
224 | else | ||
225 | BUG(); | ||
226 | } | ||
227 | |||
228 | if (enable) { | ||
229 | /* reset on CPU1 */ | ||
230 | temp = readl_relaxed(ctrl_base + HIP01_PERI9); | ||
231 | temp |= PERI9_CPU1_RESET; | ||
232 | writel_relaxed(temp, ctrl_base + HIP01_PERI9); | ||
233 | |||
234 | udelay(50); | ||
235 | |||
236 | /* unreset on CPU1 */ | ||
237 | temp = readl_relaxed(ctrl_base + HIP01_PERI9); | ||
238 | temp &= ~PERI9_CPU1_RESET; | ||
239 | writel_relaxed(temp, ctrl_base + HIP01_PERI9); | ||
240 | } | ||
241 | } | ||
242 | |||
212 | static inline void cpu_enter_lowpower(void) | 243 | static inline void cpu_enter_lowpower(void) |
213 | { | 244 | { |
214 | unsigned int v; | 245 | unsigned int v; |
diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c index 4a70f5610a2c..8880c8e8b296 100644 --- a/arch/arm/mach-hisi/platsmp.c +++ b/arch/arm/mach-hisi/platsmp.c | |||
@@ -10,10 +10,12 @@ | |||
10 | #include <linux/smp.h> | 10 | #include <linux/smp.h> |
11 | #include <linux/io.h> | 11 | #include <linux/io.h> |
12 | #include <linux/of_address.h> | 12 | #include <linux/of_address.h> |
13 | #include <linux/delay.h> | ||
13 | 14 | ||
14 | #include <asm/cacheflush.h> | 15 | #include <asm/cacheflush.h> |
15 | #include <asm/smp_plat.h> | 16 | #include <asm/smp_plat.h> |
16 | #include <asm/smp_scu.h> | 17 | #include <asm/smp_scu.h> |
18 | #include <asm/mach/map.h> | ||
17 | 19 | ||
18 | #include "core.h" | 20 | #include "core.h" |
19 | 21 | ||
@@ -132,5 +134,53 @@ struct smp_operations hix5hd2_smp_ops __initdata = { | |||
132 | #endif | 134 | #endif |
133 | }; | 135 | }; |
134 | 136 | ||
137 | |||
138 | #define SC_SCTL_REMAP_CLR 0x00000100 | ||
139 | #define HIP01_BOOT_ADDRESS 0x80000000 | ||
140 | #define REG_SC_CTRL 0x000 | ||
141 | |||
142 | void hip01_set_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr) | ||
143 | { | ||
144 | void __iomem *virt; | ||
145 | |||
146 | virt = phys_to_virt(start_addr); | ||
147 | |||
148 | writel_relaxed(0xe51ff004, virt); | ||
149 | writel_relaxed(jump_addr, virt + 4); | ||
150 | } | ||
151 | |||
152 | static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
153 | { | ||
154 | phys_addr_t jumpaddr; | ||
155 | unsigned int remap_reg_value = 0; | ||
156 | struct device_node *node; | ||
157 | |||
158 | |||
159 | jumpaddr = virt_to_phys(hisi_secondary_startup); | ||
160 | hip01_set_boot_addr(HIP01_BOOT_ADDRESS, jumpaddr); | ||
161 | |||
162 | node = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl"); | ||
163 | if (WARN_ON(!node)) | ||
164 | return -1; | ||
165 | ctrl_base = of_iomap(node, 0); | ||
166 | |||
167 | /* set the secondary core boot from DDR */ | ||
168 | remap_reg_value = readl_relaxed(ctrl_base + REG_SC_CTRL); | ||
169 | barrier(); | ||
170 | remap_reg_value |= SC_SCTL_REMAP_CLR; | ||
171 | barrier(); | ||
172 | writel_relaxed(remap_reg_value, ctrl_base + REG_SC_CTRL); | ||
173 | |||
174 | hip01_set_cpu(cpu, true); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | struct smp_operations hip01_smp_ops __initdata = { | ||
180 | .smp_prepare_cpus = hisi_common_smp_prepare_cpus, | ||
181 | .smp_boot_secondary = hip01_boot_secondary, | ||
182 | }; | ||
183 | |||
135 | CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops); | 184 | CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops); |
136 | CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops); | 185 | CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops); |
186 | CPU_METHOD_OF_DECLARE(hip01_smp, "hisilicon,hip01-smp", &hip01_smp_ops); | ||