blackfin: bf60x: pm: Add a debug option to calculate kernel wakeup time.
authorSonic Zhang <sonic.zhang@analog.com>
Thu, 17 May 2012 09:33:00 +0000 (17:33 +0800)
committerBob Liu <lliubbo@gmail.com>
Mon, 21 May 2012 06:54:52 +0000 (14:54 +0800)
Display the total time when kernel resumes normal from standby or suspend to mem
mode.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>
arch/blackfin/Kconfig.debug
arch/blackfin/include/asm/dpmc.h
arch/blackfin/mach-bf609/hibernate.S
arch/blackfin/mach-bf609/pm.c
arch/blackfin/mach-common/dpmc_modes.S
arch/blackfin/mach-common/pm.c

index e2a3d4c..7959469 100644 (file)
@@ -253,4 +253,11 @@ config BFIN_PSEUDODBG_INSNS
 
          Most people should say N here.
 
+config BFIN_PM_WAKEUP_TIME_BENCH
+       bool "Display the total time for kernel to resume from power saving mode"
+       default n
+       help
+         Display the total time when kernel resumes normal from standby or
+         suspend to mem mode.
+
 endmenu
index 528f476..e91eae8 100644 (file)
 #define PM_SYS_PUSH16(n, x)     _PM_PUSH(n, x, w, SYSMMR_BASE)
 #define PM_SYS_POP16(n, x)      _PM_POP(n, x, w, SYSMMR_BASE)
 
+       .macro bfin_init_pm_bench_cycles
+#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH
+       R4 = 0;
+       CYCLES = R4;
+       CYCLES2 = R4;
+       R4 = SYSCFG;
+       BITSET(R4, 1);
+       SYSCFG = R4;
+#endif
+       .endm
 
        .macro bfin_cpu_reg_save
        /*
        r7 = RETI;
        [--sp] = RETS;
        [--sp] = ASTAT;
+#ifndef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH
        [--sp] = CYCLES;
        [--sp] = CYCLES2;
+#endif
        [--sp] = SYSCFG;
        [--sp] = RETX;
        [--sp] = SEQSTAT;
        SEQSTAT = [sp++];
        RETX = [sp++];
        SYSCFG = [sp++];
+#ifndef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH
        CYCLES2 = [sp++];
        CYCLES = [sp++];
+#endif
        ASTAT = [sp++];
        RETS = [sp++];
 
index baedd6e..d37a532 100644 (file)
@@ -24,6 +24,9 @@ ENTRY(_enter_hibernate)
        P0.L = LO(DPM0_CTL);
        R3.H = HI(0x00000010);
        R3.L = LO(0x00000010);
+
+       bfin_init_pm_bench_cycles;
+
        [P0] = R3;
 
        SSYNC;
index 79cdf41..849d77e 100644 (file)
@@ -147,6 +147,18 @@ void bfin_deepsleep(unsigned long mask)
                        "idle;" \
                        : : \
                        );
+#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH
+       __asm__ __volatile__(
+               "%0 = 0;"
+               "CYCLES = %0;"
+               "CYCLES2 = %0;"
+               "%0 = SYSCFG;"
+               "BITSET(%0, 1);"
+               "SYSCFG = %0;"
+               : "=d,a" (dpm0_ctl) :
+       );
+#endif
+
 }
 
 __attribute__((l1_text))
index cfb7c3c..de99f3a 100644 (file)
@@ -42,6 +42,9 @@ ENTRY(_sleep_mode)
        BITCLR (R7, 5);
        w[p0] = R7.L;
        IDLE;
+
+       bfin_init_pm_bench_cycles;
+
        call _test_pll_locked;
 
        RETS = [SP++];
@@ -74,6 +77,9 @@ ENTRY(_hibernate_mode)
 
        /* Finally, we climb into our cave to hibernate */
        W[P3] = R4.L;
+
+       bfin_init_pm_bench_cycles;
+
        CLI R2;
        IDLE;
 .Lforever:
@@ -158,6 +164,8 @@ ENTRY(_sleep_deeper)
        SSYNC;
        IDLE;
 
+       bfin_init_pm_bench_cycles;
+
        call _test_pll_locked;
 
        P0.H = hi(PLL_DIV);
index 610a3cd..ca6655e 100644 (file)
@@ -247,9 +247,39 @@ static int bfin_pm_enter(suspend_state_t state)
        return 0;
 }
 
+#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH
+void bfin_pm_end(void)
+{
+       u32 cycle, cycle2;
+       u64 usec64;
+       u32 usec;
+
+       __asm__ __volatile__ (
+               "1: %0 = CYCLES2\n"
+               "%1 = CYCLES\n"
+               "%2 = CYCLES2\n"
+               "CC = %2 == %0\n"
+               "if ! CC jump 1b\n"
+               : "=d,a" (cycle2), "=d,a" (cycle), "=d,a" (usec) : : "CC"
+       );
+
+       usec64 = ((u64)cycle2 << 32) + cycle;
+       do_div(usec64, get_cclk() / USEC_PER_SEC);
+       usec = usec64;
+       if (usec == 0)
+               usec = 1;
+
+       pr_info("PM: resume of kernel completes after  %ld msec %03ld usec\n",
+               usec / USEC_PER_MSEC, usec % USEC_PER_MSEC);
+}
+#endif
+
 static const struct platform_suspend_ops bfin_pm_ops = {
        .enter = bfin_pm_enter,
        .valid  = bfin_pm_valid,
+#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH
+       .end = bfin_pm_end,
+#endif
 };
 
 static int __init bfin_pm_init(void)