blob: 37d00f66c89d8771466e1f689b073b5c1da4398c [file] [log] [blame]
Siva Durga Prasad Paladugufe4af662018-09-25 18:44:58 +05301/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <debug.h>
8#include <mmio.h>
9#include <platform.h>
10#include <psci.h>
11#include "versal_private.h"
12
13static uintptr_t versal_sec_entry;
14
15static int versal_nopmc_pwr_domain_on(u_register_t mpidr)
16{
17 uint32_t r;
18 unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
19
20 VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
21
22 if (cpu_id == -1)
23 return PSCI_E_INTERN_FAIL;
24
25 /*
26 * program RVBAR
27 */
28 mmio_write_32(FPD_APU_RVBAR_L_0 + (cpu_id << 3), versal_sec_entry);
29 mmio_write_32(FPD_APU_RVBAR_H_0 + (cpu_id << 3), versal_sec_entry >> 32);
30
31 /*
32 * clear VINITHI
33 */
34 r = mmio_read_32(FPD_APU_CONFIG_0);
35 r &= ~(1 << FPD_APU_CONFIG_0_VINITHI_SHIFT << cpu_id);
36 mmio_write_32(FPD_APU_CONFIG_0, r);
37
38 /*
39 * FIXME: Add power up sequence, By default it works
40 * now without the need of it as it was powered up by
41 * default.
42 */
43
44 /*
45 * clear power down request
46 */
47 r = mmio_read_32(FPD_APU_PWRCTL);
48 r &= ~(1 << cpu_id);
49 mmio_write_32(FPD_APU_PWRCTL, r);
50
51 /*
52 * release core reset
53 */
54 r = mmio_read_32(CRF_RST_APU);
55 r &= ~((CRF_RST_APU_ACPU_PWRON_RESET |
56 CRF_RST_APU_ACPU_RESET) << cpu_id);
57 mmio_write_32(CRF_RST_APU, r);
58
59 return PSCI_E_SUCCESS;
60}
61
62void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
63{
64 /* Enable the gic cpu interface */
65 plat_versal_gic_pcpu_init();
66
67 /* Program the gic per-cpu distributor or re-distributor interface */
68 plat_versal_gic_cpuif_enable();
69}
70
71static const struct plat_psci_ops versal_nopmc_psci_ops = {
72 .pwr_domain_on = versal_nopmc_pwr_domain_on,
73 .pwr_domain_on_finish = versal_pwr_domain_on_finish,
74};
75
76/*******************************************************************************
77 * Export the platform specific power ops.
78 ******************************************************************************/
79int plat_setup_psci_ops(uintptr_t sec_entrypoint,
80 const struct plat_psci_ops **psci_ops)
81{
82 versal_sec_entry = sec_entrypoint;
83
84 *psci_ops = &versal_nopmc_psci_ops;
85
86 return 0;
87}