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