Merge pull request #919 from davidcunado-arm/dc/smc_yielding_generic

Update terminology: standard SMC to yielding SMC
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index f7fae68..e2ede68 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -109,7 +109,7 @@
 		break;
 	}
 
-	SMC_RET0(handle);
+	SMC_RET1(handle, SMC_UNK);
 }
 
 /*******************************************************************************
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index 489fcbe..1b9cab8 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -115,9 +115,6 @@
 	b.ne	1b
 	mov	w2, #0xD		/* '\r' */
 	str	w2, [x1, #UARTTX]
-	ldr	w2, [x1, #UARTFCR]
-	orr	w2, w2, #UARTFCR_TXCLR
-	str	w2, [x1, #UARTFCR]
 
 	/* Check if the transmit FIFO is full */
 2:	ldr	w2, [x1, #UARTLSR]
@@ -125,9 +122,6 @@
 	cmp	w2, #(UARTLSR_TEMT | UARTLSR_THRE)
 	b.ne	2b
 	str	w0, [x1, #UARTTX]
-	ldr	w2, [x1, #UARTFCR]
-	orr	w2, w2, #UARTFCR_TXCLR
-	str	w2, [x1, #UARTFCR]
 	ret
 putc_error:
 	mov	w0, #-1
diff --git a/include/bl32/payloads/tlk.h b/include/bl32/payloads/tlk.h
index d355313..1a83b1f 100644
--- a/include/bl32/payloads/tlk.h
+++ b/include/bl32/payloads/tlk.h
@@ -31,7 +31,7 @@
 #ifndef __TLK_H__
 #define __TLK_H__
 
-#include <utils.h>
+#include <utils_def.h>
 
 /*
  * Generate function IDs for the Trusted OS/Apps
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 38be628..2a026b8 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -85,7 +85,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <types.h>
-#include <utils.h> /* To retain compatibility */
+#include <utils_def.h> /* To retain compatibility */
 
 /*
  * Declarations of linker defined symbols to help determine memory layout of
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 4b323d3..ef7241d 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -31,7 +31,7 @@
 #ifndef __ARCH_H__
 #define __ARCH_H__
 
-#include <utils.h>
+#include <utils_def.h>
 
 /*******************************************************************************
  * MIDR bit definitions
diff --git a/include/lib/cpus/errata_report.h b/include/lib/cpus/errata_report.h
index 6c6a844..228ffea 100644
--- a/include/lib/cpus/errata_report.h
+++ b/include/lib/cpus/errata_report.h
@@ -36,7 +36,7 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <spinlock.h>
-#include <utils.h>
+#include <utils_def.h>
 
 #if DEBUG
 void print_errata_status(void);
diff --git a/include/lib/smcc.h b/include/lib/smcc.h
index 708805f..5fad7b8 100644
--- a/include/lib/smcc.h
+++ b/include/lib/smcc.h
@@ -31,7 +31,7 @@
 #ifndef __SMCC_H__
 #define __SMCC_H__
 
-#include <utils.h>
+#include <utils_def.h>
 
 /*******************************************************************************
  * Bit definitions inside the function id as per the SMC calling convention
@@ -58,6 +58,7 @@
 
 #define SMC_64				1
 #define SMC_32				0
+#define SMC_OK				0
 #define SMC_UNK				0xffffffff
 #define SMC_TYPE_FAST			ULL(1)
 #if !ERROR_DEPRECATED
diff --git a/include/lib/utils.h b/include/lib/utils.h
index 279c913..c085b7d 100644
--- a/include/lib/utils.h
+++ b/include/lib/utils.h
@@ -31,67 +31,8 @@
 #ifndef __UTILS_H__
 #define __UTILS_H__
 
-/* Compute the number of elements in the given array */
-#define ARRAY_SIZE(a)				\
-	(sizeof(a) / sizeof((a)[0]))
-
-#define IS_POWER_OF_TWO(x)			\
-	(((x) & ((x) - 1)) == 0)
-
-#define SIZE_FROM_LOG2_WORDS(n)		(4 << (n))
-
-#define BIT(nr)				(1UL << (nr))
-
-#define MIN(x, y) __extension__ ({	\
-	__typeof__(x) _x = (x);		\
-	__typeof__(y) _y = (y);		\
-	(void)(&_x == &_y);		\
-	_x < _y ? _x : _y;		\
-})
-
-#define MAX(x, y) __extension__ ({	\
-	__typeof__(x) _x = (x);		\
-	__typeof__(y) _y = (y);		\
-	(void)(&_x == &_y);		\
-	_x > _y ? _x : _y;		\
-})
-
-/*
- * The round_up() macro rounds up a value to the given boundary in a
- * type-agnostic yet type-safe manner. The boundary must be a power of two.
- * In other words, it computes the smallest multiple of boundary which is
- * greater than or equal to value.
- *
- * round_down() is similar but rounds the value down instead.
- */
-#define round_boundary(value, boundary)		\
-	((__typeof__(value))((boundary) - 1))
-
-#define round_up(value, boundary)		\
-	((((value) - 1) | round_boundary(value, boundary)) + 1)
-
-#define round_down(value, boundary)		\
-	((value) & ~round_boundary(value, boundary))
-
-/*
- * Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
- * Both arguments must be unsigned pointer values (i.e. uintptr_t).
- */
-#define check_uptr_overflow(ptr, inc)		\
-	(((ptr) > UINTPTR_MAX - (inc)) ? 1 : 0)
-
-/*
- * For those constants to be shared between C and other sources, apply a 'ull'
- * suffix to the argument only in C, to avoid undefined or unintended behaviour.
- *
- * The GNU assembler and linker do not support the 'ull' suffix (it causes the
- * build process to fail) therefore the suffix is omitted when used in linker
- * scripts and assembler files.
-*/
-#if defined(__LINKER__) || defined(__ASSEMBLY__)
-# define ULL(_x)	(_x)
-#else
-# define ULL(_x)	(_x##ull)
+#if !ERROR_DEPRECATED
+#include <utils_def.h>
 #endif
 
 /*
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
new file mode 100644
index 0000000..202f050
--- /dev/null
+++ b/include/lib/utils_def.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016-2017, 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.
+ */
+
+#ifndef __UTILS_DEF_H__
+#define __UTILS_DEF_H__
+
+/* Compute the number of elements in the given array */
+#define ARRAY_SIZE(a)				\
+	(sizeof(a) / sizeof((a)[0]))
+
+#define IS_POWER_OF_TWO(x)			\
+	(((x) & ((x) - 1)) == 0)
+
+#define SIZE_FROM_LOG2_WORDS(n)		(4 << (n))
+
+#define BIT(nr)				(1UL << (nr))
+
+#define MIN(x, y) __extension__ ({	\
+	__typeof__(x) _x = (x);		\
+	__typeof__(y) _y = (y);		\
+	(void)(&_x == &_y);		\
+	_x < _y ? _x : _y;		\
+})
+
+#define MAX(x, y) __extension__ ({	\
+	__typeof__(x) _x = (x);		\
+	__typeof__(y) _y = (y);		\
+	(void)(&_x == &_y);		\
+	_x > _y ? _x : _y;		\
+})
+
+/*
+ * The round_up() macro rounds up a value to the given boundary in a
+ * type-agnostic yet type-safe manner. The boundary must be a power of two.
+ * In other words, it computes the smallest multiple of boundary which is
+ * greater than or equal to value.
+ *
+ * round_down() is similar but rounds the value down instead.
+ */
+#define round_boundary(value, boundary)		\
+	((__typeof__(value))((boundary) - 1))
+
+#define round_up(value, boundary)		\
+	((((value) - 1) | round_boundary(value, boundary)) + 1)
+
+#define round_down(value, boundary)		\
+	((value) & ~round_boundary(value, boundary))
+
+/*
+ * Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
+ * Both arguments must be unsigned pointer values (i.e. uintptr_t).
+ */
+#define check_uptr_overflow(ptr, inc)		\
+	(((ptr) > UINTPTR_MAX - (inc)) ? 1 : 0)
+
+/*
+ * For those constants to be shared between C and other sources, apply a 'ull'
+ * suffix to the argument only in C, to avoid undefined or unintended behaviour.
+ *
+ * The GNU assembler and linker do not support the 'ull' suffix (it causes the
+ * build process to fail) therefore the suffix is omitted when used in linker
+ * scripts and assembler files.
+*/
+#if defined(__LINKER__) || defined(__ASSEMBLY__)
+# define ULL(_x)	(_x)
+#else
+# define ULL(_x)	(_x##ull)
+#endif
+
+#endif /* __UTILS_DEF_H__ */
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 3105d7a..032ce92 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -31,7 +31,7 @@
 #ifndef __XLAT_TABLES_DEFS_H__
 #define __XLAT_TABLES_DEFS_H__
 
