Merge "FVP: In BL31/SP_MIN, map only the needed DRAM region statically" into integration
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..36f2548
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,4 @@
+[gerrit]
+host=review.trustedfirmware.org
+port=29418
+project=TF-A/trusted-firmware-a
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index b20859b..e65ab90 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <platform_def.h>
 
+#include <common/bl_common.ld.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
@@ -148,15 +149,7 @@
         __BSS_END__ = .;
     } >RAM
 
-    /*
-     * The xlat_table section is for full, aligned page tables (4K).
-     * Removing them from .bss avoids forcing 4K alignment on
-     * the .bss section. The tables are initialized to zero by the translation
-     * tables library.
-     */
-    xlat_table (NOLOAD) : {
-        *(xlat_table)
-    } >RAM
+    XLAT_TABLE_SECTION >RAM
 
 #if USE_COHERENT_MEM
     /*
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index c1338e2..d08b046 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -6,6 +6,7 @@
 
 #include <platform_def.h>
 
+#include <common/bl_common.ld.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
@@ -125,15 +126,7 @@
         __BSS_END__ = .;
     } >RAM
 
-    /*
-     * The xlat_table section is for full, aligned page tables (4K).
-     * Removing them from .bss avoids forcing 4K alignment on
-     * the .bss section. The tables are initialized to zero by the translation
-     * tables library.
-     */
-    xlat_table (NOLOAD) : {
-        *(xlat_table)
-    } >RAM
+    XLAT_TABLE_SECTION >RAM
 
 #if USE_COHERENT_MEM
     /*
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index b6570ee..a72818c 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <platform_def.h>
 
+#include <common/bl_common.ld.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
@@ -188,15 +189,7 @@
         __BSS_END__ = .;
     } >RAM
 
-    /*
-     * The xlat_table section is for full, aligned page tables (4K).
-     * Removing them from .bss avoids forcing 4K alignment on
-     * the .bss section. The tables are initialized to zero by the translation
-     * tables library.
-     */
-    xlat_table (NOLOAD) : {
-        *(xlat_table)
-    } >RAM
+    XLAT_TABLE_SECTION >RAM
 
 #if USE_COHERENT_MEM
     /*
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index 8d257ce..96545a3 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <platform_def.h>
 
+#include <common/bl_common.ld.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
@@ -102,15 +103,7 @@
         __BSS_END__ = .;
     } >RAM
 
-    /*
-     * The xlat_table section is for full, aligned page tables (4K).
-     * Removing them from .bss avoids forcing 4K alignment on
-     * the .bss section. The tables are initialized to zero by the translation
-     * tables library.
-     */
-    xlat_table (NOLOAD) : {
-        *(xlat_table)
-    } >RAM
+    XLAT_TABLE_SECTION >RAM
 
 #if USE_COHERENT_MEM
     /*
diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S
index 97db2a1..d56b513 100644
--- a/bl31/aarch64/crash_reporting.S
+++ b/bl31/aarch64/crash_reporting.S
@@ -16,6 +16,7 @@
 	.globl	report_unhandled_exception
 	.globl	report_unhandled_interrupt
 	.globl	el3_panic
+	.globl	elx_panic
 
 #if CRASH_REPORTING
 
@@ -59,7 +60,11 @@
 excpt_msg:
 	.asciz "Unhandled Exception in EL3.\nx30"
 intr_excpt_msg:
-	.asciz "Unhandled Interrupt Exception in EL3.\nx30"
+	.ascii "Unhandled Interrupt Exception in EL3.\n"
+x30_msg:
+	.asciz "x30"
+excpt_msg_el:
+	.asciz "Unhandled Exception from EL"
 
 	/*
 	 * Helper function to print from crash buf.
@@ -170,7 +175,6 @@
 	b	do_crash_reporting
 endfunc report_unhandled_exception
 
-
 	/* -----------------------------------------------------
 	 * This function allows to report a crash (if crash
 	 * reporting is enabled) when an unhandled interrupt
@@ -188,6 +192,112 @@
 endfunc report_unhandled_interrupt
 
 	/* -----------------------------------------------------
+	 * This function allows to report a crash from the lower
+	 * exception level (if crash reporting is enabled) when
+	 * panic() is invoked from C Runtime.
+	 * It prints the CPU state via the crash console making
+	 * use of 'cpu_context' structure where general purpose
+	 * registers are saved and the crash buf.
+	 * This function will not return.
+	 *
+ 	 * x0: Exception level
+	 * -----------------------------------------------------
+	 */
+func elx_panic
+	msr	spsel, #MODE_SP_ELX
+	mov	x8, x0
+
+	/* Print the crash message */
+	adr	x4, excpt_msg_el
+	bl	asm_print_str
+
+	/* Print exception level */
+	add	x0, x8, #'0'
+	bl	plat_crash_console_putc
+	bl	asm_print_newline
+
+	/* Report x0 - x29 values stored in 'gpregs_ctx' structure */
+	/* Store the ascii list pointer in x6 */
+	adr	x6, gp_regs
+	add	x7, sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0
+
+print_next:
+	ldrb	w4, [x6]
+	/* Test whether we are at end of list */
+	cbz	w4, print_x30
+	mov	x4, x6
+	/* asm_print_str updates x4 to point to next entry in list */
+	bl	asm_print_str
+	/* x0 = number of symbols printed + 1 */
+	sub	x0, x4, x6
+	/* Update x6 with the updated list pointer */
+	mov	x6, x4
+	bl	print_alignment
+	ldr	x4, [x7], #REGSZ
+	bl	asm_print_hex
+	bl	asm_print_newline
+	b	print_next
+
+print_x30:
+	adr	x4, x30_msg
+	bl	asm_print_str
+
+	/* Print spaces to align "x30" string */
+	mov	x0, #4
+	bl	print_alignment
+
+	/* Report x30 */
+	ldr	x4, [x7]
+
+	/* ----------------------------------------------------------------
+	 * Different virtual address space size can be defined for each EL.
+	 * Ensure that we use the proper one by reading the corresponding
+	 * TCR_ELx register.
+	 * ----------------------------------------------------------------
+	 */
+	cmp	x8, #MODE_EL2
+	b.lt	from_el1	/* EL1 */
+	mrs	x2, sctlr_el2
+	mrs	x1, tcr_el2
+
+	/* ----------------------------------------------------------------
+	 * Check if pointer authentication is enabled at the specified EL.
+	 * If it isn't, we can then skip stripping a PAC code.
+	 * ----------------------------------------------------------------
+	 */
+test_pauth:
+	tst	x2, #(SCTLR_EnIA_BIT | SCTLR_EnIB_BIT)
+	b.eq	no_pauth
+
+	/* Demangle address */
+	and	x1, x1, #0x3F	/* T0SZ = TCR_ELx[5:0] */
+	sub	x1, x1, #64
+	neg	x1, x1		/* bottom_pac_bit = 64 - T0SZ */
+	mov	x2, #-1
+	lsl	x2, x2, x1
+	bic	x4, x4, x2
+
+no_pauth:
+	bl	asm_print_hex
+	bl	asm_print_newline
+
+	/* tpidr_el3 contains the address to cpu_data structure */
+	mrs	x0, tpidr_el3
+	/* Calculate the Crash buffer offset in cpu_data */
+	add	x0, x0, #CPU_DATA_CRASH_BUF_OFFSET
+	/* Store crash buffer address in tpidr_el3 */
+	msr	tpidr_el3, x0
+
+	/* Print the rest of crash dump */
+	b	print_el3_sys_regs
+
+from_el1:
+	mrs	x2, sctlr_el1
+	mrs	x1, tcr_el1
+	b	test_pauth
+endfunc	elx_panic
+
+	/* -----------------------------------------------------
 	 * This function allows to report a crash (if crash
 	 * reporting is enabled) when panic() is invoked from
 	 * C Runtime. It prints the CPU state via the crash
@@ -200,9 +310,7 @@
 	prepare_crash_buf_save_x0_x1
 	adr	x0, panic_msg
 	mov	sp, x0
-	/* This call will not return */
-	b	do_crash_reporting
-endfunc el3_panic
+	/* Fall through to 'do_crash_reporting' */
 
 	/* ------------------------------------------------------------
 	 * The common crash reporting functionality. It requires x0
@@ -223,7 +331,7 @@
 	 *     the crash buf to the crash console.
 	 * ------------------------------------------------------------
 	 */
-func do_crash_reporting
+do_crash_reporting:
 	/* Retrieve the crash buf from tpidr_el3 */
 	mrs	x0, tpidr_el3
 	/* Store x2 - x6, x30 in the crash buffer */
@@ -240,9 +348,9 @@
 	/* Print spaces to align "x30" string */
 	mov	x0, #4
 	bl	print_alignment
-	/* load the crash buf address */
+	/* Load the crash buf address */
 	mrs	x0, tpidr_el3
-	/* report x30 first from the crash buf */
+	/* Report x30 first from the crash buf */
 	ldr	x4, [x0, #REGSZ * 7]
 
 #if ENABLE_PAUTH
@@ -256,7 +364,7 @@
 	/* Now mov x7 into crash buf */
 	str	x7, [x0, #REGSZ * 7]
 
-	/* Report x0 - x29 values stored in crash buf*/
+	/* Report x0 - x29 values stored in crash buf */
 	/* Store the ascii list pointer in x6 */
 	adr	x6, gp_regs
 	/* Print x0 to x7 from the crash buf */
@@ -279,6 +387,7 @@
 	bl	size_controlled_print
 
 	/* Print the el3 sys registers */
+print_el3_sys_regs:
 	adr	x6, el3_sys_regs
 	mrs	x8, scr_el3
 	mrs	x9, sctlr_el3
@@ -354,7 +463,7 @@
 
 	/* Done reporting */
 	no_ret	plat_panic_handler
-endfunc do_crash_reporting
+endfunc el3_panic
 
 #else	/* CRASH_REPORTING */
 func report_unhandled_exception
@@ -363,7 +472,6 @@
 endfunc report_unhandled_exception
 #endif	/* CRASH_REPORTING */
 
-
 func crash_panic
 	no_ret	plat_panic_handler
 endfunc crash_panic
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index fce9eb2..5f9f9df 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -6,6 +6,7 @@
 
 #include <platform_def.h>
 
+#include <common/bl_common.ld.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
@@ -297,15 +298,7 @@
         __BSS_END__ = .;
     } >NOBITS
 
-    /*
-     * The xlat_table section is for full, aligned page tables (4K).
-     * Removing them from .bss avoids forcing 4K alignment on
-     * the .bss section. The tables are initialized to zero by the translation
-     * tables library.
-     */
-    xlat_table (NOLOAD) : {
-        *(xlat_table)
-    } >NOBITS
+    XLAT_TABLE_SECTION >NOBITS
 
 #if USE_COHERENT_MEM
     /*
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 3231f9a..a90a805 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -6,6 +6,7 @@
 
 #include <platform_def.h>
 
+#include <common/bl_common.ld.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
 OUTPUT_FORMAT(elf32-littlearm)
@@ -206,15 +207,7 @@
         __BSS_END__ = .;
     } >RAM
 
-    /*
-     * The xlat_table section is for full, aligned page tables (4K).
-     * Removing them from .bss avoids forcing 4K alignment on
-     * the .bss section. The tables are initialized to zero by the translation
-     * tables library.
-     */
-    xlat_table (NOLOAD) : {
-        *(xlat_table)
-    } >RAM
+    XLAT_TABLE_SECTION >RAM
 
      __BSS_SIZE__ = SIZEOF(.bss);
 
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index 592e245..da60c63 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/bl_common.ld.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 #include <platform_def.h>
 
@@ -125,15 +126,7 @@
         __BSS_END__ = .;
     } >RAM
 
-    /*
-     * The xlat_table section is for full, aligned page tables (4K).
-     * Removing them from .bss avoids forcing 4K alignment on
-     * the .bss section. The tables are initialized to zero by the translation
-     * tables library.
-     */
-    xlat_table (NOLOAD) : {
-        *(xlat_table)
-    } >RAM
+    XLAT_TABLE_SECTION >RAM
 
 #if USE_COHERENT_MEM
     /*
diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S
index e6e3298..7db2439 100644
--- a/common/aarch64/debug.S
+++ b/common/aarch64/debug.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -156,16 +156,32 @@
 
 /* This is for the non el3 BL stages to compile through */
 	.weak el3_panic
+	.weak elx_panic
 
 func do_panic
 #if CRASH_REPORTING
 	str	x0, [sp, #-0x10]!
 	mrs	x0, currentel
-	ubfx	x0, x0, #2, #2
-	cmp	x0, #0x3
+	ubfx	x0, x0, #MODE_EL_SHIFT, #MODE_EL_WIDTH
+	cmp	x0, #MODE_EL3
+#if !HANDLE_EA_EL3_FIRST
 	ldr	x0, [sp], #0x10
 	b.eq	el3_panic
-#endif
+#else
+	b.ne	to_panic_common
+
+	/* Check EL the exception taken from */
+	mrs	x0, spsr_el3
+	ubfx	x0, x0, #SPSR_EL_SHIFT, #SPSR_EL_WIDTH
+	cmp	x0, #MODE_EL3
+	b.ne	elx_panic
+	ldr	x0, [sp], #0x10
+	b	el3_panic
+
+to_panic_common:
+	ldr	x0, [sp], #0x10
+#endif /* HANDLE_EA_EL3_FIRST */
+#endif /* CRASH_REPORTING */
 
 panic_common:
 /*
diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c
index 907117f..ef57500 100644
--- a/common/backtrace/backtrace.c
+++ b/common/backtrace/backtrace.c
@@ -37,7 +37,7 @@
 	uintptr_t return_addr;
 };
 
-static const char *get_el_str(unsigned int el)
+const char *get_el_str(unsigned int el)
 {
 	if (el == 3U) {
 		return "EL3";
diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst
index 15f39de..f86280f 100644
--- a/docs/change-log-upcoming.rst
+++ b/docs/change-log-upcoming.rst
@@ -24,6 +24,8 @@
 
 - Build System
    - Add support for documentation build as a target in Makefile
+   - Add ``COT`` build option to select the chain of trust to use when the
+     Trusted Boot feature is enabled (default: ``tbbr``).
 
 - CPU Support
    - Example: "cortex-a55: Workaround for erratum 1221012"
@@ -40,6 +42,7 @@
 
 - Platforms
    - Example: "arm/common: Introduce wrapper functions to setup secure watchdog"
+   - plat/arm: Add support for the new `dualroot` chain of trust.
 
 - PSCI
    - Example: "Adding new optional PSCI hook ``pwr_domain_on_finish_late``"
@@ -47,6 +50,7 @@
 - Security
    - Example: "UBSAN support and handlers"
    - Add support for optional firmware encryption feature (experimental).
+   - Introduce a new `dualroot` chain of trust.
 
 - Tools
    - Example: "fiptool: Add support to build fiptool on Windows."
diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst
index 4ea1f5b..3856600 100644
--- a/docs/components/fconf.rst
+++ b/docs/components/fconf.rst
@@ -99,3 +99,30 @@
 registered with ``FCONF_REGISTER_POPULATOR()`` as described above.
 
 .. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml
+
+Namespace guidance
+~~~~~~~~~~~~~~~~~~
+
+As mentioned above, properties are logically grouped around namespaces and
+sub-namespaces. The following concepts should be considered when adding new
+properties/namespaces.
+The framework differentiates two types of properties:
+ - Properties used inside common code.
+ - Properties used inside platform specific code.
+
+The first category applies to properties being part of the firmware and shared
+across multiple platforms. They should be globally accessible and defined
+inside the ``lib/fconf`` directory. The namespace must be chosen to reflect the
+feature/data abstracted.
+Example:
+ - |TBBR| related properties: tbbr.cot.bl2_id
+ - Dynamic configuration information: dyn_cfg.dtb_info.hw_config_id
+
+The second category should represent the majority of the properties defined
+within the framework: Platform specific properties. They must be accessed only
+within the platform API and are defined only inside the platform scope. The
+namespace must contain the platform name under which the properties defined
+belong.
+Example:
+ - Arm io framework: arm.io_policies.bl31_id
+
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index d0d6ef6..8e9dc38 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -1177,83 +1177,104 @@
 
 ::
 
-    x0  :0x000000004F00007C
-    x1  :0x0000000007FFFFFF
-    x2  :0x0000000004014D50
-    x3  :0x0000000000000000
-    x4  :0x0000000088007998
-    x5  :0x00000000001343AC
-    x6  :0x0000000000000016
-    x7  :0x00000000000B8A38
-    x8  :0x00000000001343AC
-    x9  :0x00000000000101A8
-    x10 :0x0000000000000002
-    x11 :0x000000000000011C
-    x12 :0x00000000FEFDC644
-    x13 :0x00000000FED93FFC
-    x14 :0x0000000000247950
-    x15 :0x00000000000007A2
-    x16 :0x00000000000007A4
-    x17 :0x0000000000247950
-    x18 :0x0000000000000000
-    x19 :0x00000000FFFFFFFF
-    x20 :0x0000000004014D50
-    x21 :0x000000000400A38C
-    x22 :0x0000000000247950
-    x23 :0x0000000000000010
-    x24 :0x0000000000000024
-    x25 :0x00000000FEFDC868
-    x26 :0x00000000FEFDC86A
-    x27 :0x00000000019EDEDC
-    x28 :0x000000000A7CFDAA
-    x29 :0x0000000004010780
-    x30 :0x000000000400F004
-    scr_el3 :0x0000000000000D3D
-    sctlr_el3   :0x0000000000C8181F
-    cptr_el3    :0x0000000000000000
-    tcr_el3 :0x0000000080803520
-    daif    :0x00000000000003C0
-    mair_el3    :0x00000000000004FF
-    spsr_el3    :0x00000000800003CC
-    elr_el3 :0x000000000400C0CC
-    ttbr0_el3   :0x00000000040172A0
-    esr_el3 :0x0000000096000210
-    sp_el3  :0x0000000004014D50
-    far_el3 :0x000000004F00007C
-    spsr_el1    :0x0000000000000000
-    elr_el1 :0x0000000000000000
-    spsr_abt    :0x0000000000000000
-    spsr_und    :0x0000000000000000
-    spsr_irq    :0x0000000000000000
-    spsr_fiq    :0x0000000000000000
-    sctlr_el1   :0x0000000030C81807
-    actlr_el1   :0x0000000000000000
-    cpacr_el1   :0x0000000000300000
-    csselr_el1  :0x0000000000000002
-    sp_el1  :0x0000000004028800
-    esr_el1 :0x0000000000000000
-    ttbr0_el1   :0x000000000402C200
-    ttbr1_el1   :0x0000000000000000
-    mair_el1    :0x00000000000004FF
-    amair_el1   :0x0000000000000000
-    tcr_el1 :0x0000000000003520
-    tpidr_el1   :0x0000000000000000
-    tpidr_el0   :0x0000000000000000
-    tpidrro_el0 :0x0000000000000000
-    dacr32_el2  :0x0000000000000000
-    ifsr32_el2  :0x0000000000000000
-    par_el1 :0x0000000000000000
-    far_el1 :0x0000000000000000
-    afsr0_el1   :0x0000000000000000
-    afsr1_el1   :0x0000000000000000
-    contextidr_el1  :0x0000000000000000
-    vbar_el1    :0x0000000004027000
-    cntp_ctl_el0    :0x0000000000000000
-    cntp_cval_el0   :0x0000000000000000
-    cntv_ctl_el0    :0x0000000000000000
-    cntv_cval_el0   :0x0000000000000000
-    cntkctl_el1 :0x0000000000000000
-    sp_el0  :0x0000000004010780
+    x0             = 0x000000002a4a0000
+    x1             = 0x0000000000000001
+    x2             = 0x0000000000000002
+    x3             = 0x0000000000000003
+    x4             = 0x0000000000000004
+    x5             = 0x0000000000000005
+    x6             = 0x0000000000000006
+    x7             = 0x0000000000000007
+    x8             = 0x0000000000000008
+    x9             = 0x0000000000000009
+    x10            = 0x0000000000000010
+    x11            = 0x0000000000000011
+    x12            = 0x0000000000000012
+    x13            = 0x0000000000000013
+    x14            = 0x0000000000000014
+    x15            = 0x0000000000000015
+    x16            = 0x0000000000000016
+    x17            = 0x0000000000000017
+    x18            = 0x0000000000000018
+    x19            = 0x0000000000000019
+    x20            = 0x0000000000000020
+    x21            = 0x0000000000000021
+    x22            = 0x0000000000000022
+    x23            = 0x0000000000000023
+    x24            = 0x0000000000000024
+    x25            = 0x0000000000000025
+    x26            = 0x0000000000000026
+    x27            = 0x0000000000000027
+    x28            = 0x0000000000000028
+    x29            = 0x0000000000000029
+    x30            = 0x0000000088000b78
+    scr_el3        = 0x000000000003073d
+    sctlr_el3      = 0x00000000b0cd183f
+    cptr_el3       = 0x0000000000000000
+    tcr_el3        = 0x000000008080351c
+    daif           = 0x00000000000002c0
+    mair_el3       = 0x00000000004404ff
+    spsr_el3       = 0x0000000060000349
+    elr_el3        = 0x0000000088000114
+    ttbr0_el3      = 0x0000000004018201
+    esr_el3        = 0x00000000be000000
+    far_el3        = 0x0000000000000000
+    spsr_el1       = 0x0000000000000000
+    elr_el1        = 0x0000000000000000
+    spsr_abt       = 0x0000000000000000
+    spsr_und       = 0x0000000000000000
+    spsr_irq       = 0x0000000000000000
+    spsr_fiq       = 0x0000000000000000
+    sctlr_el1      = 0x0000000030d00800
+    actlr_el1      = 0x0000000000000000
+    cpacr_el1      = 0x0000000000000000
+    csselr_el1     = 0x0000000000000000
+    sp_el1         = 0x0000000000000000
+    esr_el1        = 0x0000000000000000
+    ttbr0_el1      = 0x0000000000000000
+    ttbr1_el1      = 0x0000000000000000
+    mair_el1       = 0x0000000000000000
+    amair_el1      = 0x0000000000000000
+    tcr_el1        = 0x0000000000000000
+    tpidr_el1      = 0x0000000000000000
+    tpidr_el0      = 0x0000000000000000
+    tpidrro_el0    = 0x0000000000000000
+    par_el1        = 0x0000000000000000
+    mpidr_el1      = 0x0000000080000000
+    afsr0_el1      = 0x0000000000000000
+    afsr1_el1      = 0x0000000000000000
+    contextidr_el1 = 0x0000000000000000
+    vbar_el1       = 0x0000000000000000
+    cntp_ctl_el0   = 0x0000000000000000
+    cntp_cval_el0  = 0x0000000000000000
+    cntv_ctl_el0   = 0x0000000000000000
+    cntv_cval_el0  = 0x0000000000000000
+    cntkctl_el1    = 0x0000000000000000
+    sp_el0         = 0x0000000004014940
+    isr_el1        = 0x0000000000000000
+    dacr32_el2     = 0x0000000000000000
+    ifsr32_el2     = 0x0000000000000000
+    icc_hppir0_el1 = 0x00000000000003ff
+    icc_hppir1_el1 = 0x00000000000003ff
+    icc_ctlr_el3   = 0x0000000000080400
+    gicd_ispendr regs (Offsets 0x200-0x278)
+    Offset		    Value
+    0x200:	     0x0000000000000000
+    0x208:	     0x0000000000000000
+    0x210:	     0x0000000000000000
+    0x218:	     0x0000000000000000
+    0x220:	     0x0000000000000000
+    0x228:	     0x0000000000000000
+    0x230:	     0x0000000000000000
+    0x238:	     0x0000000000000000
+    0x240:	     0x0000000000000000
+    0x248:	     0x0000000000000000
+    0x250:	     0x0000000000000000
+    0x258:	     0x0000000000000000
+    0x260:	     0x0000000000000000
+    0x268:	     0x0000000000000000
+    0x270:	     0x0000000000000000
+    0x278:	     0x0000000000000000
 
 Guidelines for Reset Handlers
 -----------------------------
@@ -1838,7 +1859,7 @@
                |   BL2    |  <<<<<<<<<<<<<  |                |
                |----------|  <<<<<<<<<<<<<  |----------------|
                | SCP_BL2  |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
-               |----------|  <<<<<<<<<<<<<  |----------------|
+               |          |  <<<<<<<<<<<<<  |----------------|
                |          |  <<<<<<<<<<<<<  |     BL32       |
                |          |                 +----------------+
                |          |
@@ -1875,7 +1896,7 @@
                |   BL2    |  <<<<<<<<<<<<<  |                |
                |----------|  <<<<<<<<<<<<<  |----------------|
                | SCP_BL2  |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
-               |----------|                 +----------------+
+               |          |                 +----------------+
     0x04001000 +----------+
                |   MHU    |
     0x04000000 +----------+
diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst
index f5c8bc9..dd61b61 100644
--- a/docs/design/trusted-board-boot-build.rst
+++ b/docs/design/trusted-board-boot-build.rst
@@ -32,25 +32,28 @@
    -  ``TRUSTED_BOARD_BOOT=1``
    -  ``GENERATE_COT=1``
 
+   By default, this will use the Chain of Trust described in the TBBR-client
+   document. To select a different one, use the ``COT`` build option.
+
    In the case of Arm platforms, the location of the ROTPK hash must also be
    specified at build time. The following locations are currently supported (see
    ``ARM_ROTPK_LOCATION`` build option):
 
    -  ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted
-      root-key storage registers present in the platform. On Juno, this
+      root-key storage registers present in the platform. On Juno, these
       registers are read-only. On FVP Base and Cortex models, the registers
-      are read-only, but the value can be specified using the command line
+      are also read-only, but the value can be specified using the command line
       option ``bp.trusted_key_storage.public_key`` when launching the model.
       On Juno board, the default value corresponds to an ECDSA-SECP256R1 public
       key hash, whose private part is not currently available.
 
    -  ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in
-      plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin. Enforce generation
-      of the new hash if ROT_KEY is specified.
+      ``plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin``. Enforce
+      generation of the new hash if ``ROT_KEY`` is specified.
 
    -  ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in
-      plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin. Enforce generation
-      of the new hash if ROT_KEY is specified.
+      ``plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin``. Enforce
+      generation of the new hash if ``ROT_KEY`` is specified.
 
    Example of command line using RSA development keys:
 
@@ -64,9 +67,8 @@
        all fip
 
    The result of this build will be the bl1.bin and the fip.bin binaries. This
-   FIP will include the certificates corresponding to the Chain of Trust
-   described in the TBBR-client document. These certificates can also be found
-   in the output build directory.
+   FIP will include the certificates corresponding to the selected Chain of
+   Trust. These certificates can also be found in the output build directory.
 
 #. The optional FWU_FIP contains any additional images to be loaded from
    Non-Volatile storage during the :ref:`Firmware Update (FWU)` process. To build the
@@ -102,8 +104,8 @@
 
    The result of this build will be bl1.bin, fip.bin and fwu_fip.bin binaries.
    Both the FIP and FWU_FIP will include the certificates corresponding to the
-   Chain of Trust described in the TBBR-client document. These certificates
-   can also be found in the output build directory.
+   selected Chain of Trust. These certificates can also be found in the output
+   build directory.
 
 --------------
 
diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst
index 4802c97..96cf24c 100644
--- a/docs/design/trusted-board-boot.rst
+++ b/docs/design/trusted-board-boot.rst
@@ -19,7 +19,9 @@
 the Arm development platforms, these components are:
 
 -  A SHA-256 hash of the Root of Trust Public Key (ROTPK). It is stored in the
-   trusted root-key storage registers.
+   trusted root-key storage registers. Alternatively, a development ROTPK might
+   be used and its hash embedded into the BL1 and BL2 images (only for
+   development purposes).
 
 -  The BL1 image, on the assumption that it resides in ROM so cannot be
    tampered with.
@@ -32,17 +34,17 @@
 In the TBB CoT all certificates are self-signed. There is no need for a
 Certificate Authority (CA) because the CoT is not established by verifying the
 validity of a certificate's issuer but by the content of the certificate
-extensions. To sign the certificates, the PKCS#1 SHA-256 with RSA Encryption
-signature scheme is used with a RSA key length of 2048 bits. Future version of
-TF-A will support additional cryptographic algorithms.
+extensions. To sign the certificates, different signature schemes are available,
+please refer to the :ref:`Build Options` for more details.
 
 The certificates are categorised as "Key" and "Content" certificates. Key
 certificates are used to verify public keys which have been used to sign content
 certificates. Content certificates are used to store the hash of a boot loader
 image. An image can be authenticated by calculating its hash and matching it
-with the hash extracted from the content certificate. The SHA-256 function is
-used to calculate all hashes. The public keys and hashes are included as
-non-standard extension fields in the `X.509 v3`_ certificates.
+with the hash extracted from the content certificate. Various hash algorithms
+are supported to calculate all hashes, please refer to the :ref:`Build Options`
+for more details.. The public keys and hashes are included as non-standard
+extension fields in the `X.509 v3`_ certificates.
 
 The keys used to establish the CoT are:
 
@@ -63,10 +65,10 @@
    non secure world image (BL33). The public part is stored in one of the
    extension fields in the trusted world certificate.
 
--  **BL3-X keys**
+-  **BL3X keys**
 
    For each of SCP_BL2, BL31, BL32 and BL33, the private part is used to
-   sign the content certificate for the BL3-X image. The public part is stored
+   sign the content certificate for the BL3X image. The public part is stored
    in one of the extension fields in the corresponding key certificate.
 
 The following images are included in the CoT:
@@ -219,8 +221,7 @@
 generated by the tool in case they are not provided. The certificates are then
 passed as inputs to the ``fiptool`` utility for creating the FIP.
 
-The certificates are also stored individually in the in the output build
-directory.
+The certificates are also stored individually in the output build directory.
 
 The tool resides in the ``tools/cert_create`` directory. It uses the OpenSSL SSL
 library version to generate the X.509 certificates. The specific version of the
@@ -259,7 +260,7 @@
 
 --------------
 
-*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.*
 
 .. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt
 .. _Trusted Board Boot Requirements (TBBR): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
diff --git a/docs/design_documents/cmake_framework.rst b/docs/design_documents/cmake_framework.rst
new file mode 100644
index 0000000..d88942e
--- /dev/null
+++ b/docs/design_documents/cmake_framework.rst
@@ -0,0 +1,165 @@
+TF-A CMake buildsystem
+======================
+
+:Author: Balint Dobszay
+:Organization: Arm Limited
+:Contact: Balint Dobszay <balint.dobszay@arm.com>
+:Status: Accepted
+
+.. contents:: Table of Contents
+
+Abstract
+--------
+This document presents a proposal for a new buildsystem for TF-A using CMake,
+and as part of this a reusable CMake framework for embedded projects. For a
+summary about the proposal, please see the `Phabricator wiki page
+<https://developer.trustedfirmware.org/w/tf_a/cmake-buildsystem-proposal/>`_. As
+mentioned there, the proposal consists of two phases. The subject of this
+document is the first phase only.
+
+Introduction
+------------
+The current Makefile based buildsystem of TF-A has become complicated and hard
+to maintain, there is a need for a new, more flexible solution. The proposal is
+to use CMake language for the new buildsystem. The main reasons of this decision
+are the following:
+
+* It is a well-established, mature tool, widely accepted by open-source
+  projects.
+* TF-M is already using CMake, reducing fragmentation for tf.org projects can be
+  beneficial.
+* CMake has various advantages over Make, e.g.:
+
+  * Host and target system agnostic project.
+  * CMake project is scalable, supports project modularization.
+  * Supports software integration.
+  * Out-of-the-box support for integration with several tools (e.g. project
+    generation for various IDEs, integration with cppcheck, etc).
+
+Of course there are drawbacks too:
+
+* Language is problematic (e.g. variable scope).
+* Not embedded approach.
+
+To overcome these and other problems, we need to create workarounds for some
+tasks, wrap CMake functions, etc. Since this functionality can be useful in
+other embedded projects too, it is beneficial to collect the new code into a
+reusable framework and store this in a separate repository. The following
+diagram provides an overview of the framework structure:
+
+|Framework structure|
+
+Main features
+-------------
+
+Structured configuration description
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+In the current Makefile system the build configuration description, validation,
+processing, and the target creation, source file description are mixed and
+spread across several files. One of the goals of the framework is to organize
+this.
+
+The framework provides a solution to describe the input build parameters, flags,
+macros, etc. in a structured way. It contains two utilities for this purpose:
+
+* Map: simple key-value pair implementation.
+* Group: collection of related maps.
+
+The related parameters shall be packed into a group (or "setting group"). The
+setting groups shall be defined and filled with content in config files.
+Currently the config files are created and edited manually, but later a
+configuration management tool (e.g. Kconfig) shall be used to generate these
+files. Therefore, the framework does not contain parameter validation and
+conflict checking, these shall be handled by the configuration tool.
+
+Target description
+^^^^^^^^^^^^^^^^^^
+The framework provides an API called STGT ('simple target') to describe the
+targets, i.e. what is the build output, what source files are used, what
+libraries are linked, etc. The API wraps the CMake target functions, and also
+extends the built-in functionality, it can use the setting groups described in
+the previous section. A group can be applied onto a target, i.e. a collection of
+macros, flags, etc. can be applied onto the given output executable/library.
+This provides a more granular way than the current Makefile system where most of
+these are global and applied onto each target.
+
+Compiler abstraction
+^^^^^^^^^^^^^^^^^^^^
+Apart from the built-in CMake usage of the compiler, there are some common tasks
+that CMake does not solve (e.g. preprocessing a file). For these tasks the
+framework uses wrapper functions instead of direct calls to the compiler. This
+way it is not tied to one specific compiler.
+
+External tools
+^^^^^^^^^^^^^^
+In the TF-A buildsystem some external tools are used, e.g. fiptool for image
+generation or dtc for device tree compilation. These tools have to be found
+and/or built by the framework. For this, the CMake find_package functionality is
+used, any other necessary tools can be added later.
+
+Workflow
+--------
+The following diagram demonstrates the development workflow using the framework:
+
+|Framework workflow|
+
+The process can be split into two main phases:
+
+In the provisioning phase, first we have to obtain the necessary resources, i.e.
+clone the code repository and other dependencies. Next we have to do the
+configuration, preferably using a config tool like KConfig.
+
+In the development phase first we run CMake, which will generate the buildsystem
+using the selected generator backend (currently only the Makefile generator is
+supported). After this we run the selected build tool which in turn calls the
+compiler, linker, packaging tool, etc. Finally we can run and debug the output
+executables.
+
+Usually during development only the steps in this second phase have to be
+repeated, while the provisioning phase needs to be done only once (or rarely).
+
+Example
+-------
+This is a short example for the basic framework usage.
+
+First, we create a setting group called *mem_conf* and fill it with several
+parameters. It is worth noting the difference between *CONFIG* and *DEFINE*
+types: the former is only a CMake domain option, the latter is only a C language
+macro.
+
+Next, we create a target called *fw1* and add the *mem_conf* setting group to
+it. This means that all source and header files used by the target will have all
+the parameters declared in the setting group. Then we set the target type to
+executable, and add some source files. Since the target has the parameters from
+the settings group, we can use it for conditionally adding source files. E.g.
+*dram_controller.c* will only be added if MEM_TYPE equals dram.
+
+.. code-block:: cmake
+
+   group_new(NAME mem_conf)
+   group_add(NAME mem_conf TYPE DEFINE KEY MEM_SIZE VAL 1024)
+   group_add(NAME mem_conf TYPE CONFIG DEFINE KEY MEM_TYPE VAL dram)
+   group_add(NAME mem_conf TYPE CFLAG KEY -Os)
+
+   stgt_create(NAME fw1)
+   stgt_add_setting(NAME fw1 GROUPS mem_conf)
+   stgt_set_target(NAME fw1 TYPE exe)
+
+   stgt_add_src(NAME fw1 SRC
+       ${CMAKE_SOURCE_DIR}/main.c
+   )
+
+   stgt_add_src_cond(NAME fw1 KEY MEM_TYPE VAL dram SRC
+       ${CMAKE_SOURCE_DIR}/dram_controller.c
+   )
+
+.. |Framework structure| image::
+   ../resources/diagrams/cmake_framework_structure.png
+   :width: 75 %
+
+.. |Framework workflow| image::
+   ../resources/diagrams/cmake_framework_workflow.png
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
new file mode 100644
index 0000000..187510a
--- /dev/null
+++ b/docs/design_documents/index.rst
@@ -0,0 +1,13 @@
+Design Documents
+================
+
+.. toctree::
+   :maxdepth: 1
+   :caption: Contents
+   :numbered:
+
+   cmake_framework
+
+--------------
+
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/index.rst b/docs/index.rst
index 5088bfd..7413edd 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -14,6 +14,7 @@
    plat/index
    perf/index
    security_advisories/index
+   design_documents/index
    change-log
    change-log-upcoming
    glossary
@@ -82,7 +83,7 @@
 
 --------------
 
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
 
 .. _Armv7-A and Armv8-A: https://developer.arm.com/products/architecture/a-profile
 .. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php
diff --git a/docs/resources/diagrams/cmake_framework_structure.png b/docs/resources/diagrams/cmake_framework_structure.png
new file mode 100644
index 0000000..6006f1c
--- /dev/null
+++ b/docs/resources/diagrams/cmake_framework_structure.png
Binary files differ
diff --git a/docs/resources/diagrams/cmake_framework_workflow.png b/docs/resources/diagrams/cmake_framework_workflow.png
new file mode 100644
index 0000000..7311529
--- /dev/null
+++ b/docs/resources/diagrams/cmake_framework_workflow.png
Binary files differ
diff --git a/drivers/arm/gic/v3/gicdv3_helpers.c b/drivers/arm/gic/v3/gicdv3_helpers.c
new file mode 100644
index 0000000..3f5ff45
--- /dev/null
+++ b/drivers/arm/gic/v3/gicdv3_helpers.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include "gicv3_private.h"
+
+/*******************************************************************************
+ * GIC Distributor interface accessors for bit operations
+ ******************************************************************************/
+
+/*
+ * Accessor to read the GIC Distributor IGRPMODR corresponding to the
+ * interrupt `id`, 32 interrupt IDs at a time.
+ */
+uint32_t gicd_read_igrpmodr(uintptr_t base, unsigned int id)
+{
+	return GICD_READ(IGRPMODR, base, id);
+}
+
+/*
+ * Accessor to write the GIC Distributor IGRPMODR corresponding to the
+ * interrupt `id`, 32 interrupt IDs at a time.
+ */
+void gicd_write_igrpmodr(uintptr_t base, unsigned int id, uint32_t val)
+{
+	GICD_WRITE(IGRPMODR, base, id, val);
+}
+
+/*
+ * Accessor to get the bit corresponding to interrupt ID
+ * in GIC Distributor IGRPMODR.
+ */
+unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id)
+{
+	return GICD_GET_BIT(IGRPMODR, base, id);
+}
+
+/*
+ * Accessor to set the bit corresponding to interrupt ID
+ * in GIC Distributor IGRPMODR.
+ */
+void gicd_set_igrpmodr(uintptr_t base, unsigned int id)
+{
+	GICD_SET_BIT(IGRPMODR, base, id);
+}
+
+/*
+ * Accessor to clear the bit corresponding to interrupt ID
+ * in GIC Distributor IGRPMODR.
+ */
+void gicd_clr_igrpmodr(uintptr_t base, unsigned int id)
+{
+	GICD_CLR_BIT(IGRPMODR, base, id);
+}
diff --git a/drivers/arm/gic/v3/gicrv3_helpers.c b/drivers/arm/gic/v3/gicrv3_helpers.c
new file mode 100644
index 0000000..294acda
--- /dev/null
+++ b/drivers/arm/gic/v3/gicrv3_helpers.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv3.h>
+#include "gicv3_private.h"
+
+/*******************************************************************************
+ * GIC Redistributor functions
+ * Note: The raw register values correspond to multiple interrupt IDs and
+ * the number of interrupt IDs involved depends on the register accessed.
+ ******************************************************************************/
+
+/*
+ * Accessor to read the GIC Redistributor IPRIORITYR corresponding to the
+ * interrupt `id`, 4 interrupts IDs at a time.
+ */
+unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id)
+{
+	unsigned int n = id >> IPRIORITYR_SHIFT;
+
+	return mmio_read_32(base + GICR_IPRIORITYR + (n << 2));
+}
+
+/*
+ * Accessor to write the GIC Redistributor IPRIORITYR corresponding to the
+ * interrupt `id`, 4 interrupts IDs at a time.
+ */
+void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
+{
+	unsigned int n = id >> IPRIORITYR_SHIFT;
+
+	mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val);
+}
+
+/*
+ * Accessor to set the byte corresponding to interrupt ID
+ * in GIC Redistributor IPRIORITYR.
+ */
+void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
+{
+	GICR_WRITE_8(IPRIORITYR, base, id, pri & GIC_PRI_MASK);
+}
+
+/*
+ * Accessor to get the bit corresponding to interrupt ID
+ * from GIC Redistributor IGROUPR0.
+ */
+unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
+	unsigned int reg_val = gicr_read_igroupr0(base);
+
+	return (reg_val >> bit_num) & 0x1U;
+}
+
+/*
+ * Accessor to set the bit corresponding to interrupt ID
+ * in GIC Redistributor IGROUPR0.
+ */
+void gicr_set_igroupr0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
+	unsigned int reg_val = gicr_read_igroupr0(base);
+
+	gicr_write_igroupr0(base, reg_val | (1U << bit_num));
+}
+
+/*
+ * Accessor to clear the bit corresponding to interrupt ID
+ * in GIC Redistributor IGROUPR0.
+ */
+void gicr_clr_igroupr0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
+	unsigned int reg_val = gicr_read_igroupr0(base);
+
+	gicr_write_igroupr0(base, reg_val & ~(1U << bit_num));
+}
+
+/*
+ * Accessor to get the bit corresponding to interrupt ID
+ * from GIC Redistributor IGRPMODR0.
+ */
+unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
+	unsigned int reg_val = gicr_read_igrpmodr0(base);
+
+	return (reg_val >> bit_num) & 0x1U;
+}
+
+/*
+ * Accessor to set the bit corresponding to interrupt ID
+ * in GIC Redistributor IGRPMODR0.
+ */
+void gicr_set_igrpmodr0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
+	unsigned int reg_val = gicr_read_igrpmodr0(base);
+
+	gicr_write_igrpmodr0(base, reg_val | (1U << bit_num));
+}
+
+/*
+ * Accessor to clear the bit corresponding to interrupt ID
+ * in GIC Redistributor IGRPMODR0.
+ */
+void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
+	unsigned int reg_val = gicr_read_igrpmodr0(base);
+
+	gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num));
+}
+
+/*
+ * Accessor to set the bit corresponding to interrupt ID
+ * in GIC Redistributor ISENABLER0.
+ */
+void gicr_set_isenabler0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
+
+	gicr_write_isenabler0(base, (1U << bit_num));
+}
+
+/*
+ * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor
+ * ICENABLER0.
+ */
+void gicr_set_icenabler0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
+
+	gicr_write_icenabler0(base, (1U << bit_num));
+}
+
+/*
+ * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor
+ * ISACTIVER0.
+ */
+unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
+	unsigned int reg_val = gicr_read_isactiver0(base);
+
+	return (reg_val >> bit_num) & 0x1U;
+}
+
+/*
+ * Accessor to clear the bit corresponding to interrupt ID in GIC Redistributor
+ * ICPENDRR0.
+ */
+void gicr_set_icpendr0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
+
+	gicr_write_icpendr0(base, (1U << bit_num));
+}
+
+/*
+ * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor
+ * ISPENDR0.
+ */
+void gicr_set_ispendr0(uintptr_t base, unsigned int id)
+{
+	unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
+
+	gicr_write_ispendr0(base, (1U << bit_num));
+}
+
+/*
+ * Accessor to set the bit fields corresponding to interrupt ID
+ * in GIC Redistributor ICFGR0.
+ */
+void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg)
+{
+	/* Interrupt configuration is a 2-bit field */
+	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
+	unsigned int bit_shift = bit_num << 1U;
+
+	uint32_t reg_val = gicr_read_icfgr0(base);
+
+	/* Clear the field, and insert required configuration */
+	reg_val &= ~(GIC_CFG_MASK << bit_shift);
+	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
+
+	gicr_write_icfgr0(base, reg_val);
+}
+
+/*
+ * Accessor to set the bit fields corresponding to interrupt ID
+ * in GIC Redistributor ICFGR1.
+ */
+void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg)
+{
+	/* Interrupt configuration is a 2-bit field */
+	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
+	unsigned int bit_shift = bit_num << 1U;
+
+	uint32_t reg_val = gicr_read_icfgr1(base);
+
+	/* Clear the field, and insert required configuration */
+	reg_val &= ~(GIC_CFG_MASK << bit_shift);
+	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
+
+	gicr_write_icfgr1(base, reg_val);
+}
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index 710532e..d5aaf96 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -15,263 +15,6 @@
 #include "../common/gic_common_private.h"
 #include "gicv3_private.h"
 
