blob: e29d527c8d778db5c0157c8a6930f59b2dd67087 [file] [log] [blame]
Sean Anderson52a1db72020-10-25 21:46:58 -04001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
4 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
5 */
6
7#include <common.h>
8#include <clk.h>
9#include <dm.h>
10#include <timer.h>
11#include <asm/io.h>
Simon Glass95588622020-12-22 19:30:28 -070012#include <dm/device-internal.h>
Sean Anderson52a1db72020-10-25 21:46:58 -040013#include <linux/err.h>
14
Bin Meng51e38552023-06-21 23:11:44 +080015#define CLINT_MTIME_OFFSET 0xbff8
16#define ACLINT_MTIME_OFFSET 0
17
Sean Anderson52a1db72020-10-25 21:46:58 -040018/* mtime register */
Bin Meng51e38552023-06-21 23:11:44 +080019#define MTIME_REG(base, offset) ((ulong)(base) + (offset))
Sean Anderson52a1db72020-10-25 21:46:58 -040020
Bin Mengb5f03722023-06-21 23:11:46 +080021static u64 notrace riscv_aclint_timer_get_count(struct udevice *dev)
Sean Anderson52a1db72020-10-25 21:46:58 -040022{
Bin Meng51e38552023-06-21 23:11:44 +080023 return readq((void __iomem *)MTIME_REG(dev_get_priv(dev),
24 dev_get_driver_data(dev)));
Sean Anderson52a1db72020-10-25 21:46:58 -040025}
26
Pragnesh Patel02038c32021-01-17 18:11:25 +053027#if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
28/**
29 * timer_early_get_rate() - Get the timer rate before driver model
30 */
31unsigned long notrace timer_early_get_rate(void)
32{
33 return RISCV_MMODE_TIMER_FREQ;
34}
35
36/**
37 * timer_early_get_count() - Get the timer count before driver model
38 *
39 */
40u64 notrace timer_early_get_count(void)
41{
Bin Meng51e38552023-06-21 23:11:44 +080042 return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE,
43 RISCV_MMODE_TIMEROFF));
Pragnesh Patel02038c32021-01-17 18:11:25 +053044}
45#endif
46
Bin Mengb5f03722023-06-21 23:11:46 +080047static const struct timer_ops riscv_aclint_timer_ops = {
48 .get_count = riscv_aclint_timer_get_count,
Sean Anderson52a1db72020-10-25 21:46:58 -040049};
50
Bin Mengb5f03722023-06-21 23:11:46 +080051static int riscv_aclint_timer_probe(struct udevice *dev)
Sean Anderson52a1db72020-10-25 21:46:58 -040052{
Simon Glass95588622020-12-22 19:30:28 -070053 dev_set_priv(dev, dev_read_addr_ptr(dev));
54 if (!dev_get_priv(dev))
Sean Anderson52a1db72020-10-25 21:46:58 -040055 return -EINVAL;
56
57 return timer_timebase_fallback(dev);
58}
59
Bin Mengb5f03722023-06-21 23:11:46 +080060static const struct udevice_id riscv_aclint_timer_ids[] = {
Bin Meng51e38552023-06-21 23:11:44 +080061 { .compatible = "riscv,clint0", .data = CLINT_MTIME_OFFSET },
62 { .compatible = "sifive,clint0", .data = CLINT_MTIME_OFFSET },
63 { .compatible = "riscv,aclint-mtimer", .data = ACLINT_MTIME_OFFSET },
Sean Anderson52a1db72020-10-25 21:46:58 -040064 { }
65};
66
Bin Mengb5f03722023-06-21 23:11:46 +080067U_BOOT_DRIVER(riscv_aclint_timer) = {
68 .name = "riscv_aclint_timer",
Sean Anderson52a1db72020-10-25 21:46:58 -040069 .id = UCLASS_TIMER,
Bin Mengb5f03722023-06-21 23:11:46 +080070 .of_match = riscv_aclint_timer_ids,
71 .probe = riscv_aclint_timer_probe,
72 .ops = &riscv_aclint_timer_ops,
Sean Anderson52a1db72020-10-25 21:46:58 -040073 .flags = DM_FLAG_PRE_RELOC,
74};