-#include <utils.h>
+#include <utils_def.h>
 
 /* Miscellaneous MMU related constants */
 #define NUM_2MB_IN_GB		(1 << 9)
diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h
index 4b5e84d..88a97d9 100644
--- a/include/plat/arm/board/common/board_css_def.h
+++ b/include/plat/arm/board/common/board_css_def.h
@@ -33,7 +33,7 @@
 
 #include <common_def.h>
 #include <soc_css_def.h>
-#include <utils.h>
+#include <utils_def.h>
 #include <v2m_def.h>
 
 /*
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 43e0eb8..f5f8378 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -34,7 +34,7 @@
 #include <common_def.h>
 #include <platform_def.h>
 #include <tbbr_img_def.h>
-#include <utils.h>
+#include <utils_def.h>
 #include <xlat_tables_defs.h>
 
 
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 4ba4a84..8ea32b9 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -35,7 +35,7 @@
 #include <cassert.h>
 #include <cpu_data.h>
 #include <stdint.h>
-#include <utils.h>
+#include <utils_def.h>
 
 /*******************************************************************************
  * Forward declarations
diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h
index 489275e..1e1bab7 100644
--- a/include/plat/arm/css/common/css_pm.h
+++ b/include/plat/arm/css/common/css_pm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, 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:
@@ -35,11 +35,15 @@
 #include <psci.h>
 #include <types.h>
 
+/* System power domain at level 2, as currently implemented by CSS platforms */
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+
 /* Macros to read the CSS power domain state */
 #define CSS_CORE_PWR_STATE(state)	(state)->pwr_domain_state[ARM_PWR_LVL0]
 #define CSS_CLUSTER_PWR_STATE(state)	(state)->pwr_domain_state[ARM_PWR_LVL1]
-#define CSS_SYSTEM_PWR_STATE(state)	((PLAT_MAX_PWR_LVL > ARM_PWR_LVL1) ?\
-				(state)->pwr_domain_state[ARM_PWR_LVL2] : 0)
+#define CSS_SYSTEM_PWR_STATE(state)	\
+			((PLAT_MAX_PWR_LVL == CSS_SYSTEM_PWR_DMN_LVL) ?\
+			(state)->pwr_domain_state[CSS_SYSTEM_PWR_DMN_LVL] : 0)
 
 int css_pwr_domain_on(u_register_t mpidr);
 void css_pwr_domain_on_finish(const psci_power_state_t *target_state);
