aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 14:00:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 14:00:07 -0400
commit1ead65812486cda65093683a99b8907a7242fa93 (patch)
tree094684870815537aae4aedb69c10d669ba29f0af /drivers/clocksource
parentb6d739e9581272f0bbbd6edd15340fb8e108df96 (diff)
parentb97f0291a2504291aef850077f98cab68a5a2f33 (diff)
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer changes from Thomas Gleixner: "This assorted collection provides: - A new timer based timer broadcast feature for systems which do not provide a global accessible timer device. That allows those systems to put CPUs into deep idle states where the per cpu timer device stops. - A few NOHZ_FULL related improvements to the timer wheel - The usual updates to timer devices found in ARM SoCs - Small improvements and updates all over the place" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits) tick: Remove code duplication in tick_handle_periodic() tick: Fix spelling mistake in tick_handle_periodic() x86: hpet: Use proper destructor for delayed work workqueue: Provide destroy_delayed_work_on_stack() clocksource: CMT, MTU2, TMU and STI should depend on GENERIC_CLOCKEVENTS timer: Remove code redundancy while calling get_nohz_timer_target() hrtimer: Rearrange comments in the order struct members are declared timer: Use variable head instead of &work_list in __run_timers() clocksource: exynos_mct: silence a static checker warning arm: zynq: Add support for cpufreq arm: zynq: Don't use arm_global_timer with cpufreq clocksource/cadence_ttc: Overhaul clocksource frequency adjustment clocksource/cadence_ttc: Call clockevents_update_freq() with IRQs enabled clocksource: Add Kconfig entries for CMT, MTU2, TMU and STI sh: Remove Kconfig entries for TMU, CMT and MTU2 ARM: shmobile: Remove CMT, TMU and STI Kconfig entries clocksource: armada-370-xp: Use atomic access for shared registers clocksource: orion: Use atomic access for shared registers clocksource: timer-keystone: Delete unnecessary variable clocksource: timer-keystone: introduce clocksource driver for Keystone ...
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/Kconfig48
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/clocksource/arm_arch_timer.c1
-rw-r--r--drivers/clocksource/cadence_ttc_timer.c121
-rw-r--r--drivers/clocksource/exynos_mct.c2
-rw-r--r--drivers/clocksource/sun4i_timer.c2
-rw-r--r--drivers/clocksource/time-armada-370-xp.c12
-rw-r--r--drivers/clocksource/time-orion.c28
-rw-r--r--drivers/clocksource/timer-keystone.c241
-rw-r--r--drivers/clocksource/timer-u300.c447
10 files changed, 841 insertions, 63 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cd6950fd8caf..52e9329e3c51 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -140,3 +140,51 @@ config VF_PIT_TIMER
140 bool 140 bool
141 help 141 help
142 Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. 142 Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
143
144config SYS_SUPPORTS_SH_CMT
145 bool
146
147config SYS_SUPPORTS_SH_MTU2
148 bool
149
150config SYS_SUPPORTS_SH_TMU
151 bool
152
153config SYS_SUPPORTS_EM_STI
154 bool
155
156config SH_TIMER_CMT
157 bool "Renesas CMT timer driver" if COMPILE_TEST
158 depends on GENERIC_CLOCKEVENTS
159 default SYS_SUPPORTS_SH_CMT
160 help
161 This enables build of a clocksource and clockevent driver for
162 the Compare Match Timer (CMT) hardware available in 16/32/48-bit
163 variants on a wide range of Mobile and Automotive SoCs from Renesas.
164
165config SH_TIMER_MTU2
166 bool "Renesas MTU2 timer driver" if COMPILE_TEST
167 depends on GENERIC_CLOCKEVENTS
168 default SYS_SUPPORTS_SH_MTU2
169 help
170 This enables build of a clockevent driver for the Multi-Function
171 Timer Pulse Unit 2 (TMU2) hardware available on SoCs from Renesas.
172 This hardware comes with 16 bit-timer registers.
173
174config SH_TIMER_TMU
175 bool "Renesas TMU timer driver" if COMPILE_TEST
176 depends on GENERIC_CLOCKEVENTS
177 default SYS_SUPPORTS_SH_TMU
178 help
179 This enables build of a clocksource and clockevent driver for
180 the 32-bit Timer Unit (TMU) hardware available on a wide range
181 SoCs from Renesas.
182
183config EM_TIMER_STI
184 bool "Renesas STI timer driver" if COMPILE_TEST
185 depends on GENERIC_CLOCKEVENTS
186 default SYS_SUPPORTS_EM_STI
187 help
188 This enables build of a clocksource and clockevent driver for
189 the 48-bit System Timer (STI) hardware available on a SoCs
190 such as EMEV2 from former NEC Electronics.
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index c7ca50a9c232..aed3488d9426 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_ARCH_MARCO) += timer-marco.o
21obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o 21obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o
22obj-$(CONFIG_ARCH_MXS) += mxs_timer.o 22obj-$(CONFIG_ARCH_MXS) += mxs_timer.o
23obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o 23obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o
24obj-$(CONFIG_ARCH_U300) += timer-u300.o
24obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o 25obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o
25obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o 26obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o
26obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o 27obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o
@@ -37,3 +38,4 @@ obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
37obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o 38obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
38obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o 39obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o
39obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o 40obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o
41obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 95fb944e15ee..57e823c44d2a 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -277,6 +277,7 @@ static void __arch_timer_setup(unsigned type,
277 clk->set_next_event = arch_timer_set_next_event_phys; 277 clk->set_next_event = arch_timer_set_next_event_phys;
278 } 278 }
279 } else { 279 } else {
280 clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
280 clk->name = "arch_mem_timer"; 281 clk->name = "arch_mem_timer";
281 clk->rating = 400; 282 clk->rating = 400;
282 clk->cpumask = cpu_all_mask; 283 clk->cpumask = cpu_all_mask;
diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c
index 63f176de0d02..49fbe2847c84 100644
--- a/drivers/clocksource/cadence_ttc_timer.c
+++ b/drivers/clocksource/cadence_ttc_timer.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/clk-provider.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
20#include <linux/clockchips.h> 21#include <linux/clockchips.h>
21#include <linux/of_address.h> 22#include <linux/of_address.h>
@@ -52,6 +53,8 @@
52#define TTC_CNT_CNTRL_DISABLE_MASK 0x1 53#define TTC_CNT_CNTRL_DISABLE_MASK 0x1
53 54
54#define TTC_CLK_CNTRL_CSRC_MASK (1 << 5) /* clock source */ 55#define TTC_CLK_CNTRL_CSRC_MASK (1 << 5) /* clock source */
56#define TTC_CLK_CNTRL_PSV_MASK 0x1e
57#define TTC_CLK_CNTRL_PSV_SHIFT 1
55 58
56/* 59/*
57 * Setup the timers to use pre-scaling, using a fixed value for now that will 60 * Setup the timers to use pre-scaling, using a fixed value for now that will
@@ -63,6 +66,8 @@
63#define CLK_CNTRL_PRESCALE_EN 1 66#define CLK_CNTRL_PRESCALE_EN 1
64#define CNT_CNTRL_RESET (1 << 4) 67#define CNT_CNTRL_RESET (1 << 4)
65 68
69#define MAX_F_ERR 50
70
66/** 71/**
67 * struct ttc_timer - This definition defines local timer structure 72 * struct ttc_timer - This definition defines local timer structure
68 * 73 *
@@ -82,6 +87,8 @@ struct ttc_timer {
82 container_of(x, struct ttc_timer, clk_rate_change_nb) 87 container_of(x, struct ttc_timer, clk_rate_change_nb)
83 88
84struct ttc_timer_clocksource { 89struct ttc_timer_clocksource {
90 u32 scale_clk_ctrl_reg_old;
91 u32 scale_clk_ctrl_reg_new;
85 struct ttc_timer ttc; 92 struct ttc_timer ttc;
86 struct clocksource cs; 93 struct clocksource cs;
87}; 94};
@@ -229,32 +236,89 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
229 struct ttc_timer_clocksource, ttc); 236 struct ttc_timer_clocksource, ttc);
230 237
231 switch (event) { 238 switch (event) {
232 case POST_RATE_CHANGE: 239 case PRE_RATE_CHANGE:
240 {
241 u32 psv;
242 unsigned long factor, rate_low, rate_high;
243
244 if (ndata->new_rate > ndata->old_rate) {
245 factor = DIV_ROUND_CLOSEST(ndata->new_rate,
246 ndata->old_rate);
247 rate_low = ndata->old_rate;
248 rate_high = ndata->new_rate;
249 } else {
250 factor = DIV_ROUND_CLOSEST(ndata->old_rate,
251 ndata->new_rate);
252 rate_low = ndata->new_rate;
253 rate_high = ndata->old_rate;
254 }
255
256 if (!is_power_of_2(factor))
257 return NOTIFY_BAD;
258
259 if (abs(rate_high - (factor * rate_low)) > MAX_F_ERR)
260 return NOTIFY_BAD;
261
262 factor = __ilog2_u32(factor);
263
233 /* 264 /*
234 * Do whatever is necessary to maintain a proper time base 265 * store timer clock ctrl register so we can restore it in case
235 * 266 * of an abort.
236 * I cannot find a way to adjust the currently used clocksource
237 * to the new frequency. __clocksource_updatefreq_hz() sounds
238 * good, but does not work. Not sure what's that missing.
239 *
240 * This approach works, but triggers two clocksource switches.
241 * The first after unregister to clocksource jiffies. And
242 * another one after the register to the newly registered timer.
243 *
244 * Alternatively we could 'waste' another HW timer to ping pong
245 * between clock sources. That would also use one register and
246 * one unregister call, but only trigger one clocksource switch
247 * for the cost of another HW timer used by the OS.
248 */ 267 */
249 clocksource_unregister(&ttccs->cs); 268 ttccs->scale_clk_ctrl_reg_old =
250 clocksource_register_hz(&ttccs->cs, 269 __raw_readl(ttccs->ttc.base_addr +
251 ndata->new_rate / PRESCALE); 270 TTC_CLK_CNTRL_OFFSET);
252 /* fall through */ 271
253 case PRE_RATE_CHANGE: 272 psv = (ttccs->scale_clk_ctrl_reg_old &
273 TTC_CLK_CNTRL_PSV_MASK) >>
274 TTC_CLK_CNTRL_PSV_SHIFT;
275 if (ndata->new_rate < ndata->old_rate)
276 psv -= factor;
277 else
278 psv += factor;
279
280 /* prescaler within legal range? */
281 if (psv & ~(TTC_CLK_CNTRL_PSV_MASK >> TTC_CLK_CNTRL_PSV_SHIFT))
282 return NOTIFY_BAD;
283
284 ttccs->scale_clk_ctrl_reg_new = ttccs->scale_clk_ctrl_reg_old &
285 ~TTC_CLK_CNTRL_PSV_MASK;
286 ttccs->scale_clk_ctrl_reg_new |= psv << TTC_CLK_CNTRL_PSV_SHIFT;
287
288
289 /* scale down: adjust divider in post-change notification */
290 if (ndata->new_rate < ndata->old_rate)
291 return NOTIFY_DONE;
292
293 /* scale up: adjust divider now - before frequency change */
294 __raw_writel(ttccs->scale_clk_ctrl_reg_new,
295 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
296 break;
297 }
298 case POST_RATE_CHANGE:
299 /* scale up: pre-change notification did the adjustment */
300 if (ndata->new_rate > ndata->old_rate)
301 return NOTIFY_OK;
302
303 /* scale down: adjust divider now - after frequency change */
304 __raw_writel(ttccs->scale_clk_ctrl_reg_new,
305 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
306 break;
307
254 case ABORT_RATE_CHANGE: 308 case ABORT_RATE_CHANGE:
309 /* we have to undo the adjustment in case we scale up */
310 if (ndata->new_rate < ndata->old_rate)
311 return NOTIFY_OK;
312
313 /* restore original register value */
314 __raw_writel(ttccs->scale_clk_ctrl_reg_old,
315 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
316 /* fall through */
255 default: 317 default:
256 return NOTIFY_DONE; 318 return NOTIFY_DONE;
257 } 319 }
320
321 return NOTIFY_DONE;
258} 322}
259 323
260static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base) 324static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base)
@@ -321,25 +385,12 @@ static int ttc_rate_change_clockevent_cb(struct notifier_block *nb,
321 385
322 switch (event) { 386 switch (event) {
323 case POST_RATE_CHANGE: 387 case POST_RATE_CHANGE:
324 {
325 unsigned long flags;
326
327 /*
328 * clockevents_update_freq should be called with IRQ disabled on
329 * the CPU the timer provides events for. The timer we use is
330 * common to both CPUs, not sure if we need to run on both
331 * cores.
332 */
333 local_irq_save(flags);
334 clockevents_update_freq(&ttcce->ce,
335 ndata->new_rate / PRESCALE);
336 local_irq_restore(flags);
337
338 /* update cached frequency */ 388 /* update cached frequency */
339 ttc->freq = ndata->new_rate; 389 ttc->freq = ndata->new_rate;
340 390
391 clockevents_update_freq(&ttcce->ce, ndata->new_rate / PRESCALE);
392
341 /* fall through */ 393 /* fall through */
342 }
343 case PRE_RATE_CHANGE: 394 case PRE_RATE_CHANGE:
344 case ABORT_RATE_CHANGE: 395 case ABORT_RATE_CHANGE:
345 default: 396 default:
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 48f76bc05da0..c2e390efbdca 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -410,7 +410,7 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt)
410 mevt = container_of(evt, struct mct_clock_event_device, evt); 410 mevt = container_of(evt, struct mct_clock_event_device, evt);
411 411
412 mevt->base = EXYNOS4_MCT_L_BASE(cpu); 412 mevt->base = EXYNOS4_MCT_L_BASE(cpu);
413 sprintf(mevt->name, "mct_tick%d", cpu); 413 snprintf(mevt->name, sizeof(mevt->name), "mct_tick%d", cpu);
414 414
415 evt->name = mevt->name; 415 evt->name = mevt->name;
416 evt->cpumask = cpumask_of(cpu); 416 evt->cpumask = cpumask_of(cpu);
diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c
index bf497afba9ad..efb17c3ee120 100644
--- a/drivers/clocksource/sun4i_timer.c
+++ b/drivers/clocksource/sun4i_timer.c
@@ -196,5 +196,5 @@ static void __init sun4i_timer_init(struct device_node *node)
196 clockevents_config_and_register(&sun4i_clockevent, rate, 196 clockevents_config_and_register(&sun4i_clockevent, rate,
197 TIMER_SYNC_TICKS, 0xffffffff); 197 TIMER_SYNC_TICKS, 0xffffffff);
198} 198}
199CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-timer", 199CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer",
200 sun4i_timer_init); 200 sun4i_timer_init);
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
index ee8691b89944..0451e62fac7a 100644
--- a/drivers/clocksource/time-armada-370-xp.c
+++ b/drivers/clocksource/time-armada-370-xp.c
@@ -85,12 +85,6 @@ static u32 ticks_per_jiffy;
85 85
86static struct clock_event_device __percpu *armada_370_xp_evt; 86static struct clock_event_device __percpu *armada_370_xp_evt;
87 87
88static void timer_ctrl_clrset(u32 clr, u32 set)
89{
90 writel((readl(timer_base + TIMER_CTRL_OFF) & ~clr) | set,
91 timer_base + TIMER_CTRL_OFF);
92}
93
94static void local_timer_ctrl_clrset(u32 clr, u32 set) 88static void local_timer_ctrl_clrset(u32 clr, u32 set)
95{ 89{
96 writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set, 90 writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set,
@@ -245,7 +239,7 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np)
245 clr = TIMER0_25MHZ; 239 clr = TIMER0_25MHZ;
246 enable_mask = TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT); 240 enable_mask = TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT);
247 } 241 }
248 timer_ctrl_clrset(clr, set); 242 atomic_io_modify(timer_base + TIMER_CTRL_OFF, clr | set, set);
249 local_timer_ctrl_clrset(clr, set); 243 local_timer_ctrl_clrset(clr, set);
250 244
251 /* 245 /*
@@ -263,7 +257,9 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np)
263 writel(0xffffffff, timer_base + TIMER0_VAL_OFF); 257 writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
264 writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); 258 writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
265 259
266 timer_ctrl_clrset(0, TIMER0_RELOAD_EN | enable_mask); 260 atomic_io_modify(timer_base + TIMER_CTRL_OFF,
261 TIMER0_RELOAD_EN | enable_mask,
262 TIMER0_RELOAD_EN | enable_mask);
267 263
268 /* 264 /*
269 * Set scale and timer for sched_clock. 265 * Set scale and timer for sched_clock.
diff --git a/drivers/clocksource/time-orion.c b/drivers/clocksource/time-orion.c
index 20066222f3f2..0b3ce0399c51 100644
--- a/drivers/clocksource/time-orion.c
+++ b/drivers/clocksource/time-orion.c
@@ -35,20 +35,6 @@
35#define ORION_ONESHOT_MAX 0xfffffffe 35#define ORION_ONESHOT_MAX 0xfffffffe
36 36
37static void __iomem *timer_base; 37static void __iomem *timer_base;
38static DEFINE_SPINLOCK(timer_ctrl_lock);
39
40/*
41 * Thread-safe access to TIMER_CTRL register
42 * (shared with watchdog timer)
43 */
44void orion_timer_ctrl_clrset(u32 clr, u32 set)
45{
46 spin_lock(&timer_ctrl_lock);
47 writel((readl(timer_base + TIMER_CTRL) & ~clr) | set,
48 timer_base + TIMER_CTRL);
49 spin_unlock(&timer_ctrl_lock);
50}
51EXPORT_SYMBOL(orion_timer_ctrl_clrset);
52 38
53/* 39/*
54 * Free-running clocksource handling. 40 * Free-running clocksource handling.
@@ -68,7 +54,8 @@ static int orion_clkevt_next_event(unsigned long delta,
68{ 54{
69 /* setup and enable one-shot timer */ 55 /* setup and enable one-shot timer */
70 writel(delta, timer_base + TIMER1_VAL); 56 writel(delta, timer_base + TIMER1_VAL);
71 orion_timer_ctrl_clrset(TIMER1_RELOAD_EN, TIMER1_EN); 57 atomic_io_modify(timer_base + TIMER_CTRL,
58 TIMER1_RELOAD_EN | TIMER1_EN, TIMER1_EN);
72 59
73 return 0; 60 return 0;
74} 61}
@@ -80,10 +67,13 @@ static void orion_clkevt_mode(enum clock_event_mode mode,
80 /* setup and enable periodic timer at 1/HZ intervals */ 67 /* setup and enable periodic timer at 1/HZ intervals */
81 writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD); 68 writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD);
82 writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL); 69 writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL);
83 orion_timer_ctrl_clrset(0, TIMER1_RELOAD_EN | TIMER1_EN); 70 atomic_io_modify(timer_base + TIMER_CTRL,
71 TIMER1_RELOAD_EN | TIMER1_EN,
72 TIMER1_RELOAD_EN | TIMER1_EN);
84 } else { 73 } else {
85 /* disable timer */ 74 /* disable timer */
86 orion_timer_ctrl_clrset(TIMER1_RELOAD_EN | TIMER1_EN, 0); 75 atomic_io_modify(timer_base + TIMER_CTRL,
76 TIMER1_RELOAD_EN | TIMER1_EN, 0);
87 } 77 }
88} 78}
89 79
@@ -131,7 +121,9 @@ static void __init orion_timer_init(struct device_node *np)
131 /* setup timer0 as free-running clocksource */ 121 /* setup timer0 as free-running clocksource */
132 writel(~0, timer_base + TIMER0_VAL); 122 writel(~0, timer_base + TIMER0_VAL);
133 writel(~0, timer_base + TIMER0_RELOAD); 123 writel(~0, timer_base + TIMER0_RELOAD);
134 orion_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | TIMER0_EN); 124 atomic_io_modify(timer_base + TIMER_CTRL,
125 TIMER0_RELOAD_EN | TIMER0_EN,
126 TIMER0_RELOAD_EN | TIMER0_EN);
135 clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource", 127 clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource",
136 clk_get_rate(clk), 300, 32, 128 clk_get_rate(clk), 300, 32,
137 clocksource_mmio_readl_down); 129 clocksource_mmio_readl_down);
diff --git a/drivers/clocksource/timer-keystone.c b/drivers/clocksource/timer-keystone.c
new file mode 100644
index 000000000000..0250354f7e55
--- /dev/null
+++ b/drivers/clocksource/timer-keystone.c
@@ -0,0 +1,241 @@
1/*
2 * Keystone broadcast clock-event
3 *
4 * Copyright 2013 Texas Instruments, Inc.
5 *
6 * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/clk.h>
15#include <linux/clockchips.h>
16#include <linux/clocksource.h>
17#include <linux/interrupt.h>
18#include <linux/of_address.h>
19#include <linux/of_irq.h>
20
21#define TIMER_NAME "timer-keystone"
22
23/* Timer register offsets */
24#define TIM12 0x10
25#define TIM34 0x14
26#define PRD12 0x18
27#define PRD34 0x1c
28#define TCR 0x20
29#define TGCR 0x24
30#define INTCTLSTAT 0x44
31
32/* Timer register bitfields */
33#define TCR_ENAMODE_MASK 0xC0
34#define TCR_ENAMODE_ONESHOT_MASK 0x40
35#define TCR_ENAMODE_PERIODIC_MASK 0x80
36
37#define TGCR_TIM_UNRESET_MASK 0x03
38#define INTCTLSTAT_ENINT_MASK 0x01
39
40/**
41 * struct keystone_timer: holds timer's data
42 * @base: timer memory base address
43 * @hz_period: cycles per HZ period
44 * @event_dev: event device based on timer
45 */
46static struct keystone_timer {
47 void __iomem *base;
48 unsigned long hz_period;
49 struct clock_event_device event_dev;
50} timer;
51
52static inline u32 keystone_timer_readl(unsigned long rg)
53{
54 return readl_relaxed(timer.base + rg);
55}
56
57static inline void keystone_timer_writel(u32 val, unsigned long rg)
58{
59 writel_relaxed(val, timer.base + rg);
60}
61
62/**
63 * keystone_timer_barrier: write memory barrier
64 * use explicit barrier to avoid using readl/writel non relaxed function
65 * variants, because in our case non relaxed variants hide the true places
66 * where barrier is needed.
67 */
68static inline void keystone_timer_barrier(void)
69{
70 __iowmb();
71}
72
73/**
74 * keystone_timer_config: configures timer to work in oneshot/periodic modes.
75 * @ mode: mode to configure
76 * @ period: cycles number to configure for
77 */
78static int keystone_timer_config(u64 period, enum clock_event_mode mode)
79{
80 u32 tcr;
81 u32 off;
82
83 tcr = keystone_timer_readl(TCR);
84 off = tcr & ~(TCR_ENAMODE_MASK);
85
86 /* set enable mode */
87 switch (mode) {
88 case CLOCK_EVT_MODE_ONESHOT:
89 tcr |= TCR_ENAMODE_ONESHOT_MASK;
90 break;
91 case CLOCK_EVT_MODE_PERIODIC:
92 tcr |= TCR_ENAMODE_PERIODIC_MASK;
93 break;
94 default:
95 return -1;
96 }
97
98 /* disable timer */
99 keystone_timer_writel(off, TCR);
100 /* here we have to be sure the timer has been disabled */
101 keystone_timer_barrier();
102
103 /* reset counter to zero, set new period */
104 keystone_timer_writel(0, TIM12);
105 keystone_timer_writel(0, TIM34);
106 keystone_timer_writel(period & 0xffffffff, PRD12);
107 keystone_timer_writel(period >> 32, PRD34);
108
109 /*
110 * enable timer
111 * here we have to be sure that CNTLO, CNTHI, PRDLO, PRDHI registers
112 * have been written.
113 */
114 keystone_timer_barrier();
115 keystone_timer_writel(tcr, TCR);
116 return 0;
117}
118
119static void keystone_timer_disable(void)
120{
121 u32 tcr;
122
123 tcr = keystone_timer_readl(TCR);
124
125 /* disable timer */
126 tcr &= ~(TCR_ENAMODE_MASK);
127 keystone_timer_writel(tcr, TCR);
128}
129
130static irqreturn_t keystone_timer_interrupt(int irq, void *dev_id)
131{
132 struct clock_event_device *evt = dev_id;
133
134 evt->event_handler(evt);
135 return IRQ_HANDLED;
136}
137
138static int keystone_set_next_event(unsigned long cycles,
139 struct clock_event_device *evt)
140{
141 return keystone_timer_config(cycles, evt->mode);
142}
143
144static void keystone_set_mode(enum clock_event_mode mode,
145 struct clock_event_device *evt)
146{
147 switch (mode) {
148 case CLOCK_EVT_MODE_PERIODIC:
149 keystone_timer_config(timer.hz_period, CLOCK_EVT_MODE_PERIODIC);
150 break;
151 case CLOCK_EVT_MODE_UNUSED:
152 case CLOCK_EVT_MODE_SHUTDOWN:
153 case CLOCK_EVT_MODE_ONESHOT:
154 keystone_timer_disable();
155 break;
156 default:
157 break;
158 }
159}
160
161static void __init keystone_timer_init(struct device_node *np)
162{
163 struct clock_event_device *event_dev = &timer.event_dev;
164 unsigned long rate;
165 struct clk *clk;
166 int irq, error;
167
168 irq = irq_of_parse_and_map(np, 0);
169 if (irq == NO_IRQ) {
170 pr_err("%s: failed to map interrupts\n", __func__);
171 return;
172 }
173
174 timer.base = of_iomap(np, 0);
175 if (!timer.base) {
176 pr_err("%s: failed to map registers\n", __func__);
177 return;
178 }
179
180 clk = of_clk_get(np, 0);
181 if (IS_ERR(clk)) {
182 pr_err("%s: failed to get clock\n", __func__);
183 iounmap(timer.base);
184 return;
185 }
186
187 error = clk_prepare_enable(clk);
188 if (error) {
189 pr_err("%s: failed to enable clock\n", __func__);
190 goto err;
191 }
192
193 rate = clk_get_rate(clk);
194
195 /* disable, use internal clock source */
196 keystone_timer_writel(0, TCR);
197 /* here we have to be sure the timer has been disabled */
198 keystone_timer_barrier();
199
200 /* reset timer as 64-bit, no pre-scaler, plus features are disabled */
201 keystone_timer_writel(0, TGCR);
202
203 /* unreset timer */
204 keystone_timer_writel(TGCR_TIM_UNRESET_MASK, TGCR);
205
206 /* init counter to zero */
207 keystone_timer_writel(0, TIM12);
208 keystone_timer_writel(0, TIM34);
209
210 timer.hz_period = DIV_ROUND_UP(rate, HZ);
211
212 /* enable timer interrupts */
213 keystone_timer_writel(INTCTLSTAT_ENINT_MASK, INTCTLSTAT);
214
215 error = request_irq(irq, keystone_timer_interrupt, IRQF_TIMER,
216 TIMER_NAME, event_dev);
217 if (error) {
218 pr_err("%s: failed to setup irq\n", __func__);
219 goto err;
220 }
221
222 /* setup clockevent */
223 event_dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
224 event_dev->set_next_event = keystone_set_next_event;
225 event_dev->set_mode = keystone_set_mode;
226 event_dev->cpumask = cpu_all_mask;
227 event_dev->owner = THIS_MODULE;
228 event_dev->name = TIMER_NAME;
229 event_dev->irq = irq;
230
231 clockevents_config_and_register(event_dev, rate, 1, ULONG_MAX);
232
233 pr_info("keystone timer clock @%lu Hz\n", rate);
234 return;
235err:
236 clk_put(clk);
237 iounmap(timer.base);
238}
239
240CLOCKSOURCE_OF_DECLARE(keystone_timer, "ti,keystone-timer",
241 keystone_timer_init);
diff --git a/drivers/clocksource/timer-u300.c b/drivers/clocksource/timer-u300.c
new file mode 100644
index 000000000000..e63d469661fd
--- /dev/null
+++ b/drivers/clocksource/timer-u300.c
@@ -0,0 +1,447 @@
1/*
2 * Copyright (C) 2007-2009 ST-Ericsson AB
3 * License terms: GNU General Public License (GPL) version 2
4 * Timer COH 901 328, runs the OS timer interrupt.
5 * Author: Linus Walleij <linus.walleij@stericsson.com>
6 */
7#include <linux/interrupt.h>
8#include <linux/time.h>
9#include <linux/timex.h>
10#include <linux/clockchips.h>
11#include <linux/clocksource.h>
12#include <linux/types.h>
13#include <linux/io.h>
14#include <linux/clk.h>
15#include <linux/err.h>
16#include <linux/irq.h>
17#include <linux/delay.h>
18#include <linux/of_address.h>
19#include <linux/of_irq.h>
20#include <linux/sched_clock.h>
21
22/* Generic stuff */
23#include <asm/mach/map.h>
24#include <asm/mach/time.h>
25
26/*
27 * APP side special timer registers
28 * This timer contains four timers which can fire an interrupt each.
29 * OS (operating system) timer @ 32768 Hz
30 * DD (device driver) timer @ 1 kHz
31 * GP1 (general purpose 1) timer @ 1MHz
32 * GP2 (general purpose 2) timer @ 1MHz
33 */
34
35/* Reset OS Timer 32bit (-/W) */
36#define U300_TIMER_APP_ROST (0x0000)
37#define U300_TIMER_APP_ROST_TIMER_RESET (0x00000000)
38/* Enable OS Timer 32bit (-/W) */
39#define U300_TIMER_APP_EOST (0x0004)
40#define U300_TIMER_APP_EOST_TIMER_ENABLE (0x00000000)
41/* Disable OS Timer 32bit (-/W) */
42#define U300_TIMER_APP_DOST (0x0008)
43#define U300_TIMER_APP_DOST_TIMER_DISABLE (0x00000000)
44/* OS Timer Mode Register 32bit (-/W) */
45#define U300_TIMER_APP_SOSTM (0x000c)
46#define U300_TIMER_APP_SOSTM_MODE_CONTINUOUS (0x00000000)
47#define U300_TIMER_APP_SOSTM_MODE_ONE_SHOT (0x00000001)
48/* OS Timer Status Register 32bit (R/-) */
49#define U300_TIMER_APP_OSTS (0x0010)
50#define U300_TIMER_APP_OSTS_TIMER_STATE_MASK (0x0000000F)
51#define U300_TIMER_APP_OSTS_TIMER_STATE_IDLE (0x00000001)
52#define U300_TIMER_APP_OSTS_TIMER_STATE_ACTIVE (0x00000002)
53#define U300_TIMER_APP_OSTS_ENABLE_IND (0x00000010)
54#define U300_TIMER_APP_OSTS_MODE_MASK (0x00000020)
55#define U300_TIMER_APP_OSTS_MODE_CONTINUOUS (0x00000000)
56#define U300_TIMER_APP_OSTS_MODE_ONE_SHOT (0x00000020)
57#define U300_TIMER_APP_OSTS_IRQ_ENABLED_IND (0x00000040)
58#define U300_TIMER_APP_OSTS_IRQ_PENDING_IND (0x00000080)
59/* OS Timer Current Count Register 32bit (R/-) */
60#define U300_TIMER_APP_OSTCC (0x0014)
61/* OS Timer Terminal Count Register 32bit (R/W) */
62#define U300_TIMER_APP_OSTTC (0x0018)
63/* OS Timer Interrupt Enable Register 32bit (-/W) */
64#define U300_TIMER_APP_OSTIE (0x001c)
65#define U300_TIMER_APP_OSTIE_IRQ_DISABLE (0x00000000)
66#define U300_TIMER_APP_OSTIE_IRQ_ENABLE (0x00000001)
67/* OS Timer Interrupt Acknowledge Register 32bit (-/W) */
68#define U300_TIMER_APP_OSTIA (0x0020)
69#define U300_TIMER_APP_OSTIA_IRQ_ACK (0x00000080)
70
71/* Reset DD Timer 32bit (-/W) */
72#define U300_TIMER_APP_RDDT (0x0040)
73#define U300_TIMER_APP_RDDT_TIMER_RESET (0x00000000)
74/* Enable DD Timer 32bit (-/W) */
75#define U300_TIMER_APP_EDDT (0x0044)
76#define U300_TIMER_APP_EDDT_TIMER_ENABLE (0x00000000)
77/* Disable DD Timer 32bit (-/W) */
78#define U300_TIMER_APP_DDDT (0x0048)
79#define U300_TIMER_APP_DDDT_TIMER_DISABLE (0x00000000)
80/* DD Timer Mode Register 32bit (-/W) */
81#define U300_TIMER_APP_SDDTM (0x004c)
82#define U300_TIMER_APP_SDDTM_MODE_CONTINUOUS (0x00000000)
83#define U300_TIMER_APP_SDDTM_MODE_ONE_SHOT (0x00000001)
84/* DD Timer Status Register 32bit (R/-) */
85#define U300_TIMER_APP_DDTS (0x0050)
86#define U300_TIMER_APP_DDTS_TIMER_STATE_MASK (0x0000000F)
87#define U300_TIMER_APP_DDTS_TIMER_STATE_IDLE (0x00000001)
88#define U300_TIMER_APP_DDTS_TIMER_STATE_ACTIVE (0x00000002)
89#define U300_TIMER_APP_DDTS_ENABLE_IND (0x00000010)
90#define U300_TIMER_APP_DDTS_MODE_MASK (0x00000020)
91#define U300_TIMER_APP_DDTS_MODE_CONTINUOUS (0x00000000)
92#define U300_TIMER_APP_DDTS_MODE_ONE_SHOT (0x00000020)
93#define U300_TIMER_APP_DDTS_IRQ_ENABLED_IND (0x00000040)
94#define U300_TIMER_APP_DDTS_IRQ_PENDING_IND (0x00000080)
95/* DD Timer Current Count Register 32bit (R/-) */
96#define U300_TIMER_APP_DDTCC (0x0054)
97/* DD Timer Terminal Count Register 32bit (R/W) */
98#define U300_TIMER_APP_DDTTC (0x0058)
99/* DD Timer Interrupt Enable Register 32bit (-/W) */
100#define U300_TIMER_APP_DDTIE (0x005c)
101#define U300_TIMER_APP_DDTIE_IRQ_DISABLE (0x00000000)
102#define U300_TIMER_APP_DDTIE_IRQ_ENABLE (0x00000001)
103/* DD Timer Interrupt Acknowledge Register 32bit (-/W) */
104#define U300_TIMER_APP_DDTIA (0x0060)
105#define U300_TIMER_APP_DDTIA_IRQ_ACK (0x00000080)
106
107/* Reset GP1 Timer 32bit (-/W) */
108#define U300_TIMER_APP_RGPT1 (0x0080)
109#define U300_TIMER_APP_RGPT1_TIMER_RESET (0x00000000)
110/* Enable GP1 Timer 32bit (-/W) */
111#define U300_TIMER_APP_EGPT1 (0x0084)
112#define U300_TIMER_APP_EGPT1_TIMER_ENABLE (0x00000000)
113/* Disable GP1 Timer 32bit (-/W) */
114#define U300_TIMER_APP_DGPT1 (0x0088)
115#define U300_TIMER_APP_DGPT1_TIMER_DISABLE (0x00000000)
116/* GP1 Timer Mode Register 32bit (-/W) */
117#define U300_TIMER_APP_SGPT1M (0x008c)
118#define U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS (0x00000000)
119#define U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT (0x00000001)
120/* GP1 Timer Status Register 32bit (R/-) */
121#define U300_TIMER_APP_GPT1S (0x0090)
122#define U300_TIMER_APP_GPT1S_TIMER_STATE_MASK (0x0000000F)
123#define U300_TIMER_APP_GPT1S_TIMER_STATE_IDLE (0x00000001)
124#define U300_TIMER_APP_GPT1S_TIMER_STATE_ACTIVE (0x00000002)
125#define U300_TIMER_APP_GPT1S_ENABLE_IND (0x00000010)
126#define U300_TIMER_APP_GPT1S_MODE_MASK (0x00000020)
127#define U300_TIMER_APP_GPT1S_MODE_CONTINUOUS (0x00000000)
128#define U300_TIMER_APP_GPT1S_MODE_ONE_SHOT (0x00000020)
129#define U300_TIMER_APP_GPT1S_IRQ_ENABLED_IND (0x00000040)
130#define U300_TIMER_APP_GPT1S_IRQ_PENDING_IND (0x00000080)
131/* GP1 Timer Current Count Register 32bit (R/-) */
132#define U300_TIMER_APP_GPT1CC (0x0094)
133/* GP1 Timer Terminal Count Register 32bit (R/W) */
134#define U300_TIMER_APP_GPT1TC (0x0098)
135/* GP1 Timer Interrupt Enable Register 32bit (-/W) */
136#define U300_TIMER_APP_GPT1IE (0x009c)
137#define U300_TIMER_APP_GPT1IE_IRQ_DISABLE (0x00000000)
138#define U300_TIMER_APP_GPT1IE_IRQ_ENABLE (0x00000001)
139/* GP1 Timer Interrupt Acknowledge Register 32bit (-/W) */
140#define U300_TIMER_APP_GPT1IA (0x00a0)
141#define U300_TIMER_APP_GPT1IA_IRQ_ACK (0x00000080)
142
143/* Reset GP2 Timer 32bit (-/W) */
144#define U300_TIMER_APP_RGPT2 (0x00c0)
145#define U300_TIMER_APP_RGPT2_TIMER_RESET (0x00000000)
146/* Enable GP2 Timer 32bit (-/W) */
147#define U300_TIMER_APP_EGPT2 (0x00c4)
148#define U300_TIMER_APP_EGPT2_TIMER_ENABLE (0x00000000)
149/* Disable GP2 Timer 32bit (-/W) */
150#define U300_TIMER_APP_DGPT2 (0x00c8)
151#define U300_TIMER_APP_DGPT2_TIMER_DISABLE (0x00000000)
152/* GP2 Timer Mode Register 32bit (-/W) */
153#define U300_TIMER_APP_SGPT2M (0x00cc)
154#define U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS (0x00000000)
155#define U300_TIMER_APP_SGPT2M_MODE_ONE_SHOT (0x00000001)
156/* GP2 Timer Status Register 32bit (R/-) */
157#define U300_TIMER_APP_GPT2S (0x00d0)
158#define U300_TIMER_APP_GPT2S_TIMER_STATE_MASK (0x0000000F)
159#define U300_TIMER_APP_GPT2S_TIMER_STATE_IDLE (0x00000001)
160#define U300_TIMER_APP_GPT2S_TIMER_STATE_ACTIVE (0x00000002)
161#define U300_TIMER_APP_GPT2S_ENABLE_IND (0x00000010)
162#define U300_TIMER_APP_GPT2S_MODE_MASK (0x00000020)
163#define U300_TIMER_APP_GPT2S_MODE_CONTINUOUS (0x00000000)
164#define U300_TIMER_APP_GPT2S_MODE_ONE_SHOT (0x00000020)
165#define U300_TIMER_APP_GPT2S_IRQ_ENABLED_IND (0x00000040)
166#define U300_TIMER_APP_GPT2S_IRQ_PENDING_IND (0x00000080)
167/* GP2 Timer Current Count Register 32bit (R/-) */
168#define U300_TIMER_APP_GPT2CC (0x00d4)
169/* GP2 Timer Terminal Count Register 32bit (R/W) */
170#define U300_TIMER_APP_GPT2TC (0x00d8)
171/* GP2 Timer Interrupt Enable Register 32bit (-/W) */
172#define U300_TIMER_APP_GPT2IE (0x00dc)
173#define U300_TIMER_APP_GPT2IE_IRQ_DISABLE (0x00000000)
174#define U300_TIMER_APP_GPT2IE_IRQ_ENABLE (0x00000001)
175/* GP2 Timer Interrupt Acknowledge Register 32bit (-/W) */
176#define U300_TIMER_APP_GPT2IA (0x00e0)
177#define U300_TIMER_APP_GPT2IA_IRQ_ACK (0x00000080)
178
179/* Clock request control register - all four timers */
180#define U300_TIMER_APP_CRC (0x100)
181#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001)
182
183static void __iomem *u300_timer_base;
184
185struct u300_clockevent_data {
186 struct clock_event_device cevd;
187 unsigned ticks_per_jiffy;
188};
189
190/*
191 * The u300_set_mode() function is always called first, if we
192 * have oneshot timer active, the oneshot scheduling function
193 * u300_set_next_event() is called immediately after.
194 */
195static void u300_set_mode(enum clock_event_mode mode,
196 struct clock_event_device *evt)
197{
198 struct u300_clockevent_data *cevdata =
199 container_of(evt, struct u300_clockevent_data, cevd);
200
201 switch (mode) {
202 case CLOCK_EVT_MODE_PERIODIC:
203 /* Disable interrupts on GPT1 */
204 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
205 u300_timer_base + U300_TIMER_APP_GPT1IE);
206 /* Disable GP1 while we're reprogramming it. */
207 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
208 u300_timer_base + U300_TIMER_APP_DGPT1);
209 /*
210 * Set the periodic mode to a certain number of ticks per
211 * jiffy.
212 */
213 writel(cevdata->ticks_per_jiffy,
214 u300_timer_base + U300_TIMER_APP_GPT1TC);
215 /*
216 * Set continuous mode, so the timer keeps triggering
217 * interrupts.
218 */
219 writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS,
220 u300_timer_base + U300_TIMER_APP_SGPT1M);
221 /* Enable timer interrupts */
222 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
223 u300_timer_base + U300_TIMER_APP_GPT1IE);
224 /* Then enable the OS timer again */
225 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
226 u300_timer_base + U300_TIMER_APP_EGPT1);
227 break;
228 case CLOCK_EVT_MODE_ONESHOT:
229 /* Just break; here? */
230 /*
231 * The actual event will be programmed by the next event hook,
232 * so we just set a dummy value somewhere at the end of the
233 * universe here.
234 */
235 /* Disable interrupts on GPT1 */
236 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
237 u300_timer_base + U300_TIMER_APP_GPT1IE);
238 /* Disable GP1 while we're reprogramming it. */
239 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
240 u300_timer_base + U300_TIMER_APP_DGPT1);
241 /*
242 * Expire far in the future, u300_set_next_event() will be
243 * called soon...
244 */
245 writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC);
246 /* We run one shot per tick here! */
247 writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
248 u300_timer_base + U300_TIMER_APP_SGPT1M);
249 /* Enable interrupts for this timer */
250 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
251 u300_timer_base + U300_TIMER_APP_GPT1IE);
252 /* Enable timer */
253 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
254 u300_timer_base + U300_TIMER_APP_EGPT1);
255 break;
256 case CLOCK_EVT_MODE_UNUSED:
257 case CLOCK_EVT_MODE_SHUTDOWN:
258 /* Disable interrupts on GP1 */
259 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
260 u300_timer_base + U300_TIMER_APP_GPT1IE);
261 /* Disable GP1 */
262 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
263 u300_timer_base + U300_TIMER_APP_DGPT1);
264 break;
265 case CLOCK_EVT_MODE_RESUME:
266 /* Ignore this call */
267 break;
268 }
269}
270
271/*
272 * The app timer in one shot mode obviously has to be reprogrammed
273 * in EXACTLY this sequence to work properly. Do NOT try to e.g. replace
274 * the interrupt disable + timer disable commands with a reset command,
275 * it will fail miserably. Apparently (and I found this the hard way)
276 * the timer is very sensitive to the instruction order, though you don't
277 * get that impression from the data sheet.
278 */
279static int u300_set_next_event(unsigned long cycles,
280 struct clock_event_device *evt)
281
282{
283 /* Disable interrupts on GPT1 */
284 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
285 u300_timer_base + U300_TIMER_APP_GPT1IE);
286 /* Disable GP1 while we're reprogramming it. */
287 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
288 u300_timer_base + U300_TIMER_APP_DGPT1);
289 /* Reset the General Purpose timer 1. */
290 writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
291 u300_timer_base + U300_TIMER_APP_RGPT1);
292 /* IRQ in n * cycles */
293 writel(cycles, u300_timer_base + U300_TIMER_APP_GPT1TC);
294 /*
295 * We run one shot per tick here! (This is necessary to reconfigure,
296 * the timer will tilt if you don't!)
297 */
298 writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
299 u300_timer_base + U300_TIMER_APP_SGPT1M);
300 /* Enable timer interrupts */
301 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
302 u300_timer_base + U300_TIMER_APP_GPT1IE);
303 /* Then enable the OS timer again */
304 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
305 u300_timer_base + U300_TIMER_APP_EGPT1);
306 return 0;
307}
308
309static struct u300_clockevent_data u300_clockevent_data = {
310 /* Use general purpose timer 1 as clock event */
311 .cevd = {
312 .name = "GPT1",
313 /* Reasonably fast and accurate clock event */
314 .rating = 300,
315 .features = CLOCK_EVT_FEAT_PERIODIC |
316 CLOCK_EVT_FEAT_ONESHOT,
317 .set_next_event = u300_set_next_event,
318 .set_mode = u300_set_mode,
319 },
320};
321
322/* Clock event timer interrupt handler */
323static irqreturn_t u300_timer_interrupt(int irq, void *dev_id)
324{
325 struct clock_event_device *evt = &u300_clockevent_data.cevd;
326 /* ACK/Clear timer IRQ for the APP GPT1 Timer */
327
328 writel(U300_TIMER_APP_GPT1IA_IRQ_ACK,
329 u300_timer_base + U300_TIMER_APP_GPT1IA);
330 evt->event_handler(evt);
331 return IRQ_HANDLED;
332}
333
334static struct irqaction u300_timer_irq = {
335 .name = "U300 Timer Tick",
336 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
337 .handler = u300_timer_interrupt,
338};
339
340/*
341 * Override the global weak sched_clock symbol with this
342 * local implementation which uses the clocksource to get some
343 * better resolution when scheduling the kernel. We accept that
344 * this wraps around for now, since it is just a relative time
345 * stamp. (Inspired by OMAP implementation.)
346 */
347
348static u64 notrace u300_read_sched_clock(void)
349{
350 return readl(u300_timer_base + U300_TIMER_APP_GPT2CC);
351}
352
353static unsigned long u300_read_current_timer(void)
354{
355 return readl(u300_timer_base + U300_TIMER_APP_GPT2CC);
356}
357
358static struct delay_timer u300_delay_timer;
359
360/*
361 * This sets up the system timers, clock source and clock event.
362 */
363static void __init u300_timer_init_of(struct device_node *np)
364{
365 unsigned int irq;
366 struct clk *clk;
367 unsigned long rate;
368
369 u300_timer_base = of_iomap(np, 0);
370 if (!u300_timer_base)
371 panic("could not ioremap system timer\n");
372
373 /* Get the IRQ for the GP1 timer */
374 irq = irq_of_parse_and_map(np, 2);
375 if (!irq)
376 panic("no IRQ for system timer\n");
377
378 pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq);
379
380 /* Clock the interrupt controller */
381 clk = of_clk_get(np, 0);
382 BUG_ON(IS_ERR(clk));
383 clk_prepare_enable(clk);
384 rate = clk_get_rate(clk);
385
386 u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
387
388 sched_clock_register(u300_read_sched_clock, 32, rate);
389
390 u300_delay_timer.read_current_timer = &u300_read_current_timer;
391 u300_delay_timer.freq = rate;
392 register_current_timer_delay(&u300_delay_timer);
393
394 /*
395 * Disable the "OS" and "DD" timers - these are designed for Symbian!
396 * Example usage in cnh1601578 cpu subsystem pd_timer_app.c
397 */
398 writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE,
399 u300_timer_base + U300_TIMER_APP_CRC);
400 writel(U300_TIMER_APP_ROST_TIMER_RESET,
401 u300_timer_base + U300_TIMER_APP_ROST);
402 writel(U300_TIMER_APP_DOST_TIMER_DISABLE,
403 u300_timer_base + U300_TIMER_APP_DOST);
404 writel(U300_TIMER_APP_RDDT_TIMER_RESET,
405 u300_timer_base + U300_TIMER_APP_RDDT);
406 writel(U300_TIMER_APP_DDDT_TIMER_DISABLE,
407 u300_timer_base + U300_TIMER_APP_DDDT);
408
409 /* Reset the General Purpose timer 1. */
410 writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
411 u300_timer_base + U300_TIMER_APP_RGPT1);
412
413 /* Set up the IRQ handler */
414 setup_irq(irq, &u300_timer_irq);
415
416 /* Reset the General Purpose timer 2 */
417 writel(U300_TIMER_APP_RGPT2_TIMER_RESET,
418 u300_timer_base + U300_TIMER_APP_RGPT2);
419 /* Set this timer to run around forever */
420 writel(0xFFFFFFFFU, u300_timer_base + U300_TIMER_APP_GPT2TC);
421 /* Set continuous mode so it wraps around */
422 writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS,
423 u300_timer_base + U300_TIMER_APP_SGPT2M);
424 /* Disable timer interrupts */
425 writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE,
426 u300_timer_base + U300_TIMER_APP_GPT2IE);
427 /* Then enable the GP2 timer to use as a free running us counter */
428 writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
429 u300_timer_base + U300_TIMER_APP_EGPT2);
430
431 /* Use general purpose timer 2 as clock source */
432 if (clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC,
433 "GPT2", rate, 300, 32, clocksource_mmio_readl_up))
434 pr_err("timer: failed to initialize U300 clock source\n");
435
436 /* Configure and register the clockevent */
437 clockevents_config_and_register(&u300_clockevent_data.cevd, rate,
438 1, 0xffffffff);
439
440 /*
441 * TODO: init and register the rest of the timers too, they can be
442 * used by hrtimers!
443 */
444}
445
446CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer",
447 u300_timer_init_of);