aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/Kconfig4
-rw-r--r--arch/arm/mach-omap2/timer.c90
2 files changed, 93 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 346fd26f3aa6..4b773fd56978 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -24,6 +24,9 @@ config ARCH_OMAP2PLUS_TYPICAL
24config SOC_HAS_OMAP2_SDRC 24config SOC_HAS_OMAP2_SDRC
25 bool "OMAP2 SDRAM Controller support" 25 bool "OMAP2 SDRAM Controller support"
26 26
27config SOC_HAS_REALTIME_COUNTER
28 bool "Real time free running counter"
29
27config ARCH_OMAP2 30config ARCH_OMAP2
28 bool "TI OMAP2" 31 bool "TI OMAP2"
29 depends on ARCH_OMAP2PLUS 32 depends on ARCH_OMAP2PLUS
@@ -70,6 +73,7 @@ config SOC_OMAP5
70 select ARM_GIC 73 select ARM_GIC
71 select HAVE_SMP 74 select HAVE_SMP
72 select ARM_CPU_SUSPEND if PM 75 select ARM_CPU_SUSPEND if PM
76 select SOC_HAS_REALTIME_COUNTER
73 77
74comment "OMAP Core Type" 78comment "OMAP Core Type"
75 depends on ARCH_OMAP2 79 depends on ARCH_OMAP2
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 2ba4f57dda86..026fcfff6698 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -69,6 +69,11 @@
69#define OMAP3_SECURE_TIMER 1 69#define OMAP3_SECURE_TIMER 1
70#endif 70#endif
71 71
72#define REALTIME_COUNTER_BASE 0x48243200
73#define INCREMENTER_NUMERATOR_OFFSET 0x10
74#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
75#define NUMERATOR_DENUMERATOR_MASK 0xfffff000
76
72/* Clockevent code */ 77/* Clockevent code */
73 78
74static struct omap_dm_timer clkev; 79static struct omap_dm_timer clkev;
@@ -346,6 +351,84 @@ static void __init omap2_clocksource_init(int gptimer_id,
346 omap2_gptimer_clocksource_init(gptimer_id, fck_source); 351 omap2_gptimer_clocksource_init(gptimer_id, fck_source);
347} 352}
348 353
354#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
355/*
356 * The realtime counter also called master counter, is a free-running
357 * counter, which is related to real time. It produces the count used
358 * by the CPU local timer peripherals in the MPU cluster. The timer counts
359 * at a rate of 6.144 MHz. Because the device operates on different clocks
360 * in different power modes, the master counter shifts operation between
361 * clocks, adjusting the increment per clock in hardware accordingly to
362 * maintain a constant count rate.
363 */
364static void __init realtime_counter_init(void)
365{
366 void __iomem *base;
367 static struct clk *sys_clk;
368 unsigned long rate;
369 unsigned int reg, num, den;
370
371 base = ioremap(REALTIME_COUNTER_BASE, SZ_32);
372 if (!base) {
373 pr_err("%s: ioremap failed\n", __func__);
374 return;
375 }
376 sys_clk = clk_get(NULL, "sys_clkin_ck");
377 if (!sys_clk) {
378 pr_err("%s: failed to get system clock handle\n", __func__);
379 iounmap(base);
380 return;
381 }
382
383 rate = clk_get_rate(sys_clk);
384 /* Numerator/denumerator values refer TRM Realtime Counter section */
385 switch (rate) {
386 case 1200000:
387 num = 64;
388 den = 125;
389 break;
390 case 1300000:
391 num = 768;
392 den = 1625;
393 break;
394 case 19200000:
395 num = 8;
396 den = 25;
397 break;
398 case 2600000:
399 num = 384;
400 den = 1625;
401 break;
402 case 2700000:
403 num = 256;
404 den = 1125;
405 break;
406 case 38400000:
407 default:
408 /* Program it for 38.4 MHz */
409 num = 4;
410 den = 25;
411 break;
412 }
413
414 /* Program numerator and denumerator registers */
415 reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) &
416 NUMERATOR_DENUMERATOR_MASK;
417 reg |= num;
418 __raw_writel(reg, base + INCREMENTER_NUMERATOR_OFFSET);
419
420 reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) &
421 NUMERATOR_DENUMERATOR_MASK;
422 reg |= den;
423 __raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
424
425 iounmap(base);
426}
427#else
428static inline void __init realtime_counter_init(void)
429{}
430#endif
431
349#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \ 432#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \
350 clksrc_nr, clksrc_src) \ 433 clksrc_nr, clksrc_src) \
351static void __init omap##name##_timer_init(void) \ 434static void __init omap##name##_timer_init(void) \
@@ -403,7 +486,12 @@ OMAP_SYS_TIMER(4)
403#endif 486#endif
404 487
405#ifdef CONFIG_SOC_OMAP5 488#ifdef CONFIG_SOC_OMAP5
406OMAP_SYS_TIMER_INIT(5, 1, OMAP4_CLKEV_SOURCE, 2, OMAP4_MPU_SOURCE) 489static void __init omap5_timer_init(void)
490{
491 omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
492 omap2_clocksource_init(2, OMAP4_MPU_SOURCE);
493 realtime_counter_init();
494}
407OMAP_SYS_TIMER(5) 495OMAP_SYS_TIMER(5)
408#endif 496#endif
409 497