/* * Copyright 2017-2019 NXP * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #include #include "imx8_mu.h" #include DEFINE_BAKERY_LOCK(sc_ipc_bakery_lock); #define sc_ipc_lock_init() bakery_lock_init(&sc_ipc_bakery_lock) #define sc_ipc_lock() bakery_lock_get(&sc_ipc_bakery_lock) #define sc_ipc_unlock() bakery_lock_release(&sc_ipc_bakery_lock) void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, sc_bool_t no_resp) { sc_ipc_lock(); sc_ipc_write(ipc, msg); if (!no_resp) sc_ipc_read(ipc, msg); sc_ipc_unlock(); } sc_err_t sc_ipc_open(sc_ipc_t *ipc, sc_ipc_id_t id) { uint32_t base = id; uint32_t i; /* Get MU base associated with IPC channel */ if ((ipc == NULL) || (base == 0)) return SC_ERR_IPC; sc_ipc_lock_init(); /* Init MU */ MU_Init(base); /* Enable all RX interrupts */ for (i = 0; i < MU_RR_COUNT; i++) { MU_EnableRxFullInt(base, i); } /* Return MU address as handle */ *ipc = (sc_ipc_t) id; return SC_ERR_NONE; } void sc_ipc_close(sc_ipc_t ipc) { uint32_t base = ipc; if (base != 0) MU_Init(base); } void sc_ipc_read(sc_ipc_t ipc, void *data) { uint32_t base = ipc; sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data; uint8_t count = 0; /* Check parms */ if ((base == 0) || (msg == NULL)) return; /* Read first word */ MU_ReceiveMsg(base, 0, (uint32_t *) msg); count++; /* Check size */ if (msg->size > SC_RPC_MAX_MSG) { *((uint32_t *) msg) = 0; return; } /* Read remaining words */ while (count < msg->size) { MU_ReceiveMsg(base, count % MU_RR_COUNT, &(msg->DATA.u32[count - 1])); count++; } } void sc_ipc_write(sc_ipc_t ipc, const void *data) { sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data; uint32_t base = ipc; uint8_t count = 0; /* Check parms */ if ((base == 0) || (msg == NULL)) return; /* Check size */ if (msg->size > SC_RPC_MAX_MSG) return; /* Write first word */ MU_SendMessage(base, 0, *((uint32_t *) msg)); count++; /* Write remaining words */ while (count < msg->size) { MU_SendMessage(base, count % MU_TR_COUNT, msg->DATA.u32[count - 1]); count++; } }