Thread (17 messages) 17 messages, 4 authors, 2013-08-20
STALE4706d
Revisions (2)
  1. v1 [diff vs current]
  2. resend current

[RESEND PATCH 2/4] ARM: msm: Re-organize platsmp to make it extensible

From: Rohit Vaswani <hidden>
Date: 2013-08-02 02:16:23
Also in: linux-arm-msm, lkml
Subsystem: arm port, open firmware and flattened device tree bindings, the rest · Maintainers: Russell King, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Linus Torvalds

This makes it easy to add SMP support for new targets
by adding cpus property and the release sequence.
We add the enable-method property for the cpus property to
specify which release sequence to use.
While at it, add the 8660 cpus bindings to make SMP work.

Signed-off-by: Rohit Vaswani <redacted>
---
 Documentation/devicetree/bindings/arm/cpus.txt     |  6 ++
 Documentation/devicetree/bindings/arm/msm/scss.txt | 15 ++++
 arch/arm/boot/dts/msm8660-surf.dts                 | 23 +++++-
 arch/arm/mach-msm/platsmp.c                        | 94 +++++++++++++++++-----
 4 files changed, 115 insertions(+), 23 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/scss.txt
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index f32494d..327aad2 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -44,6 +44,12 @@ For the ARM architecture every CPU node must contain the following properties:
 		"marvell,mohawk"
 		"marvell,xsc3"
 		"marvell,xscale"
+		"qcom,scorpion"
+- enable-method: Specifies the method used to enable or take the secondary cores
+		 out of reset. This allows different reset sequence for
+		 different types of cpus.
+		 This should be one of:
+		 "qcom,scss"
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/arm/msm/scss.txt b/Documentation/devicetree/bindings/arm/msm/scss.txt
new file mode 100644
index 0000000..21c3e26
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/scss.txt
@@ -0,0 +1,15 @@
+* SCSS - Scorpion Sub-system
+
+Properties
+
+- compatible : Should contain "qcom,scss".
+
+- reg: Specifies the base address for the SCSS registers used for
+       booting up secondary cores.
+
+Example:
+
+	scss at 902000 {
+		compatible = "qcom,scss";
+		reg = <0x00902000 0x2000>;
+	};
diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/msm8660-surf.dts
index cdc010e..203e51a 100644
--- a/arch/arm/boot/dts/msm8660-surf.dts
+++ b/arch/arm/boot/dts/msm8660-surf.dts
@@ -7,6 +7,22 @@
 	compatible = "qcom,msm8660-surf", "qcom,msm8660";
 	interrupt-parent = <&intc>;
 
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "qcom,scorpion";
+		device_type = "cpu";
+		enable-method = "qcom,scss";
+
+		cpu at 0 {
+			reg = <0>;
+		};
+
+		cpu at 1 {
+			reg = <1>;
+		};
+	};
+
 	intc: interrupt-controller at 2080000 {
 		compatible = "qcom,msm-8660-qgic";
 		interrupt-controller;
@@ -37,7 +53,12 @@
 		#interrupt-cells = <2>;
 	};
 
-	serial at 19c40000 {
+	scss at 902000 {
+		compatible = "qcom,scss";
+		reg = <0x00902000 0x2000>;
+	};
+
+	serial at 19c400000 {
 		compatible = "qcom,msm-hsuart", "qcom,msm-uart";
 		reg = <0x19c40000 0x1000>,
 		      <0x19c00000 0x1000>;
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 5b481db..17022e0 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -13,6 +13,8 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/jiffies.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/smp.h>
 #include <linux/io.h>
 
@@ -47,35 +49,63 @@ static void msm_secondary_init(unsigned int cpu)
 	spin_unlock(&boot_lock);
 }
 
-static void prepare_cold_cpu(unsigned int cpu)
+static int scorpion_release_secondary(void)
 {
-	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");
+	void __iomem *sc1_base_ptr;
+	struct device_node *dn = NULL;
+
+	dn = of_find_compatible_node(dn, NULL, "qcom,scss");
+	if (!dn) {
+		pr_err("%s: Missing scss node in device tree\n", __func__);
+		return -ENXIO;
+	}
+
+	sc1_base_ptr = of_iomap(dn, 0);
+	if (sc1_base_ptr) {
+		writel_relaxed(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
+		writel_relaxed(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
+		writel_relaxed(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
+		mb();
+		iounmap(sc1_base_ptr);
+	} else {
+		return -ENOMEM;
+	}
+
+	return 0;
 }
 
-static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static DEFINE_PER_CPU(int, cold_boot_done);
+
+static void boot_cold_cpu(unsigned int cpu)
 {
-	static int cold_boot_done;
+	const char *enable_method;
+	struct device_node *dn = NULL;
 
-	/* Only need to bring cpu out of reset this way once */
-	if (cold_boot_done == false) {
-		prepare_cold_cpu(cpu);
-		cold_boot_done = true;
+	dn = of_find_node_by_name(dn, "cpus");
+	if (!dn) {
+		pr_err("%s: Missing node cpus in device tree\n", __func__);
+		return;
 	}
 
+	enable_method = of_get_property(dn, "enable-method", NULL);
+	if (!enable_method) {
+			pr_err("%s: cpus node is missing enable-method property\n",
+					__func__);
+	} else if (!strcmp(enable_method, "qcom,scss")) {
+		if (per_cpu(cold_boot_done, cpu) == false) {
+			scorpion_release_secondary();
+			per_cpu(cold_boot_done, cpu) = true;
+		}
+	} else {
+		pr_err("%s: Invalid enable-method property: %s\n",
+				__func__, enable_method);
+	}
+}
+
+static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	boot_cold_cpu(cpu);
+
 	/*
 	 * set synchronisation state between this boot processor
 	 * and the secondary one
@@ -118,8 +148,28 @@ static void __init msm_smp_init_cpus(void)
 		set_cpu_possible(i, true);
 }
 
+static const int cold_boot_flags[] __initconst = {
+	0,
+	SCM_FLAG_COLDBOOT_CPU1,
+};
+
 static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
 {
+	int cpu, map;
+	unsigned int flags = 0;
+
+	for_each_present_cpu(cpu) {
+		map = cpu_logical_map(cpu);
+		if (map > ARRAY_SIZE(cold_boot_flags)) {
+			set_cpu_present(cpu, false);
+			__WARN();
+			continue;
+		}
+		flags |= cold_boot_flags[map];
+	}
+
+	if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags))
+		pr_warn("Failed to set CPU boot address\n");
 }
 
 struct smp_operations msm_smp_ops __initdata = {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help