Skip to contentSkip to conversation

32k timer reorg and sched_clock cleanup

PATCH In review Kevin Hilman 2 participants 11 messages Nov 12, 2007 – Nov 26, 2007

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover 32k timer reorg and sched_clock cleanup

[ resend of previous series, with more sched_clock cleanup ]

Here's a short series of patches to reorganize and consolidate the 32k timer code and the implementation of sched_clock(). In particular, conslidate the usage of DM timers, move the OMAP1 specifics into mach-omap1, and have only one sched_clock().

Kevin

--

#1 lore raw

PATCH 1/4 ARM: OMAP: re-organize duplicated 32k-timer code

On OMAP2/3, the gp-timer code can be used for a 32kHz timer simply by setting the source to be the 32k clock instead of sys_clk.

This patch uses the mach-omap2/timer-gp.c code for 32kHz timer on OMAP2, moving the logic into mach-omap2/timer-gp.c, and not using plat-omap/timer32k.c which, for OMAP2, is redundant with the timer-gp code.

Also, if CONFIG_OMAP_32K_TIMER is enabled, the gptimer-based clocksource is not used. Instead the default 32k sync counter is used as the clocksource (see the clocksource in plat-omap/common.c.) This is important for sleep/suspend so there is a valid counter during sleep. Note that the suspend/sleep code needs fixing to check for overflows of this counter.

In addition, the OMAP2/3 details are removed from timer32k.c leaving that with only OMAP1 specifics. A follow-up patch will move it from plat-omap common code to mach-omap1.

---
 arch/arm/mach-omap2/Makefile   |    4 ---
 arch/arm/mach-omap2/timer-gp.c |   14 ++++++++++++
 arch/arm/plat-omap/Makefile    |    2 +
 arch/arm/plat-omap/timer32k.c  |   47 -----------------------------------------
 4 files changed, 18 insertions(+), 49 deletions(-)
arch/arm/mach-omap2/Makefile +1 -3
Index: dev/arch/arm/mach-omap2/Makefile
===================================================================
@@ -4,9 +4,7 @@
 
 # Common support
 obj-y := irq.o id.o io.o sram-fn.o memory.o prcm.o clock.o mux.o devices.o \
-	 serial.o gpmc.o
-
-obj-$(CONFIG_OMAP_MPU_TIMER)		+= timer-gp.o
+	 serial.o gpmc.o timer-gp.o
 
 # Power Management
 obj-$(CONFIG_PM) += pm.o sleep.o
arch/arm/mach-omap2/timer-gp.c +14 -0
Index: dev/arch/arm/mach-omap2/timer-gp.c
===================================================================
@@ -104,7 +104,11 @@ static void __init omap2_gp_clockevent_i
 	gptimer = omap_dm_timer_request_specific(1);
 	BUG_ON(gptimer == NULL);
 
+#if defined(CONFIG_OMAP_32K_TIMER)
+	omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ);
+#else
 	omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK);
+#endif
 	tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
 
 	omap2_gp_timer_irq.dev_id = (void *)gptimer;
@@ -122,6 +126,15 @@ static void __init omap2_gp_clockevent_i
 	clockevents_register_device(&clockevent_gpt);
 }
 
+#ifdef CONFIG_OMAP_32K_TIMER
+/* 
+ * When 32k-timer is enabled, don't use GPTimer for clocksource
+ * instead, just leave default clocksource which uses the 32k
+ * sync counter.  See clocksource setup in see plat-omap/common.c. 
+ */
+
+static inline void __init omap2_gp_clocksource_init(void) {}
+#else
 /*
  * clocksource
  */
@@ -167,6 +180,7 @@ static void __init omap2_gp_clocksource_
 	if (clocksource_register(&clocksource_gpt))
 		printk(err2, clocksource_gpt.name);
 }