-/*
- * Accessor to read the GIC Distributor IGRPMODR corresponding to the
- * interrupt `id`, 32 interrupt IDs at a time.
- */
-unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id)
-{
-	unsigned int n = id >> IGRPMODR_SHIFT;
-
-	return mmio_read_32(base + GICD_IGRPMODR + (n << 2));
-}
-
-/*
- * Accessor to write the GIC Distributor IGRPMODR corresponding to the
- * interrupt `id`, 32 interrupt IDs at a time.
- */
-void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val)
-{
-	unsigned int n = id >> IGRPMODR_SHIFT;
-
-	mmio_write_32(base + GICD_IGRPMODR + (n << 2), val);
-}
-
-/*
- * Accessor to get the bit corresponding to interrupt ID
- * in GIC Distributor IGRPMODR.
- */
-unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
-	unsigned int reg_val = gicd_read_igrpmodr(base, id);
-
-	return (reg_val >> bit_num) & 0x1U;
-}
-
-/*
- * Accessor to set the bit corresponding to interrupt ID
- * in GIC Distributor IGRPMODR.
- */
-void gicd_set_igrpmodr(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
-	unsigned int reg_val = gicd_read_igrpmodr(base, id);
-
-	gicd_write_igrpmodr(base, id, reg_val | (1U << bit_num));
-}
-
-/*
- * Accessor to clear the bit corresponding to interrupt ID
- * in GIC Distributor IGRPMODR.
- */
-void gicd_clr_igrpmodr(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
-	unsigned int reg_val = gicd_read_igrpmodr(base, id);
-
-	gicd_write_igrpmodr(base, id, reg_val & ~(1U << bit_num));
-}
-
-/*
- * Accessor to read the GIC Re-distributor IPRIORITYR corresponding to the
- * interrupt `id`, 4 interrupts IDs at a time.
- */
-unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id)
-{
-	unsigned int n = id >> IPRIORITYR_SHIFT;
-
-	return mmio_read_32(base + GICR_IPRIORITYR + (n << 2));
-}
-
-/*
- * Accessor to write the GIC Re-distributor IPRIORITYR corresponding to the
- * interrupt `id`, 4 interrupts IDs at a time.
- */
-void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
-{
-	unsigned int n = id >> IPRIORITYR_SHIFT;
-
-	mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val);
-}
-
-/*
- * Accessor to get the bit corresponding to interrupt ID
- * from GIC Re-distributor IGROUPR0.
- */
-unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
-	unsigned int reg_val = gicr_read_igroupr0(base);
-
-	return (reg_val >> bit_num) & 0x1U;
-}
-
-/*
- * Accessor to set the bit corresponding to interrupt ID
- * in GIC Re-distributor IGROUPR0.
- */
-void gicr_set_igroupr0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
-	unsigned int reg_val = gicr_read_igroupr0(base);
-
-	gicr_write_igroupr0(base, reg_val | (1U << bit_num));
-}
-
-/*
- * Accessor to clear the bit corresponding to interrupt ID
- * in GIC Re-distributor IGROUPR0.
- */
-void gicr_clr_igroupr0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
-	unsigned int reg_val = gicr_read_igroupr0(base);
-
-	gicr_write_igroupr0(base, reg_val & ~(1U << bit_num));
-}
-
-/*
- * Accessor to get the bit corresponding to interrupt ID
- * from GIC Re-distributor IGRPMODR0.
- */
-unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
-	unsigned int reg_val = gicr_read_igrpmodr0(base);
-
-	return (reg_val >> bit_num) & 0x1U;
-}
-
-/*
- * Accessor to set the bit corresponding to interrupt ID
- * in GIC Re-distributor IGRPMODR0.
- */
-void gicr_set_igrpmodr0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
-	unsigned int reg_val = gicr_read_igrpmodr0(base);
-
-	gicr_write_igrpmodr0(base, reg_val | (1U << bit_num));
-}
-
-/*
- * Accessor to clear the bit corresponding to interrupt ID
- * in GIC Re-distributor IGRPMODR0.
- */
-void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
-	unsigned int reg_val = gicr_read_igrpmodr0(base);
-
-	gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num));
-}
-
-/*
- * Accessor to set the bit corresponding to interrupt ID
- * in GIC Re-distributor ISENABLER0.
- */
-void gicr_set_isenabler0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
-
-	gicr_write_isenabler0(base, (1U << bit_num));
-}
-
-/*
- * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor
- * ICENABLER0.
- */
-void gicr_set_icenabler0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
-
-	gicr_write_icenabler0(base, (1U << bit_num));
-}
-
-/*
- * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor
- * ISACTIVER0.
- */
-unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
-	unsigned int reg_val = gicr_read_isactiver0(base);
-
-	return (reg_val >> bit_num) & 0x1U;
-}
-
-/*
- * Accessor to clear the bit corresponding to interrupt ID in GIC Re-distributor
- * ICPENDRR0.
- */
-void gicr_set_icpendr0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
-
-	gicr_write_icpendr0(base, (1U << bit_num));
-}
-
-/*
- * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor
- * ISPENDR0.
- */
-void gicr_set_ispendr0(uintptr_t base, unsigned int id)
-{
-	unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
-
-	gicr_write_ispendr0(base, (1U << bit_num));
-}
-
-/*
- * Accessor to set the byte corresponding to interrupt ID
- * in GIC Re-distributor IPRIORITYR.
- */
-void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
-{
-	uint8_t val = pri & GIC_PRI_MASK;
-
-	mmio_write_8(base + GICR_IPRIORITYR + id, val);
-}
-
-/*
- * Accessor to set the bit fields corresponding to interrupt ID
- * in GIC Re-distributor ICFGR0.
- */
-void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg)
-{
-	/* Interrupt configuration is a 2-bit field */
-	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
-	unsigned int bit_shift = bit_num << 1U;
-
-	uint32_t reg_val = gicr_read_icfgr0(base);
-
-	/* Clear the field, and insert required configuration */
-	reg_val &= ~(GIC_CFG_MASK << bit_shift);
-	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
-
-	gicr_write_icfgr0(base, reg_val);
-}
-
-/*
- * Accessor to set the bit fields corresponding to interrupt ID
- * in GIC Re-distributor ICFGR1.
- */
-void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg)
-{
-	/* Interrupt configuration is a 2-bit field */
-	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
-	unsigned int bit_shift = bit_num << 1U;
-
-	uint32_t reg_val = gicr_read_icfgr1(base);
-
-	/* Clear the field, and insert required configuration */
-	reg_val &= ~(GIC_CFG_MASK << bit_shift);
-	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
-
-	gicr_write_icfgr1(base, reg_val);
-}
-
 /******************************************************************************
  * This function marks the core as awake in the re-distributor and
  * ensures that the interface is active.
@@ -292,7 +35,6 @@
 		;
 }
 
-
 /******************************************************************************
  * This function marks the core as asleep in the re-distributor and ensures
  * that the interface is quiescent.
diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h
index 327a9a1..dae01cb 100644
--- a/drivers/arm/gic/v3/gicv3_private.h
+++ b/drivers/arm/gic/v3/gicv3_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,100 @@
 #define RWP_TRUE		U(1)
 #define RWP_FALSE		U(0)
 
+/* Calculate GIC register bit number corresponding to its interrupt ID */
+#define	BIT_NUM(REG, id)	\
+	((id) & ((1U << REG##_SHIFT) - 1U))
+
+/* Calculate 8-bit GICD register offset corresponding to its interrupt ID */
+#define	GICD_OFFSET_8(REG, id)	\
+	GICD_##REG + (id)
+
+/* Calculate 32-bit GICD register offset corresponding to its interrupt ID */
+#define	GICD_OFFSET(REG, id)	\
+	GICD_##REG + (((id) >> REG##_SHIFT) << 2)
+
+/* Calculate 64-bit GICD register offset corresponding to its interrupt ID */
+#define	GICD_OFFSET_64(REG, id)	\
+	GICD_##REG + (((id) >> REG##_SHIFT) << 3)
+
+/* Read 32-bit GIC Distributor register corresponding to its interrupt ID */
+#define GICD_READ(REG, base, id)	\
+	mmio_read_32((base) + GICD_OFFSET(REG, (id)))
+
+/* Read 64-bit GIC Distributor register corresponding to its interrupt ID */
+#define GICD_READ_64(REG, base, id)	\
+	mmio_read_64((base) + GICD_OFFSET_64(REG, (id)))
+
+/* Write to 64-bit GIC Distributor register corresponding to its interrupt ID */
+#define GICD_WRITE_64(REG, base, id, val)	\
+	mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val))
+
+/* Write to 32-bit GIC Distributor register corresponding to its interrupt ID */
+#define GICD_WRITE(REG, base, id, val)		\
+	mmio_write_32((base) + GICD_OFFSET(REG, (id)), (val))
+
+/* Write to 8-bit GIC Distributor register corresponding to its interrupt ID */
+#define GICD_WRITE_8(REG, base, id, val)	\
+	mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val))
+
+/*
+ * Bit operations on GIC Distributor register corresponding
+ * to its interrupt ID
+ */
+/* Get bit in GIC Distributor register */
+#define GICD_GET_BIT(REG, base, id)				\
+	((mmio_read_32((base) + GICD_OFFSET(REG, (id))) >>	\
+		BIT_NUM(REG, (id))) & 1U)
+
+/* Set bit in GIC Distributor register */
+#define GICD_SET_BIT(REG, base, id)				\
+	mmio_setbits_32((base) + GICD_OFFSET(REG, (id)),	\
+		((uint32_t)1 << BIT_NUM(REG, (id))))
+
+/* Clear bit in GIC Distributor register */
+#define GICD_CLR_BIT(REG, base, id)				\
+	mmio_clrbits_32((base) + GICD_OFFSET(REG, (id)),	\
+		((uint32_t)1 << BIT_NUM(REG, (id))))
+
+/* Write bit in GIC Distributor register */
+#define	GICD_WRITE_BIT(REG, base, id)				\
+	mmio_write_32((base) + GICD_OFFSET(REG, (id)),	\
+		((uint32_t)1 << BIT_NUM(REG, (id))))
+
+/*
+ * Calculate GICv3 GICR register offset
+ */
+#define GICR_OFFSET(REG, id)	\
+	GICR_##REG + (((id) >> REG##_SHIFT) << 2)
+
+/* Write to GIC Redistributor register corresponding to its interrupt ID */
+#define GICR_WRITE_8(REG, base, id, val)			\
+	mmio_write_8((base) + GICR_##REG + (id), (val))
+
+/*
+ * Bit operations on GIC Redistributor register
+ * corresponding to its interrupt ID
+ */
+/* Get bit in GIC Redistributor register */
+#define GICR_GET_BIT(REG, base, id)				\
+	((mmio_read_32((base) + GICR_OFFSET(REG, (id))) >>	\
+		BIT_NUM(REG, (id))) & 1U)
+
+/* Write bit in GIC Redistributor register */
+#define	GICR_WRITE_BIT(REG, base, id)				\
+	mmio_write_32((base) + GICR_OFFSET(REG, (id)),	\
+		((uint32_t)1 << BIT_NUM(REG, (id))))
+
+/* Set bit in GIC Redistributor register */
+#define	GICR_SET_BIT(REG, base, id)				\
+	mmio_setbits_32((base) + GICR_OFFSET(REG, (id)),	\
+		((uint32_t)1 << BIT_NUM(REG, (id))))
+
+/* Clear bit in GIC Redistributor register */
+#define	GICR_CLR_BIT(REG, base, id)				\
+	mmio_clrbits_32((base) + GICR_OFFSET(REG, (id)),	\
+		((uint32_t)1 << BIT_NUM(REG, (id))))
+
 /*
  * Macro to convert an mpidr to a value suitable for programming into a
  * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant
@@ -63,9 +157,9 @@
  * Note: The raw register values correspond to multiple interrupt IDs and
  * the number of interrupt IDs involved depends on the register accessed.
  ******************************************************************************/
-unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id);
+uint32_t gicd_read_igrpmodr(uintptr_t base, unsigned int id);
 unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id);
-void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val);
+void gicd_write_igrpmodr(uintptr_t base, unsigned int id, uint32_t val);
 void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val);
 
 /*******************************************************************************
@@ -121,27 +215,27 @@
  */
 static inline void gicd_wait_for_pending_write(uintptr_t gicd_base)
 {
-	while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U)
-		;
+	while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) {
+	}
 }
 
-static inline unsigned int gicd_read_pidr2(uintptr_t base)
+static inline uint32_t gicd_read_pidr2(uintptr_t base)
 {
 	return mmio_read_32(base + GICD_PIDR2_GICV3);
 }
 
-static inline unsigned long long gicd_read_irouter(uintptr_t base, unsigned int id)
+static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id)
 {
 	assert(id >= MIN_SPI_ID);
-	return mmio_read_64(base + GICD_IROUTER + (id << 3));
+	return GICD_READ_64(IROUTER, base, id);
 }
 
 static inline void gicd_write_irouter(uintptr_t base,
 				      unsigned int id,
-				      unsigned long long affinity)
+				      uint64_t affinity)
 {
 	assert(id >= MIN_SPI_ID);
-	mmio_write_64(base + GICD_IROUTER + (id << 3), affinity);
+	GICD_WRITE_64(IROUTER, base, id, affinity);
 }
 
 static inline void gicd_clr_ctlr(uintptr_t base,
@@ -149,8 +243,9 @@
 				 unsigned int rwp)
 {
 	gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap);
-	if (rwp != 0U)
+	if (rwp != 0U) {
 		gicd_wait_for_pending_write(base);
+	}
 }
 
 static inline void gicd_set_ctlr(uintptr_t base,
@@ -158,8 +253,9 @@
 				 unsigned int rwp)
 {
 	gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap);
-	if (rwp != 0U)
+	if (rwp != 0U) {
 		gicd_wait_for_pending_write(base);
+	}
 }
 
 /*******************************************************************************
@@ -175,17 +271,17 @@
 	mmio_write_32(base + GICR_CTLR, val);
 }
 
-static inline unsigned long long gicr_read_typer(uintptr_t base)
+static inline uint64_t gicr_read_typer(uintptr_t base)
 {
 	return mmio_read_64(base + GICR_TYPER);
 }
 
-static inline unsigned int gicr_read_waker(uintptr_t base)
+static inline uint32_t gicr_read_waker(uintptr_t base)
 {
 	return mmio_read_32(base + GICR_WAKER);
 }
 
-static inline void gicr_write_waker(uintptr_t base, unsigned int val)
+static inline void gicr_write_waker(uintptr_t base, uint32_t val)
 {
 	mmio_write_32(base + GICR_WAKER, val);
 }
@@ -199,14 +295,14 @@
  */
 static inline void gicr_wait_for_pending_write(uintptr_t gicr_base)
 {
-	while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U)
-		;
+	while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) {
+	}
 }
 
 static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base)
 {
-	while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U)
-		;
+	while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) {
+	}
 }
 
 /* Private implementation of Distributor power control hooks */
@@ -214,7 +310,7 @@
 void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num);
 
 /*******************************************************************************
- * GIC Re-distributor functions for accessing entire registers.
+ * GIC Redistributor functions for accessing entire registers.
  * Note: The raw register values correspond to multiple interrupt IDs and
  * the number of interrupt IDs involved depends on the register accessed.
  ******************************************************************************/
@@ -341,7 +437,7 @@
 	return mmio_read_32(base + GITS_CTLR);
 }
 
-static inline void gits_write_ctlr(uintptr_t base, unsigned int val)
+static inline void gits_write_ctlr(uintptr_t base, uint32_t val)
 {
 	mmio_write_32(base + GITS_CTLR, val);
 }
@@ -366,13 +462,15 @@
 	mmio_write_64(base + GITS_CWRITER, val);
 }
 
-static inline uint64_t gits_read_baser(uintptr_t base, unsigned int its_table_id)
+static inline uint64_t gits_read_baser(uintptr_t base,
+					unsigned int its_table_id)
 {
 	assert(its_table_id < 8U);
 	return mmio_read_64(base + GITS_BASER + (8U * its_table_id));
 }
 
-static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, uint64_t val)
+static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id,
+					uint64_t val)
 {
 	assert(its_table_id < 8U);
 	mmio_write_64(base + GITS_BASER + (8U * its_table_id), val);
@@ -384,9 +482,8 @@
 static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base)
 {
 	assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U);
-	while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U)
-		;
+	while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) {
+	}
 }
 
-
 #endif /* GICV3_PRIVATE_H */
diff --git a/include/arch/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S
index ea1636e..f75da0c 100644
--- a/include/arch/aarch32/asm_macros.S
+++ b/include/arch/aarch32/asm_macros.S
@@ -108,11 +108,16 @@
 #else
 	/*
 	 * Macro for mitigating against speculative execution beyond ERET.
+	 * If possible use Speculation Barrier instruction defined in ARMv8.5
 	 */
 	.macro exception_return
 	eret
+#if ARM_ARCH_AT_LEAST(8, 5)
+	sb
+#else
 	dsb	nsh
 	isb
+#endif
 	.endm
 #endif
 
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index b0c2650..2b2c116 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -452,6 +452,9 @@
 #define SPSR_M_AARCH64		U(0x0)
 #define SPSR_M_AARCH32		U(0x1)
 
+#define SPSR_EL_SHIFT		U(2)
+#define SPSR_EL_WIDTH		U(2)
+
 #define SPSR_SSBS_BIT_AARCH64	BIT_64(12)
 #define SPSR_SSBS_BIT_AARCH32	BIT_64(23)
 
@@ -557,6 +560,7 @@
 
 #define MODE_EL_SHIFT		U(0x2)
 #define MODE_EL_MASK		U(0x3)
+#define MODE_EL_WIDTH		U(0x2)
 #define MODE_EL3		U(0x3)
 #define MODE_EL2		U(0x2)
 #define MODE_EL1		U(0x1)
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index a7d5a3d..cbb9f0b 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -220,11 +220,16 @@
 
 	/*
 	 * Macro for mitigating against speculative execution beyond ERET.
+	 * If possible use Speculation Barrier instruction defined in ARMv8.5
 	 */
 	.macro exception_return
 	eret
-	dsb nsh
+#if ARM_ARCH_AT_LEAST(8, 5)
+	sb
+#else
+	dsb	nsh
 	isb
+#endif
 	.endm
 
 #endif /* ASM_MACROS_S */
diff --git a/include/bl32/payloads/tlk.h b/include/bl32/payloads/tlk.h
index ce8e3e8..fe6f352 100644
--- a/include/bl32/payloads/tlk.h
+++ b/include/bl32/payloads/tlk.h
@@ -27,6 +27,7 @@
 #define TLK_SYSTEM_SUSPEND	TLK_TOS_YIELD_FID(0xE001)
 #define TLK_SYSTEM_RESUME	TLK_TOS_YIELD_FID(0xE002)
 #define TLK_SYSTEM_OFF		TLK_TOS_YIELD_FID(0xE003)
