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