blob: d0babce4b47a6ecbc9d3ca62bf084665c49a02b9 [file] [log] [blame]
Vegard Nossum77ef50a2008-06-18 17:08:48 +02001#ifndef ASM_X86__TIMER_H
2#define ASM_X86__TIMER_H
Linus Torvalds1da177e2005-04-16 15:20:36 -07003#include <linux/init.h>
Shaohua Lic3c433e2005-09-03 15:57:07 -07004#include <linux/pm.h>
Guillaume Chazarain53d517c2008-01-30 13:30:06 +01005#include <linux/percpu.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07006
Linus Torvalds1da177e2005-04-16 15:20:36 -07007#define TICK_SIZE (tick_nsec / 1000)
Zachary Amsden6cb9a832007-03-05 00:30:35 -08008
Zachary Amsden6cb9a832007-03-05 00:30:35 -08009unsigned long long native_sched_clock(void);
Alok Katariae93ef942008-07-01 11:43:36 -070010unsigned long native_calibrate_tsc(void);
Zachary Amsden6cb9a832007-03-05 00:30:35 -080011
Jaswinder Singhcc038492008-07-21 21:52:51 +053012#ifdef CONFIG_X86_32
Linus Torvalds1da177e2005-04-16 15:20:36 -070013extern int timer_ack;
Dave Jonesc5d28fb2005-05-31 19:03:46 -070014extern int recalibrate_cpu_khz(void);
Jaswinder Singhcc038492008-07-21 21:52:51 +053015#endif /* CONFIG_X86_32 */
16
17extern int no_timer_check;
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
Zachary Amsden6cb9a832007-03-05 00:30:35 -080019#ifndef CONFIG_PARAVIRT
Alok Katariae93ef942008-07-01 11:43:36 -070020#define calibrate_tsc() native_calibrate_tsc()
Zachary Amsden6cb9a832007-03-05 00:30:35 -080021#endif
22
Guillaume Chazarain53d517c2008-01-30 13:30:06 +010023/* Accelerators for sched_clock()
Jeremy Fitzhardinge688340e2007-07-17 18:37:04 -070024 * convert from cycles(64bits) => nanoseconds (64bits)
25 * basic equation:
26 * ns = cycles / (freq / ns_per_sec)
27 * ns = cycles * (ns_per_sec / freq)
28 * ns = cycles * (10^9 / (cpu_khz * 10^3))
29 * ns = cycles * (10^6 / cpu_khz)
30 *
31 * Then we use scaling math (suggested by george@mvista.com) to get:
32 * ns = cycles * (10^6 * SC / cpu_khz) / SC
33 * ns = cycles * cyc2ns_scale / SC
34 *
35 * And since SC is a constant power of two, we can convert the div
36 * into a shift.
37 *
Guillaume Chazarain53d517c2008-01-30 13:30:06 +010038 * We can use khz divisor instead of mhz to keep a better precision, since
Jeremy Fitzhardinge688340e2007-07-17 18:37:04 -070039 * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
40 * (mathieu.desnoyers@polymtl.ca)
41 *
42 * -johnstul@us.ibm.com "math is hard, lets go shopping!"
43 */
Guillaume Chazarain53d517c2008-01-30 13:30:06 +010044
45DECLARE_PER_CPU(unsigned long, cyc2ns);
Jeremy Fitzhardinge688340e2007-07-17 18:37:04 -070046
47#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
48
Guillaume Chazarain53d517c2008-01-30 13:30:06 +010049static inline unsigned long long __cycles_2_ns(unsigned long long cyc)
Jeremy Fitzhardinge688340e2007-07-17 18:37:04 -070050{
Guillaume Chazarain53d517c2008-01-30 13:30:06 +010051 return cyc * per_cpu(cyc2ns, smp_processor_id()) >> CYC2NS_SCALE_FACTOR;
Jeremy Fitzhardinge688340e2007-07-17 18:37:04 -070052}
53
Guillaume Chazarain53d517c2008-01-30 13:30:06 +010054static inline unsigned long long cycles_2_ns(unsigned long long cyc)
55{
56 unsigned long long ns;
57 unsigned long flags;
58
59 local_irq_save(flags);
60 ns = __cycles_2_ns(cyc);
61 local_irq_restore(flags);
62
63 return ns;
64}
Jeremy Fitzhardinge688340e2007-07-17 18:37:04 -070065
Vegard Nossum77ef50a2008-06-18 17:08:48 +020066#endif /* ASM_X86__TIMER_H */