1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2017-2018 Intel Corporation <www.intel.com>
4  *
5  */
6 
7 #include <common.h>
8 #include <hang.h>
9 #include <wait_bit.h>
10 #include <asm/global_data.h>
11 #include <asm/io.h>
12 #include <asm/arch/mailbox_s10.h>
13 #include <asm/arch/system_manager.h>
14 #include <asm/secure.h>
15 #include <asm/system.h>
16 
17 DECLARE_GLOBAL_DATA_PTR;
18 
19 #define MBOX_READL(reg)			\
20 	 readl(SOCFPGA_MAILBOX_ADDRESS + (reg))
21 
22 #define MBOX_WRITEL(data, reg)		\
23 	writel(data, SOCFPGA_MAILBOX_ADDRESS + (reg))
24 
25 #define MBOX_READ_RESP_BUF(rout)	\
26 	MBOX_READL(MBOX_RESP_BUF + ((rout) * sizeof(u32)))
27 
28 #define MBOX_WRITE_CMD_BUF(data, cin)	\
29 	MBOX_WRITEL(data, MBOX_CMD_BUF + ((cin) * sizeof(u32)))
30 
mbox_polling_resp(u32 rout)31 static __always_inline int mbox_polling_resp(u32 rout)
32 {
33 	u32 rin;
34 	unsigned long i = 2000;
35 
36 	while (i) {
37 		rin = MBOX_READL(MBOX_RIN);
38 		if (rout != rin)
39 			return 0;
40 
41 		udelay(1000);
42 		i--;
43 	}
44 
45 	return -ETIMEDOUT;
46 }
47 
mbox_is_cmdbuf_full(u32 cin)48 static __always_inline int mbox_is_cmdbuf_full(u32 cin)
49 {
50 	return (((cin + 1) % MBOX_CMD_BUFFER_SIZE) == MBOX_READL(MBOX_COUT));
51 }
52 
mbox_is_cmdbuf_empty(u32 cin)53 static __always_inline int mbox_is_cmdbuf_empty(u32 cin)
54 {
55 	return (((MBOX_READL(MBOX_COUT) + 1) % MBOX_CMD_BUFFER_SIZE) == cin);
56 }
57 
mbox_wait_for_cmdbuf_empty(u32 cin)58 static __always_inline int mbox_wait_for_cmdbuf_empty(u32 cin)
59 {
60 	int timeout = 2000;
61 
62 	while (timeout) {
63 		if (mbox_is_cmdbuf_empty(cin))
64 			return 0;
65 		udelay(1000);
66 		timeout--;
67 	}
68 
69 	return -ETIMEDOUT;
70 }
71 
mbox_write_cmd_buffer(u32 * cin,u32 data,int * is_cmdbuf_overflow)72 static __always_inline int mbox_write_cmd_buffer(u32 *cin, u32 data,
73 						 int *is_cmdbuf_overflow)
74 {
75 	int timeout = 1000;
76 
77 	while (timeout) {
78 		if (mbox_is_cmdbuf_full(*cin)) {
79 			if (is_cmdbuf_overflow &&
80 			    *is_cmdbuf_overflow == 0) {
81 				/* Trigger SDM doorbell */
82 				MBOX_WRITEL(1, MBOX_DOORBELL_TO_SDM);
83 				*is_cmdbuf_overflow = 1;
84 			}
85 			udelay(1000);
86 		} else {
87 			/* write header to circular buffer */
88 			MBOX_WRITE_CMD_BUF(data, (*cin)++);
89 			*cin %= MBOX_CMD_BUFFER_SIZE;
90 			MBOX_WRITEL(*cin, MBOX_CIN);
91 			break;
92 		}
93 		timeout--;
94 	}
95 
96 	if (!timeout)
97 		return -ETIMEDOUT;
98 
99 	/* Wait for the SDM to drain the FIFO command buffer */
100 	if (is_cmdbuf_overflow && *is_cmdbuf_overflow)
101 		return mbox_wait_for_cmdbuf_empty(*cin);
102 
103 	return 0;
104 }
105 
106 /* Check for available slot and write to circular buffer.
107  * It also update command valid offset (cin) register.
108  */
mbox_fill_cmd_circular_buff(u32 header,u32 len,u32 * arg)109 static __always_inline int mbox_fill_cmd_circular_buff(u32 header, u32 len,
110 						       u32 *arg)
111 {
112 	int i, ret;
113 	int is_cmdbuf_overflow = 0;
114 	u32 cin = MBOX_READL(MBOX_CIN) % MBOX_CMD_BUFFER_SIZE;
115 
116 	ret = mbox_write_cmd_buffer(&cin, header, &is_cmdbuf_overflow);
117 	if (ret)
118 		return ret;
119 
120 	/* write arguments */
121 	for (i = 0; i < len; i++) {
122 		is_cmdbuf_overflow = 0;
123 		ret = mbox_write_cmd_buffer(&cin, arg[i], &is_cmdbuf_overflow);
124 		if (ret)
125 			return ret;
126 	}
127 
128 	/* If SDM doorbell is not triggered after the last data is
129 	 * written into mailbox FIFO command buffer, trigger the
130 	 * SDM doorbell again to ensure SDM able to read the remaining
131 	 * data.
132 	 */
133 	if (!is_cmdbuf_overflow)
134 		MBOX_WRITEL(1, MBOX_DOORBELL_TO_SDM);
135 
136 	return 0;
137 }
138 
139 /* Check the command and fill it into circular buffer */
mbox_prepare_cmd_only(u8 id,u32 cmd,u8 is_indirect,u32 len,u32 * arg)140 static __always_inline int mbox_prepare_cmd_only(u8 id, u32 cmd,
141 						 u8 is_indirect, u32 len,
142 						 u32 *arg)
143 {
144 	u32 header;
145 	int ret;
146 
147 	if (cmd > MBOX_MAX_CMD_INDEX)
148 		return -EINVAL;
149 
150 	header = MBOX_CMD_HEADER(MBOX_CLIENT_ID_UBOOT, id, len,
151 				 (is_indirect) ? 1 : 0, cmd);
152 
153 	ret = mbox_fill_cmd_circular_buff(header, len, arg);
154 
155 	return ret;
156 }
157 
158 /* Send command only without waiting for responses from SDM */
mbox_send_cmd_only_common(u8 id,u32 cmd,u8 is_indirect,u32 len,u32 * arg)159 static __always_inline int mbox_send_cmd_only_common(u8 id, u32 cmd,
160 						     u8 is_indirect, u32 len,
161 						     u32 *arg)
162 {
163 	return mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg);
164 }
165 
166 /* Return number of responses received in buffer */
__mbox_rcv_resp(u32 * resp_buf,u32 resp_buf_max_len)167 static __always_inline int __mbox_rcv_resp(u32 *resp_buf, u32 resp_buf_max_len)
168 {
169 	u32 rin;
170 	u32 rout;
171 	u32 resp_len = 0;
172 
173 	/* clear doorbell from SDM if it was SET */
174 	if (MBOX_READL(MBOX_DOORBELL_FROM_SDM) & 1)
175 		MBOX_WRITEL(0, MBOX_DOORBELL_FROM_SDM);
176 
177 	/* read current response offset */
178 	rout = MBOX_READL(MBOX_ROUT);
179 	/* read response valid offset */
180 	rin = MBOX_READL(MBOX_RIN);
181 
182 	while (rin != rout && (resp_len < resp_buf_max_len)) {
183 		/* Response received */
184 		if (resp_buf)
185 			resp_buf[resp_len++] = MBOX_READ_RESP_BUF(rout);
186 
187 		rout++;
188 		/* wrapping around when it reach the buffer size */
189 		rout %= MBOX_RESP_BUFFER_SIZE;
190 		/* update next ROUT */
191 		MBOX_WRITEL(rout, MBOX_ROUT);
192 	}
193 
194 	return resp_len;
195 }
196 
197 /* Support one command and up to 31 words argument length only */
mbox_send_cmd_common(u8 id,u32 cmd,u8 is_indirect,u32 len,u32 * arg,u8 urgent,u32 * resp_buf_len,u32 * resp_buf)198 static __always_inline int mbox_send_cmd_common(u8 id, u32 cmd, u8 is_indirect,
199 						u32 len, u32 *arg, u8 urgent,
200 						u32 *resp_buf_len,
201 						u32 *resp_buf)
202 {
203 	u32 rin;
204 	u32 resp;
205 	u32 rout;
206 	u32 status;
207 	u32 resp_len;
208 	u32 buf_len;
209 	int ret;
210 
211 	if (urgent) {
212 		/* Read status because it is toggled */
213 		status = MBOX_READL(MBOX_STATUS) & MBOX_STATUS_UA_MSK;
214 		/* Write urgent command to urgent register */
215 		MBOX_WRITEL(cmd, MBOX_URG);
216 		/* write doorbell */
217 		MBOX_WRITEL(1, MBOX_DOORBELL_TO_SDM);
218 	} else {
219 		ret = mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg);
220 		if (ret)
221 			return ret;
222 	}
223 
224 	while (1) {
225 		ret = 1000;
226 
227 		/* Wait for doorbell from SDM */
228 		do {
229 			if (MBOX_READL(MBOX_DOORBELL_FROM_SDM))
230 				break;
231 			udelay(1000);
232 		} while (--ret);
233 
234 		if (!ret)
235 			return -ETIMEDOUT;
236 
237 		/* clear interrupt */
238 		MBOX_WRITEL(0, MBOX_DOORBELL_FROM_SDM);
239 
240 		if (urgent) {
241 			u32 new_status = MBOX_READL(MBOX_STATUS);
242 
243 			/* Urgent ACK is toggled */
244 			if ((new_status & MBOX_STATUS_UA_MSK) ^ status)
245 				return 0;
246 
247 			return -ECOMM;
248 		}
249 
250 		/* read current response offset */
251 		rout = MBOX_READL(MBOX_ROUT);
252 
253 		/* read response valid offset */
254 		rin = MBOX_READL(MBOX_RIN);
255 
256 		if (rout != rin) {
257 			/* Response received */
258 			resp = MBOX_READ_RESP_BUF(rout);
259 			rout++;
260 			/* wrapping around when it reach the buffer size */
261 			rout %= MBOX_RESP_BUFFER_SIZE;
262 			/* update next ROUT */
263 			MBOX_WRITEL(rout, MBOX_ROUT);
264 
265 			/* check client ID and ID */
266 			if ((MBOX_RESP_CLIENT_GET(resp) ==
267 			     MBOX_CLIENT_ID_UBOOT) &&
268 			    (MBOX_RESP_ID_GET(resp) == id)) {
269 				int resp_err = MBOX_RESP_ERR_GET(resp);
270 
271 				if (resp_buf_len) {
272 					buf_len = *resp_buf_len;
273 					*resp_buf_len = 0;
274 				} else {
275 					buf_len = 0;
276 				}
277 
278 				resp_len = MBOX_RESP_LEN_GET(resp);
279 				while (resp_len) {
280 					ret = mbox_polling_resp(rout);
281 					if (ret)
282 						return ret;
283 					/* we need to process response buffer
284 					 * even caller doesn't need it
285 					 */
286 					resp = MBOX_READ_RESP_BUF(rout);
287 					rout++;
288 					resp_len--;
289 					rout %= MBOX_RESP_BUFFER_SIZE;
290 					MBOX_WRITEL(rout, MBOX_ROUT);
291 					if (buf_len) {
292 						/* copy response to buffer */
293 						resp_buf[*resp_buf_len] = resp;
294 						(*resp_buf_len)++;
295 						buf_len--;
296 					}
297 				}
298 				return resp_err;
299 			}
300 		}
301 	}
302 
303 	return -EIO;
304 }
305 
mbox_send_cmd_common_retry(u8 id,u32 cmd,u8 is_indirect,u32 len,u32 * arg,u8 urgent,u32 * resp_buf_len,u32 * resp_buf)306 static __always_inline int mbox_send_cmd_common_retry(u8 id, u32 cmd,
307 						      u8 is_indirect,
308 						      u32 len, u32 *arg,
309 						      u8 urgent,
310 						      u32 *resp_buf_len,
311 						      u32 *resp_buf)
312 {
313 	int ret;
314 	int i;
315 
316 	for (i = 0; i < 3; i++) {
317 		ret = mbox_send_cmd_common(id, cmd, is_indirect, len, arg,
318 					   urgent, resp_buf_len, resp_buf);
319 		if (ret == MBOX_RESP_TIMEOUT || ret == MBOX_RESP_DEVICE_BUSY)
320 			udelay(2000); /* wait for 2ms before resend */
321 		else
322 			break;
323 	}
324 
325 	return ret;
326 }
327 
mbox_init(void)328 int mbox_init(void)
329 {
330 	int ret;
331 
332 	/* enable mailbox interrupts */
333 	MBOX_WRITEL(MBOX_ALL_INTRS, MBOX_FLAGS);
334 
335 	/* Ensure urgent request is cleared */
336 	MBOX_WRITEL(0, MBOX_URG);
337 
338 	/* Ensure the Doorbell Interrupt is cleared */
339 	MBOX_WRITEL(0, MBOX_DOORBELL_FROM_SDM);
340 
341 	ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_RESTART, MBOX_CMD_DIRECT, 0,
342 			    NULL, 1, 0, NULL);
343 	if (ret)
344 		return ret;
345 
346 	/* Renable mailbox interrupts after MBOX_RESTART */
347 	MBOX_WRITEL(MBOX_ALL_INTRS, MBOX_FLAGS);
348 
349 	return 0;
350 }
351 
352 #ifdef CONFIG_CADENCE_QSPI
mbox_qspi_close(void)353 int mbox_qspi_close(void)
354 {
355 	return mbox_send_cmd(MBOX_ID_UBOOT, MBOX_QSPI_CLOSE, MBOX_CMD_DIRECT,
356 			     0, NULL, 0, 0, NULL);
357 }
358 
mbox_qspi_open(void)359 int mbox_qspi_open(void)
360 {
361 	int ret;
362 	u32 resp_buf[1];
363 	u32 resp_buf_len;
364 
365 	ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_QSPI_OPEN, MBOX_CMD_DIRECT,
366 			    0, NULL, 0, 0, NULL);
367 	if (ret) {
368 		/* retry again by closing and reopen the QSPI again */
369 		ret = mbox_qspi_close();
370 		if (ret)
371 			return ret;
372 
373 		ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_QSPI_OPEN,
374 				    MBOX_CMD_DIRECT, 0, NULL, 0, 0, NULL);
375 		if (ret)
376 			return ret;
377 	}
378 
379 	/* HPS will directly control the QSPI controller, no longer mailbox */
380 	resp_buf_len = 1;
381 	ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_QSPI_DIRECT, MBOX_CMD_DIRECT,
382 			    0, NULL, 0, (u32 *)&resp_buf_len,
383 			    (u32 *)&resp_buf);
384 	if (ret)
385 		goto error;
386 
387 	/* We are getting QSPI ref clock and set into sysmgr boot register */
388 	printf("QSPI: Reference clock at %d Hz\n", resp_buf[0]);
389 	writel(resp_buf[0],
390 	       socfpga_get_sysmgr_addr() + SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
391 
392 	return 0;
393 
394 error:
395 	mbox_qspi_close();
396 
397 	return ret;
398 }
399 #endif /* CONFIG_CADENCE_QSPI */
400 
mbox_reset_cold(void)401 int mbox_reset_cold(void)
402 {
403 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
404 	psci_system_reset();
405 #else
406 	int ret;
407 
408 	ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_REBOOT_HPS, MBOX_CMD_DIRECT,
409 			    0, NULL, 0, 0, NULL);
410 	if (ret) {
411 		/* mailbox sent failure, wait for watchdog to kick in */
412 		hang();
413 	}
414 #endif
415 	return 0;
416 }
417 
418 /* Accepted commands: CONFIG_STATUS or RECONFIG_STATUS */
mbox_get_fpga_config_status_common(u32 cmd)419 static __always_inline int mbox_get_fpga_config_status_common(u32 cmd)
420 {
421 	u32 reconfig_status_resp_len;
422 	u32 reconfig_status_resp[RECONFIG_STATUS_RESPONSE_LEN];
423 	int ret;
424 
425 	reconfig_status_resp_len = RECONFIG_STATUS_RESPONSE_LEN;
426 	ret = mbox_send_cmd_common_retry(MBOX_ID_UBOOT, cmd,
427 					 MBOX_CMD_DIRECT, 0, NULL, 0,
428 					 &reconfig_status_resp_len,
429 					 reconfig_status_resp);
430 
431 	if (ret)
432 		return ret;
433 
434 	/* Check for any error */
435 	ret = reconfig_status_resp[RECONFIG_STATUS_STATE];
436 	if (ret && ret != MBOX_CFGSTAT_STATE_CONFIG)
437 		return ret;
438 
439 	/* Make sure nStatus is not 0 */
440 	ret = reconfig_status_resp[RECONFIG_STATUS_PIN_STATUS];
441 	if (!(ret & RCF_PIN_STATUS_NSTATUS))
442 		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
443 
444 	ret = reconfig_status_resp[RECONFIG_STATUS_SOFTFUNC_STATUS];
445 	if (ret & RCF_SOFTFUNC_STATUS_SEU_ERROR)
446 		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
447 
448 	if ((ret & RCF_SOFTFUNC_STATUS_CONF_DONE) &&
449 	    (ret & RCF_SOFTFUNC_STATUS_INIT_DONE) &&
450 	    !reconfig_status_resp[RECONFIG_STATUS_STATE])
451 		return 0;	/* configuration success */
452 
453 	return MBOX_CFGSTAT_STATE_CONFIG;
454 }
455 
mbox_get_fpga_config_status(u32 cmd)456 int mbox_get_fpga_config_status(u32 cmd)
457 {
458 	return mbox_get_fpga_config_status_common(cmd);
459 }
460 
mbox_get_fpga_config_status_psci(u32 cmd)461 int __secure mbox_get_fpga_config_status_psci(u32 cmd)
462 {
463 	return mbox_get_fpga_config_status_common(cmd);
464 }
465 
mbox_send_cmd(u8 id,u32 cmd,u8 is_indirect,u32 len,u32 * arg,u8 urgent,u32 * resp_buf_len,u32 * resp_buf)466 int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg,
467 		  u8 urgent, u32 *resp_buf_len, u32 *resp_buf)
468 {
469 	return mbox_send_cmd_common_retry(id, cmd, is_indirect, len, arg,
470 					  urgent, resp_buf_len, resp_buf);
471 }
472 
mbox_send_cmd_psci(u8 id,u32 cmd,u8 is_indirect,u32 len,u32 * arg,u8 urgent,u32 * resp_buf_len,u32 * resp_buf)473 int __secure mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len,
474 				u32 *arg, u8 urgent, u32 *resp_buf_len,
475 				u32 *resp_buf)
476 {
477 	return mbox_send_cmd_common_retry(id, cmd, is_indirect, len, arg,
478 					  urgent, resp_buf_len, resp_buf);
479 }
480 
mbox_send_cmd_only(u8 id,u32 cmd,u8 is_indirect,u32 len,u32 * arg)481 int mbox_send_cmd_only(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg)
482 {
483 	return mbox_send_cmd_only_common(id, cmd, is_indirect, len, arg);
484 }
485 
mbox_send_cmd_only_psci(u8 id,u32 cmd,u8 is_indirect,u32 len,u32 * arg)486 int __secure mbox_send_cmd_only_psci(u8 id, u32 cmd, u8 is_indirect, u32 len,
487 				     u32 *arg)
488 {
489 	return mbox_send_cmd_only_common(id, cmd, is_indirect, len, arg);
490 }
491 
mbox_rcv_resp(u32 * resp_buf,u32 resp_buf_max_len)492 int mbox_rcv_resp(u32 *resp_buf, u32 resp_buf_max_len)
493 {
494 	return __mbox_rcv_resp(resp_buf, resp_buf_max_len);
495 }
496 
mbox_rcv_resp_psci(u32 * resp_buf,u32 resp_buf_max_len)497 int __secure mbox_rcv_resp_psci(u32 *resp_buf, u32 resp_buf_max_len)
498 {
499 	return __mbox_rcv_resp(resp_buf, resp_buf_max_len);
500 }
501