blob: 21ae1840571a23d29d12b494d89f5b8352b190a1 [file] [log] [blame]
Bin Meng60262cd02018-12-12 06:12:27 -08001// SPDX-License-Identifier: GPL-2.0+
2/*
Sean Andersonc33efaf2020-09-28 10:52:21 -04003 * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
Bin Meng60262cd02018-12-12 06:12:27 -08004 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
Sean Andersonc33efaf2020-09-28 10:52:21 -04005 * Copyright (C) 2018, Anup Patel <anup@brainfault.org>
6 * Copyright (C) 2012 Regents of the University of California
Bin Meng60262cd02018-12-12 06:12:27 -08007 *
Sean Andersonc33efaf2020-09-28 10:52:21 -04008 * RISC-V architecturally-defined generic timer driver
Bin Meng60262cd02018-12-12 06:12:27 -08009 *
Sean Andersonc33efaf2020-09-28 10:52:21 -040010 * This driver provides generic timer support for S-mode U-Boot.
Bin Meng60262cd02018-12-12 06:12:27 -080011 */
12
13#include <common.h>
14#include <dm.h>
15#include <errno.h>
16#include <timer.h>
Sean Andersonc33efaf2020-09-28 10:52:21 -040017#include <asm/csr.h>
Bin Meng60262cd02018-12-12 06:12:27 -080018
Sean Anderson8af7bb92020-10-07 14:37:44 -040019static u64 riscv_timer_get_count(struct udevice *dev)
Bin Meng60262cd02018-12-12 06:12:27 -080020{
Sean Anderson8af7bb92020-10-07 14:37:44 -040021 __maybe_unused u32 hi, lo;
Sean Andersonc33efaf2020-09-28 10:52:21 -040022
Sean Anderson8af7bb92020-10-07 14:37:44 -040023 if (IS_ENABLED(CONFIG_64BIT))
24 return csr_read(CSR_TIME);
Sean Andersonc33efaf2020-09-28 10:52:21 -040025
Sean Anderson8af7bb92020-10-07 14:37:44 -040026 do {
27 hi = csr_read(CSR_TIMEH);
28 lo = csr_read(CSR_TIME);
29 } while (hi != csr_read(CSR_TIMEH));
Sean Andersonc33efaf2020-09-28 10:52:21 -040030
Sean Anderson8af7bb92020-10-07 14:37:44 -040031 return ((u64)hi << 32) | lo;
Bin Meng60262cd02018-12-12 06:12:27 -080032}
33
34static int riscv_timer_probe(struct udevice *dev)
35{
36 struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
37
38 /* clock frequency was passed from the cpu driver as driver data */
39 uc_priv->clock_rate = dev->driver_data;
40
41 return 0;
42}
43
44static const struct timer_ops riscv_timer_ops = {
45 .get_count = riscv_timer_get_count,
46};
47
48U_BOOT_DRIVER(riscv_timer) = {
49 .name = "riscv_timer",
50 .id = UCLASS_TIMER,
51 .probe = riscv_timer_probe,
52 .ops = &riscv_timer_ops,
53 .flags = DM_FLAG_PRE_RELOC,
54};