xref: /optee_os/core/drivers/pm/imx/gpcv2.c (revision 19a31ec40245ae01a9adcd206eec2a4bb4479fc9)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2017, 2023 NXP
4  *
5  * Peng Fan <peng.fan@nxp.com>
6  */
7 
8 #include <io.h>
9 #include <kernel/delay_arch.h>
10 #include <mm/core_memprot.h>
11 
12 #include "local.h"
13 
14 #define GPC_PGC_C1			0x840
15 #define GPC_PGC_PCG_MASK		BIT(0)
16 
17 #define GPC_CPU_PGC_SW_PUP_REQ		0xf0
18 #define GPC_PU_PGC_SW_PUP_REQ		0xf8
19 #define GPC_CPU_PGC_SW_PDN_REQ		0xfc
20 #define GPC_PU_PGC_SW_PDN_REQ		0x104
21 #define GPC_PGC_SW_PDN_PUP_REQ_CORE1_MASK BIT(1)
22 
23 static void imx_gpcv2_set_core_pgc(bool enable, uint32_t offset)
24 {
25 	vaddr_t va = core_mmu_get_va(GPC_BASE, MEM_AREA_IO_SEC, GPC_SIZE);
26 
27 	if (enable)
28 		io_setbits32(va + offset, GPC_PGC_PCG_MASK);
29 	else
30 		io_clrbits32(va + offset, GPC_PGC_PCG_MASK);
31 }
32 
33 void imx_gpcv2_set_core1_pup_by_software(void)
34 {
35 	vaddr_t va = core_mmu_get_va(GPC_BASE, MEM_AREA_IO_SEC, GPC_SIZE);
36 	uint64_t timeout = timeout_init_us(10 * 1000);
37 
38 	imx_gpcv2_set_core_pgc(true, GPC_PGC_C1);
39 
40 	io_setbits32(va + GPC_CPU_PGC_SW_PUP_REQ,
41 		     GPC_PGC_SW_PDN_PUP_REQ_CORE1_MASK);
42 
43 	while ((io_read32(va + GPC_CPU_PGC_SW_PUP_REQ) &
44 		GPC_PGC_SW_PDN_PUP_REQ_CORE1_MASK)) {
45 		if (timeout_elapsed(timeout))
46 			return;
47 	}
48 
49 	imx_gpcv2_set_core_pgc(false, GPC_PGC_C1);
50 }
51