diff options
author | Christoph Hellwig <hch@lst.de> | 2019-08-21 10:58:36 -0400 |
---|---|---|
committer | Paul Walmsley <paul.walmsley@sifive.com> | 2019-09-05 04:52:46 -0400 |
commit | 2f12dbf190d97dc0f2f8a07269dd0d8060808539 (patch) | |
tree | d699e8fc51c7814904c0ab79c50a7144e243d544 | |
parent | f5bf645d10f2c6cc85294021af70f2b7bcc42d8e (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.h | 44 | ||||
-rw-r--r-- | drivers/clocksource/timer-riscv.c | 17 |
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 | ||
11 | typedef unsigned long cycles_t; | 11 | typedef unsigned long cycles_t; |
12 | 12 | ||
13 | static inline cycles_t get_cycles_inline(void) | 13 | static 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 |
25 | static inline uint64_t get_cycles64(void) | 20 | static inline u64 get_cycles64(void) |
21 | { | ||
22 | return get_cycles(); | ||
23 | } | ||
24 | #else /* CONFIG_64BIT */ | ||
25 | static inline u32 get_cycles_hi(void) | ||
26 | { | 26 | { |
27 | return get_cycles(); | 27 | return csr_read(CSR_TIMEH); |
28 | } | 28 | } |
29 | #else | 29 | |
30 | static inline uint64_t get_cycles64(void) | 30 | static 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 | |||
46 | static inline int read_current_timer(unsigned long *timer_val) | 44 | static 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 | |||
28 | static int riscv_clock_next_event(unsigned long delta, | 19 | static int riscv_clock_next_event(unsigned long delta, |
29 | struct clock_event_device *ce) | 20 | struct clock_event_device *ce) |
30 | { | 21 | { |