diff options
-rw-r--r-- | arch/arm/mach-mx6/system.c | 30 |
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); |