From a4c3733d32a72f11dee86d0731d7565aa6ebe22d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 28 Oct 2019 13:10:32 +0100 Subject: riscv: abstract out CSR names for supervisor vs machine mode Many of the privileged CSRs exist in a supervisor and machine version that are used very similarly. Provide versions of the CSR names and fields that map to either the S-mode or M-mode variant depending on a new CONFIG_RISCV_M_MODE kconfig symbol. Contains contributions from Damien Le Moal and Paul Walmsley . Signed-off-by: Christoph Hellwig Acked-by: Thomas Gleixner # for drivers/clocksource, drivers/irqchip [paul.walmsley@sifive.com: updated to apply] Signed-off-by: Paul Walmsley --- drivers/clocksource/timer-riscv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index 470c7ef02ea4..d083bfb535f6 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -19,7 +19,7 @@ static int riscv_clock_next_event(unsigned long delta, struct clock_event_device *ce) { - csr_set(sie, SIE_STIE); + csr_set(CSR_IE, IE_TIE); sbi_set_timer(get_cycles64() + delta); return 0; } @@ -61,13 +61,13 @@ static int riscv_timer_starting_cpu(unsigned int cpu) ce->cpumask = cpumask_of(cpu); clockevents_config_and_register(ce, riscv_timebase, 100, 0x7fffffff); - csr_set(sie, SIE_STIE); + csr_set(CSR_IE, IE_TIE); return 0; } static int riscv_timer_dying_cpu(unsigned int cpu) { - csr_clear(sie, SIE_STIE); + csr_clear(CSR_IE, IE_TIE); return 0; } @@ -76,7 +76,7 @@ void riscv_timer_interrupt(void) { struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event); - csr_clear(sie, SIE_STIE); + csr_clear(CSR_IE, IE_TIE); evdev->event_handler(evdev); } -- cgit From 4f9bbcefa142862782275a4b29f390ca8d8b9242 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 28 Oct 2019 13:10:37 +0100 Subject: 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 Reviewed-by: Anup Patel Acked-by: Thomas Gleixner # for drivers/clocksource [paul.walmsley@sifive.com: updated to apply; fixed checkpatch issue; timex.h now includes asm/mmio.h to resolve header file problems] Signed-off-by: Paul Walmsley --- drivers/clocksource/timer-riscv.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index d083bfb535f6..4e54856ce2a5 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -3,9 +3,9 @@ * Copyright (C) 2012 Regents of the University of California * Copyright (C) 2017 SiFive * - * All RISC-V systems have a timer attached to every hart. These timers can be - * read from the "time" and "timeh" CSRs, and can use the SBI to setup - * events. + * All RISC-V systems have a timer attached to every hart. These timers can + * either be read from the "time" and "timeh" CSRs, and can use the SBI to + * setup events, or directly accessed using MMIO registers. */ #include #include @@ -13,14 +13,29 @@ #include #include #include +#include #include #include +u64 __iomem *riscv_time_cmp; +u64 __iomem *riscv_time_val; + +static inline void mmio_set_timer(u64 val) +{ + void __iomem *r; + + r = riscv_time_cmp + cpuid_to_hartid_map(smp_processor_id()); + writeq_relaxed(val, r); +} + static int riscv_clock_next_event(unsigned long delta, struct clock_event_device *ce) { csr_set(CSR_IE, IE_TIE); - sbi_set_timer(get_cycles64() + delta); + if (IS_ENABLED(CONFIG_RISCV_SBI)) + sbi_set_timer(get_cycles64() + delta); + else + mmio_set_timer(get_cycles64() + delta); return 0; } -- cgit