time.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Common time prototypes and such for all ppc machines.
  3. *
  4. * Written by Cort Dougan (cort@fsmlabs.com) to merge
  5. * Paul Mackerras' version and mine for PReP and Pmac.
  6. */
  7. #ifdef __KERNEL__
  8. #ifndef __ASM_TIME_H__
  9. #define __ASM_TIME_H__
  10. #include <linux/types.h>
  11. #include <linux/rtc.h>
  12. #include <linux/threads.h>
  13. #include <asm/reg.h>
  14. /* time.c */
  15. extern unsigned tb_ticks_per_jiffy;
  16. extern unsigned tb_to_us;
  17. extern unsigned tb_last_stamp;
  18. extern unsigned long disarm_decr[NR_CPUS];
  19. extern void to_tm(int tim, struct rtc_time * tm);
  20. extern time_t last_rtc_update;
  21. extern void set_dec_cpu6(unsigned int val);
  22. int via_calibrate_decr(void);
  23. /* Accessor functions for the decrementer register.
  24. * The 4xx doesn't even have a decrementer. I tried to use the
  25. * generic timer interrupt code, which seems OK, with the 4xx PIT
  26. * in auto-reload mode. The problem is PIT stops counting when it
  27. * hits zero. If it would wrap, we could use it just like a decrementer.
  28. */
  29. static __inline__ unsigned int get_dec(void)
  30. {
  31. #if defined(CONFIG_40x)
  32. return (mfspr(SPRN_PIT));
  33. #else
  34. return (mfspr(SPRN_DEC));
  35. #endif
  36. }
  37. static __inline__ void set_dec(unsigned int val)
  38. {
  39. #if defined(CONFIG_40x)
  40. return; /* Have to let it auto-reload */
  41. #elif defined(CONFIG_8xx_CPU6)
  42. set_dec_cpu6(val);
  43. #else
  44. mtspr(SPRN_DEC, val);
  45. #endif
  46. }
  47. /* Accessor functions for the timebase (RTC on 601) registers. */
  48. /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
  49. #ifdef CONFIG_6xx
  50. extern __inline__ int __attribute_pure__ __USE_RTC(void) {
  51. return (mfspr(SPRN_PVR)>>16) == 1;
  52. }
  53. #else
  54. #define __USE_RTC() 0
  55. #endif
  56. extern __inline__ unsigned long get_tbl(void) {
  57. unsigned long tbl;
  58. #if defined(CONFIG_403GCX)
  59. asm volatile("mfspr %0, 0x3dd" : "=r" (tbl));
  60. #else
  61. asm volatile("mftb %0" : "=r" (tbl));
  62. #endif
  63. return tbl;
  64. }
  65. extern __inline__ unsigned long get_tbu(void) {
  66. unsigned long tbl;
  67. #if defined(CONFIG_403GCX)
  68. asm volatile("mfspr %0, 0x3dc" : "=r" (tbl));
  69. #else
  70. asm volatile("mftbu %0" : "=r" (tbl));
  71. #endif
  72. return tbl;
  73. }
  74. extern __inline__ void set_tb(unsigned int upper, unsigned int lower)
  75. {
  76. mtspr(SPRN_TBWL, 0);
  77. mtspr(SPRN_TBWU, upper);
  78. mtspr(SPRN_TBWL, lower);
  79. }
  80. extern __inline__ unsigned long get_rtcl(void) {
  81. unsigned long rtcl;
  82. asm volatile("mfrtcl %0" : "=r" (rtcl));
  83. return rtcl;
  84. }
  85. extern __inline__ unsigned long get_rtcu(void)
  86. {
  87. unsigned long rtcu;
  88. asm volatile("mfrtcu %0" : "=r" (rtcu));
  89. return rtcu;
  90. }
  91. extern __inline__ unsigned get_native_tbl(void) {
  92. if (__USE_RTC())
  93. return get_rtcl();
  94. else
  95. return get_tbl();
  96. }
  97. /* On machines with RTC, this function can only be used safely
  98. * after the timestamp and for 1 second. It is only used by gettimeofday
  99. * however so it should not matter.
  100. */
  101. extern __inline__ unsigned tb_ticks_since(unsigned tstamp) {
  102. if (__USE_RTC()) {
  103. int delta = get_rtcl() - tstamp;
  104. return delta<0 ? delta + 1000000000 : delta;
  105. } else {
  106. return get_tbl() - tstamp;
  107. }
  108. }
  109. #if 0
  110. extern __inline__ unsigned long get_bin_rtcl(void) {
  111. unsigned long rtcl, rtcu1, rtcu2;
  112. asm volatile("\
  113. 1: mfrtcu %0\n\
  114. mfrtcl %1\n\
  115. mfrtcu %2\n\
  116. cmpw %0,%2\n\
  117. bne- 1b\n"
  118. : "=r" (rtcu1), "=r" (rtcl), "=r" (rtcu2)
  119. : : "cr0");
  120. return rtcu2*1000000000+rtcl;
  121. }
  122. extern __inline__ unsigned binary_tbl(void) {
  123. if (__USE_RTC())
  124. return get_bin_rtcl();
  125. else
  126. return get_tbl();
  127. }
  128. #endif
  129. /* Use mulhwu to scale processor timebase to timeval */
  130. /* Specifically, this computes (x * y) / 2^32. -- paulus */
  131. #define mulhwu(x,y) \
  132. ({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
  133. unsigned mulhwu_scale_factor(unsigned, unsigned);
  134. #define account_process_vtime(tsk) do { } while (0)
  135. #define calculate_steal_time() do { } while (0)
  136. #define snapshot_timebases() do { } while (0)
  137. #endif /* __ASM_TIME_H__ */
  138. #endif /* __KERNEL__ */