aboutsummaryrefslogtreecommitdiff
path: root/plat/ti/k3
diff options
context:
space:
mode:
authorAndrew F. Davis <afd@ti.com>2019-01-22 12:39:31 -0600
committerAndrew F. Davis <afd@ti.com>2019-01-22 13:11:09 -0600
commitb5443284f4ea00c67cc3541f21ba1bcb05fea746 (patch)
tree57e4bf920387e2054067f141444e16df2cf26cf1 /plat/ti/k3
parenta0d894397d5729aa72840dc49120f4d198174e22 (diff)
downloadtrusted-firmware-a-b5443284f4ea00c67cc3541f21ba1bcb05fea746.tar.gz
ti: k3: common: Add support for runtime detection of GICR base address
Valid addresses for GICR base are always a set calculable distance from the GICD and is based on the number of cores a given instance of GICv3 IP can support. The formula for the number of address bits is given by the ARM GIC-500 TRM section 3.2 as 2^(18+log2(cores)) with the MSB set to one for GICR instances. Holes in the GIC address space are also guaranteed to safely return 0 on reads. This allows us to support runtime detection of the GICR base address by starting from GIC base address plus BIT(18) and walking until the GICR ID register (IIDR) is detected. We stop searching after BIT(20) to prevent searching out into space if something goes wrong. This can be extended out if we ever have a device with 16 or more cores. Signed-off-by: Andrew F. Davis <afd@ti.com>
Diffstat (limited to 'plat/ti/k3')
-rw-r--r--plat/ti/k3/common/k3_bl31_setup.c5
-rw-r--r--plat/ti/k3/common/k3_gicv3.c21
-rw-r--r--plat/ti/k3/include/k3_gicv3.h2
-rw-r--r--plat/ti/k3/include/platform_def.h6
4 files changed, 25 insertions, 9 deletions
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index 3fa11b2318..78fb696b22 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -23,8 +23,7 @@
const mmap_region_t plat_k3_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),
+ MAP_REGION_FLAT(K3_GIC_BASE, K3_GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_RT_BASE, SEC_PROXY_RT_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
@@ -116,7 +115,7 @@ void bl31_plat_arch_setup(void)
void bl31_platform_setup(void)
{
- k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE);
+ k3_gic_driver_init(K3_GIC_BASE);
k3_gic_init();
ti_sci_init();
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
index b7c7880141..1932eaae57 100644
--- a/plat/ti/k3/common/k3_gicv3.c
+++ b/plat/ti/k3/common/k3_gicv3.c
@@ -6,10 +6,12 @@
#include <platform_def.h>
+#include <assert.h>
#include <common/bl_common.h>
#include <common/interrupt_props.h>
#include <drivers/arm/gicv3.h>
#include <lib/utils.h>
+#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <k3_gicv3.h>
@@ -35,8 +37,25 @@ gicv3_driver_data_t k3_gic_data = {
.mpidr_to_core_pos = k3_mpidr_to_core_pos,
};
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base)
+void k3_gic_driver_init(uintptr_t gic_base)
{
+ /* GIC Distributor is always at the base of the IP */
+ uintptr_t gicd_base = gic_base;
+ /* GIC Redistributor base is run-time detected */
+ uintptr_t gicr_base = 0;
+
+ for (unsigned int gicr_shift = 18; gicr_shift < 21; gicr_shift++) {
+ uintptr_t gicr_check = gic_base + BIT(gicr_shift);
+ uint32_t iidr = mmio_read_32(gicr_check + GICR_IIDR);
+ if (iidr != 0) {
+ /* Found the GICR base */
+ gicr_base = gicr_check;
+ break;
+ }
+ }
+ /* Assert if we have not found the GICR base */
+ assert(gicr_base != 0);
+
/*
* The GICv3 driver is initialized in EL3 and does not need
* to be initialized again in SEL1. This is because the S-EL1
diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h
index 52f34ff1f6..2329a16e57 100644
--- a/plat/ti/k3/include/k3_gicv3.h
+++ b/plat/ti/k3/include/k3_gicv3.h
@@ -9,7 +9,7 @@
#include <stdint.h>
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base);
+void k3_gic_driver_init(uintptr_t gic_base);
void k3_gic_init(void);
void k3_gic_cpuif_enable(void);
void k3_gic_cpuif_disable(void);
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index 9447f04df3..f1511c136d 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -185,10 +185,8 @@
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
+#define K3_GIC_BASE 0x01800000
+#define K3_GIC_SIZE 0x200000
#define SEC_PROXY_DATA_BASE 0x32C00000
#define SEC_PROXY_DATA_SIZE 0x80000