PSCI: Migrate ARM reference platforms to new platform API

This patch migrates ARM reference platforms, Juno and FVP, to the new platform
API mandated by the new PSCI power domain topology and composite power state
frameworks. The platform specific makefiles now exports the build flag
ENABLE_PLAT_COMPAT=0 to disable the platform compatibility layer.

Change-Id: I3040ed7cce446fc66facaee9c67cb54a8cd7ca29
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index d176fac..2787ee6 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -37,9 +37,9 @@
 #include "../fvp_def.h"
 
 	.globl	plat_secondary_cold_boot_setup
-	.globl	platform_get_entrypoint
+	.globl	plat_get_my_entrypoint
 	.globl	platform_mem_init
-	.globl	platform_is_primary_cpu
+	.globl	plat_is_my_cpu_primary
 
 	.macro	fvp_choose_gicmmap  param1, param2, x_tmp, w_tmp, res
 	ldr	\x_tmp, =V2M_SYSREGS_BASE + V2M_SYS_ID
@@ -98,10 +98,10 @@
 
 
 	/* -----------------------------------------------------
-	 * void platform_get_entrypoint (unsigned int mpid);
+	 * unsigned long plat_get_my_entrypoint (void);
 	 *
 	 * Main job of this routine is to distinguish between
-	 * a cold and warm boot.
+	 * a cold and warm boot on the current CPU.
 	 * On a cold boot the secondaries first wait for the
 	 * platform to be initialized after which they are
 	 * hotplugged in. The primary proceeds to perform the
@@ -117,9 +117,9 @@
 	 * 	reset all cpus will read the same WK field
 	 * -----------------------------------------------------
 	 */
-func platform_get_entrypoint
+func plat_get_my_entrypoint
 	mov	x9, x30 // lr
