]> Git Repo - J-u-boot.git/blob - drivers/timer/starfive-timer.c
Merge tag 'v2024.07-rc5' into next
[J-u-boot.git] / drivers / timer / starfive-timer.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2022 StarFive, Inc. All rights reserved.
4  *   Author: Kuan Lim Lee <[email protected]>
5  */
6
7 #include <clk.h>
8 #include <dm.h>
9 #include <time.h>
10 #include <timer.h>
11 #include <asm/io.h>
12 #include <dm/device-internal.h>
13 #include <linux/err.h>
14
15 #define STF_TIMER_INT_STATUS    0x00
16 #define STF_TIMER_CTL           0x04
17 #define STF_TIMER_LOAD          0x08
18 #define STF_TIMER_ENABLE        0x10
19 #define STF_TIMER_RELOAD        0x14
20 #define STF_TIMER_VALUE         0x18
21 #define STF_TIMER_INT_CLR       0x20
22 #define STF_TIMER_INT_MASK      0x24
23
24 struct starfive_timer_priv {
25         void __iomem *base;
26         u32 timer_size;
27 };
28
29 static u64 notrace starfive_get_count(struct udevice *dev)
30 {
31         struct starfive_timer_priv *priv = dev_get_priv(dev);
32
33         /* Read decrement timer value and convert to increment value */
34         return priv->timer_size - readl(priv->base + STF_TIMER_VALUE);
35 }
36
37 static const struct timer_ops starfive_ops = {
38         .get_count = starfive_get_count,
39 };
40
41 static int starfive_probe(struct udevice *dev)
42 {
43         struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
44         struct starfive_timer_priv *priv = dev_get_priv(dev);
45         int timer_channel;
46         struct clk clk;
47         int ret;
48
49         priv->base = dev_read_addr_ptr(dev);
50         if (!priv->base)
51                 return -EINVAL;
52
53         timer_channel = dev_read_u32_default(dev, "channel", 0);
54         priv->base = priv->base + (0x40 * timer_channel);
55
56         /* Get clock rate from channel selectecd*/
57         ret = clk_get_by_index(dev, timer_channel, &clk);
58         if (ret)
59                 return ret;
60
61         ret = clk_enable(&clk);
62         if (ret)
63                 return ret;
64         uc_priv->clock_rate = clk_get_rate(&clk);
65
66         /*
67          * Initiate timer, channel 0
68          * Unmask Interrupt Mask
69          */
70         writel(0, priv->base + STF_TIMER_INT_MASK);
71         /* Single run mode Setting */
72         if (dev_read_bool(dev, "single-run"))
73                 writel(1, priv->base + STF_TIMER_CTL);
74         /* Set Reload value */
75         priv->timer_size = dev_read_u32_default(dev, "timer-size", -1U);
76         writel(priv->timer_size, priv->base + STF_TIMER_LOAD);
77         /* Enable to start timer */
78         writel(1, priv->base + STF_TIMER_ENABLE);
79
80         return 0;
81 }
82
83 static const struct udevice_id starfive_ids[] = {
84         { .compatible = "starfive,jh8100-timers" },
85         { }
86 };
87
88 U_BOOT_DRIVER(jh8100_starfive_timer) = {
89         .name           = "starfive_timer",
90         .id             = UCLASS_TIMER,
91         .of_match       = starfive_ids,
92         .probe          = starfive_probe,
93         .ops            = &starfive_ops,
94         .priv_auto      = sizeof(struct starfive_timer_priv),
95 };
This page took 0.028972 seconds and 4 git commands to generate.