+#define TLK_IRQ_FIRED		TLK_TOS_YIELD_FID(0xE004)
 
 /*
  * SMC function IDs that TLK uses to signal various forms of completions
@@ -39,6 +40,7 @@
 #define TLK_SUSPEND_DONE	(0x32000005 | (ULL(1) << 31))
 #define TLK_RESUME_DONE		(0x32000006 | (ULL(1) << 31))
 #define TLK_SYSTEM_OFF_DONE	(0x32000007 | (ULL(1) << 31))
+#define TLK_IRQ_DONE		(0x32000008 | (ULL(1) << 31))
 
 /*
  * Trusted Application specific function IDs
diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h
new file mode 100644
index 0000000..32c54b4
--- /dev/null
+++ b/include/common/bl_common.ld.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BL_COMMON_LD_H
+#define BL_COMMON_LD_H
+
+/*
+ * The xlat_table section is for full, aligned page tables (4K).
+ * Removing them from .bss avoids forcing 4K alignment on
+ * the .bss section. The tables are initialized to zero by the translation
+ * tables library.
+ */
+#define XLAT_TABLE_SECTION				\
+	xlat_table (NOLOAD) : {				\
+		*(xlat_table)				\
+	}
+
+#endif /* BL_COMMON_LD_H */
diff --git a/include/common/debug.h b/include/common/debug.h
index 245e698..9aef15b 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -91,6 +91,7 @@
 
 #if ENABLE_BACKTRACE
 void backtrace(const char *cookie);
+const char *get_el_str(unsigned int el);
 #else
 #define backtrace(x)
 #endif
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index c4f42d0..e6339bc 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,7 +32,7 @@
 #define GICD_SETSPI_NSR		U(0x40)
 #define GICD_CLRSPI_NSR		U(0x48)
 #define GICD_SETSPI_SR		U(0x50)
-#define GICD_CLRSPI_SR		U(0x50)
+#define GICD_CLRSPI_SR		U(0x58)
 #define GICD_IGRPMODR		U(0xd00)
 /*
  * GICD_IROUTER<n> register is at 0x6000 + 8n, where n is the interrupt id and
@@ -79,7 +79,7 @@
 #define NUM_OF_DIST_REGS	30
 
 /*******************************************************************************
- * GICv3 Re-distributor interface registers & constants
+ * GICv3 Redistributor interface registers & constants
  ******************************************************************************/
 #define GICR_PCPUBASE_SHIFT	0x11
 #define GICR_SGIBASE_OFFSET	U(65536)	/* 64 KB */
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index a80fab0..ab311f4 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -164,14 +164,20 @@
  *   Would typically be PLAT_VIRT_ADDR_SPACE_SIZE
  *   (resp. PLAT_PHY_ADDR_SPACE_SIZE) for the translation context describing the
  *   BL image currently executing.
+
+ * _base_table_section:
+ *   Specify the name of the section where the base translation tables have to
+ *   be placed by the linker.
  */
 #define REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \
-			_virt_addr_space_size, _phy_addr_space_size)	\
+			      _virt_addr_space_size, _phy_addr_space_size, \
+			      _base_table_section)			\
 	REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, (_mmap_count),	\
 					 (_xlat_tables_count),		\
 					 (_virt_addr_space_size),	\
 					 (_phy_addr_space_size),	\
-					 EL_REGIME_INVALID, "xlat_table")
+					 EL_REGIME_INVALID,		\
+					 "xlat_table", (_base_table_section))
 
 /*
  * Same as REGISTER_XLAT_CONTEXT plus the additional parameters:
@@ -191,7 +197,9 @@
 					 (_xlat_tables_count),		\
 					 (_virt_addr_space_size),	\
 					 (_phy_addr_space_size),	\
-					 (_xlat_regime), (_section_name))
+					 (_xlat_regime),		\
+					 (_section_name), ".bss"	\
+)
 
 /******************************************************************************
  * Generic translation table APIs.
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index c88fa4d..62f853d 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -24,6 +24,7 @@
 #include <platform_def.h>
 
 #include <lib/cassert.h>
+#include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_arch.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
@@ -135,7 +136,8 @@
 
 #define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count,		\
 			_xlat_tables_count, _virt_addr_space_size,	\
-			_phy_addr_space_size, _xlat_regime, _section_name)\
+			_phy_addr_space_size, _xlat_regime,		\
+			_table_section, _base_table_section)		\
 	CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size),	\
 		assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
 									\
@@ -143,52 +145,13 @@
 									\
 	static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count]	\
 		[XLAT_TABLE_ENTRIES]					\
-		__aligned(XLAT_TABLE_SIZE) __section(_section_name);	\
+		__aligned(XLAT_TABLE_SIZE) __section(_table_section);	\
 									\
 	static uint64_t _ctx_name##_base_xlat_table			\
 		[GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)]	\
 		__aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\
-			* sizeof(uint64_t));				\
-									\
-	XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
-									\
-	static xlat_ctx_t _ctx_name##_xlat_ctx = {			\
-		.pa_max_address = (_phy_addr_space_size) - 1ULL,	\
-		.va_max_address = (_virt_addr_space_size) - 1UL,	\
-		.mmap = _ctx_name##_mmap,				\
-		.mmap_num = (_mmap_count),				\
-		.tables = _ctx_name##_xlat_tables,			\
-		.tables_num = _xlat_tables_count,			\
-		 XLAT_CTX_INIT_TABLE_ATTR()				\
-		 XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name)			\
-		.next_table = 0,					\
-		.base_table = _ctx_name##_base_xlat_table,		\
-		.base_table_entries =					\
-			GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\
-		.max_pa = 0U,						\
-		.max_va = 0U,						\
-		.base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
-		.initialized = false,					\
-		.xlat_regime = (_xlat_regime)				\
-	}
-
-#define REGISTER_XLAT_CONTEXT_RO_BASE_TABLE(_ctx_name, _mmap_count,	\
-			_xlat_tables_count, _virt_addr_space_size,	\
-			_phy_addr_space_size, _xlat_regime, _section_name)\
-	CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size),	\
-		assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
-									\
-	static mmap_region_t _ctx_name##_mmap[_mmap_count + 1];		\
-									\
-	static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count]	\
-		[XLAT_TABLE_ENTRIES]					\
-		__aligned(XLAT_TABLE_SIZE) __section(_section_name);	\
-									\
-	static uint64_t _ctx_name##_base_xlat_table			\
-		[GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)]	\
-		__aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\
 			* sizeof(uint64_t))				\
-		__section(".rodata");					\
+		__section(_base_table_section);				\
 									\
 	XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
 									\
@@ -198,13 +161,13 @@
 		.mmap = _ctx_name##_mmap,				\
 		.mmap_num = (_mmap_count),				\
 		.tables = _ctx_name##_xlat_tables,			\
-		.tables_num = _xlat_tables_count,			\
+		.tables_num = ARRAY_SIZE(_ctx_name##_xlat_tables),	\
 		 XLAT_CTX_INIT_TABLE_ATTR()				\
 		 XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name)			\
 		.next_table = 0,					\
 		.base_table = _ctx_name##_base_xlat_table,		\
 		.base_table_entries =					\
-			GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\
+			ARRAY_SIZE(_ctx_name##_base_xlat_table),	\
 		.max_pa = 0U,						\
 		.max_va = 0U,						\
 		.base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h
index 7874882..71e6cfb 100644
--- a/include/services/spm_core_manifest.h
+++ b/include/services/spm_core_manifest.h
@@ -43,6 +43,11 @@
 	 */
 	uint32_t binary_size;
 
+	/*
+	 * ID of the SPMD (mandatory)
+	 */
+	uint16_t spmc_id;
+
 } spmc_manifest_sect_attribute_t;
 
 #endif /* SPMC_MANIFEST_H */
diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c
index caced8f..0605fce 100644
--- a/lib/locks/bakery/bakery_lock_normal.c
+++ b/lib/locks/bakery/bakery_lock_normal.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -77,6 +78,8 @@
 {
 	if (cached)
 		dccivac(addr);
+
+	dmbish();
 }
 
 /* Helper function to check if the lock is acquired */
diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c
index adca578..a1c974e 100644
--- a/lib/xlat_tables_v2/xlat_tables_context.c
+++ b/lib/xlat_tables_v2/xlat_tables_context.c
@@ -26,14 +26,15 @@
  * currently executing.
  */
 #if PLAT_RO_XLAT_TABLES
-REGISTER_XLAT_CONTEXT_RO_BASE_TABLE(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,
-		PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
-		EL_REGIME_INVALID, "xlat_table");
+#define BASE_XLAT_TABLE_SECTION		".rodata"
 #else
-REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,
-		PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE);
+#define BASE_XLAT_TABLE_SECTION		".bss"
 #endif
 
+REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,
+		      PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
+		      BASE_XLAT_TABLE_SECTION);
+
 void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, size_t size,
 		     unsigned int attr)
 {
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index e3651f5..38cbba9 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -16,8 +16,12 @@
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
-#include <tools_share/tbbr_oid.h>
 
+#if defined(ARM_COT_tbbr)
+#include <tools_share/tbbr_oid.h>
+#elif defined(ARM_COT_dualroot)
+#include <tools_share/dualroot_oid.h>
+#endif
 
 #if !ARM_CRYPTOCELL_INTEG
 #if !ARM_ROTPK_LOCATION_ID
@@ -108,10 +112,10 @@
 #endif
 
 /*
- * Wraper function for most Arm platforms to get ROTPK hash.
+ * Wrapper function for most Arm platforms to get ROTPK hash.
  */
-int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
-			unsigned int *flags)
+static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
+				unsigned int *flags)
 {
 #if ARM_CRYPTOCELL_INTEG
 	return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
@@ -125,10 +129,44 @@
 #else
 	return 1;
 #endif
-
 #endif /* ARM_CRYPTOCELL_INTEG */
 }
 
+#if defined(ARM_COT_tbbr)
+
+int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
+		       unsigned int *key_len, unsigned int *flags)
+{
+	return get_rotpk_info(key_ptr, key_len, flags);
+}
+
+#elif defined(ARM_COT_dualroot)
+
+int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+		       unsigned int *flags)
+{
+	/*
+	 * Return the right root of trust key hash based on the cookie value:
+	 *  - NULL means the primary ROTPK.
+	 *  - Otherwise, interpret cookie as the OID of the certificate
+	 *    extension containing the key.
+	 */
+	if (cookie == NULL) {
+		return get_rotpk_info(key_ptr, key_len, flags);
+	} else if (strcmp(cookie, PROT_PK_OID) == 0) {
+		extern unsigned char arm_protpk_hash[];
+		extern unsigned char arm_protpk_hash_end[];
+		*key_ptr = arm_protpk_hash;
+		*key_len = arm_protpk_hash_end - arm_protpk_hash;
+		*flags = ROTPK_IS_HASH;
+		return 0;
+	} else {
+		/* Invalid key ID. */
+		return 1;
+	}
+}
+#endif
+
 /*
  * Return the non-volatile counter value stored in the platform. The cookie
  * will contain the OID of the counter in the certificate.
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index c94a209..db3fb55 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -9,6 +9,7 @@
 	compatible = "spci-core-manifest-1.0";
 
 	attribute {
+		spmc_id = <0x8000>;
 		maj_ver = <0x0>;
 		min_ver = <0x9>;
 		exec_state = <0x0>;
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index e556204..4e20632 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -56,6 +56,8 @@
 FVP_GICV3_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				plat/common/plat_gicv3.c		\
 				plat/arm/common/arm_gicv3.c
 
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index cfac801..b446395 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -249,16 +249,12 @@
 #endif
 
 /*
- * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
- * SCP_BL2 size plus a little space for growth.
- */
-#define PLAT_CSS_MAX_SCP_BL2_SIZE	UL(0x14000)
-
-/*
- * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
- * SCP_BL2U size plus a little space for growth.
+ * SCP_BL2 uses up whatever remaining space is available as it is loaded before
+ * anything else in this memory region and is handed over to the SCP before
+ * BL31 is loaded over the top.
  */
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE	UL(0x14000)
+#define PLAT_CSS_MAX_SCP_BL2_SIZE	(SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT)
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE	PLAT_CSS_MAX_SCP_BL2_SIZE
 
 #define PLAT_ARM_G1S_IRQ_PROPS(grp) \
 	CSS_G1S_IRQ_PROPS(grp), \
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 8816670..5856c9f 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -18,6 +18,8 @@
 N1SDP_GIC_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/gic/v3/gic600_multichip.c	\
 				plat/common/plat_gicv3.c		\
 				plat/arm/common/arm_gicv3.c		\
@@ -63,6 +65,9 @@
 # When building for systems with hardware-assisted coherency, there's no need to
 # use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
 USE_COHERENT_MEM			:=	0
+
+# Enable the flag since N1SDP has a system level cache
+NEOVERSE_N1_EXTERNAL_LLC		:=	1
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
 include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h
index 790ed69..a118ca3 100644
--- a/plat/arm/board/rddaniel/include/platform_def.h
+++ b/plat/arm/board/rddaniel/include/platform_def.h
@@ -32,9 +32,19 @@
 					 (n * TZC400_OFFSET))
 
 #define TZC_NSAID_ALL_AP		U(0)
+#define TZC_NSAID_PCI			U(1)
+#define TZC_NSAID_HDLCD0		U(2)
+#define TZC_NSAID_CLCD			U(7)
+#define TZC_NSAID_AP			U(9)
+#define TZC_NSAID_VIRTIO		U(15)
 
 #define PLAT_ARM_TZC_NS_DEV_ACCESS	\
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP))
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI))    | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP))     | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD))   | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
 
 /*
  * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 40a7fd8..ea5a563 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -25,6 +25,8 @@
 ENT_GIC_SOURCES		:=	drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				plat/common/plat_gicv3.c		\
 				plat/arm/common/arm_gicv3.c		\
 				drivers/arm/gic/v3/gic600.c
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
index 90511ac..0ac0c2b 100644
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -133,16 +133,12 @@
 #endif
 
 /*
- * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
- * SCP_BL2 size plus a little space for growth.
- */
-#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x15000
-
-/*
- * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
- * SCP_BL2U size plus a little space for growth.
+ * SCP_BL2 uses up whatever remaining space is available as it is loaded before
+ * anything else in this memory region and is handed over to the SCP before
+ * BL31 is loaded over the top.
  */
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x15000
+#define PLAT_CSS_MAX_SCP_BL2_SIZE	(SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT)
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE	PLAT_CSS_MAX_SCP_BL2_SIZE
 
 /*
  * Most platform porting definitions provided by included headers
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
index ac34450..49fc717 100644
--- a/plat/arm/css/sgm/sgm-common.mk
+++ b/plat/arm/css/sgm/sgm-common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -25,6 +25,8 @@
 SGM_GIC_SOURCES		:=	drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				plat/common/plat_gicv3.c		\
 				plat/arm/common/arm_gicv3.c		\
 				drivers/arm/gic/v3/gic600.c		\
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index f8d3129..63871d9 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -64,6 +64,18 @@
 }
 #endif
 
+#if !ENABLE_BACKTRACE
+static const char *get_el_str(unsigned int el)
+{
+	if (el == MODE_EL3) {
+		return "EL3";
+	} else if (el == MODE_EL2) {
+		return "EL2";
+	}
+	return "S-EL1";
+}
+#endif /* !ENABLE_BACKTRACE */
+
 /* RAS functions common to AArch64 ARM platforms */
 void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
 		void *handle, uint64_t flags)
@@ -74,9 +86,17 @@
 	if (handled != 0)
 		return;
 #endif
+	unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
 
-	ERROR("Unhandled External Abort received on 0x%lx at EL3!\n",
-			read_mpidr_el1());
-	ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome);
+	ERROR("Unhandled External Abort received on 0x%lx from %s\n",
+		read_mpidr_el1(), get_el_str(level));
+	ERROR("exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome);
+#if HANDLE_EA_EL3_FIRST
+	/* Skip backtrace for lower EL */
+	if (level != MODE_EL3) {
+		(void)console_flush();
+		do_panic();
+	}
+#endif
 	panic();
 }
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index 9c3dc71..f0aa27c 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -37,6 +37,12 @@
 		return -ENOENT;
 	}
 
+	rc = fdtw_read_cells(fdt, node, "spmc_id", 1, &attr->spmc_id);
+	if (rc) {
+		ERROR("Missing SPMC ID in manifest.\n");
+		return -ENOENT;
+	}
+
 	rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state);
 	if (rc)
 		NOTICE("Execution state not specified in SPM core manifest.\n");
@@ -55,6 +61,7 @@
 
 	VERBOSE("SPM core manifest attribute section:\n");
 	VERBOSE("  version: %x.%x\n", attr->major_version, attr->minor_version);
+	VERBOSE("  spmc_id: %x\n", attr->spmc_id);
 	VERBOSE("  binary_size: 0x%x\n", attr->binary_size);
 	VERBOSE("  load_address: 0x%llx\n", attr->load_address);
 	VERBOSE("  entrypoint: 0x%llx\n", attr->entrypoint);
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index d3b4e4f..f5f8ffe 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -166,6 +166,7 @@
 
 	hikey960_edma_init();
 	hikey960_iomcu_dma_init();
+	hikey960_gpio_init();
 
 	hisi_ipc_init();
 }
diff --git a/plat/hisilicon/hikey960/hikey960_bl_common.c b/plat/hisilicon/hikey960/hikey960_bl_common.c
index 89adccb..3c4a164 100644
--- a/plat/hisilicon/hikey960/hikey960_bl_common.c
+++ b/plat/hisilicon/hikey960/hikey960_bl_common.c
@@ -466,6 +466,13 @@
 	pl061_gpio_register(GPIO19_BASE, 19);
 	pl061_gpio_register(GPIO20_BASE, 20);
 	pl061_gpio_register(GPIO21_BASE, 21);
+	pl061_gpio_register(GPIO22_BASE, 22);
+	pl061_gpio_register(GPIO23_BASE, 23);
+	pl061_gpio_register(GPIO24_BASE, 24);
+	pl061_gpio_register(GPIO25_BASE, 25);
+	pl061_gpio_register(GPIO26_BASE, 26);
+	pl061_gpio_register(GPIO27_BASE, 27);
+	pl061_gpio_register(GPIO28_BASE, 28);
 
 	/* PCIE_PERST_N output low */
 	gpio_set_direction(89, GPIO_DIR_OUT);
diff --git a/plat/hisilicon/hikey960/hikey960_pm.c b/plat/hisilicon/hikey960/hikey960_pm.c
index 9f96fc3..f836508 100644
--- a/plat/hisilicon/hikey960/hikey960_pm.c
+++ b/plat/hisilicon/hikey960/hikey960_pm.c
@@ -11,6 +11,7 @@
 #include <drivers/arm/cci.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/pl011.h>
+#include <drivers/arm/pl061_gpio.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
@@ -116,6 +117,13 @@
 	}
 }
 
+static void __dead2 hikey960_system_off(void)
+{
+	gpio_set_direction(176, GPIO_DIR_OUT);
+	gpio_set_value(176, GPIO_LEVEL_LOW);
+	panic();
+}
+
 static void __dead2 hikey960_system_reset(void)
 {
 	dsb();
@@ -293,7 +301,7 @@
 	.pwr_domain_off			= hikey960_pwr_domain_off,
 	.pwr_domain_suspend		= hikey960_pwr_domain_suspend,
 	.pwr_domain_suspend_finish	= hikey960_pwr_domain_suspend_finish,
-	.system_off			= NULL,
+	.system_off			= hikey960_system_off,
 	.system_reset			= hikey960_system_reset,
 	.validate_power_state		= hikey960_validate_power_state,
 	.validate_ns_entrypoint		= hikey960_validate_ns_entrypoint,
diff --git a/plat/hisilicon/hikey960/include/hi3660.h b/plat/hisilicon/hikey960/include/hi3660.h
index 7cc1ee0..17b495f 100644
--- a/plat/hisilicon/hikey960/include/hi3660.h
+++ b/plat/hisilicon/hikey960/include/hi3660.h
@@ -260,6 +260,13 @@
 #define GPIO17_BASE			UL(0xE8A1C000)
 #define GPIO20_BASE			UL(0xE8A1F000)
 #define GPIO21_BASE			UL(0xE8A20000)
+#define GPIO22_BASE			UL(0xFFF0B000)
+#define GPIO23_BASE			UL(0xFFF0C000)
+#define GPIO24_BASE			UL(0xFFF0D000)
+#define GPIO25_BASE			UL(0xFFF0E000)
+#define GPIO26_BASE			UL(0xFFF0F000)
+#define GPIO27_BASE			UL(0xFFF10000)
+#define GPIO28_BASE			UL(0xFFF1D000)
 
 #define TZC_REG_BASE			0xE8A21000
 #define TZC_STAT0_REG			(TZC_REG_BASE + 0x800)
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index 6cb53c7..8ebabeb 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -19,7 +19,7 @@
 
 CRASH_CONSOLE_BASE		:=	PL011_UART6_BASE
 COLD_BOOT_SINGLE_CPU		:=	1
-PLAT_PL061_MAX_GPIOS		:=	176
+PLAT_PL061_MAX_GPIOS		:=	232
 PROGRAMMABLE_RESET_ADDRESS	:=	1
 ENABLE_SVE_FOR_NS		:=	0
 PLAT_PARTITION_BLOCK_SIZE	:=	4096
@@ -95,12 +95,15 @@
 endif
 
 BL31_SOURCES		+=	drivers/arm/cci/cci.c			\
+				drivers/arm/pl061/pl061_gpio.c		\
+				drivers/gpio/gpio.c			\
 				lib/cpus/aarch64/cortex_a53.S           \
 				lib/cpus/aarch64/cortex_a72.S		\
 				lib/cpus/aarch64/cortex_a73.S		\
 				plat/common/plat_psci_common.c  \
 				plat/hisilicon/hikey960/aarch64/hikey960_helpers.S \
 				plat/hisilicon/hikey960/hikey960_bl31_setup.c \
+				plat/hisilicon/hikey960/hikey960_bl_common.c \
 				plat/hisilicon/hikey960/hikey960_pm.c	\
 				plat/hisilicon/hikey960/hikey960_topology.c \
 				plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c \
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 56caab7..f25ceb0 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -47,7 +47,6 @@
 
 #define HAB_RVT_BASE			U(0x00000900) /* HAB_RVT for i.MX8MM */
 
-#define IMX_BOOT_UART_BASE		U(0x30890000)
 #define IMX_BOOT_UART_CLK_IN_HZ		24000000 /* Select 24MHz oscillator */
 
 #define PLAT_CRASH_UART_BASE		IMX_BOOT_UART_BASE
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index c0cb6c2..5fa3003 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,6 +9,8 @@
 				-Iplat/imx/imx8m/imx8mm/include
 
 IMX_GIC_SOURCES		:=	drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/gic/v3/arm_gicv3_common.c   \
 				drivers/arm/gic/v3/gic500.c             \
 				drivers/arm/gic/v3/gicv3_main.c		\
@@ -51,3 +53,6 @@
 
 BL32_SIZE		?=	0x2000000
 $(eval $(call add_define,BL32_SIZE))
+
+IMX_BOOT_UART_BASE	?=	0x30890000
+$(eval $(call add_define,IMX_BOOT_UART_BASE))
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 80ebe40..e419f05 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,6 +9,8 @@
 				-Iplat/imx/imx8m/imx8mq/include
 
 IMX_GIC_SOURCES		:=	drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/gic/v3/arm_gicv3_common.c   \
 				drivers/arm/gic/v3/gic500.c             \
 				drivers/arm/gic/v3/gicv3_main.c		\
diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk
index 3a772e5..5ba9c3f 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,6 +8,8 @@
 				-Iplat/imx/common/include		\
 
 IMX_GIC_SOURCES	:=		drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/gic/v3/arm_gicv3_common.c   \
 				drivers/arm/gic/v3/gic500.c             \
 				drivers/arm/gic/v3/gicv3_main.c		\
diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk
index d5629d1..5e8ba06 100644
--- a/plat/imx/imx8qx/platform.mk
+++ b/plat/imx/imx8qx/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,6 +8,8 @@
 				-Iplat/imx/common/include		\
 
 IMX_GIC_SOURCES	:=		drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/gic/v3/arm_gicv3_common.c	\
 				drivers/arm/gic/v3/gic500.c		\
 				drivers/arm/gic/v3/gicv3_main.c		\
diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk
index 1e27567..fd2b7ed 100644
--- a/plat/marvell/a3700/common/a3700_common.mk
+++ b/plat/marvell/a3700/common/a3700_common.mk
@@ -81,6 +81,8 @@
 MARVELL_GIC_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/gic/v3/arm_gicv3_common.c	\
 				plat/common/plat_gicv3.c		\
 				drivers/arm/gic/v3/gic500.c
diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S
index cf68b71..0fd3866 100644
--- a/plat/mediatek/mt6795/bl31.ld.S
+++ b/plat/mediatek/mt6795/bl31.ld.S
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/bl_common.ld.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 #include <platform_def.h>
 
@@ -131,15 +132,7 @@
 
     ASSERT(. <= BL31_LIMIT, "BL3-1 image has exceeded its limit.")
 
-    /*
-     * The xlat_table section is for full, aligned page tables (4K).
-     * Removing them from .bss avoids forcing 4K alignment on
-     * the .bss section. The tables are initialized to zero by the translation
-     * tables library.
-     */
-    xlat_table (NOLOAD) : {
-        *(xlat_table)
-    } >RAM2
+    XLAT_TABLE_SECTION >RAM2
 
 #if USE_COHERENT_MEM
     /*
diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk
index 597e18b..59ffe5d 100644
--- a/plat/mediatek/mt8183/platform.mk
+++ b/plat/mediatek/mt8183/platform.mk
@@ -31,6 +31,8 @@
                    drivers/arm/gic/common/gic_common.c                   \
                    drivers/arm/gic/v3/arm_gicv3_common.c                 \
                    drivers/arm/gic/v3/gicv3_helpers.c                    \
+                   drivers/arm/gic/v3/gicdv3_helpers.c			 \
+                   drivers/arm/gic/v3/gicrv3_helpers.c			 \
                    drivers/arm/gic/v3/gic500.c                           \
                    drivers/arm/gic/v3/gicv3_main.c                       \
                    drivers/delay_timer/delay_timer.c                     \
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index c2ef981..a53f660 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -21,6 +21,7 @@
 #include <smmu.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
+#include <tegra_private.h>
 
 /* Video Memory base and size (live values) */
 static uint64_t video_mem_base;
@@ -223,6 +224,58 @@
 	mce_update_gsc_tzram();
 }
 
+/*
+ * Save MC settings before "System Suspend" to TZDRAM
+ */
+void tegra_mc_save_context(uint64_t mc_ctx_addr)
+{
+	const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+	uint32_t i, num_entries = 0;
+	mc_regs_t *mc_ctx_regs;
+	const 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;
+
+	assert((mc_ctx_addr >= tzdram_base) && (mc_ctx_addr <= tzdram_end));
+
+	/* get MC context table */
+	mc_ctx_regs = plat_mc_settings->get_mc_system_suspend_ctx();
+	assert(mc_ctx_regs != NULL);
+
+	/*
+	 * mc_ctx_regs[0].val contains the size of the context table minus
+	 * the last entry. Sanity check the table size before we start with
+	 * the context save operation.
+	 */
+	while (mc_ctx_regs[num_entries].reg != 0xFFFFFFFFU) {
+		num_entries++;
+	}
+
+	/* panic if the sizes do not match */
+	if (num_entries != mc_ctx_regs[0].val) {
+		ERROR("MC context size mismatch!");
+		panic();
+	}
+
+	/* save MC register values */
+	for (i = 1U; i < num_entries; i++) {
+		mc_ctx_regs[i].val = mmio_read_32(mc_ctx_regs[i].reg);
+	}
+
+	/* increment by 1 to take care of the last entry */
+	num_entries++;
+
+	/* Save MC config settings */
+	(void)memcpy((void *)mc_ctx_addr, mc_ctx_regs,
+			sizeof(mc_regs_t) * num_entries);
+
+	/* save the MC table address */
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO,
+		(uint32_t)mc_ctx_addr);
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI,
+		(uint32_t)(mc_ctx_addr >> 32));
+}
+
 static void tegra_lock_videomem_nonoverlap(uint64_t phys_base,
 					   uint64_t size_in_bytes)
 {
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
index 8c1b899..a4a4354 100644
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,121 +18,8 @@
 
 extern void memcpy16(void *dest, const void *src, unsigned int length);
 
-/* SMMU IDs currently supported by the driver */
-enum {
-	TEGRA_SMMU0 = 0U,
-	TEGRA_SMMU1,
-	TEGRA_SMMU2
-};
-
-static uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off)
-{
-	uint32_t ret = 0U;
-
-#if defined(TEGRA_SMMU0_BASE)
-	if (smmu_id == TEGRA_SMMU0) {
-		ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off);
-	}
-#endif
-
-#if defined(TEGRA_SMMU1_BASE)
-	if (smmu_id == TEGRA_SMMU1) {
-		ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off);
-	}
-#endif
-
-#if defined(TEGRA_SMMU2_BASE)
-	if (smmu_id == TEGRA_SMMU2) {
-		ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off);
-	}
-#endif
-
-	return ret;
-}
-
-static void tegra_smmu_write_32(uint32_t smmu_id,
-			uint32_t off, uint32_t val)
-{
-#if defined(TEGRA_SMMU0_BASE)
-	if (smmu_id == TEGRA_SMMU0) {
-		mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val);
-	}
-#endif
-
-#if defined(TEGRA_SMMU1_BASE)
-	if (smmu_id == TEGRA_SMMU1) {
-		mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val);
-	}
-#endif
-
-#if defined(TEGRA_SMMU2_BASE)
-	if (smmu_id == TEGRA_SMMU2) {
-		mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val);
-	}
-#endif
-}
-
-/*
- * Save SMMU settings before "System Suspend" to TZDRAM
- */
-void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
-{
-	uint32_t i, num_entries = 0;
-	smmu_regs_t *smmu_ctx_regs;
-	const 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;
-	uint32_t reg_id1, pgshift, cb_size;
-
-	/* sanity check SMMU settings c*/
-	reg_id1 = mmio_read_32((TEGRA_SMMU0_BASE + SMMU_GNSR0_IDR1));
-	pgshift = ((reg_id1 & ID1_PAGESIZE) != 0U) ? 16U : 12U;
-	cb_size = ((uint32_t)2 << pgshift) * \
-	((uint32_t)1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1U));
-
-	assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE)));
-	assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end));
-
-	/* get SMMU context table */
-	smmu_ctx_regs = plat_get_smmu_ctx();
-	assert(smmu_ctx_regs != NULL);
-
-	/*
-	 * smmu_ctx_regs[0].val contains the size of the context table minus
-	 * the last entry. Sanity check the table size before we start with
-	 * the context save operation.
-	 */
-	while ((smmu_ctx_regs[num_entries].reg != 0xFFFFFFFFU)) {
-		num_entries++;
-	}
-
-	/* panic if the sizes do not match */
-	if (num_entries != smmu_ctx_regs[0].val) {
-		ERROR("SMMU context size mismatch!");
-		panic();
-	}
-
-	/* save SMMU register values */
-	for (i = 1U; i < num_entries; i++) {
-		smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg);
-	}
-
-	/* increment by 1 to take care of the last entry */
-	num_entries++;
-
-	/* Save SMMU config settings */
-	(void)memcpy16((uint8_t *)smmu_ctx_addr, (uint8_t *)smmu_ctx_regs,
-			(sizeof(smmu_regs_t) * num_entries));
-
-	/* save the SMMU table address */
-	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_LO,
-		(uint32_t)smmu_ctx_addr);
-	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_HI,
-		(uint32_t)(smmu_ctx_addr >> 32));
-}
-
-#define SMMU_NUM_CONTEXTS		64
-#define SMMU_CONTEXT_BANK_MAX_IDX	64
+#define SMMU_NUM_CONTEXTS		64U
+#define SMMU_CONTEXT_BANK_MAX_IDX	64U
 
 /*
  * Init SMMU during boot or "System Suspend" exit
diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
index a0d02c9..401a07a 100644
--- a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
+++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
@@ -19,11 +19,6 @@
 #define TEGRA_RESET_ID_GPCDMA		U(70)
 
 /**
- * Clock identifier for the SE device
- */
-#define TEGRA_CLK_SE        U(124)
-
-/**
  * Function to initialise the IPC with the bpmp
  */
 int32_t tegra_bpmp_ipc_init(void);
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index a4085e2..509fe32 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -84,6 +84,41 @@
 		.override_enable = OVERRIDE_ ## access \
 	}
 
