xref: /rk3399_ARM-atf/plat/marvell/armada/a3k/common/plat_pm.c (revision 517b7f96c9b5f403f3372898421a0fddbcdf3e9b)
1b5c850d4SMarcin Wojtas /*
2d9243f26SMarek Behún  * Copyright (C) 2018-2020 Marvell International Ltd.
3b5c850d4SMarcin Wojtas  *
4b5c850d4SMarcin Wojtas  * SPDX-License-Identifier:	BSD-3-Clause
5b5c850d4SMarcin Wojtas  * https://spdx.org/licenses
6b5c850d4SMarcin Wojtas  */
7b5c850d4SMarcin Wojtas 
8b5c850d4SMarcin Wojtas #include <common/debug.h>
9b5c850d4SMarcin Wojtas #ifdef USE_CCI
10b5c850d4SMarcin Wojtas #include <drivers/arm/cci.h>
11b5c850d4SMarcin Wojtas #endif
12b5c850d4SMarcin Wojtas #include <lib/psci/psci.h>
13b5c850d4SMarcin Wojtas #include <lib/mmio.h>
14b5c850d4SMarcin Wojtas #include <plat/common/platform.h>
15b5c850d4SMarcin Wojtas 
16b5c850d4SMarcin Wojtas #include <a3700_pm.h>
17b5c850d4SMarcin Wojtas #include <arch_helpers.h>
18b5c850d4SMarcin Wojtas #include <armada_common.h>
19b5c850d4SMarcin Wojtas #include <dram_win.h>
20b5c850d4SMarcin Wojtas #include <io_addr_dec.h>
21b5c850d4SMarcin Wojtas #include <mvebu.h>
22b5c850d4SMarcin Wojtas #include <mvebu_def.h>
23b5c850d4SMarcin Wojtas #include <marvell_plat_priv.h>
24b5c850d4SMarcin Wojtas #include <plat_marvell.h>
25b5c850d4SMarcin Wojtas 
26b5c850d4SMarcin Wojtas /* Warm reset register */
27b5c850d4SMarcin Wojtas #define MVEBU_WARM_RESET_REG		(MVEBU_NB_REGS_BASE + 0x840)
28b5c850d4SMarcin Wojtas #define MVEBU_WARM_RESET_MAGIC		0x1D1E
29b5c850d4SMarcin Wojtas 
30b5c850d4SMarcin Wojtas /* North Bridge GPIO1 SEL register */
31b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO1_SEL_REG		(MVEBU_NB_REGS_BASE + 0x830)
32b5c850d4SMarcin Wojtas  #define MVEBU_NB_GPIO1_UART1_SEL	BIT(19)
33b5c850d4SMarcin Wojtas  #define MVEBU_NB_GPIO1_GPIO_25_26_EN	BIT(17)
34b5c850d4SMarcin Wojtas  #define MVEBU_NB_GPIO1_GPIO_19_EN	BIT(14)
35b5c850d4SMarcin Wojtas  #define MVEBU_NB_GPIO1_GPIO_18_EN	BIT(13)
36b5c850d4SMarcin Wojtas 
37b5c850d4SMarcin Wojtas /* CPU 1 reset register */
38b5c850d4SMarcin Wojtas #define MVEBU_CPU_1_RESET_VECTOR	(MVEBU_REGS_BASE + 0x14044)
39b5c850d4SMarcin Wojtas #define MVEBU_CPU_1_RESET_REG		(MVEBU_REGS_BASE + 0xD00C)
40b5c850d4SMarcin Wojtas #define MVEBU_CPU_1_RESET_BIT		31
41b5c850d4SMarcin Wojtas 
42b5c850d4SMarcin Wojtas /* IRQ register */
43b5c850d4SMarcin Wojtas #define MVEBU_NB_IRQ_STATUS_1_REG		(MVEBU_NB_SB_IRQ_REG_BASE)
44b5c850d4SMarcin Wojtas #define MVEBU_NB_IRQ_STATUS_2_REG		(MVEBU_NB_SB_IRQ_REG_BASE + \
45b5c850d4SMarcin Wojtas 						0x10)
46b5c850d4SMarcin Wojtas #define MVEBU_NB_IRQ_MASK_2_REG			(MVEBU_NB_SB_IRQ_REG_BASE + \
47b5c850d4SMarcin Wojtas 						0x18)
48b5c850d4SMarcin Wojtas #define MVEBU_SB_IRQ_STATUS_1_REG		(MVEBU_NB_SB_IRQ_REG_BASE + \
49b5c850d4SMarcin Wojtas 						0x40)
50b5c850d4SMarcin Wojtas #define MVEBU_SB_IRQ_STATUS_2_REG		(MVEBU_NB_SB_IRQ_REG_BASE + \
51b5c850d4SMarcin Wojtas 						0x50)
52b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_IRQ_MASK_1_REG		(MVEBU_NB_SB_IRQ_REG_BASE + \
53b5c850d4SMarcin Wojtas 						0xC8)
54b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_IRQ_MASK_2_REG		(MVEBU_NB_SB_IRQ_REG_BASE + \
55b5c850d4SMarcin Wojtas 						0xD8)
56b5c850d4SMarcin Wojtas #define MVEBU_SB_GPIO_IRQ_MASK_REG		(MVEBU_NB_SB_IRQ_REG_BASE + \
57b5c850d4SMarcin Wojtas 						0xE8)
58b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_IRQ_EN_LOW_REG		(MVEBU_NB_GPIO_IRQ_REG_BASE)
59b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_IRQ_EN_HIGH_REG		(MVEBU_NB_GPIO_IRQ_REG_BASE + \
60b5c850d4SMarcin Wojtas 						0x04)
61b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG	(MVEBU_NB_GPIO_IRQ_REG_BASE + \
62b5c850d4SMarcin Wojtas 						0x10)
63b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG	(MVEBU_NB_GPIO_IRQ_REG_BASE + \
64b5c850d4SMarcin Wojtas 						0x14)
65b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_IRQ_WK_LOW_REG		(MVEBU_NB_GPIO_IRQ_REG_BASE + \
66b5c850d4SMarcin Wojtas 						0x18)
67b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_IRQ_WK_HIGH_REG		(MVEBU_NB_GPIO_IRQ_REG_BASE + \
68b5c850d4SMarcin Wojtas 						0x1C)
69b5c850d4SMarcin Wojtas #define MVEBU_SB_GPIO_IRQ_EN_REG		(MVEBU_SB_GPIO_IRQ_REG_BASE)
70b5c850d4SMarcin Wojtas #define MVEBU_SB_GPIO_IRQ_STATUS_REG		(MVEBU_SB_GPIO_IRQ_REG_BASE + \
71b5c850d4SMarcin Wojtas 						0x10)
72b5c850d4SMarcin Wojtas #define MVEBU_SB_GPIO_IRQ_WK_REG		(MVEBU_SB_GPIO_IRQ_REG_BASE + \
73b5c850d4SMarcin Wojtas 						0x18)
74b5c850d4SMarcin Wojtas 
75b5c850d4SMarcin Wojtas /* PMU registers */
76b5c850d4SMarcin Wojtas #define MVEBU_PM_NB_PWR_CTRL_REG	(MVEBU_PMSU_REG_BASE)
77b5c850d4SMarcin Wojtas  #define MVEBU_PM_PWR_DN_CNT_SEL	BIT(28)
78b5c850d4SMarcin Wojtas  #define MVEBU_PM_SB_PWR_DWN		BIT(4)
79b5c850d4SMarcin Wojtas  #define MVEBU_PM_INTERFACE_IDLE	BIT(0)
80b5c850d4SMarcin Wojtas #define MVEBU_PM_NB_CPU_PWR_CTRL_REG	(MVEBU_PMSU_REG_BASE + 0x4)
81b5c850d4SMarcin Wojtas  #define MVEBU_PM_L2_FLUSH_EN		BIT(22)
82b5c850d4SMarcin Wojtas #define MVEBU_PM_NB_PWR_OPTION_REG	(MVEBU_PMSU_REG_BASE + 0x8)
83b5c850d4SMarcin Wojtas  #define MVEBU_PM_DDR_SR_EN		BIT(29)
84b5c850d4SMarcin Wojtas  #define MVEBU_PM_DDR_CLK_DIS_EN	BIT(28)
85b5c850d4SMarcin Wojtas  #define MVEBU_PM_WARM_RESET_EN		BIT(27)
86b5c850d4SMarcin Wojtas  #define MVEBU_PM_DDRPHY_PWRDWN_EN	BIT(23)
87b5c850d4SMarcin Wojtas  #define MVEBU_PM_DDRPHY_PAD_PWRDWN_EN	BIT(22)
88b5c850d4SMarcin Wojtas  #define MVEBU_PM_OSC_OFF_EN		BIT(21)
89b5c850d4SMarcin Wojtas  #define MVEBU_PM_TBG_OFF_EN		BIT(20)
90b5c850d4SMarcin Wojtas  #define MVEBU_PM_CPU_VDDV_OFF_EN	BIT(19)
91b5c850d4SMarcin Wojtas  #define MVEBU_PM_AVS_DISABLE_MODE	BIT(14)
92b5c850d4SMarcin Wojtas  #define MVEBU_PM_AVS_VDD2_MODE		BIT(13)
93b5c850d4SMarcin Wojtas  #define MVEBU_PM_AVS_HOLD_MODE		BIT(12)
94b5c850d4SMarcin Wojtas  #define MVEBU_PM_L2_SRAM_LKG_PD_EN	BIT(8)
95b5c850d4SMarcin Wojtas  #define MVEBU_PM_EIP_SRAM_LKG_PD_EN	BIT(7)
96b5c850d4SMarcin Wojtas  #define MVEBU_PM_DDRMC_SRAM_LKG_PD_EN	BIT(6)
97b5c850d4SMarcin Wojtas  #define MVEBU_PM_MCI_SRAM_LKG_PD_EN	BIT(5)
98b5c850d4SMarcin Wojtas  #define MVEBU_PM_MMC_SRAM_LKG_PD_EN	BIT(4)
99b5c850d4SMarcin Wojtas  #define MVEBU_PM_SATA_SRAM_LKG_PD_EN	BIT(3)
100b5c850d4SMarcin Wojtas  #define MVEBU_PM_DMA_SRAM_LKG_PD_EN	BIT(2)
101b5c850d4SMarcin Wojtas  #define MVEBU_PM_SEC_SRAM_LKG_PD_EN	BIT(1)
102b5c850d4SMarcin Wojtas  #define MVEBU_PM_CPU_SRAM_LKG_PD_EN	BIT(0)
103b5c850d4SMarcin Wojtas  #define MVEBU_PM_NB_SRAM_LKG_PD_EN	(MVEBU_PM_L2_SRAM_LKG_PD_EN |\
104b5c850d4SMarcin Wojtas 	MVEBU_PM_EIP_SRAM_LKG_PD_EN | MVEBU_PM_DDRMC_SRAM_LKG_PD_EN |\
105b5c850d4SMarcin Wojtas 	MVEBU_PM_MCI_SRAM_LKG_PD_EN | MVEBU_PM_MMC_SRAM_LKG_PD_EN |\
106b5c850d4SMarcin Wojtas 	MVEBU_PM_SATA_SRAM_LKG_PD_EN | MVEBU_PM_DMA_SRAM_LKG_PD_EN |\
107b5c850d4SMarcin Wojtas 	MVEBU_PM_SEC_SRAM_LKG_PD_EN | MVEBU_PM_CPU_SRAM_LKG_PD_EN)
108b5c850d4SMarcin Wojtas #define MVEBU_PM_NB_PWR_DEBUG_REG	(MVEBU_PMSU_REG_BASE + 0xC)
109b5c850d4SMarcin Wojtas  #define MVEBU_PM_NB_FORCE_CLK_ON	BIT(30)
110b5c850d4SMarcin Wojtas  #define MVEBU_PM_IGNORE_CM3_SLEEP	BIT(21)
111b5c850d4SMarcin Wojtas  #define MVEBU_PM_IGNORE_CM3_DEEP	BIT(20)
112b5c850d4SMarcin Wojtas #define MVEBU_PM_NB_WAKE_UP_EN_REG	(MVEBU_PMSU_REG_BASE + 0x2C)
113b5c850d4SMarcin Wojtas  #define MVEBU_PM_SB_WKP_NB_EN		BIT(31)
114b5c850d4SMarcin Wojtas  #define MVEBU_PM_NB_GPIO_WKP_EN	BIT(27)
115b5c850d4SMarcin Wojtas  #define MVEBU_PM_SOC_TIMER_WKP_EN	BIT(26)
116b5c850d4SMarcin Wojtas  #define MVEBU_PM_UART_WKP_EN		BIT(25)
117b5c850d4SMarcin Wojtas  #define MVEBU_PM_UART2_WKP_EN		BIT(19)
118b5c850d4SMarcin Wojtas  #define MVEBU_PM_CPU_TIMER_WKP_EN	BIT(17)
119b5c850d4SMarcin Wojtas  #define MVEBU_PM_NB_WKP_EN		BIT(16)
120b5c850d4SMarcin Wojtas  #define MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN	BIT(13)
121b5c850d4SMarcin Wojtas  #define MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN	BIT(12)
122b5c850d4SMarcin Wojtas #define MVEBU_PM_CPU_0_PWR_CTRL_REG	(MVEBU_PMSU_REG_BASE + 0x34)
123b5c850d4SMarcin Wojtas #define MVEBU_PM_CPU_1_PWR_CTRL_REG	(MVEBU_PMSU_REG_BASE + 0x38)
124b5c850d4SMarcin Wojtas  #define MVEBU_PM_CORE_SOC_PD		BIT(2)
125b5c850d4SMarcin Wojtas  #define MVEBU_PM_CORE_PROC_PD		BIT(1)
126b5c850d4SMarcin Wojtas  #define MVEBU_PM_CORE_PD		BIT(0)
127b5c850d4SMarcin Wojtas #define MVEBU_PM_CORE_1_RETURN_ADDR_REG	(MVEBU_PMSU_REG_BASE + 0x44)
128b5c850d4SMarcin Wojtas #define MVEBU_PM_CPU_VDD_OFF_INFO_1_REG	(MVEBU_PMSU_REG_BASE + 0x48)
129b5c850d4SMarcin Wojtas #define MVEBU_PM_CPU_VDD_OFF_INFO_2_REG	(MVEBU_PMSU_REG_BASE + 0x4C)
130b5c850d4SMarcin Wojtas  #define MVEBU_PM_LOW_POWER_STATE	BIT(0)
131b5c850d4SMarcin Wojtas #define MVEBU_PM_CPU_WAKE_UP_CONF_REG	(MVEBU_PMSU_REG_BASE + 0x54)
132b5c850d4SMarcin Wojtas  #define MVEBU_PM_CORE1_WAKEUP		BIT(13)
133b5c850d4SMarcin Wojtas  #define MVEBU_PM_CORE0_WAKEUP		BIT(12)
134b5c850d4SMarcin Wojtas #define MVEBU_PM_WAIT_DDR_RDY_VALUE	(0x15)
135b5c850d4SMarcin Wojtas #define MVEBU_PM_SB_CPU_PWR_CTRL_REG	(MVEBU_SB_WAKEUP_REG_BASE)
136b5c850d4SMarcin Wojtas   #define MVEBU_PM_SB_PM_START		BIT(0)
137b5c850d4SMarcin Wojtas #define MVEBU_PM_SB_PWR_OPTION_REG	(MVEBU_SB_WAKEUP_REG_BASE + 0x4)
138b5c850d4SMarcin Wojtas   #define MVEBU_PM_SDIO_PHY_PDWN_EN	BIT(17)
139b5c850d4SMarcin Wojtas   #define MVEBU_PM_SB_VDDV_OFF_EN	BIT(16)
140b5c850d4SMarcin Wojtas   #define MVEBU_PM_EBM_SRAM_LKG_PD_EN		BIT(11)
141b5c850d4SMarcin Wojtas   #define MVEBU_PM_PCIE_SRAM_LKG_PD_EN		BIT(10)
142b5c850d4SMarcin Wojtas   #define MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN	BIT(9)
143b5c850d4SMarcin Wojtas   #define MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN	BIT(8)
144b5c850d4SMarcin Wojtas   #define MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN	BIT(7)
145b5c850d4SMarcin Wojtas   #define MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN	BIT(6)
146b5c850d4SMarcin Wojtas   #define MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN	BIT(5)
147b5c850d4SMarcin Wojtas   #define MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN	BIT(4)
148b5c850d4SMarcin Wojtas   #define MVEBU_PM_SDIO_SRAM_LKG_PD_EN		BIT(3)
149b5c850d4SMarcin Wojtas   #define MVEBU_PM_USB2_SRAM_LKG_PD_EN		BIT(2)
150b5c850d4SMarcin Wojtas   #define MVEBU_PM_USB3_H_SRAM_LKG_PD_EN	BIT(1)
151b5c850d4SMarcin Wojtas   #define MVEBU_PM_SB_SRAM_LKG_PD_EN	(MVEBU_PM_EBM_SRAM_LKG_PD_EN |\
152b5c850d4SMarcin Wojtas 	MVEBU_PM_PCIE_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_TX_SRAM_LKG_PD_EN |\
153b5c850d4SMarcin Wojtas 	MVEBU_PM_GBE1_RX_SRAM_LKG_PD_EN | MVEBU_PM_GBE1_MIB_SRAM_LKG_PD_EN |\
154b5c850d4SMarcin Wojtas 	MVEBU_PM_GBE0_TX_SRAM_LKG_PD_EN | MVEBU_PM_GBE0_RX_SRAM_LKG_PD_EN |\
155b5c850d4SMarcin Wojtas 	MVEBU_PM_GBE0_MIB_SRAM_LKG_PD_EN | MVEBU_PM_SDIO_SRAM_LKG_PD_EN |\
156b5c850d4SMarcin Wojtas 	MVEBU_PM_USB2_SRAM_LKG_PD_EN | MVEBU_PM_USB3_H_SRAM_LKG_PD_EN)
157b5c850d4SMarcin Wojtas #define MVEBU_PM_SB_WK_EN_REG		(MVEBU_SB_WAKEUP_REG_BASE + 0x10)
158b5c850d4SMarcin Wojtas   #define MVEBU_PM_SB_GPIO_WKP_EN	BIT(24)
159b5c850d4SMarcin Wojtas   #define MVEBU_PM_SB_WKP_EN		BIT(20)
160b5c850d4SMarcin Wojtas 
161b5c850d4SMarcin Wojtas /* DRAM registers */
162b5c850d4SMarcin Wojtas #define MVEBU_DRAM_STATS_CH0_REG	(MVEBU_DRAM_REG_BASE + 0x4)
163b5c850d4SMarcin Wojtas  #define MVEBU_DRAM_WCP_EMPTY		BIT(19)
164b5c850d4SMarcin Wojtas #define MVEBU_DRAM_CMD_0_REG		(MVEBU_DRAM_REG_BASE + 0x20)
165b5c850d4SMarcin Wojtas  #define MVEBU_DRAM_CH0_CMD0		BIT(28)
166b5c850d4SMarcin Wojtas  #define MVEBU_DRAM_CS_CMD0		BIT(24)
167b5c850d4SMarcin Wojtas  #define MVEBU_DRAM_WCB_DRAIN_REQ	BIT(1)
168b5c850d4SMarcin Wojtas #define MVEBU_DRAM_PWR_CTRL_REG		(MVEBU_DRAM_REG_BASE + 0x54)
169b5c850d4SMarcin Wojtas  #define MVEBU_DRAM_PHY_CLK_GATING_EN	BIT(1)
170b5c850d4SMarcin Wojtas  #define MVEBU_DRAM_PHY_AUTO_AC_OFF_EN	BIT(0)
171b5c850d4SMarcin Wojtas 
172b5c850d4SMarcin Wojtas /* AVS registers */
173b5c850d4SMarcin Wojtas #define MVEBU_AVS_CTRL_2_REG		(MVEBU_AVS_REG_BASE + 0x8)
174b5c850d4SMarcin Wojtas  #define MVEBU_LOW_VDD_MODE_EN		BIT(6)
175b5c850d4SMarcin Wojtas 
176b5c850d4SMarcin Wojtas /* Clock registers */
177b5c850d4SMarcin Wojtas #define MVEBU_NB_CLOCK_SEL_REG		(MVEBU_NB_REGS_BASE + 0x10)
178b5c850d4SMarcin Wojtas  #define MVEBU_A53_CPU_CLK_SEL		BIT(15)
179b5c850d4SMarcin Wojtas 
180b5c850d4SMarcin Wojtas /* North Bridge Step-Down Registers */
181b5c850d4SMarcin Wojtas #define MVEBU_NB_STEP_DOWN_INT_EN_REG	MVEBU_NB_STEP_DOWN_REG_BASE
182b5c850d4SMarcin Wojtas  #define MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK	BIT(8)
183b5c850d4SMarcin Wojtas 
184b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_18	18
185b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_19	19
186b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_25	25
187b5c850d4SMarcin Wojtas #define MVEBU_NB_GPIO_26	26
188b5c850d4SMarcin Wojtas 
189b5c850d4SMarcin Wojtas typedef int (*wake_up_src_func)(union pm_wake_up_src_data *);
190b5c850d4SMarcin Wojtas 
191b5c850d4SMarcin Wojtas struct wake_up_src_func_map {
192b5c850d4SMarcin Wojtas 	enum pm_wake_up_src_type type;
193b5c850d4SMarcin Wojtas 	wake_up_src_func func;
194b5c850d4SMarcin Wojtas };
195b5c850d4SMarcin Wojtas 
marvell_psci_arch_init(int die_index)196b5c850d4SMarcin Wojtas void marvell_psci_arch_init(int die_index)
197b5c850d4SMarcin Wojtas {
198b5c850d4SMarcin Wojtas }
199b5c850d4SMarcin Wojtas 
a3700_pm_ack_irq(void)200*5993af45SMarek Behún void a3700_pm_ack_irq(void)
201b5c850d4SMarcin Wojtas {
202b5c850d4SMarcin Wojtas 	uint32_t reg;
203b5c850d4SMarcin Wojtas 
204b5c850d4SMarcin Wojtas 	reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_1_REG);
205b5c850d4SMarcin Wojtas 	if (reg)
206b5c850d4SMarcin Wojtas 		mmio_write_32(MVEBU_NB_IRQ_STATUS_1_REG, reg);
207b5c850d4SMarcin Wojtas 
208b5c850d4SMarcin Wojtas 	reg = mmio_read_32(MVEBU_NB_IRQ_STATUS_2_REG);
209b5c850d4SMarcin Wojtas 	if (reg)
210b5c850d4SMarcin Wojtas 		mmio_write_32(MVEBU_NB_IRQ_STATUS_2_REG, reg);
211b5c850d4SMarcin Wojtas 
212b5c850d4SMarcin Wojtas 	reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_1_REG);
213b5c850d4SMarcin Wojtas 	if (reg)
214b5c850d4SMarcin Wojtas 		mmio_write_32(MVEBU_SB_IRQ_STATUS_1_REG, reg);
215b5c850d4SMarcin Wojtas 
216b5c850d4SMarcin Wojtas 	reg = mmio_read_32(MVEBU_SB_IRQ_STATUS_2_REG);
217b5c850d4SMarcin Wojtas 	if (reg)
218b5c850d4SMarcin Wojtas 		mmio_write_32(MVEBU_SB_IRQ_STATUS_2_REG, reg);
219b5c850d4SMarcin Wojtas 
220b5c850d4SMarcin Wojtas 	reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG);
221b5c850d4SMarcin Wojtas 	if (reg)
222b5c850d4SMarcin Wojtas 		mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_LOW_REG, reg);
223b5c850d4SMarcin Wojtas 
224b5c850d4SMarcin Wojtas 	reg = mmio_read_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG);
225b5c850d4SMarcin Wojtas 	if (reg)
226b5c850d4SMarcin Wojtas 		mmio_write_32(MVEBU_NB_GPIO_IRQ_STATUS_HIGH_REG, reg);
227b5c850d4SMarcin Wojtas 
228b5c850d4SMarcin Wojtas 	reg = mmio_read_32(MVEBU_SB_GPIO_IRQ_STATUS_REG);
229b5c850d4SMarcin Wojtas 	if (reg)
230b5c850d4SMarcin Wojtas 		mmio_write_32(MVEBU_SB_GPIO_IRQ_STATUS_REG, reg);
231b5c850d4SMarcin Wojtas }
232b5c850d4SMarcin Wojtas 
233b5c850d4SMarcin Wojtas /*****************************************************************************
234b5c850d4SMarcin Wojtas  * A3700 handler called to check the validity of the power state
235b5c850d4SMarcin Wojtas  * parameter.
236b5c850d4SMarcin Wojtas  *****************************************************************************
237b5c850d4SMarcin Wojtas  */
a3700_validate_power_state(unsigned int power_state,psci_power_state_t * req_state)238b5c850d4SMarcin Wojtas int a3700_validate_power_state(unsigned int power_state,
239b5c850d4SMarcin Wojtas 			       psci_power_state_t *req_state)
240b5c850d4SMarcin Wojtas {
241b5c850d4SMarcin Wojtas 	ERROR("%s needs to be implemented\n", __func__);
242b5c850d4SMarcin Wojtas 	panic();
243b5c850d4SMarcin Wojtas }
244b5c850d4SMarcin Wojtas 
245b5c850d4SMarcin Wojtas /*****************************************************************************
246b5c850d4SMarcin Wojtas  * A3700 handler called when a CPU is about to enter standby.
247b5c850d4SMarcin Wojtas  *****************************************************************************
248b5c850d4SMarcin Wojtas  */
a3700_cpu_standby(plat_local_state_t cpu_state)249b5c850d4SMarcin Wojtas void a3700_cpu_standby(plat_local_state_t cpu_state)
250b5c850d4SMarcin Wojtas {
251b5c850d4SMarcin Wojtas 	ERROR("%s needs to be implemented\n", __func__);
252b5c850d4SMarcin Wojtas 	panic();
253b5c850d4SMarcin Wojtas }
254b5c850d4SMarcin Wojtas 
255b5c850d4SMarcin Wojtas /*****************************************************************************
256b5c850d4SMarcin Wojtas  * A3700 handler called when a power domain is about to be turned on. The
257b5c850d4SMarcin Wojtas  * mpidr determines the CPU to be turned on.
258b5c850d4SMarcin Wojtas  *****************************************************************************
259b5c850d4SMarcin Wojtas  */
a3700_pwr_domain_on(u_register_t mpidr)260b5c850d4SMarcin Wojtas int a3700_pwr_domain_on(u_register_t mpidr)
261b5c850d4SMarcin Wojtas {
262b5c850d4SMarcin Wojtas 	/* Set barrier */
263b5c850d4SMarcin Wojtas 	dsbsy();
264b5c850d4SMarcin Wojtas 
265b5c850d4SMarcin Wojtas 	/* Set the cpu start address to BL1 entry point */
266b5c850d4SMarcin Wojtas 	mmio_write_32(MVEBU_CPU_1_RESET_VECTOR,
267b5c850d4SMarcin Wojtas 		      PLAT_MARVELL_CPU_ENTRY_ADDR >> 2);
268b5c850d4SMarcin Wojtas 
269b5c850d4SMarcin Wojtas 	/* Get the cpu out of reset */
270b5c850d4SMarcin Wojtas 	mmio_clrbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT));
271b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_CPU_1_RESET_REG, BIT(MVEBU_CPU_1_RESET_BIT));
272b5c850d4SMarcin Wojtas 
273b5c850d4SMarcin Wojtas 	return 0;
274b5c850d4SMarcin Wojtas }
275b5c850d4SMarcin Wojtas 
276b5c850d4SMarcin Wojtas /*****************************************************************************
277b5c850d4SMarcin Wojtas  * A3700 handler called to validate the entry point.
278b5c850d4SMarcin Wojtas  *****************************************************************************
279b5c850d4SMarcin Wojtas  */
a3700_validate_ns_entrypoint(uintptr_t entrypoint)280b5c850d4SMarcin Wojtas int a3700_validate_ns_entrypoint(uintptr_t entrypoint)
281b5c850d4SMarcin Wojtas {
282b5c850d4SMarcin Wojtas 	return PSCI_E_SUCCESS;
283b5c850d4SMarcin Wojtas }
284b5c850d4SMarcin Wojtas 
285b5c850d4SMarcin Wojtas /*****************************************************************************
286b5c850d4SMarcin Wojtas  * A3700 handler called when a power domain is about to be turned off. The
287b5c850d4SMarcin Wojtas  * target_state encodes the power state that each level should transition to.
288b5c850d4SMarcin Wojtas  *****************************************************************************
289b5c850d4SMarcin Wojtas  */
a3700_pwr_domain_off(const psci_power_state_t * target_state)290b5c850d4SMarcin Wojtas void a3700_pwr_domain_off(const psci_power_state_t *target_state)
291b5c850d4SMarcin Wojtas {
292b5c850d4SMarcin Wojtas 	/* Prevent interrupts from spuriously waking up this cpu */
293b5c850d4SMarcin Wojtas 	plat_marvell_gic_cpuif_disable();
294b5c850d4SMarcin Wojtas 
295b5c850d4SMarcin Wojtas 	/* Core can not be powered down with pending IRQ,
296b5c850d4SMarcin Wojtas 	 * acknowledge all the pending IRQ
297b5c850d4SMarcin Wojtas 	 */
298b5c850d4SMarcin Wojtas 	a3700_pm_ack_irq();
299b5c850d4SMarcin Wojtas }
300b5c850d4SMarcin Wojtas 
a3700_set_gen_pwr_off_option(void)301b5c850d4SMarcin Wojtas static void a3700_set_gen_pwr_off_option(void)
302b5c850d4SMarcin Wojtas {
303b5c850d4SMarcin Wojtas 	/* Enable L2 flush -> processor state-machine option */
304b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_CPU_PWR_CTRL_REG, MVEBU_PM_L2_FLUSH_EN);
305b5c850d4SMarcin Wojtas 
306b5c850d4SMarcin Wojtas 	/*
307b5c850d4SMarcin Wojtas 	 * North bridge cannot be VDD off (always ON).
308b5c850d4SMarcin Wojtas 	 * The NB state machine support low power mode by its state machine.
309b5c850d4SMarcin Wojtas 	 * This bit MUST be set for north bridge power down, e.g.,
310b5c850d4SMarcin Wojtas 	 * OSC input cutoff(NOT TEST), SRAM power down, PMIC, etc.
311b5c850d4SMarcin Wojtas 	 * It is not related to CPU VDD OFF!!
312b5c850d4SMarcin Wojtas 	 */
313b5c850d4SMarcin Wojtas 	mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_CPU_VDDV_OFF_EN);
314b5c850d4SMarcin Wojtas 
315b5c850d4SMarcin Wojtas 	/*
316b5c850d4SMarcin Wojtas 	 * MUST: Switch CPU/AXI clock to OSC
317b5c850d4SMarcin Wojtas 	 * NB state machine clock is always connected to OSC (slow clock).
318b5c850d4SMarcin Wojtas 	 * But Core0/1/processor state machine's clock are connected to AXI
319b5c850d4SMarcin Wojtas 	 *  clock. Now, AXI clock takes the TBG as clock source.
320b5c850d4SMarcin Wojtas 	 * If using AXI clock, Core0/1/processor state machine may much faster
321b5c850d4SMarcin Wojtas 	 * than NB state machine. It will cause problem in this case if cores
322b5c850d4SMarcin Wojtas 	 * are released before north bridge gets ready.
323b5c850d4SMarcin Wojtas 	 */
324b5c850d4SMarcin Wojtas 	mmio_clrbits_32(MVEBU_NB_CLOCK_SEL_REG, MVEBU_A53_CPU_CLK_SEL);
325b5c850d4SMarcin Wojtas 
326b5c850d4SMarcin Wojtas 	/*
327b5c850d4SMarcin Wojtas 	 * These register bits will trigger north bridge
328b5c850d4SMarcin Wojtas 	 * power-down state machine regardless CM3 status.
329b5c850d4SMarcin Wojtas 	 */
330b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_SLEEP);
331b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_DEBUG_REG, MVEBU_PM_IGNORE_CM3_DEEP);
332b5c850d4SMarcin Wojtas 
333b5c850d4SMarcin Wojtas 	/*
334b5c850d4SMarcin Wojtas 	 * SRAM => controlled by north bridge state machine.
335b5c850d4SMarcin Wojtas 	 * Core VDD OFF is not related to CPU SRAM power down.
336b5c850d4SMarcin Wojtas 	 */
337b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_NB_SRAM_LKG_PD_EN);
338b5c850d4SMarcin Wojtas 
339b5c850d4SMarcin Wojtas 	/*
340b5c850d4SMarcin Wojtas 	 * Idle AXI interface in order to get L2_WFI
341b5c850d4SMarcin Wojtas 	 * L2 WFI is only asserted after CORE-0 and CORE-1 WFI asserted.
342b5c850d4SMarcin Wojtas 	 * (only both core-0/1in WFI, L2 WFI will be issued by CORE.)
343b5c850d4SMarcin Wojtas 	 * Once L2 WFI asserted, this bit is used for signalling assertion
344b5c850d4SMarcin Wojtas 	 * to AXI IO masters.
345b5c850d4SMarcin Wojtas 	 */
346b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_INTERFACE_IDLE);
347b5c850d4SMarcin Wojtas 
348b5c850d4SMarcin Wojtas 	/* Enable core0 and core1 VDD_OFF */
349b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PD);
350b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PD);
351b5c850d4SMarcin Wojtas 
352b5c850d4SMarcin Wojtas 	/* Enable North bridge power down -
353b5c850d4SMarcin Wojtas 	 * Both Cores MUST enable this bit to power down north bridge!
354b5c850d4SMarcin Wojtas 	 */
355b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD);
356b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_SOC_PD);
357b5c850d4SMarcin Wojtas 
358b5c850d4SMarcin Wojtas 	/* CA53 (processor domain) power down */
359b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_CPU_0_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD);
360b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_CPU_1_PWR_CTRL_REG, MVEBU_PM_CORE_PROC_PD);
361b5c850d4SMarcin Wojtas }
362b5c850d4SMarcin Wojtas 
a3700_en_ddr_self_refresh(void)363b5c850d4SMarcin Wojtas static void a3700_en_ddr_self_refresh(void)
364b5c850d4SMarcin Wojtas {
365b5c850d4SMarcin Wojtas 	/*
366b5c850d4SMarcin Wojtas 	 * Both count is 16 bits and configurable. By default, osc stb cnt
367b5c850d4SMarcin Wojtas 	 * is 0xFFF for lower 12 bits.
368b5c850d4SMarcin Wojtas 	 * Thus, powerdown count is smaller than osc count.
369b5c850d4SMarcin Wojtas 	 * This count is used for exiting DDR SR mode on wakeup event.
370b5c850d4SMarcin Wojtas 	 * The powerdown count also has impact on the following
371b5c850d4SMarcin Wojtas 	 * state changes: idle -> count-down -> ... (power-down, vdd off, etc)
372b5c850d4SMarcin Wojtas 	 * Here, make stable counter shorter
373b5c850d4SMarcin Wojtas 	 * Use power down count value instead of osc_stb_cnt to speed up
374b5c850d4SMarcin Wojtas 	 * DDR self refresh exit
375b5c850d4SMarcin Wojtas 	 */
376b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_PWR_DN_CNT_SEL);
377b5c850d4SMarcin Wojtas 
378b5c850d4SMarcin Wojtas 	/*
379b5c850d4SMarcin Wojtas 	 * Enable DDR SR mode => controlled by north bridge state machine
380b5c850d4SMarcin Wojtas 	 * Therefore, we must powerdown north bridge to trigger the DDR SR
381b5c850d4SMarcin Wojtas 	 * mode switching.
382b5c850d4SMarcin Wojtas 	 */
383b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_SR_EN);
384b5c850d4SMarcin Wojtas 	/* Disable DDR clock, otherwise DDR will not enter into SR mode. */
385b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDR_CLK_DIS_EN);
386b5c850d4SMarcin Wojtas 	/* Power down DDR PHY (PAD) */
387b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_DDRPHY_PWRDWN_EN);
388b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG,
389b5c850d4SMarcin Wojtas 			MVEBU_PM_DDRPHY_PAD_PWRDWN_EN);
390b5c850d4SMarcin Wojtas 
391b5c850d4SMarcin Wojtas 	/* Set wait time for DDR ready in ROM code */
392b5c850d4SMarcin Wojtas 	mmio_write_32(MVEBU_PM_CPU_VDD_OFF_INFO_1_REG,
393b5c850d4SMarcin Wojtas 		      MVEBU_PM_WAIT_DDR_RDY_VALUE);
394b5c850d4SMarcin Wojtas 
395b5c850d4SMarcin Wojtas 	/* DDR flush write buffer - mandatory */
396b5c850d4SMarcin Wojtas 	mmio_write_32(MVEBU_DRAM_CMD_0_REG, MVEBU_DRAM_CH0_CMD0 |
397b5c850d4SMarcin Wojtas 		      MVEBU_DRAM_CS_CMD0 | MVEBU_DRAM_WCB_DRAIN_REQ);
398b5c850d4SMarcin Wojtas 	while ((mmio_read_32(MVEBU_DRAM_STATS_CH0_REG) &
399b5c850d4SMarcin Wojtas 			     MVEBU_DRAM_WCP_EMPTY) != MVEBU_DRAM_WCP_EMPTY)
400b5c850d4SMarcin Wojtas 		;
401b5c850d4SMarcin Wojtas 
402b5c850d4SMarcin Wojtas 	/* Trigger PHY reset after ddr out of self refresh =>
403b5c850d4SMarcin Wojtas 	 * supply reset pulse for DDR phy after wake up
404b5c850d4SMarcin Wojtas 	 */
405b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_DRAM_PWR_CTRL_REG, MVEBU_DRAM_PHY_CLK_GATING_EN |
406b5c850d4SMarcin Wojtas 						 MVEBU_DRAM_PHY_AUTO_AC_OFF_EN);
407b5c850d4SMarcin Wojtas }
408b5c850d4SMarcin Wojtas 
a3700_pwr_dn_avs(void)409b5c850d4SMarcin Wojtas static void a3700_pwr_dn_avs(void)
410b5c850d4SMarcin Wojtas {
411b5c850d4SMarcin Wojtas 	/*
412b5c850d4SMarcin Wojtas 	 * AVS power down - controlled by north bridge statemachine
413b5c850d4SMarcin Wojtas 	 * Enable AVS power down by clear the AVS disable bit.
414b5c850d4SMarcin Wojtas 	 */
415b5c850d4SMarcin Wojtas 	mmio_clrbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_DISABLE_MODE);
416b5c850d4SMarcin Wojtas 	/*
417b5c850d4SMarcin Wojtas 	 * Should set BIT[12:13] to powerdown AVS.
418b5c850d4SMarcin Wojtas 	 * 1. Enable AVS VDD2 mode
419b5c850d4SMarcin Wojtas 	 * 2. After power down AVS, we must hold AVS output voltage.
420b5c850d4SMarcin Wojtas 	 * 3. We can choose the lower VDD for AVS power down.
421b5c850d4SMarcin Wojtas 	 */
422b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_VDD2_MODE);
423b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_AVS_HOLD_MODE);
424b5c850d4SMarcin Wojtas 
425b5c850d4SMarcin Wojtas 	/* Enable low VDD mode, AVS will set CPU to lowest core VDD 747mV */
426b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_AVS_CTRL_2_REG, MVEBU_LOW_VDD_MODE_EN);
427b5c850d4SMarcin Wojtas }
428b5c850d4SMarcin Wojtas 
a3700_pwr_dn_tbg(void)429b5c850d4SMarcin Wojtas static void a3700_pwr_dn_tbg(void)
430b5c850d4SMarcin Wojtas {
431b5c850d4SMarcin Wojtas 	/* Power down TBG */
432b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_TBG_OFF_EN);
433b5c850d4SMarcin Wojtas }
434b5c850d4SMarcin Wojtas 
a3700_pwr_dn_sb(void)435b5c850d4SMarcin Wojtas static void a3700_pwr_dn_sb(void)
436b5c850d4SMarcin Wojtas {
437b5c850d4SMarcin Wojtas 	/* Enable south bridge power down option */
438b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_CTRL_REG, MVEBU_PM_SB_PWR_DWN);
439b5c850d4SMarcin Wojtas 
440b5c850d4SMarcin Wojtas 	/* Enable SDIO_PHY_PWRDWN */
441b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SDIO_PHY_PDWN_EN);
442b5c850d4SMarcin Wojtas 
443b5c850d4SMarcin Wojtas 	/* Enable SRAM LRM on SB */
444b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_SRAM_LKG_PD_EN);
445b5c850d4SMarcin Wojtas 
446b5c850d4SMarcin Wojtas 	/* Enable SB Power Off */
447b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_SB_PWR_OPTION_REG, MVEBU_PM_SB_VDDV_OFF_EN);
448b5c850d4SMarcin Wojtas 
449b5c850d4SMarcin Wojtas 	/* Kick off South Bridge Power Off */
450b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_SB_CPU_PWR_CTRL_REG, MVEBU_PM_SB_PM_START);
451b5c850d4SMarcin Wojtas }
452b5c850d4SMarcin Wojtas 
a3700_set_pwr_off_option(void)453b5c850d4SMarcin Wojtas static void a3700_set_pwr_off_option(void)
454b5c850d4SMarcin Wojtas {
455b5c850d4SMarcin Wojtas 	/* Set general power off option */
456b5c850d4SMarcin Wojtas 	a3700_set_gen_pwr_off_option();
457b5c850d4SMarcin Wojtas 
458b5c850d4SMarcin Wojtas 	/* Enable DDR self refresh in low power mode */
459b5c850d4SMarcin Wojtas 	a3700_en_ddr_self_refresh();
460b5c850d4SMarcin Wojtas 
461b5c850d4SMarcin Wojtas 	/* Power down AVS */
462b5c850d4SMarcin Wojtas 	a3700_pwr_dn_avs();
463b5c850d4SMarcin Wojtas 
464b5c850d4SMarcin Wojtas 	/* Power down TBG */
465b5c850d4SMarcin Wojtas 	a3700_pwr_dn_tbg();
466b5c850d4SMarcin Wojtas 
467b5c850d4SMarcin Wojtas 	/* Power down south bridge, pay attention south bridge setting
468b5c850d4SMarcin Wojtas 	 * should be done before
469b5c850d4SMarcin Wojtas 	 */
470b5c850d4SMarcin Wojtas 	a3700_pwr_dn_sb();
471b5c850d4SMarcin Wojtas }
472b5c850d4SMarcin Wojtas 
a3700_set_wake_up_option(void)473b5c850d4SMarcin Wojtas static void a3700_set_wake_up_option(void)
474b5c850d4SMarcin Wojtas {
475b5c850d4SMarcin Wojtas 	/*
476b5c850d4SMarcin Wojtas 	 * Enable the wakeup event for NB SOC => north-bridge
477b5c850d4SMarcin Wojtas 	 * state-machine enablement on wake-up event
478b5c850d4SMarcin Wojtas 	 */
479b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_WKP_EN);
480b5c850d4SMarcin Wojtas 
481b5c850d4SMarcin Wojtas 	 /* Enable both core0 and core1 wakeup on demand */
482b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_CPU_WAKE_UP_CONF_REG,
483b5c850d4SMarcin Wojtas 			MVEBU_PM_CORE1_WAKEUP | MVEBU_PM_CORE0_WAKEUP);
484b5c850d4SMarcin Wojtas 
485b5c850d4SMarcin Wojtas 	/* Enable warm reset in low power mode */
486b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_PWR_OPTION_REG, MVEBU_PM_WARM_RESET_EN);
487b5c850d4SMarcin Wojtas }
488b5c850d4SMarcin Wojtas 
a3700_pm_en_nb_gpio(uint32_t gpio)489b5c850d4SMarcin Wojtas static void a3700_pm_en_nb_gpio(uint32_t gpio)
490b5c850d4SMarcin Wojtas {
491b5c850d4SMarcin Wojtas 	/* For GPIO1 interrupt -- North bridge only */
492b5c850d4SMarcin Wojtas 	if (gpio >= 32) {
493b5c850d4SMarcin Wojtas 		/* GPIO int mask */
494b5c850d4SMarcin Wojtas 		mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_2_REG, BIT(gpio - 32));
495b5c850d4SMarcin Wojtas 
496b5c850d4SMarcin Wojtas 		/* NB_CPU_WAKE-up ENABLE GPIO int */
497b5c850d4SMarcin Wojtas 		mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_HIGH_REG, BIT(gpio - 32));
498b5c850d4SMarcin Wojtas 	} else {
499b5c850d4SMarcin Wojtas 		/* GPIO int mask */
500b5c850d4SMarcin Wojtas 		mmio_clrbits_32(MVEBU_NB_GPIO_IRQ_MASK_1_REG, BIT(gpio));
501b5c850d4SMarcin Wojtas 
502b5c850d4SMarcin Wojtas 		/* NB_CPU_WAKE-up ENABLE GPIO int */
503b5c850d4SMarcin Wojtas 		mmio_setbits_32(MVEBU_NB_GPIO_IRQ_EN_LOW_REG, BIT(gpio));
504b5c850d4SMarcin Wojtas 	}
505b5c850d4SMarcin Wojtas 
506b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_NB_STEP_DOWN_INT_EN_REG,
507b5c850d4SMarcin Wojtas 			MVEBU_NB_GPIO_INT_WAKE_WCPU_CLK);
508b5c850d4SMarcin Wojtas 
509b5c850d4SMarcin Wojtas 	/* Enable using GPIO as wakeup event
510b5c850d4SMarcin Wojtas 	 * (actually not only for north bridge)
511b5c850d4SMarcin Wojtas 	 */
512b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_NB_GPIO_WKP_EN |
513b5c850d4SMarcin Wojtas 		MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN |
514b5c850d4SMarcin Wojtas 		MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN);
515b5c850d4SMarcin Wojtas }
516b5c850d4SMarcin Wojtas 
a3700_pm_en_sb_gpio(uint32_t gpio)517b5c850d4SMarcin Wojtas static void a3700_pm_en_sb_gpio(uint32_t gpio)
518b5c850d4SMarcin Wojtas {
519b5c850d4SMarcin Wojtas 	/* Enable using GPIO as wakeup event */
520b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_NB_WAKE_UP_EN_REG, MVEBU_PM_SB_WKP_NB_EN |
521b5c850d4SMarcin Wojtas 		MVEBU_PM_NB_WKP_EN | MVEBU_PM_CORE1_FIQ_IRQ_WKP_EN |
522b5c850d4SMarcin Wojtas 		MVEBU_PM_CORE0_FIQ_IRQ_WKP_EN);
523b5c850d4SMarcin Wojtas 
524b5c850d4SMarcin Wojtas 	/* SB GPIO Wake UP | South Bridge Wake Up Enable */
525b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_SB_WK_EN_REG, MVEBU_PM_SB_GPIO_WKP_EN |
526b5c850d4SMarcin Wojtas 			MVEBU_PM_SB_GPIO_WKP_EN);
527b5c850d4SMarcin Wojtas 
528b5c850d4SMarcin Wojtas 	/* GPIO int mask */
529b5c850d4SMarcin Wojtas 	mmio_clrbits_32(MVEBU_SB_GPIO_IRQ_MASK_REG, BIT(gpio));
530b5c850d4SMarcin Wojtas 
531b5c850d4SMarcin Wojtas 	/* NB_CPU_WAKE-up ENABLE GPIO int */
532b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_SB_GPIO_IRQ_EN_REG, BIT(gpio));
533b5c850d4SMarcin Wojtas }
534b5c850d4SMarcin Wojtas 
a3700_pm_src_gpio(union pm_wake_up_src_data * src_data)535b5c850d4SMarcin Wojtas int a3700_pm_src_gpio(union pm_wake_up_src_data *src_data)
536b5c850d4SMarcin Wojtas {
537b5c850d4SMarcin Wojtas 	if (src_data->gpio_data.bank_num == 0)
538b5c850d4SMarcin Wojtas 		/* North Bridge GPIO */
539b5c850d4SMarcin Wojtas 		a3700_pm_en_nb_gpio(src_data->gpio_data.gpio_num);
540b5c850d4SMarcin Wojtas 	else
541b5c850d4SMarcin Wojtas 		a3700_pm_en_sb_gpio(src_data->gpio_data.gpio_num);
542b5c850d4SMarcin Wojtas 	return 0;
543b5c850d4SMarcin Wojtas }
544b5c850d4SMarcin Wojtas 
a3700_pm_src_uart1(union pm_wake_up_src_data * src_data)545b5c850d4SMarcin Wojtas int a3700_pm_src_uart1(union pm_wake_up_src_data *src_data)
546b5c850d4SMarcin Wojtas {
547b5c850d4SMarcin Wojtas 	/* Clear Uart1 select */
548b5c850d4SMarcin Wojtas 	mmio_clrbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_UART1_SEL);
549b5c850d4SMarcin Wojtas 	/* set pin 19 gpio usage*/
550b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_19_EN);
551b5c850d4SMarcin Wojtas 	/* Enable gpio wake-up*/
552b5c850d4SMarcin Wojtas 	a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_19);
553b5c850d4SMarcin Wojtas 	/* set pin 18 gpio usage*/
554b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_18_EN);
555b5c850d4SMarcin Wojtas 	/* Enable gpio wake-up*/
556b5c850d4SMarcin Wojtas 	a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_18);
557b5c850d4SMarcin Wojtas 
558b5c850d4SMarcin Wojtas 	return 0;
559b5c850d4SMarcin Wojtas }
560b5c850d4SMarcin Wojtas 
a3700_pm_src_uart0(union pm_wake_up_src_data * src_data)561b5c850d4SMarcin Wojtas int a3700_pm_src_uart0(union pm_wake_up_src_data *src_data)
562b5c850d4SMarcin Wojtas {
563b5c850d4SMarcin Wojtas 	/* set pin 25/26 gpio usage*/
564b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_NB_GPIO1_SEL_REG, MVEBU_NB_GPIO1_GPIO_25_26_EN);
565b5c850d4SMarcin Wojtas 	/* Enable gpio wake-up*/
566b5c850d4SMarcin Wojtas 	a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_25);
567b5c850d4SMarcin Wojtas 	/* Enable gpio wake-up*/
568b5c850d4SMarcin Wojtas 	a3700_pm_en_nb_gpio(MVEBU_NB_GPIO_26);
569b5c850d4SMarcin Wojtas 
570b5c850d4SMarcin Wojtas 	return 0;
571b5c850d4SMarcin Wojtas }
572b5c850d4SMarcin Wojtas 
573b5c850d4SMarcin Wojtas struct wake_up_src_func_map src_func_table[WAKE_UP_SRC_MAX] = {
574b5c850d4SMarcin Wojtas 	{WAKE_UP_SRC_GPIO, a3700_pm_src_gpio},
575b5c850d4SMarcin Wojtas 	{WAKE_UP_SRC_UART1, a3700_pm_src_uart1},
576b5c850d4SMarcin Wojtas 	{WAKE_UP_SRC_UART0, a3700_pm_src_uart0},
577b5c850d4SMarcin Wojtas 	/* FOLLOWING SRC NOT SUPPORTED YET */
578b5c850d4SMarcin Wojtas 	{WAKE_UP_SRC_TIMER, NULL}
579b5c850d4SMarcin Wojtas };
580b5c850d4SMarcin Wojtas 
a3700_get_wake_up_src_func(enum pm_wake_up_src_type type)581b5c850d4SMarcin Wojtas static wake_up_src_func a3700_get_wake_up_src_func(
582b5c850d4SMarcin Wojtas 						  enum pm_wake_up_src_type type)
583b5c850d4SMarcin Wojtas {
584b5c850d4SMarcin Wojtas 	uint32_t loop;
585b5c850d4SMarcin Wojtas 
586b5c850d4SMarcin Wojtas 	for (loop = 0; loop < WAKE_UP_SRC_MAX; loop++) {
587b5c850d4SMarcin Wojtas 		if (src_func_table[loop].type == type)
588b5c850d4SMarcin Wojtas 			return src_func_table[loop].func;
589b5c850d4SMarcin Wojtas 	}
590b5c850d4SMarcin Wojtas 	return NULL;
591b5c850d4SMarcin Wojtas }
592b5c850d4SMarcin Wojtas 
593f2800a47SPali Rohár #pragma weak mv_wake_up_src_config_get
mv_wake_up_src_config_get(void)594f2800a47SPali Rohár struct pm_wake_up_src_config *mv_wake_up_src_config_get(void)
595f2800a47SPali Rohár {
596f2800a47SPali Rohár 	static struct pm_wake_up_src_config wake_up_src_cfg = {};
597f2800a47SPali Rohár 	return &wake_up_src_cfg;
598f2800a47SPali Rohár }
599f2800a47SPali Rohár 
a3700_set_wake_up_source(void)600b5c850d4SMarcin Wojtas static void a3700_set_wake_up_source(void)
601b5c850d4SMarcin Wojtas {
602b5c850d4SMarcin Wojtas 	struct pm_wake_up_src_config *wake_up_src;
603b5c850d4SMarcin Wojtas 	uint32_t loop;
604b5c850d4SMarcin Wojtas 	wake_up_src_func src_func = NULL;
605b5c850d4SMarcin Wojtas 
606b5c850d4SMarcin Wojtas 	wake_up_src = mv_wake_up_src_config_get();
607b5c850d4SMarcin Wojtas 	for (loop = 0; loop < wake_up_src->wake_up_src_num; loop++) {
608b5c850d4SMarcin Wojtas 		src_func = a3700_get_wake_up_src_func(
609b5c850d4SMarcin Wojtas 			   wake_up_src->wake_up_src[loop].wake_up_src_type);
610b5c850d4SMarcin Wojtas 		if (src_func)
611b5c850d4SMarcin Wojtas 			src_func(
612b5c850d4SMarcin Wojtas 				&(wake_up_src->wake_up_src[loop].wake_up_data));
613b5c850d4SMarcin Wojtas 	}
614b5c850d4SMarcin Wojtas }
615b5c850d4SMarcin Wojtas 
a3700_pm_save_lp_flag(void)616b5c850d4SMarcin Wojtas static void a3700_pm_save_lp_flag(void)
617b5c850d4SMarcin Wojtas {
618b5c850d4SMarcin Wojtas 	/* Save the flag for enter the low power mode */
619b5c850d4SMarcin Wojtas 	mmio_setbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG,
620b5c850d4SMarcin Wojtas 			MVEBU_PM_LOW_POWER_STATE);
621b5c850d4SMarcin Wojtas }
622b5c850d4SMarcin Wojtas 
a3700_pm_clear_lp_flag(void)623b5c850d4SMarcin Wojtas static void a3700_pm_clear_lp_flag(void)
624b5c850d4SMarcin Wojtas {
625b5c850d4SMarcin Wojtas 	/* Clear the flag for enter the low power mode */
626b5c850d4SMarcin Wojtas 	mmio_clrbits_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG,
627b5c850d4SMarcin Wojtas 			MVEBU_PM_LOW_POWER_STATE);
628b5c850d4SMarcin Wojtas }
629b5c850d4SMarcin Wojtas 
a3700_pm_get_lp_flag(void)630b5c850d4SMarcin Wojtas static uint32_t a3700_pm_get_lp_flag(void)
631b5c850d4SMarcin Wojtas {
632b5c850d4SMarcin Wojtas 	/* Get the flag for enter the low power mode */
633b5c850d4SMarcin Wojtas 	return mmio_read_32(MVEBU_PM_CPU_VDD_OFF_INFO_2_REG) &
634b5c850d4SMarcin Wojtas 			    MVEBU_PM_LOW_POWER_STATE;
635b5c850d4SMarcin Wojtas }
636b5c850d4SMarcin Wojtas 
637b5c850d4SMarcin Wojtas /*****************************************************************************
638b5c850d4SMarcin Wojtas  * A3700 handler called when a power domain is about to be suspended. The
639b5c850d4SMarcin Wojtas  * target_state encodes the power state that each level should transition to.
640b5c850d4SMarcin Wojtas  *****************************************************************************
641b5c850d4SMarcin Wojtas  */
a3700_pwr_domain_suspend(const psci_power_state_t * target_state)642b5c850d4SMarcin Wojtas void a3700_pwr_domain_suspend(const psci_power_state_t *target_state)
643b5c850d4SMarcin Wojtas {
644b5c850d4SMarcin Wojtas 	/* Prevent interrupts from spuriously waking up this cpu */
645b5c850d4SMarcin Wojtas 	plat_marvell_gic_cpuif_disable();
646b5c850d4SMarcin Wojtas 
647b5c850d4SMarcin Wojtas 	/* Save IRQ states */
648b5c850d4SMarcin Wojtas 	plat_marvell_gic_irq_save();
649b5c850d4SMarcin Wojtas 
650b5c850d4SMarcin Wojtas 	/* Set wake up options */
651b5c850d4SMarcin Wojtas 	a3700_set_wake_up_option();
652b5c850d4SMarcin Wojtas 
653b5c850d4SMarcin Wojtas 	/* Set wake up sources */
654b5c850d4SMarcin Wojtas 	a3700_set_wake_up_source();
655b5c850d4SMarcin Wojtas 
656b5c850d4SMarcin Wojtas 	/* SoC can not be powered down with pending IRQ,
657b5c850d4SMarcin Wojtas 	 * acknowledge all the pending IRQ
658b5c850d4SMarcin Wojtas 	 */
659b5c850d4SMarcin Wojtas 	a3700_pm_ack_irq();
660b5c850d4SMarcin Wojtas 
661b5c850d4SMarcin Wojtas 	/* Set power off options */
662b5c850d4SMarcin Wojtas 	a3700_set_pwr_off_option();
663b5c850d4SMarcin Wojtas 
664b5c850d4SMarcin Wojtas 	/* Save the flag for enter the low power mode */
665b5c850d4SMarcin Wojtas 	a3700_pm_save_lp_flag();
666b5c850d4SMarcin Wojtas 
667b5c850d4SMarcin Wojtas 	isb();
668b5c850d4SMarcin Wojtas }
669b5c850d4SMarcin Wojtas 
670b5c850d4SMarcin Wojtas /*****************************************************************************
671b5c850d4SMarcin Wojtas  * A3700 handler called when a power domain has just been powered on after
672b5c850d4SMarcin Wojtas  * being turned off earlier. The target_state encodes the low power state that
673b5c850d4SMarcin Wojtas  * each level has woken up from.
674b5c850d4SMarcin Wojtas  *****************************************************************************
675b5c850d4SMarcin Wojtas  */
a3700_pwr_domain_on_finish(const psci_power_state_t * target_state)676b5c850d4SMarcin Wojtas void a3700_pwr_domain_on_finish(const psci_power_state_t *target_state)
677b5c850d4SMarcin Wojtas {
678b5c850d4SMarcin Wojtas 	/* arch specific configuration */
679b5c850d4SMarcin Wojtas 	marvell_psci_arch_init(0);
680b5c850d4SMarcin Wojtas 
681b5c850d4SMarcin Wojtas 	/* Per-CPU interrupt initialization */
682b5c850d4SMarcin Wojtas 	plat_marvell_gic_pcpu_init();
683b5c850d4SMarcin Wojtas 	plat_marvell_gic_cpuif_enable();
684b5c850d4SMarcin Wojtas 
685b5c850d4SMarcin Wojtas 	/* Restore the per-cpu IRQ state */
686b5c850d4SMarcin Wojtas 	if (a3700_pm_get_lp_flag())
687b5c850d4SMarcin Wojtas 		plat_marvell_gic_irq_pcpu_restore();
688b5c850d4SMarcin Wojtas }
689b5c850d4SMarcin Wojtas 
690b5c850d4SMarcin Wojtas /*****************************************************************************
691b5c850d4SMarcin Wojtas  * A3700 handler called when a power domain has just been powered on after
692b5c850d4SMarcin Wojtas  * having been suspended earlier. The target_state encodes the low power state
693b5c850d4SMarcin Wojtas  * that each level has woken up from.
694b5c850d4SMarcin Wojtas  * TODO: At the moment we reuse the on finisher and reinitialize the secure
695b5c850d4SMarcin Wojtas  * context. Need to implement a separate suspend finisher.
696b5c850d4SMarcin Wojtas  *****************************************************************************
697b5c850d4SMarcin Wojtas  */
a3700_pwr_domain_suspend_finish(const psci_power_state_t * target_state)698b5c850d4SMarcin Wojtas void a3700_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
699b5c850d4SMarcin Wojtas {
700b5c850d4SMarcin Wojtas 	struct dec_win_config *io_dec_map;
701b5c850d4SMarcin Wojtas 	uint32_t dec_win_num;
702b5c850d4SMarcin Wojtas 	struct dram_win_map dram_wins_map;
703b5c850d4SMarcin Wojtas 
704b5c850d4SMarcin Wojtas 	/* arch specific configuration */
705b5c850d4SMarcin Wojtas 	marvell_psci_arch_init(0);
706b5c850d4SMarcin Wojtas 
707b5c850d4SMarcin Wojtas 	/* Interrupt initialization */
708b5c850d4SMarcin Wojtas 	plat_marvell_gic_init();
709b5c850d4SMarcin Wojtas 
710b5c850d4SMarcin Wojtas 	/* Restore IRQ states */
711b5c850d4SMarcin Wojtas 	plat_marvell_gic_irq_restore();
712b5c850d4SMarcin Wojtas 
713b5c850d4SMarcin Wojtas 	/*
714b5c850d4SMarcin Wojtas 	 * Initialize CCI for this cluster after resume from suspend state.
715b5c850d4SMarcin Wojtas 	 * No need for locks as no other CPU is active.
716b5c850d4SMarcin Wojtas 	 */
717b5c850d4SMarcin Wojtas 	plat_marvell_interconnect_init();
718b5c850d4SMarcin Wojtas 	/*
719b5c850d4SMarcin Wojtas 	 * Enable CCI coherency for the primary CPU's cluster.
720b5c850d4SMarcin Wojtas 	 * Platform specific PSCI code will enable coherency for other
721b5c850d4SMarcin Wojtas 	 * clusters.
722b5c850d4SMarcin Wojtas 	 */
723b5c850d4SMarcin Wojtas 	plat_marvell_interconnect_enter_coherency();
724b5c850d4SMarcin Wojtas 
725b5c850d4SMarcin Wojtas 	/* CPU address decoder windows initialization. */
726b5c850d4SMarcin Wojtas 	cpu_wins_init();
727b5c850d4SMarcin Wojtas 
728b5c850d4SMarcin Wojtas 	/* fetch CPU-DRAM window mapping information by reading
729b5c850d4SMarcin Wojtas 	 * CPU-DRAM decode windows (only the enabled ones)
730b5c850d4SMarcin Wojtas 	 */
731b5c850d4SMarcin Wojtas 	dram_win_map_build(&dram_wins_map);
732b5c850d4SMarcin Wojtas 
733b5c850d4SMarcin Wojtas 	/* Get IO address decoder windows */
734b5c850d4SMarcin Wojtas 	if (marvell_get_io_dec_win_conf(&io_dec_map, &dec_win_num)) {
735b5c850d4SMarcin Wojtas 		printf("No IO address decoder windows configurations found!\n");
736b5c850d4SMarcin Wojtas 		return;
737b5c850d4SMarcin Wojtas 	}
738b5c850d4SMarcin Wojtas 
739b5c850d4SMarcin Wojtas 	/* IO address decoder init */
740b5c850d4SMarcin Wojtas 	if (init_io_addr_dec(&dram_wins_map, io_dec_map, dec_win_num)) {
741b5c850d4SMarcin Wojtas 		printf("IO address decoder windows initialization failed!\n");
742b5c850d4SMarcin Wojtas 		return;
743b5c850d4SMarcin Wojtas 	}
744b5c850d4SMarcin Wojtas 
745b5c850d4SMarcin Wojtas 	/* Clear low power mode flag */
746b5c850d4SMarcin Wojtas 	a3700_pm_clear_lp_flag();
747b5c850d4SMarcin Wojtas }
748b5c850d4SMarcin Wojtas 
749b5c850d4SMarcin Wojtas /*****************************************************************************
750b5c850d4SMarcin Wojtas  * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND
751b5c850d4SMarcin Wojtas  * call to get the `power_state` parameter. This allows the platform to encode
752b5c850d4SMarcin Wojtas  * the appropriate State-ID field within the `power_state` parameter which can
753b5c850d4SMarcin Wojtas  * be utilized in `pwr_domain_suspend()` to suspend to system affinity level.
754b5c850d4SMarcin Wojtas  *****************************************************************************
755b5c850d4SMarcin Wojtas  */
a3700_get_sys_suspend_power_state(psci_power_state_t * req_state)756b5c850d4SMarcin Wojtas void a3700_get_sys_suspend_power_state(psci_power_state_t *req_state)
757b5c850d4SMarcin Wojtas {
758b5c850d4SMarcin Wojtas 	/* lower affinities use PLAT_MAX_OFF_STATE */
759b5c850d4SMarcin Wojtas 	for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
760b5c850d4SMarcin Wojtas 		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
761b5c850d4SMarcin Wojtas }
762b5c850d4SMarcin Wojtas 
763b5c850d4SMarcin Wojtas /*****************************************************************************
764b5c850d4SMarcin Wojtas  * A3700 handlers to shutdown/reboot the system
765b5c850d4SMarcin Wojtas  *****************************************************************************
766b5c850d4SMarcin Wojtas  */
a3700_system_off(void)767b5c850d4SMarcin Wojtas static void __dead2 a3700_system_off(void)
768b5c850d4SMarcin Wojtas {
769b5c850d4SMarcin Wojtas 	ERROR("%s needs to be implemented\n", __func__);
770b5c850d4SMarcin Wojtas 	panic();
771b5c850d4SMarcin Wojtas }
772b5c850d4SMarcin Wojtas 
773d9243f26SMarek Behún #pragma weak cm3_system_reset
cm3_system_reset(void)774d9243f26SMarek Behún void cm3_system_reset(void)
775d9243f26SMarek Behún {
776d9243f26SMarek Behún }
777d9243f26SMarek Behún 
778b5c850d4SMarcin Wojtas /*****************************************************************************
779b5c850d4SMarcin Wojtas  * A3700 handlers to reset the system
780b5c850d4SMarcin Wojtas  *****************************************************************************
781b5c850d4SMarcin Wojtas  */
a3700_system_reset(void)782b5c850d4SMarcin Wojtas static void __dead2 a3700_system_reset(void)
783b5c850d4SMarcin Wojtas {
784b5c850d4SMarcin Wojtas 	/* Clean the mailbox magic number to let it as act like cold boot */
785b5c850d4SMarcin Wojtas 	mmio_write_32(PLAT_MARVELL_MAILBOX_BASE, 0x0);
786b5c850d4SMarcin Wojtas 
787b5c850d4SMarcin Wojtas 	dsbsy();
788b5c850d4SMarcin Wojtas 
789b5c850d4SMarcin Wojtas 	/* Flush data cache if the mail box shared RAM is cached */
790b5c850d4SMarcin Wojtas #if PLAT_MARVELL_SHARED_RAM_CACHED
791b5c850d4SMarcin Wojtas 	flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE,
792b5c850d4SMarcin Wojtas 			   2 * sizeof(uint64_t));
793b5c850d4SMarcin Wojtas #endif
794b5c850d4SMarcin Wojtas 
795d9243f26SMarek Behún 	/* Use Cortex-M3 secure coprocessor for system reset */
796d9243f26SMarek Behún 	cm3_system_reset();
797d9243f26SMarek Behún 
798b5c850d4SMarcin Wojtas 	/* Trigger the warm reset */
799b5c850d4SMarcin Wojtas 	mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC);
800b5c850d4SMarcin Wojtas 
801b5c850d4SMarcin Wojtas 	/* Shouldn't get to this point */
802b5c850d4SMarcin Wojtas 	panic();
803b5c850d4SMarcin Wojtas }
804b5c850d4SMarcin Wojtas 
805b5c850d4SMarcin Wojtas /*****************************************************************************
806b5c850d4SMarcin Wojtas  * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
807b5c850d4SMarcin Wojtas  * platform layer will take care of registering the handlers with PSCI.
808b5c850d4SMarcin Wojtas  *****************************************************************************
809b5c850d4SMarcin Wojtas  */
810b5c850d4SMarcin Wojtas const plat_psci_ops_t plat_arm_psci_pm_ops = {
811b5c850d4SMarcin Wojtas 	.cpu_standby = a3700_cpu_standby,
812b5c850d4SMarcin Wojtas 	.pwr_domain_on = a3700_pwr_domain_on,
813b5c850d4SMarcin Wojtas 	.pwr_domain_off = a3700_pwr_domain_off,
814b5c850d4SMarcin Wojtas 	.pwr_domain_suspend = a3700_pwr_domain_suspend,
815b5c850d4SMarcin Wojtas 	.pwr_domain_on_finish = a3700_pwr_domain_on_finish,
816b5c850d4SMarcin Wojtas 	.pwr_domain_suspend_finish = a3700_pwr_domain_suspend_finish,
817b5c850d4SMarcin Wojtas 	.get_sys_suspend_power_state = a3700_get_sys_suspend_power_state,
818b5c850d4SMarcin Wojtas 	.system_off = a3700_system_off,
819b5c850d4SMarcin Wojtas 	.system_reset = a3700_system_reset,
820b5c850d4SMarcin Wojtas 	.validate_power_state = a3700_validate_power_state,
821b5c850d4SMarcin Wojtas 	.validate_ns_entrypoint = a3700_validate_ns_entrypoint
822b5c850d4SMarcin Wojtas };
823