xref: /rk3399_ARM-atf/plat/marvell/armada/a8k/common/plat_pm.c (revision a28471722afb3ae784d7bce2118c2ea703f8444c)
1*a2847172SGrzegorz Jaszczyk /*
2*a2847172SGrzegorz Jaszczyk  * Copyright (C) 2018 Marvell International Ltd.
3*a2847172SGrzegorz Jaszczyk  *
4*a2847172SGrzegorz Jaszczyk  * SPDX-License-Identifier:     BSD-3-Clause
5*a2847172SGrzegorz Jaszczyk  * https://spdx.org/licenses
6*a2847172SGrzegorz Jaszczyk  */
7*a2847172SGrzegorz Jaszczyk 
8*a2847172SGrzegorz Jaszczyk #include <assert.h>
9*a2847172SGrzegorz Jaszczyk 
10*a2847172SGrzegorz Jaszczyk #include <common/debug.h>
11*a2847172SGrzegorz Jaszczyk #include <drivers/arm/gicv2.h>
12*a2847172SGrzegorz Jaszczyk #include <drivers/console.h>
13*a2847172SGrzegorz Jaszczyk #include <drivers/delay_timer.h>
14*a2847172SGrzegorz Jaszczyk #include <drivers/marvell/cache_llc.h>
15*a2847172SGrzegorz Jaszczyk #include <lib/bakery_lock.h>
16*a2847172SGrzegorz Jaszczyk #include <lib/mmio.h>
17*a2847172SGrzegorz Jaszczyk #include <plat/common/platform.h>
18*a2847172SGrzegorz Jaszczyk 
19*a2847172SGrzegorz Jaszczyk #include <armada_common.h>
20*a2847172SGrzegorz Jaszczyk #include <marvell_pm.h>
21*a2847172SGrzegorz Jaszczyk #include <mss_pm_ipc.h>
22*a2847172SGrzegorz Jaszczyk #include <plat_marvell.h>
23*a2847172SGrzegorz Jaszczyk #include <plat_pm_trace.h>
24*a2847172SGrzegorz Jaszczyk 
25*a2847172SGrzegorz Jaszczyk #define MVEBU_PRIVATE_UID_REG		0x30
26*a2847172SGrzegorz Jaszczyk #define MVEBU_RFU_GLOBL_SW_RST		0x84
27*a2847172SGrzegorz Jaszczyk #define MVEBU_CCU_RVBAR(cpu)		(MVEBU_REGS_BASE + 0x640 + (cpu * 4))
28*a2847172SGrzegorz Jaszczyk #define MVEBU_CCU_CPU_UN_RESET(cpu)	(MVEBU_REGS_BASE + 0x650 + (cpu * 4))
29*a2847172SGrzegorz Jaszczyk 
30*a2847172SGrzegorz Jaszczyk #define MPIDR_CPU_GET(mpidr)		((mpidr) & MPIDR_CPU_MASK)
31*a2847172SGrzegorz Jaszczyk #define MPIDR_CLUSTER_GET(mpidr)	MPIDR_AFFLVL1_VAL((mpidr))
32*a2847172SGrzegorz Jaszczyk 
33*a2847172SGrzegorz Jaszczyk #define MVEBU_GPIO_MASK(index)		(1 << (index % 32))
34*a2847172SGrzegorz Jaszczyk #define MVEBU_MPP_MASK(index)		(0xF << (4 * (index % 8)))
35*a2847172SGrzegorz Jaszczyk #define MVEBU_GPIO_VALUE(index, value)	(value << (index % 32))
36*a2847172SGrzegorz Jaszczyk 
37*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_0_REG		(MVEBU_DRAM_MAC_BASE + 0x20)
38*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_CH0_OFFSET	28
39*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_CH0_MASK		(1 << MVEBU_USER_CMD_CH0_OFFSET)
40*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_CH0_EN		(1 << MVEBU_USER_CMD_CH0_OFFSET)
41*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_CS_OFFSET	24
42*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_CS_MASK		(0xF << MVEBU_USER_CMD_CS_OFFSET)
43*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_CS_ALL		(0xF << MVEBU_USER_CMD_CS_OFFSET)
44*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_SR_OFFSET	6
45*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_SR_MASK		(0x3 << MVEBU_USER_CMD_SR_OFFSET)
46*a2847172SGrzegorz Jaszczyk #define MVEBU_USER_CMD_SR_ENTER		(0x1 << MVEBU_USER_CMD_SR_OFFSET)
47*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_PWR_CTRL_REG		(MVEBU_DRAM_MAC_BASE + 0x54)
48*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_AC_ON_DLY_OFFSET	8
49*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_AC_ON_DLY_MASK		(0xF << MVEBU_MC_AC_ON_DLY_OFFSET)
50*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_AC_ON_DLY_DEF_VAR	(8 << MVEBU_MC_AC_ON_DLY_OFFSET)
51*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_AC_OFF_DLY_OFFSET	4
52*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_AC_OFF_DLY_MASK	(0xF << MVEBU_MC_AC_OFF_DLY_OFFSET)
53*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_AC_OFF_DLY_DEF_VAR	(0xC << MVEBU_MC_AC_OFF_DLY_OFFSET)
54*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_PHY_AUTO_OFF_OFFSET	0
55*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_PHY_AUTO_OFF_MASK	(1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET)
56*a2847172SGrzegorz Jaszczyk #define MVEBU_MC_PHY_AUTO_OFF_EN	(1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET)
57*a2847172SGrzegorz Jaszczyk 
58*a2847172SGrzegorz Jaszczyk /* this lock synchronize AP multiple cores execution with MSS */
59*a2847172SGrzegorz Jaszczyk DEFINE_BAKERY_LOCK(pm_sys_lock);
60*a2847172SGrzegorz Jaszczyk 
61*a2847172SGrzegorz Jaszczyk /* Weak definitions may be overridden in specific board */
62*a2847172SGrzegorz Jaszczyk #pragma weak plat_marvell_get_pm_cfg
63*a2847172SGrzegorz Jaszczyk 
64*a2847172SGrzegorz Jaszczyk /* AP806 CPU power down /power up definitions */
65*a2847172SGrzegorz Jaszczyk enum CPU_ID {
66*a2847172SGrzegorz Jaszczyk 	CPU0,
67*a2847172SGrzegorz Jaszczyk 	CPU1,
68*a2847172SGrzegorz Jaszczyk 	CPU2,
69*a2847172SGrzegorz Jaszczyk 	CPU3
70*a2847172SGrzegorz Jaszczyk };
71*a2847172SGrzegorz Jaszczyk 
72*a2847172SGrzegorz Jaszczyk #define REG_WR_VALIDATE_TIMEOUT		(2000)
73*a2847172SGrzegorz Jaszczyk 
74*a2847172SGrzegorz Jaszczyk #define FEATURE_DISABLE_STATUS_REG			\
75*a2847172SGrzegorz Jaszczyk 			(MVEBU_REGS_BASE + 0x6F8230)
76*a2847172SGrzegorz Jaszczyk #define FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET	4
77*a2847172SGrzegorz Jaszczyk #define FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK		\
78*a2847172SGrzegorz Jaszczyk 			(0x1 << FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET)
79*a2847172SGrzegorz Jaszczyk 
80*a2847172SGrzegorz Jaszczyk #ifdef MVEBU_SOC_AP807
81*a2847172SGrzegorz Jaszczyk 	#define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET		1
82*a2847172SGrzegorz Jaszczyk 	#define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET	0
83*a2847172SGrzegorz Jaszczyk #else
84*a2847172SGrzegorz Jaszczyk 	#define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET		0
85*a2847172SGrzegorz Jaszczyk 	#define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET	31
86*a2847172SGrzegorz Jaszczyk #endif
87*a2847172SGrzegorz Jaszczyk 
88*a2847172SGrzegorz Jaszczyk #define PWRC_CPUN_CR_REG(cpu_id)		\
89*a2847172SGrzegorz Jaszczyk 			(MVEBU_REGS_BASE + 0x680000 + (cpu_id * 0x10))
90*a2847172SGrzegorz Jaszczyk #define PWRC_CPUN_CR_PWR_DN_RQ_MASK		\
91*a2847172SGrzegorz Jaszczyk 			(0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET)
92*a2847172SGrzegorz Jaszczyk #define PWRC_CPUN_CR_ISO_ENABLE_OFFSET		16
93*a2847172SGrzegorz Jaszczyk #define PWRC_CPUN_CR_ISO_ENABLE_MASK		\
94*a2847172SGrzegorz Jaszczyk 			(0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)
95*a2847172SGrzegorz Jaszczyk #define PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK	\
96*a2847172SGrzegorz Jaszczyk 			(0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET)
97*a2847172SGrzegorz Jaszczyk 
98*a2847172SGrzegorz Jaszczyk #define CCU_B_PRCRN_REG(cpu_id)			\
99*a2847172SGrzegorz Jaszczyk 			(MVEBU_REGS_BASE + 0x1A50 + \
100*a2847172SGrzegorz Jaszczyk 			((cpu_id / 2) * (0x400)) + ((cpu_id % 2) * 4))
101*a2847172SGrzegorz Jaszczyk #define CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET	0
102*a2847172SGrzegorz Jaszczyk #define CCU_B_PRCRN_CPUPORESET_STATIC_MASK	\
103*a2847172SGrzegorz Jaszczyk 			(0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET)
104*a2847172SGrzegorz Jaszczyk 
105*a2847172SGrzegorz Jaszczyk /* power switch fingers */
106*a2847172SGrzegorz Jaszczyk #define AP807_PWRC_LDO_CR0_REG			\
107*a2847172SGrzegorz Jaszczyk 			(MVEBU_REGS_BASE + 0x680000 + 0x100)
108*a2847172SGrzegorz Jaszczyk #define AP807_PWRC_LDO_CR0_OFFSET		16
109*a2847172SGrzegorz Jaszczyk #define AP807_PWRC_LDO_CR0_MASK			\
110*a2847172SGrzegorz Jaszczyk 			(0xff << AP807_PWRC_LDO_CR0_OFFSET)
111*a2847172SGrzegorz Jaszczyk #define AP807_PWRC_LDO_CR0_VAL			0xfc
112*a2847172SGrzegorz Jaszczyk 
113*a2847172SGrzegorz Jaszczyk /*
114*a2847172SGrzegorz Jaszczyk  * Power down CPU:
115*a2847172SGrzegorz Jaszczyk  * Used to reduce power consumption, and avoid SoC unnecessary temperature rise.
116*a2847172SGrzegorz Jaszczyk  */
117*a2847172SGrzegorz Jaszczyk static int plat_marvell_cpu_powerdown(int cpu_id)
118*a2847172SGrzegorz Jaszczyk {
119*a2847172SGrzegorz Jaszczyk 	uint32_t	reg_val;
120*a2847172SGrzegorz Jaszczyk 	int		exit_loop = REG_WR_VALIDATE_TIMEOUT;
121*a2847172SGrzegorz Jaszczyk 
122*a2847172SGrzegorz Jaszczyk 	INFO("Powering down CPU%d\n", cpu_id);
123*a2847172SGrzegorz Jaszczyk 
124*a2847172SGrzegorz Jaszczyk 	/* 1. Isolation enable */
125*a2847172SGrzegorz Jaszczyk 	reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
126*a2847172SGrzegorz Jaszczyk 	reg_val |= 0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET;
127*a2847172SGrzegorz Jaszczyk 	mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
128*a2847172SGrzegorz Jaszczyk 
129*a2847172SGrzegorz Jaszczyk 	/* 2. Read and check Isolation enabled - verify bit set to 1 */
130*a2847172SGrzegorz Jaszczyk 	do {
131*a2847172SGrzegorz Jaszczyk 		reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
132*a2847172SGrzegorz Jaszczyk 		exit_loop--;
133*a2847172SGrzegorz Jaszczyk 	} while (!(reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) &&
134*a2847172SGrzegorz Jaszczyk 		 exit_loop > 0);
135*a2847172SGrzegorz Jaszczyk 
136*a2847172SGrzegorz Jaszczyk 	/* 3. Switch off CPU power */
137*a2847172SGrzegorz Jaszczyk 	reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
138*a2847172SGrzegorz Jaszczyk 	reg_val &= ~PWRC_CPUN_CR_PWR_DN_RQ_MASK;
139*a2847172SGrzegorz Jaszczyk 	mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
140*a2847172SGrzegorz Jaszczyk 
141*a2847172SGrzegorz Jaszczyk 	/* 4. Read and check Switch Off - verify bit set to 0 */
142*a2847172SGrzegorz Jaszczyk 	exit_loop = REG_WR_VALIDATE_TIMEOUT;
143*a2847172SGrzegorz Jaszczyk 	do {
144*a2847172SGrzegorz Jaszczyk 		reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
145*a2847172SGrzegorz Jaszczyk 		exit_loop--;
146*a2847172SGrzegorz Jaszczyk 	} while (reg_val & PWRC_CPUN_CR_PWR_DN_RQ_MASK && exit_loop > 0);
147*a2847172SGrzegorz Jaszczyk 
148*a2847172SGrzegorz Jaszczyk 	if (exit_loop <= 0)
149*a2847172SGrzegorz Jaszczyk 		goto cpu_poweroff_error;
150*a2847172SGrzegorz Jaszczyk 
151*a2847172SGrzegorz Jaszczyk 	/* 5. De-Assert power ready */
152*a2847172SGrzegorz Jaszczyk 	reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
153*a2847172SGrzegorz Jaszczyk 	reg_val &= ~PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK;
154*a2847172SGrzegorz Jaszczyk 	mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
155*a2847172SGrzegorz Jaszczyk 
156*a2847172SGrzegorz Jaszczyk 	/* 6. Assert CPU POR reset */
157*a2847172SGrzegorz Jaszczyk 	reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
158*a2847172SGrzegorz Jaszczyk 	reg_val &= ~CCU_B_PRCRN_CPUPORESET_STATIC_MASK;
159*a2847172SGrzegorz Jaszczyk 	mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val);
160*a2847172SGrzegorz Jaszczyk 
161*a2847172SGrzegorz Jaszczyk 	/* 7. Read and poll on Validate the CPU is out of reset */
162*a2847172SGrzegorz Jaszczyk 	exit_loop = REG_WR_VALIDATE_TIMEOUT;
163*a2847172SGrzegorz Jaszczyk 	do {
164*a2847172SGrzegorz Jaszczyk 		reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
165*a2847172SGrzegorz Jaszczyk 		exit_loop--;
166*a2847172SGrzegorz Jaszczyk 	} while (reg_val & CCU_B_PRCRN_CPUPORESET_STATIC_MASK && exit_loop > 0);
167*a2847172SGrzegorz Jaszczyk 
168*a2847172SGrzegorz Jaszczyk 	if (exit_loop <= 0)
169*a2847172SGrzegorz Jaszczyk 		goto cpu_poweroff_error;
170*a2847172SGrzegorz Jaszczyk 
171*a2847172SGrzegorz Jaszczyk 	INFO("Successfully powered down CPU%d\n", cpu_id);
172*a2847172SGrzegorz Jaszczyk 
173*a2847172SGrzegorz Jaszczyk 	return 0;
174*a2847172SGrzegorz Jaszczyk 
175*a2847172SGrzegorz Jaszczyk cpu_poweroff_error:
176*a2847172SGrzegorz Jaszczyk 	ERROR("ERROR: Can't power down CPU%d\n", cpu_id);
177*a2847172SGrzegorz Jaszczyk 	return -1;
178*a2847172SGrzegorz Jaszczyk }
179*a2847172SGrzegorz Jaszczyk 
180*a2847172SGrzegorz Jaszczyk /*
181*a2847172SGrzegorz Jaszczyk  * Power down CPUs 1-3 at early boot stage,
182*a2847172SGrzegorz Jaszczyk  * to reduce power consumption and SoC temperature.
183*a2847172SGrzegorz Jaszczyk  * This is triggered by BLE prior to DDR initialization.
184*a2847172SGrzegorz Jaszczyk  *
185*a2847172SGrzegorz Jaszczyk  * Note:
186*a2847172SGrzegorz Jaszczyk  * All CPUs will be powered up by plat_marvell_cpu_powerup on Linux boot stage,
187*a2847172SGrzegorz Jaszczyk  * which is triggered by PSCI ops (pwr_domain_on).
188*a2847172SGrzegorz Jaszczyk  */
189*a2847172SGrzegorz Jaszczyk int plat_marvell_early_cpu_powerdown(void)
190*a2847172SGrzegorz Jaszczyk {
191*a2847172SGrzegorz Jaszczyk 	uint32_t cpu_cluster_status =
192*a2847172SGrzegorz Jaszczyk 		mmio_read_32(FEATURE_DISABLE_STATUS_REG) &
193*a2847172SGrzegorz Jaszczyk 			     FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK;
194*a2847172SGrzegorz Jaszczyk 	/* if cpu_cluster_status bit is set,
195*a2847172SGrzegorz Jaszczyk 	 * that means we have only single cluster
196*a2847172SGrzegorz Jaszczyk 	 */
197*a2847172SGrzegorz Jaszczyk 	int cluster_count = cpu_cluster_status ? 1 : 2;
198*a2847172SGrzegorz Jaszczyk 
199*a2847172SGrzegorz Jaszczyk 	INFO("Powering off unused CPUs\n");
200*a2847172SGrzegorz Jaszczyk 
201*a2847172SGrzegorz Jaszczyk 	/* CPU1 is in AP806 cluster-0, which always exists, so power it down */
202*a2847172SGrzegorz Jaszczyk 	if (plat_marvell_cpu_powerdown(CPU1) == -1)
203*a2847172SGrzegorz Jaszczyk 		return -1;
204*a2847172SGrzegorz Jaszczyk 
205*a2847172SGrzegorz Jaszczyk 	/*
206*a2847172SGrzegorz Jaszczyk 	 * CPU2-3 are in AP806 2nd cluster (cluster-1),
207*a2847172SGrzegorz Jaszczyk 	 * which doesn't exists in dual-core systems.
208*a2847172SGrzegorz Jaszczyk 	 * so need to check if we have dual-core (single cluster)
209*a2847172SGrzegorz Jaszczyk 	 * or quad-code (2 clusters)
210*a2847172SGrzegorz Jaszczyk 	 */
211*a2847172SGrzegorz Jaszczyk 	if (cluster_count == 2) {
212*a2847172SGrzegorz Jaszczyk 		/* CPU2-3 are part of 2nd cluster */
213*a2847172SGrzegorz Jaszczyk 		if (plat_marvell_cpu_powerdown(CPU2) == -1)
214*a2847172SGrzegorz Jaszczyk 			return -1;
215*a2847172SGrzegorz Jaszczyk 		if (plat_marvell_cpu_powerdown(CPU3) == -1)
216*a2847172SGrzegorz Jaszczyk 			return -1;
217*a2847172SGrzegorz Jaszczyk 	}
218*a2847172SGrzegorz Jaszczyk 
219*a2847172SGrzegorz Jaszczyk 	return 0;
220*a2847172SGrzegorz Jaszczyk }
221*a2847172SGrzegorz Jaszczyk 
222*a2847172SGrzegorz Jaszczyk /*
223*a2847172SGrzegorz Jaszczyk  * Power up CPU - part of Linux boot stage
224*a2847172SGrzegorz Jaszczyk  */
225*a2847172SGrzegorz Jaszczyk static int plat_marvell_cpu_powerup(u_register_t mpidr)
226*a2847172SGrzegorz Jaszczyk {
227*a2847172SGrzegorz Jaszczyk 	uint32_t	reg_val;
228*a2847172SGrzegorz Jaszczyk 	int	cpu_id = MPIDR_CPU_GET(mpidr),
229*a2847172SGrzegorz Jaszczyk 		cluster = MPIDR_CLUSTER_GET(mpidr);
230*a2847172SGrzegorz Jaszczyk 	int	exit_loop = REG_WR_VALIDATE_TIMEOUT;
231*a2847172SGrzegorz Jaszczyk 
232*a2847172SGrzegorz Jaszczyk 	/* calculate absolute CPU ID */
233*a2847172SGrzegorz Jaszczyk 	cpu_id = cluster * PLAT_MARVELL_CLUSTER_CORE_COUNT + cpu_id;
234*a2847172SGrzegorz Jaszczyk 
235*a2847172SGrzegorz Jaszczyk 	INFO("Powering on CPU%d\n", cpu_id);
236*a2847172SGrzegorz Jaszczyk 
237*a2847172SGrzegorz Jaszczyk #ifdef MVEBU_SOC_AP807
238*a2847172SGrzegorz Jaszczyk 	/* Activate 2 power switch fingers */
239*a2847172SGrzegorz Jaszczyk 	reg_val = mmio_read_32(AP807_PWRC_LDO_CR0_REG);
240*a2847172SGrzegorz Jaszczyk 	reg_val &= ~(AP807_PWRC_LDO_CR0_MASK);
241*a2847172SGrzegorz Jaszczyk 	reg_val |= (AP807_PWRC_LDO_CR0_VAL << AP807_PWRC_LDO_CR0_OFFSET);
242*a2847172SGrzegorz Jaszczyk 	mmio_write_32(AP807_PWRC_LDO_CR0_REG, reg_val);
243*a2847172SGrzegorz Jaszczyk 	udelay(100);
244*a2847172SGrzegorz Jaszczyk #endif
245*a2847172SGrzegorz Jaszczyk 
246*a2847172SGrzegorz Jaszczyk 	/* 1. Switch CPU power ON */
247*a2847172SGrzegorz Jaszczyk 	reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
248*a2847172SGrzegorz Jaszczyk 	reg_val |= 0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET;
249*a2847172SGrzegorz Jaszczyk 	mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
250*a2847172SGrzegorz Jaszczyk 
251*a2847172SGrzegorz Jaszczyk 	/* 2. Wait for CPU on, up to 100 uSec: */
252*a2847172SGrzegorz Jaszczyk 	udelay(100);
253*a2847172SGrzegorz Jaszczyk 
254*a2847172SGrzegorz Jaszczyk 	/* 3. Assert power ready */
255*a2847172SGrzegorz Jaszczyk 	reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
256*a2847172SGrzegorz Jaszczyk 	reg_val |= 0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET;
257*a2847172SGrzegorz Jaszczyk 	mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
258*a2847172SGrzegorz Jaszczyk 
259*a2847172SGrzegorz Jaszczyk 	/* 4. Read & Validate power ready
260*a2847172SGrzegorz Jaszczyk 	 * used in order to generate 16 Host CPU cycles
261*a2847172SGrzegorz Jaszczyk 	 */
262*a2847172SGrzegorz Jaszczyk 	do {
263*a2847172SGrzegorz Jaszczyk 		reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
264*a2847172SGrzegorz Jaszczyk 		exit_loop--;
265*a2847172SGrzegorz Jaszczyk 	} while (!(reg_val & (0x1U << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET)) &&
266*a2847172SGrzegorz Jaszczyk 		 exit_loop > 0);
267*a2847172SGrzegorz Jaszczyk 
268*a2847172SGrzegorz Jaszczyk 	if (exit_loop <= 0)
269*a2847172SGrzegorz Jaszczyk 		goto cpu_poweron_error;
270*a2847172SGrzegorz Jaszczyk 
271*a2847172SGrzegorz Jaszczyk 	/* 5. Isolation disable */
272*a2847172SGrzegorz Jaszczyk 	reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
273*a2847172SGrzegorz Jaszczyk 	reg_val &= ~PWRC_CPUN_CR_ISO_ENABLE_MASK;
274*a2847172SGrzegorz Jaszczyk 	mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
275*a2847172SGrzegorz Jaszczyk 
276*a2847172SGrzegorz Jaszczyk 	/* 6. Read and check Isolation enabled - verify bit set to 1 */
277*a2847172SGrzegorz Jaszczyk 	exit_loop = REG_WR_VALIDATE_TIMEOUT;
278*a2847172SGrzegorz Jaszczyk 	do {
279*a2847172SGrzegorz Jaszczyk 		reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
280*a2847172SGrzegorz Jaszczyk 		exit_loop--;
281*a2847172SGrzegorz Jaszczyk 	} while ((reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) &&
282*a2847172SGrzegorz Jaszczyk 		 exit_loop > 0);
283*a2847172SGrzegorz Jaszczyk 
284*a2847172SGrzegorz Jaszczyk 	/* 7. De Assert CPU POR reset & Core reset */
285*a2847172SGrzegorz Jaszczyk 	reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
286*a2847172SGrzegorz Jaszczyk 	reg_val |= 0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET;
287*a2847172SGrzegorz Jaszczyk 	mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val);
288*a2847172SGrzegorz Jaszczyk 
289*a2847172SGrzegorz Jaszczyk 	/* 8. Read & Validate CPU POR reset */
290*a2847172SGrzegorz Jaszczyk 	exit_loop = REG_WR_VALIDATE_TIMEOUT;
291*a2847172SGrzegorz Jaszczyk 	do {
292*a2847172SGrzegorz Jaszczyk 		reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
293*a2847172SGrzegorz Jaszczyk 		exit_loop--;
294*a2847172SGrzegorz Jaszczyk 	} while (!(reg_val & (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET)) &&
295*a2847172SGrzegorz Jaszczyk 		 exit_loop > 0);
296*a2847172SGrzegorz Jaszczyk 
297*a2847172SGrzegorz Jaszczyk 	if (exit_loop <= 0)
298*a2847172SGrzegorz Jaszczyk 		goto cpu_poweron_error;
299*a2847172SGrzegorz Jaszczyk 
300*a2847172SGrzegorz Jaszczyk 	INFO("Successfully powered on CPU%d\n", cpu_id);
301*a2847172SGrzegorz Jaszczyk 
302*a2847172SGrzegorz Jaszczyk 	return 0;
303*a2847172SGrzegorz Jaszczyk 
304*a2847172SGrzegorz Jaszczyk cpu_poweron_error:
305*a2847172SGrzegorz Jaszczyk 	ERROR("ERROR: Can't power up CPU%d\n", cpu_id);
306*a2847172SGrzegorz Jaszczyk 	return -1;
307*a2847172SGrzegorz Jaszczyk }
308*a2847172SGrzegorz Jaszczyk 
309*a2847172SGrzegorz Jaszczyk static int plat_marvell_cpu_on(u_register_t mpidr)
310*a2847172SGrzegorz Jaszczyk {
311*a2847172SGrzegorz Jaszczyk 	int cpu_id;
312*a2847172SGrzegorz Jaszczyk 	int cluster;
313*a2847172SGrzegorz Jaszczyk 
314*a2847172SGrzegorz Jaszczyk 	/* Set barierr */
315*a2847172SGrzegorz Jaszczyk 	dsbsy();
316*a2847172SGrzegorz Jaszczyk 
317*a2847172SGrzegorz Jaszczyk 	/* Get cpu number - use CPU ID */
318*a2847172SGrzegorz Jaszczyk 	cpu_id =  MPIDR_CPU_GET(mpidr);
319*a2847172SGrzegorz Jaszczyk 
320*a2847172SGrzegorz Jaszczyk 	/* Get cluster number - use affinity level 1 */
321*a2847172SGrzegorz Jaszczyk 	cluster = MPIDR_CLUSTER_GET(mpidr);
322*a2847172SGrzegorz Jaszczyk 
323*a2847172SGrzegorz Jaszczyk 	/* Set CPU private UID */
324*a2847172SGrzegorz Jaszczyk 	mmio_write_32(MVEBU_REGS_BASE + MVEBU_PRIVATE_UID_REG, cluster + 0x4);
325*a2847172SGrzegorz Jaszczyk 
326*a2847172SGrzegorz Jaszczyk 	/* Set the cpu start address to BL1 entry point (align to 0x10000) */
327*a2847172SGrzegorz Jaszczyk 	mmio_write_32(MVEBU_CCU_RVBAR(cpu_id),
328*a2847172SGrzegorz Jaszczyk 		      PLAT_MARVELL_CPU_ENTRY_ADDR >> 16);
329*a2847172SGrzegorz Jaszczyk 
330*a2847172SGrzegorz Jaszczyk 	/* Get the cpu out of reset */
331*a2847172SGrzegorz Jaszczyk 	mmio_write_32(MVEBU_CCU_CPU_UN_RESET(cpu_id), 0x10001);
332*a2847172SGrzegorz Jaszczyk 
333*a2847172SGrzegorz Jaszczyk 	return 0;
334*a2847172SGrzegorz Jaszczyk }
335*a2847172SGrzegorz Jaszczyk 
336*a2847172SGrzegorz Jaszczyk /*****************************************************************************
337*a2847172SGrzegorz Jaszczyk  * A8K handler called to check the validity of the power state
338*a2847172SGrzegorz Jaszczyk  * parameter.
339*a2847172SGrzegorz Jaszczyk  *****************************************************************************
340*a2847172SGrzegorz Jaszczyk  */
341*a2847172SGrzegorz Jaszczyk static int a8k_validate_power_state(unsigned int power_state,
342*a2847172SGrzegorz Jaszczyk 			    psci_power_state_t *req_state)
343*a2847172SGrzegorz Jaszczyk {
344*a2847172SGrzegorz Jaszczyk 	int pstate = psci_get_pstate_type(power_state);
345*a2847172SGrzegorz Jaszczyk 	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
346*a2847172SGrzegorz Jaszczyk 	int i;
347*a2847172SGrzegorz Jaszczyk 
348*a2847172SGrzegorz Jaszczyk 	if (pwr_lvl > PLAT_MAX_PWR_LVL)
349*a2847172SGrzegorz Jaszczyk 		return PSCI_E_INVALID_PARAMS;
350*a2847172SGrzegorz Jaszczyk 
351*a2847172SGrzegorz Jaszczyk 	/* Sanity check the requested state */
352*a2847172SGrzegorz Jaszczyk 	if (pstate == PSTATE_TYPE_STANDBY) {
353*a2847172SGrzegorz Jaszczyk 		/*
354*a2847172SGrzegorz Jaszczyk 		 * It's possible to enter standby only on power level 0
355*a2847172SGrzegorz Jaszczyk 		 * Ignore any other power level.
356*a2847172SGrzegorz Jaszczyk 		 */
357*a2847172SGrzegorz Jaszczyk 		if (pwr_lvl != MARVELL_PWR_LVL0)
358*a2847172SGrzegorz Jaszczyk 			return PSCI_E_INVALID_PARAMS;
359*a2847172SGrzegorz Jaszczyk 
360*a2847172SGrzegorz Jaszczyk 		req_state->pwr_domain_state[MARVELL_PWR_LVL0] =
361*a2847172SGrzegorz Jaszczyk 					MARVELL_LOCAL_STATE_RET;
362*a2847172SGrzegorz Jaszczyk 	} else {
363*a2847172SGrzegorz Jaszczyk 		for (i = MARVELL_PWR_LVL0; i <= pwr_lvl; i++)
364*a2847172SGrzegorz Jaszczyk 			req_state->pwr_domain_state[i] =
365*a2847172SGrzegorz Jaszczyk 					MARVELL_LOCAL_STATE_OFF;
366*a2847172SGrzegorz Jaszczyk 	}
367*a2847172SGrzegorz Jaszczyk 
368*a2847172SGrzegorz Jaszczyk 	/*
369*a2847172SGrzegorz Jaszczyk 	 * We expect the 'state id' to be zero.
370*a2847172SGrzegorz Jaszczyk 	 */
371*a2847172SGrzegorz Jaszczyk 	if (psci_get_pstate_id(power_state))
372*a2847172SGrzegorz Jaszczyk 		return PSCI_E_INVALID_PARAMS;
373*a2847172SGrzegorz Jaszczyk 
374*a2847172SGrzegorz Jaszczyk 	return PSCI_E_SUCCESS;
375*a2847172SGrzegorz Jaszczyk }
376*a2847172SGrzegorz Jaszczyk 
377*a2847172SGrzegorz Jaszczyk /*****************************************************************************
378*a2847172SGrzegorz Jaszczyk  * A8K handler called when a CPU is about to enter standby.
379*a2847172SGrzegorz Jaszczyk  *****************************************************************************
380*a2847172SGrzegorz Jaszczyk  */
381*a2847172SGrzegorz Jaszczyk static void a8k_cpu_standby(plat_local_state_t cpu_state)
382*a2847172SGrzegorz Jaszczyk {
383*a2847172SGrzegorz Jaszczyk 	if (!is_pm_fw_running()) {
384*a2847172SGrzegorz Jaszczyk 		ERROR("%s: needs to be implemented\n", __func__);
385*a2847172SGrzegorz Jaszczyk 		panic();
386*a2847172SGrzegorz Jaszczyk 	}
387*a2847172SGrzegorz Jaszczyk }
388*a2847172SGrzegorz Jaszczyk 
389*a2847172SGrzegorz Jaszczyk /*****************************************************************************
390*a2847172SGrzegorz Jaszczyk  * A8K handler called when a power domain is about to be turned on. The
391*a2847172SGrzegorz Jaszczyk  * mpidr determines the CPU to be turned on.
392*a2847172SGrzegorz Jaszczyk  *****************************************************************************
393*a2847172SGrzegorz Jaszczyk  */
394*a2847172SGrzegorz Jaszczyk static int a8k_pwr_domain_on(u_register_t mpidr)
395*a2847172SGrzegorz Jaszczyk {
396*a2847172SGrzegorz Jaszczyk 	/* Power up CPU (CPUs 1-3 are powered off at start of BLE) */
397*a2847172SGrzegorz Jaszczyk 	plat_marvell_cpu_powerup(mpidr);
398*a2847172SGrzegorz Jaszczyk 
399*a2847172SGrzegorz Jaszczyk 	if (is_pm_fw_running()) {
400*a2847172SGrzegorz Jaszczyk 		unsigned int target =
401*a2847172SGrzegorz Jaszczyk 				((mpidr & 0xFF) + (((mpidr >> 8) & 0xFF) * 2));
402*a2847172SGrzegorz Jaszczyk 
403*a2847172SGrzegorz Jaszczyk 		/*
404*a2847172SGrzegorz Jaszczyk 		 * pm system synchronization - used to synchronize
405*a2847172SGrzegorz Jaszczyk 		 * multiple core access to MSS
406*a2847172SGrzegorz Jaszczyk 		 */
407*a2847172SGrzegorz Jaszczyk 		bakery_lock_get(&pm_sys_lock);
408*a2847172SGrzegorz Jaszczyk 
409*a2847172SGrzegorz Jaszczyk 		/* send CPU ON IPC Message to MSS */
410*a2847172SGrzegorz Jaszczyk 		mss_pm_ipc_msg_send(target, PM_IPC_MSG_CPU_ON, 0);
411*a2847172SGrzegorz Jaszczyk 
412*a2847172SGrzegorz Jaszczyk 		/* trigger IPC message to MSS */
413*a2847172SGrzegorz Jaszczyk 		mss_pm_ipc_msg_trigger();
414*a2847172SGrzegorz Jaszczyk 
415*a2847172SGrzegorz Jaszczyk 		/* pm system synchronization */
416*a2847172SGrzegorz Jaszczyk 		bakery_lock_release(&pm_sys_lock);
417*a2847172SGrzegorz Jaszczyk 
418*a2847172SGrzegorz Jaszczyk 		/* trace message */
419*a2847172SGrzegorz Jaszczyk 		PM_TRACE(TRACE_PWR_DOMAIN_ON | target);
420*a2847172SGrzegorz Jaszczyk 	} else {
421*a2847172SGrzegorz Jaszczyk 		/* proprietary CPU ON exection flow */
422*a2847172SGrzegorz Jaszczyk 		plat_marvell_cpu_on(mpidr);
423*a2847172SGrzegorz Jaszczyk 	}
424*a2847172SGrzegorz Jaszczyk 
425*a2847172SGrzegorz Jaszczyk 	return 0;
426*a2847172SGrzegorz Jaszczyk }
427*a2847172SGrzegorz Jaszczyk 
428*a2847172SGrzegorz Jaszczyk /*****************************************************************************
429*a2847172SGrzegorz Jaszczyk  * A8K handler called to validate the entry point.
430*a2847172SGrzegorz Jaszczyk  *****************************************************************************
431*a2847172SGrzegorz Jaszczyk  */
432*a2847172SGrzegorz Jaszczyk static int a8k_validate_ns_entrypoint(uintptr_t entrypoint)
433*a2847172SGrzegorz Jaszczyk {
434*a2847172SGrzegorz Jaszczyk 	return PSCI_E_SUCCESS;
435*a2847172SGrzegorz Jaszczyk }
436*a2847172SGrzegorz Jaszczyk 
437*a2847172SGrzegorz Jaszczyk /*****************************************************************************
438*a2847172SGrzegorz Jaszczyk  * A8K handler called when a power domain is about to be turned off. The
439*a2847172SGrzegorz Jaszczyk  * target_state encodes the power state that each level should transition to.
440*a2847172SGrzegorz Jaszczyk  *****************************************************************************
441*a2847172SGrzegorz Jaszczyk  */
442*a2847172SGrzegorz Jaszczyk static void a8k_pwr_domain_off(const psci_power_state_t *target_state)
443*a2847172SGrzegorz Jaszczyk {
444*a2847172SGrzegorz Jaszczyk 	if (is_pm_fw_running()) {
445*a2847172SGrzegorz Jaszczyk 		unsigned int idx = plat_my_core_pos();
446*a2847172SGrzegorz Jaszczyk 
447*a2847172SGrzegorz Jaszczyk 		/* Prevent interrupts from spuriously waking up this cpu */
448*a2847172SGrzegorz Jaszczyk 		gicv2_cpuif_disable();
449*a2847172SGrzegorz Jaszczyk 
450*a2847172SGrzegorz Jaszczyk 		/* pm system synchronization - used to synchronize multiple
451*a2847172SGrzegorz Jaszczyk 		 * core access to MSS
452*a2847172SGrzegorz Jaszczyk 		 */
453*a2847172SGrzegorz Jaszczyk 		bakery_lock_get(&pm_sys_lock);
454*a2847172SGrzegorz Jaszczyk 
455*a2847172SGrzegorz Jaszczyk 		/* send CPU OFF IPC Message to MSS */
456*a2847172SGrzegorz Jaszczyk 		mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_OFF, target_state);
457*a2847172SGrzegorz Jaszczyk 
458*a2847172SGrzegorz Jaszczyk 		/* trigger IPC message to MSS */
459*a2847172SGrzegorz Jaszczyk 		mss_pm_ipc_msg_trigger();
460*a2847172SGrzegorz Jaszczyk 
461*a2847172SGrzegorz Jaszczyk 		/* pm system synchronization */
462*a2847172SGrzegorz Jaszczyk 		bakery_lock_release(&pm_sys_lock);
463*a2847172SGrzegorz Jaszczyk 
464*a2847172SGrzegorz Jaszczyk 		/* trace message */
465*a2847172SGrzegorz Jaszczyk 		PM_TRACE(TRACE_PWR_DOMAIN_OFF);
466*a2847172SGrzegorz Jaszczyk 	} else {
467*a2847172SGrzegorz Jaszczyk 		INFO("%s: is not supported without SCP\n", __func__);
468*a2847172SGrzegorz Jaszczyk 	}
469*a2847172SGrzegorz Jaszczyk }
470*a2847172SGrzegorz Jaszczyk 
471*a2847172SGrzegorz Jaszczyk /* Get PM config to power off the SoC */
472*a2847172SGrzegorz Jaszczyk void *plat_marvell_get_pm_cfg(void)
473*a2847172SGrzegorz Jaszczyk {
474*a2847172SGrzegorz Jaszczyk 	return NULL;
475*a2847172SGrzegorz Jaszczyk }
476*a2847172SGrzegorz Jaszczyk 
477*a2847172SGrzegorz Jaszczyk /*
478*a2847172SGrzegorz Jaszczyk  * This function should be called on restore from
479*a2847172SGrzegorz Jaszczyk  * "suspend to RAM" state when the execution flow
480*a2847172SGrzegorz Jaszczyk  * has to bypass BootROM image to RAM copy and speed up
481*a2847172SGrzegorz Jaszczyk  * the system recovery
482*a2847172SGrzegorz Jaszczyk  *
483*a2847172SGrzegorz Jaszczyk  */
484*a2847172SGrzegorz Jaszczyk static void plat_marvell_exit_bootrom(void)
485*a2847172SGrzegorz Jaszczyk {
486*a2847172SGrzegorz Jaszczyk 	marvell_exit_bootrom(PLAT_MARVELL_TRUSTED_ROM_BASE);
487*a2847172SGrzegorz Jaszczyk }
488*a2847172SGrzegorz Jaszczyk 
489*a2847172SGrzegorz Jaszczyk /*
490*a2847172SGrzegorz Jaszczyk  * Prepare for the power off of the system via GPIO
491*a2847172SGrzegorz Jaszczyk  */
492*a2847172SGrzegorz Jaszczyk static void plat_marvell_power_off_gpio(struct power_off_method *pm_cfg,
493*a2847172SGrzegorz Jaszczyk 					register_t *gpio_addr,
494*a2847172SGrzegorz Jaszczyk 					register_t *gpio_data)
495*a2847172SGrzegorz Jaszczyk {
496*a2847172SGrzegorz Jaszczyk 	unsigned int gpio;
497*a2847172SGrzegorz Jaszczyk 	unsigned int idx;
498*a2847172SGrzegorz Jaszczyk 	unsigned int shift;
499*a2847172SGrzegorz Jaszczyk 	unsigned int reg;
500*a2847172SGrzegorz Jaszczyk 	unsigned int addr;
501*a2847172SGrzegorz Jaszczyk 	gpio_info_t *info;
502*a2847172SGrzegorz Jaszczyk 	unsigned int tog_bits;
503*a2847172SGrzegorz Jaszczyk 
504*a2847172SGrzegorz Jaszczyk 	assert((pm_cfg->cfg.gpio.pin_count < PMIC_GPIO_MAX_NUMBER) &&
505*a2847172SGrzegorz Jaszczyk 	       (pm_cfg->cfg.gpio.step_count < PMIC_GPIO_MAX_TOGGLE_STEP));
506*a2847172SGrzegorz Jaszczyk 
507*a2847172SGrzegorz Jaszczyk 	/* Prepare GPIOs for PMIC */
508*a2847172SGrzegorz Jaszczyk 	for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) {
509*a2847172SGrzegorz Jaszczyk 		info = &pm_cfg->cfg.gpio.info[gpio];
510*a2847172SGrzegorz Jaszczyk 		/* Set PMIC GPIO to output mode */
511*a2847172SGrzegorz Jaszczyk 		reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT_EN(
512*a2847172SGrzegorz Jaszczyk 				   info->cp_index, info->gpio_index));
513*a2847172SGrzegorz Jaszczyk 		mmio_write_32(MVEBU_CP_GPIO_DATA_OUT_EN(
514*a2847172SGrzegorz Jaszczyk 			      info->cp_index, info->gpio_index),
515*a2847172SGrzegorz Jaszczyk 			      reg & ~MVEBU_GPIO_MASK(info->gpio_index));
516*a2847172SGrzegorz Jaszczyk 
517*a2847172SGrzegorz Jaszczyk 		/* Set the appropriate MPP to GPIO mode */
518*a2847172SGrzegorz Jaszczyk 		reg = mmio_read_32(MVEBU_PM_MPP_REGS(info->cp_index,
519*a2847172SGrzegorz Jaszczyk 						     info->gpio_index));
520*a2847172SGrzegorz Jaszczyk 		mmio_write_32(MVEBU_PM_MPP_REGS(info->cp_index,
521*a2847172SGrzegorz Jaszczyk 						info->gpio_index),
522*a2847172SGrzegorz Jaszczyk 			reg & ~MVEBU_MPP_MASK(info->gpio_index));
523*a2847172SGrzegorz Jaszczyk 	}
524*a2847172SGrzegorz Jaszczyk 
525*a2847172SGrzegorz Jaszczyk 	/* Wait for MPP & GPIO pre-configurations done */
526*a2847172SGrzegorz Jaszczyk 	mdelay(pm_cfg->cfg.gpio.delay_ms);
527*a2847172SGrzegorz Jaszczyk 
528*a2847172SGrzegorz Jaszczyk 	/* Toggle the GPIO values, and leave final step to be triggered
529*a2847172SGrzegorz Jaszczyk 	 * after  DDR self-refresh is enabled
530*a2847172SGrzegorz Jaszczyk 	 */
531*a2847172SGrzegorz Jaszczyk 	for (idx = 0; idx < pm_cfg->cfg.gpio.step_count; idx++) {
532*a2847172SGrzegorz Jaszczyk 		tog_bits = pm_cfg->cfg.gpio.seq[idx];
533*a2847172SGrzegorz Jaszczyk 
534*a2847172SGrzegorz Jaszczyk 		/* The GPIOs must be within same GPIO register,
535*a2847172SGrzegorz Jaszczyk 		 * thus could get the original value by first GPIO
536*a2847172SGrzegorz Jaszczyk 		 */
537*a2847172SGrzegorz Jaszczyk 		info = &pm_cfg->cfg.gpio.info[0];
538*a2847172SGrzegorz Jaszczyk 		reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT(
539*a2847172SGrzegorz Jaszczyk 				   info->cp_index, info->gpio_index));
540*a2847172SGrzegorz Jaszczyk 		addr = MVEBU_CP_GPIO_DATA_OUT(info->cp_index, info->gpio_index);
541*a2847172SGrzegorz Jaszczyk 
542*a2847172SGrzegorz Jaszczyk 		for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) {
543*a2847172SGrzegorz Jaszczyk 			shift = pm_cfg->cfg.gpio.info[gpio].gpio_index % 32;
544*a2847172SGrzegorz Jaszczyk 			if (GPIO_LOW == (tog_bits & (1 << gpio)))
545*a2847172SGrzegorz Jaszczyk 				reg &= ~(1 << shift);
546*a2847172SGrzegorz Jaszczyk 			else
547*a2847172SGrzegorz Jaszczyk 				reg |= (1 << shift);
548*a2847172SGrzegorz Jaszczyk 		}
549*a2847172SGrzegorz Jaszczyk 
550*a2847172SGrzegorz Jaszczyk 		/* Set the GPIO register, for last step just store
551*a2847172SGrzegorz Jaszczyk 		 * register address and values to system registers
552*a2847172SGrzegorz Jaszczyk 		 */
553*a2847172SGrzegorz Jaszczyk 		if (idx < pm_cfg->cfg.gpio.step_count - 1) {
554*a2847172SGrzegorz Jaszczyk 			mmio_write_32(MVEBU_CP_GPIO_DATA_OUT(
555*a2847172SGrzegorz Jaszczyk 				      info->cp_index, info->gpio_index), reg);
556*a2847172SGrzegorz Jaszczyk 			mdelay(pm_cfg->cfg.gpio.delay_ms);
557*a2847172SGrzegorz Jaszczyk 		} else {
558*a2847172SGrzegorz Jaszczyk 			/* Save GPIO register and address values for
559*a2847172SGrzegorz Jaszczyk 			 * finishing the power down operation later
560*a2847172SGrzegorz Jaszczyk 			 */
561*a2847172SGrzegorz Jaszczyk 			*gpio_addr = addr;
562*a2847172SGrzegorz Jaszczyk 			*gpio_data = reg;
563*a2847172SGrzegorz Jaszczyk 		}
564*a2847172SGrzegorz Jaszczyk 	}
565*a2847172SGrzegorz Jaszczyk }
566*a2847172SGrzegorz Jaszczyk 
567*a2847172SGrzegorz Jaszczyk /*
568*a2847172SGrzegorz Jaszczyk  * Prepare for the power off of the system
569*a2847172SGrzegorz Jaszczyk  */
570*a2847172SGrzegorz Jaszczyk static void plat_marvell_power_off_prepare(struct power_off_method *pm_cfg,
571*a2847172SGrzegorz Jaszczyk 					   register_t *addr, register_t *data)
572*a2847172SGrzegorz Jaszczyk {
573*a2847172SGrzegorz Jaszczyk 	switch (pm_cfg->type) {
574*a2847172SGrzegorz Jaszczyk 	case PMIC_GPIO:
575*a2847172SGrzegorz Jaszczyk 		plat_marvell_power_off_gpio(pm_cfg, addr, data);
576*a2847172SGrzegorz Jaszczyk 		break;
577*a2847172SGrzegorz Jaszczyk 	default:
578*a2847172SGrzegorz Jaszczyk 		break;
579*a2847172SGrzegorz Jaszczyk 	}
580*a2847172SGrzegorz Jaszczyk }
581*a2847172SGrzegorz Jaszczyk 
582*a2847172SGrzegorz Jaszczyk /*****************************************************************************
583*a2847172SGrzegorz Jaszczyk  * A8K handler called when a power domain is about to be suspended. The
584*a2847172SGrzegorz Jaszczyk  * target_state encodes the power state that each level should transition to.
585*a2847172SGrzegorz Jaszczyk  *****************************************************************************
586*a2847172SGrzegorz Jaszczyk  */
587*a2847172SGrzegorz Jaszczyk static void a8k_pwr_domain_suspend(const psci_power_state_t *target_state)
588*a2847172SGrzegorz Jaszczyk {
589*a2847172SGrzegorz Jaszczyk 	if (is_pm_fw_running()) {
590*a2847172SGrzegorz Jaszczyk 		unsigned int idx;
591*a2847172SGrzegorz Jaszczyk 
592*a2847172SGrzegorz Jaszczyk 		/* Prevent interrupts from spuriously waking up this cpu */
593*a2847172SGrzegorz Jaszczyk 		gicv2_cpuif_disable();
594*a2847172SGrzegorz Jaszczyk 
595*a2847172SGrzegorz Jaszczyk 		idx = plat_my_core_pos();
596*a2847172SGrzegorz Jaszczyk 
597*a2847172SGrzegorz Jaszczyk 		/* pm system synchronization - used to synchronize multiple
598*a2847172SGrzegorz Jaszczyk 		 * core access to MSS
599*a2847172SGrzegorz Jaszczyk 		 */
600*a2847172SGrzegorz Jaszczyk 		bakery_lock_get(&pm_sys_lock);
601*a2847172SGrzegorz Jaszczyk 
602*a2847172SGrzegorz Jaszczyk 		/* send CPU Suspend IPC Message to MSS */
603*a2847172SGrzegorz Jaszczyk 		mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_SUSPEND, target_state);
604*a2847172SGrzegorz Jaszczyk 
605*a2847172SGrzegorz Jaszczyk 		/* trigger IPC message to MSS */
606*a2847172SGrzegorz Jaszczyk 		mss_pm_ipc_msg_trigger();
607*a2847172SGrzegorz Jaszczyk 
608*a2847172SGrzegorz Jaszczyk 		/* pm system synchronization */
609*a2847172SGrzegorz Jaszczyk 		bakery_lock_release(&pm_sys_lock);
610*a2847172SGrzegorz Jaszczyk 
611*a2847172SGrzegorz Jaszczyk 		/* trace message */
612*a2847172SGrzegorz Jaszczyk 		PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND);
613*a2847172SGrzegorz Jaszczyk 	} else {
614*a2847172SGrzegorz Jaszczyk 		uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE;
615*a2847172SGrzegorz Jaszczyk 
616*a2847172SGrzegorz Jaszczyk 		INFO("Suspending to RAM\n");
617*a2847172SGrzegorz Jaszczyk 
618*a2847172SGrzegorz Jaszczyk 		marvell_console_runtime_end();
619*a2847172SGrzegorz Jaszczyk 
620*a2847172SGrzegorz Jaszczyk 		/* Prevent interrupts from spuriously waking up this cpu */
621*a2847172SGrzegorz Jaszczyk 		gicv2_cpuif_disable();
622*a2847172SGrzegorz Jaszczyk 
623*a2847172SGrzegorz Jaszczyk 		mailbox[MBOX_IDX_SUSPEND_MAGIC] = MVEBU_MAILBOX_SUSPEND_STATE;
624*a2847172SGrzegorz Jaszczyk 		mailbox[MBOX_IDX_ROM_EXIT_ADDR] = (uintptr_t)&plat_marvell_exit_bootrom;
625*a2847172SGrzegorz Jaszczyk 
626*a2847172SGrzegorz Jaszczyk #if PLAT_MARVELL_SHARED_RAM_CACHED
627*a2847172SGrzegorz Jaszczyk 		flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE +
628*a2847172SGrzegorz Jaszczyk 		MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t),
629*a2847172SGrzegorz Jaszczyk 		2 * sizeof(uintptr_t));
630*a2847172SGrzegorz Jaszczyk #endif
631*a2847172SGrzegorz Jaszczyk 		/* Flush and disable LLC before going off-power */
632*a2847172SGrzegorz Jaszczyk 		llc_disable(0);
633*a2847172SGrzegorz Jaszczyk 
634*a2847172SGrzegorz Jaszczyk 		isb();
635*a2847172SGrzegorz Jaszczyk 		/*
636*a2847172SGrzegorz Jaszczyk 		 * Do not halt here!
637*a2847172SGrzegorz Jaszczyk 		 * The function must return for allowing the caller function
638*a2847172SGrzegorz Jaszczyk 		 * psci_power_up_finish() to do the proper context saving and
639*a2847172SGrzegorz Jaszczyk 		 * to release the CPU lock.
640*a2847172SGrzegorz Jaszczyk 		 */
641*a2847172SGrzegorz Jaszczyk 	}
642*a2847172SGrzegorz Jaszczyk }
643*a2847172SGrzegorz Jaszczyk 
644*a2847172SGrzegorz Jaszczyk /*****************************************************************************
645*a2847172SGrzegorz Jaszczyk  * A8K handler called when a power domain has just been powered on after
646*a2847172SGrzegorz Jaszczyk  * being turned off earlier. The target_state encodes the low power state that
647*a2847172SGrzegorz Jaszczyk  * each level has woken up from.
648*a2847172SGrzegorz Jaszczyk  *****************************************************************************
649*a2847172SGrzegorz Jaszczyk  */
650*a2847172SGrzegorz Jaszczyk static void a8k_pwr_domain_on_finish(const psci_power_state_t *target_state)
651*a2847172SGrzegorz Jaszczyk {
652*a2847172SGrzegorz Jaszczyk 	/* arch specific configuration */
653*a2847172SGrzegorz Jaszczyk 	marvell_psci_arch_init(0);
654*a2847172SGrzegorz Jaszczyk 
655*a2847172SGrzegorz Jaszczyk 	/* Interrupt initialization */
656*a2847172SGrzegorz Jaszczyk 	gicv2_pcpu_distif_init();
657*a2847172SGrzegorz Jaszczyk 	gicv2_cpuif_enable();
658*a2847172SGrzegorz Jaszczyk 
659*a2847172SGrzegorz Jaszczyk 	if (is_pm_fw_running()) {
660*a2847172SGrzegorz Jaszczyk 		/* trace message */
661*a2847172SGrzegorz Jaszczyk 		PM_TRACE(TRACE_PWR_DOMAIN_ON_FINISH);
662*a2847172SGrzegorz Jaszczyk 	}
663*a2847172SGrzegorz Jaszczyk }
664*a2847172SGrzegorz Jaszczyk 
665*a2847172SGrzegorz Jaszczyk /*****************************************************************************
666*a2847172SGrzegorz Jaszczyk  * A8K handler called when a power domain has just been powered on after
667*a2847172SGrzegorz Jaszczyk  * having been suspended earlier. The target_state encodes the low power state
668*a2847172SGrzegorz Jaszczyk  * that each level has woken up from.
669*a2847172SGrzegorz Jaszczyk  * TODO: At the moment we reuse the on finisher and reinitialize the secure
670*a2847172SGrzegorz Jaszczyk  * context. Need to implement a separate suspend finisher.
671*a2847172SGrzegorz Jaszczyk  *****************************************************************************
672*a2847172SGrzegorz Jaszczyk  */
673*a2847172SGrzegorz Jaszczyk static void a8k_pwr_domain_suspend_finish(
674*a2847172SGrzegorz Jaszczyk 					const psci_power_state_t *target_state)
675*a2847172SGrzegorz Jaszczyk {
676*a2847172SGrzegorz Jaszczyk 	if (is_pm_fw_running()) {
677*a2847172SGrzegorz Jaszczyk 		/* arch specific configuration */
678*a2847172SGrzegorz Jaszczyk 		marvell_psci_arch_init(0);
679*a2847172SGrzegorz Jaszczyk 
680*a2847172SGrzegorz Jaszczyk 		/* Interrupt initialization */
681*a2847172SGrzegorz Jaszczyk 		gicv2_cpuif_enable();
682*a2847172SGrzegorz Jaszczyk 
683*a2847172SGrzegorz Jaszczyk 		/* trace message */
684*a2847172SGrzegorz Jaszczyk 		PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND_FINISH);
685*a2847172SGrzegorz Jaszczyk 	} else {
686*a2847172SGrzegorz Jaszczyk 		uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE;
687*a2847172SGrzegorz Jaszczyk 
688*a2847172SGrzegorz Jaszczyk 		/* Only primary CPU requres platform init */
689*a2847172SGrzegorz Jaszczyk 		if (!plat_my_core_pos()) {
690*a2847172SGrzegorz Jaszczyk 			/* Initialize the console to provide
691*a2847172SGrzegorz Jaszczyk 			 * early debug support
692*a2847172SGrzegorz Jaszczyk 			 */
693*a2847172SGrzegorz Jaszczyk 			marvell_console_runtime_init();
694*a2847172SGrzegorz Jaszczyk 
695*a2847172SGrzegorz Jaszczyk 			bl31_plat_arch_setup();
696*a2847172SGrzegorz Jaszczyk 			marvell_bl31_platform_setup();
697*a2847172SGrzegorz Jaszczyk 			/*
698*a2847172SGrzegorz Jaszczyk 			 * Remove suspend to RAM marker from the mailbox
699*a2847172SGrzegorz Jaszczyk 			 * for treating a regular reset as a cold boot
700*a2847172SGrzegorz Jaszczyk 			 */
701*a2847172SGrzegorz Jaszczyk 			mailbox[MBOX_IDX_SUSPEND_MAGIC] = 0;
702*a2847172SGrzegorz Jaszczyk 			mailbox[MBOX_IDX_ROM_EXIT_ADDR] = 0;
703*a2847172SGrzegorz Jaszczyk #if PLAT_MARVELL_SHARED_RAM_CACHED
704*a2847172SGrzegorz Jaszczyk 			flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE +
705*a2847172SGrzegorz Jaszczyk 			MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t),
706*a2847172SGrzegorz Jaszczyk 			2 * sizeof(uintptr_t));
707*a2847172SGrzegorz Jaszczyk #endif
708*a2847172SGrzegorz Jaszczyk 		}
709*a2847172SGrzegorz Jaszczyk 	}
710*a2847172SGrzegorz Jaszczyk }
711*a2847172SGrzegorz Jaszczyk 
712*a2847172SGrzegorz Jaszczyk /*****************************************************************************
713*a2847172SGrzegorz Jaszczyk  * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND`
714*a2847172SGrzegorz Jaszczyk  * call to get the `power_state` parameter. This allows the platform to encode
715*a2847172SGrzegorz Jaszczyk  * the appropriate State-ID field within the `power_state` parameter which can
716*a2847172SGrzegorz Jaszczyk  * be utilized in `pwr_domain_suspend()` to suspend to system affinity level.
717*a2847172SGrzegorz Jaszczyk  *****************************************************************************
718*a2847172SGrzegorz Jaszczyk  */
719*a2847172SGrzegorz Jaszczyk static void a8k_get_sys_suspend_power_state(psci_power_state_t *req_state)
720*a2847172SGrzegorz Jaszczyk {
721*a2847172SGrzegorz Jaszczyk 	/* lower affinities use PLAT_MAX_OFF_STATE */
722*a2847172SGrzegorz Jaszczyk 	for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
723*a2847172SGrzegorz Jaszczyk 		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
724*a2847172SGrzegorz Jaszczyk }
725*a2847172SGrzegorz Jaszczyk 
726*a2847172SGrzegorz Jaszczyk static void
727*a2847172SGrzegorz Jaszczyk __dead2 a8k_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
728*a2847172SGrzegorz Jaszczyk {
729*a2847172SGrzegorz Jaszczyk 	struct power_off_method *pm_cfg;
730*a2847172SGrzegorz Jaszczyk 	unsigned int srcmd;
731*a2847172SGrzegorz Jaszczyk 	unsigned int sdram_reg;
732*a2847172SGrzegorz Jaszczyk 	register_t gpio_data = 0, gpio_addr = 0;
733*a2847172SGrzegorz Jaszczyk 
734*a2847172SGrzegorz Jaszczyk 	if (is_pm_fw_running()) {
735*a2847172SGrzegorz Jaszczyk 		psci_power_down_wfi();
736*a2847172SGrzegorz Jaszczyk 		panic();
737*a2847172SGrzegorz Jaszczyk 	}
738*a2847172SGrzegorz Jaszczyk 
739*a2847172SGrzegorz Jaszczyk 	pm_cfg = (struct power_off_method *)plat_marvell_get_pm_cfg();
740*a2847172SGrzegorz Jaszczyk 
741*a2847172SGrzegorz Jaszczyk 	/* Prepare for power off */
742*a2847172SGrzegorz Jaszczyk 	plat_marvell_power_off_prepare(pm_cfg, &gpio_addr, &gpio_data);
743*a2847172SGrzegorz Jaszczyk 
744*a2847172SGrzegorz Jaszczyk 	/* First step to enable DDR self-refresh
745*a2847172SGrzegorz Jaszczyk 	 * to keep the data during suspend
746*a2847172SGrzegorz Jaszczyk 	 */
747*a2847172SGrzegorz Jaszczyk 	mmio_write_32(MVEBU_MC_PWR_CTRL_REG, 0x8C1);
748*a2847172SGrzegorz Jaszczyk 
749*a2847172SGrzegorz Jaszczyk 	/* Save DDR self-refresh second step register
750*a2847172SGrzegorz Jaszczyk 	 * and value to be issued later
751*a2847172SGrzegorz Jaszczyk 	 */
752*a2847172SGrzegorz Jaszczyk 	sdram_reg = MVEBU_USER_CMD_0_REG;
753*a2847172SGrzegorz Jaszczyk 	srcmd = mmio_read_32(sdram_reg);
754*a2847172SGrzegorz Jaszczyk 	srcmd &= ~(MVEBU_USER_CMD_CH0_MASK | MVEBU_USER_CMD_CS_MASK |
755*a2847172SGrzegorz Jaszczyk 		 MVEBU_USER_CMD_SR_MASK);
756*a2847172SGrzegorz Jaszczyk 	srcmd |= (MVEBU_USER_CMD_CH0_EN | MVEBU_USER_CMD_CS_ALL |
757*a2847172SGrzegorz Jaszczyk 		 MVEBU_USER_CMD_SR_ENTER);
758*a2847172SGrzegorz Jaszczyk 
759*a2847172SGrzegorz Jaszczyk 	/*
760*a2847172SGrzegorz Jaszczyk 	 * Wait for DRAM is done using registers access only.
761*a2847172SGrzegorz Jaszczyk 	 * At this stage any access to DRAM (procedure call) will
762*a2847172SGrzegorz Jaszczyk 	 * release it from the self-refresh mode
763*a2847172SGrzegorz Jaszczyk 	 */
764*a2847172SGrzegorz Jaszczyk 	__asm__ volatile (
765*a2847172SGrzegorz Jaszczyk 		/* Align to a cache line */
766*a2847172SGrzegorz Jaszczyk 		"	.balign 64\n\t"
767*a2847172SGrzegorz Jaszczyk 
768*a2847172SGrzegorz Jaszczyk 		/* Enter self refresh */
769*a2847172SGrzegorz Jaszczyk 		"	str %[srcmd], [%[sdram_reg]]\n\t"
770*a2847172SGrzegorz Jaszczyk 
771*a2847172SGrzegorz Jaszczyk 		/*
772*a2847172SGrzegorz Jaszczyk 		 * Wait 100 cycles for DDR to enter self refresh, by
773*a2847172SGrzegorz Jaszczyk 		 * doing 50 times two instructions.
774*a2847172SGrzegorz Jaszczyk 		 */
775*a2847172SGrzegorz Jaszczyk 		"	mov x1, #50\n\t"
776*a2847172SGrzegorz Jaszczyk 		"1:	subs x1, x1, #1\n\t"
777*a2847172SGrzegorz Jaszczyk 		"	bne 1b\n\t"
778*a2847172SGrzegorz Jaszczyk 
779*a2847172SGrzegorz Jaszczyk 		/* Issue the command to trigger the SoC power off */
780*a2847172SGrzegorz Jaszczyk 		"	str	%[gpio_data], [%[gpio_addr]]\n\t"
781*a2847172SGrzegorz Jaszczyk 
782*a2847172SGrzegorz Jaszczyk 		/* Trap the processor */
783*a2847172SGrzegorz Jaszczyk 		"	b .\n\t"
784*a2847172SGrzegorz Jaszczyk 		: : [srcmd] "r" (srcmd), [sdram_reg] "r" (sdram_reg),
785*a2847172SGrzegorz Jaszczyk 		    [gpio_addr] "r" (gpio_addr),  [gpio_data] "r" (gpio_data)
786*a2847172SGrzegorz Jaszczyk 		: "x1");
787*a2847172SGrzegorz Jaszczyk 
788*a2847172SGrzegorz Jaszczyk 	panic();
789*a2847172SGrzegorz Jaszczyk }
790*a2847172SGrzegorz Jaszczyk 
791*a2847172SGrzegorz Jaszczyk /*****************************************************************************
792*a2847172SGrzegorz Jaszczyk  * A8K handlers to shutdown/reboot the system
793*a2847172SGrzegorz Jaszczyk  *****************************************************************************
794*a2847172SGrzegorz Jaszczyk  */
795*a2847172SGrzegorz Jaszczyk 
796*a2847172SGrzegorz Jaszczyk /* Set a weak stub for platforms that don't configure system power off */
797*a2847172SGrzegorz Jaszczyk #pragma weak system_power_off
798*a2847172SGrzegorz Jaszczyk int system_power_off(void)
799*a2847172SGrzegorz Jaszczyk {
800*a2847172SGrzegorz Jaszczyk 	return 0;
801*a2847172SGrzegorz Jaszczyk }
802*a2847172SGrzegorz Jaszczyk 
803*a2847172SGrzegorz Jaszczyk static void __dead2 a8k_system_off(void)
804*a2847172SGrzegorz Jaszczyk {
805*a2847172SGrzegorz Jaszczyk 	/* Call the platform specific system power off function */
806*a2847172SGrzegorz Jaszczyk 	system_power_off();
807*a2847172SGrzegorz Jaszczyk 
808*a2847172SGrzegorz Jaszczyk 	/* board doesn't have a system off implementation */
809*a2847172SGrzegorz Jaszczyk 	ERROR("%s:  needs to be implemented\n", __func__);
810*a2847172SGrzegorz Jaszczyk 	panic();
811*a2847172SGrzegorz Jaszczyk }
812*a2847172SGrzegorz Jaszczyk 
813*a2847172SGrzegorz Jaszczyk void plat_marvell_system_reset(void)
814*a2847172SGrzegorz Jaszczyk {
815*a2847172SGrzegorz Jaszczyk 	mmio_write_32(MVEBU_RFU_BASE + MVEBU_RFU_GLOBL_SW_RST, 0x0);
816*a2847172SGrzegorz Jaszczyk }
817*a2847172SGrzegorz Jaszczyk 
818*a2847172SGrzegorz Jaszczyk static void __dead2 a8k_system_reset(void)
819*a2847172SGrzegorz Jaszczyk {
820*a2847172SGrzegorz Jaszczyk 	plat_marvell_system_reset();
821*a2847172SGrzegorz Jaszczyk 
822*a2847172SGrzegorz Jaszczyk 	/* we shouldn't get to this point */
823*a2847172SGrzegorz Jaszczyk 	panic();
824*a2847172SGrzegorz Jaszczyk }
825*a2847172SGrzegorz Jaszczyk 
826*a2847172SGrzegorz Jaszczyk /*****************************************************************************
827*a2847172SGrzegorz Jaszczyk  * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
828*a2847172SGrzegorz Jaszczyk  * platform layer will take care of registering the handlers with PSCI.
829*a2847172SGrzegorz Jaszczyk  *****************************************************************************
830*a2847172SGrzegorz Jaszczyk  */
831*a2847172SGrzegorz Jaszczyk const plat_psci_ops_t plat_arm_psci_pm_ops = {
832*a2847172SGrzegorz Jaszczyk 	.cpu_standby = a8k_cpu_standby,
833*a2847172SGrzegorz Jaszczyk 	.pwr_domain_on = a8k_pwr_domain_on,
834*a2847172SGrzegorz Jaszczyk 	.pwr_domain_off = a8k_pwr_domain_off,
835*a2847172SGrzegorz Jaszczyk 	.pwr_domain_suspend = a8k_pwr_domain_suspend,
836*a2847172SGrzegorz Jaszczyk 	.pwr_domain_on_finish = a8k_pwr_domain_on_finish,
837*a2847172SGrzegorz Jaszczyk 	.get_sys_suspend_power_state = a8k_get_sys_suspend_power_state,
838*a2847172SGrzegorz Jaszczyk 	.pwr_domain_suspend_finish = a8k_pwr_domain_suspend_finish,
839*a2847172SGrzegorz Jaszczyk 	.pwr_domain_pwr_down_wfi = a8k_pwr_domain_pwr_down_wfi,
840*a2847172SGrzegorz Jaszczyk 	.system_off = a8k_system_off,
841*a2847172SGrzegorz Jaszczyk 	.system_reset = a8k_system_reset,
842*a2847172SGrzegorz Jaszczyk 	.validate_power_state = a8k_validate_power_state,
843*a2847172SGrzegorz Jaszczyk 	.validate_ns_entrypoint = a8k_validate_ns_entrypoint
844*a2847172SGrzegorz Jaszczyk };
845