diff --git a/plat/mediatek/mt8192/bl31_plat_setup.c b/plat/mediatek/mt8192/bl31_plat_setup.c index 4378c5a12..f96528196 100644 --- a/plat/mediatek/mt8192/bl31_plat_setup.c +++ b/plat/mediatek/mt8192/bl31_plat_setup.c @@ -15,6 +15,7 @@ #include /* Platform Includes */ +#include #include #include @@ -79,6 +80,9 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, ******************************************************************************/ void bl31_platform_setup(void) { + /* Initialize the GIC driver, CPU and distributor interfaces */ + mt_gic_driver_init(); + mt_gic_init(); } /******************************************************************************* diff --git a/plat/mediatek/mt8192/include/mt_gic_v3.h b/plat/mediatek/mt8192/include/mt_gic_v3.h new file mode 100644 index 000000000..34ba8a7e3 --- /dev/null +++ b/plat/mediatek/mt8192/include/mt_gic_v3.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GIC_V3_H +#define MT_GIC_V3_H + +#include +#include + +void mt_gic_driver_init(void); +void mt_gic_init(void); +void mt_gic_set_pending(uint32_t irq); +void mt_gic_distif_save(void); +void mt_gic_distif_restore(void); +void mt_gic_rdistif_init(void); +void mt_gic_rdistif_save(void); +void mt_gic_rdistif_restore(void); +void mt_gic_rdistif_restore_all(void); +void gic_sgi_save_all(void); +void gic_sgi_restore_all(void); +#endif /* MT_GIC_V3_H */ diff --git a/plat/mediatek/mt8192/include/plat_macros.S b/plat/mediatek/mt8192/include/plat_macros.S index 92cda0775..7d17e360a 100644 --- a/plat/mediatek/mt8192/include/plat_macros.S +++ b/plat/mediatek/mt8192/include/plat_macros.S @@ -24,8 +24,8 @@ cci_iface_regs: .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" /* --------------------------------------------- - * The below macro prints out relevant GIC and - * CCI registers whenever an unhandled exception + * The below macro prints out relevant GIC + * registers whenever an unhandled exception * is taken in BL31. * Clobbers: x0 - x10, x26, x27, sp * --------------------------------------------- diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h index f68015a97..5ff013ecc 100644 --- a/plat/mediatek/mt8192/include/platform_def.h +++ b/plat/mediatek/mt8192/include/platform_def.h @@ -38,6 +38,14 @@ #define SYS_COUNTER_FREQ_IN_TICKS 13000000 #define SYS_COUNTER_FREQ_IN_MHZ 13 +/******************************************************************************* + * GIC-400 & interrupt handling related constants + ******************************************************************************/ + +/* Base MTK_platform compatible GIC memory map */ +#define BASE_GICD_BASE MT_GIC_BASE +#define MT_GIC_RDIST_BASE (MT_GIC_BASE + 0x40000) + /******************************************************************************* * Platform binary types for linking ******************************************************************************/ diff --git a/plat/mediatek/mt8192/plat_mt_gic.c b/plat/mediatek/mt8192/plat_mt_gic.c new file mode 100644 index 000000000..593f5d04e --- /dev/null +++ b/plat/mediatek/mt8192/plat_mt_gic.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "../drivers/arm/gic/v3/gicv3_private.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +#define SGI_MASK 0xffff + +uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; +static uint32_t rdist_has_saved[PLATFORM_CORE_COUNT]; + +/* we save and restore the GICv3 context on system suspend */ +gicv3_dist_ctx_t dist_ctx; + +static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr) +{ + return plat_core_pos_by_mpidr(mpidr); +} + +gicv3_driver_data_t mt_gicv3_data = { + .gicd_base = MT_GIC_BASE, + .gicr_base = MT_GIC_RDIST_BASE, + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .mpidr_to_core_pos = mt_mpidr_to_core_pos, +}; + +struct gic_chip_data { + /* All cores share the same configuration */ + unsigned int saved_group; + unsigned int saved_enable; + unsigned int saved_conf0; + unsigned int saved_conf1; + unsigned int saved_grpmod; + /* Per-core sgi */ + unsigned int saved_sgi[PLATFORM_CORE_COUNT]; +}; + +static struct gic_chip_data gic_data; + +void mt_gic_driver_init(void) +{ + gicv3_driver_init(&mt_gicv3_data); +} + +void mt_gic_set_pending(uint32_t irq) +{ + gicv3_set_interrupt_pending(irq, plat_my_core_pos()); +} + +void mt_gic_distif_save(void) +{ + gicv3_distif_save(&dist_ctx); +} + +void mt_gic_distif_restore(void) +{ + gicv3_distif_init_restore(&dist_ctx); +} + +void mt_gic_rdistif_init(void) +{ + unsigned int proc_num; + unsigned int index; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + /* set all SGI/PPI as non-secure GROUP1 by default */ + mmio_write_32(gicr_base + GICR_IGROUPR0, ~0U); + mmio_write_32(gicr_base + GICR_IGRPMODR0, 0x0); + + /* setup the default PPI/SGI priorities */ + for (index = 0; index < TOTAL_PCPU_INTR_NUM; index += 4U) + gicr_write_ipriorityr(gicr_base, index, + GICD_IPRIORITYR_DEF_VAL); +} + +void mt_gic_rdistif_save(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0); + gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0); + gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0); + gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1); + gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0); + + rdist_has_saved[proc_num] = 1; +} + +void mt_gic_rdistif_restore(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + if (rdist_has_saved[proc_num] == 1) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); + mmio_write_32(gicr_base + GICR_ISENABLER0, + gic_data.saved_enable); + mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); + mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); + mmio_write_32(gicr_base + GICR_IGRPMODR0, + gic_data.saved_grpmod); + } +} + +void mt_gic_rdistif_restore_all(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); + mmio_write_32(gicr_base + GICR_ISENABLER0, + gic_data.saved_enable); + mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); + mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); + mmio_write_32(gicr_base + GICR_IGRPMODR0, + gic_data.saved_grpmod); + } +} + +void gic_sgi_save_all(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + gic_data.saved_sgi[proc_num] = + mmio_read_32(gicr_base + GICR_ISPENDR0) & SGI_MASK; + } +} + +void gic_sgi_restore_all(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + mmio_write_32(gicr_base + GICR_ICPENDR0, SGI_MASK); + mmio_write_32(gicr_base + GICR_ISPENDR0, + gic_data.saved_sgi[proc_num] & SGI_MASK); + } +} + +void mt_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk index f4ee7e7f4..c972ac61d 100644 --- a/plat/mediatek/mt8192/platform.mk +++ b/plat/mediatek/mt8192/platform.mk @@ -10,6 +10,7 @@ MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/include/ +GICV3_SUPPORT_GIC600 := 1 include drivers/arm/gic/v3/gicv3.mk include lib/xlat_tables_v2/xlat_tables.mk @@ -30,7 +31,8 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ ${MTK_PLAT_SOC}/plat_pm.c \ - ${MTK_PLAT_SOC}/plat_topology.c + ${MTK_PLAT_SOC}/plat_topology.c \ + ${MTK_PLAT_SOC}/plat_mt_gic.c # Configs for A76 and A55