xref: /rk3399_ARM-atf/plat/imx/common/sci/ipc.c (revision 118a67a9a3a810d37bca89aab28922769ca04a84)
1ff2743e5SAnson Huang /*
2*118a67a9SSamuel Holland  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
3ff2743e5SAnson Huang  *
4ff2743e5SAnson Huang  * SPDX-License-Identifier: BSD-3-Clause
5ff2743e5SAnson Huang  */
6ff2743e5SAnson Huang 
709d40e0eSAntonio Nino Diaz #include <stdlib.h>
809d40e0eSAntonio Nino Diaz 
909d40e0eSAntonio Nino Diaz #include <lib/bakery_lock.h>
1009d40e0eSAntonio Nino Diaz 
11ff2743e5SAnson Huang #include <sci/sci_scfw.h>
12ff2743e5SAnson Huang #include <sci/sci_ipc.h>
13ff2743e5SAnson Huang #include <sci/sci_rpc.h>
14ff2743e5SAnson Huang #include "imx8_mu.h"
15ff2743e5SAnson Huang 
16*118a67a9SSamuel Holland sc_ipc_t ipc_handle;
17*118a67a9SSamuel Holland 
18ff2743e5SAnson Huang DEFINE_BAKERY_LOCK(sc_ipc_bakery_lock);
19ff2743e5SAnson Huang #define sc_ipc_lock_init()	bakery_lock_init(&sc_ipc_bakery_lock)
20ff2743e5SAnson Huang #define sc_ipc_lock()		bakery_lock_get(&sc_ipc_bakery_lock)
21ff2743e5SAnson Huang #define sc_ipc_unlock()		bakery_lock_release(&sc_ipc_bakery_lock)
22ff2743e5SAnson Huang 
23ff2743e5SAnson Huang void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, bool no_resp)
24ff2743e5SAnson Huang {
25ff2743e5SAnson Huang 	sc_ipc_lock();
26ff2743e5SAnson Huang 
27ff2743e5SAnson Huang 	sc_ipc_write(ipc, msg);
28ff2743e5SAnson Huang 	if (!no_resp)
29ff2743e5SAnson Huang 		sc_ipc_read(ipc, msg);
30ff2743e5SAnson Huang 
31ff2743e5SAnson Huang 	sc_ipc_unlock();
32ff2743e5SAnson Huang }
33ff2743e5SAnson Huang 
34ff2743e5SAnson Huang sc_err_t sc_ipc_open(sc_ipc_t *ipc, sc_ipc_id_t id)
35ff2743e5SAnson Huang {
36ff2743e5SAnson Huang 	uint32_t base = id;
37ff2743e5SAnson Huang 	uint32_t i;
38ff2743e5SAnson Huang 
39ff2743e5SAnson Huang 	/* Get MU base associated with IPC channel */
40ff2743e5SAnson Huang 	if ((ipc == NULL) || (base == 0))
41ff2743e5SAnson Huang 		return SC_ERR_IPC;
42ff2743e5SAnson Huang 
43ff2743e5SAnson Huang 	sc_ipc_lock_init();
44ff2743e5SAnson Huang 
45ff2743e5SAnson Huang 	/* Init MU */
46ff2743e5SAnson Huang 	MU_Init(base);
47ff2743e5SAnson Huang 
48ff2743e5SAnson Huang 	/* Enable all RX interrupts */
49ff2743e5SAnson Huang 	for (i = 0; i < MU_RR_COUNT; i++) {
50ff2743e5SAnson Huang 		MU_EnableRxFullInt(base, i);
51ff2743e5SAnson Huang 	}
52ff2743e5SAnson Huang 
53ff2743e5SAnson Huang 	/* Return MU address as handle */
54ff2743e5SAnson Huang 	*ipc = (sc_ipc_t) id;
55ff2743e5SAnson Huang 
56ff2743e5SAnson Huang 	return SC_ERR_NONE;
57ff2743e5SAnson Huang }
58ff2743e5SAnson Huang 
59ff2743e5SAnson Huang void sc_ipc_close(sc_ipc_t ipc)
60ff2743e5SAnson Huang {
61ff2743e5SAnson Huang 	uint32_t base = ipc;
62ff2743e5SAnson Huang 
63ff2743e5SAnson Huang 	if (base != 0)
64ff2743e5SAnson Huang 		MU_Init(base);
65ff2743e5SAnson Huang }
66ff2743e5SAnson Huang 
67ff2743e5SAnson Huang void sc_ipc_read(sc_ipc_t ipc, void *data)
68ff2743e5SAnson Huang {
69ff2743e5SAnson Huang 	uint32_t base = ipc;
70ff2743e5SAnson Huang 	sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data;
71ff2743e5SAnson Huang 	uint8_t count = 0;
72ff2743e5SAnson Huang 
73ff2743e5SAnson Huang 	/* Check parms */
74ff2743e5SAnson Huang 	if ((base == 0) || (msg == NULL))
75ff2743e5SAnson Huang 		return;
76ff2743e5SAnson Huang 
77ff2743e5SAnson Huang 	/* Read first word */
78ff2743e5SAnson Huang 	MU_ReceiveMsg(base, 0, (uint32_t *) msg);
79ff2743e5SAnson Huang 	count++;
80ff2743e5SAnson Huang 
81ff2743e5SAnson Huang 	/* Check size */
82ff2743e5SAnson Huang 	if (msg->size > SC_RPC_MAX_MSG) {
83ff2743e5SAnson Huang 		*((uint32_t *) msg) = 0;
84ff2743e5SAnson Huang 		return;
85ff2743e5SAnson Huang 	}
86ff2743e5SAnson Huang 
87ff2743e5SAnson Huang 	/* Read remaining words */
88ff2743e5SAnson Huang 	while (count < msg->size) {
89ff2743e5SAnson Huang 		MU_ReceiveMsg(base, count % MU_RR_COUNT,
90ff2743e5SAnson Huang 			&(msg->DATA.u32[count - 1]));
91ff2743e5SAnson Huang 		count++;
92ff2743e5SAnson Huang 	}
93ff2743e5SAnson Huang }
94ff2743e5SAnson Huang 
95ff2743e5SAnson Huang void sc_ipc_write(sc_ipc_t ipc, void *data)
96ff2743e5SAnson Huang {
97ff2743e5SAnson Huang 	sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data;
98ff2743e5SAnson Huang 	uint32_t base = ipc;
99ff2743e5SAnson Huang 	uint8_t count = 0;
100ff2743e5SAnson Huang 
101ff2743e5SAnson Huang 	/* Check parms */
102ff2743e5SAnson Huang 	if ((base == 0) || (msg == NULL))
103ff2743e5SAnson Huang 		return;
104ff2743e5SAnson Huang 
105ff2743e5SAnson Huang 	/* Check size */
106ff2743e5SAnson Huang 	if (msg->size > SC_RPC_MAX_MSG)
107ff2743e5SAnson Huang 		return;
108ff2743e5SAnson Huang 
109ff2743e5SAnson Huang 	/* Write first word */
110ff2743e5SAnson Huang 	MU_SendMessage(base, 0, *((uint32_t *) msg));
111ff2743e5SAnson Huang 	count++;
112ff2743e5SAnson Huang 
113ff2743e5SAnson Huang 	/* Write remaining words */
114ff2743e5SAnson Huang 	while (count < msg->size) {
115ff2743e5SAnson Huang 		MU_SendMessage(base, count % MU_TR_COUNT,
116ff2743e5SAnson Huang 			msg->DATA.u32[count - 1]);
117ff2743e5SAnson Huang 		count++;
118ff2743e5SAnson Huang 	}
119ff2743e5SAnson Huang }
120ff2743e5SAnson Huang 
121