]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00219870 [MX6]Add interrupt check to idle to minish SMP impact
authorAnson Huang <b20788@freescale.com>
Thu, 9 Aug 2012 12:49:36 +0000 (20:49 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:35:11 +0000 (08:35 +0200)
CPUs may be waked up by SMP broadcast, and for this scenario, CPUs
can enter idle again directly to avoid run a long way to re-enter
idle, adding this interrupt check can minish SMP impact on peripheral
devices' performance.

Signed-off-by: Anson Huang <b20788@freescale.com>
arch/arm/mach-mx6/system.c

index ebc1ca1ee3cc0353103f4453735678efdec5e2f4..016dbec6cfc0d0103c9636cbd5005d4a06710e97 100644 (file)
@@ -30,6 +30,7 @@
 #include <mach/clock.h>
 #include <asm/proc-fns.h>
 #include <asm/system.h>
+#include <asm/hardware/gic.h>
 #include "crm_regs.h"
 #include "regs-anadig.h"
 
@@ -219,6 +220,13 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
 
 extern int tick_broadcast_oneshot_active(void);
 
+void ca9_do_idle(void)
+{
+       do {
+               cpu_do_idle();
+       } while (__raw_readl(gic_cpu_base_addr + GIC_CPU_HIGHPRI) == 1023);
+}
+
 void arch_idle_single_core(void)
 {
        u32 reg;
@@ -232,7 +240,7 @@ void arch_idle_single_core(void)
                reg |= MXC_CCM_CGPR_WAIT_MODE_FIX;
                __raw_writel(reg, MXC_CCM_CGPR);
 
-               cpu_do_idle();
+               ca9_do_idle();
        } else {
                /*
                  * Implement the 12:5 ARM:IPG_CLK ratio
@@ -250,7 +258,7 @@ void arch_idle_single_core(void)
                __raw_writel(wait_mode_arm_podf, MXC_CCM_CACRR);
                while (__raw_readl(MXC_CCM_CDHIPR))
                        ;
-               cpu_do_idle();
+               ca9_do_idle();
 
                __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR);
        }
@@ -258,7 +266,6 @@ void arch_idle_single_core(void)
 
 void arch_idle_with_workaround(cpu)
 {
-       u32 reg;
        u32 podf = wait_mode_arm_podf;
 
        *((char *)(&num_cpu_idle_lock) + (char)cpu) = 0x0;
@@ -302,7 +309,7 @@ void arch_idle_multi_core(void)
                reg |= MXC_CCM_CGPR_WAIT_MODE_FIX;
                __raw_writel(reg, MXC_CCM_CGPR);
 
-               cpu_do_idle();
+               ca9_do_idle();
        } else
                arch_idle_with_workaround(cpu);
 #ifdef CONFIG_LOCAL_TIMERS
@@ -329,7 +336,7 @@ void arch_idle(void)
                        reg &= ~MXC_CCM_CGPR_MEM_IPG_STOP_MASK;
                        __raw_writel(reg, MXC_CCM_CGPR);
 
-                       cpu_do_idle();
+                       ca9_do_idle();
                } else if (num_possible_cpus() == 1)
                        /* iMX6SL or iMX6DLS */
                        arch_idle_single_core();
@@ -337,7 +344,7 @@ void arch_idle(void)
                        arch_idle_multi_core();
        } else {
                mxc_cpu_lp_set(WAIT_CLOCKED);
-               cpu_do_idle();
+               ca9_do_idle();
        }
 }