diff --git a/plat/mediatek/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c index 1e5367f..5a0cb87 100644 --- a/plat/mediatek/mt8183/bl31_plat_setup.c +++ b/plat/mediatek/mt8183/bl31_plat_setup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -69,8 +70,8 @@ u_register_t arg2, u_register_t arg3) { struct mtk_bl31_params *arg_from_bl2 = (struct mtk_bl31_params *)arg0; - static console_16550_t console; + console_16550_register(UART0_BASE, UART_CLOCK, UART_BAUDRATE, &console); NOTICE("MT8183 bl31_setup\n"); @@ -91,6 +92,10 @@ { platform_setup_cpu(); generic_delay_timer_init(); + + /* Initialize the GIC driver, CPU and distributor interfaces */ + mt_gic_driver_init(); + mt_gic_init(); } /******************************************************************************* diff --git a/plat/mediatek/mt8183/include/mt_gic_v3.h b/plat/mediatek/mt8183/include/mt_gic_v3.h new file mode 100644 index 0000000..e2706f4 --- /dev/null +++ b/plat/mediatek/mt8183/include/mt_gic_v3.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GIC_V3_H +#define MT_GIC_V3_H + +#include + +enum irq_schedule_mode { + SW_MODE, + HW_MODE +}; + +#define GIC_INT_MASK (MCUCFG_BASE + 0x5e8) +#define GIC500_ACTIVE_SEL_SHIFT 3 +#define GIC500_ACTIVE_SEL_MASK (0x7 << GIC500_ACTIVE_SEL_SHIFT) +#define GIC500_ACTIVE_CPU_SHIFT 16 +#define GIC500_ACTIVE_CPU_MASK (0xff << GIC500_ACTIVE_CPU_SHIFT) + +void mt_gic_driver_init(void); +void mt_gic_init(void); +void mt_gic_set_pending(uint32_t irq); +uint32_t mt_gic_get_pending(uint32_t irq); +void mt_gic_cpuif_enable(void); +void mt_gic_cpuif_disable(void); +void mt_gic_pcpu_init(void); +void mt_gic_irq_save(void); +void mt_gic_irq_restore(void); +void mt_gic_sync_dcm_enable(void); +void mt_gic_sync_dcm_disable(void); + +#endif /* MT_GIC_V3_H */ diff --git a/plat/mediatek/mt8183/include/plat_private.h b/plat/mediatek/mt8183/include/plat_private.h index e57ae45..599f14f 100644 --- a/plat/mediatek/mt8183/include/plat_private.h +++ b/plat/mediatek/mt8183/include/plat_private.h @@ -21,7 +21,6 @@ void plat_cci_enable(void); void plat_cci_disable(void); void plat_cci_init_sf(void); -void plat_gic_init(void); /* Declarations for plat_topology.c */ int mt_setup_topology(void); diff --git a/plat/mediatek/mt8183/plat_mt_gic.c b/plat/mediatek/mt8183/plat_mt_gic.c new file mode 100644 index 0000000..2144379 --- /dev/null +++ b/plat/mediatek/mt8183/plat_mt_gic.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include <../drivers/arm/gic/v3/gicv3_private.h> +#include +#include +#include "plat_private.h" +#include +#include +#include +#include + +#define NR_INT_POL_CTL 20 + +uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +/* + * We save and restore the GICv3 context on system suspend. Allocate the + * data in the designated EL3 Secure carve-out memory + */ +gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); +gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); + + +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, +}; + +void setup_int_schedule_mode(enum irq_schedule_mode mode, + unsigned int active_cpu) +{ + assert(mode <= HW_MODE); + assert(active_cpu <= 0xFF); + + if (mode == HW_MODE) { + mmio_write_32(GIC_INT_MASK, + (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_SEL_MASK)) + | (0x1 << GIC500_ACTIVE_SEL_SHIFT)); + } else if (mode == SW_MODE) { + mmio_write_32(GIC_INT_MASK, + (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_SEL_MASK))); + } + + mmio_write_32(GIC_INT_MASK, + (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_CPU_MASK)) + | (active_cpu << GIC500_ACTIVE_CPU_SHIFT)); + return; +} + +void clear_sec_pol_ctl_en(void) +{ + unsigned int i; + + /* total 19 polarity ctrl registers */ + for (i = 0; i <= NR_INT_POL_CTL - 1; i++) { + mmio_write_32((SEC_POL_CTL_EN0 + (i * 4)), 0); + } + dsb(); +} + +void mt_gic_driver_init(void) +{ + gicv3_driver_init(&mt_gicv3_data); +} + +void mt_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); + + setup_int_schedule_mode(SW_MODE, 0xf); + clear_sec_pol_ctl_en(); +} + +void mt_gic_set_pending(uint32_t irq) +{ + gicv3_set_interrupt_pending(irq, plat_my_core_pos()); +} + +uint32_t mt_gic_get_pending(uint32_t irq) +{ + uint32_t bit = 1 << (irq % 32); + + return (mmio_read_32(gicv3_driver_data->gicd_base + + GICD_ISPENDR + irq / 32 * 4) & bit) ? 1 : 0; +} + +void mt_gic_cpuif_enable(void) +{ + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void mt_gic_cpuif_disable(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +void mt_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); +} + +void mt_gic_irq_save(void) +{ + gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); + gicv3_distif_save(&dist_ctx); +} + +void mt_gic_irq_restore(void) +{ + gicv3_distif_init_restore(&dist_ctx); + gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); +} + +void mt_gic_sync_dcm_enable(void) +{ + unsigned int val = mmio_read_32(GIC_SYNC_DCM); + + val &= ~GIC_SYNC_DCM_MASK; + mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_ON); +} + +void mt_gic_sync_dcm_disable(void) +{ + unsigned int val = mmio_read_32(GIC_SYNC_DCM); + + val &= ~GIC_SYNC_DCM_MASK; + mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_OFF); +} diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk index 2ceb459..607e7e3 100644 --- a/plat/mediatek/mt8183/platform.mk +++ b/plat/mediatek/mt8183/platform.mk @@ -12,14 +12,15 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ - plat/common/plat_gicv2.c \ plat/common/plat_psci_common.c \ plat/common/aarch64/crash_console_helpers.S BL31_SOURCES += drivers/arm/cci/cci.c \ drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ + drivers/arm/gic/v3/arm_gicv3_common.c \ + drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gic500.c \ + drivers/arm/gic/v3/gicv3_main.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/gpio/gpio.c \ @@ -27,11 +28,13 @@ lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a73.S \ + plat/common/plat_gicv3.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ ${MTK_PLAT_SOC}/aarch64/platform_common.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_topology.c \ + ${MTK_PLAT_SOC}/plat_mt_gic.c \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ ${MTK_PLAT_SOC}/plat_debug.c \ ${MTK_PLAT_SOC}/scu.c