+typedef struct mc_regs {
+	uint32_t reg;
+	uint32_t val;
+} mc_regs_t;
+
+#define mc_make_sid_override_cfg(name) \
+	{ \
+		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \
+		.val = 0x00000000U, \
+	}
+
+#define mc_make_sid_security_cfg(name) \
+	{ \
+		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \
+		.val = 0x00000000U, \
+	}
+
+#define mc_smmu_bypass_cfg \
+	{ \
+		.reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \
+		.val = 0x00000000U, \
+	}
+
+#define _START_OF_TABLE_ \
+	{ \
+		.reg = 0xCAFE05C7U, \
+		.val = 0x00000000U, \
+	}
+
+#define _END_OF_TABLE_ \
+	{ \
+		.reg = 0xFFFFFFFFU, \
+		.val = 0xFFFFFFFFU, \
+	}
+
 /*******************************************************************************
  * Structure to hold Memory Controller's Configuration settings
  ******************************************************************************/
@@ -96,6 +131,7 @@
 	uint32_t num_txn_override_cfgs;
 	void (*reconfig_mss_clients)(void);
 	void (*set_txn_overrides)(void);
+	mc_regs_t* (*get_mc_system_suspend_ctx)(void);
 } tegra_mc_settings_t;
 
 static inline uint32_t tegra_mc_read_32(uint32_t off)
@@ -166,6 +202,13 @@
 tegra_mc_settings_t *tegra_get_mc_settings(void);
 
 /*******************************************************************************
+ * Handler to save MC settings before "System Suspend" to TZDRAM
+ *
+ * Implemented by Tegra common memctrl_v2 driver under common/drivers/memctrl
+ ******************************************************************************/
+void tegra_mc_save_context(uint64_t mc_ctx_addr);
+
+/*******************************************************************************
  * Handler to program the scratch registers with TZDRAM settings for the
  * resume firmware.
  *
diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h
index 424a91a..601864f 100644
--- a/plat/nvidia/tegra/include/drivers/smmu.h
+++ b/plat/nvidia/tegra/include/drivers/smmu.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,566 +13,7 @@
 #include <memctrl_v2.h>
 #include <tegra_def.h>
 
-/*******************************************************************************
- * SMMU Register constants
- ******************************************************************************/
-#define SMMU_CBn_SCTLR				(0x0U)
-#define SMMU_CBn_SCTLR_STAGE2			(0x0U)
 #define SMMU_CBn_ACTLR				(0x4U)
-#define SMMU_CBn_RESUME				(0x8U)
-#define SMMU_CBn_TCR2				(0x10U)
-#define SMMU_CBn_TTBR0_LO			(0x20U)
-#define SMMU_CBn_TTBR0_HI			(0x24U)
-#define SMMU_CBn_TTBR1_LO			(0x28U)
-#define SMMU_CBn_TTBR1_HI			(0x2cU)
-#define SMMU_CBn_TCR_LPAE			(0x30U)
-#define SMMU_CBn_TCR				(0x30U)
-#define SMMU_CBn_TCR_EAE_1			(0x30U)
-#define SMMU_CBn_TCR				(0x30U)
-#define SMMU_CBn_CONTEXTIDR			(0x34U)
-#define SMMU_CBn_CONTEXTIDR_EAE_1		(0x34U)
-#define SMMU_CBn_PRRR_MAIR0			(0x38U)
-#define SMMU_CBn_NMRR_MAIR1			(0x3cU)
-#define SMMU_CBn_SMMU_CBn_PAR			(0x50U)
-#define SMMU_CBn_SMMU_CBn_PAR0			(0x50U)
-#define SMMU_CBn_SMMU_CBn_PAR1			(0x54U)
-/*      SMMU_CBn_SMMU_CBn_PAR0_Fault		(0x50U) */
-/*      SMMU_CBn_SMMU_CBn_PAR0_Fault		(0x54U) */
-#define SMMU_CBn_FSR				(0x58U)
-#define SMMU_CBn_FSRRESTORE			(0x5cU)
-#define SMMU_CBn_FAR_LO				(0x60U)
-#define SMMU_CBn_FAR_HI				(0x64U)
-#define SMMU_CBn_FSYNR0				(0x68U)
-#define SMMU_CBn_IPAFAR_LO			(0x70U)
-#define SMMU_CBn_IPAFAR_HI			(0x74U)
-#define SMMU_CBn_TLBIVA_LO			(0x600U)
-#define SMMU_CBn_TLBIVA_HI			(0x604U)
-#define SMMU_CBn_TLBIVA_AARCH_32		(0x600U)
-#define SMMU_CBn_TLBIVAA_LO			(0x608U)
-#define SMMU_CBn_TLBIVAA_HI			(0x60cU)
-#define SMMU_CBn_TLBIVAA_AARCH_32		(0x608U)
-#define SMMU_CBn_TLBIASID			(0x610U)
-#define SMMU_CBn_TLBIALL			(0x618U)
-#define SMMU_CBn_TLBIVAL_LO			(0x620U)
-#define SMMU_CBn_TLBIVAL_HI			(0x624U)
-#define SMMU_CBn_TLBIVAL_AARCH_32		(0x618U)
-#define SMMU_CBn_TLBIVAAL_LO			(0x628U)
-#define SMMU_CBn_TLBIVAAL_HI			(0x62cU)
-#define SMMU_CBn_TLBIVAAL_AARCH_32		(0x628U)
-#define SMMU_CBn_TLBIIPAS2_LO			(0x630U)
-#define SMMU_CBn_TLBIIPAS2_HI			(0x634U)
-#define SMMU_CBn_TLBIIPAS2L_LO			(0x638U)
-#define SMMU_CBn_TLBIIPAS2L_HI			(0x63cU)
-#define SMMU_CBn_TLBSYNC			(0x7f0U)
-#define SMMU_CBn_TLBSTATUS			(0x7f4U)
-#define SMMU_CBn_ATSR				(0x800U)
-#define SMMU_CBn_PMEVCNTR0			(0xe00U)
-#define SMMU_CBn_PMEVCNTR1			(0xe04U)
-#define SMMU_CBn_PMEVCNTR2			(0xe08U)
-#define SMMU_CBn_PMEVCNTR3			(0xe0cU)
-#define SMMU_CBn_PMEVTYPER0			(0xe80U)
-#define SMMU_CBn_PMEVTYPER1			(0xe84U)
-#define SMMU_CBn_PMEVTYPER2			(0xe88U)
-#define SMMU_CBn_PMEVTYPER3			(0xe8cU)
-#define SMMU_CBn_PMCFGR				(0xf00U)
-#define SMMU_CBn_PMCR				(0xf04U)
-#define SMMU_CBn_PMCEID				(0xf20U)
-#define SMMU_CBn_PMCNTENSE			(0xf40U)
-#define SMMU_CBn_PMCNTENCLR			(0xf44U)
-#define SMMU_CBn_PMCNTENSET			(0xf48U)
-#define SMMU_CBn_PMINTENCLR			(0xf4cU)
-#define SMMU_CBn_PMOVSCLR			(0xf50U)
-#define SMMU_CBn_PMOVSSET			(0xf58U)
-#define SMMU_CBn_PMAUTHSTATUS			(0xfb8U)
-#define SMMU_GNSR0_CR0				(0x0U)
-#define SMMU_GNSR0_CR2				(0x8U)
-#define SMMU_GNSR0_ACR				(0x10U)
-#define SMMU_GNSR0_IDR0				(0x20U)
-#define SMMU_GNSR0_IDR1				(0x24U)
-#define SMMU_GNSR0_IDR2				(0x28U)
-#define SMMU_GNSR0_IDR7				(0x3cU)
-#define SMMU_GNSR0_GFAR_LO			(0x40U)
-#define SMMU_GNSR0_GFAR_HI			(0x44U)
-#define SMMU_GNSR0_GFSR				(0x48U)
-#define SMMU_GNSR0_GFSRRESTORE			(0x4cU)
-#define SMMU_GNSR0_GFSYNR0			(0x50U)
-#define SMMU_GNSR0_GFSYNR1			(0x54U)
-#define SMMU_GNSR0_GFSYNR1_v2			(0x54U)
-#define SMMU_GNSR0_TLBIVMID			(0x64U)
-#define SMMU_GNSR0_TLBIALLNSNH			(0x68U)
-#define SMMU_GNSR0_TLBIALLH			(0x6cU)
-#define SMMU_GNSR0_TLBGSYNC			(0x70U)
-#define SMMU_GNSR0_TLBGSTATUS			(0x74U)
-#define SMMU_GNSR0_TLBIVAH_LO			(0x78U)
-#define SMMU_GNSR0_TLBIVALH64_LO		(0xb0U)
-#define SMMU_GNSR0_TLBIVALH64_HI		(0xb4U)
-#define SMMU_GNSR0_TLBIVMIDS1			(0xb8U)
-#define SMMU_GNSR0_TLBIVAH64_LO			(0xc0U)
-#define SMMU_GNSR0_TLBIVAH64_HI			(0xc4U)
-#define SMMU_GNSR0_SMR0				(0x800U)
-#define SMMU_GNSR0_SMRn				(0x800U)
-#define SMMU_GNSR0_SMR1				(0x804U)
-#define SMMU_GNSR0_SMR2				(0x808U)
-#define SMMU_GNSR0_SMR3				(0x80cU)
-#define SMMU_GNSR0_SMR4				(0x810U)
-#define SMMU_GNSR0_SMR5				(0x814U)
-#define SMMU_GNSR0_SMR6				(0x818U)
-#define SMMU_GNSR0_SMR7				(0x81cU)
-#define SMMU_GNSR0_SMR8				(0x820U)
-#define SMMU_GNSR0_SMR9				(0x824U)
-#define SMMU_GNSR0_SMR10			(0x828U)
-#define SMMU_GNSR0_SMR11			(0x82cU)
-#define SMMU_GNSR0_SMR12			(0x830U)
-#define SMMU_GNSR0_SMR13			(0x834U)
-#define SMMU_GNSR0_SMR14			(0x838U)
-#define SMMU_GNSR0_SMR15			(0x83cU)
-#define SMMU_GNSR0_SMR16			(0x840U)
-#define SMMU_GNSR0_SMR17			(0x844U)
-#define SMMU_GNSR0_SMR18			(0x848U)
-#define SMMU_GNSR0_SMR19			(0x84cU)
-#define SMMU_GNSR0_SMR20			(0x850U)
-#define SMMU_GNSR0_SMR21			(0x854U)
-#define SMMU_GNSR0_SMR22			(0x858U)
-#define SMMU_GNSR0_SMR23			(0x85cU)
-#define SMMU_GNSR0_SMR24			(0x860U)
-#define SMMU_GNSR0_SMR25			(0x864U)
-#define SMMU_GNSR0_SMR26			(0x868U)
-#define SMMU_GNSR0_SMR27			(0x86cU)
-#define SMMU_GNSR0_SMR28			(0x870U)
-#define SMMU_GNSR0_SMR29			(0x874U)
-#define SMMU_GNSR0_SMR30			(0x878U)
-#define SMMU_GNSR0_SMR31			(0x87cU)
-#define SMMU_GNSR0_SMR32			(0x880U)
-#define SMMU_GNSR0_SMR33			(0x884U)
-#define SMMU_GNSR0_SMR34			(0x888U)
-#define SMMU_GNSR0_SMR35			(0x88cU)
-#define SMMU_GNSR0_SMR36			(0x890U)
-#define SMMU_GNSR0_SMR37			(0x894U)
-#define SMMU_GNSR0_SMR38			(0x898U)
-#define SMMU_GNSR0_SMR39			(0x89cU)
-#define SMMU_GNSR0_SMR40			(0x8a0U)
-#define SMMU_GNSR0_SMR41			(0x8a4U)
-#define SMMU_GNSR0_SMR42			(0x8a8U)
-#define SMMU_GNSR0_SMR43			(0x8acU)
-#define SMMU_GNSR0_SMR44			(0x8b0U)
-#define SMMU_GNSR0_SMR45			(0x8b4U)
-#define SMMU_GNSR0_SMR46			(0x8b8U)
-#define SMMU_GNSR0_SMR47			(0x8bcU)
-#define SMMU_GNSR0_SMR48			(0x8c0U)
-#define SMMU_GNSR0_SMR49			(0x8c4U)
-#define SMMU_GNSR0_SMR50			(0x8c8U)
-#define SMMU_GNSR0_SMR51			(0x8ccU)
-#define SMMU_GNSR0_SMR52			(0x8d0U)
-#define SMMU_GNSR0_SMR53			(0x8d4U)
-#define SMMU_GNSR0_SMR54			(0x8d8U)
-#define SMMU_GNSR0_SMR55			(0x8dcU)
-#define SMMU_GNSR0_SMR56			(0x8e0U)
-#define SMMU_GNSR0_SMR57			(0x8e4U)
-#define SMMU_GNSR0_SMR58			(0x8e8U)
-#define SMMU_GNSR0_SMR59			(0x8ecU)
-#define SMMU_GNSR0_SMR60			(0x8f0U)
-#define SMMU_GNSR0_SMR61			(0x8f4U)
-#define SMMU_GNSR0_SMR62			(0x8f8U)
-#define SMMU_GNSR0_SMR63			(0x8fcU)
-#define SMMU_GNSR0_SMR64			(0x900U)
-#define SMMU_GNSR0_SMR65			(0x904U)
-#define SMMU_GNSR0_SMR66			(0x908U)
-#define SMMU_GNSR0_SMR67			(0x90cU)
-#define SMMU_GNSR0_SMR68			(0x910U)
-#define SMMU_GNSR0_SMR69			(0x914U)
-#define SMMU_GNSR0_SMR70			(0x918U)
-#define SMMU_GNSR0_SMR71			(0x91cU)
-#define SMMU_GNSR0_SMR72			(0x920U)
-#define SMMU_GNSR0_SMR73			(0x924U)
-#define SMMU_GNSR0_SMR74			(0x928U)
-#define SMMU_GNSR0_SMR75			(0x92cU)
-#define SMMU_GNSR0_SMR76			(0x930U)
-#define SMMU_GNSR0_SMR77			(0x934U)
-#define SMMU_GNSR0_SMR78			(0x938U)
-#define SMMU_GNSR0_SMR79			(0x93cU)
-#define SMMU_GNSR0_SMR80			(0x940U)
-#define SMMU_GNSR0_SMR81			(0x944U)
-#define SMMU_GNSR0_SMR82			(0x948U)
-#define SMMU_GNSR0_SMR83			(0x94cU)
-#define SMMU_GNSR0_SMR84			(0x950U)
-#define SMMU_GNSR0_SMR85			(0x954U)
-#define SMMU_GNSR0_SMR86			(0x958U)
-#define SMMU_GNSR0_SMR87			(0x95cU)
-#define SMMU_GNSR0_SMR88			(0x960U)
-#define SMMU_GNSR0_SMR89			(0x964U)
-#define SMMU_GNSR0_SMR90			(0x968U)
-#define SMMU_GNSR0_SMR91			(0x96cU)
-#define SMMU_GNSR0_SMR92			(0x970U)
-#define SMMU_GNSR0_SMR93			(0x974U)
-#define SMMU_GNSR0_SMR94			(0x978U)
-#define SMMU_GNSR0_SMR95			(0x97cU)
-#define SMMU_GNSR0_SMR96			(0x980U)
-#define SMMU_GNSR0_SMR97			(0x984U)
-#define SMMU_GNSR0_SMR98			(0x988U)
-#define SMMU_GNSR0_SMR99			(0x98cU)
-#define SMMU_GNSR0_SMR100			(0x990U)
-#define SMMU_GNSR0_SMR101			(0x994U)
-#define SMMU_GNSR0_SMR102			(0x998U)
-#define SMMU_GNSR0_SMR103			(0x99cU)
-#define SMMU_GNSR0_SMR104			(0x9a0U)
-#define SMMU_GNSR0_SMR105			(0x9a4U)
-#define SMMU_GNSR0_SMR106			(0x9a8U)
-#define SMMU_GNSR0_SMR107			(0x9acU)
-#define SMMU_GNSR0_SMR108			(0x9b0U)
-#define SMMU_GNSR0_SMR109			(0x9b4U)
-#define SMMU_GNSR0_SMR110			(0x9b8U)
-#define SMMU_GNSR0_SMR111			(0x9bcU)
-#define SMMU_GNSR0_SMR112			(0x9c0U)
-#define SMMU_GNSR0_SMR113			(0x9c4U)
-#define SMMU_GNSR0_SMR114			(0x9c8U)
-#define SMMU_GNSR0_SMR115			(0x9ccU)
-#define SMMU_GNSR0_SMR116			(0x9d0U)
-#define SMMU_GNSR0_SMR117			(0x9d4U)
-#define SMMU_GNSR0_SMR118			(0x9d8U)
-#define SMMU_GNSR0_SMR119			(0x9dcU)
-#define SMMU_GNSR0_SMR120			(0x9e0U)
-#define SMMU_GNSR0_SMR121			(0x9e4U)
-#define SMMU_GNSR0_SMR122			(0x9e8U)
-#define SMMU_GNSR0_SMR123			(0x9ecU)
-#define SMMU_GNSR0_SMR124			(0x9f0U)
-#define SMMU_GNSR0_SMR125			(0x9f4U)
-#define SMMU_GNSR0_SMR126			(0x9f8U)
-#define SMMU_GNSR0_SMR127			(0x9fcU)
-#define SMMU_GNSR0_S2CR0			(0xc00U)
-#define SMMU_GNSR0_S2CRn			(0xc00U)
-#define SMMU_GNSR0_S2CRn			(0xc00U)
-#define SMMU_GNSR0_S2CR1			(0xc04U)
-#define SMMU_GNSR0_S2CR2			(0xc08U)
-#define SMMU_GNSR0_S2CR3			(0xc0cU)
-#define SMMU_GNSR0_S2CR4			(0xc10U)
-#define SMMU_GNSR0_S2CR5			(0xc14U)
-#define SMMU_GNSR0_S2CR6			(0xc18U)
-#define SMMU_GNSR0_S2CR7			(0xc1cU)
-#define SMMU_GNSR0_S2CR8			(0xc20U)
-#define SMMU_GNSR0_S2CR9			(0xc24U)
-#define SMMU_GNSR0_S2CR10			(0xc28U)
-#define SMMU_GNSR0_S2CR11			(0xc2cU)
-#define SMMU_GNSR0_S2CR12			(0xc30U)
-#define SMMU_GNSR0_S2CR13			(0xc34U)
-#define SMMU_GNSR0_S2CR14			(0xc38U)
-#define SMMU_GNSR0_S2CR15			(0xc3cU)
-#define SMMU_GNSR0_S2CR16			(0xc40U)
-#define SMMU_GNSR0_S2CR17			(0xc44U)
-#define SMMU_GNSR0_S2CR18			(0xc48U)
-#define SMMU_GNSR0_S2CR19			(0xc4cU)
-#define SMMU_GNSR0_S2CR20			(0xc50U)
-#define SMMU_GNSR0_S2CR21			(0xc54U)
-#define SMMU_GNSR0_S2CR22			(0xc58U)
-#define SMMU_GNSR0_S2CR23			(0xc5cU)
-#define SMMU_GNSR0_S2CR24			(0xc60U)
-#define SMMU_GNSR0_S2CR25			(0xc64U)
-#define SMMU_GNSR0_S2CR26			(0xc68U)
-#define SMMU_GNSR0_S2CR27			(0xc6cU)
-#define SMMU_GNSR0_S2CR28			(0xc70U)
-#define SMMU_GNSR0_S2CR29			(0xc74U)
-#define SMMU_GNSR0_S2CR30			(0xc78U)
-#define SMMU_GNSR0_S2CR31			(0xc7cU)
-#define SMMU_GNSR0_S2CR32			(0xc80U)
-#define SMMU_GNSR0_S2CR33			(0xc84U)
-#define SMMU_GNSR0_S2CR34			(0xc88U)
-#define SMMU_GNSR0_S2CR35			(0xc8cU)
-#define SMMU_GNSR0_S2CR36			(0xc90U)
-#define SMMU_GNSR0_S2CR37			(0xc94U)
-#define SMMU_GNSR0_S2CR38			(0xc98U)
-#define SMMU_GNSR0_S2CR39			(0xc9cU)
-#define SMMU_GNSR0_S2CR40			(0xca0U)
-#define SMMU_GNSR0_S2CR41			(0xca4U)
-#define SMMU_GNSR0_S2CR42			(0xca8U)
-#define SMMU_GNSR0_S2CR43			(0xcacU)
-#define SMMU_GNSR0_S2CR44			(0xcb0U)
-#define SMMU_GNSR0_S2CR45			(0xcb4U)
-#define SMMU_GNSR0_S2CR46			(0xcb8U)
-#define SMMU_GNSR0_S2CR47			(0xcbcU)
-#define SMMU_GNSR0_S2CR48			(0xcc0U)
-#define SMMU_GNSR0_S2CR49			(0xcc4U)
-#define SMMU_GNSR0_S2CR50			(0xcc8U)
-#define SMMU_GNSR0_S2CR51			(0xcccU)
-#define SMMU_GNSR0_S2CR52			(0xcd0U)
-#define SMMU_GNSR0_S2CR53			(0xcd4U)
-#define SMMU_GNSR0_S2CR54			(0xcd8U)
-#define SMMU_GNSR0_S2CR55			(0xcdcU)
-#define SMMU_GNSR0_S2CR56			(0xce0U)
-#define SMMU_GNSR0_S2CR57			(0xce4U)
-#define SMMU_GNSR0_S2CR58			(0xce8U)
-#define SMMU_GNSR0_S2CR59			(0xcecU)
-#define SMMU_GNSR0_S2CR60			(0xcf0U)
-#define SMMU_GNSR0_S2CR61			(0xcf4U)
-#define SMMU_GNSR0_S2CR62			(0xcf8U)
-#define SMMU_GNSR0_S2CR63			(0xcfcU)
-#define SMMU_GNSR0_S2CR64			(0xd00U)
-#define SMMU_GNSR0_S2CR65			(0xd04U)
-#define SMMU_GNSR0_S2CR66			(0xd08U)
-#define SMMU_GNSR0_S2CR67			(0xd0cU)
-#define SMMU_GNSR0_S2CR68			(0xd10U)
-#define SMMU_GNSR0_S2CR69			(0xd14U)
-#define SMMU_GNSR0_S2CR70			(0xd18U)
-#define SMMU_GNSR0_S2CR71			(0xd1cU)
-#define SMMU_GNSR0_S2CR72			(0xd20U)
-#define SMMU_GNSR0_S2CR73			(0xd24U)
-#define SMMU_GNSR0_S2CR74			(0xd28U)
-#define SMMU_GNSR0_S2CR75			(0xd2cU)
-#define SMMU_GNSR0_S2CR76			(0xd30U)
-#define SMMU_GNSR0_S2CR77			(0xd34U)
-#define SMMU_GNSR0_S2CR78			(0xd38U)
-#define SMMU_GNSR0_S2CR79			(0xd3cU)
-#define SMMU_GNSR0_S2CR80			(0xd40U)
-#define SMMU_GNSR0_S2CR81			(0xd44U)
-#define SMMU_GNSR0_S2CR82			(0xd48U)
-#define SMMU_GNSR0_S2CR83			(0xd4cU)
-#define SMMU_GNSR0_S2CR84			(0xd50U)
-#define SMMU_GNSR0_S2CR85			(0xd54U)
-#define SMMU_GNSR0_S2CR86			(0xd58U)
-#define SMMU_GNSR0_S2CR87			(0xd5cU)
-#define SMMU_GNSR0_S2CR88			(0xd60U)
-#define SMMU_GNSR0_S2CR89			(0xd64U)
-#define SMMU_GNSR0_S2CR90			(0xd68U)
-#define SMMU_GNSR0_S2CR91			(0xd6cU)
-#define SMMU_GNSR0_S2CR92			(0xd70U)
-#define SMMU_GNSR0_S2CR93			(0xd74U)
-#define SMMU_GNSR0_S2CR94			(0xd78U)
-#define SMMU_GNSR0_S2CR95			(0xd7cU)
-#define SMMU_GNSR0_S2CR96			(0xd80U)
-#define SMMU_GNSR0_S2CR97			(0xd84U)
-#define SMMU_GNSR0_S2CR98			(0xd88U)
-#define SMMU_GNSR0_S2CR99			(0xd8cU)
-#define SMMU_GNSR0_S2CR100			(0xd90U)
-#define SMMU_GNSR0_S2CR101			(0xd94U)
-#define SMMU_GNSR0_S2CR102			(0xd98U)
-#define SMMU_GNSR0_S2CR103			(0xd9cU)
-#define SMMU_GNSR0_S2CR104			(0xda0U)
-#define SMMU_GNSR0_S2CR105			(0xda4U)
-#define SMMU_GNSR0_S2CR106			(0xda8U)
-#define SMMU_GNSR0_S2CR107			(0xdacU)
-#define SMMU_GNSR0_S2CR108			(0xdb0U)
-#define SMMU_GNSR0_S2CR109			(0xdb4U)
-#define SMMU_GNSR0_S2CR110			(0xdb8U)
-#define SMMU_GNSR0_S2CR111			(0xdbcU)
-#define SMMU_GNSR0_S2CR112			(0xdc0U)
-#define SMMU_GNSR0_S2CR113			(0xdc4U)
-#define SMMU_GNSR0_S2CR114			(0xdc8U)
-#define SMMU_GNSR0_S2CR115			(0xdccU)
-#define SMMU_GNSR0_S2CR116			(0xdd0U)
-#define SMMU_GNSR0_S2CR117			(0xdd4U)
-#define SMMU_GNSR0_S2CR118			(0xdd8U)
-#define SMMU_GNSR0_S2CR119			(0xddcU)
-#define SMMU_GNSR0_S2CR120			(0xde0U)
-#define SMMU_GNSR0_S2CR121			(0xde4U)
-#define SMMU_GNSR0_S2CR122			(0xde8U)
-#define SMMU_GNSR0_S2CR123			(0xdecU)
-#define SMMU_GNSR0_S2CR124			(0xdf0U)
-#define SMMU_GNSR0_S2CR125			(0xdf4U)
-#define SMMU_GNSR0_S2CR126			(0xdf8U)
-#define SMMU_GNSR0_S2CR127			(0xdfcU)
-#define SMMU_GNSR0_PIDR0			(0xfe0U)
-#define SMMU_GNSR0_PIDR1			(0xfe4U)
-#define SMMU_GNSR0_PIDR2			(0xfe8U)
-#define SMMU_GNSR0_PIDR3			(0xfecU)
-#define SMMU_GNSR0_PIDR4			(0xfd0U)
-#define SMMU_GNSR0_PIDR5			(0xfd4U)
-#define SMMU_GNSR0_PIDR6			(0xfd8U)
-#define SMMU_GNSR0_PIDR7			(0xfdcU)
-#define SMMU_GNSR0_CIDR0			(0xff0U)
-#define SMMU_GNSR0_CIDR1			(0xff4U)
-#define SMMU_GNSR0_CIDR2			(0xff8U)
-#define SMMU_GNSR0_CIDR3			(0xffcU)
-#define SMMU_GNSR1_CBAR0			(0x0U)
-#define SMMU_GNSR1_CBARn			(0x0U)
-#define SMMU_GNSR1_CBFRSYNRA0			(0x400U)
-#define SMMU_GNSR1_CBA2R0			(0x800U)
-#define SMMU_GNSR1_CBAR1			(0x4U)
-#define SMMU_GNSR1_CBFRSYNRA1			(0x404U)
-#define SMMU_GNSR1_CBA2R1			(0x804U)
-#define SMMU_GNSR1_CBAR2			(0x8U)
-#define SMMU_GNSR1_CBFRSYNRA2			(0x408U)
-#define SMMU_GNSR1_CBA2R2			(0x808U)
-#define SMMU_GNSR1_CBAR3			(0xcU)
-#define SMMU_GNSR1_CBFRSYNRA3			(0x40cU)
-#define SMMU_GNSR1_CBA2R3			(0x80cU)
-#define SMMU_GNSR1_CBAR4			(0x10U)
-#define SMMU_GNSR1_CBFRSYNRA4			(0x410U)
-#define SMMU_GNSR1_CBA2R4			(0x810U)
-#define SMMU_GNSR1_CBAR5			(0x14U)
-#define SMMU_GNSR1_CBFRSYNRA5			(0x414U)
-#define SMMU_GNSR1_CBA2R5			(0x814U)
-#define SMMU_GNSR1_CBAR6			(0x18U)
-#define SMMU_GNSR1_CBFRSYNRA6			(0x418U)
-#define SMMU_GNSR1_CBA2R6			(0x818U)
-#define SMMU_GNSR1_CBAR7			(0x1cU)
-#define SMMU_GNSR1_CBFRSYNRA7			(0x41cU)
-#define SMMU_GNSR1_CBA2R7			(0x81cU)
-#define SMMU_GNSR1_CBAR8			(0x20U)
-#define SMMU_GNSR1_CBFRSYNRA8			(0x420U)
-#define SMMU_GNSR1_CBA2R8			(0x820U)
-#define SMMU_GNSR1_CBAR9			(0x24U)
-#define SMMU_GNSR1_CBFRSYNRA9			(0x424U)
-#define SMMU_GNSR1_CBA2R9			(0x824U)
-#define SMMU_GNSR1_CBAR10			(0x28U)
-#define SMMU_GNSR1_CBFRSYNRA10			(0x428U)
-#define SMMU_GNSR1_CBA2R10			(0x828U)
-#define SMMU_GNSR1_CBAR11			(0x2cU)
-#define SMMU_GNSR1_CBFRSYNRA11			(0x42cU)
-#define SMMU_GNSR1_CBA2R11			(0x82cU)
-#define SMMU_GNSR1_CBAR12			(0x30U)
-#define SMMU_GNSR1_CBFRSYNRA12			(0x430U)
-#define SMMU_GNSR1_CBA2R12			(0x830U)
-#define SMMU_GNSR1_CBAR13			(0x34U)
-#define SMMU_GNSR1_CBFRSYNRA13			(0x434U)
-#define SMMU_GNSR1_CBA2R13			(0x834U)
-#define SMMU_GNSR1_CBAR14			(0x38U)
-#define SMMU_GNSR1_CBFRSYNRA14			(0x438U)
-#define SMMU_GNSR1_CBA2R14			(0x838U)
-#define SMMU_GNSR1_CBAR15			(0x3cU)
-#define SMMU_GNSR1_CBFRSYNRA15			(0x43cU)
-#define SMMU_GNSR1_CBA2R15			(0x83cU)
-#define SMMU_GNSR1_CBAR16			(0x40U)
-#define SMMU_GNSR1_CBFRSYNRA16			(0x440U)
-#define SMMU_GNSR1_CBA2R16			(0x840U)
-#define SMMU_GNSR1_CBAR17			(0x44U)
-#define SMMU_GNSR1_CBFRSYNRA17			(0x444U)
-#define SMMU_GNSR1_CBA2R17			(0x844U)
-#define SMMU_GNSR1_CBAR18			(0x48U)
-#define SMMU_GNSR1_CBFRSYNRA18			(0x448U)
-#define SMMU_GNSR1_CBA2R18			(0x848U)
-#define SMMU_GNSR1_CBAR19			(0x4cU)
-#define SMMU_GNSR1_CBFRSYNRA19			(0x44cU)
-#define SMMU_GNSR1_CBA2R19			(0x84cU)
-#define SMMU_GNSR1_CBAR20			(0x50U)
-#define SMMU_GNSR1_CBFRSYNRA20			(0x450U)
-#define SMMU_GNSR1_CBA2R20			(0x850U)
-#define SMMU_GNSR1_CBAR21			(0x54U)
-#define SMMU_GNSR1_CBFRSYNRA21			(0x454U)
-#define SMMU_GNSR1_CBA2R21			(0x854U)
-#define SMMU_GNSR1_CBAR22			(0x58U)
-#define SMMU_GNSR1_CBFRSYNRA22			(0x458U)
-#define SMMU_GNSR1_CBA2R22			(0x858U)
-#define SMMU_GNSR1_CBAR23			(0x5cU)
-#define SMMU_GNSR1_CBFRSYNRA23			(0x45cU)
-#define SMMU_GNSR1_CBA2R23			(0x85cU)
-#define SMMU_GNSR1_CBAR24			(0x60U)
-#define SMMU_GNSR1_CBFRSYNRA24			(0x460U)
-#define SMMU_GNSR1_CBA2R24			(0x860U)
-#define SMMU_GNSR1_CBAR25			(0x64U)
-#define SMMU_GNSR1_CBFRSYNRA25			(0x464U)
-#define SMMU_GNSR1_CBA2R25			(0x864U)
-#define SMMU_GNSR1_CBAR26			(0x68U)
-#define SMMU_GNSR1_CBFRSYNRA26			(0x468U)
-#define SMMU_GNSR1_CBA2R26			(0x868U)
-#define SMMU_GNSR1_CBAR27			(0x6cU)
-#define SMMU_GNSR1_CBFRSYNRA27			(0x46cU)
-#define SMMU_GNSR1_CBA2R27			(0x86cU)
-#define SMMU_GNSR1_CBAR28			(0x70U)
-#define SMMU_GNSR1_CBFRSYNRA28			(0x470U)
-#define SMMU_GNSR1_CBA2R28			(0x870U)
-#define SMMU_GNSR1_CBAR29			(0x74U)
-#define SMMU_GNSR1_CBFRSYNRA29			(0x474U)
-#define SMMU_GNSR1_CBA2R29			(0x874U)
-#define SMMU_GNSR1_CBAR30			(0x78U)
-#define SMMU_GNSR1_CBFRSYNRA30			(0x478U)
-#define SMMU_GNSR1_CBA2R30			(0x878U)
-#define SMMU_GNSR1_CBAR31			(0x7cU)
-#define SMMU_GNSR1_CBFRSYNRA31			(0x47cU)
-#define SMMU_GNSR1_CBA2R31			(0x87cU)
-#define SMMU_GNSR1_CBAR32			(0x80U)
-#define SMMU_GNSR1_CBFRSYNRA32			(0x480U)
-#define SMMU_GNSR1_CBA2R32			(0x880U)
-#define SMMU_GNSR1_CBAR33			(0x84U)
-#define SMMU_GNSR1_CBFRSYNRA33			(0x484U)
-#define SMMU_GNSR1_CBA2R33			(0x884U)
-#define SMMU_GNSR1_CBAR34			(0x88U)
-#define SMMU_GNSR1_CBFRSYNRA34			(0x488U)
-#define SMMU_GNSR1_CBA2R34			(0x888U)
-#define SMMU_GNSR1_CBAR35			(0x8cU)
-#define SMMU_GNSR1_CBFRSYNRA35			(0x48cU)
-#define SMMU_GNSR1_CBA2R35			(0x88cU)
-#define SMMU_GNSR1_CBAR36			(0x90U)
-#define SMMU_GNSR1_CBFRSYNRA36			(0x490U)
-#define SMMU_GNSR1_CBA2R36			(0x890U)
-#define SMMU_GNSR1_CBAR37			(0x94U)
-#define SMMU_GNSR1_CBFRSYNRA37			(0x494U)
-#define SMMU_GNSR1_CBA2R37			(0x894U)
-#define SMMU_GNSR1_CBAR38			(0x98U)
-#define SMMU_GNSR1_CBFRSYNRA38			(0x498U)
-#define SMMU_GNSR1_CBA2R38			(0x898U)
-#define SMMU_GNSR1_CBAR39			(0x9cU)
-#define SMMU_GNSR1_CBFRSYNRA39			(0x49cU)
-#define SMMU_GNSR1_CBA2R39			(0x89cU)
-#define SMMU_GNSR1_CBAR40			(0xa0U)
-#define SMMU_GNSR1_CBFRSYNRA40			(0x4a0U)
-#define SMMU_GNSR1_CBA2R40			(0x8a0U)
-#define SMMU_GNSR1_CBAR41			(0xa4U)
-#define SMMU_GNSR1_CBFRSYNRA41			(0x4a4U)
-#define SMMU_GNSR1_CBA2R41			(0x8a4U)
-#define SMMU_GNSR1_CBAR42			(0xa8U)
-#define SMMU_GNSR1_CBFRSYNRA42			(0x4a8U)
-#define SMMU_GNSR1_CBA2R42			(0x8a8U)
-#define SMMU_GNSR1_CBAR43			(0xacU)
-#define SMMU_GNSR1_CBFRSYNRA43			(0x4acU)
-#define SMMU_GNSR1_CBA2R43			(0x8acU)
-#define SMMU_GNSR1_CBAR44			(0xb0U)
-#define SMMU_GNSR1_CBFRSYNRA44			(0x4b0U)
-#define SMMU_GNSR1_CBA2R44			(0x8b0U)
-#define SMMU_GNSR1_CBAR45			(0xb4U)
-#define SMMU_GNSR1_CBFRSYNRA45			(0x4b4U)
-#define SMMU_GNSR1_CBA2R45			(0x8b4U)
-#define SMMU_GNSR1_CBAR46			(0xb8U)
-#define SMMU_GNSR1_CBFRSYNRA46			(0x4b8U)
-#define SMMU_GNSR1_CBA2R46			(0x8b8U)
-#define SMMU_GNSR1_CBAR47			(0xbcU)
-#define SMMU_GNSR1_CBFRSYNRA47			(0x4bcU)
-#define SMMU_GNSR1_CBA2R47			(0x8bcU)
-#define SMMU_GNSR1_CBAR48			(0xc0U)
-#define SMMU_GNSR1_CBFRSYNRA48			(0x4c0U)
-#define SMMU_GNSR1_CBA2R48			(0x8c0U)
-#define SMMU_GNSR1_CBAR49			(0xc4U)
-#define SMMU_GNSR1_CBFRSYNRA49			(0x4c4U)
-#define SMMU_GNSR1_CBA2R49			(0x8c4U)
-#define SMMU_GNSR1_CBAR50			(0xc8U)
-#define SMMU_GNSR1_CBFRSYNRA50			(0x4c8U)
-#define SMMU_GNSR1_CBA2R50			(0x8c8U)
-#define SMMU_GNSR1_CBAR51			(0xccU)
-#define SMMU_GNSR1_CBFRSYNRA51			(0x4ccU)
-#define SMMU_GNSR1_CBA2R51			(0x8ccU)
-#define SMMU_GNSR1_CBAR52			(0xd0U)
-#define SMMU_GNSR1_CBFRSYNRA52			(0x4d0U)
-#define SMMU_GNSR1_CBA2R52			(0x8d0U)
-#define SMMU_GNSR1_CBAR53			(0xd4U)
-#define SMMU_GNSR1_CBFRSYNRA53			(0x4d4U)
-#define SMMU_GNSR1_CBA2R53			(0x8d4U)
-#define SMMU_GNSR1_CBAR54			(0xd8U)
-#define SMMU_GNSR1_CBFRSYNRA54			(0x4d8U)
-#define SMMU_GNSR1_CBA2R54			(0x8d8U)
-#define SMMU_GNSR1_CBAR55			(0xdcU)
-#define SMMU_GNSR1_CBFRSYNRA55			(0x4dcU)
-#define SMMU_GNSR1_CBA2R55			(0x8dcU)
-#define SMMU_GNSR1_CBAR56			(0xe0U)
-#define SMMU_GNSR1_CBFRSYNRA56			(0x4e0U)
-#define SMMU_GNSR1_CBA2R56			(0x8e0U)
-#define SMMU_GNSR1_CBAR57			(0xe4U)
-#define SMMU_GNSR1_CBFRSYNRA57			(0x4e4U)
-#define SMMU_GNSR1_CBA2R57			(0x8e4U)
-#define SMMU_GNSR1_CBAR58			(0xe8U)
-#define SMMU_GNSR1_CBFRSYNRA58			(0x4e8U)
-#define SMMU_GNSR1_CBA2R58			(0x8e8U)
-#define SMMU_GNSR1_CBAR59			(0xecU)
-#define SMMU_GNSR1_CBFRSYNRA59			(0x4ecU)
-#define SMMU_GNSR1_CBA2R59			(0x8ecU)
-#define SMMU_GNSR1_CBAR60			(0xf0U)
-#define SMMU_GNSR1_CBFRSYNRA60			(0x4f0U)
-#define SMMU_GNSR1_CBA2R60			(0x8f0U)
-#define SMMU_GNSR1_CBAR61			(0xf4U)
-#define SMMU_GNSR1_CBFRSYNRA61			(0x4f4U)
-#define SMMU_GNSR1_CBA2R61			(0x8f4U)
-#define SMMU_GNSR1_CBAR62			(0xf8U)
-#define SMMU_GNSR1_CBFRSYNRA62			(0x4f8U)
-#define SMMU_GNSR1_CBA2R62			(0x8f8U)
-#define SMMU_GNSR1_CBAR63			(0xfcU)
-#define SMMU_GNSR1_CBFRSYNRA63			(0x4fcU)
-#define SMMU_GNSR1_CBA2R63			(0x8fcU)
 
 /*******************************************************************************
  * SMMU Global Secure Aux. Configuration Register
@@ -581,269 +23,69 @@
 #define SMMU_GSR0_PGSIZE_SHIFT			16U
 #define SMMU_GSR0_PGSIZE_4K			(0U << SMMU_GSR0_PGSIZE_SHIFT)
 #define SMMU_GSR0_PGSIZE_64K			(1U << SMMU_GSR0_PGSIZE_SHIFT)
-#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT		(1U << 26)
+#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT		(1ULL << 26U)
+#define SMMU_GSR0_PER				(0x20200U)
 
 /*******************************************************************************
  * SMMU Global Aux. Control Register
  ******************************************************************************/
 #define SMMU_CBn_ACTLR_CPRE_BIT			(1ULL << 1U)
 
