[PATCH 1/5] ARM: Add platform support for LSI AXM55xx SoC

Anders Berg anders.berg at lsi.com
Thu Apr 24 01:58:58 PDT 2014


On Tue, Apr 15, 2014 at 02:30:55PM +0200, Arnd Bergmann wrote:
> On Tuesday 15 April 2014 14:06:10 Anders Berg wrote:
> 
> > diff --git a/arch/arm/mach-axxia/Kconfig b/arch/arm/mach-axxia/Kconfig
> > new file mode 100644
> > index 0000000..336426a
> > --- /dev/null
> > +++ b/arch/arm/mach-axxia/Kconfig
> > @@ -0,0 +1,19 @@
> > +config ARCH_AXXIA
> > +	bool "LSI Axxia platforms" if (ARCH_MULTI_V7 && ARM_LPAE)
> > +	select ARM_GIC
> > +	select HAVE_SMP
> > +	select MFD_SYSCON
> > +	select ARM_AMBA
> > +	select ARCH_WANT_OPTIONAL_GPIOLIB
> > +	select HAVE_ARM_ARCH_TIMER
> > +	select ARM_TIMER_SP804
> > +	select ZONE_DMA
> > +	select ARCH_DMA_ADDR_T_64BIT
> > +	select ARCH_SUPPORTS_BIG_ENDIAN
> > +	select MIGHT_HAVE_PCI
> > +	select PCI_DOMAINS if PCI
> 
> No need to select HAVE_SMP or ARCH_WANT_OPTIONAL_GPIOLIB any more.

OK.

> 
> We should rethink the ARCH_SUPPORTS_BIG_ENDIAN option I guess. It makes
> little sense to select that from one platform in a multiplatform build
> if other platforms don't support it.
> 
> > --- /dev/null
> > +++ b/arch/arm/mach-axxia/Makefile.boot
> > @@ -0,0 +1,2 @@
> > +   zreladdr-y	+= 0x00308000
> > +params_phys-y	:= 0x00300100
> 
> This won't be used, since AUTO_ZRELADDR is set by ARCH_MULTIPLATFORM.

OK.

> 
> > diff --git a/arch/arm/mach-axxia/axxia.c b/arch/arm/mach-axxia/axxia.c
> > new file mode 100644
> > index 0000000..8d85926
> > --- /dev/null
> > +++ b/arch/arm/mach-axxia/axxia.c
> > @@ -0,0 +1,117 @@
> > +/*
> > + * Support for the LSI Axxia SoC devices based on ARM cores.
> > + *
> > + * Copyright (C) 2012 LSI
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#include <linux/amba/bus.h>
> > +#include <linux/device.h>
> > +#include <linux/dma-mapping.h>
> > +#include <linux/init.h>
> > +#include <linux/io.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/kernel.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/sizes.h>
> > +#include <asm/mach/arch.h>
> > +#include <asm/pmu.h>
> > +#include "axxia.h"
> > +
> > +/*
> > + * The PMU IRQ lines of four cores are wired together into a single interrupt.
> > + * Bounce the interrupt to other cores if it's not ours.
> > + */
> > +static irqreturn_t axxia_pmu_handler(int irq, void *dev, irq_handler_t handler)
> > +{
> > +	irqreturn_t ret = handler(irq, dev);
> > +
> > +	if (ret == IRQ_NONE) {
> > +		int cpu = smp_processor_id();
> > +		int cluster = cpu / CORES_PER_CLUSTER;
> > +		int other;
> > +
> > +		/* Look until we find another cpu that's online. */
> > +		do {
> > +			other = (++cpu % CORES_PER_CLUSTER) +
> > +				(cluster * CORES_PER_CLUSTER);
> > +		} while (!cpu_online(other));
> > +
> > +		irq_set_affinity(irq, cpumask_of(other));
> > +	}
> > +
> > +	/*
> > +	 * We should be able to get away with the amount of IRQ_NONEs we give,
> > +	 * while still having the spurious IRQ detection code kick in if the
> > +	 * interrupt really starts hitting spuriously.
> > +	 */
> > +	return ret;
> > +}
> > +
> > +static struct arm_pmu_platdata pmu_pdata = {
> > +	.handle_irq = axxia_pmu_handler,
> > +};
> > +
> > +static struct of_dev_auxdata axxia_auxdata_lookup[] __initdata = {
> > +	OF_DEV_AUXDATA("arm,cortex-a15-pmu", 0, "pmu", &pmu_pdata),
> > +	{}
> > +};
> 
> This looks similar to what we have in mach-ux500 as db8500_pmu_handler.
> 
> To avoid duplication, I'd prefer moving support for this into the
> perf_event code itself, and get rid of the auxdata.
> 

I'll drop it fow now.

> > +static int
> > +axxia_bus_notifier(struct notifier_block *nb, unsigned long event, void *obj)
> > +{
> > +	struct device *dev = obj;
> > +
> > +	if (event != BUS_NOTIFY_ADD_DEVICE)
> > +		return NOTIFY_DONE;
> > +
> > +	if (!of_property_read_bool(dev->of_node, "dma-coherent"))
> > +		return NOTIFY_DONE;
> > +
> > +	set_dma_ops(dev, &arm_coherent_dma_ops);
> > +
> > +	return NOTIFY_OK;
> > +}
> > +
> > +static struct notifier_block axxia_platform_nb = {
> > +	.notifier_call = axxia_bus_notifier,
> > +};
> > +
> > +static struct notifier_block axxia_amba_nb = {
> > +	.notifier_call = axxia_bus_notifier,
> > +};
> 
> And we definitely want to do this in a generic fashion. That should not be in
> platform specific code.

