1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright 2025 Cix Technology Group Co., Ltd.
4 */
5
6 #include <linux/device.h>
7 #include <linux/err.h>
8 #include <linux/io.h>
9 #include <linux/interrupt.h>
10 #include <linux/kernel.h>
11 #include <linux/mailbox_controller.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14
15 /*
16 * The maximum transmission size is 32 words or 128 bytes.
17 */
18 #define CIX_MBOX_MSG_WORDS 32 /* Max length = 32 words */
19 #define CIX_MBOX_MSG_LEN_MASK 0x7fL /* Max length = 128 bytes */
20
21 /* [0~7] Fast channel
22 * [8] doorbell base channel
23 * [9]fifo base channel
24 * [10] register base channel
25 */
26 #define CIX_MBOX_FAST_IDX 7
27 #define CIX_MBOX_DB_IDX 8
28 #define CIX_MBOX_FIFO_IDX 9
29 #define CIX_MBOX_REG_IDX 10
30 #define CIX_MBOX_CHANS 11
31
32 /* Register define */
33 #define CIX_REG_MSG(n) (0x0 + 0x4*(n)) /* 0x0~0x7c */
34 #define CIX_REG_DB_ACK CIX_REG_MSG(CIX_MBOX_MSG_WORDS) /* 0x80 */
35 #define CIX_ERR_COMP (CIX_REG_DB_ACK + 0x4) /* 0x84 */
36 #define CIX_ERR_COMP_CLR (CIX_REG_DB_ACK + 0x8) /* 0x88 */
37 #define CIX_REG_F_INT(IDX) (CIX_ERR_COMP_CLR + 0x4*(IDX+1)) /* 0x8c~0xa8 */
38 #define CIX_FIFO_WR (CIX_REG_F_INT(CIX_MBOX_FAST_IDX+1)) /* 0xac */
39 #define CIX_FIFO_RD (CIX_FIFO_WR + 0x4) /* 0xb0 */
40 #define CIX_FIFO_STAS (CIX_FIFO_WR + 0x8) /* 0xb4 */
41 #define CIX_FIFO_WM (CIX_FIFO_WR + 0xc) /* 0xb8 */
42 #define CIX_INT_ENABLE (CIX_FIFO_WR + 0x10) /* 0xbc */
43 #define CIX_INT_ENABLE_SIDE_B (CIX_FIFO_WR + 0x14) /* 0xc0 */
44 #define CIX_INT_CLEAR (CIX_FIFO_WR + 0x18) /* 0xc4 */
45 #define CIX_INT_STATUS (CIX_FIFO_WR + 0x1c) /* 0xc8 */
46 #define CIX_FIFO_RST (CIX_FIFO_WR + 0x20) /* 0xcc */
47
48 #define CIX_MBOX_TX 0
49 #define CIX_MBOX_RX 1
50
51 #define CIX_DB_INT_BIT BIT(0)
52 #define CIX_DB_ACK_INT_BIT BIT(1)
53
54 #define CIX_FIFO_WM_DEFAULT CIX_MBOX_MSG_WORDS
55 #define CIX_FIFO_STAS_WMK BIT(0)
56 #define CIX_FIFO_STAS_FULL BIT(1)
57 #define CIX_FIFO_STAS_EMPTY BIT(2)
58 #define CIX_FIFO_STAS_UFLOW BIT(3)
59 #define CIX_FIFO_STAS_OFLOW BIT(4)
60
61 #define CIX_FIFO_RST_BIT BIT(0)
62
63 #define CIX_DB_INT BIT(0)
64 #define CIX_ACK_INT BIT(1)
65 #define CIX_FIFO_FULL_INT BIT(2)
66 #define CIX_FIFO_EMPTY_INT BIT(3)
67 #define CIX_FIFO_WM01_INT BIT(4)
68 #define CIX_FIFO_WM10_INT BIT(5)
69 #define CIX_FIFO_OFLOW_INT BIT(6)
70 #define CIX_FIFO_UFLOW_INT BIT(7)
71 #define CIX_FIFO_N_EMPTY_INT BIT(8)
72 #define CIX_FAST_CH_INT(IDX) BIT((IDX)+9)
73
74 #define CIX_SHMEM_OFFSET 0x80
75
76 enum cix_mbox_chan_type {
77 CIX_MBOX_TYPE_DB,
78 CIX_MBOX_TYPE_REG,
79 CIX_MBOX_TYPE_FIFO,
80 CIX_MBOX_TYPE_FAST,
81 };
82
83 struct cix_mbox_con_priv {
84 enum cix_mbox_chan_type type;
85 struct mbox_chan *chan;
86 int index;
87 };
88
89 struct cix_mbox_priv {
90 struct device *dev;
91 int irq;
92 int dir;
93 void __iomem *base; /* region for mailbox */
94 struct cix_mbox_con_priv con_priv[CIX_MBOX_CHANS];
95 struct mbox_chan mbox_chans[CIX_MBOX_CHANS];
96 struct mbox_controller mbox;
97 bool use_shmem;
98 };
99
100 /*
101 * The CIX mailbox supports four types of transfers:
102 * CIX_MBOX_TYPE_DB, CIX_MBOX_TYPE_FAST, CIX_MBOX_TYPE_REG, and CIX_MBOX_TYPE_FIFO.
103 * For the REG and FIFO types of transfers, the message format is as follows:
104 */
105 union cix_mbox_msg_reg_fifo {
106 u32 length; /* unit is byte */
107 u32 buf[CIX_MBOX_MSG_WORDS]; /* buf[0] must be the byte length of this array */
108 };
109
to_cix_mbox_priv(struct mbox_controller * mbox)110 static struct cix_mbox_priv *to_cix_mbox_priv(struct mbox_controller *mbox)
111 {
112 return container_of(mbox, struct cix_mbox_priv, mbox);
113 }
114
cix_mbox_write(struct cix_mbox_priv * priv,u32 val,u32 offset)115 static void cix_mbox_write(struct cix_mbox_priv *priv, u32 val, u32 offset)
116 {
117 if (priv->use_shmem)
118 iowrite32(val, priv->base + offset - CIX_SHMEM_OFFSET);
119 else
120 iowrite32(val, priv->base + offset);
121 }
122
cix_mbox_read(struct cix_mbox_priv * priv,u32 offset)123 static u32 cix_mbox_read(struct cix_mbox_priv *priv, u32 offset)
124 {
125 if (priv->use_shmem)
126 return ioread32(priv->base + offset - CIX_SHMEM_OFFSET);
127 else
128 return ioread32(priv->base + offset);
129 }
130
mbox_fifo_empty(struct mbox_chan * chan)131 static bool mbox_fifo_empty(struct mbox_chan *chan)
132 {
133 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
134
135 return ((cix_mbox_read(priv, CIX_FIFO_STAS) & CIX_FIFO_STAS_EMPTY) ? true : false);
136 }
137
138 /*
139 *The transmission unit of the CIX mailbox is word.
140 *The byte length should be converted into the word length.
141 */
mbox_get_msg_size(void * msg)142 static inline u32 mbox_get_msg_size(void *msg)
143 {
144 u32 len;
145
146 len = ((u32 *)msg)[0] & CIX_MBOX_MSG_LEN_MASK;
147 return DIV_ROUND_UP(len, 4);
148 }
149
cix_mbox_send_data_db(struct mbox_chan * chan,void * data)150 static int cix_mbox_send_data_db(struct mbox_chan *chan, void *data)
151 {
152 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
153
154 /* trigger doorbell irq */
155 cix_mbox_write(priv, CIX_DB_INT_BIT, CIX_REG_DB_ACK);
156
157 return 0;
158 }
159
cix_mbox_send_data_reg(struct mbox_chan * chan,void * data)160 static int cix_mbox_send_data_reg(struct mbox_chan *chan, void *data)
161 {
162 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
163 union cix_mbox_msg_reg_fifo *msg = data;
164 u32 len, i;
165
166 if (!data)
167 return -EINVAL;
168
169 len = mbox_get_msg_size(data);
170 for (i = 0; i < len; i++)
171 cix_mbox_write(priv, msg->buf[i], CIX_REG_MSG(i));
172
173 /* trigger doorbell irq */
174 cix_mbox_write(priv, CIX_DB_INT_BIT, CIX_REG_DB_ACK);
175
176 return 0;
177 }
178
cix_mbox_send_data_fifo(struct mbox_chan * chan,void * data)179 static int cix_mbox_send_data_fifo(struct mbox_chan *chan, void *data)
180 {
181 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
182 union cix_mbox_msg_reg_fifo *msg = data;
183 u32 len, val, i;
184
185 if (!data)
186 return -EINVAL;
187
188 len = mbox_get_msg_size(data);
189 cix_mbox_write(priv, len, CIX_FIFO_WM);
190 for (i = 0; i < len; i++)
191 cix_mbox_write(priv, msg->buf[i], CIX_FIFO_WR);
192
193 /* Enable fifo empty interrupt */
194 val = cix_mbox_read(priv, CIX_INT_ENABLE);
195 val |= CIX_FIFO_EMPTY_INT;
196 cix_mbox_write(priv, val, CIX_INT_ENABLE);
197
198 return 0;
199 }
200
cix_mbox_send_data_fast(struct mbox_chan * chan,void * data)201 static int cix_mbox_send_data_fast(struct mbox_chan *chan, void *data)
202 {
203 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
204 struct cix_mbox_con_priv *cp = chan->con_priv;
205 u32 *arg = (u32 *)data;
206 int index = cp->index;
207
208 if (!data)
209 return -EINVAL;
210
211 if (index < 0 || index > CIX_MBOX_FAST_IDX) {
212 dev_err(priv->dev, "Invalid Mbox index %d\n", index);
213 return -EINVAL;
214 }
215
216 cix_mbox_write(priv, arg[0], CIX_REG_F_INT(index));
217
218 return 0;
219 }
220
cix_mbox_send_data(struct mbox_chan * chan,void * data)221 static int cix_mbox_send_data(struct mbox_chan *chan, void *data)
222 {
223 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
224 struct cix_mbox_con_priv *cp = chan->con_priv;
225
226 if (priv->dir != CIX_MBOX_TX) {
227 dev_err(priv->dev, "Invalid Mbox dir %d\n", priv->dir);
228 return -EINVAL;
229 }
230
231 switch (cp->type) {
232 case CIX_MBOX_TYPE_DB:
233 cix_mbox_send_data_db(chan, data);
234 break;
235 case CIX_MBOX_TYPE_REG:
236 cix_mbox_send_data_reg(chan, data);
237 break;
238 case CIX_MBOX_TYPE_FIFO:
239 cix_mbox_send_data_fifo(chan, data);
240 break;
241 case CIX_MBOX_TYPE_FAST:
242 cix_mbox_send_data_fast(chan, data);
243 break;
244 default:
245 dev_err(priv->dev, "Invalid channel type: %d\n", cp->type);
246 return -EINVAL;
247 }
248 return 0;
249 }
250
cix_mbox_isr_db(struct mbox_chan * chan)251 static void cix_mbox_isr_db(struct mbox_chan *chan)
252 {
253 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
254 u32 int_status;
255
256 int_status = cix_mbox_read(priv, CIX_INT_STATUS);
257
258 if (priv->dir == CIX_MBOX_RX) {
259 /* rx interrupt is triggered */
260 if (int_status & CIX_DB_INT) {
261 cix_mbox_write(priv, CIX_DB_INT, CIX_INT_CLEAR);
262 mbox_chan_received_data(chan, NULL);
263 /* trigger ack interrupt */
264 cix_mbox_write(priv, CIX_DB_ACK_INT_BIT, CIX_REG_DB_ACK);
265 }
266 } else {
267 /* tx ack interrupt is triggered */
268 if (int_status & CIX_ACK_INT) {
269 cix_mbox_write(priv, CIX_ACK_INT, CIX_INT_CLEAR);
270 mbox_chan_received_data(chan, NULL);
271 }
272 }
273 }
274
cix_mbox_isr_reg(struct mbox_chan * chan)275 static void cix_mbox_isr_reg(struct mbox_chan *chan)
276 {
277 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
278 u32 int_status;
279
280 int_status = cix_mbox_read(priv, CIX_INT_STATUS);
281
282 if (priv->dir == CIX_MBOX_RX) {
283 /* rx interrupt is triggered */
284 if (int_status & CIX_DB_INT) {
285 u32 data[CIX_MBOX_MSG_WORDS], len, i;
286
287 cix_mbox_write(priv, CIX_DB_INT, CIX_INT_CLEAR);
288 data[0] = cix_mbox_read(priv, CIX_REG_MSG(0));
289 len = mbox_get_msg_size(data);
290 for (i = 1; i < len; i++)
291 data[i] = cix_mbox_read(priv, CIX_REG_MSG(i));
292
293 /* trigger ack interrupt */
294 cix_mbox_write(priv, CIX_DB_ACK_INT_BIT, CIX_REG_DB_ACK);
295 mbox_chan_received_data(chan, data);
296 }
297 } else {
298 /* tx ack interrupt is triggered */
299 if (int_status & CIX_ACK_INT) {
300 cix_mbox_write(priv, CIX_ACK_INT, CIX_INT_CLEAR);
301 mbox_chan_txdone(chan, 0);
302 }
303 }
304 }
305
cix_mbox_isr_fifo(struct mbox_chan * chan)306 static void cix_mbox_isr_fifo(struct mbox_chan *chan)
307 {
308 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
309 u32 int_status, status;
310
311 int_status = cix_mbox_read(priv, CIX_INT_STATUS);
312
313 if (priv->dir == CIX_MBOX_RX) {
314 /* FIFO waterMark interrupt is generated */
315 if (int_status & (CIX_FIFO_FULL_INT | CIX_FIFO_WM01_INT)) {
316 u32 data[CIX_MBOX_MSG_WORDS] = { 0 }, i = 0;
317
318 cix_mbox_write(priv, (CIX_FIFO_FULL_INT | CIX_FIFO_WM01_INT),
319 CIX_INT_CLEAR);
320 do {
321 data[i++] = cix_mbox_read(priv, CIX_FIFO_RD);
322 } while (!mbox_fifo_empty(chan) && i < CIX_MBOX_MSG_WORDS);
323
324 mbox_chan_received_data(chan, data);
325 }
326 /* FIFO underflow is generated */
327 if (int_status & CIX_FIFO_UFLOW_INT) {
328 status = cix_mbox_read(priv, CIX_FIFO_STAS);
329 dev_err(priv->dev, "fifo underflow: int_stats %d\n", status);
330 cix_mbox_write(priv, CIX_FIFO_UFLOW_INT, CIX_INT_CLEAR);
331 }
332 } else {
333 /* FIFO empty interrupt is generated */
334 if (int_status & CIX_FIFO_EMPTY_INT) {
335 u32 val;
336
337 cix_mbox_write(priv, CIX_FIFO_EMPTY_INT, CIX_INT_CLEAR);
338 /* Disable empty irq*/
339 val = cix_mbox_read(priv, CIX_INT_ENABLE);
340 val &= ~CIX_FIFO_EMPTY_INT;
341 cix_mbox_write(priv, val, CIX_INT_ENABLE);
342 mbox_chan_txdone(chan, 0);
343 }
344 /* FIFO overflow is generated */
345 if (int_status & CIX_FIFO_OFLOW_INT) {
346 status = cix_mbox_read(priv, CIX_FIFO_STAS);
347 dev_err(priv->dev, "fifo overflow: int_stats %d\n", status);
348 cix_mbox_write(priv, CIX_FIFO_OFLOW_INT, CIX_INT_CLEAR);
349 }
350 }
351 }
352
cix_mbox_isr_fast(struct mbox_chan * chan)353 static void cix_mbox_isr_fast(struct mbox_chan *chan)
354 {
355 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
356 struct cix_mbox_con_priv *cp = chan->con_priv;
357 u32 int_status, data;
358
359 /* no irq will be trigger for TX dir mbox */
360 if (priv->dir != CIX_MBOX_RX)
361 return;
362
363 int_status = cix_mbox_read(priv, CIX_INT_STATUS);
364
365 if (int_status & CIX_FAST_CH_INT(cp->index)) {
366 cix_mbox_write(priv, CIX_FAST_CH_INT(cp->index), CIX_INT_CLEAR);
367 data = cix_mbox_read(priv, CIX_REG_F_INT(cp->index));
368 mbox_chan_received_data(chan, &data);
369 }
370 }
371
cix_mbox_isr(int irq,void * arg)372 static irqreturn_t cix_mbox_isr(int irq, void *arg)
373 {
374 struct mbox_chan *chan = arg;
375 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
376 struct cix_mbox_con_priv *cp = chan->con_priv;
377
378 switch (cp->type) {
379 case CIX_MBOX_TYPE_DB:
380 cix_mbox_isr_db(chan);
381 break;
382 case CIX_MBOX_TYPE_REG:
383 cix_mbox_isr_reg(chan);
384 break;
385 case CIX_MBOX_TYPE_FIFO:
386 cix_mbox_isr_fifo(chan);
387 break;
388 case CIX_MBOX_TYPE_FAST:
389 cix_mbox_isr_fast(chan);
390 break;
391 default:
392 dev_err(priv->dev, "Invalid channel type: %d\n", cp->type);
393 return IRQ_NONE;
394 }
395
396 return IRQ_HANDLED;
397 }
398
cix_mbox_startup(struct mbox_chan * chan)399 static int cix_mbox_startup(struct mbox_chan *chan)
400 {
401 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
402 struct cix_mbox_con_priv *cp = chan->con_priv;
403 int index = cp->index, ret;
404 u32 val;
405
406 ret = request_irq(priv->irq, cix_mbox_isr, IRQF_NO_SUSPEND,
407 dev_name(priv->dev), chan);
408 if (ret) {
409 dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq);
410 return ret;
411 }
412
413 switch (cp->type) {
414 case CIX_MBOX_TYPE_DB:
415 /* Overwrite txdone_method for DB channel */
416 chan->txdone_method = MBOX_TXDONE_BY_ACK;
417 fallthrough;
418 case CIX_MBOX_TYPE_REG:
419 if (priv->dir == CIX_MBOX_TX) {
420 /* Enable ACK interrupt */
421 val = cix_mbox_read(priv, CIX_INT_ENABLE);
422 val |= CIX_ACK_INT;
423 cix_mbox_write(priv, val, CIX_INT_ENABLE);
424 } else {
425 /* Enable Doorbell interrupt */
426 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B);
427 val |= CIX_DB_INT;
428 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B);
429 }
430 break;
431 case CIX_MBOX_TYPE_FIFO:
432 /* reset fifo */
433 cix_mbox_write(priv, CIX_FIFO_RST_BIT, CIX_FIFO_RST);
434 /* set default watermark */
435 cix_mbox_write(priv, CIX_FIFO_WM_DEFAULT, CIX_FIFO_WM);
436 if (priv->dir == CIX_MBOX_TX) {
437 /* Enable fifo overflow interrupt */
438 val = cix_mbox_read(priv, CIX_INT_ENABLE);
439 val |= CIX_FIFO_OFLOW_INT;
440 cix_mbox_write(priv, val, CIX_INT_ENABLE);
441 } else {
442 /* Enable fifo full/underflow interrupt */
443 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B);
444 val |= CIX_FIFO_UFLOW_INT|CIX_FIFO_WM01_INT;
445 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B);
446 }
447 break;
448 case CIX_MBOX_TYPE_FAST:
449 /* Only RX channel has intterupt */
450 if (priv->dir == CIX_MBOX_RX) {
451 if (index < 0 || index > CIX_MBOX_FAST_IDX) {
452 dev_err(priv->dev, "Invalid index %d\n", index);
453 ret = -EINVAL;
454 goto failed;
455 }
456 /* enable fast channel interrupt */
457 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B);
458 val |= CIX_FAST_CH_INT(index);
459 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B);
460 }
461 break;
462 default:
463 dev_err(priv->dev, "Invalid channel type: %d\n", cp->type);
464 ret = -EINVAL;
465 goto failed;
466 }
467 return 0;
468
469 failed:
470 free_irq(priv->irq, chan);
471 return ret;
472 }
473
cix_mbox_shutdown(struct mbox_chan * chan)474 static void cix_mbox_shutdown(struct mbox_chan *chan)
475 {
476 struct cix_mbox_priv *priv = to_cix_mbox_priv(chan->mbox);
477 struct cix_mbox_con_priv *cp = chan->con_priv;
478 int index = cp->index;
479 u32 val;
480
481 switch (cp->type) {
482 case CIX_MBOX_TYPE_DB:
483 case CIX_MBOX_TYPE_REG:
484 if (priv->dir == CIX_MBOX_TX) {
485 /* Disable ACK interrupt */
486 val = cix_mbox_read(priv, CIX_INT_ENABLE);
487 val &= ~CIX_ACK_INT;
488 cix_mbox_write(priv, val, CIX_INT_ENABLE);
489 } else if (priv->dir == CIX_MBOX_RX) {
490 /* Disable Doorbell interrupt */
491 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B);
492 val &= ~CIX_DB_INT;
493 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B);
494 }
495 break;
496 case CIX_MBOX_TYPE_FIFO:
497 if (priv->dir == CIX_MBOX_TX) {
498 /* Disable empty/fifo overflow irq*/
499 val = cix_mbox_read(priv, CIX_INT_ENABLE);
500 val &= ~(CIX_FIFO_EMPTY_INT | CIX_FIFO_OFLOW_INT);
501 cix_mbox_write(priv, val, CIX_INT_ENABLE);
502 } else if (priv->dir == CIX_MBOX_RX) {
503 /* Disable fifo WM01/underflow interrupt */
504 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B);
505 val &= ~(CIX_FIFO_UFLOW_INT | CIX_FIFO_WM01_INT);
506 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B);
507 }
508 break;
509 case CIX_MBOX_TYPE_FAST:
510 if (priv->dir == CIX_MBOX_RX) {
511 if (index < 0 || index > CIX_MBOX_FAST_IDX) {
512 dev_err(priv->dev, "Invalid index %d\n", index);
513 break;
514 }
515 /* Disable fast channel interrupt */
516 val = cix_mbox_read(priv, CIX_INT_ENABLE_SIDE_B);
517 val &= ~CIX_FAST_CH_INT(index);
518 cix_mbox_write(priv, val, CIX_INT_ENABLE_SIDE_B);
519 }
520 break;
521
522 default:
523 dev_err(priv->dev, "Invalid channel type: %d\n", cp->type);
524 break;
525 }
526
527 free_irq(priv->irq, chan);
528 }
529
530 static const struct mbox_chan_ops cix_mbox_chan_ops = {
531 .send_data = cix_mbox_send_data,
532 .startup = cix_mbox_startup,
533 .shutdown = cix_mbox_shutdown,
534 };
535
cix_mbox_init(struct cix_mbox_priv * priv)536 static void cix_mbox_init(struct cix_mbox_priv *priv)
537 {
538 struct cix_mbox_con_priv *cp;
539 int i;
540
541 for (i = 0; i < CIX_MBOX_CHANS; i++) {
542 cp = &priv->con_priv[i];
543 cp->index = i;
544 cp->chan = &priv->mbox_chans[i];
545 priv->mbox_chans[i].con_priv = cp;
546 if (cp->index <= CIX_MBOX_FAST_IDX)
547 cp->type = CIX_MBOX_TYPE_FAST;
548 if (cp->index == CIX_MBOX_DB_IDX)
549 cp->type = CIX_MBOX_TYPE_DB;
550 if (cp->index == CIX_MBOX_FIFO_IDX)
551 cp->type = CIX_MBOX_TYPE_FIFO;
552 if (cp->index == CIX_MBOX_REG_IDX)
553 cp->type = CIX_MBOX_TYPE_REG;
554 }
555 }
556
cix_mbox_probe(struct platform_device * pdev)557 static int cix_mbox_probe(struct platform_device *pdev)
558 {
559 struct device *dev = &pdev->dev;
560 struct cix_mbox_priv *priv;
561 struct resource *res;
562 const char *dir_str;
563 int ret;
564
565 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
566 if (!priv)
567 return -ENOMEM;
568
569 priv->dev = dev;
570 priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
571 if (IS_ERR(priv->base))
572 return PTR_ERR(priv->base);
573
574 /*
575 * The first 0x80 bytes of the register space of the cix mailbox controller
576 * can be used as shared memory for clients. When this shared memory is in
577 * use, the base address of the mailbox is offset by 0x80. Therefore, when
578 * performing subsequent read/write operations, it is necessary to subtract
579 * the offset CIX_SHMEM_OFFSET.
580 *
581 * When the base address of the mailbox is offset by 0x80, it indicates
582 * that shmem is in use.
583 */
584 priv->use_shmem = !!(res->start & CIX_SHMEM_OFFSET);
585
586 priv->irq = platform_get_irq(pdev, 0);
587 if (priv->irq < 0)
588 return priv->irq;
589
590 if (device_property_read_string(dev, "cix,mbox-dir", &dir_str)) {
591 dev_err(priv->dev, "cix,mbox_dir property not found\n");
592 return -EINVAL;
593 }
594
595 if (!strcmp(dir_str, "tx"))
596 priv->dir = 0;
597 else if (!strcmp(dir_str, "rx"))
598 priv->dir = 1;
599 else {
600 dev_err(priv->dev, "cix,mbox_dir=%s is not expected\n", dir_str);
601 return -EINVAL;
602 }
603
604 cix_mbox_init(priv);
605
606 priv->mbox.dev = dev;
607 priv->mbox.ops = &cix_mbox_chan_ops;
608 priv->mbox.chans = priv->mbox_chans;
609 priv->mbox.txdone_irq = true;
610 priv->mbox.num_chans = CIX_MBOX_CHANS;
611 priv->mbox.of_xlate = NULL;
612
613 platform_set_drvdata(pdev, priv);
614 ret = devm_mbox_controller_register(dev, &priv->mbox);
615 if (ret)
616 dev_err(dev, "Failed to register mailbox %d\n", ret);
617
618 return ret;
619 }
620
621 static const struct of_device_id cix_mbox_dt_ids[] = {
622 { .compatible = "cix,sky1-mbox" },
623 { },
624 };
625 MODULE_DEVICE_TABLE(of, cix_mbox_dt_ids);
626
627 static struct platform_driver cix_mbox_driver = {
628 .probe = cix_mbox_probe,
629 .driver = {
630 .name = "cix_mbox",
631 .of_match_table = cix_mbox_dt_ids,
632 },
633 };
634
cix_mailbox_init(void)635 static int __init cix_mailbox_init(void)
636 {
637 return platform_driver_register(&cix_mbox_driver);
638 }
639 arch_initcall(cix_mailbox_init);
640
641 MODULE_AUTHOR("Cix Technology Group Co., Ltd.");
642 MODULE_DESCRIPTION("CIX mailbox driver");
643 MODULE_LICENSE("GPL");
644