-	mov	x2, x0
+	mrs	x2, mpidr_el1
 	ldr	x1, =PWRC_BASE
 	str	w2, [x1, #PSYSR_OFF]
 	ldr	w2, [x1, #PSYSR_OFF]
@@ -139,14 +139,14 @@
 	 * ---------------------------------------------
 	 */
 	ldr	x10, =MBOX_BASE
-	bl	platform_get_core_pos
+	bl	plat_my_core_pos
 	lsl	x0, x0, #ARM_CACHE_WRITEBACK_SHIFT
 	ldr	x0, [x10, x0]
 	cbz	x0, _panic
 exit:
 	ret	x9
 _panic:	b	_panic
-endfunc platform_get_entrypoint
+endfunc plat_get_my_entrypoint
 
 
 	/* -----------------------------------------------------
@@ -172,9 +172,10 @@
 endfunc platform_mem_init
 
 
-func platform_is_primary_cpu
+func plat_is_my_cpu_primary
+	mrs	x0, mpidr_el1
 	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
 	cmp	x0, #FVP_PRIMARY_CPU
 	cset	x0, eq
 	ret
-endfunc platform_is_primary_cpu
+endfunc plat_is_my_cpu_primary
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index b1431c4..c59ffd1 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -43,6 +43,7 @@
 #include "fvp_def.h"
 #include "fvp_private.h"
 
+unsigned long wakeup_address;
 
 typedef volatile struct mailbox {
 	unsigned long value __aligned(CACHE_WRITEBACK_GRANULE);
@@ -57,7 +58,7 @@
 	uint64_t linear_id;
 	mailbox_t *fvp_mboxes;
 
-	linear_id = platform_get_core_pos(mpidr);
+	linear_id = plat_arm_calc_core_pos(mpidr);
 	fvp_mboxes = (mailbox_t *)MBOX_BASE;
 	fvp_mboxes[linear_id].value = address;
 	flush_dcache_range((unsigned long) &fvp_mboxes[linear_id],
@@ -93,10 +94,13 @@
 }
 
 /*******************************************************************************
- * FVP handler called when an affinity instance is about to enter standby.
+ * FVP handler called when a CPU is about to enter standby.
  ******************************************************************************/
-void fvp_affinst_standby(unsigned int power_state)
+void fvp_cpu_standby(plat_local_state_t cpu_state)
 {
+
+	assert(cpu_state == ARM_LOCAL_STATE_RET);
+
 	/*
 	 * Enter standby state
 	 * dsb is good practice before using wfi to enter low power states
@@ -106,25 +110,15 @@
 }
 
 /*******************************************************************************
- * FVP handler called when an affinity instance is about to be turned on. The
- * level and mpidr determine the affinity instance.
+ * FVP handler called when a power domain is about to be turned on. The
+ * mpidr determines the CPU to be turned on.
  ******************************************************************************/
-int fvp_affinst_on(unsigned long mpidr,
-		   unsigned long sec_entrypoint,
-		   unsigned int afflvl,
-		   unsigned int state)
+int fvp_pwr_domain_on(u_register_t mpidr)
 {
 	int rc = PSCI_E_SUCCESS;
 	unsigned int psysr;
 
 	/*
-	 * It's possible to turn on only affinity level 0 i.e. a cpu
-	 * on the FVP. Ignore any other affinity level.
-	 */
-	if (afflvl != MPIDR_AFFLVL0)
-		return rc;
-
-	/*
 	 * Ensure that we do not cancel an inflight power off request
 	 * for the target cpu. That would leave it in a zombie wfi.
 	 * Wait for it to power off, program the jump address for the
@@ -135,68 +129,58 @@
 		psysr = fvp_pwrc_read_psysr(mpidr);
 	} while (psysr & PSYSR_AFF_L0);
 
-	fvp_program_mailbox(mpidr, sec_entrypoint);
+	fvp_program_mailbox(mpidr, wakeup_address);
 	fvp_pwrc_write_pponr(mpidr);
 
 	return rc;
 }
 
 /*******************************************************************************
- * FVP handler called when an affinity instance is about to be turned off. The
- * level and mpidr determine the affinity instance. The 'state' arg. allows the
- * platform to decide whether the cluster is being turned off and take apt
- * actions.
- *
- * CAUTION: There is no guarantee that caches will remain turned on across calls
- * to this function as each affinity level is dealt with. So do not write & read
- * global variables across calls. It will be wise to do flush a write to the
- * global to prevent unpredictable results.
+ * FVP handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
  ******************************************************************************/
-void fvp_affinst_off(unsigned int afflvl,
-		    unsigned int state)
+void fvp_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	/* Determine if any platform actions need to be executed */
-	if (arm_do_affinst_actions(afflvl, state) == -EAGAIN)
-		return;
+	assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
+					ARM_LOCAL_STATE_OFF);
 
 	/*
-	 * If execution reaches this stage then this affinity level will be
-	 * suspended. Perform at least the cpu specific actions followed the
-	 * cluster specific operations if applicable.
+	 * If execution reaches this stage then this power domain will be
+	 * suspended. Perform at least the cpu specific actions followed
+	 * by the cluster specific operations if applicable.
 	 */
 	fvp_cpu_pwrdwn_common();
 
-	if (afflvl != MPIDR_AFFLVL0)
+	if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
+					ARM_LOCAL_STATE_OFF)
 		fvp_cluster_pwrdwn_common();
 
 }
 
 /*******************************************************************************
- * FVP handler called when an affinity instance is about to be suspended. The
- * level and mpidr determine the affinity instance. The 'state' arg. allows the
- * platform to decide whether the cluster is being turned off and take apt
- * actions.
- *
- * CAUTION: There is no guarantee that caches will remain turned on across calls
- * to this function as each affinity level is dealt with. So do not write & read
- * global variables across calls. It will be wise to do flush a write to the
- * global to prevent unpredictable results.
+ * FVP handler called when a power domain is about to be suspended. The
+ * target_state encodes the power state that each level should transition to.
  ******************************************************************************/
-void fvp_affinst_suspend(unsigned long sec_entrypoint,
-			unsigned int afflvl,
-			unsigned int state)
+void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
 	unsigned long mpidr;
 
-	/* Determine if any platform actions need to be executed. */
-	if (arm_do_affinst_actions(afflvl, state) == -EAGAIN)
+	/*
+	 * FVP has retention only at cpu level. Just return
+	 * as nothing is to be done for retention.
+	 */
+	if (target_state->pwr_domain_state[ARM_PWR_LVL0] ==
+					ARM_LOCAL_STATE_RET)
 		return;
 
+	assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
+					ARM_LOCAL_STATE_OFF);
+
 	/* Get the mpidr for this cpu */
 	mpidr = read_mpidr_el1();
 
 	/* Program the jump address for the this cpu */