diff --git a/include/plat/arm/soc/common/soc_css_def.h b/include/plat/arm/soc/common/soc_css_def.h
index efd78f0..ecced3d 100644
--- a/include/plat/arm/soc/common/soc_css_def.h
+++ b/include/plat/arm/soc/common/soc_css_def.h
@@ -32,7 +32,7 @@
 #define __SOC_CSS_DEF_H__
 
 #include <common_def.h>
-#include <utils.h>
+#include <utils_def.h>
 
 
 /*
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index 4426cce..23f3daa 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -273,15 +273,19 @@
 }
 
 /*
- * Returns attributes of area at `base_va` with size `size`. It returns the
- * attributes of the innermost region that contains it. If there are partial
- * overlaps, it returns -1, as a smaller size is needed.
+ * Look for the innermost region that contains the area at `base_va` with size
+ * `size`. Populate *attr with the attributes of this region.
+ *
+ * On success, this function returns 0.
+ * If there are partial overlaps (meaning that a smaller size is needed) or if
+ * the region can't be found in the given area, it returns -1. In this case the
+ * value pointed by attr should be ignored by the caller.
  */
-static mmap_attr_t mmap_region_attr(mmap_region_t *mm, uintptr_t base_va,
-					size_t size)
+static int mmap_region_attr(mmap_region_t *mm, uintptr_t base_va,
+					size_t size, mmap_attr_t *attr)
 {
 	/* Don't assume that the area is contained in the first region */
-	mmap_attr_t attr = -1;
+	int ret = -1;
 
 	/*
 	 * Get attributes from last (innermost) region that contains the
@@ -301,23 +305,25 @@
 	for (;; ++mm) {
 
 		if (!mm->size)
-			return attr; /* Reached end of list */
+			return ret; /* Reached end of list */
 
 		if (mm->base_va > base_va + size - 1)
-			return attr; /* Next region is after area so end */
+			return ret; /* Next region is after area so end */
 
 		if (mm->base_va + mm->size - 1 < base_va)
 			continue; /* Next region has already been overtaken */
 
-		if (mm->attr == attr)
+		if (!ret && mm->attr == *attr)
 			continue; /* Region doesn't override attribs so skip */
 
 		if (mm->base_va > base_va ||
 			mm->base_va + mm->size - 1 < base_va + size - 1)
 			return -1; /* Region doesn't fully cover our area */
 
-		attr = mm->attr;
+		*attr = mm->attr;
+		ret = 0;
 	}
+	return ret;
 }
 
 static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
@@ -360,9 +366,10 @@
 			 * there are partially overlapping regions. On success,
 			 * it will return the innermost region's attributes.
 			 */
-			mmap_attr_t attr = mmap_region_attr(mm, base_va,
-							level_size);
-			if (attr >= 0) {
+			mmap_attr_t attr;
+			int r = mmap_region_attr(mm, base_va, level_size, &attr);
+
+			if (!r) {
 				desc = mmap_desc(attr,
 					base_va - mm->base_va + mm->base_pa,
 					level);
diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h
index f0f656b..54ad909 100644
--- a/lib/xlat_tables/xlat_tables_private.h
+++ b/lib/xlat_tables/xlat_tables_private.h
@@ -33,7 +33,7 @@
 
 #include <cassert.h>
 #include <platform_def.h>
-#include <utils.h>
+#include <utils_def.h>
 
 /*
  * If the platform hasn't defined a physical and a virtual address space size
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index 048c4a8..e79890e 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -33,7 +33,7 @@
 
 #include <cassert.h>
 #include <platform_def.h>
-#include <utils.h>
+#include <utils_def.h>
 
 /*
  * If the platform hasn't defined a physical and a virtual address space size
diff --git a/plat/arm/board/juno/juno_pm.c b/plat/arm/board/juno/juno_pm.c
deleted file mode 100644
index c0fa628..0000000
--- a/plat/arm/board/juno/juno_pm.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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:
- *
- * 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 <css_pm.h>
-#include <plat_arm.h>
-
-/*
- * Custom `validate_power_state` handler for Juno. According to PSCI
- * Specification, interrupts targeted to cores in PSCI CPU SUSPEND should
- * be able to resume it. On Juno, when the system power domain is suspended,
- * the GIC is also powered down. The SCP resumes the final core to be suspend
- * when an external wake-up event is received. But the other cores cannot be
- * woken up by a targeted interrupt, because GIC doesn't forward these
- * interrupts to the SCP. Due to this hardware limitation, we down-grade PSCI
- * CPU SUSPEND requests targeted to the system power domain level
- * to cluster power domain level.
- *
- * The system power domain suspend on Juno is only supported only via
- * PSCI SYSTEM SUSPEND API.
- */
-static int juno_validate_power_state(unsigned int power_state,
-			    psci_power_state_t *req_state)
-{
-	int rc;
-	rc = arm_validate_power_state(power_state, req_state);
-
-	/*
-	 * Ensure that the system power domain level is never suspended
-	 * via PSCI CPU SUSPEND API. Currently system suspend is only
-	 * supported via PSCI SYSTEM SUSPEND API.
-	 */
-	req_state->pwr_domain_state[ARM_PWR_LVL2] = ARM_LOCAL_STATE_RUN;
-	return rc;
-}
-
-/*
- * Custom `translate_power_state_by_mpidr` handler for Juno. Unlike in the
- * `juno_validate_power_state`, we do not down-grade the system power
- * domain level request in `power_state` as it will be used to query the
- * PSCI_STAT_COUNT/RESIDENCY at the system power domain level.
- */
-static int juno_translate_power_state_by_mpidr(u_register_t mpidr,
-		unsigned int power_state,
-		psci_power_state_t *output_state)
-{
-	return arm_validate_power_state(power_state, output_state);
-}
-
-/*******************************************************************************
- * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
- * platform will take care of registering the handlers with PSCI.
- ******************************************************************************/
-plat_psci_ops_t plat_arm_psci_pm_ops = {
-	.pwr_domain_on			= css_pwr_domain_on,
-	.pwr_domain_on_finish		= css_pwr_domain_on_finish,
-	.pwr_domain_off			= css_pwr_domain_off,
-	.cpu_standby			= css_cpu_standby,
-	.pwr_domain_suspend		= css_pwr_domain_suspend,
-	.pwr_domain_suspend_finish	= css_pwr_domain_suspend_finish,
-	.system_off			= css_system_off,
-	.system_reset			= css_system_reset,
-	.validate_power_state		= juno_validate_power_state,
-	.validate_ns_entrypoint		= arm_validate_ns_entrypoint,
-	.get_sys_suspend_power_state	= css_get_sys_suspend_power_state,
-	.translate_power_state_by_mpidr = juno_translate_power_state_by_mpidr,
-	.get_node_hw_state		= css_node_hw_state
-};
diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c
index 2fcddcd..9bb760f 100644
--- a/plat/arm/board/juno/juno_trng.c
+++ b/plat/arm/board/juno/juno_trng.c
@@ -31,7 +31,7 @@
 #include <assert.h>
 #include <mmio.h>
 #include <string.h>
-#include <utils.h>
+#include <utils_def.h>
 #include "juno_def.h"
 
 #define NSAMPLE_CLOCKS	1 /* min 1 cycle, max 231 cycles */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 0855438..e29f8c8 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -73,7 +73,6 @@
 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}		\
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 5361d89..65a98ba 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -34,6 +34,7 @@
 #include <mmio.h>
 #include <plat_arm.h>
 #include <string.h>
+#include <utils.h>
 #include "css_scp_bootloader.h"
 
 /* Weak definition may be overridden in specific CSS based platform */
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index d4dd0af..21ce865 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, 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:
@@ -75,6 +75,13 @@
 CASSERT(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL1,
 		assert_max_pwr_lvl_supported_mismatch);
 
+/*
+ * Ensure that the PLAT_MAX_PWR_LVL is not greater than CSS_SYSTEM_PWR_DMN_LVL
+ * assumed by the CSS layer.
+ */
+CASSERT(PLAT_MAX_PWR_LVL <= CSS_SYSTEM_PWR_DMN_LVL,
+		assert_max_pwr_lvl_higher_than_css_sys_lvl);
+
 /*******************************************************************************
  * Handler called when a power domain is about to be turned on. The
  * level and mpidr determine the affinity instance.
@@ -243,7 +250,7 @@
 	 * System Suspend is supported only if the system power domain node
 	 * is implemented.
 	 */
-	assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
+	assert(PLAT_MAX_PWR_LVL == CSS_SYSTEM_PWR_DMN_LVL);
 
 	for (i = ARM_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++)
 		req_state->pwr_domain_state[i] = ARM_LOCAL_STATE_OFF;
@@ -257,6 +264,39 @@
 	return css_scp_get_power_state(mpidr, power_level);
 }
 
