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);