summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-axxia
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 10:05:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 10:05:51 +0000
commit5d1646d90e1f2cceb9f0828f4b28318cd0ec7744 (patch)
treea94efe259b9009378be6d90eb30d2b019d95c194 /arch/arm/mach-axxia
parentInitial commit. (diff)
downloadlinux-5d1646d90e1f2cceb9f0828f4b28318cd0ec7744.tar.xz
linux-5d1646d90e1f2cceb9f0828f4b28318cd0ec7744.zip
Adding upstream version 5.10.209.upstream/5.10.209upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'arch/arm/mach-axxia')
-rw-r--r--arch/arm/mach-axxia/Kconfig15
-rw-r--r--arch/arm/mach-axxia/Makefile3
-rw-r--r--arch/arm/mach-axxia/axxia.c19
-rw-r--r--arch/arm/mach-axxia/platsmp.c87
4 files changed, 124 insertions, 0 deletions
diff --git a/arch/arm/mach-axxia/Kconfig b/arch/arm/mach-axxia/Kconfig
new file mode 100644
index 000000000..d3eae6037
--- /dev/null
+++ b/arch/arm/mach-axxia/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+config ARCH_AXXIA
+ bool "LSI Axxia platforms"
+ depends on ARCH_MULTI_V7 && ARM_LPAE
+ select ARM_AMBA
+ select ARM_GIC
+ select ARM_TIMER_SP804
+ select HAVE_ARM_ARCH_TIMER
+ select MFD_SYSCON
+ select ZONE_DMA
+ help
+ This enables support for the LSI Axxia devices.
+
+ The LSI Axxia platforms require a Flattened Device Tree to be passed
+ to the kernel.
diff --git a/arch/arm/mach-axxia/Makefile b/arch/arm/mach-axxia/Makefile
new file mode 100644
index 000000000..8df8fe76a
--- /dev/null
+++ b/arch/arm/mach-axxia/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y += axxia.o
+obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-axxia/axxia.c b/arch/arm/mach-axxia/axxia.c
new file mode 100644
index 000000000..e21582a7f
--- /dev/null
+++ b/arch/arm/mach-axxia/axxia.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Support for the LSI Axxia SoC devices based on ARM cores.
+ *
+ * Copyright (C) 2012 LSI
+ */
+#include <linux/init.h>
+#include <asm/mach/arch.h>
+
+static const char *const axxia_dt_match[] __initconst = {
+ "lsi,axm5516",
+ "lsi,axm5516-sim",
+ "lsi,axm5516-emu",
+ NULL
+};
+
+DT_MACHINE_START(AXXIA_DT, "LSI Axxia AXM55XX")
+ .dt_compat = axxia_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
new file mode 100644
index 000000000..2e203626e
--- /dev/null
+++ b/arch/arm/mach-axxia/platsmp.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * linux/arch/arm/mach-axxia/platsmp.c
+ *
+ * Copyright (C) 2012 LSI Corporation
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/cacheflush.h>
+
+/* Syscon register offsets for releasing cores from reset */
+#define SC_CRIT_WRITE_KEY 0x1000
+#define SC_RST_CPU_HOLD 0x1010
+
+/*
+ * Write the kernel entry point for secondary CPUs to the specified address
+ */
+static void write_release_addr(u32 release_phys)
+{
+ u32 *virt = (u32 *) phys_to_virt(release_phys);
+ writel_relaxed(__pa_symbol(secondary_startup), virt);
+ /* Make sure this store is visible to other CPUs */
+ smp_wmb();
+ __cpuc_flush_dcache_area(virt, sizeof(u32));
+}
+
+static int axxia_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ struct device_node *syscon_np;
+ void __iomem *syscon;
+ u32 tmp;
+
+ syscon_np = of_find_compatible_node(NULL, NULL, "lsi,axxia-syscon");
+ if (!syscon_np)
+ return -ENOENT;
+
+ syscon = of_iomap(syscon_np, 0);
+ of_node_put(syscon_np);
+ if (!syscon)
+ return -ENOMEM;
+
+ tmp = readl(syscon + SC_RST_CPU_HOLD);
+ writel(0xab, syscon + SC_CRIT_WRITE_KEY);
+ tmp &= ~(1 << cpu);
+ writel(tmp, syscon + SC_RST_CPU_HOLD);
+
+ return 0;
+}
+
+static void __init axxia_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int cpu_count = 0;
+ int cpu;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs actually
+ * populated at the present time.
+ */
+ for_each_possible_cpu(cpu) {
+ struct device_node *np;
+ u32 release_phys;
+
+ np = of_get_cpu_node(cpu, NULL);
+ if (!np)
+ continue;
+ if (of_property_read_u32(np, "cpu-release-addr", &release_phys))
+ continue;
+
+ if (cpu_count < max_cpus) {
+ set_cpu_present(cpu, true);
+ cpu_count++;
+ }
+
+ if (release_phys != 0)
+ write_release_addr(release_phys);
+ }
+}
+
+static const struct smp_operations axxia_smp_ops __initconst = {
+ .smp_prepare_cpus = axxia_smp_prepare_cpus,
+ .smp_boot_secondary = axxia_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(axxia_smp, "lsi,syscon-release", &axxia_smp_ops);