You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.8 KiB
104 lines
2.8 KiB
/*
|
|
* 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;
|
|
}
|
|
|