aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r--arch/arm/mach-omap2/timer.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index a135d28e202c..63229c5287e6 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -222,10 +222,24 @@ void __init omap_dmtimer_init(void)
222 } 222 }
223} 223}
224 224
225/**
226 * omap_dm_timer_get_errata - get errata flags for a timer
227 *
228 * Get the timer errata flags that are specific to the OMAP device being used.
229 */
230u32 __init omap_dm_timer_get_errata(void)
231{
232 if (cpu_is_omap24xx())
233 return 0;
234
235 return OMAP_TIMER_ERRATA_I103_I767;
236}
237
225static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, 238static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
226 int gptimer_id, 239 int gptimer_id,
227 const char *fck_source, 240 const char *fck_source,
228 const char *property) 241 const char *property,
242 int posted)
229{ 243{
230 char name[10]; /* 10 = sizeof("gptXX_Xck0") */ 244 char name[10]; /* 10 = sizeof("gptXX_Xck0") */
231 const char *oh_name; 245 const char *oh_name;
@@ -311,10 +325,15 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
311 } 325 }
312 __omap_dm_timer_init_regs(timer); 326 __omap_dm_timer_init_regs(timer);
313 __omap_dm_timer_reset(timer, 1, 1); 327 __omap_dm_timer_reset(timer, 1, 1);
314 timer->posted = 1;
315 328
316 timer->rate = clk_get_rate(timer->fclk); 329 if (posted)
330 __omap_dm_timer_enable_posted(timer);
331
332 /* Check that the intended posted configuration matches the actual */
333 if (posted != timer->posted)
334 return -EINVAL;
317 335
336 timer->rate = clk_get_rate(timer->fclk);
318 timer->reserved = 1; 337 timer->reserved = 1;
319 338
320 return res; 339 return res;
@@ -326,7 +345,17 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
326{ 345{
327 int res; 346 int res;
328 347
329 res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property); 348 clkev.errata = omap_dm_timer_get_errata();
349
350 /*
351 * For clock-event timers we never read the timer counter and
352 * so we are not impacted by errata i103 and i767. Therefore,
353 * we can safely ignore this errata for clock-event timers.
354 */
355 __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767);
356
357 res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property,
358 OMAP_TIMER_POSTED);
330 BUG_ON(res); 359 BUG_ON(res);
331 360
332 omap2_gp_timer_irq.dev_id = &clkev; 361 omap2_gp_timer_irq.dev_id = &clkev;
@@ -360,7 +389,7 @@ static bool use_gptimer_clksrc;
360static cycle_t clocksource_read_cycles(struct clocksource *cs) 389static cycle_t clocksource_read_cycles(struct clocksource *cs)
361{ 390{
362 return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 391 return (cycle_t)__omap_dm_timer_read_counter(&clksrc,
363 OMAP_TIMER_POSTED); 392 OMAP_TIMER_NONPOSTED);
364} 393}
365 394
366static struct clocksource clocksource_gpt = { 395static struct clocksource clocksource_gpt = {
@@ -375,7 +404,7 @@ static u32 notrace dmtimer_read_sched_clock(void)
375{ 404{
376 if (clksrc.reserved) 405 if (clksrc.reserved)
377 return __omap_dm_timer_read_counter(&clksrc, 406 return __omap_dm_timer_read_counter(&clksrc,
378 OMAP_TIMER_POSTED); 407 OMAP_TIMER_NONPOSTED);
379 408
380 return 0; 409 return 0;
381} 410}
@@ -453,12 +482,15 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
453{ 482{
454 int res; 483 int res;
455 484
456 res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL); 485 clksrc.errata = omap_dm_timer_get_errata();
486
487 res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL,
488 OMAP_TIMER_NONPOSTED);
457 BUG_ON(res); 489 BUG_ON(res);
458 490
459 __omap_dm_timer_load_start(&clksrc, 491 __omap_dm_timer_load_start(&clksrc,
460 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 492 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0,
461 OMAP_TIMER_POSTED); 493 OMAP_TIMER_NONPOSTED);
462 setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate); 494 setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate);
463 495
464 if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) 496 if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
@@ -696,6 +728,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
696 if (timer_dev_attr) 728 if (timer_dev_attr)
697 pdata->timer_capability = timer_dev_attr->timer_capability; 729 pdata->timer_capability = timer_dev_attr->timer_capability;
698 730
731 pdata->timer_errata = omap_dm_timer_get_errata();
699 pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; 732 pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
700 733
701 pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata), 734 pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata),