1 /* 2 * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stdint.h> 9 #include <stdio.h> 10 11 #include "../drivers/arm/gic/v3/gicv3_private.h" 12 #include <bl31/interrupt_mgmt.h> 13 #include <common/bl_common.h> 14 #include <common/debug.h> 15 #include <lib/mtk_init/mtk_init.h> 16 #include <mt_gic_v3.h> 17 #include <mtk_plat_common.h> 18 #include <plat/common/platform.h> 19 #include <plat_private.h> 20 #include <platform_def.h> 21 22 #define SGI_MASK 0xffff 23 24 uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; 25 static uint32_t rdist_has_saved[PLATFORM_CORE_COUNT]; 26 27 /* we save and restore the GICv3 context on system suspend */ 28 gicv3_dist_ctx_t dist_ctx; 29 30 static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr) 31 { 32 return plat_core_pos_by_mpidr(mpidr); 33 } 34 35 gicv3_driver_data_t mt_gicv3_data = { 36 .gicd_base = MT_GIC_BASE, 37 .gicr_base = MT_GIC_RDIST_BASE, 38 .rdistif_num = PLATFORM_CORE_COUNT, 39 .rdistif_base_addrs = rdistif_base_addrs, 40 .mpidr_to_core_pos = mt_mpidr_to_core_pos, 41 }; 42 43 struct gic_chip_data { 44 /* All cores share the same configuration */ 45 unsigned int saved_group; 46 unsigned int saved_enable; 47 unsigned int saved_conf0; 48 unsigned int saved_conf1; 49 unsigned int saved_grpmod; 50 /* Per-core sgi */ 51 unsigned int saved_sgi[PLATFORM_CORE_COUNT]; 52 }; 53 54 static struct gic_chip_data gic_data; 55 56 void mt_gic_driver_init(void) 57 { 58 gicv3_driver_init(&mt_gicv3_data); 59 } 60 61 void mt_gic_set_pending(uint32_t irq) 62 { 63 gicv3_set_interrupt_pending(irq, plat_my_core_pos()); 64 } 65 66 void mt_gic_distif_save(void) 67 { 68 gicv3_distif_save(&dist_ctx); 69 } 70 71 void mt_gic_distif_restore(void) 72 { 73 gicv3_distif_init_restore(&dist_ctx); 74 } 75 76 void mt_gic_rdistif_init(void) 77 { 78 unsigned int proc_num; 79 unsigned int index; 80 uintptr_t gicr_base; 81 82 proc_num = plat_my_core_pos(); 83 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 84 85 /* set all SGI/PPI as non-secure GROUP1 by default */ 86 mmio_write_32(gicr_base + GICR_IGROUPR0, ~0U); 87 mmio_write_32(gicr_base + GICR_IGRPMODR0, 0x0); 88 89 /* setup the default PPI/SGI priorities */ 90 for (index = 0; index < TOTAL_PCPU_INTR_NUM; index += 4U) 91 gicr_write_ipriorityr(gicr_base, index, 92 GICD_IPRIORITYR_DEF_VAL); 93 } 94 95 void mt_gic_rdistif_save(void) 96 { 97 unsigned int proc_num; 98 uintptr_t gicr_base; 99 100 proc_num = plat_my_core_pos(); 101 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 102 103 gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0); 104 gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0); 105 gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0); 106 gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1); 107 gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0); 108 109 rdist_has_saved[proc_num] = 1; 110 } 111 112 void mt_gic_rdistif_restore(void) 113 { 114 unsigned int proc_num; 115 uintptr_t gicr_base; 116 117 proc_num = plat_my_core_pos(); 118 if (rdist_has_saved[proc_num] == 1) { 119 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 120 mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); 121 mmio_write_32(gicr_base + GICR_ISENABLER0, 122 gic_data.saved_enable); 123 mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); 124 mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); 125 mmio_write_32(gicr_base + GICR_IGRPMODR0, 126 gic_data.saved_grpmod); 127 } 128 } 129 130 void mt_gic_rdistif_restore_all(void) 131 { 132 unsigned int proc_num; 133 uintptr_t gicr_base; 134 135 for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { 136 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 137 mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); 138 mmio_write_32(gicr_base + GICR_ISENABLER0, 139 gic_data.saved_enable); 140 mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); 141 mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); 142 mmio_write_32(gicr_base + GICR_IGRPMODR0, 143 gic_data.saved_grpmod); 144 } 145 } 146 147 void gic_sgi_save_all(void) 148 { 149 unsigned int proc_num; 150 uintptr_t gicr_base; 151 152 for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { 153 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 154 gic_data.saved_sgi[proc_num] = 155 mmio_read_32(gicr_base + GICR_ISPENDR0) & SGI_MASK; 156 } 157 } 158 159 void gic_sgi_restore_all(void) 160 { 161 unsigned int proc_num; 162 uintptr_t gicr_base; 163 164 for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { 165 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 166 mmio_write_32(gicr_base + GICR_ICPENDR0, SGI_MASK); 167 mmio_write_32(gicr_base + GICR_ISPENDR0, 168 gic_data.saved_sgi[proc_num] & SGI_MASK); 169 } 170 } 171 172 void mt_gic_init(void) 173 { 174 gicv3_distif_init(); 175 gicv3_rdistif_init(plat_my_core_pos()); 176 gicv3_cpuif_enable(plat_my_core_pos()); 177 } 178 179 uint32_t mt_irq_get_pending(uint32_t irq) 180 { 181 uint32_t val; 182 183 val = mmio_read_32(BASE_GICD_BASE + GICD_ISPENDR + 184 irq / 32 * 4); 185 val = (val >> (irq % 32)) & 1U; 186 return val; 187 } 188 189 190 void mt_irq_set_pending(uint32_t irq) 191 { 192 uint32_t bit = 1U << (irq % 32); 193 194 mmio_write_32(BASE_GICD_BASE + GICD_ISPENDR + 195 irq / 32 * 4, bit); 196 } 197 198 int mt_gic_one_init(void) 199 { 200 INFO("[%s] GIC initialization\n", __func__); 201 202 /* Initialize the GIC driver, CPU and distributor interfaces */ 203 mt_gic_driver_init(); 204 mt_gic_init(); 205 206 return 0; 207 } 208 MTK_PLAT_SETUP_0_INIT(mt_gic_one_init); 209