+/*
+ * The system power domain suspend is only supported only via
+ * PSCI SYSTEM_SUSPEND API. PSCI CPU_SUSPEND request to system power domain
+ * will be downgraded to the lower level.
+ */
+static int css_validate_power_state(unsigned int power_state,
+			    psci_power_state_t *req_state)
+{
+	int rc;
+	rc = arm_validate_power_state(power_state, req_state);
+
+	/*
+	 * Ensure that the system power domain level is never suspended
+	 * via PSCI CPU SUSPEND API. Currently system suspend is only
+	 * supported via PSCI SYSTEM SUSPEND API.
+	 */
+	req_state->pwr_domain_state[CSS_SYSTEM_PWR_DMN_LVL] = ARM_LOCAL_STATE_RUN;
+	return rc;
+}
+
+/*
+ * Custom `translate_power_state_by_mpidr` handler for CSS. Unlike in the
+ * `css_validate_power_state`, we do not downgrade the system power
+ * domain level request in `power_state` as it will be used to query the
+ * PSCI_STAT_COUNT/RESIDENCY at the system power domain level.
+ */
+static int css_translate_power_state_by_mpidr(u_register_t mpidr,
+		unsigned int power_state,
+		psci_power_state_t *output_state)
+{
+	return arm_validate_power_state(power_state, output_state);
+}
+
 /*******************************************************************************
  * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
  * platform will take care of registering the handlers with PSCI.
@@ -270,7 +310,9 @@
 	.pwr_domain_suspend_finish	= css_pwr_domain_suspend_finish,
 	.system_off		= css_system_off,
 	.system_reset		= css_system_reset,
-	.validate_power_state	= arm_validate_power_state,
+	.validate_power_state	= css_validate_power_state,
 	.validate_ns_entrypoint = arm_validate_ns_entrypoint,
-	.get_node_hw_state	= css_node_hw_state
+	.translate_power_state_by_mpidr = css_translate_power_state_by_mpidr,
+	.get_node_hw_state	= css_node_hw_state,
+	.get_sys_suspend_power_state = css_get_sys_suspend_power_state
 };
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index 41a4ede..87c7ed0 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -40,7 +40,8 @@
 #include <string.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
-#include <xlat_tables.h>
+#include <utils.h>
+#include <xlat_tables_v2.h>
 
 #define TEGRA_GPU_RESET_REG_OFFSET	0x30
 #define  GPU_RESET_BIT			(1 << 0)
@@ -450,7 +451,7 @@
 		tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb);
 
 		/*
-		 * MCE propogates the VideoMem configuration values across the
+		 * MCE propagates the VideoMem configuration values across the
 		 * CCPLEX.
 		 */
 		mce_update_gsc_videomem();
