aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2012-09-24 14:42:24 -0400
committerTony Lindgren <tony@atomide.com>2012-09-24 14:42:24 -0400
commitef8fe6fee16f178cd80cf11b21565bca95b80182 (patch)
treee19ab2c41ae47250fd614418022b32aa783aa563
parent3fe05bd9980df7207a35b4841a94dc2875e86960 (diff)
parent0c9de3c52d2baed6bc2ee44885adb418152c71c4 (diff)
Merge branch 'devel-dt-arch-timer' into devel-dt
-rw-r--r--arch/arm/boot/dts/omap5.dtsi12
-rw-r--r--arch/arm/mach-omap2/Kconfig5
-rw-r--r--arch/arm/mach-omap2/timer.c97
3 files changed, 113 insertions, 1 deletions
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 9ac75b37c992..5db33f481a33 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -33,9 +33,21 @@
33 cpus { 33 cpus {
34 cpu@0 { 34 cpu@0 {
35 compatible = "arm,cortex-a15"; 35 compatible = "arm,cortex-a15";
36 timer {
37 compatible = "arm,armv7-timer";
38 /* 14th PPI IRQ, active low level-sensitive */
39 interrupts = <1 14 0x308>;
40 clock-frequency = <6144000>;
41 };
36 }; 42 };
37 cpu@1 { 43 cpu@1 {
38 compatible = "arm,cortex-a15"; 44 compatible = "arm,cortex-a15";
45 timer {
46 compatible = "arm,armv7-timer";
47 /* 14th PPI IRQ, active low level-sensitive */
48 interrupts = <1 14 0x308>;
49 clock-frequency = <6144000>;
50 };
39 }; 51 };
40 }; 52 };
41 53
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index eef99b77c40b..edc30b8b77ed 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -25,6 +25,9 @@ config ARCH_OMAP2PLUS_TYPICAL
25config SOC_HAS_OMAP2_SDRC 25config SOC_HAS_OMAP2_SDRC
26 bool "OMAP2 SDRAM Controller support" 26 bool "OMAP2 SDRAM Controller support"
27 27
28config SOC_HAS_REALTIME_COUNTER
29 bool "Real time free running counter"
30
28config ARCH_OMAP2 31config ARCH_OMAP2
29 bool "TI OMAP2" 32 bool "TI OMAP2"
30 depends on ARCH_OMAP2PLUS 33 depends on ARCH_OMAP2PLUS
@@ -71,6 +74,8 @@ config SOC_OMAP5
71 select ARM_GIC 74 select ARM_GIC
72 select HAVE_SMP 75 select HAVE_SMP
73 select ARM_CPU_SUSPEND if PM 76 select ARM_CPU_SUSPEND if PM
77 select SOC_HAS_REALTIME_COUNTER
78 select ARM_ARCH_TIMER
74 79
75comment "OMAP Core Type" 80comment "OMAP Core Type"
76 depends on ARCH_OMAP2 81 depends on ARCH_OMAP2
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 8f4525047200..a9c9b3dbc82c 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