1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
6 #define LOG_CATEGORY UCLASS_TIMER
12 #include <asm/global_data.h>
14 #include <dm/device_compat.h>
15 #include <dm/device-internal.h>
20 #include <linux/err.h>
23 DECLARE_GLOBAL_DATA_PTR
;
26 * Implement a timer uclass to work with lib/time.c. The timer is usually
27 * a 32/64 bits free-running up counter. The get_rate() method is used to get
28 * the input clock frequency of the timer. The get_count() method is used
29 * to get the current 64 bits count value. If the hardware is counting down,
30 * the value should be inversed inside the method. There may be no real
31 * tick, and no timer interrupt.
34 int notrace
timer_get_count(struct udevice
*dev
, u64
*count
)
36 struct timer_ops
*ops
= timer_get_ops(dev
);
41 *count
= ops
->get_count(dev
);
45 unsigned long notrace
timer_get_rate(struct udevice
*dev
)
47 struct timer_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
49 return uc_priv
->clock_rate
;
52 static int timer_pre_probe(struct udevice
*dev
)
54 if (CONFIG_IS_ENABLED(OF_REAL
)) {
55 struct timer_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
61 * It is possible that a timer device has a null ofnode
63 if (!dev_has_ofnode(dev
))
66 err
= clk_get_by_index(dev
, 0, &timer_clk
);
68 ret
= clk_get_rate(&timer_clk
);
69 if (!IS_ERR_VALUE(ret
)) {
70 uc_priv
->clock_rate
= ret
;
75 uc_priv
->clock_rate
= dev_read_u32_default(dev
, "clock-frequency", 0);
81 static int timer_post_probe(struct udevice
*dev
)
83 struct timer_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
85 if (!uc_priv
->clock_rate
)
91 #if CONFIG_IS_ENABLED(CPU)
92 int timer_timebase_fallback(struct udevice
*dev
)
95 struct cpu_plat
*cpu_plat
;
96 struct timer_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
98 /* Did we get our clock rate from the device tree? */
99 if (uc_priv
->clock_rate
)
102 /* Fall back to timebase-frequency */
103 dev_dbg(dev
, "missing clocks or clock-frequency property; falling back on timebase-frequency\n");
104 cpu
= cpu_get_current_dev();
108 cpu_plat
= dev_get_parent_plat(cpu
);
112 uc_priv
->clock_rate
= cpu_plat
->timebase_freq
;
117 u64
timer_conv_64(u32 count
)
119 /* increment tbh if tbl has rolled over */
120 if (count
< gd
->timebase_l
)
122 gd
->timebase_l
= count
;
123 return ((u64
)gd
->timebase_h
<< 32) | gd
->timebase_l
;
126 int dm_timer_init(void)
128 struct udevice
*dev
= NULL
;
129 __maybe_unused ofnode node
;
136 * Directly access gd->dm_root to suppress error messages, if the
137 * virtual root driver does not yet exist.
139 if (gd
->dm_root
== NULL
)
142 if (CONFIG_IS_ENABLED(OF_REAL
)) {
143 /* Check for a chosen timer to be used for tick */
144 node
= ofnode_get_chosen_node("tick-timer");
146 if (ofnode_valid(node
) &&
147 uclass_get_device_by_ofnode(UCLASS_TIMER
, node
, &dev
)) {
149 * If the timer is not marked to be bound before
150 * relocation, bind it anyway.
152 if (!lists_bind_fdt(dm_root(), node
, &dev
, NULL
, false)) {
153 ret
= device_probe(dev
);
161 /* Fall back to the first available timer */
162 ret
= uclass_first_device_err(UCLASS_TIMER
, &dev
);
175 UCLASS_DRIVER(timer
) = {
178 .pre_probe
= timer_pre_probe
,
179 .flags
= DM_UC_FLAG_SEQ_ALIAS
,
180 .post_probe
= timer_post_probe
,
181 .per_device_auto
= sizeof(struct timer_dev_priv
),