diff options
Diffstat (limited to 'arch/riscv/include/asm/timex.h')
-rw-r--r-- | arch/riscv/include/asm/timex.h | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h index 6a703ec9d796..bad2a7c2cda5 100644 --- a/arch/riscv/include/asm/timex.h +++ b/arch/riscv/include/asm/timex.h @@ -6,43 +6,56 @@ #ifndef _ASM_RISCV_TIMEX_H #define _ASM_RISCV_TIMEX_H -#include <asm/param.h> +#include <asm/csr.h> +#include <asm/mmio.h> typedef unsigned long cycles_t; -static inline cycles_t get_cycles_inline(void) -{ - cycles_t n; +extern u64 __iomem *riscv_time_val; +extern u64 __iomem *riscv_time_cmp; - __asm__ __volatile__ ( - "rdtime %0" - : "=r" (n)); - return n; +#ifdef CONFIG_64BIT +#define mmio_get_cycles() readq_relaxed(riscv_time_val) +#else +#define mmio_get_cycles() readl_relaxed(riscv_time_val) +#define mmio_get_cycles_hi() readl_relaxed(((u32 *)riscv_time_val) + 1) +#endif + +static inline cycles_t get_cycles(void) +{ + if (IS_ENABLED(CONFIG_RISCV_SBI)) + return csr_read(CSR_TIME); + return mmio_get_cycles(); } -#define get_cycles get_cycles_inline +#define get_cycles get_cycles #ifdef CONFIG_64BIT -static inline uint64_t get_cycles64(void) +static inline u64 get_cycles64(void) { - return get_cycles(); + return get_cycles(); } -#else -static inline uint64_t get_cycles64(void) +#else /* CONFIG_64BIT */ +static inline u32 get_cycles_hi(void) { - u32 lo, hi, tmp; - __asm__ __volatile__ ( - "1:\n" - "rdtimeh %0\n" - "rdtime %1\n" - "rdtimeh %2\n" - "bne %0, %2, 1b" - : "=&r" (hi), "=&r" (lo), "=&r" (tmp)); + if (IS_ENABLED(CONFIG_RISCV_SBI)) + return csr_read(CSR_TIMEH); + return mmio_get_cycles_hi(); +} + +static inline u64 get_cycles64(void) +{ + u32 hi, lo; + + do { + hi = get_cycles_hi(); + lo = get_cycles(); + } while (hi != get_cycles_hi()); + return ((u64)hi << 32) | lo; } -#endif +#endif /* CONFIG_64BIT */ #define ARCH_HAS_READ_CURRENT_TIMER - static inline int read_current_timer(unsigned long *timer_val) { *timer_val = get_cycles(); |