xref: /openbmc/linux/drivers/mailbox/imx-mailbox.c (revision a01822e94ee53e8ebc9632fe2764048b81921254)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
4  */
5 
6 #include <linux/clk.h>
7 #include <linux/firmware/imx/ipc.h>
8 #include <linux/interrupt.h>
9 #include <linux/io.h>
10 #include <linux/iopoll.h>
11 #include <linux/kernel.h>
12 #include <linux/mailbox_controller.h>
13 #include <linux/module.h>
14 #include <linux/of_device.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/slab.h>
17 
18 #define IMX_MU_xSR_GIPn(x)	BIT(28 + (3 - (x)))
19 #define IMX_MU_xSR_RFn(x)	BIT(24 + (3 - (x)))
20 #define IMX_MU_xSR_TEn(x)	BIT(20 + (3 - (x)))
21 #define IMX_MU_xSR_BRDIP	BIT(9)
22 
23 /* General Purpose Interrupt Enable */
24 #define IMX_MU_xCR_GIEn(x)	BIT(28 + (3 - (x)))
25 /* Receive Interrupt Enable */
26 #define IMX_MU_xCR_RIEn(x)	BIT(24 + (3 - (x)))
27 /* Transmit Interrupt Enable */
28 #define IMX_MU_xCR_TIEn(x)	BIT(20 + (3 - (x)))
29 /* General Purpose Interrupt Request */
30 #define IMX_MU_xCR_GIRn(x)	BIT(16 + (3 - (x)))
31 
32 #define IMX_MU_CHANS		16
33 /* TX0/RX0/RXDB[0-3] */
34 #define IMX_MU_SCU_CHANS	6
35 #define IMX_MU_CHAN_NAME_SIZE	20
36 
37 enum imx_mu_chan_type {
38 	IMX_MU_TYPE_TX,		/* Tx */
39 	IMX_MU_TYPE_RX,		/* Rx */
40 	IMX_MU_TYPE_TXDB,	/* Tx doorbell */
41 	IMX_MU_TYPE_RXDB,	/* Rx doorbell */
42 };
43 
44 struct imx_sc_rpc_msg_max {
45 	struct imx_sc_rpc_msg hdr;
46 	u32 data[7];
47 };
48 
49 struct imx_mu_con_priv {
50 	unsigned int		idx;
51 	char			irq_desc[IMX_MU_CHAN_NAME_SIZE];
52 	enum imx_mu_chan_type	type;
53 	struct mbox_chan	*chan;
54 	struct tasklet_struct	txdb_tasklet;
55 };
56 
57 struct imx_mu_priv {
58 	struct device		*dev;
59 	void __iomem		*base;
60 	spinlock_t		xcr_lock; /* control register lock */
61 
62 	struct mbox_controller	mbox;
63 	struct mbox_chan	mbox_chans[IMX_MU_CHANS];
64 
65 	struct imx_mu_con_priv  con_priv[IMX_MU_CHANS];
66 	const struct imx_mu_dcfg	*dcfg;
67 	struct clk		*clk;
68 	int			irq;
69 
70 	bool			side_b;
71 };
72 
73 struct imx_mu_dcfg {
74 	int (*tx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data);
75 	int (*rx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);
76 	void (*init)(struct imx_mu_priv *priv);
77 	u32	xTR[4];		/* Transmit Registers */
78 	u32	xRR[4];		/* Receive Registers */
79 	u32	xSR;		/* Status Register */
80 	u32	xCR;		/* Control Register */
81 };
82 
83 static struct imx_mu_priv *to_imx_mu_priv(struct mbox_controller *mbox)
84 {
85 	return container_of(mbox, struct imx_mu_priv, mbox);
86 }
87 
88 static void imx_mu_write(struct imx_mu_priv *priv, u32 val, u32 offs)
89 {
90 	iowrite32(val, priv->base + offs);
91 }
92 
93 static u32 imx_mu_read(struct imx_mu_priv *priv, u32 offs)
94 {
95 	return ioread32(priv->base + offs);
96 }
97 
98 static u32 imx_mu_xcr_rmw(struct imx_mu_priv *priv, u32 set, u32 clr)
99 {
100 	unsigned long flags;
101 	u32 val;
102 
103 	spin_lock_irqsave(&priv->xcr_lock, flags);
104 	val = imx_mu_read(priv, priv->dcfg->xCR);
105 	val &= ~clr;
106 	val |= set;
107 	imx_mu_write(priv, val, priv->dcfg->xCR);
108 	spin_unlock_irqrestore(&priv->xcr_lock, flags);
109 
110 	return val;
111 }
112 
113 static int imx_mu_generic_tx(struct imx_mu_priv *priv,
114 			     struct imx_mu_con_priv *cp,
115 			     void *data)
116 {
117 	u32 *arg = data;
118 
119 	switch (cp->type) {
120 	case IMX_MU_TYPE_TX:
121 		imx_mu_write(priv, *arg, priv->dcfg->xTR[cp->idx]);
122 		imx_mu_xcr_rmw(priv, IMX_MU_xCR_TIEn(cp->idx), 0);
123 		break;
124 	case IMX_MU_TYPE_TXDB:
125 		imx_mu_xcr_rmw(priv, IMX_MU_xCR_GIRn(cp->idx), 0);
126 		tasklet_schedule(&cp->txdb_tasklet);
127 		break;
128 	default:
129 		dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
130 		return -EINVAL;
131 	}
132 
133 	return 0;
134 }
135 
136 static int imx_mu_generic_rx(struct imx_mu_priv *priv,
137 			     struct imx_mu_con_priv *cp)
138 {
139 	u32 dat;
140 
141 	dat = imx_mu_read(priv, priv->dcfg->xRR[cp->idx]);
142 	mbox_chan_received_data(cp->chan, (void *)&dat);
143 
144 	return 0;
145 }
146 
147 static int imx_mu_scu_tx(struct imx_mu_priv *priv,
148 			 struct imx_mu_con_priv *cp,
149 			 void *data)
150 {
151 	struct imx_sc_rpc_msg_max *msg = data;
152 	u32 *arg = data;
153 	int i, ret;
154 	u32 xsr;
155 
156 	switch (cp->type) {
157 	case IMX_MU_TYPE_TX:
158 		/*
159 		 * msg->hdr.size specifies the number of u32 words while
160 		 * sizeof yields bytes.
161 		 */
162 
163 		if (msg->hdr.size > sizeof(*msg) / 4) {
164 			/*
165 			 * The real message size can be different to
166 			 * struct imx_sc_rpc_msg_max size
167 			 */
168 			dev_err(priv->dev, "Maximal message size (%zu bytes) exceeded on TX; got: %i bytes\n", sizeof(*msg), msg->hdr.size << 2);
169 			return -EINVAL;
170 		}
171 
172 		for (i = 0; i < 4 && i < msg->hdr.size; i++)
173 			imx_mu_write(priv, *arg++, priv->dcfg->xTR[i % 4]);
174 		for (; i < msg->hdr.size; i++) {
175 			ret = readl_poll_timeout(priv->base + priv->dcfg->xSR,
176 						 xsr,
177 						 xsr & IMX_MU_xSR_TEn(i % 4),
178 						 0, 100);
179 			if (ret) {
180 				dev_err(priv->dev, "Send data index: %d timeout\n", i);
181 				return ret;
182 			}
183 			imx_mu_write(priv, *arg++, priv->dcfg->xTR[i % 4]);
184 		}
185 
186 		imx_mu_xcr_rmw(priv, IMX_MU_xCR_TIEn(cp->idx), 0);
187 		break;
188 	default:
189 		dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
190 		return -EINVAL;
191 	}
192 
193 	return 0;
194 }
195 
196 static int imx_mu_scu_rx(struct imx_mu_priv *priv,
197 			 struct imx_mu_con_priv *cp)
198 {
199 	struct imx_sc_rpc_msg_max msg;
200 	u32 *data = (u32 *)&msg;
201 	int i, ret;
202 	u32 xsr;
203 
204 	imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_RIEn(0));
205 	*data++ = imx_mu_read(priv, priv->dcfg->xRR[0]);
206 
207 	if (msg.hdr.size > sizeof(msg) / 4) {
208 		dev_err(priv->dev, "Maximal message size (%zu bytes) exceeded on RX; got: %i bytes\n", sizeof(msg), msg.hdr.size << 2);
209 		return -EINVAL;
210 	}
211 
212 	for (i = 1; i < msg.hdr.size; i++) {
213 		ret = readl_poll_timeout(priv->base + priv->dcfg->xSR, xsr,
214 					 xsr & IMX_MU_xSR_RFn(i % 4), 0, 100);
215 		if (ret) {
216 			dev_err(priv->dev, "timeout read idx %d\n", i);
217 			return ret;
218 		}
219 		*data++ = imx_mu_read(priv, priv->dcfg->xRR[i % 4]);
220 	}
221 
222 	imx_mu_xcr_rmw(priv, IMX_MU_xCR_RIEn(0), 0);
223 	mbox_chan_received_data(cp->chan, (void *)&msg);
224 
225 	return 0;
226 }
227 
228 static void imx_mu_txdb_tasklet(unsigned long data)
229 {
230 	struct imx_mu_con_priv *cp = (struct imx_mu_con_priv *)data;
231 
232 	mbox_chan_txdone(cp->chan, 0);
233 }
234 
235 static irqreturn_t imx_mu_isr(int irq, void *p)
236 {
237 	struct mbox_chan *chan = p;
238 	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
239 	struct imx_mu_con_priv *cp = chan->con_priv;
240 	u32 val, ctrl;
241 
242 	ctrl = imx_mu_read(priv, priv->dcfg->xCR);
243 	val = imx_mu_read(priv, priv->dcfg->xSR);
244 
245 	switch (cp->type) {
246 	case IMX_MU_TYPE_TX:
247 		val &= IMX_MU_xSR_TEn(cp->idx) &
248 			(ctrl & IMX_MU_xCR_TIEn(cp->idx));
249 		break;
250 	case IMX_MU_TYPE_RX:
251 		val &= IMX_MU_xSR_RFn(cp->idx) &
252 			(ctrl & IMX_MU_xCR_RIEn(cp->idx));
253 		break;
254 	case IMX_MU_TYPE_RXDB:
255 		val &= IMX_MU_xSR_GIPn(cp->idx) &
256 			(ctrl & IMX_MU_xCR_GIEn(cp->idx));
257 		break;
258 	default:
259 		break;
260 	}
261 
262 	if (!val)
263 		return IRQ_NONE;
264 
265 	if (val == IMX_MU_xSR_TEn(cp->idx)) {
266 		imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx));
267 		mbox_chan_txdone(chan, 0);
268 	} else if (val == IMX_MU_xSR_RFn(cp->idx)) {
269 		priv->dcfg->rx(priv, cp);
270 	} else if (val == IMX_MU_xSR_GIPn(cp->idx)) {
271 		imx_mu_write(priv, IMX_MU_xSR_GIPn(cp->idx), priv->dcfg->xSR);
272 		mbox_chan_received_data(chan, NULL);
273 	} else {
274 		dev_warn_ratelimited(priv->dev, "Not handled interrupt\n");
275 		return IRQ_NONE;
276 	}
277 
278 	return IRQ_HANDLED;
279 }
280 
281 static int imx_mu_send_data(struct mbox_chan *chan, void *data)
282 {
283 	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
284 	struct imx_mu_con_priv *cp = chan->con_priv;
285 
286 	return priv->dcfg->tx(priv, cp, data);
287 }
288 
289 static int imx_mu_startup(struct mbox_chan *chan)
290 {
291 	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
292 	struct imx_mu_con_priv *cp = chan->con_priv;
293 	int ret;
294 
295 	pm_runtime_get_sync(priv->dev);
296 	if (cp->type == IMX_MU_TYPE_TXDB) {
297 		/* Tx doorbell don't have ACK support */
298 		tasklet_init(&cp->txdb_tasklet, imx_mu_txdb_tasklet,
299 			     (unsigned long)cp);
300 		return 0;
301 	}
302 
303 	ret = request_irq(priv->irq, imx_mu_isr, IRQF_SHARED |
304 			  IRQF_NO_SUSPEND, cp->irq_desc, chan);
305 	if (ret) {
306 		dev_err(priv->dev,
307 			"Unable to acquire IRQ %d\n", priv->irq);
308 		return ret;
309 	}
310 
311 	switch (cp->type) {
312 	case IMX_MU_TYPE_RX:
313 		imx_mu_xcr_rmw(priv, IMX_MU_xCR_RIEn(cp->idx), 0);
314 		break;
315 	case IMX_MU_TYPE_RXDB:
316 		imx_mu_xcr_rmw(priv, IMX_MU_xCR_GIEn(cp->idx), 0);
317 		break;
318 	default:
319 		break;
320 	}
321 
322 	return 0;
323 }
324 
325 static void imx_mu_shutdown(struct mbox_chan *chan)
326 {
327 	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
328 	struct imx_mu_con_priv *cp = chan->con_priv;
329 
330 	if (cp->type == IMX_MU_TYPE_TXDB) {
331 		tasklet_kill(&cp->txdb_tasklet);
332 		pm_runtime_put_sync(priv->dev);
333 		return;
334 	}
335 
336 	switch (cp->type) {
337 	case IMX_MU_TYPE_TX:
338 		imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx));
339 		break;
340 	case IMX_MU_TYPE_RX:
341 		imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_RIEn(cp->idx));
342 		break;
343 	case IMX_MU_TYPE_RXDB:
344 		imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_GIEn(cp->idx));
345 		break;
346 	default:
347 		break;
348 	}
349 
350 	free_irq(priv->irq, chan);
351 	pm_runtime_put_sync(priv->dev);
352 }
353 
354 static const struct mbox_chan_ops imx_mu_ops = {
355 	.send_data = imx_mu_send_data,
356 	.startup = imx_mu_startup,
357 	.shutdown = imx_mu_shutdown,
358 };
359 
360 static struct mbox_chan *imx_mu_scu_xlate(struct mbox_controller *mbox,
361 					  const struct of_phandle_args *sp)
362 {
363 	u32 type, idx, chan;
364 
365 	if (sp->args_count != 2) {
366 		dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);
367 		return ERR_PTR(-EINVAL);
368 	}
369 
370 	type = sp->args[0]; /* channel type */
371 	idx = sp->args[1]; /* index */
372 
373 	switch (type) {
374 	case IMX_MU_TYPE_TX:
375 	case IMX_MU_TYPE_RX:
376 		if (idx != 0)
377 			dev_err(mbox->dev, "Invalid chan idx: %d\n", idx);
378 		chan = type;
379 		break;
380 	case IMX_MU_TYPE_RXDB:
381 		chan = 2 + idx;
382 		break;
383 	default:
384 		dev_err(mbox->dev, "Invalid chan type: %d\n", type);
385 		return ERR_PTR(-EINVAL);
386 	}
387 
388 	if (chan >= mbox->num_chans) {
389 		dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx);
390 		return ERR_PTR(-EINVAL);
391 	}
392 
393 	return &mbox->chans[chan];
394 }
395 
396 static struct mbox_chan * imx_mu_xlate(struct mbox_controller *mbox,
397 				       const struct of_phandle_args *sp)
398 {
399 	u32 type, idx, chan;
400 
401 	if (sp->args_count != 2) {
402 		dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);
403 		return ERR_PTR(-EINVAL);
404 	}
405 
406 	type = sp->args[0]; /* channel type */
407 	idx = sp->args[1]; /* index */
408 	chan = type * 4 + idx;
409 
410 	if (chan >= mbox->num_chans) {
411 		dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx);
412 		return ERR_PTR(-EINVAL);
413 	}
414 
415 	return &mbox->chans[chan];
416 }
417 
418 static void imx_mu_init_generic(struct imx_mu_priv *priv)
419 {
420 	unsigned int i;
421 
422 	for (i = 0; i < IMX_MU_CHANS; i++) {
423 		struct imx_mu_con_priv *cp = &priv->con_priv[i];
424 
425 		cp->idx = i % 4;
426 		cp->type = i >> 2;
427 		cp->chan = &priv->mbox_chans[i];
428 		priv->mbox_chans[i].con_priv = cp;
429 		snprintf(cp->irq_desc, sizeof(cp->irq_desc),
430 			 "imx_mu_chan[%i-%i]", cp->type, cp->idx);
431 	}
432 
433 	priv->mbox.num_chans = IMX_MU_CHANS;
434 	priv->mbox.of_xlate = imx_mu_xlate;
435 
436 	if (priv->side_b)
437 		return;
438 
439 	/* Set default MU configuration */
440 	imx_mu_write(priv, 0, priv->dcfg->xCR);
441 }
442 
443 static void imx_mu_init_scu(struct imx_mu_priv *priv)
444 {
445 	unsigned int i;
446 
447 	for (i = 0; i < IMX_MU_SCU_CHANS; i++) {
448 		struct imx_mu_con_priv *cp = &priv->con_priv[i];
449 
450 		cp->idx = i < 2 ? 0 : i - 2;
451 		cp->type = i < 2 ? i : IMX_MU_TYPE_RXDB;
452 		cp->chan = &priv->mbox_chans[i];
453 		priv->mbox_chans[i].con_priv = cp;
454 		snprintf(cp->irq_desc, sizeof(cp->irq_desc),
455 			 "imx_mu_chan[%i-%i]", cp->type, cp->idx);
456 	}
457 
458 	priv->mbox.num_chans = IMX_MU_SCU_CHANS;
459 	priv->mbox.of_xlate = imx_mu_scu_xlate;
460 
461 	/* Set default MU configuration */
462 	imx_mu_write(priv, 0, priv->dcfg->xCR);
463 }
464 
465 static int imx_mu_probe(struct platform_device *pdev)
466 {
467 	struct device *dev = &pdev->dev;
468 	struct device_node *np = dev->of_node;
469 	struct imx_mu_priv *priv;
470 	const struct imx_mu_dcfg *dcfg;
471 	int ret;
472 
473 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
474 	if (!priv)
475 		return -ENOMEM;
476 
477 	priv->dev = dev;
478 
479 	priv->base = devm_platform_ioremap_resource(pdev, 0);
480 	if (IS_ERR(priv->base))
481 		return PTR_ERR(priv->base);
482 
483 	priv->irq = platform_get_irq(pdev, 0);
484 	if (priv->irq < 0)
485 		return priv->irq;
486 
487 	dcfg = of_device_get_match_data(dev);
488 	if (!dcfg)
489 		return -EINVAL;
490 	priv->dcfg = dcfg;
491 
492 	priv->clk = devm_clk_get(dev, NULL);
493 	if (IS_ERR(priv->clk)) {
494 		if (PTR_ERR(priv->clk) != -ENOENT)
495 			return PTR_ERR(priv->clk);
496 
497 		priv->clk = NULL;
498 	}
499 
500 	ret = clk_prepare_enable(priv->clk);
501 	if (ret) {
502 		dev_err(dev, "Failed to enable clock\n");
503 		return ret;
504 	}
505 
506 	priv->side_b = of_property_read_bool(np, "fsl,mu-side-b");
507 
508 	priv->dcfg->init(priv);
509 
510 	spin_lock_init(&priv->xcr_lock);
511 
512 	priv->mbox.dev = dev;
513 	priv->mbox.ops = &imx_mu_ops;
514 	priv->mbox.chans = priv->mbox_chans;
515 	priv->mbox.txdone_irq = true;
516 
517 	platform_set_drvdata(pdev, priv);
518 
519 	ret = devm_mbox_controller_register(dev, &priv->mbox);
520 	if (ret) {
521 		clk_disable_unprepare(priv->clk);
522 		return ret;
523 	}
524 
525 	pm_runtime_enable(dev);
526 
527 	ret = pm_runtime_get_sync(dev);
528 	if (ret < 0) {
529 		pm_runtime_put_noidle(dev);
530 		goto disable_runtime_pm;
531 	}
532 
533 	ret = pm_runtime_put_sync(dev);
534 	if (ret < 0)
535 		goto disable_runtime_pm;
536 
537 	return 0;
538 
539 disable_runtime_pm:
540 	pm_runtime_disable(dev);
541 	return ret;
542 }
543 
544 static int imx_mu_remove(struct platform_device *pdev)
545 {
546 	struct imx_mu_priv *priv = platform_get_drvdata(pdev);
547 
548 	clk_disable_unprepare(priv->clk);
549 	pm_runtime_disable(priv->dev);
550 
551 	return 0;
552 }
553 
554 static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {
555 	.tx	= imx_mu_generic_tx,
556 	.rx	= imx_mu_generic_rx,
557 	.init	= imx_mu_init_generic,
558 	.xTR	= {0x0, 0x4, 0x8, 0xc},
559 	.xRR	= {0x10, 0x14, 0x18, 0x1c},
560 	.xSR	= 0x20,
561 	.xCR	= 0x24,
562 };
563 
564 static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
565 	.tx	= imx_mu_generic_tx,
566 	.rx	= imx_mu_generic_rx,
567 	.init	= imx_mu_init_generic,
568 	.xTR	= {0x20, 0x24, 0x28, 0x2c},
569 	.xRR	= {0x40, 0x44, 0x48, 0x4c},
570 	.xSR	= 0x60,
571 	.xCR	= 0x64,
572 };
573 
574 static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
575 	.tx	= imx_mu_scu_tx,
576 	.rx	= imx_mu_scu_rx,
577 	.init	= imx_mu_init_scu,
578 	.xTR	= {0x0, 0x4, 0x8, 0xc},
579 	.xRR	= {0x10, 0x14, 0x18, 0x1c},
580 	.xSR	= 0x20,
581 	.xCR	= 0x24,
582 };
583 
584 static const struct of_device_id imx_mu_dt_ids[] = {
585 	{ .compatible = "fsl,imx7ulp-mu", .data = &imx_mu_cfg_imx7ulp },
586 	{ .compatible = "fsl,imx6sx-mu", .data = &imx_mu_cfg_imx6sx },
587 	{ .compatible = "fsl,imx8-mu-scu", .data = &imx_mu_cfg_imx8_scu },
588 	{ },
589 };
590 MODULE_DEVICE_TABLE(of, imx_mu_dt_ids);
591 
592 static struct platform_driver imx_mu_driver = {
593 	.probe		= imx_mu_probe,
594 	.remove		= imx_mu_remove,
595 	.driver = {
596 		.name	= "imx_mu",
597 		.of_match_table = imx_mu_dt_ids,
598 	},
599 };
600 module_platform_driver(imx_mu_driver);
601 
602 MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
603 MODULE_DESCRIPTION("Message Unit driver for i.MX");
604 MODULE_LICENSE("GPL v2");
605