2 * linux/arch/arm/mach-nomadik/timer.c
4 * Copyright (C) 2008 STMicroelectronics
5 * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2, as
9 * published by the Free Software Foundation.
15 #include <mach/hardware.h>
17 #include <mach/timex.h>
19 /* Initial value for SRC control register: all timers use MXTAL/8 source */
20 #define SRC_CR_INIT_MASK 0x00007fff
21 #define SRC_CR_INIT_VAL 0x2aaa8000
23 static u32 nmdk_cycle
; /* write-once */
24 static __iomem
void *mtu_base
;
27 * clocksource: the MTU device is a decrementing counters, so we negate
28 * the value being read.
30 static uint64_t nmdk_read_timer(void)
32 return nmdk_cycle
- readl(mtu_base
+ MTU_VAL(0));
35 static struct clocksource nmdk_clksrc
= {
36 .read
= nmdk_read_timer
,
41 static void nmdk_timer_reset(void)
45 writel(0, mtu_base
+ MTU_CR(0)); /* off */
47 /* configure load and background-load, and fire it up */
48 writel(nmdk_cycle
, mtu_base
+ MTU_LR(0));
49 writel(nmdk_cycle
, mtu_base
+ MTU_BGLR(0));
50 cr
= MTU_CRn_PRESCALE_1
| MTU_CRn_32BITS
;
51 writel(cr
, mtu_base
+ MTU_CR(0));
52 writel(cr
| MTU_CRn_ENA
, mtu_base
+ MTU_CR(0));
55 static int nmdk_timer_init(void)
60 rate
= CLOCK_TICK_RATE
; /* 2.4MHz */
61 nmdk_cycle
= (rate
+ 1000 / 2) / 1000;
63 /* Configure timer sources in "system reset controller" ctrl reg */
64 src_cr
= readl(NOMADIK_SRC_BASE
);
65 src_cr
&= SRC_CR_INIT_MASK
;
66 src_cr
|= SRC_CR_INIT_VAL
;
67 writel(src_cr
, NOMADIK_SRC_BASE
);
69 /* Save global pointer to mtu, used by functions above */
70 mtu_base
= (void *)NOMADIK_MTU0_BASE
;
72 /* Init the timer and register clocksource */
75 nmdk_clksrc
.mult
= clocksource_hz2mult(rate
, nmdk_clksrc
.shift
);
77 init_clock(&nmdk_clksrc
);
81 core_initcall(nmdk_timer_init
);