1*3d42b32bSDaniel Lezcano // SPDX-License-Identifier: GPL-2.0 2*3d42b32bSDaniel Lezcano /* 3*3d42b32bSDaniel Lezcano * Copyright (C) 2012 Regents of the University of California 4*3d42b32bSDaniel Lezcano * Copyright (C) 2017 SiFive 5*3d42b32bSDaniel Lezcano */ 6*3d42b32bSDaniel Lezcano #include <linux/clocksource.h> 7*3d42b32bSDaniel Lezcano #include <linux/clockchips.h> 8*3d42b32bSDaniel Lezcano #include <linux/cpu.h> 9*3d42b32bSDaniel Lezcano #include <linux/delay.h> 10*3d42b32bSDaniel Lezcano #include <linux/irq.h> 11*3d42b32bSDaniel Lezcano #include <linux/sched_clock.h> 12*3d42b32bSDaniel Lezcano #include <asm/smp.h> 13*3d42b32bSDaniel Lezcano #include <asm/sbi.h> 14*3d42b32bSDaniel Lezcano 15*3d42b32bSDaniel Lezcano /* 16*3d42b32bSDaniel Lezcano * All RISC-V systems have a timer attached to every hart. These timers can be 17*3d42b32bSDaniel Lezcano * read by the 'rdcycle' pseudo instruction, and can use the SBI to setup 18*3d42b32bSDaniel Lezcano * events. In order to abstract the architecture-specific timer reading and 19*3d42b32bSDaniel Lezcano * setting functions away from the clock event insertion code, we provide 20*3d42b32bSDaniel Lezcano * function pointers to the clockevent subsystem that perform two basic 21*3d42b32bSDaniel Lezcano * operations: rdtime() reads the timer on the current CPU, and 22*3d42b32bSDaniel Lezcano * next_event(delta) sets the next timer event to 'delta' cycles in the future. 23*3d42b32bSDaniel Lezcano * As the timers are inherently a per-cpu resource, these callbacks perform 24*3d42b32bSDaniel Lezcano * operations on the current hart. There is guaranteed to be exactly one timer 25*3d42b32bSDaniel Lezcano * per hart on all RISC-V systems. 26*3d42b32bSDaniel Lezcano */ 27*3d42b32bSDaniel Lezcano 28*3d42b32bSDaniel Lezcano static int riscv_clock_next_event(unsigned long delta, 29*3d42b32bSDaniel Lezcano struct clock_event_device *ce) 30*3d42b32bSDaniel Lezcano { 31*3d42b32bSDaniel Lezcano csr_set(sie, SIE_STIE); 32*3d42b32bSDaniel Lezcano sbi_set_timer(get_cycles64() + delta); 33*3d42b32bSDaniel Lezcano return 0; 34*3d42b32bSDaniel Lezcano } 35*3d42b32bSDaniel Lezcano 36*3d42b32bSDaniel Lezcano static DEFINE_PER_CPU(struct clock_event_device, riscv_clock_event) = { 37*3d42b32bSDaniel Lezcano .name = "riscv_timer_clockevent", 38*3d42b32bSDaniel Lezcano .features = CLOCK_EVT_FEAT_ONESHOT, 39*3d42b32bSDaniel Lezcano .rating = 100, 40*3d42b32bSDaniel Lezcano .set_next_event = riscv_clock_next_event, 41*3d42b32bSDaniel Lezcano }; 42*3d42b32bSDaniel Lezcano 43*3d42b32bSDaniel Lezcano /* 44*3d42b32bSDaniel Lezcano * It is guaranteed that all the timers across all the harts are synchronized 45*3d42b32bSDaniel Lezcano * within one tick of each other, so while this could technically go 46*3d42b32bSDaniel Lezcano * backwards when hopping between CPUs, practically it won't happen. 47*3d42b32bSDaniel Lezcano */ 48*3d42b32bSDaniel Lezcano static unsigned long long riscv_clocksource_rdtime(struct clocksource *cs) 49*3d42b32bSDaniel Lezcano { 50*3d42b32bSDaniel Lezcano return get_cycles64(); 51*3d42b32bSDaniel Lezcano } 52*3d42b32bSDaniel Lezcano 53*3d42b32bSDaniel Lezcano static u64 riscv_sched_clock(void) 54*3d42b32bSDaniel Lezcano { 55*3d42b32bSDaniel Lezcano return get_cycles64(); 56*3d42b32bSDaniel Lezcano } 57*3d42b32bSDaniel Lezcano 58*3d42b32bSDaniel Lezcano static DEFINE_PER_CPU(struct clocksource, riscv_clocksource) = { 59*3d42b32bSDaniel Lezcano .name = "riscv_clocksource", 60*3d42b32bSDaniel Lezcano .rating = 300, 61*3d42b32bSDaniel Lezcano .mask = CLOCKSOURCE_MASK(BITS_PER_LONG), 62*3d42b32bSDaniel Lezcano .flags = CLOCK_SOURCE_IS_CONTINUOUS, 63*3d42b32bSDaniel Lezcano .read = riscv_clocksource_rdtime, 64*3d42b32bSDaniel Lezcano }; 65*3d42b32bSDaniel Lezcano 66*3d42b32bSDaniel Lezcano static int riscv_timer_starting_cpu(unsigned int cpu) 67*3d42b32bSDaniel Lezcano { 68*3d42b32bSDaniel Lezcano struct clock_event_device *ce = per_cpu_ptr(&riscv_clock_event, cpu); 69*3d42b32bSDaniel Lezcano 70*3d42b32bSDaniel Lezcano ce->cpumask = cpumask_of(cpu); 71*3d42b32bSDaniel Lezcano clockevents_config_and_register(ce, riscv_timebase, 100, 0x7fffffff); 72*3d42b32bSDaniel Lezcano 73*3d42b32bSDaniel Lezcano csr_set(sie, SIE_STIE); 74*3d42b32bSDaniel Lezcano return 0; 75*3d42b32bSDaniel Lezcano } 76*3d42b32bSDaniel Lezcano 77*3d42b32bSDaniel Lezcano static int riscv_timer_dying_cpu(unsigned int cpu) 78*3d42b32bSDaniel Lezcano { 79*3d42b32bSDaniel Lezcano csr_clear(sie, SIE_STIE); 80*3d42b32bSDaniel Lezcano return 0; 81*3d42b32bSDaniel Lezcano } 82*3d42b32bSDaniel Lezcano 83*3d42b32bSDaniel Lezcano /* called directly from the low-level interrupt handler */ 84*3d42b32bSDaniel Lezcano void riscv_timer_interrupt(void) 85*3d42b32bSDaniel Lezcano { 86*3d42b32bSDaniel Lezcano struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event); 87*3d42b32bSDaniel Lezcano 88*3d42b32bSDaniel Lezcano csr_clear(sie, SIE_STIE); 89*3d42b32bSDaniel Lezcano evdev->event_handler(evdev); 90*3d42b32bSDaniel Lezcano } 91*3d42b32bSDaniel Lezcano 92*3d42b32bSDaniel Lezcano static int __init riscv_timer_init_dt(struct device_node *n) 93*3d42b32bSDaniel Lezcano { 94*3d42b32bSDaniel Lezcano int cpuid, hartid, error; 95*3d42b32bSDaniel Lezcano struct clocksource *cs; 96*3d42b32bSDaniel Lezcano 97*3d42b32bSDaniel Lezcano hartid = riscv_of_processor_hartid(n); 98*3d42b32bSDaniel Lezcano cpuid = riscv_hartid_to_cpuid(hartid); 99*3d42b32bSDaniel Lezcano 100*3d42b32bSDaniel Lezcano if (cpuid != smp_processor_id()) 101*3d42b32bSDaniel Lezcano return 0; 102*3d42b32bSDaniel Lezcano 103*3d42b32bSDaniel Lezcano cs = per_cpu_ptr(&riscv_clocksource, cpuid); 104*3d42b32bSDaniel Lezcano clocksource_register_hz(cs, riscv_timebase); 105*3d42b32bSDaniel Lezcano 106*3d42b32bSDaniel Lezcano sched_clock_register(riscv_sched_clock, 107*3d42b32bSDaniel Lezcano BITS_PER_LONG, riscv_timebase); 108*3d42b32bSDaniel Lezcano 109*3d42b32bSDaniel Lezcano error = cpuhp_setup_state(CPUHP_AP_RISCV_TIMER_STARTING, 110*3d42b32bSDaniel Lezcano "clockevents/riscv/timer:starting", 111*3d42b32bSDaniel Lezcano riscv_timer_starting_cpu, riscv_timer_dying_cpu); 112*3d42b32bSDaniel Lezcano if (error) 113*3d42b32bSDaniel Lezcano pr_err("RISCV timer register failed [%d] for cpu = [%d]\n", 114*3d42b32bSDaniel Lezcano error, cpuid); 115*3d42b32bSDaniel Lezcano return error; 116*3d42b32bSDaniel Lezcano } 117*3d42b32bSDaniel Lezcano 118*3d42b32bSDaniel Lezcano TIMER_OF_DECLARE(riscv_timer, "riscv", riscv_timer_init_dt); 119