1 /* 2 * Copyright (c) 2020-2024, 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 const interrupt_prop_t mtk_interrupt_props[] = { 31 PLAT_MTK_G1S_IRQ_PROPS(INTR_GROUP1S) 32 }; 33 34 static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr) 35 { 36 return plat_core_pos_by_mpidr(mpidr); 37 } 38 39 gicv3_driver_data_t mt_gicv3_data = { 40 .gicd_base = MT_GIC_BASE, 41 .gicr_base = MT_GIC_RDIST_BASE, 42 .interrupt_props = mtk_interrupt_props, 43 .interrupt_props_num = ARRAY_SIZE(mtk_interrupt_props), 44 .rdistif_num = PLATFORM_CORE_COUNT, 45 .rdistif_base_addrs = rdistif_base_addrs, 46 .mpidr_to_core_pos = mt_mpidr_to_core_pos, 47 }; 48 49 struct gic_chip_data { 50 /* All cores share the same configuration */ 51 unsigned int saved_ctlr; 52 unsigned int saved_group; 53 unsigned int saved_enable; 54 unsigned int saved_conf0; 55 unsigned int saved_conf1; 56 unsigned int saved_grpmod; 57 unsigned int saved_ispendr; 58 unsigned int saved_isactiver; 59 unsigned int saved_nsacr; 60 /* Per-core sgi */ 61 unsigned int saved_sgi[PLATFORM_CORE_COUNT]; 62 /* Per-core priority */ 63 unsigned int saved_prio[PLATFORM_CORE_COUNT][GICR_NUM_REGS(IPRIORITYR)]; 64 }; 65 66 static struct gic_chip_data gic_data; 67 68 void mt_gic_driver_init(void) 69 { 70 gicv3_driver_init(&mt_gicv3_data); 71 } 72 73 void mt_gic_set_pending(uint32_t irq) 74 { 75 gicv3_set_interrupt_pending(irq, plat_my_core_pos()); 76 } 77 78 void mt_gic_distif_save(void) 79 { 80 gicv3_distif_save(&dist_ctx); 81 } 82 83 void mt_gic_distif_restore(void) 84 { 85 gicv3_distif_init_restore(&dist_ctx); 86 } 87 88 void mt_gic_rdistif_init(void) 89 { 90 unsigned int proc_num; 91 unsigned int index; 92 uintptr_t gicr_base; 93 94 proc_num = plat_my_core_pos(); 95 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 96 97 /* set all SGI/PPI as non-secure GROUP1 by default */ 98 mmio_write_32(gicr_base + GICR_IGROUPR0, ~0U); 99 mmio_write_32(gicr_base + GICR_IGRPMODR0, 0x0); 100 101 /* setup the default PPI/SGI priorities */ 102 for (index = 0; index < TOTAL_PCPU_INTR_NUM; index += 4U) 103 gicr_write_ipriorityr(gicr_base, index, 104 GICD_IPRIORITYR_DEF_VAL); 105 } 106 107 void mt_gic_rdistif_save(void) 108 { 109 unsigned int i, proc_num; 110 uintptr_t gicr_base; 111 112 proc_num = plat_my_core_pos(); 113 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 114 115 /* 116 * Wait for any write to GICR_CTLR to complete before trying to save any 117 * state. 118 */ 119 gicr_wait_for_pending_write(gicr_base); 120 121 gic_data.saved_ctlr = mmio_read_32(gicr_base + GICR_CTLR); 122 gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0); 123 gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0); 124 gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0); 125 gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1); 126 gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0); 127 gic_data.saved_ispendr = mmio_read_32(gicr_base + GICR_ISPENDR0); 128 gic_data.saved_isactiver = mmio_read_32(gicr_base + GICR_ISACTIVER0); 129 gic_data.saved_nsacr = mmio_read_32(gicr_base + GICR_NSACR); 130 131 for (i = 0U; i < 8U; ++i) 132 gic_data.saved_prio[proc_num][i] = gicr_ipriorityr_read(gicr_base, i); 133 134 rdist_has_saved[proc_num] = 1; 135 } 136 137 void mt_gic_rdistif_restore(void) 138 { 139 unsigned int i, proc_num; 140 uintptr_t gicr_base; 141 142 proc_num = plat_my_core_pos(); 143 if (rdist_has_saved[proc_num] == 1) { 144 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 145 146 mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); 147 mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod); 148 mmio_write_32(gicr_base + GICR_NSACR, gic_data.saved_nsacr); 149 mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); 150 mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); 151 152 for (i = 0U; i < 8U; ++i) 153 gicr_ipriorityr_write(gicr_base, i, gic_data.saved_prio[proc_num][i]); 154 155 mmio_write_32(gicr_base + GICR_ISPENDR0, gic_data.saved_ispendr); 156 mmio_write_32(gicr_base + GICR_ISACTIVER0, gic_data.saved_isactiver); 157 mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable); 158 mmio_write_32(gicr_base + GICR_CTLR, gic_data.saved_ctlr); 159 160 gicr_wait_for_pending_write(gicr_base); 161 } 162 } 163 164 void mt_gic_rdistif_restore_all(void) 165 { 166 unsigned int i, proc_num; 167 uintptr_t gicr_base; 168 169 for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { 170 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 171 172 mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); 173 mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod); 174 mmio_write_32(gicr_base + GICR_NSACR, gic_data.saved_nsacr); 175 mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); 176 mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); 177 178 for (i = 0U; i < 8U; ++i) 179 gicr_ipriorityr_write(gicr_base, i, gic_data.saved_prio[proc_num][i]); 180 181 mmio_write_32(gicr_base + GICR_ISPENDR0, gic_data.saved_ispendr); 182 mmio_write_32(gicr_base + GICR_ISACTIVER0, gic_data.saved_isactiver); 183 mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable); 184 mmio_write_32(gicr_base + GICR_CTLR, gic_data.saved_ctlr); 185 186 gicr_wait_for_pending_write(gicr_base); 187 } 188 } 189 190 void gic_sgi_save_all(void) 191 { 192 unsigned int proc_num; 193 uintptr_t gicr_base; 194 195 for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { 196 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 197 gic_data.saved_sgi[proc_num] = 198 mmio_read_32(gicr_base + GICR_ISPENDR0) & SGI_MASK; 199 } 200 } 201 202 void gic_sgi_restore_all(void) 203 { 204 unsigned int proc_num; 205 uintptr_t gicr_base; 206 207 for (proc_num = 0; proc_num < PLATFORM_CORE_COUNT; proc_num++) { 208 gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; 209 mmio_write_32(gicr_base + GICR_ICPENDR0, SGI_MASK); 210 mmio_write_32(gicr_base + GICR_ISPENDR0, 211 gic_data.saved_sgi[proc_num] & SGI_MASK); 212 } 213 } 214 215 void mt_gic_init(void) 216 { 217 gicv3_distif_init(); 218 gicv3_rdistif_init(plat_my_core_pos()); 219 gicv3_cpuif_enable(plat_my_core_pos()); 220 } 221 222 uint32_t mt_irq_get_pending(uint32_t irq) 223 { 224 uint32_t val; 225 226 val = mmio_read_32(BASE_GICD_BASE + GICD_ISPENDR + 227 irq / 32 * 4); 228 val = (val >> (irq % 32)) & 1U; 229 return val; 230 } 231 232 233 void mt_irq_set_pending(uint32_t irq) 234 { 235 uint32_t bit = 1U << (irq % 32); 236 237 mmio_write_32(BASE_GICD_BASE + GICD_ISPENDR + 238 irq / 32 * 4, bit); 239 } 240 241 int mt_gic_one_init(void) 242 { 243 INFO("[%s] GIC initialization\n", __func__); 244 245 /* Initialize the GIC driver, CPU and distributor interfaces */ 246 mt_gic_driver_init(); 247 mt_gic_init(); 248 249 return 0; 250 } 251 MTK_PLAT_SETUP_0_INIT(mt_gic_one_init); 252