diff options
Diffstat (limited to 'target/linux/sunxi/patches-3.13/108-sun6i-add-smp-support.patch')
-rw-r--r-- | target/linux/sunxi/patches-3.13/108-sun6i-add-smp-support.patch | 206 |
1 files changed, 0 insertions, 206 deletions
diff --git a/target/linux/sunxi/patches-3.13/108-sun6i-add-smp-support.patch b/target/linux/sunxi/patches-3.13/108-sun6i-add-smp-support.patch deleted file mode 100644 index 24689e5..0000000 --- a/target/linux/sunxi/patches-3.13/108-sun6i-add-smp-support.patch +++ /dev/null @@ -1,206 +0,0 @@ -From 6f5002c91f35f6b171bc608b87b3f2b55451f32b Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sun, 3 Nov 2013 10:30:13 +0100 -Subject: [PATCH] ARM: sun6i: Add SMP support for the Allwinner A31 - -The A31 is a quad Cortex-A7. Add the logic to use the IPs used to -control the CPU configuration and the CPU power so that we can bring up -secondary CPUs at boot. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/mach-sunxi/Makefile | 1 + - arch/arm/mach-sunxi/common.h | 19 +++++++ - arch/arm/mach-sunxi/headsmp.S | 9 +++ - arch/arm/mach-sunxi/platsmp.c | 124 ++++++++++++++++++++++++++++++++++++++++++ - arch/arm/mach-sunxi/sunxi.c | 3 + - 5 files changed, 156 insertions(+) - create mode 100644 arch/arm/mach-sunxi/common.h - create mode 100644 arch/arm/mach-sunxi/headsmp.S - create mode 100644 arch/arm/mach-sunxi/platsmp.c - ---- a/arch/arm/mach-sunxi/Makefile -+++ b/arch/arm/mach-sunxi/Makefile -@@ -1 +1,2 @@ - obj-$(CONFIG_ARCH_SUNXI) += sunxi.o -+obj-$(CONFIG_SMP) += platsmp.o headsmp.o ---- /dev/null -+++ b/arch/arm/mach-sunxi/common.h -@@ -0,0 +1,19 @@ -+/* -+ * Core functions for Allwinner SoCs -+ * -+ * Copyright (C) 2013 Maxime Ripard -+ * -+ * Maxime Ripard <maxime.ripard@free-electrons.com> -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#ifndef __ARCH_SUNXI_COMMON_H_ -+#define __ARCH_SUNXI_COMMON_H_ -+ -+void sun6i_secondary_startup(void); -+extern struct smp_operations sun6i_smp_ops; -+ -+#endif /* __ARCH_SUNXI_COMMON_H_ */ ---- /dev/null -+++ b/arch/arm/mach-sunxi/headsmp.S -@@ -0,0 +1,9 @@ -+#include <linux/linkage.h> -+#include <linux/init.h> -+ -+ .section ".text.head", "ax" -+ -+ENTRY(sun6i_secondary_startup) -+ msr cpsr_fsxc, #0xd3 -+ b secondary_startup -+ENDPROC(sun6i_secondary_startup) ---- /dev/null -+++ b/arch/arm/mach-sunxi/platsmp.c -@@ -0,0 +1,124 @@ -+/* -+ * SMP support for Allwinner SoCs -+ * -+ * Copyright (C) 2013 Maxime Ripard -+ * -+ * Maxime Ripard <maxime.ripard@free-electrons.com> -+ * -+ * Based on code -+ * Copyright (C) 2012-2013 Allwinner Ltd. -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#include <linux/delay.h> -+#include <linux/init.h> -+#include <linux/io.h> -+#include <linux/memory.h> -+#include <linux/of.h> -+#include <linux/of_address.h> -+#include <linux/smp.h> -+ -+#include "common.h" -+ -+#define CPUCFG_CPU_PWR_CLAMP_STATUS_REG(cpu) ((cpu) * 0x40 + 0x64) -+#define CPUCFG_CPU_RST_CTRL_REG(cpu) (((cpu) + 1) * 0x40) -+#define CPUCFG_CPU_CTRL_REG(cpu) (((cpu) + 1) * 0x40 + 0x04) -+#define CPUCFG_CPU_STATUS_REG(cpu) (((cpu) + 1) * 0x40 + 0x08) -+#define CPUCFG_GEN_CTRL_REG 0x184 -+#define CPUCFG_PRIVATE0_REG 0x1a4 -+#define CPUCFG_PRIVATE1_REG 0x1a8 -+#define CPUCFG_DBG_CTL0_REG 0x1e0 -+#define CPUCFG_DBG_CTL1_REG 0x1e4 -+ -+#define PRCM_CPU_PWROFF_REG 0x100 -+#define PRCM_CPU_PWR_CLAMP_REG(cpu) (((cpu) * 4) + 0x140) -+ -+static void __iomem *cpucfg_membase; -+static void __iomem *prcm_membase; -+ -+static DEFINE_SPINLOCK(cpu_lock); -+ -+static void __init sun6i_smp_prepare_cpus(unsigned int max_cpus) -+{ -+ struct device_node *node; -+ -+ node = of_find_compatible_node(NULL, NULL, "allwinner,sun6i-a31-prcm"); -+ if (!node) { -+ pr_err("Missing A31 PRCM node in the device tree\n"); -+ return; -+ } -+ -+ prcm_membase = of_iomap(node, 0); -+ if (!prcm_membase) { -+ pr_err("Couldn't map A31 PRCM registers\n"); -+ return; -+ } -+ -+ node = of_find_compatible_node(NULL, NULL, -+ "allwinner,sun6i-a31-cpuconfig"); -+ if (!node) { -+ pr_err("Missing A31 CPU config node in the device tree\n"); -+ return; -+ } -+ -+ cpucfg_membase = of_iomap(node, 0); -+ if (!cpucfg_membase) -+ pr_err("Couldn't map A31 CPU config registers\n"); -+ -+} -+ -+static int sun6i_smp_boot_secondary(unsigned int cpu, -+ struct task_struct *idle) -+{ -+ u32 reg; -+ int i; -+ -+ if (!(prcm_membase && cpucfg_membase)) -+ return -EFAULT; -+ -+ spin_lock(&cpu_lock); -+ -+ /* Set CPU boot address */ -+ writel(virt_to_phys(sun6i_secondary_startup), -+ cpucfg_membase + CPUCFG_PRIVATE0_REG); -+ -+ /* Assert the CPU core in reset */ -+ writel(0, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu)); -+ -+ /* Assert the L1 cache in reset */ -+ reg = readl(cpucfg_membase + CPUCFG_GEN_CTRL_REG); -+ writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_GEN_CTRL_REG); -+ -+ /* Disable external debug access */ -+ reg = readl(cpucfg_membase + CPUCFG_DBG_CTL1_REG); -+ writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_DBG_CTL1_REG); -+ -+ /* Power up the CPU */ -+ for (i = 0; i <= 8; i++) -+ writel(0xff >> i, prcm_membase + PRCM_CPU_PWR_CLAMP_REG(cpu)); -+ mdelay(10); -+ -+ /* Clear CPU power-off gating */ -+ reg = readl(prcm_membase + PRCM_CPU_PWROFF_REG); -+ writel(reg & ~BIT(cpu), prcm_membase + PRCM_CPU_PWROFF_REG); -+ mdelay(1); -+ -+ /* Deassert the CPU core reset */ -+ writel(3, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu)); -+ -+ /* Enable back the external debug accesses */ -+ reg = readl(cpucfg_membase + CPUCFG_DBG_CTL1_REG); -+ writel(reg | BIT(cpu), cpucfg_membase + CPUCFG_DBG_CTL1_REG); -+ -+ spin_unlock(&cpu_lock); -+ -+ return 0; -+} -+ -+struct smp_operations sun6i_smp_ops __initdata = { -+ .smp_prepare_cpus = sun6i_smp_prepare_cpus, -+ .smp_boot_secondary = sun6i_smp_boot_secondary, -+}; ---- a/arch/arm/mach-sunxi/sunxi.c -+++ b/arch/arm/mach-sunxi/sunxi.c -@@ -25,6 +25,8 @@ - #include <asm/mach/map.h> - #include <asm/system_misc.h> - -+#include "common.h" -+ - #define SUN4I_WATCHDOG_CTRL_REG 0x00 - #define SUN4I_WATCHDOG_CTRL_RESTART BIT(0) - #define SUN4I_WATCHDOG_MODE_REG 0x04 -@@ -147,6 +149,7 @@ DT_MACHINE_START(SUN6I_DT, "Allwinner su - .init_time = sun6i_timer_init, - .dt_compat = sun6i_board_dt_compat, - .restart = sun6i_restart, -+ .smp = smp_ops(sun6i_smp_ops), - MACHINE_END - - static const char * const sun7i_board_dt_compat[] = { |