msm: idle-v7: SMP and AMP mode programming for 8x25 target

Program the Auxiliary Control Regiater(ACTLR.SMP) to switch
from Symmetric MultiProcessing Mode(SMP) to Asymmetric Multi
Processing Mode(AMP) while entering into the GDFS power mode.
This enables the CPU to be taken out of coherency by preventing
the CPU from receiving cache and TLB maintenance operations
broadcast by other CPUs in the system.

Change-Id: I74285e445e86cdb78a85705347550c762e47a0e2
Signed-off-by: Murali Nalajala <mnalajal@codeaurora.org>
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index 515727c..0028286 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -26,6 +26,24 @@
 #define SCM_CMD_TERMINATE_PC 0x2
 #endif
 
+/* Switch between smp_to_amp/amp_to_smp configuration */
+.macro SET_SMP_COHERENCY, on = 0
+ldr     r0, =target_type
+ldr     r0, [r0]
+mov     r1, #TARGET_IS_8625
+cmp     r0, r1
+bne     skip\@
+mrc	p15, 0, r0, c1, c0, 1	/* read ACTLR register */
+.if     \on
+orr	r0, r0, #(1 << 6)	/* Set the SMP bit in ACTLR */
+.else
+bic	r0, r0, #(1 << 6)	/* Clear the SMP bit */
+.endif
+mcr	p15, 0, r0, c1, c0, 1	/* write ACTLR register */
+isb
+skip\@:
+.endm
+
 ENTRY(msm_arch_idle)
 	wfi
 #ifdef CONFIG_ARCH_MSM8X60
@@ -110,13 +128,13 @@
 	mcr     p15, 0, r0, c1, c0, 0    /* disable d/i cache  */
 	dsb
 
+	SET_SMP_COHERENCY OFF
 	wfi
 
 	mcr     p15, 0, r4, c1, c0, 0    /* restore d/i cache  */
 	isb
 #endif
-
-
+	SET_SMP_COHERENCY ON
 #if defined(CONFIG_MSM_FIQ_SUPPORT)
 	cpsie   f
 #endif
@@ -132,7 +150,6 @@
 	mul	r2, r2, r1
 	add	r0, r0, r2
 #endif
-
 	ldmfd   r0, {r4-r14}		 /* restore registers */
 	mov     r0, #0                   /* return power collapse failed */
 	bx      lr
@@ -209,6 +226,8 @@
 	mcr     p15, 0, r3, c7, c5, 6   /* BPIALL */
 	dsb
 	isb
+
+	SET_SMP_COHERENCY ON
 #ifdef CONFIG_ARCH_MSM_KRAIT
 	mrc	p15, 0, r1, c0, c0, 0
 	ldr	r3, =0xff00fc00
@@ -269,6 +288,10 @@
 msm_pm_boot_vector:
 	.space  4 * NR_CPUS
 
+	.globl target_type
+target_type:
+	.long  0x0
+
 /*
  * Default the l2 flush flag to 1 so that caches are flushed during power
  * collapse unless the  L2 driver decides to flush them only during L2
diff --git a/arch/arm/mach-msm/idle.h b/arch/arm/mach-msm/idle.h
index df3045a..bfd632f 100644
--- a/arch/arm/mach-msm/idle.h
+++ b/arch/arm/mach-msm/idle.h
@@ -22,6 +22,10 @@
 #define CPU_SAVED_STATE_SIZE (4 * 11 + 4 * 10)
 #endif
 
+#define ON	1
+#define OFF	0
+#define TARGET_IS_8625	1
+
 #ifndef __ASSEMBLY__
 
 int msm_arch_idle(void);
@@ -35,6 +39,7 @@
 void msm_pm_set_l2_flush_flag(unsigned int flag);
 extern unsigned long msm_pm_pc_pgd;
 extern unsigned long msm_pm_boot_vector[NR_CPUS];
+extern uint32_t target_type;
 #else
 static inline void msm_pm_set_l2_flush_flag(unsigned int flag)
 {
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index d87d70f..a5e52be 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -1862,6 +1862,7 @@
 	unsigned int cpu;
 #endif
 	int ret;
+	int val;
 #ifdef CONFIG_CPU_V7
 	pgd_t *pc_pgd;
 	pmd_t *pmd;
@@ -1925,6 +1926,19 @@
 		return ret;
 	}
 
+	if (cpu_is_msm8625()) {
+		target_type = TARGET_IS_8625;
+		clean_caches((unsigned long)&target_type, sizeof(target_type),
+				virt_to_phys(&target_type));
+
+		/* Override the DBGNOPOWERDN for each cpu in
+		 * MPA5_GDFS_CNT_VAL register
+		 */
+		val = __raw_readl((MSM_CFG_CTL_BASE + 0x38));
+		val = val | 0x00030000;
+		__raw_writel(val, (MSM_CFG_CTL_BASE + 0x38));
+	}
+
 #ifdef CONFIG_MSM_MEMORY_LOW_POWER_MODE
 	/* The wakeup_reason field is overloaded during initialization time
 	   to signal Modem that Apps will control the low power modes of