xref: /rk3399_ARM-atf/plat/intel/soc/common/soc/socfpga_mailbox.c (revision 8329be5ae751423e482c056c7adf3248639273d3)
1 /*
2  * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
3  * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <lib/mmio.h>
9 #include <lib/spinlock.h>
10 #include <common/debug.h>
11 #include <drivers/delay_timer.h>
12 #include <platform_def.h>
13 
14 #include "socfpga_mailbox.h"
15 #include "socfpga_plat_def.h"
16 #include "socfpga_private.h"
17 #include "socfpga_sip_svc.h"
18 #include "socfpga_system_manager.h"
19 
20 #if SIP_SVC_V3
21 /* Function prototypes */
22 void mailbox_init_v3(void);
23 static int mailbox_response_handler_fsm(void);
24 static inline void mailbox_free_cmd_desc(sdm_command_t *cmd_desc);
25 static sdm_response_t *mailbox_get_resp_desc(uint8_t client_id, uint8_t job_id,
26 					     uint8_t *index);
27 static sdm_command_t *mailbox_get_cmd_desc(uint8_t client_id, uint8_t job_id);
28 static inline void mailbox_free_resp_desc(uint8_t index);
29 static sdm_command_t *mailbox_get_free_cmd_desc(void);
30 static sdm_response_t *mailbox_get_resp_desc_cid(uint8_t client_id,
31 						 uint8_t *index);
32 static int mailbox_read_response_v3(uint8_t client_id, uint8_t *job_id,
33 				    uint32_t *header, uint32_t *resp,
34 				    uint32_t *resp_len,
35 				    uint8_t ignore_client_id);
36 static int mailbox_poll_response_v3(uint8_t client_id, uint8_t job_id,
37 				    uint32_t *resp, unsigned int *resp_len,
38 				    uint32_t urgent);
39 
40 static spinlock_t mbox_db_lock;		/* Mailbox service data base lock */
41 static spinlock_t mbox_write_lock;	/* Hardware mailbox FIFO write lock */
42 static spinlock_t mbox_read_lock;	/* Hardware mailbox FIFO read lock */
43 
44 static mailbox_service_t mbox_svc;	/* Mailbox service data base */
45 static uint8_t async_v1_job_id;
46 #endif /* #if SIP_SVC_V3 */
47 
48 static mailbox_payload_t mailbox_resp_payload;
49 static mailbox_container_t mailbox_resp_ctr = {0, 0, &mailbox_resp_payload};
50 
is_mailbox_cmdbuf_full(uint32_t cin)51 static bool is_mailbox_cmdbuf_full(uint32_t cin)
52 {
53 	uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
54 
55 	return (((cin + 1U) % MBOX_CMD_BUFFER_SIZE) == cout);
56 }
57 
is_mailbox_cmdbuf_empty(uint32_t cin)58 static bool is_mailbox_cmdbuf_empty(uint32_t cin)
59 {
60 	uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
61 
62 	return (((cout + 1U) % MBOX_CMD_BUFFER_SIZE) == cin);
63 }
64 
wait_for_mailbox_cmdbuf_empty(uint32_t cin)65 static int wait_for_mailbox_cmdbuf_empty(uint32_t cin)
66 {
67 	unsigned int timeout = 20000U;
68 
69 	do {
70 		if (is_mailbox_cmdbuf_empty(cin)) {
71 			break;
72 		}
73 		udelay(50U);
74 	} while (--timeout != 0U);
75 
76 	if (timeout == 0U) {
77 		return MBOX_TIMEOUT;
78 	}
79 
80 	return MBOX_RET_OK;
81 }
82 
write_mailbox_cmd_buffer(uint32_t * cin,uint32_t cout,uint32_t data,bool * is_doorbell_triggered)83 static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout,
84 				    uint32_t data,
85 				    bool *is_doorbell_triggered)
86 {
87 	unsigned int timeout = 20000U;
88 
89 	VERBOSE("MBOX: 0x%x\n", data);
90 
91 	do {
92 		if (is_mailbox_cmdbuf_full(*cin)) {
93 			if (!(*is_doorbell_triggered)) {
94 				mmio_write_32(MBOX_OFFSET +
95 					      MBOX_DOORBELL_TO_SDM, 1U);
96 				*is_doorbell_triggered = true;
97 			}
98 			udelay(50U);
99 		} else {
100 			mmio_write_32(MBOX_ENTRY_TO_ADDR(CMD, (*cin)++), data);
101 			*cin %= MBOX_CMD_BUFFER_SIZE;
102 			mmio_write_32(MBOX_OFFSET + MBOX_CIN, *cin);
103 			break;
104 		}
105 	} while (--timeout != 0U);
106 
107 	if (timeout == 0U) {
108 		return MBOX_TIMEOUT;
109 	}
110 
111 	if (*is_doorbell_triggered) {
112 		int ret = wait_for_mailbox_cmdbuf_empty(*cin);
113 		return ret;
114 	}
115 
116 	return MBOX_RET_OK;
117 }
118 
119 /*
120  * Function description: Write the command header, and its payload one by one
121  * into the mailbox command buffer. Along with this, check for mailbox buffer
122  * full condition and trigger doorbell to SDM if the command buffer is full.
123  */
fill_mailbox_circular_buffer(uint32_t header_cmd,uint32_t * args,unsigned int len)124 static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
125 					unsigned int len)
126 {
127 	uint32_t sdm_read_offset, cmd_free_offset;
128 	unsigned int i;
129 	int ret;
130 	bool is_doorbell_triggered = false;
131 
132 #if SIP_SVC_V3
133 	spin_lock(&mbox_write_lock);
134 #endif
135 
136 	cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
137 	sdm_read_offset = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
138 
139 	/* Write the command header here */
140 	ret = write_mailbox_cmd_buffer(&cmd_free_offset, sdm_read_offset,
141 				       header_cmd, &is_doorbell_triggered);
142 	if (ret != 0) {
143 		goto restart_mailbox;
144 	}
145 
146 	/* Write the payload here w.r.to args and its len - one by one. */
147 	for (i = 0U; i < len; i++) {
148 		is_doorbell_triggered = false;
149 		ret = write_mailbox_cmd_buffer(&cmd_free_offset,
150 					       sdm_read_offset, args[i],
151 					       &is_doorbell_triggered);
152 		if (ret != 0) {
153 			goto restart_mailbox;
154 		}
155 	}
156 
157 	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
158 
159 #if SIP_SVC_V3
160 	spin_unlock(&mbox_write_lock);
161 #endif
162 	return MBOX_RET_OK;
163 
164 restart_mailbox:
165 	/*
166 	 * Attempt to restart mailbox if the driver not able to write
167 	 * into mailbox command buffer
168 	 */
169 	if (MBOX_CMD_MASK(header_cmd) != MBOX_CMD_RESTART) {
170 		INFO("Mailbox timed out: Attempting mailbox reset\n");
171 		ret = mailbox_init();
172 
173 		if (ret == MBOX_TIMEOUT) {
174 			INFO("Error: Mailbox fail to restart\n");
175 		}
176 	}
177 
178 #if SIP_SVC_V3
179 	spin_unlock(&mbox_write_lock);
180 #endif
181 	return MBOX_TIMEOUT;
182 }
183 
mailbox_read_response(unsigned int * job_id,uint32_t * response,unsigned int * resp_len)184 int mailbox_read_response(unsigned int *job_id, uint32_t *response,
185 				unsigned int *resp_len)
186 {
187 #if SIP_SVC_V3
188 	return mailbox_read_response_v3(MBOX_ATF_CLIENT_ID,
189 					(uint8_t *)job_id, NULL,
190 					response, resp_len,
191 					0);
192 #else
193 	uint32_t rin;
194 	uint32_t rout;
195 	uint32_t resp_data;
196 	unsigned int ret_resp_len;
197 
198 	if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
199 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
200 	}
201 
202 	rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
203 	rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
204 
205 	if (rout != rin) {
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 
211 
212 		if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
213 			return MBOX_WRONG_ID;
214 		}
215 
216 		*job_id = MBOX_RESP_JOB_ID(resp_data);
217 
218 		ret_resp_len = MBOX_RESP_LEN(resp_data);
219 
220 		if (iterate_resp(ret_resp_len, response, resp_len)
221 			!= MBOX_RET_OK) {
222 			return MBOX_TIMEOUT;
223 		}
224 
225 		if (MBOX_RESP_ERR(resp_data) > 0U) {
226 			INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
227 			return -MBOX_RESP_ERR(resp_data);
228 		}
229 
230 		return MBOX_RET_OK;
231 	}
232 
233 	return MBOX_NO_RESPONSE;
234 #endif
235 }
236 
mailbox_read_response_async(unsigned int * job_id,uint32_t * header,uint32_t * response,unsigned int * resp_len,uint8_t ignore_client_id)237 int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
238 				uint32_t *response, unsigned int *resp_len,
239 				uint8_t ignore_client_id)
240 {
241 #if SIP_SVC_V3
242 	/* Just to avoid the build warning */
243 	(void)mailbox_resp_ctr;
244 	return mailbox_read_response_v3(MBOX_ATF_CLIENT_ID,
245 					(uint8_t *)job_id, header,
246 					response, resp_len,
247 					ignore_client_id);
248 #else
249 	uint32_t rin;
250 	uint32_t rout;
251 	uint32_t resp_data;
252 	uint32_t ret_resp_len = 0;
253 	uint8_t is_done = 0;
254 	uint32_t resp_len_check = 0;
255 
256 	if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
257 		ret_resp_len = MBOX_RESP_LEN(
258 				mailbox_resp_ctr.payload->header) -
259 				mailbox_resp_ctr.index;
260 	}
261 
262 	if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
263 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
264 	}
265 
266 	rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
267 	rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
268 
269 	while (rout != rin && !is_done) {
270 
271 		resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
272 
273 		rout %= MBOX_RESP_BUFFER_SIZE;
274 		mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
275 		rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
276 
277 		if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
278 			mailbox_resp_ctr.payload->data[mailbox_resp_ctr.index] = resp_data;
279 			mailbox_resp_ctr.index++;
280 			ret_resp_len--;
281 		} else {
282 			if (!ignore_client_id) {
283 				if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
284 					*resp_len = 0;
285 					return MBOX_WRONG_ID;
286 				}
287 			}
288 			*job_id = MBOX_RESP_JOB_ID(resp_data);
289 			ret_resp_len = MBOX_RESP_LEN(resp_data);
290 			mailbox_resp_ctr.payload->header = resp_data;
291 			mailbox_resp_ctr.flag |= MBOX_PAYLOAD_FLAG_BUSY;
292 		}
293 
294 		if (ret_resp_len == 0) {
295 			is_done = 1;
296 		}
297 	}
298 
299 	if (is_done != 0) {
300 
301 		/* copy header data to input address if applicable */
302 		if (header != 0) {
303 			*header = mailbox_resp_ctr.payload->header;
304 		}
305 
306 		/* copy response data to input buffer if applicable */
307 		ret_resp_len = MBOX_RESP_LEN(mailbox_resp_ctr.payload->header);
308 		if ((ret_resp_len > 0) && (response != NULL) && (resp_len != NULL)) {
309 			if (*resp_len > ret_resp_len) {
310 				*resp_len = ret_resp_len;
311 			}
312 
313 			resp_len_check = (uint32_t) *resp_len;
314 
315 			if (resp_len_check > MBOX_DATA_MAX_LEN) {
316 				return MBOX_RET_ERROR;
317 			}
318 
319 			memcpy_s((uint8_t *) response, *resp_len * MBOX_WORD_BYTE,
320 				(uint8_t *) mailbox_resp_ctr.payload->data,
321 				*resp_len * MBOX_WORD_BYTE);
322 		}
323 
324 		/* reset async response param */
325 		mailbox_resp_ctr.index = 0;
326 		mailbox_resp_ctr.flag = 0;
327 
328 		if (MBOX_RESP_ERR(mailbox_resp_ctr.payload->header) > 0U) {
329 			INFO("Error in async response: %x\n",
330 				mailbox_resp_ctr.payload->header);
331 			return -MBOX_RESP_ERR(mailbox_resp_ctr.payload->header);
332 		}
333 
334 		return MBOX_RET_OK;
335 	}
336 
337 	*resp_len = 0;
338 	return (mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) ? MBOX_BUSY : MBOX_NO_RESPONSE;
339 #endif
340 }
341 
mailbox_poll_response(uint32_t job_id,uint32_t urgent,uint32_t * response,unsigned int * resp_len)342 int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
343 			  unsigned int *resp_len)
344 {
345 #if SIP_SVC_V3
346 	return mailbox_poll_response_v3(MBOX_ATF_CLIENT_ID, (uint8_t)job_id,
347 					response, resp_len, urgent);
348 #else
349 	unsigned int timeout = 40U;
350 	unsigned int sdm_loop = 255U;
351 	unsigned int ret_resp_len;
352 	uint32_t rin;
353 	uint32_t rout;
354 	uint32_t resp_data;
355 
356 	while (sdm_loop != 0U) {
357 		do {
358 			if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
359 				== 1U) {
360 				break;
361 			}
362 			mdelay(10U);
363 		} while (--timeout != 0U);
364 
365 		if (timeout == 0U) {
366 			break;
367 		}
368 
369 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
370 
371 		if ((urgent & 1U) != 0U) {
372 			mdelay(5U);
373 			if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
374 				MBOX_STATUS_UA_MASK) ^
375 				(urgent & MBOX_STATUS_UA_MASK)) {
376 				mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
377 				return MBOX_RET_OK;
378 			}
379 
380 			mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
381 			ERROR("MBOX: Mailbox did not get UA");
382 			return MBOX_RET_ERROR;
383 		}
384 
385 		rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
386 		rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
387 
388 		while (rout != rin) {
389 			resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP,
390 								(rout)++));
391 
392 			rout %= MBOX_RESP_BUFFER_SIZE;
393 			mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
394 
395 			if ((MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) ||
396 			    (MBOX_RESP_JOB_ID(resp_data) != job_id)) {
397 				continue;
398 			}
399 
400 			/* Get the return response len from the response header. */
401 			ret_resp_len = MBOX_RESP_LEN(resp_data);
402 
403 			/* Print the response header. */
404 			VERBOSE("MBOX: RespHdr: cid %d, jid %d, len %d, err_code 0x%x\n",
405 				MBOX_RESP_CLIENT_ID(resp_data),
406 				MBOX_RESP_JOB_ID(resp_data),
407 				MBOX_RESP_LEN(resp_data),
408 				MBOX_RESP_ERR(resp_data));
409 
410 			if (iterate_resp(ret_resp_len, response, resp_len)
411 				!= MBOX_RET_OK) {
412 				return MBOX_TIMEOUT;
413 			}
414 
415 			if (MBOX_RESP_ERR(resp_data) > 0U) {
416 				INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
417 				return -MBOX_RESP_ERR(resp_data);
418 			}
419 
420 			return MBOX_RET_OK;
421 		}
422 
423 	sdm_loop--;
424 	}
425 
426 	INFO("Timed out waiting for SDM\n");
427 	return MBOX_TIMEOUT;
428 #endif
429 }
430 
iterate_resp(uint32_t mbox_resp_len,uint32_t * resp_buf,unsigned int * resp_len)431 int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
432 			unsigned int *resp_len)
433 {
434 	unsigned int timeout, total_resp_len = 0U;
435 	uint32_t resp_data;
436 	uint32_t rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
437 	uint32_t rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
438 
439 	while (mbox_resp_len > 0U) {
440 		timeout = 100U;
441 		mbox_resp_len--;
442 		resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
443 
444 		if ((resp_buf != NULL) && (resp_len != NULL)
445 			&& (*resp_len != 0U)) {
446 			*(resp_buf + total_resp_len) = resp_data;
447 			*resp_len = *resp_len - 1;
448 			total_resp_len++;
449 		}
450 		rout %= MBOX_RESP_BUFFER_SIZE;
451 		mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
452 
453 		do {
454 			rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
455 			if (rout == rin) {
456 				mdelay(10U);
457 			} else {
458 				break;
459 			}
460 			timeout--;
461 		} while ((mbox_resp_len > 0U) && (timeout != 0U));
462 
463 		if (timeout == 0U) {
464 			INFO("Timed out waiting for SDM\n");
465 			return MBOX_TIMEOUT;
466 		}
467 	}
468 
469 	if (resp_len)
470 		*resp_len = total_resp_len;
471 
472 	return MBOX_RET_OK;
473 }
474 
mailbox_send_cmd_async_ext(uint32_t header_cmd,uint32_t * args,unsigned int len)475 int mailbox_send_cmd_async_ext(uint32_t header_cmd, uint32_t *args,
476 			unsigned int len)
477 {
478 	return fill_mailbox_circular_buffer(header_cmd, args, len);
479 }
480 
mailbox_send_cmd_async(uint32_t * job_id,uint32_t cmd,uint32_t * args,unsigned int len,unsigned int indirect)481 int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
482 			  unsigned int len, unsigned int indirect)
483 {
484 	int status;
485 
486 	status = fill_mailbox_circular_buffer(
487 				MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
488 				MBOX_JOB_ID_CMD(*job_id) |
489 				MBOX_CMD_LEN_CMD(len) |
490 				MBOX_INDIRECT(indirect) |
491 				cmd, args, len);
492 	if (status < 0) {
493 		return status;
494 	}
495 
496 #if SIP_SVC_V3
497 	async_v1_job_id = (uint8_t)*job_id;
498 #endif
499 	*job_id = (*job_id + 1U) % MBOX_MAX_IND_JOB_ID;
500 
501 	return MBOX_RET_OK;
502 }
503 
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)504 int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args,
505 			unsigned int len, uint32_t urgent, uint32_t *response,
506 			unsigned int *resp_len)
507 {
508 	int status = 0;
509 
510 	if (urgent != 0U) {
511 		urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
512 					MBOX_STATUS_UA_MASK;
513 		mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
514 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
515 	} else {
516 		status = fill_mailbox_circular_buffer(
517 			MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
518 			MBOX_JOB_ID_CMD(job_id) |
519 			MBOX_CMD_LEN_CMD(len) |
520 			cmd, args, len);
521 	}
522 
523 	if (status != 0) {
524 		return status;
525 	}
526 
527 	status = mailbox_poll_response(job_id, urgent, response, resp_len);
528 
529 	return status;
530 }
531 
mailbox_clear_response(void)532 void mailbox_clear_response(void)
533 {
534 	mmio_write_32(MBOX_OFFSET + MBOX_ROUT,
535 		mmio_read_32(MBOX_OFFSET + MBOX_RIN));
536 }
537 
mailbox_set_int(uint32_t interrupt)538 void mailbox_set_int(uint32_t interrupt)
539 {
540 	mmio_write_32(MBOX_OFFSET+MBOX_INT,
541 			MBOX_COE_BIT(interrupt) |
542 			MBOX_RIE_BIT(interrupt) |
543 			MBOX_UAE_BIT(interrupt));
544 }
545 
mailbox_set_qspi_open(void)546 void mailbox_set_qspi_open(void)
547 {
548 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
549 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, NULL, 0U,
550 				CMD_CASUAL, NULL, NULL);
551 }
552 
mailbox_set_qspi_direct(void)553 void mailbox_set_qspi_direct(void)
554 {
555 	uint32_t response[1], qspi_clk, reg;
556 	unsigned int resp_len = ARRAY_SIZE(response);
557 
558 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0U,
559 			 CMD_CASUAL, response, &resp_len);
560 
561 	qspi_clk = response[0];
562 	INFO("QSPI ref clock: %u\n", qspi_clk);
563 
564 	/*
565 	 * Store QSPI ref clock frequency in BOOT_SCRATCH_COLD_0 register for
566 	 * later boot loader (i.e. u-boot) use.
567 	 * The frequency is stored in kHz and occupies BOOT_SCRATCH_COLD_0
568 	 * register bits[27:0].
569 	 */
570 	qspi_clk /= 1000;
571 	reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0));
572 	reg &= ~SYSMGR_QSPI_REFCLK_MASK;
573 	reg |= qspi_clk & SYSMGR_QSPI_REFCLK_MASK;
574 	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0), reg);
575 }
576 
mailbox_set_qspi_close(void)577 void mailbox_set_qspi_close(void)
578 {
579 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
580 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, NULL, 0U,
581 				CMD_CASUAL, NULL, NULL);
582 }
583 
mailbox_qspi_set_cs(uint32_t device_select)584 void mailbox_qspi_set_cs(uint32_t device_select)
585 {
586 	uint32_t cs_setting;
587 
588 	/* QSPI device select settings at 31:28 */
589 	cs_setting = (device_select << 28);
590 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
591 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting,
592 				1U, CMD_CASUAL, NULL, NULL);
593 }
594 
mailbox_hps_qspi_enable(void)595 void mailbox_hps_qspi_enable(void)
596 {
597 	mailbox_set_qspi_open();
598 	mailbox_set_qspi_direct();
599 }
600 
mailbox_reset_cold(void)601 void mailbox_reset_cold(void)
602 {
603 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
604 
605 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0U, 0U,
606 				 CMD_CASUAL, NULL, NULL);
607 }
608 
mailbox_reset_warm(uint32_t reset_type)609 void mailbox_reset_warm(uint32_t reset_type)
610 {
611 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
612 
613 	reset_type = 0x01; // Warm reset header data must be 1
614 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, &reset_type, 1U,
615 				 CMD_CASUAL, NULL, NULL);
616 }
617 
mailbox_rsu_get_spt_offset(uint32_t * resp_buf,unsigned int resp_buf_len)618 int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, unsigned int resp_buf_len)
619 {
620 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE,
621 				NULL, 0U, CMD_CASUAL, resp_buf,
622 				&resp_buf_len);
623 }
624 
625 struct rsu_status_info {
626 	uint64_t current_image;
627 	uint64_t fail_image;
628 	uint32_t state;
629 	uint32_t version;
630 	uint32_t error_location;
631 	uint32_t error_details;
632 	uint32_t retry_counter;
633 };
634 
mailbox_rsu_status(uint32_t * resp_buf,unsigned int resp_buf_len)635 int mailbox_rsu_status(uint32_t *resp_buf, unsigned int resp_buf_len)
636 {
637 	int ret;
638 	struct rsu_status_info *info = (struct rsu_status_info *)resp_buf;
639 
640 	info->retry_counter = ~0U;
641 
642 	ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0U,
643 				CMD_CASUAL, resp_buf,
644 				&resp_buf_len);
645 
646 	if (ret < 0) {
647 		return ret;
648 	}
649 
650 	if (info->retry_counter != ~0U) {
651 		if ((info->version & RSU_VERSION_ACMF_MASK) == 0U) {
652 			info->version |= RSU_VERSION_ACMF;
653 		}
654 	}
655 
656 	return ret;
657 }
658 
mailbox_rsu_get_device_info(uint32_t * resp_buf,unsigned int resp_buf_len)659 int mailbox_rsu_get_device_info(uint32_t *resp_buf, unsigned int resp_buf_len)
660 {
661 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_GET_DEVICE_INFO, NULL, 0U,
662 				CMD_CASUAL, resp_buf,
663 				&resp_buf_len);
664 }
665 
mailbox_rsu_update(uint32_t * flash_offset)666 int mailbox_rsu_update(uint32_t *flash_offset)
667 {
668 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
669 				flash_offset, 2U,
670 				CMD_CASUAL, NULL, NULL);
671 }
672 
mailbox_hps_stage_notify(uint32_t execution_stage)673 int mailbox_hps_stage_notify(uint32_t execution_stage)
674 {
675 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY,
676 				&execution_stage, 1U, CMD_CASUAL,
677 				NULL, NULL);
678 }
679 
mailbox_init(void)680 int mailbox_init(void)
681 {
682 	int status;
683 
684 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
685 			MBOX_INT_FLAG_UAE);
686 
687 	mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
688 	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
689 
690 	status = mailbox_send_cmd(0U, MBOX_CMD_RESTART, NULL, 0U,
691 					CMD_URGENT, NULL, NULL);
692 
693 	if (status != 0) {
694 		return status;
695 	}
696 
697 #if SIP_SVC_V3
698 	/* Initialize the mailbox version3 implementation, and in V3 we
699 	 * are interested in only RIE interrupt
700 	 */
701 	mailbox_init_v3();
702 	mailbox_set_int(MBOX_INT_FLAG_RIE);
703 #else
704 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
705 			MBOX_INT_FLAG_UAE);
706 #endif
707 
708 	return MBOX_RET_OK;
709 }
710 
mailbox_send_fpga_config_comp(void)711 int mailbox_send_fpga_config_comp(void)
712 {
713 	int ret;
714 
715 	ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_FPGA_CONFIG_COMP, NULL, 0U,
716 				 CMD_CASUAL, NULL, NULL);
717 
718 	if (ret != 0) {
719 		INFO("SOCFPGA: FPGA configuration complete response, Return Code: 0x%x\n",
720 			MBOX_RESP_ERR(-ret));
721 		return MBOX_RET_ERROR;
722 	}
723 
724 	return MBOX_RET_OK;
725 }
726 
intel_mailbox_get_config_status(uint32_t cmd,bool init_done,uint32_t * err_states)727 int intel_mailbox_get_config_status(uint32_t cmd, bool init_done,
728 				    uint32_t *err_states)
729 {
730 	int status;
731 	uint32_t res, response[6];
732 	unsigned int resp_len = ARRAY_SIZE(response);
733 
734 	status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0U, CMD_CASUAL,
735 				response, &resp_len);
736 
737 	if (status < 0) {
738 		return status;
739 	}
740 
741 	res = response[RECONFIG_STATUS_STATE];
742 
743 	if (err_states != NULL)
744 		*err_states = res;
745 
746 	if (res == MBOX_CFGSTAT_VAB_BS_PREAUTH) {
747 		return MBOX_CFGSTAT_STATE_CONFIG;
748 	}
749 
750 	if ((res != 0U) && (res != MBOX_CFGSTAT_STATE_CONFIG)) {
751 		return res;
752 	}
753 
754 	res = response[RECONFIG_STATUS_PIN_STATUS];
755 	if ((res & PIN_STATUS_NSTATUS) == 0U) {
756 		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
757 	}
758 
759 	res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
760 	if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
761 		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
762 	}
763 
764 	if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
765 		return MBOX_CFGSTAT_STATE_CONFIG;
766 	}
767 
768 	if (init_done && (res & SOFTFUNC_STATUS_INIT_DONE) == 0U) {
769 		return MBOX_CFGSTAT_STATE_CONFIG;
770 	}
771 
772 	return MBOX_RET_OK;
773 }
774 
intel_mailbox_is_fpga_not_ready(void)775 int intel_mailbox_is_fpga_not_ready(void)
776 {
777 	int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true, NULL);
778 
779 	if ((ret != MBOX_RET_OK) && (ret != MBOX_CFGSTAT_STATE_CONFIG)) {
780 		ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS,
781 							false, NULL);
782 	}
783 
784 	return ret;
785 }
786 
mailbox_hwmon_readtemp(uint32_t chan,uint32_t * resp_buf)787 int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf)
788 {
789 	unsigned int resp_len = sizeof(resp_buf);
790 
791 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READTEMP, &chan, 1U,
792 				CMD_CASUAL, resp_buf,
793 				&resp_len);
794 
795 }
796 
mailbox_hwmon_readvolt(uint32_t chan,uint32_t * resp_buf)797 int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf)
798 {
799 	unsigned int resp_len = sizeof(resp_buf);
800 
801 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READVOLT, &chan, 1U,
802 				CMD_CASUAL, resp_buf,
803 				&resp_len);
804 }
805 
mailbox_seu_err_status(uint32_t * resp_buf,unsigned int resp_buf_len)806 int mailbox_seu_err_status(uint32_t *resp_buf, unsigned int resp_buf_len)
807 {
808 
809 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SEU_ERR_READ, NULL, 0U,
810 				CMD_CASUAL, resp_buf,
811 				&resp_buf_len);
812 }
813 
mailbox_safe_inject_seu_err(uint32_t * arg,unsigned int len)814 int mailbox_safe_inject_seu_err(uint32_t *arg, unsigned int len)
815 {
816 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SAFE_INJECT_SEU_ERR, arg, len,
817 			CMD_CASUAL, NULL, NULL);
818 }
819 
820 #if SIP_SVC_V3
mailbox_fill_cmd_desc(uint8_t client_id,uint8_t job_id,uint32_t * resp_buff)821 static int mailbox_fill_cmd_desc(uint8_t client_id, uint8_t job_id,
822 				 uint32_t *resp_buff)
823 {
824 	sdm_command_t *cmd_desc = NULL;
825 
826 	/* Get a free command descriptor */
827 	cmd_desc = mailbox_get_free_cmd_desc();
828 	if (cmd_desc == NULL) {
829 		return MBOX_BUFFER_FULL;
830 	}
831 
832 	/* Record all the given values for the command. */
833 	cmd_desc->client_id = client_id;
834 	cmd_desc->job_id = job_id;
835 	cmd_desc->cb = NULL;
836 	cmd_desc->cb_args = resp_buff;
837 	cmd_desc->cb_args_len = 0U;
838 
839 	return MBOX_RET_OK;
840 }
841 
842 /* Returns the command descriptor based on the client and job ID. */
mailbox_get_cmd_desc(uint8_t client_id,uint8_t job_id)843 static sdm_command_t *mailbox_get_cmd_desc(uint8_t client_id, uint8_t job_id)
844 {
845 	spin_lock(&mbox_db_lock);
846 	for (uint32_t count = 0; count < MBOX_SVC_CMD_QUEUE_SIZE; count++) {
847 		if ((mbox_svc.cmd_queue[count].client_id == client_id) &&
848 		    (mbox_svc.cmd_queue[count].job_id == job_id) &&
849 		    (mbox_svc.cmd_queue[count].flags & MBOX_SVC_CMD_IS_USED)) {
850 			spin_unlock(&mbox_db_lock);
851 			return &(mbox_svc.cmd_queue[count]);
852 		}
853 	}
854 
855 	spin_unlock(&mbox_db_lock);
856 	VERBOSE("MBOX: Command descriptor not found for cid %d, jid %d\n",
857 		client_id, job_id);
858 
859 	return NULL;
860 }
861 
862 /* Returns the response descriptor based on only client ID. */
mailbox_get_resp_desc_cid(uint8_t client_id,uint8_t * index)863 static sdm_response_t *mailbox_get_resp_desc_cid(uint8_t client_id, uint8_t *index)
864 {
865 	spin_lock(&mbox_db_lock);
866 
867 	for (uint32_t count = 0; count < MBOX_SVC_RESP_QUEUE_SIZE; count++) {
868 		if ((mbox_svc.resp_queue[count].client_id == client_id) &&
869 		    (mbox_svc.resp_queue[count].flags & FLAG_SDM_RESPONSE_IS_VALID)) {
870 			*index = count;
871 			/*
872 			 * Once we get the valid response descriptor, get the
873 			 * job ID and mark up the bitmaps.
874 			 */
875 			uint8_t job_id = mbox_svc.resp_queue[count].job_id;
876 			uint8_t transaction_id = MBOX_GET_TRANS_ID(client_id, job_id);
877 
878 			mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
879 				~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
880 			mbox_svc.interrupt_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
881 				~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
882 			spin_unlock(&mbox_db_lock);
883 			return &(mbox_svc.resp_queue[count]);
884 		}
885 	}
886 
887 	spin_unlock(&mbox_db_lock);
888 	VERBOSE("MBOX: Response descriptor not found for cid %d\n", client_id);
889 
890 	return NULL;
891 }
892 
893 /* Returns the response descriptor based on the client and job ID. */
mailbox_get_resp_desc(uint8_t client_id,uint8_t job_id,uint8_t * index)894 static sdm_response_t *mailbox_get_resp_desc(uint8_t client_id, uint8_t job_id, uint8_t *index)
895 {
896 	spin_lock(&mbox_db_lock);
897 	/*
898 	 * Let's first check whether we have a response bitmap set for the given
899 	 * client ID and job ID.
900 	 */
901 	uint8_t transaction_id = MBOX_GET_TRANS_ID(client_id, job_id);
902 
903 	if ((mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &
904 		(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE))) == 0) {
905 		spin_unlock(&mbox_db_lock);
906 		VERBOSE("MBOX: Response bitmap not set for cid %d, jid %d, bitmap 0x%16lx\n",
907 			client_id, job_id, mbox_svc.received_bitmap[transaction_id / 64]);
908 		return NULL;
909 	}
910 
911 	for (uint32_t count = 0; count < MBOX_SVC_RESP_QUEUE_SIZE; count++) {
912 		if (mbox_svc.resp_queue[count].flags & FLAG_SDM_RESPONSE_IS_VALID) {
913 			if ((mbox_svc.resp_queue[count].client_id == client_id) &&
914 			    (mbox_svc.resp_queue[count].job_id == job_id)) {
915 				*index = count;
916 				mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
917 					~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
918 				mbox_svc.interrupt_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
919 					~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
920 				spin_unlock(&mbox_db_lock);
921 				return &(mbox_svc.resp_queue[count]);
922 			}
923 		}
924 	}
925 
926 	spin_unlock(&mbox_db_lock);
927 	VERBOSE("MBOX: Response descriptor not found for cid %d, jid %d\n",
928 		client_id, job_id);
929 
930 	return NULL;
931 }
932 
mailbox_get_free_resp_desc(void)933 static int32_t mailbox_get_free_resp_desc(void)
934 {
935 	spin_lock(&mbox_db_lock);
936 	static uint32_t free_index = MBOX_SVC_RESP_QUEUE_SIZE - 1;
937 	uint32_t count = 0U, try = 0U;
938 
939 	for (try = 0; try < MBOX_SVC_RESP_QUEUE_SIZE; try++) {
940 		free_index = (free_index + 1) % MBOX_SVC_RESP_QUEUE_SIZE;
941 		if (!(mbox_svc.resp_queue[free_index].flags &
942 			FLAG_SDM_RESPONSE_IS_USED)) {
943 			count = free_index;
944 			spin_unlock(&mbox_db_lock);
945 			return count;
946 		}
947 	}
948 
949 	/* No free descriptors are available */
950 	spin_unlock(&mbox_db_lock);
951 	VERBOSE("MBOX: No free response descriptors are available\n");
952 
953 	return MBOX_BUFFER_FULL;
954 }
955 
mailbox_get_free_cmd_desc(void)956 static sdm_command_t *mailbox_get_free_cmd_desc(void)
957 {
958 	spin_lock(&mbox_db_lock);
959 	static uint32_t free_index;
960 
961 	/* Rollover the command queue free index */
962 	if (free_index == (MBOX_SVC_CMD_QUEUE_SIZE - 1)) {
963 		free_index = 0U;
964 	}
965 
966 	for (; free_index < MBOX_SVC_CMD_QUEUE_SIZE; free_index++) {
967 		if (!(mbox_svc.cmd_queue[free_index].flags &
968 			MBOX_SVC_CMD_IS_USED)) {
969 			mbox_svc.cmd_queue[free_index].flags |= MBOX_SVC_CMD_IS_USED;
970 			spin_unlock(&mbox_db_lock);
971 			return &(mbox_svc.cmd_queue[free_index]);
972 		}
973 	}
974 
975 	/* No free command descriptors are available */
976 	spin_unlock(&mbox_db_lock);
977 	VERBOSE("MBOX: No free command descriptors available\n");
978 
979 	return NULL;
980 }
981 
mailbox_free_cmd_desc(sdm_command_t * cmd_desc)982 static inline void mailbox_free_cmd_desc(sdm_command_t *cmd_desc)
983 {
984 	if (cmd_desc == NULL) {
985 		return;
986 	}
987 
988 	spin_lock(&mbox_db_lock);
989 	memset((void *)cmd_desc, 0, sizeof(sdm_command_t));
990 	spin_unlock(&mbox_db_lock);
991 }
992 
mailbox_free_resp_desc(uint8_t index)993 static inline void mailbox_free_resp_desc(uint8_t index)
994 {
995 	if (index >= MBOX_SVC_RESP_QUEUE_SIZE) {
996 		return;
997 	}
998 
999 	spin_lock(&mbox_db_lock);
1000 	memset((void *)&mbox_svc.resp_queue[index], 0, sizeof(sdm_response_t));
1001 	spin_unlock(&mbox_db_lock);
1002 }
1003 
1004 /*
1005  * This function serves the V1 _sync_read and _async_read functionality, and it
1006  * is introduced as part of V3 framework to keep backward compatible with V1
1007  * clients.
1008  */
mailbox_read_response_v3(uint8_t client_id,uint8_t * job_id,uint32_t * header,uint32_t * resp,uint32_t * resp_len,uint8_t ignore_client_id)1009 static int mailbox_read_response_v3(uint8_t client_id, uint8_t *job_id,
1010 				    uint32_t *header, uint32_t *resp,
1011 				    uint32_t *resp_len,
1012 				    uint8_t ignore_client_id)
1013 {
1014 	uint8_t di = 0U;
1015 	int status = MBOX_RET_OK;
1016 	sdm_response_t *resp_desc = NULL;
1017 	sdm_command_t *cmd_desc = NULL;
1018 
1019 	/*
1020 	 * In the V1, the client ID is always MBOX_ATF_CLIENT_ID and in this
1021 	 * routine we will collect the response which only belongs to this
1022 	 * client ID. So safe to ignore this input.
1023 	 */
1024 	(void)ignore_client_id;
1025 
1026 	/* Clear the SDM doorbell interrupt */
1027 	if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U)
1028 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
1029 
1030 	/* Fill the command descriptor index and get the same */
1031 	status = mailbox_fill_cmd_desc(client_id, async_v1_job_id, resp);
1032 	if (status != MBOX_RET_OK) {
1033 		return status;
1034 	}
1035 
1036 	cmd_desc = mailbox_get_cmd_desc(client_id, async_v1_job_id);
1037 
1038 	/* Get the response from SDM, just go through one cycle */
1039 	status = mailbox_response_handler_fsm();
1040 	if (status != MBOX_RET_OK) {
1041 		mailbox_free_cmd_desc(cmd_desc);
1042 		*resp_len = 0U;
1043 		return status;
1044 	}
1045 
1046 	/* Check the local response queue with the given client ID */
1047 	resp_desc = mailbox_get_resp_desc_cid(client_id, &di);
1048 	if (resp_desc == NULL) {
1049 		mailbox_free_cmd_desc(cmd_desc);
1050 		*resp_len = 0U;
1051 		return MBOX_NO_RESPONSE;
1052 	}
1053 
1054 	/* Update the received mailbox response length, job ID and header */
1055 	*job_id = resp_desc->job_id;
1056 	*resp_len = resp_desc->rcvd_resp_len;
1057 	if (header != NULL) {
1058 		*header = resp_desc->header;
1059 	}
1060 
1061 	/* Check the mailbox response error code */
1062 	if (MBOX_RESP_ERR(resp_desc->header) > 0U) {
1063 		INFO("MBOX: Error in async response: %x\n", resp_desc->header);
1064 		status = -MBOX_RESP_ERR(resp_desc->header);
1065 	}
1066 
1067 	/* Free up the response and command descriptors */
1068 	mailbox_free_resp_desc(di);
1069 	mailbox_free_cmd_desc(cmd_desc);
1070 
1071 	return status;
1072 }
1073 
mailbox_send_cmd_async_v3(uint8_t client_id,uint8_t job_id,uint32_t cmd,uint32_t * args,uint32_t args_len,uint8_t cmd_flag,sdm_command_callback cb,uint32_t * cb_args,uint32_t cb_args_len)1074 int mailbox_send_cmd_async_v3(uint8_t client_id, uint8_t job_id, uint32_t cmd,
1075 			      uint32_t *args, uint32_t args_len, uint8_t cmd_flag,
1076 			      sdm_command_callback cb, uint32_t *cb_args,
1077 			      uint32_t cb_args_len)
1078 {
1079 	int status = 0;
1080 	sdm_command_t *cmd_desc = NULL;
1081 
1082 	VERBOSE("MBOX: cid: %d, jid: %d, cmd: %d, cmd_flag: %d\n",
1083 		client_id, job_id, cmd, cmd_flag);
1084 
1085 	if (IS_CMD_SET(cmd_flag, URGENT)) {
1086 		mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
1087 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
1088 	} else {
1089 		/* Get a free command descriptor */
1090 		cmd_desc = mailbox_get_free_cmd_desc();
1091 		if (cmd_desc == NULL) {
1092 			return MBOX_BUFFER_FULL;
1093 		}
1094 
1095 		/* Record all the given values for the command. */
1096 		cmd_desc->client_id = client_id;
1097 		cmd_desc->job_id = job_id;
1098 		cmd_desc->cb = cb;
1099 		cmd_desc->cb_args = cb_args;
1100 		cmd_desc->cb_args_len = cb_args_len;
1101 
1102 		/* Push the command to mailbox FIFO */
1103 		status = fill_mailbox_circular_buffer(
1104 					MBOX_FRAME_CMD_HEADER(client_id, job_id,
1105 					args_len, IS_CMD_SET(cmd_flag, INDIRECT), cmd),
1106 					args,
1107 					args_len);
1108 
1109 		if (status != MBOX_RET_OK) {
1110 			INFO("MBOX: Failed to push the command to mailbox FIFO\n");
1111 			/* Free the command descriptor. */
1112 			mailbox_free_cmd_desc(cmd_desc);
1113 		}
1114 	}
1115 
1116 	INFO("MBOX: %s: status: %d\n", __func__, status);
1117 
1118 	return status;
1119 }
1120 
mailbox_poll_response_v3(uint8_t client_id,uint8_t job_id,uint32_t * resp,unsigned int * resp_len,uint32_t urgent)1121 static int mailbox_poll_response_v3(uint8_t client_id, uint8_t job_id,
1122 				    uint32_t *resp, unsigned int *resp_len,
1123 				    uint32_t urgent)
1124 {
1125 	unsigned int timeout = 40U;
1126 	unsigned int sdm_loop = 255U;
1127 	bool is_cmd_desc_fill = false;
1128 	uint8_t di = 0U;
1129 	sdm_response_t *resp_desc = NULL;
1130 	sdm_command_t *cmd_desc = NULL;
1131 
1132 	while (sdm_loop != 0U) {
1133 		do {
1134 			if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
1135 				== 1U) {
1136 				break;
1137 			}
1138 			mdelay(10U);
1139 		} while (--timeout != 0U);
1140 
1141 		if (timeout == 0U) {
1142 			INFO("%s: Timed out waiting for SDM intr\n", __func__);
1143 			break;
1144 		}
1145 
1146 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
1147 
1148 		if ((urgent & 1U) != 0U) {
1149 			mdelay(5U);
1150 			if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
1151 				MBOX_STATUS_UA_MASK) ^
1152 				(urgent & MBOX_STATUS_UA_MASK)) {
1153 				mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
1154 				return MBOX_RET_OK;
1155 			}
1156 
1157 			mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
1158 			ERROR("MBOX: Mailbox did not get UA");
1159 			return MBOX_RET_ERROR;
1160 		}
1161 
1162 		/* Fill the command descriptor index and get the same. */
1163 		if (!is_cmd_desc_fill) {
1164 			if (mailbox_fill_cmd_desc(client_id, job_id, resp) !=
1165 				MBOX_RET_OK) {
1166 				return MBOX_BUFFER_FULL;
1167 			}
1168 
1169 			cmd_desc = mailbox_get_cmd_desc(client_id, job_id);
1170 			is_cmd_desc_fill = true;
1171 		}
1172 
1173 		/* Since it is sync call, will try to read till it time out */
1174 		(void)mailbox_response_handler_fsm();
1175 
1176 		/* Check the response queue with the given client ID and job ID */
1177 		resp_desc = mailbox_get_resp_desc(client_id, job_id, &di);
1178 		if (resp_desc != NULL) {
1179 			VERBOSE("%s: Resp received for cid %d, jid %d\n",
1180 				__func__, resp_desc->client_id, resp_desc->job_id);
1181 
1182 			uint16_t header = resp_desc->header;
1183 
1184 			/* Update the return response length */
1185 			if (resp_len != NULL) {
1186 				*resp_len = resp_desc->rcvd_resp_len;
1187 			}
1188 
1189 			/* Free the response and command descriptor */
1190 			mailbox_free_resp_desc(di);
1191 			mailbox_free_cmd_desc(cmd_desc);
1192 
1193 			if (MBOX_RESP_ERR(header) > 0U) {
1194 				INFO("%s: SDM err code: 0x%x\n", __func__,
1195 					MBOX_RESP_ERR(header));
1196 				return -MBOX_RESP_ERR(header);
1197 			}
1198 
1199 			VERBOSE("%s: MBOX_RET_OK\n", __func__);
1200 			return MBOX_RET_OK;
1201 		}
1202 		sdm_loop--;
1203 	}
1204 
1205 	INFO("%s: Timed out waiting for SDM\n", __func__);
1206 	return MBOX_TIMEOUT;
1207 }
1208 
1209 /* SDM response parser handler state machine. */
mailbox_response_parser(void)1210 static void mailbox_response_parser(void)
1211 {
1212 	int di = -1;		/* Descriptor index */
1213 	uint32_t rin;
1214 	uint32_t rout;
1215 
1216 	switch (mbox_svc.next_resp_state) {
1217 	case SRS_WAIT_FOR_RESP:
1218 	{
1219 		mbox_svc.resp_state = SRS_WAIT_FOR_RESP;
1220 
1221 		rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
1222 		rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
1223 		if (rin != rout) {
1224 			mbox_svc.next_resp_state = SRS_WAIT_FOR_HEADER;
1225 		}
1226 
1227 		break;
1228 	}
1229 
1230 	case SRS_WAIT_FOR_HEADER:
1231 	{
1232 		mbox_svc.resp_state = SRS_WAIT_FOR_HEADER;
1233 		uint32_t resp_hdr;
1234 		uint8_t trans_id = 0U;
1235 
1236 		rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
1237 		rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
1238 		if (rin != rout) {
1239 			/* Read the header and dequeue from the queue. */
1240 			resp_hdr = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
1241 			rout %= MBOX_RESP_BUFFER_SIZE;
1242 			mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
1243 
1244 			/* Allocate a new response descriptor */
1245 			di = mailbox_get_free_resp_desc();
1246 			if (di != -1) {
1247 				mbox_svc.curr_di = di;
1248 				mbox_svc.resp_queue[di].header = resp_hdr;
1249 				mbox_svc.resp_queue[di].client_id = MBOX_RESP_CLIENT_ID(resp_hdr);
1250 				mbox_svc.resp_queue[di].job_id = MBOX_RESP_JOB_ID(resp_hdr);
1251 				mbox_svc.resp_queue[di].resp_len = MBOX_RESP_LEN(resp_hdr);
1252 				mbox_svc.resp_queue[di].flags |= (FLAG_SDM_RESPONSE_IS_USED |
1253 								  FLAG_SDM_RESPONSE_IS_IN_PROGRESS);
1254 				mbox_svc.resp_queue[di].err_code = MBOX_RESP_ERR(resp_hdr);
1255 				trans_id = MBOX_RESP_TRANSACTION_ID(resp_hdr);
1256 
1257 				VERBOSE("MBOX: Resp Hdr: cid %d, jid %d, len %d, err_code 0x%x\n",
1258 					mbox_svc.resp_queue[di].client_id,
1259 					mbox_svc.resp_queue[di].job_id,
1260 					mbox_svc.resp_queue[di].resp_len,
1261 					mbox_svc.resp_queue[di].err_code);
1262 
1263 				/* Check if the response is an argument response */
1264 				if (mbox_svc.resp_queue[di].resp_len > 0) {
1265 					mbox_svc.next_resp_state = SRS_WAIT_FOR_ARGUMENTS;
1266 				} else {
1267 					VERBOSE("MBOX: Received complete response with no args\n");
1268 					/* Non argument response, done */
1269 					mbox_svc.resp_queue[mbox_svc.curr_di].flags |=
1270 									FLAG_SDM_RESPONSE_IS_VALID;
1271 
1272 					/* Go back to waiting for new response */
1273 					mbox_svc.next_resp_state = SRS_WAIT_FOR_RESP;
1274 					mbox_svc.curr_di = -1;
1275 
1276 					/* Mark the transaction ID as received */
1277 					spin_lock(&mbox_db_lock);
1278 					mbox_svc.received_bitmap[trans_id / MBOX_TID_BITMAP_SIZE] |=
1279 							(1ULL << (trans_id % MBOX_TID_BITMAP_SIZE));
1280 					spin_unlock(&mbox_db_lock);
1281 				}
1282 			} else {
1283 				mbox_svc.next_resp_state = SRS_SYNC_ERROR;
1284 			}
1285 		}
1286 		break;
1287 	}
1288 
1289 	case SRS_WAIT_FOR_ARGUMENTS:
1290 	{
1291 		mbox_svc.resp_state = SRS_WAIT_FOR_ARGUMENTS;
1292 		uint16_t mbox_resp_len = mbox_svc.resp_queue[mbox_svc.curr_di].resp_len;
1293 		uint32_t *read_buff = NULL;
1294 		uint16_t read_len = 0U;
1295 		uint16_t read_max_len = 0U;
1296 		uint32_t timeout = 0U;
1297 
1298 		/* Determine where to copy the buffer. */
1299 		sdm_command_t *cmd_desc = mailbox_get_cmd_desc(
1300 						mbox_svc.resp_queue[mbox_svc.curr_di].client_id,
1301 						mbox_svc.resp_queue[mbox_svc.curr_di].job_id);
1302 		if (cmd_desc != NULL && cmd_desc->cb_args != NULL) {
1303 			read_buff = cmd_desc->cb_args;
1304 			read_max_len = mbox_resp_len;
1305 		} else {
1306 			read_buff = (uint32_t *)mbox_svc.resp_queue[mbox_svc.curr_di].resp_data;
1307 			read_max_len = MBOX_SVC_MAX_RESP_DATA_SIZE;
1308 		}
1309 
1310 		rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
1311 		rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
1312 
1313 		while ((read_len < mbox_resp_len) && (rin != rout) && (read_len < read_max_len)) {
1314 			timeout = 10000U;
1315 
1316 			/* Copy the response data to the buffer */
1317 			read_buff[read_len++] = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
1318 
1319 			VERBOSE("MBOX: 0x%x\n", read_buff[read_len - 1]);
1320 
1321 			/* Update the read out buffer index */
1322 			rout %= MBOX_RESP_BUFFER_SIZE;
1323 			mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
1324 
1325 			/*
1326 			 * The response buffer is of 16 words size, this loop checks
1327 			 * if the response buffer is empty and if empty trigger an
1328 			 * interrupt to SDM and wait for the response buffer to fill
1329 			 */
1330 			do {
1331 				if (read_len == mbox_resp_len)
1332 					break;
1333 
1334 				rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
1335 				if (rout == rin) {
1336 					mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
1337 					udelay(100);
1338 				} else {
1339 					break;
1340 				}
1341 				timeout--;
1342 			} while ((read_len < mbox_resp_len) && (timeout != 0U));
1343 
1344 			if (timeout == 0U) {
1345 				INFO("MBOX: Timeout waiting for response data\n");
1346 				mbox_svc.next_resp_state = SRS_SYNC_ERROR;
1347 				break;
1348 			}
1349 		}
1350 
1351 		/* Check if we have received all the arguments */
1352 		mbox_svc.resp_queue[mbox_svc.curr_di].rcvd_resp_len = read_len;
1353 		if (mbox_resp_len == read_len) {
1354 			uint8_t transaction_id =
1355 					((mbox_svc.resp_queue[mbox_svc.curr_di].client_id << 4) |
1356 					 (mbox_svc.resp_queue[mbox_svc.curr_di].job_id));
1357 			VERBOSE("MBOX: Received all the response data len %d, transaction_id %d\n",
1358 				read_len, transaction_id);
1359 
1360 			spin_lock(&mbox_db_lock);
1361 			mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] |=
1362 						(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
1363 			spin_unlock(&mbox_db_lock);
1364 
1365 			mbox_svc.resp_queue[mbox_svc.curr_di].flags |= FLAG_SDM_RESPONSE_IS_VALID;
1366 			mbox_svc.next_resp_state = SRS_WAIT_FOR_RESP;
1367 			mbox_svc.curr_di = -1;
1368 		} else {
1369 			mbox_svc.next_resp_state = SRS_SYNC_ERROR;
1370 			VERBOSE("MBOX: Received partial response data len %d, max len %d\n",
1371 				read_len, read_max_len);
1372 		}
1373 		break;
1374 	}
1375 
1376 	case SRS_SYNC_ERROR:
1377 	{
1378 		mbox_svc.resp_state = SRS_SYNC_ERROR;
1379 		INFO("MBOX: Error in response handling\n");
1380 		break;
1381 	}
1382 
1383 	default:
1384 		break;
1385 	} /* switch */
1386 }
1387 
mailbox_response_handler_fsm(void)1388 static int mailbox_response_handler_fsm(void)
1389 {
1390 	int status = MBOX_RET_OK;
1391 
1392 	spin_lock(&mbox_read_lock);
1393 	/* Mailbox peripheral response parser */
1394 	do {
1395 		/* Iterate till the state machine transition ends */
1396 		mailbox_response_parser();
1397 
1398 		/* Note down if there is any error in the response parsing */
1399 		if (mbox_svc.next_resp_state == SRS_SYNC_ERROR) {
1400 			status = MBOX_RET_ERROR;
1401 		}
1402 
1403 	} while (mbox_svc.resp_state != mbox_svc.next_resp_state);
1404 	spin_unlock(&mbox_read_lock);
1405 
1406 	return status;
1407 }
1408 
mailbox_response_poll_on_intr_v3(uint8_t * client_id,uint8_t * job_id,uint64_t * bitmap)1409 int mailbox_response_poll_on_intr_v3(uint8_t *client_id, uint8_t *job_id,
1410 				     uint64_t *bitmap)
1411 {
1412 	uint32_t i = 0U;
1413 	int status = MBOX_RET_OK;
1414 
1415 	/* Clear the SDM doorbell interrupt immediately */
1416 	if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
1417 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
1418 	}
1419 
1420 	/* Check mailbox FIFO for any pending responses available to read. */
1421 	status = mailbox_response_handler_fsm();
1422 	if (status != MBOX_RET_OK) {
1423 		return status;
1424 	}
1425 
1426 	/*
1427 	 * Once we read the complete mailbox FIFO, let's mark up the bitmap for
1428 	 * available responses with respect to each transcation IDs.
1429 	 */
1430 	status = MBOX_NO_RESPONSE;
1431 	spin_lock(&mbox_db_lock);
1432 	for (i = 0; i < MBOX_MAX_TIDS_BITMAP; i++) {
1433 		bitmap[i] = mbox_svc.interrupt_bitmap[i] ^ mbox_svc.received_bitmap[i];
1434 		if (bitmap[i] != 0 && status == MBOX_NO_RESPONSE) {
1435 			status = MBOX_RET_OK;
1436 		}
1437 
1438 		mbox_svc.interrupt_bitmap[i] = mbox_svc.received_bitmap[i];
1439 	}
1440 	spin_unlock(&mbox_db_lock);
1441 
1442 	return status;
1443 }
1444 
mailbox_response_poll_v3(uint8_t client_id,uint8_t job_id,uint64_t * ret_args,uint32_t * ret_args_len)1445 int mailbox_response_poll_v3(uint8_t client_id, uint8_t job_id,
1446 			     uint64_t *ret_args, uint32_t *ret_args_len)
1447 {
1448 	sdm_command_t *cmd_desc = NULL;
1449 	sdm_response_t *resp_desc = NULL;
1450 	uint8_t di = 0U;
1451 	int status = MBOX_RET_OK;
1452 
1453 	/*
1454 	 * Let's first check the local response queue with the given
1455 	 * client ID and job ID
1456 	 */
1457 	resp_desc = mailbox_get_resp_desc(client_id, job_id, &di);
1458 	if (resp_desc == NULL) {
1459 		/* Not available in the local queue, let's read mailbox FIFO */
1460 		status = mailbox_response_handler_fsm();
1461 		if (status != MBOX_RET_OK) {
1462 			return status;
1463 		}
1464 
1465 		resp_desc = mailbox_get_resp_desc(client_id, job_id, &di);
1466 	}
1467 	cmd_desc = mailbox_get_cmd_desc(client_id, job_id);
1468 
1469 	if (cmd_desc != NULL && resp_desc != NULL) {
1470 		VERBOSE("MBOX: Resp found for cid %d, jid %d\n", client_id, job_id);
1471 
1472 		/* Command callback function */
1473 		*ret_args_len = cmd_desc->cb(resp_desc, cmd_desc, ret_args);
1474 
1475 		/* Free the command and response descriptors. */
1476 		mailbox_free_cmd_desc(cmd_desc);
1477 		mailbox_free_resp_desc(di);
1478 
1479 		return MBOX_RET_OK;
1480 	}
1481 
1482 	INFO("MBOX: No resp found for cid: %d, jid: %d\n", client_id, job_id);
1483 
1484 	return MBOX_NO_RESPONSE;
1485 }
1486 
mailbox_init_v3(void)1487 void mailbox_init_v3(void)
1488 {
1489 	uint32_t count;
1490 
1491 	memset((void *)&mbox_svc, 0, sizeof(mbox_svc));
1492 
1493 	mbox_svc.next_resp_state = SRS_WAIT_FOR_RESP;
1494 	mbox_svc.resp_state = SRS_WAIT_FOR_RESP;
1495 
1496 	/* Free all entries from the response queue. */
1497 	for (count = 0; count < MBOX_SVC_RESP_QUEUE_SIZE; count++) {
1498 		mbox_svc.resp_queue[count].flags = 0;
1499 	}
1500 
1501 	/* Free all entries from the command queue. */
1502 	for (count = 0; count < MBOX_SVC_CMD_QUEUE_SIZE; count++) {
1503 		mbox_svc.cmd_queue[count].flags = 0;
1504 	}
1505 
1506 	mbox_svc.curr_di = -1;
1507 }
1508 #endif /* #if SIP_SVC_V3 */
1509