blob: e8e16aee6710fa3b7b7e38adb438b729d45091c2 [file] [log] [blame]
/*
* Copyright 2015-2016 Freescale Semiconductor, Inc.
* Copyright 2017 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*==========================================================================*/
/*!
* @file ipc.c
*
* Implementation of the IPC functions using MUs (client side).
*/
/*==========================================================================*/
/* Includes */
#include <asm/imx-common/sci/scfw.h>
#include <asm/imx-common/sci/ipc.h>
#include <asm/imx-common/sci/rpc.h>
#include <asm/arch/fsl_mu_hal.h>
/* Local Defines */
/* Local Types */
/* Local Functions */
/* Local Variables */
/*----------------------------------------------------------------------*/
/* RPC command/response */
/*----------------------------------------------------------------------*/
void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, bool no_resp)
{
sc_ipc_write(ipc, msg);
if (!no_resp)
sc_ipc_read(ipc, msg);
}
/*--------------------------------------------------------------------------*/
/* Open an IPC channel */
/*--------------------------------------------------------------------------*/
sc_err_t sc_ipc_open(sc_ipc_t *ipc, sc_ipc_id_t id)
{
MU_Type *base = (MU_Type*) id;
uint32_t i;
/* Get MU base associated with IPC channel */
if ((ipc == NULL) || (base == NULL))
return SC_ERR_IPC;
/* Init MU */
MU_HAL_Init(base);
/* Enable all RX interrupts */
for (i = 0; i < MU_RR_COUNT; i++)
{
MU_HAL_EnableRxFullInt(base, i);
}
/* Return MU address as handle */
*ipc = (sc_ipc_t) id;
return SC_ERR_NONE;
}
/*--------------------------------------------------------------------------*/
/* Close an IPC channel */
/*--------------------------------------------------------------------------*/
void sc_ipc_close(sc_ipc_t ipc)
{
MU_Type *base = (MU_Type*) ipc;
if (base != NULL)
MU_HAL_Init(base);
}
/*--------------------------------------------------------------------------*/
/* Read message from an IPC channel */
/*--------------------------------------------------------------------------*/
void sc_ipc_read(sc_ipc_t ipc, void *data)
{
MU_Type *base = (MU_Type*) ipc;
sc_rpc_msg_t *msg = (sc_rpc_msg_t*) data;
uint8_t count = 0;
/* Check parms */
if ((base == NULL) || (msg == NULL))
return;
/* Read first word */
MU_HAL_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_HAL_ReceiveMsg(base, count % MU_RR_COUNT,
&(msg->DATA.u32[count - 1]));
count++;
}
}
/*--------------------------------------------------------------------------*/
/* Write a message to an IPC channel */
/*--------------------------------------------------------------------------*/
void sc_ipc_write(sc_ipc_t ipc, void *data)
{
MU_Type *base = (MU_Type*) ipc;
sc_rpc_msg_t *msg = (sc_rpc_msg_t*) data;
uint8_t count = 0;
/* Check parms */
if ((base == NULL) || (msg == NULL))
return;
/* Check size */
if (msg->size > SC_RPC_MAX_MSG)
return;
/* Write first word */
MU_HAL_SendMsg(base, 0, *((uint32_t*) msg));
count++;
/* Write remaining words */
while (count < msg->size)
{
MU_HAL_SendMsg(base, count % MU_TR_COUNT,
msg->DATA.u32[count - 1]);
count++;
}
}