Skip to content

Commit

Permalink
LF-202-1 firmware: imx: scu: use hvc for dom0
Browse files Browse the repository at this point in the history
We use hvc to let xen handle the scfw api call for dom0.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Leonard Crestez <leonard.crestez@nxp.com>
[ Aisheng: fix minior conflicts due to
51f5afa ("firmware: imx: Skip return value check for some special SCU firmware APIs") ]
Sign-off-by: Dong Aisheng <aisheng.dong@nxp.com>
  • Loading branch information
MrVan authored and Dong Aisheng committed Nov 2, 2021
1 parent 431fd89 commit d0d51c6
Showing 1 changed file with 41 additions and 25 deletions.
66 changes: 41 additions & 25 deletions drivers/firmware/imx/imx-scu.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*
*/

#include <linux/arm-smccc.h>
#include <linux/err.h>
#include <linux/firmware/imx/ipc.h>
#include <linux/firmware/imx/sci.h>
Expand All @@ -19,6 +20,9 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>

#include <xen/xen.h>

#define FSL_HVC_SC 0xC6000000
#define SCU_MU_CHAN_NUM 8
#define MAX_RX_TIMEOUT (msecs_to_jiffies(3000))

Expand Down Expand Up @@ -204,6 +208,7 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
{
uint8_t saved_svc, saved_func;
struct imx_sc_rpc_msg *hdr;
struct arm_smccc_res res;
int ret;

if (WARN_ON(!sc_ipc || !msg))
Expand All @@ -219,33 +224,44 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
}
sc_ipc->count = 0;
sc_ipc->rx_size = 0;
ret = imx_scu_ipc_write(sc_ipc, msg);
if (ret < 0) {
dev_err(sc_ipc->dev, "RPC send msg failed: %d\n", ret);
goto out;
}

if (have_resp) {
if (!wait_for_completion_timeout(&sc_ipc->done,
MAX_RX_TIMEOUT)) {
dev_err(sc_ipc->dev, "RPC send msg timeout\n");
mutex_unlock(&sc_ipc->lock);
return -ETIMEDOUT;
if (xen_initial_domain()) {
arm_smccc_hvc(FSL_HVC_SC, (uint64_t)msg, !have_resp, 0, 0, 0,
0, 0, &res);
if (res.a0)
printk("Error FSL_HVC_SC %ld\n", res.a0);

ret = res.a0;

} else {
ret = imx_scu_ipc_write(sc_ipc, msg);
if (ret < 0) {
dev_err(sc_ipc->dev, "RPC send msg failed: %d\n", ret);
goto out;
}

/* response status is stored in hdr->func field */
hdr = msg;
ret = hdr->func;
/*
* Some special SCU firmware APIs do NOT have return value
* in hdr->func, but they do have response data, those special
* APIs are defined as void function in SCU firmware, so they
* should be treated as return success always.
*/
if ((saved_svc == IMX_SC_RPC_SVC_MISC) &&
(saved_func == IMX_SC_MISC_FUNC_UNIQUE_ID ||
saved_func == IMX_SC_MISC_FUNC_GET_BUTTON_STATUS))
ret = 0;
if (have_resp) {
if (!wait_for_completion_timeout(&sc_ipc->done,
MAX_RX_TIMEOUT)) {
dev_err(sc_ipc->dev, "RPC send msg timeout\n");
mutex_unlock(&sc_ipc->lock);
return -ETIMEDOUT;
}

/* response status is stored in hdr->func field */
hdr = msg;
ret = hdr->func;

/*
* Some special SCU firmware APIs do NOT have return value
* in hdr->func, but they do have response data, those special
* APIs are defined as void function in SCU firmware, so they
* should be treated as return success always.
*/
if ((saved_svc == IMX_SC_RPC_SVC_MISC) &&
(saved_func == IMX_SC_MISC_FUNC_UNIQUE_ID ||
saved_func == IMX_SC_MISC_FUNC_GET_BUTTON_STATUS))
ret = 0;
}
}

out:
Expand Down

0 comments on commit d0d51c6

Please sign in to comment.