cix-mailbox.c 17 KB

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