ARM: tegra11x: Fix wake-up time adjustment
Bo Yan [Mon, 4 Feb 2013 19:09:57 +0000 (11:09 -0800)]
The wake up time adjustment for per-core CPU power down entry has
a few issues: the logic of checking masking bit is wrong and
unnecessary, the timer function for getting context is not used
elsewhere and seems redundant, the calculating statement itself
is confusing.

This patch aims to fix issues above.

Change-Id: Id717f50005e0c32db80af786d9b1fbbe628c196a
Signed-off-by: Bo Yan <byan@nvidia.com>
Reviewed-on: http://git-master/r/197065
(cherry picked from commit 544629015e3a2924ea094e9809131dd0be30954d)
Reviewed-on: http://git-master/r/200855
GVS: Gerrit_Virtual_Submit
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com>

arch/arm/mach-tegra/cpuidle-t11x.c
arch/arm/mach-tegra/timer.c
arch/arm/mach-tegra/timer.h

index 6eea8f3..00cf3e0 100644 (file)
@@ -371,37 +371,17 @@ static bool tegra_cpu_core_power_down(struct cpuidle_device *dev,
 {
 #ifdef CONFIG_SMP
        s64 sleep_time;
+       u32 cntp_tval;
+       u32 cntfrq;
        ktime_t entry_time;
-       struct arch_timer_context timer_context;
        bool sleep_completed = false;
        struct tick_sched *ts = tick_get_tick_sched(dev->cpu);
        unsigned int cpu = cpu_number(dev->cpu);
 
-       if (!arch_timer_get_state(&timer_context)) {
-               if ((timer_context.cntp_ctl & ARCH_TIMER_CTRL_ENABLE) &&
-                   !(timer_context.cntp_ctl & ARCH_TIMER_CTRL_IT_MASK)) {
-                       if (timer_context.cntp_tval <= 0) {
-                               cpu_do_idle();
-                               return false;
-                       }
-                       request = div_u64((u64)timer_context.cntp_tval *
-                                       1000000, timer_context.cntfrq);
-#ifdef CONFIG_TEGRA_LP2_CPU_TIMER
-                       if (request >= state->target_residency) {
-                               timer_context.cntp_tval -= state->exit_latency *
-                                       (timer_context.cntfrq / 1000000);
-                               __asm__("mcr p15, 0, %0, c14, c2, 0\n"
-                                       :
-                                       :
-                                       "r"(timer_context.cntp_tval));
-                       }
-#endif
-               }
-       }
-
-       if (!tegra_is_cpu_wake_timer_ready(dev->cpu) ||
-           (request < state->target_residency) ||
-           (!ts) || (ts->nohz_mode == NOHZ_MODE_INACTIVE)) {
+       if ((tegra_cpu_timer_get_remain(&request) == -ETIME) ||
+               (request <= state->target_residency) || (!ts) ||
+               (ts->nohz_mode == NOHZ_MODE_INACTIVE) ||
+               !tegra_is_cpu_wake_timer_ready(dev->cpu)) {
                /*
                 * Not enough time left to enter LP2, or wake timer not ready
                 */
@@ -409,6 +389,11 @@ static bool tegra_cpu_core_power_down(struct cpuidle_device *dev,
                return false;
        }
 
+#ifdef CONFIG_TEGRA_LP2_CPU_TIMER
+       asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (cntfrq));
+       cntp_tval = (request - state->exit_latency) * (cntfrq / 1000000);
+       asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r"(cntp_tval));
+#endif
        cpu_pm_enter();
 
 #if !defined(CONFIG_TEGRA_LP2_CPU_TIMER)
@@ -436,8 +421,9 @@ static bool tegra_cpu_core_power_down(struct cpuidle_device *dev,
        tegra_cpu_wake_by_time[dev->cpu] = LLONG_MAX;
 
 #ifdef CONFIG_TEGRA_LP2_CPU_TIMER
-       if (!arch_timer_get_state(&timer_context))
-               sleep_completed = (timer_context.cntp_tval <= 0);
+       asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (cntp_tval));
+       if ((s32)cntp_tval <= 0)
+               sleep_completed = true;
 #else
        sleep_completed = !tegra_pd_timer_remain();
        tegra_pd_set_trigger(0);
index 20bbdea..1729131 100644 (file)
@@ -316,42 +316,12 @@ static void __init tegra_init_late_timer(void)
 #endif
 
 #ifdef CONFIG_ARM_ARCH_TIMER
-int arch_timer_get_state(struct arch_timer_context *context)
-{
-       s32 val;
-
-       asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
-       context->cntp_tval = val;
-       asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
-       context->cntp_ctl = val;
-       asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
-       context->cntfrq = val;
-       return 0;
-}
-
-int tegra_cpu_timer_get_remain(s64 *time)
-{
-       s32 cntp_tval;
-       int ret = 0;
-
-       asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (cntp_tval));
-
-       if (cntp_tval <= 0)
-               ret = -ETIME;
-       else
-               *time = (s64)((s64)cntp_tval * arch_timer_us_mult)
-                       >> arch_timer_us_shift;
-
-       return 0;
-}
-#endif
-
-#ifdef CONFIG_ARM_ARCH_TIMER
 
 #ifndef CONFIG_TRUSTED_FOUNDATIONS
 /* Time Stamp Counter (TSC) base address */
 static void __iomem *tsc = IO_ADDRESS(TEGRA_TSC_BASE);
 #endif
+
 static bool arch_timer_initialized;
 
 #define TSC_CNTCR              0               /* TSC control registers */
@@ -570,6 +540,22 @@ void tegra_tsc_wait_for_resume(void)
        }
 }
 
+int tegra_cpu_timer_get_remain(s64 *time)
+{
+       s32 cntp_tval;
+       int ret = 0;
+
+       asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (cntp_tval));
+
+       if (cntp_tval <= 0)
+               ret = -ETIME;
+       else
+               *time = (s64)((s64)cntp_tval * arch_timer_us_mult)
+                       >> arch_timer_us_shift;
+
+       return ret;
+}
+
 #endif
 
 #else
index 6efee0c..6880b1b 100644 (file)
@@ -59,22 +59,12 @@ static inline void tegra_twd_suspend(struct tegra_twd_context *context) {}
 static inline void tegra_twd_resume(struct tegra_twd_context *context) {}
 #endif
 
-#ifdef CONFIG_ARM_ARCH_TIMER
-struct arch_timer_context {
-       s32 cntp_tval;
-       u32 cntp_ctl;
-       u32 cntfrq;
-};
-
-int arch_timer_get_state(struct arch_timer_context *);
-int tegra_cpu_timer_get_remain(s64 *time);
-#endif
-
 #if defined(CONFIG_ARM_ARCH_TIMER) && defined(CONFIG_PM_SLEEP)
 void tegra_tsc_suspend(void);
 void tegra_tsc_resume(void);
 void tegra_tsc_wait_for_suspend(void);
 void tegra_tsc_wait_for_resume(void);
+int tegra_cpu_timer_get_remain(s64 *time);
 #else
 static inline void tegra_tsc_suspend(void) {}
 static inline void tegra_tsc_resume(void) {}