Merge "Make PAC demangling more generic" into integration
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index d9d7f84..802dafc 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -64,6 +64,14 @@
 :F: drivers/amlogic/g12a
 :F: plat/amlogic/g12a/
 
+Amlogic Meson A113D (AXG) platform port
+-----------------------------------------
+:M: Carlo Caione <ccaione@baylibre.com>
+:G: `carlocaione`_
+:F: docs/plat/meson-axg.rst
+:F: drivers/amlogic/axg
+:F: plat/amlogic/axg/
+
 Armv7-A architecture port
 -------------------------
 :M: Etienne Carriere <etienne.carriere@linaro.org>
diff --git a/docs/components/exception-handling.rst b/docs/components/exception-handling.rst
index 3f38685..e330a62 100644
--- a/docs/components/exception-handling.rst
+++ b/docs/components/exception-handling.rst
@@ -467,7 +467,7 @@
 Non-secure world to request Secure services. They're broadly classified as
 *Fast* or *Yielding* (see `SMCCC`__).
 
-.. __: `http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html`
+.. __: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
 
 -  *Fast* SMCs are atomic from the caller's point of view. I.e., they return
    to the caller only when the Secure world has finished serving the request.
@@ -621,6 +621,6 @@
 
 --------------
 
-*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.*
 
 .. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst
index 2025243..f5c8bc9 100644
--- a/docs/design/trusted-board-boot-build.rst
+++ b/docs/design/trusted-board-boot-build.rst
@@ -33,7 +33,7 @@
    -  ``GENERATE_COT=1``
 
    In the case of Arm platforms, the location of the ROTPK hash must also be
