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