aboutsummaryrefslogtreecommitdiff
path: root/drivers/timer
diff options
context:
space:
mode:
authorTorsten Duwe <duwe@lst.de>2023-08-14 18:05:28 +0200
committerLeo Yu-Chi Liang <ycliang@andestech.com>2023-09-05 10:53:36 +0800
commitf39f8f77a5268530e982aa38e921c640d532a9ae (patch)
tree642d81d389f8fc5ba2b43d9054e45aa89d73fc0e /drivers/timer
parent71914337ef579bb22705d4b88fee6b1448f7a9b1 (diff)
riscv: allow riscv timer to be instantiated via device tree
For the architectural timer on riscv, there already is a defined device tree binding[1]. Allow timer instances to be created from device tree matches, but for now retain the old mechanism, which registers the timer biggy-back with the CPU. [1] linux/Documentation/devicetree/bindings/timer/riscv,timer.yaml Signed-off-by: Torsten Duwe <duwe@suse.de> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Diffstat (limited to 'drivers/timer')
-rw-r--r--drivers/timer/riscv_timer.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c
index 3627ed79b8..28a6a6870b 100644
--- a/drivers/timer/riscv_timer.c
+++ b/drivers/timer/riscv_timer.c
@@ -13,6 +13,7 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
+#include <fdt_support.h>
#include <timer.h>
#include <asm/csr.h>
@@ -53,9 +54,26 @@ u64 notrace timer_early_get_count(void)
static int riscv_timer_probe(struct udevice *dev)
{
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ u32 rate;
- /* clock frequency was passed from the cpu driver as driver data */
- uc_priv->clock_rate = dev->driver_data;
+ /* When this function was called from the CPU driver, clock
+ * frequency is passed as driver data.
+ */
+ rate = dev->driver_data;
+
+ /* When called from an FDT match, the rate needs to be looked up. */
+ if (!rate && gd->fdt_blob) {
+ rate = fdt_getprop_u32_default(gd->fdt_blob,
+ "/cpus", "timebase-frequency", 0);
+ }
+
+ uc_priv->clock_rate = rate;
+
+ /* With rate==0, timer uclass post_probe might later fail with -EINVAL.
+ * Give a hint at the cause for debugging.
+ */
+ if (!rate)
+ log_err("riscv_timer_probe with invalid clock rate 0!\n");
return 0;
}
@@ -64,9 +82,15 @@ static const struct timer_ops riscv_timer_ops = {
.get_count = riscv_timer_get_count,
};
+static const struct udevice_id riscv_timer_ids[] = {
+ { .compatible = "riscv,timer", },
+ { }
+};
+
U_BOOT_DRIVER(riscv_timer) = {
.name = "riscv_timer",
.id = UCLASS_TIMER,
+ .of_match = of_match_ptr(riscv_timer_ids),
.probe = riscv_timer_probe,
.ops = &riscv_timer_ops,
.flags = DM_FLAG_PRE_RELOC,