vpu_mbox.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright 2020-2021 NXP
  4. */
  5. #include <linux/init.h>
  6. #include <linux/interconnect.h>
  7. #include <linux/ioctl.h>
  8. #include <linux/list.h>
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/platform_device.h>
  12. #include "vpu.h"
  13. #include "vpu_mbox.h"
  14. #include "vpu_msgs.h"
  15. static void vpu_mbox_rx_callback(struct mbox_client *cl, void *msg)
  16. {
  17. struct vpu_mbox *rx = container_of(cl, struct vpu_mbox, cl);
  18. struct vpu_core *core = container_of(rx, struct vpu_core, rx);
  19. vpu_isr(core, *(u32 *)msg);
  20. }
  21. static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox)
  22. {
  23. struct mbox_chan *ch;
  24. struct mbox_client *cl;
  25. if (!dev || !mbox)
  26. return -EINVAL;
  27. if (mbox->ch)
  28. return 0;
  29. cl = &mbox->cl;
  30. cl->dev = dev;
  31. if (mbox->block) {
  32. cl->tx_block = true;
  33. cl->tx_tout = 1000;
  34. } else {
  35. cl->tx_block = false;
  36. }
  37. cl->knows_txdone = false;
  38. cl->rx_callback = vpu_mbox_rx_callback;
  39. ch = mbox_request_channel_byname(cl, mbox->name);
  40. if (IS_ERR(ch))
  41. return dev_err_probe(dev, PTR_ERR(ch),
  42. "Failed to request mbox chan %s\n",
  43. mbox->name);
  44. mbox->ch = ch;
  45. return 0;
  46. }
  47. int vpu_mbox_init(struct vpu_core *core)
  48. {
  49. scnprintf(core->tx_type.name, sizeof(core->tx_type.name) - 1, "tx0");
  50. core->tx_type.block = true;
  51. scnprintf(core->tx_data.name, sizeof(core->tx_data.name) - 1, "tx1");
  52. core->tx_data.block = false;
  53. scnprintf(core->rx.name, sizeof(core->rx.name) - 1, "rx");
  54. core->rx.block = true;
  55. return 0;
  56. }
  57. int vpu_mbox_request(struct vpu_core *core)
  58. {
  59. int ret;
  60. ret = vpu_mbox_request_channel(core->dev, &core->tx_type);
  61. if (ret)
  62. goto error;
  63. ret = vpu_mbox_request_channel(core->dev, &core->tx_data);
  64. if (ret)
  65. goto error;
  66. ret = vpu_mbox_request_channel(core->dev, &core->rx);
  67. if (ret)
  68. goto error;
  69. dev_dbg(core->dev, "%s request mbox\n", vpu_core_type_desc(core->type));
  70. return 0;
  71. error:
  72. vpu_mbox_free(core);
  73. return ret;
  74. }
  75. void vpu_mbox_free(struct vpu_core *core)
  76. {
  77. mbox_free_channel(core->tx_type.ch);
  78. mbox_free_channel(core->tx_data.ch);
  79. mbox_free_channel(core->rx.ch);
  80. core->tx_type.ch = NULL;
  81. core->tx_data.ch = NULL;
  82. core->rx.ch = NULL;
  83. dev_dbg(core->dev, "%s free mbox\n", vpu_core_type_desc(core->type));
  84. }
  85. void vpu_mbox_send_type(struct vpu_core *core, u32 type)
  86. {
  87. mbox_send_message(core->tx_type.ch, &type);
  88. }
  89. void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data)
  90. {
  91. mbox_send_message(core->tx_data.ch, &data);
  92. mbox_send_message(core->tx_type.ch, &type);
  93. }