timer.c (2bcb132c693566bcb8208cc7ce66b72a4f852ecf) timer.c (fa6d79d27614223d82418023b7f5300f1a1530d3)
1/*
2 * linux/arch/arm/mach-omap2/timer.c
3 *
4 * OMAP2 GP timer support.
5 *
6 * Copyright (C) 2009 Nokia Corporation
7 *
8 * Update to use new clocksource/clockevent layers

--- 55 unchanged lines hidden (view full) ---

64#define OMAP3_SECURE_TIMER 12
65#else
66#define OMAP2_CLKEV_SOURCE OMAP2_MPU_SOURCE
67#define OMAP3_CLKEV_SOURCE OMAP3_MPU_SOURCE
68#define OMAP4_CLKEV_SOURCE OMAP4_MPU_SOURCE
69#define OMAP3_SECURE_TIMER 1
70#endif
71
1/*
2 * linux/arch/arm/mach-omap2/timer.c
3 *
4 * OMAP2 GP timer support.
5 *
6 * Copyright (C) 2009 Nokia Corporation
7 *
8 * Update to use new clocksource/clockevent layers

--- 55 unchanged lines hidden (view full) ---

64#define OMAP3_SECURE_TIMER 12
65#else
66#define OMAP2_CLKEV_SOURCE OMAP2_MPU_SOURCE
67#define OMAP3_CLKEV_SOURCE OMAP3_MPU_SOURCE
68#define OMAP4_CLKEV_SOURCE OMAP4_MPU_SOURCE
69#define OMAP3_SECURE_TIMER 1
70#endif
71
72#define REALTIME_COUNTER_BASE 0x48243200
73#define INCREMENTER_NUMERATOR_OFFSET 0x10
74#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
75#define NUMERATOR_DENUMERATOR_MASK 0xfffff000
76
72/* Clockevent code */
73
74static struct omap_dm_timer clkev;
75static struct clock_event_device clockevent_gpt;
76
77static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
78{
79 struct clock_event_device *evt = &clockevent_gpt;

--- 261 unchanged lines hidden (view full) ---

341 */
342 if (use_gptimer_clksrc == true)
343 omap2_gptimer_clocksource_init(gptimer_id, fck_source);
344 else if (omap2_sync32k_clocksource_init())
345 /* Fall back to gp-timer code */
346 omap2_gptimer_clocksource_init(gptimer_id, fck_source);
347}
348
77/* Clockevent code */
78
79static struct omap_dm_timer clkev;
80static struct clock_event_device clockevent_gpt;
81
82static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
83{
84 struct clock_event_device *evt = &clockevent_gpt;

--- 261 unchanged lines hidden (view full) ---

346 */
347 if (use_gptimer_clksrc == true)
348 omap2_gptimer_clocksource_init(gptimer_id, fck_source);
349 else if (omap2_sync32k_clocksource_init())
350 /* Fall back to gp-timer code */
351 omap2_gptimer_clocksource_init(gptimer_id, fck_source);
352}
353
354#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
355/*
356 * The realtime counter also called master counter, is a free-running
357 * counter, which is related to real time. It produces the count used
358 * by the CPU local timer peripherals in the MPU cluster. The timer counts
359 * at a rate of 6.144 MHz. Because the device operates on different clocks
360 * in different power modes, the master counter shifts operation between
361 * clocks, adjusting the increment per clock in hardware accordingly to
362 * maintain a constant count rate.
363 */
364static void __init realtime_counter_init(void)
365{
366 void __iomem *base;
367 static struct clk *sys_clk;
368 unsigned long rate;
369 unsigned int reg, num, den;
370
371 base = ioremap(REALTIME_COUNTER_BASE, SZ_32);
372 if (!base) {
373 pr_err("%s: ioremap failed\n", __func__);
374 return;
375 }
376 sys_clk = clk_get(NULL, "sys_clkin_ck");
377 if (!sys_clk) {
378 pr_err("%s: failed to get system clock handle\n", __func__);
379 iounmap(base);
380 return;
381 }
382
383 rate = clk_get_rate(sys_clk);
384 /* Numerator/denumerator values refer TRM Realtime Counter section */
385 switch (rate) {
386 case 1200000:
387 num = 64;
388 den = 125;
389 break;
390 case 1300000:
391 num = 768;
392 den = 1625;
393 break;
394 case 19200000:
395 num = 8;
396 den = 25;
397 break;
398 case 2600000:
399 num = 384;
400 den = 1625;
401 break;
402 case 2700000:
403 num = 256;
404 den = 1125;
405 break;
406 case 38400000:
407 default:
408 /* Program it for 38.4 MHz */
409 num = 4;
410 den = 25;
411 break;
412 }
413
414 /* Program numerator and denumerator registers */
415 reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) &
416 NUMERATOR_DENUMERATOR_MASK;
417 reg |= num;
418 __raw_writel(reg, base + INCREMENTER_NUMERATOR_OFFSET);
419
420 reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) &
421 NUMERATOR_DENUMERATOR_MASK;
422 reg |= den;
423 __raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
424
425 iounmap(base);
426}
427#else
428static inline void __init realtime_counter_init(void)
429{}
430#endif
431
349#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \
350 clksrc_nr, clksrc_src) \
351static void __init omap##name##_timer_init(void) \
352{ \
353 omap2_gp_clockevent_init((clkev_nr), clkev_src); \
354 omap2_clocksource_init((clksrc_nr), clksrc_src); \
355}
356

--- 41 unchanged lines hidden (view full) ---

398 pr_err("twd_local_timer_register failed %d\n", err);
399 }
400#endif
401}
402OMAP_SYS_TIMER(4)
403#endif
404
405#ifdef CONFIG_SOC_OMAP5
432#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \
433 clksrc_nr, clksrc_src) \
434static void __init omap##name##_timer_init(void) \
435{ \
436 omap2_gp_clockevent_init((clkev_nr), clkev_src); \
437 omap2_clocksource_init((clksrc_nr), clksrc_src); \
438}
439

--- 41 unchanged lines hidden (view full) ---

481 pr_err("twd_local_timer_register failed %d\n", err);
482 }
483#endif
484}
485OMAP_SYS_TIMER(4)
486#endif
487
488#ifdef CONFIG_SOC_OMAP5
406OMAP_SYS_TIMER_INIT(5, 1, OMAP4_CLKEV_SOURCE, 2, OMAP4_MPU_SOURCE)
489static void __init omap5_timer_init(void)
490{
491 omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
492 omap2_clocksource_init(2, OMAP4_MPU_SOURCE);
493 realtime_counter_init();
494}
407OMAP_SYS_TIMER(5)
408#endif
409
410/**
411 * omap_timer_init - build and register timer device with an
412 * associated timer hwmod
413 * @oh: timer hwmod pointer to be used to build timer device
414 * @user: parameter that can be passed from calling hwmod API

--- 103 unchanged lines hidden ---
495OMAP_SYS_TIMER(5)
496#endif
497
498/**
499 * omap_timer_init - build and register timer device with an
500 * associated timer hwmod
501 * @oh: timer hwmod pointer to be used to build timer device
502 * @user: parameter that can be passed from calling hwmod API

--- 103 unchanged lines hidden ---