]>
Commit | Line | Data |
---|---|---|
347cb2ed PC |
1 | /* |
2 | * (C) Copyright 2017 Patrice Chotard <patrice.chotard@st.com> | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <dm.h> | |
9 | #include <fdtdec.h> | |
10 | #include <timer.h> | |
11 | ||
12 | #include <asm/io.h> | |
13 | #include <asm/arch-armv7/globaltimer.h> | |
14 | ||
15 | DECLARE_GLOBAL_DATA_PTR; | |
16 | ||
17 | struct sti_timer_priv { | |
18 | struct globaltimer *global_timer; | |
19 | }; | |
20 | ||
21 | static int sti_timer_get_count(struct udevice *dev, u64 *count) | |
22 | { | |
23 | struct sti_timer_priv *priv = dev_get_priv(dev); | |
24 | struct globaltimer *global_timer = priv->global_timer; | |
25 | u32 low, high; | |
26 | u64 timer; | |
27 | u32 old = readl(&global_timer->cnt_h); | |
28 | ||
29 | while (1) { | |
30 | low = readl(&global_timer->cnt_l); | |
31 | high = readl(&global_timer->cnt_h); | |
32 | if (old == high) | |
33 | break; | |
34 | else | |
35 | old = high; | |
36 | } | |
37 | timer = high; | |
38 | *count = (u64)((timer << 32) | low); | |
39 | ||
40 | return 0; | |
41 | } | |
42 | ||
43 | static int sti_timer_probe(struct udevice *dev) | |
44 | { | |
45 | struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); | |
46 | struct sti_timer_priv *priv = dev_get_priv(dev); | |
47 | fdt_addr_t addr; | |
48 | ||
49 | uc_priv->clock_rate = CONFIG_SYS_HZ_CLOCK; | |
50 | ||
51 | /* get arm global timer base address */ | |
52 | addr = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), "reg"); | |
53 | priv->global_timer = (struct globaltimer *)addr; | |
54 | ||
55 | /* init timer */ | |
56 | writel(0x01, &priv->global_timer->ctl); | |
57 | ||
58 | return 0; | |
59 | } | |
60 | ||
61 | static const struct timer_ops sti_timer_ops = { | |
62 | .get_count = sti_timer_get_count, | |
63 | }; | |
64 | ||
65 | static const struct udevice_id sti_timer_ids[] = { | |
66 | { .compatible = "arm,cortex-a9-global-timer" }, | |
67 | {} | |
68 | }; | |
69 | ||
70 | U_BOOT_DRIVER(sti_timer) = { | |
71 | .name = "sti_timer", | |
72 | .id = UCLASS_TIMER, | |
73 | .of_match = sti_timer_ids, | |
74 | .priv_auto_alloc_size = sizeof(struct sti_timer_priv), | |
75 | .probe = sti_timer_probe, | |
76 | .ops = &sti_timer_ops, | |
77 | .flags = DM_FLAG_PRE_RELOC, | |
78 | }; |