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