blob: 928ac281f937a8cac7811df9376d40912fed0728 [file] [log] [blame]
Maxime Coqueline37e4592015-05-22 23:03:33 +02001/*
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>
Benjamin Gaignardd04af492018-01-08 14:28:51 +010019#include <linux/slab.h>
20
21#include "timer-of.h"
Maxime Coqueline37e4592015-05-22 23:03:33 +020022
23#define TIM_CR1 0x00
24#define TIM_DIER 0x0c
25#define TIM_SR 0x10
26#define TIM_EGR 0x14
27#define TIM_PSC 0x28
28#define TIM_ARR 0x2c
29
30#define TIM_CR1_CEN BIT(0)
31#define TIM_CR1_OPM BIT(3)
32#define TIM_CR1_ARPE BIT(7)
33
34#define TIM_DIER_UIE BIT(0)
35
36#define TIM_SR_UIF BIT(0)
37
38#define TIM_EGR_UG BIT(0)
39
Benjamin Gaignard4744daa2018-01-08 14:28:54 +010040#define TIM_PSC_MAX USHRT_MAX
41#define TIM_PSC_CLKRATE 10000
42
Benjamin Gaignardd04af492018-01-08 14:28:51 +010043static int stm32_clock_event_shutdown(struct clock_event_device *clkevt)
Maxime Coqueline37e4592015-05-22 23:03:33 +020044{
Benjamin Gaignardd04af492018-01-08 14:28:51 +010045 struct timer_of *to = to_timer_of(clkevt);
Maxime Coqueline37e4592015-05-22 23:03:33 +020046
Benjamin Gaignardd04af492018-01-08 14:28:51 +010047 writel_relaxed(0, timer_of_base(to) + TIM_CR1);
48
Viresh Kumar8e8af4c2015-06-18 16:24:50 +053049 return 0;
50}
Maxime Coqueline37e4592015-05-22 23:03:33 +020051
Benjamin Gaignardd04af492018-01-08 14:28:51 +010052static int stm32_clock_event_set_periodic(struct clock_event_device *clkevt)
Viresh Kumar8e8af4c2015-06-18 16:24:50 +053053{
Benjamin Gaignardd04af492018-01-08 14:28:51 +010054 struct timer_of *to = to_timer_of(clkevt);
Viresh Kumar8e8af4c2015-06-18 16:24:50 +053055
Benjamin Gaignardd04af492018-01-08 14:28:51 +010056 writel_relaxed(timer_of_period(to), timer_of_base(to) + TIM_ARR);
57 writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1);
58
Viresh Kumar8e8af4c2015-06-18 16:24:50 +053059 return 0;
Maxime Coqueline37e4592015-05-22 23:03:33 +020060}
61
62static int stm32_clock_event_set_next_event(unsigned long evt,
Benjamin Gaignardd04af492018-01-08 14:28:51 +010063 struct clock_event_device *clkevt)
Maxime Coqueline37e4592015-05-22 23:03:33 +020064{
Benjamin Gaignardd04af492018-01-08 14:28:51 +010065 struct timer_of *to = to_timer_of(clkevt);
Maxime Coqueline37e4592015-05-22 23:03:33 +020066
Benjamin Gaignardd04af492018-01-08 14:28:51 +010067 writel_relaxed(evt, timer_of_base(to) + TIM_ARR);
Maxime Coqueline37e4592015-05-22 23:03:33 +020068 writel_relaxed(TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_CEN,
Benjamin Gaignardd04af492018-01-08 14:28:51 +010069 timer_of_base(to) + TIM_CR1);
Maxime Coqueline37e4592015-05-22 23:03:33 +020070
71 return 0;
72}
73
74static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
75{
Benjamin Gaignardd04af492018-01-08 14:28:51 +010076 struct clock_event_device *clkevt = (struct clock_event_device *)dev_id;
77 struct timer_of *to = to_timer_of(clkevt);
Maxime Coqueline37e4592015-05-22 23:03:33 +020078
Benjamin Gaignardd04af492018-01-08 14:28:51 +010079 writel_relaxed(0, timer_of_base(to) + TIM_SR);
Maxime Coqueline37e4592015-05-22 23:03:33 +020080
Benjamin Gaignardd04af492018-01-08 14:28:51 +010081 clkevt->event_handler(clkevt);
Maxime Coqueline37e4592015-05-22 23:03:33 +020082
83 return IRQ_HANDLED;
84}
85
Daniel Lezcano70c62cf2018-01-08 14:28:53 +010086/**
87 * stm32_timer_width - Sort out the timer width (32/16)
88 * @to: a pointer to a timer-of structure
89 *
90 * Write the 32-bit max value and read/return the result. If the timer
91 * is 32 bits wide, the result will be UINT_MAX, otherwise it will
92 * be truncated by the 16-bit register to USHRT_MAX.
93 *
94 * Returns UINT_MAX if the timer is 32 bits wide, USHRT_MAX if it is a
95 * 16 bits wide.
96 */
97static u32 __init stm32_timer_width(struct timer_of *to)
98{
99 writel_relaxed(UINT_MAX, timer_of_base(to) + TIM_ARR);
100
101 return readl_relaxed(timer_of_base(to) + TIM_ARR);
102}
103
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100104static void __init stm32_clockevent_init(struct timer_of *to)
Maxime Coqueline37e4592015-05-22 23:03:33 +0200105{
Daniel Lezcano70c62cf2018-01-08 14:28:53 +0100106 u32 width = 0;
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100107 int prescaler;
Maxime Coqueline37e4592015-05-22 23:03:33 +0200108
Daniel Lezcanof2ed8ef2018-01-08 14:28:52 +0100109 to->clkevt.name = to->np->full_name;
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100110 to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC;
111 to->clkevt.set_state_shutdown = stm32_clock_event_shutdown;
112 to->clkevt.set_state_periodic = stm32_clock_event_set_periodic;
113 to->clkevt.set_state_oneshot = stm32_clock_event_shutdown;
114 to->clkevt.tick_resume = stm32_clock_event_shutdown;
115 to->clkevt.set_next_event = stm32_clock_event_set_next_event;
116
Daniel Lezcano70c62cf2018-01-08 14:28:53 +0100117 width = stm32_timer_width(to);
118 if (width == UINT_MAX) {
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100119 prescaler = 1;
120 to->clkevt.rating = 250;
121 } else {
Benjamin Gaignard4744daa2018-01-08 14:28:54 +0100122 prescaler = DIV_ROUND_CLOSEST(timer_of_rate(to),
123 TIM_PSC_CLKRATE);
124 /*
125 * The prescaler register is an u16, the variable
126 * can't be greater than TIM_PSC_MAX, let's cap it in
127 * this case.
128 */
129 prescaler = prescaler < TIM_PSC_MAX ? prescaler : TIM_PSC_MAX;
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100130 to->clkevt.rating = 100;
131 }
132 writel_relaxed(0, timer_of_base(to) + TIM_ARR);
133
134 writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC);
135 writel_relaxed(TIM_EGR_UG, timer_of_base(to) + TIM_EGR);
136 writel_relaxed(0, timer_of_base(to) + TIM_SR);
137 writel_relaxed(TIM_DIER_UIE, timer_of_base(to) + TIM_DIER);
138
139 /* Adjust rate and period given the prescaler value */
140 to->of_clk.rate = DIV_ROUND_CLOSEST(to->of_clk.rate, prescaler);
141 to->of_clk.period = DIV_ROUND_UP(to->of_clk.rate, HZ);
142
143 clockevents_config_and_register(&to->clkevt,
Daniel Lezcano70c62cf2018-01-08 14:28:53 +0100144 timer_of_rate(to), 0x1, width);
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100145
146 pr_info("%pOF: STM32 clockevent driver initialized (%d bits)\n",
Daniel Lezcano70c62cf2018-01-08 14:28:53 +0100147 to->np, width == UINT_MAX ? 32 : 16);
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100148}
149
150static int __init stm32_timer_init(struct device_node *node)
151{
152 struct reset_control *rstc;
153 struct timer_of *to;
154 int ret;
155
156 to = kzalloc(sizeof(*to), GFP_KERNEL);
157 if (!to)
Daniel Lezcanoe0aeca32018-01-08 14:28:50 +0100158 return -ENOMEM;
159
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100160 to->flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE;
161 to->of_irq.handler = stm32_clock_event_handler;
Maxime Coqueline37e4592015-05-22 23:03:33 +0200162
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100163 ret = timer_of_init(node, to);
164 if (ret)
165 goto err;
Maxime Coqueline37e4592015-05-22 23:03:33 +0200166
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100167 rstc = of_reset_control_get(node, NULL);
Maxime Coqueline37e4592015-05-22 23:03:33 +0200168 if (!IS_ERR(rstc)) {
169 reset_control_assert(rstc);
170 reset_control_deassert(rstc);
171 }
172
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100173 stm32_clockevent_init(to);
174 return 0;
175err:
176 kfree(to);
Daniel Lezcano38d94c52016-06-06 23:28:17 +0200177 return ret;
Maxime Coqueline37e4592015-05-22 23:03:33 +0200178}
179
Benjamin Gaignardd04af492018-01-08 14:28:51 +0100180TIMER_OF_DECLARE(stm32, "st,stm32-timer", stm32_timer_init);