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