xref: /arm-trusted-firmware/plat/marvell/armada/a3k/common/cm3_system_reset.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (C) 2020 Marek Behun, CZ.NIC
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier:     BSD-3-Clause
5*91f16700Schasinglulu  * https://spdx.org/licenses
6*91f16700Schasinglulu  */
7*91f16700Schasinglulu 
8*91f16700Schasinglulu #include <stdbool.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <common/debug.h>
11*91f16700Schasinglulu #include <drivers/delay_timer.h>
12*91f16700Schasinglulu #include <lib/mmio.h>
13*91f16700Schasinglulu 
14*91f16700Schasinglulu #include <mvebu_def.h>
15*91f16700Schasinglulu 
16*91f16700Schasinglulu /* Cortex-M3 Secure Processor Mailbox Registers */
17*91f16700Schasinglulu #define MVEBU_RWTM_PARAM0_REG			(MVEBU_RWTM_REG_BASE)
18*91f16700Schasinglulu #define MVEBU_RWTM_CMD_REG			(MVEBU_RWTM_REG_BASE + 0x40)
19*91f16700Schasinglulu #define MVEBU_RWTM_HOST_INT_RESET_REG		(MVEBU_RWTM_REG_BASE + 0xC8)
20*91f16700Schasinglulu #define MVEBU_RWTM_HOST_INT_MASK_REG		(MVEBU_RWTM_REG_BASE + 0xCC)
21*91f16700Schasinglulu #define MVEBU_RWTM_HOST_INT_SP_COMPLETE		BIT(0)
22*91f16700Schasinglulu 
23*91f16700Schasinglulu #define MVEBU_RWTM_REBOOT_CMD		0x0009
24*91f16700Schasinglulu #define MVEBU_RWTM_REBOOT_MAGIC		0xDEADBEEF
25*91f16700Schasinglulu 
26*91f16700Schasinglulu static inline bool rwtm_completed(void)
27*91f16700Schasinglulu {
28*91f16700Schasinglulu 	return (mmio_read_32(MVEBU_RWTM_HOST_INT_RESET_REG) &
29*91f16700Schasinglulu 		MVEBU_RWTM_HOST_INT_SP_COMPLETE) != 0;
30*91f16700Schasinglulu }
31*91f16700Schasinglulu 
32*91f16700Schasinglulu static bool rwtm_wait(int ms)
33*91f16700Schasinglulu {
34*91f16700Schasinglulu 	while (ms && !rwtm_completed()) {
35*91f16700Schasinglulu 		mdelay(1);
36*91f16700Schasinglulu 		--ms;
37*91f16700Schasinglulu 	}
38*91f16700Schasinglulu 
39*91f16700Schasinglulu 	return rwtm_completed();
40*91f16700Schasinglulu }
41*91f16700Schasinglulu 
42*91f16700Schasinglulu void cm3_system_reset(void)
43*91f16700Schasinglulu {
44*91f16700Schasinglulu 	int tries = 5;
45*91f16700Schasinglulu 
46*91f16700Schasinglulu 	for (; tries > 0; --tries) {
47*91f16700Schasinglulu 		mmio_clrbits_32(MVEBU_RWTM_HOST_INT_RESET_REG,
48*91f16700Schasinglulu 				MVEBU_RWTM_HOST_INT_SP_COMPLETE);
49*91f16700Schasinglulu 
50*91f16700Schasinglulu 		mmio_write_32(MVEBU_RWTM_PARAM0_REG, MVEBU_RWTM_REBOOT_MAGIC);
51*91f16700Schasinglulu 		mmio_write_32(MVEBU_RWTM_CMD_REG, MVEBU_RWTM_REBOOT_CMD);
52*91f16700Schasinglulu 
53*91f16700Schasinglulu 		if (rwtm_wait(10)) {
54*91f16700Schasinglulu 			break;
55*91f16700Schasinglulu 		}
56*91f16700Schasinglulu 
57*91f16700Schasinglulu 		mdelay(100);
58*91f16700Schasinglulu 	}
59*91f16700Schasinglulu 
60*91f16700Schasinglulu 	/* If we reach here, the command is not implemented. */
61*91f16700Schasinglulu 	WARN("System reset command not implemented in WTMI firmware!\n");
62*91f16700Schasinglulu }
63