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