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