@@ -490,7 +491,7 @@
 					tegra_mc_read_32(MC_SECURITY_CFG1_0));
 
 	/*
-	 * MCE propogates the security configuration values across the
+	 * MCE propagates the security configuration values across the
 	 * CCPLEX.
 	 */
 	mce_update_gsc_tzdram();
@@ -506,25 +507,28 @@
 {
 	uint32_t index;
 	uint32_t total_128kb_blocks = size_in_bytes >> 17;
-	uint32_t residual_4kb_blocks = (size_in_bytes & 0x1FFFF) >> 12;
+	uint32_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12;
 	uint32_t val;
 
+	INFO("Configuring TrustZone SRAM Memory Carveout\n");
+
 	/*
 	 * Reset the access configuration registers to restrict access
 	 * to the TZRAM aperture
 	 */
-	for (index = MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0;
-	     index <= MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5;
-	     index += 4)
+	for (index = MC_TZRAM_CLIENT_ACCESS_CFG0;
+	     index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
+	     index += 4U) {
 		tegra_mc_write_32(index, 0);
+	}
 
 	/*
 	 * Set the TZRAM base. TZRAM base must be 4k aligned, at least.
 	 */
-	assert(!(phys_base & 0xFFF));
+	assert((phys_base & (uint64_t)0xFFF) == 0U);
 	tegra_mc_write_32(MC_TZRAM_BASE_LO, (uint32_t)phys_base);
 	tegra_mc_write_32(MC_TZRAM_BASE_HI,
-		(uint32_t)(phys_base >> 32) & TZRAM_BASE_HI_MASK);
+		(uint32_t)(phys_base >> 32) & MC_GSC_BASE_HI_MASK);
 
 	/*
 	 * Set the TZRAM size
@@ -533,7 +537,7 @@
 	 * blocks)
 	 *
 	 */
-	val = (residual_4kb_blocks << TZRAM_SIZE_RANGE_4KB_SHIFT) |
+	val = (residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) |
 	      total_128kb_blocks;
 	tegra_mc_write_32(MC_TZRAM_SIZE, val);
 
@@ -543,17 +547,96 @@
 	 * at all.
 	 */
 	val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
-	val &= ~TZRAM_ENABLE_TZ_LOCK_BIT;
-	val |= TZRAM_LOCK_CFG_SETTINGS_BIT;
+	val &= ~MC_GSC_ENABLE_TZ_LOCK_BIT;
+	val |= MC_GSC_LOCK_CFG_SETTINGS_BIT;
 	tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
 
 	/*
-	 * MCE propogates the security configuration values across the
+	 * MCE propagates the security configuration values across the
 	 * CCPLEX.
 	 */
 	mce_update_gsc_tzram();
 }
 
+static void tegra_lock_videomem_nonoverlap(uint64_t phys_base,
+					   uint64_t size_in_bytes)
+{
+	uint32_t index;
+	uint64_t total_128kb_blocks = size_in_bytes >> 17;
+	uint64_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12;
+	uint64_t val;
+
+	/*
+	 * Reset the access configuration registers to restrict access to
+	 * old Videomem aperture
+	 */
+	for (index = MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0;
+	     index < ((uint32_t)MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0 + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
+	     index += 4U) {
+		tegra_mc_write_32(index, 0);
+	}
+
+	/*
+	 * Set the base. It must be 4k aligned, at least.
+	 */
+	assert((phys_base & (uint64_t)0xFFF) == 0U);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, (uint32_t)phys_base);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI,
+		(uint32_t)(phys_base >> 32) & (uint32_t)MC_GSC_BASE_HI_MASK);
+
+	/*
+	 * Set the aperture size
+	 *
+	 * total size = (number of 128KB blocks) + (number of remaining 4KB
+	 * blocks)
+	 *
+	 */
+	val = (uint32_t)((residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) |
+			 total_128kb_blocks);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, (uint32_t)val);
+
+	/*
+	 * Lock the configuration settings by enabling TZ-only lock and
+	 * locking the configuration against any future changes from NS
+	 * world.
+	 */
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_CFG,
+			  (uint32_t)MC_GSC_ENABLE_TZ_LOCK_BIT);
+
+	/*
+	 * MCE propagates the GSC configuration values across the
+	 * CCPLEX.
+	 */
+}
+
+static void tegra_unlock_videomem_nonoverlap(void)
+{
+	/* Clear the base */
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, 0);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI, 0);
+
+	/* Clear the size */
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, 0);
+}
+
+static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
+				 unsigned long long non_overlap_area_size)
+{
+	/*
+	 * Map the NS memory first, clean it and then unmap it.
+	 */
+	mmap_add_dynamic_region(non_overlap_area_start, /* PA */
+				non_overlap_area_start, /* VA */
+				non_overlap_area_size, /* size */
+				MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
+
+	zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size);
+	flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
+
+	mmap_remove_dynamic_region(non_overlap_area_start,
+		non_overlap_area_size);
+}
+
 /*
  * Program the Video Memory carveout region
  *
@@ -562,7 +645,10 @@
  */
 void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
 {
+	uintptr_t vmem_end_old = video_mem_base + (video_mem_size_mb << 20);
+	uintptr_t vmem_end_new = phys_base + size_in_bytes;
 	uint32_t regval;
+	unsigned long long non_overlap_area_size;
 
 	/*
 	 * The GPU is the user of the Video Memory region. In order to
@@ -570,7 +656,7 @@
 	 * new base/size ONLY if the GPU is in reset mode.
 	 */
 	regval = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
-	if ((regval & GPU_RESET_BIT) == 0) {
+	if ((regval & GPU_RESET_BIT) == 0U) {
 		ERROR("GPU not in reset! Video Memory setup failed\n");
 		return;
 	}
@@ -581,17 +667,61 @@
 	 */
 	INFO("Configuring Video Memory Carveout\n");
 
+	/*
+	 * Configure Memory Controller directly for the first time.
+	 */
+	if (video_mem_base == 0U)
+		goto done;
+
+	/*
+	 * Lock the non overlapping memory being cleared so that other masters
+	 * do not accidently write to it. The memory would be unlocked once
+	 * the non overlapping region is cleared and the new memory
+	 * settings take effect.
+	 */
+	tegra_lock_videomem_nonoverlap(video_mem_base,
+				       video_mem_size_mb << 20);
+
+	/*
+	 * Clear the old regions now being exposed. The following cases
+	 * can occur -
+	 *
+	 * 1. clear whole old region (no overlap with new region)
+	 * 2. clear old sub-region below new base
+	 * 3. clear old sub-region above new end
+	 */
+	INFO("Cleaning previous Video Memory Carveout\n");
+
+	if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
+		tegra_clear_videomem(video_mem_base,
+				     (uint64_t)video_mem_size_mb << 20);
+	} else {
+		if (video_mem_base < phys_base) {
+			non_overlap_area_size = phys_base - video_mem_base;
+			tegra_clear_videomem(video_mem_base, non_overlap_area_size);
+		}
+		if (vmem_end_old > vmem_end_new) {
+			non_overlap_area_size = vmem_end_old - vmem_end_new;
+			tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
+		}
+	}
+
+done:
+	/* program the Videomem aperture */
 	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
 	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
 			  (uint32_t)(phys_base >> 32));
 	tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
 
