1 // 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>
12 #include <asm/mach-imx/s400_api.h>
13 #include <misc.h>
14 
15 DECLARE_GLOBAL_DATA_PTR;
16 
ahab_release_rdc(u8 core_id,u8 xrdc,u32 * response)17 int ahab_release_rdc(u8 core_id, u8 xrdc, u32 *response)
18 {
19 	struct udevice *dev = gd->arch.s400_dev;
20 	int size = sizeof(struct sentinel_msg);
21 	struct sentinel_msg msg;
22 	int ret;
23 
24 	if (!dev) {
25 		printf("s400 dev is not initialized\n");
26 		return -ENODEV;
27 	}
28 
29 	msg.version = AHAB_VERSION;
30 	msg.tag = AHAB_CMD_TAG;
31 	msg.size = 2;
32 	msg.command = ELE_RELEASE_RDC_REQ;
33 	switch (xrdc) {
34 	case 0:
35 		msg.data[0] = (0x74 << 8) | core_id;
36 		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 	}
50 
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 
56 	if (response)
57 		*response = msg.data[0];
58 
59 	return ret;
60 }
61 
ahab_auth_oem_ctnr(ulong ctnr_addr,u32 * response)62 int ahab_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
63 {
64 	struct udevice *dev = gd->arch.s400_dev;
65 	int size = sizeof(struct sentinel_msg);
66 	struct sentinel_msg msg;
67 	int ret;
68 
69 	if (!dev) {
70 		printf("s400 dev is not initialized\n");
71 		return -ENODEV;
72 	}
73 
74 	msg.version = AHAB_VERSION;
75 	msg.tag = AHAB_CMD_TAG;
76 	msg.size = 3;
77 	msg.command = ELE_OEM_CNTN_AUTH_REQ;
78 	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 
ahab_release_container(u32 * response)92 int ahab_release_container(u32 *response)
93 {
94 	struct udevice *dev = gd->arch.s400_dev;
95 	int size = sizeof(struct sentinel_msg);
96 	struct sentinel_msg msg;
97 	int ret;
98 
99 	if (!dev) {
100 		printf("s400 dev is not initialized\n");
101 		return -ENODEV;
102 	}
103 
104 	msg.version = AHAB_VERSION;
105 	msg.tag = AHAB_CMD_TAG;
106 	msg.size = 1;
107 	msg.command = ELE_RELEASE_CONTAINER_REQ;
108 
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 
ahab_verify_image(u32 img_id,u32 * response)120 int ahab_verify_image(u32 img_id, u32 *response)
121 {
122 	struct udevice *dev = gd->arch.s400_dev;
123 	int size = sizeof(struct sentinel_msg);
124 	struct sentinel_msg msg;
125 	int ret;
126 
127 	if (!dev) {
128 		printf("s400 dev is not initialized\n");
129 		return -ENODEV;
130 	}
131 
132 	msg.version = AHAB_VERSION;
133 	msg.tag = AHAB_CMD_TAG;
134 	msg.size = 2;
135 	msg.command = ELE_VERIFY_IMAGE_REQ;
136 	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 
ahab_forward_lifecycle(u16 life_cycle,u32 * response)149 int ahab_forward_lifecycle(u16 life_cycle, u32 *response)
150 {
151 	struct udevice *dev = gd->arch.s400_dev;
152 	int size = sizeof(struct sentinel_msg);
153 	struct sentinel_msg msg;
154 	int ret;
155 
156 	if (!dev) {
157 		printf("s400 dev is not initialized\n");
158 		return -ENODEV;
159 	}
160 
161 	msg.version = AHAB_VERSION;
162 	msg.tag = AHAB_CMD_TAG;
163 	msg.size = 2;
164 	msg.command = ELE_FWD_LIFECYCLE_UP_REQ;
165 	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 
175 	return ret;
176 }
177 
ahab_read_common_fuse(u16 fuse_id,u32 * fuse_words,u32 fuse_num,u32 * response)178 int ahab_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
179 {
180 	struct udevice *dev = gd->arch.s400_dev;
181 	int size = sizeof(struct sentinel_msg);
182 	struct sentinel_msg msg;
183 	int ret;
184 
185 	if (!dev) {
186 		printf("s400 dev is not initialized\n");
187 		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 
201 	msg.version = AHAB_VERSION;
202 	msg.tag = AHAB_CMD_TAG;
203 	msg.size = 2;
204 	msg.command = ELE_READ_FUSE_REQ;
205 	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 
ahab_write_fuse(u16 fuse_id,u32 fuse_val,bool lock,u32 * response)226 int ahab_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
227 {
228 	struct udevice *dev = gd->arch.s400_dev;
229 	int size = sizeof(struct sentinel_msg);
230 	struct sentinel_msg msg;
231 	int ret;
232 
233 	if (!dev) {
234 		printf("s400 dev is not initialized\n");
235 		return -ENODEV;
236 	}
237 
238 	msg.version = AHAB_VERSION;
239 	msg.tag = AHAB_CMD_TAG;
240 	msg.size = 3;
241 	msg.command = ELE_WRITE_FUSE_REQ;
242 	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 }
258 
ahab_release_caam(u32 core_did,u32 * response)259 int ahab_release_caam(u32 core_did, u32 *response)
260 {
261 	struct udevice *dev = gd->arch.s400_dev;
262 	int size = sizeof(struct sentinel_msg);
263 	struct sentinel_msg msg;
264 	int ret;
265 
266 	if (!dev) {
267 		printf("s400 dev is not initialized\n");
268 		return -ENODEV;
269 	}
270 
271 	msg.version = AHAB_VERSION;
272 	msg.tag = AHAB_CMD_TAG;
273 	msg.size = 2;
274 	msg.command = ELE_RELEASE_CAAM_REQ;
275 	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 }
287 
ahab_get_fw_version(u32 * fw_version,u32 * sha1,u32 * response)288 int ahab_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
289 {
290 	struct udevice *dev = gd->arch.s400_dev;
291 	int size = sizeof(struct sentinel_msg);
292 	struct sentinel_msg msg;
293 	int ret;
294 
295 	if (!dev) {
296 		printf("s400 dev is not initialized\n");
297 		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 
310 	msg.version = AHAB_VERSION;
311 	msg.tag = AHAB_CMD_TAG;
312 	msg.size = 1;
313 	msg.command = ELE_GET_FW_VERSION_REQ;
314 
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 
ahab_dump_buffer(u32 * buffer,u32 buffer_length)329 int ahab_dump_buffer(u32 *buffer, u32 buffer_length)
330 {
331 	struct udevice *dev = gd->arch.s400_dev;
332 	int size = sizeof(struct sentinel_msg);
333 	struct sentinel_msg msg;
334 	int ret, i = 0;
335 
336 	if (!dev) {
337 		printf("s400 dev is not initialized\n");
338 		return -ENODEV;
339 	}
340 
341 	msg.version = AHAB_VERSION;
342 	msg.tag = AHAB_CMD_TAG;
343 	msg.size = 1;
344 	msg.command = ELE_DUMP_DEBUG_BUFFER_REQ;
345 
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 }
362 
ahab_get_info(struct sentinel_get_info_data * info,u32 * response)363 int ahab_get_info(struct sentinel_get_info_data *info, u32 *response)
364 {
365 	struct udevice *dev = gd->arch.s400_dev;
366 	int size = sizeof(struct sentinel_msg);
367 	struct sentinel_msg msg;
368 	int ret;
369 
370 	if (!dev) {
371 		printf("s400 dev is not initialized\n");
372 		return -ENODEV;
373 	}
374 
375 	msg.version = AHAB_VERSION;
376 	msg.tag = AHAB_CMD_TAG;
377 	msg.size = 4;
378 	msg.command = ELE_GET_INFO_REQ;
379 	msg.data[0] = upper_32_bits((ulong)info);
380 	msg.data[1] = lower_32_bits((ulong)info);
381 	msg.data[2] = sizeof(struct sentinel_get_info_data);
382 
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 
ahab_get_fw_status(u32 * status,u32 * response)394 int ahab_get_fw_status(u32 *status, u32 *response)
395 {
396 	struct udevice *dev = gd->arch.s400_dev;
397 	int size = sizeof(struct sentinel_msg);
398 	struct sentinel_msg msg;
399 	int ret;
400 
401 	if (!dev) {
402 		printf("s400 dev is not initialized\n");
403 		return -ENODEV;
404 	}
405 
406 	msg.version = AHAB_VERSION;
407 	msg.tag = AHAB_CMD_TAG;
408 	msg.size = 1;
409 	msg.command = ELE_GET_FW_STATUS_REQ;
410 
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 }
423 
ahab_release_m33_trout(void)424 int ahab_release_m33_trout(void)
425 {
426 	struct udevice *dev = gd->arch.s400_dev;
427 	int size = sizeof(struct sentinel_msg);
428 	struct sentinel_msg msg;
429 	int ret;
430 
431 	if (!dev) {
432 		printf("s400 dev is not initialized\n");
433 		return -ENODEV;
434 	}
435 
436 	msg.version = AHAB_VERSION;
437 	msg.tag = AHAB_CMD_TAG;
438 	msg.size = 1;
439 	msg.command = ELE_ENABLE_RTC_REQ;
440 
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 }
448 
ahab_get_events(u32 * events,u32 * events_cnt,u32 * response)449 int ahab_get_events(u32 *events, u32 *events_cnt, u32 *response)
450 {
451 	struct udevice *dev = gd->arch.s400_dev;
452 	int size = sizeof(struct sentinel_msg);
453 	struct sentinel_msg msg;
454 	int ret, i = 0;
455 	u32 actual_events;
456 
457 	if (!dev) {
458 		printf("s400 dev is not initialized\n");
459 		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 
467 	msg.version = AHAB_VERSION;
468 	msg.tag = AHAB_CMD_TAG;
469 	msg.size = 1;
470 	msg.command = ELE_GET_EVENTS_REQ;
471 
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 }
493