summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAnson Huang <b20788@freescale.com>2013-07-04 09:37:34 +0800
committerAnson Huang <b20788@freescale.com>2013-07-05 08:26:02 +0800
commit04b5224599fef16ef3a1856dd1b3205360b772c1 (patch)
tree1eb723e3033f48a11e8a4bdbf368b1f30ea7aab6 /arch
parentd3e5374cb5cdb478f524d76166712c753f69dd54 (diff)
ENGR00269616 mx6: Unexpected enter WAIT mode cause IPU underrun
CCM state machine has restriction that, everytime enable LPM mode, we need to make sure last wakeup from LPM mode is a dsm_wakeup_signal, which means the wakeup source must be seen by GPC, then CCM will clean its state machine and re-sample necessary signal to decide whether it can enter LPM mode. Here we use the forever pending irq #125, unmask it before we enable LPM mode and mask it after LPM is enabled, this flow will make sure CCM state machine in reliable state before we enter LPM mode. Signed-off-by: Anson Huang <b20788@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-mx6/system.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c
index f1c2e2927362..ff1feda30f5b 100644
--- a/arch/arm/mach-mx6/system.c
+++ b/arch/arm/mach-mx6/system.c
@@ -82,6 +82,22 @@ void gpc_set_wakeup(unsigned int irq[4])
return;
}
+void gpc_mask_single_irq(int irq, bool enable)
+{
+ void __iomem *reg;
+ u32 val;
+
+ reg = gpc_base + 0x8 + (irq / 32 - 1) * 4;
+ val = __raw_readl(reg);
+ if (enable)
+ val |= 1 << (irq % 32);
+ else
+ val &= ~(1 << (irq % 32));
+ __raw_writel(val, reg);
+
+ return;
+}
+
/* set cpu low power mode before WFI instruction */
void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
{
@@ -91,6 +107,18 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
u32 ccm_clpcr, anatop_val;
ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
+ /*
+ * CCM state machine has restriction that, everytime enable
+ * LPM mode, we need to make sure last wakeup from LPM mode
+ * is a dsm_wakeup_signal, which means the wakeup source
+ * must be seen by GPC, then CCM will clean its state machine
+ * and re-sample necessary signal to decide whether it can
+ * enter LPM mode. Here we use the forever pending irq #125,
+ * unmask it before we enable LPM mode and mask it after LPM
+ * is enabled, this flow will make sure CCM state machine in
+ * reliable state before we enter LPM mode.
+ */
+ gpc_mask_single_irq(MXC_INT_CHEETAH_PARITY, false);
switch (mode) {
case WAIT_CLOCKED:
@@ -149,6 +177,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
break;
default:
printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
+ gpc_mask_single_irq(MXC_INT_CHEETAH_PARITY, true);
return;
}
@@ -246,6 +275,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
}
}
__raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+ gpc_mask_single_irq(MXC_INT_CHEETAH_PARITY, true);
}
extern int tick_broadcast_oneshot_active(void);