-	fvp_program_mailbox(mpidr, sec_entrypoint);
+	fvp_program_mailbox(mpidr, wakeup_address);
 
 	/* Program the power controller to enable wakeup interrupts. */
 	fvp_pwrc_set_wen(mpidr);
@@ -205,31 +189,29 @@
 	fvp_cpu_pwrdwn_common();
 
 	/* Perform the common cluster specific operations */
-	if (afflvl != MPIDR_AFFLVL0)
+	if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
+					ARM_LOCAL_STATE_OFF)
 		fvp_cluster_pwrdwn_common();
 }
 
 /*******************************************************************************
- * FVP handler called when an affinity instance has just been powered on after
- * being turned off earlier. The level and mpidr determine the affinity
- * instance. The 'state' arg. allows the platform to decide whether the cluster
- * was turned off prior to wakeup and do what's necessary to setup it up
- * correctly.
+ * FVP handler called when a power domain has just been powered on after
+ * being turned off earlier. The target_state encodes the low power state that
+ * each level has woken up from.
  ******************************************************************************/
-void fvp_affinst_on_finish(unsigned int afflvl,
-			  unsigned int state)
+void fvp_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	unsigned long mpidr;
 
-	/* Determine if any platform actions need to be executed. */
-	if (arm_do_affinst_actions(afflvl, state) == -EAGAIN)
-		return;
+	assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
+					ARM_LOCAL_STATE_OFF);
 
 	/* Get the mpidr for this cpu */
 	mpidr = read_mpidr_el1();
 
 	/* Perform the common cluster specific operations */
