Skip to content

Commit 4f9bbce

Browse files
Christoph Hellwigpaul-walmsley-sifive
authored andcommitted
riscv: add support for MMIO access to the timer registers
When running in M-mode we can't use the SBI to set the timer, and don't have access to the time CSR as that usually is emulated by M-mode. Instead provide code that directly accesses the MMIO for the timer. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Anup Patel <[email protected]> Acked-by: Thomas Gleixner <[email protected]> # for drivers/clocksource [[email protected]: updated to apply; fixed checkpatch issue; timex.h now includes asm/mmio.h to resolve header file problems] Signed-off-by: Paul Walmsley <[email protected]>
1 parent 8bf90f3 commit 4f9bbce

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

arch/riscv/include/asm/sbi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
9595
SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid);
9696
}
9797
#else /* CONFIG_RISCV_SBI */
98-
/* stub for code that is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
98+
/* stubs for code that is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */
99+
void sbi_set_timer(uint64_t stime_value);
99100
void sbi_remote_fence_i(const unsigned long *hart_mask);
100101
#endif /* CONFIG_RISCV_SBI */
101102
#endif /* _ASM_RISCV_SBI_H */

arch/riscv/include/asm/timex.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,25 @@
77
#define _ASM_RISCV_TIMEX_H
88

99
#include <asm/csr.h>
10+
#include <asm/mmio.h>
1011

1112
typedef unsigned long cycles_t;
1213

14+
extern u64 __iomem *riscv_time_val;
15+
extern u64 __iomem *riscv_time_cmp;
16+
17+
#ifdef CONFIG_64BIT
18+
#define mmio_get_cycles() readq_relaxed(riscv_time_val)
19+
#else
20+
#define mmio_get_cycles() readl_relaxed(riscv_time_val)
21+
#define mmio_get_cycles_hi() readl_relaxed(((u32 *)riscv_time_val) + 1)
22+
#endif
23+
1324
static inline cycles_t get_cycles(void)
1425
{
15-
return csr_read(CSR_TIME);
26+
if (IS_ENABLED(CONFIG_RISCV_SBI))
27+
return csr_read(CSR_TIME);
28+
return mmio_get_cycles();
1629
}
1730
#define get_cycles get_cycles
1831

@@ -24,7 +37,9 @@ static inline u64 get_cycles64(void)
2437
#else /* CONFIG_64BIT */
2538
static inline u32 get_cycles_hi(void)
2639
{
27-
return csr_read(CSR_TIMEH);
40+
if (IS_ENABLED(CONFIG_RISCV_SBI))
41+
return csr_read(CSR_TIMEH);
42+
return mmio_get_cycles_hi();
2843
}
2944

3045
static inline u64 get_cycles64(void)

drivers/clocksource/timer-riscv.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,39 @@
33
* Copyright (C) 2012 Regents of the University of California
44
* Copyright (C) 2017 SiFive
55
*
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.
6+
* All RISC-V systems have a timer attached to every hart. These timers can
7+
* either be read from the "time" and "timeh" CSRs, and can use the SBI to
8+
* setup events, or directly accessed using MMIO registers.
99
*/
1010
#include <linux/clocksource.h>
1111
#include <linux/clockchips.h>
1212
#include <linux/cpu.h>
1313
#include <linux/delay.h>
1414
#include <linux/irq.h>
1515
#include <linux/sched_clock.h>
16+
#include <linux/io-64-nonatomic-lo-hi.h>
1617
#include <asm/smp.h>
1718
#include <asm/sbi.h>
1819

20+
u64 __iomem *riscv_time_cmp;
21+
u64 __iomem *riscv_time_val;
22+
23+
static inline void mmio_set_timer(u64 val)
24+
{
25+
void __iomem *r;
26+
27+
r = riscv_time_cmp + cpuid_to_hartid_map(smp_processor_id());
28+
writeq_relaxed(val, r);
29+
}
30+
1931
static int riscv_clock_next_event(unsigned long delta,
2032
struct clock_event_device *ce)
2133
{
2234
csr_set(CSR_IE, IE_TIE);
23-
sbi_set_timer(get_cycles64() + delta);
35+
if (IS_ENABLED(CONFIG_RISCV_SBI))
36+
sbi_set_timer(get_cycles64() + delta);
37+
else
38+
mmio_set_timer(get_cycles64() + delta);
2439
return 0;
2540
}
2641

0 commit comments

Comments
 (0)