time.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/include/asm-arm/arch-integrator/time.h
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  */
  18. #include <asm/system.h>
  19. #include <asm/leds.h>
  20. /*
  21.  * Where is the timer (VA)?
  22.  */
  23. #define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000)
  24. #define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100)
  25. #define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200)
  26. #define VA_IC_BASE     IO_ADDRESS(INTEGRATOR_IC_BASE) 
  27. /*
  28.  * How long is the timer interval?
  29.  */
  30. #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
  31. #if TIMER_INTERVAL >= 0x100000
  32. #define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */
  33. #define TIMER_CTRL 0x88 /* Enable, Clock / 256 */
  34. #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
  35. #elif TIMER_INTERVAL >= 0x10000
  36. #define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
  37. #define TIMER_CTRL 0x84 /* Enable, Clock / 16 */
  38. #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
  39. #else
  40. #define TIMER_RELOAD (TIMER_INTERVAL)
  41. #define TIMER_CTRL 0x80 /* Enable */
  42. #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
  43. #endif
  44. /*
  45.  * What does it look like?
  46.  */
  47. typedef struct TimerStruct {
  48. unsigned long TimerLoad;
  49. unsigned long TimerValue;
  50. unsigned long TimerControl;
  51. unsigned long TimerClear;
  52. } TimerStruct_t;
  53. extern unsigned long (*gettimeoffset)(void);
  54. /*
  55.  * Returns number of ms since last clock interrupt.  Note that interrupts
  56.  * will have been disabled by do_gettimeoffset()
  57.  */
  58. static unsigned long integrator_gettimeoffset(void)
  59. {
  60. volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
  61. unsigned long ticks1, ticks2, status;
  62. /*
  63.  * Get the current number of ticks.  Note that there is a race
  64.  * condition between us reading the timer and checking for
  65.  * an interrupt.  We get around this by ensuring that the
  66.  * counter has not reloaded between our two reads.
  67.  */
  68. ticks2 = timer1->TimerValue & 0xffff;
  69. do {
  70. ticks1 = ticks2;
  71. status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
  72. ticks2 = timer1->TimerValue & 0xffff;
  73. } while (ticks2 > ticks1);
  74. /*
  75.  * Number of ticks since last interrupt.
  76.  */
  77. ticks1 = TIMER_RELOAD - ticks2;
  78. /*
  79.  * Interrupt pending?  If so, we've reloaded once already.
  80.  */
  81. if (status & IRQMASK_TIMERINT1)
  82. ticks1 += TIMER_RELOAD;
  83. /*
  84.  * Convert the ticks to usecs
  85.  */
  86. return TICKS2USECS(ticks1);
  87. }
  88. /*
  89.  * IRQ handler for the timer
  90.  */
  91. static void integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  92. {
  93. volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
  94. // ...clear the interrupt
  95. timer1->TimerClear = 1;
  96. do_leds();
  97. do_timer(regs);
  98. do_profile(regs);
  99. }
  100. /*
  101.  * Set up timer interrupt, and return the current time in seconds.
  102.  */
  103. static inline void setup_timer(void)
  104. {
  105. volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
  106. volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
  107. volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
  108. timer_irq.handler = integrator_timer_interrupt;
  109. /*
  110.  * Initialise to a known state (all timers off)
  111.  */
  112. timer0->TimerControl = 0;
  113. timer1->TimerControl = 0;
  114. timer2->TimerControl = 0;
  115. timer1->TimerLoad    = TIMER_RELOAD;
  116. timer1->TimerValue   = TIMER_RELOAD;
  117. timer1->TimerControl = TIMER_CTRL | 0x40; /* periodic */
  118. /* 
  119.  * Make irqs happen for the system timer
  120.  */
  121. setup_arm_irq(IRQ_TIMERINT1, &timer_irq);
  122. gettimeoffset = integrator_gettimeoffset;
  123. }