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