+#endif
 
 static void __init omap2_gp_timer_init(void)
 {
arch/arm/plat-omap/Makefile +2 -0
Index: dev/arch/arm/plat-omap/Makefile
===================================================================
@@ -9,7 +9,9 @@ obj-m :=
 obj-n :=
 obj-  :=
 
+ifeq ($(CONFIG_ARCH_OMAP1),y)
 obj-$(CONFIG_OMAP_32K_TIMER)	+= timer32k.o
+endif
 
 # OCPI interconnect support for 1710, 1610 and 5912
 obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
arch/arm/plat-omap/timer32k.c +1 -46

71 lines not on this page · raw message

--

#2 lore raw

PATCH 2/4 ARM: OMAP: Move 32k-based sched_clock() to common code

In reply to Kevin Hilman

Since 32k timer code is moving to OMAP1 specific dir, move the 32k-based sched_clock() into common code where it is based on the 32k sync counter and can be used even when using MPU timer.

While moving, change the ticks-to-nsecs conversion to use the helper functions provided by clocksource.h.

Also removed the unused ticks_to_usec, leaving only ticks_to_nsec.

---
 arch/arm/plat-omap/common.c   |   17 +++++++++++++++++
 arch/arm/plat-omap/timer32k.c |   26 --------------------------
 2 files changed, 17 insertions(+), 26 deletions(-)
arch/arm/plat-omap/common.c +17 -0
Index: dev/arch/arm/plat-omap/common.c
===================================================================
@@ -213,6 +213,23 @@ static struct clocksource clocksource_32
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+/*
+ * Rounds down to nearest nsec.
+ */
+unsigned long long omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
+{
+	return cyc2ns(&clocksource_32k, ticks_32k);
+}
+
+/*
+ * Returns current time from boot in nsecs. It's OK for this to wrap
+ * around for now, as it's just a relative time stamp.
+ */
+unsigned long long sched_clock(void)
+{
+	return omap_32k_ticks_to_nsecs(omap_32k_read());
+}
+
 static int __init omap_init_clocksource_32k(void)
 {
 	static char err[] __initdata = KERN_ERR
arch/arm/plat-omap/timer32k.c +0 -26
Index: dev/arch/arm/plat-omap/timer32k.c
===================================================================
@@ -159,32 +159,6 @@ static inline unsigned long omap_32k_syn
 	return omap_readl(TIMER_32K_SYNCHRONIZED);
 }
 
-/*
- * Rounds down to nearest usec. Note that this will overflow for larger values.
- */
-static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
-{
-	return (ticks_32k * 5*5*5*5*5*5) >> 9;
-}
-
-/*
- * Rounds down to nearest nsec.
- */
-static inline unsigned long long
-omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
-{
-	return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
-}
-
-/*
- * Returns current time from boot in nsecs. It's OK for this to wrap
- * around for now, as it's just a relative time stamp.
- */
-unsigned long long sched_clock(void)
-{
-	return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
-}
-
 static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 {
 	struct clock_event_device *evt = &clockevent_32k_timer;

--

#3 lore raw

PATCH 3/4 ARM: OMAP: Remove MPU-timer based sched_clock()

In reply to Kevin Hilman

Remove MPU-timer based sched_clock() in favor of the common one based on 32k sync timer which works across all OMAP1/2/3 platforms.

Using 32k based one also gives a valid sched_clock() very early in the boot process.

---
 arch/arm/mach-omap1/time.c |   16 ----------------
 1 file changed, 16 deletions(-)
arch/arm/mach-omap1/time.c +0 -16
Index: dev/arch/arm/mach-omap1/time.c
===================================================================
@@ -260,22 +260,6 @@ static void __init omap_init_clocksource
 		printk(err, clocksource_mpu.name);
 }
 
-
-/*
- * Scheduler clock - returns current time in nanosec units.
- */
-unsigned long long sched_clock(void)
-{
-	unsigned long ticks = 0 - omap_mpu_timer_read(1);
-	unsigned long long ticks64;
-
-	ticks64 = omap_mpu_timer2_overflows;
-	ticks64 <<= 32;
-	ticks64 |= ticks;
-
-	return cycles_2_ns(ticks64);
-}
-
 /*
  * ---------------------------------------------------------------------------
  * Timer initialization

--

maintainer
#4 lore raw

Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()

Quoted 5 lines · Kevin Hilman

Remove MPU-timer based sched_clock() in favor of the common one based on 32k sync timer which works across all OMAP1/2/3 platforms.

Using 32k based one also gives a valid sched_clock() very early in the boot process.

AFAIK there is no 32k sync timer for 15xx, or have I missed something?

Tony

maintainer
#5 lore raw

Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()

Quoted 8 lines · Tony Lindgren
Quoted 5 lines · Kevin Hilman

Remove MPU-timer based sched_clock() in favor of the common one based on 32k sync timer which works across all OMAP1/2/3 platforms.

Using 32k based one also gives a valid sched_clock() very early in the boot process.

AFAIK there is no 32k sync timer for 15xx, or have I missed something?

I'll push the other three patches today.

Tony

#6 lore raw

Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()

In reply to Tony Lindgren
Quoted 9 lines · Tony Lindgren
Quoted 5 lines · Kevin Hilman

Remove MPU-timer based sched_clock() in favor of the common one based on 32k sync timer which works across all OMAP1/2/3 platforms.

Using 32k based one also gives a valid sched_clock() very early in the boot process.

AFAIK there is no 32k sync timer for 15xx, or have I missed something?

No there isn't.

But all this means is that 15xx has no higher resolution sched_clock(). The ARM default jiffies-based one will be used.

Kevin

maintainer
#7 lore raw

Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()

Quoted 9 lines · Kevin Hilman
Quoted 7 lines · Tony Lindgren
Quoted 5 lines · Kevin Hilman

Remove MPU-timer based sched_clock() in favor of the common one based on 32k sync timer which works across all OMAP1/2/3 platforms.

Using 32k based one also gives a valid sched_clock() very early in the boot process.

Quoted 7 lines
Quoted 2 lines

AFAIK there is no 32k sync timer for 15xx, or have I missed something?

No there isn't.

But all this means is that 15xx has no higher resolution sched_clock(). The ARM default jiffies-based one will be used.

I guess I don't understand what you're after by not using mpu timer 2 for proper sched_clock, some PM issues?

Maybe for PM reasons not having mpu timer 2 running could make sense if it blocks some sleep states. But then again there's no timesource during sleep states unless mpu timer 2 can use the 32K clock as a source clock..

Tony

#8 lore raw

Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()

Quoted 13 lines · Tony Lindgren
Quoted 12 lines · Kevin Hilman
Quoted 9 lines · Tony Lindgren
Quoted 5 lines · Kevin Hilman

Remove MPU-timer based sched_clock() in favor of the common one based on 32k sync timer which works across all OMAP1/2/3 platforms.

Using 32k based one also gives a valid sched_clock() very early in the boot process.

AFAIK there is no 32k sync timer for 15xx, or have I missed something?

Quoted 7 lines
Quoted 4 lines

No there isn't.

But all this means is that 15xx has no higher resolution sched_clock(). The ARM default jiffies-based one will be used.

I guess I don't understand what you're after by not using mpu timer 2 for proper sched_clock, some PM issues?

The main reason was for cleanup purposes. There were various Kconfig combinations that would configure different sched_clock() sources based on MPU timers or 32k timers.

I was after having a consistent sched_clock() no matter which MPU or 32k timers were enabled, and which could work on all/most platforms. The result is that everything with a 32k sync timer gets a 32k sched_clock(), everyone else gets a jiffies-based one.

The secondary reason was to not have sched_clock() based on a timer that might stop during PM activity like suspend.

Quoted 3 lines

Maybe for PM reasons not having mpu timer 2 running could make sense if it blocks some sleep states. But then again there's no timesource during sleep states unless mpu timer 2 can use the 32K clock as a source clock..

maintainer
#9 lore raw

Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()

Quoted 23 lines · Kevin Hilman
Quoted 13 lines · Tony Lindgren
Quoted 12 lines · Kevin Hilman
Quoted 9 lines · Tony Lindgren
Quoted 5 lines · Kevin Hilman

Remove MPU-timer based sched_clock() in favor of the common one based on 32k sync timer which works across all OMAP1/2/3 platforms.

Using 32k based one also gives a valid sched_clock() very early in the boot process.

AFAIK there is no 32k sync timer for 15xx, or have I missed something?

Quoted 7 lines
Quoted 4 lines

No there isn't.

But all this means is that 15xx has no higher resolution sched_clock(). The ARM default jiffies-based one will be used.

I guess I don't understand what you're after by not using mpu timer 2 for proper sched_clock, some PM issues?

Quoted 8 lines

The main reason was for cleanup purposes. There were various Kconfig combinations that would configure different sched_clock() sources based on MPU timers or 32k timers.

I was after having a consistent sched_clock() no matter which MPU or 32k timers were enabled, and which could work on all/most platforms. The result is that everything with a 32k sync timer gets a 32k sched_clock(), everyone else gets a jiffies-based one.

OK

Quoted 7 lines

The secondary reason was to not have sched_clock() based on a timer that might stop during PM activity like suspend.

Quoted 3 lines

Maybe for PM reasons not having mpu timer 2 running could make sense if it blocks some sleep states. But then again there's no timesource during sleep states unless mpu timer 2 can use the 32K clock as a source clock..

OK, I'll apply that patch, let's let the 15xx users add it back if needed ;)

Regards,

Tony

#10 lore raw

PATCH 4/4 ARM: OMAP: Move timer32k to mach-omap1

In reply to Kevin Hilman

Move now OMAP1-specific timer32k code to mach-omap1 since OMAP2/3 32k timers are done in gptimer code.

---
 arch/arm/mach-omap1/Makefile   |    3 
 arch/arm/mach-omap1/timer32k.c |  209 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/Makefile    |    4 
 arch/arm/plat-omap/timer32k.c  |  209 -----------------------------------------
 4 files changed, 211 insertions(+), 214 deletions(-)
arch/arm/mach-omap1/Makefile +2 -1
Index: dev/arch/arm/mach-omap1/Makefile
===================================================================
@@ -5,7 +5,8 @@
 # Common support
 obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o
 
-obj-$(CONFIG_OMAP_MPU_TIMER)		+= time.o
+obj-$(CONFIG_OMAP_MPU_TIMER)	+= time.o
+obj-$(CONFIG_OMAP_32K_TIMER)	+= timer32k.o
 
 # Power Management
 obj-$(CONFIG_PM) += pm.o sleep.o
arch/arm/mach-omap1/timer32k.c new file +209 -0

209 lines not on this page · raw message

arch/arm/plat-omap/Makefile +0 -4
Index: dev/arch/arm/plat-omap/Makefile
===================================================================
@@ -9,10 +9,6 @@ obj-m :=
 obj-n :=
 obj-  :=
 
-ifeq ($(CONFIG_ARCH_OMAP1),y)
-obj-$(CONFIG_OMAP_32K_TIMER)	+= timer32k.o
-endif
-
 # OCPI interconnect support for 1710, 1610 and 5912
 obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
 
arch/arm/plat-omap/timer32k.c deleted +0 -209

209 lines not on this page · raw message

--