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 __aligned(4); |
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 __aligned(4); |
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 __aligned(4); |
34 | |
35 | struct imx_sc_msg_resp_misc_get_ctrl { |
36 | struct imx_sc_rpc_msg hdr; |
37 | u32 val; |
38 | } __packed __aligned(4); |
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: &msg, have_resp: 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: &msg, have_resp: 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: &msg, have_resp: true); |
136 | } |
137 | EXPORT_SYMBOL(imx_sc_pm_cpu_start); |
138 | |