aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2009-04-23 23:11:10 -0400
committerpaul <paul@twilight.(none)>2009-04-23 23:11:10 -0400
commitf248076c0dad45b7e50f27096e1aac6a617665db (patch)
treee787e0dbba967d09a5b05a2088addb8c2459870a /arch/arm/plat-omap
parent219c5b98d5eb86c75abc716087f494fe06c6b64e (diff)
OMAP2/3 GPTIMER: allow system tick GPTIMER to be changed in board-*.c files
Add a function omap2_gp_clockevent_set_gptimer() for board-*.c files to use in .init_irq functions to configure the system tick GPTIMER. Practical choices at this point are GPTIMER1 or GPTIMER12. Both of these timers are in the WKUP powerdomain, and so are unaffected by chip power management. GPTIMER1 can use sys_clk as a source, for applications where a high-resolution timer is more important than power management. GPTIMER12 has the special property that it has the secure 32kHz oscillator as its source clock, which may be less prone to glitches than the off-chip 32kHz oscillator. But on HS devices, it may not be available for Linux use. It appears that most boards are fine with GPTIMER1, but BeagleBoard should use GPTIMER12 when using a 32KiHz timer source, due to hardware bugs in revisions B4 and below. Modify board-omap3beagle.c to use GPTIMER12. This patch originally used a Kbuild config option to select the GPTIMER, but was changed to allow this to be specified in board-*.c files, per Tony's request. Kalle Vallo <kalle.valo@nokia.com> found a bug in an earlier version of this patch - thanks Kalle. Tested on Beagle rev B4 ES2.1, with and without CONFIG_OMAP_32K_TIMER, and 3430SDP. Signed-off-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Cc: Kalle Valo <kalle.valo@nokia.com>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/dmtimer.c20
-rw-r--r--arch/arm/plat-omap/include/mach/dmtimer.h2
-rw-r--r--arch/arm/plat-omap/include/mach/timer-gp.h17
3 files changed, 32 insertions, 7 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index a05205c12f7b..55bb99631292 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -509,7 +509,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
509 509
510#ifdef CONFIG_ARCH_OMAP1 510#ifdef CONFIG_ARCH_OMAP1
511 511
512void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) 512int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
513{ 513{
514 int n = (timer - dm_timers) << 1; 514 int n = (timer - dm_timers) << 1;
515 u32 l; 515 u32 l;
@@ -517,23 +517,31 @@ void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
517 l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); 517 l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
518 l |= source << n; 518 l |= source << n;
519 omap_writel(l, MOD_CONF_CTRL_1); 519 omap_writel(l, MOD_CONF_CTRL_1);
520
521 return 0;
520} 522}
521EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); 523EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
522 524
523#else 525#else
524 526
525void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) 527int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
526{ 528{
529 int ret = -EINVAL;
530
527 if (source < 0 || source >= 3) 531 if (source < 0 || source >= 3)
528 return; 532 return -EINVAL;
529 533
530 clk_disable(timer->fclk); 534 clk_disable(timer->fclk);
531 clk_set_parent(timer->fclk, dm_source_clocks[source]); 535 ret = clk_set_parent(timer->fclk, dm_source_clocks[source]);
532 clk_enable(timer->fclk); 536 clk_enable(timer->fclk);
533 537
534 /* When the functional clock disappears, too quick writes seem to 538 /*
535 * cause an abort. */ 539 * When the functional clock disappears, too quick writes seem
540 * to cause an abort. XXX Is this still necessary?
541 */
536 __delay(150000); 542 __delay(150000);
543
544 return ret;
537} 545}
538EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); 546EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
539 547
diff --git a/arch/arm/plat-omap/include/mach/dmtimer.h b/arch/arm/plat-omap/include/mach/dmtimer.h
index 6dc703138210..20f1054c0a80 100644
--- a/arch/arm/plat-omap/include/mach/dmtimer.h
+++ b/arch/arm/plat-omap/include/mach/dmtimer.h
@@ -64,7 +64,7 @@ void omap_dm_timer_trigger(struct omap_dm_timer *timer);
64void omap_dm_timer_start(struct omap_dm_timer *timer); 64void omap_dm_timer_start(struct omap_dm_timer *timer);
65void omap_dm_timer_stop(struct omap_dm_timer *timer); 65void omap_dm_timer_stop(struct omap_dm_timer *timer);
66 66
67void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source); 67int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
68void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value); 68void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
69void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value); 69void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
70void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match); 70void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
diff --git a/arch/arm/plat-omap/include/mach/timer-gp.h b/arch/arm/plat-omap/include/mach/timer-gp.h
new file mode 100644
index 000000000000..c88d346b59d9
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/timer-gp.h
@@ -0,0 +1,17 @@
1/*
2 * OMAP2/3 GPTIMER support.headers
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
12#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
13
14int __init omap2_gp_clockevent_set_gptimer(u8 id);
15
16#endif
17