1 /* 2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch.h> 8 #include <assert.h> 9 #include <cci400.h> 10 #include <debug.h> 11 #include <mmio.h> 12 #include <stdint.h> 13 14 #define MAX_CLUSTERS 2 15 16 static uintptr_t cci_base_addr; 17 static unsigned int cci_cluster_ix_to_iface[MAX_CLUSTERS]; 18 19 cci_init(uintptr_t cci_base,int slave_iface3_cluster_ix,int slave_iface4_cluster_ix)20void cci_init(uintptr_t cci_base, 21 int slave_iface3_cluster_ix, 22 int slave_iface4_cluster_ix) 23 { 24 /* 25 * Check the passed arguments are valid. The cluster indices must be 26 * less than MAX_CLUSTERS, not the same as each other and at least one 27 * of them must refer to a valid cluster index. 28 */ 29 assert(cci_base); 30 assert(slave_iface3_cluster_ix < MAX_CLUSTERS); 31 assert(slave_iface4_cluster_ix < MAX_CLUSTERS); 32 assert(slave_iface3_cluster_ix != slave_iface4_cluster_ix); 33 assert((slave_iface3_cluster_ix >= 0) || 34 (slave_iface4_cluster_ix >= 0)); 35 36 WARN("Please migrate to common cci driver, This driver will be" \ 37 " deprecated in future\n"); 38 39 cci_base_addr = cci_base; 40 if (slave_iface3_cluster_ix >= 0) 41 cci_cluster_ix_to_iface[slave_iface3_cluster_ix] = 42 SLAVE_IFACE3_OFFSET; 43 if (slave_iface4_cluster_ix >= 0) 44 cci_cluster_ix_to_iface[slave_iface4_cluster_ix] = 45 SLAVE_IFACE4_OFFSET; 46 } 47 get_slave_iface_base(unsigned long mpidr)48static inline unsigned long get_slave_iface_base(unsigned long mpidr) 49 { 50 /* 51 * We assume the TF topology code allocates affinity instances 52 * consecutively from zero. 53 * It is a programming error if this is called without initializing 54 * the slave interface to use for this cluster. 55 */ 56 unsigned int cluster_id = 57 (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; 58 59 assert(cluster_id < MAX_CLUSTERS); 60 assert(cci_cluster_ix_to_iface[cluster_id] != 0); 61 62 return cci_base_addr + cci_cluster_ix_to_iface[cluster_id]; 63 } 64 cci_enable_cluster_coherency(unsigned long mpidr)65void cci_enable_cluster_coherency(unsigned long mpidr) 66 { 67 assert(cci_base_addr); 68 /* Enable Snoops and DVM messages */ 69 mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG, 70 DVM_EN_BIT | SNOOP_EN_BIT); 71 72 /* Wait for the dust to settle down */ 73 while (mmio_read_32(cci_base_addr + STATUS_REG) & CHANGE_PENDING_BIT) 74 ; 75 } 76 cci_disable_cluster_coherency(unsigned long mpidr)77void cci_disable_cluster_coherency(unsigned long mpidr) 78 { 79 assert(cci_base_addr); 80 /* Disable Snoops and DVM messages */ 81 mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG, 82 ~(DVM_EN_BIT | SNOOP_EN_BIT)); 83 84 /* Wait for the dust to settle down */ 85 while (mmio_read_32(cci_base_addr + STATUS_REG) & CHANGE_PENDING_BIT) 86 ; 87 } 88 89