1 /*
2 * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <lib/mmio.h>
8 #include <common/debug.h>
9 #include <drivers/delay_timer.h>
10 #include <platform_def.h>
11
12 #include "socfpga_mailbox.h"
13 #include "socfpga_plat_def.h"
14 #include "socfpga_sip_svc.h"
15 #include "socfpga_system_manager.h"
16
17 static mailbox_payload_t mailbox_resp_payload;
18 static mailbox_container_t mailbox_resp_ctr = {0, 0, &mailbox_resp_payload};
19
is_mailbox_cmdbuf_full(uint32_t cin)20 static bool is_mailbox_cmdbuf_full(uint32_t cin)
21 {
22 uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
23
24 return (((cin + 1U) % MBOX_CMD_BUFFER_SIZE) == cout);
25 }
26
is_mailbox_cmdbuf_empty(uint32_t cin)27 static bool is_mailbox_cmdbuf_empty(uint32_t cin)
28 {
29 uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
30
31 return (((cout + 1U) % MBOX_CMD_BUFFER_SIZE) == cin);
32 }
33
wait_for_mailbox_cmdbuf_empty(uint32_t cin)34 static int wait_for_mailbox_cmdbuf_empty(uint32_t cin)
35 {
36 unsigned int timeout = 200U;
37
38 do {
39 if (is_mailbox_cmdbuf_empty(cin)) {
40 break;
41 }
42 mdelay(10U);
43 } while (--timeout != 0U);
44
45 if (timeout == 0U) {
46 return MBOX_TIMEOUT;
47 }
48
49 return MBOX_RET_OK;
50 }
51
write_mailbox_cmd_buffer(uint32_t * cin,uint32_t cout,uint32_t data,bool * is_doorbell_triggered)52 static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout,
53 uint32_t data,
54 bool *is_doorbell_triggered)
55 {
56 unsigned int timeout = 100U;
57
58 do {
59 if (is_mailbox_cmdbuf_full(*cin)) {
60 if (!(*is_doorbell_triggered)) {
61 mmio_write_32(MBOX_OFFSET +
62 MBOX_DOORBELL_TO_SDM, 1U);
63 *is_doorbell_triggered = true;
64 }
65 mdelay(10U);
66 } else {
67 mmio_write_32(MBOX_ENTRY_TO_ADDR(CMD, (*cin)++), data);
68 *cin %= MBOX_CMD_BUFFER_SIZE;
69 mmio_write_32(MBOX_OFFSET + MBOX_CIN, *cin);
70 break;
71 }
72 } while (--timeout != 0U);
73
74 if (timeout == 0U) {
75 return MBOX_TIMEOUT;
76 }
77
78 if (*is_doorbell_triggered) {
79 int ret = wait_for_mailbox_cmdbuf_empty(*cin);
80 return ret;
81 }
82
83 return MBOX_RET_OK;
84 }
85
fill_mailbox_circular_buffer(uint32_t header_cmd,uint32_t * args,unsigned int len)86 static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
87 unsigned int len)
88 {
89 uint32_t sdm_read_offset, cmd_free_offset;
90 unsigned int i;
91 int ret;
92 bool is_doorbell_triggered = false;
93
94 cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
95 sdm_read_offset = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
96
97 ret = write_mailbox_cmd_buffer(&cmd_free_offset, sdm_read_offset,
98 header_cmd, &is_doorbell_triggered);
99 if (ret != 0) {
100 goto restart_mailbox;
101 }
102
103 for (i = 0U; i < len; i++) {
104 is_doorbell_triggered = false;
105 ret = write_mailbox_cmd_buffer(&cmd_free_offset,
106 sdm_read_offset, args[i],
107 &is_doorbell_triggered);
108 if (ret != 0) {
109 goto restart_mailbox;
110 }
111 }
112
113 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
114
115 return MBOX_RET_OK;
116
117 restart_mailbox:
118 /*
119 * Attempt to restart mailbox if the driver not able to write
120 * into mailbox command buffer
121 */
122 if (MBOX_CMD_MASK(header_cmd) != MBOX_CMD_RESTART) {
123 INFO("Mailbox timed out: Attempting mailbox reset\n");
124 ret = mailbox_init();
125
126 if (ret == MBOX_TIMEOUT) {
127 INFO("Error: Mailbox fail to restart\n");
128 }
129 }
130
131 return MBOX_TIMEOUT;
132 }
133
mailbox_read_response(unsigned int * job_id,uint32_t * response,unsigned int * resp_len)134 int mailbox_read_response(unsigned int *job_id, uint32_t *response,
135 unsigned int *resp_len)
136 {
137 uint32_t rin;
138 uint32_t rout;
139 uint32_t resp_data;
140 unsigned int ret_resp_len;
141
142 if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
143 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
144 }
145
146 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
147 rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
148
149 if (rout != rin) {
150 resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
151
152 rout %= MBOX_RESP_BUFFER_SIZE;
153 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
154
155
156 if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
157 return MBOX_WRONG_ID;
158 }
159
160 *job_id = MBOX_RESP_JOB_ID(resp_data);
161
162 ret_resp_len = MBOX_RESP_LEN(resp_data);
163
164 if (iterate_resp(ret_resp_len, response, resp_len)
165 != MBOX_RET_OK) {
166 return MBOX_TIMEOUT;
167 }
168
169 if (MBOX_RESP_ERR(resp_data) > 0U) {
170 INFO("Error in response: %x\n", resp_data);
171 return -MBOX_RESP_ERR(resp_data);
172 }
173
174 return MBOX_RET_OK;
175 }
176 return MBOX_NO_RESPONSE;
177 }
178
mailbox_read_response_async(unsigned int * job_id,uint32_t * header,uint32_t * response,unsigned int * resp_len,uint8_t ignore_client_id)179 int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
180 uint32_t *response, unsigned int *resp_len,
181 uint8_t ignore_client_id)
182 {
183 uint32_t rin;
184 uint32_t rout;
185 uint32_t resp_data;
186 uint32_t ret_resp_len = 0;
187 uint8_t is_done = 0;
188 uint32_t resp_len_check = 0;
189
190 if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
191 ret_resp_len = MBOX_RESP_LEN(
192 mailbox_resp_ctr.payload->header) -
193 mailbox_resp_ctr.index;
194 }
195
196 if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
197 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
198 }
199
200 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
201 rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
202
203 while (rout != rin && !is_done) {
204
205 resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
206
207 rout %= MBOX_RESP_BUFFER_SIZE;
208 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
209 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
210
211 if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
212 mailbox_resp_ctr.payload->data[mailbox_resp_ctr.index] = resp_data;
213 mailbox_resp_ctr.index++;
214 ret_resp_len--;
215 } else {
216 if (!ignore_client_id) {
217 if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
218 *resp_len = 0;
219 return MBOX_WRONG_ID;
220 }
221 }
222
223 *job_id = MBOX_RESP_JOB_ID(resp_data);
224 ret_resp_len = MBOX_RESP_LEN(resp_data);
225 mailbox_resp_ctr.payload->header = resp_data;
226 mailbox_resp_ctr.flag |= MBOX_PAYLOAD_FLAG_BUSY;
227 }
228
229 if (ret_resp_len == 0) {
230 is_done = 1;
231 }
232 }
233
234 if (is_done != 0) {
235
236 /* copy header data to input address if applicable */
237 if (header != 0) {
238 *header = mailbox_resp_ctr.payload->header;
239 }
240
241 /* copy response data to input buffer if applicable */
242 ret_resp_len = MBOX_RESP_LEN(mailbox_resp_ctr.payload->header);
243 if ((ret_resp_len > 0) && (response != NULL) && (resp_len != NULL)) {
244 if (*resp_len > ret_resp_len) {
245 *resp_len = ret_resp_len;
246 }
247
248 resp_len_check = (uint32_t) *resp_len;
249
250 if (resp_len_check > MBOX_DATA_MAX_LEN) {
251 return MBOX_RET_ERROR;
252 }
253
254 memcpy((uint8_t *) response,
255 (uint8_t *) mailbox_resp_ctr.payload->data,
256 *resp_len * MBOX_WORD_BYTE);
257 }
258
259 /* reset async response param */
260 mailbox_resp_ctr.index = 0;
261 mailbox_resp_ctr.flag = 0;
262
263 if (MBOX_RESP_ERR(mailbox_resp_ctr.payload->header) > 0U) {
264 INFO("Error in async response: %x\n",
265 mailbox_resp_ctr.payload->header);
266 return -MBOX_RESP_ERR(mailbox_resp_ctr.payload->header);
267 }
268
269 return MBOX_RET_OK;
270 }
271
272 *resp_len = 0;
273 return (mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) ? MBOX_BUSY : MBOX_NO_RESPONSE;
274 }
275
mailbox_poll_response(uint32_t job_id,uint32_t urgent,uint32_t * response,unsigned int * resp_len)276 int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
277 unsigned int *resp_len)
278 {
279 unsigned int timeout = 40U;
280 unsigned int sdm_loop = 255U;
281 unsigned int ret_resp_len;
282 uint32_t rin;
283 uint32_t rout;
284 uint32_t resp_data;
285
286 while (sdm_loop != 0U) {
287
288 do {
289 if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
290 == 1U) {
291 break;
292 }
293 mdelay(10U);
294 } while (--timeout != 0U);
295
296 if (timeout == 0U) {
297 break;
298 }
299
300 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
301
302 if ((urgent & 1U) != 0U) {
303 mdelay(5U);
304 if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
305 MBOX_STATUS_UA_MASK) ^
306 (urgent & MBOX_STATUS_UA_MASK)) {
307 mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
308 return MBOX_RET_OK;
309 }
310
311 mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
312 INFO("Error: Mailbox did not get UA");
313 return MBOX_RET_ERROR;
314 }
315
316 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
317 rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
318
319 while (rout != rin) {
320 resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP,
321 (rout)++));
322
323 rout %= MBOX_RESP_BUFFER_SIZE;
324 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
325
326 if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID
327 || MBOX_RESP_JOB_ID(resp_data) != job_id) {
328 continue;
329 }
330
331 ret_resp_len = MBOX_RESP_LEN(resp_data);
332
333 if (iterate_resp(ret_resp_len, response, resp_len)
334 != MBOX_RET_OK) {
335 return MBOX_TIMEOUT;
336 }
337
338 if (MBOX_RESP_ERR(resp_data) > 0U) {
339 INFO("Error in response: %x\n", resp_data);
340 return -MBOX_RESP_ERR(resp_data);
341 }
342
343 return MBOX_RET_OK;
344 }
345
346 sdm_loop--;
347 }
348
349 INFO("Timed out waiting for SDM\n");
350 return MBOX_TIMEOUT;
351 }
352
iterate_resp(uint32_t mbox_resp_len,uint32_t * resp_buf,unsigned int * resp_len)353 int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
354 unsigned int *resp_len)
355 {
356 unsigned int timeout, total_resp_len = 0U;
357 uint32_t resp_data;
358 uint32_t rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
359 uint32_t rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
360
361 while (mbox_resp_len > 0U) {
362 timeout = 100U;
363 mbox_resp_len--;
364 resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
365
366 if ((resp_buf != NULL) && (resp_len != NULL)
367 && (*resp_len != 0U)) {
368 *(resp_buf + total_resp_len)
369 = resp_data;
370 *resp_len = *resp_len - 1;
371 total_resp_len++;
372 }
373 rout %= MBOX_RESP_BUFFER_SIZE;
374 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
375
376 do {
377 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
378 if (rout == rin) {
379 mdelay(10U);
380 } else {
381 break;
382 }
383 timeout--;
384 } while ((mbox_resp_len > 0U) && (timeout != 0U));
385
386 if (timeout == 0U) {
387 INFO("Timed out waiting for SDM\n");
388 return MBOX_TIMEOUT;
389 }
390 }
391
392 if (resp_len)
393 *resp_len = total_resp_len;
394
395 return MBOX_RET_OK;
396 }
397
mailbox_send_cmd_async_ext(uint32_t header_cmd,uint32_t * args,unsigned int len)398 int mailbox_send_cmd_async_ext(uint32_t header_cmd, uint32_t *args,
399 unsigned int len)
400 {
401 return fill_mailbox_circular_buffer(header_cmd, args, len);
402 }
403
mailbox_send_cmd_async(uint32_t * job_id,uint32_t cmd,uint32_t * args,unsigned int len,unsigned int indirect)404 int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
405 unsigned int len, unsigned int indirect)
406 {
407 int status;
408
409 status = fill_mailbox_circular_buffer(
410 MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
411 MBOX_JOB_ID_CMD(*job_id) |
412 MBOX_CMD_LEN_CMD(len) |
413 MBOX_INDIRECT(indirect) |
414 cmd, args, len);
415 if (status < 0) {
416 return status;
417 }
418
419 *job_id = (*job_id + 1U) % MBOX_MAX_IND_JOB_ID;
420
421 return MBOX_RET_OK;
422 }
423
mailbox_send_cmd(uint32_t job_id,uint32_t cmd,uint32_t * args,unsigned int len,uint32_t urgent,uint32_t * response,unsigned int * resp_len)424 int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args,
425 unsigned int len, uint32_t urgent, uint32_t *response,
426 unsigned int *resp_len)
427 {
428 int status = 0;
429
430 if (urgent != 0U) {
431 urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
432 MBOX_STATUS_UA_MASK;
433 mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
434 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
435 }
436
437 else {
438 status = fill_mailbox_circular_buffer(
439 MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
440 MBOX_JOB_ID_CMD(job_id) |
441 MBOX_CMD_LEN_CMD(len) |
442 cmd, args, len);
443 }
444
445 if (status != 0) {
446 return status;
447 }
448
449 status = mailbox_poll_response(job_id, urgent, response, resp_len);
450
451 return status;
452 }
453
mailbox_clear_response(void)454 void mailbox_clear_response(void)
455 {
456 mmio_write_32(MBOX_OFFSET + MBOX_ROUT,
457 mmio_read_32(MBOX_OFFSET + MBOX_RIN));
458 }
459
mailbox_set_int(uint32_t interrupt)460 void mailbox_set_int(uint32_t interrupt)
461 {
462
463 mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) |
464 MBOX_UAE_BIT(interrupt));
465 }
466
467
mailbox_set_qspi_open(void)468 void mailbox_set_qspi_open(void)
469 {
470 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
471 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, NULL, 0U,
472 CMD_CASUAL, NULL, NULL);
473 }
474
mailbox_set_qspi_direct(void)475 void mailbox_set_qspi_direct(void)
476 {
477 uint32_t response[1], qspi_clk, reg;
478 unsigned int resp_len = ARRAY_SIZE(response);
479
480 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0U,
481 CMD_CASUAL, response, &resp_len);
482
483 qspi_clk = response[0];
484 INFO("QSPI ref clock: %u\n", qspi_clk);
485
486 /*
487 * Store QSPI ref clock frequency in BOOT_SCRATCH_COLD_0 register for
488 * later boot loader (i.e. u-boot) use.
489 * The frequency is stored in kHz and occupies BOOT_SCRATCH_COLD_0
490 * register bits[27:0].
491 */
492 qspi_clk /= 1000;
493 reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0));
494 reg &= ~SYSMGR_QSPI_REFCLK_MASK;
495 reg |= qspi_clk & SYSMGR_QSPI_REFCLK_MASK;
496 mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0), reg);
497 }
498
mailbox_set_qspi_close(void)499 void mailbox_set_qspi_close(void)
500 {
501 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
502 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, NULL, 0U,
503 CMD_CASUAL, NULL, NULL);
504 }
505
mailbox_qspi_set_cs(uint32_t device_select)506 void mailbox_qspi_set_cs(uint32_t device_select)
507 {
508 uint32_t cs_setting;
509
510 /* QSPI device select settings at 31:28 */
511 cs_setting = (device_select << 28);
512 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
513 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting,
514 1U, CMD_CASUAL, NULL, NULL);
515 }
516
mailbox_hps_qspi_enable(void)517 void mailbox_hps_qspi_enable(void)
518 {
519 mailbox_set_qspi_open();
520 mailbox_set_qspi_direct();
521 }
522
mailbox_reset_cold(void)523 void mailbox_reset_cold(void)
524 {
525 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
526
527 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0U, 0U,
528 CMD_CASUAL, NULL, NULL);
529 }
530
mailbox_reset_warm(uint32_t reset_type)531 void mailbox_reset_warm(uint32_t reset_type)
532 {
533 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
534
535 reset_type = 0x01; // Warm reset header data must be 1
536 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, &reset_type, 1U,
537 CMD_CASUAL, NULL, NULL);
538 }
539
mailbox_rsu_get_spt_offset(uint32_t * resp_buf,unsigned int resp_buf_len)540 int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, unsigned int resp_buf_len)
541 {
542 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE,
543 NULL, 0U, CMD_CASUAL, resp_buf,
544 &resp_buf_len);
545 }
546
547 struct rsu_status_info {
548 uint64_t current_image;
549 uint64_t fail_image;
550 uint32_t state;
551 uint32_t version;
552 uint32_t error_location;
553 uint32_t error_details;
554 uint32_t retry_counter;
555 };
556
mailbox_rsu_status(uint32_t * resp_buf,unsigned int resp_buf_len)557 int mailbox_rsu_status(uint32_t *resp_buf, unsigned int resp_buf_len)
558 {
559 int ret;
560 struct rsu_status_info *info = (struct rsu_status_info *)resp_buf;
561
562 info->retry_counter = ~0U;
563
564 ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0U,
565 CMD_CASUAL, resp_buf,
566 &resp_buf_len);
567
568 if (ret < 0) {
569 return ret;
570 }
571
572 if (info->retry_counter != ~0U) {
573 if ((info->version & RSU_VERSION_ACMF_MASK) == 0U) {
574 info->version |= RSU_VERSION_ACMF;
575 }
576 }
577
578 return ret;
579 }
580
mailbox_rsu_update(uint32_t * flash_offset)581 int mailbox_rsu_update(uint32_t *flash_offset)
582 {
583 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
584 flash_offset, 2U,
585 CMD_CASUAL, NULL, NULL);
586 }
587
mailbox_hps_stage_notify(uint32_t execution_stage)588 int mailbox_hps_stage_notify(uint32_t execution_stage)
589 {
590 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY,
591 &execution_stage, 1U, CMD_CASUAL,
592 NULL, NULL);
593 }
594
mailbox_init(void)595 int mailbox_init(void)
596 {
597 int status;
598
599 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
600 MBOX_INT_FLAG_UAE);
601 mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
602 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
603
604 status = mailbox_send_cmd(0U, MBOX_CMD_RESTART, NULL, 0U,
605 CMD_URGENT, NULL, NULL);
606
607 if (status != 0) {
608 return status;
609 }
610
611 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
612 MBOX_INT_FLAG_UAE);
613
614 return MBOX_RET_OK;
615 }
616
intel_mailbox_get_config_status(uint32_t cmd,bool init_done)617 int intel_mailbox_get_config_status(uint32_t cmd, bool init_done)
618 {
619 int status;
620 uint32_t res, response[6];
621 unsigned int resp_len = ARRAY_SIZE(response);
622
623 status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0U, CMD_CASUAL,
624 response, &resp_len);
625
626 if (status < 0) {
627 return status;
628 }
629
630 res = response[RECONFIG_STATUS_STATE];
631
632 if (res == MBOX_CFGSTAT_VAB_BS_PREAUTH) {
633 return MBOX_CFGSTAT_STATE_CONFIG;
634 }
635
636 if ((res != 0U) && (res != MBOX_CFGSTAT_STATE_CONFIG)) {
637 return res;
638 }
639
640 res = response[RECONFIG_STATUS_PIN_STATUS];
641 if ((res & PIN_STATUS_NSTATUS) == 0U) {
642 return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
643 }
644
645 res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
646 if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
647 ERROR("SoftFunction Status SEU ERROR\n");
648 }
649
650 if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
651 return MBOX_CFGSTAT_STATE_CONFIG;
652 }
653
654 if (init_done && (res & SOFTFUNC_STATUS_INIT_DONE) == 0U) {
655 return MBOX_CFGSTAT_STATE_CONFIG;
656 }
657
658 return MBOX_RET_OK;
659 }
660
intel_mailbox_is_fpga_not_ready(void)661 int intel_mailbox_is_fpga_not_ready(void)
662 {
663 int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true);
664
665 if ((ret != MBOX_RET_OK) && (ret != MBOX_CFGSTAT_STATE_CONFIG)) {
666 ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS,
667 false);
668 }
669
670 return ret;
671 }
672
mailbox_hwmon_readtemp(uint32_t chan,uint32_t * resp_buf)673 int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf)
674 {
675 unsigned int resp_len = sizeof(resp_buf);
676
677 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READTEMP, &chan, 1U,
678 CMD_CASUAL, resp_buf,
679 &resp_len);
680
681 }
682
mailbox_hwmon_readvolt(uint32_t chan,uint32_t * resp_buf)683 int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf)
684 {
685 unsigned int resp_len = sizeof(resp_buf);
686
687 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READVOLT, &chan, 1U,
688 CMD_CASUAL, resp_buf,
689 &resp_len);
690 }
691
mailbox_seu_err_status(uint32_t * resp_buf,unsigned int resp_buf_len)692 int mailbox_seu_err_status(uint32_t *resp_buf, unsigned int resp_buf_len)
693 {
694
695 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SEU_ERR_READ, NULL, 0U,
696 CMD_CASUAL, resp_buf,
697 &resp_buf_len);
698 }
699
mailbox_safe_inject_seu_err(uint32_t * arg,unsigned int len)700 int mailbox_safe_inject_seu_err(uint32_t *arg, unsigned int len)
701 {
702 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SAFE_INJECT_SEU_ERR, arg, len,
703 CMD_CASUAL, NULL, NULL);
704 }
705