aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/timer-stm32.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clocksource/timer-stm32.c')
-rw-r--r--drivers/clocksource/timer-stm32.c107
1 files changed, 82 insertions, 25 deletions
diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
index 882037f1d8d6..0d37f1a1994e 100644
--- a/drivers/clocksource/timer-stm32.c
+++ b/drivers/clocksource/timer-stm32.c
@@ -44,6 +44,42 @@
44#define TIM_PSC_MAX USHRT_MAX 44#define TIM_PSC_MAX USHRT_MAX
45#define TIM_PSC_CLKRATE 10000 45#define TIM_PSC_CLKRATE 10000
46 46
47struct stm32_timer_private {
48 int bits;
49};
50
51/**
52 * stm32_timer_of_bits_set - set accessor helper
53 * @to: a timer_of structure pointer
54 * @bits: the number of bits (16 or 32)
55 *
56 * Accessor helper to set the number of bits in the timer-of private
57 * structure.
58 *
59 */
60static void stm32_timer_of_bits_set(struct timer_of *to, int bits)
61{
62 struct stm32_timer_private *pd = to->private_data;
63
64 pd->bits = bits;
65}
66
67/**
68 * stm32_timer_of_bits_get - get accessor helper
69 * @to: a timer_of structure pointer
70 *
71 * Accessor helper to get the number of bits in the timer-of private
72 * structure.
73 *
74 * Returns an integer corresponding to the number of bits.
75 */
76static int stm32_timer_of_bits_get(struct timer_of *to)
77{
78 struct stm32_timer_private *pd = to->private_data;
79
80 return pd->bits;
81}
82
47static void stm32_clock_event_disable(struct timer_of *to) 83static void stm32_clock_event_disable(struct timer_of *to)
48{ 84{
49 writel_relaxed(0, timer_of_base(to) + TIM_DIER); 85 writel_relaxed(0, timer_of_base(to) + TIM_DIER);
@@ -124,35 +160,31 @@ static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
124 * is 32 bits wide, the result will be UINT_MAX, otherwise it will 160 * is 32 bits wide, the result will be UINT_MAX, otherwise it will
125 * be truncated by the 16-bit register to USHRT_MAX. 161 * be truncated by the 16-bit register to USHRT_MAX.
126 * 162 *
127 * Returns UINT_MAX if the timer is 32 bits wide, USHRT_MAX if it is a
128 * 16 bits wide.
129 */ 163 */
130static u32 __init stm32_timer_width(struct timer_of *to) 164static void __init stm32_timer_set_width(struct timer_of *to)
131{ 165{
166 u32 width;
167
132 writel_relaxed(UINT_MAX, timer_of_base(to) + TIM_ARR); 168 writel_relaxed(UINT_MAX, timer_of_base(to) + TIM_ARR);
133 169
134 return readl_relaxed(timer_of_base(to) + TIM_ARR); 170 width = readl_relaxed(timer_of_base(to) + TIM_ARR);
171
172 stm32_timer_of_bits_set(to, width == UINT_MAX ? 32 : 16);
135} 173}
136 174
137static void __init stm32_clockevent_init(struct timer_of *to) 175/**
176 * stm32_timer_set_prescaler - Compute and set the prescaler register
177 * @to: a pointer to a timer-of structure
178 *
179 * Depending on the timer width, compute the prescaler to always
180 * target a 10MHz timer rate for 16 bits. 32-bit timers are
181 * considered precise and long enough to not use the prescaler.
182 */
183static void __init stm32_timer_set_prescaler(struct timer_of *to)
138{ 184{
139 u32 width = 0; 185 int prescaler = 1;
140 int prescaler;
141 186
142 to->clkevt.name = to->np->full_name; 187 if (stm32_timer_of_bits_get(to) != 32) {
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), 188 prescaler = DIV_ROUND_CLOSEST(timer_of_rate(to),
157 TIM_PSC_CLKRATE); 189 TIM_PSC_CLKRATE);
158 /* 190 /*
@@ -161,7 +193,6 @@ static void __init stm32_clockevent_init(struct timer_of *to)
161 * this case. 193 * this case.
162 */ 194 */
163 prescaler = prescaler < TIM_PSC_MAX ? prescaler : TIM_PSC_MAX; 195 prescaler = prescaler < TIM_PSC_MAX ? prescaler : TIM_PSC_MAX;
164 to->clkevt.rating = 100;
165 } 196 }
166 197
167 writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC); 198 writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC);
@@ -171,12 +202,26 @@ static void __init stm32_clockevent_init(struct timer_of *to)
171 /* Adjust rate and period given the prescaler value */ 202 /* Adjust rate and period given the prescaler value */
172 to->of_clk.rate = DIV_ROUND_CLOSEST(to->of_clk.rate, prescaler); 203 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); 204 to->of_clk.period = DIV_ROUND_UP(to->of_clk.rate, HZ);
205}
206
207static void __init stm32_clockevent_init(struct timer_of *to)
208{
209 u32 bits = stm32_timer_of_bits_get(to);
174 210
175 clockevents_config_and_register(&to->clkevt, 211 to->clkevt.name = to->np->full_name;
176 timer_of_rate(to), 0x1, width); 212 to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
213 to->clkevt.set_state_shutdown = stm32_clock_event_shutdown;
214 to->clkevt.set_state_periodic = stm32_clock_event_set_periodic;
215 to->clkevt.set_state_oneshot = stm32_clock_event_set_oneshot;
216 to->clkevt.tick_resume = stm32_clock_event_shutdown;
217 to->clkevt.set_next_event = stm32_clock_event_set_next_event;
218 to->clkevt.rating = bits == 32 ? 250 : 100;
219
220 clockevents_config_and_register(&to->clkevt, timer_of_rate(to), 0x1,
221 (1 << bits) - 1);
177 222
178 pr_info("%pOF: STM32 clockevent driver initialized (%d bits)\n", 223 pr_info("%pOF: STM32 clockevent driver initialized (%d bits)\n",
179 to->np, width == UINT_MAX ? 32 : 16); 224 to->np, bits);
180} 225}
181 226
182static int __init stm32_timer_init(struct device_node *node) 227static int __init stm32_timer_init(struct device_node *node)
@@ -196,14 +241,26 @@ static int __init stm32_timer_init(struct device_node *node)
196 if (ret) 241 if (ret)
197 goto err; 242 goto err;
198 243
244 to->private_data = kzalloc(sizeof(struct stm32_timer_private),
245 GFP_KERNEL);
246 if (!to->private_data)
247 goto deinit;
248
199 rstc = of_reset_control_get(node, NULL); 249 rstc = of_reset_control_get(node, NULL);
200 if (!IS_ERR(rstc)) { 250 if (!IS_ERR(rstc)) {
201 reset_control_assert(rstc); 251 reset_control_assert(rstc);
202 reset_control_deassert(rstc); 252 reset_control_deassert(rstc);
203 } 253 }
204 254
255 stm32_timer_set_width(to);
256
257 stm32_timer_set_prescaler(to);
258
205 stm32_clockevent_init(to); 259 stm32_clockevent_init(to);
206 return 0; 260 return 0;
261
262deinit:
263 timer_of_cleanup(to);
207err: 264err:
208 kfree(to); 265 kfree(to);
209 return ret; 266 return ret;