1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2022 NXP
4  */
5 #include <drivers/imx_mu.h>
6 #include <initcall.h>
7 #include <io.h>
8 #include <kernel/delay.h>
9 #include <mm/core_memprot.h>
10 
11 #include "imx_mu_platform.h"
12 
13 #define MU_TCR		  0x120
14 #define MU_TSR		  0x124
15 #define MU_RCR		  0x128
16 #define MU_RSR		  0x12C
17 #define MU_TR(n)	  (0x200 + 0x4 * (n))
18 #define MU_RR(n)	  (0x280 + 0x4 * (n))
19 #define MU_TSR_TE(n)	  BIT32(n)
20 #define MU_RSR_RF(n)	  BIT32(n)
21 #define MU_MAX_RX_CHANNEL 4
22 #define MU_MAX_TX_CHANNEL 8
23 
mu_wait_for(vaddr_t addr,uint32_t mask)24 static TEE_Result mu_wait_for(vaddr_t addr, uint32_t mask)
25 {
26 	uint64_t timeout = timeout_init_us(1000);
27 
28 	while (!(io_read32(addr) & mask))
29 		if (timeout_elapsed(timeout))
30 			break;
31 
32 	if (io_read32(addr) & mask)
33 		return TEE_SUCCESS;
34 	else
35 		return TEE_ERROR_BUSY;
36 
37 	return TEE_SUCCESS;
38 }
39 
imx_mu_plat_get_rx_channel(void)40 unsigned int imx_mu_plat_get_rx_channel(void)
41 {
42 	return MU_MAX_RX_CHANNEL;
43 }
44 
imx_mu_plat_get_tx_channel(void)45 unsigned int imx_mu_plat_get_tx_channel(void)
46 {
47 	return MU_MAX_TX_CHANNEL;
48 }
49 
imx_mu_plat_send(vaddr_t base,unsigned int index,uint32_t msg)50 TEE_Result imx_mu_plat_send(vaddr_t base, unsigned int index, uint32_t msg)
51 {
52 	assert(index < MU_MAX_TX_CHANNEL);
53 
54 	/* Wait TX register to be empty */
55 	if (mu_wait_for(base + MU_TSR, MU_TSR_TE(index)))
56 		return TEE_ERROR_BUSY;
57 
58 	io_write32(base + MU_TR(index), msg);
59 
60 	return TEE_SUCCESS;
61 }
62 
imx_mu_plat_receive(vaddr_t base,unsigned int index,uint32_t * msg)63 TEE_Result imx_mu_plat_receive(vaddr_t base, unsigned int index, uint32_t *msg)
64 {
65 	assert(index < MU_MAX_RX_CHANNEL);
66 
67 	/* Wait RX register to be full */
68 	if (mu_wait_for(base + MU_RSR, MU_RSR_RF(index)))
69 		return TEE_ERROR_NO_DATA;
70 
71 	*msg = io_read32(base + MU_RR(index));
72 
73 	return TEE_SUCCESS;
74 }
75 
imx_mu_plat_init(vaddr_t base)76 void imx_mu_plat_init(vaddr_t base)
77 {
78 	/* Reset status registers */
79 	io_write32(base + MU_TCR, 0x0);
80 	io_write32(base + MU_RCR, 0x0);
81 }
82