msm: smp: cold and warm boot support for 4 cpus
Add support for cold and warm booting of the third and
fourth cpus in a quad-core processor via scm.
Change-Id: Ib83a993e77092f0e4dc75f336fc38efea7a4c76d
Signed-off-by: Joel King <joelking@codeaurora.org>
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 3f40a12..93624a3c 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cpumask.h>
#include <linux/delay.h>
@@ -56,12 +57,14 @@
/* KraitMP or ScorpionMP ? */
if ((read_cpuid_id() & 0xFF0) >> 4 != 0x2D) {
- base_ptr = ioremap_nocache(0x02098000, SZ_4K);
+ base_ptr = ioremap_nocache(0x02088000 + (cpu * 0x10000), SZ_4K);
if (base_ptr) {
if (machine_is_msm8960_sim() ||
machine_is_msm8960_rumi3()) {
writel_relaxed(0x10, base_ptr+0x04);
writel_relaxed(0x80, base_ptr+0x04);
+ } else if (machine_is_apq8064_sim()) {
+ writel_relaxed(0xf0000, base_ptr+0x04);
} else if (get_core_count() == 2) {
writel_relaxed(0x109, base_ptr+0x04);
writel_relaxed(0x101, base_ptr+0x04);
@@ -95,6 +98,12 @@
}
DEFINE_PER_CPU(int, cold_boot_done);
+static int cold_boot_flags[] = {
+ 0,
+ SCM_FLAG_COLDBOOT_CPU1,
+ SCM_FLAG_COLDBOOT_CPU2,
+ SCM_FLAG_COLDBOOT_CPU3,
+};
/* Executed by primary CPU, brings other CPUs out of reset. Called at boot
as well as when a CPU is coming out of shutdown induced by echo 0 >
@@ -104,16 +113,22 @@
{
int cnt = 0;
int ret;
+ int flag = 0;
pr_debug("Starting secondary CPU %d\n", cpu);
/* Set preset_lpj to avoid subsequent lpj recalculations */
preset_lpj = loops_per_jiffy;
+ if (cpu > 0 && cpu < ARRAY_SIZE(cold_boot_flags))
+ flag = cold_boot_flags[cpu];
+ else
+ __WARN();
+
if (per_cpu(cold_boot_done, cpu) == false) {
ret = scm_set_boot_addr((void *)
virt_to_phys(msm_secondary_startup),
- SCM_FLAG_COLDBOOT_CPU1);
+ flag);
if (ret == 0)
release_secondary(cpu);
else
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index 6b92d1e..24cd26a 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -36,6 +36,9 @@
flag = SCM_FLAG_WARMBOOT_CPU0;
else if (num_possible_cpus() == 2)
flag = SCM_FLAG_WARMBOOT_CPU0 | SCM_FLAG_WARMBOOT_CPU1;
+ else if (num_possible_cpus() == 4)
+ flag = SCM_FLAG_WARMBOOT_CPU0 | SCM_FLAG_WARMBOOT_CPU1 |
+ SCM_FLAG_WARMBOOT_CPU2 | SCM_FLAG_WARMBOOT_CPU3;
else
__WARN();
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
index c2c473b..b14c968 100644
--- a/arch/arm/mach-msm/scm-boot.h
+++ b/arch/arm/mach-msm/scm-boot.h
@@ -12,10 +12,14 @@
#ifndef __MACH_SCM_BOOT_H
#define __MACH_SCM_BOOT_H
-#define SCM_BOOT_ADDR 0x1
-#define SCM_FLAG_COLDBOOT_CPU1 0x1
-#define SCM_FLAG_WARMBOOT_CPU1 0x2
-#define SCM_FLAG_WARMBOOT_CPU0 0x4
+#define SCM_BOOT_ADDR 0x1
+#define SCM_FLAG_COLDBOOT_CPU1 0x01
+#define SCM_FLAG_COLDBOOT_CPU2 0x08
+#define SCM_FLAG_COLDBOOT_CPU3 0x20
+#define SCM_FLAG_WARMBOOT_CPU1 0x02
+#define SCM_FLAG_WARMBOOT_CPU0 0x04
+#define SCM_FLAG_WARMBOOT_CPU2 0x10
+#define SCM_FLAG_WARMBOOT_CPU3 0x40
int scm_set_boot_addr(void *addr, int flags);