-   specified at build time. Two locations are currently supported (see
+   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
@@ -41,17 +41,16 @@
       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
       option ``bp.trusted_key_storage.public_key`` when launching the model.
-      On both Juno and FVP models, the default value corresponds to an
-      ECDSA-SECP256R1 public key hash, whose private part is not currently
-      available.
+      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 ROTPK hash that is hardcoded
-      in the Arm platform port. The private/public RSA key pair may be
-      found in ``plat/arm/board/common/rotpk``.
+   -  ``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.
 
-   -  ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded
-      in the Arm platform port. The private/public ECDSA key pair may be
-      found in ``plat/arm/board/common/rotpk``.
+   -  ``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.
 
    Example of command line using RSA development keys:
 
@@ -108,7 +107,7 @@
 
 --------------
 
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
 
 .. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git
 .. _mbed TLS Security Center: https://tls.mbed.org/security
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index fa83b4f..031836a 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -310,8 +310,8 @@
    EL1 for handling. The default value of this option is ``0``, which means the
    Group 0 interrupts are assumed to be handled by Secure EL1.
 
-   .. __: `platform-interrupt-controller-API.rst`
-   .. __: `interrupt-framework-design.rst`
+   .. __: platform-interrupt-controller-API.rst
+   .. __: interrupt-framework-design.rst
 
 -  ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError
    Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to
@@ -468,7 +468,8 @@
    entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
 
 -  ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this
+   file that contains the ROT private key in PEM format and enforces public key
+   hash generation. If ``SAVE_KEYS=1``, this
    file name will be used to save the key.
 
 -  ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
@@ -657,4 +658,4 @@
 
 --------------
 
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index bb14717..e8357b3 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -2763,6 +2763,19 @@
    to ``no``. If any of the options ``EL3_PAYLOAD_BASE`` or ``PRELOADED_BL33_BASE``
    are used, this flag will be set to ``no`` automatically.
 
+Platform include paths
+----------------------
+
+Platforms are allowed to add more include paths to be passed to the compiler.
+The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
+particular for the file ``platform_def.h``.
+
+Example:
+
+.. code:: c
+
+  PLAT_INCLUDES  += -Iinclude/plat/myplat/include
+
 C Library
 ---------
 
@@ -2844,7 +2857,7 @@
 
 --------------
 
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
 
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
 .. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index d24ad23..9622de6 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -57,8 +57,7 @@
    ``ARM_ROTPK_LOCATION`` are:
 
    -  ``regs`` : return the ROTPK hash stored in the Trusted root-key storage
-      registers. The private key corresponding to this ROTPK hash is not
-      currently available.
+      registers.
    -  ``devel_rsa`` : return a development public key hash embedded in the BL1
       and BL2 binaries. This hash has been obtained from the RSA public key
       ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use
@@ -70,6 +69,12 @@
       use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as
       ``ROT_KEY`` when creating the certificates.
 
+-  ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``. Specifies the
+   location of the ROTPK hash. Not expected to be a build option. This defaults to
+   ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified algorithm.
+   Providing ``ROT_KEY`` enforces generation of the hash from the ``ROT_KEY`` and
+   overwrites the default hash file.
+
 -  ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options:
 
    -  ``tsram`` : Trusted SRAM (default option when TBB is not enabled)
@@ -109,6 +114,11 @@
    management operations and for SCP RAM Firmware transfer. If this option
    is set to 1, then SCMI/SDS drivers will be used. Default is 0.
 
+ - ``CSS_SGI_CHIP_COUNT``: Configures the number of chips on a SGI/RD platform
+   which supports multi-chip operation. If ``CSS_SGI_CHIP_COUNT`` is set to any
+   valid value greater than 1, the platform code performs required configuration
+   to support multi-chip operation.
+
 --------------
 
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/docs/plat/meson-axg.rst b/docs/plat/meson-axg.rst
new file mode 100644
index 0000000..1e4b2c2
--- /dev/null
+++ b/docs/plat/meson-axg.rst
@@ -0,0 +1,27 @@
+Amlogic Meson A113D (AXG)
+===========================
+
+The Amlogic Meson A113D is a SoC with a quad core Arm Cortex-A53 running at
+~1.2GHz. It also contains a Cortex-M3 used as SCP.
+
+This port is a minimal implementation of BL31 capable of booting mainline U-Boot
+and Linux:
+
+- SCPI support.
+- Basic PSCI support (CPU_ON, CPU_OFF, SYSTEM_RESET, SYSTEM_OFF). Note that CPU0
+  can't be turned off, so there is a workaround to hide this from the caller.
+- GICv2 driver set up.
+- Basic SIP services (read efuse data, enable/disable JTAG).
+
+In order to build it:
+
+.. code:: shell
+
+    CROSS_COMPILE=aarch64-none-elf- make DEBUG=1 PLAT=axg [SPD=opteed]
+         [AML_USE_ATOS=1 when using ATOS as BL32]
+
+This port has been tested on a A113D board. After building it, follow the
+instructions in the `U-Boot repository`_, replacing the mentioned **bl31.img**
+by the one built from this port.
+
+.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/s400/README
diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst
index cb8b892..f7d53a9 100644
--- a/docs/process/coding-guidelines.rst
+++ b/docs/process/coding-guidelines.rst
@@ -1,232 +1,126 @@
-Coding Style & Guidelines
-=========================
+Coding Guidelines
+=================
 
-The following sections contain TF coding guidelines. They are continually
-evolving and should not be considered "set in stone". Feel free to question them
-and provide feedback.
+This document provides some additional guidelines to consider when writing
+|TF-A| code. These are not intended to be strictly-enforced rules like the
+contents of the :ref:`Coding Style`.
 
-Some of the guidelines may also apply to other codebases.
+Automatic Editor Configuration
+------------------------------
 
-.. note::
-   The existing TF codebase does not necessarily comply with all the
-   below guidelines but the intent is for it to do so eventually.
-
-Checkpatch overrides
---------------------
-
-Some checkpatch warnings in the TF codebase are deliberately ignored. These
-include:
-
-- ``**WARNING: line over 80 characters**``: Although the codebase should
-  generally conform to the 80 character limit this is overly restrictive in some
-  cases.
-
-- ``**WARNING: Use of volatile is usually wrong``: see
-  `Why the “volatile” type class should not be used`_ . Although this document
-  contains some very useful information, there are several legitimate uses of
-  the volatile keyword within the TF codebase.
-
-Headers and inclusion
----------------------
-
-Header guards
-^^^^^^^^^^^^^
-
-For a header file called "some_driver.h" the style used by the Trusted Firmware
-is:
-
-.. code:: c
-
-  #ifndef SOME_DRIVER_H
-  #define SOME_DRIVER_H
-
-  <header content>
-
-  #endif /* SOME_DRIVER_H */
+Many of the rules given below (such as indentation size, use of tabs, and
+newlines) can be set automatically using the `EditorConfig`_ configuration file
+in the root of the repository: ``.editorconfig``. With a supported editor, the
+rules set out in this file can be automatically applied when you are editing
+files in the |TF-A| repository.
 
-Include statement ordering
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+Several editors include built-in support for EditorConfig files, and many others
+support its functionality through plugins.
 
-All header files that are included by a source file must use the following,
-grouped ordering. This is to improve readability (by making it easier to quickly
-read through the list of headers) and maintainability.
+Use of the EditorConfig file is suggested but is not required.
 
-#. *System* includes: Header files from the standard *C* library, such as
-   ``stddef.h`` and ``string.h``.
 
-#. *Project* includes: Header files under the ``include/`` directory within TF
-   are *project* includes.
-
-#. *Platform* includes: Header files relating to a single, specific platform,
-   and which are located under the ``plat/<platform_name>`` directory within TF,
-   are *platform* includes.
-
-Within each group, ``#include`` statements must be in alphabetical order,
-taking both the file and directory names into account.
-
-Groups must be separated by a single blank line for clarity.
-
-The example below illustrates the ordering rules using some contrived header
-file names; this type of name reuse should be otherwise avoided.
-
-.. code:: c
-
-  #include <string.h>
-
-  #include <a_dir/example/a_header.h>
-  #include <a_dir/example/b_header.h>
-  #include <a_dir/test/a_header.h>
-  #include <b_dir/example/a_header.h>
-
-  #include "./a_header.h"
-
-Include statement variants
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Two variants of the ``#include`` directive are acceptable in the TF codebase.
-Correct use of the two styles improves readability by suggesting the location
-of the included header and reducing ambiguity in cases where generic and
-platform-specific headers share a name.
-
-For header files that are in the same directory as the source file that is
-including them, use the ``"..."`` variant.
-
-For header files that are **not** in the same directory as the source file that
-is including them, use the ``<...>`` variant.
-
-Example (bl1_fwu.c):
-
-.. code:: c
-
-  #include <assert.h>
-  #include <errno.h>
-  #include <string.h>
-
-  #include "bl1_private.h"
-
-Platform include paths
-^^^^^^^^^^^^^^^^^^^^^^
-
-Platforms are allowed to add more include paths to be passed to the compiler.
-The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
-particular for the file ``platform_def.h``.
-
-Example:
-
-.. code:: c
-
-  PLAT_INCLUDES  += -Iinclude/plat/myplat/include
+Automatic Compliance Checking
+-----------------------------
 
-Types and typedefs
-------------------
+To assist with coding style compliance, the project Makefile contains two
+targets which both utilise the `checkpatch.pl` script that ships with the Linux
+source tree. The project also defines certain *checkpatch* options in the
+``.checkpatch.conf`` file in the top-level directory.
 
-Use of built-in *C* and *libc* data types
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. note::
+   Checkpatch errors will gate upstream merging of pull requests.
+   Checkpatch warnings will not gate merging but should be reviewed and fixed if
+   possible.
 
-The TF codebase should be kept as portable as possible, especially since both
-64-bit and 32-bit platforms are supported. To help with this, the following data
-type usage guidelines should be followed:
+To check the entire source tree, you must first download copies of
+``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
+in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
+environment variable to point to ``checkpatch.pl`` (with the other 2 files in
+the same directory) and build the `checkcodebase` target:
 
-- Where possible, use the built-in *C* data types for variable storage (for
-  example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
-  types. Most code is typically only concerned with the minimum size of the
-  data stored, which the built-in *C* types guarantee.
-
-- Avoid using the exact-size standard *C99* types in general (for example,
-  ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
-  compiler from making optimizations. There are legitimate uses for them,
-  for example to represent data of a known structure. When using them in struct
-  definitions, consider how padding in the struct will work across architectures.
-  For example, extra padding may be introduced in AArch32 systems if a struct
-  member crosses a 32-bit boundary.
+.. code:: shell
 
-- Use ``int`` as the default integer type - it's likely to be the fastest on all
-  systems. Also this can be assumed to be 32-bit as a consequence of the
-  `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
-  Standard for the Arm 64-bit Architecture`_ .
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
 
-- Avoid use of ``short`` as this may end up being slower than ``int`` in some
-  systems. If a variable must be exactly 16-bit, use ``int16_t`` or
-  ``uint16_t``.
+To just check the style on the files that differ between your local branch and
+the remote master, use:
 
-- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
-  that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
-  at least 64-bit, use ``long long``.
+.. code:: shell
 
-- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
 
-- Use ``unsigned`` for integers that can never be negative (counts,
-  indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
-  rules (10.X), where signed and unsigned types are considered different
-  essential types. Choosing the correct type will aid this. MISRA static
-  analysers will pick up any implicit signed/unsigned conversions that may lead
-  to unexpected behaviour.
+If you wish to check your patch against something other than the remote master,
+set the ``BASE_COMMIT`` variable to your desired branch. By default,
+``BASE_COMMIT`` is set to ``origin/master``.
 
-- For pointer types:
+Ignored Checkpatch Warnings
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-  - If an argument in a function declaration is pointing to a known type then
-    simply use a pointer to that type (for example: ``struct my_struct *``).
+Some checkpatch warnings in the TF codebase are deliberately ignored. These
+include:
 
-  - If a variable (including an argument in a function declaration) is pointing
-    to a general, memory-mapped address, an array of pointers or another
-    structure that is likely to require pointer arithmetic then use
-    ``uintptr_t``. This will reduce the amount of casting required in the code.
-    Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
-    may work but is less portable.
+- ``**WARNING: line over 80 characters**``: Although the codebase should
+  generally conform to the 80 character limit this is overly restrictive in some
+  cases.
 
-  - For other pointer arguments in a function declaration, use ``void *``. This
-    includes pointers to types that are abstracted away from the known API and
-    pointers to arbitrary data. This allows the calling function to pass a
-    pointer argument to the function without any explicit casting (the cast to
-    ``void *`` is implicit). The function implementation can then do the
-    appropriate casting to a specific type.
+- ``**WARNING: Use of volatile is usually wrong``: see
+  `Why the “volatile” type class should not be used`_ . Although this document
+  contains some very useful information, there are several legimate uses of the
+  volatile keyword within the TF codebase.
 
-  - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
+Performance considerations
+--------------------------
 
-- Use ``size_t`` when storing the ``sizeof()`` something.
+Avoid printf and use logging macros
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
-  can also return an error code; the signed type allows for a negative return
-  code in case of error. This practice should be used sparingly.
+``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
+which wrap ``tf_log`` and which allow the logging call to be compiled-out
+depending on the ``make`` command. Use these macros to avoid print statements
+being compiled unconditionally into the binary.
 
-- Use ``u_register_t`` when it's important to store the contents of a register
-  in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a
-  standard *C99* type but is widely available in libc implementations,
-  including the FreeBSD version included with the TF codebase. Where possible,
-  cast the variable to a more appropriate type before interpreting the data. For
-  example, the following struct in ``ep_info.h`` could use this type to minimize
-  the storage required for the set of registers:
+Each logging macro has a numerical log level:
 
 .. code:: c
 
-    typedef struct aapcs64_params {
-            u_register_t arg0;
-            u_register_t arg1;
-            u_register_t arg2;
-            u_register_t arg3;
-            u_register_t arg4;
-            u_register_t arg5;
-            u_register_t arg6;
-            u_register_t arg7;
-    } aapcs64_params_t;
+  #define LOG_LEVEL_NONE    0
+  #define LOG_LEVEL_ERROR   10
+  #define LOG_LEVEL_NOTICE  20
+  #define LOG_LEVEL_WARNING 30
+  #define LOG_LEVEL_INFO    40
+  #define LOG_LEVEL_VERBOSE 50
 
-If some code wants to operate on ``arg0`` and knows that it represents a 32-bit
-unsigned integer on all systems, cast it to ``unsigned int``.
+By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
+be compiled into debug builds and all statements with a log level
+``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
+overridden from the command line or by the platform makefile (although it may be
+necessary to clean the build directory first). For example, to enable
+``VERBOSE`` logging on FVP:
 
-These guidelines should be updated if additional types are needed.
+``make PLAT=fvp LOG_LEVEL=50 all``
 
-Avoid anonymous typedefs of structs/enums in headers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Use const data where possible
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-For example, the following definition:
+For example, the following code:
 
 .. code:: c
 
-  typedef struct {
+  struct my_struct {
           int arg1;
           int arg2;
-  } my_struct_t;
+  };
 
+  void init(struct my_struct *ptr);
+
+  void main(void)
+  {
+          struct my_struct x;
+          x.arg1 = 1;
+          x.arg2 = 2;
+          init(&x);
+  }
 
 is better written as:
 
@@ -237,31 +131,18 @@
           int arg2;
   };
 
-This allows function declarations in other header files that depend on the
-struct/enum to forward declare the struct/enum instead of including the
-entire header:
-
-.. code:: c
-
-  #include <my_struct.h>
-  void my_func(my_struct_t *arg);
-
-instead of:
-
-.. code:: c
-
-  struct my_struct;
-  void my_func(struct my_struct *arg);
-
-Some TF definitions use both a struct/enum name **and** a typedef name. This
-is discouraged for new definitions as it makes it difficult for TF to comply
-with MISRA rule 8.3, which states that "All declarations of an object or
-function shall use the same names and type qualifiers".
+  void init(const struct my_struct *ptr);
 
-The Linux coding standards also discourage new typedefs and checkpatch emits
-a warning for this.
+  void main(void)
+  {
+          const struct my_struct x = { 1, 2 };
+          init(&x);
+  }
 
-Existing typedefs will be retained for compatibility.
+This allows the linker to put the data in a read-only data section instead of a
+writeable data section, which may result in a smaller and faster binary. Note
+that this may require dependent functions (``init()`` in the above example) to
+have ``const`` arguments, assuming they don't need to modify the data.
 
 Libc functions that are banned or to be used with caution
 ---------------------------------------------------------
@@ -410,14 +291,14 @@
    then emit an ``ERROR`` message and call the platform-specific function
    ``plat_error_handler()``.
 
-Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler``
-and ``plat_error_handler`` in the same way (for example, by waiting for a secure
-watchdog to time-out or by invoking an interface on the platform's power
-controller to reset the platform). However, ``plat_error_handler`` may take
-additional action for some errors (for example, it may set a flag so the
-platform resets into a different mode). Also, ``plat_panic_handler()`` may
-implement additional debug functionality (for example, invoking a hardware
-breakpoint).
+Cases 1 and 2 are subtly different. A platform may implement
+``plat_panic_handler`` and ``plat_error_handler`` in the same way (for example,
+by waiting for a secure watchdog to time-out or by invoking an interface on the
+platform's power controller to reset the platform). However,
+``plat_error_handler`` may take additional action for some errors (for example,
+it may set a flag so the platform resets into a different mode). Also,
+``plat_panic_handler()`` may implement additional debug functionality (for
+example, invoking a hardware breakpoint).
 
 Examples of unexpected unrecoverable errors:
 
@@ -456,131 +337,115 @@
 - Secure world is waiting for a hardware response that is critical for continued
   operation.
 
-Security considerations
------------------------
-
-Part of the security of a platform is handling errors correctly, as described in
-the previous section. There are several other security considerations covered in
-this section.
-
-Do not leak secrets to the normal world
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The secure world **must not** leak secrets to the normal world, for example in
-response to an SMC.
-
-Handling Denial of Service attacks
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Use of built-in *C* and *libc* data types
+-----------------------------------------
 
-The secure world **should never** crash or become unusable due to receiving too
-many normal world requests (a *Denial of Service* or *DoS* attack). It should
-have a mechanism for throttling or ignoring normal world requests.
+The |TF-A| codebase should be kept as portable as possible, especially since
+both 64-bit and 32-bit platforms are supported. To help with this, the following
+data type usage guidelines should be followed:
 
-Performance considerations
---------------------------
+- Where possible, use the built-in *C* data types for variable storage (for
+  example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
+  types. Most code is typically only concerned with the minimum size of the
+  data stored, which the built-in *C* types guarantee.
 
-Avoid printf and use logging macros
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+- Avoid using the exact-size standard *C99* types in general (for example,
+  ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
+  compiler from making optimizations. There are legitimate uses for them,
+  for example to represent data of a known structure. When using them in struct
+  definitions, consider how padding in the struct will work across architectures.
+  For example, extra padding may be introduced in |AArch32| systems if a struct
+  member crosses a 32-bit boundary.
 
-``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
-which wrap ``tf_log`` and which allow the logging call to be compiled-out
-depending on the ``make`` command. Use these macros to avoid print statements
-being compiled unconditionally into the binary.
+- Use ``int`` as the default integer type - it's likely to be the fastest on all
+  systems. Also this can be assumed to be 32-bit as a consequence of the
+  `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
+  Standard for the Arm 64-bit Architecture`_ .
 
-Each logging macro has a numerical log level:
+- Avoid use of ``short`` as this may end up being slower than ``int`` in some
+  systems. If a variable must be exactly 16-bit, use ``int16_t`` or
+  ``uint16_t``.
 
-.. code:: c
+- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
+  that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
+  at least 64-bit, use ``long long``.
 
-  #define LOG_LEVEL_NONE    0
-  #define LOG_LEVEL_ERROR   10
-  #define LOG_LEVEL_NOTICE  20
-  #define LOG_LEVEL_WARNING 30
-  #define LOG_LEVEL_INFO    40
-  #define LOG_LEVEL_VERBOSE 50
+- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
 
+- Use ``unsigned`` for integers that can never be negative (counts,
+  indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
+  rules (10.X), where signed and unsigned types are considered different
+  essential types. Choosing the correct type will aid this. MISRA static
+  analysers will pick up any implicit signed/unsigned conversions that may lead
+  to unexpected behaviour.
 
-By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
-be compiled into debug builds and all statements with a log level
-``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
-overridden from the command line or by the platform makefile (although it may be
-necessary to clean the build directory first). For example, to enable
-``VERBOSE`` logging on FVP:
+- For pointer types:
 
-``make PLAT=fvp LOG_LEVEL=50 all``
+  - If an argument in a function declaration is pointing to a known type then
+    simply use a pointer to that type (for example: ``struct my_struct *``).
 
-Use const data where possible
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  - If a variable (including an argument in a function declaration) is pointing
+    to a general, memory-mapped address, an array of pointers or another
+    structure that is likely to require pointer arithmetic then use
+    ``uintptr_t``. This will reduce the amount of casting required in the code.
+    Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
+    may work but is less portable.
 
-For example, the following code:
+  - For other pointer arguments in a function declaration, use ``void *``. This
+    includes pointers to types that are abstracted away from the known API and
+    pointers to arbitrary data. This allows the calling function to pass a
+    pointer argument to the function without any explicit casting (the cast to
+    ``void *`` is implicit). The function implementation can then do the
+    appropriate casting to a specific type.
 
-.. code:: c
+  - Avoid pointer arithmetic generally (as this violates MISRA C 2012 rule
+    18.4) and especially on void pointers (as this is only supported via
+    language extensions and is considered non-standard). In TF-A, setting the
+    ``W`` build flag to ``W=3`` enables the *-Wpointer-arith* compiler flag and
+    this will emit warnings where pointer arithmetic is used.
 
-  struct my_struct {
-          int arg1;
-          int arg2;
-  };
+  - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
 
-  void init(struct my_struct *ptr);
+- Use ``size_t`` when storing the ``sizeof()`` something.
 
-  void main(void)
-  {
-          struct my_struct x;
-          x.arg1 = 1;
-          x.arg2 = 2;
-          init(&x);
-  }
+- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
+  can also return an error code; the signed type allows for a negative return
+  code in case of error. This practice should be used sparingly.
 
-is better written as:
+- Use ``u_register_t`` when it's important to store the contents of a register
+  in its native size (32-bit in |AArch32| and 64-bit in |AArch64|). This is not a
+  standard *C99* type but is widely available in libc implementations,
+  including the FreeBSD version included with the TF codebase. Where possible,
+  cast the variable to a more appropriate type before interpreting the data. For
+  example, the following struct in ``ep_info.h`` could use this type to minimize
+  the storage required for the set of registers:
 
 .. code:: c
 
-  struct my_struct {
-          int arg1;
-          int arg2;
-  };
-
-  void init(const struct my_struct *ptr);
-
-  void main(void)
-  {
-          const struct my_struct x = { 1, 2 };
-          init(&x);
-  }
-
-This allows the linker to put the data in a read-only data section instead of a
-writeable data section, which may result in a smaller and faster binary. Note
-that this may require dependent functions (``init()`` in the above example) to
-have ``const`` arguments, assuming they don't need to modify the data.
-
-Library and driver code
------------------------
-
-TF library code (under ``lib/`` and ``include/lib``) is any code that provides a
-reusable interface to other code, potentially even to code outside of TF.
-
-In some systems drivers must conform to a specific driver framework to provide
-services to the rest of the system. TF has no driver framework and the
-distinction between a driver and library is somewhat subjective.
+    typedef struct aapcs64_params {
+            u_register_t arg0;
+            u_register_t arg1;
+            u_register_t arg2;
+            u_register_t arg3;
+            u_register_t arg4;
+            u_register_t arg5;
+            u_register_t arg6;
+            u_register_t arg7;
+    } aapcs64_params_t;
 
-A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that
-interfaces with hardware via a memory mapped interface.
+If some code wants to operate on ``arg0`` and knows that it represents a 32-bit
+unsigned integer on all systems, cast it to ``unsigned int``.
 
-Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``)
-provide a general purpose API to that specific hardware. Other drivers (for
-example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``)
-provide a specific hardware implementation of a more abstract library API. In
-the latter case there may potentially be multiple drivers for the same hardware
-device.
+These guidelines should be updated if additional types are needed.
 
-Neither libraries nor drivers should depend on platform-specific code. If they
-require platform-specific data (for example, a base address) to operate then
-they should provide an initialization function that takes the platform-specific
-data as arguments.
+--------------
 
-TF common code (under ``common/`` and ``include/common/``) is code that is re-used
-by other generic (non-platform-specific) TF code. It is effectively internal
-library code.
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
 
+.. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/
+.. _`Procedure Call Standard for the Arm Architecture`: https://developer.arm.com/docs/ihi0042/latest/
+.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://developer.arm.com/docs/ihi0055/latest/
+.. _`EditorConfig`: http://editorconfig.org/
 .. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
-.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
-.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
+.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
+.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods
diff --git a/docs/process/coding-style.rst b/docs/process/coding-style.rst
new file mode 100644
index 0000000..fd1984d
--- /dev/null
+++ b/docs/process/coding-style.rst
@@ -0,0 +1,468 @@
+Coding Style
+============
+
+The following sections outline the |TF-A| coding style for *C* code. The style
+is based on the `Linux kernel coding style`_, with a few modifications.
+
+The style should not be considered *set in stone*. Feel free to provide feedback
+and suggestions.
+
+.. note::
+   You will almost certainly find code in the |TF-A| repository that does not
+   follow the style. The intent is for all code to do so eventually.
+
+File Encoding
+-------------
+
+The source code must use the **UTF-8** character encoding. Comments and
+documentation may use non-ASCII characters when required (e.g. Greek letters
+used for units) but code itself is still limited to ASCII characters.
+
+Newlines must be in **Unix** style, which means that only the Line Feed (``LF``)
+character is used to break a line and reset to the first column.
+
+Language
+--------
+
+The primary language for comments and naming must be International English. In
+cases where there is a conflict between the American English and British English
+spellings of a word, the American English spelling is used.
+
+Exceptions are made when referring directly to something that does not use
+international style, such as the name of a company. In these cases the existing
+name should be used as-is.
+
+C Language Standard
+-------------------
+
+The C language mode used for TF-A is *GNU99*. This is the "GNU dialect of ISO
+C99", which implies the *ISO C99* standard with GNU extensions.
+
+Both GCC and Clang compiler toolchains have support for *GNU99* mode, though
+Clang does lack support for a small number of GNU extensions. These
+missing extensions are rarely used, however, and should not pose a problem.
+
+MISRA Compliance
+----------------
+
+TF-A attempts to comply with the `MISRA C:2012 Guidelines`_. Coverity
+Static Analysis is used to regularly generate a report of current MISRA defects
+and to prevent the addition of new ones.
+
+It is not possible for the project to follow all MISRA guidelines. We maintain
+`a spreadsheet`_ that lists all rules and directives and whether we aim to
+comply with them or not. A rationale is given for each deviation.
+
+.. note::
+   Enforcing a rule does not mean that the codebase is free of defects
+   of that rule, only that they would ideally be removed.
+
+.. note::
+   Third-party libraries are not considered in our MISRA analysis and we do not
+   intend to modify them to make them MISRA compliant.
+
+Indentation
+-----------
+
+Use **tabs** for indentation. The use of spaces for indentation is forbidden
+except in the case where a term is being indented to a boundary that cannot be
+achieved using tabs alone.
+
+Tab spacing should be set to **8 characters**.
+
+Trailing whitespace is not allowed and must be trimmed.
+
+Spacing
+-------
+
+Single spacing should be used around most operators, including:
+
+- Arithmetic operators (``+``, ``-``, ``/``, ``*``)
+- Assignment operators (``=``, ``+=``, etc)
+- Boolean operators (``&&``, ``||``)
+- Comparison operators (``<``, ``>``, ``==``, etc)
+
+A space should also be used to separate parentheses and braces when they are not
+already separated by a newline, such as for the ``if`` statement in the
+following example:
+
+.. code:: c
+
+  int function_foo(bool bar)
+  {
+      if (bar) {
+          function_baz();
+      }
+  }
+
+Note that there is no space between the name of a function and the following
+parentheses.
+
+Control statements (``if``, ``for``, ``switch``, ``while``, etc) must be
+separated from the following open paranthesis by a single space. The previous
+example illustrates this for an ``if`` statement.
+
+Line Length
+-----------
+
+Line length *should* be at most **80 characters**. This limit does not include
+non-printing characters such as the line feed.
+
+This rule is a *should*, not a must, and it is acceptable to exceed the limit
+**slightly** where the readability of the code would otherwise be significantly
+reduced. Use your judgement in these cases.
+
+Blank Lines
+-----------
+
+Functions are usually separated by a single blank line. In certain cases it is
+acceptable to use additional blank lines for clarity, if required.
+
+The file must end with a single newline character. Many editors have the option
+to insert this automatically and to trim multiple blank lines at the end of the
+file.
+
+Braces
+------
+
+Opening Brace Placement
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Braces follow the **Kernighan and Ritchie (K&R)** style, where the opening brace
+is **not** placed on a new line.
+
+Example for a ``while`` loop:
+
+.. code:: c
+
+  while (condition) {
+      foo();
+      bar();
+  }
+
+This style applies to all blocks except for functions which, following the Linux
+style, **do** place the opening brace on a new line.
+
+Example for a function:
+
+.. code:: c
+
+  int my_function(void)
+  {
+      int a;
+
+      a = 1;
+      return a;
+  }
+
+Conditional Statement Bodies
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Where conditional statements (such as ``if``, ``for``, ``while`` and ``do``) are
+used, braces must be placed around the statements that form the body of the
+conditional. This is the case regardless of the number of statements in the
+body.
+
+.. note::
+  This is a notable departure from the Linux coding style that has been
+  adopted to follow MISRA guidelines more closely and to help prevent errors.
+
+For example, use the following style:
+
+.. code:: c
+
+  if (condition) {
+      foo++;
+  }
+
+instead of omitting the optional braces around a single statement:
+
+.. code:: c
+
+  /* This is violating MISRA C 2012: Rule 15.6 */
+  if (condition)
+      foo++;
+
+The reason for this is to prevent accidental changes to control flow when
+modifying the body of the conditional. For example, at a quick glance it is easy
+to think that the value of ``bar`` is only incremented if ``condition``
+evaluates to ``true`` but this is not the case - ``bar`` will always be
+incremented regardless of the condition evaluation. If the developer forgets to
+add braces around the conditional body when adding the ``bar++;`` statement then
+the program execution will not proceed as intended.
+
+.. code:: c
+
+  /* This is violating MISRA C 2012: Rule 15.6 */
+  if (condition)
+      foo++;
+      bar++;
+
+Naming
+------
+
+Functions
+^^^^^^^^^
+
+Use lowercase for function names, separating multiple words with an underscore
+character (``_``). This is sometimes referred to as *Snake Case*. An example is
+given below:
+
+.. code:: c
+
+  void bl2_arch_setup(void)
+  {
+      ...
+  }
+
+Local Variables and Parameters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Local variables and function parameters use the same format as function names:
+lowercase with underscore separation between multiple words. An example is
+given below:
+
+.. code:: c
+
+  static void set_scr_el3_from_rm(uint32_t type,
+                                  uint32_t interrupt_type_flags,
+                                  uint32_t security_state)
+  {
+      uint32_t flag, bit_pos;
+
+      ...
+
+  }
+
+Preprocessor Macros
+^^^^^^^^^^^^^^^^^^^
+
+Identifiers that are defined using preprocessor macros are written in all
+uppercase text.
+
+.. code:: c
+
+  #define BUFFER_SIZE_BYTES 64
+
+Function Attributes
+-------------------
+
+Place any function attributes after the function type and before the function
+name.
+
+.. code:: c
+
+   void __init plat_arm_interconnect_init(void);
+
+Alignment
+---------
+
+Alignment should be performed primarily with tabs, adding spaces if required to
+achieve a granularity that is smaller than the tab size. For example, with a tab
+size of eight columns it would be necessary to use one tab character and two
+spaces to indent text by ten columns.
+
+Switch Statement Alignment
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When using ``switch`` statements, align each ``case`` statement with the
+``switch`` so that they are in the same column.
+
+.. code:: c
+
+  switch (condition) {
+  case A:
+      foo();
+  case B:
+      bar();
+  default:
+      baz();
+  }
+
+Pointer Alignment
+^^^^^^^^^^^^^^^^^
+
+The reference and dereference operators (ampersand and *pointer star*) must be
+aligned with the name of the object on which they are operating, as opposed to
+the type of the object.
+
+.. code:: c
+
+  uint8_t *foo;
+
+  foo = &bar;
+
+
+Comments
+--------
+
+The general rule for comments is that the double-slash style of comment (``//``)
+is not allowed. Examples of the allowed comment formats are shown below:
+
+.. code:: c
+
+  /*
+   * This example illustrates the first allowed style for multi-line comments.
+   *
+   * Blank lines within multi-lines are allowed when they add clarity or when
+   * they separate multiple contexts.
+   *
+   */
+
+.. code:: c
+
+  /**************************************************************************
+   * This is the second allowed style for multi-line comments.
+   *
+   * In this style, the first and last lines use asterisks that run the full
+   * width of the comment at its widest point.
+   *
+   * This style can be used for additional emphasis.
+   *
+   *************************************************************************/
+
+.. code:: c
+
+  /* Single line comments can use this format */
+
+.. code:: c
+
+  /***************************************************************************
+   * This alternative single-line comment style can also be used for emphasis.
+   **************************************************************************/
+
+Headers and inclusion
+---------------------
+
+Header guards
+^^^^^^^^^^^^^
+
+For a header file called "some_driver.h" the style used by |TF-A| is:
+
+.. code:: c
+
+  #ifndef SOME_DRIVER_H
+  #define SOME_DRIVER_H
+
+  <header content>
+
+  #endif /* SOME_DRIVER_H */
+
+Include statement ordering
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+All header files that are included by a source file must use the following,
+grouped ordering. This is to improve readability (by making it easier to quickly
+read through the list of headers) and maintainability.
+
+#. *System* includes: Header files from the standard *C* library, such as
+   ``stddef.h`` and ``string.h``.
+
+#. *Project* includes: Header files under the ``include/`` directory within
+   |TF-A| are *project* includes.
+
+#. *Platform* includes: Header files relating to a single, specific platform,
+   and which are located under the ``plat/<platform_name>`` directory within
+   |TF-A|, are *platform* includes.
+
+Within each group, ``#include`` statements must be in alphabetical order,
+taking both the file and directory names into account.
+
+Groups must be separated by a single blank line for clarity.
+
+The example below illustrates the ordering rules using some contrived header
+file names; this type of name reuse should be otherwise avoided.
+
+.. code:: c
+
+  #include <string.h>
+
+  #include <a_dir/example/a_header.h>
+  #include <a_dir/example/b_header.h>
+  #include <a_dir/test/a_header.h>
+  #include <b_dir/example/a_header.h>
+
+  #include "a_header.h"
+
+Include statement variants
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Two variants of the ``#include`` directive are acceptable in the |TF-A|
+codebase. Correct use of the two styles improves readability by suggesting the
+location of the included header and reducing ambiguity in cases where generic
+and platform-specific headers share a name.
+
+For header files that are in the same directory as the source file that is
+including them, use the ``"..."`` variant.
+
+For header files that are **not** in the same directory as the source file that
+is including them, use the ``<...>`` variant.
+
+Example (bl1_fwu.c):
+
+.. code:: c
+
+  #include <assert.h>
+  #include <errno.h>
+  #include <string.h>
+
+  #include "bl1_private.h"
+
+Typedefs
+--------
+
+Avoid anonymous typedefs of structs/enums in headers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following definition:
+
+.. code:: c
+
+  typedef struct {
+          int arg1;
+          int arg2;
+  } my_struct_t;
+
+
+is better written as:
+
+.. code:: c
+
+  struct my_struct {
+          int arg1;
+          int arg2;
+  };
+
+This allows function declarations in other header files that depend on the
+struct/enum to forward declare the struct/enum instead of including the
+entire header:
+
+.. code:: c
+
+  struct my_struct;
+  void my_func(struct my_struct *arg);
+
+instead of:
+
+.. code:: c
+
+  #include <my_struct.h>
+  void my_func(my_struct_t *arg);
+
+Some TF definitions use both a struct/enum name **and** a typedef name. This
+is discouraged for new definitions as it makes it difficult for TF to comply
+with MISRA rule 8.3, which states that "All declarations of an object or
+function shall use the same names and type qualifiers".
+
+The Linux coding standards also discourage new typedefs and checkpatch emits
+a warning for this.
+
+Existing typedefs will be retained for compatibility.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
+
+.. _`Linux kernel coding style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
+.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
+.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index f569fcb..68c494b 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -23,7 +23,7 @@
 
 -  Make commits of logical units. See these general `Git guidelines`_ for
    contributing to a project.
--  Follow the :ref:`Coding Style & Guidelines`.
+-  Follow the :ref:`Coding Style` and :ref:`Coding Guidelines`.
 
    -  Use the checkpatch.pl script provided with the Linux source tree. A
       Makefile target is provided for convenience.
@@ -128,7 +128,7 @@
 
 --------------
 
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
 
 .. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
 .. _issue: https://developer.trustedfirmware.org/project/board/1/
diff --git a/docs/process/index.rst b/docs/process/index.rst
index 9c12de8..1cb5354 100644
--- a/docs/process/index.rst
+++ b/docs/process/index.rst
@@ -8,6 +8,7 @@
 
    security
    platform-compatibility-policy
+   coding-style
    coding-guidelines
    contributing
    faq
diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst
index a18a792..43a5721 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -1,10 +1,30 @@
-Security hardening
-==================
+Secure Development Guidelines
+=============================
 
 This page contains guidance on what to check for additional security measures,
 including build options that can be modified to improve security or catch issues
 early in development.
 
+Security considerations
+-----------------------
+
+Part of the security of a platform is handling errors correctly, as described in
+the previous section. There are several other security considerations covered in
+this section.
+
+Do not leak secrets to the normal world
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** leak secrets to the normal world, for example in
+response to an SMC.
+
+Handling Denial of Service attacks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **should never** crash or become unusable due to receiving too
+many normal world requests (a *Denial of Service* or *DoS* attack). It should
+have a mechanism for throttling or ignoring normal world requests.
+
 Build options
 -------------
 
@@ -53,4 +73,4 @@
 
 --------------
 
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c
index 8858742..c51f3b1 100644
--- a/drivers/arm/css/mhu/css_mhu_doorbell.c
+++ b/drivers/arm/css/mhu/css_mhu_doorbell.c
@@ -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
  */
@@ -20,11 +20,13 @@
 
 void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info)
 {
+	uintptr_t mhuv2_base = plat_info->db_reg_addr & MHU_V2_FRAME_BASE_MASK;
+
 	/* wake receiver */
-	MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR);
+	MHU_V2_ACCESS_REQUEST(mhuv2_base);
 
 	/* wait for receiver to acknowledge its ready */
-	while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0)
+	while (MHU_V2_IS_ACCESS_READY(mhuv2_base) == 0)
 		;
 
 	MHU_RING_DOORBELL(plat_info->db_reg_addr,
@@ -32,7 +34,7 @@
 			plat_info->db_preserve_mask);
 
 	/* clear the access request for the receiver */
-	MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR);
+	MHU_V2_CLEAR_REQUEST(mhuv2_base);
 
 	return;
 }
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index b945cda..097d2eb 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -63,17 +63,45 @@
 } scmi_power_state_t;
 
 /*
- * The global handle for invoking the SCMI driver APIs after the driver
+ * The global handles for invoking the SCMI driver APIs after the driver
  * has been initialized.
  */
-static void *scmi_handle;
+static void *scmi_handles[PLAT_ARM_SCMI_CHANNEL_COUNT];
 
-/* The SCMI channel global object */
-static scmi_channel_t channel;
+/* The global SCMI channels array */
+static scmi_channel_t scmi_channels[PLAT_ARM_SCMI_CHANNEL_COUNT];
 
+/*
+ * Channel ID for the default SCMI channel.
+ * The default channel is used to issue SYSTEM level SCMI requests and is
+ * initialized to the channel which has the boot cpu as its resource.
+ */
+static uint32_t default_scmi_channel_id;
+
+/*
+ * TODO: Allow use of channel specific lock instead of using a single lock for
+ * all the channels.
+ */
 ARM_SCMI_INSTANTIATE_LOCK;
 
 /*
+ * Function to obtain the SCMI Domain ID and SCMI Channel number from the linear
+ * core position. The SCMI Channel number is encoded in the upper 16 bits and
+ * the Domain ID is encoded in the lower 16 bits in each entry of the mapping
+ * array exported by the platform.
+ */
+static void css_scp_core_pos_to_scmi_channel(unsigned int core_pos,
+		unsigned int *scmi_domain_id, unsigned int *scmi_channel_id)
+{
+	unsigned int composite_id;
+
+	composite_id = plat_css_core_pos_to_scmi_dmn_id_map[core_pos];
+
+	*scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id);
+	*scmi_domain_id = GET_SCMI_DOMAIN_ID(composite_id);
+}
+
+/*
  * Helper function to suspend a CPU power domain and its parent power domains
  * if applicable.
  */
@@ -87,10 +115,10 @@
 
 	/* Check if power down at system power domain level is requested */
 	if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) {
-		/* Issue SCMI command for SYSTEM_SUSPEND */
-		ret = scmi_sys_pwr_state_set(scmi_handle,
-				SCMI_SYS_PWR_FORCEFUL_REQ,
-				SCMI_SYS_PWR_SUSPEND);
+		/* Issue SCMI command for SYSTEM_SUSPEND on all SCMI channels */
+		ret = scmi_sys_pwr_state_set(
+				scmi_handles[default_scmi_channel_id],
+				SCMI_SYS_PWR_FORCEFUL_REQ, SCMI_SYS_PWR_SUSPEND);
 		if (ret != SCMI_E_SUCCESS) {
 			ERROR("SCMI system power domain suspend return 0x%x unexpected\n",
 					ret);
@@ -99,7 +127,7 @@
 		return;
 	}
 #if !HW_ASSISTED_COHERENCY
-	unsigned int lvl;
+	unsigned int lvl, channel_id, domain_id;
 	uint32_t scmi_pwr_state = 0;
 	/*
 	 * If we reach here, then assert that power down at system power domain
@@ -127,9 +155,10 @@
 
 	SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
 
-	ret = scmi_pwr_state_set(scmi_handle,
-		plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()],
-		scmi_pwr_state);
+	css_scp_core_pos_to_scmi_channel(plat_my_core_pos(),
+			&domain_id, &channel_id);
+	ret = scmi_pwr_state_set(scmi_handles[channel_id],
+		domain_id, scmi_pwr_state);
 
 	if (ret != SCMI_E_SUCCESS) {
 		ERROR("SCMI set power state command return 0x%x unexpected\n",
@@ -145,7 +174,7 @@
  */
 void css_scp_off(const struct psci_power_state *target_state)
 {
-	unsigned int lvl = 0;
+	unsigned int lvl = 0, channel_id, domain_id;
 	int ret;
 	uint32_t scmi_pwr_state = 0;
 
@@ -168,10 +197,10 @@
 
 	SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
 
-	ret = scmi_pwr_state_set(scmi_handle,
-		plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()],
-		scmi_pwr_state);
-
+	css_scp_core_pos_to_scmi_channel(plat_my_core_pos(),
+			&domain_id, &channel_id);
+	ret = scmi_pwr_state_set(scmi_handles[channel_id],
+		domain_id, scmi_pwr_state);
 	if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
 		ERROR("SCMI set power state command return 0x%x unexpected\n",
 				ret);
@@ -185,8 +214,8 @@
  */
 void css_scp_on(u_register_t mpidr)
 {
-	unsigned int lvl = 0;
-	int core_pos, ret;
+	unsigned int lvl = 0, channel_id, core_pos, domain_id;
+	int ret;
 	uint32_t scmi_pwr_state = 0;
 
 	for (; lvl <= PLAT_MAX_PWR_LVL; lvl++)
@@ -196,13 +225,12 @@
 	SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
 
 	core_pos = plat_core_pos_by_mpidr(mpidr);
-	assert((core_pos >= 0) &&
-		(((unsigned int)core_pos) < PLATFORM_CORE_COUNT));
+	assert(core_pos >= 0 && (core_pos < PLATFORM_CORE_COUNT));
 
-	ret = scmi_pwr_state_set(scmi_handle,
-		plat_css_core_pos_to_scmi_dmn_id_map[core_pos],
-		scmi_pwr_state);
-
+	css_scp_core_pos_to_scmi_channel(core_pos, &domain_id,
+			&channel_id);
+	ret = scmi_pwr_state_set(scmi_handles[channel_id],
+		domain_id, scmi_pwr_state);
 	if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
 		ERROR("SCMI set power state command return 0x%x unexpected\n",
 				ret);
@@ -216,8 +244,9 @@
  */
 int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
 {
-	int ret, cpu_idx;
+	int ret;
 	uint32_t scmi_pwr_state = 0, lvl_state;
+	unsigned int channel_id, cpu_idx, domain_id;
 
 	/* We don't support get power state at the system power domain level */
 	if ((power_level > PLAT_MAX_PWR_LVL) ||
@@ -230,9 +259,9 @@
 	cpu_idx = plat_core_pos_by_mpidr(mpidr);
 	assert(cpu_idx > -1);
 
-	ret = scmi_pwr_state_get(scmi_handle,
-		plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx],
-		&scmi_pwr_state);
+	css_scp_core_pos_to_scmi_channel(cpu_idx, &domain_id, &channel_id);
+	ret = scmi_pwr_state_get(scmi_handles[channel_id],
+		domain_id, &scmi_pwr_state);
 
 	if (ret != SCMI_E_SUCCESS) {
 		WARN("SCMI get power state command return 0x%x unexpected\n",
@@ -271,7 +300,7 @@
 	 * Issue SCMI command. First issue a graceful
 	 * request and if that fails force the request.
 	 */
-	ret = scmi_sys_pwr_state_set(scmi_handle,
+	ret = scmi_sys_pwr_state_set(scmi_handles[default_scmi_channel_id],
 			SCMI_SYS_PWR_FORCEFUL_REQ,
 			state);
 
@@ -325,17 +354,28 @@
 
 void __init plat_arm_pwrc_setup(void)
 {
-	channel.info = plat_css_get_scmi_info();
-	channel.lock = ARM_SCMI_LOCK_GET_INSTANCE;
-	scmi_handle = scmi_init(&channel);
-	if (scmi_handle == NULL) {
-		ERROR("SCMI Initialization failed\n");
-		panic();
-	}
-	if (scmi_ap_core_init(&channel) < 0) {
-		ERROR("SCMI AP core protocol initialization failed\n");
-		panic();
+	unsigned int composite_id, idx;
+
+	for (idx = 0; idx < PLAT_ARM_SCMI_CHANNEL_COUNT; idx++) {
+		INFO("Initializing driver on Channel %d\n", idx);
+
+		scmi_channels[idx].info = plat_css_get_scmi_info(idx);
+		scmi_channels[idx].lock = ARM_SCMI_LOCK_GET_INSTANCE;
+		scmi_handles[idx] = scmi_init(&scmi_channels[idx]);
+
+		if (scmi_handles[idx] == NULL) {
+			ERROR("SCMI Initialization failed on channel %d\n", idx);
+			panic();
+		}
+
+		if (scmi_ap_core_init(&scmi_channels[idx]) < 0) {
+			ERROR("SCMI AP core protocol initialization failed\n");
+			panic();
+		}
 	}
+
+	composite_id = plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()];
+	default_scmi_channel_id = GET_SCMI_CHANNEL_ID(composite_id);
 }
 
 /******************************************************************************
@@ -347,6 +387,7 @@
 {
 	uint32_t msg_attr;
 	int ret;
+	void *scmi_handle = scmi_handles[default_scmi_channel_id];
 
 	assert(scmi_handle);
 
@@ -411,14 +452,17 @@
 #if PROGRAMMABLE_RESET_ADDRESS
 void plat_arm_program_trusted_mailbox(uintptr_t address)
 {
-	int ret;
+	int ret, i;
 
-	assert(scmi_handle);
-	ret = scmi_ap_core_set_reset_addr(scmi_handle, address,
-		SCMI_AP_CORE_LOCK_ATTR);
-	if (ret != SCMI_E_SUCCESS) {
-		ERROR("CSS: Failed to program reset address: %d\n", ret);
-		panic();
+	for (i = 0; i < PLAT_ARM_SCMI_CHANNEL_COUNT; i++) {
+		assert(scmi_handles[i]);
+
+		ret = scmi_ap_core_set_reset_addr(scmi_handles[i], address,
+				SCMI_AP_CORE_LOCK_ATTR);
+		if (ret != SCMI_E_SUCCESS) {
+			ERROR("CSS: Failed to program reset address: %d\n", ret);
+			panic();
+		}
 	}
 }
 #endif
diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h
index e6f7a1b..88302fd 100644
--- a/include/drivers/arm/css/css_mhu_doorbell.h
+++ b/include/drivers/arm/css/css_mhu_doorbell.h
@@ -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
  */
@@ -11,13 +11,13 @@
 
 #include <lib/mmio.h>
 
-/* MHUv2 Base Address */
-#define MHUV2_BASE_ADDR		PLAT_MHUV2_BASE
+/* MHUv2 Frame Base Mask */
+#define MHU_V2_FRAME_BASE_MASK			UL(~0xFFF)
 
 /* MHUv2 Control Registers Offsets */
-#define MHU_V2_MSG_NO_CAP_OFFSET		0xF80
-#define MHU_V2_ACCESS_REQ_OFFSET		0xF88
-#define MHU_V2_ACCESS_READY_OFFSET		0xF8C
+#define MHU_V2_MSG_NO_CAP_OFFSET		UL(0xF80)
+#define MHU_V2_ACCESS_REQ_OFFSET		UL(0xF88)
+#define MHU_V2_ACCESS_READY_OFFSET		UL(0xF8C)
 
 #define SENDER_REG_STAT(_channel)	(0x20 * (_channel))
 #define SENDER_REG_SET(_channel)	((0x20 * (_channel)) + 0xC)
diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h
index 1f8dc6c..e8a2863 100644
--- a/include/drivers/arm/css/scmi.h
+++ b/include/drivers/arm/css/scmi.h
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -162,7 +162,7 @@
 int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr);
 
 /* API to get the platform specific SCMI channel information. */
-scmi_channel_plat_info_t *plat_css_get_scmi_info(void);
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id);
 
 /* API to override default PSCI callbacks for platforms that support SCMI. */
 const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops);
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 5bd53f3..c825bf4 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -18,6 +18,12 @@
  * Definitions common to all ARM standard platforms
  *****************************************************************************/
 
+/*
+ * Root of trust key hash lengths
+ */
+#define ARM_ROTPK_HEADER_LEN		19
+#define ARM_ROTPK_HASH_LEN		32
+
 /* Special value used to verify platform parameters from BL2 to BL31 */
 #define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
 
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 02feec7..32dc9f9 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.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
  */
@@ -142,6 +142,11 @@
 #define STATE_SW_E_PARAM		(-2)
 #define STATE_SW_E_DENIED		(-3)
 
+/* plat_get_rotpk_info() flags */
+#define ARM_ROTPK_REGS_ID		1
+#define ARM_ROTPK_DEVEL_RSA_ID		2
+#define ARM_ROTPK_DEVEL_ECDSA_ID	3
+
 /* IO storage utility functions */
 void arm_io_setup(void);
 
@@ -255,9 +260,17 @@
 __dead2 void plat_arm_error_handler(int err);
 
 /*
- * Optional function in ARM standard platforms
+ * Optional functions in ARM standard platforms
  */
 void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames);
+int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len,
+	unsigned int *flags);
+int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
+	unsigned int *flags);
+int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
+	unsigned int *flags);
+int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
+	unsigned int *flags);
 
 #if ARM_PLAT_MT
 unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 2adf11d..7b61484 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,6 +29,10 @@
 #define SID_REG_BASE			0x2a4a0000
 #define SID_SYSTEM_ID_OFFSET		0x40
 #define SID_SYSTEM_CFG_OFFSET		0x70
+#define SID_NODE_ID_OFFSET		0x60
+#define SID_CHIP_ID_MASK		0xFF
+#define SID_MULTI_CHIP_MODE_MASK	0x100
+#define SID_MULTI_CHIP_MODE_SHIFT	8
 
 /* The slave_bootsecure controls access to GPU, DMC and CS. */
 #define CSS_NIC400_SLAVE_BOOTSECURE	8
diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h
index 93f8616..e5357f5 100644
--- a/include/plat/arm/css/common/css_pm.h
+++ b/include/plat/arm/css/common/css_pm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-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
  */
@@ -44,4 +44,15 @@
  */
 extern const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[];
 
+#define SCMI_DOMAIN_ID_MASK		U(0xFFFF)
+#define SCMI_CHANNEL_ID_MASK		U(0xFFFF)
+#define SCMI_CHANNEL_ID_SHIFT		U(16)
+
+#define SET_SCMI_CHANNEL_ID(n)		(((n) & SCMI_CHANNEL_ID_MASK) << \
+					 SCMI_CHANNEL_ID_SHIFT)
+#define SET_SCMI_DOMAIN_ID(n)		((n) & SCMI_DOMAIN_ID_MASK)
+#define GET_SCMI_CHANNEL_ID(n)		(((n) >> SCMI_CHANNEL_ID_SHIFT) & \
+					 SCMI_CHANNEL_ID_MASK)
+#define GET_SCMI_DOMAIN_ID(n)		((n) & SCMI_DOMAIN_ID_MASK)
+
 #endif /* CSS_PM_H */
diff --git a/include/tools_share/sptool.h b/include/tools_share/sptool.h
index 67a2cf0..53668e0 100644
--- a/include/tools_share/sptool.h
+++ b/include/tools_share/sptool.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,21 +9,17 @@
 
 #include <stdint.h>
 
-/* Header for a secure partition package. There is one per package. */
-struct sp_pkg_header {
-	uint64_t version;
-	uint64_t number_of_sp;
-};
+/* 4 Byte magic name "SPKG" */
+#define SECURE_PARTITION_MAGIC		0x474B5053
 
-/*
- * Entry descriptor in a secure partition package. Each entry comprises a
- * secure partition and its resource description.
- */
-struct sp_pkg_entry {
-	uint64_t sp_offset;
-	uint64_t sp_size;
-	uint64_t rd_offset;
-	uint64_t rd_size;
+/* Header for a secure partition package. */
+struct sp_pkg_header {
+	uint32_t magic;
+	uint32_t version;
+	uint32_t pm_offset;
+	uint32_t pm_size;
+	uint32_t img_offset;
+	uint32_t img_size;
 };
 
 #endif /* SPTOOL_H */
diff --git a/plat/amlogic/axg/axg_bl31_setup.c b/plat/amlogic/axg/axg_bl31_setup.c
new file mode 100644
index 0000000..8cc9d69
--- /dev/null
+++ b/plat/amlogic/axg/axg_bl31_setup.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/bl_common.h>
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv2.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "aml_private.h"
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+static image_info_t bl30_image_info;
+static image_info_t bl301_image_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	entry_point_info_t *next_image_info;
+
+	next_image_info = (type == NON_SECURE) ?
+			  &bl33_image_ep_info : &bl32_image_ep_info;
+
+	/* None of the images can have 0x0 as the entrypoint. */
+	if (next_image_info->pc != 0U)
+		return next_image_info;
+
+	return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before
+ * they are lost (potentially). This needs to be done before the MMU is
+ * initialized so that the memory layout can be used while creating page
+ * tables. BL2 has flushed this information to memory, so we are guaranteed
+ * to pick up good data.
+ ******************************************************************************/
+struct axg_bl31_param {
+	param_header_t h;
+	image_info_t *bl31_image_info;
+	entry_point_info_t *bl32_ep_info;
+	image_info_t *bl32_image_info;
+	entry_point_info_t *bl33_ep_info;
+	image_info_t *bl33_image_info;
+	image_info_t *scp_image_info[];
+};
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	struct axg_bl31_param *from_bl2;
+
+	/* Initialize the console to provide early debug support */
+	aml_console_init();
+
+	from_bl2 = (struct axg_bl31_param *)arg0;
+
+	/* Check params passed from BL2 are not NULL. */
+	assert(from_bl2 != NULL);
+	assert(from_bl2->h.type == PARAM_BL31);
+	assert(from_bl2->h.version >= VERSION_1);
+
+	/*
+	 * Copy BL32 and BL33 entry point information. It is stored in Secure
+	 * RAM, in BL2's address space.
+	 */
+	bl32_image_ep_info = *from_bl2->bl32_ep_info;
+	bl33_image_ep_info = *from_bl2->bl33_ep_info;
+
+#if AML_USE_ATOS
+	/*
+	 * BL2 is unconditionally setting 0 (OPTEE_AARCH64) in arg0 even when
+	 * the BL32 image is 32bit (OPTEE_AARCH32). This is causing the boot to
+	 * hang when ATOS (32bit Amlogic BL32 binary-only TEE OS) is used.
+	 *
+	 * Hardcode to OPTEE_AARCH32 / MODE_RW_32.
+	 */
+	bl32_image_ep_info.args.arg0 = MODE_RW_32;
+#endif
+
+	if (bl33_image_ep_info.pc == 0U) {
+		ERROR("BL31: BL33 entrypoint not obtained from BL2\n");
+		panic();
+	}
+
+	bl30_image_info = *from_bl2->scp_image_info[0];
+	bl301_image_info = *from_bl2->scp_image_info[1];
+}
+
+void bl31_plat_arch_setup(void)
+{
+	aml_setup_page_tables();
+
+	enable_mmu_el3(0);
+}
+
+static inline bool axg_scp_ready(void)
+{
+	return AML_AO_RTI_SCP_IS_READY(mmio_read_32(AML_AO_RTI_SCP_STAT));
+}
+
+static inline void axg_scp_boot(void)
+{
+	aml_scpi_upload_scp_fw(bl30_image_info.image_base,
+			       bl30_image_info.image_size, 0);
+	aml_scpi_upload_scp_fw(bl301_image_info.image_base,
+			       bl301_image_info.image_size, 1);
+	while (!axg_scp_ready())
+		;
+}
+
+/*******************************************************************************
+ * GICv2 driver setup information
+ ******************************************************************************/
+static const interrupt_prop_t axg_interrupt_props[] = {
+	INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+};
+
+static const gicv2_driver_data_t axg_gic_data = {
+	.gicd_base = AML_GICD_BASE,
+	.gicc_base = AML_GICC_BASE,
+	.interrupt_props = axg_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(axg_interrupt_props)
+};
+
+void bl31_platform_setup(void)
+{
+	aml_mhu_secure_init();
+
+	gicv2_driver_init(&axg_gic_data);
+	gicv2_distif_init();
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+
+	axg_scp_boot();
+}
diff --git a/plat/amlogic/axg/axg_common.c b/plat/amlogic/axg/axg_common.c
new file mode 100644
index 0000000..870daf4
--- /dev/null
+++ b/plat/amlogic/axg/axg_common.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl31/interrupt_mgmt.h>
+#include <common/bl_common.h>
+#include <common/ep_info.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <platform_def.h>
+#include <stdint.h>
+
+/*******************************************************************************
+ * Platform memory map regions
+ ******************************************************************************/
+#define MAP_NSDRAM0		MAP_REGION_FLAT(AML_NSDRAM0_BASE,		\
+						AML_NSDRAM0_SIZE,		\
+						MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_NS_SHARE_MEM	MAP_REGION_FLAT(AML_NS_SHARE_MEM_BASE,		\
+						AML_NS_SHARE_MEM_SIZE,		\
+						MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_SEC_SHARE_MEM	MAP_REGION_FLAT(AML_SEC_SHARE_MEM_BASE,		\
+						AML_SEC_SHARE_MEM_SIZE,		\
+						MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE0		MAP_REGION_FLAT(AML_SEC_DEVICE0_BASE,		\
+						AML_SEC_DEVICE0_SIZE,		\
+						MT_DEVICE | MT_RW)
+
+#define MAP_GIC_DEVICE		MAP_REGION_FLAT(AML_GIC_DEVICE_BASE,		\
+						AML_GIC_DEVICE_SIZE,		\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE1		MAP_REGION_FLAT(AML_SEC_DEVICE1_BASE,		\
+						AML_SEC_DEVICE1_SIZE,		\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE2		MAP_REGION_FLAT(AML_SEC_DEVICE2_BASE,		\
+						AML_SEC_DEVICE2_SIZE,		\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_TZRAM		MAP_REGION_FLAT(AML_TZRAM_BASE,			\
+						AML_TZRAM_SIZE,			\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+static const mmap_region_t axg_mmap[] = {
+	MAP_NSDRAM0,
+	MAP_NS_SHARE_MEM,
+	MAP_SEC_SHARE_MEM,
+	MAP_SEC_DEVICE0,
+	MAP_GIC_DEVICE,
+	MAP_SEC_DEVICE1,
+	MAP_SEC_DEVICE2,
+	MAP_TZRAM,
+	{0}
+};
+
+/*******************************************************************************
+ * Per-image regions
+ ******************************************************************************/
+#define MAP_BL31	MAP_REGION_FLAT(BL31_BASE,					\
+					BL31_END - BL31_BASE,				\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_BL_CODE	MAP_REGION_FLAT(BL_CODE_BASE,					\
+					BL_CODE_END - BL_CODE_BASE,			\
+					MT_CODE | MT_SECURE)
+
+#define MAP_BL_RO_DATA	MAP_REGION_FLAT(BL_RO_DATA_BASE,				\
+					BL_RO_DATA_END - BL_RO_DATA_BASE,		\
+					MT_RO_DATA | MT_SECURE)
+
+#define MAP_BL_COHERENT	MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,				\
+					BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, 	\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+/*******************************************************************************
+ * Function that sets up the translation tables.
+ ******************************************************************************/
+void aml_setup_page_tables(void)
+{
+#if IMAGE_BL31
+	const mmap_region_t axg_bl_mmap[] = {
+		MAP_BL31,
+		MAP_BL_CODE,
+		MAP_BL_RO_DATA,
+#if USE_COHERENT_MEM
+		MAP_BL_COHERENT,
+#endif
+		{0}
+	};
+#endif
+
+	mmap_add(axg_bl_mmap);
+
+	mmap_add(axg_mmap);
+
+	init_xlat_tables();
+}
+
+/*******************************************************************************
+ * Function that returns the system counter frequency
+ ******************************************************************************/
+unsigned int plat_get_syscnt_freq2(void)
+{
+	mmio_clrbits_32(AML_SYS_CPU_CFG7, PLAT_SYS_CPU_CFG7);
+	mmio_clrbits_32(AML_AO_TIMESTAMP_CNTL, PLAT_AO_TIMESTAMP_CNTL);
+
+	return AML_OSC24M_CLK_IN_HZ;
+}
diff --git a/plat/amlogic/axg/axg_def.h b/plat/amlogic/axg/axg_def.h
new file mode 100644
index 0000000..d90681a
--- /dev/null
+++ b/plat/amlogic/axg/axg_def.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AXG_DEF_H
+#define AXG_DEF_H
+
+#include <lib/utils_def.h>
+
+/*******************************************************************************
+ * System oscillator
+ ******************************************************************************/
+#define AML_OSC24M_CLK_IN_HZ			ULL(24000000) /* 24 MHz */
+
+/*******************************************************************************
+ * Memory regions
+ ******************************************************************************/
+#define AML_NS_SHARE_MEM_BASE			UL(0x05000000)
+#define AML_NS_SHARE_MEM_SIZE			UL(0x00100000)
+
+#define AML_SEC_SHARE_MEM_BASE			UL(0x05200000)
+#define AML_SEC_SHARE_MEM_SIZE			UL(0x00100000)
+
+#define AML_GIC_DEVICE_BASE			UL(0xFFC00000)
+#define AML_GIC_DEVICE_SIZE			UL(0x00008000)
+
+#define AML_NSDRAM0_BASE			UL(0x01000000)
+#define AML_NSDRAM0_SIZE			UL(0x0F000000)
+
+#define BL31_BASE				UL(0x05100000)
+#define BL31_SIZE				UL(0x00100000)
+#define BL31_LIMIT				(BL31_BASE + BL31_SIZE)
+
+/* Shared memory used for SMC services */
+#define AML_SHARE_MEM_INPUT_BASE		UL(0x050FE000)
+#define AML_SHARE_MEM_OUTPUT_BASE		UL(0x050FF000)
+
+#define AML_SEC_DEVICE0_BASE			UL(0xFFD00000)
+#define AML_SEC_DEVICE0_SIZE			UL(0x00026000)
+
+#define AML_SEC_DEVICE1_BASE			UL(0xFF800000)
+#define AML_SEC_DEVICE1_SIZE			UL(0x0000A000)
+
+#define AML_SEC_DEVICE2_BASE			UL(0xFF620000)
+#define AML_SEC_DEVICE2_SIZE			UL(0x00028000)
+
+#define AML_TZRAM_BASE				UL(0xFFFC0000)
+#define AML_TZRAM_SIZE				UL(0x00020000)
+
+/* Mailboxes */
+#define AML_MHU_SECURE_SCP_TO_AP_PAYLOAD	UL(0xFFFD3800)
+#define AML_MHU_SECURE_AP_TO_SCP_PAYLOAD	UL(0xFFFD3A00)
+#define AML_PSCI_MAILBOX_BASE			UL(0xFFFD3F00)
+
+/*******************************************************************************
+ * GIC-400 and interrupt handling related constants
+ ******************************************************************************/
+#define AML_GICD_BASE				UL(0xFFC01000)
+#define AML_GICC_BASE				UL(0xFFC02000)
+
+#define IRQ_SEC_PHY_TIMER			29
+
+#define IRQ_SEC_SGI_0				8
+#define IRQ_SEC_SGI_1				9
+#define IRQ_SEC_SGI_2				10
+#define IRQ_SEC_SGI_3				11
+#define IRQ_SEC_SGI_4				12
+#define IRQ_SEC_SGI_5				13
+#define IRQ_SEC_SGI_6				14
+#define IRQ_SEC_SGI_7				15
+#define IRQ_SEC_SGI_8				16
+
+/*******************************************************************************
+ * UART definitions
+ ******************************************************************************/
+#define AML_UART0_AO_BASE			UL(0xFF803000)
+#define AML_UART0_AO_CLK_IN_HZ			AML_OSC24M_CLK_IN_HZ
+#define AML_UART_BAUDRATE			U(115200)
+
+/*******************************************************************************
+ * Memory-mapped I/O Registers
+ ******************************************************************************/
+#define AML_AO_TIMESTAMP_CNTL			UL(0xFF8000B4)
+
+#define AML_SYS_CPU_CFG7			UL(0xFF634664)
+
+#define AML_AO_RTI_STATUS_REG3			UL(0xFF80001C)
+#define AML_AO_RTI_SCP_STAT			UL(0xFF80023C)
+#define AML_AO_RTI_SCP_READY_OFF		U(0x14)
+#define AML_A0_RTI_SCP_READY_MASK		U(3)
+#define AML_AO_RTI_SCP_IS_READY(v)					\
+	((((v) >> AML_AO_RTI_SCP_READY_OFF) &				\
+	AML_A0_RTI_SCP_READY_MASK) == AML_A0_RTI_SCP_READY_MASK)
+
+#define AML_HIU_MAILBOX_SET_0			UL(0xFF63C404)
+#define AML_HIU_MAILBOX_STAT_0			UL(0xFF63C408)
+#define AML_HIU_MAILBOX_CLR_0			UL(0xFF63C40C)
+#define AML_HIU_MAILBOX_SET_3			UL(0xFF63C428)
+#define AML_HIU_MAILBOX_STAT_3			UL(0xFF63C42C)
+#define AML_HIU_MAILBOX_CLR_3			UL(0xFF63C430)
+
+#define AML_SHA_DMA_BASE			UL(0xFF63E000)
+#define AML_SHA_DMA_DESC			(AML_SHA_DMA_BASE + 0x08)
+#define AML_SHA_DMA_STATUS			(AML_SHA_DMA_BASE + 0x28)
+
+/*******************************************************************************
+ * System Monitor Call IDs and arguments
+ ******************************************************************************/
+#define AML_SM_GET_SHARE_MEM_INPUT_BASE		U(0x82000020)
+#define AML_SM_GET_SHARE_MEM_OUTPUT_BASE	U(0x82000021)
+
+#define AML_SM_EFUSE_READ			U(0x82000030)
+#define AML_SM_EFUSE_USER_MAX			U(0x82000033)
+
+#define AML_SM_JTAG_ON				U(0x82000040)
+#define AML_SM_JTAG_OFF				U(0x82000041)
+#define AML_SM_GET_CHIP_ID			U(0x82000044)
+
+#define AML_JTAG_STATE_ON			U(0)
+#define AML_JTAG_STATE_OFF			U(1)
+
+#define AML_JTAG_M3_AO				U(0)
+#define AML_JTAG_M3_EE				U(1)
+#define AML_JTAG_A53_AO				U(2)
+#define AML_JTAG_A53_EE				U(3)
+
+#endif /* AXG_DEF_H */
diff --git a/plat/amlogic/axg/axg_pm.c b/plat/amlogic/axg/axg_pm.c
new file mode 100644
index 0000000..e67f263
--- /dev/null
+++ b/plat/amlogic/axg/axg_pm.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/console.h>
+#include <errno.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "aml_private.h"
+
+#define SCPI_POWER_ON		0
+#define SCPI_POWER_RETENTION	1
+#define SCPI_POWER_OFF		3
+
+#define SCPI_SYSTEM_SHUTDOWN	0
+#define SCPI_SYSTEM_REBOOT	1
+
+static uintptr_t axg_sec_entrypoint;
+
+static void axg_pm_set_reset_addr(u_register_t mpidr, uint64_t value)
+{
+	unsigned int core = plat_calc_core_pos(mpidr);
+	uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4);
+
+	mmio_write_64(cpu_mailbox_addr, value);
+}
+
+static void axg_pm_reset(u_register_t mpidr, uint32_t value)
+{
+	unsigned int core = plat_calc_core_pos(mpidr);
+	uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4) + 8;
+
+	mmio_write_32(cpu_mailbox_addr, value);
+}
+
+static void __dead2 axg_system_reset(void)
+{
+	u_register_t mpidr = read_mpidr_el1();
+	int ret;
+
+	INFO("BL31: PSCI_SYSTEM_RESET\n");
+
+	ret = aml_scpi_sys_power_state(SCPI_SYSTEM_REBOOT);
+	if (ret != 0) {
+		ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %i\n", ret);
+		panic();
+	}
+
+	axg_pm_reset(mpidr, 0);
+
+	wfi();
+
+	ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n");
+	panic();
+}
+
+static void __dead2 axg_system_off(void)
+{
+	u_register_t mpidr = read_mpidr_el1();
+	int ret;
+
+	INFO("BL31: PSCI_SYSTEM_OFF\n");
+
+	ret = aml_scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN);
+	if (ret != 0) {
+		ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %i\n", ret);
+		panic();
+	}
+
+	axg_pm_set_reset_addr(mpidr, 0);
+	axg_pm_reset(mpidr, 0);
+
+	dmbsy();
+	wfi();
+
+	ERROR("BL31: PSCI_SYSTEM_OFF: Operation not handled\n");
+	panic();
+}
+
+static int32_t axg_pwr_domain_on(u_register_t mpidr)
+{
+	axg_pm_set_reset_addr(mpidr, axg_sec_entrypoint);
+	aml_scpi_set_css_power_state(mpidr,
+				     SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON);
+	dmbsy();
+	sev();
+
+	return PSCI_E_SUCCESS;
+}
+
+static void axg_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+					PLAT_LOCAL_STATE_OFF);
+
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+
+	axg_pm_set_reset_addr(read_mpidr_el1(), 0);
+}
+
+static void axg_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	u_register_t mpidr = read_mpidr_el1();
+	uint32_t system_state = SCPI_POWER_ON;
+	uint32_t cluster_state = SCPI_POWER_ON;
+
+	assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+					PLAT_LOCAL_STATE_OFF);
+
+	axg_pm_reset(mpidr, -1);
+
+	gicv2_cpuif_disable();
+
+	if (target_state->pwr_domain_state[MPIDR_AFFLVL2] ==
+					PLAT_LOCAL_STATE_OFF)
+		system_state = SCPI_POWER_OFF;
+
+	if (target_state->pwr_domain_state[MPIDR_AFFLVL1] ==
+					PLAT_LOCAL_STATE_OFF)
+		cluster_state = SCPI_POWER_OFF;
+
+
+	aml_scpi_set_css_power_state(mpidr,
+				     SCPI_POWER_OFF, cluster_state,
+				     system_state);
+}
+
+static void __dead2 axg_pwr_domain_pwr_down_wfi(const psci_power_state_t
+						 *target_state)
+{
+	dsbsy();
+	axg_pm_reset(read_mpidr_el1(), 0);
+
+	for (;;)
+		wfi();
+}
+
+/*******************************************************************************
+ * Platform handlers and setup function.
+ ******************************************************************************/
+static const plat_psci_ops_t axg_ops = {
+	.pwr_domain_on			= axg_pwr_domain_on,
+	.pwr_domain_on_finish		= axg_pwr_domain_on_finish,
+	.pwr_domain_off			= axg_pwr_domain_off,
+	.pwr_domain_pwr_down_wfi	= axg_pwr_domain_pwr_down_wfi,
+	.system_off			= axg_system_off,
+	.system_reset			= axg_system_reset
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	axg_sec_entrypoint = sec_entrypoint;
+	*psci_ops = &axg_ops;
+	return 0;
+}
diff --git a/plat/amlogic/axg/include/platform_def.h b/plat/amlogic/axg/include/platform_def.h
new file mode 100644
index 0000000..a47cf73
--- /dev/null
+++ b/plat/amlogic/axg/include/platform_def.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <lib/utils_def.h>
+
+#include "../axg_def.h"
+
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+#define PLATFORM_STACK_SIZE		UL(0x1000)
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(4)
+#define PLATFORM_CLUSTER_COUNT		U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
+#define PLATFORM_CORE_COUNT		PLATFORM_CLUSTER0_CORE_COUNT
+
+#define AML_PRIMARY_CPU			U(0)
+
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL1
+#define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+#define PLAT_SYS_CPU_CFG7		(U(1) << 25)
+#define PLAT_AO_TIMESTAMP_CNTL		U(0x1ff)
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN		U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET		U(1)
+/* Local power state for power-down. Valid for CPU and cluster power domains. */
+#define PLAT_LOCAL_STATE_OFF		U(2)
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH		U(4)
+#define PLAT_LOCAL_PSTATE_MASK		((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_SHIFT		U(6)
+#define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
+
+/* Memory-related defines */
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 32)
+
+#define MAX_MMAP_REGIONS		16
+#define MAX_XLAT_TABLES			8
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk
new file mode 100644
index 0000000..3560b0c
--- /dev/null
+++ b/plat/amlogic/axg/platform.mk
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+AML_PLAT		:=	plat/amlogic
+AML_PLAT_SOC		:=	${AML_PLAT}/${PLAT}
+AML_PLAT_COMMON		:=	${AML_PLAT}/common
+
+DOIMAGEPATH		?=	tools/amlogic
+DOIMAGETOOL		?=	${DOIMAGEPATH}/doimage
+
+PLAT_INCLUDES		:=	-Iinclude/drivers/amlogic/			\
+				-I${AML_PLAT_SOC}/include			\
+				-I${AML_PLAT_COMMON}/include
+
+GIC_SOURCES		:=	drivers/arm/gic/common/gic_common.c		\
+				drivers/arm/gic/v2/gicv2_main.c			\
+				drivers/arm/gic/v2/gicv2_helpers.c		\
+				plat/common/plat_gicv2.c
+
+BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S			\
+				plat/common/plat_psci_common.c			\
+				drivers/amlogic/console/aarch64/meson_console.S	\
+				${AML_PLAT_SOC}/${PLAT}_bl31_setup.c		\
+				${AML_PLAT_SOC}/${PLAT}_pm.c			\
+				${AML_PLAT_SOC}/${PLAT}_common.c		\
+				${AML_PLAT_COMMON}/aarch64/aml_helpers.S	\
+				${AML_PLAT_COMMON}/aml_efuse.c			\
+				${AML_PLAT_COMMON}/aml_mhu.c			\
+				${AML_PLAT_COMMON}/aml_scpi.c			\
+				${AML_PLAT_COMMON}/aml_sip_svc.c		\
+				${AML_PLAT_COMMON}/aml_thermal.c		\
+				${AML_PLAT_COMMON}/aml_topology.c		\
+				${AML_PLAT_COMMON}/aml_console.c		\
+				drivers/amlogic/crypto/sha_dma.c		\
+				${XLAT_TABLES_LIB_SRCS}				\
+				${GIC_SOURCES}
+
+# Tune compiler for Cortex-A53
+ifeq ($(notdir $(CC)),armclang)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
+else
+    TF_CFLAGS_aarch64	+=	-mtune=cortex-a53
+endif
+
+# Build config flags
+# ------------------
+
+# Enable all errata workarounds for Cortex-A53
+ERRATA_A53_855873		:= 1
+ERRATA_A53_819472		:= 1
+ERRATA_A53_824069		:= 1
+ERRATA_A53_827319		:= 1
+
+WORKAROUND_CVE_2017_5715	:= 0
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA	:= 1
+
+# Use Coherent memory
+USE_COHERENT_MEM		:= 1
+
+AML_USE_ATOS			:= 0
+$(eval $(call assert_boolean,AML_USE_ATOS))
+$(eval $(call add_define,AML_USE_ATOS))
+
+# Verify build config
+# -------------------
+
+ifneq (${RESET_TO_BL31}, 0)
+  $(error Error: ${PLAT} needs RESET_TO_BL31=0)
+endif
+
+ifeq (${ARCH},aarch32)
+  $(error Error: AArch32 not supported on ${PLAT})
+endif
+
+all: ${BUILD_PLAT}/bl31.img
+distclean realclean clean: cleanimage
+
+cleanimage:
+	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+
+${DOIMAGETOOL}:
+	${Q}${MAKE} -C ${DOIMAGEPATH}
+
+${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
+	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
+
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index c71e932..3c19230 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.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
  */
@@ -8,130 +8,61 @@
 #include <stdint.h>
 #include <string.h>
 
+#include <common/debug.h>
+#include <drivers/arm/cryptocell/cc_rotpk.h>
+#include <drivers/delay_timer.h>
 #include <lib/cassert.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/common_def.h>
 #include <plat/common/platform.h>
-#include <tools_share/tbbr_oid.h>
 #include <platform_def.h>
-
-/* SHA256 algorithm */
-#define SHA256_BYTES			32
-
-/* ROTPK locations */
-#define ARM_ROTPK_REGS_ID		1
-#define ARM_ROTPK_DEVEL_RSA_ID		2
-#define ARM_ROTPK_DEVEL_ECDSA_ID	3
+#include <tools_share/tbbr_oid.h>
 
-static const unsigned char rotpk_hash_hdr[] =		\
-		"\x30\x31\x30\x0D\x06\x09\x60\x86\x48"	\
-		"\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
-static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
-static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
 
-/* Use the cryptocell variants if Cryptocell is present */
 #if !ARM_CRYPTOCELL_INTEG
 #if !ARM_ROTPK_LOCATION_ID
   #error "ARM_ROTPK_LOCATION_ID not defined"
 #endif
+#endif
 
 /* Weak definition may be overridden in specific platform */
 #pragma weak plat_get_nv_ctr
 #pragma weak plat_set_nv_ctr
 
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
-static const unsigned char arm_devel_rotpk_hash[] =	\
-		"\xB0\xF3\x82\x09\x12\x97\xD8\x3A"	\
-		"\x37\x7A\x72\x47\x1B\xEC\x32\x73"	\
-		"\xE9\x92\x32\xE2\x49\x59\xF6\x5E"	\
-		"\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
-#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
-static const unsigned char arm_devel_rotpk_hash[] =	\
-		"\x2E\x40\xBF\x6E\xF9\x12\xBB\x98"	\
-		"\x31\x71\x09\x0E\x1E\x15\x3D\x0B"	\
-		"\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B"	\
-		"\xA0\xB0\x20\x86\x4E\x6C\x07\x17";
-#endif
+extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];
+
+static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
 
 /*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier  ::=  SEQUENCE  {
- *     algorithm         OBJECT IDENTIFIER,
- *     parameters        ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- *     digestAlgorithm   AlgorithmIdentifier,
- *     digest            OCTET STRING
- * }
+ * Return the ROTPK hash stored in dedicated registers.
  */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
 			unsigned int *flags)
 {
 	uint8_t *dst;
+	uint32_t *src, tmp;
+	unsigned int words, i;
 
 	assert(key_ptr != NULL);
 	assert(key_len != NULL);
 	assert(flags != NULL);
 
 	/* Copy the DER header */
-	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
-	dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
 
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
-	|| (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
-	memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
-#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
-	uint32_t *src, tmp;
-	unsigned int words, i;
+	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
 
-	/*
-	 * Append the hash from Trusted Root-Key Storage registers. The hash has
-	 * not been written linearly into the registers, so we have to do a bit
-	 * of byte swapping:
-	 *
-	 *     0x00    0x04    0x08    0x0C    0x10    0x14    0x18    0x1C
-	 * +---------------------------------------------------------------+
-	 * | Reg0  | Reg1  | Reg2  | Reg3  | Reg4  | Reg5  | Reg6  | Reg7  |
-	 * +---------------------------------------------------------------+
-	 *  | ...                    ... |   | ...                   ...  |
-	 *  |       +--------------------+   |                    +-------+
-	 *  |       |                        |                    |
-	 *  +----------------------------+   +----------------------------+
-	 *          |                    |                        |       |
-	 *  +-------+                    |   +--------------------+       |
-	 *  |                            |   |                            |
-	 *  v                            v   v                            v
-	 * +---------------------------------------------------------------+
-	 * |                               |                               |
-	 * +---------------------------------------------------------------+
-	 *  0                           15  16                           31
-	 *
-	 * Additionally, we have to access the registers in 32-bit words
-	 */
-	words = SHA256_BYTES >> 3;
+	words = ARM_ROTPK_HASH_LEN >> 2;
 
-	/* Swap bytes 0-15 (first four registers) */
 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
 	for (i = 0 ; i < words ; i++) {
 		tmp = src[words - 1 - i];
 		/* Words are read in little endian */
-		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
-		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
-		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
 		*dst++ = (uint8_t)(tmp & 0xFF);
-	}
-
-	/* Swap bytes 16-31 (last four registers) */
-	src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
-	for (i = 0 ; i < words ; i++) {
-		tmp = src[words - 1 - i];
-		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
-		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
-		*dst++ = (uint8_t)(tmp & 0xFF);
+		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
 	}
-#endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
-		  || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */
 
 	*key_ptr = (void *)rotpk_hash_der;
 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
@@ -139,6 +70,65 @@
 	return 0;
 }
 
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+/*
+ * Return development ROTPK hash generated from ROT_KEY.
+ */
+int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	*key_ptr = arm_rotpk_header;
+	*key_len = arm_rotpk_hash_end - arm_rotpk_header;
+	*flags = ROTPK_IS_HASH;
+	return 0;
+}
+#endif
+
+#if ARM_CRYPTOCELL_INTEG
+/*
+ * Return ROTPK hash from CryptoCell.
+ */
+int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	unsigned char *dst;
+
+	assert(key_ptr != NULL);
+	assert(key_len != NULL);
+	assert(flags != NULL);
+
+	/* Copy the DER header */
+	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+	dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+	*key_ptr = rotpk_hash_der;
+	*key_len = sizeof(rotpk_hash_der);
+	return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
+}
+#endif
+
+/*
+ * Wraper function for most Arm platforms to get ROTPK hash.
+ */
+int arm_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);
+#else
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
+#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+	return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
+#else
+	return 1;
+#endif
+
+#endif /* ARM_CRYPTOCELL_INTEG */
+}
+
 /*
  * Return the non-volatile counter value stored in the platform. The cookie
  * will contain the OID of the counter in the certificate.
@@ -179,37 +169,3 @@
 {
 	return 1;
 }
-#else /* ARM_CRYPTOCELL_INTEG */
-
-#include <drivers/arm/cryptocell/cc_rotpk.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier  ::=  SEQUENCE  {
- *     algorithm         OBJECT IDENTIFIER,
- *     parameters        ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- *     digestAlgorithm   AlgorithmIdentifier,
- *     digest            OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
-			unsigned int *flags)
-{
-	unsigned char *dst;
-
-	assert(key_ptr != NULL);
-	assert(key_len != NULL);
-	assert(flags != NULL);
-
-	/* Copy the DER header */
-	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
-	dst = &rotpk_hash_der[rotpk_hash_hdr_len];
-	*key_ptr = rotpk_hash_der;
-	*key_len = sizeof(rotpk_hash_der);
-	return cc_get_rotpk_hash(dst, SHA256_BYTES, flags);
-}
-#endif /* ARM_CRYPTOCELL_INTEG */
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index b98dfd4..da63430 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.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
 #
@@ -12,31 +12,60 @@
 BL2_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c
 
 ifneq (${TRUSTED_BOARD_BOOT},0)
-  ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
-    # ROTPK hash location
-    ifeq (${ARM_ROTPK_LOCATION}, regs)
-        ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
-    else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
-        KEY_ALG := rsa
-        ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
-    else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
-        KEY_ALG := ecdsa
-        ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
-    else
-        $(error "Unsupported ARM_ROTPK_LOCATION value")
-    endif
-    $(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
+# ROTPK hash location
+ifeq (${ARM_ROTPK_LOCATION}, regs)
+	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
+else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
+	KEY_ALG := rsa
+	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
+	ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
+$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
+else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
+	KEY_ALG := ecdsa
+	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
+	ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
+$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
+else
+	$(error "Unsupported ARM_ROTPK_LOCATION value")
+endif
+
+$(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+
+# Force generation of the new hash if ROT_KEY is specified
+ifdef ROT_KEY
+	HASH_PREREQUISITES = $(ROT_KEY) FORCE
+FORCE:
+else
+	HASH_PREREQUISITES = $(ROT_KEY)
+endif
+
+$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES)
+ifndef ROT_KEY
+	$(error Cannot generate hash: no ROT_KEY defined)
+endif
+	openssl rsa -in $< -pubout -outform DER | openssl dgst \
+		-sha256 -binary > $@
+
+# Certificate NV-Counters. Use values corresponding to tied off values in
+# ARM development platforms
+TFW_NVCTR_VAL	?=	31
+NTFW_NVCTR_VAL	?=	223
+else
+# Certificate NV-Counters when CryptoCell is integrated. For development
+# platforms we set the counter to first valid value.
+TFW_NVCTR_VAL	?=	0
+NTFW_NVCTR_VAL	?=	0
+endif
+BL1_SOURCES		+=	plat/arm/board/common/board_arm_trusted_boot.c \
+				plat/arm/board/common/rotpk/arm_dev_rotpk.S
+BL2_SOURCES		+=	plat/arm/board/common/board_arm_trusted_boot.c \
+				plat/arm/board/common/rotpk/arm_dev_rotpk.S
 
-    # Certificate NV-Counters. Use values corresponding to tied off values in
-    # ARM development platforms
-    TFW_NVCTR_VAL	?=	31
-    NTFW_NVCTR_VAL	?=	223
-  else
-    # Certificate NV-Counters when CryptoCell is integrated. For development
-    # platforms we set the counter to first valid value.
-    TFW_NVCTR_VAL	?=	0
-    NTFW_NVCTR_VAL	?=	0
-  endif
-    BL1_SOURCES		+=	plat/arm/board/common/board_arm_trusted_boot.c
-    BL2_SOURCES		+=	plat/arm/board/common/board_arm_trusted_boot.c
 endif
diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
new file mode 100644
index 0000000..80f2192
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat/arm/common/arm_def.h"
+
+	.global arm_rotpk_header
+	.global arm_rotpk_header_end
+	.section .rodata.arm_rotpk_hash, "a"
+
+arm_rotpk_header:
+	.byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+	.byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+arm_rotpk_header_len:
+
+#ifdef ARM_ROTPK_HASH
+	.global arm_rotpk_hash_end
+	.incbin ARM_ROTPK_HASH
+arm_rotpk_hash_end:
+#endif
+
+.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header
+.error "Invalid ROTPK header length."
+.endif
diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c
index dc50764..a09b80e 100644
--- a/plat/arm/board/fvp/fvp_trusted_boot.c
+++ b/plat/arm/board/fvp/fvp_trusted_boot.c
@@ -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
  */
@@ -9,12 +9,31 @@
 #include <string.h>
 
 #include <lib/mmio.h>
-
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
 #include <tools_share/tbbr_oid.h>
 
 /*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm         OBJECT IDENTIFIER,
+ *     parameters        ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm   AlgorithmIdentifier,
+ *     digest            OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	return arm_get_rotpk_info(key_ptr, key_len, flags);
+}
+
+/*
  * Store a new non-volatile counter value.
  *
  * On some FVP versions, the non-volatile counters are read-only so this
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index c2b7b98..602ea6d 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -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
  */
@@ -139,13 +139,13 @@
 # if TRUSTED_BOARD_BOOT
 #  define PLATFORM_STACK_SIZE		UL(0x1000)
 # else
-#  define PLATFORM_STACK_SIZE		UL(0x440)
+#  define PLATFORM_STACK_SIZE		UL(0x500)
 # endif
 #elif defined(IMAGE_BL2)
 # if TRUSTED_BOARD_BOOT
 #  define PLATFORM_STACK_SIZE		UL(0x1000)
 # else
-#  define PLATFORM_STACK_SIZE		UL(0x400)
+#  define PLATFORM_STACK_SIZE		UL(0x440)
 # endif
 #elif defined(IMAGE_BL2U)
 # define PLATFORM_STACK_SIZE		UL(0x400)
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 97a326c..6fb34c4 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -139,7 +139,6 @@
 				plat/arm/board/fvp/fvp_bl1_setup.c		\
 				plat/arm/board/fvp/fvp_err.c			\
 				plat/arm/board/fvp/fvp_io_storage.c		\
-				plat/arm/board/fvp/fvp_trusted_boot.c		\
 				${FVP_CPU_LIBS}					\
 				${FVP_INTERCONNECT_SOURCES}
 
@@ -158,7 +157,6 @@
 				plat/arm/board/fvp/fvp_bl2_setup.c		\
 				plat/arm/board/fvp/fvp_err.c			\
 				plat/arm/board/fvp/fvp_io_storage.c		\
-				plat/arm/board/fvp/fvp_trusted_boot.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
 				${FVP_SECURITY_SOURCES}
 
@@ -302,8 +300,10 @@
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
 
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES		+=	plat/arm/board/fvp/fvp_trusted_boot.c
+BL2_SOURCES		+=	plat/arm/board/fvp/fvp_trusted_boot.c
 # FVP being a development platform, enable capability to disable Authentication
 # dynamically if TRUSTED_BOARD_BOOT is set.
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
-        DYN_DISABLE_AUTH	:=	1
+DYN_DISABLE_AUTH	:=	1
 endif
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 16bb33d..eddd7e5 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -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
  */
@@ -224,7 +224,6 @@
 
 /* MHU related constants */
 #define PLAT_CSS_MHU_BASE		UL(0x2b1f0000)
-#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
 /*
  * Base address of the first memory region used for communication between AP
@@ -301,4 +300,7 @@
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
 #endif
 
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	U(1)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
index 052ab9f..075f512 100644
--- a/plat/arm/board/juno/juno_topology.c
+++ b/plat/arm/board/juno/juno_topology.c
@@ -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
  */
@@ -20,7 +20,7 @@
 		.ring_doorbell = &mhu_ring_doorbell,
 };
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(void)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
 {
 	return &juno_scmi_plat_info;
 }
diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c
new file mode 100644
index 0000000..25a7470
--- /dev/null
+++ b/plat/arm/board/juno/juno_trusted_boot.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <drivers/arm/cryptocell/cc_rotpk.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+
+static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
+
+extern unsigned char arm_rotpk_header[];
+
+/*
+ * Return the ROTPK hash stored in the registers of Juno board.
+ */
+static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	uint8_t *dst;
+	uint32_t *src, tmp;
+	unsigned int words, i;
+
+	assert(key_ptr != NULL);
+	assert(key_len != NULL);
+	assert(flags != NULL);
+
+	/* Copy the DER header */
+	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+
+
+	/*
+	 * Append the hash from Trusted Root-Key Storage registers. The hash has
+	 * not been written linearly into the registers, so we have to do a bit
+	 * of byte swapping:
+	 *
+	 *     0x00    0x04    0x08    0x0C    0x10    0x14    0x18    0x1C
+	 * +---------------------------------------------------------------+
+	 * | Reg0  | Reg1  | Reg2  | Reg3  | Reg4  | Reg5  | Reg6  | Reg7  |
+	 * +---------------------------------------------------------------+
+	 *  | ...                    ... |   | ...                   ...  |
+	 *  |       +--------------------+   |                    +-------+
+	 *  |       |                        |                    |
+	 *  +----------------------------+   +----------------------------+
+	 *          |                    |                        |       |
+	 *  +-------+                    |   +--------------------+       |
+	 *  |                            |   |                            |
+	 *  v                            v   v                            v
+	 * +---------------------------------------------------------------+
+	 * |                               |                               |
+	 * +---------------------------------------------------------------+
+	 *  0                           15  16                           31
+	 *
+	 * Additionally, we have to access the registers in 32-bit words
+	 */
+	words = ARM_ROTPK_HASH_LEN >> 3;
+
+	/* Swap bytes 0-15 (first four registers) */
+	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
+	for (i = 0 ; i < words ; i++) {
+		tmp = src[words - 1 - i];
+		/* Words are read in little endian */
+		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+		*dst++ = (uint8_t)(tmp & 0xFF);
+	}
+
+	/* Swap bytes 16-31 (last four registers) */
+	src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2);
+	for (i = 0 ; i < words ; i++) {
+		tmp = src[words - 1 - i];
+		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
+		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
+		*dst++ = (uint8_t)(tmp & 0xFF);
+	}
+
+	*key_ptr = (void *)rotpk_hash_der;
+	*key_len = (unsigned int)sizeof(rotpk_hash_der);
+	*flags = ROTPK_IS_HASH;
+	return 0;
+}
+
+#endif
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm         OBJECT IDENTIFIER,
+ *     parameters        ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm   AlgorithmIdentifier,
+ *     digest            OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, 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);
+#else
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
+#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+	return juno_get_rotpk_info_regs(key_ptr, key_len, flags);
+#else
+	return 1;
+#endif
+
+#endif /* ARM_CRYPTOCELL_INTEG */
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index bd6bae5..a85ad53 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/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
 #
@@ -91,6 +91,11 @@
 BL1_SOURCES		+=	drivers/arm/css/sds/sds.c
 endif
 
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES		+=	plat/arm/board/juno/juno_trusted_boot.c
+BL2_SOURCES		+=	plat/arm/board/juno/juno_trusted_boot.c
+endif
+
 endif
 
 ifneq (${RESET_TO_BL31},0)
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 6a309e8..cc07852 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -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
  */
@@ -90,7 +90,6 @@
 
 #define PLAT_ARM_NSTIMER_FRAME_ID		0
 #define PLAT_CSS_MHU_BASE			0x45000000
-#define PLAT_MHUV2_BASE				PLAT_CSS_MHU_BASE
 #define PLAT_MAX_PWR_LVL			2
 
 #define PLAT_ARM_G1S_IRQS			ARM_G1S_IRQS,			\
@@ -144,4 +143,7 @@
 #define SBSA_SECURE_WDOG_BASE			UL(0x2A480000)
 #define SBSA_SECURE_WDOG_TIMEOUT		UL(100)
 
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT		U(1)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index b150b89..136287a 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -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
  */
@@ -74,7 +74,7 @@
 	0
 };
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info()
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
 {
 	return &n1sdp_scmi_plat_info;
 }
diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts
new file mode 100644
index 0000000..4d4580d
--- /dev/null
+++ b/plat/arm/board/rddaniel/fdts/rddaniel_nt_fw_config.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+	/* compatible string */
+	compatible = "arm,rd-daniel";
+
+	/*
+	 * Place holder for system-id node with default values. The
+	 * value of platform-id and config-id will be set to the
+	 * correct values during the BL2 stage of boot.
+	 */
+	system-id {
+		platform-id = <0x0>;
+		config-id = <0x0>;
+		multi-chip-mode = <0x0>;
+	};
+};
diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts
new file mode 100644
index 0000000..9acec13
--- /dev/null
+++ b/plat/arm/board/rddaniel/fdts/rddaniel_tb_fw_config.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	/* Platform Config */
+	compatible = "arm,tb_fw";
+	nt_fw_config_addr = <0x0 0xFEF00000>;
+	nt_fw_config_max_size = <0x0100000>;
+
+	/*
+	 * The following two entries are placeholders for Mbed TLS
+	 * heap information. The default values don't matter since
+	 * they will be overwritten by BL1.
+	 * In case of having shared Mbed TLS heap between BL1 and BL2,
+	 * BL1 will populate these two properties with the respective
+	 * info about the shared heap. This info will be available for
+	 * BL2 in order to locate and re-use the heap.
+	 */
+	mbedtls_heap_addr = <0x0 0x0>;
+	mbedtls_heap_size = <0x0>;
+};
diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h
new file mode 100644
index 0000000..5163602
--- /dev/null
+++ b/plat/arm/board/rddaniel/include/platform_def.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+
+#include <sgi_base_platform_def.h>
+
+#define PLAT_ARM_CLUSTER_COUNT		U(16)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
+#define CSS_SGI_MAX_PE_PER_CPU		U(1)
+
+#define PLAT_CSS_MHU_BASE		UL(0x45400000)
+#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
+ */
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 42)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 42)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#endif
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE		UL(0x30140000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rddaniel/platform.mk b/plat/arm/board/rddaniel/platform.mk
new file mode 100644
index 0000000..67f5777
--- /dev/null
+++ b/plat/arm/board/rddaniel/platform.mk
@@ -0,0 +1,43 @@
+# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/arm/css/sgi/sgi-common.mk
+
+RDDANIEL_BASE		=	plat/arm/board/rddaniel
+
+PLAT_INCLUDES		+=	-I${RDDANIEL_BASE}/include/
+
+SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_zeus.S
+
+BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+				${RDDANIEL_BASE}/rddaniel_err.c
+
+BL2_SOURCES		+=	${RDDANIEL_BASE}/rddaniel_plat.c	\
+				${RDDANIEL_BASE}/rddaniel_security.c	\
+				${RDDANIEL_BASE}/rddaniel_err.c		\
+				lib/utils/mem_region.c			\
+				plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+				${RDDANIEL_BASE}/rddaniel_plat.c	\
+				${RDDANIEL_BASE}/rddaniel_topology.c	\
+				drivers/cfi/v2m/v2m_flash.c		\
+				lib/utils/mem_region.c			\
+				plat/arm/common/arm_nor_psci_mem_protect.c
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES		+=	${RDDANIEL_BASE}/fdts/${PLAT}_tb_fw_config.dts
+TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+
+FDT_SOURCES		+=	${RDDANIEL_BASE}/fdts/${PLAT}_nt_fw_config.dts
+NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+
+override CTX_INCLUDE_AARCH32_REGS	:= 0
diff --git a/plat/arm/board/rddaniel/rddaniel_err.c b/plat/arm/board/rddaniel/rddaniel_err.c
new file mode 100644
index 0000000..5e10942
--- /dev/null
+++ b/plat/arm/board/rddaniel/rddaniel_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rddaniel error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+	while (1) {
+		wfi();
+	}
+}
diff --git a/plat/arm/board/rddaniel/rddaniel_plat.c b/plat/arm/board/rddaniel/rddaniel_plat.c
new file mode 100644
index 0000000..ab5251e
--- /dev/null
+++ b/plat/arm/board/rddaniel/rddaniel_plat.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+#include <sgi_plat.h>
+
+unsigned int plat_arm_sgi_get_platform_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
+				& SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_sgi_get_config_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+void bl31_platform_setup(void)
+{
+	sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/rddaniel/rddaniel_security.c b/plat/arm/board/rddaniel/rddaniel_security.c
new file mode 100644
index 0000000..6aa38c8
--- /dev/null
+++ b/plat/arm/board/rddaniel/rddaniel_security.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/rddaniel/rddaniel_topology.c b/plat/arm/board/rddaniel/rddaniel_topology.c
new file mode 100644
index 0000000..55f5e04
--- /dev/null
+++ b/plat/arm/board/rddaniel/rddaniel_topology.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char rd_daniel_pd_tree_desc[] = {
+	PLAT_ARM_CLUSTER_COUNT,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return rd_daniel_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF))
+};
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
index 4176921..0af821e 100644
--- a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
+++ b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,7 @@
 	system-id {
 		platform-id = <0x0>;
 		config-id = <0x0>;
+		multi-chip-mode = <0x0>;
 	};
 
 };
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
index 2be3f88..3fb6409 100644
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ b/plat/arm/board/rde1edge/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,7 +16,6 @@
 #define CSS_SGI_MAX_PE_PER_CPU		U(2)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45400000)
-#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
 /* Base address of DMC-620 instances */
 #define RDE1EDGE_DMC620_BASE0		UL(0x4e000000)
@@ -37,4 +36,9 @@
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
 #endif
 
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
index 43c37ff..88aa634 100644
--- a/plat/arm/board/rde1edge/platform.mk
+++ b/plat/arm/board/rde1edge/platform.mk
@@ -29,6 +29,11 @@
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES		+=	${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
+BL2_SOURCES		+=	${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
+endif
+
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES		+=	${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
@@ -42,4 +47,9 @@
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
 
+ifneq ($(CSS_SGI_CHIP_COUNT),1)
+ $(error  "Chip count for RDE1Edge should be 1, currently set to \
+   ${CSS_SGI_CHIP_COUNT}.")
+endif
+
 override CTX_INCLUDE_AARCH32_REGS	:= 0
diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c
index a1b8d62..44d818a 100644
--- a/plat/arm/board/rde1edge/rde1edge_plat.c
+++ b/plat/arm/board/rde1edge/rde1edge_plat.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <plat/common/platform.h>
+#include <sgi_plat.h>
 
 unsigned int plat_arm_sgi_get_platform_id(void)
 {
@@ -16,3 +17,13 @@
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
 }
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+	return 0;
+}
+
+void bl31_platform_setup(void)
+{
+	sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c
index 0b56f20..a16283e 100644
--- a/plat/arm/board/rde1edge/rde1edge_topology.c
+++ b/plat/arm/board/rde1edge/rde1edge_topology.c
@@ -7,12 +7,15 @@
 #include <plat/arm/common/plat_arm.h>
 
 /******************************************************************************
- * The power domain tree descriptor.
+ * The power domain tree descriptor. RD-E1-Edge platform consists of two
+ * clusters with eight CPUs in each cluster. The CPUs are multi-threaded with
+ * two threads per CPU.
  ******************************************************************************/
 static const unsigned char rde1edge_pd_tree_desc[] = {
+	CSS_SGI_CHIP_COUNT,
 	PLAT_ARM_CLUSTER_COUNT,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER
+	CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU
 };
 
 /******************************************************************************
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
new file mode 100644
index 0000000..c271f7f
--- /dev/null
+++ b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm         OBJECT IDENTIFIER,
+ *     parameters        ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm   AlgorithmIdentifier,
+ *     digest            OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	return arm_get_rotpk_info(key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
index fff5874..68366c5 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
+++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
@@ -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
  */
@@ -17,5 +17,6 @@
 	system-id {
 		platform-id = <0x0>;
 		config-id = <0x0>;
+		multi-chip-mode = <0x0>;
 	};
 };
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
index c635faa..ab63e23 100644
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ b/plat/arm/board/rdn1edge/include/platform_def.h
@@ -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
  */
@@ -16,7 +16,6 @@
 #define CSS_SGI_MAX_PE_PER_CPU		U(1)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45400000)
-#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
 /* Base address of DMC-620 instances */
 #define RDN1EDGE_DMC620_BASE0		UL(0x4e000000)
@@ -27,15 +26,23 @@
 
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
 
+/* Virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
+
 /*
  * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
  */
 #ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 36)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 36)
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 43)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 43)
 #else
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
 #endif
 
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk
index ca1e95e..04f70f3 100644
--- a/plat/arm/board/rdn1edge/platform.mk
+++ b/plat/arm/board/rdn1edge/platform.mk
@@ -26,9 +26,18 @@
 				${RDN1EDGE_BASE}/rdn1edge_plat.c	\
 				${RDN1EDGE_BASE}/rdn1edge_topology.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
+				drivers/arm/gic/v3/gic600_multichip.c	\
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES		+=	${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c
+BL2_SOURCES		+=	${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c
+endif
+
+# Enable dynamic addition of MMAP regions in BL31
+BL31_CFLAGS		+=	-DPLAT_XLAT_TABLES_DYNAMIC=1
+
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES		+=	${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
@@ -42,4 +51,9 @@
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
 
+ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),1 2))
+ $(error  "Chip count for RDN1Edge platform should either 1 or 2, currently \
+   set to ${CSS_SGI_CHIP_COUNT}.")
+endif
+
 override CTX_INCLUDE_AARCH32_REGS	:= 0
diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c
index 3b7e5ee..f62c6f4 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_plat.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c
@@ -1,10 +1,44 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <sgi_base_platform_def.h>
+#include <sgi_plat.h>
+
+#if defined(IMAGE_BL31)
+static const mmap_region_t rdn1edge_dynamic_mmap[] = {
+	ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
+	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
+	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1)
+};
+
+static struct gic600_multichip_data rdn1e1_multichip_data __init = {
+	.rt_owner_base = PLAT_ARM_GICD_BASE,
+	.rt_owner = 0,
+	.chip_count = CSS_SGI_CHIP_COUNT,
+	.chip_addrs = {
+		PLAT_ARM_GICD_BASE >> 16,
+		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
+	},
+	.spi_ids = {
+		{32, 255},
+		{0, 0}
+	}
+};
+
+static uintptr_t rdn1e1_multichip_gicr_frames[] = {
+	PLAT_ARM_GICR_BASE,				/* Chip 0's GICR Base */
+	PLAT_ARM_GICR_BASE +
+		CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),	/* Chip 1's GICR BASE */
+	UL(0)						/* Zero Termination */
+};
+#endif /* IMAGE_BL31 */
 
 unsigned int plat_arm_sgi_get_platform_id(void)
 {
@@ -16,3 +50,48 @@
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
 }
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+/*
+ * IMAGE_BL31 macro is added to build bl31_platform_setup function only for BL31
+ * because PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not
+ * for other stages.
+ */
+#if defined(IMAGE_BL31)
+void bl31_platform_setup(void)
+{
+	int i, ret;
+
+	if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) {
+		ERROR("Chip Count is set to %d but multi-chip mode not enabled\n",
+				CSS_SGI_CHIP_COUNT);
+		panic();
+	} else if (plat_arm_sgi_get_multi_chip_mode() == 1 &&
+			CSS_SGI_CHIP_COUNT > 1) {
+		INFO("Enabling support for multi-chip in RD-N1-Edge\n");
+
+		for (i = 0; i < ARRAY_SIZE(rdn1edge_dynamic_mmap); i++) {
+			ret = mmap_add_dynamic_region(
+					rdn1edge_dynamic_mmap[i].base_pa,
+					rdn1edge_dynamic_mmap[i].base_va,
+					rdn1edge_dynamic_mmap[i].size,
+					rdn1edge_dynamic_mmap[i].attr
+					);
+			if (ret != 0) {
+				ERROR("Failed to add dynamic mmap entry\n");
+				panic();
+			}
+		}
+
+		plat_arm_override_gicr_frames(rdn1e1_multichip_gicr_frames);
+		gic600_multichip_init(&rdn1e1_multichip_data);
+	}
+
+	sgi_bl31_common_platform_setup();
+}
+#endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdn1edge/rdn1edge_topology.c b/plat/arm/board/rdn1edge/rdn1edge_topology.c
index 687ae35..5bbea69 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_topology.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_topology.c
@@ -5,14 +5,19 @@
  */
 
 #include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
 
 /******************************************************************************
  * The power domain tree descriptor.
  ******************************************************************************/
 static const unsigned char rdn1edge_pd_tree_desc[] = {
-	PLAT_ARM_CLUSTER_COUNT,
+	(PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT),
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+#if (CSS_SGI_CHIP_COUNT > 1)
 	CSS_SGI_MAX_CPUS_PER_CLUSTER,
 	CSS_SGI_MAX_CPUS_PER_CLUSTER
+#endif
 };
 
 /*******************************************************************************
@@ -28,5 +33,22 @@
  * to the SCMI power domain ID implemented by SCP.
  ******************************************************************************/
 const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
-	0, 1, 2, 3, 4, 5, 6, 7
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+#if (CSS_SGI_CHIP_COUNT > 1)
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x4)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x5)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x6)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x7)),
+#endif
 };
diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
new file mode 100644
index 0000000..c271f7f
--- /dev/null
+++ b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm         OBJECT IDENTIFIER,
+ *     parameters        ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm   AlgorithmIdentifier,
+ *     digest            OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	return arm_get_rotpk_info(key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
index 1e1ea14..260247a 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
+++ b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,5 +17,6 @@
 	system-id {
 		platform-id = <0x0>;
 		config-id = <0x0>;
+		multi-chip-mode = <0x0>;
 	};
 };
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index fd59e52..95986cf 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -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
  */
@@ -16,7 +16,6 @@
 #define CSS_SGI_MAX_PE_PER_CPU		U(1)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45000000)
-#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
 /* Base address of DMC-620 instances */
 #define SGI575_DMC620_BASE0		UL(0x4e000000)
@@ -38,4 +37,9 @@
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
 #endif
 
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index ce2717f..76cc4e2 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -29,6 +29,11 @@
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES		+=	${SGI575_BASE}/sgi575_trusted_boot.c
+BL2_SOURCES		+=	${SGI575_BASE}/sgi575_trusted_boot.c
+endif
+
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES		+=	${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
@@ -41,3 +46,8 @@
 
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+
+ifneq ($(CSS_SGI_CHIP_COUNT),1)
+ $(error  "Chip count for SGI575 should be 1, currently set to \
+   ${CSS_SGI_CHIP_COUNT}.")
+endif
diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/sgi575/sgi575_plat.c
index 0d3fd16..dc294e6 100644
--- a/plat/arm/board/sgi575/sgi575_plat.c
+++ b/plat/arm/board/sgi575/sgi575_plat.c
@@ -1,11 +1,11 @@
 /*
- * 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
  */
 
 #include <plat/common/platform.h>
-
+#include <sgi_plat.h>
 #include <sgi_variant.h>
 
 unsigned int plat_arm_sgi_get_platform_id(void)
@@ -18,3 +18,13 @@
 	return (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT)
 			& SSC_VERSION_CONFIG_MASK;
 }
+
+unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+{
+	return 0;
+}
+
+void bl31_platform_setup(void)
+{
+	sgi_bl31_common_platform_setup();
+}
diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/sgi575/sgi575_trusted_boot.c
new file mode 100644
index 0000000..c271f7f
--- /dev/null
+++ b/plat/arm/board/sgi575/sgi575_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm         OBJECT IDENTIFIER,
+ *     parameters        ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm   AlgorithmIdentifier,
+ *     digest            OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	return arm_get_rotpk_info(key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
index 7a843c3..f096ca5 100644
--- a/plat/arm/board/sgm775/platform.mk
+++ b/plat/arm/board/sgm775/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
 #
@@ -21,3 +21,8 @@
 BL31_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c		\
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
+
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES		+=	${SGM775_BASE}/sgm775_trusted_boot.c
+BL2_SOURCES		+=	${SGM775_BASE}/sgm775_trusted_boot.c
+endif
diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c
new file mode 100644
index 0000000..c271f7f
--- /dev/null
+++ b/plat/arm/board/sgm775/sgm775_trusted_boot.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm         OBJECT IDENTIFIER,
+ *     parameters        ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm   AlgorithmIdentifier,
+ *     digest            OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	return arm_get_rotpk_info(key_ptr, key_len, flags);
+}
diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S
index b80903d..04bfb77 100644
--- a/plat/arm/css/sgi/aarch64/sgi_helper.S
+++ b/plat/arm/css/sgi/aarch64/sgi_helper.S
@@ -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,19 +18,22 @@
 	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
 	 *
 	 * Helper function to calculate the core position.
+	 * (ChipId * PLAT_ARM_CLUSTER_COUNT *
+	 *  CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
 	 * (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
 	 * (CPUId * CSS_SGI_MAX_PE_PER_CPU) +
 	 * ThreadId
 	 *
 	 * which can be simplified as:
 	 *
-	 * ((ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER + CPUId) *
-	 * CSS_SGI_MAX_PE_PER_CPU) + ThreadId
+	 * ((((ChipId * PLAT_ARM_CLUSTER_COUNT) + ClusterId) *
+	 *   CSS_SGI_MAX_CPUS_PER_CLUSTER) + CPUId) * CSS_SGI_MAX_PE_PER_CPU +
+	 * ThreadId
 	 * ------------------------------------------------------
 	 */
 
 func plat_arm_calc_core_pos
-	mov	x3, x0
+	mov	x4, x0
 
 	/*
 	 * The MT bit in MPIDR is always set for SGI platforms
@@ -38,15 +41,18 @@
 	 */
 
 	/* Extract individual affinity fields from MPIDR */
-	ubfx    x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
-	ubfx    x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
-	ubfx    x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS
 
 	/* Compute linear position */
+	mov     x4, #PLAT_ARM_CLUSTER_COUNT
+	madd    x2, x3, x4, x2
 	mov     x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER
 	madd    x1, x2, x4, x1
-	mov     x5, #CSS_SGI_MAX_PE_PER_CPU
-	madd    x0, x1, x5, x0
+	mov     x4, #CSS_SGI_MAX_PE_PER_CPU
+	madd    x0, x1, x4, x0
 	ret
 endfunc plat_arm_calc_core_pos
 
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index e214573..4986378 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -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
  */
@@ -17,12 +17,16 @@
 #include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#define PLATFORM_CORE_COUNT		(PLAT_ARM_CLUSTER_COUNT *	\
-					CSS_SGI_MAX_CPUS_PER_CLUSTER * \
+#define PLATFORM_CORE_COUNT		(CSS_SGI_CHIP_COUNT *		\
+					PLAT_ARM_CLUSTER_COUNT *	\
+					CSS_SGI_MAX_CPUS_PER_CLUSTER *	\
 					CSS_SGI_MAX_PE_PER_CPU)
 
 #define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00040000	/* 256 KB */
 
+/* Remote chip address offset (4TB per chip) */
+#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n)	((ULL(1) << 42) * (n))
+
 /*
  * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
  * plat_arm_mmap array defined for each BL stage.
@@ -35,14 +39,14 @@
 #  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	10
 # else
 #  define PLAT_ARM_MMAP_ENTRIES		8
-#  define MAX_XLAT_TABLES		5
+#  define MAX_XLAT_TABLES		8
 # endif
 #elif defined(IMAGE_BL32)
 # define PLAT_ARM_MMAP_ENTRIES		8
 # define MAX_XLAT_TABLES		5
 #elif !USE_ROMLIB
 # define PLAT_ARM_MMAP_ENTRIES		11
-# define MAX_XLAT_TABLES		5
+# define MAX_XLAT_TABLES		7
 #else
 # define PLAT_ARM_MMAP_ENTRIES		12
 # define MAX_XLAT_TABLES		6
@@ -129,10 +133,29 @@
 					CSS_SGI_DEVICE_SIZE,	\
 					MT_DEVICE | MT_RW | MT_SECURE)
 
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		0x30000000
-#define PLAT_ARM_GICC_BASE		0x2C000000
-#define PLAT_ARM_GICR_BASE		0x300C0000
+#define ARM_MAP_SHARED_RAM_REMOTE_CHIP(n)					\
+			MAP_REGION_FLAT(					\
+				CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) +		\
+				ARM_SHARED_RAM_BASE,				\
+				ARM_SHARED_RAM_SIZE,				\
+				MT_MEMORY | MT_RW | MT_SECURE			\
+			)
+
+#define CSS_SGI_MAP_DEVICE_REMOTE_CHIP(n)					\
+			MAP_REGION_FLAT(					\
+				CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) +		\
+				CSS_SGI_DEVICE_BASE,				\
+				CSS_SGI_DEVICE_SIZE,				\
+				MT_DEVICE | MT_RW | MT_SECURE			\
+			)
+
+#define SOC_CSS_MAP_DEVICE_REMOTE_CHIP(n)					\
+			MAP_REGION_FLAT(					\
+				CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) +		\
+				SOC_CSS_DEVICE_BASE,				\
+				SOC_CSS_DEVICE_SIZE,				\
+				MT_DEVICE | MT_RW | MT_SECURE			\
+			)
 
 /* Map the secure region for access from S-EL0 */
 #define PLAT_ARM_SECURE_MAP_DEVICE	MAP_REGION_FLAT(	\
@@ -212,4 +235,7 @@
 #define SBSA_SECURE_WDOG_BASE		UL(0x2A480000)
 #define SBSA_SECURE_WDOG_TIMEOUT	UL(100)
 
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	CSS_SGI_CHIP_COUNT
+
 #endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_plat.h b/plat/arm/css/sgi/include/sgi_plat.h
new file mode 100644
index 0000000..a5fbded
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_plat.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_PLAT_H
+#define SGI_PLAT_H
+
+/* BL31 platform setup common to all SGI based platforms */
+void sgi_bl31_common_platform_setup(void);
+
+#endif /* SGI_PLAT_H */
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
index c75f213..f4c5300 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/css/sgi/include/sgi_variant.h
@@ -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
  */
@@ -8,16 +8,21 @@
 #define SGI_VARIANT_H
 
 /* SSC_VERSION values for SGI575 */
-#define SGI575_SSC_VER_PART_NUM		0x0783
+#define SGI575_SSC_VER_PART_NUM			0x0783
 
 /* SID Version values for RD-N1E1-Edge */
 #define RD_N1E1_EDGE_SID_VER_PART_NUM		0x0786
 #define RD_E1_EDGE_CONFIG_ID			0x2
 
+/* SID Version values for RD-Daniel */
+#define RD_DANIEL_SID_VER_PART_NUM		0x078a
+
 /* Structure containing SGI platform variant information */
 typedef struct sgi_platform_info {
 	unsigned int platform_id;	/* Part Number of the platform */
 	unsigned int config_id;		/* Config Id of the platform */
+	unsigned int chip_id;		/* Chip Id or Node number */
+	unsigned int multi_chip_mode;	/* Multi-chip mode availability */
 } sgi_platform_info_t;
 
 extern sgi_platform_info_t sgi_plat_info;
@@ -28,4 +33,7 @@
 /* returns the configuration id of the platform */
 unsigned int plat_arm_sgi_get_config_id(void);
 
+/* returns true if operating in multi-chip configuration */
+unsigned int plat_arm_sgi_get_multi_chip_mode(void);
+
 #endif /* SGI_VARIANT_H */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 7160111..40a7fd8 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -16,6 +16,8 @@
 
 HANDLE_EA_EL3_FIRST		:=	0
 
+CSS_SGI_CHIP_COUNT		:=	1
+
 INTERCONNECT_SOURCES	:=	${CSS_ENT_BASE}/sgi_interconnect.c
 
 PLAT_INCLUDES		+=	-I${CSS_ENT_BASE}/include
@@ -52,6 +54,8 @@
 
 $(eval $(call add_define,SGI_PLAT))
 
+$(eval $(call add_define,CSS_SGI_CHIP_COUNT))
+
 override CSS_LOAD_SCP_IMAGES	:=	0
 override NEED_BL2U		:=	no
 override ARM_BL31_IN_DRAM	:=	1
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index ba050d5..fcb7e1f 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -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
  */
@@ -28,18 +28,57 @@
 		.ring_doorbell = &mhu_ring_doorbell,
 };
 
-static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info = {
+static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = {
+	{
 		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
 		.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
 		.db_preserve_mask = 0xfffffffe,
 		.db_modify_mask = 0x1,
 		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#if (CSS_SGI_CHIP_COUNT > 1)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
+		.db_reg_addr = PLAT_CSS_MHU_BASE
+			+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#endif
+	#if (CSS_SGI_CHIP_COUNT > 2)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#endif
+	#if (CSS_SGI_CHIP_COUNT > 3)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#endif
 };
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(void)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
 {
-	if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM)
-		return &rd_n1e1_edge_scmi_plat_info;
+	if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
+		sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM) {
+		if (channel_id >= sizeof(rd_n1e1_edge_scmi_plat_info))
+			panic();
+		return &rd_n1e1_edge_scmi_plat_info[channel_id];
+	}
 	else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM)
 		return &sgi575_scmi_plat_info;
 	else
@@ -51,11 +90,12 @@
 {
 	sgi_plat_info.platform_id = plat_arm_sgi_get_platform_id();
 	sgi_plat_info.config_id = plat_arm_sgi_get_config_id();
+	sgi_plat_info.multi_chip_mode = plat_arm_sgi_get_multi_chip_mode();
 
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
 }
 
-void bl31_platform_setup(void)
+void sgi_bl31_common_platform_setup(void)
 {
 	arm_bl31_platform_setup();
 
@@ -66,9 +106,13 @@
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
 {
-	/* For RD-E1-Edge platform only CPU ON/OFF is supported */
-	if ((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
-	    (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) {
+	/*
+	 * For RD-E1-Edge and RD-Daniel platforms, only CPU power ON/OFF
+	 * PSCI platform callbacks are supported.
+	 */
+	if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
+	    (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID)) ||
+	    (sgi_plat_info.platform_id == RD_DANIEL_SID_VER_PART_NUM)) {
 		ops->cpu_standby = NULL;
 		ops->system_off = NULL;
 		ops->system_reset = NULL;
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c
index a2f10dc..09f3b72 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/css/sgi/sgi_image_load.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,6 +62,13 @@
 		return -1;
 	}
 
+	platcfg = plat_arm_sgi_get_multi_chip_mode();
+	err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
+	if (err < 0) {
+		ERROR("Failed to set multi-chip-mode\n");
+		return -1;
+	}
+
 	flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
 
 	return 0;
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 24bbed5..90511ac 100644
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -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
  */
@@ -86,7 +86,6 @@
 
 /* MHU related constants */
 #define PLAT_CSS_MHU_BASE		0x2b1f0000
-#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
 #define PLAT_ARM_TRUSTED_ROM_BASE	0x00000000
 #define PLAT_ARM_TRUSTED_ROM_SIZE	0x00080000
@@ -239,4 +238,7 @@
 /* System power domain level */
 #define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
 
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	U(1)
+
 #endif /* SGM_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
index 7e92ac8..907e9fd 100644
--- a/plat/arm/css/sgm/sgm_bl31_setup.c
+++ b/plat/arm/css/sgm/sgm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,7 @@
 		.ring_doorbell = &mhu_ring_doorbell,
 };
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info()
+scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
 {
 	return &sgm775_scmi_plat_info;
 }
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 13099b4..4b11440 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -14,6 +14,7 @@
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables.h>
 
+#include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 
 static entry_point_info_t bl32_image_ep_info;
@@ -107,6 +108,8 @@
 	/* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */
 	mmio_write_64(PLAT_CPU_RELEASE_ADDR,
 		(uint64_t)plat_secondary_cpus_bl31_entry);
+
+	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
 }
 
 const mmap_region_t plat_agilex_mmap[] = {
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index c4b9e59..38f4696 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -73,6 +73,29 @@
 /* Mailbox REBOOT commands */
 #define MBOX_CMD_REBOOT_HPS		71
 
+/* Mailbox RSU commands */
+#define MBOX_GET_SUBPARTITION_TABLE	90
+#define MBOX_RSU_STATUS			91
+#define MBOX_RSU_UPDATE			92
+
+/* Mailbox RSU macros */
+#define RSU_VERSION_ACMF		BIT(8)
+#define RSU_VERSION_ACMF_MASK		0xff00
+
+/* HPS stage notify command */
+#define MBOX_HPS_STAGE_NOTIFY		93
+
+/* Execution states for HPS_STAGE_NOTIFY */
+#define HPS_EXECUTION_STATE_FSBL	0
+#define HPS_EXECUTION_STATE_SSBL	1
+#define HPS_EXECUTION_STATE_OS		2
+
+/* Mailbox reconfiguration commands */
+#define MBOX_CONFIG_STATUS		4
+#define MBOX_RECONFIG			6
+#define MBOX_RECONFIG_DATA		8
+#define MBOX_RECONFIG_STATUS		9
+
 /* Generic error handling */
 #define MBOX_TIMEOUT			-2047
 #define MBOX_NO_RESPONSE		-2
@@ -98,13 +121,6 @@
 #define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO		0xf0000007
 #define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR		0xf0000008
 
-/* Mailbox reconfiguration commands */
-#define MBOX_CONFIG_STATUS	4
-#define MBOX_RECONFIG		6
-#define MBOX_RECONFIG_DATA	8
-#define MBOX_RECONFIG_STATUS	9
-
-
 void mailbox_set_int(int interrupt_input);
 int mailbox_init(void);
 void mailbox_set_qspi_close(void);
@@ -122,4 +138,9 @@
 uint32_t intel_mailbox_get_config_status(uint32_t cmd);
 int intel_mailbox_is_fpga_not_ready(void);
 
+int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len);
+int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len);
+int mailbox_rsu_update(uint32_t *flash_offset);
+int mailbox_hps_stage_notify(uint32_t execution_stage);
+
 #endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 6bb41f3..2b1d983 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -28,6 +28,7 @@
 #define INTEL_SIP_LEGACY_SMC_ECC_DBE			0xC200000D
 #define INTEL_SIP_SMC_RSU_NOTIFY			0xC200000E
 #define INTEL_SIP_SMC_RSU_RETRY_COUNTER			0xC200000F
+#define INTEL_SIP_SMC_MBOX_SEND_CMD			0xC200001E
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR			0x400000
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 8d7c1d6..673c2d5 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -267,6 +267,55 @@
 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0);
 }
 
+int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len)
+{
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE,
+				NULL, 0, 0, (uint32_t *)resp_buf,
+				resp_buf_len);
+}
+
+struct rsu_status_info {
+	uint64_t current_image;
+	uint64_t fail_image;
+	uint32_t state;
+	uint32_t version;
+	uint32_t error_location;
+	uint32_t error_details;
+	uint32_t retry_counter;
+};
+
+int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len)
+{
+	int ret;
+	struct rsu_status_info *info = (struct rsu_status_info *)resp_buf;
+
+	info->retry_counter = ~0;
+
+	ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, 0,
+			       (uint32_t *)resp_buf, resp_buf_len);
+
+	if (ret < 0)
+		return ret;
+
+	if (info->retry_counter != ~0)
+		if (!(info->version & RSU_VERSION_ACMF_MASK))
+			info->version |= RSU_VERSION_ACMF;
+
+	return ret;
+}
+
+int mailbox_rsu_update(uint32_t *flash_offset)
+{
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
+				(uint32_t *)flash_offset, 2, 0, NULL, 0);
+}
+
+int mailbox_hps_stage_notify(uint32_t execution_stage)
+{
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY,
+				&execution_stage, 1, 0, NULL, 0);
+}
+
 int mailbox_init(void)
 {
 	int status = 0;
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index d8a6c19..d27ab9f 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -130,9 +130,14 @@
 	panic();
 }
 
+extern uint64_t intel_rsu_update_address;
+
 static void __dead2 socfpga_system_reset(void)
 {
-	mailbox_reset_cold();
+	if (intel_rsu_update_address)
+		mailbox_rsu_update((uint32_t *)&intel_rsu_update_address);
+	else
+		mailbox_reset_cold();
 
 	while (1)
 		wfi();
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 41dae9e..5b600e5 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -252,12 +252,16 @@
 	return true;
 }
 
-static bool is_address_in_ddr_range(uint64_t addr)
+static bool is_address_in_ddr_range(uint64_t addr, uint64_t size)
 {
-	if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE)
-		return true;
+	if (size > (UINT64_MAX - addr))
+		return false;
+	if (addr < DRAM_BASE)
+		return false;
+	if (addr + size > DRAM_BASE + DRAM_SIZE)
+		return false;
 
-	return false;
+	return true;
 }
 
 static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
@@ -266,8 +270,7 @@
 
 	intel_fpga_sdm_write_all();
 
-	if (!is_address_in_ddr_range(mem) ||
-		!is_address_in_ddr_range(mem + size) ||
+	if (!is_address_in_ddr_range(mem, size) ||
 		is_fpga_config_buffer_full())
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 
@@ -365,6 +368,66 @@
 	return INTEL_SIP_SMC_STATUS_ERROR;
 }
 
+/* Intel Remote System Update (RSU) services */
+uint64_t intel_rsu_update_address;
+
+static uint32_t intel_rsu_status(uint64_t *respbuf, uint32_t respbuf_sz)
+{
+	if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0)
+		return INTEL_SIP_SMC_STATUS_ERROR;
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_update(uint64_t update_address)
+{
+	intel_rsu_update_address = update_address;
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_notify(uint64_t execution_stage)
+{
+	if (mailbox_hps_stage_notify((uint32_t)execution_stage) < 0)
+		return INTEL_SIP_SMC_STATUS_ERROR;
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz,
+					uint32_t *ret_stat)
+{
+	if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0)
+		return INTEL_SIP_SMC_STATUS_ERROR;
+
+	*ret_stat = respbuf[8];
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+/* Mailbox services */
+static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args, int len,
+				    int urgent, uint32_t *response,
+				    int resp_len, int *mbox_status,
+				    int *len_in_resp)
+{
+	*len_in_resp = 0;
+	*mbox_status = 0;
+
+	if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len))
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+
+	int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent,
+				      response, resp_len);
+
+	if (status < 0) {
+		*mbox_status = -status;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	*mbox_status = 0;
+	*len_in_resp = status;
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 /*
  * This function is responsible for handling all SiP calls from the NS world
  */
@@ -381,7 +444,10 @@
 	uint32_t val = 0;
 	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
 	uint32_t completed_addr[3];
+	uint64_t rsu_respbuf[9];
 	uint32_t count = 0;
+	u_register_t x5, x6;
+	int mbox_status, len_in_resp;
 
 	switch (smc_fid) {
 	case SIP_SVC_UID:
@@ -446,6 +512,41 @@
 						 (uint32_t)x3, &val);
 		SMC_RET3(handle, status, val, x1);
 
+	case INTEL_SIP_SMC_RSU_STATUS:
+		status = intel_rsu_status(rsu_respbuf,
+					ARRAY_SIZE(rsu_respbuf));
+		if (status) {
+			SMC_RET1(handle, status);
+		} else {
+			SMC_RET4(handle, rsu_respbuf[0], rsu_respbuf[1],
+					rsu_respbuf[2], rsu_respbuf[3]);
+		}
+
+	case INTEL_SIP_SMC_RSU_UPDATE:
+		status = intel_rsu_update(x1);
+		SMC_RET1(handle, status);
+
+	case INTEL_SIP_SMC_RSU_NOTIFY:
+		status = intel_rsu_notify(x1);
+		SMC_RET1(handle, status);
+
+	case INTEL_SIP_SMC_RSU_RETRY_COUNTER:
+		status = intel_rsu_retry_counter((uint32_t *)rsu_respbuf,
+						ARRAY_SIZE(rsu_respbuf), &val);
+		if (status) {
+			SMC_RET1(handle, status);
+		} else {
+			SMC_RET2(handle, status, val);
+		}
+
+	case INTEL_SIP_SMC_MBOX_SEND_CMD:
+		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+		status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4,
+					     (uint32_t *)x5, x6, &mbox_status,
+					     &len_in_resp);
+		SMC_RET4(handle, status, mbox_status, x5, len_in_resp);
+
 	default:
 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index 29f57c4..4c31238 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -16,6 +16,7 @@
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
+#include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_system_manager.h"
@@ -115,6 +116,8 @@
 	/* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */
 	mmio_write_64(PLAT_CPU_RELEASE_ADDR,
 		(uint64_t)plat_secondary_cpus_bl31_entry);
+
+	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
 }
 
 const mmap_region_t plat_stratix10_mmap[] = {
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
index ae899c4..eaf9675 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
@@ -316,7 +316,7 @@
 	/* prepare the MRQ_CLK command */
 	req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id);
 
-	ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
+	ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req),
 			NULL, 0);
 	if (ret != 0) {
 		ERROR("%s: failed for module %d with error %d\n", __func__,
@@ -339,7 +339,7 @@
 	/* prepare the MRQ_CLK command */
 	req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id);
 
-	ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req),
+	ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, (uint32_t)sizeof(req),
 			NULL, 0);
 	if (ret != 0) {
 		ERROR("%s: failed for module %d with error %d\n", __func__,
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
index 7059c37..d85b906 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
@@ -1,17 +1,17 @@
 /*
- * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef INTF_H
-#define INTF_H
+#ifndef BPMP_INTF_H
+#define BPMP_INTF_H
 
 /**
  * Flags used in IPC req
  */
 #define FLAG_DO_ACK			(U(1) << 0)
-#define FLAG_RING_DOORBELL	(U(1) << 1)
+#define FLAG_RING_DOORBELL		(U(1) << 1)
 
 /* Bit 1 is designated for CCPlex in secure world */
 #define HSP_MASTER_CCPLEX_BIT	(U(1) << 1)
@@ -77,16 +77,16 @@
  *
  */
 enum {
-	CMD_CLK_GET_RATE = 1,
-	CMD_CLK_SET_RATE = 2,
-	CMD_CLK_ROUND_RATE = 3,
-	CMD_CLK_GET_PARENT = 4,
-	CMD_CLK_SET_PARENT = 5,
-	CMD_CLK_IS_ENABLED = 6,
-	CMD_CLK_ENABLE = 7,
-	CMD_CLK_DISABLE = 8,
-	CMD_CLK_GET_ALL_INFO = 14,
-	CMD_CLK_GET_MAX_CLK_ID = 15,
+	CMD_CLK_GET_RATE = U(1),
+	CMD_CLK_SET_RATE = U(2),
+	CMD_CLK_ROUND_RATE = U(3),
+	CMD_CLK_GET_PARENT = U(4),
+	CMD_CLK_SET_PARENT = U(5),
+	CMD_CLK_IS_ENABLED = U(6),
+	CMD_CLK_ENABLE = U(7),
+	CMD_CLK_DISABLE = U(8),
+	CMD_CLK_GET_ALL_INFO = U(14),
+	CMD_CLK_GET_MAX_CLK_ID = U(15),
 	CMD_CLK_MAX,
 };
 
@@ -124,4 +124,4 @@
  */
 #define make_mrq_clk_cmd(cmd, id)	(((cmd) << 24) | (id & 0xFFFFFF))
 
-#endif /* INTF_H */
+#endif /* BPMP_INTF_H */
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
index 42e6a1f..1b31821 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2017-2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef IVC_H
-#define IVC_H
+#ifndef BPMP_IVC_H
+#define BPMP_IVC_H
 
 #include <lib/utils_def.h>
 #include <stdint.h>
@@ -15,22 +15,21 @@
 #define IVC_CHHDR_TX_FIELDS	U(16)
 #define IVC_CHHDR_RX_FIELDS	U(16)
 
-struct ivc;
 struct ivc_channel_header;
 
-/* callback handler for notify on receiving a response */
-typedef void (* ivc_notify_function)(const struct ivc *);
-
 struct ivc {
 	struct ivc_channel_header *rx_channel;
 	struct ivc_channel_header *tx_channel;
 	uint32_t w_pos;
 	uint32_t r_pos;
-	ivc_notify_function notify;
+	void (*notify)(const struct ivc *);
 	uint32_t nframes;
 	uint32_t frame_size;
 };
 
+/* callback handler for notify on receiving a response */
+typedef void (* ivc_notify_function)(const struct ivc *);
+
 int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base,
 		uint32_t nframes, uint32_t frame_size,
 		ivc_notify_function notify);
@@ -48,4 +47,4 @@
 bool tegra_ivc_can_write(const struct ivc *ivc);
 bool tegra_ivc_can_read(const struct ivc *ivc);
 
-#endif /* IVC_H */
+#endif /* BPMP_IVC_H */
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index 2f31906..c2ef981 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,17 +27,6 @@
 static uint64_t video_mem_size_mb;
 
 /*
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- */
-#pragma weak plat_memctrl_tzdram_setup
-
-void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
-{
-	; /* do nothing */
-}
-
-/*
  * Init Memory controller during boot.
  */
 void tegra_memctrl_setup(void)
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index cbe3377..8a49e23 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -65,35 +65,6 @@
 extern uint64_t ns_image_entrypoint;
 
 /*******************************************************************************
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- ******************************************************************************/
-#pragma weak plat_early_platform_setup
-#pragma weak plat_get_bl31_params
-#pragma weak plat_get_bl31_plat_params
-#pragma weak plat_late_platform_setup
-
-void plat_early_platform_setup(void)
-{
-	; /* do nothing */
-}
-
-struct tegra_bl31_params *plat_get_bl31_params(void)
-{
-	return NULL;
-}
-
-plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
-{
-	return NULL;
-}
-
-void plat_late_platform_setup(void)
-{
-	; /* do nothing */
-}
-
-/*******************************************************************************
  * Return a pointer to the 'entry_point_info' structure of the next image for
  * security state specified. BL33 corresponds to the non-secure image type
  * while BL32 corresponds to the secure image type.
@@ -137,8 +108,7 @@
 	/*
 	 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
 	 * there's no argument to relay from a previous bootloader. Platforms
-	 * might use custom ways to get arguments, so provide handlers which
-	 * they can override.
+	 * might use custom ways to get arguments.
 	 */
 	if (arg_from_bl2 == NULL) {
 		arg_from_bl2 = plat_get_bl31_params();
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index 34b5638..50c9592 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -25,7 +25,6 @@
 				plat/common/aarch64/crash_console_helpers.S	\
 				${TEGRA_GICv2_SOURCES}				\
 				${COMMON_DIR}/aarch64/tegra_helpers.S		\
-				${COMMON_DIR}/drivers/pmc/pmc.c			\
 				${COMMON_DIR}/lib/debug/profiler.c		\
 				${COMMON_DIR}/tegra_bl31_setup.c		\
 				${COMMON_DIR}/tegra_delay_timer.c		\
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 39dc42c..1f59f30 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,97 +28,6 @@
 extern uint64_t tegra_bl31_phys_base;
 extern uint64_t tegra_sec_entry_point;
 
-/*
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- */
-#pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early
-#pragma weak tegra_soc_cpu_standby
-#pragma weak tegra_soc_pwr_domain_suspend
-#pragma weak tegra_soc_pwr_domain_on
-#pragma weak tegra_soc_pwr_domain_off
-#pragma weak tegra_soc_pwr_domain_on_finish
-#pragma weak tegra_soc_pwr_domain_power_down_wfi
-#pragma weak tegra_soc_prepare_system_reset
-#pragma weak tegra_soc_prepare_system_off
-#pragma weak tegra_soc_get_target_pwr_state
-
-int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
-{
-	return PSCI_E_NOT_SUPPORTED;
-}
-
-int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
-{
-	(void)cpu_state;
-	return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
-	(void)target_state;
-	return PSCI_E_NOT_SUPPORTED;
-}
-
-int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
-{
-	(void)mpidr;
-	return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
-{
-	(void)target_state;
-	return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
-{
-	(void)target_state;
-	return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
-{
-	(void)target_state;
-	return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_prepare_system_reset(void)
-{
-	return PSCI_E_SUCCESS;
-}
-
-__dead2 void tegra_soc_prepare_system_off(void)
-{
-	ERROR("Tegra System Off: operation not handled.\n");
-	panic();
-}
-
-plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
-					     const plat_local_state_t *states,
-					     uint32_t ncpu)
-{
-	plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
-	uint32_t num_cpu = ncpu;
-	const plat_local_state_t *local_state = states;
-
-	(void)lvl;
-
-	assert(ncpu != 0U);
-
-	do {
-		temp = *local_state;
-		if ((temp < target)) {
-			target = temp;
-		}
-		--num_cpu;
-		local_state++;
-	} while (num_cpu != 0U);
-
-	return target;
-}
-
 /*******************************************************************************
  * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND`
  * call to get the `power_state` parameter. This allows the platform to encode
@@ -311,10 +221,10 @@
 	/* per-SoC system reset handler */
 	(void)tegra_soc_prepare_system_reset();
 
-	/*
-	 * Program the PMC in order to restart the system.
-	 */
-	tegra_pmc_system_reset();
+	/* wait for the system to reset */
+	for (;;) {
+		;
+	}
 }
 
 /*******************************************************************************
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index b8ba095..1d48cc0 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,32 +27,6 @@
 #define TEGRA_SIP_FIQ_NS_GET_CONTEXT		0x82000006
 
 /*******************************************************************************
- * SoC specific SiP handler
- ******************************************************************************/
-#pragma weak plat_sip_handler
-int32_t plat_sip_handler(uint32_t smc_fid,
-		     uint64_t x1,
-		     uint64_t x2,
-		     uint64_t x3,
-		     uint64_t x4,
-		     const void *cookie,
-		     void *handle,
-		     uint64_t flags)
-{
-	/* unused parameters */
-	(void)smc_fid;
-	(void)x1;
-	(void)x2;
-	(void)x3;
-	(void)x4;
-	(void)cookie;
-	(void)handle;
-	(void)flags;
-
-	return -ENOTSUP;
-}
-
-/*******************************************************************************
  * This function is responsible for handling all SiP calls
  ******************************************************************************/
 uintptr_t tegra_sip_handler(uint32_t smc_fid,
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index dfed2aa..8e6c1fd 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -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
  */
@@ -110,4 +111,10 @@
 #define TEGRA_TZRAM_BASE		U(0x7C010000)
 #define TEGRA_TZRAM_SIZE		U(0x10000)
 
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE			ULL(0x80000000)
+#define TEGRA_DRAM_END			ULL(0x27FFFFFFF)
+
 #endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index da050a8..f2a2334 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -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
  */
@@ -279,4 +280,10 @@
 #define TEGRA_TZRAM_BASE		U(0x30000000)
 #define TEGRA_TZRAM_SIZE		U(0x40000)
 
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE			ULL(0x80000000)
+#define TEGRA_DRAM_END			ULL(0x27FFFFFFF)
+
 #endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
index df1d656..a58ae9d 100644
--- a/plat/nvidia/tegra/include/t194/tegra_def.h
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -257,6 +257,12 @@
 #define TEGRA_GPCDMA_RST_CLR_REG_OFFSET	U(0x6A0008)
 
 /*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE			ULL(0x80000000)
+#define TEGRA_DRAM_END			ULL(0xFFFFFFFFF)
+
+/*******************************************************************************
  * XUSB STREAMIDs
  ******************************************************************************/
 #define TEGRA_SID_XUSB_HOST			U(0x1b)
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index bbcfdc5..4a39aa1 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -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
  */
@@ -268,4 +269,10 @@
 #define TEGRA_TZRAM_CARVEOUT_BASE	U(0x7C04C000)
 #define TEGRA_TZRAM_CARVEOUT_SIZE	U(0x4000)
 
+/*******************************************************************************
+ * Tegra DRAM memory base address
+ ******************************************************************************/
+#define TEGRA_DRAM_BASE			ULL(0x80000000)
+#define TEGRA_DRAM_END			ULL(0x27FFFFFFF)
+
 #endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 761acde..b419d94 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,12 +19,6 @@
 #include <tegra_gic.h>
 
 /*******************************************************************************
- * Tegra DRAM memory base address
- ******************************************************************************/
-#define TEGRA_DRAM_BASE		ULL(0x80000000)
-#define TEGRA_DRAM_END		ULL(0x27FFFFFFF)
-
-/*******************************************************************************
  * Implementation defined ACTLR_EL1 bit definitions
  ******************************************************************************/
 #define ACTLR_EL1_PMSTATE_MASK		(ULL(0xF) << 0)
@@ -106,6 +101,7 @@
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state);
 int32_t tegra_soc_prepare_system_reset(void);
 __dead2 void tegra_soc_prepare_system_off(void);
 plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
index bd3f46f..0e2edf0 100644
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -35,6 +36,30 @@
 
 static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER];
 
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
+					     const plat_local_state_t *states,
+					     uint32_t ncpu)
+{
+	plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
+	uint32_t num_cpu = ncpu;
+	const plat_local_state_t *local_state = states;
+
+	(void)lvl;
+
+	assert(ncpu != 0U);
+
+	do {
+		temp = *local_state;
+		if ((temp < target)) {
+			target = temp;
+		}
+		--num_cpu;
+		local_state++;
+	} while (num_cpu != 0U);
+
+	return target;
+}
+
 int32_t tegra_soc_validate_power_state(unsigned int power_state,
 					psci_power_state_t *req_state)
 {
@@ -109,6 +134,12 @@
 	val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
 	write_actlr_el1(val | DENVER_CPU_STATE_POWER_DOWN);
 
+	return PSCI_E_SUCCESS;
+}
+
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+	(void)cpu_state;
 	return PSCI_E_SUCCESS;
 }
 
@@ -136,6 +167,16 @@
 	val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
 	write_actlr_el1(val | target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]);
 
+	return PSCI_E_SUCCESS;
+}
+
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+	return PSCI_E_NOT_SUPPORTED;
+}
+
+int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
 	return PSCI_E_SUCCESS;
 }
 
