]>
Commit | Line | Data |
---|---|---|
dadf3137 M |
1 | /* |
2 | * TI OMAP timer driver | |
3 | * | |
4 | * Copyright (C) 2015, Texas Instruments, Incorporated | |
5 | * | |
6 | * SPDX-License-Identifier: GPL-2.0+ | |
7 | */ | |
8 | ||
9 | #include <common.h> | |
10 | #include <dm.h> | |
11 | #include <errno.h> | |
12 | #include <timer.h> | |
13 | #include <asm/io.h> | |
14 | #include <asm/arch/clock.h> | |
15 | ||
16 | DECLARE_GLOBAL_DATA_PTR; | |
17 | ||
18 | /* Timer register bits */ | |
19 | #define TCLR_START BIT(0) /* Start=1 */ | |
20 | #define TCLR_AUTO_RELOAD BIT(1) /* Auto reload */ | |
21 | #define TCLR_PRE_EN BIT(5) /* Pre-scaler enable */ | |
22 | #define TCLR_PTV_SHIFT (2) /* Pre-scaler shift value */ | |
23 | ||
24 | #define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV)) | |
25 | ||
26 | struct omap_gptimer_regs { | |
27 | unsigned int tidr; /* offset 0x00 */ | |
28 | unsigned char res1[12]; | |
29 | unsigned int tiocp_cfg; /* offset 0x10 */ | |
30 | unsigned char res2[12]; | |
31 | unsigned int tier; /* offset 0x20 */ | |
32 | unsigned int tistatr; /* offset 0x24 */ | |
33 | unsigned int tistat; /* offset 0x28 */ | |
34 | unsigned int tisr; /* offset 0x2c */ | |
35 | unsigned int tcicr; /* offset 0x30 */ | |
36 | unsigned int twer; /* offset 0x34 */ | |
37 | unsigned int tclr; /* offset 0x38 */ | |
38 | unsigned int tcrr; /* offset 0x3c */ | |
39 | unsigned int tldr; /* offset 0x40 */ | |
40 | unsigned int ttgr; /* offset 0x44 */ | |
41 | unsigned int twpc; /* offset 0x48 */ | |
42 | unsigned int tmar; /* offset 0x4c */ | |
43 | unsigned int tcar1; /* offset 0x50 */ | |
44 | unsigned int tscir; /* offset 0x54 */ | |
45 | unsigned int tcar2; /* offset 0x58 */ | |
46 | }; | |
47 | ||
48 | /* Omap Timer Priv */ | |
49 | struct omap_timer_priv { | |
50 | struct omap_gptimer_regs *regs; | |
51 | }; | |
52 | ||
53 | static int omap_timer_get_count(struct udevice *dev, u64 *count) | |
54 | { | |
55 | struct omap_timer_priv *priv = dev_get_priv(dev); | |
56 | ||
57 | *count = readl(&priv->regs->tcrr); | |
58 | ||
59 | return 0; | |
60 | } | |
61 | ||
62 | static int omap_timer_probe(struct udevice *dev) | |
63 | { | |
64 | struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); | |
65 | struct omap_timer_priv *priv = dev_get_priv(dev); | |
66 | ||
67 | uc_priv->clock_rate = TIMER_CLOCK; | |
68 | ||
69 | /* start the counter ticking up, reload value on overflow */ | |
70 | writel(0, &priv->regs->tldr); | |
71 | /* enable timer */ | |
72 | writel((CONFIG_SYS_PTV << 2) | TCLR_PRE_EN | TCLR_AUTO_RELOAD | | |
73 | TCLR_START, &priv->regs->tclr); | |
74 | ||
75 | return 0; | |
76 | } | |
77 | ||
78 | static int omap_timer_ofdata_to_platdata(struct udevice *dev) | |
79 | { | |
80 | struct omap_timer_priv *priv = dev_get_priv(dev); | |
81 | ||
a821c4af | 82 | priv->regs = map_physmem(devfdt_get_addr(dev), |
871ca263 | 83 | sizeof(struct omap_gptimer_regs), MAP_NOCACHE); |
dadf3137 M |
84 | |
85 | return 0; | |
86 | } | |
87 | ||
88 | ||
89 | static const struct timer_ops omap_timer_ops = { | |
90 | .get_count = omap_timer_get_count, | |
91 | }; | |
92 | ||
93 | static const struct udevice_id omap_timer_ids[] = { | |
94 | { .compatible = "ti,am335x-timer" }, | |
95 | { .compatible = "ti,am4372-timer" }, | |
96 | { .compatible = "ti,omap5430-timer" }, | |
97 | {} | |
98 | }; | |
99 | ||
100 | U_BOOT_DRIVER(omap_timer) = { | |
101 | .name = "omap_timer", | |
102 | .id = UCLASS_TIMER, | |
103 | .of_match = omap_timer_ids, | |
104 | .ofdata_to_platdata = omap_timer_ofdata_to_platdata, | |
105 | .priv_auto_alloc_size = sizeof(struct omap_timer_priv), | |
106 | .probe = omap_timer_probe, | |
107 | .ops = &omap_timer_ops, | |
108 | .flags = DM_FLAG_PRE_RELOC, | |
109 | }; |