firmware/br-ext-chip-allwinner/board/v83x/kernel/patches/00000-arch_arm_mach-sunxi_p...

150 lines
4.4 KiB
Diff

diff -drupN a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
--- a/arch/arm/mach-sunxi/platsmp.c 2018-08-06 17:23:04.000000000 +0300
+++ b/arch/arm/mach-sunxi/platsmp.c 2022-06-12 05:28:14.000000000 +0300
@@ -20,19 +20,13 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/smp.h>
+#include <linux/sunxi-sid.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
+#include <asm/cacheflush.h>
-#define PRCM_CPU_PWROFF_REG 0x100
-#define PRCM_CPU_PWR_CLAMP_REG(cpu) (((cpu) * 4) + 0x140)
+#include "platsmp.h"
+
+void *cpus_boot_entry[NR_CPUS];
static void __iomem *cpucfg_membase;
static void __iomem *prcm_membase;
@@ -116,7 +110,7 @@ static int sun6i_smp_boot_secondary(unsi
return 0;
}
-static const struct smp_operations sun6i_smp_ops __initconst = {
+static struct smp_operations sun6i_smp_ops __initdata = {
.smp_prepare_cpus = sun6i_smp_prepare_cpus,
.smp_boot_secondary = sun6i_smp_boot_secondary,
};
@@ -185,8 +179,110 @@ static int sun8i_smp_boot_secondary(unsi
return 0;
}
-static const struct smp_operations sun8i_smp_ops __initconst = {
+struct smp_operations sun8i_smp_ops __initdata = {
.smp_prepare_cpus = sun8i_smp_prepare_cpus,
.smp_boot_secondary = sun8i_smp_boot_secondary,
};
CPU_METHOD_OF_DECLARE(sun8i_a23_smp, "allwinner,sun8i-a23", &sun8i_smp_ops);
+
+static void sunxi_set_cpus_boot_entry(int cpu, void *entry)
+{
+ if (cpu < num_possible_cpus()) {
+ cpus_boot_entry[cpu] = (void *)(virt_to_phys(entry));
+ /* barrier */
+ smp_wmb();
+ __cpuc_flush_dcache_area(cpus_boot_entry,
+ sizeof(cpus_boot_entry));
+ outer_clean_range(__pa(&cpus_boot_entry),
+ __pa(&cpus_boot_entry + 1));
+ }
+}
+
+static void __init sunxi_smp_init_cpus(void)
+{
+ unsigned int i, ncores = get_nr_cores();
+
+#if defined(CONFIG_ARCH_SUN8IW11) || defined(CONFIG_ARCH_SUN8IW7)
+ unsigned int chip_ver = sunxi_get_soc_ver();
+
+ switch (chip_ver) {
+ case SUN8IW11P2_REV_A:
+ case SUN8IW11P3_REV_A:
+ case SUN8IW11P4_REV_A:
+ case SUN8IW7P1_REV_A:
+ case SUN8IW7P1_REV_B:
+ ncores = 4;
+ break;
+ case SUN8IW11P1_REV_A:
+ case SUN8IW7P2_REV_A:
+ case SUN8IW7P2_REV_B:
+ default:
+ ncores = 2;
+ break;
+ }
+#endif
+ pr_debug("[%s] ncores = %u\n", __func__, ncores);
+ if (ncores > nr_cpu_ids) {
+ pr_warn(KERN_ERR "SMP: %u CPUs physically present. Only %d configured.\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+#ifdef CONFIG_CPU_IDLE_SUNXI
+ sunxi_idle_cpux_flag_init();
+#endif
+ pr_debug("[%s] done\n", __func__);
+}
+
+/*
+ * Boot a secondary CPU, and assign it the specified idle task.
+ * This also gives us the initial stack to use for this CPU.
+ */
+static int sunxi_smp_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ if (!(sunxi_cpucfg_base && sunxi_soft_entry_base))
+ return -EFAULT;
+
+ spin_lock(&cpu_lock);
+
+#ifdef CONFIG_CPU_IDLE_SUNXI
+ writel(virt_to_phys(sunxi_cpux_entry_judge),
+ sunxi_soft_entry_base + CPU_SOFT_ENTRY_REG(cpu));
+#else
+ writel(virt_to_phys(sunxi_secondary_startup),
+ sunxi_soft_entry_base + CPU_SOFT_ENTRY_REG(cpu));
+#endif
+
+ sunxi_set_cpus_boot_entry(cpu, secondary_startup);
+
+ sunxi_enable_cpu(cpu);
+
+ /*
+ * Now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&cpu_lock);
+ pr_debug("[%s] done\n", __func__);
+
+ return 0;
+}
+
+struct smp_operations sunxi_smp_ops = {
+ .smp_init_cpus = sunxi_smp_init_cpus,
+ .smp_boot_secondary = sunxi_smp_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = sunxi_cpu_die,
+ .cpu_kill = sunxi_cpu_kill,
+ .cpu_disable = sunxi_cpu_disable,
+#endif
+};
+
+
+CPU_METHOD_OF_DECLARE(sun8iw11p1_smp, "allwinner,sun8iw11p1", &sunxi_smp_ops);
+CPU_METHOD_OF_DECLARE(sun8iw15p1_smp, "allwinner,sun8iw15p1", &sunxi_smp_ops);
+CPU_METHOD_OF_DECLARE(sun8iw12p1_smp, "allwinner,sun8iw12p1", &sunxi_smp_ops);
+CPU_METHOD_OF_DECLARE(sun8iw17p1_smp, "allwinner,sun8iw17p1", &sunxi_smp_ops);
+CPU_METHOD_OF_DECLARE(sun8iw7p1_smp, "allwinner,sun8iw7p1", &sunxi_smp_ops);