blob: 661f70cf870f30623c04e71ab865b9db3d4636be [file] [log] [blame]
Ye Li0db17f42021-08-07 16:00:41 +08001// SPDX-License-Identifier: GPL-2.0
2/*
Peng Fanc88036d2023-06-15 18:09:08 +08003 * Copyright 2020, 2023 NXP
Mathieu Othacehec6143392024-08-26 12:07:07 +02004 * Copyright 2024 Mathieu Othacehe <othacehe@gnu.org>
Ye Li0db17f42021-08-07 16:00:41 +08005 *
6 */
7
Ye Li0db17f42021-08-07 16:00:41 +08008#include <asm/io.h>
Peng Fan00e2e862024-10-06 08:30:02 +08009#include <asm/mach-imx/sys_proto.h>
Peng Fand5c31832023-06-15 18:09:05 +080010#include <asm/mach-imx/ele_api.h>
Peng Fan00e2e862024-10-06 08:30:02 +080011#include <dm.h>
12#include <malloc.h>
13#include <memalign.h>
Ye Li0db17f42021-08-07 16:00:41 +080014#include <misc.h>
15
16DECLARE_GLOBAL_DATA_PTR;
17
Peng Fan16426c82023-06-15 18:09:09 +080018static u32 compute_crc(const struct ele_msg *msg)
19{
20 u32 crc = 0;
21 size_t i = 0;
22 u32 *data = (u32 *)msg;
23
24 for (i = 0; i < (msg->size - 1); i++)
25 crc ^= data[i];
26
27 return crc;
28}
29
Peng Fand5c31832023-06-15 18:09:05 +080030int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response)
Ye Li0db17f42021-08-07 16:00:41 +080031{
Peng Fand5c31832023-06-15 18:09:05 +080032 struct udevice *dev = gd->arch.ele_dev;
33 int size = sizeof(struct ele_msg);
34 struct ele_msg msg;
Ye Li0db17f42021-08-07 16:00:41 +080035 int ret;
36
37 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +080038 printf("ele dev is not initialized\n");
Ye Li0db17f42021-08-07 16:00:41 +080039 return -ENODEV;
40 }
41
Peng Fand5c31832023-06-15 18:09:05 +080042 msg.version = ELE_VERSION;
43 msg.tag = ELE_CMD_TAG;
Ye Li0db17f42021-08-07 16:00:41 +080044 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +080045 msg.command = ELE_RELEASE_RDC_REQ;
Ye Lid4b3ba32022-07-26 16:40:51 +080046 switch (xrdc) {
47 case 0:
Ye Liacc9afe2021-08-07 16:00:53 +080048 msg.data[0] = (0x74 << 8) | core_id;
Ye Lid4b3ba32022-07-26 16:40:51 +080049 break;
50 case 1:
51 msg.data[0] = (0x78 << 8) | core_id;
52 break;
53 case 2:
54 msg.data[0] = (0x82 << 8) | core_id;
55 break;
56 case 3:
57 msg.data[0] = (0x86 << 8) | core_id;
58 break;
59 default:
60 printf("Error: wrong xrdc index %u\n", xrdc);
61 return -EINVAL;
62 }
Ye Li0db17f42021-08-07 16:00:41 +080063
64 ret = misc_call(dev, false, &msg, size, &msg, size);
65 if (ret)
66 printf("Error: %s: ret %d, core id %u, response 0x%x\n",
67 __func__, ret, core_id, msg.data[0]);
68
Ye Lia61f2672021-08-07 16:00:52 +080069 if (response)
70 *response = msg.data[0];
71
72 return ret;
73}
74
Peng Fand5c31832023-06-15 18:09:05 +080075int ele_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +080076{
Peng Fand5c31832023-06-15 18:09:05 +080077 struct udevice *dev = gd->arch.ele_dev;
78 int size = sizeof(struct ele_msg);
79 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +080080 int ret;
81
82 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +080083 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +080084 return -ENODEV;
85 }
86
Peng Fand5c31832023-06-15 18:09:05 +080087 msg.version = ELE_VERSION;
88 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +080089 msg.size = 3;
Ye Liebb2be52023-01-30 18:39:53 +080090 msg.command = ELE_OEM_CNTN_AUTH_REQ;
Ye Lia61f2672021-08-07 16:00:52 +080091 msg.data[0] = upper_32_bits(ctnr_addr);
92 msg.data[1] = lower_32_bits(ctnr_addr);
93
94 ret = misc_call(dev, false, &msg, size, &msg, size);
95 if (ret)
96 printf("Error: %s: ret %d, cntr_addr 0x%lx, response 0x%x\n",
97 __func__, ret, ctnr_addr, msg.data[0]);
98
99 if (response)
100 *response = msg.data[0];
101
102 return ret;
103}
104
Peng Fand5c31832023-06-15 18:09:05 +0800105int ele_release_container(u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +0800106{
Peng Fand5c31832023-06-15 18:09:05 +0800107 struct udevice *dev = gd->arch.ele_dev;
108 int size = sizeof(struct ele_msg);
109 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +0800110 int ret;
111
112 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800113 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +0800114 return -ENODEV;
115 }
116
Peng Fand5c31832023-06-15 18:09:05 +0800117 msg.version = ELE_VERSION;
118 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +0800119 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800120 msg.command = ELE_RELEASE_CONTAINER_REQ;
Ye Lia61f2672021-08-07 16:00:52 +0800121
122 ret = misc_call(dev, false, &msg, size, &msg, size);
123 if (ret)
124 printf("Error: %s: ret %d, response 0x%x\n",
125 __func__, ret, msg.data[0]);
126
127 if (response)
128 *response = msg.data[0];
129
130 return ret;
131}
132
Peng Fand5c31832023-06-15 18:09:05 +0800133int ele_verify_image(u32 img_id, u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +0800134{
Peng Fand5c31832023-06-15 18:09:05 +0800135 struct udevice *dev = gd->arch.ele_dev;
136 int size = sizeof(struct ele_msg);
137 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +0800138 int ret;
139
140 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800141 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +0800142 return -ENODEV;
143 }
144
Peng Fand5c31832023-06-15 18:09:05 +0800145 msg.version = ELE_VERSION;
146 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +0800147 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800148 msg.command = ELE_VERIFY_IMAGE_REQ;
Ye Lia61f2672021-08-07 16:00:52 +0800149 msg.data[0] = 1 << img_id;
150
151 ret = misc_call(dev, false, &msg, size, &msg, size);
152 if (ret)
153 printf("Error: %s: ret %d, img_id %u, response 0x%x\n",
154 __func__, ret, img_id, msg.data[0]);
155
156 if (response)
157 *response = msg.data[0];
158
159 return ret;
160}
161
Peng Fand5c31832023-06-15 18:09:05 +0800162int ele_forward_lifecycle(u16 life_cycle, u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +0800163{
Peng Fand5c31832023-06-15 18:09:05 +0800164 struct udevice *dev = gd->arch.ele_dev;
165 int size = sizeof(struct ele_msg);
166 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +0800167 int ret;
168
169 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800170 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +0800171 return -ENODEV;
172 }
173
Peng Fand5c31832023-06-15 18:09:05 +0800174 msg.version = ELE_VERSION;
175 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +0800176 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800177 msg.command = ELE_FWD_LIFECYCLE_UP_REQ;
Ye Lia61f2672021-08-07 16:00:52 +0800178 msg.data[0] = life_cycle;
179
180 ret = misc_call(dev, false, &msg, size, &msg, size);
181 if (ret)
182 printf("Error: %s: ret %d, life_cycle 0x%x, response 0x%x\n",
183 __func__, ret, life_cycle, msg.data[0]);
184
185 if (response)
186 *response = msg.data[0];
187
Ye Li0db17f42021-08-07 16:00:41 +0800188 return ret;
189}
Ye Lif80a41b2021-08-07 16:00:54 +0800190
Peng Fand5c31832023-06-15 18:09:05 +0800191int ele_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
Ye Lif80a41b2021-08-07 16:00:54 +0800192{
Peng Fand5c31832023-06-15 18:09:05 +0800193 struct udevice *dev = gd->arch.ele_dev;
194 int size = sizeof(struct ele_msg);
195 struct ele_msg msg;
Ye Lif80a41b2021-08-07 16:00:54 +0800196 int ret;
197
198 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800199 printf("ele dev is not initialized\n");
Ye Lif80a41b2021-08-07 16:00:54 +0800200 return -ENODEV;
201 }
202
203 if (!fuse_words) {
204 printf("Invalid parameters for fuse read\n");
205 return -EINVAL;
206 }
207
Peng Fan00e2e862024-10-06 08:30:02 +0800208 if (is_imx8ulp() && ((fuse_id != 1 && fuse_num != 1) || (fuse_id == 1 && fuse_num != 4))) {
Ye Lif80a41b2021-08-07 16:00:54 +0800209 printf("Invalid fuse number parameter\n");
210 return -EINVAL;
211 }
212
Peng Fand5c31832023-06-15 18:09:05 +0800213 msg.version = ELE_VERSION;
214 msg.tag = ELE_CMD_TAG;
Ye Lif80a41b2021-08-07 16:00:54 +0800215 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800216 msg.command = ELE_READ_FUSE_REQ;
Ye Lif80a41b2021-08-07 16:00:54 +0800217 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];
Peng Fan00e2e862024-10-06 08:30:02 +0800228 if (fuse_id == 1 && is_imx8ulp()) {
Ye Lif80a41b2021-08-07 16:00:54 +0800229 /* 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
Peng Fand5c31832023-06-15 18:09:05 +0800238int ele_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
Ye Lif80a41b2021-08-07 16:00:54 +0800239{
Peng Fand5c31832023-06-15 18:09:05 +0800240 struct udevice *dev = gd->arch.ele_dev;
241 int size = sizeof(struct ele_msg);
242 struct ele_msg msg;
Ye Lif80a41b2021-08-07 16:00:54 +0800243 int ret;
244
245 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800246 printf("ele dev is not initialized\n");
Ye Lif80a41b2021-08-07 16:00:54 +0800247 return -ENODEV;
248 }
249
Peng Fand5c31832023-06-15 18:09:05 +0800250 msg.version = ELE_VERSION;
251 msg.tag = ELE_CMD_TAG;
Ye Lif80a41b2021-08-07 16:00:54 +0800252 msg.size = 3;
Ye Liebb2be52023-01-30 18:39:53 +0800253 msg.command = ELE_WRITE_FUSE_REQ;
Ye Lif80a41b2021-08-07 16:00:54 +0800254 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}
Clement Faure26386ae2022-04-06 14:30:19 +0800270
Ye Lia45bec82024-10-06 08:30:03 +0800271int ele_write_shadow_fuse(u32 fuse_id, u32 fuse_val, u32 *response)
272{
273 struct udevice *dev = gd->arch.ele_dev;
274 int size = sizeof(struct ele_msg);
275 struct ele_msg msg;
276 int ret;
277
278 if (!dev) {
279 printf("ele dev is not initialized\n");
280 return -ENODEV;
281 }
282
283 msg.version = ELE_VERSION;
284 msg.tag = ELE_CMD_TAG;
285 msg.size = 3;
286 msg.command = ELE_WRITE_SHADOW_REQ;
287 msg.data[0] = fuse_id;
288 msg.data[1] = fuse_val;
289
290 ret = misc_call(dev, false, &msg, size, &msg, size);
291 if (ret)
292 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
293 __func__, ret, fuse_id, msg.data[0]);
294
295 if (response)
296 *response = msg.data[0];
297
298 return ret;
299}
300
301int ele_read_shadow_fuse(u32 fuse_id, u32 *fuse_val, u32 *response)
302{
303 struct udevice *dev = gd->arch.ele_dev;
304 int size = sizeof(struct ele_msg);
305 struct ele_msg msg = {};
306 int ret;
307
308 if (!dev) {
309 printf("ele dev is not initialized\n");
310 return -ENODEV;
311 }
312
313 if (!fuse_val) {
314 printf("Invalid parameters for shadow read\n");
315 return -EINVAL;
316 }
317
318 msg.version = ELE_VERSION;
319 msg.tag = ELE_CMD_TAG;
320 msg.size = 2;
321 msg.command = ELE_READ_SHADOW_REQ;
322 msg.data[0] = fuse_id;
323
324 ret = misc_call(dev, false, &msg, size, &msg, size);
325 if (ret)
326 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
327 __func__, ret, fuse_id, msg.data[0]);
328
329 if (response)
330 *response = msg.data[0];
331
332 *fuse_val = msg.data[1];
333
334 return ret;
335}
336
Peng Fand5c31832023-06-15 18:09:05 +0800337int ele_release_caam(u32 core_did, u32 *response)
Clement Faure26386ae2022-04-06 14:30:19 +0800338{
Peng Fand5c31832023-06-15 18:09:05 +0800339 struct udevice *dev = gd->arch.ele_dev;
340 int size = sizeof(struct ele_msg);
341 struct ele_msg msg;
Clement Faure26386ae2022-04-06 14:30:19 +0800342 int ret;
343
344 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800345 printf("ele dev is not initialized\n");
Clement Faure26386ae2022-04-06 14:30:19 +0800346 return -ENODEV;
347 }
348
Peng Fand5c31832023-06-15 18:09:05 +0800349 msg.version = ELE_VERSION;
350 msg.tag = ELE_CMD_TAG;
Clement Faure26386ae2022-04-06 14:30:19 +0800351 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800352 msg.command = ELE_RELEASE_CAAM_REQ;
Clement Faure26386ae2022-04-06 14:30:19 +0800353 msg.data[0] = core_did;
354
355 ret = misc_call(dev, false, &msg, size, &msg, size);
356 if (ret)
357 printf("Error: %s: ret %d, response 0x%x\n",
358 __func__, ret, msg.data[0]);
359
360 if (response)
361 *response = msg.data[0];
362
363 return ret;
364}
Ye Li0a917da2022-04-06 14:30:20 +0800365
Peng Fand5c31832023-06-15 18:09:05 +0800366int ele_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530367{
Peng Fand5c31832023-06-15 18:09:05 +0800368 struct udevice *dev = gd->arch.ele_dev;
369 int size = sizeof(struct ele_msg);
370 struct ele_msg msg;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530371 int ret;
372
373 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800374 printf("ele dev is not initialized\n");
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530375 return -ENODEV;
376 }
377
378 if (!fw_version) {
379 printf("Invalid parameters for f/w version read\n");
380 return -EINVAL;
381 }
382
383 if (!sha1) {
384 printf("Invalid parameters for commit sha1\n");
385 return -EINVAL;
386 }
387
Peng Fand5c31832023-06-15 18:09:05 +0800388 msg.version = ELE_VERSION;
389 msg.tag = ELE_CMD_TAG;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530390 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800391 msg.command = ELE_GET_FW_VERSION_REQ;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530392
393 ret = misc_call(dev, false, &msg, size, &msg, size);
394 if (ret)
395 printf("Error: %s: ret %d, response 0x%x\n",
396 __func__, ret, msg.data[0]);
397
398 if (response)
399 *response = msg.data[0];
400
401 *fw_version = msg.data[1];
402 *sha1 = msg.data[2];
403
404 return ret;
405}
406
Peng Fand5c31832023-06-15 18:09:05 +0800407int ele_dump_buffer(u32 *buffer, u32 buffer_length)
Ye Li0a917da2022-04-06 14:30:20 +0800408{
Peng Fand5c31832023-06-15 18:09:05 +0800409 struct udevice *dev = gd->arch.ele_dev;
410 int size = sizeof(struct ele_msg);
411 struct ele_msg msg;
Ye Li0a917da2022-04-06 14:30:20 +0800412 int ret, i = 0;
413
414 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800415 printf("ele dev is not initialized\n");
Ye Li0a917da2022-04-06 14:30:20 +0800416 return -ENODEV;
417 }
418
Peng Fand5c31832023-06-15 18:09:05 +0800419 msg.version = ELE_VERSION;
420 msg.tag = ELE_CMD_TAG;
Ye Li0a917da2022-04-06 14:30:20 +0800421 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800422 msg.command = ELE_DUMP_DEBUG_BUFFER_REQ;
Ye Li0a917da2022-04-06 14:30:20 +0800423
424 ret = misc_call(dev, false, &msg, size, &msg, size);
425 if (ret) {
426 printf("Error: %s: ret %d, response 0x%x\n",
427 __func__, ret, msg.data[0]);
428
429 return ret;
430 }
431
432 if (buffer) {
433 buffer[i++] = *(u32 *)&msg; /* Need dump the response header */
434 for (; i < buffer_length && i < msg.size; i++)
435 buffer[i] = msg.data[i - 1];
436 }
437
438 return i;
439}
Peng Fancffe2b92022-07-26 16:40:52 +0800440
Peng Fand5c31832023-06-15 18:09:05 +0800441int ele_get_info(struct ele_get_info_data *info, u32 *response)
Peng Fancffe2b92022-07-26 16:40:52 +0800442{
Peng Fand5c31832023-06-15 18:09:05 +0800443 struct udevice *dev = gd->arch.ele_dev;
444 int size = sizeof(struct ele_msg);
445 struct ele_msg msg;
Peng Fancffe2b92022-07-26 16:40:52 +0800446 int ret;
447
448 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800449 printf("ele dev is not initialized\n");
Peng Fancffe2b92022-07-26 16:40:52 +0800450 return -ENODEV;
451 }
452
Peng Fand5c31832023-06-15 18:09:05 +0800453 msg.version = ELE_VERSION;
454 msg.tag = ELE_CMD_TAG;
Peng Fancffe2b92022-07-26 16:40:52 +0800455 msg.size = 4;
Ye Liebb2be52023-01-30 18:39:53 +0800456 msg.command = ELE_GET_INFO_REQ;
Peng Fancffe2b92022-07-26 16:40:52 +0800457 msg.data[0] = upper_32_bits((ulong)info);
458 msg.data[1] = lower_32_bits((ulong)info);
Peng Fand5c31832023-06-15 18:09:05 +0800459 msg.data[2] = sizeof(struct ele_get_info_data);
Peng Fancffe2b92022-07-26 16:40:52 +0800460
461 ret = misc_call(dev, false, &msg, size, &msg, size);
462 if (ret)
463 printf("Error: %s: ret %d, response 0x%x\n",
464 __func__, ret, msg.data[0]);
465
466 if (response)
467 *response = msg.data[0];
468
469 return ret;
470}
471
Peng Fand5c31832023-06-15 18:09:05 +0800472int ele_get_fw_status(u32 *status, u32 *response)
Peng Fancffe2b92022-07-26 16:40:52 +0800473{
Peng Fand5c31832023-06-15 18:09:05 +0800474 struct udevice *dev = gd->arch.ele_dev;
475 int size = sizeof(struct ele_msg);
476 struct ele_msg msg;
Peng Fancffe2b92022-07-26 16:40:52 +0800477 int ret;
478
479 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800480 printf("ele dev is not initialized\n");
Peng Fancffe2b92022-07-26 16:40:52 +0800481 return -ENODEV;
482 }
483
Peng Fand5c31832023-06-15 18:09:05 +0800484 msg.version = ELE_VERSION;
485 msg.tag = ELE_CMD_TAG;
Peng Fancffe2b92022-07-26 16:40:52 +0800486 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800487 msg.command = ELE_GET_FW_STATUS_REQ;
Peng Fancffe2b92022-07-26 16:40:52 +0800488
489 ret = misc_call(dev, false, &msg, size, &msg, size);
490 if (ret)
491 printf("Error: %s: ret %d, response 0x%x\n",
492 __func__, ret, msg.data[0]);
493
494 if (response)
495 *response = msg.data[0];
496
497 *status = msg.data[1] & 0xF;
498
499 return ret;
500}
Peng Fanf6ff1402022-07-26 16:40:53 +0800501
Peng Fand5c31832023-06-15 18:09:05 +0800502int ele_release_m33_trout(void)
Peng Fanf6ff1402022-07-26 16:40:53 +0800503{
Peng Fand5c31832023-06-15 18:09:05 +0800504 struct udevice *dev = gd->arch.ele_dev;
505 int size = sizeof(struct ele_msg);
506 struct ele_msg msg;
Peng Fanf6ff1402022-07-26 16:40:53 +0800507 int ret;
508
509 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800510 printf("ele dev is not initialized\n");
Peng Fanf6ff1402022-07-26 16:40:53 +0800511 return -ENODEV;
512 }
513
Peng Fand5c31832023-06-15 18:09:05 +0800514 msg.version = ELE_VERSION;
515 msg.tag = ELE_CMD_TAG;
Peng Fanf6ff1402022-07-26 16:40:53 +0800516 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800517 msg.command = ELE_ENABLE_RTC_REQ;
Peng Fanf6ff1402022-07-26 16:40:53 +0800518
519 ret = misc_call(dev, false, &msg, size, &msg, size);
520 if (ret)
521 printf("Error: %s: ret %d, response 0x%x\n",
522 __func__, ret, msg.data[0]);
523
524 return ret;
525}
Ye Li395bfd42023-01-30 18:39:50 +0800526
Peng Fand5c31832023-06-15 18:09:05 +0800527int ele_get_events(u32 *events, u32 *events_cnt, u32 *response)
Ye Li395bfd42023-01-30 18:39:50 +0800528{
Peng Fand5c31832023-06-15 18:09:05 +0800529 struct udevice *dev = gd->arch.ele_dev;
530 int size = sizeof(struct ele_msg);
531 struct ele_msg msg;
Ye Li395bfd42023-01-30 18:39:50 +0800532 int ret, i = 0;
533 u32 actual_events;
534
535 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800536 printf("ele dev is not initialized\n");
Ye Li395bfd42023-01-30 18:39:50 +0800537 return -ENODEV;
538 }
539
540 if (!events || !events_cnt || *events_cnt == 0) {
541 printf("Invalid parameters for %s\n", __func__);
542 return -EINVAL;
543 }
544
Peng Fand5c31832023-06-15 18:09:05 +0800545 msg.version = ELE_VERSION;
546 msg.tag = ELE_CMD_TAG;
Ye Li395bfd42023-01-30 18:39:50 +0800547 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800548 msg.command = ELE_GET_EVENTS_REQ;
Ye Li395bfd42023-01-30 18:39:50 +0800549
550 ret = misc_call(dev, false, &msg, size, &msg, size);
551 if (ret)
552 printf("Error: %s: ret %d, response 0x%x\n",
553 __func__, ret, msg.data[0]);
554
555 if (response)
556 *response = msg.data[0];
557
558 if (!ret) {
559 actual_events = msg.data[1] & 0xffff;
560 if (*events_cnt < actual_events)
561 actual_events = *events_cnt;
562
563 for (; i < actual_events; i++)
564 events[i] = msg.data[i + 2];
565
566 *events_cnt = actual_events;
567 }
568
569 return ret;
570}
Peng Fanc88036d2023-06-15 18:09:08 +0800571
Peng Fanaa70b852023-06-15 18:09:14 +0800572int ele_start_rng(void)
573{
574 struct udevice *dev = gd->arch.ele_dev;
575 int size = sizeof(struct ele_msg);
576 struct ele_msg msg;
577 int ret;
578
579 if (!dev) {
580 printf("ele dev is not initialized\n");
581 return -ENODEV;
582 }
583
584 msg.version = ELE_VERSION;
585 msg.tag = ELE_CMD_TAG;
586 msg.size = 1;
587 msg.command = ELE_START_RNG;
588
589 ret = misc_call(dev, false, &msg, size, &msg, size);
590 if (ret)
591 printf("Error: %s: ret %d, response 0x%x\n",
592 __func__, ret, msg.data[0]);
593
594 return ret;
595}
596
Mathieu Othacehec6143392024-08-26 12:07:07 +0200597int ele_derive_huk(u8 *key, size_t key_size, u8 *seed, size_t seed_size)
598{
599 struct udevice *dev = gd->arch.ele_dev;
600 struct ele_msg msg;
601 int msg_size = sizeof(struct ele_msg);
602 u8 *seed_aligned, *key_aligned;
603 int ret, size;
604
605 if (!dev) {
606 printf("ele dev is not initialized\n");
607 return -ENODEV;
608 }
609
610 if (key_size != 16 && key_size != 32) {
611 printf("key size can only be 16 or 32\n");
612 return -EINVAL;
613 }
614
615 if (seed_size >= (1U << 16) - 1) {
616 printf("seed size is too large\n");
617 return -EINVAL;
618 }
619
620 seed_aligned = memalign(ARCH_DMA_MINALIGN, seed_size);
621 if (!seed_aligned) {
622 printf("failed to alloc memory\n");
623 return -EINVAL;
624 }
625 memcpy(seed_aligned, seed, seed_size);
626
627 key_aligned = memalign(ARCH_DMA_MINALIGN, key_size);
628 if (!key_aligned) {
629 printf("failed to alloc memory\n");
630 ret = -EINVAL;
631 goto ret_seed;
632 }
633
634 size = ALIGN(seed_size, ARCH_DMA_MINALIGN);
635 flush_dcache_range((ulong)seed_aligned,
636 (ulong)seed_aligned + size);
637
638 size = ALIGN(key_size, ARCH_DMA_MINALIGN);
639 invalidate_dcache_range((ulong)key_aligned,
640 (ulong)key_aligned + size);
641
642 msg.version = ELE_VERSION;
643 msg.tag = ELE_CMD_TAG;
644 msg.size = 7;
645 msg.command = ELE_CMD_DERIVE_KEY;
646 msg.data[0] = upper_32_bits((ulong)key_aligned);
647 msg.data[1] = lower_32_bits((ulong)key_aligned);
648 msg.data[2] = upper_32_bits((ulong)seed_aligned);
649 msg.data[3] = lower_32_bits((ulong)seed_aligned);
650 msg.data[4] = seed_size << 16 | key_size;
651 msg.data[5] = compute_crc(&msg);
652
653 ret = misc_call(dev, false, &msg, msg_size, &msg, msg_size);
654 if (ret) {
655 printf("Error: %s: ret %d, response 0x%x\n",
656 __func__, ret, msg.data[0]);
657 goto ret_key;
658 }
659
660 invalidate_dcache_range((ulong)key_aligned,
661 (ulong)key_aligned + size);
662 memcpy(key, key_aligned, key_size);
663
664ret_key:
665 free(key_aligned);
666ret_seed:
667 free(seed_aligned);
668
669 return ret;
670}
671
Mathieu Othacehe8df8e592024-03-21 08:19:53 +0100672int ele_commit(u16 fuse_id, u32 *response, u32 *info_type)
673{
674 struct udevice *dev = gd->arch.ele_dev;
675 int size = sizeof(struct ele_msg);
676 struct ele_msg msg;
677 int ret = 0;
678
679 if (!dev) {
680 printf("ele dev is not initialized\n");
681 return -ENODEV;
682 }
683
684 msg.version = ELE_VERSION;
685 msg.tag = ELE_CMD_TAG;
686 msg.size = 2;
687 msg.command = ELE_COMMIT_REQ;
688 msg.data[0] = fuse_id;
689
690 ret = misc_call(dev, false, &msg, size, &msg, size);
691 if (ret)
692 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
693 __func__, ret, fuse_id, msg.data[0]);
694
695 if (response)
696 *response = msg.data[0];
697
698 if (info_type)
699 *info_type = msg.data[1];
700
701 return ret;
702}
703
Peng Fanc88036d2023-06-15 18:09:08 +0800704int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response)
705{
706 struct udevice *dev = gd->arch.ele_dev;
707 int size = sizeof(struct ele_msg);
708 struct ele_msg msg;
709 int ret;
710
711 if (!dev) {
712 printf("ele dev is not initialized\n");
713 return -ENODEV;
714 }
715
716 msg.version = ELE_VERSION;
717 msg.tag = ELE_CMD_TAG;
718 msg.size = 3;
719 msg.command = ELE_WRITE_SECURE_FUSE_REQ;
720
721 msg.data[0] = upper_32_bits(signed_msg_blk);
722 msg.data[1] = lower_32_bits(signed_msg_blk);
723
724 ret = misc_call(dev, false, &msg, size, &msg, size);
725 if (ret)
726 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
727 __func__, ret, msg.data[0], msg.data[1]);
728
729 if (response)
730 *response = msg.data[0];
731
732 return ret;
733}
734
735int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response)
736{
737 struct udevice *dev = gd->arch.ele_dev;
738 int size = sizeof(struct ele_msg);
739 struct ele_msg msg;
740 int ret;
741
742 if (!dev) {
743 printf("ele dev is not initialized\n");
744 return -ENODEV;
745 }
746
747 msg.version = ELE_VERSION;
748 msg.tag = ELE_CMD_TAG;
749 msg.size = 3;
750 msg.command = ELE_RET_LIFECYCLE_UP_REQ;
751
752 msg.data[0] = upper_32_bits(signed_msg_blk);
753 msg.data[1] = lower_32_bits(signed_msg_blk);
754
755 ret = misc_call(dev, false, &msg, size, &msg, size);
756 if (ret)
757 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
758 __func__, ret, msg.data[0], msg.data[1]);
759
760 if (response)
761 *response = msg.data[0];
762
763 return ret;
764}
Peng Fan16426c82023-06-15 18:09:09 +0800765
766int ele_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr, u32 max_output_size)
767{
768 struct udevice *dev = gd->arch.ele_dev;
769 int size = sizeof(struct ele_msg);
770 struct ele_msg msg;
771 int ret;
772
773 if (!dev) {
774 printf("ele dev is not initialized\n");
775 return -ENODEV;
776 }
777
778 msg.version = ELE_VERSION;
779 msg.tag = ELE_CMD_TAG;
780 msg.size = 8;
781 msg.command = ELE_GENERATE_DEK_BLOB;
782 msg.data[0] = key_id;
783 msg.data[1] = 0x0;
784 msg.data[2] = src_paddr;
785 msg.data[3] = 0x0;
786 msg.data[4] = dst_paddr;
787 msg.data[5] = max_output_size;
788 msg.data[6] = compute_crc(&msg);
789
790 ret = misc_call(dev, false, &msg, size, &msg, size);
791 if (ret)
792 printf("Error: %s: ret 0x%x, response 0x%x\n",
793 __func__, ret, msg.data[0]);
794
795 return ret;
796}