aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-hisi
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-hisi')
-rw-r--r--arch/arm/mach-hisi/Kconfig8
-rw-r--r--arch/arm/mach-hisi/core.h5
-rw-r--r--arch/arm/mach-hisi/headsmp.S2
-rw-r--r--arch/arm/mach-hisi/hisilicon.c10
-rw-r--r--arch/arm/mach-hisi/hotplug.c31
-rw-r--r--arch/arm/mach-hisi/platsmp.c56
6 files changed, 107 insertions, 5 deletions
diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig
index cd19433f76d3..83061ad0e282 100644
--- a/arch/arm/mach-hisi/Kconfig
+++ b/arch/arm/mach-hisi/Kconfig
@@ -22,6 +22,14 @@ config ARCH_HI3xxx
22 help 22 help
23 Support for Hisilicon Hi36xx SoC family 23 Support for Hisilicon Hi36xx SoC family
24 24
25config ARCH_HIP01
26 bool "Hisilicon HIP01 family" if ARCH_MULTI_V7
27 select HAVE_ARM_SCU if SMP
28 select HAVE_ARM_TWD if SMP
29 select ARM_GLOBAL_TIMER
30 help
31 Support for Hisilicon HIP01 SoC family
32
25config ARCH_HIP04 33config ARCH_HIP04
26 bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7 34 bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7
27 select ARM_ERRATA_798181 if SMP 35 select ARM_ERRATA_798181 if SMP
diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h
index 88b1f487d065..92a682d8e939 100644
--- a/arch/arm/mach-hisi/core.h
+++ b/arch/arm/mach-hisi/core.h
@@ -12,9 +12,12 @@ extern void hi3xxx_cpu_die(unsigned int cpu);
12extern int hi3xxx_cpu_kill(unsigned int cpu); 12extern int hi3xxx_cpu_kill(unsigned int cpu);
13extern void hi3xxx_set_cpu(int cpu, bool enable); 13extern void hi3xxx_set_cpu(int cpu, bool enable);
14 14
15extern void hix5hd2_secondary_startup(void); 15extern void hisi_secondary_startup(void);
16extern struct smp_operations hix5hd2_smp_ops; 16extern 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/headsmp.S b/arch/arm/mach-hisi/headsmp.S
index 278889c00b77..81e35b159e75 100644
--- a/arch/arm/mach-hisi/headsmp.S
+++ b/arch/arm/mach-hisi/headsmp.S
@@ -11,6 +11,6 @@
11 11
12 __CPUINIT 12 __CPUINIT
13 13
14ENTRY(hix5hd2_secondary_startup) 14ENTRY(hisi_secondary_startup)
15 bl v7_invalidate_l1 15 bl v7_invalidate_l1
16 b secondary_startup 16 b secondary_startup
diff --git a/arch/arm/mach-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c
index 7744c351bbfd..76b907078b58 100644
--- a/arch/arm/mach-hisi/hisilicon.c
+++ b/arch/arm/mach-hisi/hisilicon.c
@@ -72,3 +72,13 @@ static const char *hip04_compat[] __initconst = {
72DT_MACHINE_START(HIP04, "Hisilicon HiP04 (Flattened Device Tree)") 72DT_MACHINE_START(HIP04, "Hisilicon HiP04 (Flattened Device Tree)")
73 .dt_compat = hip04_compat, 73 .dt_compat = hip04_compat,
74MACHINE_END 74MACHINE_END
75
76static const char *hip01_compat[] __initconst = {
77 "hisilicon,hip01",
78 "hisilicon,hip01-ca9x2",
79 NULL,
80};
81
82DT_MACHINE_START(HIP01, "Hisilicon HIP01 (Flattened Device Tree)")
83 .dt_compat = hip01_compat,
84MACHINE_END
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 575dd8285f1f..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
@@ -96,7 +98,7 @@ struct smp_operations hi3xxx_smp_ops __initdata = {
96#endif 98#endif
97}; 99};
98 100
99static void __init hix5hd2_smp_prepare_cpus(unsigned int max_cpus) 101static void __init hisi_common_smp_prepare_cpus(unsigned int max_cpus)
100{ 102{
101 hisi_enable_scu_a9(); 103 hisi_enable_scu_a9();
102} 104}
@@ -116,7 +118,7 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
116{ 118{
117 phys_addr_t jumpaddr; 119 phys_addr_t jumpaddr;
118 120
119 jumpaddr = virt_to_phys(hix5hd2_secondary_startup); 121 jumpaddr = virt_to_phys(hisi_secondary_startup);
120 hix5hd2_set_scu_boot_addr(HIX5HD2_BOOT_ADDRESS, jumpaddr); 122 hix5hd2_set_scu_boot_addr(HIX5HD2_BOOT_ADDRESS, jumpaddr);
121 hix5hd2_set_cpu(cpu, true); 123 hix5hd2_set_cpu(cpu, true);
122 arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 124 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
@@ -125,12 +127,60 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
125 127
126 128
127struct smp_operations hix5hd2_smp_ops __initdata = { 129struct smp_operations hix5hd2_smp_ops __initdata = {
128 .smp_prepare_cpus = hix5hd2_smp_prepare_cpus, 130 .smp_prepare_cpus = hisi_common_smp_prepare_cpus,
129 .smp_boot_secondary = hix5hd2_boot_secondary, 131 .smp_boot_secondary = hix5hd2_boot_secondary,
130#ifdef CONFIG_HOTPLUG_CPU 132#ifdef CONFIG_HOTPLUG_CPU
131 .cpu_die = hix5hd2_cpu_die, 133 .cpu_die = hix5hd2_cpu_die,
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);