@@ -152,5 +193,16 @@
 	/* Wait 1 ms to make sure clock source/device logic is stabilized. */
 	mdelay(1);
 
+	/*
+	 * Program the PMC in order to restart the system.
+	 */
+	tegra_pmc_system_reset();
+
 	return PSCI_E_SUCCESS;
 }
+
+__dead2 void tegra_soc_prepare_system_off(void)
+{
+	ERROR("Tegra System Off: operation not handled.\n");
+	panic();
+}
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index df62678..2f54dd5 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -121,3 +122,35 @@
 	tegra_gic_setup(NULL, 0);
 	tegra_gic_init();
 }
+
+/*******************************************************************************
+ * Return pointer to the BL31 params from previous bootloader
+ ******************************************************************************/
+struct tegra_bl31_params *plat_get_bl31_params(void)
+{
+	return NULL;
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 platform params from previous bootloader
+ ******************************************************************************/
+plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
+{
+	return NULL;
+}
+
+/*******************************************************************************
+ * Handler for early platform setup
+ ******************************************************************************/
+void plat_early_platform_setup(void)
+{
+	; /* do nothing */
+}
+
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
+void plat_late_platform_setup(void)
+{
+	; /* do nothing */
+}
diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk
index bb7b7ee..183e188 100644
--- a/plat/nvidia/tegra/soc/t132/platform_t132.mk
+++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk
@@ -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
 #
@@ -23,6 +24,7 @@
 				lib/cpus/aarch64/denver.S		\
 				${COMMON_DIR}/drivers/flowctrl/flowctrl.c	\
 				${COMMON_DIR}/drivers/memctrl/memctrl_v1.c	\
+				${COMMON_DIR}/drivers/pmc/pmc.c			\
 				${SOC_DIR}/plat_psci_handlers.c		\
 				${SOC_DIR}/plat_sip_calls.c		\
 				${SOC_DIR}/plat_setup.c			\
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index df94396..4ca5e77 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -95,71 +95,71 @@
  ******************************************************************************/
 const static mc_streamid_security_cfg_t tegra186_streamid_sec_cfgs[] = {
 	mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(GPUSWR2, SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(GPUSRD, SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(ISPWA, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(ISPRA, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE),
 	mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, DISABLE),
+	mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE),
-	mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, DISABLE),
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 11394c0..2000e53 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.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
  */
@@ -83,6 +84,12 @@
 	return ret;
 }
 
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+	(void)cpu_state;
+	return PSCI_E_SUCCESS;
+}
+
 int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
 	const plat_local_state_t *pwr_domain_state;
