summaryrefslogtreecommitdiff
path: root/plat
diff options
context:
space:
mode:
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>2017-07-18 15:42:50 +0100
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>2017-08-02 14:10:35 +0100
commit955242d8fff132769c677d9a807ff47cd6828b7e (patch)
treec57d8d24bb569e954d2eb3cd077d7b9b2a2ac85a /plat
parent1154586b71c1e0453076a50638f00d4499eb22b0 (diff)
FVP: Support Base FVP RevC
Revision C of the Base FVP has the same memory map as earlier revisions, but has the following differences: - Implements CCI550 instead of CCI400, - Has a single instantiation of SMMUv3, - CPU MPIDs are shifted left by one level, and has MT bit set in them. The correct interconnect to program is chosen at run time based on the FVP revision. Therefore, this patch implements FVP functions for interconnect programming, rather than depending on ARM generic ones. The macros used have been renamed to reflect this change. Additionally, this patch initializes SMMUv3 as part of FVP early platform setup. New ARM config flags are introduced for feature queries at run time. Change-Id: Ic7b7f080953a51fceaf62ce7daa6de0573801f09 Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'plat')
-rw-r--r--plat/arm/board/fvp/fvp_bl31_setup.c8
-rw-r--r--plat/arm/board/fvp/fvp_common.c102
-rw-r--r--plat/arm/board/fvp/fvp_def.h1
-rw-r--r--plat/arm/board/fvp/fvp_topology.c20
-rw-r--r--plat/arm/board/fvp/include/platform_def.h13
-rw-r--r--plat/arm/board/fvp/platform.mk6
6 files changed, 128 insertions, 22 deletions
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index 52a4432d..181c9231 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -1,10 +1,12 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arm_config.h>
#include <plat_arm.h>
+#include <smmu_v3.h>
#include "fvp_private.h"
#if LOAD_IMAGE_V2
@@ -34,4 +36,8 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
* FVP PSCI code will enable coherency for other clusters.
*/
fvp_interconnect_enable();
+
+ /* On FVP RevC, intialize SMMUv3 */
+ if (arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3)
+ smmuv3_init(PLAT_FVP_SMMUV3_BASE);
}
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 2f5d7fcf..c1dcc02c 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -1,11 +1,13 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arm_config.h>
#include <arm_def.h>
+#include <assert.h>
+#include <cci.h>
#include <ccn.h>
#include <debug.h>
#include <gicv2.h>
@@ -118,6 +120,30 @@ const mmap_region_t plat_arm_mmap[] = {
ARM_CASSERT_MMAP
+#if FVP_INTERCONNECT_DRIVER != FVP_CCN
+static const int fvp_cci400_map[] = {
+ PLAT_FVP_CCI400_CLUS0_SL_PORT,
+ PLAT_FVP_CCI400_CLUS1_SL_PORT,
+};
+
+static const int fvp_cci5xx_map[] = {
+ PLAT_FVP_CCI5XX_CLUS0_SL_PORT,
+ PLAT_FVP_CCI5XX_CLUS1_SL_PORT,
+};
+
+static unsigned int get_interconnect_master(void)
+{
+ unsigned int master;
+ u_register_t mpidr;
+
+ mpidr = read_mpidr_el1();
+ master = (arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) ?
+ MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);
+
+ assert(master < FVP_CLUSTER_COUNT);
+ return master;
+}
+#endif
/*******************************************************************************
* A single boot loader stack is expected to work on both the Foundation FVP
@@ -182,8 +208,7 @@ void fvp_config_setup(void)
}
break;
case HBI_BASE_FVP:
- arm_config.flags |= ARM_CONFIG_BASE_MMAP |
- ARM_CONFIG_HAS_INTERCONNECT | ARM_CONFIG_HAS_TZC;
+ arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC);
/*
* Check for supported revisions
@@ -191,6 +216,12 @@ void fvp_config_setup(void)
*/
switch (rev) {
case REV_BASE_FVP_V0:
+ arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400;
+ break;
+ case REV_BASE_FVP_REVC:
+ arm_config.flags |= (ARM_CONFIG_FVP_SHIFTED_AFF |
+ ARM_CONFIG_FVP_HAS_SMMUV3 |
+ ARM_CONFIG_FVP_HAS_CCI5XX);
break;
default:
WARN("Unrecognized Base FVP revision %x\n", rev);
@@ -206,26 +237,67 @@ void fvp_config_setup(void)
void fvp_interconnect_init(void)
{
- if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) {
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
- if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
- ERROR("Unrecognized CCN variant detected. Only CCN-502"
- " is supported");
- panic();
- }
-#endif
- plat_arm_interconnect_init();
+ if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
+ ERROR("Unrecognized CCN variant detected. Only CCN-502"
+ " is supported");
+ panic();
+ }
+
+ plat_arm_interconnect_init();
+#else
+ uintptr_t cci_base = 0;
+ const int *cci_map = 0;
+ unsigned int map_size = 0;
+
+ if (!(arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
+ ARM_CONFIG_FVP_HAS_CCI5XX))) {
+ return;
+ }
+
+ /* Initialize the right interconnect */
+ if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) {
+ cci_base = PLAT_FVP_CCI5XX_BASE;
+ cci_map = fvp_cci5xx_map;
+ map_size = ARRAY_SIZE(fvp_cci5xx_map);
+ } else if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) {
+ cci_base = PLAT_FVP_CCI400_BASE;
+ cci_map = fvp_cci400_map;
+ map_size = ARRAY_SIZE(fvp_cci400_map);
}
+
+ assert(cci_base);
+ assert(cci_map);
+ cci_init(cci_base, cci_map, map_size);
+#endif
}
void fvp_interconnect_enable(void)
{
- if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT)
- plat_arm_interconnect_enter_coherency();
+#if FVP_INTERCONNECT_DRIVER == FVP_CCN
+ plat_arm_interconnect_enter_coherency();
+#else
+ unsigned int master;
+
+ if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
+ ARM_CONFIG_FVP_HAS_CCI5XX)) {
+ master = get_interconnect_master();
+ cci_enable_snoop_dvm_reqs(master);
+ }
+#endif
}
void fvp_interconnect_disable(void)
{
- if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT)
- plat_arm_interconnect_exit_coherency();
+#if FVP_INTERCONNECT_DRIVER == FVP_CCN
+ plat_arm_interconnect_exit_coherency();
+#else
+ unsigned int master;
+
+ if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
+ ARM_CONFIG_FVP_HAS_CCI5XX)) {
+ master = get_interconnect_master();
+ cci_disable_snoop_dvm_reqs(master);
+ }
+#endif
}
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index 84e790bf..a430bcac 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -78,6 +78,7 @@
/* Constants to distinguish FVP type */
#define HBI_BASE_FVP 0x020
#define REV_BASE_FVP_V0 0x0
+#define REV_BASE_FVP_REVC 0x2
#define HBI_FOUNDATION_FVP 0x010
#define REV_FOUNDATION_FVP_V2_0 0x0
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index 848aaf8c..cf1492b6 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -56,6 +56,26 @@ unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
******************************************************************************/
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
+ unsigned int clus_id, cpu_id, thread_id;
+
+ /* Validate affinity fields */
+ if (arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) {
+ thread_id = MPIDR_AFFLVL0_VAL(mpidr);
+ cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
+ clus_id = MPIDR_AFFLVL2_VAL(mpidr);
+ } else {
+ thread_id = 0;
+ cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+ clus_id = MPIDR_AFFLVL1_VAL(mpidr);
+ }
+
+ if (clus_id >= FVP_CLUSTER_COUNT)
+ return -1;
+ if (cpu_id >= FVP_MAX_CPUS_PER_CLUSTER)
+ return -1;
+ if (thread_id >= FVP_MAX_PE_PER_CPU)
+ return -1;
+
if (fvp_pwrc_read_psysr(mpidr) == PSYSR_INVALID)
return -1;
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 7a7cf9e7..bf038e92 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -68,10 +68,17 @@
#define PLAT_ARM_TSP_UART_BASE V2M_IOFPGA_UART2_BASE
#define PLAT_ARM_TSP_UART_CLK_IN_HZ V2M_IOFPGA_UART2_CLK_IN_HZ
+#define PLAT_FVP_SMMUV3_BASE 0x2b400000
+
/* CCI related constants */
-#define PLAT_ARM_CCI_BASE 0x2c090000
-#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 3
-#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 4
+#define PLAT_FVP_CCI400_BASE 0x2c090000
+#define PLAT_FVP_CCI400_CLUS0_SL_PORT 3
+#define PLAT_FVP_CCI400_CLUS1_SL_PORT 4
+
+/* CCI-500/CCI-550 on Base platform */
+#define PLAT_FVP_CCI5XX_BASE 0x2a000000
+#define PLAT_FVP_CCI5XX_CLUS0_SL_PORT 5
+#define PLAT_FVP_CCI5XX_CLUS1_SL_PORT 6
/* CCN related constants. Only CCN 502 is currently supported */
#define PLAT_ARM_CCN_BASE 0x2e000000
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index d9c624cd..0b6e1da5 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -72,8 +72,7 @@ $(error "Incorrect GIC driver chosen on FVP port")
endif
ifeq (${FVP_INTERCONNECT_DRIVER}, FVP_CCI)
-FVP_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \
- plat/arm/common/arm_cci.c
+FVP_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c
else ifeq (${FVP_INTERCONNECT_DRIVER}, FVP_CCN)
FVP_INTERCONNECT_SOURCES := drivers/arm/ccn/ccn.c \
plat/arm/common/arm_ccn.c
@@ -136,7 +135,8 @@ endif
BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \
${FVP_SECURITY_SOURCES}
-BL31_SOURCES += plat/arm/board/fvp/fvp_bl31_setup.c \
+BL31_SOURCES += drivers/arm/smmu/smmu_v3.c \
+ plat/arm/board/fvp/fvp_bl31_setup.c \
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/aarch64/fvp_helpers.S \