blob: 66a57a13d52f596b2711a6aca8c55559c2037fc2 [file] [log] [blame]
Anson Huangb6294132018-06-05 16:05:59 +08001/*
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
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000017#include <stdlib.h>
18
Anson Huangb6294132018-06-05 16:05:59 +080019#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>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000023
Anson Huangb6294132018-06-05 16:05:59 +080024#include "sci_pm_rpc.h"
25
26/* Local Defines */
27
28/* Local Types */
29
30/* Local Functions */
31
32sc_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
49sc_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
68sc_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
90sc_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
109sc_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
131sc_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
150sc_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
171sc_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
191sc_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
212sc_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
235sc_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
256sc_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
279sc_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
300sc_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
320sc_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
343sc_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
360sc_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
380sc_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
404void 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
419sc_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
438sc_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/**@}*/