Commit 23828a7a authored by Russell King's avatar Russell King

clockevents: ARM sp804: obtain sp804 timer rate via clks

This allows platforms to specify the rate of the SP804 clockevent via
the clk subsystem.  While ARM boards clock these at 1MHz, BCMRing also
has SP804 timers but are clocked at different rates.
Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 57cc4f7d
...@@ -28,12 +28,6 @@ ...@@ -28,12 +28,6 @@
#include <asm/hardware/arm_timer.h> #include <asm/hardware/arm_timer.h>
/*
* These timers are currently always setup to be clocked at 1MHz.
*/
#define TIMER_FREQ_KHZ (1000)
#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ)
static long __init sp804_get_clock_rate(const char *name) static long __init sp804_get_clock_rate(const char *name)
{ {
struct clk *clk; struct clk *clk;
...@@ -84,6 +78,7 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name) ...@@ -84,6 +78,7 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name)
static void __iomem *clkevt_base; static void __iomem *clkevt_base;
static unsigned long clkevt_reload;
/* /*
* IRQ handler for the timer * IRQ handler for the timer
...@@ -109,7 +104,7 @@ static void sp804_set_mode(enum clock_event_mode mode, ...@@ -109,7 +104,7 @@ static void sp804_set_mode(enum clock_event_mode mode,
switch (mode) { switch (mode) {
case CLOCK_EVT_MODE_PERIODIC: case CLOCK_EVT_MODE_PERIODIC:
writel(TIMER_RELOAD, clkevt_base + TIMER_LOAD); writel(clkevt_reload, clkevt_base + TIMER_LOAD);
ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
break; break;
...@@ -158,12 +153,17 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, ...@@ -158,12 +153,17 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
const char *name) const char *name)
{ {
struct clock_event_device *evt = &sp804_clockevent; struct clock_event_device *evt = &sp804_clockevent;
long rate = sp804_get_clock_rate(name);
if (rate < 0)
return;
clkevt_base = base; clkevt_base = base;
clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
evt->name = name; evt->name = name;
evt->irq = irq; evt->irq = irq;
evt->mult = div_sc(TIMER_FREQ_KHZ, NSEC_PER_MSEC, evt->shift); evt->mult = div_sc(rate, NSEC_PER_SEC, evt->shift);
evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt); evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt);
evt->min_delta_ns = clockevent_delta2ns(0xf, evt); evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
......
...@@ -150,6 +150,10 @@ static struct clk_lookup lookups[] = { ...@@ -150,6 +150,10 @@ static struct clk_lookup lookups[] = {
{ /* CLCD */ { /* CLCD */
.dev_id = "ct:clcd", .dev_id = "ct:clcd",
.clk = &osc1_clk, .clk = &osc1_clk,
}, { /* SP804 timers */
.dev_id = "sp804",
.con_id = "ct-timer0",
.clk = &ct_sp804_clk,
}, { /* SP804 timers */ }, { /* SP804 timers */
.dev_id = "sp804", .dev_id = "sp804",
.con_id = "ct-timer1", .con_id = "ct-timer1",
......
...@@ -368,6 +368,10 @@ static struct clk_lookup v2m_lookups[] = { ...@@ -368,6 +368,10 @@ static struct clk_lookup v2m_lookups[] = {
}, { /* CLCD */ }, { /* CLCD */
.dev_id = "mb:clcd", .dev_id = "mb:clcd",
.clk = &osc1_clk, .clk = &osc1_clk,
}, { /* SP804 timers */
.dev_id = "sp804",
.con_id = "v2m-timer0",
.clk = &v2m_sp804_clk,
}, { /* SP804 timers */ }, { /* SP804 timers */
.dev_id = "sp804", .dev_id = "sp804",
.con_id = "v2m-timer1", .con_id = "v2m-timer1",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment