1 /*
2  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <platform_def.h>
8 
9 #include <assert.h>
10 #include <common/bl_common.h>
11 #include <common/interrupt_props.h>
12 #include <drivers/arm/gicv3.h>
13 #include <lib/utils.h>
14 #include <lib/mmio.h>
15 #include <plat/common/platform.h>
16 
17 #include <k3_gicv3.h>
18 
19 /* The GICv3 driver only needs to be initialized in EL3 */
20 uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
21 
22 static const interrupt_prop_t k3_interrupt_props[] = {
23 	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
24 	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
25 };
26 
k3_mpidr_to_core_pos(unsigned long mpidr)27 static unsigned int k3_mpidr_to_core_pos(unsigned long mpidr)
28 {
29 	return (unsigned int)plat_core_pos_by_mpidr(mpidr);
30 }
31 
32 gicv3_driver_data_t k3_gic_data = {
33 	.rdistif_num = PLATFORM_CORE_COUNT,
34 	.rdistif_base_addrs = rdistif_base_addrs,
35 	.interrupt_props = k3_interrupt_props,
36 	.interrupt_props_num = ARRAY_SIZE(k3_interrupt_props),
37 	.mpidr_to_core_pos = k3_mpidr_to_core_pos,
38 };
39 
k3_gic_driver_init(uintptr_t gic_base)40 void k3_gic_driver_init(uintptr_t gic_base)
41 {
42 	/* GIC Distributor is always at the base of the IP */
43 	uintptr_t gicd_base = gic_base;
44 	/* GIC Redistributor base is run-time detected */
45 	uintptr_t gicr_base = 0;
46 
47 	for (unsigned int gicr_shift = 18; gicr_shift < 21; gicr_shift++) {
48 		uintptr_t gicr_check = gic_base + BIT(gicr_shift);
49 		uint32_t iidr = mmio_read_32(gicr_check + GICR_IIDR);
50 		if (iidr != 0) {
51 			/* Found the GICR base */
52 			gicr_base = gicr_check;
53 			break;
54 		}
55 	}
56 	/* Assert if we have not found the GICR base */
57 	assert(gicr_base != 0);
58 
59 	/*
60 	 * The GICv3 driver is initialized in EL3 and does not need
61 	 * to be initialized again in SEL1. This is because the S-EL1
62 	 * can use GIC system registers to manage interrupts and does
63 	 * not need GIC interface base addresses to be configured.
64 	 */
65 	k3_gic_data.gicd_base = gicd_base;
66 	k3_gic_data.gicr_base = gicr_base;
67 	gicv3_driver_init(&k3_gic_data);
68 }
69 
k3_gic_init(void)70 void k3_gic_init(void)
71 {
72 	gicv3_distif_init();
73 	gicv3_rdistif_init(plat_my_core_pos());
74 	gicv3_cpuif_enable(plat_my_core_pos());
75 }
76 
k3_gic_cpuif_enable(void)77 void k3_gic_cpuif_enable(void)
78 {
79 	gicv3_cpuif_enable(plat_my_core_pos());
80 }
81 
k3_gic_cpuif_disable(void)82 void k3_gic_cpuif_disable(void)
83 {
84 	gicv3_cpuif_disable(plat_my_core_pos());
85 }
86 
k3_gic_pcpu_init(void)87 void k3_gic_pcpu_init(void)
88 {
89 	gicv3_rdistif_init(plat_my_core_pos());
90 }
91