On Sun, Nov 18, 2018 at 7:00 PM Sugaya Taichi <sugaya.taichi@xxxxxxxxxxxxx> wrote: > > This adds the basic M10V SoC support under arch/arm. > Since all cores are activated in the custom bootloader before booting > linux, it is necessary to wait for sub-cores using the trampoline area. > > Signed-off-by: Sugaya Taichi <sugaya.taichi@xxxxxxxxxxxxx> > --- > arch/arm/Kconfig | 2 + > arch/arm/Makefile | 1 + > arch/arm/mach-milbeaut/Kconfig | 28 +++++++ > arch/arm/mach-milbeaut/Makefile | 3 + > arch/arm/mach-milbeaut/m10v_evb.c | 31 ++++++++ > arch/arm/mach-milbeaut/platsmp.c | 157 ++++++++++++++++++++++++++++++++++++++ > 6 files changed, 222 insertions(+) > create mode 100644 arch/arm/mach-milbeaut/Kconfig > create mode 100644 arch/arm/mach-milbeaut/Makefile > create mode 100644 arch/arm/mach-milbeaut/m10v_evb.c > create mode 100644 arch/arm/mach-milbeaut/platsmp.c > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 91be74d..0b8a1af 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -767,6 +767,8 @@ source "arch/arm/mach-mediatek/Kconfig" > > source "arch/arm/mach-meson/Kconfig" > > +source "arch/arm/mach-milbeaut/Kconfig" > + > source "arch/arm/mach-mmp/Kconfig" > > source "arch/arm/mach-moxart/Kconfig" > diff --git a/arch/arm/Makefile b/arch/arm/Makefile > index 05a91d8..627853c 100644 > --- a/arch/arm/Makefile > +++ b/arch/arm/Makefile > @@ -190,6 +190,7 @@ machine-$(CONFIG_ARCH_MV78XX0) += mv78xx0 > machine-$(CONFIG_ARCH_MVEBU) += mvebu > machine-$(CONFIG_ARCH_MXC) += imx > machine-$(CONFIG_ARCH_MEDIATEK) += mediatek > +machine-$(CONFIG_ARCH_MILBEAUT) += milbeaut > machine-$(CONFIG_ARCH_MXS) += mxs > machine-$(CONFIG_ARCH_NETX) += netx > machine-$(CONFIG_ARCH_NOMADIK) += nomadik > diff --git a/arch/arm/mach-milbeaut/Kconfig b/arch/arm/mach-milbeaut/Kconfig > new file mode 100644 > index 0000000..63b6f69 > --- /dev/null > +++ b/arch/arm/mach-milbeaut/Kconfig > @@ -0,0 +1,28 @@ > +# SPDX-License-Identifier: GPL-2.0 > +menuconfig ARCH_MILBEAUT > + bool "Socionext Milbeaut SoCs" > + depends on ARCH_MULTI_V7 > + select ARM_GIC > + select CLKDEV_LOOKUP > + select GENERIC_CLOCKEVENTS > + select CLKSRC_MMIO The clock and timer drivers' kconfig entries should select these. > + select ZONE_DMA Why is this needed? > + help > + This enables support for Socionext Milbeaut SoCs > + > +if ARCH_MILBEAUT > + > +config ARCH_MILBEAUT_M10V > + bool "Milbeaut SC2000/M10V platform" > + select ARM_ARCH_TIMER > + select M10V_TIMER > + select PINCTRL > + select PINCTRL_M10V > + help > + Support for Socionext's MILBEAUT M10V based systems > + > +config MACH_M10V_EVB > + bool "Support for Milbeaut Evaluation boards" You shouldn't need a kconfig entry for each board. > + default y > + > +endif > diff --git a/arch/arm/mach-milbeaut/Makefile b/arch/arm/mach-milbeaut/Makefile > new file mode 100644 > index 0000000..64f6f52 > --- /dev/null > +++ b/arch/arm/mach-milbeaut/Makefile > @@ -0,0 +1,3 @@ > +obj-$(CONFIG_SMP) += platsmp.o > +obj-$(CONFIG_MACH_M10V_EVB) += m10v_evb.o > + > diff --git a/arch/arm/mach-milbeaut/m10v_evb.c b/arch/arm/mach-milbeaut/m10v_evb.c > new file mode 100644 > index 0000000..a1fa7c3 > --- /dev/null > +++ b/arch/arm/mach-milbeaut/m10v_evb.c This all looks SoC specific, not board specific. > @@ -0,0 +1,31 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018 Socionext Inc. > + * Copyright: (C) 2015 Linaro Ltd. > + */ > + > +#include <linux/of.h> > +#include <linux/platform_device.h> Not needed. > + > +#include <asm/mach/arch.h> > +#include <asm/mach/map.h> > + > +static struct map_desc m10v_io_desc[] __initdata = { > +}; > + > +void __init m10v_map_io(void) > +{ > + debug_ll_io_init(); If you use earlycon instead, then this isn't needed. > + iotable_init(m10v_io_desc, ARRAY_SIZE(m10v_io_desc)); This isn't needed. > +} > + > +static const char * const m10v_compat[] = { > + "socionext,milbeaut-m10v-evb", > + NULL, > +}; > + > +DT_MACHINE_START(M10V_REB, "Socionext Milbeaut") > + .dt_compat = m10v_compat, > + .l2c_aux_mask = 0xffffffff, > + .map_io = m10v_map_io, It looks like you can remove this entire file and use the default machine desc. > +MACHINE_END > diff --git a/arch/arm/mach-milbeaut/platsmp.c b/arch/arm/mach-milbeaut/platsmp.c > new file mode 100644 > index 0000000..b706851 > --- /dev/null > +++ b/arch/arm/mach-milbeaut/platsmp.c > @@ -0,0 +1,157 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018 Socionext Inc. > + * Copyright: (C) 2015 Linaro Ltd. > + */ > + > +#include <linux/cpu_pm.h> > +#include <linux/irqchip/arm-gic.h> > +#include <linux/of_device.h> Not needed. > +#include <linux/of_address.h> > +#include <linux/platform_device.h> Not needed. > +#include <linux/suspend.h> > + > +#include <asm/cacheflush.h> > +#include <asm/cp15.h> > +#include <asm/idmap.h> > +#include <asm/smp_plat.h> > +#include <asm/suspend.h> > + > +#define M10V_MAX_CPU 4 > + > +#define KERNEL_UNBOOT_FLAG 0x12345678 > +#define CPU_FINISH_SUSPEND_FLAG 0x56784321 > + > +static void __iomem *trampoline; > + > +static int m10v_boot_secondary(unsigned int l_cpu, struct task_struct *idle) > +{ > + unsigned int mpidr, cpu, cluster; > + > + mpidr = cpu_logical_map(l_cpu); > + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); > + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); > + > + if (cpu >= M10V_MAX_CPU) > + return -EINVAL; > + > + pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); > + > + writel(virt_to_phys(secondary_startup), trampoline + cpu * 4); > + arch_send_wakeup_ipi_mask(cpumask_of(l_cpu)); > + > + return 0; > +} > + > +static void m10v_cpu_die(unsigned int l_cpu) > +{ > + gic_cpu_if_down(0); > + > + v7_exit_coherency_flush(louis); > + > + /* Now we are prepared for power-down, do it: */ > + wfi(); > +} > + > +static int m10v_cpu_kill(unsigned int l_cpu) > +{ > + unsigned int mpidr, cpu; > + > + mpidr = cpu_logical_map(l_cpu); > + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); > + > + writel(KERNEL_UNBOOT_FLAG, trampoline + cpu * 4); > + > + return 1; > +} > + > +static struct smp_operations m10v_smp_ops __initdata = { > + .smp_boot_secondary = m10v_boot_secondary, > + .cpu_die = m10v_cpu_die, > + .cpu_kill = m10v_cpu_kill, > +}; > + > +static int __init m10v_smp_init(void) > +{ > + unsigned int mpidr, cpu, cluster; > + struct device_node *np; > + > + np = of_find_compatible_node(NULL, NULL, "socionext,milbeaut-m10v-evb"); > + if (!np || !of_device_is_available(np)) Just use of_machine_is_compatible() here. > + return -ENODEV; > + of_node_put(np); > + > + np = of_find_compatible_node(NULL, NULL, "socionext,smp-trampoline"); > + if (!np) > + return -ENODEV; > + > + trampoline = of_iomap(np, 0); > + if (!trampoline) > + return -ENODEV; > + of_node_put(np); > + > + mpidr = read_cpuid_mpidr(); > + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); > + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); > + > + pr_info("MCPM boot on cpu_%u cluster_%u\n", cpu, cluster); > + > + for (cpu = 0; cpu < M10V_MAX_CPU; cpu++) > + writel(KERNEL_UNBOOT_FLAG, trampoline + cpu * 4); > + > + smp_set_ops(&m10v_smp_ops); > + > + return 0; > +} > +early_initcall(m10v_smp_init); > + > +static int m10v_pm_valid(suspend_state_t state) > +{ > + return (state == PM_SUSPEND_STANDBY) || (state == PM_SUSPEND_MEM); > +} > + > +typedef void (*phys_reset_t)(unsigned long); > +static phys_reset_t phys_reset; > + > +static int m10v_die(unsigned long arg) > +{ > + setup_mm_for_reboot(); > + asm("wfi"); > + /* Boot just like a secondary */ > + phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset); > + phys_reset(virt_to_phys(cpu_resume)); > + > + return 0; > +} > + > +static int m10v_pm_enter(suspend_state_t state) > +{ > + switch (state) { > + case PM_SUSPEND_STANDBY: > + pr_err("STANDBY\n"); > + asm("wfi"); > + break; > + case PM_SUSPEND_MEM: > + pr_err("SUSPEND\n"); > + cpu_pm_enter(); > + cpu_suspend(0, m10v_die); > + cpu_pm_exit(); > + break; > + } > + return 0; > +} > + > +static const struct platform_suspend_ops m10v_pm_ops = { > + .valid = m10v_pm_valid, > + .enter = m10v_pm_enter, > +}; > + > +struct clk *m10v_clclk_register(struct device *cpu_dev); > + > +static int __init m10v_pm_init(void) > +{ > + suspend_set_ops(&m10v_pm_ops); > + > + return 0; > +} > +late_initcall(m10v_pm_init); > -- > 1.9.1 >