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 Maostatic 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 Maostatic 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 Maostatic 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 Maostatic 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 Maostatic 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 Maostatic 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 Maostatic 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 Maostatic 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 Maostatic 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