-/*******************************************************************************
- * SMMU configuration constants
- ******************************************************************************/
-#define ID1_PAGESIZE				(1U << 31U)
-#define ID1_NUMPAGENDXB_SHIFT			28U
-#define ID1_NUMPAGENDXB_MASK			7U
-#define ID1_NUMS2CB_SHIFT			16U
-#define ID1_NUMS2CB_MASK			0xffU
-#define ID1_NUMCB_SHIFT				0U
-#define ID1_NUMCB_MASK				0xffU
-#define PGSHIFT					16U
-#define CB_SIZE					0x800000U
-
-typedef struct smmu_regs {
-	uint32_t reg;
-	uint32_t val;
-} smmu_regs_t;
-
-#define mc_make_sid_override_cfg(name) \
-	{ \
-		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \
-		.val = 0x00000000U, \
-	}
-
-#define mc_make_sid_security_cfg(name) \
-	{ \
-		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \
-		.val = 0x00000000U, \
-	}
-
-#define smmu_make_gnsr0_sec_cfg(base_addr, name) \
-	{ \
-		.reg = base_addr + SMMU_GNSR0_ ## name, \
-		.val = 0x00000000U, \
-	}
-
-/*
- * On ARM-SMMU, conditional offset to access secure aliases of non-secure registers
- * is 0x400. So, add it to register address
- */
-#define smmu_make_gnsr0_nsec_cfg(base_addr, name) \
-	{ \
-		.reg = base_addr + 0x400U + SMMU_GNSR0_ ## name, \
-		.val = 0x00000000U, \
-	}
-
-#define smmu_make_gnsr0_smr_cfg(base_addr, n) \
-	{ \
-		.reg = base_addr + SMMU_GNSR0_SMR ## n, \
-		.val = 0x00000000U, \
-	}
+/* SMMU IDs currently supported by the driver */
+enum {
+	TEGRA_SMMU0 = 0U,
+	TEGRA_SMMU1 = 1U,
+	TEGRA_SMMU2 = 2U
+};
 
-#define smmu_make_gnsr0_s2cr_cfg(base_addr, n) \
-	{ \
-		.reg = base_addr + SMMU_GNSR0_S2CR ## n, \
-		.val = 0x00000000U, \
-	}
+static inline uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off)
+{
+	uint32_t ret = 0U;
 
-#define smmu_make_gnsr1_cbar_cfg(base_addr, n) \
-	{ \
-		.reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \
-		.val = 0x00000000U, \
+#if defined(TEGRA_SMMU0_BASE)
+	if (smmu_id == TEGRA_SMMU0) {
+		ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off);
 	}
+#endif
 
-#define smmu_make_gnsr1_cba2r_cfg(base_addr, n) \
-	{ \
-		.reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \
-		.val = 0x00000000U, \
+#if defined(TEGRA_SMMU1_BASE)
+	if (smmu_id == TEGRA_SMMU1) {
+		ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off);
 	}
+#endif
 
-#define smmu_make_cb_cfg(base_addr, name, n) \
-	{ \
-		.reg = base_addr + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \
-			+ SMMU_CBn_ ## name, \
-		.val = 0x00000000U, \
+#if defined(TEGRA_SMMU2_BASE)
+	if (smmu_id == TEGRA_SMMU2) {
+		ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off);
 	}
+#endif
 
-#define smmu_make_smrg_group(base_addr, n)	\
-	smmu_make_gnsr0_smr_cfg(base_addr, n),	\
-	smmu_make_gnsr0_s2cr_cfg(base_addr, n),	\
-	smmu_make_gnsr1_cbar_cfg(base_addr, n),	\
-	smmu_make_gnsr1_cba2r_cfg(base_addr, n)	/* don't put "," here. */
+	return ret;
+}
 
-#define smmu_make_cb_group(base_addr, n)		\
-	smmu_make_cb_cfg(base_addr, SCTLR, n),	\
-	smmu_make_cb_cfg(base_addr, TCR2, n),	\
-	smmu_make_cb_cfg(base_addr, TTBR0_LO, n),	\
-	smmu_make_cb_cfg(base_addr, TTBR0_HI, n),	\
-	smmu_make_cb_cfg(base_addr, TCR, n),	\
-	smmu_make_cb_cfg(base_addr, PRRR_MAIR0, n),\
-	smmu_make_cb_cfg(base_addr, FSR, n),	\
-	smmu_make_cb_cfg(base_addr, FAR_LO, n),	\
-	smmu_make_cb_cfg(base_addr, FAR_HI, n),	\
-	smmu_make_cb_cfg(base_addr, FSYNR0, n)	/* don't put "," here. */
-
-#define smmu_make_cfg(base_addr)			\
-	smmu_make_gnsr0_nsec_cfg(base_addr, CR0),	\
-	smmu_make_gnsr0_sec_cfg(base_addr, IDR0),	\
-	smmu_make_gnsr0_sec_cfg(base_addr, IDR1),	\
-	smmu_make_gnsr0_sec_cfg(base_addr, IDR2),	\
-	smmu_make_gnsr0_nsec_cfg(base_addr, GFSR),	\
-	smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR0),	\
-	smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR1),	\
-	smmu_make_gnsr0_nsec_cfg(base_addr, TLBGSTATUS),\
-	smmu_make_gnsr0_nsec_cfg(base_addr, PIDR2),	\
-	smmu_make_smrg_group(base_addr, 0),		\
-	smmu_make_smrg_group(base_addr, 1),		\
-	smmu_make_smrg_group(base_addr, 2),		\
-	smmu_make_smrg_group(base_addr, 3),		\
-	smmu_make_smrg_group(base_addr, 4),		\
-	smmu_make_smrg_group(base_addr, 5),		\
-	smmu_make_smrg_group(base_addr, 6),		\
-	smmu_make_smrg_group(base_addr, 7),		\
-	smmu_make_smrg_group(base_addr, 8),		\
-	smmu_make_smrg_group(base_addr, 9),		\
-	smmu_make_smrg_group(base_addr, 10),		\
-	smmu_make_smrg_group(base_addr, 11),		\
-	smmu_make_smrg_group(base_addr, 12),		\
-	smmu_make_smrg_group(base_addr, 13),		\
-	smmu_make_smrg_group(base_addr, 14),		\
-	smmu_make_smrg_group(base_addr, 15),		\
-	smmu_make_smrg_group(base_addr, 16),		\
-	smmu_make_smrg_group(base_addr, 17),		\
-	smmu_make_smrg_group(base_addr, 18),		\
-	smmu_make_smrg_group(base_addr, 19),		\
-	smmu_make_smrg_group(base_addr, 20),		\
-	smmu_make_smrg_group(base_addr, 21),		\
-	smmu_make_smrg_group(base_addr, 22),		\
-	smmu_make_smrg_group(base_addr, 23),		\
-	smmu_make_smrg_group(base_addr, 24),		\
-	smmu_make_smrg_group(base_addr, 25),		\
-	smmu_make_smrg_group(base_addr, 26),		\
-	smmu_make_smrg_group(base_addr, 27),		\
-	smmu_make_smrg_group(base_addr, 28),		\
-	smmu_make_smrg_group(base_addr, 29),		\
-	smmu_make_smrg_group(base_addr, 30),		\
-	smmu_make_smrg_group(base_addr, 31),		\
-	smmu_make_smrg_group(base_addr, 32),		\
-	smmu_make_smrg_group(base_addr, 33),		\
-	smmu_make_smrg_group(base_addr, 34),		\
-	smmu_make_smrg_group(base_addr, 35),		\
-	smmu_make_smrg_group(base_addr, 36),		\
-	smmu_make_smrg_group(base_addr, 37),		\
-	smmu_make_smrg_group(base_addr, 38),		\
-	smmu_make_smrg_group(base_addr, 39),		\
-	smmu_make_smrg_group(base_addr, 40),		\
-	smmu_make_smrg_group(base_addr, 41),		\
-	smmu_make_smrg_group(base_addr, 42),		\
-	smmu_make_smrg_group(base_addr, 43),		\
-	smmu_make_smrg_group(base_addr, 44),		\
-	smmu_make_smrg_group(base_addr, 45),		\
-	smmu_make_smrg_group(base_addr, 46),		\
-	smmu_make_smrg_group(base_addr, 47),		\
-	smmu_make_smrg_group(base_addr, 48),		\
-	smmu_make_smrg_group(base_addr, 49),		\
-	smmu_make_smrg_group(base_addr, 50),		\
-	smmu_make_smrg_group(base_addr, 51),		\
-	smmu_make_smrg_group(base_addr, 52),		\
-	smmu_make_smrg_group(base_addr, 53),		\
-	smmu_make_smrg_group(base_addr, 54),		\
-	smmu_make_smrg_group(base_addr, 55),		\
-	smmu_make_smrg_group(base_addr, 56),		\
-	smmu_make_smrg_group(base_addr, 57),		\
-	smmu_make_smrg_group(base_addr, 58),		\
-	smmu_make_smrg_group(base_addr, 59),		\
-	smmu_make_smrg_group(base_addr, 60),		\
-	smmu_make_smrg_group(base_addr, 61),		\
-	smmu_make_smrg_group(base_addr, 62),		\
-	smmu_make_smrg_group(base_addr, 63),		\
-	smmu_make_cb_group(base_addr, 0),		\
-	smmu_make_cb_group(base_addr, 1),		\
-	smmu_make_cb_group(base_addr, 2),		\
-	smmu_make_cb_group(base_addr, 3),		\
-	smmu_make_cb_group(base_addr, 4),		\
-	smmu_make_cb_group(base_addr, 5),		\
-	smmu_make_cb_group(base_addr, 6),		\
-	smmu_make_cb_group(base_addr, 7),		\
-	smmu_make_cb_group(base_addr, 8),		\
-	smmu_make_cb_group(base_addr, 9),		\
-	smmu_make_cb_group(base_addr, 10),		\
-	smmu_make_cb_group(base_addr, 11),		\
-	smmu_make_cb_group(base_addr, 12),		\
-	smmu_make_cb_group(base_addr, 13),		\
-	smmu_make_cb_group(base_addr, 14),		\
-	smmu_make_cb_group(base_addr, 15),		\
-	smmu_make_cb_group(base_addr, 16),		\
-	smmu_make_cb_group(base_addr, 17),		\
-	smmu_make_cb_group(base_addr, 18),		\
-	smmu_make_cb_group(base_addr, 19),		\
-	smmu_make_cb_group(base_addr, 20),		\
-	smmu_make_cb_group(base_addr, 21),		\
-	smmu_make_cb_group(base_addr, 22),		\
-	smmu_make_cb_group(base_addr, 23),		\
-	smmu_make_cb_group(base_addr, 24),		\
-	smmu_make_cb_group(base_addr, 25),		\
-	smmu_make_cb_group(base_addr, 26),		\
-	smmu_make_cb_group(base_addr, 27),		\
-	smmu_make_cb_group(base_addr, 28),		\
-	smmu_make_cb_group(base_addr, 29),		\
-	smmu_make_cb_group(base_addr, 30),		\
-	smmu_make_cb_group(base_addr, 31),		\
-	smmu_make_cb_group(base_addr, 32),		\
-	smmu_make_cb_group(base_addr, 33),		\
-	smmu_make_cb_group(base_addr, 34),		\
-	smmu_make_cb_group(base_addr, 35),		\
-	smmu_make_cb_group(base_addr, 36),		\
-	smmu_make_cb_group(base_addr, 37),		\
-	smmu_make_cb_group(base_addr, 38),		\
-	smmu_make_cb_group(base_addr, 39),		\
-	smmu_make_cb_group(base_addr, 40),		\
-	smmu_make_cb_group(base_addr, 41),		\
-	smmu_make_cb_group(base_addr, 42),		\
-	smmu_make_cb_group(base_addr, 43),		\
-	smmu_make_cb_group(base_addr, 44),		\
-	smmu_make_cb_group(base_addr, 45),		\
-	smmu_make_cb_group(base_addr, 46),		\
-	smmu_make_cb_group(base_addr, 47),		\
-	smmu_make_cb_group(base_addr, 48),		\
-	smmu_make_cb_group(base_addr, 49),		\
-	smmu_make_cb_group(base_addr, 50),		\
-	smmu_make_cb_group(base_addr, 51),		\
-	smmu_make_cb_group(base_addr, 52),		\
-	smmu_make_cb_group(base_addr, 53),		\
-	smmu_make_cb_group(base_addr, 54),		\
-	smmu_make_cb_group(base_addr, 55),		\
-	smmu_make_cb_group(base_addr, 56),		\
-	smmu_make_cb_group(base_addr, 57),		\
-	smmu_make_cb_group(base_addr, 58),		\
-	smmu_make_cb_group(base_addr, 59),		\
-	smmu_make_cb_group(base_addr, 60),		\
-	smmu_make_cb_group(base_addr, 61),		\
-	smmu_make_cb_group(base_addr, 62),		\
-	smmu_make_cb_group(base_addr, 63)	/* don't put "," here. */
-
-#define smmu_bypass_cfg \
-	{ \
-		.reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \
-		.val = 0x00000000U, \
+static inline void tegra_smmu_write_32(uint32_t smmu_id,
+			uint32_t off, uint32_t val)
+{
+#if defined(TEGRA_SMMU0_BASE)
+	if (smmu_id == TEGRA_SMMU0) {
+		mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val);
 	}
+#endif
 
-#define _START_OF_TABLE_ \
-	{ \
-		.reg = 0xCAFE05C7U, \
-		.val = 0x00000000U, \
+#if defined(TEGRA_SMMU1_BASE)
+	if (smmu_id == TEGRA_SMMU1) {
+		mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val);
 	}
+#endif
 
-#define _END_OF_TABLE_ \
-	{ \
-		.reg = 0xFFFFFFFFU, \
-		.val = 0xFFFFFFFFU, \
+#if defined(TEGRA_SMMU2_BASE)
+	if (smmu_id == TEGRA_SMMU2) {
+		mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val);
 	}
-
+#endif
+}
 
 void tegra_smmu_init(void);
-void tegra_smmu_save_context(uint64_t smmu_ctx_addr);
-smmu_regs_t *plat_get_smmu_ctx(void);
 uint32_t plat_get_num_smmu_devices(void);
 
 #endif /* SMMU_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h
index 9e2c02b..60174ab 100644
--- a/plat/nvidia/tegra/include/t186/tegra186_private.h
+++ b/plat/nvidia/tegra/include/t186/tegra186_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +10,7 @@
 void tegra186_cpu_reset_handler(void);
 uint64_t tegra186_get_cpu_reset_handler_base(void);
 uint64_t tegra186_get_cpu_reset_handler_size(void);
-uint64_t tegra186_get_smmu_ctx_offset(void);
+uint64_t tegra186_get_mc_ctx_offset(void);
 void tegra186_set_system_suspend_entry(void);
 
 #endif /* TEGRA186_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index 3d037e1..1da9b46 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -73,6 +73,12 @@
 #define TEGRA186_SEC_IRQ_TARGET_MASK	U(0xF3) /* 4 A57 - 2 Denver */
 
 /*******************************************************************************
+ * Clock identifier for the SE device
+ ******************************************************************************/
+#define TEGRA186_CLK_SE			U(103)
+#define TEGRA_CLK_SE			TEGRA186_CLK_SE
+
+/*******************************************************************************
  * Tegra Miscellanous register constants
  ******************************************************************************/
 #define TEGRA_MISC_BASE			U(0x00100000)
@@ -269,8 +275,8 @@
 #define SCRATCH_RESET_VECTOR_LO		SECURE_SCRATCH_RSV1_LO
 #define SCRATCH_RESET_VECTOR_HI		SECURE_SCRATCH_RSV1_HI
 #define SCRATCH_SECURE_BOOTP_FCFG	SECURE_SCRATCH_RSV6
-#define SCRATCH_SMMU_TABLE_ADDR_LO	SECURE_SCRATCH_RSV11_LO
-#define SCRATCH_SMMU_TABLE_ADDR_HI	SECURE_SCRATCH_RSV11_HI
+#define SCRATCH_MC_TABLE_ADDR_LO	SECURE_SCRATCH_RSV11_LO
+#define SCRATCH_MC_TABLE_ADDR_HI	SECURE_SCRATCH_RSV11_HI
 #define SCRATCH_BL31_PARAMS_ADDR	SECURE_SCRATCH_RSV53_LO
 #define SCRATCH_BL31_PLAT_PARAMS_ADDR	SECURE_SCRATCH_RSV53_HI
 #define SCRATCH_TZDRAM_ADDR_LO		SECURE_SCRATCH_RSV55_LO
diff --git a/plat/nvidia/tegra/include/t194/tegra194_private.h b/plat/nvidia/tegra/include/t194/tegra194_private.h
index 8f1deb2..c5a51e9 100644
--- a/plat/nvidia/tegra/include/t194/tegra194_private.h
+++ b/plat/nvidia/tegra/include/t194/tegra194_private.h
@@ -10,7 +10,7 @@
 void tegra194_cpu_reset_handler(void);
 uint64_t tegra194_get_cpu_reset_handler_base(void);
 uint64_t tegra194_get_cpu_reset_handler_size(void);
-uint64_t tegra194_get_smmu_ctx_offset(void);
+uint64_t tegra194_get_mc_ctx_offset(void);
 void tegra194_set_system_suspend_entry(void);
 
 #endif /* TEGRA194_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
index a58ae9d..dc06445 100644
--- a/plat/nvidia/tegra/include/t194/tegra_def.h
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -43,6 +43,12 @@
 #define TEGRA194_SEC_IRQ_TARGET_MASK	U(0xFF) /* 8 Carmel */
 
 /*******************************************************************************
+ * Clock identifier for the SE device
+ ******************************************************************************/
+#define TEGRA194_CLK_SE			U(124)
+#define TEGRA_CLK_SE			TEGRA194_CLK_SE
+
+/*******************************************************************************
  * Tegra Miscellanous register constants
  ******************************************************************************/
 #define TEGRA_MISC_BASE			U(0x00100000)
@@ -197,6 +203,16 @@
  * Tegra scratch registers constants
  ******************************************************************************/
 #define TEGRA_SCRATCH_BASE		U(0x0C390000)
+#define  SECURE_SCRATCH_RSV68_LO	U(0x284)
+#define  SECURE_SCRATCH_RSV68_HI	U(0x288)
+#define  SECURE_SCRATCH_RSV69_LO	U(0x28C)
+#define  SECURE_SCRATCH_RSV69_HI	U(0x290)
+#define  SECURE_SCRATCH_RSV70_LO	U(0x294)
+#define  SECURE_SCRATCH_RSV70_HI	U(0x298)
+#define  SECURE_SCRATCH_RSV71_LO	U(0x29C)
+#define  SECURE_SCRATCH_RSV71_HI	U(0x2A0)
+#define  SECURE_SCRATCH_RSV72_LO	U(0x2A4)
+#define  SECURE_SCRATCH_RSV72_HI	U(0x2A8)
 #define  SECURE_SCRATCH_RSV75   	U(0x2BC)
 #define  SECURE_SCRATCH_RSV81_LO	U(0x2EC)
 #define  SECURE_SCRATCH_RSV81_HI	U(0x2F0)
@@ -215,8 +231,8 @@
 #define  SCRATCH_BL31_PLAT_PARAMS_HI_ADDR_SHIFT U(16)
 #define SCRATCH_BL31_PLAT_PARAMS_LO_ADDR SECURE_SCRATCH_RSV81_HI
 #define SCRATCH_SECURE_BOOTP_FCFG	SECURE_SCRATCH_RSV97
-#define SCRATCH_SMMU_TABLE_ADDR_LO	SECURE_SCRATCH_RSV99_LO
-#define SCRATCH_SMMU_TABLE_ADDR_HI	SECURE_SCRATCH_RSV99_HI
+#define SCRATCH_MC_TABLE_ADDR_LO	SECURE_SCRATCH_RSV99_LO
+#define SCRATCH_MC_TABLE_ADDR_HI	SECURE_SCRATCH_RSV99_HI
 #define SCRATCH_RESET_VECTOR_LO		SECURE_SCRATCH_RSV109_LO
 #define SCRATCH_RESET_VECTOR_HI		SECURE_SCRATCH_RSV109_HI
 
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index e8bce5e..f3013a8 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -44,6 +44,11 @@
 #define SC7ENTRY_FW_HEADER_SIZE_BYTES	U(0x400)
 
 /*******************************************************************************
+ * Counter-timer physical secure timer PPI
+ ******************************************************************************/
+#define TEGRA210_TIMER1_IRQ		32
+
+/*******************************************************************************
  * iRAM memory constants
  ******************************************************************************/
 #define TEGRA_IRAM_BASE			U(0x40000000)
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index a97496b..09377bb 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -516,6 +516,171 @@
 	}
 }
 
