blob: b753419f01b9ac8af1b09917a497b2614684589b [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 <hang.h>
9#include <malloc.h>
Mathieu Othacehec6143392024-08-26 12:07:07 +020010#include <memalign.h>
Ye Li0db17f42021-08-07 16:00:41 +080011#include <asm/io.h>
12#include <dm.h>
Peng Fand5c31832023-06-15 18:09:05 +080013#include <asm/mach-imx/ele_api.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
208 if ((fuse_id != 1 && fuse_num != 1) ||
209 (fuse_id == 1 && fuse_num != 4)) {
210 printf("Invalid fuse number parameter\n");
211 return -EINVAL;
212 }
213
Peng Fand5c31832023-06-15 18:09:05 +0800214 msg.version = ELE_VERSION;
215 msg.tag = ELE_CMD_TAG;
Ye Lif80a41b2021-08-07 16:00:54 +0800216 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800217 msg.command = ELE_READ_FUSE_REQ;
Ye Lif80a41b2021-08-07 16:00:54 +0800218 msg.data[0] = fuse_id;
219
220 ret = misc_call(dev, false, &msg, size, &msg, size);
221 if (ret)
222 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
223 __func__, ret, fuse_id, msg.data[0]);
224
225 if (response)
226 *response = msg.data[0];
227
228 fuse_words[0] = msg.data[1];
229 if (fuse_id == 1) {
230 /* OTP_UNIQ_ID */
231 fuse_words[1] = msg.data[2];
232 fuse_words[2] = msg.data[3];
233 fuse_words[3] = msg.data[4];
234 }
235
236 return ret;
237}
238
Peng Fand5c31832023-06-15 18:09:05 +0800239int ele_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
Ye Lif80a41b2021-08-07 16:00:54 +0800240{
Peng Fand5c31832023-06-15 18:09:05 +0800241 struct udevice *dev = gd->arch.ele_dev;
242 int size = sizeof(struct ele_msg);
243 struct ele_msg msg;
Ye Lif80a41b2021-08-07 16:00:54 +0800244 int ret;
245
246 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800247 printf("ele dev is not initialized\n");
Ye Lif80a41b2021-08-07 16:00:54 +0800248 return -ENODEV;
249 }
250
Peng Fand5c31832023-06-15 18:09:05 +0800251 msg.version = ELE_VERSION;
252 msg.tag = ELE_CMD_TAG;
Ye Lif80a41b2021-08-07 16:00:54 +0800253 msg.size = 3;
Ye Liebb2be52023-01-30 18:39:53 +0800254 msg.command = ELE_WRITE_FUSE_REQ;
Ye Lif80a41b2021-08-07 16:00:54 +0800255 msg.data[0] = (32 << 16) | (fuse_id << 5);
256 if (lock)
257 msg.data[0] |= (1 << 31);
258
259 msg.data[1] = fuse_val;
260
261 ret = misc_call(dev, false, &msg, size, &msg, size);
262 if (ret)
263 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
264 __func__, ret, fuse_id, msg.data[0]);
265
266 if (response)
267 *response = msg.data[0];
268
269 return ret;
270}
Clement Faure26386ae2022-04-06 14:30:19 +0800271
Peng Fand5c31832023-06-15 18:09:05 +0800272int ele_release_caam(u32 core_did, u32 *response)
Clement Faure26386ae2022-04-06 14:30:19 +0800273{
Peng Fand5c31832023-06-15 18:09:05 +0800274 struct udevice *dev = gd->arch.ele_dev;
275 int size = sizeof(struct ele_msg);
276 struct ele_msg msg;
Clement Faure26386ae2022-04-06 14:30:19 +0800277 int ret;
278
279 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800280 printf("ele dev is not initialized\n");
Clement Faure26386ae2022-04-06 14:30:19 +0800281 return -ENODEV;
282 }
283
Peng Fand5c31832023-06-15 18:09:05 +0800284 msg.version = ELE_VERSION;
285 msg.tag = ELE_CMD_TAG;
Clement Faure26386ae2022-04-06 14:30:19 +0800286 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800287 msg.command = ELE_RELEASE_CAAM_REQ;
Clement Faure26386ae2022-04-06 14:30:19 +0800288 msg.data[0] = core_did;
289
290 ret = misc_call(dev, false, &msg, size, &msg, size);
291 if (ret)
292 printf("Error: %s: ret %d, response 0x%x\n",
293 __func__, ret, msg.data[0]);
294
295 if (response)
296 *response = msg.data[0];
297
298 return ret;
299}
Ye Li0a917da2022-04-06 14:30:20 +0800300
Peng Fand5c31832023-06-15 18:09:05 +0800301int ele_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530302{
Peng Fand5c31832023-06-15 18:09:05 +0800303 struct udevice *dev = gd->arch.ele_dev;
304 int size = sizeof(struct ele_msg);
305 struct ele_msg msg;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530306 int ret;
307
308 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800309 printf("ele dev is not initialized\n");
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530310 return -ENODEV;
311 }
312
313 if (!fw_version) {
314 printf("Invalid parameters for f/w version read\n");
315 return -EINVAL;
316 }
317
318 if (!sha1) {
319 printf("Invalid parameters for commit sha1\n");
320 return -EINVAL;
321 }
322
Peng Fand5c31832023-06-15 18:09:05 +0800323 msg.version = ELE_VERSION;
324 msg.tag = ELE_CMD_TAG;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530325 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800326 msg.command = ELE_GET_FW_VERSION_REQ;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530327
328 ret = misc_call(dev, false, &msg, size, &msg, size);
329 if (ret)
330 printf("Error: %s: ret %d, response 0x%x\n",
331 __func__, ret, msg.data[0]);
332
333 if (response)
334 *response = msg.data[0];
335
336 *fw_version = msg.data[1];
337 *sha1 = msg.data[2];
338
339 return ret;
340}
341
Peng Fand5c31832023-06-15 18:09:05 +0800342int ele_dump_buffer(u32 *buffer, u32 buffer_length)
Ye Li0a917da2022-04-06 14:30:20 +0800343{
Peng Fand5c31832023-06-15 18:09:05 +0800344 struct udevice *dev = gd->arch.ele_dev;
345 int size = sizeof(struct ele_msg);
346 struct ele_msg msg;
Ye Li0a917da2022-04-06 14:30:20 +0800347 int ret, i = 0;
348
349 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800350 printf("ele dev is not initialized\n");
Ye Li0a917da2022-04-06 14:30:20 +0800351 return -ENODEV;
352 }
353
Peng Fand5c31832023-06-15 18:09:05 +0800354 msg.version = ELE_VERSION;
355 msg.tag = ELE_CMD_TAG;
Ye Li0a917da2022-04-06 14:30:20 +0800356 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800357 msg.command = ELE_DUMP_DEBUG_BUFFER_REQ;
Ye Li0a917da2022-04-06 14:30:20 +0800358
359 ret = misc_call(dev, false, &msg, size, &msg, size);
360 if (ret) {
361 printf("Error: %s: ret %d, response 0x%x\n",
362 __func__, ret, msg.data[0]);
363
364 return ret;
365 }
366
367 if (buffer) {
368 buffer[i++] = *(u32 *)&msg; /* Need dump the response header */
369 for (; i < buffer_length && i < msg.size; i++)
370 buffer[i] = msg.data[i - 1];
371 }
372
373 return i;
374}
Peng Fancffe2b92022-07-26 16:40:52 +0800375
Peng Fand5c31832023-06-15 18:09:05 +0800376int ele_get_info(struct ele_get_info_data *info, u32 *response)
Peng Fancffe2b92022-07-26 16:40:52 +0800377{
Peng Fand5c31832023-06-15 18:09:05 +0800378 struct udevice *dev = gd->arch.ele_dev;
379 int size = sizeof(struct ele_msg);
380 struct ele_msg msg;
Peng Fancffe2b92022-07-26 16:40:52 +0800381 int ret;
382
383 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800384 printf("ele dev is not initialized\n");
Peng Fancffe2b92022-07-26 16:40:52 +0800385 return -ENODEV;
386 }
387
Peng Fand5c31832023-06-15 18:09:05 +0800388 msg.version = ELE_VERSION;
389 msg.tag = ELE_CMD_TAG;
Peng Fancffe2b92022-07-26 16:40:52 +0800390 msg.size = 4;
Ye Liebb2be52023-01-30 18:39:53 +0800391 msg.command = ELE_GET_INFO_REQ;
Peng Fancffe2b92022-07-26 16:40:52 +0800392 msg.data[0] = upper_32_bits((ulong)info);
393 msg.data[1] = lower_32_bits((ulong)info);
Peng Fand5c31832023-06-15 18:09:05 +0800394 msg.data[2] = sizeof(struct ele_get_info_data);
Peng Fancffe2b92022-07-26 16:40:52 +0800395
396 ret = misc_call(dev, false, &msg, size, &msg, size);
397 if (ret)
398 printf("Error: %s: ret %d, response 0x%x\n",
399 __func__, ret, msg.data[0]);
400
401 if (response)
402 *response = msg.data[0];
403
404 return ret;
405}
406
Peng Fand5c31832023-06-15 18:09:05 +0800407int ele_get_fw_status(u32 *status, u32 *response)
Peng Fancffe2b92022-07-26 16:40:52 +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;
Peng Fancffe2b92022-07-26 16:40:52 +0800412 int ret;
413
414 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800415 printf("ele dev is not initialized\n");
Peng Fancffe2b92022-07-26 16:40:52 +0800416 return -ENODEV;
417 }
418
Peng Fand5c31832023-06-15 18:09:05 +0800419 msg.version = ELE_VERSION;
420 msg.tag = ELE_CMD_TAG;
Peng Fancffe2b92022-07-26 16:40:52 +0800421 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800422 msg.command = ELE_GET_FW_STATUS_REQ;
Peng Fancffe2b92022-07-26 16:40:52 +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 if (response)
430 *response = msg.data[0];
431
432 *status = msg.data[1] & 0xF;
433
434 return ret;
435}
Peng Fanf6ff1402022-07-26 16:40:53 +0800436
Peng Fand5c31832023-06-15 18:09:05 +0800437int ele_release_m33_trout(void)
Peng Fanf6ff1402022-07-26 16:40:53 +0800438{
Peng Fand5c31832023-06-15 18:09:05 +0800439 struct udevice *dev = gd->arch.ele_dev;
440 int size = sizeof(struct ele_msg);
441 struct ele_msg msg;
Peng Fanf6ff1402022-07-26 16:40:53 +0800442 int ret;
443
444 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800445 printf("ele dev is not initialized\n");
Peng Fanf6ff1402022-07-26 16:40:53 +0800446 return -ENODEV;
447 }
448
Peng Fand5c31832023-06-15 18:09:05 +0800449 msg.version = ELE_VERSION;
450 msg.tag = ELE_CMD_TAG;
Peng Fanf6ff1402022-07-26 16:40:53 +0800451 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800452 msg.command = ELE_ENABLE_RTC_REQ;
Peng Fanf6ff1402022-07-26 16:40:53 +0800453
454 ret = misc_call(dev, false, &msg, size, &msg, size);
455 if (ret)
456 printf("Error: %s: ret %d, response 0x%x\n",
457 __func__, ret, msg.data[0]);
458
459 return ret;
460}
Ye Li395bfd42023-01-30 18:39:50 +0800461
Peng Fand5c31832023-06-15 18:09:05 +0800462int ele_get_events(u32 *events, u32 *events_cnt, u32 *response)
Ye Li395bfd42023-01-30 18:39:50 +0800463{
Peng Fand5c31832023-06-15 18:09:05 +0800464 struct udevice *dev = gd->arch.ele_dev;
465 int size = sizeof(struct ele_msg);
466 struct ele_msg msg;
Ye Li395bfd42023-01-30 18:39:50 +0800467 int ret, i = 0;
468 u32 actual_events;
469
470 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800471 printf("ele dev is not initialized\n");
Ye Li395bfd42023-01-30 18:39:50 +0800472 return -ENODEV;
473 }
474
475 if (!events || !events_cnt || *events_cnt == 0) {
476 printf("Invalid parameters for %s\n", __func__);
477 return -EINVAL;
478 }
479
Peng Fand5c31832023-06-15 18:09:05 +0800480 msg.version = ELE_VERSION;
481 msg.tag = ELE_CMD_TAG;
Ye Li395bfd42023-01-30 18:39:50 +0800482 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800483 msg.command = ELE_GET_EVENTS_REQ;
Ye Li395bfd42023-01-30 18:39:50 +0800484
485 ret = misc_call(dev, false, &msg, size, &msg, size);
486 if (ret)
487 printf("Error: %s: ret %d, response 0x%x\n",
488 __func__, ret, msg.data[0]);
489
490 if (response)
491 *response = msg.data[0];
492
493 if (!ret) {
494 actual_events = msg.data[1] & 0xffff;
495 if (*events_cnt < actual_events)
496 actual_events = *events_cnt;
497
498 for (; i < actual_events; i++)
499 events[i] = msg.data[i + 2];
500
501 *events_cnt = actual_events;
502 }
503
504 return ret;
505}
Peng Fanc88036d2023-06-15 18:09:08 +0800506
Peng Fanaa70b852023-06-15 18:09:14 +0800507int ele_start_rng(void)
508{
509 struct udevice *dev = gd->arch.ele_dev;
510 int size = sizeof(struct ele_msg);
511 struct ele_msg msg;
512 int ret;
513
514 if (!dev) {
515 printf("ele dev is not initialized\n");
516 return -ENODEV;
517 }
518
519 msg.version = ELE_VERSION;
520 msg.tag = ELE_CMD_TAG;
521 msg.size = 1;
522 msg.command = ELE_START_RNG;
523
524 ret = misc_call(dev, false, &msg, size, &msg, size);
525 if (ret)
526 printf("Error: %s: ret %d, response 0x%x\n",
527 __func__, ret, msg.data[0]);
528
529 return ret;
530}
531
Mathieu Othacehec6143392024-08-26 12:07:07 +0200532int ele_derive_huk(u8 *key, size_t key_size, u8 *seed, size_t seed_size)
533{
534 struct udevice *dev = gd->arch.ele_dev;
535 struct ele_msg msg;
536 int msg_size = sizeof(struct ele_msg);
537 u8 *seed_aligned, *key_aligned;
538 int ret, size;
539
540 if (!dev) {
541 printf("ele dev is not initialized\n");
542 return -ENODEV;
543 }
544
545 if (key_size != 16 && key_size != 32) {
546 printf("key size can only be 16 or 32\n");
547 return -EINVAL;
548 }
549
550 if (seed_size >= (1U << 16) - 1) {
551 printf("seed size is too large\n");
552 return -EINVAL;
553 }
554
555 seed_aligned = memalign(ARCH_DMA_MINALIGN, seed_size);
556 if (!seed_aligned) {
557 printf("failed to alloc memory\n");
558 return -EINVAL;
559 }
560 memcpy(seed_aligned, seed, seed_size);
561
562 key_aligned = memalign(ARCH_DMA_MINALIGN, key_size);
563 if (!key_aligned) {
564 printf("failed to alloc memory\n");
565 ret = -EINVAL;
566 goto ret_seed;
567 }
568
569 size = ALIGN(seed_size, ARCH_DMA_MINALIGN);
570 flush_dcache_range((ulong)seed_aligned,
571 (ulong)seed_aligned + size);
572
573 size = ALIGN(key_size, ARCH_DMA_MINALIGN);
574 invalidate_dcache_range((ulong)key_aligned,
575 (ulong)key_aligned + size);
576
577 msg.version = ELE_VERSION;
578 msg.tag = ELE_CMD_TAG;
579 msg.size = 7;
580 msg.command = ELE_CMD_DERIVE_KEY;
581 msg.data[0] = upper_32_bits((ulong)key_aligned);
582 msg.data[1] = lower_32_bits((ulong)key_aligned);
583 msg.data[2] = upper_32_bits((ulong)seed_aligned);
584 msg.data[3] = lower_32_bits((ulong)seed_aligned);
585 msg.data[4] = seed_size << 16 | key_size;
586 msg.data[5] = compute_crc(&msg);
587
588 ret = misc_call(dev, false, &msg, msg_size, &msg, msg_size);
589 if (ret) {
590 printf("Error: %s: ret %d, response 0x%x\n",
591 __func__, ret, msg.data[0]);
592 goto ret_key;
593 }
594
595 invalidate_dcache_range((ulong)key_aligned,
596 (ulong)key_aligned + size);
597 memcpy(key, key_aligned, key_size);
598
599ret_key:
600 free(key_aligned);
601ret_seed:
602 free(seed_aligned);
603
604 return ret;
605}
606
Mathieu Othacehe8df8e592024-03-21 08:19:53 +0100607int ele_commit(u16 fuse_id, u32 *response, u32 *info_type)
608{
609 struct udevice *dev = gd->arch.ele_dev;
610 int size = sizeof(struct ele_msg);
611 struct ele_msg msg;
612 int ret = 0;
613
614 if (!dev) {
615 printf("ele dev is not initialized\n");
616 return -ENODEV;
617 }
618
619 msg.version = ELE_VERSION;
620 msg.tag = ELE_CMD_TAG;
621 msg.size = 2;
622 msg.command = ELE_COMMIT_REQ;
623 msg.data[0] = fuse_id;
624
625 ret = misc_call(dev, false, &msg, size, &msg, size);
626 if (ret)
627 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
628 __func__, ret, fuse_id, msg.data[0]);
629
630 if (response)
631 *response = msg.data[0];
632
633 if (info_type)
634 *info_type = msg.data[1];
635
636 return ret;
637}
638
Peng Fanc88036d2023-06-15 18:09:08 +0800639int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response)
640{
641 struct udevice *dev = gd->arch.ele_dev;
642 int size = sizeof(struct ele_msg);
643 struct ele_msg msg;
644 int ret;
645
646 if (!dev) {
647 printf("ele dev is not initialized\n");
648 return -ENODEV;
649 }
650
651 msg.version = ELE_VERSION;
652 msg.tag = ELE_CMD_TAG;
653 msg.size = 3;
654 msg.command = ELE_WRITE_SECURE_FUSE_REQ;
655
656 msg.data[0] = upper_32_bits(signed_msg_blk);
657 msg.data[1] = lower_32_bits(signed_msg_blk);
658
659 ret = misc_call(dev, false, &msg, size, &msg, size);
660 if (ret)
661 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
662 __func__, ret, msg.data[0], msg.data[1]);
663
664 if (response)
665 *response = msg.data[0];
666
667 return ret;
668}
669
670int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response)
671{
672 struct udevice *dev = gd->arch.ele_dev;
673 int size = sizeof(struct ele_msg);
674 struct ele_msg msg;
675 int ret;
676
677 if (!dev) {
678 printf("ele dev is not initialized\n");
679 return -ENODEV;
680 }
681
682 msg.version = ELE_VERSION;
683 msg.tag = ELE_CMD_TAG;
684 msg.size = 3;
685 msg.command = ELE_RET_LIFECYCLE_UP_REQ;
686
687 msg.data[0] = upper_32_bits(signed_msg_blk);
688 msg.data[1] = lower_32_bits(signed_msg_blk);
689
690 ret = misc_call(dev, false, &msg, size, &msg, size);
691 if (ret)
692 printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
693 __func__, ret, msg.data[0], msg.data[1]);
694
695 if (response)
696 *response = msg.data[0];
697
698 return ret;
699}
Peng Fan16426c82023-06-15 18:09:09 +0800700
701int ele_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr, u32 max_output_size)
702{
703 struct udevice *dev = gd->arch.ele_dev;
704 int size = sizeof(struct ele_msg);
705 struct ele_msg msg;
706 int ret;
707
708 if (!dev) {
709 printf("ele dev is not initialized\n");
710 return -ENODEV;
711 }
712
713 msg.version = ELE_VERSION;
714 msg.tag = ELE_CMD_TAG;
715 msg.size = 8;
716 msg.command = ELE_GENERATE_DEK_BLOB;
717 msg.data[0] = key_id;
718 msg.data[1] = 0x0;
719 msg.data[2] = src_paddr;
720 msg.data[3] = 0x0;
721 msg.data[4] = dst_paddr;
722 msg.data[5] = max_output_size;
723 msg.data[6] = compute_crc(&msg);
724
725 ret = misc_call(dev, false, &msg, size, &msg, size);
726 if (ret)
727 printf("Error: %s: ret 0x%x, response 0x%x\n",
728 __func__, ret, msg.data[0]);
729
730 return ret;
731}