1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2016 Freescale Semiconductor, Inc. 4 * Copyright 2017~2018 NXP 5 * Author: Dong Aisheng <aisheng.dong@nxp.com> 6 * 7 * File containing client-side RPC functions for the MISC service. These 8 * function are ported to clients that communicate to the SC. 9 * 10 */ 11 12 #include <linux/firmware/imx/svc/misc.h> 13 14 struct imx_sc_msg_req_misc_set_ctrl { 15 struct imx_sc_rpc_msg hdr; 16 u32 ctrl; 17 u32 val; 18 u16 resource; 19 } __packed; 20 21 struct imx_sc_msg_req_cpu_start { 22 struct imx_sc_rpc_msg hdr; 23 u32 address_hi; 24 u32 address_lo; 25 u16 resource; 26 u8 enable; 27 } __packed; 28 29 struct imx_sc_msg_req_misc_get_ctrl { 30 struct imx_sc_rpc_msg hdr; 31 u32 ctrl; 32 u16 resource; 33 } __packed; 34 35 struct imx_sc_msg_resp_misc_get_ctrl { 36 struct imx_sc_rpc_msg hdr; 37 u32 val; 38 } __packed; 39 40 /* 41 * This function sets a miscellaneous control value. 42 * 43 * @param[in] ipc IPC handle 44 * @param[in] resource resource the control is associated with 45 * @param[in] ctrl control to change 46 * @param[in] val value to apply to the control 47 * 48 * @return Returns 0 for success and < 0 for errors. 49 */ 50 51 int imx_sc_misc_set_control(struct imx_sc_ipc *ipc, u32 resource, 52 u8 ctrl, u32 val) 53 { 54 struct imx_sc_msg_req_misc_set_ctrl msg; 55 struct imx_sc_rpc_msg *hdr = &msg.hdr; 56 57 hdr->ver = IMX_SC_RPC_VERSION; 58 hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC; 59 hdr->func = (uint8_t)IMX_SC_MISC_FUNC_SET_CONTROL; 60 hdr->size = 4; 61 62 msg.ctrl = ctrl; 63 msg.val = val; 64 msg.resource = resource; 65 66 return imx_scu_call_rpc(ipc, &msg, true); 67 } 68 EXPORT_SYMBOL(imx_sc_misc_set_control); 69 70 /* 71 * This function gets a miscellaneous control value. 72 * 73 * @param[in] ipc IPC handle 74 * @param[in] resource resource the control is associated with 75 * @param[in] ctrl control to get 76 * @param[out] val pointer to return the control value 77 * 78 * @return Returns 0 for success and < 0 for errors. 79 */ 80 81 int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 resource, 82 u8 ctrl, u32 *val) 83 { 84 struct imx_sc_msg_req_misc_get_ctrl msg; 85 struct imx_sc_msg_resp_misc_get_ctrl *resp; 86 struct imx_sc_rpc_msg *hdr = &msg.hdr; 87 int ret; 88 89 hdr->ver = IMX_SC_RPC_VERSION; 90 hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC; 91 hdr->func = (uint8_t)IMX_SC_MISC_FUNC_GET_CONTROL; 92 hdr->size = 3; 93 94 msg.ctrl = ctrl; 95 msg.resource = resource; 96 97 ret = imx_scu_call_rpc(ipc, &msg, true); 98 if (ret) 99 return ret; 100 101 resp = (struct imx_sc_msg_resp_misc_get_ctrl *)&msg; 102 if (val != NULL) 103 *val = resp->val; 104 105 return 0; 106 } 107 EXPORT_SYMBOL(imx_sc_misc_get_control); 108 109 /* 110 * This function starts/stops a CPU identified by @resource 111 * 112 * @param[in] ipc IPC handle 113 * @param[in] resource resource the control is associated with 114 * @param[in] enable true for start, false for stop 115 * @param[in] phys_addr initial instruction address to be executed 116 * 117 * @return Returns 0 for success and < 0 for errors. 118 */ 119 int imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource, 120 bool enable, u64 phys_addr) 121 { 122 struct imx_sc_msg_req_cpu_start msg; 123 struct imx_sc_rpc_msg *hdr = &msg.hdr; 124 125 hdr->ver = IMX_SC_RPC_VERSION; 126 hdr->svc = IMX_SC_RPC_SVC_PM; 127 hdr->func = IMX_SC_PM_FUNC_CPU_START; 128 hdr->size = 4; 129 130 msg.address_hi = phys_addr >> 32; 131 msg.address_lo = phys_addr; 132 msg.resource = resource; 133 msg.enable = enable; 134 135 return imx_scu_call_rpc(ipc, &msg, true); 136 } 137 EXPORT_SYMBOL(imx_sc_pm_cpu_start); 138