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