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