#include <linux/clockchips.h>
#include <linux/io.h>
+#include <asm/sched_clock.h>
#include <asm/mach/time.h>
#include <mach/rk29_iomap.h>
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,
};
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 = {