diff options
-rw-r--r-- | arch/arm/mach-omap2/board-omap3beagle.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock24xx.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock24xx.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock34xx.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/timer-gp.c | 48 | ||||
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 20 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/dmtimer.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/timer-gp.h | 17 |
8 files changed, 91 insertions, 12 deletions
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 744740ae1b9c..3a7a29d1f9a7 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <mach/nand.h> | 42 | #include <mach/nand.h> |
43 | #include <mach/mux.h> | 43 | #include <mach/mux.h> |
44 | #include <mach/usb.h> | 44 | #include <mach/usb.h> |
45 | #include <mach/timer-gp.h> | ||
45 | 46 | ||
46 | #include "mmc-twl4030.h" | 47 | #include "mmc-twl4030.h" |
47 | 48 | ||
@@ -186,6 +187,9 @@ static void __init omap3_beagle_init_irq(void) | |||
186 | { | 187 | { |
187 | omap2_init_common_hw(NULL); | 188 | omap2_init_common_hw(NULL); |
188 | omap_init_irq(); | 189 | omap_init_irq(); |
190 | #ifdef CONFIG_OMAP_32K_TIMER | ||
191 | omap2_gp_clockevent_set_gptimer(12); | ||
192 | #endif | ||
189 | omap_gpio_init(); | 193 | omap_gpio_init(); |
190 | } | 194 | } |
191 | 195 | ||
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index 5ea418327e89..efc59c49341b 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c | |||
@@ -66,6 +66,7 @@ struct omap_clk { | |||
66 | static struct omap_clk omap24xx_clks[] = { | 66 | static struct omap_clk omap24xx_clks[] = { |
67 | /* external root sources */ | 67 | /* external root sources */ |
68 | CLK(NULL, "func_32k_ck", &func_32k_ck, CK_243X | CK_242X), | 68 | CLK(NULL, "func_32k_ck", &func_32k_ck, CK_243X | CK_242X), |
69 | CLK(NULL, "secure_32k_ck", &secure_32k_ck, CK_243X | CK_242X), | ||
69 | CLK(NULL, "osc_ck", &osc_ck, CK_243X | CK_242X), | 70 | CLK(NULL, "osc_ck", &osc_ck, CK_243X | CK_242X), |
70 | CLK(NULL, "sys_ck", &sys_ck, CK_243X | CK_242X), | 71 | CLK(NULL, "sys_ck", &sys_ck, CK_243X | CK_242X), |
71 | CLK(NULL, "alt_ck", &alt_ck, CK_243X | CK_242X), | 72 | CLK(NULL, "alt_ck", &alt_ck, CK_243X | CK_242X), |
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h index 33c3e5b14323..88c5acb40fcf 100644 --- a/arch/arm/mach-omap2/clock24xx.h +++ b/arch/arm/mach-omap2/clock24xx.h | |||
@@ -625,6 +625,14 @@ static struct clk func_32k_ck = { | |||
625 | .clkdm_name = "wkup_clkdm", | 625 | .clkdm_name = "wkup_clkdm", |
626 | }; | 626 | }; |
627 | 627 | ||
628 | static struct clk secure_32k_ck = { | ||
629 | .name = "secure_32k_ck", | ||
630 | .ops = &clkops_null, | ||
631 | .rate = 32768, | ||
632 | .flags = RATE_FIXED, | ||
633 | .clkdm_name = "wkup_clkdm", | ||
634 | }; | ||
635 | |||
628 | /* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */ | 636 | /* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */ |
629 | static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */ | 637 | static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */ |
630 | .name = "osc_ck", | 638 | .name = "osc_ck", |
@@ -1790,7 +1798,7 @@ static struct clk gpt12_ick = { | |||
1790 | static struct clk gpt12_fck = { | 1798 | static struct clk gpt12_fck = { |
1791 | .name = "gpt12_fck", | 1799 | .name = "gpt12_fck", |
1792 | .ops = &clkops_omap2_dflt_wait, | 1800 | .ops = &clkops_omap2_dflt_wait, |
1793 | .parent = &func_32k_ck, | 1801 | .parent = &secure_32k_ck, |
1794 | .clkdm_name = "core_l4_clkdm", | 1802 | .clkdm_name = "core_l4_clkdm", |
1795 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1803 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
1796 | .enable_bit = OMAP24XX_EN_GPT12_SHIFT, | 1804 | .enable_bit = OMAP24XX_EN_GPT12_SHIFT, |
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index f0090175d597..6763b8f73028 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h | |||
@@ -2901,7 +2901,6 @@ static struct clk sr_l4_ick = { | |||
2901 | 2901 | ||
2902 | /* SECURE_32K_FCK clocks */ | 2902 | /* SECURE_32K_FCK clocks */ |
2903 | 2903 | ||
2904 | /* XXX This clock no longer exists in 3430 TRM rev F */ | ||
2905 | static struct clk gpt12_fck = { | 2904 | static struct clk gpt12_fck = { |
2906 | .name = "gpt12_fck", | 2905 | .name = "gpt12_fck", |
2907 | .ops = &clkops_null, | 2906 | .ops = &clkops_null, |
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index 9fc13a2cc3f4..7835048041eb 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c | |||
@@ -3,6 +3,8 @@ | |||
3 | * | 3 | * |
4 | * OMAP2 GP timer support. | 4 | * OMAP2 GP timer support. |
5 | * | 5 | * |
6 | * Copyright (C) 2009 Nokia Corporation | ||
7 | * | ||
6 | * Update to use new clocksource/clockevent layers | 8 | * Update to use new clocksource/clockevent layers |
7 | * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> | 9 | * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> |
8 | * Copyright (C) 2007 MontaVista Software, Inc. | 10 | * Copyright (C) 2007 MontaVista Software, Inc. |
@@ -36,8 +38,13 @@ | |||
36 | #include <asm/mach/time.h> | 38 | #include <asm/mach/time.h> |
37 | #include <mach/dmtimer.h> | 39 | #include <mach/dmtimer.h> |
38 | 40 | ||
41 | /* MAX_GPTIMER_ID: number of GPTIMERs on the chip */ | ||
42 | #define MAX_GPTIMER_ID 12 | ||
43 | |||
39 | static struct omap_dm_timer *gptimer; | 44 | static struct omap_dm_timer *gptimer; |
40 | static struct clock_event_device clockevent_gpt; | 45 | static struct clock_event_device clockevent_gpt; |
46 | static u8 __initdata gptimer_id = 1; | ||
47 | static u8 __initdata inited; | ||
41 | 48 | ||
42 | static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) | 49 | static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) |
43 | { | 50 | { |
@@ -95,20 +102,53 @@ static struct clock_event_device clockevent_gpt = { | |||
95 | .set_mode = omap2_gp_timer_set_mode, | 102 | .set_mode = omap2_gp_timer_set_mode, |
96 | }; | 103 | }; |
97 | 104 | ||
105 | /** | ||
106 | * omap2_gp_clockevent_set_gptimer - set which GPTIMER is used for clockevents | ||
107 | * @id: GPTIMER to use (1..MAX_GPTIMER_ID) | ||
108 | * | ||
109 | * Define the GPTIMER that the system should use for the tick timer. | ||
110 | * Meant to be called from board-*.c files in the event that GPTIMER1, the | ||
111 | * default, is unsuitable. Returns -EINVAL on error or 0 on success. | ||
112 | */ | ||
113 | int __init omap2_gp_clockevent_set_gptimer(u8 id) | ||
114 | { | ||
115 | if (id < 1 || id > MAX_GPTIMER_ID) | ||
116 | return -EINVAL; | ||
117 | |||
118 | BUG_ON(inited); | ||
119 | |||
120 | gptimer_id = id; | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
98 | static void __init omap2_gp_clockevent_init(void) | 125 | static void __init omap2_gp_clockevent_init(void) |
99 | { | 126 | { |
100 | u32 tick_rate; | 127 | u32 tick_rate; |
128 | int src; | ||
129 | |||
130 | inited = 1; | ||
101 | 131 | ||
102 | gptimer = omap_dm_timer_request_specific(1); | 132 | gptimer = omap_dm_timer_request_specific(gptimer_id); |
103 | BUG_ON(gptimer == NULL); | 133 | BUG_ON(gptimer == NULL); |
104 | 134 | ||
105 | #if defined(CONFIG_OMAP_32K_TIMER) | 135 | #if defined(CONFIG_OMAP_32K_TIMER) |
106 | omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ); | 136 | src = OMAP_TIMER_SRC_32_KHZ; |
107 | #else | 137 | #else |
108 | omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK); | 138 | src = OMAP_TIMER_SRC_SYS_CLK; |
139 | WARN(gptimer_id == 12, "WARNING: GPTIMER12 can only use the " | ||
140 | "secure 32KiHz clock source\n"); | ||
109 | #endif | 141 | #endif |
142 | |||
143 | if (gptimer_id != 12) | ||
144 | WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)), | ||
145 | "timer-gp: omap_dm_timer_set_source() failed\n"); | ||
146 | |||
110 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); | 147 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); |
111 | 148 | ||
149 | pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n", | ||
150 | gptimer_id, tick_rate); | ||
151 | |||
112 | omap2_gp_timer_irq.dev_id = (void *)gptimer; | 152 | omap2_gp_timer_irq.dev_id = (void *)gptimer; |
113 | setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); | 153 | setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); |
114 | omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); | 154 | omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); |
@@ -125,6 +165,8 @@ static void __init omap2_gp_clockevent_init(void) | |||
125 | clockevents_register_device(&clockevent_gpt); | 165 | clockevents_register_device(&clockevent_gpt); |
126 | } | 166 | } |
127 | 167 | ||
168 | /* Clocksource code */ | ||
169 | |||
128 | #ifdef CONFIG_OMAP_32K_TIMER | 170 | #ifdef CONFIG_OMAP_32K_TIMER |
129 | /* | 171 | /* |
130 | * When 32k-timer is enabled, don't use GPTimer for clocksource | 172 | * When 32k-timer is enabled, don't use GPTimer for clocksource |
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 | ||
512 | void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) | 512 | int 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 | } |
521 | EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); | 523 | EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); |
522 | 524 | ||
523 | #else | 525 | #else |
524 | 526 | ||
525 | void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) | 527 | int 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 | } |
538 | EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); | 546 | EXPORT_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); | |||
64 | void omap_dm_timer_start(struct omap_dm_timer *timer); | 64 | void omap_dm_timer_start(struct omap_dm_timer *timer); |
65 | void omap_dm_timer_stop(struct omap_dm_timer *timer); | 65 | void omap_dm_timer_stop(struct omap_dm_timer *timer); |
66 | 66 | ||
67 | void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source); | 67 | int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source); |
68 | void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value); | 68 | void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value); |
69 | void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value); | 69 | void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value); |
70 | void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match); | 70 | void 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 | |||
14 | int __init omap2_gp_clockevent_set_gptimer(u8 id); | ||
15 | |||
16 | #endif | ||
17 | |||