cevt-rt3352.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2013 by John Crispin <[email protected]>
  7. */
  8. #include <linux/clockchips.h>
  9. #include <linux/clocksource.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/reset.h>
  12. #include <linux/init.h>
  13. #include <linux/time.h>
  14. #include <linux/of.h>
  15. #include <linux/of_irq.h>
  16. #include <linux/of_address.h>
  17. #include <asm/mach-ralink/ralink_regs.h>
  18. #define SYSTICK_FREQ (50 * 1000)
  19. #define SYSTICK_CONFIG 0x00
  20. #define SYSTICK_COMPARE 0x04
  21. #define SYSTICK_COUNT 0x08
  22. /* route systick irq to mips irq 7 instead of the r4k-timer */
  23. #define CFG_EXT_STK_EN 0x2
  24. /* enable the counter */
  25. #define CFG_CNT_EN 0x1
  26. struct systick_device {
  27. void __iomem *membase;
  28. struct clock_event_device dev;
  29. int irq_requested;
  30. int freq_scale;
  31. };
  32. static int systick_set_oneshot(struct clock_event_device *evt);
  33. static int systick_shutdown(struct clock_event_device *evt);
  34. static int systick_next_event(unsigned long delta,
  35. struct clock_event_device *evt)
  36. {
  37. struct systick_device *sdev;
  38. u32 count;
  39. sdev = container_of(evt, struct systick_device, dev);
  40. count = ioread32(sdev->membase + SYSTICK_COUNT);
  41. count = (count + delta) % SYSTICK_FREQ;
  42. iowrite32(count, sdev->membase + SYSTICK_COMPARE);
  43. return 0;
  44. }
  45. static void systick_event_handler(struct clock_event_device *dev)
  46. {
  47. /* noting to do here */
  48. }
  49. static irqreturn_t systick_interrupt(int irq, void *dev_id)
  50. {
  51. struct clock_event_device *dev = (struct clock_event_device *) dev_id;
  52. dev->event_handler(dev);
  53. return IRQ_HANDLED;
  54. }
  55. static struct systick_device systick = {
  56. .dev = {
  57. /*
  58. * cevt-r4k uses 300, make sure systick
  59. * gets used if available
  60. */
  61. .rating = 310,
  62. .features = CLOCK_EVT_FEAT_ONESHOT,
  63. .set_next_event = systick_next_event,
  64. .set_state_shutdown = systick_shutdown,
  65. .set_state_oneshot = systick_set_oneshot,
  66. .event_handler = systick_event_handler,
  67. },
  68. };
  69. static int systick_shutdown(struct clock_event_device *evt)
  70. {
  71. struct systick_device *sdev;
  72. sdev = container_of(evt, struct systick_device, dev);
  73. if (sdev->irq_requested)
  74. free_irq(systick.dev.irq, &systick.dev);
  75. sdev->irq_requested = 0;
  76. iowrite32(0, systick.membase + SYSTICK_CONFIG);
  77. return 0;
  78. }
  79. static int systick_set_oneshot(struct clock_event_device *evt)
  80. {
  81. const char *name = systick.dev.name;
  82. struct systick_device *sdev;
  83. int irq = systick.dev.irq;
  84. sdev = container_of(evt, struct systick_device, dev);
  85. if (!sdev->irq_requested) {
  86. if (request_irq(irq, systick_interrupt,
  87. IRQF_PERCPU | IRQF_TIMER, name, &systick.dev))
  88. pr_err("Failed to request irq %d (%s)\n", irq, name);
  89. }
  90. sdev->irq_requested = 1;
  91. iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
  92. systick.membase + SYSTICK_CONFIG);
  93. return 0;
  94. }
  95. static int __init ralink_systick_init(struct device_node *np)
  96. {
  97. int ret;
  98. systick.membase = of_iomap(np, 0);
  99. if (!systick.membase)
  100. return -ENXIO;
  101. systick.dev.name = np->name;
  102. clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
  103. systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
  104. systick.dev.max_delta_ticks = 0x7fff;
  105. systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
  106. systick.dev.min_delta_ticks = 0x3;
  107. systick.dev.irq = irq_of_parse_and_map(np, 0);
  108. if (!systick.dev.irq) {
  109. pr_err("%pOFn: request_irq failed", np);
  110. return -EINVAL;
  111. }
  112. ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
  113. SYSTICK_FREQ, 301, 16,
  114. clocksource_mmio_readl_up);
  115. if (ret)
  116. return ret;
  117. clockevents_register_device(&systick.dev);
  118. pr_info("%pOFn: running - mult: %d, shift: %d\n",
  119. np, systick.dev.mult, systick.dev.shift);
  120. return 0;
  121. }
  122. TIMER_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init);