summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2019-08-21 10:58:36 -0400
committerPaul Walmsley <paul.walmsley@sifive.com>2019-09-05 04:52:46 -0400
commit2f12dbf190d97dc0f2f8a07269dd0d8060808539 (patch)
treed699e8fc51c7814904c0ab79c50a7144e243d544
parentf5bf645d10f2c6cc85294021af70f2b7bcc42d8e (diff)
riscv: don't use the rdtime(h) pseudo-instructions
If we just use the CSRs that these map to directly the code is simpler and doesn't require extra inline assembly code. Also fix up the top-level comment in timer-riscv.c to not talk about the cycle count or mention details of the clocksource interface, of which this file is just a consumer. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Atish Patra <atish.patra@wdc.com> Signed-off-by: Paul Walmsley <paul.walmsley@sifive.com>
-rw-r--r--arch/riscv/include/asm/timex.h44
-rw-r--r--drivers/clocksource/timer-riscv.c17
2 files changed, 25 insertions, 36 deletions
diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h
index 6a703ec9d796..c7ef131b9e4c 100644
--- a/arch/riscv/include/asm/timex.h
+++ b/arch/riscv/include/asm/timex.h
@@ -6,43 +6,41 @@
6#ifndef _ASM_RISCV_TIMEX_H 6#ifndef _ASM_RISCV_TIMEX_H
7#define _ASM_RISCV_TIMEX_H 7#define _ASM_RISCV_TIMEX_H
8 8
9#include <asm/param.h> 9#include <asm/csr.h>
10 10
11typedef unsigned long cycles_t; 11typedef unsigned long cycles_t;
12 12
13static inline cycles_t get_cycles_inline(void) 13static inline cycles_t get_cycles(void)
14{ 14{
15 cycles_t n; 15 return csr_read(CSR_TIME);
16
17 __asm__ __volatile__ (
18 "rdtime %0"
19 : "=r" (n));
20 return n;
21} 16}
22#define get_cycles get_cycles_inline 17#define get_cycles get_cycles
23 18
24#ifdef CONFIG_64BIT 19#ifdef CONFIG_64BIT
25static inline uint64_t get_cycles64(void) 20static inline u64 get_cycles64(void)
21{
22 return get_cycles();
23}
24#else /* CONFIG_64BIT */
25static inline u32 get_cycles_hi(void)
26{ 26{
27 return get_cycles(); 27 return csr_read(CSR_TIMEH);
28} 28}
29#else 29
30static inline uint64_t get_cycles64(void) 30static inline u64 get_cycles64(void)
31{ 31{
32 u32 lo, hi, tmp; 32 u32 hi, lo;
33 __asm__ __volatile__ ( 33
34 "1:\n" 34 do {
35 "rdtimeh %0\n" 35 hi = get_cycles_hi();
36 "rdtime %1\n" 36 lo = get_cycles();
37 "rdtimeh %2\n" 37 } while (hi != get_cycles_hi());
38 "bne %0, %2, 1b" 38
39 : "=&r" (hi), "=&r" (lo), "=&r" (tmp));
40 return ((u64)hi << 32) | lo; 39 return ((u64)hi << 32) | lo;
41} 40}
42#endif 41#endif /* CONFIG_64BIT */
43 42
44#define ARCH_HAS_READ_CURRENT_TIMER 43#define ARCH_HAS_READ_CURRENT_TIMER
45
46static inline int read_current_timer(unsigned long *timer_val) 44static inline int read_current_timer(unsigned long *timer_val)
47{ 45{
48 *timer_val = get_cycles(); 46 *timer_val = get_cycles();
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index 09e031176bc6..470c7ef02ea4 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -2,6 +2,10 @@
2/* 2/*
3 * Copyright (C) 2012 Regents of the University of California 3 * Copyright (C) 2012 Regents of the University of California
4 * Copyright (C) 2017 SiFive 4 * Copyright (C) 2017 SiFive
5 *
6 * All RISC-V systems have a timer attached to every hart. These timers can be
7 * read from the "time" and "timeh" CSRs, and can use the SBI to setup
8 * events.
5 */ 9 */
6#include <linux/clocksource.h> 10#include <linux/clocksource.h>
7#include <linux/clockchips.h> 11#include <linux/clockchips.h>
@@ -12,19 +16,6 @@
12#include <asm/smp.h> 16#include <asm/smp.h>
13#include <asm/sbi.h> 17#include <asm/sbi.h>
14 18
15/*
16 * All RISC-V systems have a timer attached to every hart. These timers can be
17 * read by the 'rdcycle' pseudo instruction, and can use the SBI to setup
18 * events. In order to abstract the architecture-specific timer reading and
19 * setting functions away from the clock event insertion code, we provide
20 * function pointers to the clockevent subsystem that perform two basic
21 * operations: rdtime() reads the timer on the current CPU, and
22 * next_event(delta) sets the next timer event to 'delta' cycles in the future.
23 * As the timers are inherently a per-cpu resource, these callbacks perform
24 * operations on the current hart. There is guaranteed to be exactly one timer
25 * per hart on all RISC-V systems.
26 */
27
28static int riscv_clock_next_event(unsigned long delta, 19static int riscv_clock_next_event(unsigned long delta,
29 struct clock_event_device *ce) 20 struct clock_event_device *ce)
30{ 21{