Skip to contentSkip to conversation

Add smp booting support for Qualcomm ARMv8 SoCs

RFC PATCH New Kumar Gala 2 participants 6 messages Apr 10, 2015

Subsystems (3)
lore
Share & tools
lore

Kumar Gala

author
#0 lore raw

cover Add smp booting support for Qualcomm ARMv8 SoCs

This patch set adds support for SMP boot on the MSM8x16 family of Qualcomm SoCs.

To support SMP on the MSM8x16 SoCs we need to add ARMv8/64-bit SCM interfaces to setup the boot/release addresses for the secondary CPUs. In addition we need a uniquie set of cpu ops. I'm aware the desired methods for booting secondary CPUs is either via spintable or PSCI. However, these SoCs are shipping with a firmware that does not support those methods.

v2:
* Dropped introduction and use of CPU_METHOD_OF_DECLARE
* Moved qcom cpu ops from drivers/soc/qcom to arch/arm64/kernel
* Renamed msm to qcom in cpu ops code, minor cleans (remove dead defines/code)

- k

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
author
#1 lore raw

RFC PATCH v2 1/4 firmware: qcom: scm: Split out 32-bit specific SCM code

Split out the 32-bit SCM implementation into its own file to prep for supporting a 64-bit/ARM64 implementation as well. We create a simple shim to ensure both versions conform to the same interface.

---
 drivers/firmware/Makefile                      |   3 +-
 drivers/firmware/{qcom_scm.c => qcom_scm-32.c} |  15 +-
 drivers/firmware/qcom_scm.c                    | 442 +------------------------
 drivers/firmware/qcom_scm.h                    |  29 ++
 4 files changed, 42 insertions(+), 447 deletions(-)
 copy drivers/firmware/{qcom_scm.c => qcom_scm-32.c} (96%)
 create mode 100644 drivers/firmware/qcom_scm.h
drivers/firmware/Makefile +2 -1
index 3fdd391..3001f1a 100644
@@ -12,7 +12,8 @@ obj-$(CONFIG_ISCSI_IBFT_FIND)	+= iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)	+= iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)	+= memmap.o
 obj-$(CONFIG_QCOM_SCM)		+= qcom_scm.o
-CFLAGS_qcom_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
+obj-$(CONFIG_QCOM_SCM)		+= qcom_scm-32.o
+CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
 
 obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
drivers/firmware/qcom_scm-32.c renamed from drivers/firmware/qcom_scm.c +4 -11
similarity index 96%
copy from drivers/firmware/qcom_scm.c
copy to drivers/firmware/qcom_scm-32.c
index 994b50f..89be15e 100644
@@ -27,6 +27,7 @@
 #include <asm/outercache.h>
 #include <asm/cacheflush.h>
 
+#include "qcom_scm.h"
 
 #define QCOM_SCM_ENOMEM		-5
 #define QCOM_SCM_EOPNOTSUPP	-4
@@ -386,8 +387,6 @@ u32 qcom_scm_get_version(void)
 }
 EXPORT_SYMBOL(qcom_scm_get_version);
 
-#define QCOM_SCM_SVC_BOOT			0x1
-#define QCOM_SCM_BOOT_ADDR			0x1
 /*
  * Set the cold/warm boot address for one of the CPU cores.
  */
@@ -412,7 +411,7 @@ static int qcom_scm_set_boot_addr(u32 addr, int flags)
  * Set the cold boot address of the cpus. Any cpu outside the supported
  * range would be removed from the cpu present mask.
  */
-int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
+int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
 {
 	int flags = 0;
 	int cpu;
@@ -435,7 +434,6 @@ int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
 
 	return qcom_scm_set_boot_addr(virt_to_phys(entry), flags);
 }
-EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
 
 /**
  * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
@@ -445,7 +443,7 @@ EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
  * Set the Linux entry point for the SCM to transfer control to when coming
  * out of a power down. CPU power down may be executed on cpuidle or hotplug.
  */
-int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
 {
 	int ret;
 	int flags = 0;
@@ -473,10 +471,6 @@ int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
 
 	return ret;
 }
-EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
-
-#define QCOM_SCM_CMD_TERMINATE_PC	0x2
-#define QCOM_SCM_FLUSH_FLAG_MASK	0x3
 
 /**
  * qcom_scm_cpu_power_down() - Power down the cpu
@@ -486,9 +480,8 @@ EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
  * the control would return from this function, otherwise, the cpu jumps to the
  * warm boot entry point set for this cpu upon reset.
  */
-void qcom_scm_cpu_power_down(u32 flags)
+void __qcom_scm_cpu_power_down(u32 flags)
 {
 	qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC,
 			flags & QCOM_SCM_FLUSH_FLAG_MASK);
 }
