blob: 56605714f444a89a688793303de4044aeb4b4bec [file] [log] [blame]
Ye Li0db17f42021-08-07 16:00:41 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2020 NXP
4 *
5 */
6
7#include <common.h>
8#include <hang.h>
9#include <malloc.h>
10#include <asm/io.h>
11#include <dm.h>
Peng Fand5c31832023-06-15 18:09:05 +080012#include <asm/mach-imx/ele_api.h>
Ye Li0db17f42021-08-07 16:00:41 +080013#include <misc.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
Peng Fand5c31832023-06-15 18:09:05 +080017int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response)
Ye Li0db17f42021-08-07 16:00:41 +080018{
Peng Fand5c31832023-06-15 18:09:05 +080019 struct udevice *dev = gd->arch.ele_dev;
20 int size = sizeof(struct ele_msg);
21 struct ele_msg msg;
Ye Li0db17f42021-08-07 16:00:41 +080022 int ret;
23
24 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +080025 printf("ele dev is not initialized\n");
Ye Li0db17f42021-08-07 16:00:41 +080026 return -ENODEV;
27 }
28
Peng Fand5c31832023-06-15 18:09:05 +080029 msg.version = ELE_VERSION;
30 msg.tag = ELE_CMD_TAG;
Ye Li0db17f42021-08-07 16:00:41 +080031 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +080032 msg.command = ELE_RELEASE_RDC_REQ;
Ye Lid4b3ba32022-07-26 16:40:51 +080033 switch (xrdc) {
34 case 0:
Ye Liacc9afe2021-08-07 16:00:53 +080035 msg.data[0] = (0x74 << 8) | core_id;
Ye Lid4b3ba32022-07-26 16:40:51 +080036 break;
37 case 1:
38 msg.data[0] = (0x78 << 8) | core_id;
39 break;
40 case 2:
41 msg.data[0] = (0x82 << 8) | core_id;
42 break;
43 case 3:
44 msg.data[0] = (0x86 << 8) | core_id;
45 break;
46 default:
47 printf("Error: wrong xrdc index %u\n", xrdc);
48 return -EINVAL;
49 }
Ye Li0db17f42021-08-07 16:00:41 +080050
51 ret = misc_call(dev, false, &msg, size, &msg, size);
52 if (ret)
53 printf("Error: %s: ret %d, core id %u, response 0x%x\n",
54 __func__, ret, core_id, msg.data[0]);
55
Ye Lia61f2672021-08-07 16:00:52 +080056 if (response)
57 *response = msg.data[0];
58
59 return ret;
60}
61
Peng Fand5c31832023-06-15 18:09:05 +080062int ele_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +080063{
Peng Fand5c31832023-06-15 18:09:05 +080064 struct udevice *dev = gd->arch.ele_dev;
65 int size = sizeof(struct ele_msg);
66 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +080067 int ret;
68
69 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +080070 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +080071 return -ENODEV;
72 }
73
Peng Fand5c31832023-06-15 18:09:05 +080074 msg.version = ELE_VERSION;
75 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +080076 msg.size = 3;
Ye Liebb2be52023-01-30 18:39:53 +080077 msg.command = ELE_OEM_CNTN_AUTH_REQ;
Ye Lia61f2672021-08-07 16:00:52 +080078 msg.data[0] = upper_32_bits(ctnr_addr);
79 msg.data[1] = lower_32_bits(ctnr_addr);
80
81 ret = misc_call(dev, false, &msg, size, &msg, size);
82 if (ret)
83 printf("Error: %s: ret %d, cntr_addr 0x%lx, response 0x%x\n",
84 __func__, ret, ctnr_addr, msg.data[0]);
85
86 if (response)
87 *response = msg.data[0];
88
89 return ret;
90}
91
Peng Fand5c31832023-06-15 18:09:05 +080092int ele_release_container(u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +080093{
Peng Fand5c31832023-06-15 18:09:05 +080094 struct udevice *dev = gd->arch.ele_dev;
95 int size = sizeof(struct ele_msg);
96 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +080097 int ret;
98
99 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800100 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +0800101 return -ENODEV;
102 }
103
Peng Fand5c31832023-06-15 18:09:05 +0800104 msg.version = ELE_VERSION;
105 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +0800106 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800107 msg.command = ELE_RELEASE_CONTAINER_REQ;
Ye Lia61f2672021-08-07 16:00:52 +0800108
109 ret = misc_call(dev, false, &msg, size, &msg, size);
110 if (ret)
111 printf("Error: %s: ret %d, response 0x%x\n",
112 __func__, ret, msg.data[0]);
113
114 if (response)
115 *response = msg.data[0];
116
117 return ret;
118}
119
Peng Fand5c31832023-06-15 18:09:05 +0800120int ele_verify_image(u32 img_id, u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +0800121{
Peng Fand5c31832023-06-15 18:09:05 +0800122 struct udevice *dev = gd->arch.ele_dev;
123 int size = sizeof(struct ele_msg);
124 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +0800125 int ret;
126
127 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800128 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +0800129 return -ENODEV;
130 }
131
Peng Fand5c31832023-06-15 18:09:05 +0800132 msg.version = ELE_VERSION;
133 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +0800134 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800135 msg.command = ELE_VERIFY_IMAGE_REQ;
Ye Lia61f2672021-08-07 16:00:52 +0800136 msg.data[0] = 1 << img_id;
137
138 ret = misc_call(dev, false, &msg, size, &msg, size);
139 if (ret)
140 printf("Error: %s: ret %d, img_id %u, response 0x%x\n",
141 __func__, ret, img_id, msg.data[0]);
142
143 if (response)
144 *response = msg.data[0];
145
146 return ret;
147}
148
Peng Fand5c31832023-06-15 18:09:05 +0800149int ele_forward_lifecycle(u16 life_cycle, u32 *response)
Ye Lia61f2672021-08-07 16:00:52 +0800150{
Peng Fand5c31832023-06-15 18:09:05 +0800151 struct udevice *dev = gd->arch.ele_dev;
152 int size = sizeof(struct ele_msg);
153 struct ele_msg msg;
Ye Lia61f2672021-08-07 16:00:52 +0800154 int ret;
155
156 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800157 printf("ele dev is not initialized\n");
Ye Lia61f2672021-08-07 16:00:52 +0800158 return -ENODEV;
159 }
160
Peng Fand5c31832023-06-15 18:09:05 +0800161 msg.version = ELE_VERSION;
162 msg.tag = ELE_CMD_TAG;
Ye Lia61f2672021-08-07 16:00:52 +0800163 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800164 msg.command = ELE_FWD_LIFECYCLE_UP_REQ;
Ye Lia61f2672021-08-07 16:00:52 +0800165 msg.data[0] = life_cycle;
166
167 ret = misc_call(dev, false, &msg, size, &msg, size);
168 if (ret)
169 printf("Error: %s: ret %d, life_cycle 0x%x, response 0x%x\n",
170 __func__, ret, life_cycle, msg.data[0]);
171
172 if (response)
173 *response = msg.data[0];
174
Ye Li0db17f42021-08-07 16:00:41 +0800175 return ret;
176}
Ye Lif80a41b2021-08-07 16:00:54 +0800177
Peng Fand5c31832023-06-15 18:09:05 +0800178int ele_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
Ye Lif80a41b2021-08-07 16:00:54 +0800179{
Peng Fand5c31832023-06-15 18:09:05 +0800180 struct udevice *dev = gd->arch.ele_dev;
181 int size = sizeof(struct ele_msg);
182 struct ele_msg msg;
Ye Lif80a41b2021-08-07 16:00:54 +0800183 int ret;
184
185 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800186 printf("ele dev is not initialized\n");
Ye Lif80a41b2021-08-07 16:00:54 +0800187 return -ENODEV;
188 }
189
190 if (!fuse_words) {
191 printf("Invalid parameters for fuse read\n");
192 return -EINVAL;
193 }
194
195 if ((fuse_id != 1 && fuse_num != 1) ||
196 (fuse_id == 1 && fuse_num != 4)) {
197 printf("Invalid fuse number parameter\n");
198 return -EINVAL;
199 }
200
Peng Fand5c31832023-06-15 18:09:05 +0800201 msg.version = ELE_VERSION;
202 msg.tag = ELE_CMD_TAG;
Ye Lif80a41b2021-08-07 16:00:54 +0800203 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800204 msg.command = ELE_READ_FUSE_REQ;
Ye Lif80a41b2021-08-07 16:00:54 +0800205 msg.data[0] = fuse_id;
206
207 ret = misc_call(dev, false, &msg, size, &msg, size);
208 if (ret)
209 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
210 __func__, ret, fuse_id, msg.data[0]);
211
212 if (response)
213 *response = msg.data[0];
214
215 fuse_words[0] = msg.data[1];
216 if (fuse_id == 1) {
217 /* OTP_UNIQ_ID */
218 fuse_words[1] = msg.data[2];
219 fuse_words[2] = msg.data[3];
220 fuse_words[3] = msg.data[4];
221 }
222
223 return ret;
224}
225
Peng Fand5c31832023-06-15 18:09:05 +0800226int ele_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
Ye Lif80a41b2021-08-07 16:00:54 +0800227{
Peng Fand5c31832023-06-15 18:09:05 +0800228 struct udevice *dev = gd->arch.ele_dev;
229 int size = sizeof(struct ele_msg);
230 struct ele_msg msg;
Ye Lif80a41b2021-08-07 16:00:54 +0800231 int ret;
232
233 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800234 printf("ele dev is not initialized\n");
Ye Lif80a41b2021-08-07 16:00:54 +0800235 return -ENODEV;
236 }
237
Peng Fand5c31832023-06-15 18:09:05 +0800238 msg.version = ELE_VERSION;
239 msg.tag = ELE_CMD_TAG;
Ye Lif80a41b2021-08-07 16:00:54 +0800240 msg.size = 3;
Ye Liebb2be52023-01-30 18:39:53 +0800241 msg.command = ELE_WRITE_FUSE_REQ;
Ye Lif80a41b2021-08-07 16:00:54 +0800242 msg.data[0] = (32 << 16) | (fuse_id << 5);
243 if (lock)
244 msg.data[0] |= (1 << 31);
245
246 msg.data[1] = fuse_val;
247
248 ret = misc_call(dev, false, &msg, size, &msg, size);
249 if (ret)
250 printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
251 __func__, ret, fuse_id, msg.data[0]);
252
253 if (response)
254 *response = msg.data[0];
255
256 return ret;
257}
Clement Faure26386ae2022-04-06 14:30:19 +0800258
Peng Fand5c31832023-06-15 18:09:05 +0800259int ele_release_caam(u32 core_did, u32 *response)
Clement Faure26386ae2022-04-06 14:30:19 +0800260{
Peng Fand5c31832023-06-15 18:09:05 +0800261 struct udevice *dev = gd->arch.ele_dev;
262 int size = sizeof(struct ele_msg);
263 struct ele_msg msg;
Clement Faure26386ae2022-04-06 14:30:19 +0800264 int ret;
265
266 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800267 printf("ele dev is not initialized\n");
Clement Faure26386ae2022-04-06 14:30:19 +0800268 return -ENODEV;
269 }
270
Peng Fand5c31832023-06-15 18:09:05 +0800271 msg.version = ELE_VERSION;
272 msg.tag = ELE_CMD_TAG;
Clement Faure26386ae2022-04-06 14:30:19 +0800273 msg.size = 2;
Ye Liebb2be52023-01-30 18:39:53 +0800274 msg.command = ELE_RELEASE_CAAM_REQ;
Clement Faure26386ae2022-04-06 14:30:19 +0800275 msg.data[0] = core_did;
276
277 ret = misc_call(dev, false, &msg, size, &msg, size);
278 if (ret)
279 printf("Error: %s: ret %d, response 0x%x\n",
280 __func__, ret, msg.data[0]);
281
282 if (response)
283 *response = msg.data[0];
284
285 return ret;
286}
Ye Li0a917da2022-04-06 14:30:20 +0800287
Peng Fand5c31832023-06-15 18:09:05 +0800288int ele_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530289{
Peng Fand5c31832023-06-15 18:09:05 +0800290 struct udevice *dev = gd->arch.ele_dev;
291 int size = sizeof(struct ele_msg);
292 struct ele_msg msg;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530293 int ret;
294
295 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800296 printf("ele dev is not initialized\n");
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530297 return -ENODEV;
298 }
299
300 if (!fw_version) {
301 printf("Invalid parameters for f/w version read\n");
302 return -EINVAL;
303 }
304
305 if (!sha1) {
306 printf("Invalid parameters for commit sha1\n");
307 return -EINVAL;
308 }
309
Peng Fand5c31832023-06-15 18:09:05 +0800310 msg.version = ELE_VERSION;
311 msg.tag = ELE_CMD_TAG;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530312 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800313 msg.command = ELE_GET_FW_VERSION_REQ;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530314
315 ret = misc_call(dev, false, &msg, size, &msg, size);
316 if (ret)
317 printf("Error: %s: ret %d, response 0x%x\n",
318 __func__, ret, msg.data[0]);
319
320 if (response)
321 *response = msg.data[0];
322
323 *fw_version = msg.data[1];
324 *sha1 = msg.data[2];
325
326 return ret;
327}
328
Peng Fand5c31832023-06-15 18:09:05 +0800329int ele_dump_buffer(u32 *buffer, u32 buffer_length)
Ye Li0a917da2022-04-06 14:30:20 +0800330{
Peng Fand5c31832023-06-15 18:09:05 +0800331 struct udevice *dev = gd->arch.ele_dev;
332 int size = sizeof(struct ele_msg);
333 struct ele_msg msg;
Ye Li0a917da2022-04-06 14:30:20 +0800334 int ret, i = 0;
335
336 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800337 printf("ele dev is not initialized\n");
Ye Li0a917da2022-04-06 14:30:20 +0800338 return -ENODEV;
339 }
340
Peng Fand5c31832023-06-15 18:09:05 +0800341 msg.version = ELE_VERSION;
342 msg.tag = ELE_CMD_TAG;
Ye Li0a917da2022-04-06 14:30:20 +0800343 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800344 msg.command = ELE_DUMP_DEBUG_BUFFER_REQ;
Ye Li0a917da2022-04-06 14:30:20 +0800345
346 ret = misc_call(dev, false, &msg, size, &msg, size);
347 if (ret) {
348 printf("Error: %s: ret %d, response 0x%x\n",
349 __func__, ret, msg.data[0]);
350
351 return ret;
352 }
353
354 if (buffer) {
355 buffer[i++] = *(u32 *)&msg; /* Need dump the response header */
356 for (; i < buffer_length && i < msg.size; i++)
357 buffer[i] = msg.data[i - 1];
358 }
359
360 return i;
361}
Peng Fancffe2b92022-07-26 16:40:52 +0800362
Peng Fand5c31832023-06-15 18:09:05 +0800363int ele_get_info(struct ele_get_info_data *info, u32 *response)
Peng Fancffe2b92022-07-26 16:40:52 +0800364{
Peng Fand5c31832023-06-15 18:09:05 +0800365 struct udevice *dev = gd->arch.ele_dev;
366 int size = sizeof(struct ele_msg);
367 struct ele_msg msg;
Peng Fancffe2b92022-07-26 16:40:52 +0800368 int ret;
369
370 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800371 printf("ele dev is not initialized\n");
Peng Fancffe2b92022-07-26 16:40:52 +0800372 return -ENODEV;
373 }
374
Peng Fand5c31832023-06-15 18:09:05 +0800375 msg.version = ELE_VERSION;
376 msg.tag = ELE_CMD_TAG;
Peng Fancffe2b92022-07-26 16:40:52 +0800377 msg.size = 4;
Ye Liebb2be52023-01-30 18:39:53 +0800378 msg.command = ELE_GET_INFO_REQ;
Peng Fancffe2b92022-07-26 16:40:52 +0800379 msg.data[0] = upper_32_bits((ulong)info);
380 msg.data[1] = lower_32_bits((ulong)info);
Peng Fand5c31832023-06-15 18:09:05 +0800381 msg.data[2] = sizeof(struct ele_get_info_data);
Peng Fancffe2b92022-07-26 16:40:52 +0800382
383 ret = misc_call(dev, false, &msg, size, &msg, size);
384 if (ret)
385 printf("Error: %s: ret %d, response 0x%x\n",
386 __func__, ret, msg.data[0]);
387
388 if (response)
389 *response = msg.data[0];
390
391 return ret;
392}
393
Peng Fand5c31832023-06-15 18:09:05 +0800394int ele_get_fw_status(u32 *status, u32 *response)
Peng Fancffe2b92022-07-26 16:40:52 +0800395{
Peng Fand5c31832023-06-15 18:09:05 +0800396 struct udevice *dev = gd->arch.ele_dev;
397 int size = sizeof(struct ele_msg);
398 struct ele_msg msg;
Peng Fancffe2b92022-07-26 16:40:52 +0800399 int ret;
400
401 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800402 printf("ele dev is not initialized\n");
Peng Fancffe2b92022-07-26 16:40:52 +0800403 return -ENODEV;
404 }
405
Peng Fand5c31832023-06-15 18:09:05 +0800406 msg.version = ELE_VERSION;
407 msg.tag = ELE_CMD_TAG;
Peng Fancffe2b92022-07-26 16:40:52 +0800408 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800409 msg.command = ELE_GET_FW_STATUS_REQ;
Peng Fancffe2b92022-07-26 16:40:52 +0800410
411 ret = misc_call(dev, false, &msg, size, &msg, size);
412 if (ret)
413 printf("Error: %s: ret %d, response 0x%x\n",
414 __func__, ret, msg.data[0]);
415
416 if (response)
417 *response = msg.data[0];
418
419 *status = msg.data[1] & 0xF;
420
421 return ret;
422}
Peng Fanf6ff1402022-07-26 16:40:53 +0800423
Peng Fand5c31832023-06-15 18:09:05 +0800424int ele_release_m33_trout(void)
Peng Fanf6ff1402022-07-26 16:40:53 +0800425{
Peng Fand5c31832023-06-15 18:09:05 +0800426 struct udevice *dev = gd->arch.ele_dev;
427 int size = sizeof(struct ele_msg);
428 struct ele_msg msg;
Peng Fanf6ff1402022-07-26 16:40:53 +0800429 int ret;
430
431 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800432 printf("ele dev is not initialized\n");
Peng Fanf6ff1402022-07-26 16:40:53 +0800433 return -ENODEV;
434 }
435
Peng Fand5c31832023-06-15 18:09:05 +0800436 msg.version = ELE_VERSION;
437 msg.tag = ELE_CMD_TAG;
Peng Fanf6ff1402022-07-26 16:40:53 +0800438 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800439 msg.command = ELE_ENABLE_RTC_REQ;
Peng Fanf6ff1402022-07-26 16:40:53 +0800440
441 ret = misc_call(dev, false, &msg, size, &msg, size);
442 if (ret)
443 printf("Error: %s: ret %d, response 0x%x\n",
444 __func__, ret, msg.data[0]);
445
446 return ret;
447}
Ye Li395bfd42023-01-30 18:39:50 +0800448
Peng Fand5c31832023-06-15 18:09:05 +0800449int ele_get_events(u32 *events, u32 *events_cnt, u32 *response)
Ye Li395bfd42023-01-30 18:39:50 +0800450{
Peng Fand5c31832023-06-15 18:09:05 +0800451 struct udevice *dev = gd->arch.ele_dev;
452 int size = sizeof(struct ele_msg);
453 struct ele_msg msg;
Ye Li395bfd42023-01-30 18:39:50 +0800454 int ret, i = 0;
455 u32 actual_events;
456
457 if (!dev) {
Peng Fand5c31832023-06-15 18:09:05 +0800458 printf("ele dev is not initialized\n");
Ye Li395bfd42023-01-30 18:39:50 +0800459 return -ENODEV;
460 }
461
462 if (!events || !events_cnt || *events_cnt == 0) {
463 printf("Invalid parameters for %s\n", __func__);
464 return -EINVAL;
465 }
466
Peng Fand5c31832023-06-15 18:09:05 +0800467 msg.version = ELE_VERSION;
468 msg.tag = ELE_CMD_TAG;
Ye Li395bfd42023-01-30 18:39:50 +0800469 msg.size = 1;
Ye Liebb2be52023-01-30 18:39:53 +0800470 msg.command = ELE_GET_EVENTS_REQ;
Ye Li395bfd42023-01-30 18:39:50 +0800471
472 ret = misc_call(dev, false, &msg, size, &msg, size);
473 if (ret)
474 printf("Error: %s: ret %d, response 0x%x\n",
475 __func__, ret, msg.data[0]);
476
477 if (response)
478 *response = msg.data[0];
479
480 if (!ret) {
481 actual_events = msg.data[1] & 0xffff;
482 if (*events_cnt < actual_events)
483 actual_events = *events_cnt;
484
485 for (; i < actual_events; i++)
486 events[i] = msg.data[i + 2];
487
488 *events_cnt = actual_events;
489 }
490
491 return ret;
492}