timer.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * (C) Copyright 2012, ASTRI
  3. * Ho Ka Leung <kalho@astri.org>
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <asm/io.h>
  25. #include <asm/arch/clock.h>
  26. #include <div64.h>
  27. #include <linux/math64.h>
  28. #if defined(CONFIG_ARK1668FAMILY)
  29. #define TIMER_CTL0 0x00
  30. #define TIMER_PRS0 0x10
  31. #define TIMER_MOD0 0x20
  32. #define TIMER_CNT0 0x30
  33. #define TIMER_STA0 0x40
  34. #elif defined(CONFIG_ARKN141FAMILY)
  35. #define TIMER_CTL0 0x00
  36. #define TIMER_PRS0 0x0C
  37. #define TIMER_MOD0 0x18
  38. #define TIMER_CNT0 0x24
  39. #endif
  40. static void __iomem *timer_reg = (void*)CONFIG_SYS_TIMERBASE;
  41. static unsigned long long timestamp;
  42. static unsigned long lastdec;
  43. #define TIMER_PERIOD 1000000 /* 1MHz counter plus 1 = 1us */
  44. #define TIMER_LOAD_VAL 0x00ffffff
  45. void reset_timer_masked (void)
  46. {
  47. /* reset time */
  48. lastdec = readl(timer_reg + TIMER_CNT0); /* capure current decrementer value time */
  49. timestamp = 0; /* start "advancing" time stamp from 0 */
  50. }
  51. ulong get_timer_masked (void)
  52. {
  53. unsigned long now = readl(timer_reg + TIMER_CNT0); /* current tick value */
  54. if (lastdec >= now) { /* normal mode (non roll) */
  55. /* normal mode */
  56. timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
  57. } else { /* we have overflow of the count down timer */
  58. /* nts = ts + ld + (TLV - now)
  59. * ts=old stamp, ld=time that passed before passing through -1
  60. * (TLV-now) amount of time after passing though -1
  61. * nts = new "advancing time stamp"...it could also roll and cause problems.
  62. */
  63. timestamp += lastdec + (TIMER_LOAD_VAL - now);
  64. }
  65. lastdec = now;
  66. return div_u64(timestamp, 1000);
  67. }
  68. int timer_init(void)
  69. {
  70. writel(0, timer_reg + TIMER_CTL0);
  71. writel(ark_get_apb_clock() / TIMER_PERIOD - 1, timer_reg + TIMER_PRS0);
  72. writel(TIMER_LOAD_VAL, timer_reg + TIMER_MOD0);
  73. /* No timer interrupt */
  74. writel(0x03, timer_reg + TIMER_CTL0);
  75. return 0;
  76. }
  77. unsigned long long get_ticks(void)
  78. {
  79. return 0;
  80. }
  81. ulong get_timer(ulong base)
  82. {
  83. return get_timer_masked () - base;
  84. }
  85. void __udelay(unsigned long usec)
  86. {
  87. long tmo = usec;
  88. unsigned long last = readl(timer_reg + TIMER_CNT0);
  89. unsigned long now;
  90. while (tmo > 0) {
  91. now = readl(timer_reg + TIMER_CNT0);
  92. if (last >= now)
  93. tmo -= last - now;
  94. else
  95. tmo -= last + (TIMER_LOAD_VAL - now);
  96. last = now;
  97. }
  98. }
  99. ulong get_tbclk(void)
  100. {
  101. return CONFIG_SYS_HZ;
  102. }
  103. #ifdef CONFIG_SPL_BUILD
  104. void timer_init_24M(void)
  105. {
  106. writel(0, timer_reg + TIMER_CTL0);
  107. writel(23, timer_reg + TIMER_PRS0);
  108. writel(TIMER_LOAD_VAL, timer_reg + TIMER_MOD0);
  109. writel(3, timer_reg + TIMER_CTL0);
  110. }
  111. void timer_uninit(void)
  112. {
  113. writel(0, timer_reg + TIMER_CTL0);
  114. }
  115. void timer_delay_us(unsigned int us)
  116. {
  117. __udelay(us);
  118. }
  119. #endif