-EXPORT_SYMBOL(qcom_scm_cpu_power_down);
drivers/firmware/qcom_scm.c +7 -435

470 lines not on this page · raw message

drivers/firmware/qcom_scm.h new file +29 -0
new file mode 100644
index 0000000..9fbede4
@@ -0,0 +1,29 @@
+/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#ifndef __QCOM_SCM_INT_H
+#define __QCOM_SCM_INT_H
+
+#define QCOM_SCM_SVC_BOOT		0x1
+#define QCOM_SCM_BOOT_ADDR		0x1
+#define QCOM_SCM_BOOT_ADDR_MC		0x11
+
+#define QCOM_SCM_FLAG_HLOS		0x01
+#define QCOM_SCM_FLAG_COLDBOOT_MC	0x02
+#define QCOM_SCM_FLAG_WARMBOOT_MC	0x04
+extern int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);
+extern int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
+
+#define QCOM_SCM_CMD_TERMINATE_PC	0x2
+#define QCOM_SCM_FLUSH_FLAG_MASK	0x3
+#define QCOM_SCM_CMD_CORE_HOTPLUGGED	0x10
+extern void __qcom_scm_cpu_power_down(u32 flags);
+#endif
Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
author
#2 lore raw

RFC PATCH v2 2/4 firmware: qcom: scm: Add support for ARM64 SoCs

In reply to Kumar Gala

Add an implementation of the SCM interface that works on ARM64/64-bit SoCs

---
 arch/arm64/Kconfig             |   1 +
 drivers/firmware/Makefile      |   4 +
 drivers/firmware/qcom_scm-64.c | 466 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 471 insertions(+)
 create mode 100644 drivers/firmware/qcom_scm-64.c
arch/arm64/Kconfig +1 -0
index 610965dd..11e97d8 100644
@@ -180,6 +180,7 @@ config ARCH_MEDIATEK
 config ARCH_QCOM
 	bool "Qualcomm Platforms"
 	select PINCTRL
+	select QCOM_SCM
 	help
 	  This enables support for the ARMv8 based Qualcomm chipsets.
 
drivers/firmware/Makefile +4 -0
index 3001f1a..c79751a 100644
@@ -12,7 +12,11 @@ obj-$(CONFIG_ISCSI_IBFT_FIND)	+= iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)	+= iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)	+= memmap.o
 obj-$(CONFIG_QCOM_SCM)		+= qcom_scm.o
+ifdef CONFIG_64BIT
+obj-$(CONFIG_QCOM_SCM)		+= qcom_scm-64.o
+else
 obj-$(CONFIG_QCOM_SCM)		+= qcom_scm-32.o
+endif
 CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
 
 obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
drivers/firmware/qcom_scm-64.c new file +466 -0

466 lines not on this page · raw message

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
author
#3 lore raw

RFC PATCH v3 3/4 arm64: smp: move the pen to a header file

In reply to Kumar Gala

From: Abhimanyu Kapur <[email protected]>

Move the secondary_pen_release variable and the secondary_holding_pen entry function to asm/smp_plat.h so that the other cpu ops implementations can share them.

---
 arch/arm64/include/asm/smp_plat.h  | 2 ++
 arch/arm64/kernel/smp.c            | 1 +
 arch/arm64/kernel/smp_spin_table.c | 3 ---
 3 files changed, 3 insertions(+), 3 deletions(-)
arch/arm64/include/asm/smp_plat.h +2 -0
index 59e2823..235ff04 100644
@@ -34,10 +34,12 @@ static inline u32 mpidr_hash_size(void)
 	return 1 << mpidr_hash.bits;
 }
 
+extern void secondary_holding_pen(void);
 /*
  * Logical CPU mapping.
  */
 extern u64 __cpu_logical_map[NR_CPUS];
 #define cpu_logical_map(cpu)    __cpu_logical_map[cpu]
+extern volatile unsigned long secondary_holding_pen_release;
 
 #endif /* __ASM_SMP_PLAT_H */
arch/arm64/kernel/smp.c +1 -0
index 328b8ce..4ce1f23 100644
@@ -61,6 +61,7 @@
  * where to place its SVC stack
  */
 struct secondary_data secondary_data;
