timer64.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * Copyright (C) 2010, 2011 Texas Instruments Incorporated
  3. * Contributed by: Mark Salter (msalter@redhat.com)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. */
  9. #include <linux/clockchips.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/io.h>
  12. #include <linux/of.h>
  13. #include <linux/of_irq.h>
  14. #include <linux/of_address.h>
  15. #include <asm/soc.h>
  16. #include <asm/dscr.h>
  17. #include <asm/special_insns.h>
  18. #include <asm/timer64.h>
  19. struct timer_regs {
  20. u32 reserved0;
  21. u32 emumgt;
  22. u32 reserved1;
  23. u32 reserved2;
  24. u32 cntlo;
  25. u32 cnthi;
  26. u32 prdlo;
  27. u32 prdhi;
  28. u32 tcr;
  29. u32 tgcr;
  30. u32 wdtcr;
  31. };
  32. static struct timer_regs __iomem *timer;
  33. #define TCR_TSTATLO 0x001
  34. #define TCR_INVOUTPLO 0x002
  35. #define TCR_INVINPLO 0x004
  36. #define TCR_CPLO 0x008
  37. #define TCR_ENAMODELO_ONCE 0x040
  38. #define TCR_ENAMODELO_CONT 0x080
  39. #define TCR_ENAMODELO_MASK 0x0c0
  40. #define TCR_PWIDLO_MASK 0x030
  41. #define TCR_CLKSRCLO 0x100
  42. #define TCR_TIENLO 0x200
  43. #define TCR_TSTATHI (0x001 << 16)
  44. #define TCR_INVOUTPHI (0x002 << 16)
  45. #define TCR_CPHI (0x008 << 16)
  46. #define TCR_PWIDHI_MASK (0x030 << 16)
  47. #define TCR_ENAMODEHI_ONCE (0x040 << 16)
  48. #define TCR_ENAMODEHI_CONT (0x080 << 16)
  49. #define TCR_ENAMODEHI_MASK (0x0c0 << 16)
  50. #define TGCR_TIMLORS 0x001
  51. #define TGCR_TIMHIRS 0x002
  52. #define TGCR_TIMMODE_UD32 0x004
  53. #define TGCR_TIMMODE_WDT64 0x008
  54. #define TGCR_TIMMODE_CD32 0x00c
  55. #define TGCR_TIMMODE_MASK 0x00c
  56. #define TGCR_PSCHI_MASK (0x00f << 8)
  57. #define TGCR_TDDRHI_MASK (0x00f << 12)
  58. /*
  59. * Timer clocks are divided down from the CPU clock
  60. * The divisor is in the EMUMGTCLKSPD register
  61. */
  62. #define TIMER_DIVISOR \
  63. ((soc_readl(&timer->emumgt) & (0xf << 16)) >> 16)
  64. #define TIMER64_RATE (c6x_core_freq / TIMER_DIVISOR)
  65. #define TIMER64_MODE_DISABLED 0
  66. #define TIMER64_MODE_ONE_SHOT TCR_ENAMODELO_ONCE
  67. #define TIMER64_MODE_PERIODIC TCR_ENAMODELO_CONT
  68. static int timer64_mode;
  69. static int timer64_devstate_id = -1;
  70. static void timer64_config(unsigned long period)
  71. {
  72. u32 tcr = soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK;
  73. soc_writel(tcr, &timer->tcr);
  74. soc_writel(period - 1, &timer->prdlo);
  75. soc_writel(0, &timer->cntlo);
  76. tcr |= timer64_mode;
  77. soc_writel(tcr, &timer->tcr);
  78. }
  79. static void timer64_enable(void)
  80. {
  81. u32 val;
  82. if (timer64_devstate_id >= 0)
  83. dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_ENABLED);
  84. /* disable timer, reset count */
  85. soc_writel(soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK, &timer->tcr);
  86. soc_writel(0, &timer->prdlo);
  87. /* use internal clock and 1 cycle pulse width */
  88. val = soc_readl(&timer->tcr);
  89. soc_writel(val & ~(TCR_CLKSRCLO | TCR_PWIDLO_MASK), &timer->tcr);
  90. /* dual 32-bit unchained mode */
  91. val = soc_readl(&timer->tgcr) & ~TGCR_TIMMODE_MASK;
  92. soc_writel(val, &timer->tgcr);
  93. soc_writel(val | (TGCR_TIMLORS | TGCR_TIMMODE_UD32), &timer->tgcr);
  94. }
  95. static void timer64_disable(void)
  96. {
  97. /* disable timer, reset count */
  98. soc_writel(soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK, &timer->tcr);
  99. soc_writel(0, &timer->prdlo);
  100. if (timer64_devstate_id >= 0)
  101. dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_DISABLED);
  102. }
  103. static int next_event(unsigned long delta,
  104. struct clock_event_device *evt)
  105. {
  106. timer64_config(delta);
  107. return 0;
  108. }
  109. static int set_periodic(struct clock_event_device *evt)
  110. {
  111. timer64_enable();
  112. timer64_mode = TIMER64_MODE_PERIODIC;
  113. timer64_config(TIMER64_RATE / HZ);
  114. return 0;
  115. }
  116. static int set_oneshot(struct clock_event_device *evt)
  117. {
  118. timer64_enable();
  119. timer64_mode = TIMER64_MODE_ONE_SHOT;
  120. return 0;
  121. }
  122. static int shutdown(struct clock_event_device *evt)
  123. {
  124. timer64_mode = TIMER64_MODE_DISABLED;
  125. timer64_disable();
  126. return 0;
  127. }
  128. static struct clock_event_device t64_clockevent_device = {
  129. .name = "TIMER64_EVT32_TIMER",
  130. .features = CLOCK_EVT_FEAT_ONESHOT |
  131. CLOCK_EVT_FEAT_PERIODIC,
  132. .rating = 200,
  133. .set_state_shutdown = shutdown,
  134. .set_state_periodic = set_periodic,
  135. .set_state_oneshot = set_oneshot,
  136. .set_next_event = next_event,
  137. };
  138. static irqreturn_t timer_interrupt(int irq, void *dev_id)
  139. {
  140. struct clock_event_device *cd = &t64_clockevent_device;
  141. cd->event_handler(cd);
  142. return IRQ_HANDLED;
  143. }
  144. static struct irqaction timer_iact = {
  145. .name = "timer",
  146. .flags = IRQF_TIMER,
  147. .handler = timer_interrupt,
  148. .dev_id = &t64_clockevent_device,
  149. };
  150. void __init timer64_init(void)
  151. {
  152. struct clock_event_device *cd = &t64_clockevent_device;
  153. struct device_node *np, *first = NULL;
  154. u32 val;
  155. int err, found = 0;
  156. for_each_compatible_node(np, NULL, "ti,c64x+timer64") {
  157. err = of_property_read_u32(np, "ti,core-mask", &val);
  158. if (!err) {
  159. if (val & (1 << get_coreid())) {
  160. found = 1;
  161. break;
  162. }
  163. } else if (!first)
  164. first = np;
  165. }
  166. if (!found) {
  167. /* try first one with no core-mask */
  168. if (first)
  169. np = of_node_get(first);
  170. else {
  171. pr_debug("Cannot find ti,c64x+timer64 timer.\n");
  172. return;
  173. }
  174. }
  175. timer = of_iomap(np, 0);
  176. if (!timer) {
  177. pr_debug("%s: Cannot map timer registers.\n", np->full_name);
  178. goto out;
  179. }
  180. pr_debug("%s: Timer registers=%p.\n", np->full_name, timer);
  181. cd->irq = irq_of_parse_and_map(np, 0);
  182. if (cd->irq == NO_IRQ) {
  183. pr_debug("%s: Cannot find interrupt.\n", np->full_name);
  184. iounmap(timer);
  185. goto out;
  186. }
  187. /* If there is a device state control, save the ID. */
  188. err = of_property_read_u32(np, "ti,dscr-dev-enable", &val);
  189. if (!err) {
  190. timer64_devstate_id = val;
  191. /*
  192. * It is necessary to enable the timer block here because
  193. * the TIMER_DIVISOR macro needs to read a timer register
  194. * to get the divisor.
  195. */
  196. dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_ENABLED);
  197. }
  198. pr_debug("%s: Timer irq=%d.\n", np->full_name, cd->irq);
  199. clockevents_calc_mult_shift(cd, c6x_core_freq / TIMER_DIVISOR, 5);
  200. cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
  201. cd->min_delta_ns = clockevent_delta2ns(250, cd);
  202. cd->cpumask = cpumask_of(smp_processor_id());
  203. clockevents_register_device(cd);
  204. setup_irq(cd->irq, &timer_iact);
  205. out:
  206. of_node_put(np);
  207. return;
  208. }