d7d1a1b24462cc0d87d1b2ff8a31ef7be5879933
[platform/kernel/u-boot.git] / drivers / timer / orion-timer.c
1 // SPDX-License-Identifier: GPL-2.0+
2 #include <asm/io.h>
3 #include <common.h>
4 #include <dm/device.h>
5 #include <dm/fdtaddr.h>
6 #include <timer.h>
7
8 #define TIMER_CTRL              0x00
9 #define TIMER0_EN               BIT(0)
10 #define TIMER0_RELOAD_EN        BIT(1)
11 #define TIMER0_RELOAD           0x10
12 #define TIMER0_VAL              0x14
13
14 struct orion_timer_priv {
15         void *base;
16 };
17
18 static uint64_t orion_timer_get_count(struct udevice *dev)
19 {
20         struct orion_timer_priv *priv = dev_get_priv(dev);
21
22         return timer_conv_64(~readl(priv->base + TIMER0_VAL));
23 }
24
25 static int orion_timer_probe(struct udevice *dev)
26 {
27         struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
28         struct orion_timer_priv *priv = dev_get_priv(dev);
29
30         priv->base = devfdt_remap_addr_index(dev, 0);
31         if (!priv->base) {
32                 debug("unable to map registers\n");
33                 return -ENOMEM;
34         }
35
36         uc_priv->clock_rate = CONFIG_SYS_TCLK;
37
38         writel(~0, priv->base + TIMER0_VAL);
39         writel(~0, priv->base + TIMER0_RELOAD);
40
41         /* enable timer */
42         setbits_le32(priv->base + TIMER_CTRL, TIMER0_EN | TIMER0_RELOAD_EN);
43
44         return 0;
45 }
46
47 static const struct timer_ops orion_timer_ops = {
48         .get_count = orion_timer_get_count,
49 };
50
51 static const struct udevice_id orion_timer_ids[] = {
52         { .compatible = "marvell,orion-timer" },
53         {}
54 };
55
56 U_BOOT_DRIVER(orion_timer) = {
57         .name   = "orion_timer",
58         .id     = UCLASS_TIMER,
59         .of_match = orion_timer_ids,
60         .probe = orion_timer_probe,
61         .ops    = &orion_timer_ops,
62         .priv_auto      = sizeof(struct orion_timer_priv),
63 };