xref: /rk3399_ARM-atf/plat/hisilicon/hikey/hisi_pwrc.c (revision e246617b41825e5278ac0057e800afa3b3944fe3)
1127793daSHaojian Zhuang /*
2127793daSHaojian Zhuang  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3127793daSHaojian Zhuang  *
4127793daSHaojian Zhuang  * SPDX-License-Identifier: BSD-3-Clause
5127793daSHaojian Zhuang  */
6127793daSHaojian Zhuang 
7127793daSHaojian Zhuang #include <debug.h>
8127793daSHaojian Zhuang #include <mmio.h>
9ee1ebbd1SIsla Mitchell 
10ee1ebbd1SIsla Mitchell #include <hi6220_regs_acpu.h>
11ee1ebbd1SIsla Mitchell #include <hi6220_regs_ao.h>
12127793daSHaojian Zhuang #include <hisi_ipc.h>
13127793daSHaojian Zhuang #include <hisi_pwrc.h>
14127793daSHaojian Zhuang #include <hisi_sram_map.h>
15ee1ebbd1SIsla Mitchell 
16127793daSHaojian Zhuang #include <stdarg.h>
17127793daSHaojian Zhuang #include <stdio.h>
18127793daSHaojian Zhuang #include <string.h>
19127793daSHaojian Zhuang #include <platform_def.h>
20127793daSHaojian Zhuang 
21127793daSHaojian Zhuang #define CLUSTER_CORE_COUNT		(4)
22127793daSHaojian Zhuang #define CLUSTER_CORE_MASK		((1 << CLUSTER_CORE_COUNT) - 1)
23127793daSHaojian Zhuang 
24127793daSHaojian Zhuang void hisi_pwrc_set_core_bx_addr(unsigned int core, unsigned int cluster,
25127793daSHaojian Zhuang 				uintptr_t entry_point)
26127793daSHaojian Zhuang {
27127793daSHaojian Zhuang 	uintptr_t *core_entry = (uintptr_t *)PWRCTRL_ACPU_ASM_D_ARM_PARA_AD;
28127793daSHaojian Zhuang 	unsigned int i;
29127793daSHaojian Zhuang 
30127793daSHaojian Zhuang 	if (!core_entry) {
31127793daSHaojian Zhuang 		INFO("%s: core entry point is null!\n", __func__);
32127793daSHaojian Zhuang 		return;
33127793daSHaojian Zhuang 	}
34127793daSHaojian Zhuang 
35127793daSHaojian Zhuang 	i = cluster * CLUSTER_CORE_COUNT + core;
36127793daSHaojian Zhuang 	mmio_write_64((uintptr_t)(core_entry + i), entry_point);
37127793daSHaojian Zhuang }
38127793daSHaojian Zhuang 
39127793daSHaojian Zhuang void hisi_pwrc_set_cluster_wfi(unsigned int cluster)
40127793daSHaojian Zhuang {
41127793daSHaojian Zhuang 	unsigned int reg = 0;
42127793daSHaojian Zhuang 
43127793daSHaojian Zhuang 	if (cluster == 0) {
44127793daSHaojian Zhuang 		reg = mmio_read_32(ACPU_SC_SNOOP_PWD);
45127793daSHaojian Zhuang 		reg |= PD_DETECT_START0;
46127793daSHaojian Zhuang 		mmio_write_32(ACPU_SC_SNOOP_PWD, reg);
47127793daSHaojian Zhuang 	} else if (cluster == 1) {
48127793daSHaojian Zhuang 		reg = mmio_read_32(ACPU_SC_SNOOP_PWD);
49127793daSHaojian Zhuang 		reg |= PD_DETECT_START1;
50127793daSHaojian Zhuang 		mmio_write_32(ACPU_SC_SNOOP_PWD, reg);
51127793daSHaojian Zhuang 	}
52127793daSHaojian Zhuang }
53127793daSHaojian Zhuang 
54*e246617bSLeo Yan void hisi_pwrc_enable_debug(unsigned int core, unsigned int cluster)
55*e246617bSLeo Yan {
56*e246617bSLeo Yan 	unsigned int val, enable;
57*e246617bSLeo Yan 
58*e246617bSLeo Yan 	enable = 1U << (core + PDBGUP_CLUSTER1_SHIFT * cluster);
59*e246617bSLeo Yan 
60*e246617bSLeo Yan 	/* Enable debug module */
61*e246617bSLeo Yan 	val = mmio_read_32(ACPU_SC_PDBGUP_MBIST);
62*e246617bSLeo Yan 	mmio_write_32(ACPU_SC_PDBGUP_MBIST, val | enable);
63*e246617bSLeo Yan 	do {
64*e246617bSLeo Yan 		/* RAW barrier */
65*e246617bSLeo Yan 		val = mmio_read_32(ACPU_SC_PDBGUP_MBIST);
66*e246617bSLeo Yan 	} while (!(val & enable));
67*e246617bSLeo Yan }
68*e246617bSLeo Yan 
69127793daSHaojian Zhuang int hisi_pwrc_setup(void)
70127793daSHaojian Zhuang {
71127793daSHaojian Zhuang 	unsigned int reg, sec_entrypoint;
72127793daSHaojian Zhuang 	extern char pm_asm_code[], pm_asm_code_end[];
73127793daSHaojian Zhuang 	extern char v7_asm[], v7_asm_end[];
74127793daSHaojian Zhuang 
75127793daSHaojian Zhuang 	sec_entrypoint = PWRCTRL_ACPU_ASM_CODE_BASE;
76127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(0), sec_entrypoint >> 2);
77127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(1), sec_entrypoint >> 2);
78127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(2), sec_entrypoint >> 2);
79127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(3), sec_entrypoint >> 2);
80127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(4), sec_entrypoint >> 2);
81127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(5), sec_entrypoint >> 2);
82127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(6), sec_entrypoint >> 2);
83127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(7), sec_entrypoint >> 2);
84127793daSHaojian Zhuang 
85127793daSHaojian Zhuang 	memset((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, 0, 0x400);
86127793daSHaojian Zhuang 	memcpy((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, (void *)v7_asm,
87127793daSHaojian Zhuang 	       v7_asm_end - v7_asm);
88127793daSHaojian Zhuang 
89127793daSHaojian Zhuang 	memcpy((void *)PWRCTRL_ACPU_ASM_CODE_BASE, (void *)pm_asm_code,
90127793daSHaojian Zhuang 	       pm_asm_code_end - pm_asm_code);
91127793daSHaojian Zhuang 
92127793daSHaojian Zhuang 	reg = mmio_read_32(AO_SC_SYS_CTRL1);
933506ff11SLeo Yan 	/* Remap SRAM address for ACPU */
94127793daSHaojian Zhuang 	reg |= AO_SC_SYS_CTRL1_REMAP_SRAM_AARM |
95127793daSHaojian Zhuang 	       AO_SC_SYS_CTRL1_REMAP_SRAM_AARM_MSK;
963506ff11SLeo Yan 
973506ff11SLeo Yan 	/* Enable reset signal for watchdog */
983506ff11SLeo Yan 	reg |= AO_SC_SYS_CTRL1_AARM_WD_RST_CFG |
993506ff11SLeo Yan 	       AO_SC_SYS_CTRL1_AARM_WD_RST_CFG_MSK;
100127793daSHaojian Zhuang 	mmio_write_32(AO_SC_SYS_CTRL1, reg);
101127793daSHaojian Zhuang 
102127793daSHaojian Zhuang 	return 0;
103127793daSHaojian Zhuang }
104