blob: cc734b005445e76ab7ac70734d578cab888e2445 [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 */
Usama Arif78163aa2019-09-26 16:07:53 +01006#include <assert.h>
Usama Arif82e95092019-06-18 16:46:05 +01007
8#include <lib/psci/psci.h>
9#include <plat/arm/common/plat_arm.h>
Usama Arif79913a82019-09-19 11:07:24 +010010#include <plat/common/platform.h>
11#include <drivers/arm/gicv2.h>
Usama Arif82e95092019-06-18 16:46:05 +010012
13/*******************************************************************************
Usama Arif79913a82019-09-19 11:07:24 +010014 * Platform handler called when a power domain is about to be turned on. The
15 * mpidr determines the CPU to be turned on.
16 ******************************************************************************/
17static int a5ds_pwr_domain_on(u_register_t mpidr)
18{
19 unsigned int pos = plat_core_pos_by_mpidr(mpidr);
20 uint64_t *hold_base = (uint64_t *)A5DS_HOLD_BASE;
21
22 hold_base[pos] = A5DS_HOLD_STATE_GO;
23 dsbish();
24 sev();
25
26 return PSCI_E_SUCCESS;
27}
28
29/*******************************************************************************
30 * Platform handler called when a power domain has just been powered on after
31 * being turned off earlier. The target_state encodes the low power state that
32 * each level has woken up from.
33 ******************************************************************************/
34void a5ds_pwr_domain_on_finish(const psci_power_state_t *target_state)
35{
36 /* TODO: This setup is needed only after a cold boot*/
37 gicv2_pcpu_distif_init();
38
39 /* Enable the gic cpu interface */
40 gicv2_cpuif_enable();
41}
42
43/*******************************************************************************
Usama Arif78163aa2019-09-26 16:07:53 +010044 * Platform handler called when a power domain is about to be turned off. The
45 * target_state encodes the power state that each level should transition to.
46 * a5ds only has always-on power domain and there is no power control present.
47 ******************************************************************************/
48void a5ds_pwr_domain_off(const psci_power_state_t *target_state)
49{
50 ERROR("CPU_OFF not supported on this platform\n");
51 assert(false);
52 panic();
53}
54
55/*******************************************************************************
Usama Arif82e95092019-06-18 16:46:05 +010056 * Export the platform handlers via a5ds_psci_pm_ops. The ARM Standard
57 * platform layer will take care of registering the handlers with PSCI.
58 ******************************************************************************/
59plat_psci_ops_t a5ds_psci_pm_ops = {
60 /* dummy struct */
61 .validate_ns_entrypoint = NULL,
Usama Arif79913a82019-09-19 11:07:24 +010062 .pwr_domain_on = a5ds_pwr_domain_on,
Usama Arif78163aa2019-09-26 16:07:53 +010063 .pwr_domain_on_finish = a5ds_pwr_domain_on_finish,
64 .pwr_domain_off = a5ds_pwr_domain_off
Usama Arif82e95092019-06-18 16:46:05 +010065};
66
67int __init plat_setup_psci_ops(uintptr_t sec_entrypoint,
68 const plat_psci_ops_t **psci_ops)
69{
Usama Arif79913a82019-09-19 11:07:24 +010070 uintptr_t *mailbox = (void *)A5DS_TRUSTED_MAILBOX_BASE;
71 *mailbox = sec_entrypoint;
72
Usama Arif82e95092019-06-18 16:46:05 +010073 *psci_ops = &a5ds_psci_pm_ops;
74
75 return 0;
76}