RE: [PATCH 01/14] ARM: milbeaut: Add basic support for Milbeaut m10v SoC

From: sugaya.taichi
Date: Wed Nov 21 2018 - 04:33:37 EST


Hi Rob

Thank you for your comments.

> -----Original Message-----
> From: Rob Herring [mailto:robh+dt@xxxxxxxxxx]
> Sent: Tuesday, November 20, 2018 1:24 AM
> To: Sugaya, Taichi
> Cc: linux-clk; devicetree@xxxxxxxxxxxxxxx; moderated list:ARM/FREESCALE
> IMX / MXC ARM ARCHITECTURE; linux-kernel@xxxxxxxxxxxxxxx; open list:SERIAL
> DRIVERS; Michael Turquette; Stephen Boyd; Mark Rutland; Greg Kroah-Hartman;
> Daniel Lezcano; Thomas Gleixner; Russell King; Jiri Slaby; Masami Hiramatsu;
> Jassi Brar
> Subject: Re: [PATCH 01/14] ARM: milbeaut: Add basic support for Milbeaut
> m10v SoC
>
> 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.
OK. move these to the correct kconfig.

>
> > + select ZONE_DMA
>
> Why is this needed?
Ah, it may not be needed yet. confirm it.

>
> > + 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.
I see.

>
> > + 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.
Um that is right..

>
> > @@ -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.
OK.

>
> > +
> > +#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.
OK.

>
> > +}
> > +
> > +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.
OK, try to use the default machine descriptor instead.

>
> > +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.
Okay.

>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
>
> Not needed.
Okay.

>
> > +#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.
I got it, use the function instead.

Thanks
Sugaya Taichi

>
> > + 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
> >