public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] 32k timer reorg and sched_clock cleanup
@ 2007-11-12 23:24 Kevin Hilman
  2007-11-12 23:24 ` [PATCH 1/4] ARM: OMAP: re-organize duplicated 32k-timer code Kevin Hilman
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Kevin Hilman @ 2007-11-12 23:24 UTC (permalink / raw)
  To: linux-omap-open-source

[ 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

--

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] ARM: OMAP: re-organize duplicated 32k-timer code
  2007-11-12 23:24 [PATCH 0/4] 32k timer reorg and sched_clock cleanup Kevin Hilman
@ 2007-11-12 23:24 ` Kevin Hilman
  2007-11-12 23:24 ` [PATCH 2/4] ARM: OMAP: Move 32k-based sched_clock() to common code Kevin Hilman
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: Kevin Hilman @ 2007-11-12 23:24 UTC (permalink / raw)
  To: linux-omap-open-source

[-- Attachment #1: use-dmtimer-for-32k-timer.patch --]
[-- Type: text/plain, Size: 5815 bytes --]

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.

Signed-off-by: Kevin Hilman <khilman@mvista.com>
---
 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(-)

Index: dev/arch/arm/mach-omap2/Makefile
===================================================================
--- dev.orig/arch/arm/mach-omap2/Makefile
+++ 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
Index: dev/arch/arm/mach-omap2/timer-gp.c
===================================================================
--- dev.orig/arch/arm/mach-omap2/timer-gp.c
+++ 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)
 {
Index: dev/arch/arm/plat-omap/Makefile
===================================================================
--- dev.orig/arch/arm/plat-omap/Makefile
+++ 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
Index: dev/arch/arm/plat-omap/timer32k.c
===================================================================
--- dev.orig/arch/arm/plat-omap/timer32k.c
+++ dev/arch/arm/plat-omap/timer32k.c
@@ -70,10 +70,6 @@ struct sys_timer omap_timer;
 
 #if defined(CONFIG_ARCH_OMAP16XX)
 #define TIMER_32K_SYNCHRONIZED		0xfffbc410
-#elif defined(CONFIG_ARCH_OMAP24XX)
-#define TIMER_32K_SYNCHRONIZED		(OMAP2_32KSYNCT_BASE + 0x10)
-#elif defined(CONFIG_ARCH_OMAP34XX)
-#define TIMER_32K_SYNCHRONIZED		0x48320010
 #else
 #error OMAP 32KHz timer does not currently work on 15XX!
 #endif
@@ -95,8 +91,6 @@ struct sys_timer omap_timer;
 #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
 				(((nr_jiffies) * (clock_rate)) / HZ)
 
-#if defined(CONFIG_ARCH_OMAP1)
-
 static inline void omap_32k_timer_write(int val, int reg)
 {
 	omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
@@ -122,30 +116,6 @@ static inline void omap_32k_timer_stop(v
 
 #define omap_32k_timer_ack_irq()
 
-#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-
-static struct omap_dm_timer *gptimer;
-
-static inline void omap_32k_timer_start(unsigned long load_val)
-{
-	omap_dm_timer_set_load(gptimer, 1, 0xffffffff - load_val);
-	omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
-	omap_dm_timer_start(gptimer);
-}
-
-static inline void omap_32k_timer_stop(void)
-{
-	omap_dm_timer_stop(gptimer);
-}
-
-static inline void omap_32k_timer_ack_irq(void)
-{
-	u32 status = omap_dm_timer_read_status(gptimer);
-	omap_dm_timer_write_status(gptimer, status);
-}
-
-#endif
-
 static int omap_32k_timer_set_next_event(unsigned long delta,
 					 struct clock_event_device *dev)
 {
@@ -233,22 +203,7 @@ static struct irqaction omap_32k_timer_i
 
 static __init void omap_init_32k_timer(void)
 {
-	if (cpu_class_is_omap1())
-		setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	/* REVISIT: Check 24xx TIOCP_CFG settings after idle works */
-	if (cpu_class_is_omap2()) {
-		gptimer = omap_dm_timer_request_specific(1);
-		BUG_ON(gptimer == NULL);
-
-		omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ);
-		setup_irq(omap_dm_timer_get_irq(gptimer), &omap_32k_timer_irq);
-		omap_dm_timer_set_int_enable(gptimer,
-			OMAP_TIMER_INT_CAPTURE | OMAP_TIMER_INT_OVERFLOW |
-			OMAP_TIMER_INT_MATCH);
-	}
-#endif
+	setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
 
 	clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC,
 					   NSEC_PER_SEC,

--

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/4] ARM: OMAP: Move 32k-based sched_clock() to common code
  2007-11-12 23:24 [PATCH 0/4] 32k timer reorg and sched_clock cleanup Kevin Hilman
  2007-11-12 23:24 ` [PATCH 1/4] ARM: OMAP: re-organize duplicated 32k-timer code Kevin Hilman
