timer-keystone.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Keystone broadcast clock-event
  3. *
  4. * Copyright 2013 Texas Instruments, Inc.
  5. *
  6. * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.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. */
  13. #include <linux/clk.h>
  14. #include <linux/clockchips.h>
  15. #include <linux/clocksource.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/of_address.h>
  18. #include <linux/of_irq.h>
  19. #include <linux/platform_device.h>
  20. #define TIMER_NAME "timer-keystone"
  21. /* Timer register offsets */
  22. #define TIM12 0x10
  23. #define TIM34 0x14
  24. #define PRD12 0x18
  25. #define PRD34 0x1c
  26. #define TCR 0x20
  27. #define TGCR 0x24
  28. #define INTCTLSTAT 0x44
  29. /* Timer register bitfields */
  30. #define TCR_ENAMODE_MASK 0xC0
  31. #define TCR_ENAMODE_ONESHOT_MASK 0x40
  32. #define TCR_ENAMODE_PERIODIC_MASK 0x80
  33. #define TGCR_TIM_UNRESET_MASK 0x03
  34. #define INTCTLSTAT_ENINT_MASK 0x01
  35. /**
  36. * struct keystone_timer: holds timer's data
  37. * @base: timer memory base address
  38. * @hz_period: cycles per HZ period
  39. * @event_dev: event device based on timer
  40. * @registered: Flag to keep a track of registration status
  41. */
  42. static struct keystone_timer {
  43. void __iomem *base;
  44. unsigned long hz_period;
  45. struct clock_event_device event_dev;
  46. bool registered;
  47. } timer;
  48. static inline u32 keystone_timer_readl(unsigned long rg)
  49. {
  50. return readl_relaxed(timer.base + rg);
  51. }
  52. static inline void keystone_timer_writel(u32 val, unsigned long rg)
  53. {
  54. writel_relaxed(val, timer.base + rg);
  55. }
  56. /**
  57. * keystone_timer_barrier: write memory barrier
  58. * use explicit barrier to avoid using readl/writel non relaxed function
  59. * variants, because in our case non relaxed variants hide the true places
  60. * where barrier is needed.
  61. */
  62. static inline void keystone_timer_barrier(void)
  63. {
  64. __iowmb();
  65. }
  66. /**
  67. * keystone_timer_config: configures timer to work in oneshot/periodic modes.
  68. * @ mask: mask of the mode to configure
  69. * @ period: cycles number to configure for
  70. */
  71. static int keystone_timer_config(u64 period, int mask)
  72. {
  73. u32 tcr;
  74. u32 off;
  75. tcr = keystone_timer_readl(TCR);
  76. off = tcr & ~(TCR_ENAMODE_MASK);
  77. /* set enable mode */
  78. tcr |= mask;
  79. /* disable timer */
  80. keystone_timer_writel(off, TCR);
  81. /* here we have to be sure the timer has been disabled */
  82. keystone_timer_barrier();
  83. /* reset counter to zero, set new period */
  84. keystone_timer_writel(0, TIM12);
  85. keystone_timer_writel(0, TIM34);
  86. keystone_timer_writel(period & 0xffffffff, PRD12);
  87. keystone_timer_writel(period >> 32, PRD34);
  88. /*
  89. * enable timer
  90. * here we have to be sure that CNTLO, CNTHI, PRDLO, PRDHI registers
  91. * have been written.
  92. */
  93. keystone_timer_barrier();
  94. keystone_timer_writel(tcr, TCR);
  95. return 0;
  96. }
  97. static void keystone_timer_disable(void)
  98. {
  99. u32 tcr;
  100. tcr = keystone_timer_readl(TCR);
  101. /* disable timer */
  102. tcr &= ~(TCR_ENAMODE_MASK);
  103. keystone_timer_writel(tcr, TCR);
  104. }
  105. static irqreturn_t keystone_timer_interrupt(int irq, void *dev_id)
  106. {
  107. struct clock_event_device *evt = dev_id;
  108. evt->event_handler(evt);
  109. return IRQ_HANDLED;
  110. }
  111. static int keystone_set_next_event(unsigned long cycles,
  112. struct clock_event_device *evt)
  113. {
  114. return keystone_timer_config(cycles, TCR_ENAMODE_ONESHOT_MASK);
  115. }
  116. static int keystone_shutdown(struct clock_event_device *evt)
  117. {
  118. keystone_timer_disable();
  119. return 0;
  120. }
  121. static int keystone_set_periodic(struct clock_event_device *evt)
  122. {
  123. keystone_timer_config(timer.hz_period, TCR_ENAMODE_PERIODIC_MASK);
  124. return 0;
  125. }
  126. static int keystone_timer_init(struct device_node *np)
  127. {
  128. struct clock_event_device *event_dev = &timer.event_dev;
  129. unsigned long rate;
  130. struct clk *clk;
  131. int irq, error;
  132. timer.registered = false;
  133. irq = irq_of_parse_and_map(np, 0);
  134. if (!irq) {
  135. pr_err("%s: failed to map interrupts\n", __func__);
  136. return -EINVAL;
  137. }
  138. timer.base = of_iomap(np, 0);
  139. if (!timer.base) {
  140. pr_err("%s: failed to map registers\n", __func__);
  141. return -ENXIO;
  142. }
  143. clk = of_clk_get(np, 0);
  144. if (IS_ERR(clk)) {
  145. pr_err("%s: failed to get clock\n", __func__);
  146. iounmap(timer.base);
  147. return PTR_ERR(clk);
  148. }
  149. error = clk_prepare_enable(clk);
  150. if (error) {
  151. pr_err("%s: failed to enable clock\n", __func__);
  152. goto err;
  153. }
  154. rate = clk_get_rate(clk);
  155. /* disable, use internal clock source */
  156. keystone_timer_writel(0, TCR);
  157. /* here we have to be sure the timer has been disabled */
  158. keystone_timer_barrier();
  159. /* reset timer as 64-bit, no pre-scaler, plus features are disabled */
  160. keystone_timer_writel(0, TGCR);
  161. /* unreset timer */
  162. keystone_timer_writel(TGCR_TIM_UNRESET_MASK, TGCR);
  163. /* init counter to zero */
  164. keystone_timer_writel(0, TIM12);
  165. keystone_timer_writel(0, TIM34);
  166. timer.hz_period = DIV_ROUND_UP(rate, HZ);
  167. /* enable timer interrupts */
  168. keystone_timer_writel(INTCTLSTAT_ENINT_MASK, INTCTLSTAT);
  169. error = request_irq(irq, keystone_timer_interrupt, IRQF_TIMER,
  170. TIMER_NAME, event_dev);
  171. if (error) {
  172. pr_err("%s: failed to setup irq\n", __func__);
  173. goto err;
  174. }
  175. /* setup clockevent */
  176. event_dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
  177. event_dev->set_next_event = keystone_set_next_event;
  178. event_dev->set_state_shutdown = keystone_shutdown;
  179. event_dev->set_state_periodic = keystone_set_periodic;
  180. event_dev->set_state_oneshot = keystone_shutdown;
  181. event_dev->cpumask = cpu_all_mask;
  182. event_dev->owner = THIS_MODULE;
  183. event_dev->name = TIMER_NAME;
  184. event_dev->irq = irq;
  185. clockevents_config_and_register(event_dev, rate, 1, ULONG_MAX);
  186. pr_info("keystone timer clock @%lu Hz\n", rate);
  187. timer.registered = true;
  188. return 0;
  189. err:
  190. clk_put(clk);
  191. iounmap(timer.base);
  192. return error;
  193. }
  194. CLOCKSOURCE_OF_DECLARE(keystone_timer, "ti,keystone-timer",
  195. keystone_timer_init);
  196. static const struct of_device_id keystone_clocksource_of_match[] = {
  197. {.compatible = "ti,keystone-timer", },
  198. {},
  199. };
  200. static int keystone_clocksource_probe(struct platform_device *pdev)
  201. {
  202. struct clk *clk;
  203. if (timer.registered)
  204. return 0;
  205. clk = devm_clk_get(&pdev->dev, NULL);
  206. if (IS_ERR(clk)) {
  207. if (PTR_ERR(clk) != -EPROBE_DEFER)
  208. dev_err(&pdev->dev, "failed to get clock\n");
  209. return PTR_ERR(clk);
  210. }
  211. clk_put(clk);
  212. keystone_timer_init(pdev->dev.of_node);
  213. if (!timer.registered)
  214. return -EINVAL;
  215. return 0;
  216. }
  217. static struct platform_driver keystone_clocksource_driver = {
  218. .probe = keystone_clocksource_probe,
  219. .driver = {
  220. .name = "keystone_clocksource",
  221. .of_match_table = keystone_clocksource_of_match,
  222. },
  223. };
  224. static int __init keystone_clocksource_init_driver(void)
  225. {
  226. return platform_driver_register(&keystone_clocksource_driver);
  227. }
  228. device_initcall(keystone_clocksource_init_driver);