diff options
author | Dan Handley <dan.handley@arm.com> | 2014-08-04 16:11:15 +0100 |
---|---|---|
committer | Dan Handley <dan.handley@arm.com> | 2014-08-14 10:49:20 +0100 |
commit | cae3ef992e24b9ceb2ba1cd7d2ef0c6faaf29e0a (patch) | |
tree | 453461858d984fca597da46d983a33e9fda89adf /drivers | |
parent | f0e240d7f59cbf1cb99fc358ddec967cad8bf3df (diff) |
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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/arm/cci400/cci400.c | 58 |
1 files changed, 52 insertions, 6 deletions
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 <arch.h> +#include <assert.h> #include <cci400.h> #include <mmio.h> -#include <platform_def.h> + +#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) ; } |