aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/time-ts.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel/time-ts.c')
-rw-r--r--arch/blackfin/kernel/time-ts.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index 359cfb1815ca..17c38c5b5b22 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -22,8 +22,6 @@
22#include <asm/time.h> 22#include <asm/time.h>
23#include <asm/gptimers.h> 23#include <asm/gptimers.h>
24 24
25#if defined(CONFIG_CYCLES_CLOCKSOURCE)
26
27/* Accelerators for sched_clock() 25/* Accelerators for sched_clock()
28 * convert from cycles(64bits) => nanoseconds (64bits) 26 * convert from cycles(64bits) => nanoseconds (64bits)
29 * basic equation: 27 * basic equation:
@@ -46,20 +44,11 @@
46 * -johnstul@us.ibm.com "math is hard, lets go shopping!" 44 * -johnstul@us.ibm.com "math is hard, lets go shopping!"
47 */ 45 */
48 46
49static unsigned long cyc2ns_scale;
50#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ 47#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
51 48
52static inline void set_cyc2ns_scale(unsigned long cpu_khz) 49#if defined(CONFIG_CYCLES_CLOCKSOURCE)
53{
54 cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR) / cpu_khz;
55}
56
57static inline unsigned long long cycles_2_ns(cycle_t cyc)
58{
59 return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
60}
61 50
62static cycle_t bfin_read_cycles(struct clocksource *cs) 51static notrace cycle_t bfin_read_cycles(struct clocksource *cs)
63{ 52{
64 return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); 53 return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
65} 54}
@@ -69,19 +58,18 @@ static struct clocksource bfin_cs_cycles = {
69 .rating = 400, 58 .rating = 400,
70 .read = bfin_read_cycles, 59 .read = bfin_read_cycles,
71 .mask = CLOCKSOURCE_MASK(64), 60 .mask = CLOCKSOURCE_MASK(64),
72 .shift = 22, 61 .shift = CYC2NS_SCALE_FACTOR,
73 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 62 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
74}; 63};
75 64
76unsigned long long sched_clock(void) 65static inline unsigned long long bfin_cs_cycles_sched_clock(void)
77{ 66{
78 return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles)); 67 return clocksource_cyc2ns(bfin_read_cycles(&bfin_cs_cycles),
68 bfin_cs_cycles.mult, bfin_cs_cycles.shift);
79} 69}
80 70
81static int __init bfin_cs_cycles_init(void) 71static int __init bfin_cs_cycles_init(void)
82{ 72{
83 set_cyc2ns_scale(get_cclk() / 1000);
84
85 bfin_cs_cycles.mult = \ 73 bfin_cs_cycles.mult = \
86 clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift); 74 clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift);
87 75
@@ -108,7 +96,7 @@ void __init setup_gptimer0(void)
108 enable_gptimers(TIMER0bit); 96 enable_gptimers(TIMER0bit);
109} 97}
110 98
111static cycle_t bfin_read_gptimer0(void) 99static cycle_t bfin_read_gptimer0(struct clocksource *cs)
112{ 100{
113 return bfin_read_TIMER0_COUNTER(); 101 return bfin_read_TIMER0_COUNTER();
114} 102}
@@ -118,10 +106,16 @@ static struct clocksource bfin_cs_gptimer0 = {
118 .rating = 350, 106 .rating = 350,
119 .read = bfin_read_gptimer0, 107 .read = bfin_read_gptimer0,
120 .mask = CLOCKSOURCE_MASK(32), 108 .mask = CLOCKSOURCE_MASK(32),
121 .shift = 22, 109 .shift = CYC2NS_SCALE_FACTOR,
122 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 110 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
123}; 111};
124 112
113static inline unsigned long long bfin_cs_gptimer0_sched_clock(void)
114{
115 return clocksource_cyc2ns(bfin_read_TIMER0_COUNTER(),
116 bfin_cs_gptimer0.mult, bfin_cs_gptimer0.shift);
117}
118
125static int __init bfin_cs_gptimer0_init(void) 119static int __init bfin_cs_gptimer0_init(void)
126{ 120{
127 setup_gptimer0(); 121 setup_gptimer0();
@@ -138,6 +132,19 @@ static int __init bfin_cs_gptimer0_init(void)
138# define bfin_cs_gptimer0_init() 132# define bfin_cs_gptimer0_init()
139#endif 133#endif
140 134
135
136#if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE)
137/* prefer to use cycles since it has higher rating */
138notrace unsigned long long sched_clock(void)
139{
140#if defined(CONFIG_CYCLES_CLOCKSOURCE)
141 return bfin_cs_cycles_sched_clock();
142#else
143 return bfin_cs_gptimer0_sched_clock();
144#endif
145}
146#endif
147
141#ifdef CONFIG_CORE_TIMER_IRQ_L1 148#ifdef CONFIG_CORE_TIMER_IRQ_L1
142__attribute__((l1_text)) 149__attribute__((l1_text))
143#endif 150#endif