From 06cc5c1d4d7313bc864e9aac1d1cbd63d8b9ca4c Mon Sep 17 00:00:00 2001 From: Haifeng Yan Date: Fri, 11 Apr 2014 11:54:11 +0800 Subject: ARM: hisi: enable hix5hd2 SoC Enable support for the Hisilicon HiX5HD2 SoC. This HiX5HD2 SoC series support both single and dual Cortex-A9 cores. Add ARCH_HIX5HD2 to distinguish HiX5HD2 from Hi3xxx. They are different in implementation such as SMP, IPs integarted and earlycon configure. Signed-off-by: Haifeng Yan Signed-off-by: Jiancheng Xue Signed-off-by: Haojian Zhuang Acked-by: Wei Xu Signed-off-by: Olof Johansson --- arch/arm/mach-hisi/platsmp.c | 50 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-hisi/platsmp.c') diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c index 471f1ee3be2b..ecf7058d5c15 100644 --- a/arch/arm/mach-hisi/platsmp.c +++ b/arch/arm/mach-hisi/platsmp.c @@ -17,6 +17,8 @@ #include "core.h" +#define HIX5HD2_BOOT_ADDRESS 0xffff0000 + static void __iomem *ctrl_base; void hi3xxx_set_cpu_jump(int cpu, void *jump_addr) @@ -35,11 +37,9 @@ int hi3xxx_get_cpu_jump(int cpu) return readl_relaxed(ctrl_base + ((cpu - 1) << 2)); } -static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus) +static void __init hisi_enable_scu_a9(void) { - struct device_node *np = NULL; unsigned long base = 0; - u32 offset = 0; void __iomem *scu_base = NULL; if (scu_a9_has_base()) { @@ -52,6 +52,14 @@ static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus) scu_enable(scu_base); iounmap(scu_base); } +} + +static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus) +{ + struct device_node *np = NULL; + u32 offset = 0; + + hisi_enable_scu_a9(); if (!ctrl_base) { np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); if (!np) { @@ -87,3 +95,39 @@ struct smp_operations hi3xxx_smp_ops __initdata = { .cpu_kill = hi3xxx_cpu_kill, #endif }; + +static void __init hix5hd2_smp_prepare_cpus(unsigned int max_cpus) +{ + hisi_enable_scu_a9(); +} + +void hix5hd2_set_scu_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr) +{ + void __iomem *virt; + + virt = ioremap(start_addr, PAGE_SIZE); + + writel_relaxed(0xe51ff004, virt); /* ldr pc, [rc, #-4] */ + writel_relaxed(jump_addr, virt + 4); /* pc jump phy address */ + iounmap(virt); +} + +static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + phys_addr_t jumpaddr; + + jumpaddr = virt_to_phys(hix5hd2_secondary_startup); + hix5hd2_set_scu_boot_addr(HIX5HD2_BOOT_ADDRESS, jumpaddr); + hix5hd2_set_cpu(cpu, true); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + return 0; +} + + +struct smp_operations hix5hd2_smp_ops __initdata = { + .smp_prepare_cpus = hix5hd2_smp_prepare_cpus, + .smp_boot_secondary = hix5hd2_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = hix5hd2_cpu_die, +#endif +}; -- cgit v1.2.3-55-g7522 From c2fff85e21818952aa0ee5778926beee6c03e579 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 28 Jul 2014 20:14:32 +0800 Subject: ARM: hisi: remove smp from machine descriptor Use CPU_METHOD_OF_DECLARE() instead. And declare smp method in dts file. Changelog: v6: * Use hisilicon,hi3620-smp as enable-method property in Hi3620 dts. Signed-off-by: Haojian Zhuang Acked-by: Wei Xu Signed-off-by: Olof Johansson --- arch/arm/boot/dts/hi3620.dtsi | 1 + arch/arm/boot/dts/hisi-x5hd2-dkb.dts | 1 + arch/arm/mach-hisi/hisilicon.c | 4 ---- arch/arm/mach-hisi/platsmp.c | 3 +++ 4 files changed, 5 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-hisi/platsmp.c') diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi index ab1116d086be..a7b0d3d72adb 100644 --- a/arch/arm/boot/dts/hi3620.dtsi +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -33,6 +33,7 @@ cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "hisilicon,hi3620-smp"; cpu@0 { device_type = "cpu"; diff --git a/arch/arm/boot/dts/hisi-x5hd2-dkb.dts b/arch/arm/boot/dts/hisi-x5hd2-dkb.dts index 9eafb7b00a26..05b44c272c9a 100644 --- a/arch/arm/boot/dts/hisi-x5hd2-dkb.dts +++ b/arch/arm/boot/dts/hisi-x5hd2-dkb.dts @@ -21,6 +21,7 @@ cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "hisilicon,hix5hd2-smp"; cpu@0 { compatible = "arm,cortex-a9"; diff --git a/arch/arm/mach-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c index 7996c6b74339..7cda6dda3cd0 100644 --- a/arch/arm/mach-hisi/hisilicon.c +++ b/arch/arm/mach-hisi/hisilicon.c @@ -18,8 +18,6 @@ #include #include -#include "core.h" - #define HI3620_SYSCTRL_PHYS_BASE 0xfc802000 #define HI3620_SYSCTRL_VIRT_BASE 0xfe802000 @@ -55,7 +53,6 @@ static const char *hi3xxx_compat[] __initconst = { DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)") .map_io = hi3620_map_io, .dt_compat = hi3xxx_compat, - .smp = smp_ops(hi3xxx_smp_ops), MACHINE_END static const char *hix5hd2_compat[] __initconst = { @@ -65,5 +62,4 @@ static const char *hix5hd2_compat[] __initconst = { DT_MACHINE_START(HIX5HD2_DT, "Hisilicon HIX5HD2 (Flattened Device Tree)") .dt_compat = hix5hd2_compat, - .smp = smp_ops(hix5hd2_smp_ops), MACHINE_END diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c index ecf7058d5c15..575dd8285f1f 100644 --- a/arch/arm/mach-hisi/platsmp.c +++ b/arch/arm/mach-hisi/platsmp.c @@ -131,3 +131,6 @@ struct smp_operations hix5hd2_smp_ops __initdata = { .cpu_die = hix5hd2_cpu_die, #endif }; + +CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops); +CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops); -- cgit v1.2.3-55-g7522