1 // SPDX-License-Identifier: GPL-2.0
3 * Renesas RZ/G2L Multi-Function Timer Pulse Unit 3(MTU3a) Core driver
5 * Copyright (C) 2023 Renesas Electronics Corporation
8 #include <linux/bitfield.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/module.h>
15 #include <linux/mod_devicetable.h>
16 #include <linux/platform_device.h>
17 #include <linux/reset.h>
18 #include <linux/spinlock.h>
24 struct reset_control
*rstc
;
28 /******* MTU3 registers (original offset is +0x1200) *******/
29 static const unsigned long rz_mtu3_8bit_ch_reg_offs
[][13] = {
30 [RZ_MTU3_CHAN_0
] = MTU_8BIT_CH_0(0x104, 0x090, 0x100, 0x128, 0x101, 0x102, 0x103, 0x126),
31 [RZ_MTU3_CHAN_1
] = MTU_8BIT_CH_1_2(0x184, 0x091, 0x185, 0x180, 0x194, 0x181, 0x182),
32 [RZ_MTU3_CHAN_2
] = MTU_8BIT_CH_1_2(0x204, 0x092, 0x205, 0x200, 0x20c, 0x201, 0x202),
33 [RZ_MTU3_CHAN_3
] = MTU_8BIT_CH_3_4_6_7(0x008, 0x093, 0x02c, 0x000, 0x04c, 0x002, 0x004, 0x005, 0x038),
34 [RZ_MTU3_CHAN_4
] = MTU_8BIT_CH_3_4_6_7(0x009, 0x094, 0x02d, 0x001, 0x04d, 0x003, 0x006, 0x007, 0x039),
35 [RZ_MTU3_CHAN_5
] = MTU_8BIT_CH_5(0xab2, 0x1eb, 0xab4, 0xab6, 0xa84, 0xa85, 0xa86, 0xa94, 0xa95, 0xa96, 0xaa4, 0xaa5, 0xaa6),
36 [RZ_MTU3_CHAN_6
] = MTU_8BIT_CH_3_4_6_7(0x808, 0x893, 0x82c, 0x800, 0x84c, 0x802, 0x804, 0x805, 0x838),
37 [RZ_MTU3_CHAN_7
] = MTU_8BIT_CH_3_4_6_7(0x809, 0x894, 0x82d, 0x801, 0x84d, 0x803, 0x806, 0x807, 0x839),
38 [RZ_MTU3_CHAN_8
] = MTU_8BIT_CH_8(0x404, 0x098, 0x400, 0x406, 0x401, 0x402, 0x403)
41 static const unsigned long rz_mtu3_16bit_ch_reg_offs
[][12] = {
42 [RZ_MTU3_CHAN_0
] = MTU_16BIT_CH_0(0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x120, 0x122),
43 [RZ_MTU3_CHAN_1
] = MTU_16BIT_CH_1_2(0x186, 0x188, 0x18a),
44 [RZ_MTU3_CHAN_2
] = MTU_16BIT_CH_1_2(0x206, 0x208, 0x20a),
45 [RZ_MTU3_CHAN_3
] = MTU_16BIT_CH_3_6(0x010, 0x018, 0x01a, 0x024, 0x026, 0x072),
46 [RZ_MTU3_CHAN_4
] = MTU_16BIT_CH_4_7(0x012, 0x01c, 0x01e, 0x028, 0x2a, 0x074, 0x076, 0x040, 0x044, 0x046, 0x048, 0x04a),
47 [RZ_MTU3_CHAN_5
] = MTU_16BIT_CH_5(0xa80, 0xa82, 0xa90, 0xa92, 0xaa0, 0xaa2),
48 [RZ_MTU3_CHAN_6
] = MTU_16BIT_CH_3_6(0x810, 0x818, 0x81a, 0x824, 0x826, 0x872),
49 [RZ_MTU3_CHAN_7
] = MTU_16BIT_CH_4_7(0x812, 0x81c, 0x81e, 0x828, 0x82a, 0x874, 0x876, 0x840, 0x844, 0x846, 0x848, 0x84a)
52 static const unsigned long rz_mtu3_32bit_ch_reg_offs
[][5] = {
53 [RZ_MTU3_CHAN_1
] = MTU_32BIT_CH_1(0x1a0, 0x1a4, 0x1a8),
54 [RZ_MTU3_CHAN_8
] = MTU_32BIT_CH_8(0x408, 0x40c, 0x410, 0x414, 0x418)
57 static bool rz_mtu3_is_16bit_shared_reg(u16 offset
)
59 return (offset
== RZ_MTU3_TDDRA
|| offset
== RZ_MTU3_TDDRB
||
60 offset
== RZ_MTU3_TCDRA
|| offset
== RZ_MTU3_TCDRB
||
61 offset
== RZ_MTU3_TCBRA
|| offset
== RZ_MTU3_TCBRB
||
62 offset
== RZ_MTU3_TCNTSA
|| offset
== RZ_MTU3_TCNTSB
);
65 u16
rz_mtu3_shared_reg_read(struct rz_mtu3_channel
*ch
, u16 offset
)
67 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
68 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
70 if (rz_mtu3_is_16bit_shared_reg(offset
))
71 return readw(priv
->mmio
+ offset
);
73 return readb(priv
->mmio
+ offset
);
75 EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_read
);
77 u8
rz_mtu3_8bit_ch_read(struct rz_mtu3_channel
*ch
, u16 offset
)
79 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
80 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
83 ch_offs
= rz_mtu3_8bit_ch_reg_offs
[ch
->channel_number
][offset
];
85 return readb(priv
->mmio
+ ch_offs
);
87 EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_read
);
89 u16
rz_mtu3_16bit_ch_read(struct rz_mtu3_channel
*ch
, u16 offset
)
91 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
92 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
95 /* MTU8 doesn't have 16-bit registers */
96 if (ch
->channel_number
== RZ_MTU3_CHAN_8
)
99 ch_offs
= rz_mtu3_16bit_ch_reg_offs
[ch
->channel_number
][offset
];
101 return readw(priv
->mmio
+ ch_offs
);
103 EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_read
);
105 u32
rz_mtu3_32bit_ch_read(struct rz_mtu3_channel
*ch
, u16 offset
)
107 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
108 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
111 if (ch
->channel_number
!= RZ_MTU3_CHAN_1
&& ch
->channel_number
!= RZ_MTU3_CHAN_8
)
114 ch_offs
= rz_mtu3_32bit_ch_reg_offs
[ch
->channel_number
][offset
];
116 return readl(priv
->mmio
+ ch_offs
);
118 EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_read
);
120 void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel
*ch
, u16 offset
, u8 val
)
122 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
123 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
126 ch_offs
= rz_mtu3_8bit_ch_reg_offs
[ch
->channel_number
][offset
];
127 writeb(val
, priv
->mmio
+ ch_offs
);
129 EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_write
);
131 void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel
*ch
, u16 offset
, u16 val
)
133 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
134 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
137 /* MTU8 doesn't have 16-bit registers */
138 if (ch
->channel_number
== RZ_MTU3_CHAN_8
)
141 ch_offs
= rz_mtu3_16bit_ch_reg_offs
[ch
->channel_number
][offset
];
142 writew(val
, priv
->mmio
+ ch_offs
);
144 EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_write
);
146 void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel
*ch
, u16 offset
, u32 val
)
148 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
149 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
152 if (ch
->channel_number
!= RZ_MTU3_CHAN_1
&& ch
->channel_number
!= RZ_MTU3_CHAN_8
)
155 ch_offs
= rz_mtu3_32bit_ch_reg_offs
[ch
->channel_number
][offset
];
156 writel(val
, priv
->mmio
+ ch_offs
);
158 EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_write
);
160 void rz_mtu3_shared_reg_write(struct rz_mtu3_channel
*ch
, u16 offset
, u16 value
)
162 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
163 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
165 if (rz_mtu3_is_16bit_shared_reg(offset
))
166 writew(value
, priv
->mmio
+ offset
);
168 writeb((u8
)value
, priv
->mmio
+ offset
);
170 EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_write
);
172 void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel
*ch
, u16 offset
,
175 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
176 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
177 unsigned long tmdr
, flags
;
179 spin_lock_irqsave(&priv
->lock
, flags
);
180 tmdr
= rz_mtu3_shared_reg_read(ch
, offset
);
181 __assign_bit(pos
, &tmdr
, !!val
);
182 rz_mtu3_shared_reg_write(ch
, offset
, tmdr
);
183 spin_unlock_irqrestore(&priv
->lock
, flags
);
185 EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_update_bit
);
187 static u16
rz_mtu3_get_tstr_offset(struct rz_mtu3_channel
*ch
)
191 switch (ch
->channel_number
) {
198 offset
= RZ_MTU3_TSTRA
;
201 offset
= RZ_MTU3_TSTR
;
205 offset
= RZ_MTU3_TSTRB
;
215 static u8
rz_mtu3_get_tstr_bit_pos(struct rz_mtu3_channel
*ch
)
219 switch (ch
->channel_number
) {
225 bitpos
= ch
->channel_number
;
247 static void rz_mtu3_start_stop_ch(struct rz_mtu3_channel
*ch
, bool start
)
249 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
250 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
251 unsigned long flags
, tstr
;
255 offset
= rz_mtu3_get_tstr_offset(ch
);
256 bitpos
= rz_mtu3_get_tstr_bit_pos(ch
);
258 /* start stop register shared by multiple timer channels */
259 spin_lock_irqsave(&priv
->lock
, flags
);
261 tstr
= rz_mtu3_shared_reg_read(ch
, offset
);
262 __assign_bit(bitpos
, &tstr
, start
);
263 rz_mtu3_shared_reg_write(ch
, offset
, tstr
);
265 spin_unlock_irqrestore(&priv
->lock
, flags
);
268 bool rz_mtu3_is_enabled(struct rz_mtu3_channel
*ch
)
270 struct rz_mtu3
*mtu
= dev_get_drvdata(ch
->dev
->parent
);
271 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
272 unsigned long flags
, tstr
;
276 offset
= rz_mtu3_get_tstr_offset(ch
);
277 bitpos
= rz_mtu3_get_tstr_bit_pos(ch
);
279 /* start stop register shared by multiple timer channels */
280 spin_lock_irqsave(&priv
->lock
, flags
);
281 tstr
= rz_mtu3_shared_reg_read(ch
, offset
);
282 spin_unlock_irqrestore(&priv
->lock
, flags
);
284 return tstr
& BIT(bitpos
);
286 EXPORT_SYMBOL_GPL(rz_mtu3_is_enabled
);
288 int rz_mtu3_enable(struct rz_mtu3_channel
*ch
)
291 rz_mtu3_start_stop_ch(ch
, true);
295 EXPORT_SYMBOL_GPL(rz_mtu3_enable
);
297 void rz_mtu3_disable(struct rz_mtu3_channel
*ch
)
299 /* disable channel */
300 rz_mtu3_start_stop_ch(ch
, false);
302 EXPORT_SYMBOL_GPL(rz_mtu3_disable
);
304 static void rz_mtu3_reset_assert(void *data
)
306 struct rz_mtu3
*mtu
= dev_get_drvdata(data
);
307 struct rz_mtu3_priv
*priv
= mtu
->priv_data
;
309 mfd_remove_devices(data
);
310 reset_control_assert(priv
->rstc
);
313 static const struct mfd_cell rz_mtu3_devs
[] = {
315 .name
= "rz-mtu3-counter",
318 .name
= "pwm-rz-mtu3",
322 static int rz_mtu3_probe(struct platform_device
*pdev
)
324 struct rz_mtu3_priv
*priv
;
325 struct rz_mtu3
*ddata
;
329 ddata
= devm_kzalloc(&pdev
->dev
, sizeof(*ddata
), GFP_KERNEL
);
333 ddata
->priv_data
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
334 if (!ddata
->priv_data
)
337 priv
= ddata
->priv_data
;
339 priv
->mmio
= devm_platform_ioremap_resource(pdev
, 0);
340 if (IS_ERR(priv
->mmio
))
341 return PTR_ERR(priv
->mmio
);
343 priv
->rstc
= devm_reset_control_get_exclusive(&pdev
->dev
, NULL
);
344 if (IS_ERR(priv
->rstc
))
345 return PTR_ERR(priv
->rstc
);
347 ddata
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
348 if (IS_ERR(ddata
->clk
))
349 return PTR_ERR(ddata
->clk
);
351 reset_control_deassert(priv
->rstc
);
352 spin_lock_init(&priv
->lock
);
353 platform_set_drvdata(pdev
, ddata
);
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
);
361 ret
= mfd_add_devices(&pdev
->dev
, 0, rz_mtu3_devs
,
362 ARRAY_SIZE(rz_mtu3_devs
), NULL
, 0, NULL
);
366 return devm_add_action_or_reset(&pdev
->dev
, rz_mtu3_reset_assert
,
370 reset_control_assert(priv
->rstc
);
374 static const struct of_device_id rz_mtu3_of_match
[] = {
375 { .compatible
= "renesas,rz-mtu3", },
378 MODULE_DEVICE_TABLE(of
, rz_mtu3_of_match
);
380 static struct platform_driver rz_mtu3_driver
= {
381 .probe
= rz_mtu3_probe
,
384 .of_match_table
= rz_mtu3_of_match
,
387 module_platform_driver(rz_mtu3_driver
);
389 MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
390 MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a Core Driver");
391 MODULE_LICENSE("GPL");