diff options
Diffstat (limited to 'plat')
-rw-r--r-- | plat/arm/board/fvp/aarch64/fvp_helpers.S | 39 | ||||
-rw-r--r-- | plat/arm/board/fvp/platform.mk | 25 | ||||
-rw-r--r-- | plat/mediatek/mt8183/aarch64/platform_common.c | 31 | ||||
-rw-r--r-- | plat/mediatek/mt8183/bl31_plat_setup.c | 13 | ||||
-rw-r--r-- | plat/mediatek/mt8183/drivers/mcsi/mcsi.c | 211 | ||||
-rw-r--r-- | plat/mediatek/mt8183/drivers/mcsi/mcsi.h | 116 | ||||
-rw-r--r-- | plat/mediatek/mt8183/include/mt_gic_v3.h | 35 | ||||
-rw-r--r-- | plat/mediatek/mt8183/include/plat_private.h | 9 | ||||
-rw-r--r-- | plat/mediatek/mt8183/plat_mt_gic.c | 146 | ||||
-rw-r--r-- | plat/mediatek/mt8183/platform.mk | 11 |
10 files changed, 579 insertions, 57 deletions
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S index 09f19f6c3..8efc2386c 100644 --- a/plat/arm/board/fvp/aarch64/fvp_helpers.S +++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,14 +16,6 @@ .globl plat_is_my_cpu_primary .globl plat_arm_calc_core_pos - .macro fvp_choose_gicmmap param1, param2, x_tmp, w_tmp, res - mov_imm \x_tmp, V2M_SYSREGS_BASE + V2M_SYS_ID - ldr \w_tmp, [\x_tmp] - ubfx \w_tmp, \w_tmp, #V2M_SYS_ID_BLD_SHIFT, #V2M_SYS_ID_BLD_LENGTH - cmp \w_tmp, #BLD_GIC_VE_MMAP - csel \res, \param1, \param2, eq - .endm - /* ----------------------------------------------------- * void plat_secondary_cold_boot_setup (void); * @@ -50,35 +42,6 @@ func plat_secondary_cold_boot_setup str w0, [x1, #PPOFFR_OFF] /* --------------------------------------------- - * Disable GIC bypass as well - * --------------------------------------------- - */ - /* Check for GICv3 system register access */ - mrs x0, id_aa64pfr0_el1 - ubfx x0, x0, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH - cmp x0, #1 - b.ne gicv2_bypass_disable - - /* Check for SRE enable */ - mrs x1, ICC_SRE_EL3 - tst x1, #ICC_SRE_SRE_BIT - b.eq gicv2_bypass_disable - - mrs x2, ICC_SRE_EL3 - orr x2, x2, #(ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT) - msr ICC_SRE_EL3, x2 - b secondary_cold_boot_wait - -gicv2_bypass_disable: - mov_imm x0, VE_GICC_BASE - mov_imm x1, BASE_GICC_BASE - fvp_choose_gicmmap x0, x1, x2, w2, x1 - mov w0, #(IRQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP1) - orr w0, w0, #(IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP0) - str w0, [x1, #GICC_CTLR] - -secondary_cold_boot_wait: - /* --------------------------------------------- * There is no sane reason to come out of this * wfi so panic if we do. This cpu will be pow- * ered on and reset by the cpu_on pm api diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index dbc5c21ba..3cbdfbc46 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -96,8 +96,8 @@ FVP_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S ifeq (${ARCH}, aarch64) -# select a different set of CPU files, depending on whether we compile with -# hardware assisted coherency configurations or not +# select a different set of CPU files, depending on whether we compile for +# hardware assisted coherency cores or not ifeq (${HW_ASSISTED_COHERENCY}, 0) FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a35.S \ lib/cpus/aarch64/cortex_a53.S \ @@ -105,14 +105,19 @@ ifeq (${HW_ASSISTED_COHERENCY}, 0) lib/cpus/aarch64/cortex_a72.S \ lib/cpus/aarch64/cortex_a73.S else - FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ - lib/cpus/aarch64/cortex_a75.S \ - lib/cpus/aarch64/cortex_a76.S \ - lib/cpus/aarch64/cortex_a76ae.S \ - lib/cpus/aarch64/neoverse_n1.S \ - lib/cpus/aarch64/neoverse_e1.S \ - lib/cpus/aarch64/cortex_deimos.S \ - lib/cpus/aarch64/neoverse_zeus.S + # AArch64-only cores + ifeq (${CTX_INCLUDE_AARCH32_REGS}, 0) + FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \ + lib/cpus/aarch64/cortex_a76ae.S \ + lib/cpus/aarch64/neoverse_n1.S \ + lib/cpus/aarch64/neoverse_e1.S \ + lib/cpus/aarch64/cortex_deimos.S \ + lib/cpus/aarch64/neoverse_zeus.S + # AArch64/AArch32 + else + FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ + lib/cpus/aarch64/cortex_a75.S + endif endif else diff --git a/plat/mediatek/mt8183/aarch64/platform_common.c b/plat/mediatek/mt8183/aarch64/platform_common.c index ff0aaeb97..31d133908 100644 --- a/plat/mediatek/mt8183/aarch64/platform_common.c +++ b/plat/mediatek/mt8183/aarch64/platform_common.c @@ -7,10 +7,16 @@ #include <arch_helpers.h> #include <common/bl_common.h> #include <common/debug.h> +#include <mcsi/mcsi.h> #include <platform_def.h> #include <lib/utils.h> #include <lib/xlat_tables/xlat_tables.h> +static const int cci_map[] = { + PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX, + PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX +}; + /* Table of regions to map using the MMU. */ const mmap_region_t plat_mmap[] = { /* for TF text, RO, RW */ @@ -51,3 +57,28 @@ unsigned int plat_get_syscnt_freq2(void) { return SYS_COUNTER_FREQ_IN_TICKS; } + +void plat_mtk_cci_init(void) +{ + /* Initialize CCI driver */ + mcsi_init(PLAT_MT_CCI_BASE, ARRAY_SIZE(cci_map)); +} + +void plat_mtk_cci_enable(void) +{ + /* Enable CCI coherency for this cluster. + * No need for locks as no other cpu is active at the moment. + */ + cci_enable_cluster_coherency(read_mpidr()); +} + +void plat_mtk_cci_disable(void) +{ + cci_disable_cluster_coherency(read_mpidr()); +} + +void plat_mtk_cci_init_sf(void) +{ + /* Init mcsi snoop filter. */ + cci_init_sf(); +} diff --git a/plat/mediatek/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c index 1e5367fc8..b451189d4 100644 --- a/plat/mediatek/mt8183/bl31_plat_setup.c +++ b/plat/mediatek/mt8183/bl31_plat_setup.c @@ -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,13 @@ 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(); + + /* Init mcsi SF */ + plat_mtk_cci_init_sf(); } /******************************************************************************* @@ -99,6 +107,9 @@ void bl31_platform_setup(void) ******************************************************************************/ void bl31_plat_arch_setup(void) { + plat_mtk_cci_init(); + plat_mtk_cci_enable(); + enable_scu(read_mpidr()); plat_configure_mmu_el3(BL_CODE_BASE, diff --git a/plat/mediatek/mt8183/drivers/mcsi/mcsi.c b/plat/mediatek/mt8183/drivers/mcsi/mcsi.c new file mode 100644 index 000000000..cbe7f0a4a --- /dev/null +++ b/plat/mediatek/mt8183/drivers/mcsi/mcsi.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <scu.h> +#include <mcucfg.h> +#include <drivers/delay_timer.h> +#include <mcsi/mcsi.h> + +#define MAX_CLUSTERS 5 + +static unsigned long cci_base_addr; +static unsigned int cci_cluster_ix_to_iface[MAX_CLUSTERS]; + +void mcsi_init(unsigned long cci_base, + unsigned int num_cci_masters) +{ + int i; + + assert(cci_base); + assert(num_cci_masters < MAX_CLUSTERS); + + cci_base_addr = cci_base; + + for (i = 0; i < num_cci_masters; i++) + cci_cluster_ix_to_iface[i] = SLAVE_IFACE_OFFSET(i); +} + +void mcsi_cache_flush(void) +{ + /* timeout is 10ms */ + int timeout = 10000; + + /* to make flush by SF safe, need to disable BIU DCM */ + mmio_clrbits_32(CCI_CLK_CTRL, 1 << 8); + mmio_write_32(cci_base_addr + FLUSH_SF, 0x1); + + for (; timeout; timeout--, udelay(1)) { + if ((mmio_read_32(cci_base_addr + FLUSH_SF) & 0x1) == 0x0) + break; + } + + if (!timeout) { + INFO("SF lush timeout\n"); + return; + } + + /* enable BIU DCM as it was */ + mmio_setbits_32(CCI_CLK_CTRL, 1 << 8); +} + +static inline unsigned long get_slave_iface_base(unsigned long mpidr) +{ + /* + * We assume the TF topology code allocates affinity instances + * consecutively from zero. + * It is a programming error if this is called without initializing + * the slave interface to use for this cluster. + */ + unsigned int cluster_id = + (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + + assert(cluster_id < MAX_CLUSTERS); + assert(cci_cluster_ix_to_iface[cluster_id] != 0); + + return cci_base_addr + cci_cluster_ix_to_iface[cluster_id]; +} + +void cci_enable_cluster_coherency(unsigned long mpidr) +{ + unsigned long slave_base; + unsigned int support_ability; + unsigned int config = 0; + unsigned int pending = 0; + + assert(cci_base_addr); + slave_base = get_slave_iface_base(mpidr); + support_ability = mmio_read_32(slave_base); + + pending = (mmio_read_32( + cci_base_addr + SNP_PENDING_REG)) >> SNP_PENDING; + while (pending) { + pending = (mmio_read_32( + cci_base_addr + SNP_PENDING_REG)) >> SNP_PENDING; + } + + if (support_ability & SNP_SUPPORT) + config |= SNOOP_EN_BIT; + if (support_ability & DVM_SUPPORT) + config |= DVM_EN_BIT; + + mmio_write_32(slave_base, support_ability | config); + + /* Wait for the dust to settle down */ + while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING) + ; +} + +#if ERRATA_MCSIB_SW +#pragma weak mcsib_sw_workaround_main +#endif + +void cci_disable_cluster_coherency(unsigned long mpidr) +{ + unsigned long slave_base; + unsigned int config = 0; + + assert(cci_base_addr); + slave_base = get_slave_iface_base(mpidr); + + while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING) + ; + + config = mmio_read_32(slave_base); + config &= ~(DVM_EN_BIT | SNOOP_EN_BIT); + + /* Disable Snoops and DVM messages */ + mmio_write_32(slave_base, config); + +#if ERRATA_MCSIB_SW + mcsib_sw_workaround_main(); +#endif + + /* Wait for the dust to settle down */ + while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING) + ; +} + +void cci_secure_switch(unsigned int status) +{ + unsigned int config; + + config = mmio_read_32(cci_base_addr + CENTRAL_CTRL_REG); + if (status == NS_ACC) + config |= SECURE_ACC_EN; + else + config &= ~SECURE_ACC_EN; + mmio_write_32(cci_base_addr + CENTRAL_CTRL_REG, config); +} + +void cci_pmu_secure_switch(unsigned int status) +{ + unsigned int config; + + config = mmio_read_32(cci_base_addr + CENTRAL_CTRL_REG); + if (status == NS_ACC) + config |= PMU_SECURE_ACC_EN; + else + config &= ~PMU_SECURE_ACC_EN; + mmio_write_32(cci_base_addr + CENTRAL_CTRL_REG, config); +} + +void cci_init_sf(void) +{ + while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING) + ; + /* init sf1 */ + mmio_write_32(cci_base_addr + SF_INIT_REG, TRIG_SF1_INIT); + while (mmio_read_32(cci_base_addr + SF_INIT_REG) & TRIG_SF1_INIT) + ; + while (!(mmio_read_32(cci_base_addr + SF_INIT_REG) & SF1_INIT_DONE)) + ; + /* init sf2 */ + mmio_write_32(cci_base_addr + SF_INIT_REG, TRIG_SF2_INIT); + while (mmio_read_32(cci_base_addr + SF_INIT_REG) & TRIG_SF2_INIT) + ; + while (!(mmio_read_32(cci_base_addr + SF_INIT_REG) & SF2_INIT_DONE)) + ; +} + +void cci_interrupt_en(void) +{ + mmio_setbits_32(cci_base_addr + CENTRAL_CTRL_REG, INT_EN); +} + +unsigned long cci_reg_access(unsigned int op, unsigned long offset, + unsigned long val) +{ + unsigned long ret = 0; + + if ((cci_base_addr == 0) || (offset > MSCI_MEMORY_SZ)) + panic(); + + switch (op) { + case MCSI_REG_ACCESS_READ: + ret = mmio_read_32(cci_base_addr + offset); + break; + case MCSI_REG_ACCESS_WRITE: + mmio_write_32(cci_base_addr + offset, val); + dsb(); + break; + case MCSI_REG_ACCESS_SET_BITMASK: + mmio_setbits_32(cci_base_addr + offset, val); + dsb(); + break; + case MCSI_REG_ACCESS_CLEAR_BITMASK: + mmio_clrbits_32(cci_base_addr + offset, val); + dsb(); + break; + default: + break; + } + return ret; +} diff --git a/plat/mediatek/mt8183/drivers/mcsi/mcsi.h b/plat/mediatek/mt8183/drivers/mcsi/mcsi.h new file mode 100644 index 000000000..c13e22ade --- /dev/null +++ b/plat/mediatek/mt8183/drivers/mcsi/mcsi.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MCSI_H +#define MCSI_H + +#define SLAVE_IFACE7_OFFSET 0x1700 +#define SLAVE_IFACE6_OFFSET 0x1600 +#define SLAVE_IFACE5_OFFSET 0x1500 +#define SLAVE_IFACE4_OFFSET 0x1400 +#define SLAVE_IFACE3_OFFSET 0x1300 +#define SLAVE_IFACE2_OFFSET 0x1200 +#define SLAVE_IFACE1_OFFSET 0x1100 +#define SLAVE_IFACE0_OFFSET 0x1000 +#define SLAVE_IFACE_OFFSET(index) (SLAVE_IFACE0_OFFSET + \ + (0x100 * (index))) +/* Control and ID register offsets */ +#define CENTRAL_CTRL_REG 0x0 +#define ERR_FLAG_REG 0x4 +#define SF_INIT_REG 0x10 +#define SF_CTRL_REG 0x14 +#define DCM_CTRL_REG 0x18 +#define ERR_FLAG2_REG 0x20 +#define SNP_PENDING_REG 0x28 +#define ACP_PENDING_REG 0x2c +#define FLUSH_SF 0x500 +#define SYS_CCE_CTRL 0x2000 +#define MST1_CTRL 0x2100 +#define MTS2_CTRL 0x2200 +#define XBAR_ARAW_ARB 0x3000 +#define XBAR_R_ARB 0x3004 + +/* Slave interface register offsets */ +#define SNOOP_CTRL_REG 0x0 +#define QOS_CTRL_REG 0x4 +#define QOS_OVERRIDE_REG 0x8 +#define QOS_TARGET_REG 0xc +#define BD_CTRL_REG 0x40 + +/* Snoop Control register bit definitions */ +#define DVM_SUPPORT (1 << 31) +#define SNP_SUPPORT (1 << 30) +#define SHAREABLE_OVWRT (1 << 2) +#define DVM_EN_BIT (1 << 1) +#define SNOOP_EN_BIT (1 << 0) +#define SF2_INIT_DONE (1 << 17) +#define SF1_INIT_DONE (1 << 16) +#define TRIG_SF2_INIT (1 << 1) +#define TRIG_SF1_INIT (1 << 0) + +/* Status register bit definitions */ +#define SNP_PENDING 31 + +/* Status bit */ +#define NS_ACC 1 +#define S_ACC 0 + +/* Central control register bit definitions */ +#define PMU_SECURE_ACC_EN (1 << 4) +#define INT_EN (1 << 3) +#define SECURE_ACC_EN (1 << 2) +#define DVM_DIS (1 << 1) +#define SNOOP_DIS (1 << 0) + +#define MSCI_MEMORY_SZ (0x10000) + +#define MCSI_REG_ACCESS_READ (0x0) +#define MCSI_REG_ACCESS_WRITE (0x1) +#define MCSI_REG_ACCESS_SET_BITMASK (0x2) +#define MCSI_REG_ACCESS_CLEAR_BITMASK (0x3) + +#define NR_MAX_SLV (7) + +/* ICCS */ +#define CACHE_INSTR_EN (1 << 2) +#define IDLE_CACHE (1 << 3) +#define USE_SHARED_CACHE (1 << 4) +#define CACHE_SHARED_PRE_EN (1 << 5) +#define CACHE_SHARED_POST_EN (1 << 6) + +#define ACP_PENDING_MASK (0x1007f) + +#define CCI_CLK_CTRL (MCUCFG_BASE + 0x660) + +#ifndef __ASSEMBLY__ + +#include <plat/common/common_def.h> +#include <stdint.h> + +/* Function declarations */ + +/* + * The MCSI driver must be initialized with the base address of the + * MCSI device in the platform memory map, and the cluster indices for + * the MCSI slave interfaces 3 and 4 respectively. These are the fully + * coherent ACE slave interfaces of MCSI. + * The cluster indices must either be 0 or 1, corresponding to the level 1 + * affinity instance of the mpidr representing the cluster. A negative cluster + * index indicates that no cluster is present on that slave interface. + */ +void mcsi_init(unsigned long cci_base, + unsigned int num_cci_masters); +void mcsi_cache_flush(void); + +void cci_enable_cluster_coherency(unsigned long mpidr); +void cci_disable_cluster_coherency(unsigned long mpidr); + +void cci_secure_switch(unsigned int ns); +void cci_init_sf(void); +unsigned long cci_reg_access(unsigned int op, unsigned long offset, unsigned long val); + +#endif /* __ASSEMBLY__ */ +#endif /* MCSI_H */ 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 000000000..e2706f46a --- /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 <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 */ diff --git a/plat/mediatek/mt8183/include/plat_private.h b/plat/mediatek/mt8183/include/plat_private.h index e57ae45d5..0853934b9 100644 --- a/plat/mediatek/mt8183/include/plat_private.h +++ b/plat/mediatek/mt8183/include/plat_private.h @@ -17,11 +17,10 @@ void plat_configure_mmu_el3(uintptr_t total_base, uintptr_t coh_start, uintptr_t coh_limit); -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); +void plat_mtk_cci_init(void); +void plat_mtk_cci_enable(void); +void plat_mtk_cci_disable(void); +void plat_mtk_cci_init_sf(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 000000000..21443799f --- /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 <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); +} diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk index 2ceb45977..8c8e2fe9c 100644 --- a/plat/mediatek/mt8183/platform.mk +++ b/plat/mediatek/mt8183/platform.mk @@ -8,18 +8,20 @@ MTK_PLAT := plat/mediatek MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ + -I${MTK_PLAT_SOC}/drivers/ \ -I${MTK_PLAT_SOC}/include/ 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 +29,14 @@ 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}/drivers/mcsi/mcsi.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 |