+
+/*******************************************************************************
+ * Array to hold MC context for Tegra186
+ ******************************************************************************/
+static __attribute__((aligned(16))) mc_regs_t tegra186_mc_context[] = {
+	_START_OF_TABLE_,
+	mc_make_sid_security_cfg(SCEW),
+	mc_make_sid_security_cfg(AFIR),
+	mc_make_sid_security_cfg(NVDISPLAYR1),
+	mc_make_sid_security_cfg(XUSB_DEVR),
+	mc_make_sid_security_cfg(VICSRD1),
+	mc_make_sid_security_cfg(NVENCSWR),
+	mc_make_sid_security_cfg(TSECSRDB),
+	mc_make_sid_security_cfg(AXISW),
+	mc_make_sid_security_cfg(SDMMCWAB),
+	mc_make_sid_security_cfg(AONDMAW),
+	mc_make_sid_security_cfg(GPUSWR2),
+	mc_make_sid_security_cfg(SATAW),
+	mc_make_sid_security_cfg(UFSHCW),
+	mc_make_sid_security_cfg(AFIW),
+	mc_make_sid_security_cfg(SDMMCR),
+	mc_make_sid_security_cfg(SCEDMAW),
+	mc_make_sid_security_cfg(UFSHCR),
+	mc_make_sid_security_cfg(SDMMCWAA),
+	mc_make_sid_security_cfg(APEDMAW),
+	mc_make_sid_security_cfg(SESWR),
+	mc_make_sid_security_cfg(MPCORER),
+	mc_make_sid_security_cfg(PTCR),
+	mc_make_sid_security_cfg(BPMPW),
+	mc_make_sid_security_cfg(ETRW),
+	mc_make_sid_security_cfg(GPUSRD),
+	mc_make_sid_security_cfg(VICSWR),
+	mc_make_sid_security_cfg(SCEDMAR),
+	mc_make_sid_security_cfg(HDAW),
+	mc_make_sid_security_cfg(ISPWA),
+	mc_make_sid_security_cfg(EQOSW),
+	mc_make_sid_security_cfg(XUSB_HOSTW),
+	mc_make_sid_security_cfg(TSECSWR),
+	mc_make_sid_security_cfg(SDMMCRAA),
+	mc_make_sid_security_cfg(APER),
+	mc_make_sid_security_cfg(VIW),
+	mc_make_sid_security_cfg(APEW),
+	mc_make_sid_security_cfg(AXISR),
+	mc_make_sid_security_cfg(SDMMCW),
+	mc_make_sid_security_cfg(BPMPDMAW),
+	mc_make_sid_security_cfg(ISPRA),
+	mc_make_sid_security_cfg(NVDECSWR),
+	mc_make_sid_security_cfg(XUSB_DEVW),
+	mc_make_sid_security_cfg(NVDECSRD),
+	mc_make_sid_security_cfg(MPCOREW),
+	mc_make_sid_security_cfg(NVDISPLAYR),
+	mc_make_sid_security_cfg(BPMPDMAR),
+	mc_make_sid_security_cfg(NVJPGSWR),
+	mc_make_sid_security_cfg(NVDECSRD1),
+	mc_make_sid_security_cfg(TSECSRD),
+	mc_make_sid_security_cfg(NVJPGSRD),
+	mc_make_sid_security_cfg(SDMMCWA),
+	mc_make_sid_security_cfg(SCER),
+	mc_make_sid_security_cfg(XUSB_HOSTR),
+	mc_make_sid_security_cfg(VICSRD),
+	mc_make_sid_security_cfg(AONDMAR),
+	mc_make_sid_security_cfg(AONW),
+	mc_make_sid_security_cfg(SDMMCRA),
+	mc_make_sid_security_cfg(HOST1XDMAR),
+	mc_make_sid_security_cfg(EQOSR),
+	mc_make_sid_security_cfg(SATAR),
+	mc_make_sid_security_cfg(BPMPR),
+	mc_make_sid_security_cfg(HDAR),
+	mc_make_sid_security_cfg(SDMMCRAB),
+	mc_make_sid_security_cfg(ETRR),
+	mc_make_sid_security_cfg(AONR),
+	mc_make_sid_security_cfg(APEDMAR),
+	mc_make_sid_security_cfg(SESRD),
+	mc_make_sid_security_cfg(NVENCSRD),
+	mc_make_sid_security_cfg(GPUSWR),
+	mc_make_sid_security_cfg(TSECSWRB),
+	mc_make_sid_security_cfg(ISPWB),
+	mc_make_sid_security_cfg(GPUSRD2),
+	mc_make_sid_override_cfg(APER),
+	mc_make_sid_override_cfg(VICSRD),
+	mc_make_sid_override_cfg(NVENCSRD),
+	mc_make_sid_override_cfg(NVJPGSWR),
+	mc_make_sid_override_cfg(AONW),
+	mc_make_sid_override_cfg(BPMPR),
+	mc_make_sid_override_cfg(BPMPW),
+	mc_make_sid_override_cfg(HDAW),
+	mc_make_sid_override_cfg(NVDISPLAYR1),
+	mc_make_sid_override_cfg(APEDMAR),
+	mc_make_sid_override_cfg(AFIR),
+	mc_make_sid_override_cfg(AXISR),
+	mc_make_sid_override_cfg(VICSRD1),
+	mc_make_sid_override_cfg(TSECSRD),
+	mc_make_sid_override_cfg(BPMPDMAW),
+	mc_make_sid_override_cfg(MPCOREW),
+	mc_make_sid_override_cfg(XUSB_HOSTR),
+	mc_make_sid_override_cfg(GPUSWR),
+	mc_make_sid_override_cfg(XUSB_DEVR),
+	mc_make_sid_override_cfg(UFSHCW),
+	mc_make_sid_override_cfg(XUSB_HOSTW),
+	mc_make_sid_override_cfg(SDMMCWAB),
+	mc_make_sid_override_cfg(SATAW),
+	mc_make_sid_override_cfg(SCEDMAR),
+	mc_make_sid_override_cfg(HOST1XDMAR),
+	mc_make_sid_override_cfg(SDMMCWA),
+	mc_make_sid_override_cfg(APEDMAW),
+	mc_make_sid_override_cfg(SESWR),
+	mc_make_sid_override_cfg(AXISW),
+	mc_make_sid_override_cfg(AONDMAW),
+	mc_make_sid_override_cfg(TSECSWRB),
+	mc_make_sid_override_cfg(MPCORER),
+	mc_make_sid_override_cfg(ISPWB),
+	mc_make_sid_override_cfg(AONR),
+	mc_make_sid_override_cfg(BPMPDMAR),
+	mc_make_sid_override_cfg(HDAR),
+	mc_make_sid_override_cfg(SDMMCRA),
+	mc_make_sid_override_cfg(ETRW),
+	mc_make_sid_override_cfg(GPUSWR2),
+	mc_make_sid_override_cfg(EQOSR),
+	mc_make_sid_override_cfg(TSECSWR),
+	mc_make_sid_override_cfg(ETRR),
+	mc_make_sid_override_cfg(NVDECSRD),
+	mc_make_sid_override_cfg(TSECSRDB),
+	mc_make_sid_override_cfg(SDMMCRAA),
+	mc_make_sid_override_cfg(NVDECSRD1),
+	mc_make_sid_override_cfg(SDMMCR),
+	mc_make_sid_override_cfg(NVJPGSRD),
+	mc_make_sid_override_cfg(SCEDMAW),
+	mc_make_sid_override_cfg(SDMMCWAA),
+	mc_make_sid_override_cfg(APEW),
+	mc_make_sid_override_cfg(AONDMAR),
+	mc_make_sid_override_cfg(PTCR),
+	mc_make_sid_override_cfg(SCER),
+	mc_make_sid_override_cfg(ISPRA),
+	mc_make_sid_override_cfg(ISPWA),
+	mc_make_sid_override_cfg(VICSWR),
+	mc_make_sid_override_cfg(SESRD),
+	mc_make_sid_override_cfg(SDMMCW),
+	mc_make_sid_override_cfg(SDMMCRAB),
+	mc_make_sid_override_cfg(EQOSW),
+	mc_make_sid_override_cfg(GPUSRD2),
+	mc_make_sid_override_cfg(SCEW),
+	mc_make_sid_override_cfg(GPUSRD),
+	mc_make_sid_override_cfg(NVDECSWR),
+	mc_make_sid_override_cfg(XUSB_DEVW),
+	mc_make_sid_override_cfg(SATAR),
+	mc_make_sid_override_cfg(NVDISPLAYR),
+	mc_make_sid_override_cfg(VIW),
+	mc_make_sid_override_cfg(UFSHCR),
+	mc_make_sid_override_cfg(NVENCSWR),
+	mc_make_sid_override_cfg(AFIW),
+	mc_smmu_bypass_cfg,	/* TBU settings */
+	_END_OF_TABLE_,
+};
+
+/*******************************************************************************
+ * Handler to return the pointer to the MC's context struct
+ ******************************************************************************/
+static mc_regs_t *tegra186_get_mc_system_suspend_ctx(void)
+{
+	/* index of _END_OF_TABLE_ */
+	tegra186_mc_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_mc_context)) - 1U;
+
+	return tegra186_mc_context;
+}
+
 /*******************************************************************************
  * Struct to hold the memory controller settings
  ******************************************************************************/
@@ -528,6 +693,7 @@
 	.num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs),
 	.reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients,
 	.set_txn_overrides = tegra186_memctrl_set_overrides,
+	.get_mc_system_suspend_ctx = tegra186_get_mc_system_suspend_ctx,
 };
 
 /*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index a0879cc..179dd96 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -22,6 +22,7 @@
 
 #include <bpmp_ipc.h>
 #include <mce.h>
+#include <memctrl_v2.h>
 #include <security_engine.h>
 #include <smmu.h>
 #include <t18x_ari.h>
@@ -99,7 +100,7 @@
 	uint32_t cpu = plat_my_core_pos();
 	const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
 	mce_cstate_info_t cstate_info = { 0 };
-	uint64_t smmu_ctx_base;
+	uint64_t mc_ctx_base;
 	uint32_t val;
 
 	/* get the state ID */
@@ -132,10 +133,10 @@
 		val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
 		mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
 
-		/* save SMMU context to TZDRAM */
-		smmu_ctx_base = params_from_bl2->tzdram_base +
-				tegra186_get_smmu_ctx_offset();
-		tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
+		/* save MC context to TZDRAM */
+		mc_ctx_base = params_from_bl2->tzdram_base +
+				tegra186_get_mc_ctx_offset();
+		tegra_mc_save_context((uintptr_t)mc_ctx_base);
 
 		/* Prepare for system suspend */
 		cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
@@ -294,7 +295,7 @@
 		assert(tegra_bpmp_ipc_init() == 0);
 
 		/* Enable SE clock */
-		ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+		ret = tegra_bpmp_ipc_enable_clock(TEGRA186_CLK_SE);
 		if (ret != 0) {
 			ERROR("Failed to enable clock\n");
 			return ret;
@@ -319,7 +320,7 @@
 		memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
 			 (uintptr_t)BL31_END - (uintptr_t)BL31_BASE);
 
-		ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+		ret = tegra_bpmp_ipc_disable_clock(TEGRA186_CLK_SE);
 		if (ret != 0) {
 			ERROR("Failed to disable clock\n");
 			return ret;
diff --git a/plat/nvidia/tegra/soc/t186/plat_smmu.c b/plat/nvidia/tegra/soc/t186/plat_smmu.c
index b4a7fe5..f1bc235 100644
--- a/plat/nvidia/tegra/soc/t186/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t186/plat_smmu.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,171 +14,6 @@
 #define MAX_NUM_SMMU_DEVICES	U(1)
 
 /*******************************************************************************
- * Array to hold SMMU context for Tegra186
- ******************************************************************************/
-static __attribute__((aligned(16))) smmu_regs_t tegra186_smmu_context[] = {
-	_START_OF_TABLE_,
-	mc_make_sid_security_cfg(SCEW),
-	mc_make_sid_security_cfg(AFIR),
-	mc_make_sid_security_cfg(NVDISPLAYR1),
-	mc_make_sid_security_cfg(XUSB_DEVR),
-	mc_make_sid_security_cfg(VICSRD1),
-	mc_make_sid_security_cfg(NVENCSWR),
-	mc_make_sid_security_cfg(TSECSRDB),
-	mc_make_sid_security_cfg(AXISW),
-	mc_make_sid_security_cfg(SDMMCWAB),
-	mc_make_sid_security_cfg(AONDMAW),
-	mc_make_sid_security_cfg(GPUSWR2),
-	mc_make_sid_security_cfg(SATAW),
-	mc_make_sid_security_cfg(UFSHCW),
-	mc_make_sid_security_cfg(AFIW),
-	mc_make_sid_security_cfg(SDMMCR),
-	mc_make_sid_security_cfg(SCEDMAW),
-	mc_make_sid_security_cfg(UFSHCR),
-	mc_make_sid_security_cfg(SDMMCWAA),
-	mc_make_sid_security_cfg(APEDMAW),
-	mc_make_sid_security_cfg(SESWR),
-	mc_make_sid_security_cfg(MPCORER),
-	mc_make_sid_security_cfg(PTCR),
-	mc_make_sid_security_cfg(BPMPW),
-	mc_make_sid_security_cfg(ETRW),
-	mc_make_sid_security_cfg(GPUSRD),
-	mc_make_sid_security_cfg(VICSWR),
-	mc_make_sid_security_cfg(SCEDMAR),
-	mc_make_sid_security_cfg(HDAW),
-	mc_make_sid_security_cfg(ISPWA),
-	mc_make_sid_security_cfg(EQOSW),
-	mc_make_sid_security_cfg(XUSB_HOSTW),
-	mc_make_sid_security_cfg(TSECSWR),
-	mc_make_sid_security_cfg(SDMMCRAA),
-	mc_make_sid_security_cfg(APER),
-	mc_make_sid_security_cfg(VIW),
-	mc_make_sid_security_cfg(APEW),
-	mc_make_sid_security_cfg(AXISR),
-	mc_make_sid_security_cfg(SDMMCW),
-	mc_make_sid_security_cfg(BPMPDMAW),
-	mc_make_sid_security_cfg(ISPRA),
-	mc_make_sid_security_cfg(NVDECSWR),
-	mc_make_sid_security_cfg(XUSB_DEVW),
-	mc_make_sid_security_cfg(NVDECSRD),
-	mc_make_sid_security_cfg(MPCOREW),
-	mc_make_sid_security_cfg(NVDISPLAYR),
-	mc_make_sid_security_cfg(BPMPDMAR),
-	mc_make_sid_security_cfg(NVJPGSWR),
-	mc_make_sid_security_cfg(NVDECSRD1),
-	mc_make_sid_security_cfg(TSECSRD),
-	mc_make_sid_security_cfg(NVJPGSRD),
-	mc_make_sid_security_cfg(SDMMCWA),
-	mc_make_sid_security_cfg(SCER),
-	mc_make_sid_security_cfg(XUSB_HOSTR),
-	mc_make_sid_security_cfg(VICSRD),
-	mc_make_sid_security_cfg(AONDMAR),
-	mc_make_sid_security_cfg(AONW),
-	mc_make_sid_security_cfg(SDMMCRA),
-	mc_make_sid_security_cfg(HOST1XDMAR),
-	mc_make_sid_security_cfg(EQOSR),
-	mc_make_sid_security_cfg(SATAR),
-	mc_make_sid_security_cfg(BPMPR),
-	mc_make_sid_security_cfg(HDAR),
-	mc_make_sid_security_cfg(SDMMCRAB),
-	mc_make_sid_security_cfg(ETRR),
-	mc_make_sid_security_cfg(AONR),
-	mc_make_sid_security_cfg(APEDMAR),
-	mc_make_sid_security_cfg(SESRD),
-	mc_make_sid_security_cfg(NVENCSRD),
-	mc_make_sid_security_cfg(GPUSWR),
-	mc_make_sid_security_cfg(TSECSWRB),
-	mc_make_sid_security_cfg(ISPWB),
-	mc_make_sid_security_cfg(GPUSRD2),
-	mc_make_sid_override_cfg(APER),
-	mc_make_sid_override_cfg(VICSRD),
-	mc_make_sid_override_cfg(NVENCSRD),
-	mc_make_sid_override_cfg(NVJPGSWR),
-	mc_make_sid_override_cfg(AONW),
-	mc_make_sid_override_cfg(BPMPR),
-	mc_make_sid_override_cfg(BPMPW),
-	mc_make_sid_override_cfg(HDAW),
-	mc_make_sid_override_cfg(NVDISPLAYR1),
-	mc_make_sid_override_cfg(APEDMAR),
-	mc_make_sid_override_cfg(AFIR),
-	mc_make_sid_override_cfg(AXISR),
-	mc_make_sid_override_cfg(VICSRD1),
-	mc_make_sid_override_cfg(TSECSRD),
-	mc_make_sid_override_cfg(BPMPDMAW),
-	mc_make_sid_override_cfg(MPCOREW),
-	mc_make_sid_override_cfg(XUSB_HOSTR),
-	mc_make_sid_override_cfg(GPUSWR),
-	mc_make_sid_override_cfg(XUSB_DEVR),
-	mc_make_sid_override_cfg(UFSHCW),
-	mc_make_sid_override_cfg(XUSB_HOSTW),
-	mc_make_sid_override_cfg(SDMMCWAB),
-	mc_make_sid_override_cfg(SATAW),
-	mc_make_sid_override_cfg(SCEDMAR),
-	mc_make_sid_override_cfg(HOST1XDMAR),
-	mc_make_sid_override_cfg(SDMMCWA),
-	mc_make_sid_override_cfg(APEDMAW),
-	mc_make_sid_override_cfg(SESWR),
-	mc_make_sid_override_cfg(AXISW),
-	mc_make_sid_override_cfg(AONDMAW),
-	mc_make_sid_override_cfg(TSECSWRB),
-	mc_make_sid_override_cfg(MPCORER),
-	mc_make_sid_override_cfg(ISPWB),
-	mc_make_sid_override_cfg(AONR),
-	mc_make_sid_override_cfg(BPMPDMAR),
-	mc_make_sid_override_cfg(HDAR),
-	mc_make_sid_override_cfg(SDMMCRA),
-	mc_make_sid_override_cfg(ETRW),
-	mc_make_sid_override_cfg(GPUSWR2),
-	mc_make_sid_override_cfg(EQOSR),
-	mc_make_sid_override_cfg(TSECSWR),
-	mc_make_sid_override_cfg(ETRR),
-	mc_make_sid_override_cfg(NVDECSRD),
-	mc_make_sid_override_cfg(TSECSRDB),
-	mc_make_sid_override_cfg(SDMMCRAA),
-	mc_make_sid_override_cfg(NVDECSRD1),
-	mc_make_sid_override_cfg(SDMMCR),
-	mc_make_sid_override_cfg(NVJPGSRD),
-	mc_make_sid_override_cfg(SCEDMAW),
-	mc_make_sid_override_cfg(SDMMCWAA),
-	mc_make_sid_override_cfg(APEW),
-	mc_make_sid_override_cfg(AONDMAR),
-	mc_make_sid_override_cfg(PTCR),
-	mc_make_sid_override_cfg(SCER),
-	mc_make_sid_override_cfg(ISPRA),
-	mc_make_sid_override_cfg(ISPWA),
-	mc_make_sid_override_cfg(VICSWR),
-	mc_make_sid_override_cfg(SESRD),
-	mc_make_sid_override_cfg(SDMMCW),
-	mc_make_sid_override_cfg(SDMMCRAB),
-	mc_make_sid_override_cfg(EQOSW),
-	mc_make_sid_override_cfg(GPUSRD2),
-	mc_make_sid_override_cfg(SCEW),
-	mc_make_sid_override_cfg(GPUSRD),
-	mc_make_sid_override_cfg(NVDECSWR),
-	mc_make_sid_override_cfg(XUSB_DEVW),
-	mc_make_sid_override_cfg(SATAR),
-	mc_make_sid_override_cfg(NVDISPLAYR),
-	mc_make_sid_override_cfg(VIW),
-	mc_make_sid_override_cfg(UFSHCR),
-	mc_make_sid_override_cfg(NVENCSWR),
-	mc_make_sid_override_cfg(AFIW),
-	smmu_make_cfg(TEGRA_SMMU0_BASE),
-	smmu_bypass_cfg,	/* TBU settings */
-	_END_OF_TABLE_,
-};
-
-/*******************************************************************************
- * Handler to return the pointer to the SMMU's context struct
- ******************************************************************************/
-smmu_regs_t *plat_get_smmu_ctx(void)
-{
-	/* index of _END_OF_TABLE_ */
-	tegra186_smmu_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_smmu_context)) - 1U;
-
-	return tegra186_smmu_context;
-}
-
-/*******************************************************************************
  * Handler to return the support SMMU devices number
  ******************************************************************************/
 uint32_t plat_get_num_smmu_devices(void)
diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
index db69234..818c24b 100644
--- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +14,7 @@
 
 #define TEGRA186_STATE_SYSTEM_SUSPEND	0x5C7
 #define TEGRA186_STATE_SYSTEM_RESUME	0x600D
-#define TEGRA186_SMMU_CTX_SIZE		0x420
+#define TEGRA186_MC_CTX_SIZE		0x93
 
 	.globl	tegra186_cpu_reset_handler
 
@@ -69,8 +70,8 @@
 	 *
 	 * 0x000: secure world's entrypoint
 	 * 0x008: BL31 size (RO + RW)
-	 * 0x00C: SMMU context start
-	 * 0x42C: SMMU context end
+	 * 0x00C: MC context start
+	 * 0x42C: MC context end
 	 */
 
 	.align 4
@@ -85,9 +86,9 @@
 	.quad	0
 
 	.align 4
-	.globl	__tegra186_smmu_context
-__tegra186_smmu_context:
-	.rept	TEGRA186_SMMU_CTX_SIZE
+	.globl	__tegra186_mc_context
+__tegra186_mc_context:
+	.rept	TEGRA186_MC_CTX_SIZE
 	.quad	0
 	.endr
 	.size	__tegra186_cpu_reset_handler_data, \
@@ -99,7 +100,7 @@
 
 	.globl tegra186_get_cpu_reset_handler_size
 	.globl tegra186_get_cpu_reset_handler_base
-	.globl tegra186_get_smmu_ctx_offset
+	.globl tegra186_get_mc_ctx_offset
 	.globl tegra186_set_system_suspend_entry
 
 /* return size of the CPU reset handler */
@@ -116,13 +117,13 @@
 	ret
 endfunc tegra186_get_cpu_reset_handler_base
 
-/* return the size of the SMMU context */
-func tegra186_get_smmu_ctx_offset
-	adr	x0, __tegra186_smmu_context
+/* return the size of the MC context */
+func tegra186_get_mc_ctx_offset
+	adr	x0, __tegra186_mc_context
 	adr	x1, tegra186_cpu_reset_handler
 	sub	x0, x0, x1
 	ret
-endfunc tegra186_get_smmu_ctx_offset
+endfunc tegra186_get_mc_ctx_offset
 
 /* set system suspend state before SC7 entry */
 func tegra186_set_system_suspend_entry
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/se.h b/plat/nvidia/tegra/soc/t194/drivers/include/se.h
index e7cf88d..7de55a7 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/se.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/se.h
@@ -7,6 +7,8 @@
 #ifndef SE_H
 #define SE_H
 
+int32_t tegra_se_calculate_save_sha256(uint64_t src_addr,
+						uint32_t src_len_inbyte);
 int32_t tegra_se_suspend(void);
 void tegra_se_resume(void);
 
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
index a3b3389..ccdc94d 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
@@ -28,6 +28,14 @@
 #define MAX_TIMEOUT_MS		U(100)	/* Timeout in 100ms */
 #define NUM_SE_REGS_TO_SAVE	U(4)
 
+#define SE0_MAX_BUSY_TIMEOUT_MS		U(100)	/* 100ms Timeout Expired */
+#define BYTES_IN_WORD			U(4)
+#define SHA256_MAX_HASH_RESULT		U(7)
+#define SHA256_DST_SIZE			U(32)
+#define SHA_FIRST_OP			U(1)
+#define MAX_SHA_ENGINE_CHUNK_SIZE	U(0xFFFFFF)
+#define SHA256_MSG_LENGTH_ONETIME	U(0xFFFF)
+
 /*******************************************************************************
  * Data structure and global variables
  ******************************************************************************/
@@ -175,6 +183,270 @@
 	return ret;
 }
 
+/*
+ * Check that SE operation has completed after kickoff
+ * This function is invoked after an SE operation has been started,
+ * and it checks the following conditions:
+ * 1. SE0_INT_STATUS = SE0_OP_DONE
+ * 2. SE0_STATUS = IDLE
+ * 3. SE0_ERR_STATUS is clean.
+ */
+static int32_t tegra_se_sha256_hash_operation_complete(void)
+{
+	uint32_t val = 0U;
+
+	/* Poll the SE interrupt register to ensure H/W operation complete */
+	val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+	while (SE0_INT_OP_DONE(val) == SE0_INT_OP_DONE_CLEAR) {
+		val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+		if (SE0_INT_OP_DONE(val) != SE0_INT_OP_DONE_CLEAR) {
+			break;
+		}
+	}
+
+	/* Poll the SE status idle to ensure H/W operation complete */
+	val = tegra_se_read_32(SE0_SHA_STATUS_0);
+	while (val != SE0_SHA_STATUS_IDLE) {
+		val = tegra_se_read_32(SE0_SHA_STATUS_0);
+		if (val == SE0_SHA_STATUS_IDLE) {
+			break;
+		}
+	}
+
+	/* Ensure that no errors are thrown during operation */
+	val = tegra_se_read_32(SE0_ERR_STATUS_REG_OFFSET);
+	if (val != 0U) {
+		ERROR("%s: error during SE operation! 0x%x", __func__,
+				val);
+		return -ENOTSUP;
+	}
+
+	return 0;
+}
+
+/*
+ * Security engine primitive normal operations
+ */
+static int32_t tegra_se_start_normal_operation(uint64_t src_addr,
+		uint32_t nbytes, uint32_t last_buf, uint32_t src_len_inbytes)
+{
+	uint32_t val = 0U;
+	uint32_t src_in_lo;
+	uint32_t src_in_msb;
+	uint32_t src_in_hi;
+	int32_t ret = 0;
+
+	if ((src_addr == 0ULL) || (nbytes == 0U))
+		return -EINVAL;
+
+	src_in_lo = (uint32_t)src_addr;
+	src_in_msb = (uint32_t)((src_addr >> 32U) & 0xFFU);
+	src_in_hi = ((src_in_msb << SE0_IN_HI_ADDR_HI_0_MSB_SHIFT) |
+				(nbytes & MAX_SHA_ENGINE_CHUNK_SIZE));
+
+	/* set SRC_IN_ADDR_LO and SRC_IN_ADDR_HI*/
+	tegra_se_write_32(SE0_IN_ADDR, src_in_lo);
+	tegra_se_write_32(SE0_IN_HI_ADDR_HI, src_in_hi);
+
+	val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET);
+	if (val > 0U) {
+		tegra_se_write_32(SE0_INT_STATUS_REG_OFFSET, 0x0U);
+	}
+
+	/* Enable SHA interrupt for SE0 Operation */
+	tegra_se_write_32(SE0_SHA_INT_ENABLE, 0x1aU);
+
+	/* flush to DRAM for SE to use the updated contents */
+	flush_dcache_range(src_addr, src_len_inbytes);
+
+	/* Start SHA256 operation */
+	if (last_buf == 1U) {
+		tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START |
+				SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD);
+	} else {
+		tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START);
+	}
+
+	return ret;
+}
+
+static int32_t tegra_se_calculate_sha256_hash(uint64_t src_addr,
+						uint32_t src_len_inbyte)
+{
+	uint32_t val, last_buf, i;
+	int32_t ret = 0;
+	uint32_t operations;
+	uint64_t src_len_inbits;
+	uint32_t len_bits_msb;
+	uint32_t len_bits_lsb;
+	uint32_t number_of_operations, max_bytes, bytes_left, remaining_bytes;
+
+	if (src_len_inbyte > MAX_SHA_ENGINE_CHUNK_SIZE) {
+		ERROR("SHA input chunk size too big: 0x%x\n", src_len_inbyte);
+		return -EINVAL;
+	}
+
+	if (src_addr == 0ULL) {
+		return -EINVAL;
+	}
+
+	/* number of bytes per operation */
+	max_bytes = (SHA256_HASH_SIZE_BYTES * SHA256_MSG_LENGTH_ONETIME);
+
+	src_len_inbits = (uint32_t)(src_len_inbyte * 8U);
+	len_bits_msb = (uint32_t)(src_len_inbits >> 32U);
+	len_bits_lsb = (uint32_t)src_len_inbits;
+
+	/* program SE0_CONFIG for SHA256 operation */
+	val =  (uint32_t)(SE0_CONFIG_ENC_ALG_SHA | SE0_CONFIG_ENC_MODE_SHA256 |
+		SE0_CONFIG_DEC_ALG_NOP | SE0_CONFIG_DST_HASHREG);
+	tegra_se_write_32(SE0_SHA_CONFIG, val);
+
+	/* set SE0_SHA_MSG_LENGTH registers */
+	tegra_se_write_32(SE0_SHA_MSG_LENGTH_0, len_bits_lsb);
+	tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb);
+	tegra_se_write_32(SE0_SHA_MSG_LENGTH_1, len_bits_msb);
+
+	/* zero out unused SE0_SHA_MSG_LENGTH and SE0_SHA_MSG_LEFT */
+	tegra_se_write_32(SE0_SHA_MSG_LENGTH_2, 0U);
+	tegra_se_write_32(SE0_SHA_MSG_LENGTH_3, 0U);
+	tegra_se_write_32(SE0_SHA_MSG_LEFT_1, 0U);
+	tegra_se_write_32(SE0_SHA_MSG_LEFT_2, 0U);
+	tegra_se_write_32(SE0_SHA_MSG_LEFT_3, 0U);
+
+	number_of_operations = (src_len_inbyte / max_bytes);
+	remaining_bytes = (src_len_inbyte % max_bytes);
+	if (remaining_bytes > 0U) {
+		number_of_operations += 1U;
+	}
+
+	/*
+	 * 1. Operations == 1:	program SE0_SHA_TASK register to initiate SHA256
+	 *			hash generation by setting
+	 *			1(SE0_SHA_CONFIG_HW_INIT_HASH) to SE0_SHA_TASK
+	 *			and start SHA256-normal operation.
+	 * 2. 1 < Operations < number_of_operations: program SE0_SHA_TASK to
+	 *			0(SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE) to load
+	 *			intermediate SHA256 digest result from
+	 *			HASH_RESULT register to continue SHA256
+	 *			generation and start SHA256-normal operation.
+	 * 3. Operations == number_of_operations: continue with step 2 and set
+	 *			max_bytes to bytes_left to process final
+	 *			hash-result generation and start SHA256-normal
+	 *			operation.
+	 */
+	bytes_left = src_len_inbyte;
+	for (operations = 1U; operations <= number_of_operations;
+								operations++) {
+		if (operations == SHA_FIRST_OP) {
+			val = SE0_SHA_CONFIG_HW_INIT_HASH;
+		} else {
+			/* Load intermediate SHA digest result to
+			 * SHA:HASH_RESULT(0..7) to continue the SHA
+			 * calculation and tell the SHA engine to use it.
+			 */
+			for (i = 0U; (i / BYTES_IN_WORD) <=
+				SHA256_MAX_HASH_RESULT; i += BYTES_IN_WORD) {
+				val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 +
+									i);
+				tegra_se_write_32(SE0_SHA_HASH_RESULT_0 + i,
+									val);
+			}
+			val = SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE;
+			if (len_bits_lsb <= (max_bytes * 8U)) {
+				len_bits_lsb = (remaining_bytes * 8U);
+			} else {
+				len_bits_lsb -= (max_bytes * 8U);
+			}
+			tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb);
+		}
+		tegra_se_write_32(SE0_SHA_TASK_CONFIG, val);
+
+		max_bytes = (SHA256_HASH_SIZE_BYTES *
+						SHA256_MSG_LENGTH_ONETIME);
+		if (bytes_left < max_bytes) {
+			max_bytes = bytes_left;
+			last_buf = 1U;
+		} else {
+			bytes_left = bytes_left - max_bytes;
+			last_buf = 0U;
+		}
+		/* start operation */
+		ret = tegra_se_start_normal_operation(src_addr, max_bytes,
+					last_buf, src_len_inbyte);
+		if (ret != 0) {
+			ERROR("Error during SE operation! 0x%x", ret);
+			return -EINVAL;
+		}
+	}
+
+	return ret;
+}
+
+static int32_t tegra_se_save_sha256_pmc_scratch(void)
+{
+	uint32_t val = 0U, hash_offset = 0U, scratch_offset = 0U;
+	int32_t ret;
+
+	/* Check SE0 operation status */
+	ret = tegra_se_sha256_hash_operation_complete();
+	if (ret != 0) {
+		ERROR("SE operation complete Failed! 0x%x", ret);
+		return ret;
+	}
+
+	for (scratch_offset = SECURE_SCRATCH_TZDRAM_SHA256_HASH_START;
+			scratch_offset <= SECURE_SCRATCH_TZDRAM_SHA256_HASH_END;
+					scratch_offset += BYTES_IN_WORD) {
+		val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + hash_offset);
+		mmio_write_32((uint32_t)(TEGRA_SCRATCH_BASE + scratch_offset),
+									val);
+		hash_offset += BYTES_IN_WORD;
+	}
+	return 0;
+}
+
+/*
+ * Handler to generate SHA256 and save HASH-result to pmc-scratch register
+ */
+int32_t tegra_se_calculate_save_sha256(uint64_t src_addr,
+						uint32_t src_len_inbyte)
+{
+	uint32_t security;
+	int32_t val = 0;
+
+	/* Set SE_SOFT_SETTINGS=SE_SECURE to prevent NS process to change SE
+	 * registers.
+	 */
+	security = tegra_se_read_32(SE0_SECURITY);
+	tegra_se_write_32(SE0_SECURITY, security | SE0_SECURITY_SE_SOFT_SETTING);
+
+	/* Bootrom enable IN_ID bit in SE0_SHA_GSCID_0 register during SC7-exit, causing
+	 * SE0 ignores SE0 operation, and therefore failure of 2nd iteration of SC7 cycle.
+	 */
+	tegra_se_write_32(SE0_SHA_GSCID_0, 0x0U);
+
+	/* Calculate SHA256 of BL31 */
+	val = tegra_se_calculate_sha256_hash(src_addr, src_len_inbyte);
+	if (val != 0) {
+		ERROR("%s: SHA256 generation failed\n", __func__);
+		return val;
+	}
+
+	/*
+	 * Reset SE_SECURE to previous value.
+	 */
+	tegra_se_write_32(SE0_SECURITY, security);
+
+	/* copy sha256_dst to PMC Scratch register */
+	val = tegra_se_save_sha256_pmc_scratch();
+	if (val != 0) {
+		ERROR("%s: SE0 status Error.\n", __func__);
+	}
+
+	return val;
+}
+
 /*
  * Handler to power down the SE hardware blocks - SE, RNG1 and PKA1. This
  * needs to be called only during System Suspend.
@@ -187,7 +459,7 @@
 	assert(tegra_bpmp_ipc_init() == 0);
 
 	/* Enable SE clock before SE context save */
