aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/timer.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2013-05-06 17:43:45 -0400
committerArnd Bergmann <arnd@arndb.de>2013-05-06 17:43:45 -0400
commit442a33ebce9e02a2dd6662f16c9f2aad834d0115 (patch)
treeca8654a286f61da917318645cab9e061095ecdba /arch/arm/mach-omap2/timer.c
parenta94d236dc355f374857ee4e6e78b7dec8a0f29e3 (diff)
parentf31c2f1c68aff83277eddc6798adf3438e9c680a (diff)
Merge branch 'late/clksrc' into late/cleanup
There is no reason to keep the clksrc cleanups separate from the other cleanups, and this resolves some merge conflicts. Conflicts: arch/arm/mach-spear/spear13xx.c drivers/irqchip/Makefile
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r--arch/arm/mach-omap2/timer.c133
1 files changed, 65 insertions, 68 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index d00d89c93f1c..fdf1c039062c 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -46,7 +46,6 @@
46#include <asm/smp_twd.h> 46#include <asm/smp_twd.h>
47#include <asm/sched_clock.h> 47#include <asm/sched_clock.h>
48 48
49#include <asm/arch_timer.h>
50#include "omap_hwmod.h" 49#include "omap_hwmod.h"
51#include "omap_device.h" 50#include "omap_device.h"
52#include <plat/counter-32k.h> 51#include <plat/counter-32k.h>
@@ -57,16 +56,6 @@
57#include "common.h" 56#include "common.h"
58#include "powerdomain.h" 57#include "powerdomain.h"
59 58
60/* Parent clocks, eventually these will come from the clock framework */
61
62#define OMAP2_MPU_SOURCE "sys_ck"
63#define OMAP3_MPU_SOURCE OMAP2_MPU_SOURCE
64#define OMAP4_MPU_SOURCE "sys_clkin_ck"
65#define OMAP5_MPU_SOURCE "sys_clkin"
66#define OMAP2_32K_SOURCE "func_32k_ck"
67#define OMAP3_32K_SOURCE "omap_32k_fck"
68#define OMAP4_32K_SOURCE "sys_32k_ck"
69
70#define REALTIME_COUNTER_BASE 0x48243200 59#define REALTIME_COUNTER_BASE 0x48243200
71#define INCREMENTER_NUMERATOR_OFFSET 0x10 60#define INCREMENTER_NUMERATOR_OFFSET 0x10
72#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 61#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
@@ -130,7 +119,6 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
130} 119}
131 120
132static struct clock_event_device clockevent_gpt = { 121static struct clock_event_device clockevent_gpt = {
133 .name = "gp_timer",
134 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 122 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
135 .rating = 300, 123 .rating = 300,
136 .set_next_event = omap2_gp_timer_set_next_event, 124 .set_next_event = omap2_gp_timer_set_next_event,
@@ -171,6 +159,12 @@ static struct device_node * __init omap_get_timer_dt(struct of_device_id *match,
171 if (property && !of_get_property(np, property, NULL)) 159 if (property && !of_get_property(np, property, NULL))
172 continue; 160 continue;
173 161
162 if (!property && (of_get_property(np, "ti,timer-alwon", NULL) ||
163 of_get_property(np, "ti,timer-dsp", NULL) ||
164 of_get_property(np, "ti,timer-pwm", NULL) ||
165 of_get_property(np, "ti,timer-secure", NULL)))
166 continue;
167
174 of_add_property(np, &device_disabled); 168 of_add_property(np, &device_disabled);
175 return np; 169 return np;
176 } 170 }
@@ -215,16 +209,17 @@ static u32 __init omap_dm_timer_get_errata(void)
215} 209}
216 210
217static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, 211static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
218 int gptimer_id, 212 const char *fck_source,
219 const char *fck_source, 213 const char *property,
220 const char *property, 214 const char **timer_name,
221 int posted) 215 int posted)
222{ 216{
223 char name[10]; /* 10 = sizeof("gptXX_Xck0") */ 217 char name[10]; /* 10 = sizeof("gptXX_Xck0") */
224 const char *oh_name; 218 const char *oh_name;
225 struct device_node *np; 219 struct device_node *np;
226 struct omap_hwmod *oh; 220 struct omap_hwmod *oh;
227 struct resource irq, mem; 221 struct resource irq, mem;
222 struct clk *src;
228 int r = 0; 223 int r = 0;
229 224
230 if (of_have_populated_dt()) { 225 if (of_have_populated_dt()) {
@@ -244,10 +239,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
244 239
245 of_node_put(np); 240 of_node_put(np);
246 } else { 241 } else {
247 if (omap_dm_timer_reserve_systimer(gptimer_id)) 242 if (omap_dm_timer_reserve_systimer(timer->id))
248 return -ENODEV; 243 return -ENODEV;
249 244
250 sprintf(name, "timer%d", gptimer_id); 245 sprintf(name, "timer%d", timer->id);
251 oh_name = name; 246 oh_name = name;
252 } 247 }
253 248
@@ -255,6 +250,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
255 if (!oh) 250 if (!oh)
256 return -ENODEV; 251 return -ENODEV;
257 252
253 *timer_name = oh->name;
254
258 if (!of_have_populated_dt()) { 255 if (!of_have_populated_dt()) {
259 r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, 256 r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL,
260 &irq); 257 &irq);
@@ -277,24 +274,24 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
277 /* After the dmtimer is using hwmod these clocks won't be needed */ 274 /* After the dmtimer is using hwmod these clocks won't be needed */
278 timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); 275 timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh));
279 if (IS_ERR(timer->fclk)) 276 if (IS_ERR(timer->fclk))
280 return -ENODEV; 277 return PTR_ERR(timer->fclk);
281 278
282 /* FIXME: Need to remove hard-coded test on timer ID */ 279 src = clk_get(NULL, fck_source);
283 if (gptimer_id != 12) { 280 if (IS_ERR(src))
284 struct clk *src; 281 return PTR_ERR(src);
285 282
286 src = clk_get(NULL, fck_source); 283 if (clk_get_parent(timer->fclk) != src) {
287 if (IS_ERR(src)) { 284 r = clk_set_parent(timer->fclk, src);
288 r = -EINVAL; 285 if (r < 0) {
289 } else { 286 pr_warn("%s: %s cannot set source\n", __func__,
290 r = clk_set_parent(timer->fclk, src); 287 oh->name);
291 if (IS_ERR_VALUE(r))
292 pr_warn("%s: %s cannot set source\n",
293 __func__, oh->name);
294 clk_put(src); 288 clk_put(src);
289 return r;
295 } 290 }
296 } 291 }
297 292
293 clk_put(src);
294
298 omap_hwmod_setup_one(oh_name); 295 omap_hwmod_setup_one(oh_name);
299 omap_hwmod_enable(oh); 296 omap_hwmod_enable(oh);
300 __omap_dm_timer_init_regs(timer); 297 __omap_dm_timer_init_regs(timer);
@@ -318,6 +315,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
318{ 315{
319 int res; 316 int res;
320 317
318 clkev.id = gptimer_id;
321 clkev.errata = omap_dm_timer_get_errata(); 319 clkev.errata = omap_dm_timer_get_errata();
322 320
323 /* 321 /*
@@ -327,8 +325,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
327 */ 325 */
328 __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); 326 __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767);
329 327
330 res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property, 328 res = omap_dm_timer_init_one(&clkev, fck_source, property,
331 OMAP_TIMER_POSTED); 329 &clockevent_gpt.name, OMAP_TIMER_POSTED);
332 BUG_ON(res); 330 BUG_ON(res);
333 331
334 omap2_gp_timer_irq.dev_id = &clkev; 332 omap2_gp_timer_irq.dev_id = &clkev;
@@ -342,8 +340,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
342 3, /* Timer internal resynch latency */ 340 3, /* Timer internal resynch latency */
343 0xffffffff); 341 0xffffffff);
344 342
345 pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", 343 pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name,
346 gptimer_id, clkev.rate); 344 clkev.rate);
347} 345}
348 346
349/* Clocksource code */ 347/* Clocksource code */
@@ -360,7 +358,6 @@ static cycle_t clocksource_read_cycles(struct clocksource *cs)
360} 358}
361 359
362static struct clocksource clocksource_gpt = { 360static struct clocksource clocksource_gpt = {
363 .name = "gp_timer",
364 .rating = 300, 361 .rating = 300,
365 .read = clocksource_read_cycles, 362 .read = clocksource_read_cycles,
366 .mask = CLOCKSOURCE_MASK(32), 363 .mask = CLOCKSOURCE_MASK(32),
@@ -443,13 +440,16 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
443} 440}
444 441
445static void __init omap2_gptimer_clocksource_init(int gptimer_id, 442static void __init omap2_gptimer_clocksource_init(int gptimer_id,
446 const char *fck_source) 443 const char *fck_source,
444 const char *property)
447{ 445{
448 int res; 446 int res;
449 447
448 clksrc.id = gptimer_id;
450 clksrc.errata = omap_dm_timer_get_errata(); 449 clksrc.errata = omap_dm_timer_get_errata();
451 450
452 res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL, 451 res = omap_dm_timer_init_one(&clksrc, fck_source, property,
452 &clocksource_gpt.name,
453 OMAP_TIMER_NONPOSTED); 453 OMAP_TIMER_NONPOSTED);
454 BUG_ON(res); 454 BUG_ON(res);
455 455
@@ -462,8 +462,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
462 pr_err("Could not register clocksource %s\n", 462 pr_err("Could not register clocksource %s\n",
463 clocksource_gpt.name); 463 clocksource_gpt.name);
464 else 464 else
465 pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", 465 pr_info("OMAP clocksource: %s at %lu Hz\n",
466 gptimer_id, clksrc.rate); 466 clocksource_gpt.name, clksrc.rate);
467} 467}
468 468
469#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER 469#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
@@ -488,7 +488,7 @@ static void __init realtime_counter_init(void)
488 pr_err("%s: ioremap failed\n", __func__); 488 pr_err("%s: ioremap failed\n", __func__);
489 return; 489 return;
490 } 490 }
491 sys_clk = clk_get(NULL, OMAP5_MPU_SOURCE); 491 sys_clk = clk_get(NULL, "sys_clkin");
492 if (IS_ERR(sys_clk)) { 492 if (IS_ERR(sys_clk)) {
493 pr_err("%s: failed to get system clock handle\n", __func__); 493 pr_err("%s: failed to get system clock handle\n", __func__);
494 iounmap(base); 494 iounmap(base);
@@ -545,18 +545,19 @@ static inline void __init realtime_counter_init(void)
545#endif 545#endif
546 546
547#define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ 547#define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \
548 clksrc_nr, clksrc_src) \ 548 clksrc_nr, clksrc_src, clksrc_prop) \
549void __init omap##name##_gptimer_timer_init(void) \ 549void __init omap##name##_gptimer_timer_init(void) \
550{ \ 550{ \
551 if (omap_clk_init) \ 551 if (omap_clk_init) \
552 omap_clk_init(); \ 552 omap_clk_init(); \
553 omap_dmtimer_init(); \ 553 omap_dmtimer_init(); \
554 omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ 554 omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
555 omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ 555 omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \
556 clksrc_prop); \
556} 557}
557 558
558#define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ 559#define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \
559 clksrc_nr, clksrc_src) \ 560 clksrc_nr, clksrc_src, clksrc_prop) \
560void __init omap##name##_sync32k_timer_init(void) \ 561void __init omap##name##_sync32k_timer_init(void) \
561{ \ 562{ \
562 if (omap_clk_init) \ 563 if (omap_clk_init) \
@@ -565,33 +566,35 @@ void __init omap##name##_sync32k_timer_init(void) \
565 omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ 566 omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
566 /* Enable the use of clocksource="gp_timer" kernel parameter */ \ 567 /* Enable the use of clocksource="gp_timer" kernel parameter */ \
567 if (use_gptimer_clksrc) \ 568 if (use_gptimer_clksrc) \
568 omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);\ 569 omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \
570 clksrc_prop); \
569 else \ 571 else \
570 omap2_sync32k_clocksource_init(); \ 572 omap2_sync32k_clocksource_init(); \
571} 573}
572 574
573#ifdef CONFIG_ARCH_OMAP2 575#ifdef CONFIG_ARCH_OMAP2
574OMAP_SYS_32K_TIMER_INIT(2, 1, OMAP2_32K_SOURCE, "ti,timer-alwon", 576OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon",
575 2, OMAP2_MPU_SOURCE); 577 2, "timer_sys_ck", NULL);
576#endif /* CONFIG_ARCH_OMAP2 */ 578#endif /* CONFIG_ARCH_OMAP2 */
577 579
578#ifdef CONFIG_ARCH_OMAP3 580#ifdef CONFIG_ARCH_OMAP3
579OMAP_SYS_32K_TIMER_INIT(3, 1, OMAP3_32K_SOURCE, "ti,timer-alwon", 581OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon",
580 2, OMAP3_MPU_SOURCE); 582 2, "timer_sys_ck", NULL);
581OMAP_SYS_32K_TIMER_INIT(3_secure, 12, OMAP3_32K_SOURCE, "ti,timer-secure", 583OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure",
582 2, OMAP3_MPU_SOURCE); 584 2, "timer_sys_ck", NULL);
583OMAP_SYS_GP_TIMER_INIT(3_gp, 1, OMAP3_MPU_SOURCE, "ti,timer-alwon",
584 2, OMAP3_MPU_SOURCE);
585#endif /* CONFIG_ARCH_OMAP3 */ 585#endif /* CONFIG_ARCH_OMAP3 */
586 586
587#ifdef CONFIG_SOC_AM33XX 587#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
588OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon", 588OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL,
589 2, OMAP4_MPU_SOURCE); 589 1, "timer_sys_ck", "ti,timer-alwon");
590#endif /* CONFIG_SOC_AM33XX */ 590#endif
591
592#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
593static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon",
594 2, "sys_clkin_ck", NULL);
595#endif
591 596
592#ifdef CONFIG_ARCH_OMAP4 597#ifdef CONFIG_ARCH_OMAP4
593OMAP_SYS_32K_TIMER_INIT(4, 1, OMAP4_32K_SOURCE, "ti,timer-alwon",
594 2, OMAP4_MPU_SOURCE);
595#ifdef CONFIG_LOCAL_TIMERS 598#ifdef CONFIG_LOCAL_TIMERS
596static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); 599static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29);
597void __init omap4_local_timer_init(void) 600void __init omap4_local_timer_init(void)
@@ -602,7 +605,7 @@ void __init omap4_local_timer_init(void)
602 int err; 605 int err;
603 606
604 if (of_have_populated_dt()) { 607 if (of_have_populated_dt()) {
605 twd_local_timer_of_register(); 608 clocksource_of_init();
606 return; 609 return;
607 } 610 }
608 611
@@ -620,18 +623,12 @@ void __init omap4_local_timer_init(void)
620#endif /* CONFIG_ARCH_OMAP4 */ 623#endif /* CONFIG_ARCH_OMAP4 */
621 624
622#ifdef CONFIG_SOC_OMAP5 625#ifdef CONFIG_SOC_OMAP5
623OMAP_SYS_32K_TIMER_INIT(5, 1, OMAP4_32K_SOURCE, "ti,timer-alwon",
624 2, OMAP5_MPU_SOURCE);
625void __init omap5_realtime_timer_init(void) 626void __init omap5_realtime_timer_init(void)
626{ 627{
627 int err; 628 omap4_sync32k_timer_init();
628
629 omap5_sync32k_timer_init();
630 realtime_counter_init(); 629 realtime_counter_init();
631 630
632 err = arch_timer_of_register(); 631 clocksource_of_init();
633 if (err)
634 pr_err("%s: arch_timer_register failed %d\n", __func__, err);
635} 632}
636#endif /* CONFIG_SOC_OMAP5 */ 633#endif /* CONFIG_SOC_OMAP5 */
637 634