@@ -289,6 +296,11 @@
 	return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+	return PSCI_E_NOT_SUPPORTED;
+}
+
 int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
 {
 	int32_t ret = PSCI_E_SUCCESS;
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index 1018caa..7e18b5c 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -193,6 +194,14 @@
 	}
 }
 
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
+void plat_late_platform_setup(void)
+{
+	; /* do nothing */
+}
+
 /* Secure IRQs for Tegra186 */
 static const interrupt_prop_t tegra186_interrupt_props[] = {
 	INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
index ccc4665..9ccb823 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
@@ -19,123 +19,124 @@
  * occur when there is only new functionality.
  */
 enum {
-	TEGRA_NVG_VERSION_MAJOR = 6,
-	TEGRA_NVG_VERSION_MINOR = 6
+	TEGRA_NVG_VERSION_MAJOR = U(6),
+	TEGRA_NVG_VERSION_MINOR = U(6)
 };
 
 typedef enum {
-	TEGRA_NVG_CHANNEL_VERSION				= 0,
-	TEGRA_NVG_CHANNEL_POWER_PERF				= 1,
-	TEGRA_NVG_CHANNEL_POWER_MODES				= 2,
-	TEGRA_NVG_CHANNEL_WAKE_TIME				= 3,
-	TEGRA_NVG_CHANNEL_CSTATE_INFO				= 4,
-	TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND		= 5,
-	TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND		= 6,
-	TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND		= 8,
-	TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST		= 10,
-	TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE		= 11,
-	TEGRA_NVG_CHANNEL_NUM_CORES				= 20,
-	TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID			= 21,
-	TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING		= 22,
-	TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR			= 23,
-	TEGRA_NVG_CHANNEL_SHUTDOWN				= 42,
-	TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED			= 43,
-	TEGRA_NVG_CHANNEL_ONLINE_CORE				= 44,
-	TEGRA_NVG_CHANNEL_CC3_CTRL				= 45,
-	TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL			= 49,
-	TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC			= 50,
-	TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL			= 53,
-	TEGRA_NVG_CHANNEL_SECURITY_CONFIG			= 54,
-	TEGRA_NVG_CHANNEL_DEBUG_CONFIG				= 55,
-	TEGRA_NVG_CHANNEL_DDA_SNOC_MCF				= 56,
-	TEGRA_NVG_CHANNEL_DDA_MCF_ORD1				= 57,
-	TEGRA_NVG_CHANNEL_DDA_MCF_ORD2				= 58,
-	TEGRA_NVG_CHANNEL_DDA_MCF_ORD3				= 59,
-	TEGRA_NVG_CHANNEL_DDA_MCF_ISO				= 60,
-	TEGRA_NVG_CHANNEL_DDA_MCF_SISO				= 61,
-	TEGRA_NVG_CHANNEL_DDA_MCF_NISO				= 62,
-	TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE			= 63,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO			= 64,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO			= 65,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO			= 66,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE		= 67,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL			= 68,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR			= 69,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA		= 70,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA		= 71,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL			= 72,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL				= 73,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D			= 74,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD			= 75,
-	TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR			= 76,
-	TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL			= 77,
-	TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL		= 78,
-	TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL	= 79,
+	TEGRA_NVG_CHANNEL_VERSION				= U(0),
+	TEGRA_NVG_CHANNEL_POWER_PERF				= U(1),
+	TEGRA_NVG_CHANNEL_POWER_MODES				= U(2),
+	TEGRA_NVG_CHANNEL_WAKE_TIME				= U(3),
+	TEGRA_NVG_CHANNEL_CSTATE_INFO				= U(4),
+	TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND		= U(5),
+	TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND		= U(6),
+	TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND		= U(8),
+	TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST		= U(10),
+	TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE		= U(11),
+	TEGRA_NVG_CHANNEL_NUM_CORES				= U(20),
+	TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID			= U(21),
+	TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING		= U(22),
+	TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR			= U(23),
+	TEGRA_NVG_CHANNEL_SHUTDOWN				= U(42),
+	TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED			= U(43),
+	TEGRA_NVG_CHANNEL_ONLINE_CORE				= U(44),
+	TEGRA_NVG_CHANNEL_CC3_CTRL				= U(45),
+	TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL			= U(49),
+	TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC			= U(50),
+	TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL			= U(53),
+	TEGRA_NVG_CHANNEL_SECURITY_CONFIG			= U(54),
+	TEGRA_NVG_CHANNEL_DEBUG_CONFIG				= U(55),
+	TEGRA_NVG_CHANNEL_DDA_SNOC_MCF				= U(56),
+	TEGRA_NVG_CHANNEL_DDA_MCF_ORD1				= U(57),
+	TEGRA_NVG_CHANNEL_DDA_MCF_ORD2				= U(58),
+	TEGRA_NVG_CHANNEL_DDA_MCF_ORD3				= U(59),
+	TEGRA_NVG_CHANNEL_DDA_MCF_ISO				= U(60),
+	TEGRA_NVG_CHANNEL_DDA_MCF_SISO				= U(61),
+	TEGRA_NVG_CHANNEL_DDA_MCF_NISO				= U(62),
+	TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE			= U(63),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO			= U(64),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO			= U(65),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO			= U(66),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE		= U(67),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL			= U(68),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR			= U(69),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA		= U(70),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA		= U(71),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL			= U(72),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL				= U(73),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D			= U(74),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD			= U(75),
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR			= U(76),
+	TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL			= U(77),
+	TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL		= U(78),
+	TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL	= U(79),
 
 	TEGRA_NVG_CHANNEL_LAST_INDEX
 } tegra_nvg_channel_id_t;
 
 typedef enum {
-	NVG_STAT_QUERY_SC7_ENTRIES		= 1,
-	NVG_STAT_QUERY_CC6_ENTRIES		= 6,
-	NVG_STAT_QUERY_CG7_ENTRIES		= 7,
-	NVG_STAT_QUERY_C6_ENTRIES		= 10,
-	NVG_STAT_QUERY_C7_ENTRIES		= 14,
-	NVG_STAT_QUERY_SC7_RESIDENCY_SUM	= 32,
-	NVG_STAT_QUERY_CC6_RESIDENCY_SUM	= 41,
-	NVG_STAT_QUERY_CG7_RESIDENCY_SUM	= 46,
-	NVG_STAT_QUERY_C6_RESIDENCY_SUM		= 51,
-	NVG_STAT_QUERY_C7_RESIDENCY_SUM		= 56,
-	NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM	= 60,
-	NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM	= 61,
-	NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM	= 62,
-	NVG_STAT_QUERY_C6_ENTRY_TIME_SUM	= 63,
-	NVG_STAT_QUERY_C7_ENTRY_TIME_SUM	= 64,
-	NVG_STAT_QUERY_SC7_EXIT_TIME_SUM	= 70,
-	NVG_STAT_QUERY_CC6_EXIT_TIME_SUM	= 71,
-	NVG_STAT_QUERY_CG7_EXIT_TIME_SUM	= 72,
-	NVG_STAT_QUERY_C6_EXIT_TIME_SUM		= 73,
-	NVG_STAT_QUERY_C7_EXIT_TIME_SUM		= 74,
-	NVG_STAT_QUERY_SC7_ENTRY_LAST		= 80,
-	NVG_STAT_QUERY_CC6_ENTRY_LAST		= 81,
-	NVG_STAT_QUERY_CG7_ENTRY_LAST		= 82,
-	NVG_STAT_QUERY_C6_ENTRY_LAST		= 83,
-	NVG_STAT_QUERY_C7_ENTRY_LAST		= 84,
-	NVG_STAT_QUERY_SC7_EXIT_LAST		= 90,
-	NVG_STAT_QUERY_CC6_EXIT_LAST		= 91,
-	NVG_STAT_QUERY_CG7_EXIT_LAST		= 92,
-	NVG_STAT_QUERY_C6_EXIT_LAST		= 93,
-	NVG_STAT_QUERY_C7_EXIT_LAST		= 94
+	NVG_STAT_QUERY_SC7_ENTRIES				= U(1),
+	NVG_STAT_QUERY_CC6_ENTRIES				= U(6),
+	NVG_STAT_QUERY_CG7_ENTRIES				= U(7),
+	NVG_STAT_QUERY_C6_ENTRIES				= U(10),
+	NVG_STAT_QUERY_C7_ENTRIES				= U(14),
+	NVG_STAT_QUERY_SC7_RESIDENCY_SUM			= U(32),
+	NVG_STAT_QUERY_CC6_RESIDENCY_SUM			= U(41),
+	NVG_STAT_QUERY_CG7_RESIDENCY_SUM			= U(46),
+	NVG_STAT_QUERY_C6_RESIDENCY_SUM				= U(51),
+	NVG_STAT_QUERY_C7_RESIDENCY_SUM				= U(56),
+	NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM			= U(60),
+	NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM			= U(61),
+	NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM			= U(62),
+	NVG_STAT_QUERY_C6_ENTRY_TIME_SUM			= U(63),
+	NVG_STAT_QUERY_C7_ENTRY_TIME_SUM			= U(64),
+	NVG_STAT_QUERY_SC7_EXIT_TIME_SUM			= U(70),
+	NVG_STAT_QUERY_CC6_EXIT_TIME_SUM			= U(71),
+	NVG_STAT_QUERY_CG7_EXIT_TIME_SUM			= U(72),
+	NVG_STAT_QUERY_C6_EXIT_TIME_SUM				= U(73),
+	NVG_STAT_QUERY_C7_EXIT_TIME_SUM				= U(74),
+	NVG_STAT_QUERY_SC7_ENTRY_LAST				= U(80),
+	NVG_STAT_QUERY_CC6_ENTRY_LAST				= U(81),
+	NVG_STAT_QUERY_CG7_ENTRY_LAST				= U(82),
+	NVG_STAT_QUERY_C6_ENTRY_LAST				= U(83),
+	NVG_STAT_QUERY_C7_ENTRY_LAST				= U(84),
+	NVG_STAT_QUERY_SC7_EXIT_LAST				= U(90),
+	NVG_STAT_QUERY_CC6_EXIT_LAST				= U(91),
+	NVG_STAT_QUERY_CG7_EXIT_LAST				= U(92),
+	NVG_STAT_QUERY_C6_EXIT_LAST				= U(93),
+	NVG_STAT_QUERY_C7_EXIT_LAST				= U(94)
+
 } tegra_nvg_stat_query_t;
 
 typedef enum {
-	TEGRA_NVG_CORE_C0 = 0,
-	TEGRA_NVG_CORE_C1 = 1,
-	TEGRA_NVG_CORE_C6 = 6,
-	TEGRA_NVG_CORE_C7 = 7,
-	TEGRA_NVG_CORE_WARMRSTREQ = 8
+	TEGRA_NVG_CORE_C0 = U(0),
+	TEGRA_NVG_CORE_C1 = U(1),
+	TEGRA_NVG_CORE_C6 = U(6),
+	TEGRA_NVG_CORE_C7 = U(7),
+	TEGRA_NVG_CORE_WARMRSTREQ = U(8)
 } tegra_nvg_core_sleep_state_t;
 
 typedef enum {
-	TEGRA_NVG_SHUTDOWN = 0U,
-	TEGRA_NVG_REBOOT = 1U
+	TEGRA_NVG_SHUTDOWN = U(0),
+	TEGRA_NVG_REBOOT = U(1)
 } tegra_nvg_shutdown_reboot_state_t;
 
 typedef enum {
-	TEGRA_NVG_CLUSTER_CC0 = 0,
-	TEGRA_NVG_CLUSTER_AUTO_CC1 = 1,
-	TEGRA_NVG_CLUSTER_CC6 = 6
+	TEGRA_NVG_CLUSTER_CC0		= U(0),
+	TEGRA_NVG_CLUSTER_AUTO_CC1	= U(1),
+	TEGRA_NVG_CLUSTER_CC6		= U(6)
 } tegra_nvg_cluster_sleep_state_t;
 
 typedef enum {
-	TEGRA_NVG_CG_CG0 = 0,
-	TEGRA_NVG_CG_CG7 = 7
+	TEGRA_NVG_CG_CG0 = U(0),
+	TEGRA_NVG_CG_CG7 = U(7)
 } tegra_nvg_cluster_group_sleep_state_t;
 
 typedef enum {
-	TEGRA_NVG_SYSTEM_SC0 = 0,
-	TEGRA_NVG_SYSTEM_SC7 = 7,
-	TEGRA_NVG_SYSTEM_SC8 = 8
+	TEGRA_NVG_SYSTEM_SC0 = U(0),
+	TEGRA_NVG_SYSTEM_SC7 = U(7),
+	TEGRA_NVG_SYSTEM_SC8 = U(8)
 } tegra_nvg_system_sleep_state_t;
 
 // ---------------------------------------------------------------------------
@@ -145,95 +146,95 @@
 typedef union {
 	uint64_t flat;
 	struct nvg_version_channel_t {
-		uint32_t minor_version	: 32;
-		uint32_t major_version	: 32;
+		uint32_t minor_version : U(32);
+		uint32_t major_version : U(32);
 	} bits;
 } nvg_version_data_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_power_perf_channel_t {
-		uint32_t perf_per_watt	: 1;
-		uint32_t reserved_31_1	: 31;
-		uint32_t reserved_63_32	: 32;
+		uint32_t perf_per_watt	: U(1);
+		uint32_t reserved_31_1	: U(31);
+		uint32_t reserved_63_32	: U(32);
 	} bits;
 } nvg_power_perf_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_power_modes_channel_t {
-		uint32_t low_battery	: 1;
-		uint32_t reserved_1_1	: 1;
-		uint32_t battery_save	: 1;
-		uint32_t reserved_31_3	: 29;
-		uint32_t reserved_63_32	: 32;
+		uint32_t low_battery	: U(1);
+		uint32_t reserved_1_1	: U(1);
+		uint32_t battery_save	: U(1);
+		uint32_t reserved_31_3	: U(29);
+		uint32_t reserved_63_32	: U(32);
 	} bits;
 } nvg_power_modes_channel_t;
 
 typedef union nvg_channel_1_data_u {
 	uint64_t flat;
 	struct nvg_channel_1_data_s {
-		uint32_t perf_per_watt_mode	: 1;
-		uint32_t reserved_31_1		: 31;
-		uint32_t reserved_63_32		: 32;
+		uint32_t perf_per_watt_mode	: U(1);
+		uint32_t reserved_31_1		: U(31);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_channel_1_data_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_ccplex_cache_control_channel_t {
-		uint32_t gpu_ways	: 5;
-		uint32_t reserved_7_5	: 3;
-		uint32_t gpu_only_ways	: 5;
-		uint32_t reserved_31_13	: 19;
-		uint32_t reserved_63_32	: 32;
+		uint32_t gpu_ways	: U(5);
+		uint32_t reserved_7_5	: U(3);
+		uint32_t gpu_only_ways	: U(5);
+		uint32_t reserved_31_13 : U(19);
+		uint32_t reserved_63_32 : U(32);
 	} bits;
 } nvg_ccplex_cache_control_channel_t;
 
 typedef union nvg_channel_2_data_u {
 	uint64_t flat;
 	struct nvg_channel_2_data_s {
-		uint32_t reserved_1_0		: 2;
-		uint32_t battery_saver_mode	: 1;
-		uint32_t reserved_31_3		: 29;
-		uint32_t reserved_63_32		: 32;
+		uint32_t reserved_1_0		: U(2);
+		uint32_t battery_saver_mode	: U(1);
+		uint32_t reserved_31_3		: U(29);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_channel_2_data_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_wake_time_channel_t {
-		uint32_t wake_time	: 32;
-		uint32_t reserved_63_32	: 32;
+		uint32_t wake_time		: U(32);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_wake_time_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_cstate_info_channel_t {
-		uint32_t cluster_state			: 3;
-		uint32_t reserved_6_3			: 4;
-		uint32_t update_cluster			: 1;
-		uint32_t cg_cstate				: 3;
-		uint32_t reserved_14_11			: 4;
-		uint32_t update_cg				: 1;
-		uint32_t system_cstate			: 4;
-		uint32_t reserved_22_20			: 3;
-		uint32_t update_system			: 1;
-		uint32_t reserved_30_24			: 7;
-		uint32_t update_wake_mask		: 1;
+		uint32_t cluster_state			: U(3);
+		uint32_t reserved_6_3			: U(4);
+		uint32_t update_cluster			: U(1);
+		uint32_t cg_cstate			: U(3);
+		uint32_t reserved_14_11			: U(4);
+		uint32_t update_cg			: U(1);
+		uint32_t system_cstate			: U(4);
+		uint32_t reserved_22_20			: U(3);
+		uint32_t update_system			: U(1);
+		uint32_t reserved_30_24			: U(7);
+		uint32_t update_wake_mask		: U(1);
 		union {
-			uint32_t flat				: 32;
+			uint32_t flat			: U(32);
 			struct {
-				uint32_t vfiq			: 1;
-				uint32_t virq			: 1;
-				uint32_t fiq			: 1;
-				uint32_t irq			: 1;
-				uint32_t serror			: 1;
-				uint32_t reserved_10_5	: 6;
-				uint32_t fiqout			: 1;
-				uint32_t irqout			: 1;
-				uint32_t reserved_31_13	: 19;
+				uint32_t vfiq		: U(1);
+				uint32_t virq		: U(1);
+				uint32_t fiq		: U(1);
+				uint32_t irq		: U(1);
+				uint32_t serror		: U(1);
+				uint32_t reserved_10_5	: U(6);
+				uint32_t fiqout		: U(1);
+				uint32_t irqout		: U(1);
+				uint32_t reserved_31_13	: U(19);
 			} carmel;
 		} wake_mask;
 	} bits;
@@ -242,183 +243,182 @@
 typedef union {
 	uint64_t flat;
 	struct nvg_lower_bound_channel_t {
-		uint32_t crossover_value : 32;
-		uint32_t reserved_63_32	: 32;
+		uint32_t crossover_value	: U(32);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_lower_bound_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_cstate_stat_query_channel_t {
-		uint32_t unit_id	: 4;
-		uint32_t reserved_15_4	: 12;
-		uint32_t stat_id	: 16;
-		uint32_t reserved_63_32	: 32;
+		uint32_t unit_id		: U(4);
+		uint32_t reserved_15_4		: U(12);
+		uint32_t stat_id		: U(16);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_cstate_stat_query_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_num_cores_channel_t {
-		uint32_t num_cores		: 4;
-		uint32_t reserved_31_4	: 28;
-		uint32_t reserved_63_32 : 32;
+		uint32_t num_cores		: U(4);
+		uint32_t reserved_31_4		: U(28);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_num_cores_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_unique_logical_id_channel_t {
-		uint32_t unique_core_id	: 3;
-		uint32_t reserved_31_3	: 29;
-		uint32_t reserved_63_32 : 32;
+		uint32_t unique_core_id		: U(3);
+		uint32_t reserved_31_3		: U(29);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_unique_logical_id_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_logical_to_physical_mappings_channel_t {
-		uint32_t lcore0_pcore_id	: 4;
-		uint32_t lcore1_pcore_id	: 4;
-		uint32_t lcore2_pcore_id	: 4;
-		uint32_t lcore3_pcore_id	: 4;
-		uint32_t lcore4_pcore_id	: 4;
-		uint32_t lcore5_pcore_id	: 4;
-		uint32_t lcore6_pcore_id	: 4;
-		uint32_t lcore7_pcore_id	: 4;
-		uint32_t reserved_63_32		: 32;
+		uint32_t lcore0_pcore_id	: U(4);
+		uint32_t lcore1_pcore_id	: U(4);
+		uint32_t lcore2_pcore_id	: U(4);
+		uint32_t lcore3_pcore_id	: U(4);
+		uint32_t lcore4_pcore_id	: U(4);
+		uint32_t lcore5_pcore_id	: U(4);
+		uint32_t lcore6_pcore_id	: U(4);
+		uint32_t lcore7_pcore_id	: U(4);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_logical_to_physical_mappings_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_logical_to_mpidr_channel_write_t {
-		uint32_t lcore_id		: 3;
-		uint32_t reserved_31_3	: 29;
-		uint32_t reserved_63_32	: 32;
+		uint32_t lcore_id		: U(3);
+		uint32_t reserved_31_3		: U(29);
+		uint32_t reserved_63_32		: U(32);
 	} write;
 	struct nvg_logical_to_mpidr_channel_read_t {
-		uint32_t mpidr			: 32;
-		uint32_t reserved_63_32	: 32;
+		uint32_t mpidr			: U(32);
+		uint32_t reserved_63_32		: U(32);
 	} read;
 } nvg_logical_to_mpidr_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_is_sc7_allowed_channel_t {
-		uint32_t is_sc7_allowed	: 1;
-		uint32_t reserved_31_1	: 31;
-		uint32_t reserved_63_32	: 32;
+		uint32_t is_sc7_allowed		: U(1);
+		uint32_t reserved_31_1		: U(31);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_is_sc7_allowed_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_core_online_channel_t {
-		uint32_t core_id	: 4;
-		uint32_t reserved_31_4	: 28;
-		uint32_t reserved_63_32	: 32;
+		uint32_t core_id		: U(4);
+		uint32_t reserved_31_4		: U(28);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_core_online_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_cc3_control_channel_t {
-		uint32_t freq_req	: 9;
-		uint32_t reserved_30_9	: 22;
-		uint32_t enable		: 1;
-		uint32_t reserved_63_32	: 32;
+		uint32_t freq_req		: U(9);
+		uint32_t reserved_30_9		: U(22);
+		uint32_t enable			: U(1);
+		uint32_t reserved_63_32		: U(32);
 	} bits;
 } nvg_cc3_control_channel_t;
 
 typedef enum {
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL			=	0,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC			=	1,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1			=	2,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2			=	3,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA			=	4,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB			=	5,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP			=	6,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_APE			=	7,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE			=	8,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE			=	9,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_APR			=	10,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM			=	11,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC		=	12,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE		=	13,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE		=	14,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7			=	15,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE		=	16,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE			=	17,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP		=	18,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1			=	19,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP		=	20,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7			=	21,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP	=	22,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW		=	23,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST		=	24,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB			=	25,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_CV				=	26,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2			=	27,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW		=	28,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES		=	29,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_30				=	30,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_31				=	31,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM			=	32,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK			=	33,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS			=	34,
-	TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR			=	35,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL		=	U(0),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC		=	U(1),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1		=	U(2),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2		=	U(3),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA		=	U(4),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB		=	U(5),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP		=	U(6),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_APE		=	U(7),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE		=	U(8),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE		=	U(9),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_APR		=	U(10),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM		=	U(11),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC	=	U(12),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE	=	U(13),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE	=	U(14),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7		=	U(15),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE	=	U(16),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE		=	U(17),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP	=	U(18),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1		=	U(19),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP	=	U(20),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7		=	U(21),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP =	U(22),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW	=	U(23),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST	=	U(24),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB		=	U(25),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_CV			=	U(26),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2		=	U(27),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW	=	U(28),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES	=	U(29),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_30			=	U(30),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_31			=	U(31),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM		=	U(32),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK		=	U(33),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS		=	U(34),
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR		=	U(35),
 	TEGRA_NVG_CHANNEL_UPDATE_GSC_LAST_INDEX
 } tegra_nvg_channel_update_gsc_gsc_enum_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_update_ccplex_gsc_channel_t {
-		uint32_t gsc_enum	: 16;
-		uint32_t reserved_31_16	: 16;
-		uint32_t reserved_63_32	: 32;
+		uint32_t gsc_enum	: U(16);
+		uint32_t reserved_31_16 : U(16);
+		uint32_t reserved_63_32 : U(32);
 	} bits;
 } nvg_update_ccplex_gsc_channel_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_security_config_channel_t {
-		uint32_t strict_checking_enabled : 1;
-		uint32_t strict_checking_locked	: 1;
-		uint32_t reserved_31_2		: 30;
-		uint32_t reserved_63_32		: 32;
+		uint32_t strict_checking_enabled	: U(1);
+		uint32_t strict_checking_locked		: U(1);
+		uint32_t reserved_31_2			: U(30);
+		uint32_t reserved_63_32			: U(32);
 	} bits;
 } nvg_security_config_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_shutdown_channel_t {
-		uint32_t reboot		: 1;
-		uint32_t reserved_31_1	: 31;
-		uint32_t reserved_63_32	: 32;
+		uint32_t reboot				: U(1);
+		uint32_t reserved_31_1			: U(31);
+		uint32_t reserved_63_32			: U(32);
 	} bits;
 } nvg_shutdown_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_debug_config_channel_t {
-		uint32_t enter_debug_state_on_mca : 1;
-		uint32_t reserved_31_1            : 31;
-		uint32_t reserved_63_32           : 32;
+		uint32_t enter_debug_state_on_mca	: U(1);
+		uint32_t reserved_31_1			: U(31);
+		uint32_t reserved_63_32			: U(32);
 	} bits;
 } nvg_debug_config_t;
 
 typedef union {
 	uint64_t flat;
 	struct nvg_hsm_error_ctrl_channel_t {
-		uint32_t uncorr			: 1;
-		uint32_t corr			: 1;
-		uint32_t reserved_31_2	: 30;
-		uint32_t reserved_63_32	: 32;
+		uint32_t uncorr				: U(1);
+		uint32_t corr				: U(1);
+		uint32_t reserved_31_2			: U(30);
+		uint32_t reserved_63_32			: U(32);
 	} bits;
 } nvg_hsm_error_ctrl_channel_t;
 
 extern nvg_debug_config_t nvg_debug_config;
 
-#endif
-
+#endif /* T194_NVG_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
index 1012cdf..ef740a1 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
@@ -15,8 +15,8 @@
 #include <t194_nvg.h>
 #include <tegra_private.h>
 
-#define	ID_AFR0_EL1_CACHE_OPS_SHIFT	12
-#define	ID_AFR0_EL1_CACHE_OPS_MASK	0xFU
+#define	ID_AFR0_EL1_CACHE_OPS_SHIFT	U(12)
+#define	ID_AFR0_EL1_CACHE_OPS_MASK	U(0xF)
 /*
  * Reports the major and minor version of this interface.
  *
@@ -209,7 +209,7 @@
 	uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET |
 				     STRICT_CHECKING_LOCKED_SET);
 
-	nvg_set_request_data(TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params);
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params);
 }
 #endif
 
@@ -221,7 +221,8 @@
 void nvg_system_reboot(void)
 {
 	/* issue command for reboot */
-	nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_REBOOT);
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN,
+			     (uint64_t)TEGRA_NVG_REBOOT);
 }
 
 /*
@@ -232,5 +233,6 @@
 void nvg_system_shutdown(void)
 {
 	/* issue command for shutdown */
-	nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_SHUTDOWN);
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN,
+			     (uint64_t)TEGRA_NVG_SHUTDOWN);
 }
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
index 3a2e959..a3b3389 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
@@ -15,6 +15,7 @@
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
+#include <se.h>
 #include <tegra_platform.h>
 
 #include "se_private.h"
