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