summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAnson Huang <b20788@freescale.com>2013-07-04 09:37:34 +0800
committerguoyin.chen <guoyin.chen@freescale.com>2013-07-05 12:59:08 +0800
commitf128c5660150679f00e518da8e3f582e9a2f03a8 (patch)
tree8c35380555eabbed93b64f36e5c7735475475ea3 /arch
parent06bc5bf8a1497765a4567cf8e40d4f2c641b9891 (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 4990a4a0abbb..6b30d08cb830 100644
--- a/arch/arm/mach-mx6/system.c
+++ b/arch/arm/mach-mx6/system.c
@@ -81,6 +81,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)
{
@@ -90,6 +106,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:
@@ -148,6 +176,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;
}
@@ -245,6 +274,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);