xref: /aosp_15_r20/external/arm-trusted-firmware/plat/hisilicon/hikey/hisi_pwrc.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park #include <stdarg.h>
8*54fd6939SJiyong Park #include <stdio.h>
9*54fd6939SJiyong Park #include <string.h>
10*54fd6939SJiyong Park 
11*54fd6939SJiyong Park #include <platform_def.h>
12*54fd6939SJiyong Park 
13*54fd6939SJiyong Park #include <common/debug.h>
14*54fd6939SJiyong Park #include <lib/mmio.h>
15*54fd6939SJiyong Park 
16*54fd6939SJiyong Park #include <hi6220_regs_acpu.h>
17*54fd6939SJiyong Park #include <hi6220_regs_ao.h>
18*54fd6939SJiyong Park #include <hisi_ipc.h>
19*54fd6939SJiyong Park #include <hisi_pwrc.h>
20*54fd6939SJiyong Park #include <hisi_sram_map.h>
21*54fd6939SJiyong Park 
22*54fd6939SJiyong Park #define CLUSTER_CORE_COUNT		(4)
23*54fd6939SJiyong Park #define CLUSTER_CORE_MASK		((1 << CLUSTER_CORE_COUNT) - 1)
24*54fd6939SJiyong Park 
hisi_pwrc_set_core_bx_addr(unsigned int core,unsigned int cluster,uintptr_t entry_point)25*54fd6939SJiyong Park void hisi_pwrc_set_core_bx_addr(unsigned int core, unsigned int cluster,
26*54fd6939SJiyong Park 				uintptr_t entry_point)
27*54fd6939SJiyong Park {
28*54fd6939SJiyong Park 	uintptr_t *core_entry = (uintptr_t *)PWRCTRL_ACPU_ASM_D_ARM_PARA_AD;
29*54fd6939SJiyong Park 	unsigned int i;
30*54fd6939SJiyong Park 
31*54fd6939SJiyong Park 	if (!core_entry) {
32*54fd6939SJiyong Park 		INFO("%s: core entry point is null!\n", __func__);
33*54fd6939SJiyong Park 		return;
34*54fd6939SJiyong Park 	}
35*54fd6939SJiyong Park 
36*54fd6939SJiyong Park 	i = cluster * CLUSTER_CORE_COUNT + core;
37*54fd6939SJiyong Park 	mmio_write_64((uintptr_t)(core_entry + i), entry_point);
38*54fd6939SJiyong Park }
39*54fd6939SJiyong Park 
hisi_pwrc_set_cluster_wfi(unsigned int cluster)40*54fd6939SJiyong Park void hisi_pwrc_set_cluster_wfi(unsigned int cluster)
41*54fd6939SJiyong Park {
42*54fd6939SJiyong Park 	unsigned int reg = 0;
43*54fd6939SJiyong Park 
44*54fd6939SJiyong Park 	if (cluster == 0) {
45*54fd6939SJiyong Park 		reg = mmio_read_32(ACPU_SC_SNOOP_PWD);
46*54fd6939SJiyong Park 		reg |= PD_DETECT_START0;
47*54fd6939SJiyong Park 		mmio_write_32(ACPU_SC_SNOOP_PWD, reg);
48*54fd6939SJiyong Park 	} else if (cluster == 1) {
49*54fd6939SJiyong Park 		reg = mmio_read_32(ACPU_SC_SNOOP_PWD);
50*54fd6939SJiyong Park 		reg |= PD_DETECT_START1;
51*54fd6939SJiyong Park 		mmio_write_32(ACPU_SC_SNOOP_PWD, reg);
52*54fd6939SJiyong Park 	}
53*54fd6939SJiyong Park }
54*54fd6939SJiyong Park 
hisi_pwrc_enable_debug(unsigned int core,unsigned int cluster)55*54fd6939SJiyong Park void hisi_pwrc_enable_debug(unsigned int core, unsigned int cluster)
56*54fd6939SJiyong Park {
57*54fd6939SJiyong Park 	unsigned int val, enable;
58*54fd6939SJiyong Park 
59*54fd6939SJiyong Park 	enable = 1U << (core + PDBGUP_CLUSTER1_SHIFT * cluster);
60*54fd6939SJiyong Park 
61*54fd6939SJiyong Park 	/* Enable debug module */
62*54fd6939SJiyong Park 	val = mmio_read_32(ACPU_SC_PDBGUP_MBIST);
63*54fd6939SJiyong Park 	mmio_write_32(ACPU_SC_PDBGUP_MBIST, val | enable);
64*54fd6939SJiyong Park 	do {
65*54fd6939SJiyong Park 		/* RAW barrier */
66*54fd6939SJiyong Park 		val = mmio_read_32(ACPU_SC_PDBGUP_MBIST);
67*54fd6939SJiyong Park 	} while (!(val & enable));
68*54fd6939SJiyong Park }
69*54fd6939SJiyong Park 
hisi_pwrc_setup(void)70*54fd6939SJiyong Park int hisi_pwrc_setup(void)
71*54fd6939SJiyong Park {
72*54fd6939SJiyong Park 	unsigned int reg, sec_entrypoint;
73*54fd6939SJiyong Park 	extern char pm_asm_code[], pm_asm_code_end[];
74*54fd6939SJiyong Park 	extern char v7_asm[], v7_asm_end[];
75*54fd6939SJiyong Park 
76*54fd6939SJiyong Park 	sec_entrypoint = PWRCTRL_ACPU_ASM_CODE_BASE;
77*54fd6939SJiyong Park 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(0), sec_entrypoint >> 2);
78*54fd6939SJiyong Park 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(1), sec_entrypoint >> 2);
79*54fd6939SJiyong Park 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(2), sec_entrypoint >> 2);
80*54fd6939SJiyong Park 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(3), sec_entrypoint >> 2);
81*54fd6939SJiyong Park 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(4), sec_entrypoint >> 2);
82*54fd6939SJiyong Park 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(5), sec_entrypoint >> 2);
83*54fd6939SJiyong Park 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(6), sec_entrypoint >> 2);
84*54fd6939SJiyong Park 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(7), sec_entrypoint >> 2);
85*54fd6939SJiyong Park 
86*54fd6939SJiyong Park 	memset((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, 0, 0x400);
87*54fd6939SJiyong Park 	memcpy((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, (void *)v7_asm,
88*54fd6939SJiyong Park 	       v7_asm_end - v7_asm);
89*54fd6939SJiyong Park 
90*54fd6939SJiyong Park 	memcpy((void *)PWRCTRL_ACPU_ASM_CODE_BASE, (void *)pm_asm_code,
91*54fd6939SJiyong Park 	       pm_asm_code_end - pm_asm_code);
92*54fd6939SJiyong Park 
93*54fd6939SJiyong Park 	reg = mmio_read_32(AO_SC_SYS_CTRL1);
94*54fd6939SJiyong Park 	/* Remap SRAM address for ACPU */
95*54fd6939SJiyong Park 	reg |= AO_SC_SYS_CTRL1_REMAP_SRAM_AARM |
96*54fd6939SJiyong Park 	       AO_SC_SYS_CTRL1_REMAP_SRAM_AARM_MSK;
97*54fd6939SJiyong Park 
98*54fd6939SJiyong Park 	/* Enable reset signal for watchdog */
99*54fd6939SJiyong Park 	reg |= AO_SC_SYS_CTRL1_AARM_WD_RST_CFG |
100*54fd6939SJiyong Park 	       AO_SC_SYS_CTRL1_AARM_WD_RST_CFG_MSK;
101*54fd6939SJiyong Park 	mmio_write_32(AO_SC_SYS_CTRL1, reg);
102*54fd6939SJiyong Park 
103*54fd6939SJiyong Park 	return 0;
104*54fd6939SJiyong Park }
105