xref: /rk3399_ARM-atf/plat/imx/imx8m/imx8mm/gpc.c (revision 44dea5444b087acd758b1c8370999be635e17e43)
1179f82a2SJacky Bai /*
2*44dea544SJacky Bai  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
3179f82a2SJacky Bai  *
4179f82a2SJacky Bai  * SPDX-License-Identifier: BSD-3-Clause
5179f82a2SJacky Bai  */
6179f82a2SJacky Bai 
7179f82a2SJacky Bai #include <stdlib.h>
8179f82a2SJacky Bai #include <stdint.h>
9179f82a2SJacky Bai #include <stdbool.h>
10179f82a2SJacky Bai 
11179f82a2SJacky Bai #include <common/debug.h>
12179f82a2SJacky Bai #include <drivers/delay_timer.h>
13179f82a2SJacky Bai #include <lib/mmio.h>
14179f82a2SJacky Bai #include <lib/psci/psci.h>
15179f82a2SJacky Bai #include <lib/smccc.h>
16179f82a2SJacky Bai #include <platform_def.h>
17179f82a2SJacky Bai #include <services/std_svc.h>
18179f82a2SJacky Bai 
19179f82a2SJacky Bai #include <gpc.h>
20179f82a2SJacky Bai #include <imx_sip_svc.h>
21179f82a2SJacky Bai 
22*44dea544SJacky Bai #define MIPI_PWR_REQ		BIT(0)
23*44dea544SJacky Bai #define PCIE_PWR_REQ		BIT(1)
24*44dea544SJacky Bai #define OTG1_PWR_REQ		BIT(2)
25*44dea544SJacky Bai #define OTG2_PWR_REQ		BIT(3)
26*44dea544SJacky Bai #define HSIOMIX_PWR_REQ		BIT(4)
27*44dea544SJacky Bai #define GPU2D_PWR_REQ		BIT(6)
28*44dea544SJacky Bai #define GPUMIX_PWR_REQ		BIT(7)
29*44dea544SJacky Bai #define VPUMIX_PWR_REQ		BIT(8)
30*44dea544SJacky Bai #define GPU3D_PWR_REQ		BIT(9)
31*44dea544SJacky Bai #define DISPMIX_PWR_REQ		BIT(10)
32*44dea544SJacky Bai #define VPU_G1_PWR_REQ		BIT(11)
33*44dea544SJacky Bai #define VPU_G2_PWR_REQ		BIT(12)
34*44dea544SJacky Bai #define VPU_H1_PWR_REQ		BIT(13)
35*44dea544SJacky Bai 
36*44dea544SJacky Bai #define HSIOMIX_ADB400_SYNC	(0x3 << 5)
37*44dea544SJacky Bai #define DISPMIX_ADB400_SYNC	BIT(7)
38*44dea544SJacky Bai #define VPUMIX_ADB400_SYNC	BIT(8)
39*44dea544SJacky Bai #define GPU3D_ADB400_SYNC	BIT(9)
40*44dea544SJacky Bai #define GPU2D_ADB400_SYNC	BIT(10)
41*44dea544SJacky Bai #define GPUMIX_ADB400_SYNC	BIT(11)
42*44dea544SJacky Bai #define HSIOMIX_ADB400_ACK	(0x3 << 23)
43*44dea544SJacky Bai #define DISPMIX_ADB400_ACK	BIT(25)
44*44dea544SJacky Bai #define VPUMIX_ADB400_ACK	BIT(26)
45*44dea544SJacky Bai #define GPU3D_ADB400_ACK	BIT(27)
46*44dea544SJacky Bai #define GPU2D_ADB400_ACK	BIT(28)
47*44dea544SJacky Bai #define GPUMIX_ADB400_ACK	BIT(29)
48*44dea544SJacky Bai 
49*44dea544SJacky Bai #define MIPI_PGC		0xc00
50*44dea544SJacky Bai #define PCIE_PGC		0xc40
51*44dea544SJacky Bai #define OTG1_PGC		0xc80
52*44dea544SJacky Bai #define OTG2_PGC		0xcc0
53*44dea544SJacky Bai #define HSIOMIX_PGC	        0xd00
54*44dea544SJacky Bai #define GPU2D_PGC		0xd80
55*44dea544SJacky Bai #define GPUMIX_PGC		0xdc0
56*44dea544SJacky Bai #define VPUMIX_PGC		0xe00
57*44dea544SJacky Bai #define GPU3D_PGC		0xe40
58*44dea544SJacky Bai #define DISPMIX_PGC		0xe80
59*44dea544SJacky Bai #define VPU_G1_PGC		0xec0
60*44dea544SJacky Bai #define VPU_G2_PGC		0xf00
61*44dea544SJacky Bai #define VPU_H1_PGC		0xf40
62*44dea544SJacky Bai 
63*44dea544SJacky Bai enum pu_domain_id {
64*44dea544SJacky Bai 	HSIOMIX,
65*44dea544SJacky Bai 	PCIE,
66*44dea544SJacky Bai 	OTG1,
67*44dea544SJacky Bai 	OTG2,
68*44dea544SJacky Bai 	GPUMIX,
69*44dea544SJacky Bai 	VPUMIX,
70*44dea544SJacky Bai 	VPU_G1,
71*44dea544SJacky Bai 	VPU_G2,
72*44dea544SJacky Bai 	VPU_H1,
73*44dea544SJacky Bai 	DISPMIX,
74*44dea544SJacky Bai 	MIPI,
75*44dea544SJacky Bai 	/* below two domain only for ATF internal use */
76*44dea544SJacky Bai 	GPU2D,
77*44dea544SJacky Bai 	GPU3D,
78*44dea544SJacky Bai 	MAX_DOMAINS,
79*44dea544SJacky Bai };
80*44dea544SJacky Bai 
81*44dea544SJacky Bai /* PU domain */
82*44dea544SJacky Bai static struct imx_pwr_domain pu_domains[] = {
83*44dea544SJacky Bai 	IMX_MIX_DOMAIN(HSIOMIX, false),
84*44dea544SJacky Bai 	IMX_PD_DOMAIN(PCIE, false),
85*44dea544SJacky Bai 	IMX_PD_DOMAIN(OTG1, true),
86*44dea544SJacky Bai 	IMX_PD_DOMAIN(OTG2, true),
87*44dea544SJacky Bai 	IMX_MIX_DOMAIN(GPUMIX, false),
88*44dea544SJacky Bai 	IMX_MIX_DOMAIN(VPUMIX, false),
89*44dea544SJacky Bai 	IMX_PD_DOMAIN(VPU_G1, false),
90*44dea544SJacky Bai 	IMX_PD_DOMAIN(VPU_G2, false),
91*44dea544SJacky Bai 	IMX_PD_DOMAIN(VPU_H1, false),
92*44dea544SJacky Bai 	IMX_MIX_DOMAIN(DISPMIX, false),
93*44dea544SJacky Bai 	IMX_PD_DOMAIN(MIPI, false),
94*44dea544SJacky Bai 	/* below two domain only for ATF internal use */
95*44dea544SJacky Bai 	IMX_MIX_DOMAIN(GPU2D, false),
96*44dea544SJacky Bai 	IMX_MIX_DOMAIN(GPU3D, false),
97*44dea544SJacky Bai };
98*44dea544SJacky Bai 
99*44dea544SJacky Bai static unsigned int pu_domain_status;
100*44dea544SJacky Bai 
101*44dea544SJacky Bai #define GPU_RCR		0x40
102*44dea544SJacky Bai #define VPU_RCR		0x44
103*44dea544SJacky Bai 
104*44dea544SJacky Bai #define VPU_CTL_BASE		0x38330000
105*44dea544SJacky Bai #define BLK_SFT_RSTN_CSR	0x0
106*44dea544SJacky Bai #define H1_SFT_RSTN		BIT(2)
107*44dea544SJacky Bai #define G1_SFT_RSTN		BIT(1)
108*44dea544SJacky Bai #define G2_SFT_RSTN		BIT(0)
109*44dea544SJacky Bai 
110*44dea544SJacky Bai #define DISP_CTL_BASE		0x32e28000
111*44dea544SJacky Bai 
112*44dea544SJacky Bai void vpu_sft_reset_assert(uint32_t domain_id)
113*44dea544SJacky Bai {
114*44dea544SJacky Bai 	uint32_t val;
115*44dea544SJacky Bai 
116*44dea544SJacky Bai 	val = mmio_read_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR);
117*44dea544SJacky Bai 
118*44dea544SJacky Bai 	switch (domain_id) {
119*44dea544SJacky Bai 	case VPU_G1:
120*44dea544SJacky Bai 		val &= ~G1_SFT_RSTN;
121*44dea544SJacky Bai 		mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
122*44dea544SJacky Bai 		break;
123*44dea544SJacky Bai 	case VPU_G2:
124*44dea544SJacky Bai 		val &= ~G2_SFT_RSTN;
125*44dea544SJacky Bai 		mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
126*44dea544SJacky Bai 		break;
127*44dea544SJacky Bai 	case VPU_H1:
128*44dea544SJacky Bai 		val &= ~H1_SFT_RSTN;
129*44dea544SJacky Bai 		mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
130*44dea544SJacky Bai 		break;
131*44dea544SJacky Bai 	default:
132*44dea544SJacky Bai 		break;
133*44dea544SJacky Bai 	}
134*44dea544SJacky Bai }
135*44dea544SJacky Bai 
136*44dea544SJacky Bai void vpu_sft_reset_deassert(uint32_t domain_id)
137*44dea544SJacky Bai {
138*44dea544SJacky Bai 	uint32_t val;
139*44dea544SJacky Bai 
140*44dea544SJacky Bai 	val = mmio_read_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR);
141*44dea544SJacky Bai 
142*44dea544SJacky Bai 	switch (domain_id) {
143*44dea544SJacky Bai 	case VPU_G1:
144*44dea544SJacky Bai 		val |= G1_SFT_RSTN;
145*44dea544SJacky Bai 		mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
146*44dea544SJacky Bai 		break;
147*44dea544SJacky Bai 	case VPU_G2:
148*44dea544SJacky Bai 		val |= G2_SFT_RSTN;
149*44dea544SJacky Bai 		mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
150*44dea544SJacky Bai 		break;
151*44dea544SJacky Bai 	case VPU_H1:
152*44dea544SJacky Bai 		val |= H1_SFT_RSTN;
153*44dea544SJacky Bai 		mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
154*44dea544SJacky Bai 		break;
155*44dea544SJacky Bai 	default:
156*44dea544SJacky Bai 		break;
157*44dea544SJacky Bai 	}
158*44dea544SJacky Bai }
159*44dea544SJacky Bai 
160*44dea544SJacky Bai void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
161*44dea544SJacky Bai {
162*44dea544SJacky Bai 	if (domain_id >= MAX_DOMAINS) {
163*44dea544SJacky Bai 		return;
164*44dea544SJacky Bai 	}
165*44dea544SJacky Bai 
166*44dea544SJacky Bai 	struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id];
167*44dea544SJacky Bai 
168*44dea544SJacky Bai 	if (on) {
169*44dea544SJacky Bai 		pu_domain_status |= (1 << domain_id);
170*44dea544SJacky Bai 
171*44dea544SJacky Bai 		if (domain_id == VPU_G1 || domain_id == VPU_G2 ||
172*44dea544SJacky Bai 		    domain_id == VPU_H1) {
173*44dea544SJacky Bai 			vpu_sft_reset_assert(domain_id);
174*44dea544SJacky Bai 		}
175*44dea544SJacky Bai 
176*44dea544SJacky Bai 		/* HSIOMIX has no PU bit, so skip for it */
177*44dea544SJacky Bai 		if (domain_id != HSIOMIX) {
178*44dea544SJacky Bai 			/* clear the PGC bit */
179*44dea544SJacky Bai 			mmio_clrbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
180*44dea544SJacky Bai 
181*44dea544SJacky Bai 			/* power up the domain */
182*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, pwr_domain->pwr_req);
183*44dea544SJacky Bai 
184*44dea544SJacky Bai 			/* wait for power request done */
185*44dea544SJacky Bai 			while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & pwr_domain->pwr_req) {
186*44dea544SJacky Bai 				;
187*44dea544SJacky Bai 			}
188*44dea544SJacky Bai 		}
189*44dea544SJacky Bai 
190*44dea544SJacky Bai 		if (domain_id == VPU_G1 || domain_id == VPU_G2 ||
191*44dea544SJacky Bai 		    domain_id == VPU_H1) {
192*44dea544SJacky Bai 			vpu_sft_reset_deassert(domain_id);
193*44dea544SJacky Bai 			/* dealy for a while to make sure reset done */
194*44dea544SJacky Bai 			udelay(100);
195*44dea544SJacky Bai 		}
196*44dea544SJacky Bai 
197*44dea544SJacky Bai 		if (domain_id == GPUMIX) {
198*44dea544SJacky Bai 			/* assert reset */
199*44dea544SJacky Bai 			mmio_write_32(IMX_SRC_BASE + GPU_RCR, 0x1);
200*44dea544SJacky Bai 
201*44dea544SJacky Bai 			/* power up GPU2D */
202*44dea544SJacky Bai 			mmio_clrbits_32(IMX_GPC_BASE + GPU2D_PGC, 0x1);
203*44dea544SJacky Bai 
204*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, GPU2D_PWR_REQ);
205*44dea544SJacky Bai 
206*44dea544SJacky Bai 			/* wait for power request done */
207*44dea544SJacky Bai 			while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & GPU2D_PWR_REQ) {
208*44dea544SJacky Bai 				;
209*44dea544SJacky Bai 			}
210*44dea544SJacky Bai 
211*44dea544SJacky Bai 			udelay(1);
212*44dea544SJacky Bai 
213*44dea544SJacky Bai 			/* power up GPU3D */
214*44dea544SJacky Bai 			mmio_clrbits_32(IMX_GPC_BASE + GPU3D_PGC, 0x1);
215*44dea544SJacky Bai 
216*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, GPU3D_PWR_REQ);
217*44dea544SJacky Bai 
218*44dea544SJacky Bai 			/* wait for power request done */
219*44dea544SJacky Bai 			while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & GPU3D_PWR_REQ) {
220*44dea544SJacky Bai 				;
221*44dea544SJacky Bai 			}
222*44dea544SJacky Bai 
223*44dea544SJacky Bai 			udelay(10);
224*44dea544SJacky Bai 			/* release the gpumix reset */
225*44dea544SJacky Bai 			mmio_write_32(IMX_SRC_BASE + GPU_RCR, 0x0);
226*44dea544SJacky Bai 			udelay(10);
227*44dea544SJacky Bai 		}
228*44dea544SJacky Bai 
229*44dea544SJacky Bai 		/* vpu sft clock enable */
230*44dea544SJacky Bai 		if (domain_id == VPUMIX) {
231*44dea544SJacky Bai 			mmio_write_32(IMX_SRC_BASE + VPU_RCR, 0x1);
232*44dea544SJacky Bai 			udelay(5);
233*44dea544SJacky Bai 			mmio_write_32(IMX_SRC_BASE + VPU_RCR, 0x0);
234*44dea544SJacky Bai 			udelay(5);
235*44dea544SJacky Bai 
236*44dea544SJacky Bai 			/* enable all clock */
237*44dea544SJacky Bai 			mmio_write_32(VPU_CTL_BASE + 0x4, 0x7);
238*44dea544SJacky Bai 		}
239*44dea544SJacky Bai 
240*44dea544SJacky Bai 		if (domain_id == DISPMIX) {
241*44dea544SJacky Bai 			/* special setting for DISPMIX */
242*44dea544SJacky Bai 			mmio_write_32(DISP_CTL_BASE + 0x4, 0x1fff);
243*44dea544SJacky Bai 			mmio_write_32(DISP_CTL_BASE, 0x7f);
244*44dea544SJacky Bai 			mmio_write_32(DISP_CTL_BASE + 0x8, 0x30000);
245*44dea544SJacky Bai 		}
246*44dea544SJacky Bai 
247*44dea544SJacky Bai 		/* handle the ADB400 sync */
248*44dea544SJacky Bai 		if (pwr_domain->need_sync) {
249*44dea544SJacky Bai 			/* clear adb power down request */
250*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
251*44dea544SJacky Bai 
252*44dea544SJacky Bai 			/* wait for adb power request ack */
253*44dea544SJacky Bai 			while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
254*44dea544SJacky Bai 				;
255*44dea544SJacky Bai 			}
256*44dea544SJacky Bai 		}
257*44dea544SJacky Bai 
258*44dea544SJacky Bai 		if (domain_id == GPUMIX) {
259*44dea544SJacky Bai 			/* power up GPU2D ADB */
260*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU2D_ADB400_SYNC);
261*44dea544SJacky Bai 
262*44dea544SJacky Bai 			/* wait for adb power request ack */
263*44dea544SJacky Bai 			while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU2D_ADB400_ACK)) {
264*44dea544SJacky Bai 				;
265*44dea544SJacky Bai 			}
266*44dea544SJacky Bai 
267*44dea544SJacky Bai 			/* power up GPU3D ADB */
268*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU3D_ADB400_SYNC);
269*44dea544SJacky Bai 
270*44dea544SJacky Bai 			/* wait for adb power request ack */
271*44dea544SJacky Bai 			while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU3D_ADB400_ACK)) {
272*44dea544SJacky Bai 				;
273*44dea544SJacky Bai 			}
274*44dea544SJacky Bai 		}
275*44dea544SJacky Bai 	} else {
276*44dea544SJacky Bai 		pu_domain_status &= ~(1 << domain_id);
277*44dea544SJacky Bai 
278*44dea544SJacky Bai 		if (domain_id == OTG1 || domain_id == OTG2) {
279*44dea544SJacky Bai 			return;
280*44dea544SJacky Bai 		}
281*44dea544SJacky Bai 
282*44dea544SJacky Bai 		/* GPU2D & GPU3D ADB power down */
283*44dea544SJacky Bai 		if (domain_id == GPUMIX) {
284*44dea544SJacky Bai 			mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU2D_ADB400_SYNC);
285*44dea544SJacky Bai 
286*44dea544SJacky Bai 			/* wait for adb power request ack */
287*44dea544SJacky Bai 			while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU2D_ADB400_ACK)) {
288*44dea544SJacky Bai 				;
289*44dea544SJacky Bai 			}
290*44dea544SJacky Bai 
291*44dea544SJacky Bai 			mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU3D_ADB400_SYNC);
292*44dea544SJacky Bai 
293*44dea544SJacky Bai 				/* wait for adb power request ack */
294*44dea544SJacky Bai 			while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU3D_ADB400_ACK)) {
295*44dea544SJacky Bai 				;
296*44dea544SJacky Bai 			}
297*44dea544SJacky Bai 		}
298*44dea544SJacky Bai 
299*44dea544SJacky Bai 		/* handle the ADB400 sync */
300*44dea544SJacky Bai 		if (pwr_domain->need_sync) {
301*44dea544SJacky Bai 			/* set adb power down request */
302*44dea544SJacky Bai 			mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
303*44dea544SJacky Bai 
304*44dea544SJacky Bai 			/* wait for adb power request ack */
305*44dea544SJacky Bai 			while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
306*44dea544SJacky Bai 				;
307*44dea544SJacky Bai 			}
308*44dea544SJacky Bai 		}
309*44dea544SJacky Bai 
310*44dea544SJacky Bai 		if (domain_id == GPUMIX) {
311*44dea544SJacky Bai 			/* power down GPU2D */
312*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + GPU2D_PGC, 0x1);
313*44dea544SJacky Bai 
314*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, GPU2D_PWR_REQ);
315*44dea544SJacky Bai 
316*44dea544SJacky Bai 			/* wait for power request done */
317*44dea544SJacky Bai 			while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & GPU2D_PWR_REQ) {
318*44dea544SJacky Bai 				;
319*44dea544SJacky Bai 			}
320*44dea544SJacky Bai 
321*44dea544SJacky Bai 			/* power down GPU3D */
322*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + GPU3D_PGC, 0x1);
323*44dea544SJacky Bai 
324*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, GPU3D_PWR_REQ);
325*44dea544SJacky Bai 
326*44dea544SJacky Bai 			/* wait for power request done */
327*44dea544SJacky Bai 			while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & GPU3D_PWR_REQ) {
328*44dea544SJacky Bai 				;
329*44dea544SJacky Bai 			}
330*44dea544SJacky Bai 		}
331*44dea544SJacky Bai 
332*44dea544SJacky Bai 		/* HSIOMIX has no PU bit, so skip for it */
333*44dea544SJacky Bai 		if (domain_id != HSIOMIX) {
334*44dea544SJacky Bai 			/* set the PGC bit */
335*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
336*44dea544SJacky Bai 
337*44dea544SJacky Bai 			/* power down the domain */
338*44dea544SJacky Bai 			mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, pwr_domain->pwr_req);
339*44dea544SJacky Bai 
340*44dea544SJacky Bai 			/* wait for power request done */
341*44dea544SJacky Bai 			while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & pwr_domain->pwr_req) {
342*44dea544SJacky Bai 				;
343*44dea544SJacky Bai 			}
344*44dea544SJacky Bai 		}
345*44dea544SJacky Bai 	}
346*44dea544SJacky Bai }
347*44dea544SJacky Bai 
348179f82a2SJacky Bai void imx_gpc_init(void)
349179f82a2SJacky Bai {
350179f82a2SJacky Bai 	unsigned int val;
351179f82a2SJacky Bai 	int i;
352179f82a2SJacky Bai 
353179f82a2SJacky Bai 	/* mask all the wakeup irq by default */
354179f82a2SJacky Bai 	for (i = 0; i < 4; i++) {
355179f82a2SJacky Bai 		mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0);
356179f82a2SJacky Bai 		mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0);
357179f82a2SJacky Bai 		mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0);
358179f82a2SJacky Bai 		mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0);
359179f82a2SJacky Bai 		mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0);
360179f82a2SJacky Bai 	}
361179f82a2SJacky Bai 
362179f82a2SJacky Bai 	val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC);
363179f82a2SJacky Bai 	/* use GIC wake_request to wakeup C0~C3 from LPM */
364179f82a2SJacky Bai 	val |= 0x30c00000;
365179f82a2SJacky Bai 	/* clear the MASTER0 LPM handshake */
366179f82a2SJacky Bai 	val &= ~(1 << 6);
367179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val);
368179f82a2SJacky Bai 
369179f82a2SJacky Bai 	/* clear MASTER1 & MASTER2 mapping in CPU0(A53) */
370179f82a2SJacky Bai 	mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING |
371179f82a2SJacky Bai 		MASTER2_MAPPING));
372179f82a2SJacky Bai 
373179f82a2SJacky Bai 	/* set all mix/PU in A53 domain */
374179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0xffff);
375179f82a2SJacky Bai 
376179f82a2SJacky Bai 	/*
377179f82a2SJacky Bai 	 * Set the CORE & SCU power up timing:
378179f82a2SJacky Bai 	 * SW = 0x1, SW2ISO = 0x1;
379179f82a2SJacky Bai 	 * the CPU CORE and SCU power up timming counter
380179f82a2SJacky Bai 	 * is drived  by 32K OSC, each domain's power up
381179f82a2SJacky Bai 	 * latency is (SW + SW2ISO) / 32768
382179f82a2SJacky Bai 	 */
383179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x81);
384179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x81);
385179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x81);
386179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x81);
387179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x81);
388179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING,
389179f82a2SJacky Bai 		      (0x59 << 10) | 0x5B | (0x2 << 20));
390179f82a2SJacky Bai 
391179f82a2SJacky Bai 	/* set DUMMY PDN/PUP ACK by default for A53 domain */
392179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53,
393179f82a2SJacky Bai 		      A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK);
394179f82a2SJacky Bai 
395179f82a2SJacky Bai 	/* clear DSM by default */
396179f82a2SJacky Bai 	val = mmio_read_32(IMX_GPC_BASE + SLPCR);
397179f82a2SJacky Bai 	val &= ~SLPCR_EN_DSM;
398179f82a2SJacky Bai 	/* enable the fast wakeup wait mode */
399179f82a2SJacky Bai 	val |= SLPCR_A53_FASTWUP_WAIT_MODE;
400179f82a2SJacky Bai 	/* clear the RBC */
401179f82a2SJacky Bai 	val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT);
402179f82a2SJacky Bai 	/* set the STBY_COUNT to 0x5, (128 * 30)us */
403179f82a2SJacky Bai 	val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT);
404179f82a2SJacky Bai 	val |= (0x5 << SLPCR_STBY_COUNT_SHFT);
405179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + SLPCR, val);
406179f82a2SJacky Bai 
407179f82a2SJacky Bai 	/*
408179f82a2SJacky Bai 	 * USB PHY power up needs to make sure RESET bit in SRC is clear,
409179f82a2SJacky Bai 	 * otherwise, the PU power up bit in GPC will NOT self-cleared.
410179f82a2SJacky Bai 	 * only need to do it once.
411179f82a2SJacky Bai 	 */
412179f82a2SJacky Bai 	mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
413179f82a2SJacky Bai 	mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1);
414179f82a2SJacky Bai 
415179f82a2SJacky Bai 	/* enable all the power domain by default */
416179f82a2SJacky Bai 	mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x3fcf);
417179f82a2SJacky Bai }
418