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);
}