blob: 98de77d10dfb02721939821ca9a3148bc4cbca63 [file] [log] [blame]
Usama Arif82e95092019-06-18 16:46:05 +01001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <lib/psci/psci.h>
8#include <plat/arm/common/plat_arm.h>
Usama Arif79913a82019-09-19 11:07:24 +01009#include <plat/common/platform.h>
10#include <drivers/arm/gicv2.h>
Usama Arif82e95092019-06-18 16:46:05 +010011
12/*******************************************************************************
Usama Arif79913a82019-09-19 11:07:24 +010013 * Platform handler called when a power domain is about to be turned on. The
14 * mpidr determines the CPU to be turned on.
15 ******************************************************************************/
16static int a5ds_pwr_domain_on(u_register_t mpidr)
17{
18 unsigned int pos = plat_core_pos_by_mpidr(mpidr);
19 uint64_t *hold_base = (uint64_t *)A5DS_HOLD_BASE;
20
21 hold_base[pos] = A5DS_HOLD_STATE_GO;
22 dsbish();
23 sev();
24
25 return PSCI_E_SUCCESS;
26}
27
28/*******************************************************************************
29 * Platform handler called when a power domain has just been powered on after
30 * being turned off earlier. The target_state encodes the low power state that
31 * each level has woken up from.
32 ******************************************************************************/
33void a5ds_pwr_domain_on_finish(const psci_power_state_t *target_state)
34{
35 /* TODO: This setup is needed only after a cold boot*/
36 gicv2_pcpu_distif_init();
37
38 /* Enable the gic cpu interface */
39 gicv2_cpuif_enable();
40}
41
42/*******************************************************************************
Usama Arif82e95092019-06-18 16:46:05 +010043 * Export the platform handlers via a5ds_psci_pm_ops. The ARM Standard
44 * platform layer will take care of registering the handlers with PSCI.
45 ******************************************************************************/
46plat_psci_ops_t a5ds_psci_pm_ops = {
47 /* dummy struct */
48 .validate_ns_entrypoint = NULL,
Usama Arif79913a82019-09-19 11:07:24 +010049 .pwr_domain_on = a5ds_pwr_domain_on,
50 .pwr_domain_on_finish = a5ds_pwr_domain_on_finish
Usama Arif82e95092019-06-18 16:46:05 +010051};
52
53int __init plat_setup_psci_ops(uintptr_t sec_entrypoint,
54 const plat_psci_ops_t **psci_ops)
55{
Usama Arif79913a82019-09-19 11:07:24 +010056 uintptr_t *mailbox = (void *)A5DS_TRUSTED_MAILBOX_BASE;
57 *mailbox = sec_entrypoint;
58
Usama Arif82e95092019-06-18 16:46:05 +010059 *psci_ops = &a5ds_psci_pm_ops;
60
61 return 0;
62}