]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/misc/imx_ele/ele_api.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / drivers / misc / imx_ele / ele_api.c
CommitLineData
0c00d03a
YL
1// SPDX-License-Identifier: GPL-2.0
2/*
31e5ec23 3 * Copyright 2020, 2023 NXP
0c00d03a
YL
4 *
5 */
6
d678a59d 7#include <common.h>
0c00d03a
YL
8#include <hang.h>
9#include <malloc.h>
10#include <asm/io.h>
11#include <dm.h>
d3ee9dbd 12#include <asm/mach-imx/ele_api.h>
0c00d03a
YL
13#include <misc.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
d0e2a012
PF
17static u32 compute_crc(const struct ele_msg *msg)
18{
19 u32 crc = 0;
20 size_t i = 0;
21 u32 *data = (u32 *)msg;
22
23 for (i = 0; i < (msg->size - 1); i++)
24 crc ^= data[i];
25
26 return crc;
27}
28
d3ee9dbd 29int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response)
0c00d03a 30{
d3ee9dbd
PF
31 struct udevice *dev = gd->arch.ele_dev;
32 int size = sizeof(struct ele_msg);
33 struct ele_msg msg;
0c00d03a
YL
34 int ret;
35
36 if (!dev) {
d3ee9dbd 37 printf("ele dev is not initialized\n");
0c00d03a
YL
38 return -ENODEV;
39 }
40
d3ee9dbd
PF
41 msg.version = ELE_VERSION;
42 msg.tag = ELE_CMD_TAG;
0c00d03a 43 msg.size = 2;
040fc2be 44 msg.command = ELE_RELEASE_RDC_REQ;
e5fcf913
YL
45 switch (xrdc) {
46 case 0:
7aeaf4d9 47 msg.data[0] = (0x74 << 8) | core_id;
e5fcf913
YL
48 break;
49 case 1:
50 msg.data[0] = (0x78 << 8) | core_id;
51 break;
52 case 2:
53 msg.data[0] = (0x82 << 8) | core_id;
54 break;
55 case 3:
56 msg.data[0] = (0x86 << 8) | core_id;
57 break;
58 default:
59 printf("Error: wrong xrdc index %u\n", xrdc);
60 return -EINVAL;
61 }
0c00d03a
YL
62
63 ret = misc_call(dev, false, &msg, size, &msg, size);
64 if (ret)
65 printf("Error: %s: ret %d, core id %u, response 0x%x\n",
66 __func__, ret, core_id, msg.data[0]);
67
6306f75d
YL
68 if (response)
69 *response = msg.data[0];
70
71 return ret;
72}
73
d3ee9dbd 74int ele_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
6306f75d 75{
d3ee9dbd
PF
76 struct udevice *dev = gd->arch.ele_dev;
77 int size = sizeof(struct ele_msg);
78 struct ele_msg msg;
6306f75d
YL
79 int ret;
80
81 if (!dev) {
d3ee9dbd 82 printf("ele dev is not initialized\n");
6306f75d
YL
83 return -ENODEV;
84 }
85
d3ee9dbd
PF
86 msg.version = ELE_VERSION;
87 msg.tag = ELE_CMD_TAG;
6306f75d 88 msg.size = 3;
040fc2be 89 msg.command = ELE_OEM_CNTN_AUTH_REQ;
6306f75d
YL
90 msg.data[0] = upper_32_bits(ctnr_addr);
91 msg.data[1] = lower_32_bits(ctnr_addr);
92
93 ret = misc_call(dev, false, &msg, size, &msg, size);
94 if (ret)
95 printf("Error: %s: ret %d, cntr_addr 0x%lx, response 0x%x\n",
96 __func__, ret, ctnr_addr, msg.data[0]);
97
98 if (response)
99 *response = msg.data[0];
100
101 return ret;
102}
103
d3ee9dbd 104int ele_release_container(u32 *response)
6306f75d 105{
d3ee9dbd
PF
106 struct udevice *dev = gd->arch.ele_dev;
107 int size = sizeof(struct ele_msg);
108 struct ele_msg msg;
6306f75d
YL
109 int ret;
110
111 if (!dev) {
d3ee9dbd 112 printf("ele dev is not initialized\n");
6306f75d
YL
113 return -ENODEV;
114 }
115
d3ee9dbd
PF
116 msg.version = ELE_VERSION;
117 msg.tag = ELE_CMD_TAG;
6306f75d 118 msg.size = 1;
040fc2be 119 msg.command = ELE_RELEASE_CONTAINER_REQ;
6306f75d
YL
120
121 ret = misc_call(dev, false, &msg, size, &msg, size);
122 if (ret)
123 printf("Error: %s: ret %d, response 0x%x\n",
124 __func__, ret, msg.data[0]);
125
126 if (response)
127 *response = msg.data[0];
128
129 return ret;
130}
131
d3ee9dbd 132int ele_verify_image(u32 img_id, u32 *response)
6306f75d 133{
d3ee9dbd
PF
134 struct udevice *dev = gd->arch.ele_dev;
135 int size = sizeof(struct ele_msg);
136 struct ele_msg msg;
6306f75d
YL
137 int ret;
138
139 if (!dev) {
d3ee9dbd 140 printf("ele dev is not initialized\n");
6306f75d
YL
141 return -ENODEV;
142 }
143
d3ee9dbd
PF
144 msg.version = ELE_VERSION;
145 msg.tag = ELE_CMD_TAG;
6306f75d 146 msg.size = 2;
040fc2be 147 msg.command = ELE_VERIFY_IMAGE_REQ;
6306f75d
YL
148 msg.data[0] = 1 << img_id;
149
150 ret = misc_call(dev, false, &msg, size, &msg, size);
151 if (ret)
152 printf("Error: %s: ret %d, img_id %u, response 0x%x\n",
153 __func__, ret, img_id, msg.data[0]);
154
155 if (response)
156 *response = msg.data[0];
157
158 return ret;
159}
160
d3ee9dbd 161int ele_forward_lifecycle(u16 life_cycle, u32 *response)
6306f75d 162{
d3ee9dbd
PF
163 struct udevice *dev = gd->arch.ele_dev;
164 int size = sizeof(struct ele_msg);
165 struct ele_msg msg;
6306f75d
YL
166 int ret;
167
168 if (!dev) {
d3ee9dbd 169 printf("ele dev is not initialized\n");
6306f75d
YL
170 return -ENODEV;
171 }
172
d3ee9dbd
PF
173 msg.version = ELE_VERSION;
174 msg.tag = ELE_CMD_TAG;
6306f75d 175 msg.size = 2;
040fc2be 176 msg.command = ELE_FWD_LIFECYCLE_UP_REQ;
6306f75d
YL
177 msg.data[0] = life_cycle;
178
179 ret = misc_call(dev, false, &msg, size, &msg, size);
180 if (ret)
181 printf("Error: %s: ret %d, life_cycle 0x%x, response 0x%x\n",
182 __func__, ret, life_cycle, msg.data[0]);
183
184 if (response)
185 *response = msg.data[0];
186
0c00d03a
YL
187 return ret;
188}
26b53212 189
d3ee9dbd 190int ele_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
26b53212 191{
d3ee9dbd
PF
192 struct udevice *dev = gd->arch.ele_dev;
193 int size = sizeof(struct ele_msg);
194 struct ele_msg msg;
26b53212
YL
195 int ret;
196
197 if (!dev) {
d3ee9dbd 198 printf("ele dev is not initialized\n");
26b53212
YL
199 return -ENODEV;
200 }
201
202 if (!fuse_words) {
203 printf("Invalid parameters for fuse read\n");
204 return -EINVAL;
205 }
206
207 if ((fuse_id != 1 && fuse_num != 1) ||
208 (fuse_id == 1 && fuse_num != 4)) {
209 printf("Invalid fuse number parameter\n");
210 return -EINVAL;
211 }
212
d3ee9dbd
PF
213 msg.version = ELE_VERSION;
214 msg.tag = ELE_CMD_TAG;
26b53212 215 msg.size = 2;
040fc2be 216 msg.command = ELE_READ_FUSE_REQ;
26b53212
YL
217 msg.data[0] = fuse_id;
218
219 ret = misc_call(dev, false, &msg, size, &msg, size);
220 if (ret)
221 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
222 __func__, ret, fuse_id, msg.data[0]);
223
224 if (response)
225 *response = msg.data[0];
226
227 fuse_words[0] = msg.data[1];
228 if (fuse_id == 1) {
229 /* OTP_UNIQ_ID */
230 fuse_words[1] = msg.data[2];
231 fuse_words[2] = msg.data[3];
232 fuse_words[3] = msg.data[4];
233 }
234
235 return ret;
236}
237
d3ee9dbd 238int ele_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
26b53212 239{
d3ee9dbd
PF
240 struct udevice *dev = gd->arch.ele_dev;
241 int size = sizeof(struct ele_msg);
242 struct ele_msg msg;
26b53212
YL
243 int ret;
244
245 if (!dev) {
d3ee9dbd 246 printf("ele dev is not initialized\n");
26b53212
YL
247 return -ENODEV;
248 }
249
d3ee9dbd
PF
250 msg.version = ELE_VERSION;
251 msg.tag = ELE_CMD_TAG;
26b53212 252 msg.size = 3;
040fc2be 253 msg.command = ELE_WRITE_FUSE_REQ;
26b53212
YL
254 msg.data[0] = (32 << 16) | (fuse_id << 5);
255 if (lock)
256 msg.data[0] |= (1 << 31);
257
258 msg.data[1] = fuse_val;
259
260 ret = misc_call(dev, false, &msg, size, &msg, size);
261 if (ret)
262 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
263 __func__, ret, fuse_id, msg.data[0]);
264
265 if (response)
266 *response = msg.data[0];
267
268 return ret;
269}
a55ca506 270
d3ee9dbd 271int ele_release_caam(u32 core_did, u32 *response)
a55ca506 272{
d3ee9dbd
PF
273 struct udevice *dev = gd->arch.ele_dev;
274 int size = sizeof(struct ele_msg);
275 struct ele_msg msg;
a55ca506
CF
276 int ret;
277
278 if (!dev) {
d3ee9dbd 279 printf("ele dev is not initialized\n");
a55ca506
CF
280 return -ENODEV;
281 }
282
d3ee9dbd
PF
283 msg.version = ELE_VERSION;
284 msg.tag = ELE_CMD_TAG;
a55ca506 285 msg.size = 2;
040fc2be 286 msg.command = ELE_RELEASE_CAAM_REQ;
a55ca506
CF
287 msg.data[0] = core_did;
288
289 ret = misc_call(dev, false, &msg, size, &msg, size);
290 if (ret)
291 printf("Error: %s: ret %d, response 0x%x\n",
292 __func__, ret, msg.data[0]);
293
294 if (response)
295 *response = msg.data[0];
296
297 return ret;
298}
203412f6 299
d3ee9dbd 300int ele_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
cad77280 301{
d3ee9dbd
PF
302 struct udevice *dev = gd->arch.ele_dev;
303 int size = sizeof(struct ele_msg);
304 struct ele_msg msg;
cad77280
GJ
305 int ret;
306
307 if (!dev) {
d3ee9dbd 308 printf("ele dev is not initialized\n");
cad77280
GJ
309 return -ENODEV;
310 }
311
312 if (!fw_version) {
313 printf("Invalid parameters for f/w version read\n");
314 return -EINVAL;
315 }
316
317 if (!sha1) {
318 printf("Invalid parameters for commit sha1\n");
319 return -EINVAL;
320 }
321
d3ee9dbd
PF
322 msg.version = ELE_VERSION;
323 msg.tag = ELE_CMD_TAG;
cad77280 324 msg.size = 1;
040fc2be 325 msg.command = ELE_GET_FW_VERSION_REQ;
cad77280
GJ
326
327 ret = misc_call(dev, false, &msg, size, &msg, size);
328 if (ret)
329 printf("Error: %s: ret %d, response 0x%x\n",
330 __func__, ret, msg.data[0]);
331
332 if (response)
333 *response = msg.data[0];
334
335 *fw_version = msg.data[1];
336 *sha1 = msg.data[2];
337
338 return ret;
339}
340
d3ee9dbd 341int ele_dump_buffer(u32 *buffer, u32 buffer_length)
203412f6 342{
d3ee9dbd
PF
343 struct udevice *dev = gd->arch.ele_dev;
344 int size = sizeof(struct ele_msg);
345 struct ele_msg msg;
203412f6
YL
346 int ret, i = 0;
347
348 if (!dev) {
d3ee9dbd 349 printf("ele dev is not initialized\n");
203412f6
YL
350 return -ENODEV;
351 }
352
d3ee9dbd
PF
353 msg.version = ELE_VERSION;
354 msg.tag = ELE_CMD_TAG;
203412f6 355 msg.size = 1;
040fc2be 356 msg.command = ELE_DUMP_DEBUG_BUFFER_REQ;
203412f6
YL
357
358 ret = misc_call(dev, false, &msg, size, &msg, size);
359 if (ret) {
360 printf("Error: %s: ret %d, response 0x%x\n",
361 __func__, ret, msg.data[0]);
362
363 return ret;
364 }
365
366 if (buffer) {
367 buffer[i++] = *(u32 *)&msg; /* Need dump the response header */
368 for (; i < buffer_length && i < msg.size; i++)
369 buffer[i] = msg.data[i - 1];
370 }
371
372 return i;
373}
625473d6 374
d3ee9dbd 375int ele_get_info(struct ele_get_info_data *info, u32 *response)
625473d6 376{
d3ee9dbd
PF
377 struct udevice *dev = gd->arch.ele_dev;
378 int size = sizeof(struct ele_msg);
379 struct ele_msg msg;
625473d6
PF
380 int ret;
381
382 if (!dev) {
d3ee9dbd 383 printf("ele dev is not initialized\n");
625473d6
PF
384 return -ENODEV;
385 }
386
d3ee9dbd
PF
387 msg.version = ELE_VERSION;
388 msg.tag = ELE_CMD_TAG;
625473d6 389 msg.size = 4;
040fc2be 390 msg.command = ELE_GET_INFO_REQ;
625473d6
PF
391 msg.data[0] = upper_32_bits((ulong)info);
392 msg.data[1] = lower_32_bits((ulong)info);
d3ee9dbd 393 msg.data[2] = sizeof(struct ele_get_info_data);
625473d6
PF
394
395 ret = misc_call(dev, false, &msg, size, &msg, size);
396 if (ret)
397 printf("Error: %s: ret %d, response 0x%x\n",
398 __func__, ret, msg.data[0]);
399
400 if (response)
401 *response = msg.data[0];
402
403 return ret;
404}
405
d3ee9dbd 406int ele_get_fw_status(u32 *status, u32 *response)
625473d6 407{
d3ee9dbd
PF
408 struct udevice *dev = gd->arch.ele_dev;
409 int size = sizeof(struct ele_msg);
410 struct ele_msg msg;
625473d6
PF
411 int ret;
412
413 if (!dev) {
d3ee9dbd 414 printf("ele dev is not initialized\n");
625473d6
PF
415 return -ENODEV;
416 }
417
d3ee9dbd
PF
418 msg.version = ELE_VERSION;
419 msg.tag = ELE_CMD_TAG;
625473d6 420 msg.size = 1;
040fc2be 421 msg.command = ELE_GET_FW_STATUS_REQ;
625473d6
PF
422
423 ret = misc_call(dev, false, &msg, size, &msg, size);
424 if (ret)
425 printf("Error: %s: ret %d, response 0x%x\n",
426 __func__, ret, msg.data[0]);
427
428 if (response)
429 *response = msg.data[0];
430
431 *status = msg.data[1] & 0xF;
432
433 return ret;
434}
27272456 435
d3ee9dbd 436int ele_release_m33_trout(void)
27272456 437{
d3ee9dbd
PF
438 struct udevice *dev = gd->arch.ele_dev;
439 int size = sizeof(struct ele_msg);
440 struct ele_msg msg;
27272456
PF
441 int ret;
442
443 if (!dev) {
d3ee9dbd 444 printf("ele dev is not initialized\n");
27272456
PF
445 return -ENODEV;
446 }
447
d3ee9dbd
PF
448 msg.version = ELE_VERSION;
449 msg.tag = ELE_CMD_TAG;
27272456 450 msg.size = 1;
040fc2be 451 msg.command = ELE_ENABLE_RTC_REQ;
27272456
PF
452
453 ret = misc_call(dev, false, &msg, size, &msg, size);
454 if (ret)
455 printf("Error: %s: ret %d, response 0x%x\n",
456 __func__, ret, msg.data[0]);
457
458 return ret;
459}
76c184fe 460
d3ee9dbd 461int ele_get_events(u32 *events, u32 *events_cnt, u32 *response)
76c184fe 462{
d3ee9dbd
PF
463 struct udevice *dev = gd->arch.ele_dev;
464 int size = sizeof(struct ele_msg);
465 struct ele_msg msg;
76c184fe
YL
466 int ret, i = 0;
467 u32 actual_events;
468
469 if (!dev) {
d3ee9dbd 470 printf("ele dev is not initialized\n");
76c184fe
YL
471 return -ENODEV;
472 }
473
474 if (!events || !events_cnt || *events_cnt == 0) {
475 printf("Invalid parameters for %s\n", __func__);
476 return -EINVAL;
477 }
478
d3ee9dbd
PF
479 msg.version = ELE_VERSION;
480 msg.tag = ELE_CMD_TAG;
76c184fe 481 msg.size = 1;
040fc2be 482 msg.command = ELE_GET_EVENTS_REQ;
76c184fe
YL
483
484 ret = misc_call(dev, false, &msg, size, &msg, size);
485 if (ret)
486 printf("Error: %s: ret %d, response 0x%x\n",
487 __func__, ret, msg.data[0]);
488
489 if (response)
490 *response = msg.data[0];
491
492 if (!ret) {
493 actual_events = msg.data[1] & 0xffff;
494 if (*events_cnt < actual_events)
495 actual_events = *events_cnt;
496
497 for (; i < actual_events; i++)
498 events[i] = msg.data[i + 2];
499
500 *events_cnt = actual_events;
501 }
502
503 return ret;
504}
31e5ec23 505
1c3f5df2
PF
506int ele_start_rng(void)
507{
508 struct udevice *dev = gd->arch.ele_dev;
509 int size = sizeof(struct ele_msg);
510 struct ele_msg msg;
511 int ret;
512
513 if (!dev) {
514 printf("ele dev is not initialized\n");
515 return -ENODEV;
516 }
517
518 msg.version = ELE_VERSION;
519 msg.tag = ELE_CMD_TAG;
520 msg.size = 1;
521 msg.command = ELE_START_RNG;
522
523 ret = misc_call(dev, false, &msg, size, &msg, size);
524 if (ret)
525 printf("Error: %s: ret %d, response 0x%x\n",
526 __func__, ret, msg.data[0]);
527
528 return ret;
529}
530
6bb74584
MO
531int ele_commit(u16 fuse_id, u32 *response, u32 *info_type)
532{
533 struct udevice *dev = gd->arch.ele_dev;
534 int size = sizeof(struct ele_msg);
535 struct ele_msg msg;
536 int ret = 0;
537
538 if (!dev) {
539 printf("ele dev is not initialized\n");
540 return -ENODEV;
541 }
542
543 msg.version = ELE_VERSION;
544 msg.tag = ELE_CMD_TAG;
545 msg.size = 2;
546 msg.command = ELE_COMMIT_REQ;
547 msg.data[0] = fuse_id;
548
549 ret = misc_call(dev, false, &msg, size, &msg, size);
550 if (ret)
551 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
552 __func__, ret, fuse_id, msg.data[0]);
553
554 if (response)
555 *response = msg.data[0];
556
557 if (info_type)
558 *info_type = msg.data[1];
559
560 return ret;
561}
562
31e5ec23
PF
563int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response)
564{
565 struct udevice *dev = gd->arch.ele_dev;
566 int size = sizeof(struct ele_msg);
567 struct ele_msg msg;
568 int ret;
569
570 if (!dev) {
571 printf("ele dev is not initialized\n");
572 return -ENODEV;
573 }
574
575 msg.version = ELE_VERSION;
576 msg.tag = ELE_CMD_TAG;
577 msg.size = 3;
578 msg.command = ELE_WRITE_SECURE_FUSE_REQ;
579
580 msg.data[0] = upper_32_bits(signed_msg_blk);
581 msg.data[1] = lower_32_bits(signed_msg_blk);
582
583 ret = misc_call(dev, false, &msg, size, &msg, size);
584 if (ret)
585 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
586 __func__, ret, msg.data[0], msg.data[1]);
587
588 if (response)
589 *response = msg.data[0];
590
591 return ret;
592}
593
594int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response)
595{
596 struct udevice *dev = gd->arch.ele_dev;
597 int size = sizeof(struct ele_msg);
598 struct ele_msg msg;
599 int ret;
600
601 if (!dev) {
602 printf("ele dev is not initialized\n");
603 return -ENODEV;
604 }
605
606 msg.version = ELE_VERSION;
607 msg.tag = ELE_CMD_TAG;
608 msg.size = 3;
609 msg.command = ELE_RET_LIFECYCLE_UP_REQ;
610
611 msg.data[0] = upper_32_bits(signed_msg_blk);
612 msg.data[1] = lower_32_bits(signed_msg_blk);
613
614 ret = misc_call(dev, false, &msg, size, &msg, size);
615 if (ret)
616 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
617 __func__, ret, msg.data[0], msg.data[1]);
618
619 if (response)
620 *response = msg.data[0];
621
622 return ret;
623}
d0e2a012
PF
624
625int ele_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr, u32 max_output_size)
626{
627 struct udevice *dev = gd->arch.ele_dev;
628 int size = sizeof(struct ele_msg);
629 struct ele_msg msg;
630 int ret;
631
632 if (!dev) {
633 printf("ele dev is not initialized\n");
634 return -ENODEV;
635 }
636
637 msg.version = ELE_VERSION;
638 msg.tag = ELE_CMD_TAG;
639 msg.size = 8;
640 msg.command = ELE_GENERATE_DEK_BLOB;
641 msg.data[0] = key_id;
642 msg.data[1] = 0x0;
643 msg.data[2] = src_paddr;
644 msg.data[3] = 0x0;
645 msg.data[4] = dst_paddr;
646 msg.data[5] = max_output_size;
647 msg.data[6] = compute_crc(&msg);
648
649 ret = misc_call(dev, false, &msg, size, &msg, size);
650 if (ret)
651 printf("Error: %s: ret 0x%x, response 0x%x\n",
652 __func__, ret, msg.data[0]);
653
654 return ret;
655}