I'll drop this too. I saw there was some work in progress on this.

> 
> > +static const char *axxia_dt_match[] __initconst = {
> > +	"lsi,axm55xx",
> > +	"lsi,axm55xx-sim",
> > +	"lsi,axm55xx-emu",
> > +	NULL
> > +};
> 
> Please no 'xx' in compatible strings. You can list all the relevant
> model numbers here, or require that machines list a specific model
> as compatible, e.g.
> 
> 	compatible = "lsi,axm5510-sim", "lsi,axm5510", "lsi,axm5502";
> 

Got that. I'll use lsi,axm5516 as the complatible model number.

> > +
> > +DT_MACHINE_START(AXXIA_DT, "LSI Axxia AXM55XX")
> > +	.dt_compat	= axxia_dt_match,
> > +	.smp		= smp_ops(axxia_smp_ops),
> > +	.init_machine	= axxia_dt_init,
> > +MACHINE_END
> 
> Please have a look at how smp ops are hooked up in mach-qcom and see
> if you can do it that way as well.
> 

Yes, that will work nicely.

> > diff --git a/arch/arm/mach-axxia/axxia.h b/arch/arm/mach-axxia/axxia.h
> > new file mode 100644
> > index 0000000..594dd97
> > --- /dev/null
> > +++ b/arch/arm/mach-axxia/axxia.h
> > @@ -0,0 +1,42 @@
> > +/*
> > + * Prototypes for platform functions.
> > + *
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, see <http://www.gnu.org/licenses/>.
> > + */
> > +#ifndef __AXXIA_H
> > +#define __AXXIA_H
> > +
> > +#define CORES_PER_CLUSTER      4
> > +
> > +#define AXXIA_PERIPH_PHYS      0x2000000000ULL
> > +#define AXXIA_SYSCON_PHYS      0x2010030000ULL
> 
> Remove these -- they have to come from DT.
> 
> > +#if 0
> > +#define AXXIA_UART0_PHYS       0x2010080000ULL
> > +#define AXXIA_UART1_PHYS       0x2010081000ULL
> > +#define AXXIA_UART2_PHYS       0x2010082000ULL
> > +#define AXXIA_UART3_PHYS       0x2010083000ULL
> > +
> > +#ifdef CONFIG_DEBUG_LL
> > +#define AXXIA_DEBUG_UART_VIRT  0xf0080000
> > +#define AXXIA_DEBUG_UART_PHYS  AXXIA_UART0_PHYS
> > +#endif
> > +#endif
> 
> You can put these constants directly into debug code.
> 

Ok.

> 
> > diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
> > new file mode 100644
> > index 0000000..fd7f507
> > --- /dev/null
> > +++ b/arch/arm/mach-axxia/platsmp.c
> > @@ -0,0 +1,183 @@
> > +/*
> > + *  linux/arch/arm/mach-axxia/platsmp.c
> > + *
> > + *  Copyright (C) 2012 LSI Corporation
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> 
> Have you considered using PSCI to bring up the secondary CPUs?
> 

The current u-boot is a bit dated... But I agree. I'll push for an update to this.

> > +static int axxia_boot_secondary(unsigned int cpu,
> > +					  struct task_struct *idle)
> > +{
> > +	unsigned long timeout;
> > +
> > +	/* Release the specified core */
> > +	write_pen_release(cpu_logical_map(cpu));
> > +
> > +	/* Send a wakeup event to get the idled cpu out of WFE state */
> > +	dsb_sev();
> > +
> > +	/* Wait for so long, then give up if nothing happens ... */
> > +	timeout = jiffies + (1 * HZ);
> > +	while (time_before(jiffies, timeout)) {
> > +		/* Make sure stores to pen_release have completed */
> > +		smp_rmb();
> > +		if (pen_release == -1)
> > +			break;
> > +		udelay(1);
> > +	}
> > +
> > +	return pen_release != -1 ? -ENOSYS : 0;
> > +}
> 
> This is pretty sad. No hardware support for waking up CPUs?
> 

I'll rework this. There are sw control of the resets to individual cores. And
the holding pen is not needed (too much other platsmp implementations), I will
have the secondary cores released directly into secondary_startup.

> > +static void __init axxia_smp_prepare_cpus(unsigned int max_cpus)
> > +{
> > +	void __iomem *syscon;
> > +	int cpu_count = 0;
> > +	int cpu;
> > +
> > +	syscon = ioremap(AXXIA_SYSCON_PHYS, SZ_64K);
> > +	if (WARN_ON(!syscon))
> > +		return;
> > +
> > +	check_fixup_sev(syscon);
> 
> Please use the syscon driver and regmap. That driver might need a little
> help to get syscon_node_to_regmap() to work before driver initialization,
> but other people need the same thing, and we should just implement it.

Ok, until then... I'll drop the hardcoded address and get the address from the
syscon node.

> 
> > diff --git a/drivers/clk/clk-axxia.c b/drivers/clk/clk-axxia.c
> > new file mode 100644
> > index 0000000..996b8f2
> > --- /dev/null
> > +++ b/drivers/clk/clk-axxia.c
> > @@ -0,0 +1,281 @@
> > +/*
> > + * arch/arm/mach-axxia/clock.c
> 
> This should be a separate patch, and get merged by the clk maintainer.
Ok.

I'll submit a v2 with the corrections.

/Anders

> 
> 	Arnd
> 
> 



More information about the linux-arm-kernel mailing list