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
sc_call_rpc(sc_ipc_t ipc,sc_rpc_msg_t * msg,bool no_resp)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
sc_ipc_open(sc_ipc_t * ipc,sc_ipc_id_t id)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
sc_ipc_close(sc_ipc_t ipc)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
sc_ipc_read(sc_ipc_t ipc,void * data)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
sc_ipc_write(sc_ipc_t ipc,void * data)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