1 /*
2  * Copyright 2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <stdbool.h>
7 
8 #include <platform_def.h>
9 #include <pwr_ctrl.h>
10 
11 /*Do the necessary GPC, SRC, BLK_CTRL_S init */
pwr_sys_init(void)12 void pwr_sys_init(void)
13 {
14 	unsigned int cpu;
15 
16 	/*
17 	 * Assigned A55 cluster to 3, m33 to 2, A55 CORE0 & CORE1 to 0/1.
18 	 * domain0/1 only used for trigger LPM of themselves. A55 cluster & M33's
19 	 * domain assignment should be align with the TRDC DID.
20 	 */
21 	gpc_assign_domains(0x3102);
22 
23 	/* CA55 core0/1 config */
24 	for (cpu = CPU_A55C0; cpu <= CPU_A55_PLAT; cpu++) {
25 		/* clear the cpu sleep hold */
26 		gpc_clear_cpu_sleep_hold(cpu);
27 		/* use gic wakeup source by default */
28 		gpc_select_wakeup_gic(cpu);
29 		/*
30 		 * Ignore A55 core0/1's LPM trigger for system sleep.
31 		 * normally, for A55 side, only the A55 cluster(plat)
32 		 * domain will be used to trigger the system wide low
33 		 * power mode transition.
34 		 */
35 		if (cpu != CPU_A55_PLAT) {
36 			gpc_force_cpu_suspend(cpu);
37 		}
38 	}
39 
40 	/* boot core(A55C0) */
41 	src_mem_lpm_en(SRC_A55P0_MEM, MEM_OFF);
42 	/* For A55 core, only need to be on in RUN mode */
43 	src_mix_set_lpm(SRC_A55C0, 0x0, CM_MODE_WAIT);
44 	/* whitelist: 0x1 for domain 0 only */
45 	src_authen_config(SRC_A55C0, 0x1, 0x1);
46 
47 	/* A55 cluster */
48 	gpc_select_wakeup_gic(CPU_A55_PLAT);
49 	gpc_clear_cpu_sleep_hold(CPU_A55_PLAT);
50 
51 	/* SCU MEM must be OFF when A55 PLAT OFF */
52 	src_mem_lpm_en(SRC_A55_SCU_MEM, MEM_OFF);
53 	/* L3 memory in retention by default */
54 	src_mem_lpm_en(SRC_A55_L3_MEM, MEM_RETN);
55 
56 	src_mix_set_lpm(SRC_A55P, 0x3, 0x1);
57 	/* whitelist: 0x8 for domain 3 only */
58 	src_authen_config(SRC_A55P, 0x8, 0x1);
59 
60 	/* enable the HW LP handshake between S401 & A55 cluster */
61 	mmio_setbits_32(BLK_CTRL_S_BASE + HW_LP_HANDHSK, BIT(5));
62 }
63 
64