From 61fef9e8601a39e6d7dca611a7bba9b60bf327d7 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Wed, 27 Mar 2019 16:26:03 +0000 Subject: [PATCH] Grab timer frequency from FDT. RISC-V timer has no dedicated DTS node and we have to get timer frequency from cpus node. Tested on Government Furnished Equipment (GFE) cores synthesized on Xilinx VCU118. Reviewed by: markj Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D19727 --- sys/riscv/riscv/timer.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/sys/riscv/riscv/timer.c b/sys/riscv/riscv/timer.c index 93d0cefbc3a5..5ee5ca221584 100644 --- a/sys/riscv/riscv/timer.c +++ b/sys/riscv/riscv/timer.c @@ -61,7 +61,10 @@ __FBSDID("$FreeBSD$"); #include #include -#define DEFAULT_FREQ 10000000 +#include +#include +#include +#include #define TIMER_COUNTS 0x00 #define TIMER_MTIMECMP(cpu) (cpu * 8) @@ -156,6 +159,32 @@ riscv_timer_intr(void *arg) return (FILTER_HANDLED); } +static int +riscv_timer_get_timebase(device_t dev, uint32_t *freq) +{ + phandle_t node; + int len; + + node = OF_finddevice("/cpus"); + if (node == -1) { + if (bootverbose) + device_printf(dev, "Can't find cpus node.\n"); + return (ENXIO); + } + + len = OF_getproplen(node, "timebase-frequency"); + if (len != 4) { + if (bootverbose) + device_printf(dev, + "Can't find timebase-frequency property.\n"); + return (ENXIO); + } + + OF_getencprop(node, "timebase-frequency", freq, len); + + return (0); +} + static int riscv_timer_probe(device_t dev) { @@ -176,10 +205,9 @@ riscv_timer_attach(device_t dev) return (ENXIO); if (device_get_unit(dev) != 0) - return ENXIO; + return (ENXIO); - sc->clkfreq = DEFAULT_FREQ; - if (sc->clkfreq == 0) { + if (riscv_timer_get_timebase(dev, &sc->clkfreq) != 0) { device_printf(dev, "No clock frequency specified\n"); return (ENXIO); }