@@ -54,7 +55,7 @@
 	 */
 	do {
 		val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS);
-		se_is_busy = !!(val & CTX_SAVE_AUTO_SE_BUSY);
+		se_is_busy = ((val & CTX_SAVE_AUTO_SE_BUSY) != 0U);
 
 		/* sleep until SE finishes */
 		if (se_is_busy) {
@@ -186,7 +187,8 @@
 	assert(tegra_bpmp_ipc_init() == 0);
 
 	/* Enable SE clock before SE context save */
-	tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+	ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+	assert(ret == 0);
 
 	/* save SE registers */
 	se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT);
@@ -201,7 +203,8 @@
 	}
 
 	/* Disable SE clock after SE context save */
-	tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+	ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+	assert(ret == 0);
 
 	return ret;
 }
@@ -211,11 +214,14 @@
  */
 void tegra_se_resume(void)
 {
+	int32_t ret = 0;
+
 	/* initialise communication channel with BPMP */
 	assert(tegra_bpmp_ipc_init() == 0);
 
 	/* Enable SE clock before SE context restore */
-	tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+	ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE);
+	assert(ret == 0);
 
 	/*
 	 * When TZ takes over after System Resume, TZ should first reconfigure
@@ -229,5 +235,6 @@
 	mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]);
 
 	/* Disable SE clock after SE context restore */
