sspm.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <arch_helpers.h>
  7. #include <common/debug.h>
  8. #include <drivers/delay_timer.h>
  9. #include <errno.h>
  10. #include <lib/mmio.h>
  11. #include <sspm.h>
  12. static void memcpy_to_sspm(uint32_t dst, uint32_t *src, uint32_t len)
  13. {
  14. while (len--) {
  15. mmio_write_32(dst, *src);
  16. dst += sizeof(uint32_t);
  17. src++;
  18. }
  19. }
  20. static void memcpy_from_sspm(uint32_t *dst, uint32_t src, uint32_t len)
  21. {
  22. while (len--) {
  23. *dst = mmio_read_32(src);
  24. dst++;
  25. src += sizeof(uint32_t);
  26. }
  27. }
  28. int sspm_mbox_read(uint32_t slot, uint32_t *data, uint32_t len)
  29. {
  30. if (slot >= 32) {
  31. ERROR("%s:slot = %d\n", __func__, slot);
  32. return -EINVAL;
  33. }
  34. if (data)
  35. memcpy_from_sspm(data,
  36. MBOX3_BASE + slot * 4,
  37. len);
  38. return 0;
  39. }
  40. int sspm_mbox_write(uint32_t slot, uint32_t *data, uint32_t len)
  41. {
  42. if (slot >= 32) {
  43. ERROR("%s:slot = %d\n", __func__, slot);
  44. return -EINVAL;
  45. }
  46. if (data)
  47. memcpy_to_sspm(MBOX3_BASE + slot * 4,
  48. data,
  49. len);
  50. return 0;
  51. }
  52. static int sspm_ipi_check_ack(uint32_t id)
  53. {
  54. int ret = 0;
  55. if (id == IPI_ID_PLATFORM) {
  56. if ((mmio_read_32(MBOX0_BASE + MBOX_IN_IRQ_OFS) & 0x1) == 0x1)
  57. ret = -EINPROGRESS;
  58. } else if (id == IPI_ID_SUSPEND) {
  59. if ((mmio_read_32(MBOX1_BASE + MBOX_IN_IRQ_OFS) & 0x2) == 0x2)
  60. ret = -EINPROGRESS;
  61. } else {
  62. ERROR("%s: id = %d\n", __func__, id);
  63. ret = -EINVAL;
  64. }
  65. return ret;
  66. }
  67. int sspm_ipi_send_non_blocking(uint32_t id, uint32_t *data)
  68. {
  69. int ret = 0;
  70. ret = sspm_ipi_check_ack(id);
  71. if (ret)
  72. return ret;
  73. if (id == IPI_ID_PLATFORM) {
  74. memcpy_to_sspm(MBOX0_BASE + PINR_OFFSET_PLATFORM * 4,
  75. data,
  76. PINR_SIZE_PLATFORM);
  77. dsb();
  78. mmio_write_32(MBOX0_BASE + MBOX_OUT_IRQ_OFS, 0x1);
  79. } else if (id == IPI_ID_SUSPEND) {
  80. memcpy_to_sspm(MBOX1_BASE + PINR_OFFSET_SUSPEND * 4,
  81. data,
  82. PINR_SIZE_SUSPEND);
  83. dsb();
  84. mmio_write_32(MBOX1_BASE + MBOX_OUT_IRQ_OFS,
  85. 0x2);
  86. }
  87. return 0;
  88. }
  89. int sspm_ipi_recv_non_blocking(uint32_t id, uint32_t *data, uint32_t len)
  90. {
  91. int ret = 0;
  92. ret = sspm_ipi_check_ack(id);
  93. if (ret == -EINPROGRESS) {
  94. if (id == IPI_ID_PLATFORM) {
  95. memcpy_from_sspm(data,
  96. MBOX0_BASE + PINR_OFFSET_PLATFORM * 4,
  97. len);
  98. dsb();
  99. /* clear interrupt bit*/
  100. mmio_write_32(MBOX0_BASE + MBOX_IN_IRQ_OFS,
  101. 0x1);
  102. ret = 0;
  103. } else if (id == IPI_ID_SUSPEND) {
  104. memcpy_from_sspm(data,
  105. MBOX1_BASE + PINR_OFFSET_SUSPEND * 4,
  106. len);
  107. dsb();
  108. /* clear interrupt bit*/
  109. mmio_write_32(MBOX1_BASE + MBOX_IN_IRQ_OFS,
  110. 0x2);
  111. ret = 0;
  112. }
  113. } else if (ret == 0) {
  114. ret = -EBUSY;
  115. }
  116. return ret;
  117. }
  118. int sspm_alive_show(void)
  119. {
  120. uint32_t ipi_data, count;
  121. int ret = 0;
  122. count = 5;
  123. ipi_data = 0xdead;
  124. if (sspm_ipi_send_non_blocking(IPI_ID_PLATFORM, &ipi_data) != 0) {
  125. ERROR("sspm init send fail! ret=%d\n", ret);
  126. return -1;
  127. }
  128. while (sspm_ipi_recv_non_blocking(IPI_ID_PLATFORM,
  129. &ipi_data,
  130. sizeof(ipi_data) / sizeof(uint32_t))
  131. && count) {
  132. mdelay(100);
  133. count--;
  134. }
  135. return (ipi_data == 1) ? 0 : -1;
  136. }