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