aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWang Long <long.wanglong@huawei.com>2014-12-23 22:10:02 -0500
committerOlof Johansson <olof@lixom.net>2015-01-21 17:33:39 -0500
commit7fda91e731554336c08a8157b886387d890a9676 (patch)
tree3cdf75fa716ec06d77f3ec95eccd34a9978db06c
parent29d189e1395a3f0924f7a442bb4b968c9e6de9c1 (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.h3
-rw-r--r--arch/arm/mach-hisi/hotplug.c31
-rw-r--r--arch/arm/mach-hisi/platsmp.c50
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;
17extern void hix5hd2_set_cpu(int cpu, bool enable); 17extern void hix5hd2_set_cpu(int cpu, bool enable);
18extern void hix5hd2_cpu_die(unsigned int cpu); 18extern void hix5hd2_cpu_die(unsigned int cpu);
19 19
20extern struct smp_operations hip01_smp_ops;
21extern void hip01_set_cpu(int cpu, bool enable);
22extern 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
68enum { 71enum {
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
215void 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
212static inline void cpu_enter_lowpower(void) 243static 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
142void 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
152static 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
179struct smp_operations hip01_smp_ops __initdata = {
180 .smp_prepare_cpus = hisi_common_smp_prepare_cpus,
181 .smp_boot_secondary = hip01_boot_secondary,
182};
183
135CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops); 184CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops);
136CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops); 185CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops);
186CPU_METHOD_OF_DECLARE(hip01_smp, "hisilicon,hip01-smp", &hip01_smp_ops);