-	if (afflvl != MPIDR_AFFLVL0) {
+	if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
+					ARM_LOCAL_STATE_OFF) {
 		/*
 		 * This CPU might have woken up whilst the cluster was
 		 * attempting to power down. In this case the FVP power
@@ -262,16 +244,22 @@
 }
 
 /*******************************************************************************
- * FVP handler called when an affinity instance has just been powered on after
- * having been suspended earlier. The level and mpidr determine the affinity
- * instance.
+ * FVP handler called when a power domain has just been powered on after
+ * having been suspended earlier. The target_state encodes the low power state
+ * that each level has woken up from.
  * TODO: At the moment we reuse the on finisher and reinitialize the secure
  * context. Need to implement a separate suspend finisher.
  ******************************************************************************/
-void fvp_affinst_suspend_finish(unsigned int afflvl,
-			       unsigned int state)
+void fvp_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
 {
-	fvp_affinst_on_finish(afflvl, state);
+	/*
+	 * Nothing to be done on waking up from retention from CPU level.
+	 */
+	if (target_state->pwr_domain_state[ARM_PWR_LVL0] ==
+					ARM_LOCAL_STATE_RET)
+		return;
+
+	fvp_pwr_domain_on_finish(target_state);
 }
 
 /*******************************************************************************
@@ -304,23 +292,28 @@
 /*******************************************************************************
  * Export the platform handlers to enable psci to invoke them
  ******************************************************************************/
-static const plat_pm_ops_t fvp_plat_pm_ops = {
-	.affinst_standby = fvp_affinst_standby,
-	.affinst_on = fvp_affinst_on,
-	.affinst_off = fvp_affinst_off,
-	.affinst_suspend = fvp_affinst_suspend,
-	.affinst_on_finish = fvp_affinst_on_finish,
-	.affinst_suspend_finish = fvp_affinst_suspend_finish,
+static const plat_psci_ops_t fvp_plat_psci_ops = {
+	.cpu_standby = fvp_cpu_standby,
+	.pwr_domain_on = fvp_pwr_domain_on,
+	.pwr_domain_off = fvp_pwr_domain_off,
+	.pwr_domain_suspend = fvp_pwr_domain_suspend,
+	.pwr_domain_on_finish = fvp_pwr_domain_on_finish,
+	.pwr_domain_suspend_finish = fvp_pwr_domain_suspend_finish,
 	.system_off = fvp_system_off,
 	.system_reset = fvp_system_reset,
 	.validate_power_state = arm_validate_power_state
 };
 
 /*******************************************************************************
- * Export the platform specific power ops & initialize the fvp power controller
+ * Export the platform specific psci ops & initialize the fvp power controller
  ******************************************************************************/
-int platform_setup_pm(const plat_pm_ops_t **plat_ops)
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+				const plat_psci_ops_t **psci_ops)
 {
-	*plat_ops = &fvp_plat_pm_ops;
+	*psci_ops = &fvp_plat_psci_ops;
+	wakeup_address = sec_entrypoint;
+
+	flush_dcache_range((unsigned long)&wakeup_address,
+				sizeof(wakeup_address));
 	return 0;
 }
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index c90e82f..a212eda 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -29,204 +29,41 @@
  */
 
 #include <arch.h>
-#include <assert.h>
+#include <plat_arm.h>
 #include <platform_def.h>
-/* TODO: Reusing psci error codes & state information. Get our own! */
-#include <psci.h>
 #include "drivers/pwrc/fvp_pwrc.h"
-#include "fvp_def.h"
 
-/* We treat '255' as an invalid affinity instance */
-#define AFFINST_INVAL	0xff
+/*
+ * 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
 
-/*******************************************************************************
- * We support 3 flavours of the FVP: Foundation, Base AEM & Base Cortex. Each
- * flavour has a different topology. The common bit is that there can be a max.
- * of 2 clusters (affinity 1) and 4 cpus (affinity 0) per cluster. So we define
- * a tree like data structure which caters to these maximum bounds. It simply
- * marks the absent affinity level instances as PSCI_AFF_ABSENT e.g. there is no
- * cluster 1 on the Foundation FVP. The 'data' field is currently unused.
- ******************************************************************************/
-typedef struct affinity_info {
-	unsigned char sibling;
-	unsigned char child;
-	unsigned char state;
-	unsigned int data;
-} affinity_info_t;
+/* 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
+};
 
 /*******************************************************************************
- * The following two data structures store the topology tree for the fvp. There
- * is a separate array for each affinity level i.e. cpus and clusters. The child
- * and sibling references allow traversal inside and in between the two arrays.
- ******************************************************************************/
-static affinity_info_t fvp_aff1_topology_map[ARM_CLUSTER_COUNT];
-static affinity_info_t fvp_aff0_topology_map[PLATFORM_CORE_COUNT];
-
-/* Simple global variable to safeguard us from stupidity */
-static unsigned int topology_setup_done;
-
-/*******************************************************************************
  * This function implements a part of the critical interface between the psci
- * generic layer and the platform to allow the former to detect the platform
- * topology. psci queries the platform to determine how many affinity instances
- * are present at a particular level for a given mpidr e.g. consider a dual
- * cluster platform where each cluster has 4 cpus. A call to this function with
- * (0, 0x100) will return the number of cpus implemented under cluster 1 i.e. 4.
- * Similarly a call with (1, 0x100) will return 2 i.e. the number of clusters.
- * This is 'cause we are effectively asking how many affinity level 1 instances
- * are implemented under affinity level 2 instance 0.
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
  ******************************************************************************/
-unsigned int plat_get_aff_count(unsigned int aff_lvl,
-				unsigned long mpidr)
+int plat_core_pos_by_mpidr(u_register_t mpidr)
 {
-	unsigned int aff_count = 1, ctr;
-	unsigned char parent_aff_id;
-
-	assert(topology_setup_done == 1);
-
-	switch (aff_lvl) {
-	case 3:
-	case 2:
-		/*
-		 * Assert if the parent affinity instance is not 0.
-		 * This also takes care of level 3 in an obfuscated way
-		 */
-		parent_aff_id = (mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK;
-		assert(parent_aff_id == 0);
-
-		/*
-		 * Report that we implement a single instance of
-		 * affinity levels 2 & 3 which are AFF_ABSENT
-		 */
-		break;
-	case 1:
-		/* Assert if the parent affinity instance is not 0. */
-		parent_aff_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
-		assert(parent_aff_id == 0);
-
-		/* Fetch the starting index in the aff1 array */
-		for (ctr = 0;
-		     fvp_aff1_topology_map[ctr].sibling != AFFINST_INVAL;
-		     ctr = fvp_aff1_topology_map[ctr].sibling) {
-			aff_count++;
-		}
-
-		break;
-	case 0:
-		/* Assert if the cluster id is anything apart from 0 or 1 */
-		parent_aff_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-		assert(parent_aff_id < ARM_CLUSTER_COUNT);
-
-		/* Fetch the starting index in the aff0 array */
-		for (ctr = fvp_aff1_topology_map[parent_aff_id].child;
-		     fvp_aff0_topology_map[ctr].sibling != AFFINST_INVAL;
-		     ctr = fvp_aff0_topology_map[ctr].sibling) {
-			aff_count++;
-		}
-
-		break;
-	default:
-		assert(0);
-	}
-
-	return aff_count;
-}
-
-/*******************************************************************************
- * This function implements a part of the critical interface between the psci
- * generic layer and the platform to allow the former to detect the state of a
- * affinity instance in the platform topology. psci queries the platform to
- * determine whether an affinity instance is present or absent. This caters for
- * topologies where an intermediate affinity level instance is missing e.g.
- * consider a platform which implements a single cluster with 4 cpus and there
- * is another cpu sitting directly on the interconnect along with the cluster.
- * The mpidrs of the cluster would range from 0x0-0x3. The mpidr of the single
- * cpu would be 0x100 to highlight that it does not belong to cluster 0. Cluster
- * 1 is however missing but needs to be accounted to reach this single cpu in
- * the topology tree. Hence it will be marked as PSCI_AFF_ABSENT. This is not
- * applicable to the FVP but depicted as an example.
- ******************************************************************************/
-unsigned int plat_get_aff_state(unsigned int aff_lvl,
-				unsigned long mpidr)
-{
-	unsigned int aff_state = PSCI_AFF_ABSENT, idx;
-	idx = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-
-	assert(topology_setup_done == 1);
-
-	switch (aff_lvl) {
-	case 3:
-	case 2:
-		/* Report affinity levels 2 & 3 as absent */
-		break;
-	case 1:
-		aff_state = fvp_aff1_topology_map[idx].state;
-		break;
-	case 0:
-		/*
-		 * First get start index of the aff0 in its array & then add
-		 * to it the affinity id that we want the state of
-		 */
-		idx = fvp_aff1_topology_map[idx].child;
-		idx += (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
-		aff_state = fvp_aff0_topology_map[idx].state;
-		break;
-	default:
-		assert(0);
-	}
-
-	return aff_state;
-}
-
-/*******************************************************************************
- * This function populates the FVP specific topology information depending upon
- * the FVP flavour its running on. We construct all the mpidrs we can handle
- * and rely on the PWRC.PSYSR to flag absent cpus when their status is queried.
- ******************************************************************************/
-void plat_arm_topology_setup(void)
-{
-	unsigned char aff0, aff1, aff_state, aff0_offset = 0;
-	unsigned long mpidr;
-
-	topology_setup_done = 0;
-
-	for (aff1 = 0; aff1 < ARM_CLUSTER_COUNT; aff1++) {
-
-		fvp_aff1_topology_map[aff1].child = aff0_offset;
-		fvp_aff1_topology_map[aff1].sibling = aff1 + 1;
-
-		for (aff0 = 0; aff0 < FVP_MAX_CPUS_PER_CLUSTER; aff0++) {
-
-			mpidr = aff1 << MPIDR_AFF1_SHIFT;
-			mpidr |= aff0 << MPIDR_AFF0_SHIFT;
-
-			if (fvp_pwrc_read_psysr(mpidr) != PSYSR_INVALID) {
-				/*
-				 * Presence of even a single aff0 indicates
-				 * presence of parent aff1 on the FVP.
-				 */
-				aff_state = PSCI_AFF_PRESENT;
-				fvp_aff1_topology_map[aff1].state =
-					PSCI_AFF_PRESENT;
-			} else {
-				aff_state = PSCI_AFF_ABSENT;
-			}
-
-			fvp_aff0_topology_map[aff0_offset].child = AFFINST_INVAL;
-			fvp_aff0_topology_map[aff0_offset].state = aff_state;
-			fvp_aff0_topology_map[aff0_offset].sibling =
-				aff0_offset + 1;
-
-			/* Increment the absolute number of aff0s traversed */
-			aff0_offset++;
-		}
-
-		/* Tie-off the last aff0 sibling to -1 to avoid overflow */
-		fvp_aff0_topology_map[aff0_offset - 1].sibling = AFFINST_INVAL;
-	}
+	if (arm_check_mpidr(mpidr) == -1)
+		return -1;
 
-	/* Tie-off the last aff1 sibling to AFFINST_INVAL to avoid overflow */
-	fvp_aff1_topology_map[aff1 - 1].sibling = AFFINST_INVAL;
+	if (fvp_pwrc_read_psysr(mpidr) == PSYSR_INVALID)
+		return -1;
 
-	topology_setup_done = 1;
+	return plat_arm_calc_core_pos(mpidr);
 }
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index a1a0971..51b718e 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -28,7 +28,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-
 PLAT_INCLUDES		:=	-Iplat/arm/board/fvp/include
 
 
@@ -63,5 +62,8 @@
 				plat/arm/board/fvp/aarch64/fvp_helpers.S	\
 				plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c
 
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT	:= 	0
+
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
diff --git a/plat/arm/board/fvp/tsp/tsp-fvp.mk b/plat/arm/board/fvp/tsp/tsp-fvp.mk
index 8773ee0..99db2f4 100644
--- a/plat/arm/board/fvp/tsp/tsp-fvp.mk
+++ b/plat/arm/board/fvp/tsp/tsp-fvp.mk
@@ -29,6 +29,8 @@
 #
 
 # TSP source files specific to FVP platform
-BL32_SOURCES		+=	plat/arm/board/fvp/tsp/fvp_tsp_setup.c
+BL32_SOURCES		+=	plat/arm/board/fvp/fvp_topology.c		\
+				plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c	\
+				plat/arm/board/fvp/tsp/fvp_tsp_setup.c
 
 include plat/arm/common/tsp/arm_tsp.mk
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 98834e7..b80cfb3 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -48,6 +48,9 @@
 # power down sequence
 SKIP_A57_L1_FLUSH_PWR_DWN	:=	 1
 
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT	:= 	0
+
 include plat/arm/board/common/board_css.mk
 include plat/arm/common/arm_common.mk
 include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/board/juno/tsp/tsp-juno.mk b/plat/arm/board/juno/tsp/tsp-juno.mk
index 55b031a..bb67012 100644
--- a/plat/arm/board/juno/tsp/tsp-juno.mk
+++ b/plat/arm/board/juno/tsp/tsp-juno.mk
@@ -28,4 +28,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
+BL32_SOURCES		+=	plat/arm/css/common/css_topology.c
+
 include plat/arm/common/tsp/arm_tsp.mk