+	/* unlock the previous locked nonoverlapping aperture */
+	tegra_unlock_videomem_nonoverlap();
+
 	/* store new values */
 	video_mem_base = phys_base;
 	video_mem_size_mb = size_in_bytes >> 20;
 
 	/*
-	 * MCE propogates the VideoMem configuration values across the
+	 * MCE propagates the VideoMem configuration values across the
 	 * CCPLEX.
 	 */
 	mce_update_gsc_videomem();
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
index a985532..60fd300 100644
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
@@ -89,7 +89,6 @@
 {
 	uint32_t i, num_entries = 0;
 	smmu_regs_t *smmu_ctx_regs;
-#if DEBUG
 	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
 	uint64_t tzdram_base = params_from_bl2->tzdram_base;
 	uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size;
@@ -102,8 +101,6 @@
 	(1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1));
 
 	assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE)));
-#endif
-
 	assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end));
 
 	/* get SMMU context table */
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index 8307af7..1dc8066 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -205,6 +205,11 @@
 	}
 
 	/*
+	 * Initialize delay timer
+	 */
+	tegra_delay_timer_init();
+
+	/*
 	 * Do initial security configuration to allow DRAM/device access.
 	 */
 	tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
@@ -264,11 +269,6 @@
 	plat_gic_setup();
 
 	/*
-	 * Initialize delay timer
-	 */
-	tegra_delay_timer_init();
-
-	/*
 	 * Setup secondary CPU POR infrastructure.
 	 */
 	plat_secondary_setup();
@@ -354,6 +354,12 @@
 			MT_DEVICE | MT_RW | MT_SECURE);
 #endif
 
+	/* map on-chip free running uS timer */
+	mmap_add_region(page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
+			page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
+			(uint64_t)TEGRA_TMRUS_SIZE,
+			MT_DEVICE | MT_RO | MT_SECURE);
+
 	/* add MMIO space */
 	plat_mmio_map = plat_get_mmio_map();
 	if (plat_mmio_map)
@@ -375,13 +381,12 @@
  ******************************************************************************/
 int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
 {
-	uint64_t end = base + size_in_bytes - 1;
+	uint64_t end = base + size_in_bytes;
 
 	/*
 	 * Check if the NS DRAM address is valid
 	 */
-	if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END) ||
-	    (base >= end)) {
+	if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END)) {
 		ERROR("NS address is out-of-bounds!\n");
 		return -EFAULT;
 	}
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index e8e25ef..cb4d188 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -28,19 +28,6 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-CRASH_REPORTING		:=	1
-$(eval $(call add_define,CRASH_REPORTING))
-
-ASM_ASSERTION		:=	1
-$(eval $(call add_define,ASM_ASSERTION))
-
-USE_COHERENT_MEM	:=	0
-
-SEPARATE_CODE_AND_RODATA :=	1
-
-PLAT_XLAT_TABLES_DYNAMIC :=	1
-$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
-
 PLAT_INCLUDES		:=	-Iplat/nvidia/tegra/include/drivers \
 				-Iplat/nvidia/tegra/include \
 				-Iplat/nvidia/tegra/include/${TARGET_SOC}
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index 4ba4f12..e488bd8 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, 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:
@@ -58,6 +58,7 @@
  * Tegra micro-seconds timer constants
  ******************************************************************************/
 #define TEGRA_TMRUS_BASE		0x60005010
