blob: 16ea1da7c0a8aac3e85eee14a305fc14d28b93e1 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Mediatek SoCs General-Purpose Timer handling.
3 *
4 * Copyright (C) 2014 Matthias Brugger
5 *
6 * Matthias Brugger <matthias.bgg@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21#include <linux/clk.h>
22#include <linux/clockchips.h>
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25#include <linux/irqreturn.h>
26#include <linux/of.h>
27#include <linux/of_address.h>
28#include <linux/of_irq.h>
29#include <linux/sched_clock.h>
30#include <linux/slab.h>
31
32#define GPT_IRQ_EN_REG 0x00
33#define GPT_IRQ_ENABLE(val) BIT((val) - 1)
34#define GPT_IRQ_ACK_REG 0x08
35#define GPT_IRQ_ACK(val) BIT((val) - 1)
36
37#define TIMER_CTRL_REG(val) (0x10 * (val))
38#define TIMER_CTRL_CMP(val) (((val) & 0x7) << 6)
39#define TIMER_CTRL_CMP_GE (5)
40#define TIMER_CTRL_OP(val) (((val) & 0x3) << 4)
41#define TIMER_CTRL_OP_ONESHOT (0)
42#define TIMER_CTRL_OP_REPEAT (1)
43#define TIMER_CTRL_OP_FREERUN (3)
44#define TIMER_CTRL_CLEAR (2)
45#define TIMER_CTRL_ENABLE (1)
46#define TIMER_CTRL_DISABLE (0)
47
48#define TIMER_CLK_REG(val) (0x04 + (0x10 * (val)))
49#define TIMER_CLK_SRC(val) (((val) & 0x1) << 4)
50#define TIMER_CLK_SRC_SYS13M (0)
51#define TIMER_CLK_SRC_RTC32K (1)
52#define TIMER_CLK_DIV1 (0x0)
53#define TIMER_CLK_DIV2 (0x1)
54
55#define TIMER_CNT_REG(val) (0x08 + (0x10 * (val)))
56#define TIMER_CMP_REG(val) (0x0C + (0x10 * (val)))
57
58#define GPT_CLK_EVT 1
59#define GPT_CLK_SRC 2
60
61static const unsigned long gpt_srcclk_table[] = {
62 32000,
63 13000000
64};
65
66struct mtk_clock_event_device {
67 void __iomem *gpt_base;
68 u32 ticks_per_jiffy;
69 struct clock_event_device dev;
70};
71
72static void __iomem *gpt_sched_reg __read_mostly;
73
74static u64 notrace mtk_read_sched_clock(void)
75{
76 return readl_relaxed(gpt_sched_reg);
77}
78
79static inline struct mtk_clock_event_device *to_mtk_clk(
80 struct clock_event_device *c)
81{
82 return container_of(c, struct mtk_clock_event_device, dev);
83}
84
85static void mtk_clkevt_time_stop(struct mtk_clock_event_device *evt, u8 timer)
86{
87 u32 val;
88
89 val = readl(evt->gpt_base + TIMER_CTRL_REG(timer));
90 writel(val & ~TIMER_CTRL_ENABLE, evt->gpt_base +
91 TIMER_CTRL_REG(timer));
92}
93
94static void mtk_clkevt_time_setup(struct mtk_clock_event_device *evt,
95 unsigned long delay, u8 timer)
96{
97 writel(delay, evt->gpt_base + TIMER_CMP_REG(timer));
98}
99
100static void mtk_clkevt_time_start(struct mtk_clock_event_device *evt,
101 bool periodic, u8 timer)
102{
103 u32 val;
104
105 /* Acknowledge interrupt */
106 writel(GPT_IRQ_ACK(timer), evt->gpt_base + GPT_IRQ_ACK_REG);
107
108 val = readl(evt->gpt_base + TIMER_CTRL_REG(timer));
109
110 /* Clear 2 bit timer operation mode field */
111 val &= ~TIMER_CTRL_OP(0x3);
112
113 if (periodic)
114 val |= TIMER_CTRL_OP(TIMER_CTRL_OP_REPEAT);
115 else
116 val |= TIMER_CTRL_OP(TIMER_CTRL_OP_ONESHOT);
117
118 writel(val | TIMER_CTRL_ENABLE | TIMER_CTRL_CLEAR,
119 evt->gpt_base + TIMER_CTRL_REG(timer));
120}
121
122static int mtk_clkevt_shutdown(struct clock_event_device *clk)
123{
124 mtk_clkevt_time_stop(to_mtk_clk(clk), GPT_CLK_EVT);
125 return 0;
126}
127
128static int mtk_clkevt_set_periodic(struct clock_event_device *clk)
129{
130 struct mtk_clock_event_device *evt = to_mtk_clk(clk);
131
132 mtk_clkevt_time_stop(evt, GPT_CLK_EVT);
133 mtk_clkevt_time_setup(evt, evt->ticks_per_jiffy, GPT_CLK_EVT);
134 mtk_clkevt_time_start(evt, true, GPT_CLK_EVT);
135 return 0;
136}
137
138static int mtk_clkevt_next_event(unsigned long event,
139 struct clock_event_device *clk)
140{
141 struct mtk_clock_event_device *evt = to_mtk_clk(clk);
142
143 mtk_clkevt_time_stop(evt, GPT_CLK_EVT);
144 mtk_clkevt_time_setup(evt, event, GPT_CLK_EVT);
145 mtk_clkevt_time_start(evt, false, GPT_CLK_EVT);
146
147 return 0;
148}
149
150static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
151{
152 /* Disable all interrupts */
153 writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
154 /* Acknowledge all interrupts */
155 writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
156}
157
158static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
159{
160 struct mtk_clock_event_device *evt = dev_id;
161
162 /* Acknowledge timer0 irq */
163 writel(GPT_IRQ_ACK(GPT_CLK_EVT), evt->gpt_base + GPT_IRQ_ACK_REG);
164 evt->dev.event_handler(&evt->dev);
165
166 return IRQ_HANDLED;
167}
168
169static void
170__init mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer,
171 u8 option, u8 clk)
172{
173 writel(TIMER_CTRL_CLEAR | TIMER_CTRL_DISABLE,
174 evt->gpt_base + TIMER_CTRL_REG(timer));
175
176 writel((clk ? TIMER_CLK_SRC(TIMER_CLK_SRC_SYS13M) :
177 TIMER_CLK_SRC(TIMER_CLK_SRC_RTC32K)) | TIMER_CLK_DIV1,
178 evt->gpt_base + TIMER_CLK_REG(timer));
179
180 writel(0x0, evt->gpt_base + TIMER_CMP_REG(timer));
181
182 writel(TIMER_CTRL_CMP(TIMER_CTRL_CMP_GE) | TIMER_CTRL_OP(option) |
183 TIMER_CTRL_ENABLE, evt->gpt_base + TIMER_CTRL_REG(timer));
184}
185
186static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
187{
188 u32 val;
189
190 /* Disable all interrupts */
191 writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
192
193 /* Acknowledge all spurious pending interrupts */
194 writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
195
196 val = readl(evt->gpt_base + GPT_IRQ_EN_REG);
197 writel(val | GPT_IRQ_ENABLE(timer),
198 evt->gpt_base + GPT_IRQ_EN_REG);
199}
200
201static int __init mtk_timer_init(struct device_node *node)
202{
203 struct mtk_clock_event_device *evt;
204 struct resource res;
205 unsigned long rate = 0;
206 struct clk *clk;
207
208 evt = kzalloc(sizeof(*evt), GFP_KERNEL);
209 if (!evt)
210 return -ENOMEM;
211
212 evt->dev.name = "mtk_tick";
213 evt->dev.rating = 300;
214 evt->dev.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
215 evt->dev.set_state_shutdown = mtk_clkevt_shutdown;
216 evt->dev.set_state_periodic = mtk_clkevt_set_periodic;
217 evt->dev.set_state_oneshot = mtk_clkevt_shutdown;
218 evt->dev.tick_resume = mtk_clkevt_shutdown;
219 evt->dev.set_next_event = mtk_clkevt_next_event;
220 evt->dev.cpumask = cpu_possible_mask;
221
222 evt->gpt_base = of_io_request_and_map(node, 0, "mtk-timer");
223 if (IS_ERR(evt->gpt_base)) {
224 pr_err("Can't get resource\n");
225 goto err_kzalloc;
226 }
227
228 evt->dev.irq = irq_of_parse_and_map(node, 0);
229 if (evt->dev.irq <= 0) {
230 pr_err("Can't parse IRQ\n");
231 goto err_mem;
232 }
233
234 clk = of_clk_get(node, 0);
235 if (IS_ERR(clk)) {
236 pr_err("Can't get timer clock\n");
237 goto err_irq;
238 }
239
240 if (clk_prepare_enable(clk)) {
241 pr_err("Can't prepare clock\n");
242 goto err_clk_put;
243 }
244 rate = clk_get_rate(clk);
245
246 mtk_timer_global_reset(evt);
247
248 if (rate == gpt_srcclk_table[1] * 2)
249 rate = gpt_srcclk_table[1];
250
251 if (request_irq(evt->dev.irq, mtk_timer_interrupt,
252 IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) {
253 pr_err("failed to setup irq %d\n", evt->dev.irq);
254 goto err_clk_disable;
255 }
256
257 evt->ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
258
259 /* Configure clock source */
260 mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN,
261 (rate == gpt_srcclk_table[1]));
262 clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC),
263 node->name, rate, 300, 32, clocksource_mmio_readl_up);
264 gpt_sched_reg = evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC);
265 sched_clock_register(mtk_read_sched_clock, 32, rate);
266
267 /* Configure clock event */
268 mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT,
269 (rate == gpt_srcclk_table[1]));
270 clockevents_config_and_register(&evt->dev, rate, 0x3,
271 0xffffffff);
272
273 mtk_timer_enable_irq(evt, GPT_CLK_EVT);
274
275 return 0;
276
277err_clk_disable:
278 clk_disable_unprepare(clk);
279err_clk_put:
280 clk_put(clk);
281err_irq:
282 irq_dispose_mapping(evt->dev.irq);
283err_mem:
284 iounmap(evt->gpt_base);
285 of_address_to_resource(node, 0, &res);
286 release_mem_region(res.start, resource_size(&res));
287err_kzalloc:
288 kfree(evt);
289
290 return -EINVAL;
291}
292TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_timer_init);