xref: /rk3399_ARM-atf/plat/hisilicon/hikey/hisi_pwrc.c (revision 9a207532f8216bf83fed0891fed9ed0bc72ca450)
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 
7*09d40e0eSAntonio Nino Diaz #include <stdarg.h>
8*09d40e0eSAntonio Nino Diaz #include <stdio.h>
9*09d40e0eSAntonio Nino Diaz #include <string.h>
10*09d40e0eSAntonio Nino Diaz 
11*09d40e0eSAntonio Nino Diaz #include <platform_def.h>
12*09d40e0eSAntonio Nino Diaz 
13*09d40e0eSAntonio Nino Diaz #include <common/debug.h>
14*09d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
15ee1ebbd1SIsla Mitchell 
16ee1ebbd1SIsla Mitchell #include <hi6220_regs_acpu.h>
17ee1ebbd1SIsla Mitchell #include <hi6220_regs_ao.h>
18127793daSHaojian Zhuang #include <hisi_ipc.h>
19127793daSHaojian Zhuang #include <hisi_pwrc.h>
20127793daSHaojian Zhuang #include <hisi_sram_map.h>
21ee1ebbd1SIsla Mitchell 
22127793daSHaojian Zhuang #define CLUSTER_CORE_COUNT		(4)
23127793daSHaojian Zhuang #define CLUSTER_CORE_MASK		((1 << CLUSTER_CORE_COUNT) - 1)
24127793daSHaojian Zhuang 
hisi_pwrc_set_core_bx_addr(unsigned int core,unsigned int cluster,uintptr_t entry_point)25127793daSHaojian Zhuang void hisi_pwrc_set_core_bx_addr(unsigned int core, unsigned int cluster,
26127793daSHaojian Zhuang 				uintptr_t entry_point)
27127793daSHaojian Zhuang {
28127793daSHaojian Zhuang 	uintptr_t *core_entry = (uintptr_t *)PWRCTRL_ACPU_ASM_D_ARM_PARA_AD;
29127793daSHaojian Zhuang 	unsigned int i;
30127793daSHaojian Zhuang 
31127793daSHaojian Zhuang 	if (!core_entry) {
32127793daSHaojian Zhuang 		INFO("%s: core entry point is null!\n", __func__);
33127793daSHaojian Zhuang 		return;
34127793daSHaojian Zhuang 	}
35127793daSHaojian Zhuang 
36127793daSHaojian Zhuang 	i = cluster * CLUSTER_CORE_COUNT + core;
37127793daSHaojian Zhuang 	mmio_write_64((uintptr_t)(core_entry + i), entry_point);
38127793daSHaojian Zhuang }
39127793daSHaojian Zhuang 
hisi_pwrc_set_cluster_wfi(unsigned int cluster)40127793daSHaojian Zhuang void hisi_pwrc_set_cluster_wfi(unsigned int cluster)
41127793daSHaojian Zhuang {
42127793daSHaojian Zhuang 	unsigned int reg = 0;
43127793daSHaojian Zhuang 
44127793daSHaojian Zhuang 	if (cluster == 0) {
45127793daSHaojian Zhuang 		reg = mmio_read_32(ACPU_SC_SNOOP_PWD);
46127793daSHaojian Zhuang 		reg |= PD_DETECT_START0;
47127793daSHaojian Zhuang 		mmio_write_32(ACPU_SC_SNOOP_PWD, reg);
48127793daSHaojian Zhuang 	} else if (cluster == 1) {
49127793daSHaojian Zhuang 		reg = mmio_read_32(ACPU_SC_SNOOP_PWD);
50127793daSHaojian Zhuang 		reg |= PD_DETECT_START1;
51127793daSHaojian Zhuang 		mmio_write_32(ACPU_SC_SNOOP_PWD, reg);
52127793daSHaojian Zhuang 	}
53127793daSHaojian Zhuang }
54127793daSHaojian Zhuang 
hisi_pwrc_enable_debug(unsigned int core,unsigned int cluster)55e246617bSLeo Yan void hisi_pwrc_enable_debug(unsigned int core, unsigned int cluster)
56e246617bSLeo Yan {
57e246617bSLeo Yan 	unsigned int val, enable;
58e246617bSLeo Yan 
59e246617bSLeo Yan 	enable = 1U << (core + PDBGUP_CLUSTER1_SHIFT * cluster);
60e246617bSLeo Yan 
61e246617bSLeo Yan 	/* Enable debug module */
62e246617bSLeo Yan 	val = mmio_read_32(ACPU_SC_PDBGUP_MBIST);
63e246617bSLeo Yan 	mmio_write_32(ACPU_SC_PDBGUP_MBIST, val | enable);
64e246617bSLeo Yan 	do {
65e246617bSLeo Yan 		/* RAW barrier */
66e246617bSLeo Yan 		val = mmio_read_32(ACPU_SC_PDBGUP_MBIST);
67e246617bSLeo Yan 	} while (!(val & enable));
68e246617bSLeo Yan }
69e246617bSLeo Yan 
hisi_pwrc_setup(void)70127793daSHaojian Zhuang int hisi_pwrc_setup(void)
71127793daSHaojian Zhuang {
72127793daSHaojian Zhuang 	unsigned int reg, sec_entrypoint;
73127793daSHaojian Zhuang 	extern char pm_asm_code[], pm_asm_code_end[];
74127793daSHaojian Zhuang 	extern char v7_asm[], v7_asm_end[];
75127793daSHaojian Zhuang 
76127793daSHaojian Zhuang 	sec_entrypoint = PWRCTRL_ACPU_ASM_CODE_BASE;
77127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(0), sec_entrypoint >> 2);
78127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(1), sec_entrypoint >> 2);
79127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(2), sec_entrypoint >> 2);
80127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(3), sec_entrypoint >> 2);
81127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(4), sec_entrypoint >> 2);
82127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(5), sec_entrypoint >> 2);
83127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(6), sec_entrypoint >> 2);
84127793daSHaojian Zhuang 	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(7), sec_entrypoint >> 2);
85127793daSHaojian Zhuang 
86127793daSHaojian Zhuang 	memset((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, 0, 0x400);
87127793daSHaojian Zhuang 	memcpy((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, (void *)v7_asm,
88127793daSHaojian Zhuang 	       v7_asm_end - v7_asm);
89127793daSHaojian Zhuang 
90127793daSHaojian Zhuang 	memcpy((void *)PWRCTRL_ACPU_ASM_CODE_BASE, (void *)pm_asm_code,
91127793daSHaojian Zhuang 	       pm_asm_code_end - pm_asm_code);
92127793daSHaojian Zhuang 
93127793daSHaojian Zhuang 	reg = mmio_read_32(AO_SC_SYS_CTRL1);
943506ff11SLeo Yan 	/* Remap SRAM address for ACPU */
95127793daSHaojian Zhuang 	reg |= AO_SC_SYS_CTRL1_REMAP_SRAM_AARM |
96127793daSHaojian Zhuang 	       AO_SC_SYS_CTRL1_REMAP_SRAM_AARM_MSK;
973506ff11SLeo Yan 
983506ff11SLeo Yan 	/* Enable reset signal for watchdog */
993506ff11SLeo Yan 	reg |= AO_SC_SYS_CTRL1_AARM_WD_RST_CFG |
1003506ff11SLeo Yan 	       AO_SC_SYS_CTRL1_AARM_WD_RST_CFG_MSK;
101127793daSHaojian Zhuang 	mmio_write_32(AO_SC_SYS_CTRL1, reg);
102127793daSHaojian Zhuang 
103127793daSHaojian Zhuang 	return 0;
104127793daSHaojian Zhuang }
105