xref: /rk3399_ARM-atf/plat/imx/imx9/imx94/imx94_psci.c (revision 480e8dd9df291cc0e31695983fa6ff235e1671cd)
1*4249a4fbSJacky Bai /*
2*4249a4fbSJacky Bai  * Copyright 2024-2025 NXP
3*4249a4fbSJacky Bai  *
4*4249a4fbSJacky Bai  * SPDX-License-Identifier: BSD-3-Clause
5*4249a4fbSJacky Bai  */
6*4249a4fbSJacky Bai 
7*4249a4fbSJacky Bai #include <lib/psci/psci.h>
8*4249a4fbSJacky Bai #include <scmi_imx9.h>
9*4249a4fbSJacky Bai 
10*4249a4fbSJacky Bai #include <imx9_psci_common.h>
11*4249a4fbSJacky Bai #include <imx9_sys_sleep.h>
12*4249a4fbSJacky Bai #include <imx_scmi_client.h>
13*4249a4fbSJacky Bai #include <plat_imx8.h>
14*4249a4fbSJacky Bai 
15*4249a4fbSJacky Bai uint32_t mask_all[IMR_NUM] = {
16*4249a4fbSJacky Bai 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
17*4249a4fbSJacky Bai 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
18*4249a4fbSJacky Bai 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
19*4249a4fbSJacky Bai 	0xffffffff, 0xffffffff, 0xffffffff
20*4249a4fbSJacky Bai };
21*4249a4fbSJacky Bai 
22*4249a4fbSJacky Bai /*
23*4249a4fbSJacky Bai  * IRQ masks used to check if any of the below IRQ is
24*4249a4fbSJacky Bai  * enabled as the wakeup source:
25*4249a4fbSJacky Bai  * lpuart1: 21, flexcan2-5: 40, 42, 44, 46, usdhc1-3: 96, 97, 116
26*4249a4fbSJacky Bai  */
27*4249a4fbSJacky Bai uint32_t wakeup_irq_mask[IMR_NUM] = {
28*4249a4fbSJacky Bai 	0x600000, 0x5500, 0xFFC0, 0x100003, 0x0, 0x0, 0x0, 0x0,
29*4249a4fbSJacky Bai 	0x0, 0x0, 0x0, 0x80
30*4249a4fbSJacky Bai };
31*4249a4fbSJacky Bai 
32*4249a4fbSJacky Bai struct per_hsk_cfg per_hsk_cfg[] = {
33*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_CAN2, 40U },
34*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_CAN3, 42U },
35*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_CAN4, 44U },
36*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_CAN5, 46U },
37*4249a4fbSJacky Bai 
38*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART1, 21U },
39*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART2, 22U },
40*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART3, 74U },
41*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART4, 75U },
42*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART5, 76U },
43*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART6, 77U },
44*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART7, 78U },
45*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART8, 79U },
46*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART9, 80U },
47*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART10, 81U },
48*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART11, 82U },
49*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_LPUART12, 83U },
50*4249a4fbSJacky Bai 
51*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_GPIO2, 54U },
52*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_GPIO3, 56U },
53*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_GPIO4, 58U },
54*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_GPIO5, 60U },
55*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_GPIO6, 62U },
56*4249a4fbSJacky Bai 	{ CPU_PER_LPI_IDX_GPIO7, 64U },
57*4249a4fbSJacky Bai };
58*4249a4fbSJacky Bai 
59*4249a4fbSJacky Bai struct gpio_ctx gpios[GPIO_NUM] = {
60*4249a4fbSJacky Bai 	GPIO_CTX(GPIO2_BASE, 32U),
61*4249a4fbSJacky Bai 	GPIO_CTX(GPIO3_BASE, 26U),
62*4249a4fbSJacky Bai 	GPIO_CTX(GPIO4_BASE, 32U),
63*4249a4fbSJacky Bai 	GPIO_CTX(GPIO5_BASE, 32U),
64*4249a4fbSJacky Bai 	GPIO_CTX(GPIO6_BASE, 32U),
65*4249a4fbSJacky Bai 	GPIO_CTX(GPIO7_BASE, 22U),
66*4249a4fbSJacky Bai };
67*4249a4fbSJacky Bai 
68*4249a4fbSJacky Bai struct wdog_ctx wdogs[WDOG_NUM] = {
69*4249a4fbSJacky Bai 	{ WDOG3_BASE },
70*4249a4fbSJacky Bai 	{ WDOG4_BASE },
71*4249a4fbSJacky Bai };
72*4249a4fbSJacky Bai 
73*4249a4fbSJacky Bai static const plat_psci_ops_t imx_plat_psci_ops = {
74*4249a4fbSJacky Bai 	.validate_ns_entrypoint = imx_validate_ns_entrypoint,
75*4249a4fbSJacky Bai 	.validate_power_state = imx_validate_power_state,
76*4249a4fbSJacky Bai 	.pwr_domain_on = imx_pwr_domain_on,
77*4249a4fbSJacky Bai 	.pwr_domain_off = imx_pwr_domain_off,
78*4249a4fbSJacky Bai 	.pwr_domain_on_finish = imx_pwr_domain_on_finish,
79*4249a4fbSJacky Bai 	.pwr_domain_suspend = imx_pwr_domain_suspend,
80*4249a4fbSJacky Bai 	.pwr_domain_suspend_finish = imx_pwr_domain_suspend_finish,
81*4249a4fbSJacky Bai 	.get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
82*4249a4fbSJacky Bai 	.pwr_domain_pwr_down = imx_pwr_domain_pwr_down,
83*4249a4fbSJacky Bai 	.system_reset = imx_system_reset,
84*4249a4fbSJacky Bai 	.system_off = imx_system_off,
85*4249a4fbSJacky Bai };
86*4249a4fbSJacky Bai 
87*4249a4fbSJacky Bai /* Export the platform specific psci ops */
plat_setup_psci_ops(uintptr_t sec_entrypoint,const plat_psci_ops_t ** psci_ops)88*4249a4fbSJacky Bai int plat_setup_psci_ops(uintptr_t sec_entrypoint,
89*4249a4fbSJacky Bai 			const plat_psci_ops_t **psci_ops)
90*4249a4fbSJacky Bai {
91*4249a4fbSJacky Bai 	uint32_t mask = DEBUG_WAKEUP_MASK | EVENT_WAKEUP_MASK;
92*4249a4fbSJacky Bai 
93*4249a4fbSJacky Bai 	/* sec_entrypoint is used for warm reset */
94*4249a4fbSJacky Bai 	secure_entrypoint = sec_entrypoint;
95*4249a4fbSJacky Bai 	imx_set_cpu_boot_entry(0U, secure_entrypoint, SCMI_CPU_VEC_FLAGS_BOOT);
96*4249a4fbSJacky Bai 
97*4249a4fbSJacky Bai 	/*
98*4249a4fbSJacky Bai 	 * Set NON-IRQ wakeup mask for both last core and cluster.
99*4249a4fbSJacky Bai 	 * Disable wakeup on DEBUG_WAKEUP
100*4249a4fbSJacky Bai 	 */
101*4249a4fbSJacky Bai 	scmi_core_nonIrq_wake_set(imx9_scmi_handle, IMX9_SCMI_CPU_A55C0, 0U, 1U, mask);
102*4249a4fbSJacky Bai 	scmi_core_nonIrq_wake_set(imx9_scmi_handle, IMX9_SCMI_CPU_A55P, 0U, 1U, mask);
103*4249a4fbSJacky Bai 
104*4249a4fbSJacky Bai 	/*
105*4249a4fbSJacky Bai 	 * Setup A55 Cluster state for Cpuidle.
106*4249a4fbSJacky Bai 	 */
107*4249a4fbSJacky Bai 	struct scmi_lpm_config cpu_lpm_cfg[] = {
108*4249a4fbSJacky Bai 		{
109*4249a4fbSJacky Bai 			SCMI_PWR_MIX_SLICE_IDX_A55P,
110*4249a4fbSJacky Bai 			SCMI_CPU_PD_LPM_ON_RUN,
111*4249a4fbSJacky Bai 			BIT_32(SCMI_PWR_MEM_SLICE_IDX_A55L3)
112*4249a4fbSJacky Bai 		},
113*4249a4fbSJacky Bai 		{
114*4249a4fbSJacky Bai 			SCMI_PWR_MIX_SLICE_IDX_NOC,
115*4249a4fbSJacky Bai 			SCMI_CPU_PD_LPM_ON_ALWAYS,
116*4249a4fbSJacky Bai 			0U
117*4249a4fbSJacky Bai 		},
118*4249a4fbSJacky Bai 		{
119*4249a4fbSJacky Bai 			SCMI_PWR_MIX_SLICE_IDX_WAKEUP,
120*4249a4fbSJacky Bai 			SCMI_CPU_PD_LPM_ON_ALWAYS,
121*4249a4fbSJacky Bai 			0U
122*4249a4fbSJacky Bai 		}
123*4249a4fbSJacky Bai 	};
124*4249a4fbSJacky Bai 
125*4249a4fbSJacky Bai 	/* Set the default LPM state for suspend/hotplug */
126*4249a4fbSJacky Bai 	scmi_core_lpm_mode_set(imx9_scmi_handle,
127*4249a4fbSJacky Bai 			       IMX9_SCMI_CPU_A55P,
128*4249a4fbSJacky Bai 			       ARRAY_SIZE(cpu_lpm_cfg),
129*4249a4fbSJacky Bai 			       cpu_lpm_cfg);
130*4249a4fbSJacky Bai 
131*4249a4fbSJacky Bai 	/* Set the LPM state for cpuidle for A55C0 (boot core) */
132*4249a4fbSJacky Bai 	cpu_lpm_cfg[0].power_domain = SCMI_PWR_MIX_SLICE_IDX_A55C0;
133*4249a4fbSJacky Bai 	cpu_lpm_cfg[0].lpmsetting = SCMI_CPU_PD_LPM_ON_RUN;
134*4249a4fbSJacky Bai 	cpu_lpm_cfg[0].retentionmask = 0U;
135*4249a4fbSJacky Bai 	scmi_core_lpm_mode_set(imx9_scmi_handle, IMX9_SCMI_CPU_A55C0,
136*4249a4fbSJacky Bai 				1U, cpu_lpm_cfg);
137*4249a4fbSJacky Bai 
138*4249a4fbSJacky Bai 	/*
139*4249a4fbSJacky Bai 	 * Set core/custer to GIC wakeup source since NOCMIX is not
140*4249a4fbSJacky Bai 	 * powered down, config the target mode to WAIT
141*4249a4fbSJacky Bai 	 */
142*4249a4fbSJacky Bai 	scmi_core_set_sleep_mode(imx9_scmi_handle, IMX9_SCMI_CPU_A55C0,
143*4249a4fbSJacky Bai 				 SCMI_GIC_WAKEUP, SCMI_CPU_SLEEP_WAIT);
144*4249a4fbSJacky Bai 
145*4249a4fbSJacky Bai 	scmi_core_set_sleep_mode(imx9_scmi_handle, IMX9_SCMI_CPU_A55P,
146*4249a4fbSJacky Bai 				 SCMI_GIC_WAKEUP, SCMI_CPU_SLEEP_WAIT);
147*4249a4fbSJacky Bai 
148*4249a4fbSJacky Bai 	/* Enable the wdog3 per handshake */
149*4249a4fbSJacky Bai 	struct scmi_per_lpm_config per_lpm[1] = {
150*4249a4fbSJacky Bai 		{ CPU_PER_LPI_IDX_WDOG3, SCMI_CPU_PD_LPM_ON_RUN_WAIT_STOP },
151*4249a4fbSJacky Bai 	};
152*4249a4fbSJacky Bai 
153*4249a4fbSJacky Bai 	scmi_per_lpm_mode_set(imx9_scmi_handle, IMX9_SCMI_CPU_A55P,
154*4249a4fbSJacky Bai 			      1U, per_lpm);
155*4249a4fbSJacky Bai 
156*4249a4fbSJacky Bai 	*psci_ops = &imx_plat_psci_ops;
157*4249a4fbSJacky Bai 
158*4249a4fbSJacky Bai 	return 0;
159*4249a4fbSJacky Bai }
160