| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- From 391848e75f8b0ba14816da1ac8f2d838fd0d5744 Mon Sep 17 00:00:00 2001
- From: Rohit Vaswani <[email protected]>
- Date: Tue, 21 May 2013 19:13:29 -0700
- Subject: [PATCH 009/182] ARM: qcom: Re-organize platsmp to make it extensible
- This makes it easy to add SMP support for new devices by keying
- on a device node for the release sequence. We add the
- enable-method property for the cpus property to specify that we
- want to use the gcc-msm8660 release sequence (which is going to
- look for the global clock controller device node to map some
- Scorpion specific power and control registers). We also remove
- the nr_cpus detection code as that is done generically in the DT
- CPU detection code.
- Signed-off-by: Rohit Vaswani <[email protected]>
- [sboyd: Port to CPU_METHOD_OF_DECLARE]
- Signed-off-by: Stephen Boyd <[email protected]>
- Signed-off-by: Kumar Gala <[email protected]>
- ---
- arch/arm/mach-msm/common.h | 2 -
- arch/arm/mach-qcom/board.c | 14 -----
- arch/arm/mach-qcom/platsmp.c | 118 +++++++++++++++++++++++-------------------
- 3 files changed, 65 insertions(+), 69 deletions(-)
- --- a/arch/arm/mach-msm/common.h
- +++ b/arch/arm/mach-msm/common.h
- @@ -23,8 +23,6 @@ extern void msm_map_qsd8x50_io(void);
- extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
- unsigned int mtype, void *caller);
-
- -extern struct smp_operations msm_smp_ops;
- -
- struct msm_mmc_platform_data;
-
- extern void msm_add_devices(void);
- --- a/arch/arm/mach-qcom/board.c
- +++ b/arch/arm/mach-qcom/board.c
- @@ -11,30 +11,16 @@
- */
-
- #include <linux/init.h>
- -#include <linux/of.h>
- -#include <linux/of_platform.h>
-
- #include <asm/mach/arch.h>
- -#include <asm/mach/map.h>
- -
- -extern struct smp_operations qcom_smp_ops;
-
- static const char * const qcom_dt_match[] __initconst = {
- "qcom,msm8660-surf",
- "qcom,msm8960-cdp",
- - NULL
- -};
- -
- -static const char * const apq8074_dt_match[] __initconst = {
- "qcom,apq8074-dragonboard",
- NULL
- };
-
- DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
- - .smp = smp_ops(qcom_smp_ops),
- .dt_compat = qcom_dt_match,
- MACHINE_END
- -
- -DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)")
- - .dt_compat = apq8074_dt_match,
- -MACHINE_END
- --- a/arch/arm/mach-qcom/platsmp.c
- +++ b/arch/arm/mach-qcom/platsmp.c
- @@ -13,17 +13,18 @@
- #include <linux/errno.h>
- #include <linux/delay.h>
- #include <linux/device.h>
- +#include <linux/of.h>
- +#include <linux/of_address.h>
- #include <linux/smp.h>
- #include <linux/io.h>
-
- -#include <asm/cputype.h>
- #include <asm/smp_plat.h>
-
- #include "scm-boot.h"
-
- -#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
- -#define SCSS_CPU1CORE_RESET 0xD80
- -#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
- +#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x35a0
- +#define SCSS_CPU1CORE_RESET 0x2d80
- +#define SCSS_DBG_STATUS_CORE_PWRDUP 0x2e64
-
- extern void secondary_startup(void);
-
- @@ -36,12 +37,6 @@ static void __ref qcom_cpu_die(unsigned
- }
- #endif
-
- -static inline int get_core_count(void)
- -{
- - /* 1 + the PART[1:0] field of MIDR */
- - return ((read_cpuid_id() >> 4) & 3) + 1;
- -}
- -
- static void qcom_secondary_init(unsigned int cpu)
- {
- /*
- @@ -51,33 +46,41 @@ static void qcom_secondary_init(unsigned
- spin_unlock(&boot_lock);
- }
-
- -static void prepare_cold_cpu(unsigned int cpu)
- +static int scss_release_secondary(unsigned int cpu)
- {
- - int ret;
- - ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
- - SCM_FLAG_COLDBOOT_CPU1);
- - if (ret == 0) {
- - void __iomem *sc1_base_ptr;
- - sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
- - if (sc1_base_ptr) {
- - writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
- - writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
- - writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
- - iounmap(sc1_base_ptr);
- - }
- - } else
- - printk(KERN_DEBUG "Failed to set secondary core boot "
- - "address\n");
- + struct device_node *node;
- + void __iomem *base;
- +
- + node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
- + if (!node) {
- + pr_err("%s: can't find node\n", __func__);
- + return -ENXIO;
- + }
- +
- + base = of_iomap(node, 0);
- + of_node_put(node);
- + if (!base)
- + return -ENOMEM;
- +
- + writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
- + writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
- + writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
- + mb();
- + iounmap(base);
- +
- + return 0;
- }
-
- -static int qcom_boot_secondary(unsigned int cpu, struct task_struct *idle)
- +static DEFINE_PER_CPU(int, cold_boot_done);
- +
- +static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
- {
- - static int cold_boot_done;
- + int ret = 0;
-
- - /* Only need to bring cpu out of reset this way once */
- - if (cold_boot_done == false) {
- - prepare_cold_cpu(cpu);
- - cold_boot_done = true;
- + if (!per_cpu(cold_boot_done, cpu)) {
- + ret = func(cpu);
- + if (!ret)
- + per_cpu(cold_boot_done, cpu) = true;
- }
-
- /*
- @@ -99,39 +102,48 @@ static int qcom_boot_secondary(unsigned
- */
- spin_unlock(&boot_lock);
-
- - return 0;
- + return ret;
- }
-
- -/*
- - * Initialise the CPU possible map early - this describes the CPUs
- - * which may be present or become present in the system. The msm8x60
- - * does not support the ARM SCU, so just set the possible cpu mask to
- - * NR_CPUS.
- - */
- -static void __init qcom_smp_init_cpus(void)
- -{
- - unsigned int i, ncores = get_core_count();
- -
- - if (ncores > nr_cpu_ids) {
- - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
- - ncores, nr_cpu_ids);
- - ncores = nr_cpu_ids;
- - }
- -
- - for (i = 0; i < ncores; i++)
- - set_cpu_possible(i, true);
- +static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
- +{
- + return qcom_boot_secondary(cpu, scss_release_secondary);
- }
-
- static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
- {
- + int cpu, map;
- + unsigned int flags = 0;
- + static const int cold_boot_flags[] = {
- + 0,
- + SCM_FLAG_COLDBOOT_CPU1,
- + };
- +
- + for_each_present_cpu(cpu) {
- + map = cpu_logical_map(cpu);
- + if (WARN_ON(map >= ARRAY_SIZE(cold_boot_flags))) {
- + set_cpu_present(cpu, false);
- + continue;
- + }
- + flags |= cold_boot_flags[map];
- + }
- +
- + if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) {
- + for_each_present_cpu(cpu) {
- + if (cpu == smp_processor_id())
- + continue;
- + set_cpu_present(cpu, false);
- + }
- + pr_warn("Failed to set CPU boot address, disabling SMP\n");
- + }
- }
-
- -struct smp_operations qcom_smp_ops __initdata = {
- - .smp_init_cpus = qcom_smp_init_cpus,
- +static struct smp_operations smp_msm8660_ops __initdata = {
- .smp_prepare_cpus = qcom_smp_prepare_cpus,
- .smp_secondary_init = qcom_secondary_init,
- - .smp_boot_secondary = qcom_boot_secondary,
- + .smp_boot_secondary = msm8660_boot_secondary,
- #ifdef CONFIG_HOTPLUG_CPU
- .cpu_die = qcom_cpu_die,
- #endif
- };
- +CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
|