xref: /rk3399_ARM-atf/plat/mediatek/mt8183/plat_mt_gic.c (revision 28a773eff427f21cbfa30e026c11a72f58079bc0)
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