mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-08-15 08:57:02 +02:00
Since we use a DTB with all platform information to pass this on to a kernel loaded as BL33, we can as well make use of it for our own purposes. Every DT would contain a node for the GIC(v3) interrupt controller, so we can read the base address for the distributor and redistributors from there. This avoids hard coding this information in the code and allows for a more flexible binary. Change-Id: Ic530e223a21a45bc30a07a21048116d5af69e972 Signed-off-by: Andre Przywara <andre.przywara@arm.com>
80 lines
2.0 KiB
C
80 lines
2.0 KiB
C
/*
|
|
* Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <common/debug.h>
|
|
#include <common/fdt_wrappers.h>
|
|
#include <drivers/arm/gicv3.h>
|
|
#include <drivers/arm/gic_common.h>
|
|
#include <libfdt.h>
|
|
|
|
#include <platform_def.h>
|
|
#include <plat/common/platform.h>
|
|
#include <platform_def.h>
|
|
|
|
static const interrupt_prop_t fpga_interrupt_props[] = {
|
|
PLATFORM_G1S_PROPS(INTR_GROUP1S),
|
|
PLATFORM_G0_PROPS(INTR_GROUP0)
|
|
};
|
|
|
|
static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT];
|
|
|
|
static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr)
|
|
{
|
|
return (unsigned int)plat_core_pos_by_mpidr(mpidr);
|
|
}
|
|
|
|
static gicv3_driver_data_t fpga_gicv3_driver_data = {
|
|
.interrupt_props = fpga_interrupt_props,
|
|
.interrupt_props_num = ARRAY_SIZE(fpga_interrupt_props),
|
|
.rdistif_num = PLATFORM_CORE_COUNT,
|
|
.rdistif_base_addrs = fpga_rdistif_base_addrs,
|
|
.mpidr_to_core_pos = fpga_mpidr_to_core_pos
|
|
};
|
|
|
|
void plat_fpga_gic_init(void)
|
|
{
|
|
const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
|
|
int node, ret;
|
|
|
|
node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-v3");
|
|
if (node < 0) {
|
|
WARN("No \"arm,gic-v3\" compatible node found in DT, no GIC support.\n");
|
|
return;
|
|
}
|
|
|
|
/* TODO: Assuming only empty "ranges;" properties up the bus path. */
|
|
ret = fdt_get_reg_props_by_index(fdt, node, 0,
|
|
&fpga_gicv3_driver_data.gicd_base, NULL);
|
|
if (ret < 0) {
|
|
WARN("Could not read GIC distributor address from DT.\n");
|
|
return;
|
|
}
|
|
|
|
ret = fdt_get_reg_props_by_index(fdt, node, 1,
|
|
&fpga_gicv3_driver_data.gicr_base, NULL);
|
|
if (ret < 0) {
|
|
WARN("Could not read GIC redistributor address from DT.\n");
|
|
return;
|
|
}
|
|
|
|
gicv3_driver_init(&fpga_gicv3_driver_data);
|
|
gicv3_distif_init();
|
|
gicv3_rdistif_init(plat_my_core_pos());
|
|
gicv3_cpuif_enable(plat_my_core_pos());
|
|
}
|
|
|
|
void fpga_pwr_gic_on_finish(void)
|
|
{
|
|
gicv3_rdistif_init(plat_my_core_pos());
|
|
gicv3_cpuif_enable(plat_my_core_pos());
|
|
}
|
|
|
|
void fpga_pwr_gic_off(void)
|
|
{
|
|
gicv3_cpuif_disable(plat_my_core_pos());
|
|
gicv3_rdistif_off(plat_my_core_pos());
|
|
}
|