diff --git a/docs/user-guide.md b/docs/user-guide.md
index 7fd765815dd8f12efc7b07f42869ceef08f802c7..0db622b80469e8dfb059c211a91be00bfcd966bc 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -486,6 +486,11 @@ map is explained in the [Firmware Design].
     Trusted Firmware must be compiled with GICv2 only driver using
     `FVP_USE_GIC_DRIVER=FVP_GICV2` build option.
 
+*   `FVP_CLUSTER_COUNT`    : Configures the cluster count to be used to
+     build the topology tree within Trusted Firmware. By default the
+     Trusted Firmware is configured for dual cluster topology and this option
+     can be used to override the default value.
+
 ### Creating a Firmware Image Package
 
 FIPs are automatically created as part of the build instructions described in
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 4c8435607b1a60081db94caa3394afb4772e205c..f6c090f49f1241018c52d3268e0eb146e3d3f904 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -44,7 +44,6 @@
 /* Special value used to verify platform parameters from BL2 to BL31 */
 #define ARM_BL31_PLAT_PARAM_VAL		0x0f1e2d3c4b5a6978ULL
 
-#define ARM_CLUSTER_COUNT		2
 #define ARM_SYSTEM_COUNT		1
 
 #define ARM_CACHE_WRITEBACK_SHIFT	6
@@ -218,10 +217,6 @@
  */
 #define PLAT_MAX_OFF_STATE		ARM_LOCAL_STATE_OFF
 
-
-#define PLATFORM_CORE_COUNT		(PLAT_ARM_CLUSTER0_CORE_COUNT + \
-					 PLAT_ARM_CLUSTER1_CORE_COUNT)
-
 /*
  * Some data must be aligned on the biggest cache line size in the platform.
  * This is known only to the platform as it might have a combination of
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 8d7e83b5796049666a284f0496b2727a98090100..e9eebaa09d09c59f71d9ccc61a41e5438580b41a 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -179,6 +179,7 @@ int arm_io_is_toc_valid(void);
 /*
  * Mandatory functions required in ARM standard platforms
  */
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr);
 void plat_arm_gic_driver_init(void);
 void plat_arm_gic_init(void);
 void plat_arm_gic_cpuif_enable(void);
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index 41b872af5988a16f575968be02a911aadd312a49..dbca280cb2b9b9f9d0a2372aca02346cc1c632df 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -33,7 +33,9 @@
 
 #include <arm_def.h>
 
-
+#ifndef FVP_CLUSTER_COUNT
+#define FVP_CLUSTER_COUNT		2
+#endif
 #define FVP_MAX_CPUS_PER_CLUSTER	4
 
 #define FVP_PRIMARY_CPU			0x0
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index a212eda74c88bc0d26e0428a78532e5560d56c18..741aad645b21aac7c09f115629024805d6e8ddaa 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -29,27 +29,47 @@
  */
 
 #include <arch.h>
+#include <cassert.h>
 #include <plat_arm.h>
 #include <platform_def.h>
 #include "drivers/pwrc/fvp_pwrc.h"
 
-/*
- * The FVP power domain tree does not have a single system level power domain
- * i.e. a single root node. The first entry in the power domain descriptor
- * specifies the number of power domains at the highest power level. For the FVP
- * this is 2 i.e. the number of cluster power domains.
- */
-#define FVP_PWR_DOMAINS_AT_MAX_PWR_LVL	ARM_CLUSTER_COUNT
-
 /* The FVP power domain tree descriptor */
-const unsigned char arm_power_domain_tree_desc[] = {
-	/* No of root nodes */
-	FVP_PWR_DOMAINS_AT_MAX_PWR_LVL,
-	/* No of children for the first node */
-	PLAT_ARM_CLUSTER0_CORE_COUNT,
-	/* No of children for the second node */
-	PLAT_ARM_CLUSTER1_CORE_COUNT
-};
+unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 1];
+
+
+CASSERT(FVP_CLUSTER_COUNT && FVP_CLUSTER_COUNT <= 256, assert_invalid_fvp_cluster_count);
+
+/*******************************************************************************
+ * This function dynamically constructs the topology according to
+ * FVP_CLUSTER_COUNT and returns it.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	int i;
+
+	/*
+	 * The FVP power domain tree does not have a single system level power domain
+	 * i.e. a single root node. The first entry in the power domain descriptor
+	 * specifies the number of power domains at the highest power level. For the FVP
+	 * this is the number of cluster power domains.
+	 */
+	fvp_power_domain_tree_desc[0] = FVP_CLUSTER_COUNT;
+
+	for (i = 0; i < FVP_CLUSTER_COUNT; i++)
+		fvp_power_domain_tree_desc[i + 1] = FVP_MAX_CPUS_PER_CLUSTER;
+
+	return fvp_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+	return FVP_MAX_CPUS_PER_CLUSTER;
+}
 
 /*******************************************************************************
  * This function implements a part of the critical interface between the psci
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 9c82cbfa2a719fb48387557e1f9ca63e4689978d..b912643e6e910292d3c54212067906d089e4dbfb 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -39,9 +39,10 @@
 #include "../fvp_def.h"
 
 /* Required platform porting definitions */
