GNU Linux-libre 4.9.317-gnu1
[releases.git] / drivers / clocksource / timer-stm32.c
1 /*
2  * Copyright (C) Maxime Coquelin 2015
3  * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
4  * License terms:  GNU General Public License (GPL), version 2
5  *
6  * Inspired by time-efm32.c from Uwe Kleine-Koenig
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/clocksource.h>
11 #include <linux/clockchips.h>
12 #include <linux/irq.h>
13 #include <linux/interrupt.h>
14 #include <linux/of.h>
15 #include <linux/of_address.h>
16 #include <linux/of_irq.h>
17 #include <linux/clk.h>
18 #include <linux/reset.h>
19 #include <linux/slab.h>
20
21 #define TIM_CR1         0x00
22 #define TIM_DIER        0x0c
23 #define TIM_SR          0x10
24 #define TIM_EGR         0x14
25 #define TIM_PSC         0x28
26 #define TIM_ARR         0x2c
27
28 #define TIM_CR1_CEN     BIT(0)
29 #define TIM_CR1_OPM     BIT(3)
30 #define TIM_CR1_ARPE    BIT(7)
31
32 #define TIM_DIER_UIE    BIT(0)
33
34 #define TIM_SR_UIF      BIT(0)
35
36 #define TIM_EGR_UG      BIT(0)
37
38 struct stm32_clock_event_ddata {
39         struct clock_event_device evtdev;
40         unsigned periodic_top;
41         void __iomem *base;
42 };
43
44 static int stm32_clock_event_shutdown(struct clock_event_device *evtdev)
45 {
46         struct stm32_clock_event_ddata *data =
47                 container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
48         void *base = data->base;
49
50         writel_relaxed(0, base + TIM_CR1);
51         return 0;
52 }
53
54 static int stm32_clock_event_set_periodic(struct clock_event_device *evtdev)
55 {
56         struct stm32_clock_event_ddata *data =
57                 container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
58         void *base = data->base;
59
60         writel_relaxed(data->periodic_top, base + TIM_ARR);
61         writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, base + TIM_CR1);
62         return 0;
63 }
64
65 static int stm32_clock_event_set_next_event(unsigned long evt,
66                                             struct clock_event_device *evtdev)
67 {
68         struct stm32_clock_event_ddata *data =
69                 container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
70
71         writel_relaxed(evt, data->base + TIM_ARR);
72         writel_relaxed(TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_CEN,
73                        data->base + TIM_CR1);
74
75         return 0;
76 }
77
78 static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
79 {
80         struct stm32_clock_event_ddata *data = dev_id;
81
82         writel_relaxed(0, data->base + TIM_SR);
83
84         data->evtdev.event_handler(&data->evtdev);
85
86         return IRQ_HANDLED;
87 }
88
89 static struct stm32_clock_event_ddata clock_event_ddata = {
90         .evtdev = {
91                 .name = "stm32 clockevent",
92                 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
93                 .set_state_shutdown = stm32_clock_event_shutdown,
94                 .set_state_periodic = stm32_clock_event_set_periodic,
95                 .set_state_oneshot = stm32_clock_event_shutdown,
96                 .tick_resume = stm32_clock_event_shutdown,
97                 .set_next_event = stm32_clock_event_set_next_event,
98                 .rating = 200,
99         },
100 };
101
102 static int __init stm32_clockevent_init(struct device_node *np)
103 {
104         struct stm32_clock_event_ddata *data = &clock_event_ddata;
105         struct clk *clk;
106         struct reset_control *rstc;
107         unsigned long rate, max_delta;
108         int irq, ret, bits, prescaler = 1;
109
110         data = kmemdup(&clock_event_ddata, sizeof(*data), GFP_KERNEL);
111         if (!data)
112                 return -ENOMEM;
113
114         clk = of_clk_get(np, 0);
115         if (IS_ERR(clk)) {
116                 ret = PTR_ERR(clk);
117                 pr_err("failed to get clock for clockevent (%d)\n", ret);
118                 goto err_clk_get;
119         }
120
121         ret = clk_prepare_enable(clk);
122         if (ret) {
123                 pr_err("failed to enable timer clock for clockevent (%d)\n",
124                        ret);
125                 goto err_clk_enable;
126         }
127
128         rate = clk_get_rate(clk);
129
130         rstc = of_reset_control_get(np, NULL);
131         if (!IS_ERR(rstc)) {
132                 reset_control_assert(rstc);
133                 reset_control_deassert(rstc);
134         }
135
136         data->base = of_iomap(np, 0);
137         if (!data->base) {
138                 ret = -ENXIO;
139                 pr_err("failed to map registers for clockevent\n");
140                 goto err_iomap;
141         }
142
143         irq = irq_of_parse_and_map(np, 0);
144         if (!irq) {
145                 ret = -EINVAL;
146                 pr_err("%s: failed to get irq.\n", np->full_name);
147                 goto err_get_irq;
148         }
149
150         /* Detect whether the timer is 16 or 32 bits */
151         writel_relaxed(~0U, data->base + TIM_ARR);
152         max_delta = readl_relaxed(data->base + TIM_ARR);
153         if (max_delta == ~0U) {
154                 prescaler = 1;
155                 bits = 32;
156         } else {
157                 prescaler = 1024;
158                 bits = 16;
159         }
160         writel_relaxed(0, data->base + TIM_ARR);
161
162         writel_relaxed(prescaler - 1, data->base + TIM_PSC);
163         writel_relaxed(TIM_EGR_UG, data->base + TIM_EGR);
164         writel_relaxed(0, data->base + TIM_SR);
165         writel_relaxed(TIM_DIER_UIE, data->base + TIM_DIER);
166
167         data->periodic_top = DIV_ROUND_CLOSEST(rate, prescaler * HZ);
168
169         clockevents_config_and_register(&data->evtdev,
170                                         DIV_ROUND_CLOSEST(rate, prescaler),
171                                         0x1, max_delta);
172
173         ret = request_irq(irq, stm32_clock_event_handler, IRQF_TIMER,
174                         "stm32 clockevent", data);
175         if (ret) {
176                 pr_err("%s: failed to request irq.\n", np->full_name);
177                 goto err_get_irq;
178         }
179
180         pr_info("%s: STM32 clockevent driver initialized (%d bits)\n",
181                         np->full_name, bits);
182
183         return ret;
184
185 err_get_irq:
186         iounmap(data->base);
187 err_iomap:
188         clk_disable_unprepare(clk);
189 err_clk_enable:
190         clk_put(clk);
191 err_clk_get:
192         kfree(data);
193         return ret;
194 }
195
196 CLOCKSOURCE_OF_DECLARE(stm32, "st,stm32-timer", stm32_clockevent_init);