time.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * linux/arch/arm/mach-imx/time.c
  3. *
  4. * Copyright (C) 2000-2001 Deep Blue Solutions
  5. * Copyright (C) 2002 Shane Nay (shane@minirl.com)
  6. * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.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. #include <linux/kernel.h>
  13. #include <linux/sched.h>
  14. #include <linux/init.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/irq.h>
  17. #include <linux/time.h>
  18. #include <linux/clocksource.h>
  19. #include <linux/clockchips.h>
  20. #include <linux/clk.h>
  21. #include <linux/io.h>
  22. #include <mach/hardware.h>
  23. #include <asm/leds.h>
  24. #include <asm/irq.h>
  25. #include <asm/mach/time.h>
  26. /* Use timer 1 as system timer */
  27. #define TIMER_BASE IMX_TIM1_BASE
  28. static struct clock_event_device clockevent_imx;
  29. static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
  30. /*
  31. * IRQ handler for the timer
  32. */
  33. static irqreturn_t
  34. imx_timer_interrupt(int irq, void *dev_id)
  35. {
  36. struct clock_event_device *evt = &clockevent_imx;
  37. uint32_t tstat;
  38. irqreturn_t ret = IRQ_NONE;
  39. /* clear the interrupt */
  40. tstat = IMX_TSTAT(TIMER_BASE);
  41. IMX_TSTAT(TIMER_BASE) = 0;
  42. if (tstat & TSTAT_COMP) {
  43. evt->event_handler(evt);
  44. ret = IRQ_HANDLED;
  45. }
  46. return ret;
  47. }
  48. static struct irqaction imx_timer_irq = {
  49. .name = "i.MX Timer Tick",
  50. .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
  51. .handler = imx_timer_interrupt,
  52. };
  53. /*
  54. * Set up timer hardware into expected mode and state.
  55. */
  56. static void __init imx_timer_hardware_init(void)
  57. {
  58. /*
  59. * Initialise to a known state (all timers off, and timing reset)
  60. */
  61. IMX_TCTL(TIMER_BASE) = 0;
  62. IMX_TPRER(TIMER_BASE) = 0;
  63. IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_TEN;
  64. }
  65. cycle_t imx_get_cycles(struct clocksource *cs)
  66. {
  67. return IMX_TCN(TIMER_BASE);
  68. }
  69. static struct clocksource clocksource_imx = {
  70. .name = "imx_timer1",
  71. .rating = 200,
  72. .read = imx_get_cycles,
  73. .mask = 0xFFFFFFFF,
  74. .shift = 20,
  75. .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  76. };
  77. static int __init imx_clocksource_init(unsigned long rate)
  78. {
  79. clocksource_imx.mult =
  80. clocksource_hz2mult(rate, clocksource_imx.shift);
  81. clocksource_register(&clocksource_imx);
  82. return 0;
  83. }
  84. static int imx_set_next_event(unsigned long evt,
  85. struct clock_event_device *unused)
  86. {
  87. unsigned long tcmp;
  88. tcmp = IMX_TCN(TIMER_BASE) + evt;
  89. IMX_TCMP(TIMER_BASE) = tcmp;
  90. return (int32_t)(tcmp - IMX_TCN(TIMER_BASE)) < 0 ? -ETIME : 0;
  91. }
  92. #ifdef DEBUG
  93. static const char *clock_event_mode_label[]={
  94. [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
  95. [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
  96. [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
  97. [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
  98. };
  99. #endif /*DEBUG*/
  100. static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
  101. {
  102. unsigned long flags;
  103. /*
  104. * The timer interrupt generation is disabled at least
  105. * for enough time to call imx_set_next_event()
  106. */
  107. local_irq_save(flags);
  108. /* Disable interrupt in GPT module */
  109. IMX_TCTL(TIMER_BASE) &= ~TCTL_IRQEN;
  110. if (mode != clockevent_mode) {
  111. /* Set event time into far-far future */
  112. IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) - 3;
  113. /* Clear pending interrupt */
  114. IMX_TSTAT(TIMER_BASE) &= ~TSTAT_COMP;
  115. }
  116. #ifdef DEBUG
  117. printk(KERN_INFO "imx_set_mode: changing mode from %s to %s\n",
  118. clock_event_mode_label[clockevent_mode], clock_event_mode_label[mode]);
  119. #endif /*DEBUG*/
  120. /* Remember timer mode */
  121. clockevent_mode = mode;
  122. local_irq_restore(flags);
  123. switch (mode) {
  124. case CLOCK_EVT_MODE_PERIODIC:
  125. printk(KERN_ERR "imx_set_mode: Periodic mode is not supported for i.MX\n");
  126. break;
  127. case CLOCK_EVT_MODE_ONESHOT:
  128. /*
  129. * Do not put overhead of interrupt enable/disable into
  130. * imx_set_next_event(), the core has about 4 minutes
  131. * to call imx_set_next_event() or shutdown clock after
  132. * mode switching
  133. */
  134. local_irq_save(flags);
  135. IMX_TCTL(TIMER_BASE) |= TCTL_IRQEN;
  136. local_irq_restore(flags);
  137. break;
  138. case CLOCK_EVT_MODE_SHUTDOWN:
  139. case CLOCK_EVT_MODE_UNUSED:
  140. case CLOCK_EVT_MODE_RESUME:
  141. /* Left event sources disabled, no more interrupts appears */
  142. break;
  143. }
  144. }
  145. static struct clock_event_device clockevent_imx = {
  146. .name = "imx_timer1",
  147. .features = CLOCK_EVT_FEAT_ONESHOT,
  148. .shift = 32,
  149. .set_mode = imx_set_mode,
  150. .set_next_event = imx_set_next_event,
  151. .rating = 200,
  152. };
  153. static int __init imx_clockevent_init(unsigned long rate)
  154. {
  155. clockevent_imx.mult = div_sc(rate, NSEC_PER_SEC,
  156. clockevent_imx.shift);
  157. clockevent_imx.max_delta_ns =
  158. clockevent_delta2ns(0xfffffffe, &clockevent_imx);
  159. clockevent_imx.min_delta_ns =
  160. clockevent_delta2ns(0xf, &clockevent_imx);
  161. clockevent_imx.cpumask = cpumask_of(0);
  162. clockevents_register_device(&clockevent_imx);
  163. return 0;
  164. }
  165. extern int imx_clocks_init(void);
  166. static void __init imx_timer_init(void)
  167. {
  168. struct clk *clk;
  169. unsigned long rate;
  170. imx_clocks_init();
  171. clk = clk_get(NULL, "perclk1");
  172. clk_enable(clk);
  173. rate = clk_get_rate(clk);
  174. imx_timer_hardware_init();
  175. imx_clocksource_init(rate);
  176. imx_clockevent_init(rate);
  177. /*
  178. * Make irqs happen for the system timer
  179. */
  180. setup_irq(TIM1_INT, &imx_timer_irq);
  181. }
  182. struct sys_timer imx_timer = {
  183. .init = imx_timer_init,
  184. };