feat(msm8916): initialize CCI-400 for multiple clusters
The MSM8939 SoC is very similar to MSM8916 but uses an ARM CCI-400
for cache coherence between the two CPU clusters. Add the necessary
code to initialize it with the existing driver.
No functional change for platforms with a single cluster. The CCI
related code is discarded entirely in this case.
Change-Id: I041d60222d8d2aeca53b392934c87280c66b0db0
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
diff --git a/plat/qti/msm8916/include/msm8916_mmap.h b/plat/qti/msm8916/include/msm8916_mmap.h
index 5cb2f44..20c5a57 100644
--- a/plat/qti/msm8916/include/msm8916_mmap.h
+++ b/plat/qti/msm8916/include/msm8916_mmap.h
@@ -43,4 +43,9 @@
#define APCS_ALIAS_ACS(cluster, cpu) (_APCS_CPU(cluster, cpu) + 0x88000)
#define APCS_ALIAS_SAW2(cluster, cpu) (_APCS_CPU(cluster, cpu) + 0x89000)
+/* Only on platforms with multiple clusters (e.g. MSM8939) */
+#define APCS_CCI_BASE (APCS_BASE + 0x1c0000)
+#define APCS_CCI_SAW2 (APCS_BASE + 0x1d2000)
+#define APCS_CCI_ACS (APCS_BASE + 0x1d4000)
+
#endif /* MSM8916_MMAP_H */
diff --git a/plat/qti/msm8916/msm8916_bl31_setup.c b/plat/qti/msm8916/msm8916_bl31_setup.c
index 449be7f..c588020 100644
--- a/plat/qti/msm8916/msm8916_bl31_setup.c
+++ b/plat/qti/msm8916/msm8916_bl31_setup.c
@@ -33,6 +33,7 @@
u_register_t arg2, u_register_t arg3)
{
msm8916_early_platform_setup();
+ msm8916_configure_early();
}
void bl31_plat_arch_setup(void)
diff --git a/plat/qti/msm8916/msm8916_config.c b/plat/qti/msm8916/msm8916_config.c
index 47eede2..b37fd19 100644
--- a/plat/qti/msm8916/msm8916_config.c
+++ b/plat/qti/msm8916/msm8916_config.c
@@ -7,6 +7,7 @@
#include <assert.h>
#include <arch.h>
+#include <drivers/arm/cci.h>
#include <lib/mmio.h>
#include "msm8916_config.h"
@@ -14,6 +15,16 @@
#include <msm8916_mmap.h>
#include <platform_def.h>
+static const int cci_map[] = { 3, 4 };
+
+void msm8916_configure_early(void)
+{
+ if (PLATFORM_CLUSTER_COUNT > 1) {
+ cci_init(APCS_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
+ }
+}
+
static void msm8916_configure_timer(uintptr_t base)
{
/* Set timer frequency */
@@ -81,6 +92,12 @@
for (cluster = 0; cluster < PLATFORM_CLUSTER_COUNT; cluster++) {
msm8916_configure_apcs_cluster(cluster);
}
+
+ if (PLATFORM_CLUSTER_COUNT > 1) {
+ /* Disallow non-secure access to CCI ACS and SAW2 */
+ mmio_write_32(APCS_CCI_ACS, 0);
+ mmio_write_32(APCS_CCI_SAW2, 0);
+ }
}
/*
diff --git a/plat/qti/msm8916/msm8916_config.h b/plat/qti/msm8916/msm8916_config.h
index 992625b..977d02c 100644
--- a/plat/qti/msm8916/msm8916_config.h
+++ b/plat/qti/msm8916/msm8916_config.h
@@ -8,5 +8,6 @@
#define MSM8916_CONFIG_H
void msm8916_configure(void);
+void msm8916_configure_early(void);
#endif /* MSM8916_CONFIG_H */
diff --git a/plat/qti/msm8916/msm8916_pm.c b/plat/qti/msm8916/msm8916_pm.c
index 6267344..79c670f 100644
--- a/plat/qti/msm8916/msm8916_pm.c
+++ b/plat/qti/msm8916/msm8916_pm.c
@@ -7,6 +7,7 @@
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/cci.h>
#include <drivers/arm/gicv2.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
@@ -29,6 +30,8 @@
#define MPIDR_APCS_CLUSTER(mpidr) 0
#endif
+#define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1])
+
static int msm8916_pwr_domain_on(u_register_t mpidr)
{
msm8916_cpu_boot(APCS_ALIAS_ACS(MPIDR_APCS_CLUSTER(mpidr),
@@ -38,6 +41,11 @@
static void msm8916_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
+ if (PLATFORM_CLUSTER_COUNT > 1 &&
+ CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
+ }
+
gicv2_pcpu_distif_init();
gicv2_cpuif_enable();
}
diff --git a/plat/qti/msm8916/platform.mk b/plat/qti/msm8916/platform.mk
index 2110494..9432435 100644
--- a/plat/qti/msm8916/platform.mk
+++ b/plat/qti/msm8916/platform.mk
@@ -18,7 +18,8 @@
plat/qti/msm8916/${ARCH}/uartdm_console.S
MSM8916_CPU := $(if ${ARM_CORTEX_A7},cortex_a7,cortex_a53)
-MSM8916_PM_SOURCES := lib/cpus/${ARCH}/${MSM8916_CPU}.S \
+MSM8916_PM_SOURCES := drivers/arm/cci/cci.c \
+ lib/cpus/${ARCH}/${MSM8916_CPU}.S \
plat/common/plat_psci_common.c \
plat/qti/msm8916/msm8916_config.c \
plat/qti/msm8916/msm8916_cpu_boot.c \
diff --git a/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c b/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
index 78ab0c7..3c93305 100644
--- a/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
+++ b/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
@@ -27,6 +27,7 @@
u_register_t arg2, u_register_t arg3)
{
msm8916_early_platform_setup();
+ msm8916_configure_early();
}
void sp_min_plat_arch_setup(void)