• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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