]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
4697abea | 2 | /* |
3 | * Copyright 2016 Google Inc. | |
4697abea | 4 | */ |
5 | ||
4697abea | 6 | #include <dm.h> |
7 | #include <errno.h> | |
8 | #include <timer.h> | |
9 | #include <asm/io.h> | |
10 | #include <asm/arch/timer.h> | |
61b29b82 | 11 | #include <linux/err.h> |
4697abea | 12 | |
4697abea | 13 | #define AST_TICK_TIMER 1 |
14 | #define AST_TMC_RELOAD_VAL 0xffffffff | |
15 | ||
16 | struct ast_timer_priv { | |
17 | struct ast_timer *regs; | |
18 | struct ast_timer_counter *tmc; | |
19 | }; | |
20 | ||
21 | static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer, | |
22 | int n) | |
23 | { | |
24 | if (n > 3) | |
25 | return &timer->timers2[n - 4]; | |
26 | else | |
27 | return &timer->timers1[n - 1]; | |
28 | } | |
29 | ||
30 | static int ast_timer_probe(struct udevice *dev) | |
31 | { | |
32 | struct ast_timer_priv *priv = dev_get_priv(dev); | |
33 | struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); | |
34 | ||
35 | writel(AST_TMC_RELOAD_VAL, &priv->tmc->reload_val); | |
36 | ||
37 | /* | |
38 | * Stop the timer. This will also load reload_val into | |
39 | * the status register. | |
40 | */ | |
41 | clrbits_le32(&priv->regs->ctrl1, | |
42 | AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER)); | |
43 | /* Start the timer from the fixed 1MHz clock. */ | |
44 | setbits_le32(&priv->regs->ctrl1, | |
45 | (AST_TMC_EN | AST_TMC_1MHZ) << | |
46 | AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER)); | |
47 | ||
48 | uc_priv->clock_rate = AST_TMC_RATE; | |
49 | ||
50 | return 0; | |
51 | } | |
52 | ||
8af7bb91 | 53 | static u64 ast_timer_get_count(struct udevice *dev) |
4697abea | 54 | { |
55 | struct ast_timer_priv *priv = dev_get_priv(dev); | |
56 | ||
8af7bb91 | 57 | return AST_TMC_RELOAD_VAL - readl(&priv->tmc->status); |
4697abea | 58 | } |
59 | ||
d1998a9f | 60 | static int ast_timer_of_to_plat(struct udevice *dev) |
4697abea | 61 | { |
62 | struct ast_timer_priv *priv = dev_get_priv(dev); | |
63 | ||
702e57e1 | 64 | priv->regs = dev_read_addr_ptr(dev); |
3fe69d37 OP |
65 | if (!priv->regs) |
66 | return -EINVAL; | |
4697abea | 67 | |
68 | priv->tmc = ast_get_timer_counter(priv->regs, AST_TICK_TIMER); | |
69 | ||
70 | return 0; | |
71 | } | |
72 | ||
73 | static const struct timer_ops ast_timer_ops = { | |
74 | .get_count = ast_timer_get_count, | |
75 | }; | |
76 | ||
77 | static const struct udevice_id ast_timer_ids[] = { | |
78 | { .compatible = "aspeed,ast2500-timer" }, | |
79 | { .compatible = "aspeed,ast2400-timer" }, | |
80 | { } | |
81 | }; | |
82 | ||
83 | U_BOOT_DRIVER(ast_timer) = { | |
84 | .name = "ast_timer", | |
85 | .id = UCLASS_TIMER, | |
86 | .of_match = ast_timer_ids, | |
87 | .probe = ast_timer_probe, | |
41575d8e | 88 | .priv_auto = sizeof(struct ast_timer_priv), |
d1998a9f | 89 | .of_to_plat = ast_timer_of_to_plat, |
4697abea | 90 | .ops = &ast_timer_ops, |
4697abea | 91 | }; |