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