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