From cae3ef992e24b9ceb2ba1cd7d2ef0c6faaf29e0a Mon Sep 17 00:00:00 2001 From: Dan Handley Date: Mon, 4 Aug 2014 16:11:15 +0100 Subject: Remove platform dependency in CCI-400 driver * Create cci_init() function in CCI-400 driver to allow platform to provide arguments needed by the driver (i.e. base address and cluster indices for the ACE slave interfaces). * Rename cci_(en|dis)able_coherency to cci_(en|dis)able_cluster_coherency to make it clear that the driver only enables/disables the coherency of CPU clusters and not other devices connected to the CCI-400. * Update FVP port to use new cci_init() function and remove unnecessary CCI defintions from platform_def.h. Also rename fvp_cci_setup() to fvp_cci_enable() to more clearly differentiate between CCI initialization and enabling. THIS CHANGE REQUIRES PLATFORM PORTS THAT USE THE CCI-400 DRIVER TO BE UPDATED Fixes ARM-software/tf-issues#168 Change-Id: I1946a51409b91217b92285b6375082619f607fec --- drivers/arm/cci400/cci400.c | 58 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/arm/cci400/cci400.c b/drivers/arm/cci400/cci400.c index af10f21..6a8737a 100644 --- a/drivers/arm/cci400/cci400.c +++ b/drivers/arm/cci400/cci400.c @@ -28,34 +28,80 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include #include -#include + +#define MAX_CLUSTERS 2 + +static unsigned long cci_base_addr; +static unsigned int cci_cluster_ix_to_iface[MAX_CLUSTERS]; + + +void cci_init(unsigned long cci_base, + int slave_iface3_cluster_ix, + int slave_iface4_cluster_ix) +{ + /* + * Check the passed arguments are valid. The cluster indices must be + * less than MAX_CLUSTERS, not the same as each other and at least one + * of them must be refer to a valid cluster index. + */ + assert(cci_base); + assert(slave_iface3_cluster_ix < MAX_CLUSTERS); + assert(slave_iface4_cluster_ix < MAX_CLUSTERS); + assert(slave_iface3_cluster_ix != slave_iface4_cluster_ix); + assert((slave_iface3_cluster_ix >= 0) || + (slave_iface3_cluster_ix >= 0)); + + cci_base_addr = cci_base; + if (slave_iface3_cluster_ix >= 0) + cci_cluster_ix_to_iface[slave_iface3_cluster_ix] = + SLAVE_IFACE3_OFFSET; + if (slave_iface4_cluster_ix >= 0) + cci_cluster_ix_to_iface[slave_iface4_cluster_ix] = + SLAVE_IFACE4_OFFSET; +} static inline unsigned long get_slave_iface_base(unsigned long mpidr) { - return CCI400_BASE + SLAVE_IFACE_OFFSET(CCI400_SL_IFACE_INDEX(mpidr)); + /* + * We assume the TF topology code allocates affinity instances + * consecutively from zero. + * It is a programming error if this is called without initializing + * the slave interface to use for this cluster. + */ + unsigned int cluster_id = + (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + + assert(cluster_id < MAX_CLUSTERS); + assert(cci_cluster_ix_to_iface[cluster_id] != 0); + + return cci_base_addr + cci_cluster_ix_to_iface[cluster_id]; } -void cci_enable_coherency(unsigned long mpidr) +void cci_enable_cluster_coherency(unsigned long mpidr) { + assert(cci_base_addr); /* Enable Snoops and DVM messages */ mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG, DVM_EN_BIT | SNOOP_EN_BIT); /* Wait for the dust to settle down */ - while (mmio_read_32(CCI400_BASE + STATUS_REG) & CHANGE_PENDING_BIT) + while (mmio_read_32(cci_base_addr + STATUS_REG) & CHANGE_PENDING_BIT) ; } -void cci_disable_coherency(unsigned long mpidr) +void cci_disable_cluster_coherency(unsigned long mpidr) { + assert(cci_base_addr); /* Disable Snoops and DVM messages */ mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG, ~(DVM_EN_BIT | SNOOP_EN_BIT)); /* Wait for the dust to settle down */ - while (mmio_read_32(CCI400_BASE + STATUS_REG) & CHANGE_PENDING_BIT) + while (mmio_read_32(cci_base_addr + STATUS_REG) & CHANGE_PENDING_BIT) ; } -- cgit v1.2.3