David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 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); |