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