diff options
author | Tony Lindgren <tony@atomide.com> | 2013-04-03 13:47:59 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2013-04-03 13:47:59 -0400 |
commit | 7f585bbfc54fec9dcf387fd2edb2d6f4908badf8 (patch) | |
tree | fd79064e390217a56f77c5cd8236c0db6f8d9528 /arch/arm/mach-omap2/timer.c | |
parent | 43231b5be657fde1c4ced180d829bbd59ceef9ad (diff) | |
parent | 4615943cf3a531bc76f589c22bd366da092b7c0f (diff) |
Merge branch 'omap-timer-for-v3.10' of git://github.com/jonhunter/linux into omap-for-v3.10/timer
Conflicts:
arch/arm/mach-omap2/timer.c
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r-- | arch/arm/mach-omap2/timer.c | 124 |
1 files changed, 63 insertions, 61 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 06cbb49cc976..858ec7c17d56 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -57,16 +57,6 @@ | |||
57 | #include "common.h" | 57 | #include "common.h" |
58 | #include "powerdomain.h" | 58 | #include "powerdomain.h" |
59 | 59 | ||
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 | 60 | #define REALTIME_COUNTER_BASE 0x48243200 |
71 | #define INCREMENTER_NUMERATOR_OFFSET 0x10 | 61 | #define INCREMENTER_NUMERATOR_OFFSET 0x10 |
72 | #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 | 62 | #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 |
@@ -130,7 +120,6 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, | |||
130 | } | 120 | } |
131 | 121 | ||
132 | static struct clock_event_device clockevent_gpt = { | 122 | static struct clock_event_device clockevent_gpt = { |
133 | .name = "gp_timer", | ||
134 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 123 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
135 | .rating = 300, | 124 | .rating = 300, |
136 | .set_next_event = omap2_gp_timer_set_next_event, | 125 | .set_next_event = omap2_gp_timer_set_next_event, |
@@ -171,6 +160,12 @@ static struct device_node * __init omap_get_timer_dt(struct of_device_id *match, | |||
171 | if (property && !of_get_property(np, property, NULL)) | 160 | if (property && !of_get_property(np, property, NULL)) |
172 | continue; | 161 | continue; |
173 | 162 | ||
163 | if (!property && (of_get_property(np, "ti,timer-alwon", NULL) || | ||
164 | of_get_property(np, "ti,timer-dsp", NULL) || | ||
165 | of_get_property(np, "ti,timer-pwm", NULL) || | ||
166 | of_get_property(np, "ti,timer-secure", NULL))) | ||
167 | continue; | ||
168 | |||
174 | of_add_property(np, &device_disabled); | 169 | of_add_property(np, &device_disabled); |
175 | return np; | 170 | return np; |
176 | } | 171 | } |
@@ -215,16 +210,17 @@ static u32 __init omap_dm_timer_get_errata(void) | |||
215 | } | 210 | } |
216 | 211 | ||
217 | static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | 212 | static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, |
218 | int gptimer_id, | 213 | const char *fck_source, |
219 | const char *fck_source, | 214 | const char *property, |
220 | const char *property, | 215 | const char **timer_name, |
221 | int posted) | 216 | int posted) |
222 | { | 217 | { |
223 | char name[10]; /* 10 = sizeof("gptXX_Xck0") */ | 218 | char name[10]; /* 10 = sizeof("gptXX_Xck0") */ |
224 | const char *oh_name; | 219 | const char *oh_name; |
225 | struct device_node *np; | 220 | struct device_node *np; |
226 | struct omap_hwmod *oh; | 221 | struct omap_hwmod *oh; |
227 | struct resource irq, mem; | 222 | struct resource irq, mem; |
223 | struct clk *src; | ||
228 | int r = 0; | 224 | int r = 0; |
229 | 225 | ||
230 | if (of_have_populated_dt()) { | 226 | if (of_have_populated_dt()) { |
@@ -244,10 +240,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
244 | 240 | ||
245 | of_node_put(np); | 241 | of_node_put(np); |
246 | } else { | 242 | } else { |
247 | if (omap_dm_timer_reserve_systimer(gptimer_id)) | 243 | if (omap_dm_timer_reserve_systimer(timer->id)) |
248 | return -ENODEV; | 244 | return -ENODEV; |
249 | 245 | ||
250 | sprintf(name, "timer%d", gptimer_id); | 246 | sprintf(name, "timer%d", timer->id); |
251 | oh_name = name; | 247 | oh_name = name; |
252 | } | 248 | } |
253 | 249 | ||
@@ -255,6 +251,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
255 | if (!oh) | 251 | if (!oh) |
256 | return -ENODEV; | 252 | return -ENODEV; |
257 | 253 | ||
254 | *timer_name = oh->name; | ||
255 | |||
258 | if (!of_have_populated_dt()) { | 256 | if (!of_have_populated_dt()) { |
259 | r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, | 257 | r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, |
260 | &irq); | 258 | &irq); |
@@ -277,24 +275,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 */ | 275 | /* After the dmtimer is using hwmod these clocks won't be needed */ |
278 | timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); | 276 | timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); |
279 | if (IS_ERR(timer->fclk)) | 277 | if (IS_ERR(timer->fclk)) |
280 | return -ENODEV; | 278 | return PTR_ERR(timer->fclk); |
281 | 279 | ||
282 | /* FIXME: Need to remove hard-coded test on timer ID */ | 280 | src = clk_get(NULL, fck_source); |
283 | if (gptimer_id != 12) { | 281 | if (IS_ERR(src)) |
284 | struct clk *src; | 282 | return PTR_ERR(src); |
285 | 283 | ||
286 | src = clk_get(NULL, fck_source); | 284 | if (clk_get_parent(timer->fclk) != src) { |
287 | if (IS_ERR(src)) { | 285 | r = clk_set_parent(timer->fclk, src); |
288 | r = -EINVAL; | 286 | if (r < 0) { |
289 | } else { | 287 | pr_warn("%s: %s cannot set source\n", __func__, |
290 | r = clk_set_parent(timer->fclk, src); | 288 | oh->name); |
291 | if (r < 0) | ||
292 | pr_warn("%s: %s cannot set source\n", | ||
293 | __func__, oh->name); | ||
294 | clk_put(src); | 289 | clk_put(src); |
290 | return r; | ||
295 | } | 291 | } |
296 | } | 292 | } |
297 | 293 | ||
294 | clk_put(src); | ||
295 | |||
298 | omap_hwmod_setup_one(oh_name); | 296 | omap_hwmod_setup_one(oh_name); |
299 | omap_hwmod_enable(oh); | 297 | omap_hwmod_enable(oh); |
300 | __omap_dm_timer_init_regs(timer); | 298 | __omap_dm_timer_init_regs(timer); |
@@ -318,6 +316,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
318 | { | 316 | { |
319 | int res; | 317 | int res; |
320 | 318 | ||
319 | clkev.id = gptimer_id; | ||
321 | clkev.errata = omap_dm_timer_get_errata(); | 320 | clkev.errata = omap_dm_timer_get_errata(); |
322 | 321 | ||
323 | /* | 322 | /* |
@@ -327,8 +326,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
327 | */ | 326 | */ |
328 | __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); | 327 | __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); |
329 | 328 | ||
330 | res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property, | 329 | res = omap_dm_timer_init_one(&clkev, fck_source, property, |
331 | OMAP_TIMER_POSTED); | 330 | &clockevent_gpt.name, OMAP_TIMER_POSTED); |
332 | BUG_ON(res); | 331 | BUG_ON(res); |
333 | 332 | ||
334 | omap2_gp_timer_irq.dev_id = &clkev; | 333 | omap2_gp_timer_irq.dev_id = &clkev; |
@@ -342,8 +341,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
342 | 3, /* Timer internal resynch latency */ | 341 | 3, /* Timer internal resynch latency */ |
343 | 0xffffffff); | 342 | 0xffffffff); |
344 | 343 | ||
345 | pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", | 344 | pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, |
346 | gptimer_id, clkev.rate); | 345 | clkev.rate); |
347 | } | 346 | } |
348 | 347 | ||
349 | /* Clocksource code */ | 348 | /* Clocksource code */ |
@@ -360,7 +359,6 @@ static cycle_t clocksource_read_cycles(struct clocksource *cs) | |||
360 | } | 359 | } |
361 | 360 | ||
362 | static struct clocksource clocksource_gpt = { | 361 | static struct clocksource clocksource_gpt = { |
363 | .name = "gp_timer", | ||
364 | .rating = 300, | 362 | .rating = 300, |
365 | .read = clocksource_read_cycles, | 363 | .read = clocksource_read_cycles, |
366 | .mask = CLOCKSOURCE_MASK(32), | 364 | .mask = CLOCKSOURCE_MASK(32), |
@@ -443,13 +441,16 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) | |||
443 | } | 441 | } |
444 | 442 | ||
445 | static void __init omap2_gptimer_clocksource_init(int gptimer_id, | 443 | static void __init omap2_gptimer_clocksource_init(int gptimer_id, |
446 | const char *fck_source) | 444 | const char *fck_source, |
445 | const char *property) | ||
447 | { | 446 | { |
448 | int res; | 447 | int res; |
449 | 448 | ||
449 | clksrc.id = gptimer_id; | ||
450 | clksrc.errata = omap_dm_timer_get_errata(); | 450 | clksrc.errata = omap_dm_timer_get_errata(); |
451 | 451 | ||
452 | res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL, | 452 | res = omap_dm_timer_init_one(&clksrc, fck_source, property, |
453 | &clocksource_gpt.name, | ||
453 | OMAP_TIMER_NONPOSTED); | 454 | OMAP_TIMER_NONPOSTED); |
454 | BUG_ON(res); | 455 | BUG_ON(res); |
455 | 456 | ||
@@ -462,8 +463,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id, | |||
462 | pr_err("Could not register clocksource %s\n", | 463 | pr_err("Could not register clocksource %s\n", |
463 | clocksource_gpt.name); | 464 | clocksource_gpt.name); |
464 | else | 465 | else |
465 | pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", | 466 | pr_info("OMAP clocksource: %s at %lu Hz\n", |
466 | gptimer_id, clksrc.rate); | 467 | clocksource_gpt.name, clksrc.rate); |
467 | } | 468 | } |
468 | 469 | ||
469 | #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER | 470 | #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER |
@@ -488,7 +489,7 @@ static void __init realtime_counter_init(void) | |||
488 | pr_err("%s: ioremap failed\n", __func__); | 489 | pr_err("%s: ioremap failed\n", __func__); |
489 | return; | 490 | return; |
490 | } | 491 | } |
491 | sys_clk = clk_get(NULL, OMAP5_MPU_SOURCE); | 492 | sys_clk = clk_get(NULL, "sys_clkin"); |
492 | if (IS_ERR(sys_clk)) { | 493 | if (IS_ERR(sys_clk)) { |
493 | pr_err("%s: failed to get system clock handle\n", __func__); | 494 | pr_err("%s: failed to get system clock handle\n", __func__); |
494 | iounmap(base); | 495 | iounmap(base); |
@@ -545,49 +546,52 @@ static inline void __init realtime_counter_init(void) | |||
545 | #endif | 546 | #endif |
546 | 547 | ||
547 | #define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ | 548 | #define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ |
548 | clksrc_nr, clksrc_src) \ | 549 | clksrc_nr, clksrc_src, clksrc_prop) \ |
549 | void __init omap##name##_gptimer_timer_init(void) \ | 550 | void __init omap##name##_gptimer_timer_init(void) \ |
550 | { \ | 551 | { \ |
551 | omap_dmtimer_init(); \ | 552 | omap_dmtimer_init(); \ |
552 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ | 553 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ |
553 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ | 554 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ |
555 | clksrc_prop); \ | ||
554 | } | 556 | } |
555 | 557 | ||
556 | #define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ | 558 | #define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ |
557 | clksrc_nr, clksrc_src) \ | 559 | clksrc_nr, clksrc_src, clksrc_prop) \ |
558 | void __init omap##name##_sync32k_timer_init(void) \ | 560 | void __init omap##name##_sync32k_timer_init(void) \ |
559 | { \ | 561 | { \ |
560 | omap_dmtimer_init(); \ | 562 | omap_dmtimer_init(); \ |
561 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ | 563 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ |
562 | /* Enable the use of clocksource="gp_timer" kernel parameter */ \ | 564 | /* Enable the use of clocksource="gp_timer" kernel parameter */ \ |
563 | if (use_gptimer_clksrc) \ | 565 | if (use_gptimer_clksrc) \ |
564 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);\ | 566 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ |
567 | clksrc_prop); \ | ||
565 | else \ | 568 | else \ |
566 | omap2_sync32k_clocksource_init(); \ | 569 | omap2_sync32k_clocksource_init(); \ |
567 | } | 570 | } |
568 | 571 | ||
569 | #ifdef CONFIG_ARCH_OMAP2 | 572 | #ifdef CONFIG_ARCH_OMAP2 |
570 | OMAP_SYS_32K_TIMER_INIT(2, 1, OMAP2_32K_SOURCE, "ti,timer-alwon", | 573 | OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon", |
571 | 2, OMAP2_MPU_SOURCE); | 574 | 2, "timer_sys_ck", NULL); |
572 | #endif /* CONFIG_ARCH_OMAP2 */ | 575 | #endif /* CONFIG_ARCH_OMAP2 */ |
573 | 576 | ||
574 | #ifdef CONFIG_ARCH_OMAP3 | 577 | #ifdef CONFIG_ARCH_OMAP3 |
575 | OMAP_SYS_32K_TIMER_INIT(3, 1, OMAP3_32K_SOURCE, "ti,timer-alwon", | 578 | OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon", |
576 | 2, OMAP3_MPU_SOURCE); | 579 | 2, "timer_sys_ck", NULL); |
577 | OMAP_SYS_32K_TIMER_INIT(3_secure, 12, OMAP3_32K_SOURCE, "ti,timer-secure", | 580 | OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure", |
578 | 2, OMAP3_MPU_SOURCE); | 581 | 2, "timer_sys_ck", NULL); |
579 | OMAP_SYS_GP_TIMER_INIT(3_gp, 1, OMAP3_MPU_SOURCE, "ti,timer-alwon", | ||
580 | 2, OMAP3_MPU_SOURCE); | ||
581 | #endif /* CONFIG_ARCH_OMAP3 */ | 582 | #endif /* CONFIG_ARCH_OMAP3 */ |
582 | 583 | ||
583 | #ifdef CONFIG_SOC_AM33XX | 584 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) |
584 | OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon", | 585 | OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL, |
585 | 2, OMAP4_MPU_SOURCE); | 586 | 1, "timer_sys_ck", "ti,timer-alwon"); |
586 | #endif /* CONFIG_SOC_AM33XX */ | 587 | #endif |
588 | |||
589 | #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) | ||
590 | static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon", | ||
591 | 2, "sys_clkin_ck", NULL); | ||
592 | #endif | ||
587 | 593 | ||
588 | #ifdef CONFIG_ARCH_OMAP4 | 594 | #ifdef CONFIG_ARCH_OMAP4 |
589 | OMAP_SYS_32K_TIMER_INIT(4, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", | ||
590 | 2, OMAP4_MPU_SOURCE); | ||
591 | #ifdef CONFIG_LOCAL_TIMERS | 595 | #ifdef CONFIG_LOCAL_TIMERS |
592 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); | 596 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); |
593 | void __init omap4_local_timer_init(void) | 597 | void __init omap4_local_timer_init(void) |
@@ -616,13 +620,11 @@ void __init omap4_local_timer_init(void) | |||
616 | #endif /* CONFIG_ARCH_OMAP4 */ | 620 | #endif /* CONFIG_ARCH_OMAP4 */ |
617 | 621 | ||
618 | #ifdef CONFIG_SOC_OMAP5 | 622 | #ifdef CONFIG_SOC_OMAP5 |
619 | OMAP_SYS_32K_TIMER_INIT(5, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", | ||
620 | 2, OMAP5_MPU_SOURCE); | ||
621 | void __init omap5_realtime_timer_init(void) | 623 | void __init omap5_realtime_timer_init(void) |
622 | { | 624 | { |
623 | int err; | 625 | int err; |
624 | 626 | ||
625 | omap5_sync32k_timer_init(); | 627 | omap4_sync32k_timer_init(); |
626 | realtime_counter_init(); | 628 | realtime_counter_init(); |
627 | 629 | ||
628 | err = arch_timer_of_register(); | 630 | err = arch_timer_of_register(); |