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