1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2020-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_ATR(n) (0x0 + (n) * (4))
14 #define MU_ARR(n) (0x10 + (n) * (4))
15 #define MU_ASR_OFFSET 0x20
16 #define MU_ACR_OFFSET 0x24
17
18 #define MU_SR_RF(n) SHIFT_U32(1, 27 - (n))
19 #define MU_SR_TE(n) SHIFT_U32(1, 23 - (n))
20
21 #define MU_CR_GIE_MASK GENMASK_32(31, 28)
22 #define MU_CR_RIE_MASK GENMASK_32(27, 24)
23 #define MU_CR_TIE_MASK GENMASK_32(23, 20)
24 #define MU_CR_GIR_MASK GENMASK_32(19, 16)
25 #define MU_CR_F_MASK GENMASK_32(2, 0)
26
27 #define MU_MAX_CHANNEL 4
28
mu_wait_for(vaddr_t addr,uint32_t mask)29 static TEE_Result mu_wait_for(vaddr_t addr, uint32_t mask)
30 {
31 uint64_t timeout = timeout_init_us(1000);
32
33 while (!(io_read32(addr) & mask))
34 if (timeout_elapsed(timeout))
35 break;
36
37 if (io_read32(addr) & mask)
38 return TEE_SUCCESS;
39 else
40 return TEE_ERROR_BUSY;
41
42 return TEE_SUCCESS;
43 }
44
imx_mu_plat_get_rx_channel(void)45 unsigned int imx_mu_plat_get_rx_channel(void)
46 {
47 return MU_MAX_CHANNEL;
48 }
49
imx_mu_plat_get_tx_channel(void)50 unsigned int imx_mu_plat_get_tx_channel(void)
51 {
52 return MU_MAX_CHANNEL;
53 }
54
imx_mu_plat_init(vaddr_t base)55 void imx_mu_plat_init(vaddr_t base)
56 {
57 io_clrbits32(base + MU_ACR_OFFSET,
58 MU_CR_GIE_MASK | MU_CR_RIE_MASK | MU_CR_TIE_MASK |
59 MU_CR_GIR_MASK | MU_CR_F_MASK);
60 }
61
imx_mu_plat_send(vaddr_t base,unsigned int index,uint32_t msg)62 TEE_Result imx_mu_plat_send(vaddr_t base, unsigned int index, uint32_t msg)
63 {
64 assert(index < MU_MAX_CHANNEL);
65
66 /* Wait TX register to be empty */
67 if (mu_wait_for(base + MU_ASR_OFFSET, MU_SR_TE(index)))
68 return TEE_ERROR_BUSY;
69
70 /* Write message in TX register */
71 io_write32(base + MU_ATR(index), msg);
72
73 return TEE_SUCCESS;
74 }
75
imx_mu_plat_receive(vaddr_t base,unsigned int index,uint32_t * msg)76 TEE_Result imx_mu_plat_receive(vaddr_t base, unsigned int index, uint32_t *msg)
77 {
78 assert(index < MU_MAX_CHANNEL);
79
80 /* Wait RX register to be full */
81 if (mu_wait_for(base + MU_ASR_OFFSET, MU_SR_RF(index)))
82 return TEE_ERROR_NO_DATA;
83
84 /* Read message in RX register */
85 *msg = io_read32(base + MU_ARR(index));
86
87 return TEE_SUCCESS;
88 }
89