-	ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+	ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE);
 	assert(ret == 0);
 
 	/* save SE registers */
@@ -203,7 +475,7 @@
 	}
 
 	/* Disable SE clock after SE context save */
-	ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+	ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE);
 	assert(ret == 0);
 
 	return ret;
@@ -220,7 +492,7 @@
 	assert(tegra_bpmp_ipc_init() == 0);
 
 	/* Enable SE clock before SE context restore */
-	ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+	ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE);
 	assert(ret == 0);
 
 	/*
@@ -235,6 +507,6 @@
 	mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]);
 
 	/* Disable SE clock after SE context restore */
-	ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+	ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE);
 	assert(ret == 0);
 }
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
index 577217b..fc118aa 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
@@ -9,6 +9,86 @@
 #define SE_PRIVATE_H
 
 #include <lib/utils_def.h>
+#include <tegra_def.h>
+
+/* SE0 security register */
+#define SE0_SECURITY				U(0x18)
+#define SE0_SECURITY_SE_SOFT_SETTING		(((uint32_t)1) << 16U)
+
+/* SE0 SHA GSCID register */
+#define SE0_SHA_GSCID_0				U(0x100)
+
+/* SE0 config register */
+#define SE0_SHA_CONFIG				U(0x104)
+#define SE0_SHA_TASK_CONFIG			U(0x108)
+#define SE0_SHA_CONFIG_HW_INIT_HASH		(((uint32_t)1) << 0U)
+#define SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE	U(0)
+
+#define SE0_CONFIG_ENC_ALG_SHIFT		U(12)
+#define SE0_CONFIG_ENC_ALG_SHA	\
+		(((uint32_t)3) << SE0_CONFIG_ENC_ALG_SHIFT)
+#define SE0_CONFIG_DEC_ALG_SHIFT		U(8)
+#define SE0_CONFIG_DEC_ALG_NOP	\
+		(((uint32_t)0) << SE0_CONFIG_DEC_ALG_SHIFT)
+#define SE0_CONFIG_DST_SHIFT			U(2)
+#define SE0_CONFIG_DST_HASHREG	\
+		(((uint32_t)1) << SE0_CONFIG_DST_SHIFT)
+#define SHA256_HASH_SIZE_BYTES			U(256)
+
+#define SE0_CONFIG_ENC_MODE_SHIFT		U(24)
+#define SE0_CONFIG_ENC_MODE_SHA256	\
+			(((uint32_t)5) << SE0_CONFIG_ENC_MODE_SHIFT)
+
+/* SHA input message length */
+#define SE0_IN_ADDR				U(0x10c)
+#define SE0_IN_HI_ADDR_HI			U(0x110)
+#define SE0_IN_HI_ADDR_HI_0_MSB_SHIFT		U(24)
+
+/* SHA input message length */
+#define SE0_SHA_MSG_LENGTH_0			U(0x11c)
+#define SE0_SHA_MSG_LENGTH_1			U(0x120)
+#define SE0_SHA_MSG_LENGTH_2			U(0x124)
+#define SE0_SHA_MSG_LENGTH_3			U(0x128)
+
+/* SHA input message left  */
+#define SE0_SHA_MSG_LEFT_0			U(0x12c)
+#define SE0_SHA_MSG_LEFT_1			U(0x130)
+#define SE0_SHA_MSG_LEFT_2			U(0x134)
+#define SE0_SHA_MSG_LEFT_3			U(0x138)
+
+/* SE HASH-RESULT */
+#define SE0_SHA_HASH_RESULT_0			U(0x13c)
+
+/* SE OPERATION */
+#define SE0_OPERATION_REG_OFFSET		U(0x17c)
+#define SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT	U(16)
+#define SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD	\
+		((uint32_t)0x1 << SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT)
+#define SE0_OPERATION_SHIFT			U(0)
+#define SE0_OP_START	\
+		(((uint32_t)0x1) << SE0_OPERATION_SHIFT)
+
+/* SE Interrupt */
+#define SE0_SHA_INT_ENABLE			U(0x180)
+
+#define SE0_INT_STATUS_REG_OFFSET		U(0x184)
+#define SE0_INT_OP_DONE_SHIFT			U(4)
+#define SE0_INT_OP_DONE_CLEAR	\
+		(((uint32_t)0U) << SE0_INT_OP_DONE_SHIFT)
+#define SE0_INT_OP_DONE(x)	\
+		((x) & (((uint32_t)0x1U) << SE0_INT_OP_DONE_SHIFT))
+
+/* SE SHA Status */
+#define SE0_SHA_STATUS_0			U(0x188)
+#define SE0_SHA_STATUS_IDLE			U(0)
+
+/* SE error status */
+#define SE0_ERR_STATUS_REG_OFFSET		U(0x18c)
+#define SE0_ERR_STATUS_CLEAR			U(0)
+
+/* SE error status */
+#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_START	SECURE_SCRATCH_RSV68_LO
+#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_END	SECURE_SCRATCH_RSV71_HI
 
 /* SE0_INT_ENABLE_0 */
 #define SE0_INT_ENABLE				U(0x88)
@@ -20,7 +100,7 @@
 
 /* SE0_SHA_INT_STATUS_0 */
 #define SHA_INT_STATUS				U(0x184)
-#define  SHA_SE_OP_DONE				(U(1) << 4)
+#define SHA_SE_OP_DONE				(U(1) << 4)
 
 /* SE0_SHA_ERR_STATUS_0 */
 #define SHA_ERR_STATUS				U(0x18C)
diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
index d5f72b6..2d5f8e3 100644
--- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
@@ -15,12 +15,15 @@
  * Array to hold stream_id override config register offsets
  ******************************************************************************/
 const static uint32_t tegra194_streamid_override_regs[] = {
+	MC_STREAMID_OVERRIDE_CFG_PTCR,
 	MC_STREAMID_OVERRIDE_CFG_HDAR,
 	MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR,
 	MC_STREAMID_OVERRIDE_CFG_NVENCSRD,
 	MC_STREAMID_OVERRIDE_CFG_SATAR,
+	MC_STREAMID_OVERRIDE_CFG_MPCORER,
 	MC_STREAMID_OVERRIDE_CFG_NVENCSWR,
 	MC_STREAMID_OVERRIDE_CFG_HDAW,
+	MC_STREAMID_OVERRIDE_CFG_MPCOREW,
 	MC_STREAMID_OVERRIDE_CFG_SATAW,
 	MC_STREAMID_OVERRIDE_CFG_ISPRA,
 	MC_STREAMID_OVERRIDE_CFG_ISPFALR,
@@ -131,6 +134,9 @@
 	MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1,
 	MC_STREAMID_OVERRIDE_CFG_ISPRA1,
 	MC_STREAMID_OVERRIDE_CFG_PCIE0R1,
+	MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD,
+	MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1,
+	MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR,
 	MC_STREAMID_OVERRIDE_CFG_MIU0R,
 	MC_STREAMID_OVERRIDE_CFG_MIU0W,
 	MC_STREAMID_OVERRIDE_CFG_MIU1R,
@@ -142,19 +148,26 @@
 	MC_STREAMID_OVERRIDE_CFG_MIU4R,
 	MC_STREAMID_OVERRIDE_CFG_MIU4W,
 	MC_STREAMID_OVERRIDE_CFG_MIU5R,
-	MC_STREAMID_OVERRIDE_CFG_MIU5W
+	MC_STREAMID_OVERRIDE_CFG_MIU5W,
+	MC_STREAMID_OVERRIDE_CFG_MIU6R,
+	MC_STREAMID_OVERRIDE_CFG_MIU6W,
+	MC_STREAMID_OVERRIDE_CFG_MIU7R,
+	MC_STREAMID_OVERRIDE_CFG_MIU7W
 };
 
 /*******************************************************************************
  * Array to hold the security configs for stream IDs
  ******************************************************************************/
 const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = {
+	mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE),
@@ -265,6 +278,9 @@
 	mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(PCIE0R1, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(NVDEC1SRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(NVDEC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(NVDEC1SWR, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, DISABLE),
@@ -276,17 +292,290 @@
 	mc_make_sec_cfg(MIU4R, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(MIU4W, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(MIU5R, NON_SECURE, OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE)
+	mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(MIU6R, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(MIU6W, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(MIU7R, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(MIU7W, NON_SECURE, OVERRIDE, DISABLE)
 };
 
 /*******************************************************************************
+ * Array to hold MC context for Tegra194
+ ******************************************************************************/
+static __attribute__((aligned(16))) mc_regs_t tegra194_mc_context[] = {
+	_START_OF_TABLE_,
+	mc_make_sid_security_cfg(HDAR),
+	mc_make_sid_security_cfg(HOST1XDMAR),
+	mc_make_sid_security_cfg(NVENCSRD),
+	mc_make_sid_security_cfg(SATAR),
+	mc_make_sid_security_cfg(NVENCSWR),
+	mc_make_sid_security_cfg(HDAW),
+	mc_make_sid_security_cfg(SATAW),
+	mc_make_sid_security_cfg(ISPRA),
+	mc_make_sid_security_cfg(ISPFALR),
+	mc_make_sid_security_cfg(ISPWA),
+	mc_make_sid_security_cfg(ISPWB),
+	mc_make_sid_security_cfg(XUSB_HOSTR),
+	mc_make_sid_security_cfg(XUSB_HOSTW),
+	mc_make_sid_security_cfg(XUSB_DEVR),
+	mc_make_sid_security_cfg(XUSB_DEVW),
+	mc_make_sid_security_cfg(TSECSRD),
+	mc_make_sid_security_cfg(TSECSWR),
+	mc_make_sid_security_cfg(SDMMCRA),
+	mc_make_sid_security_cfg(SDMMCR),
+	mc_make_sid_security_cfg(SDMMCRAB),
+	mc_make_sid_security_cfg(SDMMCWA),
+	mc_make_sid_security_cfg(SDMMCW),
+	mc_make_sid_security_cfg(SDMMCWAB),
+	mc_make_sid_security_cfg(VICSRD),
+	mc_make_sid_security_cfg(VICSWR),
+	mc_make_sid_security_cfg(VIW),
+	mc_make_sid_security_cfg(NVDECSRD),
+	mc_make_sid_security_cfg(NVDECSWR),
+	mc_make_sid_security_cfg(APER),
+	mc_make_sid_security_cfg(APEW),
+	mc_make_sid_security_cfg(NVJPGSRD),
+	mc_make_sid_security_cfg(NVJPGSWR),
+	mc_make_sid_security_cfg(SESRD),
+	mc_make_sid_security_cfg(SESWR),
+	mc_make_sid_security_cfg(AXIAPR),
+	mc_make_sid_security_cfg(AXIAPW),
+	mc_make_sid_security_cfg(ETRR),
+	mc_make_sid_security_cfg(ETRW),
+	mc_make_sid_security_cfg(TSECSRDB),
+	mc_make_sid_security_cfg(TSECSWRB),
+	mc_make_sid_security_cfg(AXISR),
+	mc_make_sid_security_cfg(AXISW),
+	mc_make_sid_security_cfg(EQOSR),
+	mc_make_sid_security_cfg(EQOSW),
+	mc_make_sid_security_cfg(UFSHCR),
+	mc_make_sid_security_cfg(UFSHCW),
+	mc_make_sid_security_cfg(NVDISPLAYR),
+	mc_make_sid_security_cfg(BPMPR),
+	mc_make_sid_security_cfg(BPMPW),
+	mc_make_sid_security_cfg(BPMPDMAR),
+	mc_make_sid_security_cfg(BPMPDMAW),
+	mc_make_sid_security_cfg(AONR),
+	mc_make_sid_security_cfg(AONW),
+	mc_make_sid_security_cfg(AONDMAR),
+	mc_make_sid_security_cfg(AONDMAW),
+	mc_make_sid_security_cfg(SCER),
+	mc_make_sid_security_cfg(SCEW),
+	mc_make_sid_security_cfg(SCEDMAR),
+	mc_make_sid_security_cfg(SCEDMAW),
+	mc_make_sid_security_cfg(APEDMAR),
+	mc_make_sid_security_cfg(APEDMAW),
+	mc_make_sid_security_cfg(NVDISPLAYR1),
+	mc_make_sid_security_cfg(VICSRD1),
+	mc_make_sid_security_cfg(NVDECSRD1),
+	mc_make_sid_security_cfg(VIFALR),
+	mc_make_sid_security_cfg(VIFALW),
+	mc_make_sid_security_cfg(DLA0RDA),
+	mc_make_sid_security_cfg(DLA0FALRDB),
+	mc_make_sid_security_cfg(DLA0WRA),
+	mc_make_sid_security_cfg(DLA0FALWRB),
+	mc_make_sid_security_cfg(DLA1RDA),
+	mc_make_sid_security_cfg(DLA1FALRDB),
+	mc_make_sid_security_cfg(DLA1WRA),
+	mc_make_sid_security_cfg(DLA1FALWRB),
+	mc_make_sid_security_cfg(PVA0RDA),
+	mc_make_sid_security_cfg(PVA0RDB),
+	mc_make_sid_security_cfg(PVA0RDC),
+	mc_make_sid_security_cfg(PVA0WRA),
+	mc_make_sid_security_cfg(PVA0WRB),
+	mc_make_sid_security_cfg(PVA0WRC),
+	mc_make_sid_security_cfg(PVA1RDA),
+	mc_make_sid_security_cfg(PVA1RDB),
+	mc_make_sid_security_cfg(PVA1RDC),
+	mc_make_sid_security_cfg(PVA1WRA),
+	mc_make_sid_security_cfg(PVA1WRB),
+	mc_make_sid_security_cfg(PVA1WRC),
+	mc_make_sid_security_cfg(RCER),
+	mc_make_sid_security_cfg(RCEW),
+	mc_make_sid_security_cfg(RCEDMAR),
+	mc_make_sid_security_cfg(RCEDMAW),
+	mc_make_sid_security_cfg(NVENC1SRD),
+	mc_make_sid_security_cfg(NVENC1SWR),
+	mc_make_sid_security_cfg(PCIE0R),
+	mc_make_sid_security_cfg(PCIE0W),
+	mc_make_sid_security_cfg(PCIE1R),
+	mc_make_sid_security_cfg(PCIE1W),
+	mc_make_sid_security_cfg(PCIE2AR),
+	mc_make_sid_security_cfg(PCIE2AW),
+	mc_make_sid_security_cfg(PCIE3R),
+	mc_make_sid_security_cfg(PCIE3W),
+	mc_make_sid_security_cfg(PCIE4R),
+	mc_make_sid_security_cfg(PCIE4W),
+	mc_make_sid_security_cfg(PCIE5R),
+	mc_make_sid_security_cfg(PCIE5W),
+	mc_make_sid_security_cfg(ISPFALW),
+	mc_make_sid_security_cfg(DLA0RDA1),
+	mc_make_sid_security_cfg(DLA1RDA1),
+	mc_make_sid_security_cfg(PVA0RDA1),
+	mc_make_sid_security_cfg(PVA0RDB1),
+	mc_make_sid_security_cfg(PVA1RDA1),
+	mc_make_sid_security_cfg(PVA1RDB1),
+	mc_make_sid_security_cfg(PCIE5R1),
+	mc_make_sid_security_cfg(NVENCSRD1),
+	mc_make_sid_security_cfg(NVENC1SRD1),
+	mc_make_sid_security_cfg(ISPRA1),
+	mc_make_sid_security_cfg(PCIE0R1),
+	mc_make_sid_security_cfg(MIU0R),
+	mc_make_sid_security_cfg(MIU0W),
+	mc_make_sid_security_cfg(MIU1R),
+	mc_make_sid_security_cfg(MIU1W),
+	mc_make_sid_security_cfg(MIU2R),
+	mc_make_sid_security_cfg(MIU2W),
+	mc_make_sid_security_cfg(MIU3R),
+	mc_make_sid_security_cfg(MIU3W),
+	mc_make_sid_override_cfg(HDAR),
+	mc_make_sid_override_cfg(HOST1XDMAR),
+	mc_make_sid_override_cfg(NVENCSRD),
+	mc_make_sid_override_cfg(SATAR),
+	mc_make_sid_override_cfg(NVENCSWR),
+	mc_make_sid_override_cfg(HDAW),
+	mc_make_sid_override_cfg(SATAW),
+	mc_make_sid_override_cfg(ISPRA),
+	mc_make_sid_override_cfg(ISPFALR),
+	mc_make_sid_override_cfg(ISPWA),
+	mc_make_sid_override_cfg(ISPWB),
+	mc_make_sid_override_cfg(XUSB_HOSTR),
+	mc_make_sid_override_cfg(XUSB_HOSTW),
+	mc_make_sid_override_cfg(XUSB_DEVR),
+	mc_make_sid_override_cfg(XUSB_DEVW),
+	mc_make_sid_override_cfg(TSECSRD),
+	mc_make_sid_override_cfg(TSECSWR),
+	mc_make_sid_override_cfg(SDMMCRA),
+	mc_make_sid_override_cfg(SDMMCR),
+	mc_make_sid_override_cfg(SDMMCRAB),
+	mc_make_sid_override_cfg(SDMMCWA),
+	mc_make_sid_override_cfg(SDMMCW),
+	mc_make_sid_override_cfg(SDMMCWAB),
+	mc_make_sid_override_cfg(VICSRD),
+	mc_make_sid_override_cfg(VICSWR),
+	mc_make_sid_override_cfg(VIW),
+	mc_make_sid_override_cfg(NVDECSRD),
+	mc_make_sid_override_cfg(NVDECSWR),
+	mc_make_sid_override_cfg(APER),
+	mc_make_sid_override_cfg(APEW),
+	mc_make_sid_override_cfg(NVJPGSRD),
+	mc_make_sid_override_cfg(NVJPGSWR),
+	mc_make_sid_override_cfg(SESRD),
+	mc_make_sid_override_cfg(SESWR),
+	mc_make_sid_override_cfg(AXIAPR),
+	mc_make_sid_override_cfg(AXIAPW),
+	mc_make_sid_override_cfg(ETRR),
+	mc_make_sid_override_cfg(ETRW),
+	mc_make_sid_override_cfg(TSECSRDB),
+	mc_make_sid_override_cfg(TSECSWRB),
+	mc_make_sid_override_cfg(AXISR),
+	mc_make_sid_override_cfg(AXISW),
+	mc_make_sid_override_cfg(EQOSR),
+	mc_make_sid_override_cfg(EQOSW),
+	mc_make_sid_override_cfg(UFSHCR),
+	mc_make_sid_override_cfg(UFSHCW),
+	mc_make_sid_override_cfg(NVDISPLAYR),
+	mc_make_sid_override_cfg(BPMPR),
+	mc_make_sid_override_cfg(BPMPW),
+	mc_make_sid_override_cfg(BPMPDMAR),
+	mc_make_sid_override_cfg(BPMPDMAW),
+	mc_make_sid_override_cfg(AONR),
+	mc_make_sid_override_cfg(AONW),
+	mc_make_sid_override_cfg(AONDMAR),
+	mc_make_sid_override_cfg(AONDMAW),
+	mc_make_sid_override_cfg(SCER),
+	mc_make_sid_override_cfg(SCEW),
+	mc_make_sid_override_cfg(SCEDMAR),
+	mc_make_sid_override_cfg(SCEDMAW),
+	mc_make_sid_override_cfg(APEDMAR),
+	mc_make_sid_override_cfg(APEDMAW),
+	mc_make_sid_override_cfg(NVDISPLAYR1),
+	mc_make_sid_override_cfg(VICSRD1),
+	mc_make_sid_override_cfg(NVDECSRD1),
+	mc_make_sid_override_cfg(VIFALR),
+	mc_make_sid_override_cfg(VIFALW),
+	mc_make_sid_override_cfg(DLA0RDA),
+	mc_make_sid_override_cfg(DLA0FALRDB),
+	mc_make_sid_override_cfg(DLA0WRA),
+	mc_make_sid_override_cfg(DLA0FALWRB),
+	mc_make_sid_override_cfg(DLA1RDA),
+	mc_make_sid_override_cfg(DLA1FALRDB),
+	mc_make_sid_override_cfg(DLA1WRA),
+	mc_make_sid_override_cfg(DLA1FALWRB),
+	mc_make_sid_override_cfg(PVA0RDA),
+	mc_make_sid_override_cfg(PVA0RDB),
+	mc_make_sid_override_cfg(PVA0RDC),
+	mc_make_sid_override_cfg(PVA0WRA),
+	mc_make_sid_override_cfg(PVA0WRB),
+	mc_make_sid_override_cfg(PVA0WRC),
+	mc_make_sid_override_cfg(PVA1RDA),
+	mc_make_sid_override_cfg(PVA1RDB),
+	mc_make_sid_override_cfg(PVA1RDC),
+	mc_make_sid_override_cfg(PVA1WRA),
+	mc_make_sid_override_cfg(PVA1WRB),
+	mc_make_sid_override_cfg(PVA1WRC),
+	mc_make_sid_override_cfg(RCER),
+	mc_make_sid_override_cfg(RCEW),
+	mc_make_sid_override_cfg(RCEDMAR),
+	mc_make_sid_override_cfg(RCEDMAW),
+	mc_make_sid_override_cfg(NVENC1SRD),
+	mc_make_sid_override_cfg(NVENC1SWR),
+	mc_make_sid_override_cfg(PCIE0R),
+	mc_make_sid_override_cfg(PCIE0W),
+	mc_make_sid_override_cfg(PCIE1R),
+	mc_make_sid_override_cfg(PCIE1W),
+	mc_make_sid_override_cfg(PCIE2AR),
+	mc_make_sid_override_cfg(PCIE2AW),
+	mc_make_sid_override_cfg(PCIE3R),
+	mc_make_sid_override_cfg(PCIE3W),
+	mc_make_sid_override_cfg(PCIE4R),
+	mc_make_sid_override_cfg(PCIE4W),
+	mc_make_sid_override_cfg(PCIE5R),
+	mc_make_sid_override_cfg(PCIE5W),
+	mc_make_sid_override_cfg(ISPFALW),
+	mc_make_sid_override_cfg(DLA0RDA1),
+	mc_make_sid_override_cfg(DLA1RDA1),
+	mc_make_sid_override_cfg(PVA0RDA1),
+	mc_make_sid_override_cfg(PVA0RDB1),
+	mc_make_sid_override_cfg(PVA1RDA1),
+	mc_make_sid_override_cfg(PVA1RDB1),
+	mc_make_sid_override_cfg(PCIE5R1),
+	mc_make_sid_override_cfg(NVENCSRD1),
+	mc_make_sid_override_cfg(NVENC1SRD1),
+	mc_make_sid_override_cfg(ISPRA1),
+	mc_make_sid_override_cfg(PCIE0R1),
+	mc_make_sid_override_cfg(MIU0R),
+	mc_make_sid_override_cfg(MIU0W),
+	mc_make_sid_override_cfg(MIU1R),
+	mc_make_sid_override_cfg(MIU1W),
+	mc_make_sid_override_cfg(MIU2R),
+	mc_make_sid_override_cfg(MIU2W),
+	mc_make_sid_override_cfg(MIU3R),
+	mc_make_sid_override_cfg(MIU3W),
+	mc_smmu_bypass_cfg,	/* TBU settings */
+	_END_OF_TABLE_,
+};
+
+/*******************************************************************************
+ * Handler to return the pointer to the MC's context struct
+ ******************************************************************************/
+static mc_regs_t *tegra194_get_mc_system_suspend_ctx(void)
+{
+	/* index of _END_OF_TABLE_ */
+	tegra194_mc_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_mc_context) - 1U;
+
+	return tegra194_mc_context;
+}
+
+/*******************************************************************************
  * Struct to hold the memory controller settings
  ******************************************************************************/
 static tegra_mc_settings_t tegra194_mc_settings = {
 	.streamid_override_cfg = tegra194_streamid_override_regs,
 	.num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_override_regs),
 	.streamid_security_cfg = tegra194_streamid_sec_cfgs,
-	.num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs)
+	.num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs),
+	.get_mc_system_suspend_ctx = tegra194_get_mc_system_suspend_ctx
 };
 
 /*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index 144e418..d92025b 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -10,14 +10,17 @@
 #include <string.h>
 
 #include <arch_helpers.h>
+#include <bpmp_ipc.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
+#include <drivers/delay_timer.h>
 #include <denver.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/psci/psci.h>
 #include <mce.h>
 #include <mce_private.h>
+#include <memctrl_v2.h>
 #include <plat/common/platform.h>
 #include <se.h>
 #include <smmu.h>
@@ -116,7 +119,7 @@
 	const plat_local_state_t *pwr_domain_state;
 	uint8_t stateid_afflvl0, stateid_afflvl2;
 	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
-	uint64_t smmu_ctx_base;
+	uint64_t mc_ctx_base;
 	uint32_t val;
 	mce_cstate_info_t sc7_cstate_info = {
 		.cluster = (uint32_t)TEGRA_NVG_CLUSTER_CC6,
@@ -135,7 +138,7 @@
 	stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
 		TEGRA194_STATE_ID_MASK;
 
-	if ((stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) {
+	if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) {
 
 		/* Enter CPU powerdown */
 		(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
@@ -149,10 +152,10 @@
 		val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
 		mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
 
-		/* save SMMU context */
-		smmu_ctx_base = params_from_bl2->tzdram_base +
-				tegra194_get_smmu_ctx_offset();
-		tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
+		/* save MC context */
+		mc_ctx_base = params_from_bl2->tzdram_base +
+				tegra194_get_mc_ctx_offset();
+		tegra_mc_save_context((uintptr_t)mc_ctx_base);
 
 		/*
 		 * Suspend SE, RNG1 and PKA1 only on silcon and fpga,
@@ -289,9 +292,34 @@
 	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
 	uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
 		TEGRA194_STATE_ID_MASK;
+	uint64_t src_len_in_bytes = (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE;
 	uint64_t val;
+	int32_t ret = PSCI_E_SUCCESS;
 
 	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+		val = params_from_bl2->tzdram_base +
+		      tegra194_get_cpu_reset_handler_size();
+
+		/* initialise communication channel with BPMP */
+		ret = tegra_bpmp_ipc_init();
+		assert(ret == 0);
+
+		/* Enable SE clock before SE context save */
+		ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE);
+		assert(ret == 0);
+
+		/*
+		 * It is very unlikely that the BL31 image would be
+		 * bigger than 2^32 bytes
+		 */
+		assert(src_len_in_bytes < UINT32_MAX);
+
+		if (tegra_se_calculate_save_sha256(BL31_BASE,
+					(uint32_t)src_len_in_bytes) != 0) {
+			ERROR("Hash calculation failed. Reboot\n");
+			(void)tegra_soc_prepare_system_reset();
+		}
+
 		/*
 		 * The TZRAM loses power when we enter system suspend. To
 		 * allow graceful exit from system suspend, we need to copy
@@ -300,10 +328,14 @@
 		val = params_from_bl2->tzdram_base +
 		      tegra194_get_cpu_reset_handler_size();
 		memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
-		       (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
+		       src_len_in_bytes);
+
+		/* Disable SE clock after SE context save */
+		ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE);
+		assert(ret == 0);
 	}
 
-	return PSCI_E_SUCCESS;
+	return ret;
 }
 
 int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c
index c397c91..0882142 100644
--- a/plat/nvidia/tegra/soc/t194/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,8 @@
 #include <tegra_def.h>
 #include <tegra_private.h>
 
+extern uint64_t tegra_bl31_phys_base;
+
 #define MISCREG_AA64_RST_LOW		0x2004U
 #define MISCREG_AA64_RST_HIGH		0x2008U
 
