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