timer.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * (C) Copyright 2009
  3. * 2N Telekomunikace, <www.2n.cz>
  4. *
  5. * (C) Copyright 2003
  6. * Texas Instruments, <www.ti.com>
  7. *
  8. * (C) Copyright 2002
  9. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  10. * Marius Groeger <mgroeger@sysgo.de>
  11. *
  12. * (C) Copyright 2002
  13. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  14. * Alex Zuepke <azu@sysgo.de>
  15. *
  16. * (C) Copyright 2002
  17. * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
  18. *
  19. * SPDX-License-Identifier: GPL-2.0+
  20. */
  21. #include <common.h>
  22. #include <arm925t.h>
  23. #include <configs/omap1510.h>
  24. #include <asm/io.h>
  25. #define TIMER_LOAD_VAL 0xffffffff
  26. #define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (2 << CONFIG_SYS_PTV))
  27. static uint32_t timestamp;
  28. static uint32_t lastdec;
  29. /* nothing really to do with interrupts, just starts up a counter. */
  30. int timer_init (void)
  31. {
  32. /* Start the decrementer ticking down from 0xffffffff */
  33. __raw_writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + LOAD_TIM);
  34. __raw_writel(MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE |
  35. (CONFIG_SYS_PTV << MPUTIM_PTV_BIT),
  36. CONFIG_SYS_TIMERBASE + CNTL_TIMER);
  37. /* init the timestamp and lastdec value */
  38. lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) /
  39. (TIMER_CLOCK / CONFIG_SYS_HZ);
  40. timestamp = 0; /* start "advancing" time stamp from 0 */
  41. return 0;
  42. }
  43. /*
  44. * timer without interrupts
  45. */
  46. ulong get_timer (ulong base)
  47. {
  48. return get_timer_masked () - base;
  49. }
  50. /* delay x useconds AND preserve advance timestamp value */
  51. void __udelay (unsigned long usec)
  52. {
  53. int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000;
  54. uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
  55. while (tmo > 0) {
  56. now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
  57. if (last < now) /* count down timer underflow */
  58. tmo -= TIMER_LOAD_VAL - now + last;
  59. else
  60. tmo -= last - now;
  61. last = now;
  62. }
  63. }
  64. ulong get_timer_masked (void)
  65. {
  66. uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) /
  67. (TIMER_CLOCK / CONFIG_SYS_HZ);
  68. if (lastdec < now) /* count down timer underflow */
  69. timestamp += TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ) -
  70. now + lastdec;
  71. else
  72. timestamp += lastdec - now;
  73. lastdec = now;
  74. return timestamp;
  75. }
  76. /*
  77. * This function is derived from PowerPC code (read timebase as long long).
  78. * On ARM it just returns the timer value.
  79. */
  80. unsigned long long get_ticks(void)
  81. {
  82. return get_timer(0);
  83. }
  84. /*
  85. * This function is derived from PowerPC code (timebase clock frequency).
  86. * On ARM it returns the number of timer ticks per second.
  87. */
  88. ulong get_tbclk (void)
  89. {
  90. return CONFIG_SYS_HZ;
  91. }