timebase.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Common timebase prototypes and such for all ppc machines.
  4. */
  5. #ifndef _ASM_POWERPC_VDSO_TIMEBASE_H
  6. #define _ASM_POWERPC_VDSO_TIMEBASE_H
  7. #include <asm/reg.h>
  8. /*
  9. * We use __powerpc64__ here because we want the compat VDSO to use the 32-bit
  10. * version below in the else case of the ifdef.
  11. */
  12. #if defined(__powerpc64__) && (defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_E500))
  13. #define mftb() ({unsigned long rval; \
  14. asm volatile( \
  15. "90: mfspr %0, %2;\n" \
  16. ASM_FTR_IFSET( \
  17. "97: cmpwi %0,0;\n" \
  18. " beq- 90b;\n", "", %1) \
  19. : "=r" (rval) \
  20. : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL) : "cr0"); \
  21. rval;})
  22. #elif defined(CONFIG_PPC_8xx)
  23. #define mftb() ({unsigned long rval; \
  24. asm volatile("mftbl %0" : "=r" (rval)); rval;})
  25. #else
  26. #define mftb() ({unsigned long rval; \
  27. asm volatile("mfspr %0, %1" : \
  28. "=r" (rval) : "i" (SPRN_TBRL)); rval;})
  29. #endif /* !CONFIG_PPC_CELL */
  30. #if defined(CONFIG_PPC_8xx)
  31. #define mftbu() ({unsigned long rval; \
  32. asm volatile("mftbu %0" : "=r" (rval)); rval;})
  33. #else
  34. #define mftbu() ({unsigned long rval; \
  35. asm volatile("mfspr %0, %1" : "=r" (rval) : \
  36. "i" (SPRN_TBRU)); rval;})
  37. #endif
  38. #define mttbl(v) asm volatile("mttbl %0":: "r"(v))
  39. #define mttbu(v) asm volatile("mttbu %0":: "r"(v))
  40. static __always_inline u64 get_tb(void)
  41. {
  42. unsigned int tbhi, tblo, tbhi2;
  43. /*
  44. * We use __powerpc64__ here not CONFIG_PPC64 because we want the compat
  45. * VDSO to use the 32-bit compatible version in the while loop below.
  46. */
  47. if (__is_defined(__powerpc64__))
  48. return mftb();
  49. do {
  50. tbhi = mftbu();
  51. tblo = mftb();
  52. tbhi2 = mftbu();
  53. } while (tbhi != tbhi2);
  54. return ((u64)tbhi << 32) | tblo;
  55. }
  56. static inline void set_tb(unsigned int upper, unsigned int lower)
  57. {
  58. mtspr(SPRN_TBWL, 0);
  59. mtspr(SPRN_TBWU, upper);
  60. mtspr(SPRN_TBWL, lower);
  61. }
  62. #endif /* _ASM_POWERPC_VDSO_TIMEBASE_H */