mediatek: mt8183: add GIC driver
authorkenny liang <kenny.liang@mediatek.com>
Thu, 2 May 2019 14:26:22 +0000 (22:26 +0800)
committerJohn Tsichritzis <john.tsichritzis@arm.com>
Thu, 6 Jun 2019 10:00:16 +0000 (11:00 +0100)
Add Mediatek GIC driver to support interrupt functions.

Signed-off-by: kenny liang <kenny.liang@mediatek.com>
Change-Id: I967a18f2e45b7bbc88c506dd4f1f40a745227ad9

plat/mediatek/mt8183/bl31_plat_setup.c
plat/mediatek/mt8183/include/mt_gic_v3.h [new file with mode: 0644]
plat/mediatek/mt8183/include/plat_private.h
plat/mediatek/mt8183/plat_mt_gic.c [new file with mode: 0644]
plat/mediatek/mt8183/platform.mk

index 1e5367fc8bab0843c6bfa24d3d357a20ea391ad1..5a0cb87f1dbcd4aa913f2546003bff94cb6faa63 100644 (file)
@@ -12,6 +12,7 @@
 #include <common/debug.h>
 #include <drivers/generic_delay_timer.h>
 #include <mcucfg.h>
+#include <mt_gic_v3.h>
 #include <lib/mmio.h>
 #include <mtk_plat_common.h>
 #include <plat_debug.h>
@@ -69,8 +70,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
                                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 @@ void bl31_platform_setup(void)
 {
        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 (file)
index 0000000..e2706f4
--- /dev/null
@@ -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 <lib/mmio.h>
+
+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 */
index e57ae45d5c78622fcd710cd6121bd04a9b6a1dda..599f14f3bb8155ba8347003bd69b34b4af852851 100644 (file)
@@ -21,7 +21,6 @@ void plat_cci_init(void);
 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 (file)
index 0000000..2144379
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv3.h>
+#include <bl31/interrupt_mgmt.h>
+#include <../drivers/arm/gic/v3/gicv3_private.h>
+#include <mt_gic_v3.h>
+#include <mtk_plat_common.h>
+#include "plat_private.h"
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#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);
+}
index 2ceb45977088d81f5ed191f4f0de1e213b92893b..607e7e3aafa9103bf46150bc853958cc6c7b9523 100644 (file)
@@ -12,14 +12,15 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
 
 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 @@ BL31_SOURCES    += drivers/arm/cci/cci.c                                 \
                    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