xref: /rk3399_ARM-atf/plat/imx/imx8ulp/imx8ulp_psci.c (revision e1d5c3c8f435424394367e2ff19240b1b8a3073c)
1 /*
2  * Copyright 2021-2024 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdbool.h>
8 
9 #include <arch.h>
10 #include <arch_helpers.h>
11 #include <common/debug.h>
12 #include <drivers/arm/gicv3.h>
13 #include <lib/mmio.h>
14 #include <lib/psci/psci.h>
15 
16 #include <plat_imx8.h>
17 #include <upower_api.h>
18 
19 extern void cgc1_save(void);
20 extern void cgc1_restore(void);
21 extern void imx_apd_ctx_save(unsigned int cpu);
22 extern void imx_apd_ctx_restore(unsigned int cpu);
23 extern void usb_wakeup_enable(bool enable);
24 extern void upower_wait_resp(void);
25 extern bool is_lpav_owned_by_apd(void);
26 extern void apd_io_pad_off(void);
27 extern int upower_pmic_i2c_read(uint32_t reg_addr, uint32_t *reg_val);
28 
29 static uintptr_t secure_entrypoint;
30 
31 #define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0])
32 #define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1])
33 #define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
34 
35 #define RVBARADDRx(c)		(IMX_SIM1_BASE + 0x5c + 0x4 * (c))
36 #define WKPUx(c)		(IMX_SIM1_BASE + 0x3c + 0x4 * (c))
37 #define AD_COREx_LPMODE(c)	(IMX_CMC1_BASE + 0x50 + 0x4 * (c))
38 
39 #define PMIC_CFG(v, m, msk)		\
40 	{				\
41 		.volt = (v),		\
42 		.mode = (m),		\
43 		.mode_msk = (msk),	\
44 	}
45 
46 #define PAD_CFG(c, r, t)		\
47 	{				\
48 		.pad_close = (c),	\
49 		.pad_reset = (r),	\
50 		.pad_tqsleep = (t)	\
51 	}
52 
53 #define BIAS_CFG(m, n, p, mbias)	\
54 	{				\
55 		.dombias_cfg = {	\
56 			.mode = (m),	\
57 			.rbbn = (n),	\
58 			.rbbp = (p),	\
59 		},			\
60 		.membias_cfg = {mbias},	\
61 	}
62 
63 #define SWT_BOARD(swt_on, msk)	\
64 	{			\
65 		.on = (swt_on),	\
66 		.mask = (msk),	\
67 	}
68 
69 #define SWT_MEM(a, p, m)	\
70 	{			\
71 		.array = (a),	\
72 		.perif = (p),	\
73 		.mask = (m),	\
74 	}
75 
76 static int imx_pwr_set_cpu_entry(unsigned int cpu, unsigned int entry)
77 {
78 	mmio_write_32(RVBARADDRx(cpu), entry);
79 
80 	/* set update bit */
81 	mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(24 + cpu));
82 	/* wait for ack */
83 	while (!(mmio_read_32(IMX_SIM1_BASE + 0x8) & BIT_32(26 + cpu))) {
84 	}
85 
86 	/* clear update bit */
87 	mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) & ~BIT_32(24 + cpu));
88 	/* clear ack bit */
89 	mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(26 + cpu));
90 
91 	return 0;
92 }
93 
94 static volatile uint32_t cgc1_nicclk;
95 int imx_pwr_domain_on(u_register_t mpidr)
96 {
97 	unsigned int cpu = MPIDR_AFFLVL0_VAL(mpidr);
98 
99 	imx_pwr_set_cpu_entry(cpu, secure_entrypoint);
100 
101 	/* slow down the APD NIC bus clock */
102 	cgc1_nicclk = mmio_read_32(IMX_CGC1_BASE + 0x34);
103 	mmio_clrbits_32(IMX_CGC1_BASE + 0x34, GENMASK_32(29, 28));
104 
105 	mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f);
106 	mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0);
107 
108 	/* enable wku wakeup for idle */
109 	mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0xffffffff);
110 
111 	return PSCI_E_SUCCESS;
112 }
113 
114 void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
115 {
116 	imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
117 	plat_gic_pcpu_init();
118 	plat_gic_cpuif_enable();
119 
120 	/* set APD NIC back to orignally setting */
121 	mmio_write_32(IMX_CGC1_BASE + 0x34, cgc1_nicclk);
122 }
123 
124 int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
125 {
126 	return PSCI_E_SUCCESS;
127 }
128 
129 void imx_pwr_domain_off(const psci_power_state_t *target_state)
130 {
131 	unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
132 
133 	plat_gic_cpuif_disable();
134 
135 	/* disable wakeup */
136 	mmio_write_32(WKPUx(cpu), 0);
137 
138 	/* set core power mode to PD */
139 	mmio_write_32(AD_COREx_LPMODE(cpu), 0x3);
140 }
141 
142 /* APD power mode config */
143 ps_apd_pwr_mode_cfgs_t apd_pwr_mode_cfgs = {
144 	[DPD_PWR_MODE] = {
145 		.swt_board_offs = 0x180,
146 		.swt_mem_offs = 0x188,
147 		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
148 		.pad_cfg = PAD_CFG(0x0, 0xc, 0x01e80a02),
149 		.bias_cfg = BIAS_CFG(0x0, 0x2, 0x2, 0x0),
150 	},
151 
152 	/* PD */
153 	[PD_PWR_MODE] = {
154 		.swt_board_offs = 0x170,
155 		.swt_mem_offs = 0x178,
156 		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
157 		.pad_cfg = PAD_CFG(0x0, 0xc, 0x01e80a00),
158 		.bias_cfg = BIAS_CFG(0x0, 0x2, 0x2, 0x0),
159 	},
160 
161 	[ADMA_PWR_MODE] = {
162 		.swt_board_offs = 0x120,
163 		.swt_mem_offs = 0x128,
164 		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
165 		.pad_cfg = PAD_CFG(0x0, 0x0, 0x0deb7a00),
166 		.bias_cfg = BIAS_CFG(0x2, 0x2, 0x2, 0x0),
167 	},
168 
169 	[ACT_PWR_MODE] = {
170 		.swt_board_offs = 0x110,
171 		.swt_mem_offs = 0x118,
172 		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
173 		.pad_cfg = PAD_CFG(0x0, 0x0, 0x0deb7a00),
174 		.bias_cfg = BIAS_CFG(0x2, 0x2, 0x2, 0x0),
175 	},
176 };
177 
178 /* APD power switch config */
179 ps_apd_swt_cfgs_t apd_swt_cfgs = {
180 	[DPD_PWR_MODE] = {
181 		.swt_board[0] = SWT_BOARD(0x0, 0x1fffc),
182 		.swt_mem[0] = SWT_MEM(0x0, 0x0, 0x1ffff),
183 		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0),
184 	},
185 
186 	[PD_PWR_MODE] = {
187 		.swt_board[0] = SWT_BOARD(0x0, 0x00001fffc),
188 		.swt_mem[0] = SWT_MEM(0x00010c00, 0x0, 0x1ffff),
189 		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003f0000, 0x0),
190 	},
191 
192 	[ADMA_PWR_MODE] = {
193 		.swt_board[0] = SWT_BOARD(0x15f74, 0x15f74),
194 		.swt_mem[0] = SWT_MEM(0x0001fffd, 0x0001fffd, 0x1ffff),
195 		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0),
196 	},
197 
198 	[ACT_PWR_MODE] = {
199 		.swt_board[0] = SWT_BOARD(0x15f74, 0x15f74),
200 		.swt_mem[0] = SWT_MEM(0x0001fffd, 0x0001fffd, 0x1ffff),
201 		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0),
202 	},
203 };
204 
205 /* PMIC config for power down, LDO1 should be OFF */
206 ps_apd_pmic_reg_data_cfgs_t pd_pmic_reg_cfgs = {
207 	[0] = {
208 		.tag = PMIC_REG_VALID_TAG,
209 		.power_mode = PD_PWR_MODE,
210 		.i2c_addr = 0x30,
211 		.i2c_data = 0x9c,
212 	},
213 	[1] = {
214 		.tag = PMIC_REG_VALID_TAG,
215 		.power_mode = PD_PWR_MODE,
216 		.i2c_addr = 0x22,
217 		.i2c_data = 0xb,
218 	},
219 	[2] = {
220 		.tag = PMIC_REG_VALID_TAG,
221 		.power_mode = ACT_PWR_MODE,
222 		.i2c_addr = 0x30,
223 		.i2c_data = 0x9d,
224 	},
225 	[3] = {
226 		.tag = PMIC_REG_VALID_TAG,
227 		.power_mode = ACT_PWR_MODE,
228 		.i2c_addr = 0x22,
229 		.i2c_data = 0x28,
230 	},
231 };
232 
233 /* PMIC config for deep power down, BUCK3 should be OFF */
234 ps_apd_pmic_reg_data_cfgs_t dpd_pmic_reg_cfgs = {
235 	[0] = {
236 		.tag = PMIC_REG_VALID_TAG,
237 		.power_mode = DPD_PWR_MODE,
238 		.i2c_addr = 0x21,
239 		.i2c_data = 0x78,
240 	},
241 	[1] = {
242 		.tag = PMIC_REG_VALID_TAG,
243 		.power_mode = DPD_PWR_MODE,
244 		.i2c_addr = 0x30,
245 		.i2c_data = 0x9c,
246 	},
247 	[2] = {
248 		.tag = PMIC_REG_VALID_TAG,
249 		.power_mode = ACT_PWR_MODE,
250 		.i2c_addr = 0x21,
251 		.i2c_data = 0x79,
252 	},
253 	[3] = {
254 		.tag = PMIC_REG_VALID_TAG,
255 		.power_mode = ACT_PWR_MODE,
256 		.i2c_addr = 0x30,
257 		.i2c_data = 0x9d,
258 	},
259 };
260 
261 struct ps_pwr_mode_cfg_t *pwr_sys_cfg = (struct ps_pwr_mode_cfg_t *)UPWR_DRAM_SHARED_BASE_ADDR;
262 
263 void imx_set_pwr_mode_cfg(abs_pwr_mode_t mode)
264 {
265 	uint32_t volt;
266 
267 	if (mode >= NUM_PWR_MODES) {
268 		return;
269 	}
270 
271 	/* apd power mode config */
272 	memcpy(&pwr_sys_cfg->ps_apd_pwr_mode_cfg[mode], &apd_pwr_mode_cfgs[mode],
273 		 sizeof(struct ps_apd_pwr_mode_cfg_t));
274 
275 	/* apd power switch config */
276 	memcpy(&pwr_sys_cfg->ps_apd_swt_cfg[mode], &apd_swt_cfgs[mode], sizeof(swt_config_t));
277 
278 	/*
279 	 * BUCK3 & LDO1 can only be shutdown when LPAV is owned by APD side
280 	 * otherwise RTD side is responsible to control them in low power mode.
281 	 */
282 	if (is_lpav_owned_by_apd()) {
283 		/* power off the BUCK3 in DPD mode */
284 		if (mode == DPD_PWR_MODE) {
285 			memcpy(&pwr_sys_cfg->ps_apd_pmic_reg_data_cfg, &dpd_pmic_reg_cfgs,
286 				 sizeof(ps_apd_pmic_reg_data_cfgs_t));
287 		/* LDO1 should be power off in PD mode */
288 		} else if (mode == PD_PWR_MODE) {
289 			/* overwrite the buck3 voltage setting in active mode */
290 			upower_pmic_i2c_read(0x22, &volt);
291 			pd_pmic_reg_cfgs[3].i2c_data = volt;
292 			memcpy(&pwr_sys_cfg->ps_apd_pmic_reg_data_cfg, &pd_pmic_reg_cfgs,
293 				 sizeof(ps_apd_pmic_reg_data_cfgs_t));
294 		}
295 	}
296 }
297 
298 void imx_domain_suspend(const psci_power_state_t *target_state)
299 {
300 	unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
301 
302 	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
303 		plat_gic_cpuif_disable();
304 		imx_pwr_set_cpu_entry(cpu, secure_entrypoint);
305 		/* core put into power down */
306 		mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x3);
307 		/* FIXME config wakeup interrupt in WKPU */
308 		mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x7fffffe3);
309 	} else {
310 		/* for core standby/retention mode */
311 		mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x1);
312 		mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x7fffffe3);
313 		dsb();
314 		write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
315 		isb();
316 	}
317 
318 	if (is_local_state_retn(CLUSTER_PWR_STATE(target_state))) {
319 		/*
320 		 * just for sleep mode for now, need to update to
321 		 * support more modes, same for suspend finish call back.
322 		 */
323 		mmio_write_32(IMX_CMC1_BASE + 0x10, 0x1);
324 		mmio_write_32(IMX_CMC1_BASE + 0x20, 0x1);
325 
326 	} else if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
327 		/*
328 		 * for cluster off state, put cluster into power down mode,
329 		 * config the cluster clock to be off.
330 		 */
331 		mmio_write_32(IMX_CMC1_BASE + 0x10, 0x7);
332 		mmio_write_32(IMX_CMC1_BASE + 0x20, 0xf);
333 	}
334 
335 	if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
336 		/*
337 		 * low power mode config info used by upower
338 		 * to do low power mode transition.
339 		 */
340 		imx_set_pwr_mode_cfg(ADMA_PWR_MODE);
341 		imx_set_pwr_mode_cfg(ACT_PWR_MODE);
342 		imx_set_pwr_mode_cfg(PD_PWR_MODE);
343 
344 		/* clear the upower wakeup */
345 		upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL);
346 		upower_wait_resp();
347 
348 		/* enable the USB wakeup */
349 		usb_wakeup_enable(true);
350 
351 		/* config the WUU to enabled the wakeup source */
352 		mmio_write_32(IMX_PCC3_BASE + 0x98, 0xc0800000);
353 
354 		/* !!! clear all the pad wakeup pending event */
355 		mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff);
356 
357 		/* enable upower usb phy wakeup by default */
358 		mmio_setbits_32(IMX_WUU1_BASE + 0x18, BIT(4) | BIT(1) | BIT(0));
359 
360 		/* enabled all pad wakeup by default */
361 		mmio_write_32(IMX_WUU1_BASE + 0x8, 0xffffffff);
362 
363 		/* save the AD domain context before entering PD mode */
364 		imx_apd_ctx_save(cpu);
365 	}
366 }
367 
368 extern void imx8ulp_init_scmi_server(void);
369 void imx_domain_suspend_finish(const psci_power_state_t *target_state)
370 {
371 	unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
372 
373 	if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
374 		/* restore the ap domain context */
375 		imx_apd_ctx_restore(cpu);
376 
377 		/* clear the upower wakeup */
378 		upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL);
379 		upower_wait_resp();
380 
381 		/* disable all pad wakeup */
382 		mmio_write_32(IMX_WUU1_BASE + 0x8, 0x0);
383 
384 		/* clear all the pad wakeup pending event */
385 		mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff);
386 
387 		/*
388 		 * disable the usb wakeup after resume to make sure the pending
389 		 * usb wakeup in WUU can be cleared successfully, otherwise,
390 		 * APD will resume failed in next PD mode.
391 		 */
392 		usb_wakeup_enable(false);
393 
394 		/* re-init the SCMI channel */
395 		imx8ulp_init_scmi_server();
396 	}
397 
398 	/* clear cluster's LPM setting. */
399 	mmio_write_32(IMX_CMC1_BASE + 0x20, 0x0);
400 	mmio_write_32(IMX_CMC1_BASE + 0x10, 0x0);
401 
402 	/* clear core's LPM setting */
403 	mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x0);
404 	mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x0);
405 
406 	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
407 		imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
408 		plat_gic_cpuif_enable();
409 	} else {
410 		dsb();
411 		write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT));
412 		isb();
413 	}
414 }
415 
416 void __dead2 imx8ulp_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
417 {
418 	while (1) {
419 		wfi();
420 	}
421 }
422 
423 void __dead2 imx8ulp_system_reset(void)
424 {
425 	imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
426 
427 	/* Write invalid command to WDOG CNT to trigger reset */
428 	mmio_write_32(IMX_WDOG3_BASE + 0x4, 0x12345678);
429 
430 	while (true) {
431 		wfi();
432 	}
433 }
434 
435 int imx_validate_power_state(unsigned int power_state,
436 			 psci_power_state_t *req_state)
437 {
438 	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
439 	int pwr_type = psci_get_pstate_type(power_state);
440 
441 	if (pwr_lvl > PLAT_MAX_PWR_LVL) {
442 		return PSCI_E_INVALID_PARAMS;
443 	}
444 
445 	if (pwr_type == PSTATE_TYPE_STANDBY) {
446 		CORE_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
447 		CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
448 	}
449 
450 	/* No power down state support */
451 	if (pwr_type == PSTATE_TYPE_POWERDOWN) {
452 		return PSCI_E_INVALID_PARAMS;
453 	}
454 
455 	return PSCI_E_SUCCESS;
456 }
457 
458 void imx_get_sys_suspend_power_state(psci_power_state_t *req_state)
459 {
460 	unsigned int i;
461 
462 	for (i = IMX_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++) {
463 		req_state->pwr_domain_state[i] = PLAT_POWER_DOWN_OFF_STATE;
464 	}
465 }
466 
467 void __dead2 imx_system_off(void)
468 {
469 	unsigned int i;
470 
471 	/* config the all the core into OFF mode and IRQ masked. */
472 	for (i = 0U; i < PLATFORM_CORE_COUNT; i++) {
473 		/* disable wakeup from wkpu */
474 		mmio_write_32(WKPUx(i), 0x0);
475 
476 		/* reset the core reset entry to 0x1000 */
477 		imx_pwr_set_cpu_entry(i, 0x1000);
478 
479 		/* config the core power mode to off */
480 		mmio_write_32(AD_COREx_LPMODE(i), 0x3);
481 	}
482 
483 	plat_gic_cpuif_disable();
484 
485 	/* power off all the pad */
486 	apd_io_pad_off();
487 
488 	/* Config the power mode info for entering DPD mode and ACT mode */
489 	imx_set_pwr_mode_cfg(ADMA_PWR_MODE);
490 	imx_set_pwr_mode_cfg(ACT_PWR_MODE);
491 	imx_set_pwr_mode_cfg(DPD_PWR_MODE);
492 
493 	/* Set the APD domain into DPD mode */
494 	mmio_write_32(IMX_CMC1_BASE + 0x10, 0x7);
495 	mmio_write_32(IMX_CMC1_BASE + 0x20, 0x1f);
496 
497 	/* make sure no pending upower wakeup */
498 	upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL);
499 	upower_wait_resp();
500 
501 	/* enable the upower wakeup from wuu, act as APD boot up method  */
502 	mmio_write_32(IMX_PCC3_BASE + 0x98, 0xc0800000);
503 	mmio_setbits_32(IMX_WUU1_BASE + 0x18, BIT(4));
504 
505 	/* make sure no pad wakeup event is pending */
506 	mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff);
507 
508 	wfi();
509 
510 	ERROR("power off failed.\n");
511 	panic();
512 }
513 
514 static const plat_psci_ops_t imx_plat_psci_ops = {
515 	.pwr_domain_on = imx_pwr_domain_on,
516 	.pwr_domain_on_finish = imx_pwr_domain_on_finish,
517 	.validate_ns_entrypoint = imx_validate_ns_entrypoint,
518 	.system_off = imx_system_off,
519 	.system_reset = imx8ulp_system_reset,
520 	.pwr_domain_off = imx_pwr_domain_off,
521 	.pwr_domain_suspend = imx_domain_suspend,
522 	.pwr_domain_suspend_finish = imx_domain_suspend_finish,
523 	.get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
524 	.validate_power_state = imx_validate_power_state,
525 	.pwr_domain_pwr_down_wfi = imx8ulp_pwr_domain_pwr_down_wfi,
526 };
527 
528 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
529 			const plat_psci_ops_t **psci_ops)
530 {
531 	secure_entrypoint = sec_entrypoint;
532 	imx_pwr_set_cpu_entry(0, sec_entrypoint);
533 	*psci_ops = &imx_plat_psci_ops;
534 
535 	mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f);
536 	mmio_write_32(IMX_SIM1_BASE + 0x3c, 0xffffffff);
537 
538 	return 0;
539 }
540