1*28a773efSkenny liang /* 2*28a773efSkenny liang * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. 3*28a773efSkenny liang * 4*28a773efSkenny liang * SPDX-License-Identifier: BSD-3-Clause 5*28a773efSkenny liang */ 6*28a773efSkenny liang 7*28a773efSkenny liang #include <common/bl_common.h> 8*28a773efSkenny liang #include <common/debug.h> 9*28a773efSkenny liang #include <drivers/arm/gicv3.h> 10*28a773efSkenny liang #include <bl31/interrupt_mgmt.h> 11*28a773efSkenny liang #include <../drivers/arm/gic/v3/gicv3_private.h> 12*28a773efSkenny liang #include <mt_gic_v3.h> 13*28a773efSkenny liang #include <mtk_plat_common.h> 14*28a773efSkenny liang #include "plat_private.h" 15*28a773efSkenny liang #include <plat/common/platform.h> 16*28a773efSkenny liang #include <platform_def.h> 17*28a773efSkenny liang #include <stdint.h> 18*28a773efSkenny liang #include <stdio.h> 19*28a773efSkenny liang 20*28a773efSkenny liang #define NR_INT_POL_CTL 20 21*28a773efSkenny liang 22*28a773efSkenny liang uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; 23*28a773efSkenny liang 24*28a773efSkenny liang /* 25*28a773efSkenny liang * We save and restore the GICv3 context on system suspend. Allocate the 26*28a773efSkenny liang * data in the designated EL3 Secure carve-out memory 27*28a773efSkenny liang */ 28*28a773efSkenny liang gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); 29*28a773efSkenny liang gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); 30*28a773efSkenny liang 31*28a773efSkenny liang 32*28a773efSkenny liang static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr) 33*28a773efSkenny liang { 34*28a773efSkenny liang return plat_core_pos_by_mpidr(mpidr); 35*28a773efSkenny liang } 36*28a773efSkenny liang 37*28a773efSkenny liang gicv3_driver_data_t mt_gicv3_data = { 38*28a773efSkenny liang .gicd_base = MT_GIC_BASE, 39*28a773efSkenny liang .gicr_base = MT_GIC_RDIST_BASE, 40*28a773efSkenny liang .rdistif_num = PLATFORM_CORE_COUNT, 41*28a773efSkenny liang .rdistif_base_addrs = rdistif_base_addrs, 42*28a773efSkenny liang .mpidr_to_core_pos = mt_mpidr_to_core_pos, 43*28a773efSkenny liang }; 44*28a773efSkenny liang 45*28a773efSkenny liang void setup_int_schedule_mode(enum irq_schedule_mode mode, 46*28a773efSkenny liang unsigned int active_cpu) 47*28a773efSkenny liang { 48*28a773efSkenny liang assert(mode <= HW_MODE); 49*28a773efSkenny liang assert(active_cpu <= 0xFF); 50*28a773efSkenny liang 51*28a773efSkenny liang if (mode == HW_MODE) { 52*28a773efSkenny liang mmio_write_32(GIC_INT_MASK, 53*28a773efSkenny liang (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_SEL_MASK)) 54*28a773efSkenny liang | (0x1 << GIC500_ACTIVE_SEL_SHIFT)); 55*28a773efSkenny liang } else if (mode == SW_MODE) { 56*28a773efSkenny liang mmio_write_32(GIC_INT_MASK, 57*28a773efSkenny liang (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_SEL_MASK))); 58*28a773efSkenny liang } 59*28a773efSkenny liang 60*28a773efSkenny liang mmio_write_32(GIC_INT_MASK, 61*28a773efSkenny liang (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_CPU_MASK)) 62*28a773efSkenny liang | (active_cpu << GIC500_ACTIVE_CPU_SHIFT)); 63*28a773efSkenny liang return; 64*28a773efSkenny liang } 65*28a773efSkenny liang 66*28a773efSkenny liang void clear_sec_pol_ctl_en(void) 67*28a773efSkenny liang { 68*28a773efSkenny liang unsigned int i; 69*28a773efSkenny liang 70*28a773efSkenny liang /* total 19 polarity ctrl registers */ 71*28a773efSkenny liang for (i = 0; i <= NR_INT_POL_CTL - 1; i++) { 72*28a773efSkenny liang mmio_write_32((SEC_POL_CTL_EN0 + (i * 4)), 0); 73*28a773efSkenny liang } 74*28a773efSkenny liang dsb(); 75*28a773efSkenny liang } 76*28a773efSkenny liang 77*28a773efSkenny liang void mt_gic_driver_init(void) 78*28a773efSkenny liang { 79*28a773efSkenny liang gicv3_driver_init(&mt_gicv3_data); 80*28a773efSkenny liang } 81*28a773efSkenny liang 82*28a773efSkenny liang void mt_gic_init(void) 83*28a773efSkenny liang { 84*28a773efSkenny liang gicv3_distif_init(); 85*28a773efSkenny liang gicv3_rdistif_init(plat_my_core_pos()); 86*28a773efSkenny liang gicv3_cpuif_enable(plat_my_core_pos()); 87*28a773efSkenny liang 88*28a773efSkenny liang setup_int_schedule_mode(SW_MODE, 0xf); 89*28a773efSkenny liang clear_sec_pol_ctl_en(); 90*28a773efSkenny liang } 91*28a773efSkenny liang 92*28a773efSkenny liang void mt_gic_set_pending(uint32_t irq) 93*28a773efSkenny liang { 94*28a773efSkenny liang gicv3_set_interrupt_pending(irq, plat_my_core_pos()); 95*28a773efSkenny liang } 96*28a773efSkenny liang 97*28a773efSkenny liang uint32_t mt_gic_get_pending(uint32_t irq) 98*28a773efSkenny liang { 99*28a773efSkenny liang uint32_t bit = 1 << (irq % 32); 100*28a773efSkenny liang 101*28a773efSkenny liang return (mmio_read_32(gicv3_driver_data->gicd_base + 102*28a773efSkenny liang GICD_ISPENDR + irq / 32 * 4) & bit) ? 1 : 0; 103*28a773efSkenny liang } 104*28a773efSkenny liang 105*28a773efSkenny liang void mt_gic_cpuif_enable(void) 106*28a773efSkenny liang { 107*28a773efSkenny liang gicv3_cpuif_enable(plat_my_core_pos()); 108*28a773efSkenny liang } 109*28a773efSkenny liang 110*28a773efSkenny liang void mt_gic_cpuif_disable(void) 111*28a773efSkenny liang { 112*28a773efSkenny liang gicv3_cpuif_disable(plat_my_core_pos()); 113*28a773efSkenny liang } 114*28a773efSkenny liang 115*28a773efSkenny liang void mt_gic_pcpu_init(void) 116*28a773efSkenny liang { 117*28a773efSkenny liang gicv3_rdistif_init(plat_my_core_pos()); 118*28a773efSkenny liang } 119*28a773efSkenny liang 120*28a773efSkenny liang void mt_gic_irq_save(void) 121*28a773efSkenny liang { 122*28a773efSkenny liang gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); 123*28a773efSkenny liang gicv3_distif_save(&dist_ctx); 124*28a773efSkenny liang } 125*28a773efSkenny liang 126*28a773efSkenny liang void mt_gic_irq_restore(void) 127*28a773efSkenny liang { 128*28a773efSkenny liang gicv3_distif_init_restore(&dist_ctx); 129*28a773efSkenny liang gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); 130*28a773efSkenny liang } 131*28a773efSkenny liang 132*28a773efSkenny liang void mt_gic_sync_dcm_enable(void) 133*28a773efSkenny liang { 134*28a773efSkenny liang unsigned int val = mmio_read_32(GIC_SYNC_DCM); 135*28a773efSkenny liang 136*28a773efSkenny liang val &= ~GIC_SYNC_DCM_MASK; 137*28a773efSkenny liang mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_ON); 138*28a773efSkenny liang } 139*28a773efSkenny liang 140*28a773efSkenny liang void mt_gic_sync_dcm_disable(void) 141*28a773efSkenny liang { 142*28a773efSkenny liang unsigned int val = mmio_read_32(GIC_SYNC_DCM); 143*28a773efSkenny liang 144*28a773efSkenny liang val &= ~GIC_SYNC_DCM_MASK; 145*28a773efSkenny liang mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_OFF); 146*28a773efSkenny liang } 147