1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <platform_def.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <common/debug.h> 12*91f16700Schasinglulu #include <common/fdt_fixup.h> 13*91f16700Schasinglulu #include <lib/mmio.h> 14*91f16700Schasinglulu #include <lib/psci/psci.h> 15*91f16700Schasinglulu 16*91f16700Schasinglulu #include <sunxi_cpucfg.h> 17*91f16700Schasinglulu #include <sunxi_private.h> 18*91f16700Schasinglulu 19*91f16700Schasinglulu static bool psci_is_scpi; 20*91f16700Schasinglulu 21*91f16700Schasinglulu #if SUNXI_PSCI_USE_SCPI 22*91f16700Schasinglulu bool sunxi_psci_is_scpi(void) 23*91f16700Schasinglulu { 24*91f16700Schasinglulu return psci_is_scpi; 25*91f16700Schasinglulu } 26*91f16700Schasinglulu #endif 27*91f16700Schasinglulu 28*91f16700Schasinglulu #ifndef SUNXI_ALT_RVBAR_LO_REG 29*91f16700Schasinglulu #define SUNXI_ALT_RVBAR_LO_REG(n) 0 30*91f16700Schasinglulu #define SUNXI_ALT_RVBAR_HI_REG(n) 0 31*91f16700Schasinglulu #endif 32*91f16700Schasinglulu 33*91f16700Schasinglulu int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint) 34*91f16700Schasinglulu { 35*91f16700Schasinglulu /* The non-secure entry point must be in DRAM */ 36*91f16700Schasinglulu if (ns_entrypoint < SUNXI_DRAM_BASE) { 37*91f16700Schasinglulu return PSCI_E_INVALID_ADDRESS; 38*91f16700Schasinglulu } 39*91f16700Schasinglulu 40*91f16700Schasinglulu return PSCI_E_SUCCESS; 41*91f16700Schasinglulu } 42*91f16700Schasinglulu 43*91f16700Schasinglulu int plat_setup_psci_ops(uintptr_t sec_entrypoint, 44*91f16700Schasinglulu const plat_psci_ops_t **psci_ops) 45*91f16700Schasinglulu { 46*91f16700Schasinglulu assert(psci_ops); 47*91f16700Schasinglulu 48*91f16700Schasinglulu /* Program all CPU entry points. */ 49*91f16700Schasinglulu for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; ++cpu) { 50*91f16700Schasinglulu if (sunxi_cpucfg_has_per_cluster_regs()) { 51*91f16700Schasinglulu mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu), 52*91f16700Schasinglulu sec_entrypoint & 0xffffffff); 53*91f16700Schasinglulu mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu), 54*91f16700Schasinglulu sec_entrypoint >> 32); 55*91f16700Schasinglulu } else { 56*91f16700Schasinglulu mmio_write_32(SUNXI_ALT_RVBAR_LO_REG(cpu), 57*91f16700Schasinglulu sec_entrypoint & 0xffffffff); 58*91f16700Schasinglulu mmio_write_32(SUNXI_ALT_RVBAR_HI_REG(cpu), 59*91f16700Schasinglulu sec_entrypoint >> 32); 60*91f16700Schasinglulu } 61*91f16700Schasinglulu } 62*91f16700Schasinglulu 63*91f16700Schasinglulu if (sunxi_set_scpi_psci_ops(psci_ops) == 0) { 64*91f16700Schasinglulu INFO("PSCI: Suspend is available via SCPI\n"); 65*91f16700Schasinglulu psci_is_scpi = true; 66*91f16700Schasinglulu } else { 67*91f16700Schasinglulu INFO("PSCI: Suspend is unavailable\n"); 68*91f16700Schasinglulu sunxi_set_native_psci_ops(psci_ops); 69*91f16700Schasinglulu } 70*91f16700Schasinglulu 71*91f16700Schasinglulu return 0; 72*91f16700Schasinglulu } 73