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