123e47edeSVikram Kanigiri /* 238aecbb4SAntonio Nino Diaz * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 323e47edeSVikram Kanigiri * 4*82cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 523e47edeSVikram Kanigiri */ 623e47edeSVikram Kanigiri 723e47edeSVikram Kanigiri #include <arch.h> 823e47edeSVikram Kanigiri #include <assert.h> 923e47edeSVikram Kanigiri #include <cci.h> 1023e47edeSVikram Kanigiri #include <debug.h> 1123e47edeSVikram Kanigiri #include <mmio.h> 1202462972SJuan Castillo #include <stdint.h> 1323e47edeSVikram Kanigiri 1402462972SJuan Castillo static uintptr_t g_cci_base; 1523e47edeSVikram Kanigiri static unsigned int g_max_master_id; 1623e47edeSVikram Kanigiri static const int *g_cci_slave_if_map; 1723e47edeSVikram Kanigiri 18aa61368eSAntonio Nino Diaz #if ENABLE_ASSERTIONS 1923e47edeSVikram Kanigiri static int validate_cci_map(const int *map) 2023e47edeSVikram Kanigiri { 2123e47edeSVikram Kanigiri unsigned int valid_cci_map = 0; 2223e47edeSVikram Kanigiri int slave_if_id; 2323e47edeSVikram Kanigiri int i; 2423e47edeSVikram Kanigiri 2523e47edeSVikram Kanigiri /* Validate the map */ 2623e47edeSVikram Kanigiri for (i = 0; i <= g_max_master_id; i++) { 2723e47edeSVikram Kanigiri slave_if_id = map[i]; 2823e47edeSVikram Kanigiri 2923e47edeSVikram Kanigiri if (slave_if_id < 0) 3023e47edeSVikram Kanigiri continue; 3123e47edeSVikram Kanigiri 3223e47edeSVikram Kanigiri if (slave_if_id >= CCI_SLAVE_INTERFACE_COUNT) { 3338aecbb4SAntonio Nino Diaz ERROR("Slave interface ID is invalid\n"); 3423e47edeSVikram Kanigiri return 0; 3523e47edeSVikram Kanigiri } 3623e47edeSVikram Kanigiri 3723e47edeSVikram Kanigiri if (valid_cci_map & (1 << slave_if_id)) { 3838aecbb4SAntonio Nino Diaz ERROR("Multiple masters are assigned same slave interface ID\n"); 3923e47edeSVikram Kanigiri return 0; 4023e47edeSVikram Kanigiri } 4123e47edeSVikram Kanigiri valid_cci_map |= 1 << slave_if_id; 4223e47edeSVikram Kanigiri } 4323e47edeSVikram Kanigiri 4423e47edeSVikram Kanigiri if (!valid_cci_map) { 4538aecbb4SAntonio Nino Diaz ERROR("No master is assigned a valid slave interface\n"); 4623e47edeSVikram Kanigiri return 0; 4723e47edeSVikram Kanigiri } 4823e47edeSVikram Kanigiri 4923e47edeSVikram Kanigiri return 1; 5023e47edeSVikram Kanigiri } 51aa61368eSAntonio Nino Diaz #endif /* ENABLE_ASSERTIONS */ 5223e47edeSVikram Kanigiri 5302462972SJuan Castillo void cci_init(uintptr_t cci_base, 5423e47edeSVikram Kanigiri const int *map, 5523e47edeSVikram Kanigiri unsigned int num_cci_masters) 5623e47edeSVikram Kanigiri { 5723e47edeSVikram Kanigiri assert(map); 5823e47edeSVikram Kanigiri assert(cci_base); 5923e47edeSVikram Kanigiri 6023e47edeSVikram Kanigiri g_cci_base = cci_base; 6123e47edeSVikram Kanigiri 6223e47edeSVikram Kanigiri /* 6323e47edeSVikram Kanigiri * Master Id's are assigned from zero, So in an array of size n 6423e47edeSVikram Kanigiri * the max master id is (n - 1). 6523e47edeSVikram Kanigiri */ 6623e47edeSVikram Kanigiri g_max_master_id = num_cci_masters - 1; 6723e47edeSVikram Kanigiri 6823e47edeSVikram Kanigiri assert(validate_cci_map(map)); 6923e47edeSVikram Kanigiri g_cci_slave_if_map = map; 7023e47edeSVikram Kanigiri } 7123e47edeSVikram Kanigiri 7223e47edeSVikram Kanigiri void cci_enable_snoop_dvm_reqs(unsigned int master_id) 7323e47edeSVikram Kanigiri { 7423e47edeSVikram Kanigiri int slave_if_id; 7523e47edeSVikram Kanigiri 7623e47edeSVikram Kanigiri assert(g_cci_base); 7723e47edeSVikram Kanigiri assert(master_id <= g_max_master_id); 7823e47edeSVikram Kanigiri 7923e47edeSVikram Kanigiri slave_if_id = g_cci_slave_if_map[master_id]; 8023e47edeSVikram Kanigiri assert((slave_if_id < CCI_SLAVE_INTERFACE_COUNT) && (slave_if_id >= 0)); 8123e47edeSVikram Kanigiri 8223e47edeSVikram Kanigiri /* 8323e47edeSVikram Kanigiri * Enable Snoops and DVM messages, no need for Read/Modify/Write as 8423e47edeSVikram Kanigiri * rest of bits are write ignore 8523e47edeSVikram Kanigiri */ 8623e47edeSVikram Kanigiri mmio_write_32(g_cci_base + 8723e47edeSVikram Kanigiri SLAVE_IFACE_OFFSET(slave_if_id) + 8823e47edeSVikram Kanigiri SNOOP_CTRL_REG, DVM_EN_BIT | SNOOP_EN_BIT); 8923e47edeSVikram Kanigiri 9023e47edeSVikram Kanigiri /* Wait for the dust to settle down */ 9123e47edeSVikram Kanigiri while (mmio_read_32(g_cci_base + STATUS_REG) & CHANGE_PENDING_BIT) 9223e47edeSVikram Kanigiri ; 9323e47edeSVikram Kanigiri } 9423e47edeSVikram Kanigiri 9523e47edeSVikram Kanigiri void cci_disable_snoop_dvm_reqs(unsigned int master_id) 9623e47edeSVikram Kanigiri { 9723e47edeSVikram Kanigiri int slave_if_id; 9823e47edeSVikram Kanigiri 9923e47edeSVikram Kanigiri assert(g_cci_base); 10023e47edeSVikram Kanigiri assert(master_id <= g_max_master_id); 10123e47edeSVikram Kanigiri 10223e47edeSVikram Kanigiri slave_if_id = g_cci_slave_if_map[master_id]; 10323e47edeSVikram Kanigiri assert((slave_if_id < CCI_SLAVE_INTERFACE_COUNT) && (slave_if_id >= 0)); 10423e47edeSVikram Kanigiri 10523e47edeSVikram Kanigiri /* 10623e47edeSVikram Kanigiri * Disable Snoops and DVM messages, no need for Read/Modify/Write as 10723e47edeSVikram Kanigiri * rest of bits are write ignore. 10823e47edeSVikram Kanigiri */ 10923e47edeSVikram Kanigiri mmio_write_32(g_cci_base + 11023e47edeSVikram Kanigiri SLAVE_IFACE_OFFSET(slave_if_id) + 11123e47edeSVikram Kanigiri SNOOP_CTRL_REG, ~(DVM_EN_BIT | SNOOP_EN_BIT)); 11223e47edeSVikram Kanigiri 11323e47edeSVikram Kanigiri /* Wait for the dust to settle down */ 11423e47edeSVikram Kanigiri while (mmio_read_32(g_cci_base + STATUS_REG) & CHANGE_PENDING_BIT) 11523e47edeSVikram Kanigiri ; 11623e47edeSVikram Kanigiri } 11723e47edeSVikram Kanigiri 118