]> git.ipfire.org Git - people/ms/linux.git/blame - drivers/mailbox/imx-mailbox.c
mailbox:imx: using pm_runtime_resume_and_get
[people/ms/linux.git] / drivers / mailbox / imx-mailbox.c
CommitLineData
2bb70056
OR
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
a5cb407a 4 * Copyright 2022 NXP, Peng Fan <peng.fan@nxp.com>
2bb70056
OR
5 */
6
7#include <linux/clk.h>
0a67003b 8#include <linux/firmware/imx/ipc.h>
97961f78 9#include <linux/firmware/imx/s4.h>
2bb70056
OR
10#include <linux/interrupt.h>
11#include <linux/io.h>
0a67003b 12#include <linux/iopoll.h>
11dac1d3 13#include <linux/jiffies.h>
2bb70056
OR
14#include <linux/kernel.h>
15#include <linux/mailbox_controller.h>
16#include <linux/module.h>
17#include <linux/of_device.h>
676f23ea 18#include <linux/pm_runtime.h>
892cb524 19#include <linux/suspend.h>
2bb70056
OR
20#include <linux/slab.h>
21
2bb70056 22#define IMX_MU_CHANS 16
0a67003b
PF
23/* TX0/RX0/RXDB[0-3] */
24#define IMX_MU_SCU_CHANS 6
97961f78
PF
25/* TX0/RX0 */
26#define IMX_MU_S4_CHANS 2
2bb70056
OR
27#define IMX_MU_CHAN_NAME_SIZE 20
28
11dac1d3
FL
29#define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))
30#define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))
31
a5cb407a 32/* Please not change TX & RX */
2bb70056 33enum imx_mu_chan_type {
a5cb407a
PF
34 IMX_MU_TYPE_TX = 0, /* Tx */
35 IMX_MU_TYPE_RX = 1, /* Rx */
36 IMX_MU_TYPE_TXDB = 2, /* Tx doorbell */
37 IMX_MU_TYPE_RXDB = 3, /* Rx doorbell */
2bb70056
OR
38};
39
f689a7cf 40enum imx_mu_xcr {
4f0b776e 41 IMX_MU_GIER,
f689a7cf
PF
42 IMX_MU_GCR,
43 IMX_MU_TCR,
44 IMX_MU_RCR,
45 IMX_MU_xCR_MAX,
46};
47
48enum imx_mu_xsr {
49 IMX_MU_SR,
50 IMX_MU_GSR,
51 IMX_MU_TSR,
52 IMX_MU_RSR,
53};
54
0a67003b
PF
55struct imx_sc_rpc_msg_max {
56 struct imx_sc_rpc_msg hdr;
11dac1d3 57 u32 data[30];
0a67003b
PF
58};
59
97961f78
PF
60struct imx_s4_rpc_msg_max {
61 struct imx_s4_rpc_msg hdr;
62 u32 data[254];
63};
64
2bb70056
OR
65struct imx_mu_con_priv {
66 unsigned int idx;
67 char irq_desc[IMX_MU_CHAN_NAME_SIZE];
68 enum imx_mu_chan_type type;
69 struct mbox_chan *chan;
70 struct tasklet_struct txdb_tasklet;
71};
72
73struct imx_mu_priv {
74 struct device *dev;
75 void __iomem *base;
97961f78 76 void *msg;
2bb70056
OR
77 spinlock_t xcr_lock; /* control register lock */
78
79 struct mbox_controller mbox;
80 struct mbox_chan mbox_chans[IMX_MU_CHANS];
81
82 struct imx_mu_con_priv con_priv[IMX_MU_CHANS];
c6c6bc6e 83 const struct imx_mu_dcfg *dcfg;
2bb70056 84 struct clk *clk;
cfd162f6 85 int irq[IMX_MU_CHANS];
892cb524 86 bool suspend;
2bb70056 87
f689a7cf 88 u32 xcr[4];
ba5f9fa0 89
2bb70056
OR
90 bool side_b;
91};
92
4f0b776e
PF
93enum imx_mu_type {
94 IMX_MU_V1,
97961f78
PF
95 IMX_MU_V2 = BIT(1),
96 IMX_MU_V2_S4 = BIT(15),
a5cb407a 97 IMX_MU_V2_IRQ = BIT(16),
4f0b776e
PF
98};
99
63b38357
PF
100struct imx_mu_dcfg {
101 int (*tx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data);
102 int (*rx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);
315d2e56 103 int (*rxdb)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);
63b38357 104 void (*init)(struct imx_mu_priv *priv);
4f0b776e 105 enum imx_mu_type type;
32f7443d
PF
106 u32 xTR; /* Transmit Register0 */
107 u32 xRR; /* Receive Register0 */
f689a7cf
PF
108 u32 xSR[4]; /* Status Registers */
109 u32 xCR[4]; /* Control Registers */
c6c6bc6e
RZ
110};
111
97961f78
PF
112#define IMX_MU_xSR_GIPn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x))))
113#define IMX_MU_xSR_RFn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))
114#define IMX_MU_xSR_TEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x))))
4f0b776e
PF
115
116/* General Purpose Interrupt Enable */
97961f78 117#define IMX_MU_xCR_GIEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x))))
4f0b776e 118/* Receive Interrupt Enable */
97961f78 119#define IMX_MU_xCR_RIEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))
4f0b776e 120/* Transmit Interrupt Enable */
97961f78 121#define IMX_MU_xCR_TIEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x))))
4f0b776e 122/* General Purpose Interrupt Request */
97961f78 123#define IMX_MU_xCR_GIRn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(16 + (3 - (x))))
4f0b776e
PF
124
125
2bb70056
OR
126static struct imx_mu_priv *to_imx_mu_priv(struct mbox_controller *mbox)
127{
128 return container_of(mbox, struct imx_mu_priv, mbox);
129}
130
131static void imx_mu_write(struct imx_mu_priv *priv, u32 val, u32 offs)
132{
133 iowrite32(val, priv->base + offs);
134}
135
136static u32 imx_mu_read(struct imx_mu_priv *priv, u32 offs)
137{
138 return ioread32(priv->base + offs);
139}
140
11dac1d3
FL
141static int imx_mu_tx_waiting_write(struct imx_mu_priv *priv, u32 val, u32 idx)
142{
143 u64 timeout_time = get_jiffies_64() + IMX_MU_SECO_TX_TOUT;
144 u32 status;
145 u32 can_write;
146
147 dev_dbg(priv->dev, "Trying to write %.8x to idx %d\n", val, idx);
148
149 do {
150 status = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_TSR]);
151 can_write = status & IMX_MU_xSR_TEn(priv->dcfg->type, idx % 4);
152 } while (!can_write && time_is_after_jiffies64(timeout_time));
153
154 if (!can_write) {
155 dev_err(priv->dev, "timeout trying to write %.8x at %d(%.8x)\n",
156 val, idx, status);
157 return -ETIME;
158 }
159
160 imx_mu_write(priv, val, priv->dcfg->xTR + (idx % 4) * 4);
161
162 return 0;
163}
164
165static int imx_mu_rx_waiting_read(struct imx_mu_priv *priv, u32 *val, u32 idx)
166{
167 u64 timeout_time = get_jiffies_64() + IMX_MU_SECO_RX_TOUT;
168 u32 status;
169 u32 can_read;
170
171 dev_dbg(priv->dev, "Trying to read from idx %d\n", idx);
172
173 do {
174 status = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_RSR]);
175 can_read = status & IMX_MU_xSR_RFn(priv->dcfg->type, idx % 4);
176 } while (!can_read && time_is_after_jiffies64(timeout_time));
177
178 if (!can_read) {
179 dev_err(priv->dev, "timeout trying to read idx %d (%.8x)\n",
180 idx, status);
181 return -ETIME;
182 }
183
184 *val = imx_mu_read(priv, priv->dcfg->xRR + (idx % 4) * 4);
185 dev_dbg(priv->dev, "Read %.8x\n", *val);
186
187 return 0;
188}
189
f689a7cf 190static u32 imx_mu_xcr_rmw(struct imx_mu_priv *priv, enum imx_mu_xcr type, u32 set, u32 clr)
2bb70056
OR
191{
192 unsigned long flags;
193 u32 val;
194
195 spin_lock_irqsave(&priv->xcr_lock, flags);
f689a7cf 196 val = imx_mu_read(priv, priv->dcfg->xCR[type]);
2bb70056
OR
197 val &= ~clr;
198 val |= set;
f689a7cf 199 imx_mu_write(priv, val, priv->dcfg->xCR[type]);
2bb70056
OR
200 spin_unlock_irqrestore(&priv->xcr_lock, flags);
201
202 return val;
203}
204
63b38357
PF
205static int imx_mu_generic_tx(struct imx_mu_priv *priv,
206 struct imx_mu_con_priv *cp,
207 void *data)
208{
209 u32 *arg = data;
210
211 switch (cp->type) {
212 case IMX_MU_TYPE_TX:
32f7443d 213 imx_mu_write(priv, *arg, priv->dcfg->xTR + cp->idx * 4);
4f0b776e 214 imx_mu_xcr_rmw(priv, IMX_MU_TCR, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx), 0);
63b38357
PF
215 break;
216 case IMX_MU_TYPE_TXDB:
4f0b776e 217 imx_mu_xcr_rmw(priv, IMX_MU_GCR, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0);
63b38357
PF
218 tasklet_schedule(&cp->txdb_tasklet);
219 break;
220 default:
221 dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
222 return -EINVAL;
223 }
224
225 return 0;
226}
227
228static int imx_mu_generic_rx(struct imx_mu_priv *priv,
229 struct imx_mu_con_priv *cp)
230{
231 u32 dat;
232
32f7443d 233 dat = imx_mu_read(priv, priv->dcfg->xRR + (cp->idx) * 4);
63b38357
PF
234 mbox_chan_received_data(cp->chan, (void *)&dat);
235
236 return 0;
237}
238
315d2e56
PF
239static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,
240 struct imx_mu_con_priv *cp)
241{
242 imx_mu_write(priv, IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx),
243 priv->dcfg->xSR[IMX_MU_GSR]);
244 mbox_chan_received_data(cp->chan, NULL);
245
246 return 0;
247}
248
97961f78 249static int imx_mu_specific_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data)
0a67003b 250{
0a67003b
PF
251 u32 *arg = data;
252 int i, ret;
253 u32 xsr;
97961f78
PF
254 u32 size, max_size, num_tr;
255
256 if (priv->dcfg->type & IMX_MU_V2_S4) {
257 size = ((struct imx_s4_rpc_msg_max *)data)->hdr.size;
258 max_size = sizeof(struct imx_s4_rpc_msg_max);
259 num_tr = 8;
260 } else {
261 size = ((struct imx_sc_rpc_msg_max *)data)->hdr.size;
262 max_size = sizeof(struct imx_sc_rpc_msg_max);
263 num_tr = 4;
264 }
0a67003b
PF
265
266 switch (cp->type) {
267 case IMX_MU_TYPE_TX:
9d8ca628
PF
268 /*
269 * msg->hdr.size specifies the number of u32 words while
270 * sizeof yields bytes.
271 */
272
97961f78 273 if (size > max_size / 4) {
0a67003b
PF
274 /*
275 * The real message size can be different to
97961f78 276 * struct imx_sc_rpc_msg_max/imx_s4_rpc_msg_max size
0a67003b 277 */
97961f78 278 dev_err(priv->dev, "Maximal message size (%u bytes) exceeded on TX; got: %i bytes\n", max_size, size << 2);
0a67003b
PF
279 return -EINVAL;
280 }
281
97961f78
PF
282 for (i = 0; i < num_tr && i < size; i++)
283 imx_mu_write(priv, *arg++, priv->dcfg->xTR + (i % num_tr) * 4);
284 for (; i < size; i++) {
f689a7cf 285 ret = readl_poll_timeout(priv->base + priv->dcfg->xSR[IMX_MU_TSR],
0a67003b 286 xsr,
97961f78 287 xsr & IMX_MU_xSR_TEn(priv->dcfg->type, i % num_tr),
81a9d3b9 288 0, 5 * USEC_PER_SEC);
0a67003b
PF
289 if (ret) {
290 dev_err(priv->dev, "Send data index: %d timeout\n", i);
291 return ret;
292 }
97961f78 293 imx_mu_write(priv, *arg++, priv->dcfg->xTR + (i % num_tr) * 4);
0a67003b
PF
294 }
295
4f0b776e 296 imx_mu_xcr_rmw(priv, IMX_MU_TCR, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx), 0);
0a67003b
PF
297 break;
298 default:
299 dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
300 return -EINVAL;
301 }
302
303 return 0;
304}
305
97961f78 306static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp)
0a67003b 307{
97961f78 308 u32 *data;
0a67003b
PF
309 int i, ret;
310 u32 xsr;
97961f78
PF
311 u32 size, max_size;
312
313 data = (u32 *)priv->msg;
0a67003b 314
4f0b776e 315 imx_mu_xcr_rmw(priv, IMX_MU_RCR, 0, IMX_MU_xCR_RIEn(priv->dcfg->type, 0));
32f7443d 316 *data++ = imx_mu_read(priv, priv->dcfg->xRR);
0a67003b 317
97961f78
PF
318 if (priv->dcfg->type & IMX_MU_V2_S4) {
319 size = ((struct imx_s4_rpc_msg_max *)priv->msg)->hdr.size;
320 max_size = sizeof(struct imx_s4_rpc_msg_max);
321 } else {
322 size = ((struct imx_sc_rpc_msg_max *)priv->msg)->hdr.size;
323 max_size = sizeof(struct imx_sc_rpc_msg_max);
324 }
325
326 if (size > max_size / 4) {
327 dev_err(priv->dev, "Maximal message size (%u bytes) exceeded on RX; got: %i bytes\n", max_size, size << 2);
0a67003b
PF
328 return -EINVAL;
329 }
330
97961f78 331 for (i = 1; i < size; i++) {
f689a7cf 332 ret = readl_poll_timeout(priv->base + priv->dcfg->xSR[IMX_MU_RSR], xsr,
81a9d3b9
RV
333 xsr & IMX_MU_xSR_RFn(priv->dcfg->type, i % 4), 0,
334 5 * USEC_PER_SEC);
0a67003b
PF
335 if (ret) {
336 dev_err(priv->dev, "timeout read idx %d\n", i);
337 return ret;
338 }
32f7443d 339 *data++ = imx_mu_read(priv, priv->dcfg->xRR + (i % 4) * 4);
0a67003b
PF
340 }
341
4f0b776e 342 imx_mu_xcr_rmw(priv, IMX_MU_RCR, IMX_MU_xCR_RIEn(priv->dcfg->type, 0), 0);
97961f78 343 mbox_chan_received_data(cp->chan, (void *)priv->msg);
0a67003b
PF
344
345 return 0;
346}
347
11dac1d3
FL
348static int imx_mu_seco_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp,
349 void *data)
350{
351 struct imx_sc_rpc_msg_max *msg = data;
352 u32 *arg = data;
353 u32 byte_size;
354 int err;
355 int i;
356
357 dev_dbg(priv->dev, "Sending message\n");
358
359 switch (cp->type) {
360 case IMX_MU_TYPE_TXDB:
361 byte_size = msg->hdr.size * sizeof(u32);
362 if (byte_size > sizeof(*msg)) {
363 /*
364 * The real message size can be different to
365 * struct imx_sc_rpc_msg_max size
366 */
367 dev_err(priv->dev,
368 "Exceed max msg size (%zu) on TX, got: %i\n",
369 sizeof(*msg), byte_size);
370 return -EINVAL;
371 }
372
373 print_hex_dump_debug("from client ", DUMP_PREFIX_OFFSET, 4, 4,
374 data, byte_size, false);
375
376 /* Send first word */
377 dev_dbg(priv->dev, "Sending header\n");
378 imx_mu_write(priv, *arg++, priv->dcfg->xTR);
379
380 /* Send signaling */
381 dev_dbg(priv->dev, "Sending signaling\n");
382 imx_mu_xcr_rmw(priv, IMX_MU_GCR,
383 IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0);
384
385 /* Send words to fill the mailbox */
386 for (i = 1; i < 4 && i < msg->hdr.size; i++) {
387 dev_dbg(priv->dev, "Sending word %d\n", i);
388 imx_mu_write(priv, *arg++,
389 priv->dcfg->xTR + (i % 4) * 4);
390 }
391
392 /* Send rest of message waiting for remote read */
393 for (; i < msg->hdr.size; i++) {
394 dev_dbg(priv->dev, "Sending word %d\n", i);
395 err = imx_mu_tx_waiting_write(priv, *arg++, i);
396 if (err) {
397 dev_err(priv->dev, "Timeout tx %d\n", i);
398 return err;
399 }
400 }
401
402 /* Simulate hack for mbox framework */
403 tasklet_schedule(&cp->txdb_tasklet);
404
405 break;
406 default:
407 dev_warn_ratelimited(priv->dev,
408 "Send data on wrong channel type: %d\n",
409 cp->type);
410 return -EINVAL;
411 }
412
413 return 0;
414}
415
416static int imx_mu_seco_rxdb(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp)
417{
418 struct imx_sc_rpc_msg_max msg;
419 u32 *data = (u32 *)&msg;
420 u32 byte_size;
421 int err = 0;
422 int i;
423
424 dev_dbg(priv->dev, "Receiving message\n");
425
426 /* Read header */
427 dev_dbg(priv->dev, "Receiving header\n");
428 *data++ = imx_mu_read(priv, priv->dcfg->xRR);
429 byte_size = msg.hdr.size * sizeof(u32);
430 if (byte_size > sizeof(msg)) {
431 dev_err(priv->dev, "Exceed max msg size (%zu) on RX, got: %i\n",
432 sizeof(msg), byte_size);
433 err = -EINVAL;
434 goto error;
435 }
436
437 /* Read message waiting they are written */
438 for (i = 1; i < msg.hdr.size; i++) {
439 dev_dbg(priv->dev, "Receiving word %d\n", i);
440 err = imx_mu_rx_waiting_read(priv, data++, i);
441 if (err) {
442 dev_err(priv->dev, "Timeout rx %d\n", i);
443 goto error;
444 }
445 }
446
447 /* Clear GIP */
448 imx_mu_write(priv, IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx),
449 priv->dcfg->xSR[IMX_MU_GSR]);
450
451 print_hex_dump_debug("to client ", DUMP_PREFIX_OFFSET, 4, 4,
452 &msg, byte_size, false);
453
454 /* send data to client */
455 dev_dbg(priv->dev, "Sending message to client\n");
456 mbox_chan_received_data(cp->chan, (void *)&msg);
457
458 goto exit;
459
460error:
461 mbox_chan_received_data(cp->chan, ERR_PTR(err));
462
463exit:
464 return err;
465}
466
2bb70056
OR
467static void imx_mu_txdb_tasklet(unsigned long data)
468{
469 struct imx_mu_con_priv *cp = (struct imx_mu_con_priv *)data;
470
471 mbox_chan_txdone(cp->chan, 0);
472}
473
474static irqreturn_t imx_mu_isr(int irq, void *p)
475{
476 struct mbox_chan *chan = p;
477 struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
478 struct imx_mu_con_priv *cp = chan->con_priv;
63b38357 479 u32 val, ctrl;
2bb70056 480
2bb70056
OR
481 switch (cp->type) {
482 case IMX_MU_TYPE_TX:
f689a7cf
PF
483 ctrl = imx_mu_read(priv, priv->dcfg->xCR[IMX_MU_TCR]);
484 val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_TSR]);
4f0b776e
PF
485 val &= IMX_MU_xSR_TEn(priv->dcfg->type, cp->idx) &
486 (ctrl & IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx));
2bb70056
OR
487 break;
488 case IMX_MU_TYPE_RX:
f689a7cf
PF
489 ctrl = imx_mu_read(priv, priv->dcfg->xCR[IMX_MU_RCR]);
490 val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_RSR]);
4f0b776e
PF
491 val &= IMX_MU_xSR_RFn(priv->dcfg->type, cp->idx) &
492 (ctrl & IMX_MU_xCR_RIEn(priv->dcfg->type, cp->idx));
2bb70056
OR
493 break;
494 case IMX_MU_TYPE_RXDB:
4f0b776e 495 ctrl = imx_mu_read(priv, priv->dcfg->xCR[IMX_MU_GIER]);
f689a7cf 496 val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_GSR]);
4f0b776e
PF
497 val &= IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx) &
498 (ctrl & IMX_MU_xCR_GIEn(priv->dcfg->type, cp->idx));
2bb70056
OR
499 break;
500 default:
e80a7e7e
NC
501 dev_warn_ratelimited(priv->dev, "Unhandled channel type %d\n",
502 cp->type);
503 return IRQ_NONE;
2bb70056
OR
504 }
505
506 if (!val)
507 return IRQ_NONE;
508
4f0b776e
PF
509 if ((val == IMX_MU_xSR_TEn(priv->dcfg->type, cp->idx)) &&
510 (cp->type == IMX_MU_TYPE_TX)) {
511 imx_mu_xcr_rmw(priv, IMX_MU_TCR, 0, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx));
2bb70056 512 mbox_chan_txdone(chan, 0);
4f0b776e
PF
513 } else if ((val == IMX_MU_xSR_RFn(priv->dcfg->type, cp->idx)) &&
514 (cp->type == IMX_MU_TYPE_RX)) {
63b38357 515 priv->dcfg->rx(priv, cp);
4f0b776e
PF
516 } else if ((val == IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx)) &&
517 (cp->type == IMX_MU_TYPE_RXDB)) {
315d2e56 518 priv->dcfg->rxdb(priv, cp);
2bb70056
OR
519 } else {
520 dev_warn_ratelimited(priv->dev, "Not handled interrupt\n");
521 return IRQ_NONE;
522 }
523
892cb524
RG
524 if (priv->suspend)
525 pm_system_wakeup();
526
2bb70056
OR
527 return IRQ_HANDLED;
528}
529
530static int imx_mu_send_data(struct mbox_chan *chan, void *data)
531{
532 struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
533 struct imx_mu_con_priv *cp = chan->con_priv;
2bb70056 534
63b38357 535 return priv->dcfg->tx(priv, cp, data);
2bb70056
OR
536}
537
538static int imx_mu_startup(struct mbox_chan *chan)
539{
540 struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
541 struct imx_mu_con_priv *cp = chan->con_priv;
a5cb407a 542 unsigned long irq_flag = 0;
2bb70056
OR
543 int ret;
544
676f23ea 545 pm_runtime_get_sync(priv->dev);
2bb70056
OR
546 if (cp->type == IMX_MU_TYPE_TXDB) {
547 /* Tx doorbell don't have ACK support */
548 tasklet_init(&cp->txdb_tasklet, imx_mu_txdb_tasklet,
549 (unsigned long)cp);
550 return 0;
551 }
552
b7b2796b
AH
553 /* IPC MU should be with IRQF_NO_SUSPEND set */
554 if (!priv->dev->pm_domain)
555 irq_flag |= IRQF_NO_SUSPEND;
556
a5cb407a
PF
557 if (!(priv->dcfg->type & IMX_MU_V2_IRQ))
558 irq_flag |= IRQF_SHARED;
559
560 ret = request_irq(priv->irq[cp->type], imx_mu_isr, irq_flag, cp->irq_desc, chan);
2bb70056 561 if (ret) {
a5cb407a 562 dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq[cp->type]);
2bb70056
OR
563 return ret;
564 }
565
566 switch (cp->type) {
567 case IMX_MU_TYPE_RX:
4f0b776e 568 imx_mu_xcr_rmw(priv, IMX_MU_RCR, IMX_MU_xCR_RIEn(priv->dcfg->type, cp->idx), 0);
2bb70056
OR
569 break;
570 case IMX_MU_TYPE_RXDB:
4f0b776e 571 imx_mu_xcr_rmw(priv, IMX_MU_GIER, IMX_MU_xCR_GIEn(priv->dcfg->type, cp->idx), 0);
2bb70056
OR
572 break;
573 default:
574 break;
575 }
576
577 return 0;
578}
579
580static void imx_mu_shutdown(struct mbox_chan *chan)
581{
582 struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
583 struct imx_mu_con_priv *cp = chan->con_priv;
584
bf159d15 585 if (cp->type == IMX_MU_TYPE_TXDB) {
2bb70056 586 tasklet_kill(&cp->txdb_tasklet);
676f23ea 587 pm_runtime_put_sync(priv->dev);
bf159d15
DB
588 return;
589 }
2bb70056 590
5f0af07e
DB
591 switch (cp->type) {
592 case IMX_MU_TYPE_TX:
4f0b776e 593 imx_mu_xcr_rmw(priv, IMX_MU_TCR, 0, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx));
5f0af07e
DB
594 break;
595 case IMX_MU_TYPE_RX:
4f0b776e 596 imx_mu_xcr_rmw(priv, IMX_MU_RCR, 0, IMX_MU_xCR_RIEn(priv->dcfg->type, cp->idx));
5f0af07e
DB
597 break;
598 case IMX_MU_TYPE_RXDB:
4f0b776e 599 imx_mu_xcr_rmw(priv, IMX_MU_GIER, 0, IMX_MU_xCR_GIEn(priv->dcfg->type, cp->idx));
5f0af07e
DB
600 break;
601 default:
602 break;
603 }
2bb70056 604
a5cb407a 605 free_irq(priv->irq[cp->type], chan);
676f23ea 606 pm_runtime_put_sync(priv->dev);
2bb70056
OR
607}
608
609static const struct mbox_chan_ops imx_mu_ops = {
610 .send_data = imx_mu_send_data,
611 .startup = imx_mu_startup,
612 .shutdown = imx_mu_shutdown,
613};
614
97961f78
PF
615static struct mbox_chan *imx_mu_specific_xlate(struct mbox_controller *mbox,
616 const struct of_phandle_args *sp)
0a67003b
PF
617{
618 u32 type, idx, chan;
619
620 if (sp->args_count != 2) {
621 dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);
622 return ERR_PTR(-EINVAL);
623 }
624
625 type = sp->args[0]; /* channel type */
626 idx = sp->args[1]; /* index */
627
628 switch (type) {
629 case IMX_MU_TYPE_TX:
630 case IMX_MU_TYPE_RX:
631 if (idx != 0)
632 dev_err(mbox->dev, "Invalid chan idx: %d\n", idx);
633 chan = type;
634 break;
635 case IMX_MU_TYPE_RXDB:
636 chan = 2 + idx;
637 break;
638 default:
639 dev_err(mbox->dev, "Invalid chan type: %d\n", type);
1b3a347b 640 return ERR_PTR(-EINVAL);
0a67003b
PF
641 }
642
643 if (chan >= mbox->num_chans) {
644 dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx);
645 return ERR_PTR(-EINVAL);
646 }
647
648 return &mbox->chans[chan];
649}
650
2bb70056
OR
651static struct mbox_chan * imx_mu_xlate(struct mbox_controller *mbox,
652 const struct of_phandle_args *sp)
653{
654 u32 type, idx, chan;
655
656 if (sp->args_count != 2) {
657 dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);
658 return ERR_PTR(-EINVAL);
659 }
660
661 type = sp->args[0]; /* channel type */
662 idx = sp->args[1]; /* index */
663 chan = type * 4 + idx;
664
665 if (chan >= mbox->num_chans) {
666 dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx);
667 return ERR_PTR(-EINVAL);
668 }
669
670 return &mbox->chans[chan];
671}
672
11dac1d3
FL
673static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,
674 const struct of_phandle_args *sp)
675{
676 u32 type;
677
678 if (sp->args_count < 1) {
679 dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);
680 return ERR_PTR(-EINVAL);
681 }
682
683 type = sp->args[0]; /* channel type */
684
685 /* Only supports TXDB and RXDB */
686 if (type == IMX_MU_TYPE_TX || type == IMX_MU_TYPE_RX) {
687 dev_err(mbox->dev, "Invalid type: %d\n", type);
688 return ERR_PTR(-EINVAL);
689 }
690
691 return imx_mu_xlate(mbox, sp);
692}
693
2bb70056
OR
694static void imx_mu_init_generic(struct imx_mu_priv *priv)
695{
63b38357
PF
696 unsigned int i;
697
698 for (i = 0; i < IMX_MU_CHANS; i++) {
699 struct imx_mu_con_priv *cp = &priv->con_priv[i];
700
701 cp->idx = i % 4;
702 cp->type = i >> 2;
703 cp->chan = &priv->mbox_chans[i];
704 priv->mbox_chans[i].con_priv = cp;
705 snprintf(cp->irq_desc, sizeof(cp->irq_desc),
706 "imx_mu_chan[%i-%i]", cp->type, cp->idx);
707 }
708
709 priv->mbox.num_chans = IMX_MU_CHANS;
710 priv->mbox.of_xlate = imx_mu_xlate;
711
2bb70056
OR
712 if (priv->side_b)
713 return;
714
715 /* Set default MU configuration */
f689a7cf
PF
716 for (i = 0; i < IMX_MU_xCR_MAX; i++)
717 imx_mu_write(priv, 0, priv->dcfg->xCR[i]);
2bb70056
OR
718}
719
97961f78 720static void imx_mu_init_specific(struct imx_mu_priv *priv)
0a67003b
PF
721{
722 unsigned int i;
97961f78 723 int num_chans = priv->dcfg->type & IMX_MU_V2_S4 ? IMX_MU_S4_CHANS : IMX_MU_SCU_CHANS;
0a67003b 724
97961f78 725 for (i = 0; i < num_chans; i++) {
0a67003b
PF
726 struct imx_mu_con_priv *cp = &priv->con_priv[i];
727
728 cp->idx = i < 2 ? 0 : i - 2;
729 cp->type = i < 2 ? i : IMX_MU_TYPE_RXDB;
730 cp->chan = &priv->mbox_chans[i];
731 priv->mbox_chans[i].con_priv = cp;
732 snprintf(cp->irq_desc, sizeof(cp->irq_desc),
733 "imx_mu_chan[%i-%i]", cp->type, cp->idx);
734 }
735
97961f78
PF
736 priv->mbox.num_chans = num_chans;
737 priv->mbox.of_xlate = imx_mu_specific_xlate;
0a67003b
PF
738
739 /* Set default MU configuration */
f689a7cf
PF
740 for (i = 0; i < IMX_MU_xCR_MAX; i++)
741 imx_mu_write(priv, 0, priv->dcfg->xCR[i]);
0a67003b
PF
742}
743
11dac1d3
FL
744static void imx_mu_init_seco(struct imx_mu_priv *priv)
745{
746 imx_mu_init_generic(priv);
747 priv->mbox.of_xlate = imx_mu_seco_xlate;
748}
749
2bb70056
OR
750static int imx_mu_probe(struct platform_device *pdev)
751{
752 struct device *dev = &pdev->dev;
753 struct device_node *np = dev->of_node;
2bb70056 754 struct imx_mu_priv *priv;
c6c6bc6e 755 const struct imx_mu_dcfg *dcfg;
a5cb407a 756 int i, ret;
97961f78 757 u32 size;
2bb70056
OR
758
759 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
760 if (!priv)
761 return -ENOMEM;
762
763 priv->dev = dev;
764
0c40e631 765 priv->base = devm_platform_ioremap_resource(pdev, 0);
2bb70056
OR
766 if (IS_ERR(priv->base))
767 return PTR_ERR(priv->base);
768
c6c6bc6e
RZ
769 dcfg = of_device_get_match_data(dev);
770 if (!dcfg)
771 return -EINVAL;
772 priv->dcfg = dcfg;
a5cb407a
PF
773 if (priv->dcfg->type & IMX_MU_V2_IRQ) {
774 priv->irq[IMX_MU_TYPE_TX] = platform_get_irq_byname(pdev, "tx");
775 if (priv->irq[IMX_MU_TYPE_TX] < 0)
776 return priv->irq[IMX_MU_TYPE_TX];
777 priv->irq[IMX_MU_TYPE_RX] = platform_get_irq_byname(pdev, "rx");
778 if (priv->irq[IMX_MU_TYPE_RX] < 0)
779 return priv->irq[IMX_MU_TYPE_RX];
780 } else {
781 ret = platform_get_irq(pdev, 0);
782 if (ret < 0)
783 return ret;
784
785 for (i = 0; i < IMX_MU_CHANS; i++)
786 priv->irq[i] = ret;
787 }
c6c6bc6e 788
97961f78
PF
789 if (priv->dcfg->type & IMX_MU_V2_S4)
790 size = sizeof(struct imx_s4_rpc_msg_max);
791 else
792 size = sizeof(struct imx_sc_rpc_msg_max);
793
794 priv->msg = devm_kzalloc(dev, size, GFP_KERNEL);
05d06f37
DC
795 if (!priv->msg)
796 return -ENOMEM;
97961f78 797
2bb70056
OR
798 priv->clk = devm_clk_get(dev, NULL);
799 if (IS_ERR(priv->clk)) {
800 if (PTR_ERR(priv->clk) != -ENOENT)
801 return PTR_ERR(priv->clk);
802
803 priv->clk = NULL;
804 }
805
806 ret = clk_prepare_enable(priv->clk);
807 if (ret) {
808 dev_err(dev, "Failed to enable clock\n");
809 return ret;
810 }
811
2bb70056
OR
812 priv->side_b = of_property_read_bool(np, "fsl,mu-side-b");
813
63b38357
PF
814 priv->dcfg->init(priv);
815
2bb70056
OR
816 spin_lock_init(&priv->xcr_lock);
817
818 priv->mbox.dev = dev;
819 priv->mbox.ops = &imx_mu_ops;
820 priv->mbox.chans = priv->mbox_chans;
2bb70056
OR
821 priv->mbox.txdone_irq = true;
822
823 platform_set_drvdata(pdev, priv);
824
676f23ea 825 ret = devm_mbox_controller_register(dev, &priv->mbox);
47303f94
FE
826 if (ret) {
827 clk_disable_unprepare(priv->clk);
676f23ea 828 return ret;
47303f94 829 }
676f23ea
AH
830
831 pm_runtime_enable(dev);
832
504ff5b0 833 ret = pm_runtime_resume_and_get(dev);
834 if (ret < 0)
676f23ea 835 goto disable_runtime_pm;
676f23ea
AH
836
837 ret = pm_runtime_put_sync(dev);
838 if (ret < 0)
839 goto disable_runtime_pm;
840
bb2b2624
AH
841 clk_disable_unprepare(priv->clk);
842
676f23ea
AH
843 return 0;
844
845disable_runtime_pm:
846 pm_runtime_disable(dev);
bb2b2624 847 clk_disable_unprepare(priv->clk);
676f23ea 848 return ret;
2bb70056
OR
849}
850
851static int imx_mu_remove(struct platform_device *pdev)
852{
853 struct imx_mu_priv *priv = platform_get_drvdata(pdev);
854
676f23ea 855 pm_runtime_disable(priv->dev);
2bb70056
OR
856
857 return 0;
858}
859
63b38357
PF
860static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {
861 .tx = imx_mu_generic_tx,
862 .rx = imx_mu_generic_rx,
315d2e56 863 .rxdb = imx_mu_generic_rxdb,
63b38357 864 .init = imx_mu_init_generic,
32f7443d
PF
865 .xTR = 0x0,
866 .xRR = 0x10,
f689a7cf
PF
867 .xSR = {0x20, 0x20, 0x20, 0x20},
868 .xCR = {0x24, 0x24, 0x24, 0x24},
63b38357
PF
869};
870
871static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
872 .tx = imx_mu_generic_tx,
873 .rx = imx_mu_generic_rx,
315d2e56 874 .rxdb = imx_mu_generic_rxdb,
63b38357 875 .init = imx_mu_init_generic,
32f7443d
PF
876 .xTR = 0x20,
877 .xRR = 0x40,
f689a7cf
PF
878 .xSR = {0x60, 0x60, 0x60, 0x60},
879 .xCR = {0x64, 0x64, 0x64, 0x64},
63b38357
PF
880};
881
4f0b776e
PF
882static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
883 .tx = imx_mu_generic_tx,
884 .rx = imx_mu_generic_rx,
315d2e56 885 .rxdb = imx_mu_generic_rxdb,
4f0b776e
PF
886 .init = imx_mu_init_generic,
887 .type = IMX_MU_V2,
888 .xTR = 0x200,
889 .xRR = 0x280,
890 .xSR = {0xC, 0x118, 0x124, 0x12C},
891 .xCR = {0x110, 0x114, 0x120, 0x128},
892};
893
97961f78
PF
894static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp_s4 = {
895 .tx = imx_mu_specific_tx,
896 .rx = imx_mu_specific_rx,
897 .init = imx_mu_init_specific,
898 .type = IMX_MU_V2 | IMX_MU_V2_S4,
899 .xTR = 0x200,
900 .xRR = 0x280,
901 .xSR = {0xC, 0x118, 0x124, 0x12C},
902 .xCR = {0x110, 0x114, 0x120, 0x128},
903};
904
0184cc20
PF
905static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = {
906 .tx = imx_mu_specific_tx,
907 .rx = imx_mu_specific_rx,
908 .init = imx_mu_init_specific,
909 .type = IMX_MU_V2 | IMX_MU_V2_S4 | IMX_MU_V2_IRQ,
910 .xTR = 0x200,
911 .xRR = 0x280,
912 .xSR = {0xC, 0x118, 0x124, 0x12C},
913 .xCR = {0x110, 0x114, 0x120, 0x128},
914};
915
0a67003b 916static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
97961f78
PF
917 .tx = imx_mu_specific_tx,
918 .rx = imx_mu_specific_rx,
919 .init = imx_mu_init_specific,
315d2e56 920 .rxdb = imx_mu_generic_rxdb,
4f0b776e
PF
921 .xTR = 0x0,
922 .xRR = 0x10,
f689a7cf
PF
923 .xSR = {0x20, 0x20, 0x20, 0x20},
924 .xCR = {0x24, 0x24, 0x24, 0x24},
0a67003b
PF
925};
926
11dac1d3
FL
927static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = {
928 .tx = imx_mu_seco_tx,
929 .rx = imx_mu_generic_rx,
930 .rxdb = imx_mu_seco_rxdb,
931 .init = imx_mu_init_seco,
932 .xTR = 0x0,
933 .xRR = 0x10,
934 .xSR = {0x20, 0x20, 0x20, 0x20},
935 .xCR = {0x24, 0x24, 0x24, 0x24},
936};
937
2bb70056 938static const struct of_device_id imx_mu_dt_ids[] = {
c6c6bc6e
RZ
939 { .compatible = "fsl,imx7ulp-mu", .data = &imx_mu_cfg_imx7ulp },
940 { .compatible = "fsl,imx6sx-mu", .data = &imx_mu_cfg_imx6sx },
4f0b776e 941 { .compatible = "fsl,imx8ulp-mu", .data = &imx_mu_cfg_imx8ulp },
97961f78 942 { .compatible = "fsl,imx8ulp-mu-s4", .data = &imx_mu_cfg_imx8ulp_s4 },
0184cc20 943 { .compatible = "fsl,imx93-mu-s4", .data = &imx_mu_cfg_imx93_s4 },
0a67003b 944 { .compatible = "fsl,imx8-mu-scu", .data = &imx_mu_cfg_imx8_scu },
11dac1d3 945 { .compatible = "fsl,imx8-mu-seco", .data = &imx_mu_cfg_imx8_seco },
2bb70056
OR
946 { },
947};
948MODULE_DEVICE_TABLE(of, imx_mu_dt_ids);
949
03b70130 950static int __maybe_unused imx_mu_suspend_noirq(struct device *dev)
ba5f9fa0
DA
951{
952 struct imx_mu_priv *priv = dev_get_drvdata(dev);
f689a7cf 953 int i;
ba5f9fa0 954
f689a7cf
PF
955 if (!priv->clk) {
956 for (i = 0; i < IMX_MU_xCR_MAX; i++)
957 priv->xcr[i] = imx_mu_read(priv, priv->dcfg->xCR[i]);
958 }
ba5f9fa0 959
892cb524
RG
960 priv->suspend = true;
961
ba5f9fa0
DA
962 return 0;
963}
964
03b70130 965static int __maybe_unused imx_mu_resume_noirq(struct device *dev)
ba5f9fa0
DA
966{
967 struct imx_mu_priv *priv = dev_get_drvdata(dev);
f689a7cf 968 int i;
ba5f9fa0
DA
969
970 /*
971 * ONLY restore MU when context lost, the TIE could
972 * be set during noirq resume as there is MU data
973 * communication going on, and restore the saved
974 * value will overwrite the TIE and cause MU data
975 * send failed, may lead to system freeze. This issue
976 * is observed by testing freeze mode suspend.
977 */
8219efd0 978 if (!priv->clk && !imx_mu_read(priv, priv->dcfg->xCR[0])) {
f689a7cf
PF
979 for (i = 0; i < IMX_MU_xCR_MAX; i++)
980 imx_mu_write(priv, priv->xcr[i], priv->dcfg->xCR[i]);
981 }
ba5f9fa0 982
892cb524
RG
983 priv->suspend = false;
984
ba5f9fa0
DA
985 return 0;
986}
987
03b70130 988static int __maybe_unused imx_mu_runtime_suspend(struct device *dev)
bb2b2624
AH
989{
990 struct imx_mu_priv *priv = dev_get_drvdata(dev);
991
992 clk_disable_unprepare(priv->clk);
993
994 return 0;
995}
996
03b70130 997static int __maybe_unused imx_mu_runtime_resume(struct device *dev)
bb2b2624
AH
998{
999 struct imx_mu_priv *priv = dev_get_drvdata(dev);
1000 int ret;
1001
1002 ret = clk_prepare_enable(priv->clk);
1003 if (ret)
1004 dev_err(dev, "failed to enable clock\n");
1005
1006 return ret;
1007}
1008
ba5f9fa0
DA
1009static const struct dev_pm_ops imx_mu_pm_ops = {
1010 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_mu_suspend_noirq,
1011 imx_mu_resume_noirq)
bb2b2624
AH
1012 SET_RUNTIME_PM_OPS(imx_mu_runtime_suspend,
1013 imx_mu_runtime_resume, NULL)
ba5f9fa0
DA
1014};
1015
2bb70056
OR
1016static struct platform_driver imx_mu_driver = {
1017 .probe = imx_mu_probe,
1018 .remove = imx_mu_remove,
1019 .driver = {
1020 .name = "imx_mu",
1021 .of_match_table = imx_mu_dt_ids,
ba5f9fa0 1022 .pm = &imx_mu_pm_ops,
2bb70056
OR
1023 },
1024};
1025module_platform_driver(imx_mu_driver);
1026
1027MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
1028MODULE_DESCRIPTION("Message Unit driver for i.MX");
1029MODULE_LICENSE("GPL v2");