1*35d18d8dSBoyan Karatotev /*
2*35d18d8dSBoyan Karatotev * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
3*35d18d8dSBoyan Karatotev *
4*35d18d8dSBoyan Karatotev * SPDX-License-Identifier: BSD-3-Clause
5*35d18d8dSBoyan Karatotev */
6*35d18d8dSBoyan Karatotev
7*35d18d8dSBoyan Karatotev #include <drivers/arm/gicv2.h>
8*35d18d8dSBoyan Karatotev #include <plat/arm/common/plat_arm.h>
9*35d18d8dSBoyan Karatotev #include <plat/common/platform.h>
10*35d18d8dSBoyan Karatotev #include <platform_def.h>
11*35d18d8dSBoyan Karatotev
12*35d18d8dSBoyan Karatotev /******************************************************************************
13*35d18d8dSBoyan Karatotev * The following functions are defined as weak to allow a platform to override
14*35d18d8dSBoyan Karatotev * the way the GICv2 driver is initialised and used.
15*35d18d8dSBoyan Karatotev *****************************************************************************/
16*35d18d8dSBoyan Karatotev #pragma weak plat_arm_gic_driver_init
17*35d18d8dSBoyan Karatotev #pragma weak plat_arm_gic_init
18*35d18d8dSBoyan Karatotev #pragma weak plat_arm_gic_cpuif_enable
19*35d18d8dSBoyan Karatotev #pragma weak plat_arm_gic_cpuif_disable
20*35d18d8dSBoyan Karatotev #pragma weak plat_arm_gic_pcpu_init
21*35d18d8dSBoyan Karatotev
22*35d18d8dSBoyan Karatotev /******************************************************************************
23*35d18d8dSBoyan Karatotev * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
24*35d18d8dSBoyan Karatotev * interrupts.
25*35d18d8dSBoyan Karatotev *****************************************************************************/
26*35d18d8dSBoyan Karatotev static const interrupt_prop_t arm_interrupt_props[] = {
27*35d18d8dSBoyan Karatotev PLAT_ARM_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
28*35d18d8dSBoyan Karatotev PLAT_ARM_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
29*35d18d8dSBoyan Karatotev };
30*35d18d8dSBoyan Karatotev
31*35d18d8dSBoyan Karatotev static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
32*35d18d8dSBoyan Karatotev
33*35d18d8dSBoyan Karatotev static const gicv2_driver_data_t arm_gic_data = {
34*35d18d8dSBoyan Karatotev .gicd_base = PLAT_ARM_GICD_BASE,
35*35d18d8dSBoyan Karatotev .gicc_base = PLAT_ARM_GICC_BASE,
36*35d18d8dSBoyan Karatotev .interrupt_props = arm_interrupt_props,
37*35d18d8dSBoyan Karatotev .interrupt_props_num = ARRAY_SIZE(arm_interrupt_props),
38*35d18d8dSBoyan Karatotev .target_masks = target_mask_array,
39*35d18d8dSBoyan Karatotev .target_masks_num = ARRAY_SIZE(target_mask_array),
40*35d18d8dSBoyan Karatotev };
41*35d18d8dSBoyan Karatotev
42*35d18d8dSBoyan Karatotev /******************************************************************************
43*35d18d8dSBoyan Karatotev * ARM common helper to initialize the GICv2 only driver.
44*35d18d8dSBoyan Karatotev *****************************************************************************/
plat_arm_gic_driver_init(void)45*35d18d8dSBoyan Karatotev void plat_arm_gic_driver_init(void)
46*35d18d8dSBoyan Karatotev {
47*35d18d8dSBoyan Karatotev gicv2_driver_init(&arm_gic_data);
48*35d18d8dSBoyan Karatotev }
49*35d18d8dSBoyan Karatotev
plat_arm_gic_init(void)50*35d18d8dSBoyan Karatotev void plat_arm_gic_init(void)
51*35d18d8dSBoyan Karatotev {
52*35d18d8dSBoyan Karatotev gicv2_distif_init();
53*35d18d8dSBoyan Karatotev gicv2_pcpu_distif_init();
54*35d18d8dSBoyan Karatotev gicv2_set_pe_target_mask(plat_my_core_pos());
55*35d18d8dSBoyan Karatotev gicv2_cpuif_enable();
56*35d18d8dSBoyan Karatotev }
57*35d18d8dSBoyan Karatotev
58*35d18d8dSBoyan Karatotev /******************************************************************************
59*35d18d8dSBoyan Karatotev * ARM common helper to enable the GICv2 CPU interface
60*35d18d8dSBoyan Karatotev *****************************************************************************/
plat_arm_gic_cpuif_enable(void)61*35d18d8dSBoyan Karatotev void plat_arm_gic_cpuif_enable(void)
62*35d18d8dSBoyan Karatotev {
63*35d18d8dSBoyan Karatotev gicv2_cpuif_enable();
64*35d18d8dSBoyan Karatotev }
65*35d18d8dSBoyan Karatotev
66*35d18d8dSBoyan Karatotev /******************************************************************************
67*35d18d8dSBoyan Karatotev * ARM common helper to disable the GICv2 CPU interface
68*35d18d8dSBoyan Karatotev *****************************************************************************/
plat_arm_gic_cpuif_disable(void)69*35d18d8dSBoyan Karatotev void plat_arm_gic_cpuif_disable(void)
70*35d18d8dSBoyan Karatotev {
71*35d18d8dSBoyan Karatotev gicv2_cpuif_disable();
72*35d18d8dSBoyan Karatotev }
73*35d18d8dSBoyan Karatotev
74*35d18d8dSBoyan Karatotev /******************************************************************************
75*35d18d8dSBoyan Karatotev * ARM common helper to initialize the per cpu distributor interface in GICv2
76*35d18d8dSBoyan Karatotev *****************************************************************************/
plat_arm_gic_pcpu_init(void)77*35d18d8dSBoyan Karatotev void plat_arm_gic_pcpu_init(void)
78*35d18d8dSBoyan Karatotev {
79*35d18d8dSBoyan Karatotev gicv2_pcpu_distif_init();
80*35d18d8dSBoyan Karatotev gicv2_set_pe_target_mask(plat_my_core_pos());
81*35d18d8dSBoyan Karatotev }
82*35d18d8dSBoyan Karatotev
83*35d18d8dSBoyan Karatotev /******************************************************************************
84*35d18d8dSBoyan Karatotev * Stubs for Redistributor power management. Although GICv2 doesn't have
85*35d18d8dSBoyan Karatotev * Redistributor interface, these are provided for the sake of uniform GIC API
86*35d18d8dSBoyan Karatotev *****************************************************************************/
plat_arm_gic_redistif_on(void)87*35d18d8dSBoyan Karatotev void plat_arm_gic_redistif_on(void)
88*35d18d8dSBoyan Karatotev {
89*35d18d8dSBoyan Karatotev return;
90*35d18d8dSBoyan Karatotev }
91*35d18d8dSBoyan Karatotev
plat_arm_gic_redistif_off(void)92*35d18d8dSBoyan Karatotev void plat_arm_gic_redistif_off(void)
93*35d18d8dSBoyan Karatotev {
94*35d18d8dSBoyan Karatotev return;
95*35d18d8dSBoyan Karatotev }
96*35d18d8dSBoyan Karatotev
97*35d18d8dSBoyan Karatotev
98*35d18d8dSBoyan Karatotev /******************************************************************************
99*35d18d8dSBoyan Karatotev * ARM common helper to save & restore the GICv3 on resume from system suspend.
100*35d18d8dSBoyan Karatotev * The normal world currently takes care of saving and restoring the GICv2
101*35d18d8dSBoyan Karatotev * registers due to legacy reasons. Hence we just initialize the Distributor
102*35d18d8dSBoyan Karatotev * on resume from system suspend.
103*35d18d8dSBoyan Karatotev *****************************************************************************/
plat_arm_gic_save(void)104*35d18d8dSBoyan Karatotev void plat_arm_gic_save(void)
105*35d18d8dSBoyan Karatotev {
106*35d18d8dSBoyan Karatotev return;
107*35d18d8dSBoyan Karatotev }
108*35d18d8dSBoyan Karatotev
plat_arm_gic_resume(void)109*35d18d8dSBoyan Karatotev void plat_arm_gic_resume(void)
110*35d18d8dSBoyan Karatotev {
111*35d18d8dSBoyan Karatotev gicv2_distif_init();
112*35d18d8dSBoyan Karatotev gicv2_pcpu_distif_init();
113*35d18d8dSBoyan Karatotev }
114