-	tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE);
+	ret = tegra_bpmp_ipc_disable_clock(TEGRA_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 a2c5d1c..577217b 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
@@ -74,12 +74,12 @@
 
 static inline uint32_t tegra_se_read_32(uint32_t offset)
 {
-	return mmio_read_32(TEGRA_SE0_BASE + offset);
+	return mmio_read_32((uint32_t)(TEGRA_SE0_BASE + offset));
 }
 
 static inline void tegra_se_write_32(uint32_t offset, uint32_t val)
 {
-	mmio_write_32(TEGRA_SE0_BASE + offset, val);
+	mmio_write_32((uint32_t)(TEGRA_SE0_BASE + offset), val);
 }
 
 #endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index cc8be12..144e418 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -44,14 +44,6 @@
 	uint32_t wake_time;
 } __aligned(CACHE_WRITEBACK_GRANULE) t19x_percpu_data[PLATFORM_CORE_COUNT];
 
-/*
- * tegra_fake_system_suspend acts as a boolean var controlling whether
- * we are going to take fake system suspend code or normal system suspend code
- * path. This variable is set inside the sip call handlers, when the kernel
- * requests an SIP call to set the suspend debug flags.
- */
-bool tegra_fake_system_suspend;
-
 int32_t tegra_soc_validate_power_state(uint32_t power_state,
 					psci_power_state_t *req_state)
 {
@@ -171,30 +163,27 @@
 			assert(ret == 0);
 		}
 
