1 /* 2 * Copyright (c) 2015-2017, 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 <cci.h> 10 #include <debug.h> 11 #include <mmio.h> 12 #include <stdint.h> 13 14 static uintptr_t g_cci_base; 15 static unsigned int g_max_master_id; 16 static const int *g_cci_slave_if_map; 17 18 #if ENABLE_ASSERTIONS 19 static int validate_cci_map(const int *map) 20 { 21 unsigned int valid_cci_map = 0; 22 int slave_if_id; 23 int i; 24 25 /* Validate the map */ 26 for (i = 0; i <= g_max_master_id; i++) { 27 slave_if_id = map[i]; 28 29 if (slave_if_id < 0) 30 continue; 31 32 if (slave_if_id >= CCI_SLAVE_INTERFACE_COUNT) { 33 ERROR("Slave interface ID is invalid\n"); 34 return 0; 35 } 36 37 if (valid_cci_map & (1 << slave_if_id)) { 38 ERROR("Multiple masters are assigned same slave interface ID\n"); 39 return 0; 40 } 41 valid_cci_map |= 1 << slave_if_id; 42 } 43 44 if (!valid_cci_map) { 45 ERROR("No master is assigned a valid slave interface\n"); 46 return 0; 47 } 48 49 return 1; 50 } 51 #endif /* ENABLE_ASSERTIONS */ 52 53 void cci_init(uintptr_t cci_base, 54 const int *map, 55 unsigned int num_cci_masters) 56 { 57 assert(map); 58 assert(cci_base); 59 60 g_cci_base = cci_base; 61 62 /* 63 * Master Id's are assigned from zero, So in an array of size n 64 * the max master id is (n - 1). 65 */ 66 g_max_master_id = num_cci_masters - 1; 67 68 assert(validate_cci_map(map)); 69 g_cci_slave_if_map = map; 70 } 71 72 void cci_enable_snoop_dvm_reqs(unsigned int master_id) 73 { 74 int slave_if_id; 75 76 assert(g_cci_base); 77 assert(master_id <= g_max_master_id); 78 79 slave_if_id = g_cci_slave_if_map[master_id]; 80 assert((slave_if_id < CCI_SLAVE_INTERFACE_COUNT) && (slave_if_id >= 0)); 81 82 /* 83 * Enable Snoops and DVM messages, no need for Read/Modify/Write as 84 * rest of bits are write ignore 85 */ 86 mmio_write_32(g_cci_base + 87 SLAVE_IFACE_OFFSET(slave_if_id) + 88 SNOOP_CTRL_REG, DVM_EN_BIT | SNOOP_EN_BIT); 89 90 /* Wait for the dust to settle down */ 91 while (mmio_read_32(g_cci_base + STATUS_REG) & CHANGE_PENDING_BIT) 92 ; 93 } 94 95 void cci_disable_snoop_dvm_reqs(unsigned int master_id) 96 { 97 int slave_if_id; 98 99 assert(g_cci_base); 100 assert(master_id <= g_max_master_id); 101 102 slave_if_id = g_cci_slave_if_map[master_id]; 103 assert((slave_if_id < CCI_SLAVE_INTERFACE_COUNT) && (slave_if_id >= 0)); 104 105 /* 106 * Disable Snoops and DVM messages, no need for Read/Modify/Write as 107 * rest of bits are write ignore. 108 */ 109 mmio_write_32(g_cci_base + 110 SLAVE_IFACE_OFFSET(slave_if_id) + 111 SNOOP_CTRL_REG, ~(DVM_EN_BIT | SNOOP_EN_BIT)); 112 113 /* Wait for the dust to settle down */ 114 while (mmio_read_32(g_cci_base + STATUS_REG) & CHANGE_PENDING_BIT) 115 ; 116 } 117 118