ipc.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <stdlib.h>
  7. #include <lib/bakery_lock.h>
  8. #include <sci/sci_scfw.h>
  9. #include <sci/sci_ipc.h>
  10. #include <sci/sci_rpc.h>
  11. #include "imx8_mu.h"
  12. sc_ipc_t ipc_handle;
  13. DEFINE_BAKERY_LOCK(sc_ipc_bakery_lock);
  14. #define sc_ipc_lock_init() bakery_lock_init(&sc_ipc_bakery_lock)
  15. #define sc_ipc_lock() bakery_lock_get(&sc_ipc_bakery_lock)
  16. #define sc_ipc_unlock() bakery_lock_release(&sc_ipc_bakery_lock)
  17. void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, bool no_resp)
  18. {
  19. sc_ipc_lock();
  20. sc_ipc_write(ipc, msg);
  21. if (!no_resp)
  22. sc_ipc_read(ipc, msg);
  23. sc_ipc_unlock();
  24. }
  25. sc_err_t sc_ipc_open(sc_ipc_t *ipc, sc_ipc_id_t id)
  26. {
  27. uint32_t base = id;
  28. uint32_t i;
  29. /* Get MU base associated with IPC channel */
  30. if ((ipc == NULL) || (base == 0))
  31. return SC_ERR_IPC;
  32. sc_ipc_lock_init();
  33. /* Init MU */
  34. MU_Init(base);
  35. /* Enable all RX interrupts */
  36. for (i = 0; i < MU_RR_COUNT; i++) {
  37. MU_EnableRxFullInt(base, i);
  38. }
  39. /* Return MU address as handle */
  40. *ipc = (sc_ipc_t) id;
  41. return SC_ERR_NONE;
  42. }
  43. void sc_ipc_close(sc_ipc_t ipc)
  44. {
  45. uint32_t base = ipc;
  46. if (base != 0)
  47. MU_Init(base);
  48. }
  49. void sc_ipc_read(sc_ipc_t ipc, void *data)
  50. {
  51. uint32_t base = ipc;
  52. sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data;
  53. uint8_t count = 0;
  54. /* Check parms */
  55. if ((base == 0) || (msg == NULL))
  56. return;
  57. /* Read first word */
  58. MU_ReceiveMsg(base, 0, (uint32_t *) msg);
  59. count++;
  60. /* Check size */
  61. if (msg->size > SC_RPC_MAX_MSG) {
  62. *((uint32_t *) msg) = 0;
  63. return;
  64. }
  65. /* Read remaining words */
  66. while (count < msg->size) {
  67. MU_ReceiveMsg(base, count % MU_RR_COUNT,
  68. &(msg->DATA.u32[count - 1]));
  69. count++;
  70. }
  71. }
  72. void sc_ipc_write(sc_ipc_t ipc, void *data)
  73. {
  74. sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data;
  75. uint32_t base = ipc;
  76. uint8_t count = 0;
  77. /* Check parms */
  78. if ((base == 0) || (msg == NULL))
  79. return;
  80. /* Check size */
  81. if (msg->size > SC_RPC_MAX_MSG)
  82. return;
  83. /* Write first word */
  84. MU_SendMessage(base, 0, *((uint32_t *) msg));
  85. count++;
  86. /* Write remaining words */
  87. while (count < msg->size) {
  88. MU_SendMessage(base, count % MU_TR_COUNT,
  89. msg->DATA.u32[count - 1]);
  90. count++;
  91. }
  92. }