-#define PLAT_NUM_PWR_DOMAINS		(ARM_CLUSTER_COUNT + \
+#define PLAT_NUM_PWR_DOMAINS		(FVP_CLUSTER_COUNT + \
 					PLATFORM_CORE_COUNT)
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+#define PLATFORM_CORE_COUNT		(FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER)
 
 /*
  * Other platform porting definitions are provided by included headers
@@ -50,8 +51,7 @@
 /*
  * Required ARM standard platform porting definitions
  */
-#define PLAT_ARM_CLUSTER0_CORE_COUNT	4
-#define PLAT_ARM_CLUSTER1_CORE_COUNT	4
+#define PLAT_ARM_CLUSTER_COUNT		FVP_CLUSTER_COUNT
 
 #define PLAT_ARM_TRUSTED_ROM_BASE	0x00000000
 #define PLAT_ARM_TRUSTED_ROM_SIZE	0x04000000	/* 64 MB */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index c82c21a8c2f6d3378fb290ca39b26b0229599485..aad2e2ef522cf1142ede1bb1f381c4a8965d2836 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -34,6 +34,11 @@ FVP_USE_GIC_DRIVER	:= FVP_GICV3_LEGACY
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))
 
+# If FVP_CLUSTER_COUNT has been defined, pass it into the build system.
+ifdef FVP_CLUSTER_COUNT
+$(eval $(call add_define,FVP_CLUSTER_COUNT))
+endif
+
 # Choose the GIC sources depending upon the how the FVP will be invoked
 ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3)
 FVP_GIC_SOURCES		:=	drivers/arm/gic/common/gic_common.c	\
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index deac0fffdd7a1c03c9594c1cf75bfc52eb92b066..e1e0af67b553680b4a94e6f21e002dec33f4ba72 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -41,11 +41,15 @@
 #include <v2m_def.h>
 #include "../juno_def.h"
 
+/* Required platform porting definitions */
 /* Juno supports system power domain */
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL2
 #define PLAT_NUM_PWR_DOMAINS		(ARM_SYSTEM_COUNT + \
-					ARM_CLUSTER_COUNT + \
+					JUNO_CLUSTER_COUNT + \
 					PLATFORM_CORE_COUNT)
+#define PLATFORM_CORE_COUNT		(JUNO_CLUSTER0_CORE_COUNT + \
+					JUNO_CLUSTER1_CORE_COUNT)
+
 /*
  * Other platform porting definitions are provided by included headers
  */
@@ -53,8 +57,7 @@
 /*
  * Required ARM standard platform porting definitions
  */
-#define PLAT_ARM_CLUSTER0_CORE_COUNT	2
-#define PLAT_ARM_CLUSTER1_CORE_COUNT	4
+#define PLAT_ARM_CLUSTER_COUNT		JUNO_CLUSTER_COUNT
 
 /* Use the bypass address */
 #define PLAT_ARM_TRUSTED_ROM_BASE	V2M_FLASH0_BASE + BL1_ROM_BYPASS_OFFSET
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index f4e225996d1aa8912e798cfad9b51d1dd52d5d56..f27bbb22e78a5a83e358065d1f5cb96c9cd28d9f 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -52,6 +52,13 @@
 
 #define JUNO_SSC_VER_PART_NUM		0x030
 
+/*******************************************************************************
+ * Juno topology related constants
+ ******************************************************************************/
+#define JUNO_CLUSTER_COUNT		2
+#define JUNO_CLUSTER0_CORE_COUNT	2
+#define JUNO_CLUSTER1_CORE_COUNT	4
+
 /*******************************************************************************
  * TZC-400 related constants
  ******************************************************************************/
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee4ec4419f162ae75b3c290d8eb0ff2d7e4b5f3f
--- /dev/null
+++ b/plat/arm/board/juno/juno_topology.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arm_def.h>
+#include <plat_arm.h>
+#include "juno_def.h"
+
+/*
+ * On Juno, the system power level is the highest power level.
+ * The first entry in the power domain descriptor specifies the
+ * number of system power domains i.e. 1.
+ */
+#define JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL	 ARM_SYSTEM_COUNT
+
+/*
+ * The Juno power domain tree descriptor. The cluster power domains
+ * are arranged so that when the PSCI generic code creates the power
+ * domain tree, the indices of the CPU power domain nodes it allocates
+ * match the linear indices returned by plat_core_pos_by_mpidr()
+ * i.e. CLUSTER1 CPUs are allocated indices from 0 to 3 and the higher
+ * indices for CLUSTER0 CPUs.
+ */
+const unsigned char juno_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL,
+	/* No of children for the root node */
+	JUNO_CLUSTER_COUNT,
+	/* No of children for the first cluster node */
+	JUNO_CLUSTER1_CORE_COUNT,
+	/* No of children for the second cluster node */
+	JUNO_CLUSTER0_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the Juno topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return juno_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+	return (((mpidr) & 0x100) ? JUNO_CLUSTER1_CORE_COUNT :\
+				JUNO_CLUSTER0_CORE_COUNT);
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 3ffc7e7737b0635397a9c44bc32b1e9cc12e52f1..1876821b1bddbfd24d34900ad187546bb22b2a93 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -62,6 +62,7 @@ BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
 				lib/cpus/aarch64/cortex_a57.S		\
 				lib/cpus/aarch64/cortex_a72.S		\
 				plat/arm/board/juno/juno_pm.c		\
