xref: /openbmc/linux/drivers/mfd/rz-mtu3.c (revision 3def3387)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Renesas RZ/G2L Multi-Function Timer Pulse Unit 3(MTU3a) Core driver
4  *
5  * Copyright (C) 2023 Renesas Electronics Corporation
6  */
7 
8 #include <linux/bitfield.h>
9 #include <linux/clk.h>
10 #include <linux/interrupt.h>
11 #include <linux/irq.h>
12 #include <linux/mfd/core.h>
13 #include <linux/mfd/rz-mtu3.h>
14 #include <linux/of_platform.h>
15 #include <linux/reset.h>
16 #include <linux/spinlock.h>
17 
18 #include "rz-mtu3.h"
19 
20 struct rz_mtu3_priv {
21 	void __iomem *mmio;
22 	struct reset_control *rstc;
23 	raw_spinlock_t lock;
24 };
25 
26 /******* MTU3 registers (original offset is +0x1200) *******/
27 static const unsigned long rz_mtu3_8bit_ch_reg_offs[][13] = {
28 	[RZ_MTU3_CHAN_0] = MTU_8BIT_CH_0(0x104, 0x090, 0x100, 0x128, 0x101, 0x102, 0x103, 0x126),
29 	[RZ_MTU3_CHAN_1] = MTU_8BIT_CH_1_2(0x184, 0x091, 0x185, 0x180, 0x194, 0x181, 0x182),
30 	[RZ_MTU3_CHAN_2] = MTU_8BIT_CH_1_2(0x204, 0x092, 0x205, 0x200, 0x20c, 0x201, 0x202),
31 	[RZ_MTU3_CHAN_3] = MTU_8BIT_CH_3_4_6_7(0x008, 0x093, 0x02c, 0x000, 0x04c, 0x002, 0x004, 0x005, 0x038),
32 	[RZ_MTU3_CHAN_4] = MTU_8BIT_CH_3_4_6_7(0x009, 0x094, 0x02d, 0x001, 0x04d, 0x003, 0x006, 0x007, 0x039),
33 	[RZ_MTU3_CHAN_5] = MTU_8BIT_CH_5(0xab2, 0x1eb, 0xab4, 0xab6, 0xa84, 0xa85, 0xa86, 0xa94, 0xa95, 0xa96, 0xaa4, 0xaa5, 0xaa6),
34 	[RZ_MTU3_CHAN_6] = MTU_8BIT_CH_3_4_6_7(0x808, 0x893, 0x82c, 0x800, 0x84c, 0x802, 0x804, 0x805, 0x838),
35 	[RZ_MTU3_CHAN_7] = MTU_8BIT_CH_3_4_6_7(0x809, 0x894, 0x82d, 0x801, 0x84d, 0x803, 0x806, 0x807, 0x839),
36 	[RZ_MTU3_CHAN_8] = MTU_8BIT_CH_8(0x404, 0x098, 0x400, 0x406, 0x401, 0x402, 0x403)
37 };
38 
39 static const unsigned long rz_mtu3_16bit_ch_reg_offs[][12] = {
40 	[RZ_MTU3_CHAN_0] = MTU_16BIT_CH_0(0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x120, 0x122),
41 	[RZ_MTU3_CHAN_1] = MTU_16BIT_CH_1_2(0x186, 0x188, 0x18a),
42 	[RZ_MTU3_CHAN_2] = MTU_16BIT_CH_1_2(0x206, 0x208, 0x20a),
43 	[RZ_MTU3_CHAN_3] = MTU_16BIT_CH_3_6(0x010, 0x018, 0x01a, 0x024, 0x026, 0x072),
44 	[RZ_MTU3_CHAN_4] = MTU_16BIT_CH_4_7(0x012, 0x01c, 0x01e, 0x028, 0x2a, 0x074, 0x076, 0x040, 0x044, 0x046, 0x048, 0x04a),
45 	[RZ_MTU3_CHAN_5] = MTU_16BIT_CH_5(0xa80, 0xa82, 0xa90, 0xa92, 0xaa0, 0xaa2),
46 	[RZ_MTU3_CHAN_6] = MTU_16BIT_CH_3_6(0x810, 0x818, 0x81a, 0x824, 0x826, 0x872),
47 	[RZ_MTU3_CHAN_7] = MTU_16BIT_CH_4_7(0x812, 0x81c, 0x81e, 0x828, 0x82a, 0x874, 0x876, 0x840, 0x844, 0x846, 0x848, 0x84a)
48 };
49 
50 static const unsigned long rz_mtu3_32bit_ch_reg_offs[][5] = {
51 	[RZ_MTU3_CHAN_1] = MTU_32BIT_CH_1(0x1a0, 0x1a4, 0x1a8),
52 	[RZ_MTU3_CHAN_8] = MTU_32BIT_CH_8(0x408, 0x40c, 0x410, 0x414, 0x418)
53 };
54 
55 static bool rz_mtu3_is_16bit_shared_reg(u16 offset)
56 {
57 	return (offset == RZ_MTU3_TDDRA || offset == RZ_MTU3_TDDRB ||
58 		offset == RZ_MTU3_TCDRA || offset == RZ_MTU3_TCDRB ||
59 		offset == RZ_MTU3_TCBRA || offset == RZ_MTU3_TCBRB ||
60 		offset == RZ_MTU3_TCNTSA || offset == RZ_MTU3_TCNTSB);
61 }
62 
63 u16 rz_mtu3_shared_reg_read(struct rz_mtu3_channel *ch, u16 offset)
64 {
65 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
66 	struct rz_mtu3_priv *priv = mtu->priv_data;
67 
68 	if (rz_mtu3_is_16bit_shared_reg(offset))
69 		return readw(priv->mmio + offset);
70 	else
71 		return readb(priv->mmio + offset);
72 }
73 EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_read);
74 
75 u8 rz_mtu3_8bit_ch_read(struct rz_mtu3_channel *ch, u16 offset)
76 {
77 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
78 	struct rz_mtu3_priv *priv = mtu->priv_data;
79 	u16 ch_offs;
80 
81 	ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset];
82 
83 	return readb(priv->mmio + ch_offs);
84 }
85 EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_read);
86 
87 u16 rz_mtu3_16bit_ch_read(struct rz_mtu3_channel *ch, u16 offset)
88 {
89 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
90 	struct rz_mtu3_priv *priv = mtu->priv_data;
91 	u16 ch_offs;
92 
93 	/* MTU8 doesn't have 16-bit registers */
94 	if (ch->channel_number == RZ_MTU3_CHAN_8)
95 		return 0;
96 
97 	ch_offs = rz_mtu3_16bit_ch_reg_offs[ch->channel_number][offset];
98 
99 	return readw(priv->mmio + ch_offs);
100 }
101 EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_read);
102 
103 u32 rz_mtu3_32bit_ch_read(struct rz_mtu3_channel *ch, u16 offset)
104 {
105 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
106 	struct rz_mtu3_priv *priv = mtu->priv_data;
107 	u16 ch_offs;
108 
109 	if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8)
110 		return 0;
111 
112 	ch_offs = rz_mtu3_32bit_ch_reg_offs[ch->channel_number][offset];
113 
114 	return readl(priv->mmio + ch_offs);
115 }
116 EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_read);
117 
118 void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u8 val)
119 {
120 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
121 	struct rz_mtu3_priv *priv = mtu->priv_data;
122 	u16 ch_offs;
123 
124 	ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset];
125 	writeb(val, priv->mmio + ch_offs);
126 }
127 EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_write);
128 
129 void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u16 val)
130 {
131 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
132 	struct rz_mtu3_priv *priv = mtu->priv_data;
133 	u16 ch_offs;
134 
135 	/* MTU8 doesn't have 16-bit registers */
136 	if (ch->channel_number == RZ_MTU3_CHAN_8)
137 		return;
138 
139 	ch_offs = rz_mtu3_16bit_ch_reg_offs[ch->channel_number][offset];
140 	writew(val, priv->mmio + ch_offs);
141 }
142 EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_write);
143 
144 void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u32 val)
145 {
146 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
147 	struct rz_mtu3_priv *priv = mtu->priv_data;
148 	u16 ch_offs;
149 
150 	if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8)
151 		return;
152 
153 	ch_offs = rz_mtu3_32bit_ch_reg_offs[ch->channel_number][offset];
154 	writel(val, priv->mmio + ch_offs);
155 }
156 EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_write);
157 
158 void rz_mtu3_shared_reg_write(struct rz_mtu3_channel *ch, u16 offset, u16 value)
159 {
160 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
161 	struct rz_mtu3_priv *priv = mtu->priv_data;
162 
163 	if (rz_mtu3_is_16bit_shared_reg(offset))
164 		writew(value, priv->mmio + offset);
165 	else
166 		writeb((u8)value, priv->mmio + offset);
167 }
168 EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_write);
169 
170 void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch, u16 offset,
171 				   u16 pos, u8 val)
172 {
173 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
174 	struct rz_mtu3_priv *priv = mtu->priv_data;
175 	unsigned long tmdr, flags;
176 
177 	raw_spin_lock_irqsave(&priv->lock, flags);
178 	tmdr = rz_mtu3_shared_reg_read(ch, offset);
179 	__assign_bit(pos, &tmdr, !!val);
180 	rz_mtu3_shared_reg_write(ch, offset, tmdr);
181 	raw_spin_unlock_irqrestore(&priv->lock, flags);
182 }
183 EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_update_bit);
184 
185 static u16 rz_mtu3_get_tstr_offset(struct rz_mtu3_channel *ch)
186 {
187 	u16 offset;
188 
189 	switch (ch->channel_number) {
190 	case RZ_MTU3_CHAN_0:
191 	case RZ_MTU3_CHAN_1:
192 	case RZ_MTU3_CHAN_2:
193 	case RZ_MTU3_CHAN_3:
194 	case RZ_MTU3_CHAN_4:
195 	case RZ_MTU3_CHAN_8:
196 		offset = RZ_MTU3_TSTRA;
197 		break;
198 	case RZ_MTU3_CHAN_5:
199 		offset = RZ_MTU3_TSTR;
200 		break;
201 	case RZ_MTU3_CHAN_6:
202 	case RZ_MTU3_CHAN_7:
203 		offset = RZ_MTU3_TSTRB;
204 		break;
205 	default:
206 		offset = 0;
207 		break;
208 	}
209 
210 	return offset;
211 }
212 
213 static u8 rz_mtu3_get_tstr_bit_pos(struct rz_mtu3_channel *ch)
214 {
215 	u8 bitpos;
216 
217 	switch (ch->channel_number) {
218 	case RZ_MTU3_CHAN_0:
219 	case RZ_MTU3_CHAN_1:
220 	case RZ_MTU3_CHAN_2:
221 	case RZ_MTU3_CHAN_6:
222 	case RZ_MTU3_CHAN_7:
223 		bitpos = ch->channel_number;
224 		break;
225 	case RZ_MTU3_CHAN_3:
226 		bitpos = 6;
227 		break;
228 	case RZ_MTU3_CHAN_4:
229 		bitpos = 7;
230 		break;
231 	case RZ_MTU3_CHAN_5:
232 		bitpos = 2;
233 		break;
234 	case RZ_MTU3_CHAN_8:
235 		bitpos = 3;
236 		break;
237 	default:
238 		bitpos = 0;
239 		break;
240 	}
241 
242 	return bitpos;
243 }
244 
245 static void rz_mtu3_start_stop_ch(struct rz_mtu3_channel *ch, bool start)
246 {
247 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
248 	struct rz_mtu3_priv *priv = mtu->priv_data;
249 	unsigned long flags, tstr;
250 	u16 offset;
251 	u8 bitpos;
252 
253 	/* start stop register shared by multiple timer channels */
254 	raw_spin_lock_irqsave(&priv->lock, flags);
255 
256 	offset = rz_mtu3_get_tstr_offset(ch);
257 	bitpos = rz_mtu3_get_tstr_bit_pos(ch);
258 	tstr = rz_mtu3_shared_reg_read(ch, offset);
259 	__assign_bit(bitpos, &tstr, start);
260 	rz_mtu3_shared_reg_write(ch, offset, tstr);
261 
262 	raw_spin_unlock_irqrestore(&priv->lock, flags);
263 }
264 
265 bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch)
266 {
267 	struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
268 	struct rz_mtu3_priv *priv = mtu->priv_data;
269 	unsigned long flags, tstr;
270 	bool ret = false;
271 	u16 offset;
272 	u8 bitpos;
273 
274 	/* start stop register shared by multiple timer channels */
275 	raw_spin_lock_irqsave(&priv->lock, flags);
276 
277 	offset = rz_mtu3_get_tstr_offset(ch);
278 	bitpos = rz_mtu3_get_tstr_bit_pos(ch);
279 	tstr = rz_mtu3_shared_reg_read(ch, offset);
280 	ret = tstr & BIT(bitpos);
281 
282 	raw_spin_unlock_irqrestore(&priv->lock, flags);
283 
284 	return ret;
285 }
286 EXPORT_SYMBOL_GPL(rz_mtu3_is_enabled);
287 
288 int rz_mtu3_enable(struct rz_mtu3_channel *ch)
289 {
290 	/* enable channel */
291 	rz_mtu3_start_stop_ch(ch, true);
292 
293 	return 0;
294 }
295 EXPORT_SYMBOL_GPL(rz_mtu3_enable);
296 
297 void rz_mtu3_disable(struct rz_mtu3_channel *ch)
298 {
299 	/* disable channel */
300 	rz_mtu3_start_stop_ch(ch, false);
301 }
302 EXPORT_SYMBOL_GPL(rz_mtu3_disable);
303 
304 static void rz_mtu3_reset_assert(void *data)
305 {
306 	struct rz_mtu3 *mtu = dev_get_drvdata(data);
307 	struct rz_mtu3_priv *priv = mtu->priv_data;
308 
309 	mfd_remove_devices(data);
310 	reset_control_assert(priv->rstc);
311 }
312 
313 static const struct mfd_cell rz_mtu3_devs[] = {
314 	{
315 		.name = "rz-mtu3-counter",
316 	},
317 	{
318 		.name = "pwm-rz-mtu3",
319 	},
320 };
321 
322 static int rz_mtu3_probe(struct platform_device *pdev)
323 {
324 	struct rz_mtu3_priv *priv;
325 	struct rz_mtu3 *ddata;
326 	unsigned int i;
327 	int ret;
328 
329 	ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
330 	if (!ddata)
331 		return -ENOMEM;
332 
333 	ddata->priv_data = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
334 	if (!ddata->priv_data)
335 		return -ENOMEM;
336 
337 	priv = ddata->priv_data;
338 
339 	priv->mmio = devm_platform_ioremap_resource(pdev, 0);
340 	if (IS_ERR(priv->mmio))
341 		return PTR_ERR(priv->mmio);
342 
343 	priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
344 	if (IS_ERR(priv->rstc))
345 		return PTR_ERR(priv->rstc);
346 
347 	ddata->clk = devm_clk_get(&pdev->dev, NULL);
348 	if (IS_ERR(ddata->clk))
349 		return PTR_ERR(ddata->clk);
350 
351 	reset_control_deassert(priv->rstc);
352 	raw_spin_lock_init(&priv->lock);
353 	platform_set_drvdata(pdev, ddata);
354 
355 	for (i = 0; i < RZ_MTU_NUM_CHANNELS; i++) {
356 		ddata->channels[i].channel_number = i;
357 		ddata->channels[i].is_busy = false;
358 		mutex_init(&ddata->channels[i].lock);
359 	}
360 
361 	ret = mfd_add_devices(&pdev->dev, 0, rz_mtu3_devs,
362 			      ARRAY_SIZE(rz_mtu3_devs), NULL, 0, NULL);
363 	if (ret < 0)
364 		goto err_assert;
365 
366 	return devm_add_action_or_reset(&pdev->dev, rz_mtu3_reset_assert,
367 					&pdev->dev);
368 
369 err_assert:
370 	reset_control_assert(priv->rstc);
371 	return ret;
372 }
373 
374 static const struct of_device_id rz_mtu3_of_match[] = {
375 	{ .compatible = "renesas,rz-mtu3", },
376 	{ /* sentinel */ }
377 };
378 MODULE_DEVICE_TABLE(of, rz_mtu3_of_match);
379 
380 static struct platform_driver rz_mtu3_driver = {
381 	.probe = rz_mtu3_probe,
382 	.driver	= {
383 		.name = "rz-mtu3",
384 		.of_match_table = rz_mtu3_of_match,
385 	},
386 };
387 module_platform_driver(rz_mtu3_driver);
388 
389 MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
390 MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a Core Driver");
391 MODULE_LICENSE("GPL");
392