1 /* 2 * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <drivers/arm/gicv3.h> 8 #include <plat/common/platform.h> 9 10 #include <platform_def.h> 11 12 /* The GICv3 driver only needs to be initialized in EL3 */ 13 static uintptr_t brcm_rdistif_base_addrs[PLATFORM_CORE_COUNT]; 14 15 static const interrupt_prop_t brcm_interrupt_props[] = { 16 /* G1S interrupts */ 17 PLAT_BRCM_G1S_IRQ_PROPS(INTR_GROUP1S), 18 /* G0 interrupts */ 19 PLAT_BRCM_G0_IRQ_PROPS(INTR_GROUP0) 20 }; 21 22 /* 23 * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register 24 * to core position. 25 * 26 * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity 27 * values read from GICR_TYPER don't have an MT field. To reuse the same 28 * translation used for CPUs, we insert MT bit read from the PE's MPIDR into 29 * that read from GICR_TYPER. 30 * 31 * Assumptions: 32 * 33 * - All CPUs implemented in the system have MPIDR_EL1.MT bit set; 34 * - No CPUs implemented in the system use affinity level 3. 35 */ 36 static unsigned int brcm_gicv3_mpidr_hash(u_register_t mpidr) 37 { 38 mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); 39 return plat_core_pos_by_mpidr(mpidr); 40 } 41 42 static const gicv3_driver_data_t brcm_gic_data = { 43 .gicd_base = PLAT_BRCM_GICD_BASE, 44 .gicr_base = PLAT_BRCM_GICR_BASE, 45 .interrupt_props = brcm_interrupt_props, 46 .interrupt_props_num = ARRAY_SIZE(brcm_interrupt_props), 47 .rdistif_num = PLATFORM_CORE_COUNT, 48 .rdistif_base_addrs = brcm_rdistif_base_addrs, 49 .mpidr_to_core_pos = brcm_gicv3_mpidr_hash 50 }; 51 52 void plat_brcm_gic_driver_init(void) 53 { 54 /* TODO Check if this is required to be initialized here 55 * after getting initialized in EL3, should we re-init this here 56 * in S-EL1 57 */ 58 gicv3_driver_init(&brcm_gic_data); 59 } 60 61 void plat_brcm_gic_init(void) 62 { 63 gicv3_distif_init(); 64 gicv3_rdistif_init(plat_my_core_pos()); 65 gicv3_cpuif_enable(plat_my_core_pos()); 66 } 67 68 void plat_brcm_gic_cpuif_enable(void) 69 { 70 gicv3_cpuif_enable(plat_my_core_pos()); 71 } 72 73 void plat_brcm_gic_cpuif_disable(void) 74 { 75 gicv3_cpuif_disable(plat_my_core_pos()); 76 } 77 78 void plat_brcm_gic_pcpu_init(void) 79 { 80 gicv3_rdistif_init(plat_my_core_pos()); 81 } 82 83 void plat_brcm_gic_redistif_on(void) 84 { 85 gicv3_rdistif_on(plat_my_core_pos()); 86 } 87 88 void plat_brcm_gic_redistif_off(void) 89 { 90 gicv3_rdistif_off(plat_my_core_pos()); 91 } 92