From: Dirk Behme <dirk.behme@googlemail.com>
To: OMAP-Linux <linux-omap-open-source@linux.omap.com>
Subject: [RFC] [PATCH] ARM: OMAP1: Add clocksource driver for OMAP1
Date: Tue, 07 Nov 2006 16:32:27 +0100 [thread overview]
Message-ID: <4550A70B.7020609@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1480 bytes --]
Add clocksource driver for OMAP1.
Signed-off-by: Dirk Behme <dirk.behme_at_gmail.com>
What do you think about this? OSK still boots and I can't
see any runtime issues. But maybe others?
For reference see
- The two new files highres.txt and hrtimers.txt in
http://tglx.de/projects/hrtimers/2.6.18/patch-2.6.18-hrt-dyntick2.patch
-
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2006-October/036695.html
(and the other "clocksource" patches there)
-
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2006-October/036713.html
Next steps would be:
* Move omap_clocksource_init() to something like
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2006-October/036700.html
* Add clockevent system, e.g.
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2006-October/036705.html
(and the other "clockevent" patches there)
* Enable generic time and generic clock events:
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2006-October/036696.html
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2006-October/036711.html
But seems that we have to wait some integration cylces
of mainline for this.
Cheers
Dirk
Btw: With clocksource added, we should be able to use
rt-preempt patch:
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2006-October/036496.html
rt.wiki.kernel.org
http://www.linuxdevices.com/news/NS9566944929.html
if it will be available for 2.6.19 (with some small OMAP
specific adaptions) .
[-- Attachment #2: omap1_clocksource_patch.txt --]
[-- Type: text/plain, Size: 4969 bytes --]
Index: linux-osk/arch/arm/mach-omap1/time.c
===================================================================
--- linux-osk.orig/arch/arm/mach-omap1/time.c
+++ linux-osk/arch/arm/mach-omap1/time.c
@@ -39,6 +39,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/clocksource.h>
#include <asm/system.h>
#include <asm/hardware.h>
@@ -58,36 +59,6 @@ struct sys_timer omap_timer;
#define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE
#define OMAP_MPU_TIMER_OFFSET 0x100
-/* cycles to nsec conversions taken from arch/i386/kernel/timers/timer_tsc.c,
- * converted to use kHz by Kevin Hilman */
-/* convert from cycles(64bits) => nanoseconds (64bits)
- * basic equation:
- * ns = cycles / (freq / ns_per_sec)
- * ns = cycles * (ns_per_sec / freq)
- * ns = cycles * (10^9 / (cpu_khz * 10^3))
- * ns = cycles * (10^6 / cpu_khz)
- *
- * Then we use scaling math (suggested by george at mvista.com) to get:
- * ns = cycles * (10^6 * SC / cpu_khz / SC
- * ns = cycles * cyc2ns_scale / SC
- *
- * And since SC is a constant power of two, we can convert the div
- * into a shift.
- * -johnstul at us.ibm.com "math is hard, lets go shopping!"
- */
-static unsigned long cyc2ns_scale;
-#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-
-static inline void set_cyc2ns_scale(unsigned long cpu_khz)
-{
- cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
-}
-
-static inline unsigned long long cycles_2_ns(unsigned long long cyc)
-{
- return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
-}
-
/*
* MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs
* will break. On P2, the timer count rate is 6.5 MHz after programming PTV
@@ -131,43 +102,9 @@ static inline void omap_mpu_timer_start(
timer->cntl = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_AR | MPU_TIMER_ST);
}
-unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks)
-{
- unsigned long long nsec;
-
- nsec = cycles_2_ns((unsigned long long)nr_ticks);
- return (unsigned long)nsec / 1000;
-}
-
-/*
- * Last processed system timer interrupt
- */
-static unsigned long omap_mpu_timer_last = 0;
-
-/*
- * Returns elapsed usecs since last system timer interrupt
- */
-static unsigned long omap_mpu_timer_gettimeoffset(void)
-{
- unsigned long now = 0 - omap_mpu_timer_read(0);
- unsigned long elapsed = now - omap_mpu_timer_last;
-
- return omap_mpu_timer_ticks_to_usecs(elapsed);
-}
-
-/*
- * Elapsed time between interrupts is calculated using timer0.
- * Latency during the interrupt is calculated using timer1.
- * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz).
- */
static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id)
{
- unsigned long now, latency;
-
write_seqlock(&xtime_lock);
- now = 0 - omap_mpu_timer_read(0);
- latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1);
- omap_mpu_timer_last = now - latency;
timer_tick();
write_sequnlock(&xtime_lock);
@@ -180,42 +117,33 @@ static struct irqaction omap_mpu_timer_i
.handler = omap_mpu_timer_interrupt,
};
-static unsigned long omap_mpu_timer1_overflows;
-static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
+static __init void omap_init_mpu_timer(void)
{
- omap_mpu_timer1_overflows++;
- return IRQ_HANDLED;
+ setup_irq(INT_TIMER1, &omap_mpu_timer_irq);
+ omap_mpu_timer_start(0, MPU_TIMER_TICK_PERIOD);
}
-static struct irqaction omap_mpu_timer1_irq = {
- .name = "mpu timer1 overflow",
- .flags = IRQF_DISABLED,
- .handler = omap_mpu_timer1_interrupt,
-};
-
-static __init void omap_init_mpu_timer(void)
+cycle_t omap_get_cycles(void)
{
- set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000);
- omap_timer.offset = omap_mpu_timer_gettimeoffset;
- setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
- setup_irq(INT_TIMER2, &omap_mpu_timer_irq);
- omap_mpu_timer_start(0, 0xffffffff);
- omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD);
+ return omap_mpu_timer_read(0);
}
-/*
- * Scheduler clock - returns current time in nanosec units.
- */
-unsigned long long sched_clock(void)
-{
- unsigned long ticks = 0 - omap_mpu_timer_read(0);
- unsigned long long ticks64;
+static struct clocksource clocksource_omap = {
+ .name = "timer0",
+ .rating = 200,
+ .read = omap_get_cycles,
+ .mask = 0xFFFFFFFF,
+ .shift = 20,
+ .is_continuous = 1,
+};
- ticks64 = omap_mpu_timer1_overflows;
- ticks64 <<= 32;
- ticks64 |= ticks;
+static int __init omap_init_clocksource(void)
+{
+ clocksource_omap.mult = clocksource_khz2mult(MPU_TICKS_PER_SEC/1000,
+ clocksource_omap.shift);
+ clocksource_register(&clocksource_omap);
- return cycles_2_ns(ticks64);
+ return 0;
}
/*
@@ -226,9 +154,9 @@ unsigned long long sched_clock(void)
static void __init omap_timer_init(void)
{
omap_init_mpu_timer();
+ omap_init_clocksource();
}
struct sys_timer omap_timer = {
.init = omap_timer_init,
- .offset = NULL, /* Initialized later */
};
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
next reply other threads:[~2006-11-07 15:32 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-11-07 15:32 Dirk Behme [this message]
[not found] ` <4550CA9E.6090500@mvista.com>
2006-11-08 16:44 ` [RFC] [PATCH] ARM: OMAP1: Add clocksource driver for OMAP1 Dirk Behme
2006-11-10 0:29 ` Tony Lindgren
2006-11-10 0:48 ` Kevin Hilman
2006-11-10 0:53 ` Tony Lindgren
2006-11-30 19:57 ` Woodruff, Richard
2006-11-30 21:30 ` David Brownell
2006-11-30 21:49 ` Woodruff, Richard
2006-11-30 22:32 ` David Brownell
2006-11-30 22:57 ` Woodruff, Richard
2006-11-30 22:12 ` tony
2006-11-30 21:59 ` tony
2006-11-30 22:24 ` Woodruff, Richard
2006-11-30 22:37 ` tony
2006-11-30 17:55 ` Dirk Behme
2006-11-30 17:50 ` Daniel Walker
2006-12-01 16:12 ` Dirk Behme
2006-12-02 3:21 ` Daniel Walker
2006-12-02 6:11 ` Dirk Behme
2006-12-02 6:54 ` Daniel Walker
2006-12-02 7:06 ` Dirk Behme
2006-12-02 7:18 ` Daniel Walker
2006-12-04 23:34 ` Kevin Hilman
2006-11-30 19:14 ` David Brownell
2006-11-30 20:33 ` Dirk Behme
2006-11-30 21:22 ` [RFC] [PATCH] ARM: Add clocksource driver for OMAP1 and OMAP2 David Brownell
2006-12-01 18:21 ` Dirk Behme
2006-12-01 19:03 ` David Brownell
2006-12-01 22:13 ` Tony Lindgren
2006-12-03 2:58 ` David Brownell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4550A70B.7020609@gmail.com \
--to=dirk.behme@googlemail.com \
--cc=linux-omap-open-source@linux.omap.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox