1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * RISC-V Arch Timer(sstc) specific interface
4 *
5 * Copyright (c) 2024 Intel Corporation
6 */
7
8#ifndef SELFTEST_KVM_ARCH_TIMER_H
9#define SELFTEST_KVM_ARCH_TIMER_H
10
11#include <asm/csr.h>
12#include <asm/vdso/processor.h>
13
14static unsigned long timer_freq;
15
16#define msec_to_cycles(msec)	\
17	((timer_freq) * (uint64_t)(msec) / 1000)
18
19#define usec_to_cycles(usec)	\
20	((timer_freq) * (uint64_t)(usec) / 1000000)
21
22#define cycles_to_usec(cycles) \
23	((uint64_t)(cycles) * 1000000 / (timer_freq))
24
25static inline uint64_t timer_get_cycles(void)
26{
27	return csr_read(CSR_TIME);
28}
29
30static inline void timer_set_cmp(uint64_t cval)
31{
32	csr_write(CSR_STIMECMP, cval);
33}
34
35static inline uint64_t timer_get_cmp(void)
36{
37	return csr_read(CSR_STIMECMP);
38}
39
40static inline void timer_irq_enable(void)
41{
42	csr_set(CSR_SIE, IE_TIE);
43}
44
45static inline void timer_irq_disable(void)
46{
47	csr_clear(CSR_SIE, IE_TIE);
48}
49
50static inline void timer_set_next_cmp_ms(uint32_t msec)
51{
52	uint64_t now_ct = timer_get_cycles();
53	uint64_t next_ct = now_ct + msec_to_cycles(msec);
54
55	timer_set_cmp(next_ct);
56}
57
58static inline void __delay(uint64_t cycles)
59{
60	uint64_t start = timer_get_cycles();
61
62	while ((timer_get_cycles() - start) < cycles)
63		cpu_relax();
64}
65
66static inline void udelay(unsigned long usec)
67{
68	__delay(usec_to_cycles(usec));
69}
70
71#endif /* SELFTEST_KVM_ARCH_TIMER_H */
72