1*23e47edeSVikram Kanigiri /* 2*23e47edeSVikram Kanigiri * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3*23e47edeSVikram Kanigiri * 4*23e47edeSVikram Kanigiri * Redistribution and use in source and binary forms, with or without 5*23e47edeSVikram Kanigiri * modification, are permitted provided that the following conditions are met: 6*23e47edeSVikram Kanigiri * 7*23e47edeSVikram Kanigiri * Redistributions of source code must retain the above copyright notice, this 8*23e47edeSVikram Kanigiri * list of conditions and the following disclaimer. 9*23e47edeSVikram Kanigiri * 10*23e47edeSVikram Kanigiri * Redistributions in binary form must reproduce the above copyright notice, 11*23e47edeSVikram Kanigiri * this list of conditions and the following disclaimer in the documentation 12*23e47edeSVikram Kanigiri * and/or other materials provided with the distribution. 13*23e47edeSVikram Kanigiri * 14*23e47edeSVikram Kanigiri * Neither the name of ARM nor the names of its contributors may be used 15*23e47edeSVikram Kanigiri * to endorse or promote products derived from this software without specific 16*23e47edeSVikram Kanigiri * prior written permission. 17*23e47edeSVikram Kanigiri * 18*23e47edeSVikram Kanigiri * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*23e47edeSVikram Kanigiri * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*23e47edeSVikram Kanigiri * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*23e47edeSVikram Kanigiri * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*23e47edeSVikram Kanigiri * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*23e47edeSVikram Kanigiri * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*23e47edeSVikram Kanigiri * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*23e47edeSVikram Kanigiri * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*23e47edeSVikram Kanigiri * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*23e47edeSVikram Kanigiri * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*23e47edeSVikram Kanigiri * POSSIBILITY OF SUCH DAMAGE. 29*23e47edeSVikram Kanigiri */ 30*23e47edeSVikram Kanigiri 31*23e47edeSVikram Kanigiri #include <arch.h> 32*23e47edeSVikram Kanigiri #include <assert.h> 33*23e47edeSVikram Kanigiri #include <cci.h> 34*23e47edeSVikram Kanigiri #include <debug.h> 35*23e47edeSVikram Kanigiri #include <mmio.h> 36*23e47edeSVikram Kanigiri 37*23e47edeSVikram Kanigiri static unsigned long g_cci_base; 38*23e47edeSVikram Kanigiri static unsigned int g_max_master_id; 39*23e47edeSVikram Kanigiri static const int *g_cci_slave_if_map; 40*23e47edeSVikram Kanigiri 41*23e47edeSVikram Kanigiri #if DEBUG 42*23e47edeSVikram Kanigiri static int validate_cci_map(const int *map) 43*23e47edeSVikram Kanigiri { 44*23e47edeSVikram Kanigiri unsigned int valid_cci_map = 0; 45*23e47edeSVikram Kanigiri int slave_if_id; 46*23e47edeSVikram Kanigiri int i; 47*23e47edeSVikram Kanigiri 48*23e47edeSVikram Kanigiri /* Validate the map */ 49*23e47edeSVikram Kanigiri for (i = 0; i <= g_max_master_id; i++) { 50*23e47edeSVikram Kanigiri slave_if_id = map[i]; 51*23e47edeSVikram Kanigiri 52*23e47edeSVikram Kanigiri if (slave_if_id < 0) 53*23e47edeSVikram Kanigiri continue; 54*23e47edeSVikram Kanigiri 55*23e47edeSVikram Kanigiri if (slave_if_id >= CCI_SLAVE_INTERFACE_COUNT) { 56*23e47edeSVikram Kanigiri tf_printf("Slave interface ID is invalid\n"); 57*23e47edeSVikram Kanigiri return 0; 58*23e47edeSVikram Kanigiri } 59*23e47edeSVikram Kanigiri 60*23e47edeSVikram Kanigiri if (valid_cci_map & (1 << slave_if_id)) { 61*23e47edeSVikram Kanigiri tf_printf("Multiple masters are assigned same" 62*23e47edeSVikram Kanigiri " slave interface ID\n"); 63*23e47edeSVikram Kanigiri return 0; 64*23e47edeSVikram Kanigiri } 65*23e47edeSVikram Kanigiri valid_cci_map |= 1 << slave_if_id; 66*23e47edeSVikram Kanigiri } 67*23e47edeSVikram Kanigiri 68*23e47edeSVikram Kanigiri if (!valid_cci_map) { 69*23e47edeSVikram Kanigiri tf_printf("No master is assigned a valid slave interface\n"); 70*23e47edeSVikram Kanigiri return 0; 71*23e47edeSVikram Kanigiri } 72*23e47edeSVikram Kanigiri 73*23e47edeSVikram Kanigiri return 1; 74*23e47edeSVikram Kanigiri } 75*23e47edeSVikram Kanigiri #endif /* DEBUG */ 76*23e47edeSVikram Kanigiri 77*23e47edeSVikram Kanigiri void cci_init(unsigned long cci_base, 78*23e47edeSVikram Kanigiri const int *map, 79*23e47edeSVikram Kanigiri unsigned int num_cci_masters) 80*23e47edeSVikram Kanigiri { 81*23e47edeSVikram Kanigiri assert(map); 82*23e47edeSVikram Kanigiri assert(cci_base); 83*23e47edeSVikram Kanigiri 84*23e47edeSVikram Kanigiri g_cci_base = cci_base; 85*23e47edeSVikram Kanigiri 86*23e47edeSVikram Kanigiri /* 87*23e47edeSVikram Kanigiri * Master Id's are assigned from zero, So in an array of size n 88*23e47edeSVikram Kanigiri * the max master id is (n - 1). 89*23e47edeSVikram Kanigiri */ 90*23e47edeSVikram Kanigiri g_max_master_id = num_cci_masters - 1; 91*23e47edeSVikram Kanigiri 92*23e47edeSVikram Kanigiri assert(validate_cci_map(map)); 93*23e47edeSVikram Kanigiri g_cci_slave_if_map = map; 94*23e47edeSVikram Kanigiri } 95*23e47edeSVikram Kanigiri 96*23e47edeSVikram Kanigiri void cci_enable_snoop_dvm_reqs(unsigned int master_id) 97*23e47edeSVikram Kanigiri { 98*23e47edeSVikram Kanigiri int slave_if_id; 99*23e47edeSVikram Kanigiri 100*23e47edeSVikram Kanigiri assert(g_cci_base); 101*23e47edeSVikram Kanigiri assert(master_id <= g_max_master_id); 102*23e47edeSVikram Kanigiri 103*23e47edeSVikram Kanigiri slave_if_id = g_cci_slave_if_map[master_id]; 104*23e47edeSVikram Kanigiri assert((slave_if_id < CCI_SLAVE_INTERFACE_COUNT) && (slave_if_id >= 0)); 105*23e47edeSVikram Kanigiri 106*23e47edeSVikram Kanigiri /* 107*23e47edeSVikram Kanigiri * Enable Snoops and DVM messages, no need for Read/Modify/Write as 108*23e47edeSVikram Kanigiri * rest of bits are write ignore 109*23e47edeSVikram Kanigiri */ 110*23e47edeSVikram Kanigiri mmio_write_32(g_cci_base + 111*23e47edeSVikram Kanigiri SLAVE_IFACE_OFFSET(slave_if_id) + 112*23e47edeSVikram Kanigiri SNOOP_CTRL_REG, DVM_EN_BIT | SNOOP_EN_BIT); 113*23e47edeSVikram Kanigiri 114*23e47edeSVikram Kanigiri /* Wait for the dust to settle down */ 115*23e47edeSVikram Kanigiri while (mmio_read_32(g_cci_base + STATUS_REG) & CHANGE_PENDING_BIT) 116*23e47edeSVikram Kanigiri ; 117*23e47edeSVikram Kanigiri } 118*23e47edeSVikram Kanigiri 119*23e47edeSVikram Kanigiri void cci_disable_snoop_dvm_reqs(unsigned int master_id) 120*23e47edeSVikram Kanigiri { 121*23e47edeSVikram Kanigiri int slave_if_id; 122*23e47edeSVikram Kanigiri 123*23e47edeSVikram Kanigiri assert(g_cci_base); 124*23e47edeSVikram Kanigiri assert(master_id <= g_max_master_id); 125*23e47edeSVikram Kanigiri 126*23e47edeSVikram Kanigiri slave_if_id = g_cci_slave_if_map[master_id]; 127*23e47edeSVikram Kanigiri assert((slave_if_id < CCI_SLAVE_INTERFACE_COUNT) && (slave_if_id >= 0)); 128*23e47edeSVikram Kanigiri 129*23e47edeSVikram Kanigiri /* 130*23e47edeSVikram Kanigiri * Disable Snoops and DVM messages, no need for Read/Modify/Write as 131*23e47edeSVikram Kanigiri * rest of bits are write ignore. 132*23e47edeSVikram Kanigiri */ 133*23e47edeSVikram Kanigiri mmio_write_32(g_cci_base + 134*23e47edeSVikram Kanigiri SLAVE_IFACE_OFFSET(slave_if_id) + 135*23e47edeSVikram Kanigiri SNOOP_CTRL_REG, ~(DVM_EN_BIT | SNOOP_EN_BIT)); 136*23e47edeSVikram Kanigiri 137*23e47edeSVikram Kanigiri /* Wait for the dust to settle down */ 138*23e47edeSVikram Kanigiri while (mmio_read_32(g_cci_base + STATUS_REG) & CHANGE_PENDING_BIT) 139*23e47edeSVikram Kanigiri ; 140*23e47edeSVikram Kanigiri } 141*23e47edeSVikram Kanigiri 142