提交 4d2e4d7f 编写于 作者: C Changhwan Youn 提交者: Kukjin Kim

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: NChanghwan Youn <chaos.youn@samsung.com>
Signed-off-by: NKukjin Kim <kgene.kim@samsung.com>
上级 3dbe6d4c
...@@ -29,12 +29,13 @@ ...@@ -29,12 +29,13 @@
#include <mach/regs-mct.h> #include <mach/regs-mct.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#define TICK_BASE_CNT 1
enum { enum {
MCT_INT_SPI, MCT_INT_SPI,
MCT_INT_PPI MCT_INT_PPI
}; };
static unsigned long clk_cnt_per_tick;
static unsigned long clk_rate; static unsigned long clk_rate;
static unsigned int mct_int_type; static unsigned int mct_int_type;
...@@ -205,11 +206,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles, ...@@ -205,11 +206,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles,
static void exynos4_comp_set_mode(enum clock_event_mode mode, static void exynos4_comp_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
unsigned long cycles_per_jiffy;
exynos4_mct_comp0_stop(); exynos4_mct_comp0_stop();
switch (mode) { switch (mode) {
case CLOCK_EVT_MODE_PERIODIC: case CLOCK_EVT_MODE_PERIODIC:
exynos4_mct_comp0_start(mode, clk_cnt_per_tick); cycles_per_jiffy =
(((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
exynos4_mct_comp0_start(mode, cycles_per_jiffy);
break; break;
case CLOCK_EVT_MODE_ONESHOT: case CLOCK_EVT_MODE_ONESHOT:
...@@ -248,9 +252,7 @@ static struct irqaction mct_comp_event_irq = { ...@@ -248,9 +252,7 @@ static struct irqaction mct_comp_event_irq = {
static void exynos4_clockevent_init(void) static void exynos4_clockevent_init(void)
{ {
clk_cnt_per_tick = clk_rate / 2 / HZ; clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5);
clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
mct_comp_device.max_delta_ns = mct_comp_device.max_delta_ns =
clockevent_delta2ns(0xffffffff, &mct_comp_device); clockevent_delta2ns(0xffffffff, &mct_comp_device);
mct_comp_device.min_delta_ns = mct_comp_device.min_delta_ns =
...@@ -314,12 +316,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode, ...@@ -314,12 +316,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
unsigned long cycles_per_jiffy;
exynos4_mct_tick_stop(mevt); exynos4_mct_tick_stop(mevt);
switch (mode) { switch (mode) {
case CLOCK_EVT_MODE_PERIODIC: case CLOCK_EVT_MODE_PERIODIC:
exynos4_mct_tick_start(clk_cnt_per_tick, mevt); cycles_per_jiffy =
(((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
exynos4_mct_tick_start(cycles_per_jiffy, mevt);
break; break;
case CLOCK_EVT_MODE_ONESHOT: case CLOCK_EVT_MODE_ONESHOT:
...@@ -393,7 +398,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) ...@@ -393,7 +398,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
evt->rating = 450; evt->rating = 450;
clockevents_calc_mult_shift(evt, clk_rate / 2, 5); clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5);
evt->max_delta_ns = evt->max_delta_ns =
clockevent_delta2ns(0x7fffffff, evt); clockevent_delta2ns(0x7fffffff, evt);
evt->min_delta_ns = evt->min_delta_ns =
...@@ -401,7 +406,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) ...@@ -401,7 +406,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
clockevents_register_device(evt); clockevents_register_device(evt);
exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET); exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
if (mct_int_type == MCT_INT_SPI) { if (mct_int_type == MCT_INT_SPI) {
if (cpu == 0) { if (cpu == 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册