+volatile unsigned long secondary_holding_pen_release = INVALID_HWID;
 
 enum ipi_msg_type {
 	IPI_RESCHEDULE,
arch/arm64/kernel/smp_spin_table.c +0 -3
index 14944e5..808536e 100644
@@ -28,9 +28,6 @@
 #include <asm/io.h>
 #include <asm/smp_plat.h>
 
-extern void secondary_holding_pen(void);
-volatile unsigned long secondary_holding_pen_release = INVALID_HWID;
-
 static phys_addr_t cpu_release_addr[NR_CPUS];
 
 /*
Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
author
#4 lore raw

RFC PATCH v2 4/4 arm64: qcom: add cpu operations

In reply to Kumar Gala

From: Abhimanyu Kapur <[email protected]>

Add qcom cpu operations for arm-v8 cpus. Implement secondary cpu boot ops As a part of this change update device tree documentation for:

1. Arm cortex-a ACC device which provides percpu reg
2. Armv8 cortex-a compatible string in arm/cpus.txt

---
 Documentation/devicetree/bindings/arm/cpus.txt     |   2 +
 Documentation/devicetree/bindings/arm/msm/acc.txt  |  19 ++
 arch/arm64/kernel/Makefile                         |   3 +
 arch/arm64/kernel/cpu_ops.c                        |   4 +
 .../kernel/qcom-special-cpu-ops-dont-copy-this.c   | 329 +++++++++++++++++++++
 5 files changed, 357 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/acc.txt
 create mode 100644 arch/arm64/kernel/qcom-special-cpu-ops-dont-copy-this.c
Documentation/devicetree/bindings/arm/cpus.txt +2 -0
index 8b9e0a9..35cabe5 100644
@@ -185,6 +185,8 @@ nodes to be present and contain the properties described below.
 			  be one of:
 			     "psci"
 			     "spin-table"
+			     "qcom,arm-cortex-acc"
+
 			# On ARM 32-bit systems this property is optional and
 			  can be one of:
 			    "allwinner,sun6i-a31"
Documentation/devicetree/bindings/arm/msm/acc.txt new file +19 -0
new file mode 100644
index 0000000..ae2d725
@@ -0,0 +1,19 @@
+Application Processor Sub-system (APSS) Application Clock Controller (ACC)
+
+The ACC provides clock, power domain, and reset control to a CPU. There is one ACC
+register region per CPU within the APSS remapped region as well as an alias register
+region that remaps accesses to the ACC associated with the CPU accessing the region.
+
+Required properties:
+- compatible:		Must be "qcom,arm-cortex-acc"
+- reg:			The first element specifies the base address and size of
+			the register region. An optional second element specifies
+			the base address and size of the alias register region.
+
+Example:
+
+	clock-controller at b088000 {
+		compatible = "qcom,arm-cortex-acc";
+		reg = <0x0b088000 0x1000>,
+		      <0x0b008000 0x1000>;
+	}
arch/arm64/kernel/Makefile +3 -0
index 5ee07ee..8d77ac5 100644
@@ -25,6 +25,9 @@ arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o topology.o
+ifdef CONFIG_SMP
+arm64-obj-$(CONFIG_ARCH_QCOM)		+= qcom-special-cpu-ops-dont-copy-this.o
+endif
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
arch/arm64/kernel/cpu_ops.c +4 -0
index cce9524..d002168 100644
@@ -24,6 +24,7 @@
 
 extern const struct cpu_operations smp_spin_table_ops;
 extern const struct cpu_operations cpu_psci_ops;
+extern const struct cpu_operations qcom_cortex_a_ops;
 
 const struct cpu_operations *cpu_ops[NR_CPUS];
 
@@ -32,6 +33,9 @@ static const struct cpu_operations *supported_cpu_ops[] __initconst = {
 	&smp_spin_table_ops,
 #endif
 	&cpu_psci_ops,
+#ifdef CONFIG_ARCH_QCOM
+	&qcom_cortex_a_ops,
+#endif
 	NULL,
 };
 
arch/arm64/kernel/qcom-special-cpu-ops-dont-copy-this.c new file +329 -0

329 lines not on this page · raw message

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
#5 lore raw

Re: [RFC PATCH v2 4/4] arm64: qcom: add cpu operations

arch/arm64/kernel/qcom-special-cpu-ops-dont-copy-this.c line 308

Quoted 13 lines · On Friday 10 April 2015 15:43:25 Kumar Gala wrote:
arch/arm64/kernel/qcom-special-cpu-ops-dont-copy-this.c new file +13 -0
+static int qcom_cpu_boot(unsigned int cpu)
+{
+       int ret = 0;
+
+       if (per_cpu(cold_boot_done, cpu) == false) {
+               ret = qcom_unclamp_secondary_arm_cpu(cpu);
+               if (ret)
+                       return ret;
+               per_cpu(cold_boot_done, cpu) = true;
+       }
+       return secondary_pen_release(cpu);
+}
+

Please add a comment here to explain why you need a two-stage process here, rather than just booting the CPU without the secondary_pen.

Are you working around a specific silicon bug here?

Arnd