xref: /optee_os/core/drivers/imx/mu/imx_mu_8ulp_9x.c (revision 90a9b9cc445a25c7eeb540903ae26aa61a9ce61a)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2022-2023 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_PAR 0x004
14 #define MU_TCR		  0x120
15 #define MU_TSR		  0x124
16 #define MU_RCR		  0x128
17 #define MU_RSR		  0x12C
18 #define MU_TR(n)	  (0x200 + 0x4 * (n))
19 #define MU_RR(n)	  (0x280 + 0x4 * (n))
20 #define MU_TSR_TE(n)	  BIT32(n)
21 #define MU_RSR_RF(n)	  BIT32(n)
22 
23 #define RR_NUM_MASK GENMASK_32(15, 8)
24 #define RR_NUM_SHIFT 8
25 #define TR_NUM_MASK GENMASK_32(7, 0)
26 
mu_wait_for(vaddr_t addr,uint32_t mask)27 static TEE_Result mu_wait_for(vaddr_t addr, uint32_t mask)
28 {
29 	uint64_t timeout = timeout_init_us(1000);
30 
31 	while (!(io_read32(addr) & mask))
32 		if (timeout_elapsed(timeout))
33 			break;
34 
35 	if (io_read32(addr) & mask)
36 		return TEE_SUCCESS;
37 	else
38 		return TEE_ERROR_BUSY;
39 
40 	return TEE_SUCCESS;
41 }
42 
imx_mu_plat_get_rx_channel(vaddr_t base)43 unsigned int imx_mu_plat_get_rx_channel(vaddr_t base)
44 {
45 	return (io_read32(base + MU_PAR) & RR_NUM_MASK) >> RR_NUM_SHIFT;
46 }
47 
imx_mu_plat_get_tx_channel(vaddr_t base)48 unsigned int imx_mu_plat_get_tx_channel(vaddr_t base)
49 {
50 	return io_read32(base + MU_PAR) & TR_NUM_MASK;
51 }
52 
imx_mu_plat_send(vaddr_t base,unsigned int index,uint32_t msg)53 TEE_Result imx_mu_plat_send(vaddr_t base, unsigned int index, uint32_t msg)
54 {
55 	assert(index < imx_mu_plat_get_tx_channel(base));
56 
57 	/* Wait TX register to be empty */
58 	if (mu_wait_for(base + MU_TSR, MU_TSR_TE(index)))
59 		return TEE_ERROR_BUSY;
60 
61 	io_write32(base + MU_TR(index), msg);
62 
63 	return TEE_SUCCESS;
64 }
65 
imx_mu_plat_receive(vaddr_t base,unsigned int index,uint32_t * msg)66 TEE_Result imx_mu_plat_receive(vaddr_t base, unsigned int index, uint32_t *msg)
67 {
68 	assert(index < imx_mu_plat_get_rx_channel(base));
69 
70 	/* Wait RX register to be full */
71 	if (mu_wait_for(base + MU_RSR, MU_RSR_RF(index)))
72 		return TEE_ERROR_NO_DATA;
73 
74 	*msg = io_read32(base + MU_RR(index));
75 
76 	return TEE_SUCCESS;
77 }
78 
imx_mu_plat_init(vaddr_t base)79 void imx_mu_plat_init(vaddr_t base)
80 {
81 	/* Reset status registers */
82 	io_write32(base + MU_TCR, 0x0);
83 	io_write32(base + MU_RCR, 0x0);
84 }
85