You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ia64_timer.c 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "etherboot.h"
  2. #include "timer.h"
  3. #include "sal.h"
  4. #include "pal.h"
  5. #include "init.h"
  6. static inline unsigned long get_cycles(void)
  7. {
  8. unsigned long result;
  9. __asm__ __volatile__(";;mov %0=ar.itc;;" : "=r"(result));
  10. return result;
  11. }
  12. /* ------ Calibrate the TSC -------
  13. * Time how long it takes to excute a loop that runs in known time.
  14. * And find the convertion needed to get to CLOCK_TICK_RATE
  15. */
  16. static unsigned long calibrate_cycles(void)
  17. {
  18. unsigned long platform_ticks_per_second, drift_info;
  19. struct pal_freq_ratio itc_ratio;
  20. long result;
  21. result = sal_freq_base(SAL_FREQ_BASE_PLATFORM, &platform_ticks_per_second, &drift_info);
  22. if (result != 0) {
  23. printf("sal_freq_base failed: %lx\n",result);
  24. exit(1);
  25. } else {
  26. result = pal_freq_ratios(0,0,&itc_ratio);
  27. if (result != 0) {
  28. printf("pal_freq_ratios failed: %lx\n", result);
  29. exit(1);
  30. }
  31. }
  32. /* Avoid division by zero */
  33. if (itc_ratio.den == 0)
  34. itc_ratio.den = 1;
  35. return (platform_ticks_per_second *itc_ratio.num)/(itc_ratio.den*TICKS_PER_SEC);
  36. }
  37. static unsigned long clocks_per_tick;
  38. static void setup_timers(void)
  39. {
  40. if (!clocks_per_tick) {
  41. clocks_per_tick = calibrate_cycles();
  42. /* Display the CPU Mhz to easily test if the calibration was bad */
  43. printf("ITC %ld Mhz\n", (clocks_per_tick/1000 * TICKS_PER_SEC)/1000);
  44. }
  45. }
  46. unsigned long currticks(void)
  47. {
  48. return get_cycles()/clocks_per_tick;
  49. }
  50. static unsigned long timer_timeout;
  51. static int __timer_running(void)
  52. {
  53. return get_cycles() < timer_timeout;
  54. }
  55. void udelay(unsigned int usecs)
  56. {
  57. unsigned long now;
  58. now = get_cycles();
  59. timer_timeout = now + usecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000));
  60. while(__timer_running());
  61. }
  62. void ndelay(unsigned int nsecs)
  63. {
  64. unsigned long now;
  65. now = get_cycles();
  66. timer_timeout = now + nsecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000*1000));
  67. while(__timer_running());
  68. }
  69. void load_timer2(unsigned int timer2_ticks)
  70. {
  71. unsigned long now;
  72. unsigned long clocks;
  73. now = get_cycles();
  74. clocks = timer2_ticks * ((clocks_per_tick * TICKS_PER_SEC)/CLOCK_TICK_RATE);
  75. timer_timeout = now + clocks;
  76. }
  77. int timer2_running(void)
  78. {
  79. return __timer_running();
  80. }
  81. INIT_FN ( INIT_TIMERS, setup_timers, NULL, NULL );