128a773efSkenny liang /* 2f992b960Skenny liang * Copyright (c) 2019, MediaTek Inc. All rights reserved. 328a773efSkenny liang * 428a773efSkenny liang * SPDX-License-Identifier: BSD-3-Clause 528a773efSkenny liang */ 628a773efSkenny liang 7f992b960Skenny liang #include <assert.h> 828a773efSkenny liang #include <common/bl_common.h> 928a773efSkenny liang #include <common/debug.h> 1028a773efSkenny liang #include <drivers/arm/gicv3.h> 1128a773efSkenny liang #include <bl31/interrupt_mgmt.h> 1228a773efSkenny liang #include <mt_gic_v3.h> 1328a773efSkenny liang #include <mtk_plat_common.h> 14*4450a518Skenny liang #include "../drivers/arm/gic/v3/gicv3_private.h" 1528a773efSkenny liang #include "plat_private.h" 1628a773efSkenny liang #include <plat/common/platform.h> 1728a773efSkenny liang #include <platform_def.h> 1828a773efSkenny liang #include <stdint.h> 1928a773efSkenny liang #include <stdio.h> 2028a773efSkenny liang 2128a773efSkenny liang uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; 22*4450a518Skenny liang static uint32_t rdist_has_saved[PLATFORM_CORE_COUNT]; 2328a773efSkenny liang 24f992b960Skenny liang /* we save and restore the GICv3 context on system suspend */ 25f992b960Skenny liang gicv3_dist_ctx_t dist_ctx; 2628a773efSkenny liang 2728a773efSkenny liang static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr) 2828a773efSkenny liang { 2928a773efSkenny liang return plat_core_pos_by_mpidr(mpidr); 3028a773efSkenny liang } 3128a773efSkenny liang 3228a773efSkenny liang gicv3_driver_data_t mt_gicv3_data = { 3328a773efSkenny liang .gicd_base = MT_GIC_BASE, 3428a773efSkenny liang .gicr_base = MT_GIC_RDIST_BASE, 3528a773efSkenny liang .rdistif_num = PLATFORM_CORE_COUNT, 3628a773efSkenny liang .rdistif_base_addrs = rdistif_base_addrs, 3728a773efSkenny liang .mpidr_to_core_pos = mt_mpidr_to_core_pos, 3828a773efSkenny liang }; 3928a773efSkenny liang 40*4450a518Skenny liang struct gic_chip_data { 41*4450a518Skenny liang unsigned int saved_group; 42*4450a518Skenny liang unsigned int saved_enable; 43*4450a518Skenny liang unsigned int saved_conf0; 44*4450a518Skenny liang unsigned int saved_conf1; 45*4450a518Skenny liang unsigned int saved_grpmod; 46*4450a518Skenny liang }; 47*4450a518Skenny liang 48*4450a518Skenny liang static struct gic_chip_data gic_data; 49*4450a518Skenny liang 5028a773efSkenny liang void clear_sec_pol_ctl_en(void) 5128a773efSkenny liang { 5228a773efSkenny liang unsigned int i; 5328a773efSkenny liang 5428a773efSkenny liang /* total 19 polarity ctrl registers */ 5528a773efSkenny liang for (i = 0; i <= NR_INT_POL_CTL - 1; i++) { 5628a773efSkenny liang mmio_write_32((SEC_POL_CTL_EN0 + (i * 4)), 0); 5728a773efSkenny liang } 5828a773efSkenny liang dsb(); 5928a773efSkenny liang } 6028a773efSkenny liang 6128a773efSkenny liang void mt_gic_driver_init(void) 6228a773efSkenny liang { 6328a773efSkenny liang gicv3_driver_init(&mt_gicv3_data); 6428a773efSkenny liang } 6528a773efSkenny liang 6628a773efSkenny liang void mt_gic_set_pending(uint32_t irq) 6728a773efSkenny liang { 6828a773efSkenny liang gicv3_set_interrupt_pending(irq, plat_my_core_pos()); 6928a773efSkenny liang } 7028a773efSkenny liang 7128a773efSkenny liang void mt_gic_cpuif_enable(void) 7228a773efSkenny liang { 7328a773efSkenny liang gicv3_cpuif_enable(plat_my_core_pos()); 7428a773efSkenny liang } 7528a773efSkenny liang 7628a773efSkenny liang void mt_gic_cpuif_disable(void) 7728a773efSkenny liang { 7828a773efSkenny liang gicv3_cpuif_disable(plat_my_core_pos()); 7928a773efSkenny liang } 8028a773efSkenny liang 81*4450a518Skenny liang void mt_gic_rdistif_init(void) 8228a773efSkenny liang { 83*4450a518Skenny liang unsigned int proc_num; 84*4450a518Skenny liang unsigned int index; 85*4450a518Skenny liang uintptr_t gicr_base; 86*4450a518Skenny liang 87*4450a518Skenny liang proc_num = plat_my_core_pos(); 88*4450a518Skenny liang gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 89*4450a518Skenny liang 90*4450a518Skenny liang /* set all SGI/PPI as non-secure GROUP1 by default */ 91*4450a518Skenny liang mmio_write_32(gicr_base + GICR_IGROUPR0, ~0U); 92*4450a518Skenny liang mmio_write_32(gicr_base + GICR_IGRPMODR0, 0x0); 93*4450a518Skenny liang 94*4450a518Skenny liang /* setup the default PPI/SGI priorities */ 95*4450a518Skenny liang for (index = 0; index < TOTAL_PCPU_INTR_NUM; index += 4U) 96*4450a518Skenny liang gicr_write_ipriorityr(gicr_base, index, 97*4450a518Skenny liang GICD_IPRIORITYR_DEF_VAL); 9828a773efSkenny liang } 9928a773efSkenny liang 100*4450a518Skenny liang void mt_gic_distif_save(void) 10128a773efSkenny liang { 10228a773efSkenny liang gicv3_distif_save(&dist_ctx); 10328a773efSkenny liang } 10428a773efSkenny liang 105*4450a518Skenny liang void mt_gic_distif_restore(void) 10628a773efSkenny liang { 10728a773efSkenny liang gicv3_distif_init_restore(&dist_ctx); 108*4450a518Skenny liang } 109*4450a518Skenny liang 110*4450a518Skenny liang void mt_gic_rdistif_save(void) 111*4450a518Skenny liang { 112*4450a518Skenny liang unsigned int proc_num; 113*4450a518Skenny liang uintptr_t gicr_base; 114*4450a518Skenny liang 115*4450a518Skenny liang proc_num = plat_my_core_pos(); 116*4450a518Skenny liang gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 117*4450a518Skenny liang 118*4450a518Skenny liang gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0); 119*4450a518Skenny liang gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0); 120*4450a518Skenny liang gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0); 121*4450a518Skenny liang gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1); 122*4450a518Skenny liang gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0); 123*4450a518Skenny liang 124*4450a518Skenny liang rdist_has_saved[proc_num] = 1; 125*4450a518Skenny liang } 126*4450a518Skenny liang 127*4450a518Skenny liang void mt_gic_rdistif_restore(void) 128*4450a518Skenny liang { 129*4450a518Skenny liang unsigned int proc_num; 130*4450a518Skenny liang uintptr_t gicr_base; 131*4450a518Skenny liang 132*4450a518Skenny liang proc_num = plat_my_core_pos(); 133*4450a518Skenny liang if (rdist_has_saved[proc_num] == 1) { 134*4450a518Skenny liang gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 135*4450a518Skenny liang mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); 136*4450a518Skenny liang mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable); 137*4450a518Skenny liang mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); 138*4450a518Skenny liang mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); 139*4450a518Skenny liang mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod); 140*4450a518Skenny liang } 14128a773efSkenny liang } 14228a773efSkenny liang 14328a773efSkenny liang void mt_gic_sync_dcm_enable(void) 14428a773efSkenny liang { 145*4450a518Skenny liang mmio_clrsetbits_32(GIC_SYNC_DCM, GIC_SYNC_DCM_MASK, GIC_SYNC_DCM_ON); 14628a773efSkenny liang } 14728a773efSkenny liang 14828a773efSkenny liang void mt_gic_sync_dcm_disable(void) 14928a773efSkenny liang { 150*4450a518Skenny liang mmio_clrsetbits_32(GIC_SYNC_DCM, GIC_SYNC_DCM_MASK, GIC_SYNC_DCM_OFF); 151*4450a518Skenny liang } 15228a773efSkenny liang 153*4450a518Skenny liang void mt_gic_init(void) 154*4450a518Skenny liang { 155*4450a518Skenny liang gicv3_distif_init(); 156*4450a518Skenny liang gicv3_cpuif_enable(plat_my_core_pos()); 157*4450a518Skenny liang mt_gic_rdistif_init(); 158*4450a518Skenny liang 159*4450a518Skenny liang clear_sec_pol_ctl_en(); 16028a773efSkenny liang } 161