sunxi_msgbox.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <stdbool.h>
  8. #include <drivers/delay_timer.h>
  9. #include <lib/bakery_lock.h>
  10. #include <lib/mmio.h>
  11. #include <lib/utils_def.h>
  12. #include <sunxi_mmap.h>
  13. #define REMOTE_IRQ_EN_REG 0x0040
  14. #define REMOTE_IRQ_STAT_REG 0x0050
  15. #define LOCAL_IRQ_EN_REG 0x0060
  16. #define LOCAL_IRQ_STAT_REG 0x0070
  17. #define RX_IRQ(n) BIT(0 + 2 * (n))
  18. #define TX_IRQ(n) BIT(1 + 2 * (n))
  19. #define FIFO_STAT_REG(n) (0x0100 + 0x4 * (n))
  20. #define FIFO_STAT_MASK GENMASK(0, 0)
  21. #define MSG_STAT_REG(n) (0x0140 + 0x4 * (n))
  22. #define MSG_STAT_MASK GENMASK(2, 0)
  23. #define MSG_DATA_REG(n) (0x0180 + 0x4 * (n))
  24. #define RX_CHAN 1
  25. #define TX_CHAN 0
  26. #define MHU_MAX_SLOT_ID 31
  27. #define MHU_TIMEOUT_DELAY 10
  28. #define MHU_TIMEOUT_ITERS 10000
  29. static DEFINE_BAKERY_LOCK(mhu_secure_message_lock);
  30. static bool sunxi_msgbox_last_tx_done(unsigned int chan)
  31. {
  32. uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + REMOTE_IRQ_STAT_REG);
  33. return (stat & RX_IRQ(chan)) == 0U;
  34. }
  35. static bool sunxi_msgbox_peek_data(unsigned int chan)
  36. {
  37. uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_STAT_REG(chan));
  38. return (stat & MSG_STAT_MASK) != 0U;
  39. }
  40. void mhu_secure_message_start(unsigned int slot_id __unused)
  41. {
  42. uint32_t timeout = MHU_TIMEOUT_ITERS;
  43. bakery_lock_get(&mhu_secure_message_lock);
  44. /* Wait for all previous messages to be acknowledged. */
  45. while (!sunxi_msgbox_last_tx_done(TX_CHAN) && --timeout)
  46. udelay(MHU_TIMEOUT_DELAY);
  47. }
  48. void mhu_secure_message_send(unsigned int slot_id)
  49. {
  50. mmio_write_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(TX_CHAN), BIT(slot_id));
  51. }
  52. uint32_t mhu_secure_message_wait(void)
  53. {
  54. uint32_t timeout = MHU_TIMEOUT_ITERS;
  55. uint32_t msg = 0;
  56. /* Wait for a message from the SCP. */
  57. while (!sunxi_msgbox_peek_data(RX_CHAN) && --timeout)
  58. udelay(MHU_TIMEOUT_DELAY);
  59. /* Return the most recent message in the FIFO. */
  60. while (sunxi_msgbox_peek_data(RX_CHAN))
  61. msg = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(RX_CHAN));
  62. return msg;
  63. }
  64. void mhu_secure_message_end(unsigned int slot_id)
  65. {
  66. /* Acknowledge a response by clearing the IRQ status. */
  67. mmio_write_32(SUNXI_MSGBOX_BASE + LOCAL_IRQ_STAT_REG, RX_IRQ(RX_CHAN));
  68. bakery_lock_release(&mhu_secure_message_lock);
  69. }