@ 2007-11-12 23:24 ` Kevin Hilman
  2007-11-12 23:24 ` [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock() Kevin Hilman
  2007-11-12 23:24 ` [PATCH 4/4] ARM: OMAP: Move timer32k to mach-omap1 Kevin Hilman
  3 siblings, 0 replies; 11+ messages in thread
From: Kevin Hilman @ 2007-11-12 23:24 UTC (permalink / raw)
  To: linux-omap-open-source

[-- Attachment #1: sched-clock-32k.patch --]
[-- Type: text/plain, Size: 2474 bytes --]

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.

Signed-off-by: Kevin Hilman <khilman@mvista.com>

---
 arch/arm/plat-omap/common.c   |   17 +++++++++++++++++
 arch/arm/plat-omap/timer32k.c |   26 --------------------------
 2 files changed, 17 insertions(+), 26 deletions(-)

Index: dev/arch/arm/plat-omap/common.c
===================================================================
--- dev.orig/arch/arm/plat-omap/common.c
+++ 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
Index: dev/arch/arm/plat-omap/timer32k.c
===================================================================
--- dev.orig/arch/arm/plat-omap/timer32k.c
+++ 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;

--

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()
  2007-11-12 23:24 [PATCH 0/4] 32k timer reorg and sched_clock cleanup Kevin Hilman
  2007-11-12 23:24 ` [PATCH 1/4] ARM: OMAP: re-organize duplicated 32k-timer code Kevin Hilman
  2007-11-12 23:24 ` [PATCH 2/4] ARM: OMAP: Move 32k-based sched_clock() to common code Kevin Hilman
@ 2007-11-12 23:24 ` Kevin Hilman
  2007-11-23 19:18   ` Tony Lindgren
  2007-11-12 23:24 ` [PATCH 4/4] ARM: OMAP: Move timer32k to mach-omap1 Kevin Hilman
  3 siblings, 1 reply; 11+ messages in thread
From: Kevin Hilman @ 2007-11-12 23:24 UTC (permalink / raw)
  To: linux-omap-open-source

[-- Attachment #1: remove-MPU-sched-clock.patch --]
[-- Type: text/plain, Size: 1069 bytes --]

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.

Signed-off-by: Kevin Hilman <khilman@mvista.com>
---
 arch/arm/mach-omap1/time.c |   16 ----------------
 1 file changed, 16 deletions(-)

Index: dev/arch/arm/mach-omap1/time.c
===================================================================
--- dev.orig/arch/arm/mach-omap1/time.c
+++ 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

--

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/4] ARM: OMAP: Move timer32k to mach-omap1
  2007-11-12 23:24 [PATCH 0/4] 32k timer reorg and sched_clock cleanup Kevin Hilman
                   ` (2 preceding siblings ...)
  2007-11-12 23:24 ` [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock() Kevin Hilman
@ 2007-11-12 23:24 ` Kevin Hilman
  3 siblings, 0 replies; 11+ messages in thread
From: Kevin Hilman @ 2007-11-12 23:24 UTC (permalink / raw)
  To: linux-omap-open-source

[-- Attachment #1: move-timer32k-to-omap1.patch --]
[-- Type: text/plain, Size: 14364 bytes --]

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

Signed-off-by: Kevin Hilman <khilman@mvista.com>
---
 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(-)

Index: dev/arch/arm/mach-omap1/Makefile
===================================================================
--- dev.orig/arch/arm/mach-omap1/Makefile
+++ 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
Index: dev/arch/arm/mach-omap1/timer32k.c
===================================================================
--- /dev/null
+++ dev/arch/arm/mach-omap1/timer32k.c
@@ -0,0 +1,209 @@
+/*
+ * linux/arch/arm/plat-omap/timer32k.c
+ *
+ * OMAP 32K Timer
+ *
+ * Copyright (C) 2004 - 2005 Nokia Corporation
+ * Partial timer rewrite and additional dynamic tick timer support by
+ * Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * OMAP Dual-mode timer framework support by Timo Teras
+ *
+ * MPU timer code based on the older MPU timer code for OMAP
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/arch/dmtimer.h>
+
+struct sys_timer omap_timer;
+
+/*
+ * ---------------------------------------------------------------------------
+ * 32KHz OS timer
+ *
+ * This currently works only on 16xx, as 1510 does not have the continuous
+ * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
+ * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
+ * on 1510 would be possible, but the timer would not be as accurate as
+ * with the 32KHz synchronized timer.
+ * ---------------------------------------------------------------------------
+ */
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+#define TIMER_32K_SYNCHRONIZED		0xfffbc410
+#else
+#error OMAP 32KHz timer does not currently work on 15XX!
+#endif
+
+/* 16xx specific defines */
+#define OMAP1_32K_TIMER_BASE		0xfffb9000
+#define OMAP1_32K_TIMER_CR		0x08
+#define OMAP1_32K_TIMER_TVR		0x00
+#define OMAP1_32K_TIMER_TCR		0x04
+
+#define OMAP_32K_TICKS_PER_SEC		(32768)
+
+/*
+ * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
+ * so with HZ = 128, TVR = 255.
+ */
+#define OMAP_32K_TIMER_TICK_PERIOD	((OMAP_32K_TICKS_PER_SEC / HZ) - 1)
+
+#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
+				(((nr_jiffies) * (clock_rate)) / HZ)
+
+static inline void omap_32k_timer_write(int val, int reg)
+{
+	omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
+}
+
+static inline unsigned long omap_32k_timer_read(int reg)
+{
+	return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
+}
+
+static inline void omap_32k_timer_start(unsigned long load_val)
+{
+	if (!load_val)
+		load_val = 1;
+	omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
+	omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
+}
+
+static inline void omap_32k_timer_stop(void)
+{
+	omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR);
+}
+
+#define omap_32k_timer_ack_irq()
+
+static int omap_32k_timer_set_next_event(unsigned long delta,
+					 struct clock_event_device *dev)
+{
+	omap_32k_timer_start(delta);
+
+	return 0;
+}
+
+static void omap_32k_timer_set_mode(enum clock_event_mode mode,
+				    struct clock_event_device *evt)
+{
+	omap_32k_timer_stop();
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+	case CLOCK_EVT_MODE_ONESHOT:
+		omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+}
+
+static struct clock_event_device clockevent_32k_timer = {
+	.name		= "32k-timer",
+	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.set_next_event	= omap_32k_timer_set_next_event,
+	.set_mode	= omap_32k_timer_set_mode,
+};
+
+/*
+ * The 32KHz synchronized timer is an additional timer on 16xx.
+ * It is always running.
+ */
+static inline unsigned long omap_32k_sync_timer_read(void)
+{
+	return omap_readl(TIMER_32K_SYNCHRONIZED);
+}
+
+static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &clockevent_32k_timer;
+	omap_32k_timer_ack_irq();
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction omap_32k_timer_irq = {
+	.name		= "32KHz timer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= omap_32k_timer_interrupt,
+};
+
+static __init void omap_init_32k_timer(void)
+{
+	setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
+
+	clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC,
+					   NSEC_PER_SEC,
+					   clockevent_32k_timer.shift);
+	clockevent_32k_timer.max_delta_ns =
+		clockevent_delta2ns(0xfffffffe, &clockevent_32k_timer);
+	clockevent_32k_timer.min_delta_ns =
+		clockevent_delta2ns(1, &clockevent_32k_timer);
+
+	clockevent_32k_timer.cpumask = cpumask_of_cpu(0);
+	clockevents_register_device(&clockevent_32k_timer);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+static void __init omap_timer_init(void)
+{
+#ifdef CONFIG_OMAP_DM_TIMER
+	omap_dm_timer_init();
+#endif
+	omap_init_32k_timer();
+}
+
+struct sys_timer omap_timer = {
+	.init		= omap_timer_init,
+};
Index: dev/arch/arm/plat-omap/Makefile
===================================================================
--- dev.orig/arch/arm/plat-omap/Makefile
+++ 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
 
Index: dev/arch/arm/plat-omap/timer32k.c
===================================================================
--- dev.orig/arch/arm/plat-omap/timer32k.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * linux/arch/arm/plat-omap/timer32k.c
- *
- * OMAP 32K Timer
- *
- * Copyright (C) 2004 - 2005 Nokia Corporation
- * Partial timer rewrite and additional dynamic tick timer support by
- * Tony Lindgen <tony@atomide.com> and
- * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- * OMAP Dual-mode timer framework support by Timo Teras
- *
- * MPU timer code based on the older MPU timer code for OMAP
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: Greg Lonnon <glonnon@ridgerun.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-
-#include <asm/system.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/leds.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-#include <asm/arch/dmtimer.h>
-
-struct sys_timer omap_timer;
-
-/*
- * ---------------------------------------------------------------------------
- * 32KHz OS timer
- *
- * This currently works only on 16xx, as 1510 does not have the continuous
- * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
- * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
- * on 1510 would be possible, but the timer would not be as accurate as
- * with the 32KHz synchronized timer.
- * ---------------------------------------------------------------------------
- */
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-#define TIMER_32K_SYNCHRONIZED		0xfffbc410
-#else
-#error OMAP 32KHz timer does not currently work on 15XX!
-#endif
-
-/* 16xx specific defines */
-#define OMAP1_32K_TIMER_BASE		0xfffb9000
-#define OMAP1_32K_TIMER_CR		0x08
-#define OMAP1_32K_TIMER_TVR		0x00
-#define OMAP1_32K_TIMER_TCR		0x04
-
-#define OMAP_32K_TICKS_PER_SEC		(32768)
-
-/*
- * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
- * so with HZ = 128, TVR = 255.
- */
-#define OMAP_32K_TIMER_TICK_PERIOD	((OMAP_32K_TICKS_PER_SEC / HZ) - 1)
-
-#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
-				(((nr_jiffies) * (clock_rate)) / HZ)
-
-static inline void omap_32k_timer_write(int val, int reg)
-{
-	omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
-}
-
-static inline unsigned long omap_32k_timer_read(int reg)
-{
-	return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
-}
-
-static inline void omap_32k_timer_start(unsigned long load_val)
-{
-	if (!load_val)
-		load_val = 1;
-	omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
-	omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
-}
-
-static inline void omap_32k_timer_stop(void)
-{
-	omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR);
-}
-
-#define omap_32k_timer_ack_irq()
-
-static int omap_32k_timer_set_next_event(unsigned long delta,
-					 struct clock_event_device *dev)
-{
-	omap_32k_timer_start(delta);
-
-	return 0;
-}
-
-static void omap_32k_timer_set_mode(enum clock_event_mode mode,
-				    struct clock_event_device *evt)
-{
-	omap_32k_timer_stop();
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-	case CLOCK_EVT_MODE_ONESHOT:
-		omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		break;
-	case CLOCK_EVT_MODE_RESUME:
-		break;
-	}
-}
-
-static struct clock_event_device clockevent_32k_timer = {
-	.name		= "32k-timer",
-	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.shift		= 32,
-	.set_next_event	= omap_32k_timer_set_next_event,
-	.set_mode	= omap_32k_timer_set_mode,
-};
-
-/*
- * The 32KHz synchronized timer is an additional timer on 16xx.
- * It is always running.
- */
-static inline unsigned long omap_32k_sync_timer_read(void)
-{
-	return omap_readl(TIMER_32K_SYNCHRONIZED);
-}
-
-static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = &clockevent_32k_timer;
-	omap_32k_timer_ack_irq();
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction omap_32k_timer_irq = {
-	.name		= "32KHz timer",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= omap_32k_timer_interrupt,
-};
-
-static __init void omap_init_32k_timer(void)
-{
-	setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
-
-	clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC,
-					   NSEC_PER_SEC,
-					   clockevent_32k_timer.shift);
-	clockevent_32k_timer.max_delta_ns =
-		clockevent_delta2ns(0xfffffffe, &clockevent_32k_timer);
-	clockevent_32k_timer.min_delta_ns =
-		clockevent_delta2ns(1, &clockevent_32k_timer);
-
-	clockevent_32k_timer.cpumask = cpumask_of_cpu(0);
-	clockevents_register_device(&clockevent_32k_timer);
-}
-
-/*
- * ---------------------------------------------------------------------------
- * Timer initialization
- * ---------------------------------------------------------------------------
- */
-static void __init omap_timer_init(void)
-{
-#ifdef CONFIG_OMAP_DM_TIMER
-	omap_dm_timer_init();
-#endif
-	omap_init_32k_timer();
-}
-
-struct sys_timer omap_timer = {
-	.init		= omap_timer_init,
-};

--

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()
  2007-11-12 23:24 ` [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock() Kevin Hilman
@ 2007-11-23 19:18   ` Tony Lindgren
  2007-11-23 20:26     ` Tony Lindgren
  2007-11-26 15:59     ` Kevin Hilman
  0 siblings, 2 replies; 11+ messages in thread
From: Tony Lindgren @ 2007-11-23 19:18 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap-open-source

* Kevin Hilman <khilman@mvista.com> [071112 15:25]:
> 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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()
  2007-11-23 19:18   ` Tony Lindgren
@ 2007-11-23 20:26     ` Tony Lindgren
  2007-11-26 15:59     ` Kevin Hilman
  1 sibling, 0 replies; 11+ messages in thread
From: Tony Lindgren @ 2007-11-23 20:26 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap-open-source

* Tony Lindgren <tony@atomide.com> [071123 11:19]:
> * Kevin Hilman <khilman@mvista.com> [071112 15:25]:
> > 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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()
  2007-11-23 19:18   ` Tony Lindgren
  2007-11-23 20:26     ` Tony Lindgren
@ 2007-11-26 15:59     ` Kevin Hilman
  2007-11-26 18:40       ` Tony Lindgren
  1 sibling, 1 reply; 11+ messages in thread
From: Kevin Hilman @ 2007-11-26 15:59 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap-open-source


On Fri, 2007-11-23 at 11:18 -0800, Tony Lindgren wrote:
> * Kevin Hilman <khilman@mvista.com> [071112 15:25]:
> > 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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()
  2007-11-26 15:59     ` Kevin Hilman
@ 2007-11-26 18:40       ` Tony Lindgren
  2007-11-26 19:30         ` Kevin Hilman
  0 siblings, 1 reply; 11+ messages in thread
From: Tony Lindgren @ 2007-11-26 18:40 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap-open-source

* Kevin Hilman <khilman@mvista.com> [071126 07:59]:
> 
> On Fri, 2007-11-23 at 11:18 -0800, Tony Lindgren wrote:
> > * Kevin Hilman <khilman@mvista.com> [071112 15:25]:
> > > 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.

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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()
  2007-11-26 18:40       ` Tony Lindgren
@ 2007-11-26 19:30         ` Kevin Hilman
  2007-11-26 20:12           ` Tony Lindgren
  0 siblings, 1 reply; 11+ messages in thread
From: Kevin Hilman @ 2007-11-26 19:30 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap-open-source


On Mon, 2007-11-26 at 10:40 -0800, Tony Lindgren wrote:
> * Kevin Hilman <khilman@mvista.com> [071126 07:59]:
> > 
> > On Fri, 2007-11-23 at 11:18 -0800, Tony Lindgren wrote:
> > > * Kevin Hilman <khilman@mvista.com> [071112 15:25]:
> > > > 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.
> 
> 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.

> 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..

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock()
  2007-11-26 19:30         ` Kevin Hilman
@ 2007-11-26 20:12           ` Tony Lindgren
  0 siblings, 0 replies; 11+ messages in thread
From: Tony Lindgren @ 2007-11-26 20:12 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap-open-source

* Kevin Hilman <khilman@mvista.com> [071126 11:30]:
> 
> On Mon, 2007-11-26 at 10:40 -0800, Tony Lindgren wrote:
> > * Kevin Hilman <khilman@mvista.com> [071126 07:59]:
> > > 
> > > On Fri, 2007-11-23 at 11:18 -0800, Tony Lindgren wrote:
> > > > * Kevin Hilman <khilman@mvista.com> [071112 15:25]:
> > > > > 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.
> > 
> > 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.

OK

> The secondary reason was to not have sched_clock() based on a timer that
> might stop during PM activity like suspend.
> 
> > 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

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2007-11-26 20:12 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-12 23:24 [PATCH 0/4] 32k timer reorg and sched_clock cleanup Kevin Hilman
2007-11-12 23:24 ` [PATCH 1/4] ARM: OMAP: re-organize duplicated 32k-timer code Kevin Hilman
2007-11-12 23:24 ` [PATCH 2/4] ARM: OMAP: Move 32k-based sched_clock() to common code Kevin Hilman
2007-11-12 23:24 ` [PATCH 3/4] ARM: OMAP: Remove MPU-timer based sched_clock() Kevin Hilman
2007-11-23 19:18   ` Tony Lindgren
2007-11-23 20:26     ` Tony Lindgren
2007-11-26 15:59     ` Kevin Hilman
2007-11-26 18:40       ` Tony Lindgren
2007-11-26 19:30         ` Kevin Hilman
2007-11-26 20:12           ` Tony Lindgren
2007-11-12 23:24 ` [PATCH 4/4] ARM: OMAP: Move timer32k to mach-omap1 Kevin Hilman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox