apple-mailbox.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. // SPDX-License-Identifier: GPL-2.0-only OR MIT
  2. /*
  3. * Apple mailbox driver
  4. *
  5. * Copyright (C) 2021 The Asahi Linux Contributors
  6. *
  7. * This driver adds support for two mailbox variants (called ASC and M3 by
  8. * Apple) found in Apple SoCs such as the M1. It consists of two FIFOs used to
  9. * exchange 64+32 bit messages between the main CPU and a co-processor.
  10. * Various coprocessors implement different IPC protocols based on these simple
  11. * messages and shared memory buffers.
  12. *
  13. * Both the main CPU and the co-processor see the same set of registers but
  14. * the first FIFO (A2I) is always used to transfer messages from the application
  15. * processor (us) to the I/O processor and the second one (I2A) for the
  16. * other direction.
  17. */
  18. #include <linux/apple-mailbox.h>
  19. #include <linux/delay.h>
  20. #include <linux/device.h>
  21. #include <linux/gfp.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/io.h>
  24. #include <linux/mailbox_controller.h>
  25. #include <linux/module.h>
  26. #include <linux/of.h>
  27. #include <linux/platform_device.h>
  28. #include <linux/spinlock.h>
  29. #include <linux/types.h>
  30. #define APPLE_ASC_MBOX_CONTROL_FULL BIT(16)
  31. #define APPLE_ASC_MBOX_CONTROL_EMPTY BIT(17)
  32. #define APPLE_ASC_MBOX_A2I_CONTROL 0x110
  33. #define APPLE_ASC_MBOX_A2I_SEND0 0x800
  34. #define APPLE_ASC_MBOX_A2I_SEND1 0x808
  35. #define APPLE_ASC_MBOX_A2I_RECV0 0x810
  36. #define APPLE_ASC_MBOX_A2I_RECV1 0x818
  37. #define APPLE_ASC_MBOX_I2A_CONTROL 0x114
  38. #define APPLE_ASC_MBOX_I2A_SEND0 0x820
  39. #define APPLE_ASC_MBOX_I2A_SEND1 0x828
  40. #define APPLE_ASC_MBOX_I2A_RECV0 0x830
  41. #define APPLE_ASC_MBOX_I2A_RECV1 0x838
  42. #define APPLE_M3_MBOX_CONTROL_FULL BIT(16)
  43. #define APPLE_M3_MBOX_CONTROL_EMPTY BIT(17)
  44. #define APPLE_M3_MBOX_A2I_CONTROL 0x50
  45. #define APPLE_M3_MBOX_A2I_SEND0 0x60
  46. #define APPLE_M3_MBOX_A2I_SEND1 0x68
  47. #define APPLE_M3_MBOX_A2I_RECV0 0x70
  48. #define APPLE_M3_MBOX_A2I_RECV1 0x78
  49. #define APPLE_M3_MBOX_I2A_CONTROL 0x80
  50. #define APPLE_M3_MBOX_I2A_SEND0 0x90
  51. #define APPLE_M3_MBOX_I2A_SEND1 0x98
  52. #define APPLE_M3_MBOX_I2A_RECV0 0xa0
  53. #define APPLE_M3_MBOX_I2A_RECV1 0xa8
  54. #define APPLE_M3_MBOX_IRQ_ENABLE 0x48
  55. #define APPLE_M3_MBOX_IRQ_ACK 0x4c
  56. #define APPLE_M3_MBOX_IRQ_A2I_EMPTY BIT(0)
  57. #define APPLE_M3_MBOX_IRQ_A2I_NOT_EMPTY BIT(1)
  58. #define APPLE_M3_MBOX_IRQ_I2A_EMPTY BIT(2)
  59. #define APPLE_M3_MBOX_IRQ_I2A_NOT_EMPTY BIT(3)
  60. #define APPLE_MBOX_MSG1_OUTCNT GENMASK(56, 52)
  61. #define APPLE_MBOX_MSG1_INCNT GENMASK(51, 48)
  62. #define APPLE_MBOX_MSG1_OUTPTR GENMASK(47, 44)
  63. #define APPLE_MBOX_MSG1_INPTR GENMASK(43, 40)
  64. #define APPLE_MBOX_MSG1_MSG GENMASK(31, 0)
  65. struct apple_mbox_hw {
  66. unsigned int control_full;
  67. unsigned int control_empty;
  68. unsigned int a2i_control;
  69. unsigned int a2i_send0;
  70. unsigned int a2i_send1;
  71. unsigned int i2a_control;
  72. unsigned int i2a_recv0;
  73. unsigned int i2a_recv1;
  74. bool has_irq_controls;
  75. unsigned int irq_enable;
  76. unsigned int irq_ack;
  77. unsigned int irq_bit_recv_not_empty;
  78. unsigned int irq_bit_send_empty;
  79. };
  80. struct apple_mbox {
  81. void __iomem *regs;
  82. const struct apple_mbox_hw *hw;
  83. int irq_recv_not_empty;
  84. int irq_send_empty;
  85. struct mbox_chan chan;
  86. struct device *dev;
  87. struct mbox_controller controller;
  88. spinlock_t rx_lock;
  89. };
  90. static const struct of_device_id apple_mbox_of_match[];
  91. static bool apple_mbox_hw_can_send(struct apple_mbox *apple_mbox)
  92. {
  93. u32 mbox_ctrl =
  94. readl_relaxed(apple_mbox->regs + apple_mbox->hw->a2i_control);
  95. return !(mbox_ctrl & apple_mbox->hw->control_full);
  96. }
  97. static bool apple_mbox_hw_send_empty(struct apple_mbox *apple_mbox)
  98. {
  99. u32 mbox_ctrl =
  100. readl_relaxed(apple_mbox->regs + apple_mbox->hw->a2i_control);
  101. return mbox_ctrl & apple_mbox->hw->control_empty;
  102. }
  103. static int apple_mbox_hw_send(struct apple_mbox *apple_mbox,
  104. struct apple_mbox_msg *msg)
  105. {
  106. if (!apple_mbox_hw_can_send(apple_mbox))
  107. return -EBUSY;
  108. dev_dbg(apple_mbox->dev, "> TX %016llx %08x\n", msg->msg0, msg->msg1);
  109. writeq_relaxed(msg->msg0, apple_mbox->regs + apple_mbox->hw->a2i_send0);
  110. writeq_relaxed(FIELD_PREP(APPLE_MBOX_MSG1_MSG, msg->msg1),
  111. apple_mbox->regs + apple_mbox->hw->a2i_send1);
  112. return 0;
  113. }
  114. static bool apple_mbox_hw_can_recv(struct apple_mbox *apple_mbox)
  115. {
  116. u32 mbox_ctrl =
  117. readl_relaxed(apple_mbox->regs + apple_mbox->hw->i2a_control);
  118. return !(mbox_ctrl & apple_mbox->hw->control_empty);
  119. }
  120. static int apple_mbox_hw_recv(struct apple_mbox *apple_mbox,
  121. struct apple_mbox_msg *msg)
  122. {
  123. if (!apple_mbox_hw_can_recv(apple_mbox))
  124. return -ENOMSG;
  125. msg->msg0 = readq_relaxed(apple_mbox->regs + apple_mbox->hw->i2a_recv0);
  126. msg->msg1 = FIELD_GET(
  127. APPLE_MBOX_MSG1_MSG,
  128. readq_relaxed(apple_mbox->regs + apple_mbox->hw->i2a_recv1));
  129. dev_dbg(apple_mbox->dev, "< RX %016llx %08x\n", msg->msg0, msg->msg1);
  130. return 0;
  131. }
  132. static int apple_mbox_chan_send_data(struct mbox_chan *chan, void *data)
  133. {
  134. struct apple_mbox *apple_mbox = chan->con_priv;
  135. struct apple_mbox_msg *msg = data;
  136. int ret;
  137. ret = apple_mbox_hw_send(apple_mbox, msg);
  138. if (ret)
  139. return ret;
  140. /*
  141. * The interrupt is level triggered and will keep firing as long as the
  142. * FIFO is empty. It will also keep firing if the FIFO was empty
  143. * at any point in the past until it has been acknowledged at the
  144. * mailbox level. By acknowledging it here we can ensure that we will
  145. * only get the interrupt once the FIFO has been cleared again.
  146. * If the FIFO is already empty before the ack it will fire again
  147. * immediately after the ack.
  148. */
  149. if (apple_mbox->hw->has_irq_controls) {
  150. writel_relaxed(apple_mbox->hw->irq_bit_send_empty,
  151. apple_mbox->regs + apple_mbox->hw->irq_ack);
  152. }
  153. enable_irq(apple_mbox->irq_send_empty);
  154. return 0;
  155. }
  156. static irqreturn_t apple_mbox_send_empty_irq(int irq, void *data)
  157. {
  158. struct apple_mbox *apple_mbox = data;
  159. /*
  160. * We don't need to acknowledge the interrupt at the mailbox level
  161. * here even if supported by the hardware. It will keep firing but that
  162. * doesn't matter since it's disabled at the main interrupt controller.
  163. * apple_mbox_chan_send_data will acknowledge it before enabling
  164. * it at the main controller again.
  165. */
  166. disable_irq_nosync(apple_mbox->irq_send_empty);
  167. mbox_chan_txdone(&apple_mbox->chan, 0);
  168. return IRQ_HANDLED;
  169. }
  170. static int apple_mbox_poll(struct apple_mbox *apple_mbox)
  171. {
  172. struct apple_mbox_msg msg;
  173. int ret = 0;
  174. while (apple_mbox_hw_recv(apple_mbox, &msg) == 0) {
  175. mbox_chan_received_data(&apple_mbox->chan, (void *)&msg);
  176. ret++;
  177. }
  178. /*
  179. * The interrupt will keep firing even if there are no more messages
  180. * unless we also acknowledge it at the mailbox level here.
  181. * There's no race if a message comes in between the check in the while
  182. * loop above and the ack below: If a new messages arrives inbetween
  183. * those two the interrupt will just fire again immediately after the
  184. * ack since it's level triggered.
  185. */
  186. if (apple_mbox->hw->has_irq_controls) {
  187. writel_relaxed(apple_mbox->hw->irq_bit_recv_not_empty,
  188. apple_mbox->regs + apple_mbox->hw->irq_ack);
  189. }
  190. return ret;
  191. }
  192. static irqreturn_t apple_mbox_recv_irq(int irq, void *data)
  193. {
  194. struct apple_mbox *apple_mbox = data;
  195. spin_lock(&apple_mbox->rx_lock);
  196. apple_mbox_poll(apple_mbox);
  197. spin_unlock(&apple_mbox->rx_lock);
  198. return IRQ_HANDLED;
  199. }
  200. static bool apple_mbox_chan_peek_data(struct mbox_chan *chan)
  201. {
  202. struct apple_mbox *apple_mbox = chan->con_priv;
  203. unsigned long flags;
  204. int ret;
  205. spin_lock_irqsave(&apple_mbox->rx_lock, flags);
  206. ret = apple_mbox_poll(apple_mbox);
  207. spin_unlock_irqrestore(&apple_mbox->rx_lock, flags);
  208. return ret > 0;
  209. }
  210. static int apple_mbox_chan_flush(struct mbox_chan *chan, unsigned long timeout)
  211. {
  212. struct apple_mbox *apple_mbox = chan->con_priv;
  213. unsigned long deadline = jiffies + msecs_to_jiffies(timeout);
  214. while (time_before(jiffies, deadline)) {
  215. if (apple_mbox_hw_send_empty(apple_mbox)) {
  216. mbox_chan_txdone(&apple_mbox->chan, 0);
  217. return 0;
  218. }
  219. udelay(1);
  220. }
  221. return -ETIME;
  222. }
  223. static int apple_mbox_chan_startup(struct mbox_chan *chan)
  224. {
  225. struct apple_mbox *apple_mbox = chan->con_priv;
  226. /*
  227. * Only some variants of this mailbox HW provide interrupt control
  228. * at the mailbox level. We therefore need to handle enabling/disabling
  229. * interrupts at the main interrupt controller anyway for hardware that
  230. * doesn't. Just always keep the interrupts we care about enabled at
  231. * the mailbox level so that both hardware revisions behave almost
  232. * the same.
  233. */
  234. if (apple_mbox->hw->has_irq_controls) {
  235. writel_relaxed(apple_mbox->hw->irq_bit_recv_not_empty |
  236. apple_mbox->hw->irq_bit_send_empty,
  237. apple_mbox->regs + apple_mbox->hw->irq_enable);
  238. }
  239. enable_irq(apple_mbox->irq_recv_not_empty);
  240. return 0;
  241. }
  242. static void apple_mbox_chan_shutdown(struct mbox_chan *chan)
  243. {
  244. struct apple_mbox *apple_mbox = chan->con_priv;
  245. disable_irq(apple_mbox->irq_recv_not_empty);
  246. }
  247. static const struct mbox_chan_ops apple_mbox_ops = {
  248. .send_data = apple_mbox_chan_send_data,
  249. .peek_data = apple_mbox_chan_peek_data,
  250. .flush = apple_mbox_chan_flush,
  251. .startup = apple_mbox_chan_startup,
  252. .shutdown = apple_mbox_chan_shutdown,
  253. };
  254. static struct mbox_chan *apple_mbox_of_xlate(struct mbox_controller *mbox,
  255. const struct of_phandle_args *args)
  256. {
  257. if (args->args_count != 0)
  258. return ERR_PTR(-EINVAL);
  259. return &mbox->chans[0];
  260. }
  261. static int apple_mbox_probe(struct platform_device *pdev)
  262. {
  263. int ret;
  264. const struct of_device_id *match;
  265. char *irqname;
  266. struct apple_mbox *mbox;
  267. struct device *dev = &pdev->dev;
  268. match = of_match_node(apple_mbox_of_match, pdev->dev.of_node);
  269. if (!match)
  270. return -EINVAL;
  271. if (!match->data)
  272. return -EINVAL;
  273. mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
  274. if (!mbox)
  275. return -ENOMEM;
  276. platform_set_drvdata(pdev, mbox);
  277. mbox->dev = dev;
  278. mbox->regs = devm_platform_ioremap_resource(pdev, 0);
  279. if (IS_ERR(mbox->regs))
  280. return PTR_ERR(mbox->regs);
  281. mbox->hw = match->data;
  282. mbox->irq_recv_not_empty =
  283. platform_get_irq_byname(pdev, "recv-not-empty");
  284. if (mbox->irq_recv_not_empty < 0)
  285. return -ENODEV;
  286. mbox->irq_send_empty = platform_get_irq_byname(pdev, "send-empty");
  287. if (mbox->irq_send_empty < 0)
  288. return -ENODEV;
  289. mbox->controller.dev = mbox->dev;
  290. mbox->controller.num_chans = 1;
  291. mbox->controller.chans = &mbox->chan;
  292. mbox->controller.ops = &apple_mbox_ops;
  293. mbox->controller.txdone_irq = true;
  294. mbox->controller.of_xlate = apple_mbox_of_xlate;
  295. mbox->chan.con_priv = mbox;
  296. spin_lock_init(&mbox->rx_lock);
  297. irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-recv", dev_name(dev));
  298. if (!irqname)
  299. return -ENOMEM;
  300. ret = devm_request_threaded_irq(dev, mbox->irq_recv_not_empty, NULL,
  301. apple_mbox_recv_irq,
  302. IRQF_NO_AUTOEN | IRQF_ONESHOT, irqname,
  303. mbox);
  304. if (ret)
  305. return ret;
  306. irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-send", dev_name(dev));
  307. if (!irqname)
  308. return -ENOMEM;
  309. ret = devm_request_irq(dev, mbox->irq_send_empty,
  310. apple_mbox_send_empty_irq, IRQF_NO_AUTOEN,
  311. irqname, mbox);
  312. if (ret)
  313. return ret;
  314. return devm_mbox_controller_register(dev, &mbox->controller);
  315. }
  316. static const struct apple_mbox_hw apple_mbox_asc_hw = {
  317. .control_full = APPLE_ASC_MBOX_CONTROL_FULL,
  318. .control_empty = APPLE_ASC_MBOX_CONTROL_EMPTY,
  319. .a2i_control = APPLE_ASC_MBOX_A2I_CONTROL,
  320. .a2i_send0 = APPLE_ASC_MBOX_A2I_SEND0,
  321. .a2i_send1 = APPLE_ASC_MBOX_A2I_SEND1,
  322. .i2a_control = APPLE_ASC_MBOX_I2A_CONTROL,
  323. .i2a_recv0 = APPLE_ASC_MBOX_I2A_RECV0,
  324. .i2a_recv1 = APPLE_ASC_MBOX_I2A_RECV1,
  325. .has_irq_controls = false,
  326. };
  327. static const struct apple_mbox_hw apple_mbox_m3_hw = {
  328. .control_full = APPLE_M3_MBOX_CONTROL_FULL,
  329. .control_empty = APPLE_M3_MBOX_CONTROL_EMPTY,
  330. .a2i_control = APPLE_M3_MBOX_A2I_CONTROL,
  331. .a2i_send0 = APPLE_M3_MBOX_A2I_SEND0,
  332. .a2i_send1 = APPLE_M3_MBOX_A2I_SEND1,
  333. .i2a_control = APPLE_M3_MBOX_I2A_CONTROL,
  334. .i2a_recv0 = APPLE_M3_MBOX_I2A_RECV0,
  335. .i2a_recv1 = APPLE_M3_MBOX_I2A_RECV1,
  336. .has_irq_controls = true,
  337. .irq_enable = APPLE_M3_MBOX_IRQ_ENABLE,
  338. .irq_ack = APPLE_M3_MBOX_IRQ_ACK,
  339. .irq_bit_recv_not_empty = APPLE_M3_MBOX_IRQ_I2A_NOT_EMPTY,
  340. .irq_bit_send_empty = APPLE_M3_MBOX_IRQ_A2I_EMPTY,
  341. };
  342. static const struct of_device_id apple_mbox_of_match[] = {
  343. { .compatible = "apple,asc-mailbox-v4", .data = &apple_mbox_asc_hw },
  344. { .compatible = "apple,m3-mailbox-v2", .data = &apple_mbox_m3_hw },
  345. {}
  346. };
  347. MODULE_DEVICE_TABLE(of, apple_mbox_of_match);
  348. static struct platform_driver apple_mbox_driver = {
  349. .driver = {
  350. .name = "apple-mailbox",
  351. .of_match_table = apple_mbox_of_match,
  352. },
  353. .probe = apple_mbox_probe,
  354. };
  355. module_platform_driver(apple_mbox_driver);
  356. MODULE_LICENSE("Dual MIT/GPL");
  357. MODULE_AUTHOR("Sven Peter <[email protected]>");
  358. MODULE_DESCRIPTION("Apple Mailbox driver");