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