oxnas_rps_timer.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * arch/arm/mach-ox820/rps-time.c
  3. *
  4. * Copyright (C) 2009 Oxford Semiconductor Ltd
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms and conditions of the GNU General Public License,
  8. * version 2, as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <linux/init.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/irq.h>
  21. #include <linux/io.h>
  22. #include <linux/clockchips.h>
  23. #include <linux/clk.h>
  24. #include <linux/of_irq.h>
  25. #include <linux/of_address.h>
  26. #include <linux/sched_clock.h>
  27. #include <mach/hardware.h>
  28. enum {
  29. TIMER_LOAD = 0,
  30. TIMER_CURR = 4,
  31. TIMER_CTRL = 8,
  32. TIMER_CLRINT = 0xC,
  33. TIMER_BITS = 24,
  34. TIMER_MAX_VAL = (1 << TIMER_BITS) - 1,
  35. TIMER_PERIODIC = (1 << 6),
  36. TIMER_ENABLE = (1 << 7),
  37. TIMER_DIV1 = (0 << 2),
  38. TIMER_DIV16 = (1 << 2),
  39. TIMER_DIV256 = (2 << 2),
  40. TIMER1_OFFSET = 0,
  41. TIMER2_OFFSET = 0x20,
  42. };
  43. static u64 notrace rps_read_sched_clock(void)
  44. {
  45. return ~readl_relaxed(RPSA_TIMER2_VAL);
  46. }
  47. static void __init rps_clocksource_init(void __iomem *base, ulong ref_rate)
  48. {
  49. int ret;
  50. ulong clock_rate;
  51. /* use prescale 16 */
  52. clock_rate = ref_rate / 16;
  53. iowrite32(TIMER_MAX_VAL, base + TIMER_LOAD);
  54. iowrite32(TIMER_PERIODIC | TIMER_ENABLE | TIMER_DIV16,
  55. base + TIMER_CTRL);
  56. ret = clocksource_mmio_init(base + TIMER_CURR, "rps_clocksource_timer",
  57. clock_rate, 250, TIMER_BITS,
  58. clocksource_mmio_readl_down);
  59. if (ret)
  60. panic("can't register clocksource\n");
  61. sched_clock_register(rps_read_sched_clock, TIMER_BITS, clock_rate);
  62. }
  63. static void __init rps_timer_init(struct device_node *np)
  64. {
  65. struct clk *refclk;
  66. unsigned long ref_rate;
  67. void __iomem *base;
  68. refclk = of_clk_get(np, 0);
  69. if (IS_ERR(refclk) || clk_prepare_enable(refclk))
  70. panic("rps_timer_init: failed to get refclk\n");
  71. ref_rate = clk_get_rate(refclk);
  72. base = of_iomap(np, 0);
  73. if (!base)
  74. panic("rps_timer_init: failed to map io\n");
  75. rps_clocksource_init(base + TIMER2_OFFSET, ref_rate);
  76. }
  77. CLOCKSOURCE_OF_DECLARE(nas782x, "plxtech,nas782x-rps-timer", rps_timer_init);