+#define TEGRA_TMRUS_SIZE		0x1000
 
 /*******************************************************************************
  * Tegra Clock and Reset Controller constants
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index ae11d28..8d7ab6e 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -157,6 +157,16 @@
 #define TEGRA_MC_STREAMID_BASE		0x02C00000
 #define TEGRA_MC_BASE			0x02C10000
 
+/* General Security Carveout register macros */
+#define MC_GSC_CONFIG_REGS_SIZE		0x40UL
+#define MC_GSC_LOCK_CFG_SETTINGS_BIT	(1UL << 1)
+#define MC_GSC_ENABLE_TZ_LOCK_BIT	(1UL << 0)
+#define MC_GSC_SIZE_RANGE_4KB_SHIFT	27UL
+#define MC_GSC_BASE_LO_SHIFT		12UL
+#define MC_GSC_BASE_LO_MASK		0xFFFFFUL
+#define MC_GSC_BASE_HI_SHIFT		0UL
+#define MC_GSC_BASE_HI_MASK		3UL
+
 /* TZDRAM carveout configuration registers */
 #define MC_SECURITY_CFG0_0		0x70
 #define MC_SECURITY_CFG1_0		0x74
@@ -165,34 +175,24 @@
 /* Video Memory carveout configuration registers */
 #define MC_VIDEO_PROTECT_BASE_HI	0x978
 #define MC_VIDEO_PROTECT_BASE_LO	0x648
-#define MC_VIDEO_PROTECT_SIZE_MB	0x64c
+#define MC_VIDEO_PROTECT_SIZE_MB	0x64C
+
+/*
+ * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the
+ * non-overlapping Video memory region
+ */
+#define MC_VIDEO_PROTECT_CLEAR_CFG	0x25A0
+#define MC_VIDEO_PROTECT_CLEAR_BASE_LO	0x25A4
+#define MC_VIDEO_PROTECT_CLEAR_BASE_HI	0x25A8
+#define MC_VIDEO_PROTECT_CLEAR_SIZE	0x25AC
+#define MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0	0x25B0
 
 /* TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers */
+#define MC_TZRAM_CARVEOUT_CFG		0x2190
 #define MC_TZRAM_BASE_LO		0x2194
-#define  TZRAM_BASE_LO_SHIFT		12
-#define  TZRAM_BASE_LO_MASK		0xFFFFF
 #define MC_TZRAM_BASE_HI		0x2198
-#define  TZRAM_BASE_HI_SHIFT		0
-#define  TZRAM_BASE_HI_MASK		3
 #define MC_TZRAM_SIZE			0x219C
-#define  TZRAM_SIZE_RANGE_4KB_SHIFT	27
-
-#define MC_TZRAM_CARVEOUT_CFG			0x2190
-#define  TZRAM_LOCK_CFG_SETTINGS_BIT		(1 << 1)
-#define  TZRAM_ENABLE_TZ_LOCK_BIT		(1 << 0)
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0	0x21A0
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1	0x21A4
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG2	0x21A8
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG3	0x21AC
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG4	0x21B0
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG5	0x21B4
-
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS0	0x21B8
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS1	0x21BC
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS2	0x21C0
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS3	0x21C4
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS4	0x21C8
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5	0x21CC
+#define MC_TZRAM_CLIENT_ACCESS_CFG0	0x21A0
 
 /*******************************************************************************
  * Tegra UART Controller constants
@@ -237,6 +237,7 @@
  * Tegra micro-seconds timer constants
  ******************************************************************************/
 #define TEGRA_TMRUS_BASE		0x0C2E0000
+#define TEGRA_TMRUS_SIZE		0x1000
 
 /*******************************************************************************
  * Tegra Power Mgmt Controller constants
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index 0961355..d8ad10c 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, 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:
@@ -83,6 +83,7 @@
  * Tegra micro-seconds timer constants
  ******************************************************************************/
 #define TEGRA_TMRUS_BASE		0x60005010
+#define TEGRA_TMRUS_SIZE		0x1000
 
 /*******************************************************************************
  * Tegra Clock and Reset Controller constants
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index 2eeffca..1f7a4dc 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -30,12 +30,29 @@
 
 SOC_DIR			:=	plat/nvidia/tegra/soc/${TARGET_SOC}
 
-# Enable PSCI v1.0 extended state ID format
-PSCI_EXTENDED_STATE_ID	:=	1
+# dump the state on crash console
+CRASH_REPORTING		:=	1
+$(eval $(call add_define,CRASH_REPORTING))
+
+# enable assert() for release/debug builds
+ENABLE_ASSERTIONS	:=	1
 
 # Disable the PSCI platform compatibility layer
 ENABLE_PLAT_COMPAT	:=	0
 
+# enable dynamic memory mapping
+PLAT_XLAT_TABLES_DYNAMIC :=	1
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+
+# Enable PSCI v1.0 extended state ID format
+PSCI_EXTENDED_STATE_ID	:=	1
+
+# code and read-only data should be put on separate memory pages
+SEPARATE_CODE_AND_RODATA :=	1
+
+# do not use coherent memory
+USE_COHERENT_MEM	:=	0
+
 include plat/nvidia/tegra/common/tegra_common.mk
 include ${SOC_DIR}/platform_${TARGET_SOC}.mk
 
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
index f05f3d0..af21c28 100644
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, 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:
@@ -132,7 +132,7 @@
 
 int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
-#if DEBUG
+#if ENABLE_ASSERTIONS
 	int cpu = read_mpidr() & MPIDR_CPU_MASK;
 
 	/* SYSTEM_SUSPEND only on CPU0 */
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index 7f711a7..87fadbe 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, 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,10 +30,13 @@
 
 #include <arch.h>
 #include <arch_helpers.h>
+#include <assert.h>
 #include <debug.h>
+#include <delay_timer.h>
 #include <denver.h>
 #include <mmio.h>
 #include <mce_private.h>
+#include <platform.h>
 #include <sys/errno.h>
 #include <t18x_ari.h>
 
@@ -49,10 +52,13 @@
 #define ARI_RESPONSE_DATA_HI		0x18
 
 /* Status values for the current request */
