1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Texas Instruments K3 Mailbox Driver
4 * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
5 */
6
7 #include <io.h>
8 #include <kernel/delay.h>
9 #include <mm/core_memprot.h>
10 #include <mm/core_mmu.h>
11 #include <platform_config.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "ti_sci_protocol.h"
18 #include "ti_sci_transport.h"
19
20 static vaddr_t mailbox_tx_base;
21 static vaddr_t mailbox_rx_base;
22 static vaddr_t mailbox_tx_sram_va;
23 static vaddr_t mailbox_rx_sram_va;
24
ti_mailbox_poll_rx_status(void)25 static TEE_Result ti_mailbox_poll_rx_status(void)
26 {
27 uint32_t num_messages_pending = 0U;
28 vaddr_t mailbox_status_addr = mailbox_rx_base + TI_MAILBOX_MSG_STATUS;
29
30 if (IO_READ32_POLL_TIMEOUT(mailbox_status_addr, num_messages_pending,
31 num_messages_pending != 0, 10, 1000)) {
32 EMSG("Mailbox RX status polling timed out");
33 return TEE_ERROR_TIMEOUT;
34 }
35
36 return TEE_SUCCESS;
37 }
38
ti_sci_transport_send(const struct ti_sci_msg * msg)39 TEE_Result ti_sci_transport_send(const struct ti_sci_msg *msg)
40 {
41 uint32_t num_bytes = 0;
42 paddr_t phys_addr = 0;
43
44 if (!msg)
45 return TEE_ERROR_BAD_PARAMETERS;
46
47 num_bytes = msg->len;
48 if (num_bytes > TI_SCI_MAX_MESSAGE_SIZE) {
49 EMSG("Message size exceeds maximum allowed size");
50 return TEE_ERROR_BAD_STATE;
51 }
52
53 if (io_read32(mailbox_tx_base + TI_MAILBOX_FIFO_STATUS) != 0U) {
54 EMSG("Mailbox TX FIFO is full");
55 return TEE_ERROR_BUSY;
56 }
57
58 memmove((void *)mailbox_tx_sram_va, msg->buf, num_bytes);
59 phys_addr = virt_to_phys((void *)mailbox_tx_sram_va);
60 io_write32(mailbox_tx_base + TI_MAILBOX_MSG, (uint32_t)phys_addr);
61
62 return TEE_SUCCESS;
63 }
64
ti_sci_transport_recv(struct ti_sci_msg * msg)65 TEE_Result ti_sci_transport_recv(struct ti_sci_msg *msg)
66 {
67 uint32_t num_bytes = 0;
68 uint64_t recv_pa = 0;
69 vaddr_t recv_offset = 0;
70 vaddr_t recv_va = 0;
71 TEE_Result ret = TEE_SUCCESS;
72
73 if (!msg)
74 return TEE_ERROR_BAD_PARAMETERS;
75
76 num_bytes = msg->len;
77 if (num_bytes > TI_SCI_MAX_MESSAGE_SIZE) {
78 EMSG("Message size exceeds maximum allowed size\n");
79 return TEE_ERROR_BAD_STATE;
80 }
81
82 ret = ti_mailbox_poll_rx_status();
83 if (ret != TEE_SUCCESS) {
84 EMSG("Mailbox RX status polling failed");
85 return ret;
86 }
87
88 recv_pa = io_read32(mailbox_rx_base + TI_MAILBOX_MSG);
89 if (recv_pa < MAILBOX_RX_START_REGION) {
90 EMSG("Message not received invalid address\n");
91 return TEE_ERROR_BAD_FORMAT;
92 }
93
94 recv_offset = (vaddr_t)(recv_pa - MAILBOX_RX_START_REGION);
95 recv_va = (vaddr_t)(mailbox_rx_sram_va + recv_offset);
96 memmove(msg->buf, (uint8_t *)recv_va, num_bytes);
97 return TEE_SUCCESS;
98 }
99
ti_sci_transport_init(void)100 TEE_Result ti_sci_transport_init(void)
101 {
102 mailbox_rx_base = core_mmu_get_va(TI_MAILBOX_RX_BASE,
103 MEM_AREA_IO_SEC,
104 TI_MAILBOX_DEFAULT_SIZE);
105 if (!mailbox_rx_base)
106 return TEE_ERROR_OUT_OF_MEMORY;
107
108 mailbox_tx_base = core_mmu_get_va(TI_MAILBOX_TX_BASE,
109 MEM_AREA_IO_SEC,
110 TI_MAILBOX_DEFAULT_SIZE);
111 if (!mailbox_tx_base)
112 return TEE_ERROR_OUT_OF_MEMORY;
113
114 mailbox_tx_sram_va = core_mmu_get_va(MAILBOX_TX_START_REGION,
115 MEM_AREA_IO_SEC,
116 TI_MAILBOX_DEFAULT_SIZE);
117 if (!mailbox_tx_sram_va)
118 return TEE_ERROR_OUT_OF_MEMORY;
119
120 mailbox_rx_sram_va = core_mmu_get_va(MAILBOX_RX_START_REGION,
121 MEM_AREA_IO_SEC,
122 TI_MAILBOX_DEFAULT_SIZE);
123 if (!mailbox_rx_sram_va)
124 return TEE_ERROR_OUT_OF_MEMORY;
125
126 return TEE_SUCCESS;
127 }
128