rk29: implement sched_clock()
author黄涛 <huangtao@rock-chips.com>
Fri, 11 Mar 2011 05:20:01 +0000 (13:20 +0800)
committer黄涛 <huangtao@rock-chips.com>
Fri, 11 Mar 2011 05:20:01 +0000 (13:20 +0800)
arch/arm/Kconfig
arch/arm/mach-rk29/timer.c

index 5a41a4dec78eefad2e8ce4de71d0fc351aafc060..df6eafbf69b87004dbd06830228a1b63496bac8c 100644 (file)
@@ -721,10 +721,10 @@ config ARCH_RK2818
           
 config ARCH_RK29
        bool "Rockchip Soc Rk29"
-       select HAVE_CLK
        select CPU_V7
        select HAVE_CLK
        select COMMON_CLKDEV
+       select HAVE_SCHED_CLOCK
        select ARCH_HAS_CPUFREQ
        select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
index 501d820668ab5c8aed866cd72a21f66c2477c741..b00430d785332868f8c612e898d2697ccfb5efa0 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/clockchips.h>
 #include <linux/io.h>
 
+#include <asm/sched_clock.h>
 #include <asm/mach/time.h>
 #include <mach/rk29_iomap.h>
 
@@ -166,12 +167,20 @@ static cycle_t rk29_timer_read(struct clocksource *cs)
        return ~RK_TIMER_READVALUE(TIMER_CLKSRC);
 }
 
+/*
+ * Constants generated by clocksource_hz2mult(24000000, 26).
+ * This gives a resolution of about 41ns and a wrap period of about 178s.
+ */
+#define MULT   2796202667u
+#define SHIFT  26
+#define MASK   (u32)~0
+
 static struct clocksource rk29_timer_clocksource = {
        .name           = TIMER_CLKSRC_NAME,
        .rating         = 200,
        .read           = rk29_timer_read,
        .mask           = CLOCKSOURCE_MASK(32),
-       .shift          = 26,
+       .shift          = SHIFT,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -189,15 +198,36 @@ static void __init rk29_timer_init_clocksource(void)
        RK_TIMER_SETCOUNT(TIMER_CLKSRC, 0xFFFFFFFF);
        RK_TIMER_ENABLE_FREE_RUNNING(TIMER_CLKSRC);
 
-       cs->mult = clocksource_hz2mult(24000000, cs->shift);
+       cs->mult = MULT;
        if (clocksource_register(cs))
                printk(err, cs->name);
 }
 
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+       u32 cyc = ~RK_TIMER_READVALUE(TIMER_CLKSRC);
+       return cyc_to_fixed_sched_clock(&cd, cyc, MASK, MULT, SHIFT);
+}
+
+static void notrace rk29_update_sched_clock(void)
+{
+       u32 cyc = ~RK_TIMER_READVALUE(TIMER_CLKSRC);
+       update_sched_clock(&cd, cyc, MASK);
+}
+
+static void __init rk29_sched_clock_init(void)
+{
+       init_fixed_sched_clock(&cd, rk29_update_sched_clock,
+                              32, 24000000, MULT, SHIFT);
+}
+
 static void __init rk29_timer_init(void)
 {
        rk29_timer_init_clocksource();
        rk29_timer_init_clockevent();
+       rk29_sched_clock_init();
 }
 
 struct sys_timer rk29_timer = {