arch_timer.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * LoongArch Constant Timer specific interface
  4. */
  5. #ifndef SELFTEST_KVM_ARCH_TIMER_H
  6. #define SELFTEST_KVM_ARCH_TIMER_H
  7. #include "processor.h"
  8. /* LoongArch timer frequency is constant 100MHZ */
  9. #define TIMER_FREQ (100UL << 20)
  10. #define msec_to_cycles(msec) (TIMER_FREQ * (unsigned long)(msec) / 1000)
  11. #define usec_to_cycles(usec) (TIMER_FREQ * (unsigned long)(usec) / 1000000)
  12. #define cycles_to_usec(cycles) ((unsigned long)(cycles) * 1000000 / TIMER_FREQ)
  13. static inline unsigned long timer_get_cycles(void)
  14. {
  15. unsigned long val = 0;
  16. __asm__ __volatile__(
  17. "rdtime.d %0, $zero\n\t"
  18. : "=r"(val)
  19. :
  20. );
  21. return val;
  22. }
  23. static inline unsigned long timer_get_cfg(void)
  24. {
  25. return csr_read(LOONGARCH_CSR_TCFG);
  26. }
  27. static inline unsigned long timer_get_val(void)
  28. {
  29. return csr_read(LOONGARCH_CSR_TVAL);
  30. }
  31. static inline void disable_timer(void)
  32. {
  33. csr_write(0, LOONGARCH_CSR_TCFG);
  34. }
  35. static inline void timer_irq_enable(void)
  36. {
  37. unsigned long val;
  38. val = csr_read(LOONGARCH_CSR_ECFG);
  39. val |= ECFGF_TIMER;
  40. csr_write(val, LOONGARCH_CSR_ECFG);
  41. }
  42. static inline void timer_irq_disable(void)
  43. {
  44. unsigned long val;
  45. val = csr_read(LOONGARCH_CSR_ECFG);
  46. val &= ~ECFGF_TIMER;
  47. csr_write(val, LOONGARCH_CSR_ECFG);
  48. }
  49. static inline void timer_set_next_cmp_ms(unsigned int msec, bool period)
  50. {
  51. unsigned long val;
  52. val = msec_to_cycles(msec) & CSR_TCFG_VAL;
  53. val |= CSR_TCFG_EN;
  54. if (period)
  55. val |= CSR_TCFG_PERIOD;
  56. csr_write(val, LOONGARCH_CSR_TCFG);
  57. }
  58. static inline void __delay(uint64_t cycles)
  59. {
  60. uint64_t start = timer_get_cycles();
  61. while ((timer_get_cycles() - start) < cycles)
  62. cpu_relax();
  63. }
  64. static inline void udelay(unsigned long usec)
  65. {
  66. __delay(usec_to_cycles(usec));
  67. }
  68. #endif /* SELFTEST_KVM_ARCH_TIMER_H */