aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Hunter <jon-hunter@ti.com>2013-01-28 18:53:57 -0500
committerJon Hunter <jon-hunter@ti.com>2013-04-01 14:49:30 -0400
commit2eb03937df3ebc822dab413bd69533dcd66afd48 (patch)
tree53526b7cf6941fba64d8b27a50e5106e39172a0c
parent00ea4d5618e86b926163c7d080763c6560be9fe3 (diff)
ARM: OMAP3: Update clocksource timer selection
When booting with device-tree for OMAP3 and AM335x devices and a gptimer is used as the clocksource (which is always the case for AM335x), a gptimer located in a power domain that is not always-on is selected. Ideally we should use a gptimer for clocksource that is located in a power domain that is always on (such as the wake-up domain) so that time can be maintained during a kernel suspend without keeping on additional power domains unnecessarily. In order to fix this so that we can select a gptimer located in a power domain that is always-on, the following changes were made ... 1. Currently, only when selecting a gptimer to use for a clockevent timer, do we pass a timer property that can be used to select a specific gptimer. Change this so that we can pass a property when selecting a gptimer to use for a clocksource timer too. 2. Currently, when selecting either a gptimer to use for a clockevent timer or a clocksource timer and no timer property is passed, then the first available timer is selected regardless of the properties it has. Change this so that if no properties are passed, then a timer that does not have additional features (such as always-on, dsp-irq, pwm, and secure) is selected. For OMAP3 and AM335x devices that use a gptimer for clocksource, change the selection of the gptimer so that by default the gptimer located in the always-on power domain is used for clocksource instead of clockevents. Please note that using a gptimer for both clocksource and clockevents can have a system power impact during idle. The reason being is that OMAP and AMxxx devices typically only have one gptimer in a power domain that is always-on. Therefore when the kernel is idle both the clocksource and clockevent timers will be active and this will keep additional power domains on. During kernel suspend, only the clocksource timer is active and therefore, it is better to use a gptimer in a power domain that is always-on for clocksource. Signed-off-by: Jon Hunter <jon-hunter@ti.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Acked-by: Igor Grinberg <grinberg@compulab.co.il>
-rw-r--r--arch/arm/mach-omap2/timer.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index ffb17beb5754..04ac1b43fbf2 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -161,6 +161,12 @@ static struct device_node * __init omap_get_timer_dt(struct of_device_id *match,
161 if (property && !of_get_property(np, property, NULL)) 161 if (property && !of_get_property(np, property, NULL))
162 continue; 162 continue;
163 163
164 if (!property && (of_get_property(np, "ti,timer-alwon", NULL) ||
165 of_get_property(np, "ti,timer-dsp", NULL) ||
166 of_get_property(np, "ti,timer-pwm", NULL) ||
167 of_get_property(np, "ti,timer-secure", NULL)))
168 continue;
169
164 of_add_property(np, &device_disabled); 170 of_add_property(np, &device_disabled);
165 return np; 171 return np;
166 } 172 }
@@ -442,13 +448,14 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
442} 448}
443 449
444static void __init omap2_gptimer_clocksource_init(int gptimer_id, 450static void __init omap2_gptimer_clocksource_init(int gptimer_id,
445 const char *fck_source) 451 const char *fck_source,
452 const char *property)
446{ 453{
447 int res; 454 int res;
448 455
449 clksrc.errata = omap_dm_timer_get_errata(); 456 clksrc.errata = omap_dm_timer_get_errata();
450 457
451 res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL, 458 res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, property,
452 &clocksource_gpt.name, 459 &clocksource_gpt.name,
453 OMAP_TIMER_NONPOSTED); 460 OMAP_TIMER_NONPOSTED);
454 BUG_ON(res); 461 BUG_ON(res);
@@ -545,47 +552,49 @@ static inline void __init realtime_counter_init(void)
545#endif 552#endif
546 553
547#define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ 554#define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \
548 clksrc_nr, clksrc_src) \ 555 clksrc_nr, clksrc_src, clksrc_prop) \
549void __init omap##name##_gptimer_timer_init(void) \ 556void __init omap##name##_gptimer_timer_init(void) \
550{ \ 557{ \
551 omap_dmtimer_init(); \ 558 omap_dmtimer_init(); \
552 omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ 559 omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
553 omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ 560 omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \
561 clksrc_prop); \
554} 562}
555 563
556#define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ 564#define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \
557 clksrc_nr, clksrc_src) \ 565 clksrc_nr, clksrc_src, clksrc_prop) \
558void __init omap##name##_sync32k_timer_init(void) \ 566void __init omap##name##_sync32k_timer_init(void) \
559{ \ 567{ \
560 omap_dmtimer_init(); \ 568 omap_dmtimer_init(); \
561 omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ 569 omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \
562 /* Enable the use of clocksource="gp_timer" kernel parameter */ \ 570 /* Enable the use of clocksource="gp_timer" kernel parameter */ \
563 if (use_gptimer_clksrc) \ 571 if (use_gptimer_clksrc) \
564 omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);\ 572 omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \
573 clksrc_prop); \
565 else \ 574 else \
566 omap2_sync32k_clocksource_init(); \ 575 omap2_sync32k_clocksource_init(); \
567} 576}
568 577
569#ifdef CONFIG_ARCH_OMAP2 578#ifdef CONFIG_ARCH_OMAP2
570OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon", 579OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon",
571 2, "timer_sys_ck"); 580 2, "timer_sys_ck", NULL);
572#endif /* CONFIG_ARCH_OMAP2 */ 581#endif /* CONFIG_ARCH_OMAP2 */
573 582
574#ifdef CONFIG_ARCH_OMAP3 583#ifdef CONFIG_ARCH_OMAP3
575OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon", 584OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon",
576 2, "timer_sys_ck"); 585 2, "timer_sys_ck", NULL);
577OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure", 586OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure",
578 2, "timer_sys_ck"); 587 2, "timer_sys_ck", NULL);
579#endif /* CONFIG_ARCH_OMAP3 */ 588#endif /* CONFIG_ARCH_OMAP3 */
580 589
581#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) 590#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
582OMAP_SYS_GP_TIMER_INIT(3, 1, "timer_sys_ck", "ti,timer-alwon", 591OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL,
583 2, "timer_sys_ck"); 592 1, "timer_sys_ck", "ti,timer-alwon");
584#endif 593#endif
585 594
586#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) 595#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
587OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon", 596OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon",
588 2, "sys_clkin_ck"); 597 2, "sys_clkin_ck", NULL);
589#endif 598#endif
590 599
591#ifdef CONFIG_ARCH_OMAP4 600#ifdef CONFIG_ARCH_OMAP4