blob: 4e90171420f91712b555bab9285bcf90cbf77e1c [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>
Ye Lic408ed32022-07-26 16:40:49 +080012#include <asm/mach-imx/s400_api.h>
Ye Li0db17f42021-08-07 16:00:41 +080013#include <misc.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
Ye Lid4b3ba32022-07-26 16:40:51 +080017int ahab_release_rdc(u8 core_id, u8 xrdc, u32 *response)
Ye Li0db17f42021-08-07 16:00:41 +080018{
19 struct udevice *dev = gd->arch.s400_dev;
20 int size = sizeof(struct imx8ulp_s400_msg);
21 struct imx8ulp_s400_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 = AHAB_RELEASE_RDC_REQ_CID;
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
62int ahab_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
63{
64 struct udevice *dev = gd->arch.s400_dev;
65 int size = sizeof(struct imx8ulp_s400_msg);
66 struct imx8ulp_s400_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 = AHAB_AUTH_OEM_CTNR_CID;
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
92int ahab_release_container(u32 *response)
93{
94 struct udevice *dev = gd->arch.s400_dev;
95 int size = sizeof(struct imx8ulp_s400_msg);
96 struct imx8ulp_s400_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 = AHAB_RELEASE_CTNR_CID;
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
120int ahab_verify_image(u32 img_id, u32 *response)
121{
122 struct udevice *dev = gd->arch.s400_dev;
123 int size = sizeof(struct imx8ulp_s400_msg);
124 struct imx8ulp_s400_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 = AHAB_VERIFY_IMG_CID;
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
149int ahab_forward_lifecycle(u16 life_cycle, u32 *response)
150{
151 struct udevice *dev = gd->arch.s400_dev;
152 int size = sizeof(struct imx8ulp_s400_msg);
153 struct imx8ulp_s400_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 = AHAB_FWD_LIFECYCLE_UP_REQ_CID;
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
Ye Li0db17f42021-08-07 16:00:41 +0800175 return ret;
176}
Ye Lif80a41b2021-08-07 16:00:54 +0800177
178int 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 imx8ulp_s400_msg);
182 struct imx8ulp_s400_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 = AHAB_READ_FUSE_REQ_CID;
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
226int 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 imx8ulp_s400_msg);
230 struct imx8ulp_s400_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 = AHAB_WRITE_FUSE_REQ_CID;
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}
Clement Faure26386ae2022-04-06 14:30:19 +0800258
259int ahab_release_caam(u32 core_did, u32 *response)
260{
261 struct udevice *dev = gd->arch.s400_dev;
262 int size = sizeof(struct imx8ulp_s400_msg);
263 struct imx8ulp_s400_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 = AHAB_CAAM_RELEASE_CID;
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}
Ye Li0a917da2022-04-06 14:30:20 +0800287
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530288int ahab_get_fw_version(u32 *fw_version, u32 *sha1, u32 *response)
289{
290 struct udevice *dev = gd->arch.s400_dev;
Ye Lic408ed32022-07-26 16:40:49 +0800291 int size = sizeof(struct sentinel_msg);
292 struct sentinel_msg msg;
Gaurav Jain580cc7b2022-05-11 14:07:55 +0530293 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 = AHAB_GET_FW_VERSION_CID;
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
Ye Li0a917da2022-04-06 14:30:20 +0800329int ahab_dump_buffer(u32 *buffer, u32 buffer_length)
330{
331 struct udevice *dev = gd->arch.s400_dev;
332 int size = sizeof(struct imx8ulp_s400_msg);
333 struct imx8ulp_s400_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 = AHAB_LOG_CID;
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}