2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
10 #include <platform_def.h>
17 void imx_set_cpu_secure_entry(unsigned int core_id
, uintptr_t sec_entrypoint
)
21 temp_base
= (uint64_t) sec_entrypoint
;
24 mmio_write_32(IMX_SRC_BASE
+ SRC_GPR1_OFFSET
+ (core_id
<< 3),
25 ((uint32_t)(temp_base
>> 22) & 0xffff));
26 mmio_write_32(IMX_SRC_BASE
+ SRC_GPR1_OFFSET
+ (core_id
<< 3) + 4,
27 ((uint32_t)temp_base
& 0x003fffff));
30 /* use wfi power down the core */
31 void imx_set_cpu_pwr_off(unsigned int core_id
)
33 /* enable the wfi power down of the core */
34 mmio_setbits_32(IMX_GPC_BASE
+ LPCR_A53_AD
, COREx_WFI_PDN(core_id
) |
35 (1 << (core_id
+ 20)));
36 /* assert the pcg pcr bit of the core */
37 mmio_setbits_32(IMX_GPC_BASE
+ COREx_PGC_PCR(core_id
), 0x1);
40 /* use the sw method to power up the core */
41 void imx_set_cpu_pwr_on(unsigned int core_id
)
43 /* clear the wfi power down bit of the core */
44 mmio_clrbits_32(IMX_GPC_BASE
+ LPCR_A53_AD
, COREx_WFI_PDN(core_id
));
45 /* assert the ncpuporeset */
46 mmio_clrbits_32(IMX_SRC_BASE
+ SRC_A53RCR1
, (1 << core_id
));
47 /* assert the pcg pcr bit of the core */
48 mmio_setbits_32(IMX_GPC_BASE
+ COREx_PGC_PCR(core_id
), 0x1);
49 /* sw power up the core */
50 mmio_setbits_32(IMX_GPC_BASE
+ CPU_PGC_UP_TRG
, (1 << core_id
));
52 /* wait for the power up finished */
53 while ((mmio_read_32(IMX_GPC_BASE
+ CPU_PGC_UP_TRG
) & (1 << core_id
)) != 0)
56 /* deassert the pcg pcr bit of the core */
57 mmio_clrbits_32(IMX_GPC_BASE
+ COREx_PGC_PCR(core_id
), 0x1);
58 /* deassert the ncpuporeset */
59 mmio_setbits_32(IMX_SRC_BASE
+ SRC_A53RCR1
, (1 << core_id
));
62 /* if out of lpm, we need to do reverse steps */
63 void imx_set_cpu_lpm(unsigned int core_id
, bool pdn
)
66 /* enable the core WFI PDN & IRQ PUP */
67 mmio_setbits_32(IMX_GPC_BASE
+ LPCR_A53_AD
, COREx_WFI_PDN(core_id
) |
68 (1 << (core_id
+ 20)) | COREx_IRQ_WUP(core_id
));
69 /* assert the pcg pcr bit of the core */
70 mmio_setbits_32(IMX_GPC_BASE
+ COREx_PGC_PCR(core_id
), 0x1);
72 /* disable CORE WFI PDN & IRQ PUP */
73 mmio_clrbits_32(IMX_GPC_BASE
+ LPCR_A53_AD
, COREx_WFI_PDN(core_id
) |
74 COREx_IRQ_WUP(core_id
));
75 /* deassert the pcg pcr bit of the core */
76 mmio_setbits_32(IMX_GPC_BASE
+ COREx_PGC_PCR(core_id
), 0x1);
80 void imx_set_sys_wakeup(unsigned int last_core
, bool pdn
)
85 void imx_pup_pdn_slot_config(int last_core
, bool pdn
)
88 /* SLOT0 for A53 PLAT power down */
89 mmio_setbits_32(IMX_GPC_BASE
+ SLTx_CFG(0), SLT_PLAT_PDN
);
90 /* SLOT1 for A53 PLAT power up */
91 mmio_setbits_32(IMX_GPC_BASE
+ SLTx_CFG(1), SLT_PLAT_PUP
);
92 /* SLOT2 for A53 primary core power up */
93 mmio_setbits_32(IMX_GPC_BASE
+ SLTx_CFG(2), SLT_COREx_PUP(last_core
));
94 /* ACK setting: PLAT ACK for PDN, CORE ACK for PUP */
95 mmio_clrsetbits_32(IMX_GPC_BASE
+ PGC_ACK_SEL_A53
, 0xFFFFFFFF,
96 A53_PLAT_PDN_ACK
| A53_PLAT_PUP_ACK
);
98 mmio_clrbits_32(IMX_GPC_BASE
+ SLTx_CFG(0), 0xFFFFFFFF);
99 mmio_clrbits_32(IMX_GPC_BASE
+ SLTx_CFG(1), 0xFFFFFFFF);
100 mmio_clrbits_32(IMX_GPC_BASE
+ SLTx_CFG(2), 0xFFFFFFFF);
101 mmio_clrsetbits_32(IMX_GPC_BASE
+ PGC_ACK_SEL_A53
, 0xFFFFFFFF,
102 A53_DUMMY_PDN_ACK
| A53_DUMMY_PUP_ACK
);
106 void imx_set_cluster_standby(bool retention
)
109 * Enable BIT 6 of A53 AD register to make sure system
110 * don't enter LPM mode.
113 mmio_setbits_32(IMX_GPC_BASE
+ LPCR_A53_AD
, (1 << 6));
115 mmio_clrbits_32(IMX_GPC_BASE
+ LPCR_A53_AD
, (1 << 6));
118 void imx_set_cluster_powerdown(unsigned int last_core
, uint8_t power_state
)
122 if (is_local_state_off(power_state
)) {
123 val
= mmio_read_32(IMX_GPC_BASE
+ LPCR_A53_BSC
);
124 val
|= A53_LPM_STOP
; /* enable C0-C1's STOP mode */
125 val
&= ~CPU_CLOCK_ON_LPM
; /* disable CPU clock in LPM mode */
126 mmio_write_32(IMX_GPC_BASE
+ LPCR_A53_BSC
, val
);
128 /* enable C2-3's STOP mode */
129 mmio_setbits_32(IMX_GPC_BASE
+ LPCR_A53_BSC2
, A53_LPM_STOP
);
131 /* enable PLAT/SCU power down */
132 val
= mmio_read_32(IMX_GPC_BASE
+ LPCR_A53_AD
);
133 val
&= ~EN_L2_WFI_PDN
;
134 val
|= L2PGE
| EN_PLAT_PDN
;
135 val
&= ~COREx_IRQ_WUP(last_core
); /* disable IRQ PUP for last core */
136 val
|= COREx_LPM_PUP(last_core
); /* enable LPM PUP for last core */
137 mmio_write_32(IMX_GPC_BASE
+ LPCR_A53_AD
, val
);
139 imx_pup_pdn_slot_config(last_core
, true);
141 /* enable PLAT PGC */
142 mmio_setbits_32(IMX_GPC_BASE
+ A53_PLAT_PGC
, 0x1);
145 mmio_clrbits_32(IMX_GPC_BASE
+ A53_PLAT_PGC
, 0x1);
147 /* clear the slot and ack for cluster power down */
148 imx_pup_pdn_slot_config(last_core
, false);
150 val
= mmio_read_32(IMX_GPC_BASE
+ LPCR_A53_BSC
);
151 val
&= ~A53_LPM_MASK
; /* clear the C0~1 LPM */
152 val
|= CPU_CLOCK_ON_LPM
; /* disable cpu clock in LPM */
153 mmio_write_32(IMX_GPC_BASE
+ LPCR_A53_BSC
, val
);
155 /* set A53 LPM to RUN mode */
156 mmio_clrbits_32(IMX_GPC_BASE
+ LPCR_A53_BSC2
, A53_LPM_MASK
);
158 /* clear PLAT/SCU power down */
159 val
= mmio_read_32(IMX_GPC_BASE
+ LPCR_A53_AD
);
160 val
|= EN_L2_WFI_PDN
;
161 val
&= ~(L2PGE
| EN_PLAT_PDN
);
162 val
&= ~COREx_LPM_PUP(last_core
); /* disable C0's LPM PUP */
163 mmio_write_32(IMX_GPC_BASE
+ LPCR_A53_AD
, val
);
167 /* config the system level power mode */
168 void imx_set_sys_lpm(bool retention
)
172 /* set system DSM mode SLPCR(0x14) */
173 val
= mmio_read_32(IMX_GPC_BASE
+ SLPCR
);
174 val
&= ~(SLPCR_EN_DSM
| SLPCR_VSTBY
| SLPCR_SBYOS
|
175 SLPCR_BYPASS_PMIC_READY
| SLPCR_RBC_EN
);
178 val
|= (SLPCR_EN_DSM
| SLPCR_VSTBY
| SLPCR_SBYOS
|
179 SLPCR_BYPASS_PMIC_READY
| SLPCR_RBC_EN
|
180 SLPCR_A53_FASTWUP_STOP_MODE
);
182 mmio_write_32(IMX_GPC_BASE
+ SLPCR
, val
);
185 void imx_set_rbc_count(void)
187 mmio_setbits_32(IMX_GPC_BASE
+ SLPCR
, 0x3f << SLPCR_RBC_COUNT_SHIFT
);
190 void imx_clear_rbc_count(void)
192 mmio_clrbits_32(IMX_GPC_BASE
+ SLPCR
, 0x3f << SLPCR_RBC_COUNT_SHIFT
);
195 void imx_gpc_init(void)
199 /* mask all the interrupt by default */
200 /* Due to the hardware design requirement, need to make
201 * sure GPR interrupt(#32) is unmasked during RUN mode to
202 * avoid entering DSM mode by mistake.
204 for (i
= 0; i
< 4; i
++) {
205 mmio_write_32(IMX_GPC_BASE
+ IMR1_CORE0_A53
+ i
* 4, 0xFFFFFFFE);
206 mmio_write_32(IMX_GPC_BASE
+ IMR1_CORE1_A53
+ i
* 4, 0xFFFFFFFE);
207 mmio_write_32(IMX_GPC_BASE
+ IMR1_CORE2_A53
+ i
* 4, 0xFFFFFFFE);
208 mmio_write_32(IMX_GPC_BASE
+ IMR1_CORE3_A53
+ i
* 4, 0xFFFFFFFE);
209 mmio_write_32(IMX_GPC_BASE
+ IMR1_CORE0_M4
+ i
* 4, ~0x0);
212 /* use external IRQs to wakeup C0~C3 from LPM */
213 val
= mmio_read_32(IMX_GPC_BASE
+ LPCR_A53_BSC
);
214 val
|= IRQ_SRC_A53_WUP
;
215 /* clear the MASTER0 LPM handshake */
216 val
&= ~MASTER0_LPM_HSK
;
217 mmio_write_32(IMX_GPC_BASE
+ LPCR_A53_BSC
, val
);
219 /* mask M4 DSM trigger if M4 is NOT enabled */
220 mmio_setbits_32(IMX_GPC_BASE
+ LPCR_M4
, DSM_MODE_MASK
);
222 /* set all mix/PU in A53 domain */
223 mmio_write_32(IMX_GPC_BASE
+ PGC_CPU_0_1_MAPPING
, 0xfffd);
225 /* set SCU timming */
226 mmio_write_32(IMX_GPC_BASE
+ PGC_SCU_TIMING
,
227 (0x59 << 10) | 0x5B | (0x2 << 20));
229 /* set DUMMY PDN/PUP ACK by default for A53 domain */
230 mmio_write_32(IMX_GPC_BASE
+ PGC_ACK_SEL_A53
, A53_DUMMY_PUP_ACK
|
233 /* disable DSM mode by default */
234 mmio_clrbits_32(IMX_GPC_BASE
+ SLPCR
, DSM_MODE_MASK
);
237 * USB PHY power up needs to make sure RESET bit in SRC is clear,
238 * otherwise, the PU power up bit in GPC will NOT self-cleared.
239 * only need to do it once.
241 mmio_clrbits_32(IMX_SRC_BASE
+ SRC_OTG1PHY_SCR
, 0x1);
242 mmio_clrbits_32(IMX_SRC_BASE
+ SRC_OTG2PHY_SCR
, 0x1);