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 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 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 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 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