diff options
Diffstat (limited to '')
-rw-r--r-- | plat/hisilicon/hikey/hisi_pwrc.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/plat/hisilicon/hikey/hisi_pwrc.c b/plat/hisilicon/hikey/hisi_pwrc.c new file mode 100644 index 0000000..e2e3db7 --- /dev/null +++ b/plat/hisilicon/hikey/hisi_pwrc.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include <platform_def.h> + +#include <common/debug.h> +#include <lib/mmio.h> + +#include <hi6220_regs_acpu.h> +#include <hi6220_regs_ao.h> +#include <hisi_ipc.h> +#include <hisi_pwrc.h> +#include <hisi_sram_map.h> + +#define CLUSTER_CORE_COUNT (4) +#define CLUSTER_CORE_MASK ((1 << CLUSTER_CORE_COUNT) - 1) + +void hisi_pwrc_set_core_bx_addr(unsigned int core, unsigned int cluster, + uintptr_t entry_point) +{ + uintptr_t *core_entry = (uintptr_t *)PWRCTRL_ACPU_ASM_D_ARM_PARA_AD; + unsigned int i; + + if (!core_entry) { + INFO("%s: core entry point is null!\n", __func__); + return; + } + + i = cluster * CLUSTER_CORE_COUNT + core; + mmio_write_64((uintptr_t)(core_entry + i), entry_point); +} + +void hisi_pwrc_set_cluster_wfi(unsigned int cluster) +{ + unsigned int reg = 0; + + if (cluster == 0) { + reg = mmio_read_32(ACPU_SC_SNOOP_PWD); + reg |= PD_DETECT_START0; + mmio_write_32(ACPU_SC_SNOOP_PWD, reg); + } else if (cluster == 1) { + reg = mmio_read_32(ACPU_SC_SNOOP_PWD); + reg |= PD_DETECT_START1; + mmio_write_32(ACPU_SC_SNOOP_PWD, reg); + } +} + +void hisi_pwrc_enable_debug(unsigned int core, unsigned int cluster) +{ + unsigned int val, enable; + + enable = 1U << (core + PDBGUP_CLUSTER1_SHIFT * cluster); + + /* Enable debug module */ + val = mmio_read_32(ACPU_SC_PDBGUP_MBIST); + mmio_write_32(ACPU_SC_PDBGUP_MBIST, val | enable); + do { + /* RAW barrier */ + val = mmio_read_32(ACPU_SC_PDBGUP_MBIST); + } while (!(val & enable)); +} + +int hisi_pwrc_setup(void) +{ + unsigned int reg, sec_entrypoint; + extern char pm_asm_code[], pm_asm_code_end[]; + extern char v7_asm[], v7_asm_end[]; + + sec_entrypoint = PWRCTRL_ACPU_ASM_CODE_BASE; + mmio_write_32(ACPU_SC_CPUx_RVBARADDR(0), sec_entrypoint >> 2); + mmio_write_32(ACPU_SC_CPUx_RVBARADDR(1), sec_entrypoint >> 2); + mmio_write_32(ACPU_SC_CPUx_RVBARADDR(2), sec_entrypoint >> 2); + mmio_write_32(ACPU_SC_CPUx_RVBARADDR(3), sec_entrypoint >> 2); + mmio_write_32(ACPU_SC_CPUx_RVBARADDR(4), sec_entrypoint >> 2); + mmio_write_32(ACPU_SC_CPUx_RVBARADDR(5), sec_entrypoint >> 2); + mmio_write_32(ACPU_SC_CPUx_RVBARADDR(6), sec_entrypoint >> 2); + mmio_write_32(ACPU_SC_CPUx_RVBARADDR(7), sec_entrypoint >> 2); + + memset((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, 0, 0x400); + memcpy((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, (void *)v7_asm, + v7_asm_end - v7_asm); + + memcpy((void *)PWRCTRL_ACPU_ASM_CODE_BASE, (void *)pm_asm_code, + pm_asm_code_end - pm_asm_code); + + reg = mmio_read_32(AO_SC_SYS_CTRL1); + /* Remap SRAM address for ACPU */ + reg |= AO_SC_SYS_CTRL1_REMAP_SRAM_AARM | + AO_SC_SYS_CTRL1_REMAP_SRAM_AARM_MSK; + + /* Enable reset signal for watchdog */ + reg |= AO_SC_SYS_CTRL1_AARM_WD_RST_CFG | + AO_SC_SYS_CTRL1_AARM_WD_RST_CFG_MSK; + mmio_write_32(AO_SC_SYS_CTRL1, reg); + + return 0; +} |