cevt-txx9.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. * Based on linux/arch/mips/kernel/cevt-r4k.c,
  7. * linux/arch/mips/jmr3927/rbhma3100/setup.c
  8. *
  9. * Copyright 2001 MontaVista Software Inc.
  10. * Copyright (C) 2000-2001 Toshiba Corporation
  11. * Copyright (C) 2007 MIPS Technologies, Inc.
  12. * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
  13. */
  14. #include <linux/init.h>
  15. #include <linux/interrupt.h>
  16. #include <asm/time.h>
  17. #include <asm/txx9tmr.h>
  18. #define TCR_BASE (TXx9_TMTCR_CCDE | TXx9_TMTCR_CRE | TXx9_TMTCR_TMODE_ITVL)
  19. #define TIMER_CCD 0 /* 1/2 */
  20. #define TIMER_CLK(imclk) ((imclk) / (2 << TIMER_CCD))
  21. static struct txx9_tmr_reg __iomem *txx9_cs_tmrptr;
  22. static cycle_t txx9_cs_read(void)
  23. {
  24. return __raw_readl(&txx9_cs_tmrptr->trr);
  25. }
  26. /* Use 1 bit smaller width to use full bits in that width */
  27. #define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1)
  28. static struct clocksource txx9_clocksource = {
  29. .name = "TXx9",
  30. .rating = 200,
  31. .read = txx9_cs_read,
  32. .mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
  33. .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  34. };
  35. void __init txx9_clocksource_init(unsigned long baseaddr,
  36. unsigned int imbusclk)
  37. {
  38. struct txx9_tmr_reg __iomem *tmrptr;
  39. clocksource_set_clock(&txx9_clocksource, TIMER_CLK(imbusclk));
  40. clocksource_register(&txx9_clocksource);
  41. tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
  42. __raw_writel(TCR_BASE, &tmrptr->tcr);
  43. __raw_writel(0, &tmrptr->tisr);
  44. __raw_writel(TIMER_CCD, &tmrptr->ccdr);
  45. __raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr);
  46. __raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
  47. __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
  48. txx9_cs_tmrptr = tmrptr;
  49. }
  50. static struct txx9_tmr_reg __iomem *txx9_tmrptr;
  51. static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
  52. {
  53. /* stop and reset counter */
  54. __raw_writel(TCR_BASE, &tmrptr->tcr);
  55. /* clear pending interrupt */
  56. __raw_writel(0, &tmrptr->tisr);
  57. }
  58. static void txx9tmr_set_mode(enum clock_event_mode mode,
  59. struct clock_event_device *evt)
  60. {
  61. struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
  62. txx9tmr_stop_and_clear(tmrptr);
  63. switch (mode) {
  64. case CLOCK_EVT_MODE_PERIODIC:
  65. __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE,
  66. &tmrptr->itmr);
  67. /* start timer */
  68. __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >>
  69. evt->shift,
  70. &tmrptr->cpra);
  71. __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
  72. break;
  73. case CLOCK_EVT_MODE_SHUTDOWN:
  74. case CLOCK_EVT_MODE_UNUSED:
  75. __raw_writel(0, &tmrptr->itmr);
  76. break;
  77. case CLOCK_EVT_MODE_ONESHOT:
  78. __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
  79. break;
  80. case CLOCK_EVT_MODE_RESUME:
  81. __raw_writel(TIMER_CCD, &tmrptr->ccdr);
  82. __raw_writel(0, &tmrptr->itmr);
  83. break;
  84. }
  85. }
  86. static int txx9tmr_set_next_event(unsigned long delta,
  87. struct clock_event_device *evt)
  88. {
  89. struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
  90. txx9tmr_stop_and_clear(tmrptr);
  91. /* start timer */
  92. __raw_writel(delta, &tmrptr->cpra);
  93. __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
  94. return 0;
  95. }
  96. static struct clock_event_device txx9tmr_clock_event_device = {
  97. .name = "TXx9",
  98. .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
  99. .rating = 200,
  100. .cpumask = CPU_MASK_CPU0,
  101. .set_mode = txx9tmr_set_mode,
  102. .set_next_event = txx9tmr_set_next_event,
  103. };
  104. static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
  105. {
  106. struct clock_event_device *cd = &txx9tmr_clock_event_device;
  107. struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
  108. __raw_writel(0, &tmrptr->tisr); /* ack interrupt */
  109. cd->event_handler(cd);
  110. return IRQ_HANDLED;
  111. }
  112. static struct irqaction txx9tmr_irq = {
  113. .handler = txx9tmr_interrupt,
  114. .flags = IRQF_DISABLED | IRQF_PERCPU,
  115. .name = "txx9tmr",
  116. };
  117. void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
  118. unsigned int imbusclk)
  119. {
  120. struct clock_event_device *cd = &txx9tmr_clock_event_device;
  121. struct txx9_tmr_reg __iomem *tmrptr;
  122. tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
  123. txx9tmr_stop_and_clear(tmrptr);
  124. __raw_writel(TIMER_CCD, &tmrptr->ccdr);
  125. __raw_writel(0, &tmrptr->itmr);
  126. txx9_tmrptr = tmrptr;
  127. clockevent_set_clock(cd, TIMER_CLK(imbusclk));
  128. cd->max_delta_ns =
  129. clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd);
  130. cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
  131. cd->irq = irq;
  132. clockevents_register_device(cd);
  133. setup_irq(irq, &txx9tmr_irq);
  134. printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d\n",
  135. baseaddr, irq);
  136. }
  137. void __init txx9_tmr_init(unsigned long baseaddr)
  138. {
  139. struct txx9_tmr_reg __iomem *tmrptr;
  140. tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
  141. /* Start once to make CounterResetEnable effective */
  142. __raw_writel(TXx9_TMTCR_CRE | TXx9_TMTCR_TCE, &tmrptr->tcr);
  143. /* Stop and reset the counter */
  144. __raw_writel(TXx9_TMTCR_CRE, &tmrptr->tcr);
  145. __raw_writel(0, &tmrptr->tisr);
  146. __raw_writel(0xffffffff, &tmrptr->cpra);
  147. __raw_writel(0, &tmrptr->itmr);
  148. __raw_writel(0, &tmrptr->ccdr);
  149. __raw_writel(0, &tmrptr->pgmr);
  150. iounmap(tmrptr);
  151. }