diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c index dea2802..ca7d214 100644 --- a/plat/ti/k3/common/k3_bl31_setup.c +++ b/plat/ti/k3/common/k3_bl31_setup.c @@ -12,12 +12,15 @@ #include #include #include +#include #include /* Table of regions to map using the MMU */ const mmap_region_t plat_arm_mmap[] = { MAP_REGION_FLAT(SHARED_RAM_BASE, SHARED_RAM_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(K3_GICD_BASE, K3_GICD_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(K3_GICR_BASE, K3_GICR_SIZE, MT_DEVICE | MT_RW | MT_SECURE), { /* sentinel */ } }; @@ -107,7 +110,8 @@ void bl31_platform_setup(void) { - /* TODO: Initialize the GIC CPU and distributor interfaces */ + k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE); + k3_gic_init(); } void platform_mem_init(void) diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c new file mode 100644 index 0000000..3253130 --- /dev/null +++ b/plat/ti/k3/common/k3_gicv3.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +/* The GICv3 driver only needs to be initialized in EL3 */ +uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static const interrupt_prop_t k3_interrupt_props[] = { + PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S), + PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0) +}; + +static unsigned int k3_mpidr_to_core_pos(unsigned long mpidr) +{ + return (unsigned int)plat_core_pos_by_mpidr(mpidr); +} + +gicv3_driver_data_t k3_gic_data = { + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .interrupt_props = k3_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(k3_interrupt_props), + .mpidr_to_core_pos = k3_mpidr_to_core_pos, +}; + +void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base) +{ + /* + * The GICv3 driver is initialized in EL3 and does not need + * to be initialized again in SEL1. This is because the S-EL1 + * can use GIC system registers to manage interrupts and does + * not need GIC interface base addresses to be configured. + */ + k3_gic_data.gicd_base = gicd_base; + k3_gic_data.gicr_base = gicr_base; + gicv3_driver_init(&k3_gic_data); +} + +void k3_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void k3_gic_cpuif_enable(void) +{ + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void k3_gic_cpuif_disable(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +void k3_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); +} diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index 56a60a8..0c153f7 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -42,6 +42,13 @@ drivers/ti/uart/aarch64/16550_console.S \ ${PLAT_PATH}/common/k3_console.c \ +K3_GIC_SOURCES += \ + drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/v3/gicv3_helpers.c \ + plat/common/plat_gicv3.c \ + ${PLAT_PATH}/common/k3_gicv3.c \ + PLAT_BL_COMMON_SOURCES += \ plat/arm/common/arm_common.c \ lib/cpus/aarch64/cortex_a53.S \ @@ -52,3 +59,4 @@ ${PLAT_PATH}/common/k3_bl31_setup.c \ ${PLAT_PATH}/common/k3_helpers.S \ ${PLAT_PATH}/common/k3_topology.c \ + ${K3_GIC_SOURCES} \ diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h new file mode 100644 index 0000000..bbf5bf9 --- /dev/null +++ b/plat/ti/k3/include/k3_gicv3.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __K3_GICV3_H__ +#define __K3_GICV3_H__ + +void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base); +void k3_gic_init(void); +void k3_gic_cpuif_enable(void); +void k3_gic_cpuif_disable(void); +void k3_gic_pcpu_init(void); + +#endif /* __K3_GICV3_H__ */ diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h index a82bb36..8856af2 100644 --- a/plat/ti/k3/include/platform_def.h +++ b/plat/ti/k3/include/platform_def.h @@ -148,4 +148,48 @@ #define SYS_COUNTER_FREQ_IN_TICKS 200000000 #endif +/* Interrupt numbers */ +#define ARM_IRQ_SEC_PHY_TIMER 29 + +#define ARM_IRQ_SEC_SGI_0 8 +#define ARM_IRQ_SEC_SGI_1 9 +#define ARM_IRQ_SEC_SGI_2 10 +#define ARM_IRQ_SEC_SGI_3 11 +#define ARM_IRQ_SEC_SGI_4 12 +#define ARM_IRQ_SEC_SGI_5 13 +#define ARM_IRQ_SEC_SGI_6 14 +#define ARM_IRQ_SEC_SGI_7 15 + +/* + * Define properties of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLAT_ARM_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE) + +#define PLAT_ARM_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE) + +#define K3_GICD_BASE 0x01800000 +#define K3_GICD_SIZE 0x10000 +#define K3_GICR_BASE 0x01880000 +#define K3_GICR_SIZE 0x100000 + #endif /* __PLATFORM_DEF_H__ */