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