1 /*
2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /*!
8 * File containing client-side RPC functions for the PM service. These
9 * functions are ported to clients that communicate to the SC.
10 *
11 * @addtogroup PM_SVC
12 * @{
13 */
14
15 /* Includes */
16
17 #include <stdlib.h>
18
19 #include <sci/sci_types.h>
20 #include <sci/svc/rm/sci_rm_api.h>
21 #include <sci/svc/pm/sci_pm_api.h>
22 #include <sci/sci_rpc.h>
23
24 #include "sci_pm_rpc.h"
25
26 /* Local Defines */
27
28 /* Local Types */
29
30 /* Local Functions */
31
sc_pm_set_sys_power_mode(sc_ipc_t ipc,sc_pm_power_mode_t mode)32 sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_pm_power_mode_t mode)
33 {
34 sc_rpc_msg_t msg;
35 uint8_t result;
36
37 RPC_VER(&msg) = SC_RPC_VERSION;
38 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
39 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_SYS_POWER_MODE;
40 RPC_U8(&msg, 0U) = (uint8_t)mode;
41 RPC_SIZE(&msg) = 2U;
42
43 sc_call_rpc(ipc, &msg, SC_FALSE);
44
45 result = RPC_R8(&msg);
46 return (sc_err_t)result;
47 }
48
sc_pm_set_partition_power_mode(sc_ipc_t ipc,sc_rm_pt_t pt,sc_pm_power_mode_t mode)49 sc_err_t sc_pm_set_partition_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
50 sc_pm_power_mode_t mode)
51 {
52 sc_rpc_msg_t msg;
53 uint8_t result;
54
55 RPC_VER(&msg) = SC_RPC_VERSION;
56 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
57 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_PARTITION_POWER_MODE;
58 RPC_U8(&msg, 0U) = (uint8_t)pt;
59 RPC_U8(&msg, 1U) = (uint8_t)mode;
60 RPC_SIZE(&msg) = 2U;
61
62 sc_call_rpc(ipc, &msg, SC_FALSE);
63
64 result = RPC_R8(&msg);
65 return (sc_err_t)result;
66 }
67
sc_pm_get_sys_power_mode(sc_ipc_t ipc,sc_rm_pt_t pt,sc_pm_power_mode_t * mode)68 sc_err_t sc_pm_get_sys_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt,
69 sc_pm_power_mode_t *mode)
70 {
71 sc_rpc_msg_t msg;
72 uint8_t result;
73
74 RPC_VER(&msg) = SC_RPC_VERSION;
75 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
76 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_SYS_POWER_MODE;
77 RPC_U8(&msg, 0U) = (uint8_t)pt;
78 RPC_SIZE(&msg) = 2U;
79
80 sc_call_rpc(ipc, &msg, SC_FALSE);
81
82 result = RPC_R8(&msg);
83 if (mode != NULL) {
84 *mode = RPC_U8(&msg, 0U);
85 }
86
87 return (sc_err_t)result;
88 }
89
sc_pm_set_resource_power_mode(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_power_mode_t mode)90 sc_err_t sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
91 sc_pm_power_mode_t mode)
92 {
93 sc_rpc_msg_t msg;
94 uint8_t result;
95
96 RPC_VER(&msg) = SC_RPC_VERSION;
97 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
98 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_RESOURCE_POWER_MODE;
99 RPC_U16(&msg, 0U) = (uint16_t)resource;
100 RPC_U8(&msg, 2U) = (uint8_t)mode;
101 RPC_SIZE(&msg) = 2U;
102
103 sc_call_rpc(ipc, &msg, SC_FALSE);
104
105 result = RPC_R8(&msg);
106 return (sc_err_t)result;
107 }
108
sc_pm_get_resource_power_mode(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_power_mode_t * mode)109 sc_err_t sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
110 sc_pm_power_mode_t *mode)
111 {
112 sc_rpc_msg_t msg;
113 uint8_t result;
114
115 RPC_VER(&msg) = SC_RPC_VERSION;
116 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
117 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_RESOURCE_POWER_MODE;
118 RPC_U16(&msg, 0U) = (uint16_t)resource;
119 RPC_SIZE(&msg) = 2U;
120
121 sc_call_rpc(ipc, &msg, SC_FALSE);
122
123 result = RPC_R8(&msg);
124 if (mode != NULL) {
125 *mode = RPC_U8(&msg, 0U);
126 }
127
128 return (sc_err_t)result;
129 }
130
sc_pm_req_low_power_mode(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_power_mode_t mode)131 sc_err_t sc_pm_req_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
132 sc_pm_power_mode_t mode)
133 {
134 sc_rpc_msg_t msg;
135 uint8_t result;
136
137 RPC_VER(&msg) = SC_RPC_VERSION;
138 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
139 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REQ_LOW_POWER_MODE;
140 RPC_U16(&msg, 0U) = (uint16_t)resource;
141 RPC_U8(&msg, 2U) = (uint8_t)mode;
142 RPC_SIZE(&msg) = 2U;
143
144 sc_call_rpc(ipc, &msg, SC_FALSE);
145
146 result = RPC_R8(&msg);
147 return (sc_err_t)result;
148 }
149
sc_pm_req_cpu_low_power_mode(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_power_mode_t mode,sc_pm_wake_src_t wake_src)150 sc_err_t sc_pm_req_cpu_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
151 sc_pm_power_mode_t mode,
152 sc_pm_wake_src_t wake_src)
153 {
154 sc_rpc_msg_t msg;
155 uint8_t result;
156
157 RPC_VER(&msg) = SC_RPC_VERSION;
158 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
159 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REQ_CPU_LOW_POWER_MODE;
160 RPC_U16(&msg, 0U) = (uint16_t)resource;
161 RPC_U8(&msg, 2U) = (uint8_t)mode;
162 RPC_U8(&msg, 3U) = (uint8_t)wake_src;
163 RPC_SIZE(&msg) = 2U;
164
165 sc_call_rpc(ipc, &msg, SC_FALSE);
166
167 result = RPC_R8(&msg);
168 return (sc_err_t)result;
169 }
170
sc_pm_set_cpu_resume_addr(sc_ipc_t ipc,sc_rsrc_t resource,sc_faddr_t address)171 sc_err_t sc_pm_set_cpu_resume_addr(sc_ipc_t ipc, sc_rsrc_t resource,
172 sc_faddr_t address)
173 {
174 sc_rpc_msg_t msg;
175 uint8_t result;
176
177 RPC_VER(&msg) = SC_RPC_VERSION;
178 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
179 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CPU_RESUME_ADDR;
180 RPC_U32(&msg, 0U) = (uint32_t)(address >> 32U);
181 RPC_U32(&msg, 4U) = (uint32_t)address;
182 RPC_U16(&msg, 8U) = (uint16_t)resource;
183 RPC_SIZE(&msg) = 4U;
184
185 sc_call_rpc(ipc, &msg, SC_FALSE);
186
187 result = RPC_R8(&msg);
188 return (sc_err_t)result;
189 }
190
sc_pm_set_cpu_resume(sc_ipc_t ipc,sc_rsrc_t resource,sc_bool_t isPrimary,sc_faddr_t address)191 sc_err_t sc_pm_set_cpu_resume(sc_ipc_t ipc, sc_rsrc_t resource,
192 sc_bool_t isPrimary, sc_faddr_t address)
193 {
194 sc_rpc_msg_t msg;
195 uint8_t result;
196
197 RPC_VER(&msg) = SC_RPC_VERSION;
198 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
199 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CPU_RESUME;
200 RPC_U32(&msg, 0U) = (uint32_t)(address >> 32U);
201 RPC_U32(&msg, 4U) = (uint32_t)address;
202 RPC_U16(&msg, 8U) = (uint16_t)resource;
203 RPC_U8(&msg, 10U) = (uint8_t)isPrimary;
204 RPC_SIZE(&msg) = 4U;
205
206 sc_call_rpc(ipc, &msg, SC_FALSE);
207
208 result = RPC_R8(&msg);
209 return (sc_err_t)result;
210 }
211
sc_pm_req_sys_if_power_mode(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_sys_if_t sys_if,sc_pm_power_mode_t hpm,sc_pm_power_mode_t lpm)212 sc_err_t sc_pm_req_sys_if_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
213 sc_pm_sys_if_t sys_if,
214 sc_pm_power_mode_t hpm,
215 sc_pm_power_mode_t lpm)
216 {
217 sc_rpc_msg_t msg;
218 uint8_t result;
219
220 RPC_VER(&msg) = SC_RPC_VERSION;
221 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
222 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REQ_SYS_IF_POWER_MODE;
223 RPC_U16(&msg, 0U) = (uint16_t)resource;
224 RPC_U8(&msg, 2U) = (uint8_t)sys_if;
225 RPC_U8(&msg, 3U) = (uint8_t)hpm;
226 RPC_U8(&msg, 4U) = (uint8_t)lpm;
227 RPC_SIZE(&msg) = 3U;
228
229 sc_call_rpc(ipc, &msg, SC_FALSE);
230
231 result = RPC_R8(&msg);
232 return (sc_err_t)result;
233 }
234
sc_pm_set_clock_rate(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_clk_t clk,sc_pm_clock_rate_t * rate)235 sc_err_t sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
236 sc_pm_clk_t clk, sc_pm_clock_rate_t *rate)
237 {
238 sc_rpc_msg_t msg;
239 uint8_t result;
240
241 RPC_VER(&msg) = SC_RPC_VERSION;
242 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
243 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CLOCK_RATE;
244 RPC_U32(&msg, 0U) = *(uint32_t *)rate;
245 RPC_U16(&msg, 4U) = (uint16_t)resource;
246 RPC_U8(&msg, 6U) = (uint8_t)clk;
247 RPC_SIZE(&msg) = 3U;
248
249 sc_call_rpc(ipc, &msg, SC_FALSE);
250
251 *rate = RPC_U32(&msg, 0U);
252 result = RPC_R8(&msg);
253 return (sc_err_t)result;
254 }
255
sc_pm_get_clock_rate(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_clk_t clk,sc_pm_clock_rate_t * rate)256 sc_err_t sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource,
257 sc_pm_clk_t clk, sc_pm_clock_rate_t *rate)
258 {
259 sc_rpc_msg_t msg;
260 uint8_t result;
261
262 RPC_VER(&msg) = SC_RPC_VERSION;
263 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
264 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_CLOCK_RATE;
265 RPC_U16(&msg, 0U) = (uint16_t)resource;
266 RPC_U8(&msg, 2U) = (uint8_t)clk;
267 RPC_SIZE(&msg) = 2U;
268
269 sc_call_rpc(ipc, &msg, SC_FALSE);
270
271 if (rate != NULL) {
272 *rate = RPC_U32(&msg, 0U);
273 }
274
275 result = RPC_R8(&msg);
276 return (sc_err_t)result;
277 }
278
sc_pm_clock_enable(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_clk_t clk,sc_bool_t enable,sc_bool_t autog)279 sc_err_t sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource,
280 sc_pm_clk_t clk, sc_bool_t enable, sc_bool_t autog)
281 {
282 sc_rpc_msg_t msg;
283 uint8_t result;
284
285 RPC_VER(&msg) = SC_RPC_VERSION;
286 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
287 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_CLOCK_ENABLE;
288 RPC_U16(&msg, 0U) = (uint16_t)resource;
289 RPC_U8(&msg, 2U) = (uint8_t)clk;
290 RPC_U8(&msg, 3U) = (uint8_t)enable;
291 RPC_U8(&msg, 4U) = (uint8_t)autog;
292 RPC_SIZE(&msg) = 3U;
293
294 sc_call_rpc(ipc, &msg, SC_FALSE);
295
296 result = RPC_R8(&msg);
297 return (sc_err_t)result;
298 }
299
sc_pm_set_clock_parent(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_clk_t clk,sc_pm_clk_parent_t parent)300 sc_err_t sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
301 sc_pm_clk_t clk, sc_pm_clk_parent_t parent)
302 {
303 sc_rpc_msg_t msg;
304 uint8_t result;
305
306 RPC_VER(&msg) = SC_RPC_VERSION;
307 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
308 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CLOCK_PARENT;
309 RPC_U16(&msg, 0U) = (uint16_t)resource;
310 RPC_U8(&msg, 2U) = (uint8_t)clk;
311 RPC_U8(&msg, 3U) = (uint8_t)parent;
312 RPC_SIZE(&msg) = 2U;
313
314 sc_call_rpc(ipc, &msg, SC_FALSE);
315
316 result = RPC_R8(&msg);
317 return (sc_err_t)result;
318 }
319
sc_pm_get_clock_parent(sc_ipc_t ipc,sc_rsrc_t resource,sc_pm_clk_t clk,sc_pm_clk_parent_t * parent)320 sc_err_t sc_pm_get_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
321 sc_pm_clk_t clk, sc_pm_clk_parent_t *parent)
322 {
323 sc_rpc_msg_t msg;
324 uint8_t result;
325
326 RPC_VER(&msg) = SC_RPC_VERSION;
327 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
328 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_CLOCK_PARENT;
329 RPC_U16(&msg, 0U) = (uint16_t)resource;
330 RPC_U8(&msg, 2U) = (uint8_t)clk;
331 RPC_SIZE(&msg) = 2U;
332
333 sc_call_rpc(ipc, &msg, SC_FALSE);
334
335 result = RPC_R8(&msg);
336 if (parent != NULL) {
337 *parent = RPC_U8(&msg, 0U);
338 }
339
340 return (sc_err_t)result;
341 }
342
sc_pm_reset(sc_ipc_t ipc,sc_pm_reset_type_t type)343 sc_err_t sc_pm_reset(sc_ipc_t ipc, sc_pm_reset_type_t type)
344 {
345 sc_rpc_msg_t msg;
346 uint8_t result;
347
348 RPC_VER(&msg) = SC_RPC_VERSION;
349 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
350 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_RESET;
351 RPC_U8(&msg, 0U) = (uint8_t)type;
352 RPC_SIZE(&msg) = 2U;
353
354 sc_call_rpc(ipc, &msg, SC_FALSE);
355
356 result = RPC_R8(&msg);
357 return (sc_err_t)result;
358 }
359
sc_pm_reset_reason(sc_ipc_t ipc,sc_pm_reset_reason_t * reason)360 sc_err_t sc_pm_reset_reason(sc_ipc_t ipc, sc_pm_reset_reason_t *reason)
361 {
362 sc_rpc_msg_t msg;
363 uint8_t result;
364
365 RPC_VER(&msg) = SC_RPC_VERSION;
366 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
367 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_RESET_REASON;
368 RPC_SIZE(&msg) = 1U;
369
370 sc_call_rpc(ipc, &msg, SC_FALSE);
371
372 result = RPC_R8(&msg);
373 if (reason != NULL) {
374 *reason = RPC_U8(&msg, 0U);
375 }
376
377 return (sc_err_t)result;
378 }
379
sc_pm_boot(sc_ipc_t ipc,sc_rm_pt_t pt,sc_rsrc_t resource_cpu,sc_faddr_t boot_addr,sc_rsrc_t resource_mu,sc_rsrc_t resource_dev)380 sc_err_t sc_pm_boot(sc_ipc_t ipc, sc_rm_pt_t pt,
381 sc_rsrc_t resource_cpu, sc_faddr_t boot_addr,
382 sc_rsrc_t resource_mu, sc_rsrc_t resource_dev)
383 {
384 sc_rpc_msg_t msg;
385 uint8_t result;
386
387 RPC_VER(&msg) = SC_RPC_VERSION;
388 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
389 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_BOOT;
390 RPC_U32(&msg, 0U) = (uint32_t)(boot_addr >> 32U);
391 RPC_U32(&msg, 4U) = (uint32_t)boot_addr;
392 RPC_U16(&msg, 8U) = (uint16_t)resource_cpu;
393 RPC_U16(&msg, 10U) = (uint16_t)resource_mu;
394 RPC_U16(&msg, 12U) = (uint16_t)resource_dev;
395 RPC_U8(&msg, 14U) = (uint8_t)pt;
396 RPC_SIZE(&msg) = 5U;
397
398 sc_call_rpc(ipc, &msg, SC_FALSE);
399
400 result = RPC_R8(&msg);
401 return (sc_err_t)result;
402 }
403
sc_pm_reboot(sc_ipc_t ipc,sc_pm_reset_type_t type)404 void sc_pm_reboot(sc_ipc_t ipc, sc_pm_reset_type_t type)
405 {
406 sc_rpc_msg_t msg;
407
408 RPC_VER(&msg) = SC_RPC_VERSION;
409 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
410 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REBOOT;
411 RPC_U8(&msg, 0U) = (uint8_t)type;
412 RPC_SIZE(&msg) = 2U;
413
414 sc_call_rpc(ipc, &msg, SC_TRUE);
415
416 return;
417 }
418
sc_pm_reboot_partition(sc_ipc_t ipc,sc_rm_pt_t pt,sc_pm_reset_type_t type)419 sc_err_t sc_pm_reboot_partition(sc_ipc_t ipc, sc_rm_pt_t pt,
420 sc_pm_reset_type_t type)
421 {
422 sc_rpc_msg_t msg;
423 uint8_t result;
424
425 RPC_VER(&msg) = SC_RPC_VERSION;
426 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
427 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REBOOT_PARTITION;
428 RPC_U8(&msg, 0U) = (uint8_t)pt;
429 RPC_U8(&msg, 1U) = (uint8_t)type;
430 RPC_SIZE(&msg) = 2U;
431
432 sc_call_rpc(ipc, &msg, SC_FALSE);
433
434 result = RPC_R8(&msg);
435 return (sc_err_t)result;
436 }
437
sc_pm_cpu_start(sc_ipc_t ipc,sc_rsrc_t resource,sc_bool_t enable,sc_faddr_t address)438 sc_err_t sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
439 sc_faddr_t address)
440 {
441 sc_rpc_msg_t msg;
442 uint8_t result;
443
444 RPC_VER(&msg) = SC_RPC_VERSION;
445 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM;
446 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_CPU_START;
447 RPC_U32(&msg, 0U) = (uint32_t)(address >> 32U);
448 RPC_U32(&msg, 4U) = (uint32_t)address;
449 RPC_U16(&msg, 8U) = (uint16_t)resource;
450 RPC_U8(&msg, 10U) = (uint8_t)enable;
451 RPC_SIZE(&msg) = 4U;
452
453 sc_call_rpc(ipc, &msg, SC_FALSE);
454
455 result = RPC_R8(&msg);
456 return (sc_err_t)result;
457 }
458
459 /**@}*/
460