• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)20 void 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)48 static 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)65 void 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)77 void 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