ARM: UniPhier: add basic support for UniPhier architecture
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Fri, 8 May 2015 04:07:11 +0000 (13:07 +0900)
committerArnd Bergmann <arnd@arndb.de>
Tue, 12 May 2015 14:55:37 +0000 (16:55 +0200)
Initial commit for a new SoC family, UniPhier, developed by
Socionext Inc. (formerly, System LSI Business Division of
Panasonic Corporation).

This commit includes a minimal set of components for booting the
kernel, including SMP support.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/mach-uniphier/Kconfig [new file with mode: 0644]
arch/arm/mach-uniphier/Makefile [new file with mode: 0644]
arch/arm/mach-uniphier/platsmp.c [new file with mode: 0644]
arch/arm/mach-uniphier/uniphier.c [new file with mode: 0644]

index 45df48b..b2e0d98 100644 (file)
@@ -937,6 +937,8 @@ source "arch/arm/mach-tegra/Kconfig"
 
 source "arch/arm/mach-u300/Kconfig"
 
+source "arch/arm/mach-uniphier/Kconfig"
+
 source "arch/arm/mach-ux500/Kconfig"
 
 source "arch/arm/mach-versatile/Kconfig"
index 985227c..fe8f9ef 100644 (file)
@@ -200,6 +200,7 @@ machine-$(CONFIG_ARCH_SUNXI)                += sunxi
 machine-$(CONFIG_ARCH_TEGRA)           += tegra
 machine-$(CONFIG_ARCH_U300)            += u300
 machine-$(CONFIG_ARCH_U8500)           += ux500
+machine-$(CONFIG_ARCH_UNIPHIER)                += uniphier
 machine-$(CONFIG_ARCH_VERSATILE)       += versatile
 machine-$(CONFIG_ARCH_VEXPRESS)                += vexpress
 machine-$(CONFIG_ARCH_VT8500)          += vt8500
diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig
new file mode 100644 (file)
index 0000000..a017b1d
--- /dev/null
@@ -0,0 +1,11 @@
+config ARCH_UNIPHIER
+       bool "Socionext UniPhier SoCs"
+       depends on ARCH_MULTI_V7
+       select ARM_AMBA
+       select ARM_GLOBAL_TIMER
+       select ARM_GIC
+       select HAVE_ARM_SCU
+       select HAVE_ARM_TWD
+       help
+         Support for UniPhier SoC family developed by Socionext Inc.
+         (formerly, System LSI Business Division of Panasonic Corporation)
diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile
new file mode 100644 (file)
index 0000000..60bd226
--- /dev/null
@@ -0,0 +1,2 @@
+obj-y                  := uniphier.o
+obj-$(CONFIG_SMP)      += platsmp.o
diff --git a/arch/arm/mach-uniphier/platsmp.c b/arch/arm/mach-uniphier/platsmp.c
new file mode 100644 (file)
index 0000000..5943e1c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * 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.
+ */
+
+#include <linux/sizes.h>
+#include <linux/compiler.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <asm/smp.h>
+#include <asm/smp_scu.h>
+
+static struct regmap *sbcm_regmap;
+
+static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus)
+{
+       static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
+       unsigned long scu_base_phys = 0;
+       void __iomem *scu_base;
+
+       sbcm_regmap = syscon_regmap_lookup_by_compatible(
+                       "socionext,uniphier-system-bus-controller-misc");
+       if (IS_ERR(sbcm_regmap)) {
+               pr_err("failed to regmap system-bus-controller-misc\n");
+               goto err;
+       }
+
+       if (scu_a9_has_base())
+               scu_base_phys = scu_a9_get_base();
+
+       if (!scu_base_phys) {
+               pr_err("failed to get scu base\n");
+               goto err;
+       }
+
+       scu_base = ioremap(scu_base_phys, SZ_128);
+       if (!scu_base) {
+               pr_err("failed to remap scu base (0x%08lx)\n", scu_base_phys);
+               goto err;
+       }
+
+       scu_enable(scu_base);
+       iounmap(scu_base);
+
+       return;
+err:
+       pr_warn("disabling SMP\n");
+       init_cpu_present(&only_cpu_0);
+       sbcm_regmap = NULL;
+}
+
+static void __naked uniphier_secondary_startup(void)
+{
+       asm("bl         v7_invalidate_l1\n"
+           "b          secondary_startup\n");
+};
+
+static int uniphier_boot_secondary(unsigned int cpu,
+                                  struct task_struct *idle)
+{
+       int ret;
+
+       if (!sbcm_regmap)
+               return -ENODEV;
+
+       ret = regmap_write(sbcm_regmap, 0x1208,
+                          virt_to_phys(uniphier_secondary_startup));
+       if (!ret)
+               asm("sev"); /* wake up secondary CPU */
+
+       return ret;
+}
+
+struct smp_operations uniphier_smp_ops __initdata = {
+       .smp_prepare_cpus       = uniphier_smp_prepare_cpus,
+       .smp_boot_secondary     = uniphier_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(uniphier_smp, "socionext,uniphier-smp",
+                     &uniphier_smp_ops);
diff --git a/arch/arm/mach-uniphier/uniphier.c b/arch/arm/mach-uniphier/uniphier.c
new file mode 100644 (file)
index 0000000..9be10ef
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * 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.
+ */
+
+#include <asm/mach/arch.h>
+
+static const char * const uniphier_dt_compat[] __initconst = {
+       "socionext,ph1-sld3",
+       "socionext,ph1-ld4",
+       "socionext,ph1-pro4",
+       "socionext,ph1-sld8",
+       "socionext,ph1-pro5",
+       "socionext,proxstream2",
+       "socionext,ph1-ld6b",
+       NULL,
+};
+
+DT_MACHINE_START(UNIPHIER, "Socionext UniPhier")
+       .dt_compat      = uniphier_dt_compat,
+MACHINE_END