timer.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include <stdint.h>
  2. #include "amt630hv160.h"
  3. #include "clock.h"
  4. #include "timer.h"
  5. #include "chip.h"
  6. #define TIMER_PERIOD 1000000
  7. #define TIMER_LOAD_VAL 0xFFFFFFFF
  8. /* For convenience the high frequency timer increments a variable that is then
  9. used as the time base for the run time stats. */
  10. volatile uint32_t ulHighFrequencyTimerCounts = 0;
  11. void vTimerInit(uint32_t id, int32_t inten, int32_t periodic, uint32_t rate)
  12. {
  13. uint32_t regbase = REGS_TIMER_BASE;
  14. uint32_t ctrl = TIMER_CTRL_INT_MASK;
  15. if (inten) ctrl &= ~TIMER_CTRL_INT_MASK;
  16. if (periodic) ctrl |= TIMER_CTRL_PERIODIC;
  17. writel(0, regbase + TIMER_CTRL(id));
  18. writel(ulClkGetRate(CLK_TIMER) / rate, regbase + TIMER_LOAD_COUNT(id));
  19. writel(ctrl, regbase + TIMER_CTRL(id));
  20. }
  21. void vTimerEnable(uint32_t id)
  22. {
  23. uint32_t regbase = REGS_TIMER_BASE;
  24. writel(readl(regbase + TIMER_CTRL(id)) | TIMER_CTRL_ENABLE, regbase + TIMER_CTRL(id));
  25. }
  26. void vTimerDisable(uint32_t id)
  27. {
  28. uint32_t regbase = REGS_TIMER_BASE;
  29. writel(readl(regbase + TIMER_CTRL(id)) & ~TIMER_CTRL_ENABLE, regbase + TIMER_CTRL(id));
  30. }
  31. void vTimerClrInt(uint32_t id)
  32. {
  33. uint32_t regbase = REGS_TIMER_BASE;
  34. volatile uint32_t val;
  35. val = readl(regbase + TIMER_EOI(id));
  36. }
  37. /*-----------------------------------------------------------*/
  38. static void prvRunTimer_Handler( void *para )
  39. {
  40. vTimerClrInt((uint32_t)para);
  41. ulHighFrequencyTimerCounts++;
  42. }
  43. void vInitialiseTimerForRunTimeState(void)
  44. {
  45. vTimerInit(TIMER_ID1, 1, 1, configTICK_RATE_HZ * 20);
  46. request_irq(TIMER1_IRQn, 1, prvRunTimer_Handler, (void*)TIMER_ID1);
  47. vTimerEnable(TIMER_ID1);
  48. }
  49. uint32_t ulGetRunTimeCountValue(void)
  50. {
  51. uint32_t regbase = REGS_TIMER_BASE;
  52. return TIMER_LOAD_VAL - readl(regbase + TIMER_CURRENT_VAL(TIMER_ID1));
  53. }
  54. void vInitialiseTimerForDelay(void)
  55. {
  56. uint32_t regbase = REGS_TIMER_BASE;
  57. writel(0, regbase + TIMER_CTRL(TIMER_ID2));
  58. writel(TIMER_LOAD_VAL, regbase + TIMER_LOAD_COUNT(TIMER_ID2));
  59. writel(TIMER_CTRL_INT_MASK | TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE,
  60. regbase + TIMER_CTRL(TIMER_ID2));
  61. }
  62. void udelay(uint32_t usec)
  63. {
  64. uint32_t regbase = REGS_TIMER_BASE;
  65. long tmo = usec * (ulClkGetRate(CLK_TIMER) / TIMER_PERIOD);
  66. unsigned long last = readl(regbase + TIMER_CURRENT_VAL(TIMER_ID2));
  67. unsigned long now;
  68. while (tmo > 0) {
  69. now = readl(regbase + TIMER_CURRENT_VAL(TIMER_ID2));
  70. if (last >= now)
  71. tmo -= last - now;
  72. else
  73. tmo -= last + (TIMER_LOAD_VAL - now);
  74. last = now;
  75. }
  76. }
  77. void mdelay(uint32_t msec)
  78. {
  79. udelay(msec * 1000);
  80. }
  81. void vTimerUdelay(uint32_t usec)
  82. {
  83. udelay(usec);
  84. }
  85. void vTimerMdelay(uint32_t msec)
  86. {
  87. vTimerUdelay(msec * 1000);
  88. }
  89. static unsigned long long timestamp;
  90. static unsigned long lastdec;
  91. uint32_t get_timer_masked(void)
  92. {
  93. uint32_t regbase = REGS_TIMER_BASE;
  94. unsigned long now = readl(regbase + TIMER_CURRENT_VAL(TIMER_ID2));
  95. if (lastdec >= now) { /* normal mode (non roll) */
  96. /* normal mode */
  97. timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
  98. } else { /* we have overflow of the count down timer */
  99. /* nts = ts + ld + (TLV - now)
  100. * ts=old stamp, ld=time that passed before passing through -1
  101. * (TLV-now) amount of time after passing though -1
  102. * nts = new "advancing time stamp"...it could also roll and cause problems.
  103. */
  104. timestamp += lastdec + (TIMER_LOAD_VAL - now);
  105. }
  106. lastdec = now;
  107. return timestamp / (ulClkGetRate(CLK_TIMER) / TIMER_PERIOD);
  108. }
  109. uint32_t get_timer(uint32_t base)
  110. {
  111. uint32_t now = get_timer_masked();
  112. if (now >= base) {
  113. return now - base;
  114. } else {
  115. return 0xffffffff - base + now;
  116. }
  117. }