blob: 227bc5287374122504fe465f36d7280361933b01 [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
Ye Li24b5dae2019-11-13 21:20:43 -0800177int sc_pm_resource_reset(sc_ipc_t ipc, sc_rsrc_t resource)
178{
179 struct udevice *dev = gd->arch.scu_dev;
180 int size = sizeof(struct sc_rpc_msg_s);
181 struct sc_rpc_msg_s msg;
182 int ret;
183
184 RPC_VER(&msg) = SC_RPC_VERSION;
185 RPC_SIZE(&msg) = 2U;
186 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_PM);
187 RPC_FUNC(&msg) = (u8)(PM_FUNC_RESOURCE_RESET);
188
189 RPC_U16(&msg, 0U) = (u16)(resource);
190
191 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
192 if (ret)
193 printf("%s: resource:%d res:%d\n",
194 __func__, resource, RPC_R8(&msg));
195
196 return ret;
197}
198
Peng Fan55486382018-10-18 14:28:12 +0200199/* PAD */
200int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val)
201{
202 struct udevice *dev = gd->arch.scu_dev;
203 int size = sizeof(struct sc_rpc_msg_s);
204 struct sc_rpc_msg_s msg;
205 int ret;
206
207 if (!dev)
208 hang();
209
210 RPC_VER(&msg) = SC_RPC_VERSION;
211 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PAD;
212 RPC_FUNC(&msg) = (u8)PAD_FUNC_SET;
213 RPC_U32(&msg, 0U) = (u32)val;
214 RPC_U16(&msg, 4U) = (u16)pad;
215 RPC_SIZE(&msg) = 3U;
216
217 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
218 if (ret)
219 printf("%s: val:%d pad:%d: res:%d\n",
220 __func__, val, pad, RPC_R8(&msg));
221
222 return ret;
223}
224
225/* MISC */
Peng Fand4191db2019-09-23 10:12:31 +0000226int sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
227 sc_ctrl_t ctrl, u32 val)
228{
229 struct udevice *dev = gd->arch.scu_dev;
230 int size = sizeof(struct sc_rpc_msg_s);
231 struct sc_rpc_msg_s msg;
232 int ret;
233
234 if (!dev)
235 hang();
236
237 RPC_VER(&msg) = SC_RPC_VERSION;
238 RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
239 RPC_FUNC(&msg) = (u8)MISC_FUNC_SET_CONTROL;
240 RPC_U32(&msg, 0U) = (u32)ctrl;
241 RPC_U32(&msg, 4U) = (u32)val;
242 RPC_U16(&msg, 8U) = (u16)resource;
243 RPC_SIZE(&msg) = 4U;
244
245 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
246 if (ret)
247 printf("%s: ctrl:%d resource:%d: res:%d\n",
248 __func__, ctrl, resource, RPC_R8(&msg));
249
250 return ret;
251}
252
Peng Fan55486382018-10-18 14:28:12 +0200253int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
254 u32 *val)
255{
256 struct udevice *dev = gd->arch.scu_dev;
257 int size = sizeof(struct sc_rpc_msg_s);
258 struct sc_rpc_msg_s msg;
259 int ret;
260
261 if (!dev)
262 hang();
263
264 RPC_VER(&msg) = SC_RPC_VERSION;
265 RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
266 RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_CONTROL;
267 RPC_U32(&msg, 0U) = (u32)ctrl;
268 RPC_U16(&msg, 4U) = (u16)resource;
269 RPC_SIZE(&msg) = 3U;
270
271 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
272 if (ret)
273 printf("%s: ctrl:%d resource:%d: res:%d\n",
274 __func__, ctrl, resource, RPC_R8(&msg));
275
Peng Fan927a3dc2018-12-15 12:19:49 +0000276 if (val)
Peng Fan55486382018-10-18 14:28:12 +0200277 *val = RPC_U32(&msg, 0U);
278
279 return ret;
280}
281
Peng Fand4191db2019-09-23 10:12:31 +0000282int sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource, sc_rm_sid_t sid)
283{
284 struct udevice *dev = gd->arch.scu_dev;
285 struct sc_rpc_msg_s msg;
286 int size = sizeof(struct sc_rpc_msg_s);
287 int ret;
288
289 RPC_VER(&msg) = SC_RPC_VERSION;
290 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
291 RPC_FUNC(&msg) = (u8)RM_FUNC_SET_MASTER_SID;
292 RPC_U16(&msg, 0U) = (u16)resource;
293 RPC_U16(&msg, 2U) = (u16)sid;
294 RPC_SIZE(&msg) = 2U;
295
296 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
297 if (ret)
298 printf("%s: resource:%d sid:%d: res:%d\n",
299 __func__, resource, sid, RPC_R8(&msg));
300
301 return ret;
302}
303
Peng Fan55486382018-10-18 14:28:12 +0200304void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev)
305{
306 struct udevice *dev = gd->arch.scu_dev;
307 int size = sizeof(struct sc_rpc_msg_s);
308 struct sc_rpc_msg_s msg;
309 int ret;
310
311 if (!dev)
312 hang();
313
314 RPC_VER(&msg) = SC_RPC_VERSION;
315 RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
316 RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_DEV;
317 RPC_SIZE(&msg) = 1U;
318
319 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
320 if (ret)
321 printf("%s: res:%d\n", __func__, RPC_R8(&msg));
322
Peng Fan927a3dc2018-12-15 12:19:49 +0000323 if (boot_dev)
Peng Fan55486382018-10-18 14:28:12 +0200324 *boot_dev = RPC_U16(&msg, 0U);
325}
326
327void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
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) = (u8)SC_RPC_SVC_MISC;
339 RPC_FUNC(&msg) = (u8)MISC_FUNC_BOOT_STATUS;
340 RPC_U8(&msg, 0U) = (u8)status;
341 RPC_SIZE(&msg) = 2U;
342
343 ret = misc_call(dev, SC_TRUE, &msg, size, &msg, size);
344 if (ret)
345 printf("%s: status:%d res:%d\n",
346 __func__, status, RPC_R8(&msg));
347}
348
349void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit)
350{
351 struct udevice *dev = gd->arch.scu_dev;
352 int size = sizeof(struct sc_rpc_msg_s);
353 struct sc_rpc_msg_s msg;
354 int ret;
355
356 if (!dev)
357 hang();
358
359 RPC_VER(&msg) = SC_RPC_VERSION;
360 RPC_SVC(&msg) = SC_RPC_SVC_MISC;
361 RPC_FUNC(&msg) = MISC_FUNC_BUILD_INFO;
362 RPC_SIZE(&msg) = 1;
363
364 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
365 if (ret < 0) {
366 printf("%s: err: %d\n", __func__, ret);
367 return;
368 }
369
370 if (build)
371 *build = RPC_U32(&msg, 0);
372 if (commit)
373 *commit = RPC_U32(&msg, 4);
374}
375
376int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val)
377{
378 struct udevice *dev = gd->arch.scu_dev;
379 int size = sizeof(struct sc_rpc_msg_s);
380 struct sc_rpc_msg_s msg;
381 int ret;
382
383 if (!dev)
384 hang();
385
386 RPC_VER(&msg) = SC_RPC_VERSION;
387 RPC_SVC(&msg) = SC_RPC_SVC_MISC;
388 RPC_FUNC(&msg) = MISC_FUNC_OTP_FUSE_READ;
389 RPC_U32(&msg, 0) = word;
390 RPC_SIZE(&msg) = 2;
391
392 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
393 if (ret < 0)
394 return ret;
395
396 if (val)
397 *val = RPC_U32(&msg, 0U);
398
399 return 0;
400}
401
Peng Fanba44e012019-05-05 13:23:51 +0000402int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,
403 s16 *celsius, s8 *tenths)
404{
405 struct udevice *dev = gd->arch.scu_dev;
406 int size = sizeof(struct sc_rpc_msg_s);
407 struct sc_rpc_msg_s msg;
408 int ret;
409
410 RPC_VER(&msg) = SC_RPC_VERSION;
411 RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
412 RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_TEMP;
413 RPC_U16(&msg, 0U) = (u16)resource;
414 RPC_U8(&msg, 2U) = (u8)temp;
415 RPC_SIZE(&msg) = 2U;
416
417 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
418 if (ret < 0)
419 return ret;
420
421 if (celsius)
422 *celsius = RPC_I16(&msg, 0U);
423
424 if (tenths)
425 *tenths = RPC_I8(&msg, 2U);
426
427 return 0;
428}
429
Peng Fan55486382018-10-18 14:28:12 +0200430/* RM */
431sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
432{
433 struct udevice *dev = gd->arch.scu_dev;
434 int size = sizeof(struct sc_rpc_msg_s);
435 struct sc_rpc_msg_s msg;
436 int ret;
437 sc_err_t result;
438
439 if (!dev)
440 hang();
441
442 RPC_VER(&msg) = SC_RPC_VERSION;
443 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
444 RPC_FUNC(&msg) = (u8)RM_FUNC_IS_MEMREG_OWNED;
445 RPC_U8(&msg, 0U) = (u8)mr;
446 RPC_SIZE(&msg) = 2U;
447
448 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
449 result = RPC_R8(&msg);
450
451 if (result != 0 && result != 1) {
452 printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
453 if (ret)
454 printf("%s: mr:%d res:%d\n", __func__, mr,
455 RPC_R8(&msg));
456 }
457
458 return (sc_bool_t)result;
459}
460
Peng Fand4191db2019-09-23 10:12:31 +0000461int sc_rm_find_memreg(sc_ipc_t ipc, sc_rm_mr_t *mr, sc_faddr_t addr_start,
462 sc_faddr_t addr_end)
Peng Fanb612a302019-08-26 08:12:03 +0000463{
464 struct udevice *dev = gd->arch.scu_dev;
Peng Fand4191db2019-09-23 10:12:31 +0000465 int size = sizeof(struct sc_rpc_msg_s);
Peng Fanb612a302019-08-26 08:12:03 +0000466 struct sc_rpc_msg_s msg;
Peng Fand4191db2019-09-23 10:12:31 +0000467 int ret;
468
469 if (!dev)
470 hang();
471
472 RPC_VER(&msg) = SC_RPC_VERSION;
473 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_RM);
474 RPC_FUNC(&msg) = (u8)(RM_FUNC_FIND_MEMREG);
475 RPC_U32(&msg, 0U) = (u32)(addr_start >> 32ULL);
476 RPC_U32(&msg, 4U) = (u32)(addr_start);
477 RPC_U32(&msg, 8U) = (u32)(addr_end >> 32ULL);
478 RPC_U32(&msg, 12U) = (u32)(addr_end);
479 RPC_SIZE(&msg) = 5U;
480
481 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
482 if (ret)
483 printf("%s: start:0x%llx, end:0x%llx res:%d\n", __func__, addr_start, addr_end, RPC_R8(&msg));
484
485 if (mr)
486 *mr = RPC_U8(&msg, 0U);
487
488 return ret;
489}
490
491int sc_rm_set_memreg_permissions(sc_ipc_t ipc, sc_rm_mr_t mr,
492 sc_rm_pt_t pt, sc_rm_perm_t perm)
493{
494 struct udevice *dev = gd->arch.scu_dev;
Peng Fanb612a302019-08-26 08:12:03 +0000495 int size = sizeof(struct sc_rpc_msg_s);
Peng Fand4191db2019-09-23 10:12:31 +0000496 struct sc_rpc_msg_s msg;
Peng Fanb612a302019-08-26 08:12:03 +0000497 int ret;
498
Peng Fand4191db2019-09-23 10:12:31 +0000499 if (!dev)
500 hang();
501
Peng Fanb612a302019-08-26 08:12:03 +0000502 RPC_VER(&msg) = SC_RPC_VERSION;
Peng Fand4191db2019-09-23 10:12:31 +0000503 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_RM);
504 RPC_FUNC(&msg) = (u8)(RM_FUNC_SET_MEMREG_PERMISSIONS);
505 RPC_U8(&msg, 0U) = (u8)(mr);
506 RPC_U8(&msg, 1U) = (u8)(pt);
507 RPC_U8(&msg, 2U) = (u8)(perm);
Peng Fanb612a302019-08-26 08:12:03 +0000508 RPC_SIZE(&msg) = 2U;
509
510 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
Peng Fand4191db2019-09-23 10:12:31 +0000511 if (ret) {
512 printf("%s: mr:%u, pt:%u, perm:%u, res:%d\n", __func__,
513 mr, pt, perm, RPC_R8(&msg));
514 }
Peng Fanb612a302019-08-26 08:12:03 +0000515
516 return ret;
517}
518
Peng Fan55486382018-10-18 14:28:12 +0200519int sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr, sc_faddr_t *addr_start,
520 sc_faddr_t *addr_end)
521{
522 struct udevice *dev = gd->arch.scu_dev;
523 int size = sizeof(struct sc_rpc_msg_s);
524 struct sc_rpc_msg_s msg;
525 int ret;
526
527 if (!dev)
528 hang();
529
530 RPC_VER(&msg) = SC_RPC_VERSION;
531 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
532 RPC_FUNC(&msg) = (u8)RM_FUNC_GET_MEMREG_INFO;
533 RPC_U8(&msg, 0U) = (u8)mr;
534 RPC_SIZE(&msg) = 2U;
535
536 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
537 if (ret)
538 printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
539
540 if (addr_start)
541 *addr_start = ((u64)RPC_U32(&msg, 0U) << 32U) |
542 RPC_U32(&msg, 4U);
543
544 if (addr_end)
545 *addr_end = ((u64)RPC_U32(&msg, 8U) << 32U) |
546 RPC_U32(&msg, 12U);
547
548 return ret;
549}
550
551sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource)
552{
553 struct udevice *dev = gd->arch.scu_dev;
554 int size = sizeof(struct sc_rpc_msg_s);
555 struct sc_rpc_msg_s msg;
556 int ret;
557 u8 result;
558
559 if (!dev)
560 hang();
561
562 RPC_VER(&msg) = SC_RPC_VERSION;
563 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
564 RPC_FUNC(&msg) = (u8)RM_FUNC_IS_RESOURCE_OWNED;
565 RPC_U16(&msg, 0U) = (u16)resource;
566 RPC_SIZE(&msg) = 2U;
567
568 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
569 result = RPC_R8(&msg);
570 if (result != 0 && result != 1) {
571 printf("%s: resource:%d res:%d\n",
572 __func__, resource, RPC_R8(&msg));
573 if (ret)
574 printf("%s: res:%d res:%d\n", __func__, resource,
575 RPC_R8(&msg));
576 }
577
578 return !!result;
579}
Peng Fand4191db2019-09-23 10:12:31 +0000580
581int sc_rm_partition_alloc(sc_ipc_t ipc, sc_rm_pt_t *pt, sc_bool_t secure,
582 sc_bool_t isolated, sc_bool_t restricted,
583 sc_bool_t grant, sc_bool_t coherent)
584{
585 struct udevice *dev = gd->arch.scu_dev;
586 struct sc_rpc_msg_s msg;
587 int size = sizeof(struct sc_rpc_msg_s);
588 int ret;
589
590 RPC_VER(&msg) = SC_RPC_VERSION;
591 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
592 RPC_FUNC(&msg) = (u8)RM_FUNC_PARTITION_ALLOC;
593 RPC_U8(&msg, 0U) = B2U8(secure);
594 RPC_U8(&msg, 1U) = B2U8(isolated);
595 RPC_U8(&msg, 2U) = B2U8(restricted);
596 RPC_U8(&msg, 3U) = B2U8(grant);
597 RPC_U8(&msg, 4U) = B2U8(coherent);
598 RPC_SIZE(&msg) = 3U;
599
600 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
601 if (ret) {
602 printf("%s: secure:%u isolated:%u restricted:%u grant:%u coherent:%u res:%d\n",
603 __func__, secure, isolated, restricted, grant, coherent,
604 RPC_R8(&msg));
605 }
606
607 if (pt)
608 *pt = RPC_U8(&msg, 0U);
609
610 return ret;
611}
612
613int sc_rm_partition_free(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_PARTITION_FREE;
623 RPC_U8(&msg, 0U) = (u8)pt;
624 RPC_SIZE(&msg) = 2U;
625
626 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
627 if (ret) {
628 printf("%s: pt:%u res:%d\n",
629 __func__, pt, RPC_R8(&msg));
630 }
631
632 return ret;
633}
634
635int sc_rm_get_partition(sc_ipc_t ipc, sc_rm_pt_t *pt)
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_GET_PARTITION;
645 RPC_SIZE(&msg) = 1U;
646
647 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
648 if (ret)
649 printf("%s: res:%d\n", __func__, RPC_R8(&msg));
650
651 if (pt)
652 *pt = RPC_U8(&msg, 0U);
653
654 return ret;
655}
656
657int sc_rm_set_parent(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_pt_t pt_parent)
658{
659 struct udevice *dev = gd->arch.scu_dev;
660 struct sc_rpc_msg_s msg;
661 int size = sizeof(struct sc_rpc_msg_s);
662 int ret;
663
664 RPC_VER(&msg) = SC_RPC_VERSION;
665 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
666 RPC_FUNC(&msg) = (u8)RM_FUNC_SET_PARENT;
667 RPC_U8(&msg, 0U) = (u8)pt;
668 RPC_U8(&msg, 1U) = (u8)pt_parent;
669 RPC_SIZE(&msg) = 2U;
670
671 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
672 if (ret) {
673 printf("%s: pt:%u, pt_parent:%u, res:%d\n",
674 __func__, pt, pt_parent, RPC_R8(&msg));
675 }
676
677 return ret;
678}
679
680int sc_rm_assign_resource(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rsrc_t resource)
681{
682 struct udevice *dev = gd->arch.scu_dev;
683 struct sc_rpc_msg_s msg;
684 int size = sizeof(struct sc_rpc_msg_s);
685 int ret;
686
687 RPC_VER(&msg) = SC_RPC_VERSION;
688 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
689 RPC_FUNC(&msg) = (u8)RM_FUNC_ASSIGN_RESOURCE;
690 RPC_U16(&msg, 0U) = (u16)resource;
691 RPC_U8(&msg, 2U) = (u8)pt;
692 RPC_SIZE(&msg) = 2U;
693
694 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
695 if (ret) {
696 printf("%s: pt:%u, resource:%u, res:%d\n",
697 __func__, pt, resource, RPC_R8(&msg));
698 }
699
700 return ret;
701}
702
703int sc_rm_assign_pad(sc_ipc_t ipc, sc_rm_pt_t pt, sc_pad_t pad)
704{
705 struct udevice *dev = gd->arch.scu_dev;
706 struct sc_rpc_msg_s msg;
707 int size = sizeof(struct sc_rpc_msg_s);
708 int ret;
709
710 RPC_VER(&msg) = SC_RPC_VERSION;
711 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
712 RPC_FUNC(&msg) = (u8)RM_FUNC_ASSIGN_PAD;
713 RPC_U16(&msg, 0U) = (u16)pad;
714 RPC_U8(&msg, 2U) = (u8)pt;
715 RPC_SIZE(&msg) = 2U;
716
717 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
718 if (ret) {
719 printf("%s: pt:%u, pad:%u, res:%d\n",
720 __func__, pt, pad, RPC_R8(&msg));
721 }
722
723 return ret;
724}
725
726sc_bool_t sc_rm_is_pad_owned(sc_ipc_t ipc, sc_pad_t pad)
727{
728 struct udevice *dev = gd->arch.scu_dev;
729 struct sc_rpc_msg_s msg;
730 int size = sizeof(struct sc_rpc_msg_s);
731 int ret;
732 u8 result;
733
734 RPC_VER(&msg) = SC_RPC_VERSION;
735 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
736 RPC_FUNC(&msg) = (u8)RM_FUNC_IS_PAD_OWNED;
737 RPC_U8(&msg, 0U) = (u8)pad;
738 RPC_SIZE(&msg) = 2U;
739
740 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
741 result = RPC_R8(&msg);
742 if (result != 0 && result != 1) {
743 printf("%s: pad:%d res:%d\n", __func__, pad, RPC_R8(&msg));
744 if (ret) {
745 printf("%s: pad:%d res:%d\n", __func__,
746 pad, RPC_R8(&msg));
747 }
748 }
749
750 return !!result;
751}
752
753int sc_rm_get_resource_owner(sc_ipc_t ipc, sc_rsrc_t resource,
754 sc_rm_pt_t *pt)
755{
756 struct udevice *dev = gd->arch.scu_dev;
757 struct sc_rpc_msg_s msg;
758 int size = sizeof(struct sc_rpc_msg_s);
759 int ret;
760
761 RPC_VER(&msg) = SC_RPC_VERSION;
762 RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
763 RPC_FUNC(&msg) = (u8)RM_FUNC_GET_RESOURCE_OWNER;
764 RPC_U16(&msg, 0U) = (u16)resource;
765 RPC_SIZE(&msg) = 2U;
766
767 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
768 if (pt)
769 *pt = RPC_U8(&msg, 0U);
770
771 return ret;
772}
773
774int sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
775 sc_faddr_t address)
776{
777 struct udevice *dev = gd->arch.scu_dev;
778 struct sc_rpc_msg_s msg;
779 int size = sizeof(struct sc_rpc_msg_s);
780 int ret;
781
782 RPC_VER(&msg) = SC_RPC_VERSION;
783 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
784 RPC_FUNC(&msg) = (u8)PM_FUNC_CPU_START;
785 RPC_U32(&msg, 0U) = (u32)(address >> 32ULL);
786 RPC_U32(&msg, 4U) = (u32)address;
787 RPC_U16(&msg, 8U) = (u16)resource;
788 RPC_U8(&msg, 10U) = B2U8(enable);
789 RPC_SIZE(&msg) = 4U;
790
791 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
792 if (ret) {
793 printf("%s: resource:%d address:0x%llx: res:%d\n",
794 __func__, resource, address, RPC_R8(&msg));
795 }
796
797 return ret;
798}
799
800int sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
801 sc_pm_power_mode_t *mode)
802{
803 struct udevice *dev = gd->arch.scu_dev;
804 struct sc_rpc_msg_s msg;
805 int size = sizeof(struct sc_rpc_msg_s);
806 int ret;
807
808 RPC_VER(&msg) = SC_RPC_VERSION;
809 RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
810 RPC_FUNC(&msg) = (u8)PM_FUNC_GET_RESOURCE_POWER_MODE;
811 RPC_U16(&msg, 0U) = (u16)resource;
812 RPC_SIZE(&msg) = 2U;
813
814 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
815 if (ret) {
816 printf("%s: resource:%d: res:%d\n",
817 __func__, resource, RPC_R8(&msg));
818 }
819
820 if (mode)
821 *mode = RPC_U8(&msg, 0U);
822
823 return ret;
824}
825
826int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd,
827 sc_faddr_t addr)
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_AUTHENTICATE;
837 RPC_U32(&msg, 0U) = (u32)(addr >> 32ULL);
838 RPC_U32(&msg, 4U) = (u32)addr;
839 RPC_U8(&msg, 8U) = (u8)cmd;
840 RPC_SIZE(&msg) = 4U;
841
842 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
843 if (ret)
844 printf("%s: res:%d\n", __func__, RPC_R8(&msg));
845
846 return ret;
847}
848
849int sc_seco_forward_lifecycle(sc_ipc_t ipc, u32 change)
850{
851 struct udevice *dev = gd->arch.scu_dev;
852 struct sc_rpc_msg_s msg;
853 int size = sizeof(struct sc_rpc_msg_s);
854 int ret;
855
856 RPC_VER(&msg) = SC_RPC_VERSION;
857 RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
858 RPC_FUNC(&msg) = (u8)SECO_FUNC_FORWARD_LIFECYCLE;
859 RPC_U32(&msg, 0U) = (u32)change;
860 RPC_SIZE(&msg) = 2U;
861
862 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
863 if (ret) {
864 printf("%s: change:%u, res:%d\n", __func__,
865 change, RPC_R8(&msg));
866 }
867
868 return ret;
869}
870
871int sc_seco_chip_info(sc_ipc_t ipc, u16 *lc, u16 *monotonic, u32 *uid_l,
872 u32 *uid_h)
873{
874 struct udevice *dev = gd->arch.scu_dev;
875 struct sc_rpc_msg_s msg;
876 int size = sizeof(struct sc_rpc_msg_s);
877 int ret;
878
879 RPC_VER(&msg) = SC_RPC_VERSION;
880 RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
881 RPC_FUNC(&msg) = (u8)SECO_FUNC_CHIP_INFO;
882 RPC_SIZE(&msg) = 1U;
883
884 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
885 if (ret)
886 printf("%s: res:%d\n", __func__, RPC_R8(&msg));
887
888 if (uid_l)
889 *uid_l = RPC_U32(&msg, 0U);
890
891 if (uid_h)
892 *uid_h = RPC_U32(&msg, 4U);
893
894 if (lc)
895 *lc = RPC_U16(&msg, 8U);
896
897 if (monotonic)
898 *monotonic = RPC_U16(&msg, 10U);
899
900 return ret;
901}
902
903void sc_seco_build_info(sc_ipc_t ipc, u32 *version, u32 *commit)
904{
905 struct udevice *dev = gd->arch.scu_dev;
906 struct sc_rpc_msg_s msg;
907 int size = sizeof(struct sc_rpc_msg_s);
908
909 RPC_VER(&msg) = SC_RPC_VERSION;
910 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO);
911 RPC_FUNC(&msg) = (u8)(SECO_FUNC_BUILD_INFO);
912 RPC_SIZE(&msg) = 1U;
913
914 misc_call(dev, SC_FALSE, &msg, size, &msg, size);
915
916 if (version)
917 *version = RPC_U32(&msg, 0U);
918
919 if (commit)
920 *commit = RPC_U32(&msg, 4U);
921}
922
923int sc_seco_get_event(sc_ipc_t ipc, u8 idx, u32 *event)
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_GET_EVENT;
933 RPC_U8(&msg, 0U) = (u8)idx;
934 RPC_SIZE(&msg) = 2U;
935
936 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
937 if (ret)
938 printf("%s: idx: %u, res:%d\n", __func__, idx, RPC_R8(&msg));
939
940 if (event)
941 *event = RPC_U32(&msg, 0U);
942
943 return ret;
944}
945
946int sc_seco_gen_key_blob(sc_ipc_t ipc, u32 id, sc_faddr_t load_addr,
947 sc_faddr_t export_addr, u16 max_size)
948{
949 struct udevice *dev = gd->arch.scu_dev;
950 struct sc_rpc_msg_s msg;
951 int size = sizeof(struct sc_rpc_msg_s);
952 int ret;
953
954 RPC_VER(&msg) = SC_RPC_VERSION;
955 RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
956 RPC_FUNC(&msg) = (u8)SECO_FUNC_GEN_KEY_BLOB;
957 RPC_U32(&msg, 0U) = (u32)(load_addr >> 32ULL);
958 RPC_U32(&msg, 4U) = (u32)load_addr;
959 RPC_U32(&msg, 8U) = (u32)(export_addr >> 32ULL);
960 RPC_U32(&msg, 12U) = (u32)export_addr;
961 RPC_U32(&msg, 16U) = (u32)id;
962 RPC_U16(&msg, 20U) = (u16)max_size;
963 RPC_SIZE(&msg) = 7U;
964
965 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
966 if (ret) {
967 printf("%s: id: %u, load_addr 0x%llx, export_addr 0x%llx, res:%d\n",
968 __func__, id, load_addr, export_addr, RPC_R8(&msg));
969 }
970
971 return ret;
972}
Breno Lima184c7e22019-10-16 18:10:54 -0300973
974int sc_seco_get_mp_key(sc_ipc_t ipc, sc_faddr_t dst_addr,
975 u16 dst_size)
976{
977 struct udevice *dev = gd->arch.scu_dev;
978 struct sc_rpc_msg_s msg;
979 int size = sizeof(struct sc_rpc_msg_s);
980 int ret;
981
982 RPC_VER(&msg) = SC_RPC_VERSION;
983 RPC_SIZE(&msg) = 4U;
984 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO);
985 RPC_FUNC(&msg) = (u8)(SECO_FUNC_GET_MP_KEY);
986
987 RPC_U32(&msg, 0U) = (u32)(dst_addr >> 32ULL);
988 RPC_U32(&msg, 4U) = (u32)(dst_addr);
989 RPC_U16(&msg, 8U) = (u16)(dst_size);
990
991 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
992 if (ret)
993 printf("%s, dst_addr:0x%llx, res:%d\n",
994 __func__, dst_addr, RPC_R8(&msg));
995
996 return ret;
997}
998
999int sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr, uint8_t size_m,
1000 uint8_t lock)
1001{
1002 struct udevice *dev = gd->arch.scu_dev;
1003 struct sc_rpc_msg_s msg;
1004 int size = sizeof(struct sc_rpc_msg_s);
1005 int ret;
1006
1007 RPC_VER(&msg) = SC_RPC_VERSION;
1008 RPC_SIZE(&msg) = 4U;
1009 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO);
1010 RPC_FUNC(&msg) = (u8)(SECO_FUNC_UPDATE_MPMR);
1011
1012 RPC_U32(&msg, 0U) = (u32)(addr >> 32ULL);
1013 RPC_U32(&msg, 4U) = (u32)(addr);
1014 RPC_U8(&msg, 8U) = (u8)(size_m);
1015 RPC_U8(&msg, 9U) = (u8)(lock);
1016
1017 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
1018 if (ret)
1019 printf("%s, addr:0x%llx, size_m:%x, lock:0x%x, res:%d\n",
1020 __func__, addr, size_m, lock, RPC_R8(&msg));
1021 return ret;
1022}
1023
1024int sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr,
1025 u16 msg_size, sc_faddr_t dst_addr,
1026 u16 dst_size)
1027{
1028 struct udevice *dev = gd->arch.scu_dev;
1029 struct sc_rpc_msg_s msg;
1030 int size = sizeof(struct sc_rpc_msg_s);
1031 int ret;
1032
1033 RPC_VER(&msg) = SC_RPC_VERSION;
1034 RPC_SIZE(&msg) = 6U;
1035 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO);
1036 RPC_FUNC(&msg) = (u8)(SECO_FUNC_GET_MP_SIGN);
1037
1038 RPC_U32(&msg, 0U) = (u32)(msg_addr >> 32ULL);
1039 RPC_U32(&msg, 4U) = (u32)(msg_addr);
1040 RPC_U32(&msg, 8U) = (u32)(dst_addr >> 32ULL);
1041 RPC_U32(&msg, 12U) = (u32)(dst_addr);
1042 RPC_U16(&msg, 16U) = (u16)(msg_size);
1043 RPC_U16(&msg, 18U) = (u16)(dst_size);
1044
1045 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
1046 if (ret)
1047 printf("%s, msg_addr:0x%llx, msg_size:%x, dst_addr:0x%llx,"
1048 "dst_size:%x, res:%d\n", __func__, msg_addr, msg_size,
1049 dst_addr, dst_size, RPC_R8(&msg));
1050
1051 return ret;
1052}
Ye Li24b5dae2019-11-13 21:20:43 -08001053
1054int sc_seco_secvio_dgo_config(sc_ipc_t ipc, uint8_t id, uint8_t access,
1055 u32 *data)
1056{
1057 struct udevice *dev = gd->arch.scu_dev;
1058 struct sc_rpc_msg_s msg;
1059 int size = sizeof(struct sc_rpc_msg_s);
1060 int ret;
1061
1062 RPC_VER(&msg) = SC_RPC_VERSION;
1063 RPC_SIZE(&msg) = 3U;
1064 RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO);
1065 RPC_FUNC(&msg) = (u8)(SECO_FUNC_SECVIO_DGO_CONFIG);
1066
1067 RPC_U32(&msg, 0U) = (u32)(*data);
1068 RPC_U8(&msg, 4U) = (u8)(id);
1069 RPC_U8(&msg, 5U) = (u8)(access);
1070
1071 ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
1072 if (ret)
1073 printf("%s, id:0x%x, access:%x, res:%d\n",
1074 __func__, id, access, RPC_R8(&msg));
1075
1076 if (data)
1077 *data = RPC_U32(&msg, 0U);
1078
1079 return ret;
1080}