1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2020-2021 NXP
4  */
5 #include <drivers/imx_mu.h>
6 #include <io.h>
7 #include <kernel/delay.h>
8 #include <tee_api_types.h>
9 
10 #define MU_ATR(n)     (0x0 + (n) * (4))
11 #define MU_ARR(n)     (0x10 + (n) * (4))
12 #define MU_ASR_OFFSET 0x20
13 #define MU_ACR_OFFSET 0x24
14 
15 #define MU_SR_RF(n) SHIFT_U32(1, 27 - (n))
16 #define MU_SR_TE(n) SHIFT_U32(1, 23 - (n))
17 
18 #define MU_CR_GIE_MASK GENMASK_32(31, 28)
19 #define MU_CR_RIE_MASK GENMASK_32(27, 24)
20 #define MU_CR_TIE_MASK GENMASK_32(23, 20)
21 #define MU_CR_GIR_MASK GENMASK_32(19, 16)
22 #define MU_CR_F_MASK   GENMASK_32(2, 0)
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 			return TEE_ERROR_BUSY;
31 	}
32 
33 	return TEE_SUCCESS;
34 }
35 
mu_init(vaddr_t base)36 void mu_init(vaddr_t base)
37 {
38 	io_clrbits32(base + MU_ACR_OFFSET, MU_CR_GIE_MASK | MU_CR_RIE_MASK |
39 					   MU_CR_TIE_MASK | MU_CR_GIR_MASK |
40 					   MU_CR_F_MASK);
41 }
42 
mu_send_msg(vaddr_t base,unsigned int index,uint32_t msg)43 TEE_Result mu_send_msg(vaddr_t base, unsigned int index, uint32_t msg)
44 {
45 	/* Wait TX register to be empty */
46 	if (mu_wait_for(base + MU_ASR_OFFSET, MU_SR_TE(index)))
47 		return TEE_ERROR_BUSY;
48 
49 	/* Write message in TX register */
50 	io_write32(base + MU_ATR(index), msg);
51 
52 	return TEE_SUCCESS;
53 }
54 
mu_receive_msg(vaddr_t base,unsigned int index,uint32_t * msg)55 TEE_Result mu_receive_msg(vaddr_t base, unsigned int index, uint32_t *msg)
56 {
57 	/* Wait RX register to be full */
58 	if (mu_wait_for(base + MU_ASR_OFFSET, MU_SR_RF(index)))
59 		return TEE_ERROR_BUSY;
60 
61 	*msg = io_read32(base + MU_ARR(index));
62 
63 	return TEE_SUCCESS;
64 }
65