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