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