[PATCH v7 08/11] ARM: hi3xxx: add smp support
Olof Johansson
olof at lixom.net
Tue Aug 27 22:12:11 EDT 2013
Hi,
Some comments below.
On Tue, Aug 20, 2013 at 10:31:10AM +0800, Haojian Zhuang wrote:
> From: Zhangfei Gao <zhangfei.gao at linaro.org>
>
> Enable SMP support on hi3xxx platform
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao at linaro.org>
> Tested-by: Zhang Mingjun <zhang.mingjun at linaro.org>
> Tested-by: Li Xin <li.xin at linaro.org>
> ---
> .../bindings/arm/hisilicon/hisilicon.txt | 47 ++++++++++++++++
> arch/arm/boot/dts/hi3620.dtsi | 28 +++++++++-
> arch/arm/boot/dts/hi4511.dts | 2 +-
> arch/arm/mach-hi3xxx/Kconfig | 2 +
> arch/arm/mach-hi3xxx/Makefile | 3 +-
> arch/arm/mach-hi3xxx/core.h | 14 +++++
> arch/arm/mach-hi3xxx/hi3xxx.c | 5 ++
> arch/arm/mach-hi3xxx/platsmp.c | 43 ++++++++++++++
> arch/arm/mach-hi3xxx/system.c | 65 ++++++++++++++++++++++
> 9 files changed, 206 insertions(+), 3 deletions(-)
> create mode 100644 arch/arm/mach-hi3xxx/core.h
> create mode 100644 arch/arm/mach-hi3xxx/platsmp.c
> create mode 100644 arch/arm/mach-hi3xxx/system.c
>
> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
> index 3be60c8..4cc5c57 100644
> --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
> +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
> @@ -8,3 +8,50 @@ Required root node properties:
> Hi4511 Board
> Required root node properties:
> - compatible = "hisilicon,hi3620-hi4511";
> +
> +
> +Hisilicon sctrl resiter
Resiter seems like odd naming here.
> +
> +Required properties:
> +- compatible : "hisilicon,sctrl"
> +- reg : Address and size of sysctrl.
sysctrl or sctrl? sysctrl isn't really too long, might as well use that.
> +
> +Optional properties:
> +- smp_reg : offset in sysctrl for notifying slave cpu booting
> + cpu 1, reg;
> + cpu 2, reg + 0x4;
> + cpu 3, reg + 0x8;
> + If reg value is not zero, cpun exit wfi and go
> +- resume_reg : offset in sysctrl for notifying cpu0 when resume
> +- reset_reg : offset in sysctrl for system reset
Underscores are usually not used in properties, you use dashes instead.
Anyway, I suggest defining those as the different cells in a regular 'reg'
property instead.
> +
> +Example:
> + hi3716:
> + sctrl at f8000000 {
Labels are usually not done on a separate line before.
Common node names would be more clear-text than this. Maybe "system-controller"
in this case.
> + compatible = "hisilicon,sctrl";
> + reg = <0xf8000000 0x1000>;
> + smp_reg = <0xc0>;
> + reboot_reg = <0x4>;
> + };
> +
> + hi3620:
> + sctrl at fc802000 {
> + compatible = "hisilicon,sctrl";
> + reg = <0xfc802000 0x1000>;
> + smp_reg = <0x31c>;
> + resume_reg = <0x308>;
> + reboot_reg = <0x4>;
> + };
> +
> +Hi3716 cpuctrl register
> +Required properties:
> +- compatible : "hisilicon,cpuctrl"
> +- reg : Address and size of cpuctrl.
> +
> +Hi3716 specific cpuctrl register, control hotplug info etc.
Controlling hotplug _info_? Seems like odd wording here.
> +Example:
> + hi3716:
> + cpuctrl at f8a22000 {
> + compatible = "hisilicon,cpuctrl";
> + reg = <0xf8a22000 0x2000>;
> + };
> diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
> index 39fa37f..ee81192 100644
> --- a/arch/arm/boot/dts/hi3620.dtsi
> +++ b/arch/arm/boot/dts/hi3620.dtsi
> @@ -32,6 +32,24 @@
> reg = <0x0>;
> next-level-cache = <&L2>;
> };
> + cpu1: cpu at 1 {
Do you need labels here? I don't think these are referred to as phandles
anywhere?
> + compatible = "arm,cortex-a9";
> + device_type = "cpu";
> + reg = <1>;
> + next-level-cache = <&L2>;
> + };
> + cpu2: cpu at 2 {
> + compatible = "arm,cortex-a9";
> + device_type = "cpu";
> + reg = <2>;
> + next-level-cache = <&L2>;
> + };
> + cpu3: cpu at 3 {
> + compatible = "arm,cortex-a9";
> + device_type = "cpu";
> + reg = <3>;
> + next-level-cache = <&L2>;
> + };
> };
>
> osc32k: osc32k {
> @@ -130,7 +148,9 @@
> reg = <0xfc802000 0x1000>;
> #address-cells = <1>;
> #size-cells = <0>;
> -
> + smp_reg = <0x31c>;
> + resume_reg = <0x308>;
> + reboot_reg = <0x4>;
>
> timer0_mux: timer0_mux {
> compatible = "hisilicon,clk-mux";
> @@ -1242,6 +1262,12 @@
> status = "disabled";
> };
>
> + timer5: timer at fc000600 {
> + compatible = "arm,cortex-a9-twd-timer";
> + reg = <0xfc000600 0x20>;
> + interrupts = <1 13 0xf01>;
> + };
> +
> uart0: uart at fcb00000 {
> compatible = "arm,pl011", "arm,primecell";
> reg = <0xfcb00000 0x1000>;
> diff --git a/arch/arm/boot/dts/hi4511.dts b/arch/arm/boot/dts/hi4511.dts
> index 7e67564..c9fd329 100644
> --- a/arch/arm/boot/dts/hi4511.dts
> +++ b/arch/arm/boot/dts/hi4511.dts
> @@ -15,7 +15,7 @@
> compatible = "hisilicon,hi3620-hi4511";
>
> chosen {
> - bootargs = "console=ttyAMA0,115200 root=/dev/ram0 earlyprintk";
> + bootargs = "console=ttyAMA0,115200 root=/dev/ram0 nr_cpus=4 earlyprintk";
nr_cpus should not be needed on the command line.
> };
>
> memory {
> diff --git a/arch/arm/mach-hi3xxx/Kconfig b/arch/arm/mach-hi3xxx/Kconfig
> index 68bd26c..d2e7d57 100644
> --- a/arch/arm/mach-hi3xxx/Kconfig
> +++ b/arch/arm/mach-hi3xxx/Kconfig
> @@ -6,6 +6,8 @@ config ARCH_HI3xxx
> select CACHE_L2X0
> select CLKSRC_OF
> select GENERIC_CLOCKEVENTS
> + select HAVE_ARM_SCU
> + select HAVE_SMP
> select PINCTRL
> select PINCTRL_SINGLE
> help
> diff --git a/arch/arm/mach-hi3xxx/Makefile b/arch/arm/mach-hi3xxx/Makefile
> index d68ebb3..0917f1c 100644
> --- a/arch/arm/mach-hi3xxx/Makefile
> +++ b/arch/arm/mach-hi3xxx/Makefile
> @@ -2,4 +2,5 @@
> # Makefile for Hisilicon Hi36xx/Hi37xx processors line
> #
>
> -obj-y += hi3xxx.o
> +obj-y += hi3xxx.o system.o
> +obj-$(CONFIG_SMP) += platsmp.o
> diff --git a/arch/arm/mach-hi3xxx/core.h b/arch/arm/mach-hi3xxx/core.h
> new file mode 100644
> index 0000000..2cfd643
> --- /dev/null
> +++ b/arch/arm/mach-hi3xxx/core.h
> @@ -0,0 +1,14 @@
> +#ifndef __HISILICON_CORE_H
> +#define __HISILICON_CORE_H
> +
> +#include <linux/init.h>
I don't think you need linux/init.h here?
> +#include <linux/reboot.h>
> +
> +extern void hs_set_cpu_jump(int cpu, void *jump_addr);
> +extern int hs_get_cpu_jump(int cpu);
> +extern void secondary_startup(void);
> +extern void hs_map_io(void);
> +extern void hs_restart(enum reboot_mode, const char *cmd);
> +extern struct smp_operations hs_smp_ops;
> +
> +#endif
> diff --git a/arch/arm/mach-hi3xxx/hi3xxx.c b/arch/arm/mach-hi3xxx/hi3xxx.c
> index e7c54bc..567a0d5 100644
> --- a/arch/arm/mach-hi3xxx/hi3xxx.c
> +++ b/arch/arm/mach-hi3xxx/hi3xxx.c
> @@ -19,8 +19,11 @@
> #include <asm/mach/arch.h>
> #include <asm/mach/map.h>
>
> +#include "core.h"
> +
> static void __init hi3xxx_timer_init(void)
> {
> + hs_map_io();
> of_clk_init(NULL);
> clocksource_of_init();
> }
> @@ -33,4 +36,6 @@ static const char *hs_compat[] __initdata = {
> DT_MACHINE_START(HI3xxx, "Hisilicon Hi36xx/Hi37xx (Flattened Device Tree)")
> .init_time = hi3xxx_timer_init,
> .dt_compat = hs_compat,
> + .smp = smp_ops(hs_smp_ops),
> + .restart = hs_restart,
> MACHINE_END
> diff --git a/arch/arm/mach-hi3xxx/platsmp.c b/arch/arm/mach-hi3xxx/platsmp.c
> new file mode 100644
> index 0000000..a76a3cc
> --- /dev/null
> +++ b/arch/arm/mach-hi3xxx/platsmp.c
> @@ -0,0 +1,43 @@
> +/*
> + * Copyright (c) 2013 Linaro Ltd.
> + * Copyright (c) 2013 Hisilicon Limited.
> + * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + */
> +#include <linux/smp.h>
> +#include <linux/io.h>
> +#include <asm/smp_scu.h>
> +
> +#include "core.h"
> +
> +static void __init hs_smp_prepare_cpus(unsigned int max_cpus)
> +{
> + unsigned long base;
> + void __iomem *scu_base;
> +
> + if (scu_a9_has_base()) {
> + base = scu_a9_get_base();
> + scu_base = ioremap(base, SZ_4K);
> + if (!scu_base) {
> + pr_err("ioremap(scu_base) failed\n");
> + return;
> + }
> + scu_enable(scu_base);
> + iounmap(scu_base);
> + }
> +}
> +
> +static int hs_boot_secondary(unsigned int cpu, struct task_struct *idle)
> +{
> + hs_set_cpu_jump(cpu, secondary_startup);
> + arch_send_wakeup_ipi_mask(cpumask_of(cpu));
> + return 0;
> +}
> +
> +struct smp_operations hs_smp_ops __initdata = {
> + .smp_prepare_cpus = hs_smp_prepare_cpus,
> + .smp_boot_secondary = hs_boot_secondary,
> +};
> diff --git a/arch/arm/mach-hi3xxx/system.c b/arch/arm/mach-hi3xxx/system.c
> new file mode 100644
> index 0000000..51bb247
> --- /dev/null
> +++ b/arch/arm/mach-hi3xxx/system.c
> @@ -0,0 +1,65 @@
> +/*
> + * Copyright (c) 2013 Linaro Ltd.
> + * Copyright (c) 2013 Hisilicon Limited.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + */
> +#include <linux/io.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +
> +#include <asm/proc-fns.h>
> +#include <asm/smp_plat.h>
> +
> +#include "core.h"
> +
> +static void __iomem *hs_sctrl_base;
> +static int hs_smp_reg;
> +static int hs_resume_reg;
> +static int hs_reboot_reg;
> +
> +void hs_map_io(void)
> +{
> + struct device_node *np;
> +
> + np = of_find_compatible_node(NULL, NULL, "hisilicon,sctrl");
> + if (np) {
> + hs_sctrl_base = of_iomap(np, 0);
> + if (!hs_sctrl_base)
> + pr_err("of_iomap(sctrl_base) failed\n");
> + of_property_read_u32(np, "smp_reg", &hs_smp_reg);
> + of_property_read_u32(np, "resume_reg", &hs_resume_reg);
> + of_property_read_u32(np, "reboot_reg", &hs_reboot_reg);
> + }
> +}
> +
> +void hs_set_cpu_jump(int cpu, void *jump_addr)
> +{
> + int offset = hs_smp_reg;
> +
> + cpu = cpu_logical_map(cpu);
> + if (cpu > 0)
> + offset += 0x04 * (cpu - 1);
> + writel_relaxed(virt_to_phys(jump_addr), hs_sctrl_base + offset);
> +}
> +
> +int hs_get_cpu_jump(int cpu)
> +{
> + int offset = hs_smp_reg;
> +
> + cpu = cpu_logical_map(cpu);
> + if (cpu > 0)
> + offset += 0x04 * (cpu - 1);
> + return readl_relaxed(hs_sctrl_base + offset);
> +}
> +
> +void hs_restart(enum reboot_mode mode, const char *cmd)
> +{
> + writel_relaxed(0xdeadbeef, hs_sctrl_base + hs_reboot_reg);
> +
> + while (1)
> + cpu_do_idle();
> +}
> +
> --
> 1.8.1.2
>
More information about the linux-arm-kernel
mailing list