timer.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * This file contains driver for the Xilinx PS Timer Counter IP.
  3. *
  4. * Copyright (C) 2011 Xilinx
  5. *
  6. * based on arch/mips/kernel/time.c timer driver
  7. *
  8. * This software is licensed under the terms of the GNU General Public
  9. * License version 2, as published by the Free Software Foundation, and
  10. * may be copied, distributed, and modified under those terms.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. */
  17. #include <linux/kernel.h>
  18. #include <linux/init.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/irq.h>
  21. #include <linux/types.h>
  22. #include <linux/clocksource.h>
  23. #include <linux/clockchips.h>
  24. #include <linux/io.h>
  25. #include <asm/mach/time.h>
  26. #include <mach/zynq_soc.h>
  27. #include "common.h"
  28. #define IRQ_TIMERCOUNTER0 42
  29. /*
  30. * This driver configures the 2 16-bit count-up timers as follows:
  31. *
  32. * T1: Timer 1, clocksource for generic timekeeping
  33. * T2: Timer 2, clockevent source for hrtimers
  34. * T3: Timer 3, <unused>
  35. *
  36. * The input frequency to the timer module for emulation is 2.5MHz which is
  37. * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32,
  38. * the timers are clocked at 78.125KHz (12.8 us resolution).
  39. *
  40. * The input frequency to the timer module in silicon will be 200MHz. With the
  41. * pre-scaler of 32, the timers are clocked at 6.25MHz (160ns resolution).
  42. */
  43. #define XTTCPSS_CLOCKSOURCE 0 /* Timer 1 as a generic timekeeping */
  44. #define XTTCPSS_CLOCKEVENT 1 /* Timer 2 as a clock event */
  45. #define XTTCPSS_TIMER_BASE TTC0_BASE
  46. #define XTTCPCC_EVENT_TIMER_IRQ (IRQ_TIMERCOUNTER0 + 1)
  47. /*
  48. * Timer Register Offset Definitions of Timer 1, Increment base address by 4
  49. * and use same offsets for Timer 2
  50. */
  51. #define XTTCPSS_CLK_CNTRL_OFFSET 0x00 /* Clock Control Reg, RW */
  52. #define XTTCPSS_CNT_CNTRL_OFFSET 0x0C /* Counter Control Reg, RW */
  53. #define XTTCPSS_COUNT_VAL_OFFSET 0x18 /* Counter Value Reg, RO */
  54. #define XTTCPSS_INTR_VAL_OFFSET 0x24 /* Interval Count Reg, RW */
  55. #define XTTCPSS_MATCH_1_OFFSET 0x30 /* Match 1 Value Reg, RW */
  56. #define XTTCPSS_MATCH_2_OFFSET 0x3C /* Match 2 Value Reg, RW */
  57. #define XTTCPSS_MATCH_3_OFFSET 0x48 /* Match 3 Value Reg, RW */
  58. #define XTTCPSS_ISR_OFFSET 0x54 /* Interrupt Status Reg, RO */
  59. #define XTTCPSS_IER_OFFSET 0x60 /* Interrupt Enable Reg, RW */
  60. #define XTTCPSS_CNT_CNTRL_DISABLE_MASK 0x1
  61. /* Setup the timers to use pre-scaling */
  62. #define TIMER_RATE (PERIPHERAL_CLOCK_RATE / 32)
  63. /**
  64. * struct xttcpss_timer - This definition defines local timer structure
  65. *
  66. * @base_addr: Base address of timer
  67. **/
  68. struct xttcpss_timer {
  69. void __iomem *base_addr;
  70. };
  71. static struct xttcpss_timer timers[2];
  72. static struct clock_event_device xttcpss_clockevent;
  73. /**
  74. * xttcpss_set_interval - Set the timer interval value
  75. *
  76. * @timer: Pointer to the timer instance
  77. * @cycles: Timer interval ticks
  78. **/
  79. static void xttcpss_set_interval(struct xttcpss_timer *timer,
  80. unsigned long cycles)
  81. {
  82. u32 ctrl_reg;
  83. /* Disable the counter, set the counter value and re-enable counter */
  84. ctrl_reg = __raw_readl(timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
  85. ctrl_reg |= XTTCPSS_CNT_CNTRL_DISABLE_MASK;
  86. __raw_writel(ctrl_reg, timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
  87. __raw_writel(cycles, timer->base_addr + XTTCPSS_INTR_VAL_OFFSET);
  88. /* Reset the counter (0x10) so that it starts from 0, one-shot
  89. mode makes this needed for timing to be right. */
  90. ctrl_reg |= 0x10;
  91. ctrl_reg &= ~XTTCPSS_CNT_CNTRL_DISABLE_MASK;
  92. __raw_writel(ctrl_reg, timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
  93. }
  94. /**
  95. * xttcpss_clock_event_interrupt - Clock event timer interrupt handler
  96. *
  97. * @irq: IRQ number of the Timer
  98. * @dev_id: void pointer to the xttcpss_timer instance
  99. *
  100. * returns: Always IRQ_HANDLED - success
  101. **/
  102. static irqreturn_t xttcpss_clock_event_interrupt(int irq, void *dev_id)
  103. {
  104. struct clock_event_device *evt = &xttcpss_clockevent;
  105. struct xttcpss_timer *timer = dev_id;
  106. /* Acknowledge the interrupt and call event handler */
  107. __raw_writel(__raw_readl(timer->base_addr + XTTCPSS_ISR_OFFSET),
  108. timer->base_addr + XTTCPSS_ISR_OFFSET);
  109. evt->event_handler(evt);
  110. return IRQ_HANDLED;
  111. }
  112. static struct irqaction event_timer_irq = {
  113. .name = "xttcpss clockevent",
  114. .flags = IRQF_DISABLED | IRQF_TIMER,
  115. .handler = xttcpss_clock_event_interrupt,
  116. };
  117. /**
  118. * xttcpss_timer_hardware_init - Initialize the timer hardware
  119. *
  120. * Initialize the hardware to start the clock source, get the clock
  121. * event timer ready to use, and hook up the interrupt.
  122. **/
  123. static void __init xttcpss_timer_hardware_init(void)
  124. {
  125. /* Setup the clock source counter to be an incrementing counter
  126. * with no interrupt and it rolls over at 0xFFFF. Pre-scale
  127. it by 32 also. Let it start running now.
  128. */
  129. timers[XTTCPSS_CLOCKSOURCE].base_addr = XTTCPSS_TIMER_BASE;
  130. __raw_writel(0x0, timers[XTTCPSS_CLOCKSOURCE].base_addr +
  131. XTTCPSS_IER_OFFSET);
  132. __raw_writel(0x9, timers[XTTCPSS_CLOCKSOURCE].base_addr +
  133. XTTCPSS_CLK_CNTRL_OFFSET);
  134. __raw_writel(0x10, timers[XTTCPSS_CLOCKSOURCE].base_addr +
  135. XTTCPSS_CNT_CNTRL_OFFSET);
  136. /* Setup the clock event timer to be an interval timer which
  137. * is prescaled by 32 using the interval interrupt. Leave it
  138. * disabled for now.
  139. */
  140. timers[XTTCPSS_CLOCKEVENT].base_addr = XTTCPSS_TIMER_BASE + 4;
  141. __raw_writel(0x23, timers[XTTCPSS_CLOCKEVENT].base_addr +
  142. XTTCPSS_CNT_CNTRL_OFFSET);
  143. __raw_writel(0x9, timers[XTTCPSS_CLOCKEVENT].base_addr +
  144. XTTCPSS_CLK_CNTRL_OFFSET);
  145. __raw_writel(0x1, timers[XTTCPSS_CLOCKEVENT].base_addr +
  146. XTTCPSS_IER_OFFSET);
  147. /* Setup IRQ the clock event timer */
  148. event_timer_irq.dev_id = &timers[XTTCPSS_CLOCKEVENT];
  149. setup_irq(XTTCPCC_EVENT_TIMER_IRQ, &event_timer_irq);
  150. }
  151. /**
  152. * __raw_readl_cycles - Reads the timer counter register
  153. *
  154. * returns: Current timer counter register value
  155. **/
  156. static cycle_t __raw_readl_cycles(struct clocksource *cs)
  157. {
  158. struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKSOURCE];
  159. return (cycle_t)__raw_readl(timer->base_addr +
  160. XTTCPSS_COUNT_VAL_OFFSET);
  161. }
  162. /*
  163. * Instantiate and initialize the clock source structure
  164. */
  165. static struct clocksource clocksource_xttcpss = {
  166. .name = "xttcpss_timer1",
  167. .rating = 200, /* Reasonable clock source */
  168. .read = __raw_readl_cycles,
  169. .mask = CLOCKSOURCE_MASK(16),
  170. .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  171. };
  172. /**
  173. * xttcpss_set_next_event - Sets the time interval for next event
  174. *
  175. * @cycles: Timer interval ticks
  176. * @evt: Address of clock event instance
  177. *
  178. * returns: Always 0 - success
  179. **/
  180. static int xttcpss_set_next_event(unsigned long cycles,
  181. struct clock_event_device *evt)
  182. {
  183. struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT];
  184. xttcpss_set_interval(timer, cycles);
  185. return 0;
  186. }
  187. /**
  188. * xttcpss_set_mode - Sets the mode of timer
  189. *
  190. * @mode: Mode to be set
  191. * @evt: Address of clock event instance
  192. **/
  193. static void xttcpss_set_mode(enum clock_event_mode mode,
  194. struct clock_event_device *evt)
  195. {
  196. struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT];
  197. u32 ctrl_reg;
  198. switch (mode) {
  199. case CLOCK_EVT_MODE_PERIODIC:
  200. xttcpss_set_interval(timer, TIMER_RATE / HZ);
  201. break;
  202. case CLOCK_EVT_MODE_ONESHOT:
  203. case CLOCK_EVT_MODE_UNUSED:
  204. case CLOCK_EVT_MODE_SHUTDOWN:
  205. ctrl_reg = __raw_readl(timer->base_addr +
  206. XTTCPSS_CNT_CNTRL_OFFSET);
  207. ctrl_reg |= XTTCPSS_CNT_CNTRL_DISABLE_MASK;
  208. __raw_writel(ctrl_reg,
  209. timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
  210. break;
  211. case CLOCK_EVT_MODE_RESUME:
  212. ctrl_reg = __raw_readl(timer->base_addr +
  213. XTTCPSS_CNT_CNTRL_OFFSET);
  214. ctrl_reg &= ~XTTCPSS_CNT_CNTRL_DISABLE_MASK;
  215. __raw_writel(ctrl_reg,
  216. timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
  217. break;
  218. }
  219. }
  220. /*
  221. * Instantiate and initialize the clock event structure
  222. */
  223. static struct clock_event_device xttcpss_clockevent = {
  224. .name = "xttcpss_timer2",
  225. .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
  226. .set_next_event = xttcpss_set_next_event,
  227. .set_mode = xttcpss_set_mode,
  228. .rating = 200,
  229. };
  230. /**
  231. * xttcpss_timer_init - Initialize the timer
  232. *
  233. * Initializes the timer hardware and register the clock source and clock event
  234. * timers with Linux kernal timer framework
  235. **/
  236. static void __init xttcpss_timer_init(void)
  237. {
  238. xttcpss_timer_hardware_init();
  239. clocksource_register_hz(&clocksource_xttcpss, TIMER_RATE);
  240. /* Calculate the parameters to allow the clockevent to operate using
  241. integer math
  242. */
  243. clockevents_calc_mult_shift(&xttcpss_clockevent, TIMER_RATE, 4);
  244. xttcpss_clockevent.max_delta_ns =
  245. clockevent_delta2ns(0xfffe, &xttcpss_clockevent);
  246. xttcpss_clockevent.min_delta_ns =
  247. clockevent_delta2ns(1, &xttcpss_clockevent);
  248. /* Indicate that clock event is on 1st CPU as SMP boot needs it */
  249. xttcpss_clockevent.cpumask = cpumask_of(0);
  250. clockevents_register_device(&xttcpss_clockevent);
  251. }
  252. /*
  253. * Instantiate and initialize the system timer structure
  254. */
  255. struct sys_timer xttcpss_sys_timer = {
  256. .init = xttcpss_timer_init,
  257. };