Path: blob/master/tools/testing/selftests/kvm/include/loongarch/arch_timer.h
49255 views
/* SPDX-License-Identifier: GPL-2.0 */1/*2* LoongArch Constant Timer specific interface3*/4#ifndef SELFTEST_KVM_ARCH_TIMER_H5#define SELFTEST_KVM_ARCH_TIMER_H67#include "processor.h"89/* LoongArch timer frequency is constant 100MHZ */10#define TIMER_FREQ (100UL << 20)11#define msec_to_cycles(msec) (TIMER_FREQ * (unsigned long)(msec) / 1000)12#define usec_to_cycles(usec) (TIMER_FREQ * (unsigned long)(usec) / 1000000)13#define cycles_to_usec(cycles) ((unsigned long)(cycles) * 1000000 / TIMER_FREQ)1415static inline unsigned long timer_get_cycles(void)16{17unsigned long val = 0;1819__asm__ __volatile__(20"rdtime.d %0, $zero\n\t"21: "=r"(val)22:23);2425return val;26}2728static inline unsigned long timer_get_cfg(void)29{30return csr_read(LOONGARCH_CSR_TCFG);31}3233static inline unsigned long timer_get_val(void)34{35return csr_read(LOONGARCH_CSR_TVAL);36}3738static inline void disable_timer(void)39{40csr_write(0, LOONGARCH_CSR_TCFG);41}4243static inline void timer_irq_enable(void)44{45unsigned long val;4647val = csr_read(LOONGARCH_CSR_ECFG);48val |= ECFGF_TIMER;49csr_write(val, LOONGARCH_CSR_ECFG);50}5152static inline void timer_irq_disable(void)53{54unsigned long val;5556val = csr_read(LOONGARCH_CSR_ECFG);57val &= ~ECFGF_TIMER;58csr_write(val, LOONGARCH_CSR_ECFG);59}6061static inline void timer_set_next_cmp_ms(unsigned int msec, bool period)62{63unsigned long val;6465val = msec_to_cycles(msec) & CSR_TCFG_VAL;66val |= CSR_TCFG_EN;67if (period)68val |= CSR_TCFG_PERIOD;69csr_write(val, LOONGARCH_CSR_TCFG);70}7172static inline void __delay(uint64_t cycles)73{74uint64_t start = timer_get_cycles();7576while ((timer_get_cycles() - start) < cycles)77cpu_relax();78}7980static inline void udelay(unsigned long usec)81{82__delay(usec_to_cycles(usec));83}84#endif /* SELFTEST_KVM_ARCH_TIMER_H */858687