summaryrefslogtreecommitdiffstats
path: root/arch/riscv/include/asm/timex.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv/include/asm/timex.h')
-rw-r--r--arch/riscv/include/asm/timex.h59
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();
OpenPOWER on IntegriCloud