diff options
Diffstat (limited to 'arch/arm/mach-mx6/system.c')
-rw-r--r-- | arch/arm/mach-mx6/system.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index f6ffa2999ed2..4990a4a0abbb 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -57,6 +57,7 @@ volatile unsigned int num_cpu_idle; volatile unsigned int num_cpu_idle_lock = 0x0; int wait_mode_arm_podf; int cur_arm_podf; +bool enet_is_active; void arch_idle_with_workaround(int cpu); extern void *mx6sl_wfi_iram_base; @@ -350,7 +351,7 @@ void arch_idle_single_core(void) } } -void arch_idle_with_workaround(cpu) +void arch_idle_with_workaround(int cpu) { u32 podf = wait_mode_arm_podf; @@ -369,18 +370,10 @@ void arch_idle_with_workaround(cpu) } -void arch_idle_multi_core(void) +void arch_idle_multi_core(int cpu) { u32 reg; - int cpu = smp_processor_id(); -#ifdef CONFIG_LOCAL_TIMERS - if (!tick_broadcast_oneshot_active() - || !tick_oneshot_mode_active()) - return; - - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); -#endif /* iMX6Q and iMX6DL */ if ((cpu_is_mx6q() && chip_rev >= IMX_CHIP_REVISION_1_2) || (cpu_is_mx6dl() && chip_rev >= IMX_CHIP_REVISION_1_1)) { @@ -398,24 +391,37 @@ void arch_idle_multi_core(void) ca9_do_idle(); } else arch_idle_with_workaround(cpu); -#ifdef CONFIG_LOCAL_TIMERS - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); -#endif - } void arch_idle(void) { + int cpu = smp_processor_id(); + if (enable_wait_mode) { - mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); +#ifdef CONFIG_LOCAL_TIMERS + if (!tick_broadcast_oneshot_active() + || !tick_oneshot_mode_active()) + return; + + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); +#endif + if (enet_is_active) + /* Don't allow the chip to enter WAIT mode if enet is active + * and the GPIO workaround for ENET interrupts is not used, + * since all ENET interrupts donot wake up the SOC. + */ + mxc_cpu_lp_set(WAIT_CLOCKED); + else + mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); if (mem_clk_on_in_wait) { u32 reg; /* * MX6SL, MX6Q (TO1.2 or later) and - * MX6DL (TO1.1 or later) have a bit in CCM_CGPR that - * when cleared keeps the clocks to memories ON - * when ARM is in WFI. This mode can be used when - * IPG clock is very low (12MHz) and the ARM:IPG ratio + * MX6DL (TO1.1 or later) have a bit in + * CCM_CGPR that when cleared keeps the + * clocks to memories ON when ARM is in WFI. + * This mode can be used when IPG clock is + * very low (12MHz) and the ARM:IPG ratio * perhaps cannot be maintained. */ reg = __raw_readl(MXC_CCM_CGPR); @@ -427,8 +433,11 @@ void arch_idle(void) /* iMX6SL or iMX6DLS */ arch_idle_single_core(); else - arch_idle_multi_core(); - } else { + arch_idle_multi_core(cpu); +#ifdef CONFIG_LOCAL_TIMERS + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); +#endif + } else { mxc_cpu_lp_set(WAIT_CLOCKED); ca9_do_idle(); } |