-#define ARI_REQ_PENDING			1
-#define ARI_REQ_ONGOING			3
-#define ARI_REQUEST_VALID_BIT		(1 << 8)
-#define ARI_EVT_MASK_STANDBYWFI_BIT	(1 << 7)
+#define ARI_REQ_PENDING			1U
+#define ARI_REQ_ONGOING			3U
+#define ARI_REQUEST_VALID_BIT		(1U << 8)
+#define ARI_EVT_MASK_STANDBYWFI_BIT	(1U << 7)
+
+/* default timeout (ms) to wait for ARI completion */
+#define ARI_MAX_RETRY_COUNT		2000
 
 /*******************************************************************************
  * ARI helper functions
@@ -96,7 +102,8 @@
 static int ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req,
 		uint32_t lo, uint32_t hi)
 {
-	int status;
+	uint32_t retries = ARI_MAX_RETRY_COUNT;
+	uint32_t status;
 
 	/* program the request, event_mask, hi and lo registers */
 	ari_write_32(ari_base, lo, ARI_REQUEST_DATA_LO);
@@ -112,10 +119,36 @@
 	if (evt_mask)
 		return 0;
 
+	/* For shutdown/reboot commands, we dont have to check for timeouts */
+	if ((req == (uint32_t)TEGRA_ARI_MISC_CCPLEX) &&
+	    ((lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
+	     (lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
+			return 0;
+	}
+
+	/*
+	 * Wait for the command response for not more than the timeout
+	 */
+	while (retries != 0U) {
+
-	/* NOTE: add timeout check if needed */
-	status = ari_read_32(ari_base, ARI_STATUS);
-	while (status & (ARI_REQ_ONGOING | ARI_REQ_PENDING))
+		/* read the command status */
 		status = ari_read_32(ari_base, ARI_STATUS);
+		if ((status & (ARI_REQ_ONGOING | ARI_REQ_PENDING)) == 0U)
+			break;
+
+		/* delay 1 ms */
+		mdelay(1);
+
+		/* decrement the retry count */
+		retries--;
+	}
+
+	/* assert if the command timed out */
+	if (retries == 0U) {
+		ERROR("ARI request timed out: req %d on CPU %d\n",
+			req, plat_my_core_pos());
+		assert(retries != 0U);
+	}
 
 	return 0;
 }
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 9790b81..a7f41c1 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -188,8 +188,11 @@
 	int core_pos = read_mpidr() & MPIDR_CPU_MASK;
 	mce_cstate_info_t cstate_info = { 0 };
 
-	/* get the current core's power state */
-	target = *(states + core_pos);
+	/* get the power state at this level */
+	if (lvl == MPIDR_AFFLVL1)
+		target = *(states + core_pos);
+	if (lvl == MPIDR_AFFLVL2)
+		target = *(states + cpu);
 
 	/* CPU suspend */
 	if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) {
@@ -242,7 +245,8 @@
 	}
 
 	/* System Suspend */
-	if ((lvl == MPIDR_AFFLVL2) || (target == PSTATE_ID_SOC_POWERDN))
+	if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
+	    (target == PSTATE_ID_SOC_POWERDN))
 		return PSTATE_ID_SOC_POWERDN;
 
 	/* default state */
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 05028a1..91a13e8 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -100,6 +100,39 @@
 	return PSCI_E_SUCCESS;
 }
 
+/*******************************************************************************
+ * Platform handler to calculate the proper target power level at the
+ * specified affinity level
+ ******************************************************************************/
+plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
+					     const plat_local_state_t *states,
+					     unsigned int ncpu)
+{
+	plat_local_state_t target = *states;
+	int cpu = plat_my_core_pos();
+	int core_pos = read_mpidr() & MPIDR_CPU_MASK;
+
+	/* get the power state at this level */
+	if (lvl == MPIDR_AFFLVL1)
+		target = *(states + core_pos);
+	if (lvl == MPIDR_AFFLVL2)
+		target = *(states + cpu);
+
+	/* Cluster idle/power-down */
+	if ((lvl == MPIDR_AFFLVL1) && ((target == PSTATE_ID_CLUSTER_IDLE) ||
+	    (target == PSTATE_ID_CLUSTER_POWERDN))) {
+		return target;
+	}
+
+	/* System Suspend */
+	if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
+	    (target == PSTATE_ID_SOC_POWERDN))
+		return PSTATE_ID_SOC_POWERDN;
+
+	/* default state */
+	return PSCI_LOCAL_STATE_RUN;
+}
+
 int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
 	u_register_t mpidr = read_mpidr();
@@ -121,14 +154,14 @@
 
 	} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
 
-		assert(stateid_afflvl0 == PLAT_MAX_OFF_STATE);
+		assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_IDLE);
 
 		/* Prepare for cluster idle */
 		tegra_fc_cluster_idle(mpidr);
 
 	} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_POWERDN) {
 
-		assert(stateid_afflvl0 == PLAT_MAX_OFF_STATE);
+		assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_POWERDN);
 
 		/* Prepare for cluster powerdn */
 		tegra_fc_cluster_powerdn(mpidr);
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index 8946869..cd26e6e 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -40,7 +40,7 @@
 PLATFORM_MAX_CPUS_PER_CLUSTER		:= 4
 $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
 
-MAX_XLAT_TABLES				:= 3
+MAX_XLAT_TABLES				:= 4
 $(eval $(call add_define,MAX_XLAT_TABLES))
 
 MAX_MMAP_REGIONS			:= 8
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index f538422..02e1db7 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -632,7 +632,7 @@
 
 		cm_el1_sysregs_context_restore(NON_SECURE);
 		cm_set_next_eret_context(NON_SECURE);
-		SMC_RET0(handle);
+		SMC_RET1(handle, SMC_OK);
 
 		/*
 		 * Request from non secure world to resume the preempted