blob: b2fdeef13ab0d991941cc19acf4298ec60e11752 [file] [log] [blame]
Peng Fanad9d40a2018-10-18 14:28:12 +02001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2018 NXP
4 *
5 * Peng Fan <peng.fan@nxp.com>
6 */
7
8#include <common.h>
9#include <asm/io.h>
10#include <dm.h>
11#include <asm/arch/sci/sci.h>
12#include <misc.h>
13
14DECLARE_GLOBAL_DATA_PTR;
15
Peng Fan4d817552019-09-23 10:12:31 +000016#define B2U8(X) (((X) != SC_FALSE) ? (u8)(0x01U) : (u8)(0x00U))
17
Peng Fanad9d40a2018-10-18 14:28:12 +020018/* CLK and PM */
19int sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
20 sc_pm_clock_rate_t *rate)
21{
22 struct udevice *dev = gd->arch.scu_dev;
23 int size = sizeof(struct sc_rpc_msg_s);
24 struct sc_rpc_msg_s msg;
25 int ret;
26
27 RPC_VER(&msg) = SC_RPC_VERSION;
28 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
29 RPC_FUNC(&msg) = (u8)PM_FUNC_SET_CLOCK_RATE;
30 RPC_U32(&msg, 0U) = *(u32 *)rate;
31 RPC_U16(&msg, 4U) = (u16)resource;
32 RPC_U8(&msg, 6U) = (u8)clk;
33 RPC_SIZE(&msg) = 3U;
34
35 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
36 if (ret)
37 printf("%s: rate:%u resource:%u: clk:%u res:%d\n",
38 __func__, *rate, resource, clk, RPC_R8(&msg));
39
40 *rate = RPC_U32(&msg, 0U);
41
42 return ret;
43}
44
45int sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
46 sc_pm_clock_rate_t *rate)
47{
48 struct udevice *dev = gd->arch.scu_dev;
49 int size = sizeof(struct sc_rpc_msg_s);
50 struct sc_rpc_msg_s msg;
51 int ret;
52
53 RPC_VER(&msg) = SC_RPC_VERSION;
54 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
55 RPC_FUNC(&msg) = (u8)PM_FUNC_GET_CLOCK_RATE;
56 RPC_U16(&msg, 0U) = (u16)resource;
57 RPC_U8(&msg, 2U) = (u8)clk;
58 RPC_SIZE(&msg) = 2U;
59
60 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
61 if (ret) {
62 printf("%s: resource:%d clk:%d: res:%d\n",
63 __func__, resource, clk, RPC_R8(&msg));
64 return ret;
65 }
66
67 if (rate)
68 *rate = RPC_U32(&msg, 0U);
69
70 return 0;
71}
72
73int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
74 sc_bool_t enable, sc_bool_t autog)
75{
76 struct udevice *dev = gd->arch.scu_dev;
77 int size = sizeof(struct sc_rpc_msg_s);
78 struct sc_rpc_msg_s msg;
79 int ret;
80
81 RPC_VER(&msg) = SC_RPC_VERSION;
82 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
83 RPC_FUNC(&msg) = (u8)PM_FUNC_CLOCK_ENABLE;
84 RPC_U16(&msg, 0U) = (u16)resource;
85 RPC_U8(&msg, 2U) = (u8)clk;
86 RPC_U8(&msg, 3U) = (u8)enable;
87 RPC_U8(&msg, 4U) = (u8)autog;
88 RPC_SIZE(&msg) = 3U;
89
90 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
91 if (ret)
92 printf("%s: resource:%d clk:%d: enable:%d autog: %d, res:%d\n",
93 __func__, resource, clk, enable, autog, RPC_R8(&msg));
94
95 return ret;
96}
97
Peng Fan4d817552019-09-23 10:12:31 +000098int sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
99 sc_pm_clk_t clk, sc_pm_clk_parent_t parent)
100{
101 struct udevice *dev = gd->arch.scu_dev;
102 int size = sizeof(struct sc_rpc_msg_s);
103 struct sc_rpc_msg_s msg;
104 int ret;
105
106 RPC_VER(&msg) = SC_RPC_VERSION;
107 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
108 RPC_FUNC(&msg) = (u8)PM_FUNC_SET_CLOCK_PARENT;
109 RPC_U16(&msg, 0U) = (u16)resource;
110 RPC_U8(&msg, 2U) = (u8)clk;
111 RPC_U8(&msg, 3U) = (u8)parent;
112 RPC_SIZE(&msg) = 2U;
113
114 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
115 if (ret)
116 printf("%s: resource:%d clk:%d: parent clk: %d, res:%d\n",
117 __func__, resource, clk, parent, RPC_R8(&msg));
118
119 return ret;
120}
121
Peng Fanad9d40a2018-10-18 14:28:12 +0200122int sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
123 sc_pm_power_mode_t mode)
124{
125 struct udevice *dev = gd->arch.scu_dev;
126 int size = sizeof(struct sc_rpc_msg_s);
127 struct sc_rpc_msg_s msg;
128 int ret;
129
130 if (!dev)
131 hang();
132
133 RPC_VER(&msg) = SC_RPC_VERSION;
134 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
135 RPC_FUNC(&msg) = (u8)PM_FUNC_SET_RESOURCE_POWER_MODE;
136 RPC_U16(&msg, 0U) = (u16)resource;
137 RPC_U8(&msg, 2U) = (u8)mode;
138 RPC_SIZE(&msg) = 2U;
139
140 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
141 if (ret)
142 printf("%s: resource:%d mode:%d: res:%d\n",
143 __func__, resource, mode, RPC_R8(&msg));
144
145 return ret;
146}
147
Peng Fan8cacd782019-08-26 08:12:16 +0000148sc_bool_t sc_pm_is_partition_started(sc_ipc_t ipc, sc_rm_pt_t pt)
149{
150 struct udevice *dev = gd->arch.scu_dev;
151 int size = sizeof(struct sc_rpc_msg_s);
152 struct sc_rpc_msg_s msg;
153 int ret;
154 u8 result;
155
156 RPC_VER(&msg) = SC_RPC_VERSION;
157 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_PM);
158 RPC_FUNC(&msg) = (u8)(PM_FUNC_IS_PARTITION_STARTED);
159 RPC_U8(&msg, 0U) = (u8)(pt);
160 RPC_SIZE(&msg) = 2U;
161
162 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
163
164 result = RPC_R8(&msg);
165 if (result != 0 && result != 1) {
166 printf("%s: partition:%d res:%d\n",
167 __func__, pt, RPC_R8(&msg));
168 if (ret)
169 printf("%s: partition:%d res:%d\n", __func__, pt,
170 RPC_R8(&msg));
171 }
172 return !!result;
173}
174
Peng Fanad9d40a2018-10-18 14:28:12 +0200175/* PAD */
176int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val)
177{
178 struct udevice *dev = gd->arch.scu_dev;
179 int size = sizeof(struct sc_rpc_msg_s);
180 struct sc_rpc_msg_s msg;
181 int ret;
182
183 if (!dev)
184 hang();
185
186 RPC_VER(&msg) = SC_RPC_VERSION;
187 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PAD;
188 RPC_FUNC(&msg) = (u8)PAD_FUNC_SET;
189 RPC_U32(&msg, 0U) = (u32)val;
190 RPC_U16(&msg, 4U) = (u16)pad;
191 RPC_SIZE(&msg) = 3U;
192
193 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
194 if (ret)
195 printf("%s: val:%d pad:%d: res:%d\n",
196 __func__, val, pad, RPC_R8(&msg));
197
198 return ret;
199}
200
201/* MISC */
Peng Fan4d817552019-09-23 10:12:31 +0000202int sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
203 sc_ctrl_t ctrl, u32 val)
204{
205 struct udevice *dev = gd->arch.scu_dev;
206 int size = sizeof(struct sc_rpc_msg_s);
207 struct sc_rpc_msg_s msg;
208 int ret;
209
210 if (!dev)
211 hang();
212
213 RPC_VER(&msg) = SC_RPC_VERSION;
214 RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
215 RPC_FUNC(&msg) = (u8)MISC_FUNC_SET_CONTROL;
216 RPC_U32(&msg, 0U) = (u32)ctrl;
217 RPC_U32(&msg, 4U) = (u32)val;
218 RPC_U16(&msg, 8U) = (u16)resource;
219 RPC_SIZE(&msg) = 4U;
220
221 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
222 if (ret)
223 printf("%s: ctrl:%d resource:%d: res:%d\n",
224 __func__, ctrl, resource, RPC_R8(&msg));
225
226 return ret;
227}
228
Peng Fanad9d40a2018-10-18 14:28:12 +0200229int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
230 u32 *val)
231{
232 struct udevice *dev = gd->arch.scu_dev;
233 int size = sizeof(struct sc_rpc_msg_s);
234 struct sc_rpc_msg_s msg;
235 int ret;
236
237 if (!dev)
238 hang();
239
240 RPC_VER(&msg) = SC_RPC_VERSION;
241 RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
242 RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_CONTROL;
243 RPC_U32(&msg, 0U) = (u32)ctrl;
244 RPC_U16(&msg, 4U) = (u16)resource;
245 RPC_SIZE(&msg) = 3U;
246
247 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
248 if (ret)
249 printf("%s: ctrl:%d resource:%d: res:%d\n",
250 __func__, ctrl, resource, RPC_R8(&msg));
251
Peng Fanecab65e2018-12-15 12:19:49 +0000252 if (val)
Peng Fanad9d40a2018-10-18 14:28:12 +0200253 *val = RPC_U32(&msg, 0U);
254
255 return ret;
256}
257
Peng Fan4d817552019-09-23 10:12:31 +0000258int sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource, sc_rm_sid_t sid)
259{
260 struct udevice *dev = gd->arch.scu_dev;
261 struct sc_rpc_msg_s msg;
262 int size = sizeof(struct sc_rpc_msg_s);
263 int ret;
264
265 RPC_VER(&msg) = SC_RPC_VERSION;
266 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
267 RPC_FUNC(&msg) = (u8)RM_FUNC_SET_MASTER_SID;
268 RPC_U16(&msg, 0U) = (u16)resource;
269 RPC_U16(&msg, 2U) = (u16)sid;
270 RPC_SIZE(&msg) = 2U;
271
272 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
273 if (ret)
274 printf("%s: resource:%d sid:%d: res:%d\n",
275 __func__, resource, sid, RPC_R8(&msg));
276
277 return ret;
278}
279
Peng Fanad9d40a2018-10-18 14:28:12 +0200280void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev)
281{
282 struct udevice *dev = gd->arch.scu_dev;
283 int size = sizeof(struct sc_rpc_msg_s);
284 struct sc_rpc_msg_s msg;
285 int ret;
286
287 if (!dev)
288 hang();
289
290 RPC_VER(&msg) = SC_RPC_VERSION;
291 RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
292 RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_DEV;
293 RPC_SIZE(&msg) = 1U;
294
295 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
296 if (ret)
297 printf("%s: res:%d\n", __func__, RPC_R8(&msg));
298
Peng Fanecab65e2018-12-15 12:19:49 +0000299 if (boot_dev)
Peng Fanad9d40a2018-10-18 14:28:12 +0200300 *boot_dev = RPC_U16(&msg, 0U);
301}
302
303void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
304{
305 struct udevice *dev = gd->arch.scu_dev;
306 int size = sizeof(struct sc_rpc_msg_s);
307 struct sc_rpc_msg_s msg;
308 int ret;
309
310 if (!dev)
311 hang();
312
313 RPC_VER(&msg) = SC_RPC_VERSION;
314 RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
315 RPC_FUNC(&msg) = (u8)MISC_FUNC_BOOT_STATUS;
316 RPC_U8(&msg, 0U) = (u8)status;
317 RPC_SIZE(&msg) = 2U;
318
319 ret = misc_call(dev, SC_TRUE, &msg, size, &msg, size);
320 if (ret)
321 printf("%s: status:%d res:%d\n",
322 __func__, status, RPC_R8(&msg));
323}
324
325void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit)
326{
327 struct udevice *dev = gd->arch.scu_dev;
328 int size = sizeof(struct sc_rpc_msg_s);
329 struct sc_rpc_msg_s msg;
330 int ret;
331
332 if (!dev)
333 hang();
334
335 RPC_VER(&msg) = SC_RPC_VERSION;
336 RPC_SVC(&msg) = SC_RPC_SVC_MISC;
337 RPC_FUNC(&msg) = MISC_FUNC_BUILD_INFO;
338 RPC_SIZE(&msg) = 1;
339
340 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
341 if (ret < 0) {
342 printf("%s: err: %d\n", __func__, ret);
343 return;
344 }
345
346 if (build)
347 *build = RPC_U32(&msg, 0);
348 if (commit)
349 *commit = RPC_U32(&msg, 4);
350}
351
352int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val)
353{
354 struct udevice *dev = gd->arch.scu_dev;
355 int size = sizeof(struct sc_rpc_msg_s);
356 struct sc_rpc_msg_s msg;
357 int ret;
358
359 if (!dev)
360 hang();
361
362 RPC_VER(&msg) = SC_RPC_VERSION;
363 RPC_SVC(&msg) = SC_RPC_SVC_MISC;
364 RPC_FUNC(&msg) = MISC_FUNC_OTP_FUSE_READ;
365 RPC_U32(&msg, 0) = word;
366 RPC_SIZE(&msg) = 2;
367
368 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
369 if (ret < 0)
370 return ret;
371
372 if (val)
373 *val = RPC_U32(&msg, 0U);
374
375 return 0;
376}
377
Peng Fan7752a0f2019-05-05 13:23:51 +0000378int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,
379 s16 *celsius, s8 *tenths)
380{
381 struct udevice *dev = gd->arch.scu_dev;
382 int size = sizeof(struct sc_rpc_msg_s);
383 struct sc_rpc_msg_s msg;
384 int ret;
385
386 RPC_VER(&msg) = SC_RPC_VERSION;
387 RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
388 RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_TEMP;
389 RPC_U16(&msg, 0U) = (u16)resource;
390 RPC_U8(&msg, 2U) = (u8)temp;
391 RPC_SIZE(&msg) = 2U;
392
393 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
394 if (ret < 0)
395 return ret;
396
397 if (celsius)
398 *celsius = RPC_I16(&msg, 0U);
399
400 if (tenths)
401 *tenths = RPC_I8(&msg, 2U);
402
403 return 0;
404}
405
Peng Fanad9d40a2018-10-18 14:28:12 +0200406/* RM */
407sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
408{
409 struct udevice *dev = gd->arch.scu_dev;
410 int size = sizeof(struct sc_rpc_msg_s);
411 struct sc_rpc_msg_s msg;
412 int ret;
413 sc_err_t result;
414
415 if (!dev)
416 hang();
417
418 RPC_VER(&msg) = SC_RPC_VERSION;
419 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
420 RPC_FUNC(&msg) = (u8)RM_FUNC_IS_MEMREG_OWNED;
421 RPC_U8(&msg, 0U) = (u8)mr;
422 RPC_SIZE(&msg) = 2U;
423
424 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
425 result = RPC_R8(&msg);
426
427 if (result != 0 && result != 1) {
428 printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
429 if (ret)
430 printf("%s: mr:%d res:%d\n", __func__, mr,
431 RPC_R8(&msg));
432 }
433
434 return (sc_bool_t)result;
435}
436
Peng Fan4d817552019-09-23 10:12:31 +0000437int sc_rm_find_memreg(sc_ipc_t ipc, sc_rm_mr_t *mr, sc_faddr_t addr_start,
438 sc_faddr_t addr_end)
Peng Fan26864472019-08-26 08:12:03 +0000439{
440 struct udevice *dev = gd->arch.scu_dev;
Peng Fan26864472019-08-26 08:12:03 +0000441 int size = sizeof(struct sc_rpc_msg_s);
Peng Fan4d817552019-09-23 10:12:31 +0000442 struct sc_rpc_msg_s msg;
Peng Fan26864472019-08-26 08:12:03 +0000443 int ret;
444
Peng Fan4d817552019-09-23 10:12:31 +0000445 if (!dev)
446 hang();
447
Peng Fan26864472019-08-26 08:12:03 +0000448 RPC_VER(&msg) = SC_RPC_VERSION;
Peng Fan4d817552019-09-23 10:12:31 +0000449 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_RM);
450 RPC_FUNC(&msg) = (u8)(RM_FUNC_FIND_MEMREG);
451 RPC_U32(&msg, 0U) = (u32)(addr_start >> 32ULL);
452 RPC_U32(&msg, 4U) = (u32)(addr_start);
453 RPC_U32(&msg, 8U) = (u32)(addr_end >> 32ULL);
454 RPC_U32(&msg, 12U) = (u32)(addr_end);
455 RPC_SIZE(&msg) = 5U;
Peng Fan26864472019-08-26 08:12:03 +0000456
457 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
458 if (ret)
Peng Fan4d817552019-09-23 10:12:31 +0000459 printf("%s: start:0x%llx, end:0x%llx res:%d\n", __func__, addr_start, addr_end, RPC_R8(&msg));
460
461 if (mr)
462 *mr = RPC_U8(&msg, 0U);
463
464 return ret;
465}
466
467int sc_rm_set_memreg_permissions(sc_ipc_t ipc, sc_rm_mr_t mr,
468 sc_rm_pt_t pt, sc_rm_perm_t perm)
469{
470 struct udevice *dev = gd->arch.scu_dev;
471 int size = sizeof(struct sc_rpc_msg_s);
472 struct sc_rpc_msg_s msg;
473 int ret;
474
475 if (!dev)
476 hang();
477
478 RPC_VER(&msg) = SC_RPC_VERSION;
479 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_RM);
480 RPC_FUNC(&msg) = (u8)(RM_FUNC_SET_MEMREG_PERMISSIONS);
481 RPC_U8(&msg, 0U) = (u8)(mr);
482 RPC_U8(&msg, 1U) = (u8)(pt);
483 RPC_U8(&msg, 2U) = (u8)(perm);
484 RPC_SIZE(&msg) = 2U;
485
486 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
487 if (ret) {
488 printf("%s: mr:%u, pt:%u, perm:%u, res:%d\n", __func__,
489 mr, pt, perm, RPC_R8(&msg));
490 }
Peng Fan26864472019-08-26 08:12:03 +0000491
492 return ret;
493}
494
Peng Fanad9d40a2018-10-18 14:28:12 +0200495int sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr, sc_faddr_t *addr_start,
496 sc_faddr_t *addr_end)
497{
498 struct udevice *dev = gd->arch.scu_dev;
499 int size = sizeof(struct sc_rpc_msg_s);
500 struct sc_rpc_msg_s msg;
501 int ret;
502
503 if (!dev)
504 hang();
505
506 RPC_VER(&msg) = SC_RPC_VERSION;
507 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
508 RPC_FUNC(&msg) = (u8)RM_FUNC_GET_MEMREG_INFO;
509 RPC_U8(&msg, 0U) = (u8)mr;
510 RPC_SIZE(&msg) = 2U;
511
512 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
513 if (ret)
514 printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
515
516 if (addr_start)
517 *addr_start = ((u64)RPC_U32(&msg, 0U) << 32U) |
518 RPC_U32(&msg, 4U);
519
520 if (addr_end)
521 *addr_end = ((u64)RPC_U32(&msg, 8U) << 32U) |
522 RPC_U32(&msg, 12U);
523
524 return ret;
525}
526
527sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource)
528{
529 struct udevice *dev = gd->arch.scu_dev;
530 int size = sizeof(struct sc_rpc_msg_s);
531 struct sc_rpc_msg_s msg;
532 int ret;
533 u8 result;
534
535 if (!dev)
536 hang();
537
538 RPC_VER(&msg) = SC_RPC_VERSION;
539 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
540 RPC_FUNC(&msg) = (u8)RM_FUNC_IS_RESOURCE_OWNED;
541 RPC_U16(&msg, 0U) = (u16)resource;
542 RPC_SIZE(&msg) = 2U;
543
544 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
545 result = RPC_R8(&msg);
546 if (result != 0 && result != 1) {
547 printf("%s: resource:%d res:%d\n",
548 __func__, resource, RPC_R8(&msg));
549 if (ret)
550 printf("%s: res:%d res:%d\n", __func__, resource,
551 RPC_R8(&msg));
552 }
553
554 return !!result;
555}
Peng Fan4d817552019-09-23 10:12:31 +0000556
557int sc_rm_partition_alloc(sc_ipc_t ipc, sc_rm_pt_t *pt, sc_bool_t secure,
558 sc_bool_t isolated, sc_bool_t restricted,
559 sc_bool_t grant, sc_bool_t coherent)
560{
561 struct udevice *dev = gd->arch.scu_dev;
562 struct sc_rpc_msg_s msg;
563 int size = sizeof(struct sc_rpc_msg_s);
564 int ret;
565
566 RPC_VER(&msg) = SC_RPC_VERSION;
567 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
568 RPC_FUNC(&msg) = (u8)RM_FUNC_PARTITION_ALLOC;
569 RPC_U8(&msg, 0U) = B2U8(secure);
570 RPC_U8(&msg, 1U) = B2U8(isolated);
571 RPC_U8(&msg, 2U) = B2U8(restricted);
572 RPC_U8(&msg, 3U) = B2U8(grant);
573 RPC_U8(&msg, 4U) = B2U8(coherent);
574 RPC_SIZE(&msg) = 3U;
575
576 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
577 if (ret) {
578 printf("%s: secure:%u isolated:%u restricted:%u grant:%u coherent:%u res:%d\n",
579 __func__, secure, isolated, restricted, grant, coherent,
580 RPC_R8(&msg));
581 }
582
583 if (pt)
584 *pt = RPC_U8(&msg, 0U);
585
586 return ret;
587}
588
589int sc_rm_partition_free(sc_ipc_t ipc, sc_rm_pt_t pt)
590{
591 struct udevice *dev = gd->arch.scu_dev;
592 struct sc_rpc_msg_s msg;
593 int size = sizeof(struct sc_rpc_msg_s);
594 int ret;
595
596 RPC_VER(&msg) = SC_RPC_VERSION;
597 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
598 RPC_FUNC(&msg) = (u8)RM_FUNC_PARTITION_FREE;
599 RPC_U8(&msg, 0U) = (u8)pt;
600 RPC_SIZE(&msg) = 2U;
601
602 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
603 if (ret) {
604 printf("%s: pt:%u res:%d\n",
605 __func__, pt, RPC_R8(&msg));
606 }
607
608 return ret;
609}
610
611int sc_rm_get_partition(sc_ipc_t ipc, sc_rm_pt_t *pt)
612{
613 struct udevice *dev = gd->arch.scu_dev;
614 struct sc_rpc_msg_s msg;
615 int size = sizeof(struct sc_rpc_msg_s);
616 int ret;
617
618 RPC_VER(&msg) = SC_RPC_VERSION;
619 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
620 RPC_FUNC(&msg) = (u8)RM_FUNC_GET_PARTITION;
621 RPC_SIZE(&msg) = 1U;
622
623 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
624 if (ret)
625 printf("%s: res:%d\n", __func__, RPC_R8(&msg));
626
627 if (pt)
628 *pt = RPC_U8(&msg, 0U);
629
630 return ret;
631}
632
633int sc_rm_set_parent(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_pt_t pt_parent)
634{
635 struct udevice *dev = gd->arch.scu_dev;
636 struct sc_rpc_msg_s msg;
637 int size = sizeof(struct sc_rpc_msg_s);
638 int ret;
639
640 RPC_VER(&msg) = SC_RPC_VERSION;
641 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
642 RPC_FUNC(&msg) = (u8)RM_FUNC_SET_PARENT;
643 RPC_U8(&msg, 0U) = (u8)pt;
644 RPC_U8(&msg, 1U) = (u8)pt_parent;
645 RPC_SIZE(&msg) = 2U;
646
647 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
648 if (ret) {
649 printf("%s: pt:%u, pt_parent:%u, res:%d\n",
650 __func__, pt, pt_parent, RPC_R8(&msg));
651 }
652
653 return ret;
654}
655
656int sc_rm_assign_resource(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rsrc_t resource)
657{
658 struct udevice *dev = gd->arch.scu_dev;
659 struct sc_rpc_msg_s msg;
660 int size = sizeof(struct sc_rpc_msg_s);
661 int ret;
662
663 RPC_VER(&msg) = SC_RPC_VERSION;
664 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
665 RPC_FUNC(&msg) = (u8)RM_FUNC_ASSIGN_RESOURCE;
666 RPC_U16(&msg, 0U) = (u16)resource;
667 RPC_U8(&msg, 2U) = (u8)pt;
668 RPC_SIZE(&msg) = 2U;
669
670 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
671 if (ret) {
672 printf("%s: pt:%u, resource:%u, res:%d\n",
673 __func__, pt, resource, RPC_R8(&msg));
674 }
675
676 return ret;
677}
678
679int sc_rm_assign_pad(sc_ipc_t ipc, sc_rm_pt_t pt, sc_pad_t pad)
680{
681 struct udevice *dev = gd->arch.scu_dev;
682 struct sc_rpc_msg_s msg;
683 int size = sizeof(struct sc_rpc_msg_s);
684 int ret;
685
686 RPC_VER(&msg) = SC_RPC_VERSION;
687 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
688 RPC_FUNC(&msg) = (u8)RM_FUNC_ASSIGN_PAD;
689 RPC_U16(&msg, 0U) = (u16)pad;
690 RPC_U8(&msg, 2U) = (u8)pt;
691 RPC_SIZE(&msg) = 2U;
692
693 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
694 if (ret) {
695 printf("%s: pt:%u, pad:%u, res:%d\n",
696 __func__, pt, pad, RPC_R8(&msg));
697 }
698
699 return ret;
700}
701
702sc_bool_t sc_rm_is_pad_owned(sc_ipc_t ipc, sc_pad_t pad)
703{
704 struct udevice *dev = gd->arch.scu_dev;
705 struct sc_rpc_msg_s msg;
706 int size = sizeof(struct sc_rpc_msg_s);
707 int ret;
708 u8 result;
709
710 RPC_VER(&msg) = SC_RPC_VERSION;
711 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
712 RPC_FUNC(&msg) = (u8)RM_FUNC_IS_PAD_OWNED;
713 RPC_U8(&msg, 0U) = (u8)pad;
714 RPC_SIZE(&msg) = 2U;
715
716 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
717 result = RPC_R8(&msg);
718 if (result != 0 && result != 1) {
719 printf("%s: pad:%d res:%d\n", __func__, pad, RPC_R8(&msg));
720 if (ret) {
721 printf("%s: pad:%d res:%d\n", __func__,
722 pad, RPC_R8(&msg));
723 }
724 }
725
726 return !!result;
727}
728
729int sc_rm_get_resource_owner(sc_ipc_t ipc, sc_rsrc_t resource,
730 sc_rm_pt_t *pt)
731{
732 struct udevice *dev = gd->arch.scu_dev;
733 struct sc_rpc_msg_s msg;
734 int size = sizeof(struct sc_rpc_msg_s);
735 int ret;
736
737 RPC_VER(&msg) = SC_RPC_VERSION;
738 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
739 RPC_FUNC(&msg) = (u8)RM_FUNC_GET_RESOURCE_OWNER;
740 RPC_U16(&msg, 0U) = (u16)resource;
741 RPC_SIZE(&msg) = 2U;
742
743 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
744 if (pt)
745 *pt = RPC_U8(&msg, 0U);
746
747 return ret;
748}
749
750int sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
751 sc_faddr_t address)
752{
753 struct udevice *dev = gd->arch.scu_dev;
754 struct sc_rpc_msg_s msg;
755 int size = sizeof(struct sc_rpc_msg_s);
756 int ret;
757
758 RPC_VER(&msg) = SC_RPC_VERSION;
759 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
760 RPC_FUNC(&msg) = (u8)PM_FUNC_CPU_START;
761 RPC_U32(&msg, 0U) = (u32)(address >> 32ULL);
762 RPC_U32(&msg, 4U) = (u32)address;
763 RPC_U16(&msg, 8U) = (u16)resource;
764 RPC_U8(&msg, 10U) = B2U8(enable);
765 RPC_SIZE(&msg) = 4U;
766
767 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
768 if (ret) {
769 printf("%s: resource:%d address:0x%llx: res:%d\n",
770 __func__, resource, address, RPC_R8(&msg));
771 }
772
773 return ret;
774}
775
776int sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
777 sc_pm_power_mode_t *mode)
778{
779 struct udevice *dev = gd->arch.scu_dev;
780 struct sc_rpc_msg_s msg;
781 int size = sizeof(struct sc_rpc_msg_s);
782 int ret;
783
784 RPC_VER(&msg) = SC_RPC_VERSION;
785 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
786 RPC_FUNC(&msg) = (u8)PM_FUNC_GET_RESOURCE_POWER_MODE;
787 RPC_U16(&msg, 0U) = (u16)resource;
788 RPC_SIZE(&msg) = 2U;
789
790 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
791 if (ret) {
792 printf("%s: resource:%d: res:%d\n",
793 __func__, resource, RPC_R8(&msg));
794 }
795
796 if (mode)
797 *mode = RPC_U8(&msg, 0U);
798
799 return ret;
800}
801
802int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd,
803 sc_faddr_t addr)
804{
805 struct udevice *dev = gd->arch.scu_dev;
806 struct sc_rpc_msg_s msg;
807 int size = sizeof(struct sc_rpc_msg_s);
808 int ret;
809
810 RPC_VER(&msg) = SC_RPC_VERSION;
811 RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
812 RPC_FUNC(&msg) = (u8)SECO_FUNC_AUTHENTICATE;
813 RPC_U32(&msg, 0U) = (u32)(addr >> 32ULL);
814 RPC_U32(&msg, 4U) = (u32)addr;
815 RPC_U8(&msg, 8U) = (u8)cmd;
816 RPC_SIZE(&msg) = 4U;
817
818 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
819 if (ret)
820 printf("%s: res:%d\n", __func__, RPC_R8(&msg));
821
822 return ret;
823}
824
825int sc_seco_forward_lifecycle(sc_ipc_t ipc, u32 change)
826{
827 struct udevice *dev = gd->arch.scu_dev;
828 struct sc_rpc_msg_s msg;
829 int size = sizeof(struct sc_rpc_msg_s);
830 int ret;
831
832 RPC_VER(&msg) = SC_RPC_VERSION;
833 RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
834 RPC_FUNC(&msg) = (u8)SECO_FUNC_FORWARD_LIFECYCLE;
835 RPC_U32(&msg, 0U) = (u32)change;
836 RPC_SIZE(&msg) = 2U;
837
838 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
839 if (ret) {
840 printf("%s: change:%u, res:%d\n", __func__,
841 change, RPC_R8(&msg));
842 }
843
844 return ret;
845}
846
847int sc_seco_chip_info(sc_ipc_t ipc, u16 *lc, u16 *monotonic, u32 *uid_l,
848 u32 *uid_h)
849{
850 struct udevice *dev = gd->arch.scu_dev;
851 struct sc_rpc_msg_s msg;
852 int size = sizeof(struct sc_rpc_msg_s);
853 int ret;
854
855 RPC_VER(&msg) = SC_RPC_VERSION;
856 RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
857 RPC_FUNC(&msg) = (u8)SECO_FUNC_CHIP_INFO;
858 RPC_SIZE(&msg) = 1U;
859
860 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
861 if (ret)
862 printf("%s: res:%d\n", __func__, RPC_R8(&msg));
863
864 if (uid_l)
865 *uid_l = RPC_U32(&msg, 0U);
866
867 if (uid_h)
868 *uid_h = RPC_U32(&msg, 4U);
869
870 if (lc)
871 *lc = RPC_U16(&msg, 8U);
872
873 if (monotonic)
874 *monotonic = RPC_U16(&msg, 10U);
875
876 return ret;
877}
878
879void sc_seco_build_info(sc_ipc_t ipc, u32 *version, u32 *commit)
880{
881 struct udevice *dev = gd->arch.scu_dev;
882 struct sc_rpc_msg_s msg;
883 int size = sizeof(struct sc_rpc_msg_s);
884
885 RPC_VER(&msg) = SC_RPC_VERSION;
886 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO);
887 RPC_FUNC(&msg) = (u8)(SECO_FUNC_BUILD_INFO);
888 RPC_SIZE(&msg) = 1U;
889
890 misc_call(dev, SC_FALSE, &msg, size, &msg, size);
891
892 if (version)
893 *version = RPC_U32(&msg, 0U);
894
895 if (commit)
896 *commit = RPC_U32(&msg, 4U);
897}
898
899int sc_seco_get_event(sc_ipc_t ipc, u8 idx, u32 *event)
900{
901 struct udevice *dev = gd->arch.scu_dev;
902 struct sc_rpc_msg_s msg;
903 int size = sizeof(struct sc_rpc_msg_s);
904 int ret;
905
906 RPC_VER(&msg) = SC_RPC_VERSION;
907 RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
908 RPC_FUNC(&msg) = (u8)SECO_FUNC_GET_EVENT;
909 RPC_U8(&msg, 0U) = (u8)idx;
910 RPC_SIZE(&msg) = 2U;
911
912 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
913 if (ret)
914 printf("%s: idx: %u, res:%d\n", __func__, idx, RPC_R8(&msg));
915
916 if (event)
917 *event = RPC_U32(&msg, 0U);
918
919 return ret;
920}
921
922int sc_seco_gen_key_blob(sc_ipc_t ipc, u32 id, sc_faddr_t load_addr,
923 sc_faddr_t export_addr, u16 max_size)
924{
925 struct udevice *dev = gd->arch.scu_dev;
926 struct sc_rpc_msg_s msg;
927 int size = sizeof(struct sc_rpc_msg_s);
928 int ret;
929
930 RPC_VER(&msg) = SC_RPC_VERSION;
931 RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
932 RPC_FUNC(&msg) = (u8)SECO_FUNC_GEN_KEY_BLOB;
933 RPC_U32(&msg, 0U) = (u32)(load_addr >> 32ULL);
934 RPC_U32(&msg, 4U) = (u32)load_addr;
935 RPC_U32(&msg, 8U) = (u32)(export_addr >> 32ULL);
936 RPC_U32(&msg, 12U) = (u32)export_addr;
937 RPC_U32(&msg, 16U) = (u32)id;
938 RPC_U16(&msg, 20U) = (u16)max_size;
939 RPC_SIZE(&msg) = 7U;
940
941 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
942 if (ret) {
943 printf("%s: id: %u, load_addr 0x%llx, export_addr 0x%llx, res:%d\n",
944 __func__, id, load_addr, export_addr, RPC_R8(&msg));
945 }
946
947 return ret;
948}