-		if (!tegra_fake_system_suspend) {
-
-			/* Prepare for system suspend */
-			mce_update_cstate_info(&sc7_cstate_info);
+		/* Prepare for system suspend */
+		mce_update_cstate_info(&sc7_cstate_info);
 
-			do {
-				val = (uint32_t)mce_command_handler(
-						(uint32_t)MCE_CMD_IS_SC7_ALLOWED,
-						(uint32_t)TEGRA_NVG_CORE_C7,
-						MCE_CORE_SLEEP_TIME_INFINITE,
-						0U);
-			} while (val == 0U);
-
-			/* Instruct the MCE to enter system suspend state */
-			ret = mce_command_handler(
-					(uint64_t)MCE_CMD_ENTER_CSTATE,
-					(uint64_t)TEGRA_NVG_CORE_C7,
+		do {
+			val = (uint32_t)mce_command_handler(
+					(uint32_t)MCE_CMD_IS_SC7_ALLOWED,
+					(uint32_t)TEGRA_NVG_CORE_C7,
 					MCE_CORE_SLEEP_TIME_INFINITE,
 					0U);
-			assert(ret == 0);
+		} while (val == 0U);
 
-			/* set system suspend state for house-keeping */
-			tegra194_set_system_suspend_entry();
-		}
+		/* Instruct the MCE to enter system suspend state */
+		ret = mce_command_handler(
+				(uint64_t)MCE_CMD_ENTER_CSTATE,
+				(uint64_t)TEGRA_NVG_CORE_C7,
+				MCE_CORE_SLEEP_TIME_INFINITE,
+				0U);
+		assert(ret == 0);
+
+		/* set system suspend state for house-keeping */
+		tegra194_set_system_suspend_entry();
 	} else {
 		; /* do nothing */
 	}
