| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- /* SPDX-License-Identifier: GPL-2.0 */
- /*
- * LoongArch Constant Timer specific interface
- */
- #ifndef SELFTEST_KVM_ARCH_TIMER_H
- #define SELFTEST_KVM_ARCH_TIMER_H
- #include "processor.h"
- /* LoongArch timer frequency is constant 100MHZ */
- #define TIMER_FREQ (100UL << 20)
- #define msec_to_cycles(msec) (TIMER_FREQ * (unsigned long)(msec) / 1000)
- #define usec_to_cycles(usec) (TIMER_FREQ * (unsigned long)(usec) / 1000000)
- #define cycles_to_usec(cycles) ((unsigned long)(cycles) * 1000000 / TIMER_FREQ)
- static inline unsigned long timer_get_cycles(void)
- {
- unsigned long val = 0;
- __asm__ __volatile__(
- "rdtime.d %0, $zero\n\t"
- : "=r"(val)
- :
- );
- return val;
- }
- static inline unsigned long timer_get_cfg(void)
- {
- return csr_read(LOONGARCH_CSR_TCFG);
- }
- static inline unsigned long timer_get_val(void)
- {
- return csr_read(LOONGARCH_CSR_TVAL);
- }
- static inline void disable_timer(void)
- {
- csr_write(0, LOONGARCH_CSR_TCFG);
- }
- static inline void timer_irq_enable(void)
- {
- unsigned long val;
- val = csr_read(LOONGARCH_CSR_ECFG);
- val |= ECFGF_TIMER;
- csr_write(val, LOONGARCH_CSR_ECFG);
- }
- static inline void timer_irq_disable(void)
- {
- unsigned long val;
- val = csr_read(LOONGARCH_CSR_ECFG);
- val &= ~ECFGF_TIMER;
- csr_write(val, LOONGARCH_CSR_ECFG);
- }
- static inline void timer_set_next_cmp_ms(unsigned int msec, bool period)
- {
- unsigned long val;
- val = msec_to_cycles(msec) & CSR_TCFG_VAL;
- val |= CSR_TCFG_EN;
- if (period)
- val |= CSR_TCFG_PERIOD;
- csr_write(val, LOONGARCH_CSR_TCFG);
- }
- static inline void __delay(uint64_t cycles)
- {
- uint64_t start = timer_get_cycles();
- while ((timer_get_cycles() - start) < cycles)
- cpu_relax();
- }
- static inline void udelay(unsigned long usec)
- {
- __delay(usec_to_cycles(usec));
- }
- #endif /* SELFTEST_KVM_ARCH_TIMER_H */
|