arm-trusted-firmware/plat/arm/board/a5ds/a5ds_pm.c
Vishnu Banavath c20c05252c drivers: add a driver for snoop control unit
The SCU connects one to four Cortex-A5/Cortex-A9 processors
to the memory system through the AXI interfaces.

The SCU functions are to:
- maintain data cache coherency between the Cortex-A5/Cortex-A9
  processors
- initiate L2 AXI memory accesses
- arbitrate between Cortex-A5/Cortex-A9 processors requesting
  L2 accesses
- manage ACP accesses.

Snoop Control Unit will enable to snoop on other CPUs caches.
This is very important when it comes to synchronizing data between
CPUs. As an example, there is a high chance that data might be
cache'd and other CPUs can't see the change. In such cases,
if snoop control unit is enabled, data is synchoronized immediately
between CPUs and the changes are visible to other CPUs.

This driver provides functionality to enable SCU as well as enabling
user to know the following
- number of CPUs present
- is a particular CPU operating in SMP mode or AMP mode
- data cache size of a particular CPU
- does SCU has ACP port
- is L2CPRESENT

Change-Id: I0d977970154fa60df57caf449200d471f02312a0
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
2020-01-03 10:44:28 +00:00

75 lines
2.6 KiB
C

/*
* Copyright (c) 2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <drivers/arm/gicv2.h>
#include <lib/psci/psci.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
/*******************************************************************************
* Platform handler called when a power domain is about to be turned on. The
* mpidr determines the CPU to be turned on.
******************************************************************************/
static int a5ds_pwr_domain_on(u_register_t mpidr)
{
unsigned int pos = plat_core_pos_by_mpidr(mpidr);
uint64_t *hold_base = (uint64_t *)A5DS_HOLD_BASE;
hold_base[pos] = A5DS_HOLD_STATE_GO;
dsbish();
sev();
return PSCI_E_SUCCESS;
}
/*******************************************************************************
* Platform handler called when a power domain has just been powered on after
* being turned off earlier. The target_state encodes the low power state that
* each level has woken up from.
******************************************************************************/
void a5ds_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
/* TODO: This setup is needed only after a cold boot*/
gicv2_pcpu_distif_init();
/* Enable the gic cpu interface */
gicv2_cpuif_enable();
}
/*******************************************************************************
* Platform handler called when a power domain is about to be turned off. The
* target_state encodes the power state that each level should transition to.
* a5ds only has always-on power domain and there is no power control present.
******************************************************************************/
void a5ds_pwr_domain_off(const psci_power_state_t *target_state)
{
ERROR("CPU_OFF not supported on this platform\n");
assert(false);
panic();
}
/*******************************************************************************
* Export the platform handlers via a5ds_psci_pm_ops. The ARM Standard
* platform layer will take care of registering the handlers with PSCI.
******************************************************************************/
plat_psci_ops_t a5ds_psci_pm_ops = {
/* dummy struct */
.validate_ns_entrypoint = NULL,
.pwr_domain_on = a5ds_pwr_domain_on,
.pwr_domain_on_finish = a5ds_pwr_domain_on_finish,
.pwr_domain_off = a5ds_pwr_domain_off
};
int __init plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
uintptr_t *mailbox = (void *)A5DS_TRUSTED_MAILBOX_BASE;
*mailbox = sec_entrypoint;
*psci_ops = &a5ds_psci_pm_ops;
return 0;
}