@@ -301,7 +290,6 @@
 	uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
 		TEGRA194_STATE_ID_MASK;
 	uint64_t val;
-	u_register_t ns_sctlr_el1;
 
 	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
 		/*
@@ -313,35 +301,16 @@
 		      tegra194_get_cpu_reset_handler_size();
 		memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
 		       (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
-
-		/*
-		 * In fake suspend mode, ensure that the loopback procedure
-		 * towards system suspend exit is started, instead of calling
-		 * WFI. This is done by disabling both MMU's of EL1 & El3
-		 * and calling tegra_secure_entrypoint().
-		 */
-		if (tegra_fake_system_suspend) {
-
-			/*
-			 * Disable EL1's MMU.
-			 */
-			ns_sctlr_el1 = read_sctlr_el1();
-			ns_sctlr_el1 &= (~((u_register_t)SCTLR_M_BIT));
-			write_sctlr_el1(ns_sctlr_el1);
-
-			/*
-			 * Disable MMU to power up the CPU in a "clean"
-			 * state
-			 */
-			disable_mmu_el3();
-			tegra_secure_entrypoint();
-			panic();
-		}
 	}
 
 	return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+	return PSCI_E_NOT_SUPPORTED;
+}
+
 int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
 {
 	uint64_t target_cpu = mpidr & MPIDR_CPU_MASK;
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
index 8873358..33694a1 100644
--- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.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
  */
@@ -18,12 +18,9 @@
 #include <tegra_platform.h>
 #include <stdbool.h>
 
-extern bool tegra_fake_system_suspend;
-
 /*******************************************************************************
  * Tegra194 SiP SMCs
  ******************************************************************************/
-#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND		0xC2FFFE03U
 
 /*******************************************************************************
  * This function is responsible for handling all T194 SiP calls
@@ -39,25 +36,11 @@
 {
 	int32_t ret = -ENOTSUP;
 
+	(void)smc_fid;
 	(void)x1;
 	(void)x4;
 	(void)cookie;
 	(void)flags;
 
-	if (smc_fid == TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND) {
-		/*
-		 * System suspend mode is set if the platform ATF is
-		 * running on VDK and there is a debug SIP call. This mode
-		 * ensures that the debug path is exercised, instead of
-		 * regular code path to suit the pre-silicon platform needs.
-		 * This includes replacing the call to WFI, with calls to
-		 * system suspend exit procedures.
-		 */
-		if (tegra_platform_is_virt_dev_kit()) {
-			tegra_fake_system_suspend = true;
-			ret = 0;
-		}
-	}
-
 	return ret;
 }
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 12241c2..4ef9558 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.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
  */
@@ -184,6 +185,12 @@
 	return target;
 }
 
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+	(void)cpu_state;
+	return PSCI_E_SUCCESS;
+}
+
 int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
 	u_register_t mpidr = read_mpidr();
@@ -412,6 +419,11 @@
 	return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+	return PSCI_E_NOT_SUPPORTED;
+}
+
 int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
@@ -567,5 +579,16 @@
 	/* Wait 1 ms to make sure clock source/device logic is stabilized. */
 	mdelay(1);
 
+	/*
+	 * Program the PMC in order to restart the system.
+	 */
+	tegra_pmc_system_reset();
+
 	return PSCI_E_SUCCESS;
 }
+
+__dead2 void tegra_soc_prepare_system_off(void)
+{
+	ERROR("Tegra System Off: operation not handled.\n");
+	panic();
+}
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index bfa8184..da1f1b3 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -141,6 +142,22 @@
 }
 
 /*******************************************************************************
+ * Return pointer to the BL31 params from previous bootloader
+ ******************************************************************************/
+struct tegra_bl31_params *plat_get_bl31_params(void)
+{
+	return NULL;
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 platform params from previous bootloader
+ ******************************************************************************/
+plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
+{
+	return NULL;
+}
+
+/*******************************************************************************
  * Handler for early platform setup
  ******************************************************************************/
 void plat_early_platform_setup(void)
@@ -168,6 +185,9 @@
 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 };
 
+/*******************************************************************************
+ * Handler for late platform setup
+ ******************************************************************************/
 void plat_late_platform_setup(void)
 {
 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index a11aef4..4f2db53 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -33,6 +34,7 @@
 				${COMMON_DIR}/drivers/bpmp/bpmp.c		\
 				${COMMON_DIR}/drivers/flowctrl/flowctrl.c	\
 				${COMMON_DIR}/drivers/memctrl/memctrl_v1.c	\
+				${COMMON_DIR}/drivers/pmc/pmc.c			\
 				${SOC_DIR}/plat_psci_handlers.c			\
 				${SOC_DIR}/plat_setup.c				\
 				${SOC_DIR}/drivers/se/security_engine.c		\
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index b95bf5a..bc10569 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -15,6 +15,7 @@
 MARCH32_DIRECTIVE 	:= 	-mcpu=cortex-a15
 $(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING))
 $(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER))
+$(eval $(call add_define,ARMV7_SUPPORTS_VFP))
 # Qemu expects a BL32 boot stage.
 NEED_BL32		:=	yes
 endif # ARMv7
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index 7158bfa..b87ac3f 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -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
  */
@@ -80,7 +80,6 @@
 #define DRAMINFO_BASE			0x2E00FFC0
 
 #define PLAT_SQ_MHU_BASE		0x45000000
-#define PLAT_MHUV2_BASE			0xFFFFFFFF /* MHUV2 is not supported */
 
 #define PLAT_SQ_SCP_COM_SHARED_MEM_BASE		0x45400000
 #define SCPI_CMD_GET_DRAMINFO			0x1
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index a3a9f43..45b2803 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -165,7 +165,7 @@
 	{
 		uint32_t result[4] = {0};
 
-		pm_get_callbackdata(result, sizeof(result));
+		pm_get_callbackdata(result, ARRAY_SIZE(result));
 		SMC_RET2(handle,
 			 (uint64_t)result[0] | ((uint64_t)result[1] << 32),
 			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 98dbe7d..3f4f069 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -423,7 +423,7 @@
 	{
 		uint32_t result[4] = {0};
 
-		pm_get_callbackdata(result, (sizeof(result)/sizeof(uint32_t)));
+		pm_get_callbackdata(result, ARRAY_SIZE(result));
 		SMC_RET2(handle,
 			 (uint64_t)result[0] | ((uint64_t)result[1] << 32),
 			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
diff --git a/tools/sptool/sptool.c b/tools/sptool/sptool.c
index a33b664..38baa2c 100644
--- a/tools/sptool/sptool.c
+++ b/tools/sptool/sptool.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdarg.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -16,25 +17,26 @@
 #define PAGE_SIZE		4096
 
 /*
- * Linked list of entries describing entries in the secure
- * partition package.
+ * Entry describing Secure Partition package.
  */
-struct sp_entry_info {
+struct sp_pkg_info {
 	/* Location of the files in the host's RAM. */
-	void *sp_data, *rd_data;
+	void *img_data, *pm_data;
 
 	/* Size of the files. */
-	uint64_t sp_size, rd_size;
+	uint32_t img_size, pm_size;
 
 	/* Location of the binary files inside the package output file */
-	uint64_t sp_offset, rd_offset;
-
-	struct sp_entry_info *next;
+	uint32_t img_offset, pm_offset;
 };
 
-static struct sp_entry_info *sp_info_head;
-
-static uint64_t sp_count;
+/*
+ * List of input provided by user
+ */
+struct arg_list {
+	char *usr_input;
+	struct arg_list *next;
+};
 
 /* Align an address to a power-of-two boundary. */
 static unsigned int align_to(unsigned int address, unsigned int boundary)
@@ -89,34 +91,69 @@
 	}
 }
 
-static void cleanup(void)
+/*
+ * Free SP package structure
+ */
+static void cleanup(struct sp_pkg_info *sp)
 {
-	struct sp_entry_info *sp = sp_info_head;
 
-	while (sp != NULL) {
-		struct sp_entry_info *next = sp->next;
-
-		if (sp->sp_data != NULL)
-			free(sp->sp_data);
+	if (sp != NULL) {
+		if (sp->img_data != NULL) {
+			free(sp->img_data);
+		}
 
-		if (sp->rd_data != NULL)
-			free(sp->rd_data);
+		if (sp->pm_data != NULL) {
+			free(sp->pm_data);
+		}
 
 		free(sp);
 
-		sp = next;
 	}
+}
 
-	sp_count = 0;
-	sp_info_head = NULL;
+/*
+ * Free argument list structure
+ */
+static void freelist(struct arg_list *head)
+{
+	struct arg_list *tmp;
+
+	while (head != NULL) {
+		tmp = head;
+		head = head->next;
+		free(tmp);
+	}
 }
 
 /*
+ * Append user inputs in argument list structure
+ */
+static void append_user_input(struct arg_list **head, char *args)
+{
+	struct arg_list *tmp = *head;
+
+	if (tmp == NULL) {
+		tmp = xzalloc(sizeof(struct arg_list),
+				"Failed to allocate arg_list struct");
+		tmp->usr_input = args;
+		*head = tmp;
+	} else {
+		while (tmp->next != NULL) {
+			tmp = tmp->next;
+		}
+		tmp->next = xzalloc(sizeof(struct arg_list),
+				"Failed to allocate arg_list struct");
+		tmp = tmp->next;
+		tmp->usr_input = args;
+	}
+}
+
+/*
  * Allocate a buffer big enough to store the content of the specified file and
  * load the file into it. Fill 'size' with the file size. Exit the program on
  * error.
  */
-static void load_file(const char *path, void **ptr, uint64_t *size)
+static void load_file(const char *path, void **ptr, uint32_t *size)
 {
 	FILE *f = fopen(path, "rb");
 	if (f == NULL) {
@@ -147,59 +184,40 @@
 	fclose(f);
 }
 
-static void load_sp_rd(char *path)
+/*
+ * Parse the string containing input payloads and fill in the
+ * SP Package data structure.
+ */
+static void load_sp_pm(char *path, struct sp_pkg_info **sp_out)
 {
+	struct sp_pkg_info *sp_pkg;
+
 	char *split_mark = strstr(path, ":");
 
 	*split_mark = '\0';
 
 	char *sp_path = path;
-	char *rd_path = split_mark + 1;
-
-	struct sp_entry_info *sp;
-
-	if (sp_info_head == NULL) {
-		sp_info_head = xzalloc(sizeof(struct sp_entry_info),
-			"Failed to allocate sp_entry_info struct");
-
-		sp = sp_info_head;
-	} else {
-		sp = sp_info_head;
-
-		while (sp->next != NULL) {
-			sp = sp->next;
-		}
-
-		sp->next = xzalloc(sizeof(struct sp_entry_info),
-			"Failed to allocate sp_entry_info struct");
+	char *pm_path = split_mark + 1;
 
-		sp = sp->next;
-	}
+	sp_pkg = xzalloc(sizeof(struct sp_pkg_info),
+		"Failed to allocate sp_pkg_info struct");
 
-	load_file(sp_path, &sp->sp_data, &sp->sp_size);
-	printf("Loaded image file %s (%lu bytes)\n", sp_path, sp->sp_size);
+	load_file(pm_path, &sp_pkg->pm_data, &sp_pkg->pm_size);
+	printf("\nLoaded SP Manifest file %s (%u bytes)\n", pm_path, sp_pkg->pm_size);
 
-	load_file(rd_path, &sp->rd_data, &sp->rd_size);
-	printf("Loaded RD file %s (%lu bytes)\n", rd_path, sp->rd_size);
+	load_file(sp_path, &sp_pkg->img_data, &sp_pkg->img_size);
+	printf("Loaded SP Image file %s (%u bytes)\n", sp_path, sp_pkg->img_size);
 
-	sp_count++;
+	*sp_out = sp_pkg;
 }
 
-static void output_write(const char *path)
+/*
+ * Write SP package data structure into output file.
+ */
+static void output_write(const char *path, struct sp_pkg_info *sp, bool header)
 {
-	struct sp_entry_info *sp;
-
-	if (sp_count == 0) {
-		fprintf(stderr, "error: At least one SP must be provided.\n");
-		exit(1);
-	}
-
-	/* The layout of the structs is specified in the header file sptool.h */
-
-	printf("Writing %lu partitions to output file.\n", sp_count);
-
-	unsigned int header_size = (sizeof(struct sp_pkg_header) * 8)
-				 + (sizeof(struct sp_pkg_entry) * 8 * sp_count);
+	struct sp_pkg_header sp_header_info;
+	unsigned int file_ptr = 0;
 
 	FILE *f = fopen(path, "wb");
 	if (f == NULL) {
@@ -207,70 +225,46 @@
 		exit(1);
 	}
 
-	unsigned int file_ptr = align_to(header_size, PAGE_SIZE);
-
-	/* First, save all partition images aligned to page boundaries */
-
-	sp = sp_info_head;
-
-	for (uint64_t i = 0; i < sp_count; i++) {
-		xfseek(f, file_ptr, SEEK_SET);
-
-		printf("Writing image %lu to offset 0x%x (0x%lx bytes)\n",
-		       i, file_ptr, sp->sp_size);
-
-		sp->sp_offset = file_ptr;
-		xfwrite(sp->sp_data, sp->sp_size, f);
-		file_ptr = align_to(file_ptr + sp->sp_size, PAGE_SIZE);
-		sp = sp->next;
+	/* Reserve Header size */
+	if (header) {
+		file_ptr = sizeof(struct sp_pkg_header);
 	}
 
-	/* Now, save resource description blobs aligned to 8 bytes */
+	/* Save partition manifest */
+	xfseek(f, file_ptr, SEEK_SET);
+	printf("Writing SP Manifest at offset 0x%x (%u bytes)\n",
+	       file_ptr, sp->pm_size);
 
-	sp = sp_info_head;
+	sp->pm_offset = file_ptr;
+	xfwrite(sp->pm_data, sp->pm_size, f);
 
-	for (uint64_t i = 0; i < sp_count; i++) {
-		xfseek(f, file_ptr, SEEK_SET);
+	/* Save partition image aligned to Page size */
+	file_ptr = align_to((sp->pm_offset + sp->pm_size), PAGE_SIZE);
+	xfseek(f, file_ptr, SEEK_SET);
+	printf("Writing SP Image at offset 0x%x (%u bytes)\n",
+	       file_ptr, sp->img_size);
 
-		printf("Writing RD blob %lu to offset 0x%x (0x%lx bytes)\n",
-		       i, file_ptr, sp->rd_size);
+	sp->img_offset = file_ptr;
+	xfwrite(sp->img_data, sp->img_size, f);
 
-		sp->rd_offset = file_ptr;
-		xfwrite(sp->rd_data, sp->rd_size, f);
-		file_ptr = align_to(file_ptr + sp->rd_size, 8);
-		sp = sp->next;
-	}
-
-	/* Finally, write header */
-
-	uint64_t version = 0x1;
-	uint64_t sp_num = sp_count;
-
-	xfseek(f, 0, SEEK_SET);
+	/* Finally, write header, if needed */
+	if (header) {
+		sp_header_info.magic = SECURE_PARTITION_MAGIC;
+		sp_header_info.version = 0x1;
+		sp_header_info.img_offset = sp->img_offset;
+		sp_header_info.img_size = sp->img_size;
+		sp_header_info.pm_offset = sp->pm_offset;
+		sp_header_info.pm_size = sp->pm_size;
 
-	xfwrite(&version, sizeof(uint64_t), f);
-	xfwrite(&sp_num, sizeof(uint64_t), f);
+		xfseek(f, 0, SEEK_SET);
 
-	sp = sp_info_head;
+		printf("Writing package header\n");
 
-	for (unsigned int i = 0; i < sp_count; i++) {
-
-		uint64_t sp_offset, sp_size, rd_offset, rd_size;
-
-		sp_offset = sp->sp_offset;
-		sp_size = align_to(sp->sp_size, PAGE_SIZE);
-		rd_offset = sp->rd_offset;
-		rd_size = sp->rd_size;
-
-		xfwrite(&sp_offset, sizeof(uint64_t), f);
-		xfwrite(&sp_size, sizeof(uint64_t), f);
-		xfwrite(&rd_offset, sizeof(uint64_t), f);
-		xfwrite(&rd_size, sizeof(uint64_t), f);
-
-		sp = sp->next;
+		xfwrite(&sp_header_info, sizeof(struct sp_pkg_header), f);
 	}
 
 	/* All information has been written now */
+	printf("\nsptool: Built Secure Partition blob %s\n", path);
 
 	fclose(f);
 }
@@ -286,30 +280,51 @@
 #endif
 	printf(" [<args>]\n\n");
 
-	printf("This tool takes as inputs several image binary files and the\n"
-	       "resource description blobs as input and generates a package\n"
-	       "file that contains them.\n\n");
+	printf("This tool takes as input set of image binary files and the\n"
+	       "partition manifest blobs as input and generates set of\n"
+	       "output package files\n"
+	       "Usage example: sptool -i sp1.bin:sp1.dtb -o sp1.pkg\n"
+	       "                      -i sp2.bin:sp2.dtb -o sp2.pkg ...\n\n");
 	printf("Commands supported:\n");
 	printf("  -o <path>            Set output file path.\n");
-	printf("  -i <sp_path:rd_path> Add Secure Partition image and Resource\n"
-	       "                       Description blob (specified in two paths\n"
+	printf("  -i <sp_path:pm_path> Add Secure Partition image and\n"
+	       "                       Manifest blob (specified in two paths\n"
 	       "                       separated by a colon).\n");
+	printf("  -n                   Generate package without header\n");
 	printf("  -h                   Show this message.\n");
 	exit(1);
 }
 
 int main(int argc, char *argv[])
 {
+	struct sp_pkg_info *sp_pkg = NULL;
+	struct arg_list *in_head = NULL;
+	struct arg_list *out_head = NULL;
+	struct arg_list *in_list = NULL;
+	struct arg_list *out_list = NULL;
+	unsigned int match_counter = 0;
+	bool need_header = true;
+
 	int ch;
-	const char *outname = NULL;
 
-	while ((ch = getopt(argc, argv, "hi:o:")) != -1) {
+	if (argc <= 1) {
+		fprintf(stderr, "error: File paths must be provided.\n\n");
+		usage();
+		return 1;
+	}
+
+	while ((ch = getopt(argc, argv, "hni:o:")) != -1) {
 		switch (ch) {
 		case 'i':
-			load_sp_rd(optarg);
+			append_user_input(&in_head, optarg);
+			match_counter++;
 			break;
 		case 'o':
-			outname = optarg;
+			append_user_input(&out_head, optarg);
+			match_counter--;
+			break;
+		case 'n':
+			need_header = false;
 			break;
 		case 'h':
 		default:
@@ -317,18 +332,29 @@
 		}
 	}
 
-	argc -= optind;
-	argv += optind;
-
-	if (outname == NULL) {
-		fprintf(stderr, "error: An output file path must be provided.\n\n");
+	if (match_counter) {
+		fprintf(stderr, "error: Input/Output count mismatch.\n\n");
+		freelist(in_head);
+		freelist(out_head);
 		usage();
 		return 1;
 	}
 
-	output_write(outname);
+	in_list = in_head;
+	out_list = out_head;
+	while (in_list != NULL) {
+		load_sp_pm(in_list->usr_input, &sp_pkg);
+		output_write(out_list->usr_input, sp_pkg, need_header);
+		in_list = in_list->next;
+		out_list = out_list->next;
+	}
+
+	argc -= optind;
+	argv += optind;
 
-	cleanup();
+	cleanup(sp_pkg);
+	freelist(in_head);
+	freelist(out_head);
 
 	return 0;
 }