@@ -25,10 +27,14 @@
 {
 	uint32_t addr_low, addr_high;
 	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
-	uint64_t cpu_reset_handler_base, cpu_reset_handler_size;
+	uint64_t cpu_reset_handler_base, cpu_reset_handler_size, tzdram_addr;
+	uint64_t src_len_bytes = BL_END - tegra_bl31_phys_base;
 
 	INFO("Setting up secondary CPU boot\n");
 
+	tzdram_addr = params_from_bl2->tzdram_base +
+		      tegra194_get_cpu_reset_handler_size();
+
 	/*
 	 * The BL31 code resides in the TZSRAM which loses state
 	 * when we enter System Suspend. Copy the wakeup trampoline
@@ -53,4 +59,8 @@
 			addr_low);
 	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
 			addr_high);
+	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO,
+						(uint32_t)tzdram_addr);
+	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI,
+						(uint32_t)src_len_bytes);
 }
diff --git a/plat/nvidia/tegra/soc/t194/plat_smmu.c b/plat/nvidia/tegra/soc/t194/plat_smmu.c
index 3b4a380..310e951 100644
--- a/plat/nvidia/tegra/soc/t194/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t194/plat_smmu.c
@@ -8,7 +8,6 @@
 #include <common/debug.h>
 #include <smmu.h>
 #include <tegra_def.h>
-#include <tegra_mc_def.h>
 
 #define BOARD_SYSTEM_FPGA_BASE		U(1)
 #define BASE_CONFIG_SMMU_DEVICES	U(2)
@@ -20,276 +19,6 @@
 }
 
 /*******************************************************************************
- * Array to hold SMMU context for Tegra194
- ******************************************************************************/
-static __attribute__((aligned(16))) smmu_regs_t tegra194_smmu_context[] = {
-	_START_OF_TABLE_,
-	mc_make_sid_security_cfg(HDAR),
-	mc_make_sid_security_cfg(HOST1XDMAR),
-	mc_make_sid_security_cfg(NVENCSRD),
-	mc_make_sid_security_cfg(SATAR),
-	mc_make_sid_security_cfg(NVENCSWR),
-	mc_make_sid_security_cfg(HDAW),
-	mc_make_sid_security_cfg(SATAW),
-	mc_make_sid_security_cfg(ISPRA),
-	mc_make_sid_security_cfg(ISPFALR),
-	mc_make_sid_security_cfg(ISPWA),
-	mc_make_sid_security_cfg(ISPWB),
-	mc_make_sid_security_cfg(XUSB_HOSTR),
-	mc_make_sid_security_cfg(XUSB_HOSTW),
-	mc_make_sid_security_cfg(XUSB_DEVR),
-	mc_make_sid_security_cfg(XUSB_DEVW),
-	mc_make_sid_security_cfg(TSECSRD),
-	mc_make_sid_security_cfg(TSECSWR),
-	mc_make_sid_security_cfg(SDMMCRA),
-	mc_make_sid_security_cfg(SDMMCR),
-	mc_make_sid_security_cfg(SDMMCRAB),
-	mc_make_sid_security_cfg(SDMMCWA),
-	mc_make_sid_security_cfg(SDMMCW),
-	mc_make_sid_security_cfg(SDMMCWAB),
-	mc_make_sid_security_cfg(VICSRD),
-	mc_make_sid_security_cfg(VICSWR),
-	mc_make_sid_security_cfg(VIW),
-	mc_make_sid_security_cfg(NVDECSRD),
-	mc_make_sid_security_cfg(NVDECSWR),
-	mc_make_sid_security_cfg(APER),
-	mc_make_sid_security_cfg(APEW),
-	mc_make_sid_security_cfg(NVJPGSRD),
-	mc_make_sid_security_cfg(NVJPGSWR),
-	mc_make_sid_security_cfg(SESRD),
-	mc_make_sid_security_cfg(SESWR),
-	mc_make_sid_security_cfg(AXIAPR),
-	mc_make_sid_security_cfg(AXIAPW),
-	mc_make_sid_security_cfg(ETRR),
-	mc_make_sid_security_cfg(ETRW),
-	mc_make_sid_security_cfg(TSECSRDB),
-	mc_make_sid_security_cfg(TSECSWRB),
-	mc_make_sid_security_cfg(AXISR),
-	mc_make_sid_security_cfg(AXISW),
-	mc_make_sid_security_cfg(EQOSR),
-	mc_make_sid_security_cfg(EQOSW),
-	mc_make_sid_security_cfg(UFSHCR),
-	mc_make_sid_security_cfg(UFSHCW),
-	mc_make_sid_security_cfg(NVDISPLAYR),
-	mc_make_sid_security_cfg(BPMPR),
-	mc_make_sid_security_cfg(BPMPW),
-	mc_make_sid_security_cfg(BPMPDMAR),
-	mc_make_sid_security_cfg(BPMPDMAW),
-	mc_make_sid_security_cfg(AONR),
-	mc_make_sid_security_cfg(AONW),
-	mc_make_sid_security_cfg(AONDMAR),
-	mc_make_sid_security_cfg(AONDMAW),
-	mc_make_sid_security_cfg(SCER),
-	mc_make_sid_security_cfg(SCEW),
-	mc_make_sid_security_cfg(SCEDMAR),
-	mc_make_sid_security_cfg(SCEDMAW),
-	mc_make_sid_security_cfg(APEDMAR),
-	mc_make_sid_security_cfg(APEDMAW),
-	mc_make_sid_security_cfg(NVDISPLAYR1),
-	mc_make_sid_security_cfg(VICSRD1),
-	mc_make_sid_security_cfg(NVDECSRD1),
-	mc_make_sid_security_cfg(VIFALR),
-	mc_make_sid_security_cfg(VIFALW),
-	mc_make_sid_security_cfg(DLA0RDA),
-	mc_make_sid_security_cfg(DLA0FALRDB),
-	mc_make_sid_security_cfg(DLA0WRA),
-	mc_make_sid_security_cfg(DLA0FALWRB),
-	mc_make_sid_security_cfg(DLA1RDA),
-	mc_make_sid_security_cfg(DLA1FALRDB),
-	mc_make_sid_security_cfg(DLA1WRA),
-	mc_make_sid_security_cfg(DLA1FALWRB),
-	mc_make_sid_security_cfg(PVA0RDA),
-	mc_make_sid_security_cfg(PVA0RDB),
-	mc_make_sid_security_cfg(PVA0RDC),
-	mc_make_sid_security_cfg(PVA0WRA),
-	mc_make_sid_security_cfg(PVA0WRB),
-	mc_make_sid_security_cfg(PVA0WRC),
-	mc_make_sid_security_cfg(PVA1RDA),
-	mc_make_sid_security_cfg(PVA1RDB),
-	mc_make_sid_security_cfg(PVA1RDC),
-	mc_make_sid_security_cfg(PVA1WRA),
-	mc_make_sid_security_cfg(PVA1WRB),
-	mc_make_sid_security_cfg(PVA1WRC),
-	mc_make_sid_security_cfg(RCER),
-	mc_make_sid_security_cfg(RCEW),
-	mc_make_sid_security_cfg(RCEDMAR),
-	mc_make_sid_security_cfg(RCEDMAW),
-	mc_make_sid_security_cfg(NVENC1SRD),
-	mc_make_sid_security_cfg(NVENC1SWR),
-	mc_make_sid_security_cfg(PCIE0R),
-	mc_make_sid_security_cfg(PCIE0W),
-	mc_make_sid_security_cfg(PCIE1R),
-	mc_make_sid_security_cfg(PCIE1W),
-	mc_make_sid_security_cfg(PCIE2AR),
-	mc_make_sid_security_cfg(PCIE2AW),
-	mc_make_sid_security_cfg(PCIE3R),
-	mc_make_sid_security_cfg(PCIE3W),
-	mc_make_sid_security_cfg(PCIE4R),
-	mc_make_sid_security_cfg(PCIE4W),
-	mc_make_sid_security_cfg(PCIE5R),
-	mc_make_sid_security_cfg(PCIE5W),
-	mc_make_sid_security_cfg(ISPFALW),
-	mc_make_sid_security_cfg(DLA0RDA1),
-	mc_make_sid_security_cfg(DLA1RDA1),
-	mc_make_sid_security_cfg(PVA0RDA1),
-	mc_make_sid_security_cfg(PVA0RDB1),
-	mc_make_sid_security_cfg(PVA1RDA1),
-	mc_make_sid_security_cfg(PVA1RDB1),
-	mc_make_sid_security_cfg(PCIE5R1),
-	mc_make_sid_security_cfg(NVENCSRD1),
-	mc_make_sid_security_cfg(NVENC1SRD1),
-	mc_make_sid_security_cfg(ISPRA1),
-	mc_make_sid_security_cfg(PCIE0R1),
-	mc_make_sid_security_cfg(MIU0R),
-	mc_make_sid_security_cfg(MIU0W),
-	mc_make_sid_security_cfg(MIU1R),
-	mc_make_sid_security_cfg(MIU1W),
-	mc_make_sid_security_cfg(MIU2R),
-	mc_make_sid_security_cfg(MIU2W),
-	mc_make_sid_security_cfg(MIU3R),
-	mc_make_sid_security_cfg(MIU3W),
-	mc_make_sid_override_cfg(HDAR),
-	mc_make_sid_override_cfg(HOST1XDMAR),
-	mc_make_sid_override_cfg(NVENCSRD),
-	mc_make_sid_override_cfg(SATAR),
-	mc_make_sid_override_cfg(NVENCSWR),
-	mc_make_sid_override_cfg(HDAW),
-	mc_make_sid_override_cfg(SATAW),
-	mc_make_sid_override_cfg(ISPRA),
-	mc_make_sid_override_cfg(ISPFALR),
-	mc_make_sid_override_cfg(ISPWA),
-	mc_make_sid_override_cfg(ISPWB),
-	mc_make_sid_override_cfg(XUSB_HOSTR),
-	mc_make_sid_override_cfg(XUSB_HOSTW),
-	mc_make_sid_override_cfg(XUSB_DEVR),
-	mc_make_sid_override_cfg(XUSB_DEVW),
-	mc_make_sid_override_cfg(TSECSRD),
-	mc_make_sid_override_cfg(TSECSWR),
-	mc_make_sid_override_cfg(SDMMCRA),
-	mc_make_sid_override_cfg(SDMMCR),
-	mc_make_sid_override_cfg(SDMMCRAB),
-	mc_make_sid_override_cfg(SDMMCWA),
-	mc_make_sid_override_cfg(SDMMCW),
-	mc_make_sid_override_cfg(SDMMCWAB),
-	mc_make_sid_override_cfg(VICSRD),
-	mc_make_sid_override_cfg(VICSWR),
-	mc_make_sid_override_cfg(VIW),
-	mc_make_sid_override_cfg(NVDECSRD),
-	mc_make_sid_override_cfg(NVDECSWR),
-	mc_make_sid_override_cfg(APER),
-	mc_make_sid_override_cfg(APEW),
-	mc_make_sid_override_cfg(NVJPGSRD),
-	mc_make_sid_override_cfg(NVJPGSWR),
-	mc_make_sid_override_cfg(SESRD),
-	mc_make_sid_override_cfg(SESWR),
-	mc_make_sid_override_cfg(AXIAPR),
-	mc_make_sid_override_cfg(AXIAPW),
-	mc_make_sid_override_cfg(ETRR),
-	mc_make_sid_override_cfg(ETRW),
-	mc_make_sid_override_cfg(TSECSRDB),
-	mc_make_sid_override_cfg(TSECSWRB),
-	mc_make_sid_override_cfg(AXISR),
-	mc_make_sid_override_cfg(AXISW),
-	mc_make_sid_override_cfg(EQOSR),
-	mc_make_sid_override_cfg(EQOSW),
-	mc_make_sid_override_cfg(UFSHCR),
-	mc_make_sid_override_cfg(UFSHCW),
-	mc_make_sid_override_cfg(NVDISPLAYR),
-	mc_make_sid_override_cfg(BPMPR),
-	mc_make_sid_override_cfg(BPMPW),
-	mc_make_sid_override_cfg(BPMPDMAR),
-	mc_make_sid_override_cfg(BPMPDMAW),
-	mc_make_sid_override_cfg(AONR),
-	mc_make_sid_override_cfg(AONW),
-	mc_make_sid_override_cfg(AONDMAR),
-	mc_make_sid_override_cfg(AONDMAW),
-	mc_make_sid_override_cfg(SCER),
-	mc_make_sid_override_cfg(SCEW),
-	mc_make_sid_override_cfg(SCEDMAR),
-	mc_make_sid_override_cfg(SCEDMAW),
-	mc_make_sid_override_cfg(APEDMAR),
-	mc_make_sid_override_cfg(APEDMAW),
-	mc_make_sid_override_cfg(NVDISPLAYR1),
-	mc_make_sid_override_cfg(VICSRD1),
-	mc_make_sid_override_cfg(NVDECSRD1),
-	mc_make_sid_override_cfg(VIFALR),
-	mc_make_sid_override_cfg(VIFALW),
-	mc_make_sid_override_cfg(DLA0RDA),
-	mc_make_sid_override_cfg(DLA0FALRDB),
-	mc_make_sid_override_cfg(DLA0WRA),
-	mc_make_sid_override_cfg(DLA0FALWRB),
-	mc_make_sid_override_cfg(DLA1RDA),
-	mc_make_sid_override_cfg(DLA1FALRDB),
-	mc_make_sid_override_cfg(DLA1WRA),
-	mc_make_sid_override_cfg(DLA1FALWRB),
-	mc_make_sid_override_cfg(PVA0RDA),
-	mc_make_sid_override_cfg(PVA0RDB),
-	mc_make_sid_override_cfg(PVA0RDC),
-	mc_make_sid_override_cfg(PVA0WRA),
-	mc_make_sid_override_cfg(PVA0WRB),
-	mc_make_sid_override_cfg(PVA0WRC),
-	mc_make_sid_override_cfg(PVA1RDA),
-	mc_make_sid_override_cfg(PVA1RDB),
-	mc_make_sid_override_cfg(PVA1RDC),
-	mc_make_sid_override_cfg(PVA1WRA),
-	mc_make_sid_override_cfg(PVA1WRB),
-	mc_make_sid_override_cfg(PVA1WRC),
-	mc_make_sid_override_cfg(RCER),
-	mc_make_sid_override_cfg(RCEW),
-	mc_make_sid_override_cfg(RCEDMAR),
-	mc_make_sid_override_cfg(RCEDMAW),
-	mc_make_sid_override_cfg(NVENC1SRD),
-	mc_make_sid_override_cfg(NVENC1SWR),
-	mc_make_sid_override_cfg(PCIE0R),
-	mc_make_sid_override_cfg(PCIE0W),
-	mc_make_sid_override_cfg(PCIE1R),
-	mc_make_sid_override_cfg(PCIE1W),
-	mc_make_sid_override_cfg(PCIE2AR),
-	mc_make_sid_override_cfg(PCIE2AW),
-	mc_make_sid_override_cfg(PCIE3R),
-	mc_make_sid_override_cfg(PCIE3W),
-	mc_make_sid_override_cfg(PCIE4R),
-	mc_make_sid_override_cfg(PCIE4W),
-	mc_make_sid_override_cfg(PCIE5R),
-	mc_make_sid_override_cfg(PCIE5W),
-	mc_make_sid_override_cfg(ISPFALW),
-	mc_make_sid_override_cfg(DLA0RDA1),
-	mc_make_sid_override_cfg(DLA1RDA1),
-	mc_make_sid_override_cfg(PVA0RDA1),
-	mc_make_sid_override_cfg(PVA0RDB1),
-	mc_make_sid_override_cfg(PVA1RDA1),
-	mc_make_sid_override_cfg(PVA1RDB1),
-	mc_make_sid_override_cfg(PCIE5R1),
-	mc_make_sid_override_cfg(NVENCSRD1),
-	mc_make_sid_override_cfg(NVENC1SRD1),
-	mc_make_sid_override_cfg(ISPRA1),
-	mc_make_sid_override_cfg(PCIE0R1),
-	mc_make_sid_override_cfg(MIU0R),
-	mc_make_sid_override_cfg(MIU0W),
-	mc_make_sid_override_cfg(MIU1R),
-	mc_make_sid_override_cfg(MIU1W),
-	mc_make_sid_override_cfg(MIU2R),
-	mc_make_sid_override_cfg(MIU2W),
-	mc_make_sid_override_cfg(MIU3R),
-	mc_make_sid_override_cfg(MIU3W),
-	smmu_make_cfg(TEGRA_SMMU0_BASE),
-	smmu_make_cfg(TEGRA_SMMU2_BASE),
-	smmu_bypass_cfg,	/* TBU settings */
-	_END_OF_TABLE_,
-};
-
-/*******************************************************************************
- * Handler to return the pointer to the SMMU's context struct
- ******************************************************************************/
-smmu_regs_t *plat_get_smmu_ctx(void)
-{
-	/* index of _END_OF_TABLE_ */
-	tegra194_smmu_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_smmu_context) - 1U;
-
-	return tegra194_smmu_context;
-}
-
-/*******************************************************************************
  * Handler to return the support SMMU devices number
  ******************************************************************************/
 uint32_t plat_get_num_smmu_devices(void)
diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
index 540c201..819920f 100644
--- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
@@ -12,7 +12,7 @@
 
 #define TEGRA194_STATE_SYSTEM_SUSPEND	0x5C7
 #define TEGRA194_STATE_SYSTEM_RESUME	0x600D
-#define TEGRA194_SMMU_CTX_SIZE		0x80D
+#define TEGRA194_MC_CTX_SIZE		0xFB
 
 	.align 4
 	.globl	tegra194_cpu_reset_handler
@@ -69,8 +69,8 @@
 	 *
 	 * 0x0000: secure world's entrypoint
 	 * 0x0008: BL31 size (RO + RW)
-	 * 0x0010: SMMU context start
-	 * 0x2490: SMMU context end
+	 * 0x0010: MC context start
+	 * 0x2490: MC context end
 	 */
 
 	.align 4
@@ -79,14 +79,13 @@
 __tegra194_cpu_reset_handler_data:
 	.quad	tegra_secure_entrypoint
 	.quad	__BL31_END__ - BL31_BASE
-
 	.globl	__tegra194_system_suspend_state
 __tegra194_system_suspend_state:
 	.quad	0
 
 	.align 4
-__tegra194_smmu_context:
-	.rept	TEGRA194_SMMU_CTX_SIZE
+__tegra194_mc_context:
+	.rept	TEGRA194_MC_CTX_SIZE
 	.quad	0
 	.endr
 	.size	__tegra194_cpu_reset_handler_data, \
@@ -98,7 +97,7 @@
 
 	.globl tegra194_get_cpu_reset_handler_size
 	.globl tegra194_get_cpu_reset_handler_base
-	.globl tegra194_get_smmu_ctx_offset
+	.globl tegra194_get_mc_ctx_offset
 	.globl tegra194_set_system_suspend_entry
 
 /* return size of the CPU reset handler */
@@ -115,13 +114,13 @@
 	ret
 endfunc tegra194_get_cpu_reset_handler_base
 
-/* return the size of the SMMU context */
-func tegra194_get_smmu_ctx_offset
-	adr	x0, __tegra194_smmu_context
+/* return the size of the MC context */
+func tegra194_get_mc_ctx_offset
+	adr	x0, __tegra194_mc_context
 	adr	x1, tegra194_cpu_reset_handler
 	sub	x0, x0, x1
 	ret
-endfunc tegra194_get_smmu_ctx_offset
+endfunc tegra194_get_mc_ctx_offset
 
 /* set system suspend state before SC7 entry */
 func tegra194_set_system_suspend_entry
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index 933e925..6d014bf 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -179,6 +179,8 @@
 
 /* Secure IRQs for Tegra186 */
 static const interrupt_prop_t tegra210_interrupt_props[] = {
+	INTR_PROP_DESC(TEGRA210_TIMER1_IRQ, GIC_HIGHEST_SEC_PRIORITY,
+			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 	INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, GIC_HIGHEST_SEC_PRIORITY,
 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 };
diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
index 7d26fe7..904f8d6 100644
--- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c
@@ -88,7 +88,6 @@
 			return -EINVAL;
 		}
 	} else {
-		ERROR("%s: unsupported function ID\n", __func__);
 		return -ENOTSUP;
 	}
 	return 0;
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 928d69a..6aa198c 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -140,6 +140,8 @@
 				${PLAT_QEMU_COMMON_PATH}/qemu_gicv2.c
 
 QEMU_GICV3_SOURCES	:=	drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/common/gic_common.c	\
 				plat/common/plat_gicv3.c		\
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 51832d0..6ad3d8b 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -63,6 +63,8 @@
 endif
 
 QEMU_GIC_SOURCES	:=	drivers/arm/gic/v3/gicv3_helpers.c		\
+				drivers/arm/gic/v3/gicdv3_helpers.c		\
+				drivers/arm/gic/v3/gicrv3_helpers.c		\
 				drivers/arm/gic/v3/gicv3_main.c			\
 				drivers/arm/gic/common/gic_common.c		\
 				plat/common/plat_gicv3.c			\
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index 5a23d3c..0dc1840 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -29,6 +29,8 @@
 				drivers/arm/gic/v3/gic500.c		\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				plat/common/plat_gicv3.c		\
 				${RK_PLAT}/common/rockchip_gicv3.c
 
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index ab1f69e..0d9071b 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -33,6 +33,8 @@
 BL31_SOURCES		+=	drivers/arm/ccn/ccn.c			\
 				drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				lib/cpus/aarch64/cortex_a53.S		\
 				plat/common/plat_gicv3.c		\
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index 8e96b68..a014f52 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -58,6 +58,8 @@
 BL31_SOURCES		+=	drivers/arm/cci/cci.c			\
 				drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				lib/cpus/aarch64/cortex_a53.S		\
 				lib/cpus/aarch64/cortex_a72.S		\
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index b86287b..bd1a16b 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -149,14 +149,8 @@
 
 # Macros and rules to build TF binary
 STM32_TF_ELF_LDFLAGS	:=	--hash-style=gnu --as-needed
-STM32_DT_BASENAME	:=	$(DTB_FILE_NAME:.dtb=)
-STM32_TF_STM32		:=	${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32
-STM32_TF_BINARY		:=	$(STM32_TF_STM32:.stm32=.bin)
-STM32_TF_MAPFILE	:=	$(STM32_TF_STM32:.stm32=.map)
-STM32_TF_LINKERFILE	:=	$(STM32_TF_STM32:.stm32=.ld)
-STM32_TF_ELF		:=	$(STM32_TF_STM32:.stm32=.elf)
-STM32_TF_DTBFILE	:=      ${BUILD_PLAT}/fdts/${DTB_FILE_NAME}
-STM32_TF_OBJS		:=	${BUILD_PLAT}/stm32mp1.o
+STM32_TF_STM32		:=	$(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME)))
+STM32_TF_LINKERFILE	:=	${BUILD_PLAT}/stm32mp1.ld
 
 BL2_CFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC=1
 
@@ -164,7 +158,7 @@
 STM32IMAGEPATH		?= tools/stm32image
 STM32IMAGE		?= ${STM32IMAGEPATH}/stm32image${BIN_EXT}
 
-.PHONY:			${STM32_TF_STM32}
+.PHONY:			check_dtc_version stm32image clean_stm32image
 .SUFFIXES:
 
 all: check_dtc_version ${STM32_TF_STM32} stm32image
@@ -192,32 +186,32 @@
 	fi
 
 
-${STM32_TF_OBJS}:	plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP} ${STM32_TF_DTBFILE}
-			@echo "  AS      $<"
+${BUILD_PLAT}/stm32mp1-%.o:	${BUILD_PLAT}/fdts/%.dtb plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP}
+			@echo "  AS      stm32mp1.S"
 			${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
 				${BL32_PATH} \
 				-DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" \
-				-DDTB_BIN_PATH=\"${STM32_TF_DTBFILE}\" \
+				-DDTB_BIN_PATH=\"$<\" \
 				-c plat/st/stm32mp1/stm32mp1.S -o $@
 
 ${STM32_TF_LINKERFILE}:	plat/st/stm32mp1/stm32mp1.ld.S ${BUILD_PLAT}
 			@echo "  LDS     $<"
 			${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} -P -E $< -o $@
 
-${STM32_TF_ELF}:	${STM32_TF_OBJS} ${STM32_TF_LINKERFILE}
+tf-a-%.elf:		stm32mp1-%.o ${STM32_TF_LINKERFILE}
 			@echo "  LDS     $<"
-			${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=${STM32_TF_MAPFILE} --script ${STM32_TF_LINKERFILE} ${STM32_TF_OBJS}
+			${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
 
-${STM32_TF_BINARY}:	${STM32_TF_ELF}
-			${Q}${OC} -O binary ${STM32_TF_ELF} $@
+tf-a-%.bin:		tf-a-%.elf
+			${Q}${OC} -O binary $< $@
 			@echo
 			@echo "Built $@ successfully"
 			@echo
 
-${STM32_TF_STM32}:	stm32image ${STM32_TF_BINARY}
+tf-a-%.stm32:		tf-a-%.bin stm32image
 			@echo
 			@echo "Generated $@"
-			$(eval LOADADDR =  $(shell cat ${STM32_TF_MAPFILE} | grep RAM | awk '{print $$2}'))
-			$(eval ENTRY =  $(shell cat ${STM32_TF_MAPFILE} | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
-			${STM32IMAGE} -s ${STM32_TF_BINARY} -d $@ -l $(LOADADDR) -e ${ENTRY} -v ${STM32_TF_VERSION}
+			$(eval LOADADDR =  $(shell cat $(@:.stm32=.map) | grep RAM | awk '{print $$2}'))
+			$(eval ENTRY =  $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
+			${STM32IMAGE} -s $< -d $@ -l $(LOADADDR) -e ${ENTRY} -v ${STM32_TF_VERSION}
 			@echo
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index 7956497..587b44b 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -57,6 +57,8 @@
 				drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				plat/common/plat_gicv3.c		\
 				${PLAT_PATH}/common/k3_gicv3.c		\
 
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 1e231cc..5d7fd69 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -52,6 +52,8 @@
 				drivers/arm/gic/v3/gic500.c			\
 				drivers/arm/gic/v3/gicv3_main.c			\
 				drivers/arm/gic/v3/gicv3_helpers.c		\
+				drivers/arm/gic/v3/gicdv3_helpers.c	\
+				drivers/arm/gic/v3/gicrv3_helpers.c	\
 				drivers/arm/pl011/aarch64/pl011_console.S	\
 				plat/common/aarch64/crash_console_helpers.S	\
 				plat/arm/common/arm_cci.c			\
diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c
index 3cfc52d..32ae8ec 100644
--- a/services/spd/tlkd/tlkd_main.c
+++ b/services/spd/tlkd/tlkd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
  * responsible for initialising and maintaining communication with the SP.
  ******************************************************************************/
 #include <assert.h>
+#include <bl31/interrupt_mgmt.h>
 #include <errno.h>
 #include <stddef.h>
 
@@ -49,6 +50,50 @@
 static int32_t tlkd_init(void);
 
 /*******************************************************************************
+ * Secure Payload Dispatcher's timer interrupt handler
+ ******************************************************************************/
+static uint64_t tlkd_interrupt_handler(uint32_t id,
+					uint32_t flags,
+					void *handle,
+					void *cookie)
+{
+	cpu_context_t *s_cpu_context;
+	int irq = plat_ic_get_pending_interrupt_id();
+
+	/* acknowledge the interrupt and mark it complete */
+	(void)plat_ic_acknowledge_interrupt();
+	plat_ic_end_of_interrupt(irq);
+
+	/*
+	 * Disable the routing of NS interrupts from secure world to
+	 * EL3 while interrupted on this core.
+	 */
+	disable_intr_rm_local(INTR_TYPE_S_EL1, SECURE);
+
+	/* Check the security state when the exception was generated */
+	assert(get_interrupt_src_ss(flags) == NON_SECURE);
+	assert(handle == cm_get_context(NON_SECURE));
+
+	/* Save non-secure state */
+	cm_el1_sysregs_context_save(NON_SECURE);
+
+	/* Get a reference to the secure context */
+	s_cpu_context = cm_get_context(SECURE);
+	assert(s_cpu_context);
+
+	/*
+	 * Restore non-secure state. There is no need to save the
+	 * secure system register context since the SP was supposed
+	 * to preserve it during S-EL1 interrupt handling.
+	 */
+	cm_el1_sysregs_context_restore(SECURE);
+	cm_set_next_eret_context(SECURE);
+
+	/* Provide the IRQ number to the SPD */
+	SMC_RET4(s_cpu_context, (uint32_t)TLK_IRQ_FIRED, 0, (uint32_t)irq, 0);
+}
+
+/*******************************************************************************
  * Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type
  * (aarch32/aarch64) if not already known and initialises the context for entry
  * into the SP for its initialisation.
@@ -56,6 +101,8 @@
 static int32_t tlkd_setup(void)
 {
 	entry_point_info_t *tlk_ep_info;
+	uint32_t flags;
+	int32_t ret;
 
 	/*
 	 * Get information about the Secure Payload (BL32) image. Its
@@ -86,6 +133,18 @@
 		tlk_ep_info->pc,
 		&tlk_ctx);
 
+	/* get a list of all S-EL1 IRQs from the platform */
+
+	/* register interrupt handler */
+	flags = 0;
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	ret = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+					      tlkd_interrupt_handler,
+					      flags);
+	if (ret != 0) {
+		ERROR("failed to register tlkd interrupt handler (%d)\n", ret);
+	}
+
 	/*
 	 * All TLK SPD initialization done. Now register our init function
 	 * with BL31 for deferred invocation
@@ -385,6 +444,34 @@
 		break;
 
 	/*
+	 * This function ID is used by SP to indicate that it has completed
+	 * handling the secure interrupt.
+	 */
+	case TLK_IRQ_DONE:
+
+		if (ns)
+			SMC_RET1(handle, SMC_UNK);
+
+		assert(handle == cm_get_context(SECURE));
+
+		/* save secure world context */
+		cm_el1_sysregs_context_save(SECURE);
+
+		/* Get a reference to the non-secure context */
+		ns_cpu_context = cm_get_context(NON_SECURE);
+		assert(ns_cpu_context);
+
+		/*
+		 * Restore non-secure state. There is no need to save the
+		 * secure system register context since the SP was supposed
+		 * to preserve it during S-EL1 interrupt handling.
+		 */
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+
+		SMC_RET0(ns_cpu_context);
+
+	/*
 	 * Return the number of service function IDs implemented to
 	 * provide service to non-secure
 	 */
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 2cdf4f5..a3e1a2d 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -162,6 +162,16 @@
 	INFO("SPM core run time EL%x.\n",
 	     SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1);
 
+	/* Validate the SPMC ID, Ensure high bit is set */
+	if (!(spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) &
+			SPMC_SECURE_ID_MASK) {
+		WARN("Invalid ID (0x%x) for SPMC.\n",
+		     spmc_attrs.spmc_id);
+		return 1;
+	}
+
+	INFO("SPMC ID %x.\n", spmc_attrs.spmc_id);
+
 	/* Validate the SPM core execution state */
 	if ((spmc_attrs.exec_state != MODE_RW_64) &&
 	    (spmc_attrs.exec_state != MODE_RW_32)) {
@@ -436,6 +446,26 @@
 
 		break; /* not reached */
 
+	case SPCI_ID_GET:
+		/*
+		 * Returns the ID of the calling SPCI component.
+		*/
+		if (!secure_origin) {
+			SMC_RET8(handle, SPCI_SUCCESS_SMC32,
+				 SPCI_TARGET_INFO_MBZ, SPCI_NS_ENDPOINT_ID,
+				 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+				 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+				 SPCI_PARAM_MBZ);
+		} else {
+			SMC_RET8(handle, SPCI_SUCCESS_SMC32,
+				 SPCI_TARGET_INFO_MBZ, spmc_attrs.spmc_id,
+				 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+				 SPCI_PARAM_MBZ, SPCI_PARAM_MBZ,
+				 SPCI_PARAM_MBZ);
+		}
+
+		break; /* not reached */
+
 	case SPCI_RX_RELEASE:
 	case SPCI_RXTX_MAP_SMC32:
 	case SPCI_RXTX_MAP_SMC64:
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 61b479a..0ad35c7 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -55,6 +55,15 @@
 } spmd_spm_core_context_t;
 
 /*
+ * Reserve ID for NS physical SPCI Endpoint.
+ */
+#define SPCI_NS_ENDPOINT_ID		U(0)
+
+/* Mask and shift to check valid secure SPCI Endpoint ID. */
+#define SPMC_SECURE_ID_MASK		0x1
+#define SPMC_SECURE_ID_SHIFT		15
+
+/*
  * Data structure used by the SPM dispatcher (SPMD) in EL3 to track sequence of
  * SPCI calls from lower ELs.
  *