]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/clocksource/timer-stm32.c
clocksource/drivers/stm32: Add oneshot mode
[linux.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 #include "timer-of.h"
22
23 #define TIM_CR1         0x00
24 #define TIM_DIER        0x0c
25 #define TIM_SR          0x10
26 #define TIM_EGR         0x14
27 #define TIM_CNT         0x24
28 #define TIM_PSC         0x28
29 #define TIM_ARR         0x2c
30 #define TIM_CCR1        0x34
31
32 #define TIM_CR1_CEN     BIT(0)
33 #define TIM_CR1_UDIS    BIT(1)
34 #define TIM_CR1_OPM     BIT(3)
35 #define TIM_CR1_ARPE    BIT(7)
36
37 #define TIM_DIER_UIE    BIT(0)
38 #define TIM_DIER_CC1IE  BIT(1)
39
40 #define TIM_SR_UIF      BIT(0)
41
42 #define TIM_EGR_UG      BIT(0)
43
44 #define TIM_PSC_MAX     USHRT_MAX
45 #define TIM_PSC_CLKRATE 10000
46
47 static void stm32_clock_event_disable(struct timer_of *to)
48 {
49         writel_relaxed(0, timer_of_base(to) + TIM_DIER);
50 }
51
52 static void stm32_clock_event_enable(struct timer_of *to)
53 {
54         writel_relaxed(TIM_CR1_UDIS | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1);
55 }
56
57 static int stm32_clock_event_shutdown(struct clock_event_device *clkevt)
58 {
59         struct timer_of *to = to_timer_of(clkevt);
60
61         stm32_clock_event_disable(to);
62
63         return 0;
64 }
65
66 static int stm32_clock_event_set_next_event(unsigned long evt,
67                                             struct clock_event_device *clkevt)
68 {
69         struct timer_of *to = to_timer_of(clkevt);
70         unsigned long now, next;
71
72         next = readl_relaxed(timer_of_base(to) + TIM_CNT) + evt;
73         writel_relaxed(next, timer_of_base(to) + TIM_CCR1);
74         now = readl_relaxed(timer_of_base(to) + TIM_CNT);
75
76         if ((next - now) > evt)
77                 return -ETIME;
78
79         writel_relaxed(TIM_DIER_CC1IE, timer_of_base(to) + TIM_DIER);
80
81         return 0;
82 }
83
84 static int stm32_clock_event_set_periodic(struct clock_event_device *clkevt)
85 {
86         struct timer_of *to = to_timer_of(clkevt);
87
88         stm32_clock_event_enable(to);
89
90         return stm32_clock_event_set_next_event(timer_of_period(to), clkevt);
91 }
92
93 static int stm32_clock_event_set_oneshot(struct clock_event_device *clkevt)
94 {
95         struct timer_of *to = to_timer_of(clkevt);
96
97         stm32_clock_event_enable(to);
98
99         return 0;
100 }
101
102 static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
103 {
104         struct clock_event_device *clkevt = (struct clock_event_device *)dev_id;
105         struct timer_of *to = to_timer_of(clkevt);
106
107         writel_relaxed(0, timer_of_base(to) + TIM_SR);
108
109         if (clockevent_state_periodic(clkevt))
110                 stm32_clock_event_set_periodic(clkevt);
111         else
112                 stm32_clock_event_shutdown(clkevt);
113
114         clkevt->event_handler(clkevt);
115
116         return IRQ_HANDLED;
117 }
118
119 /**
120  * stm32_timer_width - Sort out the timer width (32/16)
121  * @to: a pointer to a timer-of structure
122  *
123  * Write the 32-bit max value and read/return the result. If the timer
124  * is 32 bits wide, the result will be UINT_MAX, otherwise it will
125  * be truncated by the 16-bit register to USHRT_MAX.
126  *
127  * Returns UINT_MAX if the timer is 32 bits wide, USHRT_MAX if it is a
128  * 16 bits wide.
129  */
130 static u32 __init stm32_timer_width(struct timer_of *to)
131 {
132         writel_relaxed(UINT_MAX, timer_of_base(to) + TIM_ARR);
133
134         return readl_relaxed(timer_of_base(to) + TIM_ARR);
135 }
136
137 static void __init stm32_clockevent_init(struct timer_of *to)
138 {
139         u32 width = 0;
140         int prescaler;
141
142         to->clkevt.name = to->np->full_name;
143         to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC;
144         to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
145         to->clkevt.set_state_shutdown = stm32_clock_event_shutdown;
146         to->clkevt.set_state_periodic = stm32_clock_event_set_periodic;
147         to->clkevt.set_state_oneshot = stm32_clock_event_set_oneshot;
148         to->clkevt.tick_resume = stm32_clock_event_shutdown;
149         to->clkevt.set_next_event = stm32_clock_event_set_next_event;
150
151         width = stm32_timer_width(to);
152         if (width == UINT_MAX) {
153                 prescaler = 1;
154                 to->clkevt.rating = 250;
155         } else {
156                 prescaler = DIV_ROUND_CLOSEST(timer_of_rate(to),
157                                               TIM_PSC_CLKRATE);
158                 /*
159                  * The prescaler register is an u16, the variable
160                  * can't be greater than TIM_PSC_MAX, let's cap it in
161                  * this case.
162                  */
163                 prescaler = prescaler < TIM_PSC_MAX ? prescaler : TIM_PSC_MAX;
164                 to->clkevt.rating = 100;
165         }
166
167         writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC);
168         writel_relaxed(TIM_EGR_UG, timer_of_base(to) + TIM_EGR);
169         writel_relaxed(0, timer_of_base(to) + TIM_SR);
170
171         /* Adjust rate and period given the prescaler value */
172         to->of_clk.rate = DIV_ROUND_CLOSEST(to->of_clk.rate, prescaler);
173         to->of_clk.period = DIV_ROUND_UP(to->of_clk.rate, HZ);
174
175         clockevents_config_and_register(&to->clkevt,
176                                         timer_of_rate(to), 0x1, width);
177
178         pr_info("%pOF: STM32 clockevent driver initialized (%d bits)\n",
179                 to->np, width == UINT_MAX ? 32 : 16);
180 }
181
182 static int __init stm32_timer_init(struct device_node *node)
183 {
184         struct reset_control *rstc;
185         struct timer_of *to;
186         int ret;
187
188         to = kzalloc(sizeof(*to), GFP_KERNEL);
189         if (!to)
190                 return -ENOMEM;
191
192         to->flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE;
193         to->of_irq.handler = stm32_clock_event_handler;
194
195         ret = timer_of_init(node, to);
196         if (ret)
197                 goto err;
198
199         rstc = of_reset_control_get(node, NULL);
200         if (!IS_ERR(rstc)) {
201                 reset_control_assert(rstc);
202                 reset_control_deassert(rstc);
203         }
204
205         stm32_clockevent_init(to);
206         return 0;
207 err:
208         kfree(to);
209         return ret;
210 }
211
212 TIMER_OF_DECLARE(stm32, "st,stm32-timer", stm32_timer_init);