1179f82a2SJacky Bai /*
244dea544SJacky 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*2a6ffa99SJacky Bai #define CCGR(x) (0x4000 + (x) * 16)
2344dea544SJacky Bai
2444dea544SJacky Bai enum pu_domain_id {
2544dea544SJacky Bai HSIOMIX,
2644dea544SJacky Bai PCIE,
2744dea544SJacky Bai OTG1,
2844dea544SJacky Bai OTG2,
2944dea544SJacky Bai GPUMIX,
3044dea544SJacky Bai VPUMIX,
3144dea544SJacky Bai VPU_G1,
3244dea544SJacky Bai VPU_G2,
3344dea544SJacky Bai VPU_H1,
3444dea544SJacky Bai DISPMIX,
3544dea544SJacky Bai MIPI,
3644dea544SJacky Bai /* below two domain only for ATF internal use */
3744dea544SJacky Bai GPU2D,
3844dea544SJacky Bai GPU3D,
3944dea544SJacky Bai MAX_DOMAINS,
4044dea544SJacky Bai };
4144dea544SJacky Bai
4244dea544SJacky Bai /* PU domain */
4344dea544SJacky Bai static struct imx_pwr_domain pu_domains[] = {
4444dea544SJacky Bai IMX_MIX_DOMAIN(HSIOMIX, false),
4544dea544SJacky Bai IMX_PD_DOMAIN(PCIE, false),
4644dea544SJacky Bai IMX_PD_DOMAIN(OTG1, true),
4744dea544SJacky Bai IMX_PD_DOMAIN(OTG2, true),
4844dea544SJacky Bai IMX_MIX_DOMAIN(GPUMIX, false),
4944dea544SJacky Bai IMX_MIX_DOMAIN(VPUMIX, false),
5044dea544SJacky Bai IMX_PD_DOMAIN(VPU_G1, false),
5144dea544SJacky Bai IMX_PD_DOMAIN(VPU_G2, false),
5244dea544SJacky Bai IMX_PD_DOMAIN(VPU_H1, false),
5344dea544SJacky Bai IMX_MIX_DOMAIN(DISPMIX, false),
5444dea544SJacky Bai IMX_PD_DOMAIN(MIPI, false),
5544dea544SJacky Bai /* below two domain only for ATF internal use */
5644dea544SJacky Bai IMX_MIX_DOMAIN(GPU2D, false),
5744dea544SJacky Bai IMX_MIX_DOMAIN(GPU3D, false),
5844dea544SJacky Bai };
5944dea544SJacky Bai
6044dea544SJacky Bai static unsigned int pu_domain_status;
6144dea544SJacky Bai
6244dea544SJacky Bai #define GPU_RCR 0x40
6344dea544SJacky Bai #define VPU_RCR 0x44
6444dea544SJacky Bai
6544dea544SJacky Bai #define VPU_CTL_BASE 0x38330000
6644dea544SJacky Bai #define BLK_SFT_RSTN_CSR 0x0
6744dea544SJacky Bai #define H1_SFT_RSTN BIT(2)
6844dea544SJacky Bai #define G1_SFT_RSTN BIT(1)
6944dea544SJacky Bai #define G2_SFT_RSTN BIT(0)
7044dea544SJacky Bai
7144dea544SJacky Bai #define DISP_CTL_BASE 0x32e28000
7244dea544SJacky Bai
vpu_sft_reset_assert(uint32_t domain_id)7344dea544SJacky Bai void vpu_sft_reset_assert(uint32_t domain_id)
7444dea544SJacky Bai {
7544dea544SJacky Bai uint32_t val;
7644dea544SJacky Bai
7744dea544SJacky Bai val = mmio_read_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR);
7844dea544SJacky Bai
7944dea544SJacky Bai switch (domain_id) {
8044dea544SJacky Bai case VPU_G1:
8144dea544SJacky Bai val &= ~G1_SFT_RSTN;
8244dea544SJacky Bai mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
8344dea544SJacky Bai break;
8444dea544SJacky Bai case VPU_G2:
8544dea544SJacky Bai val &= ~G2_SFT_RSTN;
8644dea544SJacky Bai mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
8744dea544SJacky Bai break;
8844dea544SJacky Bai case VPU_H1:
8944dea544SJacky Bai val &= ~H1_SFT_RSTN;
9044dea544SJacky Bai mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
9144dea544SJacky Bai break;
9244dea544SJacky Bai default:
9344dea544SJacky Bai break;
9444dea544SJacky Bai }
9544dea544SJacky Bai }
9644dea544SJacky Bai
vpu_sft_reset_deassert(uint32_t domain_id)9744dea544SJacky Bai void vpu_sft_reset_deassert(uint32_t domain_id)
9844dea544SJacky Bai {
9944dea544SJacky Bai uint32_t val;
10044dea544SJacky Bai
10144dea544SJacky Bai val = mmio_read_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR);
10244dea544SJacky Bai
10344dea544SJacky Bai switch (domain_id) {
10444dea544SJacky Bai case VPU_G1:
10544dea544SJacky Bai val |= G1_SFT_RSTN;
10644dea544SJacky Bai mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
10744dea544SJacky Bai break;
10844dea544SJacky Bai case VPU_G2:
10944dea544SJacky Bai val |= G2_SFT_RSTN;
11044dea544SJacky Bai mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
11144dea544SJacky Bai break;
11244dea544SJacky Bai case VPU_H1:
11344dea544SJacky Bai val |= H1_SFT_RSTN;
11444dea544SJacky Bai mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
11544dea544SJacky Bai break;
11644dea544SJacky Bai default:
11744dea544SJacky Bai break;
11844dea544SJacky Bai }
11944dea544SJacky Bai }
12044dea544SJacky Bai
imx_gpc_pm_domain_enable(uint32_t domain_id,bool on)12144dea544SJacky Bai void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
12244dea544SJacky Bai {
12344dea544SJacky Bai if (domain_id >= MAX_DOMAINS) {
12444dea544SJacky Bai return;
12544dea544SJacky Bai }
12644dea544SJacky Bai
12744dea544SJacky Bai struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id];
12844dea544SJacky Bai
12944dea544SJacky Bai if (on) {
13044dea544SJacky Bai pu_domain_status |= (1 << domain_id);
13144dea544SJacky Bai
13244dea544SJacky Bai if (domain_id == VPU_G1 || domain_id == VPU_G2 ||
13344dea544SJacky Bai domain_id == VPU_H1) {
13444dea544SJacky Bai vpu_sft_reset_assert(domain_id);
13544dea544SJacky Bai }
13644dea544SJacky Bai
13744dea544SJacky Bai /* HSIOMIX has no PU bit, so skip for it */
13844dea544SJacky Bai if (domain_id != HSIOMIX) {
13944dea544SJacky Bai /* clear the PGC bit */
14044dea544SJacky Bai mmio_clrbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
14144dea544SJacky Bai
14244dea544SJacky Bai /* power up the domain */
14344dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, pwr_domain->pwr_req);
14444dea544SJacky Bai
14544dea544SJacky Bai /* wait for power request done */
14644dea544SJacky Bai while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & pwr_domain->pwr_req) {
14744dea544SJacky Bai ;
14844dea544SJacky Bai }
14944dea544SJacky Bai }
15044dea544SJacky Bai
15144dea544SJacky Bai if (domain_id == VPU_G1 || domain_id == VPU_G2 ||
15244dea544SJacky Bai domain_id == VPU_H1) {
15344dea544SJacky Bai vpu_sft_reset_deassert(domain_id);
15444dea544SJacky Bai /* dealy for a while to make sure reset done */
15544dea544SJacky Bai udelay(100);
15644dea544SJacky Bai }
15744dea544SJacky Bai
15844dea544SJacky Bai if (domain_id == GPUMIX) {
15944dea544SJacky Bai /* assert reset */
16044dea544SJacky Bai mmio_write_32(IMX_SRC_BASE + GPU_RCR, 0x1);
16144dea544SJacky Bai
16244dea544SJacky Bai /* power up GPU2D */
16344dea544SJacky Bai mmio_clrbits_32(IMX_GPC_BASE + GPU2D_PGC, 0x1);
16444dea544SJacky Bai
16544dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, GPU2D_PWR_REQ);
16644dea544SJacky Bai
16744dea544SJacky Bai /* wait for power request done */
16844dea544SJacky Bai while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & GPU2D_PWR_REQ) {
16944dea544SJacky Bai ;
17044dea544SJacky Bai }
17144dea544SJacky Bai
17244dea544SJacky Bai udelay(1);
17344dea544SJacky Bai
17444dea544SJacky Bai /* power up GPU3D */
17544dea544SJacky Bai mmio_clrbits_32(IMX_GPC_BASE + GPU3D_PGC, 0x1);
17644dea544SJacky Bai
17744dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, GPU3D_PWR_REQ);
17844dea544SJacky Bai
17944dea544SJacky Bai /* wait for power request done */
18044dea544SJacky Bai while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & GPU3D_PWR_REQ) {
18144dea544SJacky Bai ;
18244dea544SJacky Bai }
18344dea544SJacky Bai
18444dea544SJacky Bai udelay(10);
18544dea544SJacky Bai /* release the gpumix reset */
18644dea544SJacky Bai mmio_write_32(IMX_SRC_BASE + GPU_RCR, 0x0);
18744dea544SJacky Bai udelay(10);
18844dea544SJacky Bai }
18944dea544SJacky Bai
19044dea544SJacky Bai /* vpu sft clock enable */
19144dea544SJacky Bai if (domain_id == VPUMIX) {
19244dea544SJacky Bai mmio_write_32(IMX_SRC_BASE + VPU_RCR, 0x1);
19344dea544SJacky Bai udelay(5);
19444dea544SJacky Bai mmio_write_32(IMX_SRC_BASE + VPU_RCR, 0x0);
19544dea544SJacky Bai udelay(5);
19644dea544SJacky Bai
19744dea544SJacky Bai /* enable all clock */
19844dea544SJacky Bai mmio_write_32(VPU_CTL_BASE + 0x4, 0x7);
19944dea544SJacky Bai }
20044dea544SJacky Bai
20144dea544SJacky Bai if (domain_id == DISPMIX) {
20244dea544SJacky Bai /* special setting for DISPMIX */
20344dea544SJacky Bai mmio_write_32(DISP_CTL_BASE + 0x4, 0x1fff);
20444dea544SJacky Bai mmio_write_32(DISP_CTL_BASE, 0x7f);
20544dea544SJacky Bai mmio_write_32(DISP_CTL_BASE + 0x8, 0x30000);
20644dea544SJacky Bai }
20744dea544SJacky Bai
20844dea544SJacky Bai /* handle the ADB400 sync */
20944dea544SJacky Bai if (pwr_domain->need_sync) {
21044dea544SJacky Bai /* clear adb power down request */
21144dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
21244dea544SJacky Bai
21344dea544SJacky Bai /* wait for adb power request ack */
21444dea544SJacky Bai while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
21544dea544SJacky Bai ;
21644dea544SJacky Bai }
21744dea544SJacky Bai }
21844dea544SJacky Bai
21944dea544SJacky Bai if (domain_id == GPUMIX) {
22044dea544SJacky Bai /* power up GPU2D ADB */
22144dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU2D_ADB400_SYNC);
22244dea544SJacky Bai
22344dea544SJacky Bai /* wait for adb power request ack */
22444dea544SJacky Bai while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU2D_ADB400_ACK)) {
22544dea544SJacky Bai ;
22644dea544SJacky Bai }
22744dea544SJacky Bai
22844dea544SJacky Bai /* power up GPU3D ADB */
22944dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU3D_ADB400_SYNC);
23044dea544SJacky Bai
23144dea544SJacky Bai /* wait for adb power request ack */
23244dea544SJacky Bai while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU3D_ADB400_ACK)) {
23344dea544SJacky Bai ;
23444dea544SJacky Bai }
23544dea544SJacky Bai }
23644dea544SJacky Bai } else {
23744dea544SJacky Bai pu_domain_status &= ~(1 << domain_id);
23844dea544SJacky Bai
23944dea544SJacky Bai if (domain_id == OTG1 || domain_id == OTG2) {
24044dea544SJacky Bai return;
24144dea544SJacky Bai }
24244dea544SJacky Bai
24344dea544SJacky Bai /* GPU2D & GPU3D ADB power down */
24444dea544SJacky Bai if (domain_id == GPUMIX) {
24544dea544SJacky Bai mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU2D_ADB400_SYNC);
24644dea544SJacky Bai
24744dea544SJacky Bai /* wait for adb power request ack */
24844dea544SJacky Bai while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU2D_ADB400_ACK)) {
24944dea544SJacky Bai ;
25044dea544SJacky Bai }
25144dea544SJacky Bai
25244dea544SJacky Bai mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU3D_ADB400_SYNC);
25344dea544SJacky Bai
25444dea544SJacky Bai /* wait for adb power request ack */
25544dea544SJacky Bai while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU3D_ADB400_ACK)) {
25644dea544SJacky Bai ;
25744dea544SJacky Bai }
25844dea544SJacky Bai }
25944dea544SJacky Bai
26044dea544SJacky Bai /* handle the ADB400 sync */
26144dea544SJacky Bai if (pwr_domain->need_sync) {
26244dea544SJacky Bai /* set adb power down request */
26344dea544SJacky Bai mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
26444dea544SJacky Bai
26544dea544SJacky Bai /* wait for adb power request ack */
26644dea544SJacky Bai while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
26744dea544SJacky Bai ;
26844dea544SJacky Bai }
26944dea544SJacky Bai }
27044dea544SJacky Bai
27144dea544SJacky Bai if (domain_id == GPUMIX) {
27244dea544SJacky Bai /* power down GPU2D */
27344dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + GPU2D_PGC, 0x1);
27444dea544SJacky Bai
27544dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, GPU2D_PWR_REQ);
27644dea544SJacky Bai
27744dea544SJacky Bai /* wait for power request done */
27844dea544SJacky Bai while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & GPU2D_PWR_REQ) {
27944dea544SJacky Bai ;
28044dea544SJacky Bai }
28144dea544SJacky Bai
28244dea544SJacky Bai /* power down GPU3D */
28344dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + GPU3D_PGC, 0x1);
28444dea544SJacky Bai
28544dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, GPU3D_PWR_REQ);
28644dea544SJacky Bai
28744dea544SJacky Bai /* wait for power request done */
28844dea544SJacky Bai while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & GPU3D_PWR_REQ) {
28944dea544SJacky Bai ;
29044dea544SJacky Bai }
29144dea544SJacky Bai }
29244dea544SJacky Bai
29344dea544SJacky Bai /* HSIOMIX has no PU bit, so skip for it */
29444dea544SJacky Bai if (domain_id != HSIOMIX) {
29544dea544SJacky Bai /* set the PGC bit */
29644dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
29744dea544SJacky Bai
29844dea544SJacky Bai /* power down the domain */
29944dea544SJacky Bai mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, pwr_domain->pwr_req);
30044dea544SJacky Bai
30144dea544SJacky Bai /* wait for power request done */
30244dea544SJacky Bai while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & pwr_domain->pwr_req) {
30344dea544SJacky Bai ;
30444dea544SJacky Bai }
30544dea544SJacky Bai }
30644dea544SJacky Bai }
30744dea544SJacky Bai }
30844dea544SJacky Bai
imx_gpc_init(void)309179f82a2SJacky Bai void imx_gpc_init(void)
310179f82a2SJacky Bai {
311179f82a2SJacky Bai unsigned int val;
312179f82a2SJacky Bai int i;
313179f82a2SJacky Bai
314179f82a2SJacky Bai /* mask all the wakeup irq by default */
315179f82a2SJacky Bai for (i = 0; i < 4; i++) {
316179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0);
317179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0);
318179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0);
319179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0);
320179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0);
321179f82a2SJacky Bai }
322179f82a2SJacky Bai
323179f82a2SJacky Bai val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC);
324179f82a2SJacky Bai /* use GIC wake_request to wakeup C0~C3 from LPM */
325179f82a2SJacky Bai val |= 0x30c00000;
326179f82a2SJacky Bai /* clear the MASTER0 LPM handshake */
327179f82a2SJacky Bai val &= ~(1 << 6);
328179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val);
329179f82a2SJacky Bai
330179f82a2SJacky Bai /* clear MASTER1 & MASTER2 mapping in CPU0(A53) */
331179f82a2SJacky Bai mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING |
332179f82a2SJacky Bai MASTER2_MAPPING));
333179f82a2SJacky Bai
334179f82a2SJacky Bai /* set all mix/PU in A53 domain */
335179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0xffff);
336179f82a2SJacky Bai
337179f82a2SJacky Bai /*
338179f82a2SJacky Bai * Set the CORE & SCU power up timing:
339179f82a2SJacky Bai * SW = 0x1, SW2ISO = 0x1;
3401b491eeaSElyes Haouas * the CPU CORE and SCU power up timing counter
341179f82a2SJacky Bai * is drived by 32K OSC, each domain's power up
342179f82a2SJacky Bai * latency is (SW + SW2ISO) / 32768
343179f82a2SJacky Bai */
344179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x81);
345179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x81);
346179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x81);
347179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x81);
348179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x81);
349179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING,
350179f82a2SJacky Bai (0x59 << 10) | 0x5B | (0x2 << 20));
351179f82a2SJacky Bai
352179f82a2SJacky Bai /* set DUMMY PDN/PUP ACK by default for A53 domain */
353179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53,
354179f82a2SJacky Bai A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK);
355179f82a2SJacky Bai
356179f82a2SJacky Bai /* clear DSM by default */
357179f82a2SJacky Bai val = mmio_read_32(IMX_GPC_BASE + SLPCR);
358179f82a2SJacky Bai val &= ~SLPCR_EN_DSM;
359179f82a2SJacky Bai /* enable the fast wakeup wait mode */
360179f82a2SJacky Bai val |= SLPCR_A53_FASTWUP_WAIT_MODE;
361179f82a2SJacky Bai /* clear the RBC */
362179f82a2SJacky Bai val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT);
363179f82a2SJacky Bai /* set the STBY_COUNT to 0x5, (128 * 30)us */
364179f82a2SJacky Bai val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT);
365179f82a2SJacky Bai val |= (0x5 << SLPCR_STBY_COUNT_SHFT);
366179f82a2SJacky Bai mmio_write_32(IMX_GPC_BASE + SLPCR, val);
367179f82a2SJacky Bai
368179f82a2SJacky Bai /*
369179f82a2SJacky Bai * USB PHY power up needs to make sure RESET bit in SRC is clear,
370179f82a2SJacky Bai * otherwise, the PU power up bit in GPC will NOT self-cleared.
371179f82a2SJacky Bai * only need to do it once.
372179f82a2SJacky Bai */
373179f82a2SJacky Bai mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
374179f82a2SJacky Bai mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1);
375179f82a2SJacky Bai }
376