aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r--arch/arm/mach-omap2/timer.c97
1 files changed, 96 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 810aa1a332e1..8847d6eb2313 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -42,6 +42,7 @@
42#include <asm/smp_twd.h> 42#include <asm/smp_twd.h>
43#include <asm/sched_clock.h> 43#include <asm/sched_clock.h>
44 44
45#include <asm/arch_timer.h>
45#include <plat/omap_hwmod.h> 46#include <plat/omap_hwmod.h>
46#include <plat/omap_device.h> 47#include <plat/omap_device.h>
47#include <plat/dmtimer.h> 48#include <plat/dmtimer.h>
@@ -72,6 +73,11 @@
72#define OMAP3_SECURE_TIMER 1 73#define OMAP3_SECURE_TIMER 1
73#endif 74#endif
74 75
76#define REALTIME_COUNTER_BASE 0x48243200
77#define INCREMENTER_NUMERATOR_OFFSET 0x10
78#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
79#define NUMERATOR_DENUMERATOR_MASK 0xfffff000
80
75/* Clockevent code */ 81/* Clockevent code */
76 82
77static struct omap_dm_timer clkev; 83static struct omap_dm_timer clkev;
@@ -349,6 +355,84 @@ static void __init omap2_clocksource_init(int gptimer_id,
349 omap2_gptimer_clocksource_init(gptimer_id, fck_source); 355 omap2_gptimer_clocksource_init(gptimer_id, fck_source);
350} 356}
351 357
358#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
359/*
360 * The realtime counter also called master counter, is a free-running
361 * counter, which is related to real time. It produces the count used
362 * by the CPU local timer peripherals in the MPU cluster. The timer counts
363 * at a rate of 6.144 MHz. Because the device operates on different clocks
364 * in different power modes, the master counter shifts operation between
365 * clocks, adjusting the increment per clock in hardware accordingly to
366 * maintain a constant count rate.
367 */
368static void __init realtime_counter_init(void)
369{
370 void __iomem *base;
371 static struct clk *sys_clk;
372 unsigned long rate;
373 unsigned int reg, num, den;
374
375 base = ioremap(REALTIME_COUNTER_BASE, SZ_32);
376 if (!base) {
377 pr_err("%s: ioremap failed\n", __func__);
378 return;
379 }
380 sys_clk = clk_get(NULL, "sys_clkin_ck");
381 if (!sys_clk) {
382 pr_err("%s: failed to get system clock handle\n", __func__);
383 iounmap(base);
384 return;
385 }
386
387 rate = clk_get_rate(sys_clk);
388 /* Numerator/denumerator values refer TRM Realtime Counter section */
389 switch (rate) {
390 case 1200000:
391 num = 64;
392 den = 125;
393 break;
394 case 1300000:
395 num = 768;
396 den = 1625;
397 break;
398 case 19200000:
399 num = 8;
400 den = 25;
401 break;
402 case 2600000:
403 num = 384;
404 den = 1625;
405 break;
406 case 2700000:
407 num = 256;
408 den = 1125;
409 break;
410 case 38400000:
411 default:
412 /* Program it for 38.4 MHz */
413 num = 4;
414 den = 25;
415 break;
416 }
417
418 /* Program numerator and denumerator registers */
419 reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) &
420 NUMERATOR_DENUMERATOR_MASK;
421 reg |= num;
422 __raw_writel(reg, base + INCREMENTER_NUMERATOR_OFFSET);
423
424 reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) &
425 NUMERATOR_DENUMERATOR_MASK;
426 reg |= den;
427 __raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
428
429 iounmap(base);
430}
431#else
432static inline void __init realtime_counter_init(void)
433{}
434#endif
435
352#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \ 436#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \
353 clksrc_nr, clksrc_src) \ 437 clksrc_nr, clksrc_src) \
354static void __init omap##name##_timer_init(void) \ 438static void __init omap##name##_timer_init(void) \
@@ -410,7 +494,18 @@ OMAP_SYS_TIMER(4)
410#endif 494#endif
411 495
412#ifdef CONFIG_SOC_OMAP5 496#ifdef CONFIG_SOC_OMAP5
413OMAP_SYS_TIMER_INIT(5, 1, OMAP4_CLKEV_SOURCE, 2, OMAP4_MPU_SOURCE) 497static void __init omap5_timer_init(void)
498{
499 int err;
500
501 omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
502 omap2_clocksource_init(2, OMAP4_MPU_SOURCE);
503 realtime_counter_init();
504
505 err = arch_timer_of_register();
506 if (err)
507 pr_err("%s: arch_timer_register failed %d\n", __func__, err);
508}
414OMAP_SYS_TIMER(5) 509OMAP_SYS_TIMER(5)
415#endif 510#endif
416 511