2 * Based on arm clockevents implementation and old bfin time tick.
4 * Copyright 2008-2009 Analog Devics Inc.
8 * Licensed under the GPL-2
11 #include <linux/module.h>
12 #include <linux/profile.h>
13 #include <linux/interrupt.h>
14 #include <linux/time.h>
15 #include <linux/timex.h>
16 #include <linux/irq.h>
17 #include <linux/clocksource.h>
18 #include <linux/clockchips.h>
19 #include <linux/cpufreq.h>
21 #include <asm/blackfin.h>
23 #include <asm/gptimers.h>
25 /* Accelerators for sched_clock()
26 * convert from cycles(64bits) => nanoseconds (64bits)
28 * ns = cycles / (freq / ns_per_sec)
29 * ns = cycles * (ns_per_sec / freq)
30 * ns = cycles * (10^9 / (cpu_khz * 10^3))
31 * ns = cycles * (10^6 / cpu_khz)
33 * Then we use scaling math (suggested by george@mvista.com) to get:
34 * ns = cycles * (10^6 * SC / cpu_khz) / SC
35 * ns = cycles * cyc2ns_scale / SC
37 * And since SC is a constant power of two, we can convert the div
40 * We can use khz divisor instead of mhz to keep a better precision, since
41 * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
42 * (mathieu.desnoyers@polymtl.ca)
44 * -johnstul@us.ibm.com "math is hard, lets go shopping!"
47 #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
49 #if defined(CONFIG_CYCLES_CLOCKSOURCE)
51 static notrace cycle_t
bfin_read_cycles(struct clocksource
*cs
)
53 return __bfin_cycles_off
+ (get_cycles() << __bfin_cycles_mod
);
56 static struct clocksource bfin_cs_cycles
= {
57 .name
= "bfin_cs_cycles",
59 .read
= bfin_read_cycles
,
60 .mask
= CLOCKSOURCE_MASK(64),
61 .shift
= CYC2NS_SCALE_FACTOR
,
62 .flags
= CLOCK_SOURCE_IS_CONTINUOUS
,
65 static inline unsigned long long bfin_cs_cycles_sched_clock(void)
67 return cyc2ns(&bfin_cs_cycles
, bfin_read_cycles(&bfin_cs_cycles
));
70 static int __init
bfin_cs_cycles_init(void)
72 bfin_cs_cycles
.mult
= \
73 clocksource_hz2mult(get_cclk(), bfin_cs_cycles
.shift
);
75 if (clocksource_register(&bfin_cs_cycles
))
76 panic("failed to register clocksource");
81 # define bfin_cs_cycles_init()
84 #ifdef CONFIG_GPTMR0_CLOCKSOURCE
86 void __init
setup_gptimer0(void)
88 disable_gptimers(TIMER0bit
);
90 set_gptimer_config(TIMER0_id
, \
91 TIMER_OUT_DIS
| TIMER_PERIOD_CNT
| TIMER_MODE_PWM
);
92 set_gptimer_period(TIMER0_id
, -1);
93 set_gptimer_pwidth(TIMER0_id
, -2);
95 enable_gptimers(TIMER0bit
);
98 static cycle_t
bfin_read_gptimer0(struct clocksource
*cs
)
100 return bfin_read_TIMER0_COUNTER();
103 static struct clocksource bfin_cs_gptimer0
= {
104 .name
= "bfin_cs_gptimer0",
106 .read
= bfin_read_gptimer0
,
107 .mask
= CLOCKSOURCE_MASK(32),
108 .shift
= CYC2NS_SCALE_FACTOR
,
109 .flags
= CLOCK_SOURCE_IS_CONTINUOUS
,
112 static inline unsigned long long bfin_cs_gptimer0_sched_clock(void)
114 return cyc2ns(&bfin_cs_gptimer0
, bfin_read_TIMER0_COUNTER());
117 static int __init
bfin_cs_gptimer0_init(void)
121 bfin_cs_gptimer0
.mult
= \
122 clocksource_hz2mult(get_sclk(), bfin_cs_gptimer0
.shift
);
124 if (clocksource_register(&bfin_cs_gptimer0
))
125 panic("failed to register clocksource");
130 # define bfin_cs_gptimer0_init()
134 #if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE)
135 /* prefer to use cycles since it has higher rating */
136 notrace
unsigned long long sched_clock(void)
138 #if defined(CONFIG_CYCLES_CLOCKSOURCE)
139 return bfin_cs_cycles_sched_clock();
141 return bfin_cs_gptimer0_sched_clock();
146 #ifdef CONFIG_CORE_TIMER_IRQ_L1
147 __attribute__((l1_text
))
149 irqreturn_t
timer_interrupt(int irq
, void *dev_id
);
151 static int bfin_timer_set_next_event(unsigned long, \
152 struct clock_event_device
*);
154 static void bfin_timer_set_mode(enum clock_event_mode
, \
155 struct clock_event_device
*);
157 static struct clock_event_device clockevent_bfin
= {
158 #if defined(CONFIG_TICKSOURCE_GPTMR0)
159 .name
= "bfin_gptimer0",
163 .name
= "bfin_core_timer",
168 .features
= CLOCK_EVT_FEAT_PERIODIC
| CLOCK_EVT_FEAT_ONESHOT
,
169 .set_next_event
= bfin_timer_set_next_event
,
170 .set_mode
= bfin_timer_set_mode
,
173 static struct irqaction bfin_timer_irq
= {
174 #if defined(CONFIG_TICKSOURCE_GPTMR0)
175 .name
= "Blackfin GPTimer0",
177 .name
= "Blackfin CoreTimer",
179 .flags
= IRQF_DISABLED
| IRQF_TIMER
| \
180 IRQF_IRQPOLL
| IRQF_PERCPU
,
181 .handler
= timer_interrupt
,
182 .dev_id
= &clockevent_bfin
,
185 #if defined(CONFIG_TICKSOURCE_GPTMR0)
186 static int bfin_timer_set_next_event(unsigned long cycles
,
187 struct clock_event_device
*evt
)
189 disable_gptimers(TIMER0bit
);
191 /* it starts counting three SCLK cycles after the TIMENx bit is set */
192 set_gptimer_pwidth(TIMER0_id
, cycles
- 3);
193 enable_gptimers(TIMER0bit
);
197 static void bfin_timer_set_mode(enum clock_event_mode mode
,
198 struct clock_event_device
*evt
)
201 case CLOCK_EVT_MODE_PERIODIC
: {
202 set_gptimer_config(TIMER0_id
, \
203 TIMER_OUT_DIS
| TIMER_IRQ_ENA
| \
204 TIMER_PERIOD_CNT
| TIMER_MODE_PWM
);
205 set_gptimer_period(TIMER0_id
, get_sclk() / HZ
);
206 set_gptimer_pwidth(TIMER0_id
, get_sclk() / HZ
- 1);
207 enable_gptimers(TIMER0bit
);
210 case CLOCK_EVT_MODE_ONESHOT
:
211 disable_gptimers(TIMER0bit
);
212 set_gptimer_config(TIMER0_id
, \
213 TIMER_OUT_DIS
| TIMER_IRQ_ENA
| TIMER_MODE_PWM
);
214 set_gptimer_period(TIMER0_id
, 0);
216 case CLOCK_EVT_MODE_UNUSED
:
217 case CLOCK_EVT_MODE_SHUTDOWN
:
218 disable_gptimers(TIMER0bit
);
220 case CLOCK_EVT_MODE_RESUME
:
225 static void bfin_timer_ack(void)
227 set_gptimer_status(TIMER_GROUP1
, TIMER_STATUS_TIMIL0
);
230 static void __init
bfin_timer_init(void)
232 disable_gptimers(TIMER0bit
);
235 static unsigned long __init
bfin_clockevent_check(void)
237 setup_irq(IRQ_TIMER0
, &bfin_timer_irq
);
241 #else /* CONFIG_TICKSOURCE_CORETMR */
243 static int bfin_timer_set_next_event(unsigned long cycles
,
244 struct clock_event_device
*evt
)
246 bfin_write_TCNTL(TMPWR
);
248 bfin_write_TCOUNT(cycles
);
250 bfin_write_TCNTL(TMPWR
| TMREN
);
254 static void bfin_timer_set_mode(enum clock_event_mode mode
,
255 struct clock_event_device
*evt
)
258 case CLOCK_EVT_MODE_PERIODIC
: {
259 unsigned long tcount
= ((get_cclk() / (HZ
* TIME_SCALE
)) - 1);
260 bfin_write_TCNTL(TMPWR
);
262 bfin_write_TSCALE(TIME_SCALE
- 1);
263 bfin_write_TPERIOD(tcount
);
264 bfin_write_TCOUNT(tcount
);
266 bfin_write_TCNTL(TMPWR
| TMREN
| TAUTORLD
);
269 case CLOCK_EVT_MODE_ONESHOT
:
270 bfin_write_TCNTL(TMPWR
);
272 bfin_write_TSCALE(TIME_SCALE
- 1);
273 bfin_write_TPERIOD(0);
274 bfin_write_TCOUNT(0);
276 case CLOCK_EVT_MODE_UNUSED
:
277 case CLOCK_EVT_MODE_SHUTDOWN
:
281 case CLOCK_EVT_MODE_RESUME
:
286 static void bfin_timer_ack(void)
290 static void __init
bfin_timer_init(void)
292 /* power up the timer, but don't enable it just yet */
293 bfin_write_TCNTL(TMPWR
);
297 * the TSCALE prescaler counter.
299 bfin_write_TSCALE(TIME_SCALE
- 1);
300 bfin_write_TPERIOD(0);
301 bfin_write_TCOUNT(0);
306 static unsigned long __init
bfin_clockevent_check(void)
308 setup_irq(IRQ_CORETMR
, &bfin_timer_irq
);
309 return get_cclk() / TIME_SCALE
;
312 void __init
setup_core_timer(void)
315 bfin_timer_set_mode(CLOCK_EVT_MODE_PERIODIC
, NULL
);
317 #endif /* CONFIG_TICKSOURCE_GPTMR0 */
320 * timer_interrupt() needs to keep up the real-time clock,
321 * as well as call the "do_timer()" routine every clocktick
323 irqreturn_t
timer_interrupt(int irq
, void *dev_id
)
325 struct clock_event_device
*evt
= dev_id
;
327 evt
->event_handler(evt
);
332 static int __init
bfin_clockevent_init(void)
334 unsigned long timer_clk
;
336 timer_clk
= bfin_clockevent_check();
340 clockevent_bfin
.mult
= div_sc(timer_clk
, NSEC_PER_SEC
, clockevent_bfin
.shift
);
341 clockevent_bfin
.max_delta_ns
= clockevent_delta2ns(-1, &clockevent_bfin
);
342 clockevent_bfin
.min_delta_ns
= clockevent_delta2ns(100, &clockevent_bfin
);
343 clockevent_bfin
.cpumask
= cpumask_of(0);
344 clockevents_register_device(&clockevent_bfin
);
349 void __init
time_init(void)
351 time_t secs_since_1970
= (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */
353 #ifdef CONFIG_RTC_DRV_BFIN
354 /* [#2663] hack to filter junk RTC values that would cause
355 * userspace to have to deal with time values greater than
356 * 2^31 seconds (which uClibc cannot cope with yet)
358 if ((bfin_read_RTC_STAT() & 0xC0000000) == 0xC0000000) {
359 printk(KERN_NOTICE
"bfin-rtc: invalid date; resetting\n");
360 bfin_write_RTC_STAT(0);
364 /* Initialize xtime. From now on, xtime is updated with timer interrupts */
365 xtime
.tv_sec
= secs_since_1970
;
367 set_normalized_timespec(&wall_to_monotonic
, -xtime
.tv_sec
, -xtime
.tv_nsec
);
369 bfin_cs_cycles_init();
370 bfin_cs_gptimer0_init();
371 bfin_clockevent_init();