summaryrefslogtreecommitdiff
path: root/arch/arm/mach-hisi/platsmp.c
diff options
context:
space:
mode:
authorWang Long <long.wanglong@huawei.com>2014-12-24 06:10:02 +0300
committerOlof Johansson <olof@lixom.net>2015-01-22 01:33:39 +0300
commit7fda91e731554336c08a8157b886387d890a9676 (patch)
tree3cdf75fa716ec06d77f3ec95eccd34a9978db06c /arch/arm/mach-hisi/platsmp.c
parent29d189e1395a3f0924f7a442bb4b968c9e6de9c1 (diff)
downloadlinux-7fda91e731554336c08a8157b886387d890a9676.tar.xz
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>
Diffstat (limited to 'arch/arm/mach-hisi/platsmp.c')
-rw-r--r--arch/arm/mach-hisi/platsmp.c50
1 files changed, 50 insertions, 0 deletions
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 @@
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/of_address.h>
+#include <linux/delay.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include <asm/smp_scu.h>
+#include <asm/mach/map.h>
#include "core.h"
@@ -132,5 +134,53 @@ struct smp_operations hix5hd2_smp_ops __initdata = {
#endif
};
+
+#define SC_SCTL_REMAP_CLR 0x00000100
+#define HIP01_BOOT_ADDRESS 0x80000000
+#define REG_SC_CTRL 0x000
+
+void hip01_set_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr)
+{
+ void __iomem *virt;
+
+ virt = phys_to_virt(start_addr);
+
+ writel_relaxed(0xe51ff004, virt);
+ writel_relaxed(jump_addr, virt + 4);
+}
+
+static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ phys_addr_t jumpaddr;
+ unsigned int remap_reg_value = 0;
+ struct device_node *node;
+
+
+ jumpaddr = virt_to_phys(hisi_secondary_startup);
+ hip01_set_boot_addr(HIP01_BOOT_ADDRESS, jumpaddr);
+
+ node = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
+ if (WARN_ON(!node))
+ return -1;
+ ctrl_base = of_iomap(node, 0);
+
+ /* set the secondary core boot from DDR */
+ remap_reg_value = readl_relaxed(ctrl_base + REG_SC_CTRL);
+ barrier();
+ remap_reg_value |= SC_SCTL_REMAP_CLR;
+ barrier();
+ writel_relaxed(remap_reg_value, ctrl_base + REG_SC_CTRL);
+
+ hip01_set_cpu(cpu, true);
+
+ return 0;
+}
+
+struct smp_operations hip01_smp_ops __initdata = {
+ .smp_prepare_cpus = hisi_common_smp_prepare_cpus,
+ .smp_boot_secondary = hip01_boot_secondary,
+};
+
CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops);
CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops);
+CPU_METHOD_OF_DECLARE(hip01_smp, "hisilicon,hip01-smp", &hip01_smp_ops);