aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorChanghwan Youn <chaos.youn@samsung.com>2012-03-09 18:09:21 -0500
committerKukjin Kim <kgene.kim@samsung.com>2012-03-10 10:26:59 -0500
commit4d2e4d7f2c2b1a4382286821a59fa2f4012cb748 (patch)
tree93f3f8631c16c0a7e6784b12a9df05cfb51faf3a /arch
parent3dbe6d4cacc76100f3166cd824d3ce7a8cef7cef (diff)
ARM: EXYNOS: fix cycle count for periodic mode of clock event timers
EXYNOS SOC series use MCT for kernel timer and MCT has two types of clock event timers, which are mct-comp and mct-tick. Because the clock rate of each event timer is diffent from the other, this patch fixes cycles_per_jiffy for each timer's periodic mode. Signed-off-by: Changhwan Youn <chaos.youn@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-exynos/mct.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index 85b5527d091..3e894ba25b0 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -29,12 +29,13 @@
29#include <mach/regs-mct.h> 29#include <mach/regs-mct.h>
30#include <asm/mach/time.h> 30#include <asm/mach/time.h>
31 31
32#define TICK_BASE_CNT 1
33
32enum { 34enum {
33 MCT_INT_SPI, 35 MCT_INT_SPI,
34 MCT_INT_PPI 36 MCT_INT_PPI
35}; 37};
36 38
37static unsigned long clk_cnt_per_tick;
38static unsigned long clk_rate; 39static unsigned long clk_rate;
39static unsigned int mct_int_type; 40static unsigned int mct_int_type;
40 41
@@ -205,11 +206,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles,
205static void exynos4_comp_set_mode(enum clock_event_mode mode, 206static void exynos4_comp_set_mode(enum clock_event_mode mode,
206 struct clock_event_device *evt) 207 struct clock_event_device *evt)
207{ 208{
209 unsigned long cycles_per_jiffy;
208 exynos4_mct_comp0_stop(); 210 exynos4_mct_comp0_stop();
209 211
210 switch (mode) { 212 switch (mode) {
211 case CLOCK_EVT_MODE_PERIODIC: 213 case CLOCK_EVT_MODE_PERIODIC:
212 exynos4_mct_comp0_start(mode, clk_cnt_per_tick); 214 cycles_per_jiffy =
215 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
216 exynos4_mct_comp0_start(mode, cycles_per_jiffy);
213 break; 217 break;
214 218
215 case CLOCK_EVT_MODE_ONESHOT: 219 case CLOCK_EVT_MODE_ONESHOT:
@@ -248,9 +252,7 @@ static struct irqaction mct_comp_event_irq = {
248 252
249static void exynos4_clockevent_init(void) 253static void exynos4_clockevent_init(void)
250{ 254{
251 clk_cnt_per_tick = clk_rate / 2 / HZ; 255 clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5);
252
253 clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
254 mct_comp_device.max_delta_ns = 256 mct_comp_device.max_delta_ns =
255 clockevent_delta2ns(0xffffffff, &mct_comp_device); 257 clockevent_delta2ns(0xffffffff, &mct_comp_device);
256 mct_comp_device.min_delta_ns = 258 mct_comp_device.min_delta_ns =
@@ -314,12 +316,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
314 struct clock_event_device *evt) 316 struct clock_event_device *evt)
315{ 317{
316 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); 318 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
319 unsigned long cycles_per_jiffy;
317 320
318 exynos4_mct_tick_stop(mevt); 321 exynos4_mct_tick_stop(mevt);
319 322
320 switch (mode) { 323 switch (mode) {
321 case CLOCK_EVT_MODE_PERIODIC: 324 case CLOCK_EVT_MODE_PERIODIC:
322 exynos4_mct_tick_start(clk_cnt_per_tick, mevt); 325 cycles_per_jiffy =
326 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
327 exynos4_mct_tick_start(cycles_per_jiffy, mevt);
323 break; 328 break;
324 329
325 case CLOCK_EVT_MODE_ONESHOT: 330 case CLOCK_EVT_MODE_ONESHOT:
@@ -393,7 +398,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
393 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 398 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
394 evt->rating = 450; 399 evt->rating = 450;
395 400
396 clockevents_calc_mult_shift(evt, clk_rate / 2, 5); 401 clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5);
397 evt->max_delta_ns = 402 evt->max_delta_ns =
398 clockevent_delta2ns(0x7fffffff, evt); 403 clockevent_delta2ns(0x7fffffff, evt);
399 evt->min_delta_ns = 404 evt->min_delta_ns =
@@ -401,7 +406,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
401 406
402 clockevents_register_device(evt); 407 clockevents_register_device(evt);
403 408
404 exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET); 409 exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
405 410
406 if (mct_int_type == MCT_INT_SPI) { 411 if (mct_int_type == MCT_INT_SPI) {
407 if (cpu == 0) { 412 if (cpu == 0) {