+				plat/arm/board/juno/juno_topology.c	\
 				${JUNO_GIC_SOURCES}			\
 				${JUNO_INTERCONNECT_SOURCES}		\
 				${JUNO_SECURITY_SOURCES}
diff --git a/plat/arm/board/juno/tsp/tsp-juno.mk b/plat/arm/board/juno/tsp/tsp-juno.mk
index 2ef964e8beae4b9bb84150a93503dd3e7244b86b..4e8060786be28563c3031ed7845f7f678b354f56 100644
--- a/plat/arm/board/juno/tsp/tsp-juno.mk
+++ b/plat/arm/board/juno/tsp/tsp-juno.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -28,7 +28,8 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-BL32_SOURCES		+=	plat/arm/css/common/css_topology.c	\
+BL32_SOURCES		+=	plat/arm/board/juno/juno_topology.c	\
+				plat/arm/css/common/css_topology.c	\
 				${JUNO_GIC_SOURCES}
 
 include plat/arm/common/tsp/arm_tsp.mk
diff --git a/plat/arm/common/arm_topology.c b/plat/arm/common/arm_topology.c
index cb0bb9c9c3367eb38d219656bca6b1eeabafec87..4430b139991cdbe1bbf20d540ca1705a5c32cf2c 100644
--- a/plat/arm/common/arm_topology.c
+++ b/plat/arm/common/arm_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -29,26 +29,9 @@
  */
 
 #include <arch.h>
-#include <psci.h>
 #include <plat_arm.h>
 #include <platform_def.h>
 
-#define get_arm_cluster_core_count(mpidr)\
-		(((mpidr) & 0x100) ? PLAT_ARM_CLUSTER1_CORE_COUNT :\
-				PLAT_ARM_CLUSTER0_CORE_COUNT)
-
-/* The power domain tree descriptor which need to be exported by ARM platforms */
-extern const unsigned char arm_power_domain_tree_desc[];
-
-
-/*******************************************************************************
- * This function returns the ARM default topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
-	return arm_power_domain_tree_desc;
-}
-
 /*******************************************************************************
  * This function validates an MPIDR by checking whether it falls within the
  * acceptable bounds. An error code (-1) is returned if an incorrect mpidr
@@ -66,12 +49,12 @@ int arm_check_mpidr(u_register_t mpidr)
 	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
 	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
 
-	if (cluster_id >= ARM_CLUSTER_COUNT)
+	if (cluster_id >= PLAT_ARM_CLUSTER_COUNT)
 		return -1;
 
 	/* Validate cpu_id by checking whether it represents a CPU in
 	   one of the two clusters present on the platform. */
-	if (cpu_id >= get_arm_cluster_core_count(mpidr))
+	if (cpu_id >= plat_arm_get_cluster_core_count(mpidr))
 		return -1;
 
 	return 0;
diff --git a/plat/arm/css/common/css_topology.c b/plat/arm/css/common/css_topology.c
index 03f81e615bbb2dabc67d1b104229f9bfb8150702..d5f0275a8e04389f802ea8f6698ec15cd3ea3eee 100644
--- a/plat/arm/css/common/css_topology.c
+++ b/plat/arm/css/common/css_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -30,33 +30,6 @@
 
 #include <plat_arm.h>
 
-/*
- * On ARM CSS platforms, by default, the system power level is treated as the
- * highest. The first entry in the power domain descriptor specifies the
- * number of system power domains i.e. 1.
- */
-#define CSS_PWR_DOMAINS_AT_MAX_PWR_LVL	ARM_SYSTEM_COUNT
-
-/*
- * The CSS power domain tree descriptor for dual cluster CSS platforms.
- * The cluster power domains are arranged so that when the PSCI generic
- * code creates the power domain tree, the indices of the CPU power
- * domain nodes it allocates match the linear indices returned by
- * plat_core_pos_by_mpidr() i.e. CLUSTER1 CPUs are allocated indices
- * from 0 to 3 and the higher indices for CLUSTER0 CPUs.
- */
-const unsigned char arm_power_domain_tree_desc[] = {
-	/* No of root nodes */
-	CSS_PWR_DOMAINS_AT_MAX_PWR_LVL,
-	/* No of children for the root node */
-	ARM_CLUSTER_COUNT,
-	/* No of children for the first cluster node */
-	PLAT_ARM_CLUSTER1_CORE_COUNT,
-	/* No of children for the second cluster node */
-	PLAT_ARM_CLUSTER0_CORE_COUNT
-};
-
-
 /******************************************************************************
  * This function implements a part of the critical interface between the psci
  * generic layer and the platform that allows the former to query the platform