162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2016 Freescale Semiconductor, Inc. 462306a36Sopenharmony_ci * Copyright 2017~2018 NXP 562306a36Sopenharmony_ci * Author: Dong Aisheng <aisheng.dong@nxp.com> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * File containing client-side RPC functions for the MISC service. These 862306a36Sopenharmony_ci * function are ported to clients that communicate to the SC. 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/firmware/imx/svc/misc.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistruct imx_sc_msg_req_misc_set_ctrl { 1562306a36Sopenharmony_ci struct imx_sc_rpc_msg hdr; 1662306a36Sopenharmony_ci u32 ctrl; 1762306a36Sopenharmony_ci u32 val; 1862306a36Sopenharmony_ci u16 resource; 1962306a36Sopenharmony_ci} __packed __aligned(4); 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistruct imx_sc_msg_req_cpu_start { 2262306a36Sopenharmony_ci struct imx_sc_rpc_msg hdr; 2362306a36Sopenharmony_ci u32 address_hi; 2462306a36Sopenharmony_ci u32 address_lo; 2562306a36Sopenharmony_ci u16 resource; 2662306a36Sopenharmony_ci u8 enable; 2762306a36Sopenharmony_ci} __packed __aligned(4); 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistruct imx_sc_msg_req_misc_get_ctrl { 3062306a36Sopenharmony_ci struct imx_sc_rpc_msg hdr; 3162306a36Sopenharmony_ci u32 ctrl; 3262306a36Sopenharmony_ci u16 resource; 3362306a36Sopenharmony_ci} __packed __aligned(4); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistruct imx_sc_msg_resp_misc_get_ctrl { 3662306a36Sopenharmony_ci struct imx_sc_rpc_msg hdr; 3762306a36Sopenharmony_ci u32 val; 3862306a36Sopenharmony_ci} __packed __aligned(4); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* 4162306a36Sopenharmony_ci * This function sets a miscellaneous control value. 4262306a36Sopenharmony_ci * 4362306a36Sopenharmony_ci * @param[in] ipc IPC handle 4462306a36Sopenharmony_ci * @param[in] resource resource the control is associated with 4562306a36Sopenharmony_ci * @param[in] ctrl control to change 4662306a36Sopenharmony_ci * @param[in] val value to apply to the control 4762306a36Sopenharmony_ci * 4862306a36Sopenharmony_ci * @return Returns 0 for success and < 0 for errors. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ciint imx_sc_misc_set_control(struct imx_sc_ipc *ipc, u32 resource, 5262306a36Sopenharmony_ci u8 ctrl, u32 val) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci struct imx_sc_msg_req_misc_set_ctrl msg; 5562306a36Sopenharmony_ci struct imx_sc_rpc_msg *hdr = &msg.hdr; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci hdr->ver = IMX_SC_RPC_VERSION; 5862306a36Sopenharmony_ci hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC; 5962306a36Sopenharmony_ci hdr->func = (uint8_t)IMX_SC_MISC_FUNC_SET_CONTROL; 6062306a36Sopenharmony_ci hdr->size = 4; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci msg.ctrl = ctrl; 6362306a36Sopenharmony_ci msg.val = val; 6462306a36Sopenharmony_ci msg.resource = resource; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci return imx_scu_call_rpc(ipc, &msg, true); 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ciEXPORT_SYMBOL(imx_sc_misc_set_control); 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* 7162306a36Sopenharmony_ci * This function gets a miscellaneous control value. 7262306a36Sopenharmony_ci * 7362306a36Sopenharmony_ci * @param[in] ipc IPC handle 7462306a36Sopenharmony_ci * @param[in] resource resource the control is associated with 7562306a36Sopenharmony_ci * @param[in] ctrl control to get 7662306a36Sopenharmony_ci * @param[out] val pointer to return the control value 7762306a36Sopenharmony_ci * 7862306a36Sopenharmony_ci * @return Returns 0 for success and < 0 for errors. 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ciint imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 resource, 8262306a36Sopenharmony_ci u8 ctrl, u32 *val) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci struct imx_sc_msg_req_misc_get_ctrl msg; 8562306a36Sopenharmony_ci struct imx_sc_msg_resp_misc_get_ctrl *resp; 8662306a36Sopenharmony_ci struct imx_sc_rpc_msg *hdr = &msg.hdr; 8762306a36Sopenharmony_ci int ret; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci hdr->ver = IMX_SC_RPC_VERSION; 9062306a36Sopenharmony_ci hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC; 9162306a36Sopenharmony_ci hdr->func = (uint8_t)IMX_SC_MISC_FUNC_GET_CONTROL; 9262306a36Sopenharmony_ci hdr->size = 3; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci msg.ctrl = ctrl; 9562306a36Sopenharmony_ci msg.resource = resource; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci ret = imx_scu_call_rpc(ipc, &msg, true); 9862306a36Sopenharmony_ci if (ret) 9962306a36Sopenharmony_ci return ret; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci resp = (struct imx_sc_msg_resp_misc_get_ctrl *)&msg; 10262306a36Sopenharmony_ci if (val != NULL) 10362306a36Sopenharmony_ci *val = resp->val; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci return 0; 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ciEXPORT_SYMBOL(imx_sc_misc_get_control); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* 11062306a36Sopenharmony_ci * This function starts/stops a CPU identified by @resource 11162306a36Sopenharmony_ci * 11262306a36Sopenharmony_ci * @param[in] ipc IPC handle 11362306a36Sopenharmony_ci * @param[in] resource resource the control is associated with 11462306a36Sopenharmony_ci * @param[in] enable true for start, false for stop 11562306a36Sopenharmony_ci * @param[in] phys_addr initial instruction address to be executed 11662306a36Sopenharmony_ci * 11762306a36Sopenharmony_ci * @return Returns 0 for success and < 0 for errors. 11862306a36Sopenharmony_ci */ 11962306a36Sopenharmony_ciint imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource, 12062306a36Sopenharmony_ci bool enable, u64 phys_addr) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci struct imx_sc_msg_req_cpu_start msg; 12362306a36Sopenharmony_ci struct imx_sc_rpc_msg *hdr = &msg.hdr; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci hdr->ver = IMX_SC_RPC_VERSION; 12662306a36Sopenharmony_ci hdr->svc = IMX_SC_RPC_SVC_PM; 12762306a36Sopenharmony_ci hdr->func = IMX_SC_PM_FUNC_CPU_START; 12862306a36Sopenharmony_ci hdr->size = 4; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci msg.address_hi = phys_addr >> 32; 13162306a36Sopenharmony_ci msg.address_lo = phys_addr; 13262306a36Sopenharmony_ci msg.resource = resource; 13362306a36Sopenharmony_ci msg.enable = enable; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci return imx_scu_call_rpc(ipc, &msg, true); 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ciEXPORT_SYMBOL(imx_sc_pm_cpu_start); 138