diff options
Diffstat (limited to 'arch/arm/mach-omap2/timer-gp.c')
-rw-r--r-- | arch/arm/mach-omap2/timer-gp.c | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index cf2ec85b95fa..2b8cb701c89f 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c | |||
@@ -262,20 +262,22 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
262 | * sync counter. See clocksource setup in plat-omap/counter_32k.c | 262 | * sync counter. See clocksource setup in plat-omap/counter_32k.c |
263 | */ | 263 | */ |
264 | 264 | ||
265 | static void __init omap2_gp_clocksource_init(void) | 265 | static void __init omap2_gp_clocksource_init(int unused, const char *dummy) |
266 | { | 266 | { |
267 | omap_init_clocksource_32k(); | 267 | omap_init_clocksource_32k(); |
268 | } | 268 | } |
269 | 269 | ||
270 | #else | 270 | #else |
271 | |||
272 | static struct omap_dm_timer clksrc; | ||
273 | |||
271 | /* | 274 | /* |
272 | * clocksource | 275 | * clocksource |
273 | */ | 276 | */ |
274 | static DEFINE_CLOCK_DATA(cd); | 277 | static DEFINE_CLOCK_DATA(cd); |
275 | static struct omap_dm_timer *gpt_clocksource; | ||
276 | static cycle_t clocksource_read_cycles(struct clocksource *cs) | 278 | static cycle_t clocksource_read_cycles(struct clocksource *cs) |
277 | { | 279 | { |
278 | return (cycle_t)omap_dm_timer_read_counter(gpt_clocksource); | 280 | return (cycle_t)__omap_dm_timer_read_counter(clksrc.io_base, 1); |
279 | } | 281 | } |
280 | 282 | ||
281 | static struct clocksource clocksource_gpt = { | 283 | static struct clocksource clocksource_gpt = { |
@@ -290,43 +292,48 @@ static void notrace dmtimer_update_sched_clock(void) | |||
290 | { | 292 | { |
291 | u32 cyc; | 293 | u32 cyc; |
292 | 294 | ||
293 | cyc = omap_dm_timer_read_counter(gpt_clocksource); | 295 | cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1); |
294 | 296 | ||
295 | update_sched_clock(&cd, cyc, (u32)~0); | 297 | update_sched_clock(&cd, cyc, (u32)~0); |
296 | } | 298 | } |
297 | 299 | ||
298 | /* Setup free-running counter for clocksource */ | 300 | unsigned long long notrace sched_clock(void) |
299 | static void __init omap2_gp_clocksource_init(void) | ||
300 | { | 301 | { |
301 | static struct omap_dm_timer *gpt; | 302 | u32 cyc = 0; |
302 | u32 tick_rate; | ||
303 | static char err1[] __initdata = KERN_ERR | ||
304 | "%s: failed to request dm-timer\n"; | ||
305 | static char err2[] __initdata = KERN_ERR | ||
306 | "%s: can't register clocksource!\n"; | ||
307 | 303 | ||
308 | gpt = omap_dm_timer_request(); | 304 | if (clksrc.reserved) |
309 | if (!gpt) | 305 | cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1); |
310 | printk(err1, clocksource_gpt.name); | ||
311 | gpt_clocksource = gpt; | ||
312 | 306 | ||
313 | omap_dm_timer_set_source(gpt, OMAP_TIMER_SRC_SYS_CLK); | 307 | return cyc_to_sched_clock(&cd, cyc, (u32)~0); |
314 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt)); | 308 | } |
309 | |||
310 | /* Setup free-running counter for clocksource */ | ||
311 | static void __init omap2_gp_clocksource_init(int gptimer_id, | ||
312 | const char *fck_source) | ||
313 | { | ||
314 | int res; | ||
315 | |||
316 | res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source); | ||
317 | BUG_ON(res); | ||
315 | 318 | ||
316 | omap_dm_timer_set_load_start(gpt, 1, 0); | 319 | pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", |
320 | gptimer_id, clksrc.rate); | ||
317 | 321 | ||
318 | init_sched_clock(&cd, dmtimer_update_sched_clock, 32, tick_rate); | 322 | __omap_dm_timer_load_start(clksrc.io_base, OMAP_TIMER_CTRL_ST, 0, 1); |
323 | init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate); | ||
319 | 324 | ||
320 | if (clocksource_register_hz(&clocksource_gpt, tick_rate)) | 325 | if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) |
321 | printk(err2, clocksource_gpt.name); | 326 | pr_err("Could not register clocksource %s\n", |
327 | clocksource_gpt.name); | ||
322 | } | 328 | } |
323 | #endif | 329 | #endif |
324 | 330 | ||
325 | #define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src) \ | 331 | #define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \ |
332 | clksrc_nr, clksrc_src) \ | ||
326 | static void __init omap##name##_timer_init(void) \ | 333 | static void __init omap##name##_timer_init(void) \ |
327 | { \ | 334 | { \ |
328 | omap2_gp_clockevent_init((clkev_nr), clkev_src); \ | 335 | omap2_gp_clockevent_init((clkev_nr), clkev_src); \ |
329 | omap2_gp_clocksource_init(); \ | 336 | omap2_gp_clocksource_init((clksrc_nr), clksrc_src); \ |
330 | } | 337 | } |
331 | 338 | ||
332 | #define OMAP_SYS_TIMER(name) \ | 339 | #define OMAP_SYS_TIMER(name) \ |
@@ -335,14 +342,15 @@ struct sys_timer omap##name##_timer = { \ | |||
335 | }; | 342 | }; |
336 | 343 | ||
337 | #ifdef CONFIG_ARCH_OMAP2 | 344 | #ifdef CONFIG_ARCH_OMAP2 |
338 | OMAP_SYS_TIMER_INIT(2, 1, OMAP2_CLKEV_SOURCE) | 345 | OMAP_SYS_TIMER_INIT(2, 1, OMAP2_CLKEV_SOURCE, 2, OMAP2_MPU_SOURCE) |
339 | OMAP_SYS_TIMER(2) | 346 | OMAP_SYS_TIMER(2) |
340 | #endif | 347 | #endif |
341 | 348 | ||
342 | #ifdef CONFIG_ARCH_OMAP3 | 349 | #ifdef CONFIG_ARCH_OMAP3 |
343 | OMAP_SYS_TIMER_INIT(3, 1, OMAP3_CLKEV_SOURCE) | 350 | OMAP_SYS_TIMER_INIT(3, 1, OMAP3_CLKEV_SOURCE, 2, OMAP3_MPU_SOURCE) |
344 | OMAP_SYS_TIMER(3) | 351 | OMAP_SYS_TIMER(3) |
345 | OMAP_SYS_TIMER_INIT(3_secure, OMAP3_SECURE_TIMER, OMAP3_CLKEV_SOURCE) | 352 | OMAP_SYS_TIMER_INIT(3_secure, OMAP3_SECURE_TIMER, OMAP3_CLKEV_SOURCE, |
353 | 2, OMAP3_MPU_SOURCE) | ||
346 | OMAP_SYS_TIMER(3_secure) | 354 | OMAP_SYS_TIMER(3_secure) |
347 | #endif | 355 | #endif |
348 | 356 | ||
@@ -354,7 +362,7 @@ static void __init omap4_timer_init(void) | |||
354 | BUG_ON(!twd_base); | 362 | BUG_ON(!twd_base); |
355 | #endif | 363 | #endif |
356 | omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE); | 364 | omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE); |
357 | omap2_gp_clocksource_init(); | 365 | omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE); |
358 | } | 366 | } |
359 | OMAP_SYS_TIMER(4) | 367 | OMAP_SYS_TIMER(4) |
360 | #endif | 368 | #endif |