]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00269616 mx6: Unexpected enter WAIT mode cause IPU underrun
authorAnson Huang <b20788@freescale.com>
Thu, 4 Jul 2013 01:37:34 +0000 (09:37 +0800)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:14:09 +0000 (14:14 +0200)
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>
arch/arm/mach-mx6/system.c

index f1c2e292736264436843ceb53e060293a4206fce..ff1feda30f5bb4affaf9a39be44750d4aa0b806a 100644 (file)
@@ -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);