Merge changes Ie7766e80,Ia74dbc36 into integration

* changes:
  plat: marvell: do not rely on argument passed via smc
  plat: marvell: sip: make sure that comphy init will use correct address
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index c295176..1734d7e 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -420,7 +420,7 @@
 	mov	x0, #SMC_UNK
 	str	x0, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
 #if CTX_INCLUDE_PAUTH_REGS
-	bl	pauth_context_save
+	bl	pauth_context_restore
 #endif
 	b	restore_gp_registers_eret
 
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 83b7860..4559903 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -16,6 +16,9 @@
     RAM (rwx): ORIGIN = BL32_BASE, LENGTH = BL32_LIMIT - BL32_BASE
 }
 
+#ifdef PLAT_SP_MIN_EXTRA_LD_SCRIPT
+#include <plat_sp_min.ld.S>
+#endif
 
 SECTIONS
 {
diff --git a/bl32/sp_min/sp_min_private.h b/bl32/sp_min/sp_min_private.h
index 6b5d792..628581a 100644
--- a/bl32/sp_min/sp_min_private.h
+++ b/bl32/sp_min/sp_min_private.h
@@ -7,7 +7,6 @@
 #ifndef SP_MIN_PRIVATE_H
 #define SP_MIN_PRIVATE_H
 
-void sp_min_warm_entrypoint(void);
 void sp_min_main(void);
 void sp_min_warm_boot(void);
 void sp_min_fiq(void);
diff --git a/docs/auth-framework.rst b/docs/auth-framework.rst
index 7e401b7..0142fbd 100644
--- a/docs/auth-framework.rst
+++ b/docs/auth-framework.rst
@@ -80,7 +80,7 @@
 A CoT is basically a sequence of authentication images which usually starts with
 a root of trust and culminates in a single data image. The following diagram
 illustrates how this maps to a CoT for the BL31 image described in the
-TBBR-Client specification.
+`TBBR-Client specification`_.
 
 ::
 
@@ -606,13 +606,13 @@
         unsigned int img_id;
         const struct auth_img_desc_s *parent;
         img_type_t img_type;
-        auth_method_desc_t img_auth_methods[AUTH_METHOD_NUM];
-        auth_param_desc_t authenticated_data[COT_MAX_VERIFIED_PARAMS];
+        const auth_method_desc_t *const img_auth_methods;
+        const auth_param_desc_t *const authenticated_data;
     } auth_img_desc_t;
 
-A CoT is defined as an array of ``auth_image_desc_t`` structures linked together
-by the ``parent`` field. Those nodes with no parent must be authenticated using
-the ROTPK stored in the platform.
+A CoT is defined as an array of pointers to ``auth_image_desc_t`` structures
+linked together by the ``parent`` field. Those nodes with no parent must be
+authenticated using the ROTPK stored in the platform.
 
 Implementation example
 ----------------------
@@ -625,15 +625,15 @@
 The TBBR CoT
 ~~~~~~~~~~~~
 
-The CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of an
-array of image descriptors and it is registered in the framework using the macro
-``REGISTER_COT(cot_desc)``, where 'cot_desc' must be the name of the array
-(passing a pointer or any other type of indirection will cause the registration
-process to fail).
+The CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of
+an array of pointers to image descriptors and it is registered in the framework
+using the macro ``REGISTER_COT(cot_desc)``, where 'cot_desc' must be the name
+of the array (passing a pointer or any other type of indirection will cause the
+registration process to fail).
 
-The number of images participating in the boot process depends on the CoT. There
-is, however, a minimum set of images that are mandatory in TF-A and thus all
-CoTs must present:
+The number of images participating in the boot process depends on the CoT.
+There is, however, a minimum set of images that are mandatory in TF-A and thus
+all CoTs must present:
 
 -  ``BL2``
 -  ``SCP_BL2`` (platform specific)
@@ -674,13 +674,15 @@
    is NULL, the authentication parameters will be obtained from the platform
    (i.e. the BL2 and Trusted Key certificates are signed with the ROT private
    key, whose public part is stored in the platform).
--  ``img_auth_methods``: this array defines the authentication methods that must
-   be checked to consider an image authenticated. Each method consists of a
-   type and a list of parameter descriptors. A parameter descriptor consists of
-   a type and a cookie which will point to specific information required to
-   extract that parameter from the image (i.e. if the parameter is stored in an
-   x509v3 extension, the cookie will point to the extension OID). Depending on
-   the method type, a different number of parameters must be specified.
+-  ``img_auth_methods``: this points to an array which defines the
+   authentication methods that must be checked to consider an image
+   authenticated. Each method consists of a type and a list of parameter
+   descriptors. A parameter descriptor consists of a type and a cookie which
+   will point to specific information required to extract that parameter from
+   the image (i.e. if the parameter is stored in an x509v3 extension, the
+   cookie will point to the extension OID). Depending on the method type, a
+   different number of parameters must be specified. This pointer should not be
+   NULL.
    Supported methods are:
 
    -  ``AUTH_METHOD_HASH``: the hash of the image must match the hash extracted
@@ -700,11 +702,11 @@
       -  ``alg``: the signature algorithm used (obtained from current image)
       -  ``data``: the data to be signed (obtained from current image)
 
--  ``authenticated_data``: this array indicates what authentication parameters
-   must be extracted from an image once it has been authenticated. Each
-   parameter consists of a parameter descriptor and the buffer address/size
-   to store the parameter. The CoT is responsible for allocating the required
-   memory to store the parameters.
+-  ``authenticated_data``: this array pointer indicates what authentication
+   parameters must be extracted from an image once it has been authenticated.
+   Each parameter consists of a parameter descriptor and the buffer
+   address/size to store the parameter. The CoT is responsible for allocating
+   the required memory to store the parameters. This pointer may be NULL.
 
 In the ``tbbr_cot.c`` file, a set of buffers are allocated to store the parameters
 extracted from the certificates. In the case of the TBBR CoT, these parameters
@@ -722,102 +724,130 @@
 
 .. code:: c
 
-    [TRUSTED_KEY_CERT_ID] = {
-        .img_id = TRUSTED_KEY_CERT_ID,
-        .img_type = IMG_CERT,
-        .parent = NULL,
-        .img_auth_methods = {
-            [0] = {
-                .type = AUTH_METHOD_SIG,
-                .param.sig = {
-                    .pk = &subject_pk,
-                    .sig = &sig,
-                    .alg = &sig_alg,
-                    .data = &raw_data,
-                }
-            }
-        },
-        .authenticated_data = {
-            [0] = {
-                .type_desc = &trusted_world_pk,
-                .data = {
-                    .ptr = (void *)trusted_world_pk_buf,
-                    .len = (unsigned int)PK_DER_LEN
-                }
+    static const auth_img_desc_t trusted_key_cert = {
+            .img_id = TRUSTED_KEY_CERT_ID,
+            .img_type = IMG_CERT,
+            .parent = NULL,
+            .img_auth_methods =  (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+                    [0] = {
+                            .type = AUTH_METHOD_SIG,
+                            .param.sig = {
+                                    .pk = &subject_pk,
+                                    .sig = &sig,
+                                    .alg = &sig_alg,
+                                    .data = &raw_data
+                            }
+                    },
+                    [1] = {
+                            .type = AUTH_METHOD_NV_CTR,
+                            .param.nv_ctr = {
+                                    .cert_nv_ctr = &trusted_nv_ctr,
+                                    .plat_nv_ctr = &trusted_nv_ctr
+                            }
+                    }
             },
-            [1] = {
-                .type_desc = &non_trusted_world_pk,
-                .data = {
-                    .ptr = (void *)non_trusted_world_pk_buf,
-                    .len = (unsigned int)PK_DER_LEN
-                }
-            }
-        }
-    },
-    [SOC_FW_KEY_CERT_ID] = {
-        .img_id = SOC_FW_KEY_CERT_ID,
-        .img_type = IMG_CERT,
-        .parent = &cot_desc[TRUSTED_KEY_CERT_ID],
-        .img_auth_methods = {
-            [0] = {
-                .type = AUTH_METHOD_SIG,
-                .param.sig = {
-                    .pk = &trusted_world_pk,
-                    .sig = &sig,
-                    .alg = &sig_alg,
-                    .data = &raw_data,
-                }
+            .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+                    [0] = {
+                            .type_desc = &trusted_world_pk,
+                            .data = {
+                                    .ptr = (void *)trusted_world_pk_buf,
+                                    .len = (unsigned int)PK_DER_LEN
+                            }
+                    },
+                    [1] = {
+                            .type_desc = &non_trusted_world_pk,
+                            .data = {
+                                    .ptr = (void *)non_trusted_world_pk_buf,
+                                    .len = (unsigned int)PK_DER_LEN
+                            }
+                    }
             }
-        },
-        .authenticated_data = {
-            [0] = {
-                .type_desc = &soc_fw_content_pk,
-                .data = {
-                    .ptr = (void *)content_pk_buf,
-                    .len = (unsigned int)PK_DER_LEN
-                }
-            }
-        }
-    },
-    [SOC_FW_CONTENT_CERT_ID] = {
-        .img_id = SOC_FW_CONTENT_CERT_ID,
-        .img_type = IMG_CERT,
-        .parent = &cot_desc[SOC_FW_KEY_CERT_ID],
-        .img_auth_methods = {
-            [0] = {
-                .type = AUTH_METHOD_SIG,
-                .param.sig = {
-                    .pk = &soc_fw_content_pk,
-                    .sig = &sig,
-                    .alg = &sig_alg,
-                    .data = &raw_data,
-                }
+    };
+    static const auth_img_desc_t soc_fw_key_cert = {
+            .img_id = SOC_FW_KEY_CERT_ID,
+            .img_type = IMG_CERT,
+            .parent = &trusted_key_cert,
+            .img_auth_methods =  (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+                    [0] = {
+                            .type = AUTH_METHOD_SIG,
+                            .param.sig = {
+                                    .pk = &trusted_world_pk,
+                                    .sig = &sig,
+                                    .alg = &sig_alg,
+                                    .data = &raw_data
+                            }
+                    },
+                    [1] = {
+                            .type = AUTH_METHOD_NV_CTR,
+                            .param.nv_ctr = {
+                                    .cert_nv_ctr = &trusted_nv_ctr,
+                                    .plat_nv_ctr = &trusted_nv_ctr
+                            }
+                    }
+            },
+            .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+                    [0] = {
+                            .type_desc = &soc_fw_content_pk,
+                            .data = {
+                                    .ptr = (void *)content_pk_buf,
+                                    .len = (unsigned int)PK_DER_LEN
+                            }
+                    }
             }
-        },
-        .authenticated_data = {
-            [0] = {
-                .type_desc = &soc_fw_hash,
-                .data = {
-                    .ptr = (void *)soc_fw_hash_buf,
-                    .len = (unsigned int)HASH_DER_LEN
-                }
+    };
+    static const auth_img_desc_t soc_fw_content_cert = {
+            .img_id = SOC_FW_CONTENT_CERT_ID,
+            .img_type = IMG_CERT,
+            .parent = &soc_fw_key_cert,
+            .img_auth_methods =  (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+                    [0] = {
+                            .type = AUTH_METHOD_SIG,
+                            .param.sig = {
+                                    .pk = &soc_fw_content_pk,
+                                    .sig = &sig,
+                                    .alg = &sig_alg,
+                                    .data = &raw_data
+                            }
+                    },
+                    [1] = {
+                            .type = AUTH_METHOD_NV_CTR,
+                            .param.nv_ctr = {
+                                    .cert_nv_ctr = &trusted_nv_ctr,
+                                    .plat_nv_ctr = &trusted_nv_ctr
+                            }
+                    }
+            },
+            .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+                    [0] = {
+                            .type_desc = &soc_fw_hash,
+                            .data = {
+                                    .ptr = (void *)soc_fw_hash_buf,
+                                    .len = (unsigned int)HASH_DER_LEN
+                            }
+                    },
+                    [1] = {
+                            .type_desc = &soc_fw_config_hash,
+                            .data = {
+                                    .ptr = (void *)soc_fw_config_hash_buf,
+                                    .len = (unsigned int)HASH_DER_LEN
+                            }
+                    }
             }
-        }
-    },
-    [BL31_IMAGE_ID] = {
-        .img_id = BL31_IMAGE_ID,
-        .img_type = IMG_RAW,
-        .parent = &cot_desc[SOC_FW_CONTENT_CERT_ID],
-        .img_auth_methods = {
-            [0] = {
-                .type = AUTH_METHOD_HASH,
-                .param.hash = {
-                    .data = &raw_data,
-                    .hash = &soc_fw_hash,
-                }
+    };
+    static const auth_img_desc_t bl31_image = {
+            .img_id = BL31_IMAGE_ID,
+            .img_type = IMG_RAW,
+            .parent = &soc_fw_content_cert,
+            .img_auth_methods =  (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+                    [0] = {
+                            .type = AUTH_METHOD_HASH,
+                            .param.hash = {
+                                    .data = &raw_data,
+                                    .hash = &soc_fw_hash
+                            }
+                    }
             }
-        }
-    }
+    };
 
 The **Trusted Key certificate** is signed with the ROT private key and contains
 the Trusted World public key and the Non-Trusted World public key as x509v3
@@ -935,7 +965,8 @@
 
 --------------
 
-*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
 
 .. _Trusted Board Boot: ./trusted-board-boot.rst
 .. _Platform Porting Guide: ./porting-guide.rst
+.. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
diff --git a/docs/change-log.rst b/docs/change-log.rst
index d652ff6..1aca22b 100644
--- a/docs/change-log.rst
+++ b/docs/change-log.rst
@@ -1,14 +1,16 @@
+Trusted Firmware-A Release Notes
+================================
 
-.. section-numbering::
-    :suffix: .
+This document contains a summary of the new features, changes, fixes and known
+issues in each release of Trusted Firmware-A.
 
 .. contents::
 
-Trusted Firmware-A - version 2.1
-================================
+Version 2.1
+-----------
 
 New Features
-------------
+^^^^^^^^^^^^
 
 - Architecture
    - Support for ARMv8.3 pointer authentication in the normal and secure worlds
@@ -198,7 +200,7 @@
 
 
 Changed
--------
+^^^^^^^
 
 - Build System
    - Warning levels are now selectable with ``W=<1,2,3>``
@@ -311,7 +313,7 @@
 
 
 Resolved Issues
----------------
+^^^^^^^^^^^^^^^
 
 - Architecture
    - Incorrect check for SSBS feature detection
@@ -401,7 +403,7 @@
 
 
 Deprecations
-------------
+^^^^^^^^^^^^
 
 - Common Code
    - ``plat_crash_console_init`` function
@@ -424,7 +426,7 @@
 
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 - Build System Issues
    - dtb: DTB creation not supported when building on a Windows host.
@@ -448,11 +450,11 @@
 
    - mediatek/mt6795: This platform does not build in this release
 
-Trusted Firmware-A - version 2.0
-================================
+Version 2.0
+-----------
 
 New Features
-------------
+^^^^^^^^^^^^
 
 -  Removal of a number of deprecated APIs
 
@@ -469,12 +471,12 @@
    -  This release is otherwise unchanged from 1.6 release
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  No issues known at 1.6 release resolved in 2.0 release
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 -  DTB creation not supported when building on a Windows host. This step in the
    build process is skipped when running on a Windows host. Known issue from
@@ -487,11 +489,11 @@
    confirmed to be working after the removal of the deprecated interfaces
    although they do build.
 
-Trusted Firmware-A - version 1.6
-================================
+Version 1.6
+-----------
 
 New Features
-------------
+^^^^^^^^^^^^
 
 -  Addressing Speculation Security Vulnerabilities
 
@@ -760,22 +762,22 @@
    -  STMicroelectronics STM32MP1 Platform
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  No issues known at 1.5 release resolved in 1.6 release
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 -  DTB creation not supported when building on a Windows host. This step in the
    build process is skipped when running on a Windows host. Known issue from
    1.5 version.
 
-Trusted Firmware-A - version 1.5
-================================
+Version 1.5
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Added new firmware support to enable RAS (Reliability, Availability, and
    Serviceability) functionality.
@@ -1044,7 +1046,7 @@
       facilitate transfer by DMA.
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  TF-A can be built with optimisations disabled (-O0).
 
@@ -1052,16 +1054,16 @@
    running TF-A in AArch32 execution mode (resolving `tf-issue#501`_).
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 -  DTB creation not supported when building on a Windows host. This step in the
    build process is skipped when running on a Windows host.
 
-Trusted Firmware-A - version 1.4
-================================
+Version 1.4
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Enabled support for platforms with hardware assisted coherency.
 
@@ -1318,7 +1320,7 @@
    pre-empted SMC during PSCI power management requests.
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  TF-A can be built with the latest mbed TLS version (v2.4.2). The earlier
    version 2.3.0 cannot be used due to build warnings that the TF-A build
@@ -1332,7 +1334,7 @@
    shutdown request using the PSCI SYSTEM_OFF API.
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 -  Building TF-A with compiler optimisations disabled (-O0) fails.
 
@@ -1346,12 +1348,12 @@
    platform, please use GCC compiler version of at least 5.0. See `PR#1002`_ for
    more details.
 
-Trusted Firmware-A - version 1.3
-================================
+Version 1.3
+-----------
 
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Added support for running TF-A in AArch32 execution state.
 
@@ -1552,10 +1554,10 @@
       interrupts and then restoring after resume.
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Known issues
-------------
+^^^^^^^^^^^^
 
 -  The version of the AEMv8 Base FVP used in this release resets the model
    instead of terminating its execution in response to a shutdown request using
@@ -1569,11 +1571,11 @@
 
 -  TBBR is not currently supported when running TF-A in AArch32 state.
 
-Trusted Firmware-A - version 1.2
-================================
+Version 1.2
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  The Trusted Board Boot implementation on Arm platforms now conforms to the
    mandatory requirements of the TBBR specification.
@@ -1690,7 +1692,7 @@
    common driver. The standalone CCI-400 driver has been deprecated.
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  The Trusted Board Boot implementation has been redesigned to provide greater
    modularity and scalability. See the `Authentication Framework`_ document.
@@ -1705,7 +1707,7 @@
 -  GICv3 is now fully supported and stable.
 
 Known issues
-------------
+^^^^^^^^^^^^
 
 -  The version of the AEMv8 Base FVP used in this release resets the model
    instead of terminating its execution in response to a shutdown request using
@@ -1721,11 +1723,11 @@
 
 -  Building TF-A with compiler optimisations disabled (``-O0``) fails.
 
-Trusted Firmware-A - version 1.1
-================================
+Version 1.1
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  A prototype implementation of Trusted Board Boot has been added. Boot
    loader images are verified by BL1 and BL2 during the cold boot path. BL1 and
@@ -1828,7 +1830,7 @@
    added. Details of using it with TF-A can be found in `OP-TEE Dispatcher`_
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  The Juno port has been aligned with the FVP port as follows.
 
@@ -1855,7 +1857,7 @@
    the Cortex-A57-A53 Base FVPs.
 
 Known issues
-------------
+^^^^^^^^^^^^
 
 -  The Trusted Board Boot implementation is a prototype. There are issues with
    the modularity and scalability of the design. Support for a Trusted
@@ -1883,11 +1885,11 @@
 
 -  The Juno-specific firmware design documentation is incomplete.
 
-Trusted Firmware-A - version 1.0
-================================
+Version 1.0
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  It is now possible to map higher physical addresses using non-flat virtual
    to physical address mappings in the MMU setup.
@@ -2009,7 +2011,7 @@
    Juno platform.
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  Removed the concept of top/bottom image loading. The image loader now
    automatically detects the position of the image inside the current memory
@@ -2023,7 +2025,7 @@
    resolved. This TF-A version uses Linaro toolchain 14.07 (based on GCC 4.9).
 
 Known issues
-------------
+^^^^^^^^^^^^
 
 -  GICv3 support is experimental. The Linux kernel patches to support this are
    not widely available. There are known issues with GICv3 initialization in
@@ -2063,11 +2065,11 @@
 
    A similar change can be made to the other Cortex-A57-A53 Base FVP variants.
 
-Trusted Firmware-A - version 0.4
-================================
+Version 0.4
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Makefile improvements:
 
@@ -2145,7 +2147,7 @@
    interrupt handling during TSP processing.
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  Now support use of the model parameter ``-C bp.secure_memory=1`` in the Base
    FVPs (see **New features**).
@@ -2164,7 +2166,7 @@
    checking.
 
 Known issues
-------------
+^^^^^^^^^^^^
 
 -  GICv3 support is experimental. The Linux kernel patches to support this are
    not widely available. There are known issues with GICv3 initialization in
@@ -2193,11 +2195,11 @@
 -  The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
    its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
 
-Trusted Firmware-A - version 0.3
-================================
+Version 0.3
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Support for Foundation FVP Version 2.0 added.
    The documented UEFI configuration disables some devices that are unavailable
@@ -2274,7 +2276,7 @@
    NOTE: The TSP/TSPD is not built by default.
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  Support has been added for switching context between secure and normal
    worlds in EL3.
@@ -2299,7 +2301,7 @@
    in this release, for both Foundation and Base FVPs.
 
 Known issues
-------------
+^^^^^^^^^^^^
 
 The following is a list of issues which are expected to be fixed in the future
 releases of TF-A.
@@ -2347,11 +2349,11 @@
 -  The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
    its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
 
-Trusted Firmware-A - version 0.2
-================================
+Version 0.2
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  First source release.
 
@@ -2359,13 +2361,13 @@
    by default since there are known issues (see below).
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  The "psci" nodes in the FDTs provided in this release now fully comply
    with the recommendations made in the PSCI specification.
 
 Known issues
-------------
+^^^^^^^^^^^^
 
 The following is a list of issues which are expected to be fixed in the future
 releases of TF-A.
@@ -2427,5 +2429,3 @@
 .. _OP-TEE Dispatcher: optee-dispatcher.rst
 .. _tf-issue#501: https://github.com/ARM-software/tf-issues/issues/501
 .. _PR#1002: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193
-.. _mbed TLS releases: https://tls.mbed.org/tech-updates/releases
-.. _Firmware Design: firmware-design.rst
diff --git a/docs/cpu-specific-build-macros.rst b/docs/cpu-specific-build-macros.rst
index ca3366d..e1c89bf 100644
--- a/docs/cpu-specific-build-macros.rst
+++ b/docs/cpu-specific-build-macros.rst
@@ -71,6 +71,11 @@
 The value of the build flags is 0 by default, that is, disabled. A value of 1
 will enable it.
 
+For Cortex-A9, the following errata build flags are defined :
+
+-  ``ERRATA_A9_794073``: This applies errata 794073 workaround to Cortex-A9
+   CPU. This needs to be enabled for all revisions of the CPU.
+
 For Cortex-A15, the following errata build flags are defined :
 
 -  ``ERRATA_A15_816470``: This applies errata 816470 workaround to Cortex-A15
@@ -87,6 +92,11 @@
 -  ``ERRATA_A17_852423``: This applies errata 852423 workaround to Cortex-A17
    CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
 
+For Cortex-A35, the following errata build flags are defined :
+
+-  ``ERRATA_A35_855472``: This applies errata 855472 workaround to Cortex-A35
+   CPUs. This needs to be enabled only for revision r0p0 of Cortex-A35.
+
 For Cortex-A53, the following errata build flags are defined :
 
 -  ``ERRATA_A53_819472``: This applies errata 819472 workaround to all
@@ -223,6 +233,11 @@
 
 For DSU errata, the following build flags are defined:
 
+-  ``ERRATA_DSU_798953``: This applies errata 798953 workaround for the
+   affected DSU configurations. This errata applies only for those DSUs that
+   revision is r0p0 (on r0p1 it is fixed). However, please note that this
+   workaround results in increased DSU power consumption on idle.
+
 -  ``ERRATA_DSU_936184``: This applies errata 936184 workaround for the
    affected DSU configurations. This errata applies only for those DSUs that
    contain the ACP interface **and** the DSU revision is older than r2p0 (on
@@ -260,7 +275,7 @@
 
 --------------
 
-*Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.*
 
 .. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
 .. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index 66b16fa..8384c9c 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -2655,8 +2655,7 @@
 References
 ----------
 
-.. [#] Trusted Board Boot Requirements CLIENT PDD (Arm DEN0006C-1). Available
-       under NDA through your Arm account representative.
+.. [#] `Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D)`_
 .. [#] `Power State Coordination Interface PDD`_
 .. [#] `SMC Calling Convention PDD`_
 .. [#] `TF-A Interrupt Management Design guide`_.
@@ -2684,5 +2683,6 @@
 .. _Xlat_tables design: xlat-tables-lib-v2-design.rst
 .. _Exception Handling Framework: exception-handling.rst
 .. _ROMLIB Design: romlib-design.rst
+.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
 
 .. |Image 1| image:: diagrams/rt-svc-descs-layout.png?raw=true
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
new file mode 100644
index 0000000..e88706b
--- /dev/null
+++ b/docs/plat/rockchip.rst
@@ -0,0 +1,54 @@
+Trusted Firmware-A for Rockchip SoCs
+====================================
+
+Trusted Firmware-A supports a number of Rockchip ARM SoCs from both
+AARCH32 and AARCH64 fields.
+
+This includes right now:
+-  rk3288: Quad-Core Cortex-A17 (past A12)
+-  rk3328: Quad-Core Cortex-A53
+-  rk3368: Octa-Core Cortex-A53
+-  rk3399: Hexa-Core Cortex-A53/A72
+
+
+Boot Sequence
+=============
+
+For AARCH32:
+    Bootrom --> BL1/BL2 --> BL32 --> BL33 --> Linux kernel
+
+For AARCH64:
+    Bootrom --> BL1/BL2 --> BL31 --> BL33 --> Linux kernel
+
+BL1/2 and BL33 can currently be supplied from either:
+-  Coreboot + Depthcharge
+-  U-Boot - either separately as TPL+SPL or only SPL
+
+
+How to build
+============
+
+Rockchip SoCs expect TF-A's BL31 (AARCH64) or BL32 (AARCH32) to get
+integrated with other boot software like U-Boot or Coreboot, so only
+these images need to get build from the TF-A repository.
+
+For AARCH64 architectures the build command looks like
+
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399 bl32
+
+while AARCH32 needs a slightly different command
+
+    make ARCH=aarch32 CROSS_COMPILE=arm-linux-gnueabihf- PLAT=rk3288 AARCH32_SP=sp_min bl32
+
+Both need replacing the PLAT argument with the platform from above you
+want to build for and the CROSS_COMPILE argument with you cross-
+compilation toolchain.
+
+
+How to deploy
+=============
+
+Both upstream U-Boot and Coreboot projects contain instructions on where
+to put the built images during their respective build process.
+So after successfully building TF-A just follow their build instructions
+to continue.
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index bfae9cc..75dfa3f 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -69,11 +69,15 @@
 
 ROM code -> BL2 (compiled with BL2_AT_EL3) -> BL32 (SP_min) -> BL33 (U-Boot)
 
+or if Op-TEE is used:
+
+ROM code -> BL2 (compiled with BL2_AT_EL3) -> OP-TEE -> BL33 (U-Boot)
+
 
 Build Instructions
 ------------------
 
-To build:
+To build with SP_min:
 
 .. code:: bash
 
@@ -83,6 +87,12 @@
     make DEVICE_TREE=stm32mp157c-ev1 all
     ./tools/mkimage -T stm32image -a 0xC0100000 -e 0xC0100000 -d u-boot.bin u-boot.stm32
 
+To build TF-A with with Op-TEE support:
+
+.. code:: bash
+
+    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee
+
 The following build options are supported:
 
 - ``ENABLE_STACK_PROTECTOR``: To enable the stack protection.
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 3ea86b0..6244a63 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -841,6 +841,33 @@
 represents the power domain topology and how this relates to the linear CPU
 index, please refer `Power Domain Topology Design`_.
 
+Function : plat_get_mbedtls_heap() [when TRUSTED_BOARD_BOOT == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Arguments : void **heap_addr, size_t *heap_size
+    Return    : int
+
+This function is invoked during Mbed TLS library initialisation to get a heap,
+by means of a starting address and a size. This heap will then be used
+internally by the Mbed TLS library. Hence, each BL stage that utilises Mbed TLS
+must be able to provide a heap to it.
+
+A helper function can be found in `drivers/auth/mbedtls/mbedtls_common.c` in
+which a heap is statically reserved during compile time inside every image
+(i.e. every BL stage) that utilises Mbed TLS. In this default implementation,
+the function simply returns the address and size of this "pre-allocated" heap.
+For a platform to use this default implementation, only a call to the helper
+from inside plat_get_mbedtls_heap() body is enough and nothing else is needed.
+
+However, by writting their own implementation, platforms have the potential to
+optimise memory usage. For example, on some Arm platforms, the Mbed TLS heap is
+shared between BL1 and BL2 stages and, thus, the necessary space is not reserved
+twice.
+
+On success the function should return 0 and a negative error code otherwise.
+
 Common optional modifications
 -----------------------------
 
@@ -1054,29 +1081,6 @@
 the log output. The implementation should be robust to future changes that
 increase the number of log levels.
 
-Function : plat_get_mbedtls_heap()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Arguments : void **heap_addr, size_t *heap_size
-    Return    : int
-
-This function is invoked during Mbed TLS library initialisation to get
-a heap, by means of a starting address and a size. This heap will then be used
-internally by the Mbed TLS library. The heap is requested from the current BL
-stage, i.e. the current BL image inside which Mbed TLS is used.
-
-In the default implementation a heap is statically allocated inside every image
-(i.e. every BL stage) that utilises Mbed TLS. So, in this case, the function
-simply returns the address and size of this "pre-allocated" heap. However, by
-overriding the default implementation, platforms have the potential to optimise
-memory usage. For example, on some Arm platforms, the Mbed TLS heap is shared
-between BL1 and BL2 stages and, thus, the necessary space is not reserved
-twice.
-
-On success the function should return 0 and a negative error code otherwise.
-
 Modifications specific to a Boot Loader stage
 ---------------------------------------------
 
diff --git a/docs/trusted-board-boot.rst b/docs/trusted-board-boot.rst
index 1ca6fef..3ba9636 100644
--- a/docs/trusted-board-boot.rst
+++ b/docs/trusted-board-boot.rst
@@ -12,9 +12,9 @@
 normal world bootloader. It does this by establishing a Chain of Trust using
 Public-Key-Cryptography Standards (PKCS).
 
-This document describes the design of Trusted Firmware-A (TF-A) TBB, which is
-an implementation of the Trusted Board Boot Requirements (TBBR) specification,
-Arm DEN0006C-1. It should be used in conjunction with the `Firmware Update`_
+This document describes the design of Trusted Firmware-A (TF-A) TBB, which is an
+implementation of the `Trusted Board Boot Requirements (TBBR)`_ specification,
+Arm DEN0006D. It should be used in conjunction with the `Firmware Update`_
 design document, which implements a specific aspect of the TBBR.
 
 Chain of Trust
@@ -206,7 +206,7 @@
 
 The authentication framework included in TF-A provides support to implement
 the desired trusted boot sequence. Arm platforms use this framework to
-implement the boot requirements specified in the TBBR-client document.
+implement the boot requirements specified in the `TBBR-client`_ document.
 
 More information about the authentication framework can be found in the
 `Auth Framework`_ document.
@@ -230,9 +230,11 @@
 
 --------------
 
-*Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
 
 .. _Firmware Update: firmware-update.rst
 .. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt
 .. _User Guide: user-guide.rst
 .. _Auth Framework: auth-framework.rst
+.. _TBBR-client: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _Trusted Board Boot Requirements (TBBR): `TBBR-client`_
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 769ad45..b9f0871 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -1219,11 +1219,13 @@
     make PLAT=<platform> [DEBUG=1] [V=1] certtool
 
 For platforms that require their own IDs in certificate files, the generic
-'cert_create' tool can be built with the following command:
+'cert_create' tool can be built with the following command. Note that the target
+platform must define its IDs within a ``platform_oid.h`` header file for the
+build to succeed.
 
 ::
 
-    make USE_TBBR_DEFS=0 [DEBUG=1] [V=1] certtool
+    make PLAT=<platform> USE_TBBR_DEFS=0 [DEBUG=1] [V=1] certtool
 
 ``DEBUG=1`` builds the tool in debug mode. ``V=1`` makes the build process more
 verbose. The following command should be used to obtain help about the tool:
@@ -1669,6 +1671,8 @@
 -  ``FVP_Base_Cortex-A73x4``
 -  ``FVP_Base_Cortex-A75x4``
 -  ``FVP_Base_Cortex-A76x4``
+-  ``FVP_Base_Cortex-A76AEx4`` (Tested with internal model)
+-  ``FVP_Base_Cortex-A76AEx8`` (Tested with internal model)
 -  ``FVP_Base_Neoverse-N1x4`` (Tested with internal model)
 -  ``FVP_Base_Deimos``
 -  ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
diff --git a/drivers/arm/sbsa/sbsa.c b/drivers/arm/sbsa/sbsa.c
new file mode 100644
index 0000000..6f00a60
--- /dev/null
+++ b/drivers/arm/sbsa/sbsa.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
+#include <lib/mmio.h>
+#include <stdint_.h>
+#include <assert.h>
+
+void sbsa_watchdog_offset_reg_write(uintptr_t base, uint64_t value)
+{
+	assert((value >> SBSA_WDOG_WOR_WIDTH) == 0);
+	mmio_write_32(base + SBSA_WDOG_WOR_LOW_OFFSET,
+		 ((uint32_t)value & UINT32_MAX));
+	mmio_write_32(base + SBSA_WDOG_WOR_HIGH_OFFSET, (uint32_t)(value >> 32));
+}
+
+/*
+ * Start the watchdog timer at base address "base" for a
+ * period of "ms" milliseconds.The watchdog has to be
+ * refreshed within this time period.
+ */
+void sbsa_wdog_start(uintptr_t base, uint64_t ms)
+{
+	uint64_t counter_freq;
+	uint64_t offset_reg_value;
+
+	counter_freq = (uint64_t)plat_get_syscnt_freq2();
+	offset_reg_value = ms * counter_freq / 1000;
+
+	sbsa_watchdog_offset_reg_write(base, offset_reg_value);
+	mmio_write_32(base + SBSA_WDOG_WCS_OFFSET, SBSA_WDOG_WCS_EN);
+}
+
+/* Stop the watchdog */
+void sbsa_wdog_stop(uintptr_t base)
+{
+	mmio_write_32(base + SBSA_WDOG_WCS_OFFSET, (0x0));
+}
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 97e1220..01f8f29 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -30,6 +30,10 @@
 
 #pragma weak plat_set_nv_ctr2
 
+/* Pointer to CoT */
+extern const auth_img_desc_t **const cot_desc_ptr;
+extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
+
 static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
 		const auth_param_type_desc_t *b)
 {
@@ -49,6 +53,9 @@
 {
 	int i;
 
+	if (img_desc->authenticated_data == NULL)
+		return 1;
+
 	for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) {
 		if (0 == cmp_auth_param_type_desc(param_type_desc,
 				img_desc->authenticated_data[i].type_desc)) {
@@ -300,7 +307,7 @@
 	assert(parent_id != NULL);
 
 	/* Get the image descriptor */
-	img_desc = &cot_desc_ptr[img_id];
+	img_desc = cot_desc_ptr[img_id];
 
 	/* Check if the image has no parent (ROT) */
 	if (img_desc->parent == NULL) {
@@ -349,7 +356,7 @@
 	int rc, i;
 
 	/* Get the image descriptor from the chain of trust */
-	img_desc = &cot_desc_ptr[img_id];
+	img_desc = cot_desc_ptr[img_id];
 
 	/* Ask the parser to check the image integrity */
 	rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len);
@@ -357,6 +364,8 @@
 
 	/* Authenticate the image using the methods indicated in the image
 	 * descriptor. */
+	if (img_desc->img_auth_methods == NULL)
+		return 1;
 	for (i = 0 ; i < AUTH_METHOD_NUM ; i++) {
 		auth_method = &img_desc->img_auth_methods[i];
 		switch (auth_method->type) {
@@ -385,25 +394,27 @@
 
 	/* Extract the parameters indicated in the image descriptor to
 	 * authenticate the children images. */
-	for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) {
-		if (img_desc->authenticated_data[i].type_desc == NULL) {
-			continue;
-		}
+	if (img_desc->authenticated_data != NULL) {
+		for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) {
+			if (img_desc->authenticated_data[i].type_desc == NULL) {
+				continue;
+			}
 
-		/* Get the parameter from the image parser module */
-		rc = img_parser_get_auth_param(img_desc->img_type,
-				img_desc->authenticated_data[i].type_desc,
-				img_ptr, img_len, &param_ptr, &param_len);
-		return_if_error(rc);
+			/* Get the parameter from the image parser module */
+			rc = img_parser_get_auth_param(img_desc->img_type,
+					img_desc->authenticated_data[i].type_desc,
+					img_ptr, img_len, &param_ptr, &param_len);
+			return_if_error(rc);
 
-		/* Check parameter size */
-		if (param_len > img_desc->authenticated_data[i].data.len) {
-			return 1;
-		}
+			/* Check parameter size */
+			if (param_len > img_desc->authenticated_data[i].data.len) {
+				return 1;
+			}
 
-		/* Copy the parameter for later use */
-		memcpy((void *)img_desc->authenticated_data[i].data.ptr,
-				(void *)param_ptr, param_len);
+			/* Copy the parameter for later use */
+			memcpy((void *)img_desc->authenticated_data[i].data.ptr,
+					(void *)param_ptr, param_len);
+		}
 	}
 
 	/* Mark image as authenticated */
diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c
index cdb5042..4a8efae 100644
--- a/drivers/auth/mbedtls/mbedtls_common.c
+++ b/drivers/auth/mbedtls/mbedtls_common.c
@@ -16,8 +16,6 @@
 #include <drivers/auth/mbedtls/mbedtls_config.h>
 #include <plat/common/platform.h>
 
-#pragma weak plat_get_mbedtls_heap
-
 static void cleanup(void)
 {
 	ERROR("EXIT from BL2\n");
@@ -58,10 +56,10 @@
 }
 
 /*
- * The following default implementation of the function simply returns the
- * by default allocated heap.
+ * The following helper function simply returns the default allocated heap.
+ * It can be used by platforms for their plat_get_mbedtls_heap() implementation.
  */
-int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size)
 {
 	static unsigned char heap[TF_MBEDTLS_HEAP_SIZE];
 
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c
index ec14a18..da3631b 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,29 +27,31 @@
  * extracted from the certificates. In this case, because of the way the CoT is
  * established, we can reuse some of the buffers on different stages
  */
+
 static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
 static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char hw_config_hash_buf[HASH_DER_LEN];
 static unsigned char scp_fw_hash_buf[HASH_DER_LEN];
+static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
+
+#ifdef IMAGE_BL2
 static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN];
-static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
 static unsigned char trusted_world_pk_buf[PK_DER_LEN];
 static unsigned char non_trusted_world_pk_buf[PK_DER_LEN];
 static unsigned char content_pk_buf[PK_DER_LEN];
 static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
+#endif
 
 /*
  * Parameter type descriptors
  */
 static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
-static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
 
 static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, 0);
@@ -60,11 +62,29 @@
 static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_RAW_DATA, 0);
 
+
+static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
+static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
+#ifdef IMAGE_BL1
+static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, FWU_HASH_OID);
+#endif /* IMAGE_BL1 */
+
+#ifdef IMAGE_BL2
+static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
 static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
 static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID);
-
 static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID);
 static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC(
@@ -73,13 +93,6 @@
 		AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID);
 static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID);
-
-static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
-static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
 static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, SCP_FW_HASH_OID);
 static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
@@ -98,678 +111,716 @@
 		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
 static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, FWU_HASH_OID);
 
-/*
- * TBBR Chain of trust definition
- */
-static const auth_img_desc_t cot_desc[] = {
+#endif /* IMAGE_BL2 */
+
+
 	/*
 	 * BL2
 	 */
-	[TRUSTED_BOOT_FW_CERT_ID] = {
-		.img_id = TRUSTED_BOOT_FW_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = NULL,
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &subject_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+static const auth_img_desc_t trusted_boot_fw_cert = {
+	.img_id = TRUSTED_BOOT_FW_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &tb_fw_hash,
-				.data = {
-					.ptr = (void *)tb_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &tb_fw_config_hash,
-				.data = {
-					.ptr = (void *)tb_fw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[2] = {
-				.type_desc = &hw_config_hash,
-				.data = {
-					.ptr = (void *)hw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[BL2_IMAGE_ID] = {
-		.img_id = BL2_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_BOOT_FW_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tb_fw_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tb_fw_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tb_fw_config_hash,
+			.data = {
+				.ptr = (void *)tb_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &hw_config_hash,
+			.data = {
+				.ptr = (void *)hw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	/* HW Config */
-	[HW_CONFIG_ID] = {
-		.img_id = HW_CONFIG_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_BOOT_FW_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &hw_config_hash,
-				}
+	}
+	};
+#ifdef IMAGE_BL1
+static const auth_img_desc_t bl2_image = {
+	.img_id = BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_hash
 			}
 		}
-	},
-	/* TB FW Config */
-	[TB_FW_CONFIG_ID] = {
-		.img_id = TB_FW_CONFIG_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_BOOT_FW_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tb_fw_config_hash,
-				}
+	}
+};
+#endif /* IMAGE_BL1 */
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
 			}
 		}
-	},
-	/*
-	 * Trusted key certificate
-	 */
-	[TRUSTED_KEY_CERT_ID] = {
-		.img_id = TRUSTED_KEY_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = NULL,
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &subject_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	}
+};
+/* TB FW Config */
+#ifdef IMAGE_BL1
+static const auth_img_desc_t tb_fw_config = {
+	.img_id = TB_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_config_hash
+			}
+		}
+	}
+};
+#endif /* IMAGE_BL1 */
+#ifdef IMAGE_BL2
+/*
+ * Trusted key certificate
+ */
+static const auth_img_desc_t trusted_key_cert = {
+	.img_id = TRUSTED_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &trusted_world_pk,
-				.data = {
-					.ptr = (void *)trusted_world_pk_buf,
-					.len = (unsigned int)PK_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &non_trusted_world_pk,
-				.data = {
-					.ptr = (void *)non_trusted_world_pk_buf,
-					.len = (unsigned int)PK_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	/*
-	 * SCP Firmware
-	 */
-	[SCP_FW_KEY_CERT_ID] = {
-		.img_id = SCP_FW_KEY_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[TRUSTED_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &trusted_world_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &trusted_world_pk,
+			.data = {
+				.ptr = (void *)trusted_world_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &scp_fw_content_pk,
-				.data = {
-					.ptr = (void *)content_pk_buf,
-					.len = (unsigned int)PK_DER_LEN
-				}
+		[1] = {
+			.type_desc = &non_trusted_world_pk,
+			.data = {
+				.ptr = (void *)non_trusted_world_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
 			}
 		}
-	},
-	[SCP_FW_CONTENT_CERT_ID] = {
-		.img_id = SCP_FW_CONTENT_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[SCP_FW_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &scp_fw_content_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	}
+};
+/*
+ * SCP Firmware
+ */
+static const auth_img_desc_t scp_fw_key_cert = {
+	.img_id = SCP_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &scp_fw_hash,
-				.data = {
-					.ptr = (void *)scp_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[SCP_BL2_IMAGE_ID] = {
-		.img_id = SCP_BL2_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[SCP_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &scp_fw_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
 			}
 		}
-	},
-	/*
-	 * SoC Firmware
-	 */
-	[SOC_FW_KEY_CERT_ID] = {
-		.img_id = SOC_FW_KEY_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[TRUSTED_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &trusted_world_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	}
+};
+static const auth_img_desc_t scp_fw_content_cert = {
+	.img_id = SCP_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &scp_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &scp_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &soc_fw_content_pk,
-				.data = {
-					.ptr = (void *)content_pk_buf,
-					.len = (unsigned int)PK_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[SOC_FW_CONTENT_CERT_ID] = {
-		.img_id = SOC_FW_CONTENT_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[SOC_FW_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &soc_fw_content_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_fw_hash,
+			.data = {
+				.ptr = (void *)scp_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t scp_bl2_image = {
+	.img_id = SCP_BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &scp_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &scp_fw_hash
+			}
+		}
+	}
+};
+/*
+ * SoC Firmware
+ */
+static const auth_img_desc_t soc_fw_key_cert = {
+	.img_id = SOC_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &soc_fw_hash,
-				.data = {
-					.ptr = (void *)soc_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &soc_fw_config_hash,
-				.data = {
-					.ptr = (void *)soc_fw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[BL31_IMAGE_ID] = {
-		.img_id = BL31_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[SOC_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &soc_fw_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &soc_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
 			}
 		}
-	},
-	/* SOC FW Config */
-	[SOC_FW_CONFIG_ID] = {
-		.img_id = SOC_FW_CONFIG_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[SOC_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &soc_fw_config_hash,
-				}
+	}
+};
+static const auth_img_desc_t soc_fw_content_cert = {
+	.img_id = SOC_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &soc_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &soc_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	/*
-	 * Trusted OS Firmware
-	 */
-	[TRUSTED_OS_FW_KEY_CERT_ID] = {
-		.img_id = TRUSTED_OS_FW_KEY_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[TRUSTED_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &trusted_world_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &soc_fw_hash,
+			.data = {
+				.ptr = (void *)soc_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &tos_fw_content_pk,
-				.data = {
-					.ptr = (void *)content_pk_buf,
-					.len = (unsigned int)PK_DER_LEN
-				}
+		[1] = {
+			.type_desc = &soc_fw_config_hash,
+			.data = {
+				.ptr = (void *)soc_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
-		.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[TRUSTED_OS_FW_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &tos_fw_content_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	}
+};
+static const auth_img_desc_t bl31_image = {
+	.img_id = BL31_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &soc_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &soc_fw_hash
+			}
+		}
+	}
+};
+/* SOC FW Config */
+static const auth_img_desc_t soc_fw_config = {
+	.img_id = SOC_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &soc_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &soc_fw_config_hash
+			}
+		}
+	}
+};
+/*
+ * Trusted OS Firmware
+ */
+static const auth_img_desc_t trusted_os_fw_key_cert = {
+	.img_id = TRUSTED_OS_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &tos_fw_hash,
-				.data = {
-					.ptr = (void *)tos_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &tos_fw_extra1_hash,
-				.data = {
-					.ptr = (void *)tos_fw_extra1_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[2] = {
-				.type_desc = &tos_fw_extra2_hash,
-				.data = {
-					.ptr = (void *)tos_fw_extra2_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[3] = {
-				.type_desc = &tos_fw_config_hash,
-				.data = {
-					.ptr = (void *)tos_fw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[BL32_IMAGE_ID] = {
-		.img_id = BL32_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_OS_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tos_fw_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tos_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
 			}
 		}
-	},
-	[BL32_EXTRA1_IMAGE_ID] = {
-		.img_id = BL32_EXTRA1_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_OS_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tos_fw_extra1_hash,
-				}
+	}
+};
+static const auth_img_desc_t trusted_os_fw_content_cert = {
+	.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_os_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &tos_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[BL32_EXTRA2_IMAGE_ID] = {
-		.img_id = BL32_EXTRA2_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_OS_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tos_fw_extra2_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tos_fw_hash,
+			.data = {
+				.ptr = (void *)tos_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tos_fw_extra1_hash,
+			.data = {
+				.ptr = (void *)tos_fw_extra1_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &tos_fw_extra2_hash,
+			.data = {
+				.ptr = (void *)tos_fw_extra2_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[3] = {
+			.type_desc = &tos_fw_config_hash,
+			.data = {
+				.ptr = (void *)tos_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	/* TOS FW Config */
-	[TOS_FW_CONFIG_ID] = {
-		.img_id = TOS_FW_CONFIG_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_OS_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tos_fw_config_hash,
-				}
+	}
+};
+static const auth_img_desc_t bl32_image = {
+	.img_id = BL32_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_hash
 			}
 		}
-	},
-	/*
-	 * Non-Trusted Firmware
-	 */
-	[NON_TRUSTED_FW_KEY_CERT_ID] = {
-		.img_id = NON_TRUSTED_FW_KEY_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[TRUSTED_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &non_trusted_world_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &non_trusted_nv_ctr,
-					.plat_nv_ctr = &non_trusted_nv_ctr
-				}
+	}
+};
+static const auth_img_desc_t bl32_extra1_image = {
+	.img_id = BL32_EXTRA1_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_extra1_hash
+			}
+		}
+	}
+};
+static const auth_img_desc_t bl32_extra2_image = {
+	.img_id = BL32_EXTRA2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_extra2_hash
+			}
+		}
+	}
+};
+/* TOS FW Config */
+static const auth_img_desc_t tos_fw_config = {
+	.img_id = TOS_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_config_hash
+			}
+		}
+	}
+};
+/*
+ * Non-Trusted Firmware
+ */
+static const auth_img_desc_t non_trusted_fw_key_cert = {
+	.img_id = NON_TRUSTED_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &non_trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &nt_fw_content_pk,
-				.data = {
-					.ptr = (void *)content_pk_buf,
-					.len = (unsigned int)PK_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
 			}
 		}
 	},
-	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
-		.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[NON_TRUSTED_FW_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &nt_fw_content_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &non_trusted_nv_ctr,
-					.plat_nv_ctr = &non_trusted_nv_ctr
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &nt_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t non_trusted_fw_content_cert = {
+	.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &non_trusted_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &nt_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &nt_world_bl_hash,
-				.data = {
-					.ptr = (void *)nt_world_bl_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &nt_fw_config_hash,
-				.data = {
-					.ptr = (void *)nt_fw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
 			}
 		}
 	},
-	[BL33_IMAGE_ID] = {
-		.img_id = BL33_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[NON_TRUSTED_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &nt_world_bl_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &nt_world_bl_hash,
+			.data = {
+				.ptr = (void *)nt_world_bl_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &nt_fw_config_hash,
+			.data = {
+				.ptr = (void *)nt_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	/* NT FW Config */
-	[NT_FW_CONFIG_ID] = {
-		.img_id = NT_FW_CONFIG_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[NON_TRUSTED_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &nt_fw_config_hash,
-				}
+	}
+};
+static const auth_img_desc_t bl33_image = {
+	.img_id = BL33_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &non_trusted_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &nt_world_bl_hash
 			}
 		}
+	}
+};
+/* NT FW Config */
+static const auth_img_desc_t nt_fw_config = {
+	.img_id = NT_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &non_trusted_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &nt_fw_config_hash
+			}
+		}
+	}
+};
+#else  /* IMAGE_BL2 */
+/*
+ * FWU auth descriptor.
+ */
+static const auth_img_desc_t fwu_cert = {
+	.img_id = FWU_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		}
 	},
-	/*
-	 * FWU auth descriptor.
-	 */
-	[FWU_CERT_ID] = {
-		.img_id = FWU_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = NULL,
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &subject_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_bl2u_hash,
+			.data = {
+				.ptr = (void *)scp_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &scp_bl2u_hash,
-				.data = {
-					.ptr = (void *)scp_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &bl2u_hash,
-				.data = {
-					.ptr = (void *)tb_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[2] = {
-				.type_desc = &ns_bl2u_hash,
-				.data = {
-					.ptr = (void *)nt_world_bl_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type_desc = &bl2u_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &ns_bl2u_hash,
+			.data = {
+				.ptr = (void *)nt_world_bl_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	/*
-	 * SCP_BL2U
-	 */
-	[SCP_BL2U_IMAGE_ID] = {
-		.img_id = SCP_BL2U_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[FWU_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &scp_bl2u_hash,
-				}
+	}
+};
+/*
+ * SCP_BL2U
+ */
+static const auth_img_desc_t scp_bl2u_image = {
+	.img_id = SCP_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &scp_bl2u_hash
 			}
 		}
-	},
-	/*
-	 * BL2U
-	 */
-	[BL2U_IMAGE_ID] = {
-		.img_id = BL2U_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[FWU_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &bl2u_hash,
-				}
+	}
+};
+/*
+ * BL2U
+ */
+static const auth_img_desc_t bl2u_image = {
+	.img_id = BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &bl2u_hash
 			}
 		}
-	},
-	/*
-	 * NS_BL2U
-	 */
-	[NS_BL2U_IMAGE_ID] = {
-		.img_id = NS_BL2U_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[FWU_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &ns_bl2u_hash,
+	}
+};
+/*
+ * NS_BL2U
+ */
+static const auth_img_desc_t ns_bl2u_image = {
+	.img_id = NS_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &ns_bl2u_hash
 				}
 			}
 		}
-	}
+	};
+#endif /* IMAGE_BL2 */
+/*
+ * TBBR Chain of trust definition
+ */
+
+#ifdef IMAGE_BL1
+static const auth_img_desc_t * const cot_desc[] = {
+	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
+	[BL2_IMAGE_ID]				=	&bl2_image,
+	[HW_CONFIG_ID]				=	&hw_config,
+	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
+	[FWU_CERT_ID]				=	&fwu_cert,
+	[SCP_BL2U_IMAGE_ID]			=	&scp_bl2u_image,
+	[BL2U_IMAGE_ID]				=	&bl2u_image,
+	[NS_BL2U_IMAGE_ID]			=	&ns_bl2u_image
+};
+#else /* IMAGE_BL2 */
+static const auth_img_desc_t * const cot_desc[] = {
+	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
+	[HW_CONFIG_ID]				=	&hw_config,
+	[TRUSTED_KEY_CERT_ID]			=	&trusted_key_cert,
+	[SCP_FW_KEY_CERT_ID]			=	&scp_fw_key_cert,
+	[SCP_FW_CONTENT_CERT_ID]		=	&scp_fw_content_cert,
+	[SCP_BL2_IMAGE_ID]			=	&scp_bl2_image,
+	[SOC_FW_KEY_CERT_ID]			=	&soc_fw_key_cert,
+	[SOC_FW_CONTENT_CERT_ID]		=	&soc_fw_content_cert,
+	[BL31_IMAGE_ID]				=	&bl31_image,
+	[SOC_FW_CONFIG_ID]			=	&soc_fw_config,
+	[TRUSTED_OS_FW_KEY_CERT_ID]		=	&trusted_os_fw_key_cert,
+	[TRUSTED_OS_FW_CONTENT_CERT_ID]		=	&trusted_os_fw_content_cert,
+	[BL32_IMAGE_ID]				=	&bl32_image,
+	[BL32_EXTRA1_IMAGE_ID]			=	&bl32_extra1_image,
+	[BL32_EXTRA2_IMAGE_ID]			=	&bl32_extra2_image,
+	[TOS_FW_CONFIG_ID]			=	&tos_fw_config,
+	[NON_TRUSTED_FW_KEY_CERT_ID]		=	&non_trusted_fw_key_cert,
+	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
+	[BL33_IMAGE_ID]				=	&bl33_image,
+	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
 };
+#endif
 
 /* Register the CoT in the authentication module */
 REGISTER_COT(cot_desc);
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index b5ff88b..1ec81c3 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -20,8 +20,10 @@
 {
 	/* Assert that the struct is not on the stack (common mistake). */
 	assert((console < stacks_start) || (console >= stacks_end));
-	/* Assert that we won't make a circle in the list. */
-	assert(!console_is_registered(console));
+
+	/* Check that we won't make a circle in the list. */
+	if (console_is_registered(console) == 1)
+		return 1;
 
 	console->next = console_list;
 	console_list = console;
diff --git a/drivers/renesas/rcar/board/board.c b/drivers/renesas/rcar/board/board.c
index 1e83306..df17802 100644
--- a/drivers/renesas/rcar/board/board.c
+++ b/drivers/renesas/rcar/board/board.c
@@ -32,7 +32,7 @@
 
 #define SXS_ID	{ 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
 #define SX_ID	{ 0x10U, 0x11U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
-#define SKP_ID	{ 0x10U, 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
+#define SKP_ID	{ 0x10U, 0x10U, 0x20U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
 #define SK_ID	{ 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
 #define EB4_ID	{ 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
 #define EB_ID	{ 0x10U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU }
diff --git a/drivers/renesas/rcar/console/rcar_printf.c b/drivers/renesas/rcar/console/rcar_printf.c
index 2a6e2c0..e75b9f4 100644
--- a/drivers/renesas/rcar/console/rcar_printf.c
+++ b/drivers/renesas/rcar/console/rcar_printf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -94,9 +94,6 @@
 			     sizeof(t_log->header.head));
 		t_log->header.index = 0U;
 		t_log->header.size = 0U;
-#ifndef IMAGE_BL2
-		rcar_stack_generic_timer[INDEX_TIMER_COUNT] = 0U;
-#endif
 	}
 	rcar_lock_init();
 
diff --git a/drivers/renesas/rcar/console/rcar_printf.h b/drivers/renesas/rcar/console/rcar_printf.h
index bcb00c3..5da70e6 100644
--- a/drivers/renesas/rcar/console/rcar_printf.h
+++ b/drivers/renesas/rcar/console/rcar_printf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,8 +12,4 @@
 int32_t rcar_set_log_data(int32_t c);
 int32_t rcar_log_init(void);
 
-#if IMAGE_BL31
-extern uint64_t rcar_stack_generic_timer[5];
-#endif
-
 #endif /* RCAR_PRINTF_H */
diff --git a/drivers/renesas/rcar/pwrc/call_sram.S b/drivers/renesas/rcar/pwrc/call_sram.S
index 7c96b7e..aa8644c 100644
--- a/drivers/renesas/rcar/pwrc/call_sram.S
+++ b/drivers/renesas/rcar/pwrc/call_sram.S
@@ -1,21 +1,13 @@
 /*
- * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch.h>
 #include <asm_macros.S>
-#include "rcar_def.h"
 
 .global rcar_pwrc_switch_stack
-.global rcar_pwrc_save_generic_timer
-.global rcar_pwrc_restore_generic_timer
-
-#define OFFSET_SP_X9_X10	(0x00)
-#define OFFSET_CNTFID0		(0x10)
-#define OFFSET_CNTPCT_EL0	(0x18)
-#define OFFSET_TIMER_COUNT	(0x20)
 
 /*
  * x0 : jump address,
@@ -54,37 +46,3 @@
 	ldp	x29, x30, [sp,#-16]
 	ret
 endfunc rcar_pwrc_switch_stack
-
-/* x0 : stack pointer base address */
-func rcar_pwrc_save_generic_timer
-
-	stp	x9, x10, [x0, #OFFSET_SP_X9_X10]
-
-	/* save CNTFID0 and cntpct_el0 */
-	mov_imm	x10, (RCAR_CNTC_BASE + CNTFID_OFF)
-	ldr	x9, [x10]
-	mrs	x10, cntpct_el0
-	stp	x9, x10, [x0, #OFFSET_CNTFID0]
-
-	ldp	x9, x10, [x0, #OFFSET_SP_X9_X10]
-
-	ret
-endfunc rcar_pwrc_save_generic_timer
-
-/* x0 : Stack pointer base address */
-func rcar_pwrc_restore_generic_timer
-
-	stp	x9, x10, [x0, #OFFSET_SP_X9_X10]
-
-	/* restore CNTFID0 and cntpct_el0 */
-	ldr	x10, [x0, #OFFSET_CNTFID0]
-	mov_imm	x9, (RCAR_CNTC_BASE + CNTFID_OFF)
-	str	x10, [x9]
-	ldp	x9, x10, [x0, #OFFSET_CNTPCT_EL0]
-	add	x9, x9, x10
-	str	x9, [x0, #OFFSET_TIMER_COUNT]
-
-	ldp	x9, x10, [x0, #OFFSET_SP_X9_X10]
-
-	ret
-endfunc rcar_pwrc_restore_generic_timer
diff --git a/drivers/renesas/rcar/pwrc/pwrc.c b/drivers/renesas/rcar/pwrc/pwrc.c
index 8bea1b5..d97e593 100644
--- a/drivers/renesas/rcar/pwrc/pwrc.c
+++ b/drivers/renesas/rcar/pwrc/pwrc.c
@@ -13,6 +13,7 @@
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
 
 #include "iic_dvfs.h"
 #include "rcar_def.h"
@@ -50,6 +51,7 @@
 #define	DBSC4_REG_DBRFEN			(DBSC4_REG_BASE + 0x0204U)
 #define	DBSC4_REG_DBWAIT			(DBSC4_REG_BASE + 0x0210U)
 #define	DBSC4_REG_DBCALCNF			(DBSC4_REG_BASE + 0x0424U)
+#define	DBSC4_REG_DBDFIPMSTRCNF			(DBSC4_REG_BASE + 0x0520U)
 #define	DBSC4_REG_DBPDLK0			(DBSC4_REG_BASE + 0x0620U)
 #define	DBSC4_REG_DBPDRGA0			(DBSC4_REG_BASE + 0x0624U)
 #define	DBSC4_REG_DBPDRGD0			(DBSC4_REG_BASE + 0x0628U)
@@ -61,6 +63,7 @@
 #define	DBSC4_BIT_DBACEN_ACCEN			((uint32_t)(1U << 0))
 #define	DBSC4_BIT_DBRFEN_ARFEN			((uint32_t)(1U << 0))
 #define	DBSC4_BIT_DBCAMxSTAT0			(0x00000001U)
+#define	DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN		(0x00000001U)
 #define	DBSC4_SET_DBCMD_OPC_PRE			(0x04000000U)
 #define	DBSC4_SET_DBCMD_OPC_SR			(0x0A000000U)
 #define	DBSC4_SET_DBCMD_OPC_PD			(0x08000000U)
@@ -124,6 +127,14 @@
 #define	RST_MODEMR				(RST_BASE + 0x0060U)
 #define	RST_MODEMR_BIT0				(0x00000001U)
 
+#define RCAR_CNTCR_OFF				(0x00U)
+#define RCAR_CNTCVL_OFF				(0x08U)
+#define RCAR_CNTCVU_OFF				(0x0CU)
+#define RCAR_CNTFID_OFF				(0x20U)
+
+#define RCAR_CNTCR_EN				((uint32_t)1U << 0U)
+#define RCAR_CNTCR_FCREQ(x)			((uint32_t)(x) << 8U)
+
 #if PMIC_ROHM_BD9571
 #define	BIT_BKUP_CTRL_OUT			((uint8_t)(1U << 4))
 #define	PMIC_BKUP_MODE_CNT			(0x20U)
@@ -321,6 +332,39 @@
 	rcar_lock_release();
 }
 
+static uint64_t rcar_pwrc_saved_cntpct_el0;
+static uint32_t rcar_pwrc_saved_cntfid;
+
+#if RCAR_SYSTEM_SUSPEND
+static void rcar_pwrc_save_timer_state(void)
+{
+	rcar_pwrc_saved_cntpct_el0 = read_cntpct_el0();
+
+	rcar_pwrc_saved_cntfid =
+		mmio_read_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF));
+}
+#endif
+
+void rcar_pwrc_restore_timer_state(void)
+{
+	/* Stop timer before restoring counter value */
+	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF), 0U);
+
+	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVL_OFF),
+		(uint32_t)(rcar_pwrc_saved_cntpct_el0 & 0xFFFFFFFFU));
+	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVU_OFF),
+		(uint32_t)(rcar_pwrc_saved_cntpct_el0 >> 32U));
+
+	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTFID_OFF),
+		rcar_pwrc_saved_cntfid);
+
+	/* Start generic timer back */
+	write_cntfrq_el0((u_register_t)plat_get_syscnt_freq2());
+
+	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCR_OFF),
+		(RCAR_CNTCR_FCREQ(0U) | RCAR_CNTCR_EN));
+}
+
 #if !PMIC_ROHM_BD9571
 void rcar_pwrc_system_reset(void)
 {
@@ -393,6 +437,11 @@
 
 self_refresh:
 
+	/* DFI_PHYMSTR_ACK setting */
+	mmio_write_32(DBSC4_REG_DBDFIPMSTRCNF,
+			mmio_read_32(DBSC4_REG_DBDFIPMSTRCNF) &
+			(~DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN));
+
 	/* Set the Self-Refresh mode */
 	mmio_write_32(DBSC4_REG_DBACEN, 0);
 
@@ -633,7 +682,7 @@
 				       DEVICE_SRAM_STACK_SIZE);
 	uint32_t sctlr;
 
-	rcar_pwrc_save_generic_timer(rcar_stack_generic_timer);
+	rcar_pwrc_save_timer_state();
 
 	/* disable MMU */
 	sctlr = (uint32_t) read_sctlr_el3();
diff --git a/drivers/renesas/rcar/pwrc/pwrc.h b/drivers/renesas/rcar/pwrc/pwrc.h
index d4d6fc4..cfb35ff 100644
--- a/drivers/renesas/rcar/pwrc/pwrc.h
+++ b/drivers/renesas/rcar/pwrc/pwrc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,6 +52,7 @@
 uint32_t rcar_pwrc_get_cluster(void);
 uint32_t rcar_pwrc_get_mpidr_cluster(uint64_t mpidr);
 uint32_t rcar_pwrc_get_cpu_num(uint32_t cluster_type);
+void rcar_pwrc_restore_timer_state(void);
 void plat_secondary_reset(void);
 
 void rcar_pwrc_code_copy_to_system_ram(void);
@@ -67,12 +68,8 @@
 void rcar_pwrc_suspend_to_ram(void);
 #endif
 
-extern void rcar_pwrc_save_generic_timer(uint64_t *rcar_stack_generic_timer);
 extern uint32_t rcar_pwrc_switch_stack(uintptr_t jump, uintptr_t stack,
 				       void *arg);
-
-extern uint64_t rcar_stack_generic_timer[5];
-
 #endif
 
 #endif /* PWRC_H */
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
index f88de83..16581bd 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
+++ b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
@@ -95,7 +95,6 @@
 static uint32_t max_density;
 static uint32_t ddr0800_mul;
 static uint32_t ddr_mul;
-static uint32_t ddr_mbps;
 static uint32_t DDR_PHY_SLICE_REGSET_OFS;
 static uint32_t DDR_PHY_ADR_V_REGSET_OFS;
 static uint32_t DDR_PHY_ADR_I_REGSET_OFS;
@@ -1136,6 +1135,7 @@
 	uint32_t ch;
 
 	if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
+		// PLL setting for PHY : H3 Ver.1.x
 		reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_PLL_WAIT),
 				   (0x0064U <<
 				    ddr_regdef_lsb(_reg_PHY_PLL_WAIT)));
@@ -1175,6 +1175,9 @@
 						 _reg_PHY_LP4_BOOT_TOP_PLL_CTRL));
 	}
 
+	reg_ddrphy_write_a(ddr_regdef_adr(_reg_PHY_LPDDR3_CS),
+				_cnf_DDR_PHY_ADR_G_REGSET[ddr_regdef_adr(_reg_PHY_LPDDR3_CS) - DDR_PHY_ADR_G_REGSET_OFS]);
+
 	/* protect register interface */
 	ddrphy_regif_idle();
 	pll3_control(0);
@@ -1902,7 +1905,14 @@
 	CACS DLY
 	***********************************************************************/
 	dataL = Boardcnf->cacs_dly + _f_scale_adj(Boardcnf->cacs_dly_adj);
-	set_dfifrequency(0x1f);
+
+	if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
+		set_dfifrequency(0x1f);
+	} else {
+		ddr_setval_ach(_reg_PHY_FREQ_SEL_MULTICAST_EN, 0x00);
+		ddr_setval_ach(_reg_PHY_FREQ_SEL_INDEX, 0x01);
+	}
+
 	foreach_vch(ch) {
 		int16_t adj;
 		for (i = 0; i < _reg_PHY_CLK_CACS_SLAVE_DELAY_X_NUM; i++) {
@@ -1921,7 +1931,13 @@
 			}
 		}
 	}
+
+	if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
+		set_dfifrequency(0x00);
+	} else {
+		ddr_setval_ach(_reg_PHY_FREQ_SEL_MULTICAST_EN, 0x01);
+		ddr_setval_ach(_reg_PHY_FREQ_SEL_INDEX, 0x00);
+	}
-	set_dfifrequency(0x00);
 
 	/***********************************************************************
 	WDQDM DLY
@@ -2234,7 +2250,16 @@
 		 + (0x28 * 2)) * 400 * 2 * ddr_mbpsdiv / ddr_mbps + 7;
 	if (tmp[0] < dataL)
 		tmp[0] = dataL;
-	mmio_write_32(DBSC_DBSCHRW1, tmp[0]);
+
+	if ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30)) {
+		mmio_write_32(DBSC_DBSCHRW1, tmp[0]
+			+ ((mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFF)
+			* 400 * 2 * ddr_mbpsdiv +(ddr_mbps-1))/ddr_mbps - 3);
+	} else {
+		mmio_write_32(DBSC_DBSCHRW1, tmp[0]
+			+ ((mmio_read_32(DBSC_DBTR(22)) & 0x0000FFFF)
+			* 400 * 2 * ddr_mbpsdiv +(ddr_mbps-1))/ddr_mbps);
+	}
 
 	/***********************************************************************
 	QOS and CAM
@@ -2378,6 +2403,38 @@
 	dataL = (get_refperiod()) * ddr_mbps / 2000 / ddr_mbpsdiv;
 	mmio_write_32(DBSC_DBRFCNF1, 0x00080000 | (dataL & 0x0000ffff));
 	mmio_write_32(DBSC_DBRFCNF2, 0x00010000 | DBSC_REFINTS);
+
+#ifdef DDR_BACKUPMODE
+	if (ddrBackup == DRAM_BOOT_STATUS_WARM) {
+#ifdef DDR_BACKUPMODE_HALF	/* for Half channel(ch0,1 only) */
+		PutStr(" DEBUG_MESS : DDR_BACKUPMODE_HALF ", 1);
+		send_dbcmd(0x08040001);
+		wait_dbcmd();
+		send_dbcmd(0x0A040001);
+		wait_dbcmd();
+		send_dbcmd(0x04040010);
+		wait_dbcmd();
+
+		if (Prr_Product == PRR_PRODUCT_H3) {
+			send_dbcmd(0x08140001);
+			wait_dbcmd();
+			send_dbcmd(0x0A140001);
+			wait_dbcmd();
+			send_dbcmd(0x04140010);
+			wait_dbcmd();
+		}
+#else /* DDR_BACKUPMODE_HALF                              //for All channels */
+		send_dbcmd(0x08840001);
+		wait_dbcmd();
+		send_dbcmd(0x0A840001);
+		wait_dbcmd();
+
+		send_dbcmd(0x04840010);
+		wait_dbcmd();
+#endif /* DDR_BACKUPMODE_HALF */
+	}
+#endif /* DDR_BACKUPMODE */
+
 #if RCAR_REWT_TRAINING != 0
 	/* Periodic-WriteDQ Training seeting */
 	if (((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11))
@@ -2432,37 +2489,6 @@
 		mmio_write_32(DBSC_DBDFICUPDCNF, 0x28240001);
 #endif /* RCAR_DRAM_SPLIT == 2 */
 	}
-
-#ifdef DDR_BACKUPMODE
-	if (ddrBackup == DRAM_BOOT_STATUS_WARM) {
-#ifdef DDR_BACKUPMODE_HALF	/* for Half channel(ch0,1 only) */
-		PutStr(" DEBUG_MESS : DDR_BACKUPMODE_HALF ", 1);
-		send_dbcmd(0x08040001);
-		wait_dbcmd();
-		send_dbcmd(0x0A040001);
-		wait_dbcmd();
-		send_dbcmd(0x04040010);
-		wait_dbcmd();
-
-		if (Prr_Product == PRR_PRODUCT_H3) {
-			send_dbcmd(0x08140001);
-			wait_dbcmd();
-			send_dbcmd(0x0A140001);
-			wait_dbcmd();
-			send_dbcmd(0x04140010);
-			wait_dbcmd();
-		}
-#else /* DDR_BACKUPMODE_HALF                              //for All channels */
-		send_dbcmd(0x08840001);
-		wait_dbcmd();
-		send_dbcmd(0x0A840001);
-		wait_dbcmd();
-
-		send_dbcmd(0x04840010);
-		wait_dbcmd();
-#endif /* DDR_BACKUPMODE_HALF */
-	}
-#endif /* DDR_BACKUPMODE */
 
 	mmio_write_32(DBSC_DBRFEN, 0x00000001);
 	/* dram access enable */
@@ -3104,6 +3130,7 @@
 	/***********************************************************************
 	exec pi_training
 	***********************************************************************/
+	ddr_setval_ach(_reg_PHY_FREQ_SEL_MULTICAST_EN, 0x00);
 	ddr_setval_ach_as(_reg_PHY_PER_CS_TRAINING_MULTICAST_EN, 0x00);
 
 	if ((Prr_Product == PRR_PRODUCT_H3) && (Prr_Cut <= PRR_PRODUCT_11)) {
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
index 43978c2..513bb03 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
+++ b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#define BOARDNUM 19
+#define BOARDNUM 20
 #define BOARD_JUDGE_AUTO
 
 #ifdef BOARD_JUDGE_AUTO
@@ -1374,6 +1374,57 @@
 	  }
 	 }
 	},
+/* boardcnf[19] RENESAS SALVATOR-X board with M3-W/SIP(16Gbit 1rank) */
+        {
+         0x03,
+         0x01,
+         0x02c0,
+         0,
+         0x0300,
+         0x00a0,
+	 {
+          {
+	   {0x04, 0xff},
+	    0x00543210,
+	    0x3201,
+	   {0x70612543, 0x43251670, 0x45326170, 0x10672534},
+	   {0x08, 0x08, 0x08, 0x08},
+	   WDQLVL_PAT,
+	   {0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0},
+	   {0, 0, 0, 0},
+	   {0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0},
+	   {0, 0, 0, 0},
+	   {0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0}
+	   },
+	  {
+	   {0x04, 0xff},
+	    0x00543210,
+	    0x2310,
+	   {0x01327654, 0x34526107, 0x35421670, 0x70615324},
+	   {0x08, 0x08, 0x08, 0x08},
+	   WDQLVL_PAT,
+	   {0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0},
+	   {0, 0, 0, 0},
+	   {0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0},
+	   {0, 0, 0, 0},
+	   {0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0}
+	  }
+	 }
+	},
 };
 
 void boardcnf_get_brd_clk(uint32_t brd, uint32_t * clk, uint32_t * div)
@@ -1618,9 +1669,12 @@
 		} else if (Prr_Product == PRR_PRODUCT_M3N) {
 			/* RENESAS SALVATOR-X (M3-N/SIP) */
 			brd = 11;
-		} else if ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30)) {
+		} else if ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut <= PRR_PRODUCT_20)) {
 			/* RENESAS SALVATOR-X (M3-W/SIP) */
 			brd = 0;
+		} else if ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut < PRR_PRODUCT_30)) {
+			/* RENESAS SALVATOR-X (M3-W Ver.1.3/SIP) */
+			brd = 19;
 		} else if ((Prr_Product == PRR_PRODUCT_M3) && (Prr_Cut >= PRR_PRODUCT_30)) {
 			/* RENESAS SALVATOR-X (M3-W ver.3.0/SIP) */
 			brd = 18;
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
index 6a3d1c0..24ff833 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
+++ b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
@@ -1,10 +1,10 @@
 /*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#define RCAR_DDR_VERSION        "rev.0.35rc01"
+#define RCAR_DDR_VERSION	"rev.0.35"
 #define DRAM_CH_CNT		(0x04)
 #define SLICE_CNT		(0x04)
 #define CS_CNT			(0x02)
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h b/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h
index 2e46401..6e4c30e 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h
+++ b/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -239,8 +239,8 @@
 /*069d*/ 0x0002c000,
 /*069e*/ 0x02c002c0,
 /*069f*/ 0x000002c0,
-/*06a0*/ 0x01421142,
-/*06a1*/ 0x00000142,
+/*06a0*/ 0x03421342,
+/*06a1*/ 0x00000342,
 /*06a2*/ 0x00000000,
 /*06a3*/ 0x00000000,
 /*06a4*/ 0x05020000,
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h b/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h
index 1762298..3c62107 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h
+++ b/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -219,8 +219,8 @@
 /*0b95*/ 0x0002c000,
 /*0b96*/ 0x02c002c0,
 /*0b97*/ 0x000002c0,
-/*0b98*/ 0x01421142,
-/*0b99*/ 0x00000142,
+/*0b98*/ 0x03421342,
+/*0b99*/ 0x00000342,
 /*0b9a*/ 0x00000000,
 /*0b9b*/ 0x00000000,
 /*0b9c*/ 0x05020000,
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h b/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
index a9569ee..42c3351 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
+++ b/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -240,8 +240,8 @@
 /*0b9e*/ 0x02c002c0,
 /*0b9f*/ 0x000002c0,
 /*0ba0*/ 0x08040201,
-/*0ba1*/ 0x01421142,
-/*0ba2*/ 0x00000142,
+/*0ba1*/ 0x03421342,
+/*0ba2*/ 0x00000342,
 /*0ba3*/ 0x00000000,
 /*0ba4*/ 0x00000000,
 /*0ba5*/ 0x05030000,
diff --git a/drivers/staging/renesas/rcar/qos/H3/qos_init_h3_v20.c b/drivers/staging/renesas/rcar/qos/H3/qos_init_h3_v20.c
index c4f8701..c7137de 100644
--- a/drivers/staging/renesas/rcar/qos/H3/qos_init_h3_v20.c
+++ b/drivers/staging/renesas/rcar/qos/H3/qos_init_h3_v20.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,7 @@
 #include "qos_init_h3_v20.h"
 
 
-#define	RCAR_QOS_VERSION		"rev.0.20"
+#define	RCAR_QOS_VERSION		"rev.0.21"
 
 #define QOSWT_TIME_BANK0				(20000000U)	/* unit:ns */
 
diff --git a/drivers/staging/renesas/rcar/qos/H3/qos_init_h3_v30.c b/drivers/staging/renesas/rcar/qos/H3/qos_init_h3_v30.c
index 95f4810..ffc9025 100644
--- a/drivers/staging/renesas/rcar/qos/H3/qos_init_h3_v30.c
+++ b/drivers/staging/renesas/rcar/qos/H3/qos_init_h3_v30.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,7 @@
 #include "qos_init_h3_v30.h"
 
 
-#define	RCAR_QOS_VERSION		"rev.0.10"
+#define	RCAR_QOS_VERSION		"rev.0.11"
 
 #define QOSCTRL_FSS			(QOS_BASE1 + 0x0048U)
 
diff --git a/drivers/staging/renesas/rcar/qos/H3/qos_init_h3n_v30.c b/drivers/staging/renesas/rcar/qos/H3/qos_init_h3n_v30.c
index 71e0396..6503b43 100644
--- a/drivers/staging/renesas/rcar/qos/H3/qos_init_h3n_v30.c
+++ b/drivers/staging/renesas/rcar/qos/H3/qos_init_h3n_v30.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,7 @@
 #include "qos_init_h3n_v30.h"
 
 
-#define	RCAR_QOS_VERSION		"rev.0.06"
+#define	RCAR_QOS_VERSION		"rev.0.07"
 
 #define QOSCTRL_FSS			(QOS_BASE1 + 0x0048U)
 
diff --git a/drivers/staging/renesas/rcar/qos/M3/qos_init_m3_v11.c b/drivers/staging/renesas/rcar/qos/M3/qos_init_m3_v11.c
index 10fa6b4..cee9dd0 100644
--- a/drivers/staging/renesas/rcar/qos/M3/qos_init_m3_v11.c
+++ b/drivers/staging/renesas/rcar/qos/M3/qos_init_m3_v11.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2017-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +12,7 @@
 #include "../qos_reg.h"
 #include "qos_init_m3_v11.h"
 
-#define	RCAR_QOS_VERSION		"rev.0.18"
+#define	RCAR_QOS_VERSION		"rev.0.19"
 
 
 #define QOSWT_TIME_BANK0				(20000000U)	/* unit:ns */
diff --git a/drivers/staging/renesas/rcar/qos/M3/qos_init_m3_v30.c b/drivers/staging/renesas/rcar/qos/M3/qos_init_m3_v30.c
index 319e393..e5a31c4 100644
--- a/drivers/staging/renesas/rcar/qos/M3/qos_init_m3_v30.c
+++ b/drivers/staging/renesas/rcar/qos/M3/qos_init_m3_v30.c
@@ -12,7 +12,7 @@
 #include "../qos_reg.h"
 #include "qos_init_m3_v30.h"
 
-#define	RCAR_QOS_VERSION		"rev.0.1"
+#define	RCAR_QOS_VERSION		"rev.0.02"
 
 #define QOSCTRL_EARLYR			(QOS_BASE1 + 0x0060U)
 #define QOSCTRL_FSS			(QOS_BASE1 + 0x0048U)
diff --git a/drivers/staging/renesas/rcar/qos/M3N/qos_init_m3n_v10.c b/drivers/staging/renesas/rcar/qos/M3N/qos_init_m3n_v10.c
index 52a3ca2..bd023e2 100644
--- a/drivers/staging/renesas/rcar/qos/M3N/qos_init_m3n_v10.c
+++ b/drivers/staging/renesas/rcar/qos/M3N/qos_init_m3n_v10.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2017-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +12,7 @@
 #include "../qos_reg.h"
 #include "qos_init_m3n_v10.h"
 
-#define	RCAR_QOS_VERSION		"rev.0.08"
+#define	RCAR_QOS_VERSION		"rev.0.09"
 
 #define QOSCTRL_EARLYR			(QOS_BASE1 + 0x0060U)
 #define QOSCTRL_FSS			(QOS_BASE1 + 0x0048U)
diff --git a/drivers/staging/renesas/rcar/qos/qos_common.h b/drivers/staging/renesas/rcar/qos/qos_common.h
index 89dcf06..c3a83ac 100644
--- a/drivers/staging/renesas/rcar/qos/qos_common.h
+++ b/drivers/staging/renesas/rcar/qos/qos_common.h
@@ -34,9 +34,9 @@
 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3N)
 /* define used for M3N */
 #if (RCAR_REF_INT == RCAR_REF_DEFAULT)	/* REF 1.95usec */
-#define SUB_SLOT_CYCLE_M3N		(0x84U)	/* 132 */
+#define SUB_SLOT_CYCLE_M3N		(0x7EU)	/* 126 */
 #else /* REF 3.9usec */
-#define SUB_SLOT_CYCLE_M3N		(0x108U)	/* 264 */
+#define SUB_SLOT_CYCLE_M3N		(0xFCU)	/* 252 */
 #endif /* (RCAR_REF_INT == RCAR_REF_DEFAULT) */
 
 #define SL_INIT_SSLOTCLK_M3N		(SUB_SLOT_CYCLE_M3N -1U)
@@ -46,9 +46,9 @@
 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_H3)
 /* define used for H3 */
 #if (RCAR_REF_INT == RCAR_REF_DEFAULT)	/* REF 1.95usec */
-#define SUB_SLOT_CYCLE_H3_20		(0x84U)	/* 132 */
+#define SUB_SLOT_CYCLE_H3_20		(0x7EU)	/* 126 */
 #else /* REF 3.9usec */
-#define SUB_SLOT_CYCLE_H3_20		(0x108U)	/* 264 */
+#define SUB_SLOT_CYCLE_H3_20		(0xFCU)	/* 252 */
 #endif /* (RCAR_REF_INT == RCAR_REF_DEFAULT) */
 
 #define SL_INIT_SSLOTCLK_H3_20		(SUB_SLOT_CYCLE_H3_20 -1U)
@@ -64,9 +64,9 @@
 #if (RCAR_LSI == RCAR_H3N)
 /* define used for H3N */
 #if (RCAR_REF_INT == RCAR_REF_DEFAULT)	/* REF 1.95usec */
-#define SUB_SLOT_CYCLE_H3N		(0x84U)	/* 132 */
+#define SUB_SLOT_CYCLE_H3N		(0x7EU)	/* 126 */
 #else /* REF 3.9usec */
-#define SUB_SLOT_CYCLE_H3N		(0x108U)	/* 264 */
+#define SUB_SLOT_CYCLE_H3N		(0xFCU)	/* 252 */
 #endif /* (RCAR_REF_INT == RCAR_REF_DEFAULT) */
 
 #define SL_INIT_SSLOTCLK_H3N		(SUB_SLOT_CYCLE_H3N -1U)
@@ -77,11 +77,11 @@
 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3)
 /* define used for M3 */
 #if (RCAR_REF_INT == RCAR_REF_DEFAULT)	/* REF 1.95usec */
-#define SUB_SLOT_CYCLE_M3_11		(0x84U)	/* 132 */
-#define SUB_SLOT_CYCLE_M3_30		(0x84U)	/* 132 */
+#define SUB_SLOT_CYCLE_M3_11		(0x7EU)	/* 126 */
+#define SUB_SLOT_CYCLE_M3_30		(0x7EU)	/* 126 */
 #else /* REF 3.9usec */
-#define SUB_SLOT_CYCLE_M3_11		(0x108U)	/* 264 */
-#define SUB_SLOT_CYCLE_M3_30		(0x108U)	/* 264 */
+#define SUB_SLOT_CYCLE_M3_11		(0xFCU)	/* 252 */
+#define SUB_SLOT_CYCLE_M3_30		(0xFCU)	/* 252 */
 #endif /* (RCAR_REF_INT == RCAR_REF_DEFAULT) */
 
 #define SL_INIT_SSLOTCLK_M3_11		(SUB_SLOT_CYCLE_M3_11 -1U)
diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S
new file mode 100644
index 0000000..6921884
--- /dev/null
+++ b/drivers/ti/uart/aarch32/16550_console.S
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <console_macros.S>
+#include <drivers/ti/uart/uart_16550.h>
+
+	/*
+	 * "core" functions are low-level implementations that don't require
+	 * writable memory and are thus safe to call in BL1 crash context.
+	 */
+	.globl console_16550_core_init
+	.globl console_16550_core_putc
+	.globl console_16550_core_getc
+	.globl console_16550_core_flush
+
+	.globl console_16550_putc
+	.globl console_16550_getc
+	.globl console_16550_flush
+
+	/* -----------------------------------------------
+	 * int console_16550_core_init(uintptr_t base_addr,
+	 * unsigned int uart_clk, unsigned int baud_rate)
+	 * Function to initialize the console without a
+	 * C Runtime to print debug information. This
+	 * function will be accessed by console_init and
+	 * crash reporting.
+	 * In: r0 - console base address
+	 *     r1 - Uart clock in Hz
+	 *     r2 - Baud rate
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : r1, r2, r3
+	 * -----------------------------------------------
+	 */
+func console_16550_core_init
+	/* Check the input base address */
+	cmp	r0, #0
+	beq	init_fail
+	/* Check baud rate and uart clock for sanity */
+	cmp	r1, #0
+	beq	init_fail
+	cmp	r2, #0
+	beq	init_fail
+
+	/* Program the baudrate */
+	/* Divisor =  Uart clock / (16 * baudrate) */
+	lsl	r2, r2, #4
+	udiv	r2, r1, r2
+	and	r1, r2, #0xff		/* w1 = DLL */
+	lsr	r2, r2, #8
+	and	r2, r2, #0xff		/* w2 = DLLM */
+	ldr	r3, [r0, #UARTLCR]
+	orr	r3, r3, #UARTLCR_DLAB
+	str	r3, [r0, #UARTLCR]	/* enable DLL, DLLM programming */
+	str	r1, [r0, #UARTDLL]	/* program DLL */
+	str	r2, [r0, #UARTDLLM]	/* program DLLM */
+	mov	r2, #~UARTLCR_DLAB
+	and	r3, r3, r2
+	str	r3, [r0, #UARTLCR]	/* disable DLL, DLLM programming */
+
+	/* 8n1 */
+	mov	r3, #3
+	str	r3, [r0, #UARTLCR]
+	/* no interrupt */
+	mov	r3, #0
+	str	r3, [r0, #UARTIER]
+#ifdef TI_16550_MDR_QUIRK
+	/* UART must be enabled on some platforms via the MDR register */
+	str	r3, [r0, #UARTMDR1]
+#endif /* TI_16550_MDR_QUIRK */
+	/* enable fifo, DMA */
+	mov	r3, #(UARTFCR_FIFOEN | UARTFCR_DMAEN)
+	str	r3, [r0, #UARTFCR]
+	/* DTR + RTS */
+	mov	r3, #3
+	str	r3, [r0, #UARTMCR]
+	mov	r0, #1
+	bx	lr
+init_fail:
+	mov	r0, #0
+	bx	lr
+endfunc console_16550_core_init
+
+	.globl console_16550_register
+
+	/* -------------------------------------------------------
+	 * int console_stm32_register(uintptr_t baseaddr,
+	 *     uint32_t clock, uint32_t baud,
+	 *     struct console_stm32 *console);
+	 * Function to initialize and register a new STM32
+	 * console. Storage passed in for the console struct
+	 * *must* be persistent (i.e. not from the stack).
+	 * In: r0 - UART register base address
+	 *     r1 - UART clock in Hz
+	 *     r2 - Baud rate
+	 *     r3 - pointer to empty console_stm32 struct
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : r0, r1, r2
+	 * -------------------------------------------------------
+	 */
+func console_16550_register
+	push	{r4, lr}
+	mov	r4, r3
+	cmp	r4, #0
+	beq	register_fail
+	str	r0, [r4, #CONSOLE_T_16550_BASE]
+
+	bl	console_16550_core_init
+	cmp	r0, #0
+	beq	register_fail
+
+	mov	r0, r4
+	pop	{r4, lr}
+	finish_console_register 16550 putc=1, getc=1, flush=1
+
+register_fail:
+	pop	{r4, pc}
+endfunc console_16550_register
+
+	/* --------------------------------------------------------
+	 * int console_16550_core_putc(int c, uintptr_t base_addr)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : r0 - character to be printed
+	 *      r1 - console base address
+	 * Out : return -1 on error else return character.
+	 * Clobber list : r2
+	 * --------------------------------------------------------
+	 */
+func console_16550_core_putc
+#if ENABLE_ASSERTIONS
+	cmp	r1, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+	/* Prepend '\r' to '\n' */
+	cmp	r0, #0xA
+	bne	2f
+	/* Check if the transmit FIFO is full */
+1:	ldr	r2, [r1, #UARTLSR]
+	and	r2, r2, #(UARTLSR_TEMT | UARTLSR_THRE)
+	cmp	r2, #(UARTLSR_TEMT | UARTLSR_THRE)
+	bne	1b
+	mov	r2, #0xD		/* '\r' */
+	str	r2, [r1, #UARTTX]
+
+	/* Check if the transmit FIFO is full */
+2:	ldr	r2, [r1, #UARTLSR]
+	and	r2, r2, #(UARTLSR_TEMT | UARTLSR_THRE)
+	cmp	r2, #(UARTLSR_TEMT | UARTLSR_THRE)
+	bne	2b
+	str	r0, [r1, #UARTTX]
+	bx	lr
+endfunc console_16550_core_putc
+
+	/* --------------------------------------------------------
+	 * int console_16550_putc(int c, console_16550_t *console)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : r0 - character to be printed
+	 *      r1 - pointer to console_t structure
+	 * Out : return -1 on error else return character.
+	 * Clobber list : r2
+	 * --------------------------------------------------------
+	 */
+func console_16550_putc
+#if ENABLE_ASSERTIONS
+	cmp	r1, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	r1, [r1, #CONSOLE_T_16550_BASE]
+	b	console_16550_core_putc
+endfunc console_16550_putc
+
+	/* ---------------------------------------------
+	 * int console_16550_core_getc(uintptr_t base_addr)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 on if no character is available.
+	 * In :  r0 - console base address
+	 * Clobber list : r0, r1
+	 * ---------------------------------------------
+	 */
+func console_16550_core_getc
+#if ENABLE_ASSERTIONS
+	cmp	r0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+	/* Check if the receive FIFO is empty */
+1:	ldr	r1, [r0, #UARTLSR]
+	tst	r1, #UARTLSR_RDR_BIT
+	beq	no_char
+	ldr	r1, [r0, #UARTRX]
+	mov	r0, r1
+	bx	lr
+no_char:
+	mov	r0, #ERROR_NO_PENDING_CHAR
+	bx	lr
+endfunc console_16550_core_getc
+
+	/* ---------------------------------------------
+	 * int console_16550_getc(console_16550_t *console)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 on if no character is available.
+	 * In :  r0 - pointer to console_t stucture
+	 * Out : r0 - character if available, else -1
+	 * Clobber list : r0, r1
+	 * ---------------------------------------------
+	 */
+func console_16550_getc
+#if ENABLE_ASSERTIONS
+	cmp	r0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	r0, [r0, #CONSOLE_T_16550_BASE]
+	b	console_16550_core_getc
+endfunc console_16550_getc
+
+	/* ---------------------------------------------
+	 * int console_16550_core_flush(uintptr_t base_addr)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : r0 - console base address
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : r0, r1
+	 * ---------------------------------------------
+	 */
+func console_16550_core_flush
+#if ENABLE_ASSERTIONS
+	cmp	r0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+	/* Loop until the transmit FIFO is empty */
+1:	ldr	r1, [r0, #UARTLSR]
+	and	r1, r1, #(UARTLSR_TEMT | UARTLSR_THRE)
+	cmp	r1, #(UARTLSR_TEMT | UARTLSR_THRE)
+	bne	1b
+
+	mov	r0, #0
+	bx	lr
+endfunc console_16550_core_flush
+
+	/* ---------------------------------------------
+	 * int console_16550_flush(console_pl011_t *console)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : r0 - pointer to console_t structure
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : r0, r1
+	 * ---------------------------------------------
+	 */
+func console_16550_flush
+#if ENABLE_ASSERTIONS
+	cmp	r0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	r0, [r0, #CONSOLE_T_16550_BASE]
+	b	console_16550_core_flush
+endfunc console_16550_flush
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index 322aed5..0bd8978 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -92,9 +92,14 @@
 	 *
 	 * FPEXC.EN: Enable access to Advanced SIMD and floating point features
 	 *  from all exception levels.
+         *
+         * __SOFTFP__: Predefined macro exposed by soft-float toolchain.
+         *  ARMv7 and Cortex-A32(ARMv8/aarch32) has both soft-float and
+         *  hard-float variants of toolchain, avoid compiling below code with
+         *  soft-float toolchain as "vmsr" instruction will not be recognized.
 	 * ---------------------------------------------------------------------
 	 */
-#if (ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_VFP)
+#if ((ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_VFP)) && !(__SOFTFP__)
 	ldr	r0, =(FPEXC_RESET_VAL | FPEXC_EN_BIT)
 	vmsr	FPEXC, r0
 	isb
diff --git a/include/bl32/sp_min/platform_sp_min.h b/include/bl32/sp_min/platform_sp_min.h
index feb4ec3..971f661 100644
--- a/include/bl32/sp_min/platform_sp_min.h
+++ b/include/bl32/sp_min/platform_sp_min.h
@@ -18,6 +18,7 @@
 void sp_min_plat_runtime_setup(void);
 void sp_min_plat_arch_setup(void);
 entry_point_info_t *sp_min_plat_get_bl33_ep_info(void);
+void sp_min_warm_entrypoint(void);
 
 /* Platforms that enable SP_MIN_WITH_SECURE_FIQ shall implement this api */
 void sp_min_plat_fiq_handler(uint32_t id);
diff --git a/include/drivers/arm/sbsa.h b/include/drivers/arm/sbsa.h
new file mode 100644
index 0000000..9403634
--- /dev/null
+++ b/include/drivers/arm/sbsa.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SBSA_H
+#define SBSA_H
+
+#include <stdint.h>
+
+/* Register Offsets */
+#define SBSA_WDOG_WCS_OFFSET		UL(0x000)
+#define SBSA_WDOG_WOR_LOW_OFFSET	UL(0x008)
+#define SBSA_WDOG_WOR_HIGH_OFFSET	UL(0x00C)
+
+#define SBSA_WDOG_WCS_EN		U(0x1)
+
+#define SBSA_WDOG_WOR_WIDTH		UL(48)
+
+void sbsa_wdog_start(uintptr_t base, uint64_t ms);
+void sbsa_wdog_stop(uintptr_t base);
+
+#endif /* SBSA_H */
diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h
index 9089953..39f5372 100644
--- a/include/drivers/auth/auth_mod.h
+++ b/include/drivers/auth/auth_mod.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,8 +27,8 @@
 	unsigned int img_id;
 	img_type_t img_type;
 	const struct auth_img_desc_s *parent;
-	auth_method_desc_t img_auth_methods[AUTH_METHOD_NUM];
-	auth_param_desc_t authenticated_data[COT_MAX_VERIFIED_PARAMS];
+	const auth_method_desc_t *const img_auth_methods;
+	const auth_param_desc_t *const authenticated_data;
 } auth_img_desc_t;
 
 /* Public functions */
@@ -38,13 +38,13 @@
 			void *img_ptr,
 			unsigned int img_len);
 
-/* Macro to register a CoT defined as an array of auth_img_desc_t */
+/* Macro to register a CoT defined as an array of auth_img_desc_t pointers */
 #define REGISTER_COT(_cot) \
-	const auth_img_desc_t *const cot_desc_ptr = \
-			(const auth_img_desc_t *const)&_cot[0]; \
+	const auth_img_desc_t **const cot_desc_ptr = \
+			(const auth_img_desc_t **const)_cot; \
 	unsigned int auth_img_flags[MAX_NUMBER_IDS]
 
-extern const auth_img_desc_t *const cot_desc_ptr;
+extern const auth_img_desc_t **const cot_desc_ptr;
 extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
 
 #endif /* TRUSTED_BOARD_BOOT */
diff --git a/include/lib/cpus/aarch32/cortex_a12.h b/include/lib/cpus/aarch32/cortex_a12.h
index 8f6e7b8..abacdba 100644
--- a/include/lib/cpus/aarch32/cortex_a12.h
+++ b/include/lib/cpus/aarch32/cortex_a12.h
@@ -12,7 +12,7 @@
 /*******************************************************************************
  * Cortex-A12 midr with version/revision set to 0
  ******************************************************************************/
-#define CORTEX_A12_MIDR			U(0x410FC0C0)
+#define CORTEX_A12_MIDR			U(0x410FC0D0)
 
 /*******************************************************************************
  * CPU Auxiliary Control register specific definitions.
diff --git a/include/lib/cpus/aarch64/cortex_a35.h b/include/lib/cpus/aarch64/cortex_a35.h
index 0678804..5421478 100644
--- a/include/lib/cpus/aarch64/cortex_a35.h
+++ b/include/lib/cpus/aarch64/cortex_a35.h
@@ -19,4 +19,11 @@
 #define CORTEX_A35_CPUECTLR_EL1			S3_1_C15_C2_1
 #define CORTEX_A35_CPUECTLR_SMPEN_BIT		(ULL(1) << 6)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A35_CPUACTLR_EL1			S3_1_C15_C2_0
+
+#define CORTEX_A35_CPUACTLR_EL1_ENDCCASCI	(ULL(1) << 44)
+
 #endif /* CORTEX_A35_H */
diff --git a/include/lib/cpus/aarch64/cortex_a76ae.h b/include/lib/cpus/aarch64/cortex_a76ae.h
new file mode 100644
index 0000000..9e34efb
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a76ae.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A76AE_H
+#define CORTEX_A76AE_H
+
+#include <lib/utils_def.h>
+
+/* Cortex-A76AE MIDR for revision 0 */
+#define CORTEX_A76AE_MIDR		U(0x410FD0E0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A76AE_CPUPWRCTLR_EL1	S3_0_C15_C2_7
+
+/* Definitions of register field mask in CORTEX_A76AE_CPUPWRCTLR_EL1 */
+#define CORTEX_A76AE_CORE_PWRDN_EN_MASK	U(0x1)
+
+#define CORTEX_A76AE_CPUECTLR_EL1	S3_0_C15_C1_4
+
+#endif /* CORTEX_A76AE_H */
diff --git a/include/lib/cpus/aarch64/dsu_def.h b/include/lib/cpus/aarch64/dsu_def.h
index b7ba28a..0969acf 100644
--- a/include/lib/cpus/aarch64/dsu_def.h
+++ b/include/lib/cpus/aarch64/dsu_def.h
@@ -10,23 +10,31 @@
 #include <lib/utils_def.h>
 
 /********************************************************************
- * DSU control registers definitions				    *
+ * DSU Cluster Configuration registers definitions
  ********************************************************************/
 #define CLUSTERCFR_EL1		S3_0_C15_C3_0
-#define CLUSTERIDR_EL1		S3_0_C15_C3_1
-#define CLUSTERACTLR_EL1	S3_0_C15_C3_3
+
+#define CLUSTERCFR_ACP_SHIFT	U(11)
 
 /********************************************************************
- * DSU control registers bit fields				    *
+ * DSU Cluster Main Revision ID registers definitions
  ********************************************************************/
+#define CLUSTERIDR_EL1		S3_0_C15_C3_1
+
 #define CLUSTERIDR_REV_SHIFT	U(0)
 #define CLUSTERIDR_REV_BITS	U(4)
 #define CLUSTERIDR_VAR_SHIFT	U(4)
 #define CLUSTERIDR_VAR_BITS	U(4)
-#define CLUSTERCFR_ACP_SHIFT	U(11)
+
+/********************************************************************
+ * DSU Cluster Auxiliary Control registers definitions
+ ********************************************************************/
+#define CLUSTERACTLR_EL1	S3_0_C15_C3_3
+
+#define CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING	(ULL(1) << 15)
 
 /********************************************************************
- * Masks applied for DSU errata workarounds			    *
+ * Masks applied for DSU errata workarounds
  ********************************************************************/
 #define DSU_ERRATA_936184_MASK	(U(0x3) << 15)
 
diff --git a/include/lib/cpus/aarch64/neoverse_n1.h b/include/lib/cpus/aarch64/neoverse_n1.h
index 908993e..ed5f136 100644
--- a/include/lib/cpus/aarch64/neoverse_n1.h
+++ b/include/lib/cpus/aarch64/neoverse_n1.h
@@ -13,10 +13,9 @@
 #define NEOVERSE_N1_MIDR		U(0x410fd0c0)
 
 /*******************************************************************************
- * CPU Extended Control register specific definitions.
+ * CPU Power Control register specific definitions.
  ******************************************************************************/
 #define NEOVERSE_N1_CPUPWRCTLR_EL1	S3_0_C15_C2_7
-#define NEOVERSE_N1_CPUECTLR_EL1	S3_0_C15_C1_4
 
 /* Definitions of register field mask in NEOVERSE_N1_CPUPWRCTLR_EL1 */
 #define NEOVERSE_N1_CORE_PWRDN_EN_MASK	U(0x1)
@@ -26,6 +25,18 @@
 #define NEOVERSE_N1_AMU_NR_COUNTERS	U(5)
 #define NEOVERSE_N1_AMU_GROUP0_MASK	U(0x1f)
 
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_N1_CPUECTLR_EL1	S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_N1_CPUACTLR2_EL1	S3_0_C15_C1_1
+
+#define NEOVERSE_N1_CPUACTLR2_EL1_BIT_2	(ULL(1) << 2)
+
 /* Instruction patching registers */
 #define CPUPSELR_EL3	S3_6_C15_C8_0
 #define CPUPCR_EL3	S3_6_C15_C8_1
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 527375f..97e6722 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -295,4 +295,8 @@
 extern const mmap_region_t plat_arm_mmap[];
 extern const unsigned int arm_pm_idle_states[];
 
+/* secure watchdog */
+void plat_arm_secure_wdt_start(void);
+void plat_arm_secure_wdt_stop(void);
+
 #endif /* PLAT_ARM_H */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 4832e49..3f9ab1b 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -47,6 +47,7 @@
 uintptr_t plat_get_ns_image_entrypoint(void);
 unsigned int plat_my_core_pos(void);
 int plat_core_pos_by_mpidr(u_register_t mpidr);
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
 
 #if STACK_PROTECTOR_ENABLED
 /*
@@ -103,7 +104,6 @@
 const char *plat_log_get_prefix(unsigned int log_level);
 void bl2_plat_preload_setup(void);
 int plat_try_next_boot_source(void);
-int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
 uint64_t *plat_init_apiakey(void);
 
 /*******************************************************************************
@@ -262,6 +262,7 @@
 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
 int plat_set_nv_ctr2(void *cookie, const struct auth_img_desc_s *img_desc,
 		unsigned int nv_ctr);
+int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size);
 
 /*******************************************************************************
  * Secure Partitions functions
diff --git a/lib/aarch32/cache_helpers.S b/lib/aarch32/cache_helpers.S
index 810af0f..7cbefe6 100644
--- a/lib/aarch32/cache_helpers.S
+++ b/lib/aarch32/cache_helpers.S
@@ -90,23 +90,23 @@
 	.endm
 
 func do_dcsw_op
-	push	{r4-r12,lr}
+	push	{r4-r12, lr}
 	adr	r11, dcsw_loop_table	// compute cache op based on the operation type
 	add	r6, r11, r0, lsl #3	// cache op is 2x32-bit instructions
 loop1:
 	add	r10, r1, r1, LSR #1	// Work out 3x current cache level
 	mov	r12, r2, LSR r10	// extract cache type bits from clidr
-	and	r12, r12, #7   		// mask the bits for current cache only
+	and	r12, r12, #7		// mask the bits for current cache only
 	cmp	r12, #2			// see what cache we have at this level
-	blo	level_done      	// no cache or only instruction cache at this level
+	blo	level_done		// no cache or only instruction cache at this level
 
 	stcopr	r1, CSSELR		// select current cache level in csselr
 	isb				// isb to sych the new cssr&csidr
 	ldcopr	r12, CCSIDR		// read the new ccsidr
-	and	r10, r12, #7   		// extract the length of the cache lines
-	add	r10, r10, #4        	// add 4 (r10 = line length offset)
+	and	r10, r12, #7		// extract the length of the cache lines
+	add	r10, r10, #4		// add 4 (r10 = line length offset)
 	ubfx	r4, r12, #3, #10	// r4 = maximum way number (right aligned)
-	clz	r5, r4            	// r5 = the bit position of the way size increment
+	clz	r5, r4			// r5 = the bit position of the way size increment
 	mov	r9, r4			// r9 working copy of the aligned max way number
 
 loop2:
@@ -117,21 +117,23 @@
 	orr	r0, r0, r7, LSL r10	// factor in the set number
 
 	blx	r6
-	subs	r7, r7, #1              // decrement the set number
+	subs	r7, r7, #1		// decrement the set number
 	bhs	loop3
-	subs	r9, r9, #1              // decrement the way number
+	subs	r9, r9, #1		// decrement the way number
 	bhs	loop2
 level_done:
 	add	r1, r1, #2		// increment the cache number
 	cmp	r3, r1
-	dsb	sy			// ensure completion of previous cache maintenance instruction
+	// Ensure completion of previous cache maintenance instruction. Note
+	// this also mitigates erratum 814220 on Cortex-A7
+	dsb	sy
 	bhi	loop1
 
 	mov	r6, #0
 	stcopr	r6, CSSELR		//select cache level 0 in csselr
 	dsb	sy
 	isb
-	pop	{r4-r12,pc}
+	pop	{r4-r12, pc}
 
 dcsw_loop_table:
 	stcopr	r0, DCISW
diff --git a/lib/aarch32/misc_helpers.S b/lib/aarch32/misc_helpers.S
index 77cf6cd..6d2ec1c 100644
--- a/lib/aarch32/misc_helpers.S
+++ b/lib/aarch32/misc_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -171,6 +171,10 @@
 func disable_mmu_secure
 	mov	r1, #(SCTLR_M_BIT | SCTLR_C_BIT)
 do_disable_mmu:
+#if ERRATA_A9_794073
+	stcopr	r0, BPIALL
+	dsb
+#endif
 	ldcopr	r0, SCTLR
 	bic	r0, r0, r1
 	stcopr	r0, SCTLR
diff --git a/lib/cpus/aarch32/cortex_a9.S b/lib/cpus/aarch32/cortex_a9.S
index 1fb10b2..7200343 100644
--- a/lib/cpus/aarch32/cortex_a9.S
+++ b/lib/cpus/aarch32/cortex_a9.S
@@ -35,6 +35,15 @@
 	bx	lr
 endfunc cortex_a9_enable_smp
 
+func check_errata_a9_794073
+#if ERRATA_A9_794073
+	mov	r0, #ERRATA_APPLIES
+#else
+	mov	r0, #ERRATA_MISSING
+#endif
+	bx	lr
+endfunc check_errata_cve_2017_5715
+
 func check_errata_cve_2017_5715
 #if WORKAROUND_CVE_2017_5715
 	mov	r0, #ERRATA_APPLIES
@@ -59,6 +68,7 @@
 	 * checking functions of each errata.
 	 */
 	report_errata WORKAROUND_CVE_2017_5715, cortex_a9, cve_2017_5715
+	report_errata ERRATA_A9_794073, cortex_a9, a9_79407
 
 	pop	{r12, lr}
 	bx	lr
diff --git a/lib/cpus/aarch64/cortex_a35.S b/lib/cpus/aarch64/cortex_a35.S
index 96e5dd3..be3c652 100644
--- a/lib/cpus/aarch64/cortex_a35.S
+++ b/lib/cpus/aarch64/cortex_a35.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,12 +36,47 @@
 	ret
 endfunc cortex_a35_disable_smp
 
+	 /* ---------------------------------------------------
+	 * Errata Workaround for Cortex A35 Errata #855472.
+	 * This applies to revisions r0p0 of Cortex A35.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * ---------------------------------------------------
+	 */
+func errata_a35_855472_wa
+	 /*
+	  * Compare x0 against revision r0p0
+	  */
+	 mov	x17, x30
+	 bl	check_errata_855472
+	 cbz	x0, 1f
+	 mrs	x1, CORTEX_A35_CPUACTLR_EL1
+	 orr	x1, x1, #CORTEX_A35_CPUACTLR_EL1_ENDCCASCI
+	 msr	CORTEX_A35_CPUACTLR_EL1, x1
+	 isb
+1:
+	ret	x17
+endfunc errata_a35_855472_wa
+
+func check_errata_855472
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_855472
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A35.
 	 * Clobbers: x0
 	 * -------------------------------------------------
 	 */
 func cortex_a35_reset_func
+	mov	x19, x30
+	bl	cpu_get_rev_var
+
+#if ERRATA_A35_855472
+	bl	errata_a35_855472_wa
+#endif
+
 	/* ---------------------------------------------
 	 * Enable the SMP bit.
 	 * ---------------------------------------------
@@ -50,7 +85,7 @@
 	orr	x0, x0, #CORTEX_A35_CPUECTLR_SMPEN_BIT
 	msr	CORTEX_A35_CPUECTLR_EL1, x0
 	isb
-	ret
+	ret	x19
 endfunc cortex_a35_reset_func
 
 func cortex_a35_core_pwr_dwn
@@ -119,6 +154,18 @@
  * Errata printing function for Cortex A35. Must follow AAPCS.
  */
 func cortex_a35_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata ERRATA_A35_855472, cortex_a35, 855472
+
+	ldp	x8, x30, [sp], #16
 	ret
 endfunc cortex_a35_errata_report
 #endif
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index f20082d..6fd3c53 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.S
@@ -45,31 +45,35 @@
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A53 Errata #819472.
 	 * This applies only to revision <= r0p1 of Cortex A53.
+	 * Due to the nature of the errata it is applied unconditionally
+	 * when built in, report it as applicable in this case
 	 * ---------------------------------------------------
 	 */
 func check_errata_819472
-	/*
-	 * Even though this is only needed for revision <= r0p1, it
-	 * is always applied due to limitations of the current
-	 * errata framework.
-	 */
-	mov	x0, #ERRATA_APPLIES
+#if ERRATA_A53_819472
+	mov x0, #ERRATA_APPLIES
 	ret
+#else
+	mov	x1, #0x01
+	b	cpu_rev_var_ls
+#endif
 endfunc check_errata_819472
 
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A53 Errata #824069.
 	 * This applies only to revision <= r0p2 of Cortex A53.
+	 * Due to the nature of the errata it is applied unconditionally
+	 * when built in, report it as applicable in this case
 	 * ---------------------------------------------------
 	 */
 func check_errata_824069
-	/*
-	 * Even though this is only needed for revision <= r0p2, it
-	 * is always applied due to limitations of the current
-	 * errata framework.
-	 */
-	mov	x0, #ERRATA_APPLIES
+#if ERRATA_A53_824069
+	mov x0, #ERRATA_APPLIES
 	ret
+#else
+	mov	x1, #0x02
+	b	cpu_rev_var_ls
+#endif
 endfunc check_errata_824069
 
 	/* --------------------------------------------------
@@ -103,16 +107,18 @@
 	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A53 Errata #827319.
 	 * This applies only to revision <= r0p2 of Cortex A53.
+	 * Due to the nature of the errata it is applied unconditionally
+	 * when built in, report it as applicable in this case
 	 * ---------------------------------------------------
 	 */
 func check_errata_827319
-	/*
-	 * Even though this is only needed for revision <= r0p2, it
-	 * is always applied due to limitations of the current
-	 * errata framework.
-	 */
-	mov	x0, #ERRATA_APPLIES
+#if ERRATA_A53_827319
+	mov x0, #ERRATA_APPLIES
 	ret
+#else
+	mov	x1, #0x02
+	b	cpu_rev_var_ls
+#endif
 endfunc check_errata_827319
 
 	/* ---------------------------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index 1da80ef..b9a3f36 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -173,6 +173,10 @@
 func cortex_a55_reset_func
 	mov	x19, x30
 
+#if ERRATA_DSU_798953
+	bl	errata_dsu_798953_wa
+#endif
+
 #if ERRATA_DSU_936184
 	bl	errata_dsu_936184_wa
 #endif
@@ -237,6 +241,7 @@
 	 * Report all errata. The revision variant information is at x8, where
 	 * "report_errata" is expecting it and it doesn't corrupt it.
 	 */
+	report_errata ERRATA_DSU_798953, cortex_a55, dsu_798953
 	report_errata ERRATA_DSU_936184, cortex_a55, dsu_936184
 	report_errata ERRATA_A55_768277, cortex_a55, 768277
 	report_errata ERRATA_A55_778703, cortex_a55, 778703
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index 2040188..fda1aec 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -100,6 +100,10 @@
 	isb
 #endif
 
+#if ERRATA_DSU_798953
+	bl	errata_dsu_798953_wa
+#endif
+
 #if ERRATA_DSU_936184
 	bl	errata_dsu_936184_wa
 #endif
@@ -186,6 +190,7 @@
 	report_errata ERRATA_A75_790748, cortex_a75, 790748
 	report_errata WORKAROUND_CVE_2017_5715, cortex_a75, cve_2017_5715
 	report_errata WORKAROUND_CVE_2018_3639, cortex_a75, cve_2018_3639
+	report_errata ERRATA_DSU_798953, cortex_a75, dsu_798953
 	report_errata ERRATA_DSU_936184, cortex_a75, dsu_936184
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index e544018..4bf6e77 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -344,9 +344,14 @@
 #endif /* DYNAMIC_WORKAROUND_CVE_2018_3639 */
 #endif /* WORKAROUND_CVE_2018_3639 */
 
+#if ERRATA_DSU_798953
+	bl	errata_dsu_798953_wa
+#endif
+
 #if ERRATA_DSU_936184
 	bl	errata_dsu_936184_wa
 #endif
+
 	ret	x19
 endfunc cortex_a76_reset_func
 
@@ -368,7 +373,7 @@
 
 #if REPORT_ERRATA
 /*
- * Errata printing function for Cortex Cortex A76. Must follow AAPCS.
+ * Errata printing function for Cortex A76. Must follow AAPCS.
  */
 func cortex_a76_errata_report
 	stp	x8, x30, [sp, #-16]!
@@ -384,6 +389,7 @@
 	report_errata ERRATA_A76_1130799, cortex_a76, 1130799
 	report_errata ERRATA_A76_1220197, cortex_a76, 1220197
 	report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639
+	report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953
 	report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S
new file mode 100644
index 0000000..1ba8e9a
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a76ae.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <cortex_a76ae.h>
+#include <cpu_macros.S>
+
+	/* ---------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ---------------------------------------------
+	 */
+func cortex_a76ae_core_pwr_dwn
+	/* ---------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------
+	 */
+	mrs	x0, CORTEX_A76AE_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_A76AE_CORE_PWRDN_EN_MASK
+	msr	CORTEX_A76AE_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_a76ae_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex-A76AE. Must follow AAPCS.
+ */
+func cortex_a76ae_errata_report
+	ret
+endfunc cortex_a76ae_errata_report
+#endif	/* REPORT_ERRATA */
+
+	/* ---------------------------------------------
+	 * This function provides cortex_a76ae specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a76ae_regs, "aS"
+cortex_a76ae_regs:  /* The ASCII list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a76ae_cpu_reg_dump
+	adr	x6, cortex_a76ae_regs
+	mrs	x8, CORTEX_A76AE_CPUECTLR_EL1
+	ret
+endfunc cortex_a76ae_cpu_reg_dump
+
+declare_cpu_ops cortex_a76ae, CORTEX_A76AE_MIDR, CPU_NO_RESET_FUNC, \
+	cortex_a76ae_core_pwr_dwn
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
index eb84daa..100ffaa 100644
--- a/lib/cpus/aarch64/dsu_helpers.S
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,20 +8,73 @@
 #include <dsu_def.h>
 #include <lib/cpus/errata_report.h>
 
-/* -----------------------------------------------------------------------
- * DSU erratum 936184 check function
- * Checks the DSU variant, revision and configuration to determine if
- * the erratum applies. Erratum applies if ACP interface is present
- * in the DSU and revision-variant < r2p0.
- *
- * The erratum was fixed in r2p0.
- *
- * This function is called from both assembly and C environment. So it
- * follows AAPCS.
- *
- * Clobbers: x0-x3
- * -----------------------------------------------------------------------
- */
+	/* -----------------------------------------------------------------------
+	 * DSU erratum 798953 check function
+	 * Checks the DSU variant, revision and configuration to determine if
+	 * the erratum applies. Erratum applies on all configurations of the
+	 * DSU and if revision-variant is r0p0.
+	 *
+	 * The erratum was fixed in r0p1.
+	 *
+	 * This function is called from both assembly and C environment. So it
+	 * follows AAPCS.
+	 *
+	 * Clobbers: x0-x3
+	 * -----------------------------------------------------------------------
+	 */
+	.globl	check_errata_dsu_798953
+	.globl	errata_dsu_798953_wa
+
+func check_errata_dsu_798953
+	mov	x2, #ERRATA_APPLIES
+	mov	x3, #ERRATA_NOT_APPLIES
+
+	/* Check if DSU is equal to r0p0 */
+	mrs	x1, CLUSTERIDR_EL1
+
+	/* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
+	ubfx	x0, x1, #CLUSTERIDR_REV_SHIFT,\
+			#(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
+	mov	x1, #(0x0 << CLUSTERIDR_REV_SHIFT)
+	cmp	x0, x1
+	csel	x0, x2, x3, EQ
+	ret
+endfunc check_errata_dsu_798953
+
+	/* --------------------------------------------------
+	 * Errata Workaround for DSU erratum #798953.
+	 *
+	 * Can clobber only: x0-x17
+	 * --------------------------------------------------
+	 */
+func errata_dsu_798953_wa
+	mov	x17, x30
+	bl	check_errata_dsu_798953
+	cbz	x0, 1f
+
+	/* If erratum applies, disable high-level clock gating */
+	mrs	x0, CLUSTERACTLR_EL1
+	orr	x0, x0, #CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING
+	msr	CLUSTERACTLR_EL1, x0
+	isb
+1:
+	ret	x17
+endfunc errata_dsu_798953_wa
+
+	/* -----------------------------------------------------------------------
+	 * DSU erratum 936184 check function
+	 * Checks the DSU variant, revision and configuration to determine if
+	 * the erratum applies. Erratum applies if ACP interface is present
+	 * in the DSU and revision-variant < r2p0.
+	 *
+	 * The erratum was fixed in r2p0.
+	 *
+	 * This function is called from both assembly and C environment. So it
+	 * follows AAPCS.
+	 *
+	 * Clobbers: x0-x3
+	 * -----------------------------------------------------------------------
+	 */
 	.globl	check_errata_dsu_936184
 	.globl	errata_dsu_936184_wa
 
@@ -41,19 +94,19 @@
 	/* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
 	ubfx	x0, x1, #CLUSTERIDR_REV_SHIFT,\
 			#(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
-	mov	x1, #(0x2 << CLUSTERIDR_REV_BITS)
+	mov	x1, #(0x2 << CLUSTERIDR_VAR_SHIFT)
 	cmp	x0, x1
 	csel	x0, x2, x3, hs
 1:
 	ret
 endfunc check_errata_dsu_936184
 
-/* --------------------------------------------------
- * Errata Workaround for DSU erratum #936184.
- *
- * Can clobber only: x0-x17
- * --------------------------------------------------
- */
+	/* --------------------------------------------------
+	 * Errata Workaround for DSU erratum #936184.
+	 *
+	 * Can clobber only: x0-x17
+	 * --------------------------------------------------
+	 */
 func errata_dsu_936184_wa
 	mov	x17, x30
 	bl	check_errata_dsu_936184
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index 060c625..ce63899 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -50,6 +50,12 @@
 	/* Disables speculative loads */
 	msr	SSBS, xzr
 
+	/* Forces all cacheable atomic instructions to be near */
+	mrs	x0, NEOVERSE_N1_CPUACTLR2_EL1
+	orr	x0, x0, #NEOVERSE_N1_CPUACTLR2_EL1_BIT_2
+	msr	NEOVERSE_N1_CPUACTLR2_EL1, x0
+	isb
+
 	bl	cpu_get_rev_var
 	mov	x18, x0
 
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index c42eb1c..4deb262 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -53,6 +53,9 @@
 # These should be enabled by the platform if the erratum workaround needs to be
 # applied.
 
+# Flag to apply erratum 794073 workaround when disabling mmu.
+ERRATA_A9_794073	?=0
+
 # Flag to apply erratum 816470 workaround during power down. This erratum
 # applies only to revision >= r3p0 of the Cortex A15 cpu.
 ERRATA_A15_816470	?=0
@@ -69,6 +72,10 @@
 # only to revision <= r1p2 of the Cortex A17 cpu.
 ERRATA_A17_852423	?=0
 
+# Flag to apply erratum 855472 workaround during reset. This erratum applies
+# only to revision r0p0 of the Cortex A35 cpu.
+ERRATA_A35_855472	?=0
+
 # Flag to apply erratum 819472 workaround during reset. This erratum applies
 # only to revision <= r0p1 of the Cortex A53 cpu.
 ERRATA_A53_819472	?=0
@@ -207,11 +214,19 @@
 # only to r0p0 and r1p0 of the Neoverse N1 cpu.
 ERRATA_N1_1043202	?=1
 
+# Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
+# Applying the workaround results in higher DSU power consumption on idle.
+ERRATA_DSU_798953	?=0
+
 # Flag to apply DSU erratum 936184. This erratum applies to DSUs containing
 # the ACP interface and revision < r2p0. Applying the workaround results in
 # higher DSU power consumption on idle.
 ERRATA_DSU_936184	?=0
 
+# Process ERRATA_A9_794073 flag
+$(eval $(call assert_boolean,ERRATA_A9_794073))
+$(eval $(call add_define,ERRATA_A9_794073))
+
 # Process ERRATA_A15_816470 flag
 $(eval $(call assert_boolean,ERRATA_A15_816470))
 $(eval $(call add_define,ERRATA_A15_816470))
@@ -228,6 +243,10 @@
 $(eval $(call assert_boolean,ERRATA_A17_852423))
 $(eval $(call add_define,ERRATA_A17_852423))
 
+# Process ERRATA_A35_855472 flag
+$(eval $(call assert_boolean,ERRATA_A35_855472))
+$(eval $(call add_define,ERRATA_A35_855472))
+
 # Process ERRATA_A53_819472 flag
 $(eval $(call assert_boolean,ERRATA_A53_819472))
 $(eval $(call add_define,ERRATA_A53_819472))
@@ -360,6 +379,10 @@
 $(eval $(call assert_boolean,ERRATA_N1_1043202))
 $(eval $(call add_define,ERRATA_N1_1043202))
 
+# Process ERRATA_DSU_798953 flag
+$(eval $(call assert_boolean,ERRATA_DSU_798953))
+$(eval $(call add_define,ERRATA_DSU_798953))
+
 # Process ERRATA_DSU_936184 flag
 $(eval $(call assert_boolean,ERRATA_DSU_936184))
 $(eval $(call add_define,ERRATA_DSU_936184))
diff --git a/maintainers.rst b/maintainers.rst
index 52c3dac..4bee64c 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -208,6 +208,8 @@
 :M: Tony Xie <tony.xie@rock-chips.com>
 :G: `TonyXie06`_
 :G: `rockchip-linux`_
+:M: Heiko Stuebner <heiko@sntech.de>
+:G: `mmind`_
 :F: plat/rockchip/
 
 STM32MP1 platform port
@@ -277,6 +279,7 @@
 .. _niej: https://github.com/niej
 .. _kostapr: https://github.com/kostapr
 .. _masahir0y: https://github.com/masahir0y
+.. _mmind: https://github.com/mmind
 .. _mtk09422: https://github.com/mtk09422
 .. _npoushin: https://github.com/npoushin
 .. _qoriq-open-source: https://github.com/qoriq-open-source
diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c
index 75090e8..aa56716 100644
--- a/plat/arm/board/fvp/fvp_bl1_setup.c
+++ b/plat/arm/board/fvp/fvp_bl1_setup.c
@@ -5,9 +5,10 @@
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <drivers/arm/sp805.h>
 #include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/arm_def.h>
 #include <plat/common/platform.h>
-
 #include "fvp_private.h"
 
 /*******************************************************************************
@@ -30,3 +31,13 @@
 	 */
 	fvp_interconnect_enable();
 }
+
+void plat_arm_secure_wdt_start(void)
+{
+	sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sp805_stop(ARM_SP805_TWDG_BASE);
+}
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 61a3734..c11d848 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -103,6 +103,7 @@
 				lib/cpus/aarch64/cortex_a73.S			\
 				lib/cpus/aarch64/cortex_a75.S			\
 				lib/cpus/aarch64/cortex_a76.S			\
+				lib/cpus/aarch64/cortex_a76ae.S			\
 				lib/cpus/aarch64/neoverse_n1.S			\
 				lib/cpus/aarch64/cortex_deimos.S		\
 				lib/cpus/aarch64/neoverse_zeus.S
@@ -111,7 +112,8 @@
 FVP_CPU_LIBS		+=	lib/cpus/aarch32/cortex_a32.S
 endif
 
-BL1_SOURCES		+=	drivers/io/io_semihosting.c			\
+BL1_SOURCES		+=	drivers/arm/sp805/sp805.c			\
+				drivers/io/io_semihosting.c			\
 				lib/semihosting/semihosting.c			\
 				lib/semihosting/${ARCH}/semihosting_call.S	\
 				plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
diff --git a/plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c b/plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c
index 47cd876..4338f6f 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c
+++ b/plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c
@@ -4,8 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <drivers/arm/sp805.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 
 /*******************************************************************************
  * Perform any BL1 specific platform actions.
@@ -14,3 +16,13 @@
 {
 	arm_bl1_early_platform_setup();
 }
+
+void plat_arm_secure_wdt_start(void)
+{
+	sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sp805_stop(ARM_SP805_TWDG_BASE);
+}
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index 33f5c47..7a3d22d 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -12,6 +12,7 @@
 #include <drivers/arm/css/sds.h>
 #include <drivers/arm/sp805.h>
 #include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/arm_def.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
@@ -112,3 +113,13 @@
 	juno_reset_to_aarch32_state();
 }
 #endif /* JUNO_AARCH32_EL3_RUNTIME */
+
+void plat_arm_secure_wdt_start(void)
+{
+	sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sp805_stop(ARM_SP805_TWDG_BASE);
+}
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index 9d7f0e4..6566b15 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,7 @@
 #include <platform_def.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/arm/soc/common/soc_css.h>
+#include <plat/common/platform.h>
 
 #include "juno_tzmp1_def.h"
 
@@ -144,3 +145,10 @@
 	init_v550();
 #endif
 }
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
+#endif
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index e44791b..40e6264 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -62,6 +62,7 @@
 				lib/cpus/aarch64/cortex_a72.S		\
 				plat/arm/board/juno/juno_err.c		\
 				plat/arm/board/juno/juno_bl1_setup.c	\
+				drivers/arm/sp805/sp805.c		\
 				${JUNO_INTERCONNECT_SOURCES}		\
 				${JUNO_SECURITY_SOURCES}
 
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 03bd380..adb957e 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -87,4 +87,8 @@
 /* Platform ID address */
 #define SSC_VERSION				(SSC_REG_BASE + SSC_VERSION_OFFSET)
 
+/* Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_BASE			UL(0x2A480000)
+#define SBSA_SECURE_WDOG_TIMEOUT		UL(100)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
index 6905896..f36f9e2 100644
--- a/plat/arm/board/n1sdp/n1sdp_plat.c
+++ b/plat/arm/board/n1sdp/n1sdp_plat.c
@@ -10,6 +10,7 @@
 #include <common/debug.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
 
 /*
  * Table of regions to map using the MMU.
@@ -22,3 +23,12 @@
 	{0}
 };
 
+void plat_arm_secure_wdt_start(void)
+{
+	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 653d081..d0c34c8 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -25,6 +25,7 @@
 PLAT_BL_COMMON_SOURCES	:=	${N1SDP_BASE}/n1sdp_plat.c	        \
 				${N1SDP_BASE}/aarch64/n1sdp_helper.S
 
+BL1_SOURCES		+=	drivers/arm/sbsa/sbsa.c
 
 BL31_SOURCES		:=	${N1SDP_CPU_SOURCES}			\
 				${INTERCONNECT_SOURCES}			\
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 1e9edef..8e0c046 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -11,7 +11,6 @@
 #include <arch.h>
 #include <bl1/bl1.h>
 #include <common/bl_common.h>
-#include <drivers/arm/sp805.h>
 #include <lib/utils.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/arm/common/plat_arm.h>
@@ -67,7 +66,7 @@
 
 #if !ARM_DISABLE_TRUSTED_WDOG
 	/* Enable watchdog */
-	sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+	plat_arm_secure_wdt_start();
 #endif
 
 	/* Initialize the console to provide early debug support */
@@ -172,7 +171,7 @@
 {
 #if !ARM_DISABLE_TRUSTED_WDOG
 	/* Disable watchdog before leaving BL1 */
-	sp805_stop(ARM_SP805_TWDG_BASE);
+	plat_arm_secure_wdt_stop();
 #endif
 
 #ifdef EL3_PAYLOAD_BASE
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 5e890ed..c3d9e03 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -158,8 +158,7 @@
 PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
 endif
 
-BL1_SOURCES		+=	drivers/arm/sp805/sp805.c			\
-				drivers/io/io_fip.c				\
+BL1_SOURCES		+=	drivers/io/io_fip.c				\
 				drivers/io/io_memmap.c				\
 				drivers/io/io_storage.c				\
 				plat/arm/common/arm_bl1_setup.c			\
diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c
index 84886b4..580b2ee 100644
--- a/plat/arm/common/arm_console.c
+++ b/plat/arm/common/arm_console.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,9 +80,7 @@
 {
 	(void)console_flush();
 
-#if MULTI_CONSOLE_API
-	(void)console_unregister(&arm_runtime_console.console);
-#else
+#if !MULTI_CONSOLE_API
 	console_uninit();
-#endif /* MULTI_CONSOLE_API */
+#endif /* !MULTI_CONSOLE_API */
 }
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 c0e6555..032a1f4 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -208,5 +208,8 @@
 #define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
 					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
 
+/*Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_BASE		UL(0x2A480000)
+#define SBSA_SECURE_WDOG_TIMEOUT	UL(100)
 
 #endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 613d3d5..b736b0b 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -33,7 +33,8 @@
 PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c	\
 				${CSS_ENT_BASE}/aarch64/sgi_helper.S
 
-BL1_SOURCES		+=	${INTERCONNECT_SOURCES}
+BL1_SOURCES		+=	${INTERCONNECT_SOURCES}			\
+				drivers/arm/sbsa/sbsa.c
 
 BL2_SOURCES		+=	${CSS_ENT_BASE}/sgi_image_load.c
 
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 42eff86..3e207ec 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -13,6 +13,8 @@
 #include <drivers/arm/ccn.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
+#include <sgi_base_platform_def.h>
 #include <services/secure_partition.h>
 
 #define SGI_MAP_FLASH0_RO	MAP_REGION_FLAT(V2M_FLASH0_BASE,\
@@ -139,3 +141,13 @@
 	return arm_get_mbedtls_heap(heap_addr, heap_size);
 }
 #endif
+
+void plat_arm_secure_wdt_start(void)
+{
+	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
diff --git a/plat/arm/css/sgm/include/platform_oid.h b/plat/arm/css/sgm/include/platform_oid.h
deleted file mode 100644
index fd1854a..0000000
--- a/plat/arm/css/sgm/include/platform_oid.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/board/common/board_arm_oid.h>
-
-/*
- * Required platform OIDs
- * (Provided by included header)
- */
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
index ddeac68..34e78b2 100644
--- a/plat/arm/css/sgm/sgm-common.mk
+++ b/plat/arm/css/sgm/sgm-common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,7 +12,7 @@
 				${CSS_SGM_BASE}/aarch64/css_sgm_helpers.S
 
 SECURITY_SOURCES	:=	drivers/arm/tzc/tzc_dmc500.c		\
-				plat/arm/common/arm_tzc_dmc500.c 	\
+				plat/arm/common/arm_tzc_dmc500.c	\
 				${CSS_SGM_BASE}/sgm_security.c
 
 SGM_CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a55.S		\
@@ -30,10 +30,12 @@
 
 BL1_SOURCES		+=	$(SGM_CPU_SOURCES)			\
 				${INTERCONNECT_SOURCES}			\
-				${CSS_SGM_BASE}/sgm_bl1_setup.c	\
-				${CSS_SGM_BASE}/sgm_plat_config.c
+				${CSS_SGM_BASE}/sgm_bl1_setup.c		\
+				${CSS_SGM_BASE}/sgm_plat_config.c	\
+				drivers/arm/sp805/sp805.c
 
-BL2_SOURCES		+=	${SECURITY_SOURCES}
+BL2_SOURCES		+=	${SECURITY_SOURCES}			\
+				${CSS_SGM_BASE}/sgm_plat_config.c
 
 BL2U_SOURCES		+=	${SECURITY_SOURCES}
 
@@ -41,7 +43,7 @@
 				${INTERCONNECT_SOURCES}			\
 				${SECURITY_SOURCES}			\
 				${SGM_GIC_SOURCES}			\
-				${CSS_SGM_BASE}/sgm_topology.c	\
+				${CSS_SGM_BASE}/sgm_topology.c		\
 				${CSS_SGM_BASE}/sgm_bl31_setup.c	\
 				${CSS_SGM_BASE}/sgm_plat_config.c
 
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
index 2036515..5fd9655 100644
--- a/plat/arm/css/sgm/sgm_bl1_setup.c
+++ b/plat/arm/css/sgm/sgm_bl1_setup.c
@@ -8,7 +8,8 @@
 #include <common/debug.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/arm/soc/common/soc_css.h>
-
+#include <plat/arm/common/arm_def.h>
+#include <drivers/arm/sp805.h>
 #include <sgm_plat_config.h>
 
 void bl1_early_platform_setup(void)
@@ -32,3 +33,13 @@
 	plat_arm_interconnect_enter_coherency();
 #endif
 }
+
+void plat_arm_secure_wdt_start(void)
+{
+	sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sp805_stop(ARM_SP805_TWDG_BASE);
+}
diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c
index d9e65c5..eed3631 100644
--- a/plat/arm/css/sgm/sgm_plat_config.c
+++ b/plat/arm/css/sgm/sgm_plat_config.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,7 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
+#include <plat/common/platform.h>
 #include <plat/arm/common/plat_arm.h>
 
 #include <sgm_plat_config.h>
@@ -74,9 +75,6 @@
 #if TRUSTED_BOARD_BOOT
 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
 {
-	assert(heap_addr != NULL);
-	assert(heap_size != NULL);
-
-	return arm_get_mbedtls_heap(heap_addr, heap_size);
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
 }
 #endif
diff --git a/plat/hisilicon/hikey/hikey_tbbr.c b/plat/hisilicon/hikey/hikey_tbbr.c
index 1f05d18..b7dda8d 100644
--- a/plat/hisilicon/hikey/hikey_tbbr.c
+++ b/plat/hisilicon/hikey/hikey_tbbr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,3 +29,8 @@
 {
 	return 1;
 }
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c b/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c
index 659a1c4..bcf6865 100644
--- a/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c
+++ b/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c
@@ -147,13 +147,19 @@
 
 }
 
-int hisi_test_ap_suspend_flag(unsigned int cluster)
+int hisi_test_ap_suspend_flag(void)
 {
-	unsigned int val;
+	unsigned int val1;
+	unsigned int val2;
+
+	val1 = mmio_read_32(CPUIDLE_FLAG_REG(0));
+	val1 &= AP_SUSPEND_FLAG;
 
-	val = mmio_read_32(CPUIDLE_FLAG_REG(cluster));
-	val &= AP_SUSPEND_FLAG;
-	return !!val;
+	val2 = mmio_read_32(CPUIDLE_FLAG_REG(1));
+	val2 &= AP_SUSPEND_FLAG;
+
+	val1 |= val2;
+	return (val1 != 0);
 }
 
 void hisi_set_cluster_pwdn_flag(unsigned int cluster,
@@ -164,7 +170,8 @@
 	hisi_cpuhotplug_lock(cluster, core);
 
 	val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
-	val = (value << (cluster << 1)) | (val & 0xFFFFFFF);
+	val &= ~(0x3U << ((2 * cluster) + 28));
+	val |= (value << (2 * cluster));
 	mmio_write_32(REG_SCBAKDATA3_OFFSET, val);
 
 	hisi_cpuhotplug_unlock(cluster, core);
@@ -258,6 +265,17 @@
 	return val;
 }
 
+static int check_hotplug(unsigned int cluster, unsigned int boot_flag)
+{
+	unsigned int mask = 0xF;
+
+	if (hisi_test_ap_suspend_flag() ||
+	    ((boot_flag & mask) == mask))
+		return 0;
+
+	return 1;
+}
+
 int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core)
 {
 	unsigned int mask = 0xf << (core * 4);
@@ -268,7 +286,8 @@
 	mask = (PDC_COREPWRSTAT_MASK & (~mask));
 	pdc_stat &= mask;
 
-	if ((boot_flag ^ cpuidle_flag) || pdc_stat)
+	if ((boot_flag ^ cpuidle_flag) || pdc_stat ||
+	    check_hotplug(cluster, boot_flag))
 		return 0;
 	else
 		return 1;
diff --git a/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.h b/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.h
index c0170ad..e0cb381 100644
--- a/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.h
+++ b/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.h
@@ -39,7 +39,7 @@
 int cluster_is_powered_on(unsigned int cluster);
 void hisi_enter_core_idle(unsigned int cluster, unsigned int core);
 void hisi_enter_cluster_idle(unsigned int cluster, unsigned int core);
-int hisi_test_ap_suspend_flag(unsigned int cluster);
+int hisi_test_ap_suspend_flag(void);
 void hisi_enter_ap_suspend(unsigned int cluster, unsigned int core);
 
 
diff --git a/plat/hisilicon/hikey960/hikey960_pm.c b/plat/hisilicon/hikey960/hikey960_pm.c
index 676cfa3..ede893e 100644
--- a/plat/hisilicon/hikey960/hikey960_pm.c
+++ b/plat/hisilicon/hikey960/hikey960_pm.c
@@ -228,7 +228,7 @@
 			/* check the SR flag bit to determine
 			 * CLUSTER_IDLE_IPC or AP_SR_IPC to send
 			 */
-			if (hisi_test_ap_suspend_flag(cluster))
+			if (hisi_test_ap_suspend_flag())
 				hisi_enter_ap_suspend(cluster, core);
 			else
 				hisi_enter_cluster_idle(cluster, core);
@@ -268,7 +268,7 @@
 	hisi_clear_cpuidle_flag(cluster, core);
 	hisi_cpuidle_unlock(cluster, core);
 
-	if (hisi_test_ap_suspend_flag(cluster)) {
+	if (hisi_test_ap_suspend_flag()) {
 		hikey960_sr_dma_reinit();
 		gicv2_cpuif_enable();
 		console_pl011_register(uart_base, PL011_UART_CLK_IN_HZ,
diff --git a/plat/hisilicon/hikey960/hikey960_tbbr.c b/plat/hisilicon/hikey960/hikey960_tbbr.c
index e435ec2..ed4da3b 100644
--- a/plat/hisilicon/hikey960/hikey960_tbbr.c
+++ b/plat/hisilicon/hikey960/hikey960_tbbr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,3 +29,8 @@
 {
 	return 1;
 }
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/imx/imx7/warp7/warp7_trusted_boot.c b/plat/imx/imx7/warp7/warp7_trusted_boot.c
index 8157cd5..6a00224 100644
--- a/plat/imx/imx7/warp7/warp7_trusted_boot.c
+++ b/plat/imx/imx7/warp7/warp7_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,3 +29,8 @@
 {
 	return 1;
 }
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index d50af20..d87624e 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -28,7 +28,6 @@
 				lib/xlat_tables/aarch64/xlat_tables.c		\
 				lib/xlat_tables/xlat_tables_common.c		\
 				lib/cpus/aarch64/cortex_a53.S			\
-				drivers/console/aarch64/console.S		\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 7004c56..89c2da0 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -28,7 +28,6 @@
 				lib/xlat_tables/aarch64/xlat_tables.c		\
 				lib/xlat_tables/xlat_tables_common.c		\
 				lib/cpus/aarch64/cortex_a53.S			\
-				drivers/console/aarch64/console.S		\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
diff --git a/plat/qemu/qemu_trusted_boot.c b/plat/qemu/qemu_trusted_boot.c
index 17666b9..1ef7e43 100644
--- a/plat/qemu/qemu_trusted_boot.c
+++ b/plat/qemu/qemu_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,3 +29,8 @@
 {
 	return 1;
 }
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/renesas/rcar/include/rcar_version.h b/plat/renesas/rcar/include/rcar_version.h
index e436324..ff56f92 100644
--- a/plat/renesas/rcar/include/rcar_version.h
+++ b/plat/renesas/rcar/include/rcar_version.h
@@ -9,7 +9,7 @@
 
 #include <arch_helpers.h>
 
-#define VERSION_OF_RENESAS		"2.0.1"
+#define VERSION_OF_RENESAS		"2.0.3"
 #define	VERSION_OF_RENESAS_MAXLEN	(128)
 
 extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN];
diff --git a/plat/renesas/rcar/plat_pm.c b/plat/renesas/rcar/plat_pm.c
index f41c172..e678da5 100644
--- a/plat/renesas/rcar/plat_pm.c
+++ b/plat/renesas/rcar/plat_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -35,8 +35,6 @@
 #define CLUSTER_PWR_STATE(s)	((s)->pwr_domain_state[MPIDR_AFFLVL1])
 #define CORE_PWR_STATE(s)	((s)->pwr_domain_state[MPIDR_AFFLVL0])
 
-uint64_t rcar_stack_generic_timer[5] __attribute__ ((section("data")));
-
 extern void rcar_pwrc_restore_generic_timer(uint64_t *stack);
 extern void plat_rcar_gic_driver_init(void);
 extern void plat_rcar_gic_init(void);
@@ -150,11 +148,7 @@
 	if (cluster_type == RCAR_CLUSTER_A53A57)
 		plat_cci_init();
 
-	rcar_pwrc_restore_generic_timer(rcar_stack_generic_timer);
-
-	/* start generic timer */
-	write_cntfrq_el0(plat_get_syscnt_freq2());
-	mmio_write_32(RCAR_CNTC_BASE + CNTCR_OFF, CNTCR_FCREQ(U(0)) | CNTCR_EN);
+	rcar_pwrc_restore_timer_state();
 	rcar_pwrc_setup();
 	rcar_pwrc_code_copy_to_system_ram();
 
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index ca5623d..85cbe07 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -265,7 +265,7 @@
 
 # Process RCAR_REWT_TRAINING flag
 ifndef RCAR_REWT_TRAINING
-RCAR_REWT_TRAINING := 0
+RCAR_REWT_TRAINING := 1
 endif
 $(eval $(call add_define,RCAR_REWT_TRAINING))
 
diff --git a/plat/rockchip/common/aarch32/plat_helpers.S b/plat/rockchip/common/aarch32/plat_helpers.S
new file mode 100644
index 0000000..475c297
--- /dev/null
+++ b/plat/rockchip/common/aarch32/plat_helpers.S
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a12.h>
+#include <plat_private.h>
+#include <plat_pmu_macros.S>
+
+	.globl	cpuson_entry_point
+	.globl	cpuson_flags
+	.globl	platform_cpu_warmboot
+	.globl	plat_secondary_cold_boot_setup
+	.globl	plat_report_exception
+	.globl	plat_is_my_cpu_primary
+	.globl	plat_my_core_pos
+	.globl	plat_reset_handler
+	.globl	plat_panic_handler
+
+	/*
+	 * void plat_reset_handler(void);
+	 *
+	 * Determine the SOC type and call the appropriate reset
+	 * handler.
+	 *
+	 */
+func plat_reset_handler
+	bx	lr
+endfunc plat_reset_handler
+
+func plat_my_core_pos
+	ldcopr	r0, MPIDR
+	and	r1, r0, #MPIDR_CPU_MASK
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+	and	r0, r0, #PLAT_RK_MPIDR_CLUSTER_MASK
+#else
+	and	r0, r0, #MPIDR_CLUSTER_MASK
+#endif
+	add	r0, r1, r0, LSR #PLAT_RK_CLST_TO_CPUID_SHIFT
+	bx	lr
+endfunc plat_my_core_pos
+
+	/* --------------------------------------------------------------------
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * This function performs any platform specific actions
+	 * needed for a secondary cpu after a cold reset e.g
+	 * mark the cpu's presence, mechanism to place it in a
+	 * holding pen etc.
+	 * --------------------------------------------------------------------
+	 */
+func plat_secondary_cold_boot_setup
+	/* rk3288 does not do cold boot for secondary CPU */
+cb_panic:
+	b	cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+func plat_is_my_cpu_primary
+	ldcopr	r0, MPIDR
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+	ldr	r1, =(PLAT_RK_MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+#else
+	ldr	r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+#endif
+	and	r0, r1
+	cmp	r0, #PLAT_RK_PRIMARY_CPU
+	moveq	r0, #1
+	movne	r0, #0
+	bx	lr
+endfunc plat_is_my_cpu_primary
+
+	/* --------------------------------------------------------------------
+	 * void plat_panic_handler(void)
+	 * Call system reset function on panic. Set up an emergency stack so we
+	 * can run C functions (it only needs to last for a few calls until we
+	 * reboot anyway).
+	 * --------------------------------------------------------------------
+	 */
+func plat_panic_handler
+	bl	plat_set_my_stack
+	b	rockchip_soc_soft_reset
+endfunc plat_panic_handler
+
+	/* --------------------------------------------------------------------
+	 * void platform_cpu_warmboot (void);
+	 * cpus online or resume entrypoint
+	 * --------------------------------------------------------------------
+	 */
+func platform_cpu_warmboot _align=16
+	push	{ r4 - r7, lr }
+	ldcopr	r0, MPIDR
+	and	r5, r0, #MPIDR_CPU_MASK
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+	and	r6, r0, #PLAT_RK_MPIDR_CLUSTER_MASK
+#else
+	and	r6, r0, #MPIDR_CLUSTER_MASK
+#endif
+	mov	r0, r6
+
+	func_rockchip_clst_warmboot
+	/* --------------------------------------------------------------------
+	 * big cluster id is 1
+	 * big cores id is from 0-3, little cores id 4-7
+	 * --------------------------------------------------------------------
+	 */
+	add	r7, r5, r6, LSR #PLAT_RK_CLST_TO_CPUID_SHIFT
+	/* --------------------------------------------------------------------
+	 * get per cpuup flag
+         * --------------------------------------------------------------------
+	 */
+	ldr	r4, =cpuson_flags
+	add	r4, r4, r7, lsl #2
+	ldr	r1, [r4]
+	/* --------------------------------------------------------------------
+	 * check cpuon reason
+         * --------------------------------------------------------------------
+	 */
+	cmp	r1, #PMU_CPU_AUTO_PWRDN
+	beq	boot_entry
+	cmp	r1, #PMU_CPU_HOTPLUG
+	beq	boot_entry
+	/* --------------------------------------------------------------------
+	 * If the boot core cpuson_flags or cpuson_entry_point is not
+	 * expection. force the core into wfe.
+	 * --------------------------------------------------------------------
+	 */
+wfe_loop:
+	wfe
+	b	wfe_loop
+boot_entry:
+	mov	r1, #0
+	str	r1, [r4]
+	/* --------------------------------------------------------------------
+	 * get per cpuup boot addr
+	 * --------------------------------------------------------------------
+	 */
+	ldr	r5, =cpuson_entry_point
+	ldr	r2, [r5, r7, lsl #2] /* ehem. #3 */
+	pop	{ r4 - r7, lr }
+
+	bx	r2
+endfunc platform_cpu_warmboot
+
+	/* --------------------------------------------------------------------
+	 * Per-CPU Secure entry point - resume or power up
+	 * --------------------------------------------------------------------
+	 */
+	.section tzfw_coherent_mem, "a"
+	.align  3
+cpuson_entry_point:
+	.rept	PLATFORM_CORE_COUNT
+	.quad	0
+	.endr
+cpuson_flags:
+	.rept	PLATFORM_CORE_COUNT
+	.word	0
+	.endr
+rockchip_clst_warmboot_data
diff --git a/plat/rockchip/common/aarch32/platform_common.c b/plat/rockchip/common/aarch32/platform_common.c
new file mode 100644
index 0000000..9030951
--- /dev/null
+++ b/plat/rockchip/common/aarch32/platform_common.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables.h>
+
+#include <plat_private.h>
+
+void plat_configure_mmu_svc_mon(unsigned long total_base,
+				unsigned long total_size,
+				unsigned long ro_start,
+				unsigned long ro_limit,
+				unsigned long coh_start,
+				unsigned long coh_limit)
+{
+	mmap_add_region(total_base, total_base, total_size,
+			MT_MEMORY | MT_RW | MT_SECURE);
+	mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
+			MT_MEMORY | MT_RO | MT_SECURE);
+	mmap_add_region(coh_start, coh_start, coh_limit - coh_start,
+			MT_DEVICE | MT_RW | MT_SECURE);
+	mmap_add(plat_rk_mmap);
+	rockchip_plat_mmu_svc_mon();
+	init_xlat_tables();
+	enable_mmu_svc_mon(0);
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return SYS_COUNTER_FREQ_IN_TICKS;
+}
+
+/*
+ * generic pm code does cci handling, but rockchip arm32 platforms
+ * have ever only 1 cluster, so nothing to do.
+ */
+void plat_cci_init(void)
+{
+}
+
+void plat_cci_enable(void)
+{
+}
+
+void plat_cci_disable(void)
+{
+}
diff --git a/plat/rockchip/common/aarch32/pmu_sram_cpus_on.S b/plat/rockchip/common/aarch32/pmu_sram_cpus_on.S
new file mode 100644
index 0000000..a05ae54
--- /dev/null
+++ b/plat/rockchip/common/aarch32/pmu_sram_cpus_on.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+	.globl pmu_cpuson_entrypoint
+	.macro pmusram_entry_func _name
+	.section .pmusram.entry, "ax"
+	.type \_name, %function
+	.cfi_startproc
+	\_name:
+	.endm
+
+pmusram_entry_func pmu_cpuson_entrypoint
+
+#if PSRAM_CHECK_WAKEUP_CPU
+check_wake_cpus:
+	ldcopr	r0, MPIDR
+	and	r1, r0, #MPIDR_CPU_MASK
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+	and	r0, r0, #PLAT_RK_MPIDR_CLUSTER_MASK
+#else
+	and	r0, r0, #MPIDR_CLUSTER_MASK
+#endif
+	orr	r0, r0, r1
+
+	/* primary_cpu */
+	ldr	r1, boot_mpidr
+	cmp	r0, r1
+	beq	sys_wakeup
+
+	/*
+	 * If the core is not the primary cpu,
+	 * force the core into wfe.
+	 */
+wfe_loop:
+	wfe
+	b	wfe_loop
+sys_wakeup:
+#endif
+
+#if PSRAM_DO_DDR_RESUME
+ddr_resume:
+	ldr	r2, =__bl32_sram_stack_end
+	mov     sp, r2
+	bl	dmc_resume
+#endif
+	bl	sram_restore
+sys_resume:
+	bl	sp_min_warm_entrypoint
+endfunc pmu_cpuson_entrypoint
diff --git a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S b/plat/rockchip/common/aarch64/pmu_sram_cpus_on.S
similarity index 100%
rename from plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
rename to plat/rockchip/common/aarch64/pmu_sram_cpus_on.S
diff --git a/plat/rockchip/common/drivers/pmu/pmu_com.h b/plat/rockchip/common/drivers/pmu/pmu_com.h
index 4b4b00f..5359f73 100644
--- a/plat/rockchip/common/drivers/pmu/pmu_com.h
+++ b/plat/rockchip/common/drivers/pmu/pmu_com.h
@@ -88,6 +88,17 @@
 		cluster_id = 0;
 	}
 
+	/*
+	 * wfe/wfi tracking not possible, hopefully the host
+	 * was sucessful in enabling wfe/wfi.
+	 * We'll give a bit of additional time, like the kernel does.
+	 */
+	if ((cluster_id && clstb_cpu_wfe < 0) ||
+	    (!cluster_id && clstl_cpu_wfe < 0)) {
+		mdelay(1);
+		return 0;
+	}
+
 	if (cluster_id)
 		wfie_msk <<= (clstb_cpu_wfe + cpu_id);
 	else
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index e8750a5..f9470e5 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -68,6 +68,16 @@
 /******************************************************************************
  * Function and variable prototypes
  *****************************************************************************/
+#ifdef AARCH32
+void plat_configure_mmu_svc_mon(unsigned long total_base,
+				unsigned long total_size,
+				unsigned long,
+				unsigned long,
+				unsigned long,
+				unsigned long);
+
+void rockchip_plat_mmu_svc_mon(void);
+#else
 void plat_configure_mmu_el3(unsigned long total_base,
 			    unsigned long total_size,
 			    unsigned long,
@@ -75,6 +85,9 @@
 			    unsigned long,
 			    unsigned long);
 
+void rockchip_plat_mmu_el3(void);
+#endif
+
 void plat_cci_init(void);
 void plat_cci_enable(void);
 void plat_cci_disable(void);
@@ -128,13 +141,11 @@
 extern const unsigned char rockchip_power_domain_tree_desc[];
 
 extern void *pmu_cpuson_entrypoint;
-extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT];
+extern u_register_t cpuson_entry_point[PLATFORM_CORE_COUNT];
 extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
 
 extern const mmap_region_t plat_rk_mmap[];
 
-void rockchip_plat_mmu_el3(void);
-
 #endif /* __ASSEMBLY__ */
 
 /******************************************************************************
diff --git a/plat/rockchip/common/plat_topology.c b/plat/rockchip/common/plat_topology.c
index a31e410..4987eeb 100644
--- a/plat/rockchip/common/plat_topology.c
+++ b/plat/rockchip/common/plat_topology.c
@@ -24,7 +24,11 @@
 	unsigned int cluster_id, cpu_id;
 
 	cpu_id = mpidr & MPIDR_AFFLVL_MASK;
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+	cluster_id = mpidr & PLAT_RK_MPIDR_CLUSTER_MASK;
+#else
 	cluster_id = mpidr & MPIDR_CLUSTER_MASK;
+#endif
 
 	cpu_id += (cluster_id >> PLAT_RK_CLST_TO_CPUID_SHIFT);
 
diff --git a/plat/rockchip/common/sp_min_plat_setup.c b/plat/rockchip/common/sp_min_plat_setup.c
new file mode 100644
index 0000000..7250919
--- /dev/null
+++ b/plat/rockchip/common/sp_min_plat_setup.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/coreboot.h>
+#include <lib/mmio.h>
+#include <plat_private.h>
+#include <plat/common/platform.h>
+
+static entry_point_info_t bl33_ep_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.
+ * A NULL pointer is returned if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
+{
+	entry_point_info_t *next_image_info;
+
+	next_image_info = &bl33_ep_info;
+
+	if (next_image_info->pc == 0U) {
+		return NULL;
+	}
+
+	return next_image_info;
+}
+
+#pragma weak params_early_setup
+void params_early_setup(void *plat_param_from_bl2)
+{
+}
+
+unsigned int plat_is_my_cpu_primary(void);
+
+/*******************************************************************************
+ * Perform any BL32 specific platform actions.
+ ******************************************************************************/
+void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				  u_register_t arg2, u_register_t arg3)
+{
+	static console_16550_t console;
+	struct rockchip_bl31_params *arg_from_bl2 = (struct rockchip_bl31_params *) arg0;
+	void *plat_params_from_bl2 = (void *) arg1;
+
+	params_early_setup(plat_params_from_bl2);
+
+#if COREBOOT
+	if (coreboot_serial.type)
+		console_16550_register(coreboot_serial.baseaddr,
+				       coreboot_serial.input_hertz,
+				       coreboot_serial.baud,
+				       &console);
+#else
+	console_16550_register(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK,
+			       PLAT_RK_UART_BAUDRATE, &console);
+#endif
+	VERBOSE("sp_min_setup\n");
+
+	/* Passing a NULL context is a critical programming error */
+	assert(arg_from_bl2);
+
+	assert(arg_from_bl2->h.type == PARAM_BL31);
+	assert(arg_from_bl2->h.version >= VERSION_1);
+
+	bl33_ep_info = *arg_from_bl2->bl33_ep_info;
+}
+
+/*******************************************************************************
+ * Perform any sp_min platform setup code
+ ******************************************************************************/
+void sp_min_platform_setup(void)
+{
+	generic_delay_timer_init();
+	plat_rockchip_soc_init();
+
+	/* Initialize the gic cpu and distributor interfaces */
+	plat_rockchip_gic_driver_init();
+	plat_rockchip_gic_init();
+	plat_rockchip_pmu_init();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void sp_min_plat_arch_setup(void)
+{
+	plat_cci_init();
+	plat_cci_enable();
+
+	plat_configure_mmu_svc_mon(BL_CODE_BASE,
+				   BL_COHERENT_RAM_END - BL_CODE_BASE,
+				   BL_CODE_BASE,
+				   BL_CODE_END,
+				   BL_COHERENT_RAM_BASE,
+				   BL_COHERENT_RAM_END);
+}
+
+void sp_min_plat_fiq_handler(uint32_t id)
+{
+	VERBOSE("[sp_min] interrupt #%d\n", id);
+}
diff --git a/plat/rockchip/rk3288/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3288/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 0000000..2003749
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+.macro	func_rockchip_clst_warmboot
+	/* Nothing to do for rk3288 */
+.endm
+
+.macro rockchip_clst_warmboot_data
+	/* Nothing to do for rk3288 */
+.endm
diff --git a/plat/rockchip/rk3288/drivers/pmu/pmu.c b/plat/rockchip/rk3288/drivers/pmu/pmu.c
new file mode 100644
index 0000000..d6d7098
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/pmu/pmu.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+
+#include <plat_private.h>
+#include <pmu.h>
+#include <pmu_com.h>
+#include <rk3288_def.h>
+#include <secure.h>
+#include <soc.h>
+
+DEFINE_BAKERY_LOCK(rockchip_pd_lock);
+
+static uint32_t cpu_warm_boot_addr;
+
+static uint32_t store_pmu_pwrmode_con;
+static uint32_t store_sgrf_soc_con0;
+static uint32_t store_sgrf_cpu_con0;
+
+/* These enum are variants of low power mode */
+enum {
+	ROCKCHIP_ARM_OFF_LOGIC_NORMAL = 0,
+	ROCKCHIP_ARM_OFF_LOGIC_DEEP = 1,
+};
+
+static inline int rk3288_pmu_bus_idle(uint32_t req, uint32_t idle)
+{
+	uint32_t mask = BIT(req);
+	uint32_t idle_mask = 0;
+	uint32_t idle_target = 0;
+	uint32_t val;
+	uint32_t wait_cnt = 0;
+
+	switch (req) {
+	case bus_ide_req_gpu:
+		idle_mask = BIT(pmu_idle_ack_gpu) | BIT(pmu_idle_gpu);
+		idle_target = (idle << pmu_idle_ack_gpu) |
+			      (idle << pmu_idle_gpu);
+		break;
+	case bus_ide_req_core:
+		idle_mask = BIT(pmu_idle_ack_core) | BIT(pmu_idle_core);
+		idle_target = (idle << pmu_idle_ack_core) |
+			      (idle << pmu_idle_core);
+		break;
+	case bus_ide_req_cpup:
+		idle_mask = BIT(pmu_idle_ack_cpup) | BIT(pmu_idle_cpup);
+		idle_target = (idle << pmu_idle_ack_cpup) |
+			      (idle << pmu_idle_cpup);
+		break;
+	case bus_ide_req_bus:
+		idle_mask = BIT(pmu_idle_ack_bus) | BIT(pmu_idle_bus);
+		idle_target = (idle << pmu_idle_ack_bus) |
+			      (idle << pmu_idle_bus);
+		break;
+	case bus_ide_req_dma:
+		idle_mask = BIT(pmu_idle_ack_dma) | BIT(pmu_idle_dma);
+		idle_target = (idle << pmu_idle_ack_dma) |
+			      (idle << pmu_idle_dma);
+		break;
+	case bus_ide_req_peri:
+		idle_mask = BIT(pmu_idle_ack_peri) | BIT(pmu_idle_peri);
+		idle_target = (idle << pmu_idle_ack_peri) |
+			      (idle << pmu_idle_peri);
+		break;
+	case bus_ide_req_video:
+		idle_mask = BIT(pmu_idle_ack_video) | BIT(pmu_idle_video);
+		idle_target = (idle << pmu_idle_ack_video) |
+			      (idle << pmu_idle_video);
+		break;
+	case bus_ide_req_hevc:
+		idle_mask = BIT(pmu_idle_ack_hevc) | BIT(pmu_idle_hevc);
+		idle_target = (idle << pmu_idle_ack_hevc) |
+			      (idle << pmu_idle_hevc);
+		break;
+	case bus_ide_req_vio:
+		idle_mask = BIT(pmu_idle_ack_vio) | BIT(pmu_idle_vio);
+		idle_target = (pmu_idle_ack_vio) |
+			      (idle << pmu_idle_vio);
+		break;
+	case bus_ide_req_alive:
+		idle_mask = BIT(pmu_idle_ack_alive) | BIT(pmu_idle_alive);
+		idle_target = (idle << pmu_idle_ack_alive) |
+			      (idle << pmu_idle_alive);
+		break;
+	default:
+		ERROR("%s: Unsupported the idle request\n", __func__);
+		break;
+	}
+
+	val = mmio_read_32(PMU_BASE + PMU_BUS_IDE_REQ);
+	if (idle)
+		val |= mask;
+	else
+		val &= ~mask;
+
+	mmio_write_32(PMU_BASE + PMU_BUS_IDE_REQ, val);
+
+	while ((mmio_read_32(PMU_BASE +
+	       PMU_BUS_IDE_ST) & idle_mask) != idle_target) {
+		wait_cnt++;
+		if (!(wait_cnt % MAX_WAIT_CONUT))
+			WARN("%s:st=%x(%x)\n", __func__,
+			     mmio_read_32(PMU_BASE + PMU_BUS_IDE_ST),
+			     idle_mask);
+	}
+
+	return 0;
+}
+
+static bool rk3288_sleep_disable_osc(void)
+{
+	static const uint32_t reg_offset[] = { GRF_UOC0_CON0, GRF_UOC1_CON0,
+					       GRF_UOC2_CON0 };
+	uint32_t reg, i;
+
+	/*
+	 * if any usb phy is still on(GRF_SIDDQ==0), that means we need the
+	 * function of usb wakeup, so do not switch to 32khz, since the usb phy
+	 * clk does not connect to 32khz osc
+	 */
+	for (i = 0; i < ARRAY_SIZE(reg_offset); i++) {
+		reg = mmio_read_32(GRF_BASE + reg_offset[i]);
+		if (!(reg & GRF_SIDDQ))
+			return false;
+	}
+
+	return true;
+}
+
+static void pmu_set_sleep_mode(int level)
+{
+	uint32_t mode_set, mode_set1;
+	bool osc_disable = rk3288_sleep_disable_osc();
+
+	mode_set = BIT(pmu_mode_glb_int_dis) | BIT(pmu_mode_l2_flush_en) |
+		   BIT(pmu_mode_sref0_enter) | BIT(pmu_mode_sref1_enter) |
+		   BIT(pmu_mode_ddrc0_gt) | BIT(pmu_mode_ddrc1_gt) |
+		   BIT(pmu_mode_en) | BIT(pmu_mode_chip_pd) |
+		   BIT(pmu_mode_scu_pd);
+
+	mode_set1 = BIT(pmu_mode_clr_core) | BIT(pmu_mode_clr_cpup);
+
+	if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) {
+		/* arm off, logic deep sleep */
+		mode_set |= BIT(pmu_mode_bus_pd) | BIT(pmu_mode_pmu_use_lf) |
+			    BIT(pmu_mode_ddrio1_ret) |
+			    BIT(pmu_mode_ddrio0_ret) |
+			    BIT(pmu_mode_pmu_alive_use_lf) |
+			    BIT(pmu_mode_pll_pd);
+
+		if (osc_disable)
+			mode_set |= BIT(pmu_mode_osc_dis);
+
+		mode_set1 |= BIT(pmu_mode_clr_alive) | BIT(pmu_mode_clr_bus) |
+			     BIT(pmu_mode_clr_peri) | BIT(pmu_mode_clr_dma);
+
+		mmio_write_32(PMU_BASE + PMU_WAKEUP_CFG1,
+			      pmu_armint_wakeup_en);
+
+		/*
+		 * In deep suspend we use PMU_PMU_USE_LF to let the rk3288
+		 * switch its main clock supply to the alternative 32kHz
+		 * source. Therefore set 30ms on a 32kHz clock for pmic
+		 * stabilization. Similar 30ms on 24MHz for the other
+		 * mode below.
+		 */
+		mmio_write_32(PMU_BASE + PMU_STABL_CNT, 32 * 30);
+
+		/* only wait for stabilization, if we turned the osc off */
+		mmio_write_32(PMU_BASE + PMU_OSC_CNT,
+					 osc_disable ? 32 * 30 : 0);
+	} else {
+		/*
+		 * arm off, logic normal
+		 * if pmu_clk_core_src_gate_en is not set,
+		 * wakeup will be error
+		 */
+		mode_set |= BIT(pmu_mode_core_src_gt);
+
+		mmio_write_32(PMU_BASE + PMU_WAKEUP_CFG1,
+			      BIT(pmu_armint_wakeup_en) |
+			      BIT(pmu_gpioint_wakeup_en));
+
+		/* 30ms on a 24MHz clock for pmic stabilization */
+		mmio_write_32(PMU_BASE + PMU_STABL_CNT, 24000 * 30);
+
+		/* oscillator is still running, so no need to wait */
+		mmio_write_32(PMU_BASE + PMU_OSC_CNT, 0);
+	}
+
+	mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, mode_set);
+	mmio_write_32(PMU_BASE + PMU_PWRMODE_CON1, mode_set1);
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+	uint32_t cpu_pd;
+
+	cpu_pd = PD_CPU0 + cpu_id;
+
+	/* if the core has been on, power it off first */
+	if (pmu_power_domain_st(cpu_pd) == pmu_pd_on) {
+		/* put core in reset - some sort of A12/A17 bug */
+		mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(0),
+			      BIT(cpu_id) | (BIT(cpu_id) << 16));
+
+		pmu_power_domain_ctr(cpu_pd, pmu_pd_off);
+	}
+
+	pmu_power_domain_ctr(cpu_pd, pmu_pd_on);
+
+	/* pull core out of reset */
+	mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(0), BIT(cpu_id) << 16);
+
+	return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id)
+{
+	uint32_t cpu_pd = PD_CPU0 + cpu_id;
+
+	if (pmu_power_domain_st(cpu_pd) == pmu_pd_off)
+		return 0;
+
+	if (check_cpu_wfie(cpu_id, CKECK_WFEI_MSK))
+		return -EINVAL;
+
+	/* put core in reset - some sort of A12/A17 bug */
+	mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(0),
+		      BIT(cpu_id) | (BIT(cpu_id) << 16));
+
+	pmu_power_domain_ctr(cpu_pd, pmu_pd_off);
+
+	return 0;
+}
+
+static void nonboot_cpus_off(void)
+{
+	uint32_t boot_cpu, cpu;
+
+	boot_cpu = plat_my_core_pos();
+	boot_cpu = MPIDR_AFFLVL0_VAL(read_mpidr());
+
+	/* turn off noboot cpus */
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
+		if (cpu == boot_cpu)
+			continue;
+
+		cpus_power_domain_off(cpu);
+	}
+}
+
+void sram_save(void)
+{
+	/* TODO: support the sdram save for rk3288 SoCs*/
+}
+
+void sram_restore(void)
+{
+	/* TODO: support the sdram restore for rk3288 SoCs */
+}
+
+int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
+{
+	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+
+	assert(cpu_id < PLATFORM_CORE_COUNT);
+	assert(cpuson_flags[cpu_id] == 0);
+	cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+	cpuson_entry_point[cpu_id] = entrypoint;
+	dsb();
+
+	cpus_power_domain_on(cpu_id);
+
+	/*
+	 * We communicate with the bootrom to active the cpus other
+	 * than cpu0, after a blob of initialize code, they will
+	 * stay at wfe state, once they are actived, they will check
+	 * the mailbox:
+	 * sram_base_addr + 4: 0xdeadbeaf
+	 * sram_base_addr + 8: start address for pc
+	 * The cpu0 need to wait the other cpus other than cpu0 entering
+	 * the wfe state.The wait time is affected by many aspects.
+	 * (e.g: cpu frequency, bootrom frequency, sram frequency, ...)
+	 */
+	mdelay(1); /* ensure the cpus other than cpu0 to startup */
+
+	/* tell the bootrom mailbox where to start from */
+	mmio_write_32(SRAM_BASE + 8, cpu_warm_boot_addr);
+	mmio_write_32(SRAM_BASE + 4, 0xDEADBEAF);
+	dsb();
+	sev();
+
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+	mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, store_pmu_pwrmode_con);
+	mmio_write_32(SGRF_BASE + SGRF_CPU_CON(0),
+		      store_sgrf_cpu_con0 | SGRF_DAPDEVICE_MSK);
+
+	/* disable fastboot mode */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0),
+		      store_sgrf_soc_con0 | SGRF_FAST_BOOT_DIS);
+
+	secure_watchdog_ungate();
+	clk_gate_con_restore();
+	clk_sel_con_restore();
+	clk_plls_resume();
+
+	secure_gic_init();
+	plat_rockchip_gic_init();
+
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+	nonboot_cpus_off();
+
+	store_sgrf_cpu_con0 = mmio_read_32(SGRF_BASE + SGRF_CPU_CON(0));
+	store_sgrf_soc_con0 = mmio_read_32(SGRF_BASE + SGRF_SOC_CON(0));
+	store_pmu_pwrmode_con = mmio_read_32(PMU_BASE + PMU_PWRMODE_CON);
+
+	/* save clk-gates and ungate all for suspend */
+	clk_gate_con_save();
+	clk_gate_con_disable();
+	clk_sel_con_save();
+
+	pmu_set_sleep_mode(ROCKCHIP_ARM_OFF_LOGIC_NORMAL);
+
+	clk_plls_suspend();
+	secure_watchdog_gate();
+
+	/*
+	 * The dapswjdp can not auto reset before resume, that cause it may
+	 * access some illegal address during resume. Let's disable it before
+	 * suspend, and the MASKROM will enable it back.
+	 */
+	mmio_write_32(SGRF_BASE + SGRF_CPU_CON(0), SGRF_DAPDEVICE_MSK);
+
+	/*
+	 * SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
+	 */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0), SGRF_FAST_BOOT_ENA);
+
+	/* boot-address of resuming system is from this register value */
+	mmio_write_32(SGRF_BASE + SGRF_FAST_BOOT_ADDR,
+		      (uint32_t)&pmu_cpuson_entrypoint);
+
+	/* flush all caches - otherwise we might loose the resume address */
+	dcsw_op_all(DC_OP_CISW);
+
+	return 0;
+}
+
+void rockchip_plat_mmu_svc_mon(void)
+{
+}
+
+void plat_rockchip_pmu_init(void)
+{
+	uint32_t cpu;
+
+	cpu_warm_boot_addr = (uint32_t)platform_cpu_warmboot;
+
+	/* on boot all power-domains are on */
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+		cpuson_flags[cpu] = pmu_pd_on;
+
+	nonboot_cpus_off();
+}
diff --git a/plat/rockchip/rk3288/drivers/pmu/pmu.h b/plat/rockchip/rk3288/drivers/pmu/pmu.h
new file mode 100644
index 0000000..06d5528
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/pmu/pmu.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMU_H
+#define PMU_H
+
+/* Allocate sp reginon in pmusram */
+#define PSRAM_SP_SIZE		0x80
+#define PSRAM_SP_BOTTOM		(PSRAM_SP_TOP - PSRAM_SP_SIZE)
+
+/*****************************************************************************
+ * pmu con,reg
+ *****************************************************************************/
+#define PMU_WAKEUP_CFG0		0x0
+#define PMU_WAKEUP_CFG1		0x4
+#define PMU_PWRDN_CON		0x8
+#define PMU_PWRDN_ST		0xc
+
+#define PMU_PWRMODE_CON		0x18
+#define PMU_BUS_IDE_REQ		0x10
+#define PMU_BUS_IDE_ST		0x14
+
+#define PMU_OSC_CNT		0x20
+#define PMU_PLL_CNT		0x24
+#define PMU_STABL_CNT		0x28
+#define PMU_DDRIO0_PWR_CNT	0x2c
+#define PMU_DDRIO1_PWR_CNT	0x30
+#define PMU_WKUPRST_CNT		0x44
+#define PMU_SFT_CON		0x48
+#define PMU_PWRMODE_CON1	0x90
+
+enum pmu_pdid {
+	PD_CPU0 = 0,
+	PD_CPU1,
+	PD_CPU2,
+	PD_CPU3,
+	PD_BUS = 5,
+	PD_PERI,
+	PD_VIO,
+	PD_VIDEO,
+	PD_GPU,
+	PD_SCU = 11,
+	PD_HEVC = 14,
+	PD_END
+};
+
+enum pmu_bus_ide {
+	bus_ide_req_bus = 0,
+	bus_ide_req_peri,
+	bus_ide_req_gpu,
+	bus_ide_req_video,
+	bus_ide_req_vio,
+	bus_ide_req_core,
+	bus_ide_req_alive,
+	bus_ide_req_dma,
+	bus_ide_req_cpup,
+	bus_ide_req_hevc,
+	bus_ide_req_end
+};
+
+enum pmu_pwrmode {
+	pmu_mode_en = 0,
+	pmu_mode_core_src_gt,
+	pmu_mode_glb_int_dis,
+	pmu_mode_l2_flush_en,
+	pmu_mode_bus_pd,
+	pmu_mode_cpu0_pd,
+	pmu_mode_scu_pd,
+	pmu_mode_pll_pd = 7,
+	pmu_mode_chip_pd,
+	pmu_mode_pwr_off_comb,
+	pmu_mode_pmu_alive_use_lf,
+	pmu_mode_pmu_use_lf,
+	pmu_mode_osc_dis = 12,
+	pmu_mode_input_clamp,
+	pmu_mode_wkup_rst,
+	pmu_mode_sref0_enter,
+	pmu_mode_sref1_enter,
+	pmu_mode_ddrio0_ret,
+	pmu_mode_ddrio1_ret,
+	pmu_mode_ddrc0_gt,
+	pmu_mode_ddrc1_gt,
+	pmu_mode_ddrio0_ret_deq,
+	pmu_mode_ddrio1_ret_deq,
+};
+
+enum pmu_pwrmode1 {
+	pmu_mode_clr_bus = 0,
+	pmu_mode_clr_core,
+	pmu_mode_clr_cpup,
+	pmu_mode_clr_alive,
+	pmu_mode_clr_dma,
+	pmu_mode_clr_peri,
+	pmu_mode_clr_gpu,
+	pmu_mode_clr_video,
+	pmu_mode_clr_hevc,
+	pmu_mode_clr_vio
+};
+
+enum pmu_sft_con {
+	pmu_sft_ddrio0_ret_cfg = 6,
+	pmu_sft_ddrio1_ret_cfg = 9,
+	pmu_sft_l2flsh = 15,
+};
+
+enum pmu_wakeup_cfg1 {
+	pmu_armint_wakeup_en = 0,
+	pmu_gpio_wakeup_negedge,
+	pmu_sdmmc0_wakeup_en,
+	pmu_gpioint_wakeup_en,
+};
+
+enum pmu_bus_idle_st {
+	pmu_idle_bus = 0,
+	pmu_idle_peri,
+	pmu_idle_gpu,
+	pmu_idle_video,
+	pmu_idle_vio,
+	pmu_idle_core,
+	pmu_idle_alive,
+	pmu_idle_dma,
+	pmu_idle_cpup,
+	pmu_idle_hevc,
+	pmu_idle_ack_bus = 16,
+	pmu_idle_ack_peri,
+	pmu_idle_ack_gpu,
+	pmu_idle_ack_video,
+	pmu_idle_ack_vio,
+	pmu_idle_ack_core,
+	pmu_idle_ack_alive,
+	pmu_idle_ack_dma,
+	pmu_idle_ack_cpup,
+	pmu_idle_ack_hevc,
+};
+
+#define CHECK_CPU_WFIE_BASE		(0)
+
+#define clstl_cpu_wfe		-1
+#define clstb_cpu_wfe		-1
+#define CKECK_WFEI_MSK		0
+
+
+#define PD_CTR_LOOP		500
+#define CHK_CPU_LOOP		500
+
+#define MAX_WAIT_CONUT 1000
+
+#endif /* PMU_H */
diff --git a/plat/rockchip/rk3288/drivers/secure/secure.c b/plat/rockchip/rk3288/drivers/secure/secure.c
new file mode 100644
index 0000000..68994e4
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/secure/secure.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+
+#include <plat_private.h>
+#include <secure.h>
+#include <soc.h>
+
+static void sgrf_ddr_rgn_global_bypass(uint32_t bypass)
+{
+	if (bypass)
+		/* set bypass (non-secure regions) for whole ddr regions */
+		mmio_write_32(SGRF_BASE + SGRF_SOC_CON(21),
+			      SGRF_DDR_RGN_BYPS);
+	else
+		/* cancel bypass for whole ddr regions */
+		mmio_write_32(SGRF_BASE + SGRF_SOC_CON(21),
+			      SGRF_DDR_RGN_NO_BYPS);
+}
+
+/**
+ * There are 8 + 1 regions for DDR secure control:
+ * DDR_RGN_0 ~ DDR_RGN_7: Per DDR_RGNs grain size is 1MB
+ * DDR_RGN_X - the memories of exclude DDR_RGN_0 ~ DDR_RGN_7
+ *
+ * SGRF_SOC_CON6 - start address of RGN_0 + control
+ * SGRF_SOC_CON7 - end address of RGN_0
+ * ...
+ * SGRF_SOC_CON20 - start address of the RGN_7 + control
+ * SGRF_SOC_CON21 - end address of the RGN_7 + RGN_X control
+ *
+ * @rgn - the DDR regions 0 ~ 7 which are can be configured.
+ * The @st and @ed indicate the start and end addresses for which to set
+ * the security, and the unit is byte. When the st_mb == 0, ed_mb == 0, the
+ * address range 0x0 ~ 0xfffff is secure.
+ *
+ * For example, if we would like to set the range [0, 32MB) is security via
+ * DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31.
+ */
+static void sgrf_ddr_rgn_config(uint32_t rgn, uintptr_t st, uintptr_t ed)
+{
+	uintptr_t st_mb, ed_mb;
+
+	assert(rgn <= 7);
+	assert(st < ed);
+
+	/* check aligned 1MB */
+	assert(st % SIZE_M(1) == 0);
+	assert(ed % SIZE_M(1) == 0);
+
+	st_mb = st / SIZE_M(1);
+	ed_mb = ed / SIZE_M(1);
+
+	/* set ddr region addr start */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2)),
+		      BITS_WITH_WMASK(st_mb, SGRF_DDR_RGN_ADDR_WMSK, 0));
+
+	/* set ddr region addr end */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2) + 1),
+		      BITS_WITH_WMASK((ed_mb - 1), SGRF_DDR_RGN_ADDR_WMSK, 0));
+
+	/* select region security */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2)),
+		      SGRF_DDR_RGN_SECURE_SEL);
+
+	/* enable region security */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2)),
+		      SGRF_DDR_RGN_SECURE_EN);
+}
+
+void secure_watchdog_gate(void)
+{
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0), SGRF_PCLK_WDT_GATE);
+}
+
+void secure_watchdog_ungate(void)
+{
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0), SGRF_PCLK_WDT_UNGATE);
+}
+
+__pmusramfunc void sram_secure_timer_init(void)
+{
+	mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, 0);
+
+	mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT1, 0xffffffff);
+
+	/* auto reload & enable the timer */
+	mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, TIMER_EN);
+}
+
+void secure_gic_init(void)
+{
+	/* (re-)enable non-secure access to the gic*/
+	mmio_write_32(CORE_AXI_BUS_BASE + CORE_AXI_SECURITY0,
+		      AXI_SECURITY0_GIC);
+}
+
+void secure_timer_init(void)
+{
+	mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, 0);
+
+	mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT1, 0xffffffff);
+
+	/* auto reload & enable the timer */
+	mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, TIMER_EN);
+}
+
+void secure_sgrf_init(void)
+{
+	/*
+	 * We use the first sram part to talk to the bootrom,
+	 * so make it secure.
+	 */
+	mmio_write_32(TZPC_BASE + TZPC_R0SIZE, TZPC_SRAM_SECURE_4K(1));
+
+	secure_gic_init();
+
+	/* set all master ip to non-secure */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2), SGRF_SOC_CON2_MST_NS);
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), SGRF_SOC_CON3_MST_NS);
+
+	/* setting all configurable ip into non-secure */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4),
+		      SGRF_SOC_CON4_SECURE_WMSK /*TODO:|SGRF_STIMER_SECURE*/);
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SOC_CON5_SECURE_WMSK);
+
+	/* secure dma to non-secure */
+	mmio_write_32(TZPC_BASE + TZPC_DECPROT1SET, 0xff);
+	mmio_write_32(TZPC_BASE + TZPC_DECPROT2SET, 0xff);
+	mmio_write_32(SGRF_BASE + SGRF_BUSDMAC_CON(1), 0x3800);
+	dsb();
+
+	/* rst dma1 */
+	mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(1),
+		      RST_DMA1_MSK | (RST_DMA1_MSK << 16));
+	/* rst dma2 */
+	mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(4),
+		      RST_DMA2_MSK | (RST_DMA2_MSK << 16));
+
+	dsb();
+
+	/* release dma1 rst*/
+	mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(1), (RST_DMA1_MSK << 16));
+	/* release dma2 rst*/
+	mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(4), (RST_DMA2_MSK << 16));
+}
+
+void secure_sgrf_ddr_rgn_init(void)
+{
+	sgrf_ddr_rgn_config(0, TZRAM_BASE, TZRAM_SIZE);
+	sgrf_ddr_rgn_global_bypass(0);
+}
diff --git a/plat/rockchip/rk3288/drivers/secure/secure.h b/plat/rockchip/rk3288/drivers/secure/secure.h
new file mode 100644
index 0000000..6c0b2b7
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/secure/secure.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURE_H
+#define SECURE_H
+
+/******************************************************************************
+ * TZPC TrustZone controller
+ ******************************************************************************/
+
+#define TZPC_R0SIZE			0x0
+#define TZPC_SRAM_SECURE_4K(n)		((n) > 0x200 ? 0x200 : (n))
+#define TZPC_DECPROT1STAT		0x80c
+#define TZPC_DECPROT1SET		0x810
+#define TZPC_DECPROT1CLR		0x814
+#define TZPC_DECPROT2STAT		0x818
+#define TZPC_DECPROT2SET		0x818
+#define TZPC_DECPROT2CLR		0x820
+
+/**************************************************
+ * sgrf reg, offset
+ **************************************************/
+/*
+ * soc_con0-5 start at 0x0, soc_con6-... start art 0x50
+ * adjusted for the 5 lower registers
+ */
+#define SGRF_SOC_CON(n)			((((n) < 6) ? 0x0 : 0x38) + (n) * 4)
+#define SGRF_BUSDMAC_CON(n)		(0x20 + (n) * 4)
+#define SGRF_CPU_CON(n)			(0x40 + (n) * 4)
+#define SGRF_SOC_STATUS(n)		(0x100 + (n) * 4)
+#define SGRF_FAST_BOOT_ADDR		0x120
+
+/* SGRF_SOC_CON0 */
+#define SGRF_FAST_BOOT_ENA		BIT_WITH_WMSK(8)
+#define SGRF_FAST_BOOT_DIS		WMSK_BIT(8)
+#define SGRF_PCLK_WDT_GATE		BIT_WITH_WMSK(6)
+#define SGRF_PCLK_WDT_UNGATE		WMSK_BIT(6)
+#define SGRF_PCLK_STIMER_GATE		BIT_WITH_WMSK(4)
+
+#define SGRF_SOC_CON2_MST_NS		0xffe0ffe0
+#define SGRF_SOC_CON3_MST_NS		0x003f003f
+
+/* SGRF_SOC_CON4 */
+#define SGRF_SOC_CON4_SECURE_WMSK	0xffff0000
+#define SGRF_DDRC1_SECURE		BIT_WITH_WMSK(12)
+#define SGRF_DDRC0_SECURE		BIT_WITH_WMSK(11)
+#define SGRF_PMUSRAM_SECURE		BIT_WITH_WMSK(8)
+#define SGRF_WDT_SECURE			BIT_WITH_WMSK(7)
+#define SGRF_STIMER_SECURE		BIT_WITH_WMSK(6)
+
+/* SGRF_SOC_CON5 */
+#define SGRF_SLV_SEC_BYPS		BIT_WITH_WMSK(15)
+#define SGRF_SLV_SEC_NO_BYPS		WMSK_BIT(15)
+#define SGRF_SOC_CON5_SECURE_WMSK	0x00ff0000
+
+/* ddr regions in SGRF_SOC_CON6 and following */
+#define SGRF_DDR_RGN_SECURE_SEL		BIT_WITH_WMSK(15)
+#define SGRF_DDR_RGN_SECURE_EN		BIT_WITH_WMSK(14)
+#define SGRF_DDR_RGN_ADDR_WMSK		0x0fff
+
+/* SGRF_SOC_CON21 */
+/* All security of the DDR RGNs are bypassed */
+#define SGRF_DDR_RGN_BYPS		BIT_WITH_WMSK(15)
+#define SGRF_DDR_RGN_NO_BYPS		WMSK_BIT(15)
+
+/* SGRF_CPU_CON0 */
+#define SGRF_DAPDEVICE_ENA		BIT_WITH_WMSK(0)
+#define SGRF_DAPDEVICE_MSK		WMSK_BIT(0)
+
+/*****************************************************************************
+ * core-axi
+ *****************************************************************************/
+#define CORE_AXI_SECURITY0		0x08
+#define AXI_SECURITY0_GIC		BIT(0)
+
+/*****************************************************************************
+ * secure timer
+ *****************************************************************************/
+#define TIMER_LOAD_COUNT0		0x00
+#define TIMER_LOAD_COUNT1		0x04
+#define TIMER_CURRENT_VALUE0		0x08
+#define TIMER_CURRENT_VALUE1		0x0C
+#define TIMER_CONTROL_REG		0x10
+#define TIMER_INTSTATUS			0x18
+
+#define TIMER_EN			0x1
+
+#define STIMER1_BASE			(STIME_BASE + 0x20)
+
+/* export secure operating APIs */
+void secure_watchdog_gate(void);
+void secure_watchdog_ungate(void);
+void secure_gic_init(void);
+void secure_timer_init(void);
+void secure_sgrf_init(void);
+void secure_sgrf_ddr_rgn_init(void);
+__pmusramfunc void sram_secure_timer_init(void);
+
+#endif /* SECURE_H */
diff --git a/plat/rockchip/rk3288/drivers/soc/soc.c b/plat/rockchip/rk3288/drivers/soc/soc.c
new file mode 100644
index 0000000..db90ae4
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/soc/soc.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <plat_private.h>
+#include <rk3288_def.h>
+#include <soc.h>
+#include <secure.h>
+
+/* sleep data for pll suspend */
+static struct deepsleep_data_s slp_data;
+
+/* Table of regions to map using the MMU. */
+const mmap_region_t plat_rk_mmap[] = {
+	MAP_REGION_FLAT(GIC400_BASE, GIC400_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(STIME_BASE, STIME_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(SGRF_BASE, SGRF_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TZPC_BASE, TZPC_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(SRAM_BASE, SRAM_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(PMU_BASE, PMU_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(UART_DBG_BASE, UART_DBG_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CRU_BASE, CRU_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(GRF_BASE, GRF_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DDR_PCTL0_BASE, DDR_PCTL0_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DDR_PHY0_BASE, DDR_PHY0_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DDR_PCTL1_BASE, DDR_PCTL1_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DDR_PHY1_BASE, DDR_PHY1_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(SERVICE_BUS_BASE, SERVICE_BUS_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CORE_AXI_BUS_BASE, CORE_AXI_BUS_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	{ 0 }
+};
+
+/* The RockChip power domain tree descriptor */
+const unsigned char rockchip_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* No of children for the root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of children for the first cluster node */
+	PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+void plat_rockchip_soc_init(void)
+{
+	secure_timer_init();
+	secure_sgrf_init();
+	/*
+	 * We cannot enable ddr security at this point, as the kernel
+	 * seems to have an issue with it even living in the same 128MB
+	 * memory block. Only when moving the kernel to the second
+	 * 128MB block does it not conflict, but then we'd loose this
+	 * memory area for use. Late maybe enable
+	 * secure_sgrf_ddr_rgn_init();
+	 */
+}
+
+void regs_update_bits(uintptr_t addr, uint32_t val,
+		      uint32_t mask, uint32_t shift)
+{
+	uint32_t tmp, orig;
+
+	orig = mmio_read_32(addr);
+
+	tmp = orig & ~(mask << shift);
+	tmp |= (val & mask) << shift;
+
+	if (tmp != orig)
+		mmio_write_32(addr, tmp);
+	dsb();
+}
+
+static void pll_save(uint32_t pll_id)
+{
+	uint32_t *pll = slp_data.pll_con[pll_id];
+
+	pll[0] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 0));
+	pll[1] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 1));
+	pll[2] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 2));
+	pll[3] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 3));
+}
+
+void clk_plls_suspend(void)
+{
+	pll_save(NPLL_ID);
+	pll_save(CPLL_ID);
+	pll_save(GPLL_ID);
+	pll_save(APLL_ID);
+	slp_data.pll_mode = mmio_read_32(CRU_BASE + PLL_MODE_CON);
+
+	/*
+	 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
+	 * avoid crashes on resume. The Mask ROM on the system will
+	 * put APLL, CPLL, and GPLL into slow mode at resume time
+	 * anyway (which is why we restore them), but we might not
+	 * even make it to the Mask ROM if this isn't done at suspend
+	 * time.
+	 *
+	 * NOTE: only APLL truly matters here, but we'll do them all.
+	 */
+	mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
+}
+
+void clk_plls_resume(void)
+{
+	/* restore pll-modes */
+	mmio_write_32(CRU_BASE + PLL_MODE_CON,
+		      slp_data.pll_mode | REG_SOC_WMSK);
+}
+
+void clk_gate_con_save(void)
+{
+	uint32_t i = 0;
+
+	for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
+		slp_data.cru_gate_con[i] =
+			mmio_read_32(CRU_BASE + CRU_CLKGATES_CON(i));
+}
+
+void clk_gate_con_disable(void)
+{
+	uint32_t i;
+
+	for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
+		mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i), REG_SOC_WMSK);
+}
+
+void clk_gate_con_restore(void)
+{
+	uint32_t i;
+
+	for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
+		mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i),
+			      REG_SOC_WMSK | slp_data.cru_gate_con[i]);
+}
+
+void clk_sel_con_save(void)
+{
+	uint32_t i = 0;
+
+	for (i = 0; i < CRU_CLKSELS_CON_CNT; i++)
+		slp_data.cru_sel_con[i] =
+			mmio_read_32(CRU_BASE + CRU_CLKSELS_CON(i));
+}
+
+void clk_sel_con_restore(void)
+{
+	uint32_t i, val;
+
+	for (i = 0; i < CRU_CLKSELS_CON_CNT; i++) {
+		/* fractional dividers don't have write-masks */
+		if ((i >= 7 && i <= 9) ||
+		    (i >= 17 && i <= 20) ||
+		    (i == 23) || (i == 41))
+			val = slp_data.cru_sel_con[i];
+		else
+			val = slp_data.cru_sel_con[i] | REG_SOC_WMSK;
+
+		mmio_write_32(CRU_BASE + CRU_CLKSELS_CON(i), val);
+	}
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+	uint32_t temp_val;
+
+	/*
+	 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
+	 * avoid crashes on resume. The Mask ROM on the system will
+	 * put APLL, CPLL, and GPLL into slow mode at resume time
+	 * anyway (which is why we restore them), but we might not
+	 * even make it to the Mask ROM if this isn't done at suspend
+	 * time.
+	 *
+	 * NOTE: only APLL truly matters here, but we'll do them all.
+	 */
+	mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
+
+	temp_val = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON);
+	temp_val &= ~PMU_RST_MASK;
+	temp_val |= PMU_RST_BY_SECOND_SFT;
+	mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, temp_val);
+	mmio_write_32(CRU_BASE + CRU_GLB_SRST_SND, 0xeca8);
+
+	/*
+	 * Maybe the HW needs some times to reset the system,
+	 * so we do not hope the core to excute valid codes.
+	 */
+	while (1)
+		;
+}
diff --git a/plat/rockchip/rk3288/drivers/soc/soc.h b/plat/rockchip/rk3288/drivers/soc/soc.h
new file mode 100644
index 0000000..b96c4dc
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/soc/soc.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOC_H
+#define SOC_H
+
+enum plls_id {
+	APLL_ID = 0,
+	DPLL_ID,
+	CPLL_ID,
+	GPLL_ID,
+	NPLL_ID,
+	END_PLL_ID,
+};
+
+
+#define CYCL_24M_CNT_US(us)	(24 * (us))
+#define CYCL_24M_CNT_MS(ms)	((ms) * CYCL_24M_CNT_US(1000))
+
+/*****************************************************************************
+ * grf regs
+ *****************************************************************************/
+#define GRF_UOC0_CON0		0x320
+#define GRF_UOC1_CON0		0x334
+#define GRF_UOC2_CON0		0x348
+#define GRF_SIDDQ		BIT(13)
+
+/*****************************************************************************
+ * cru reg, offset
+ *****************************************************************************/
+#define CRU_SOFTRST_CON		0x1b8
+#define CRU_SOFTRSTS_CON(n)	(CRU_SOFTRST_CON + ((n) * 4))
+#define CRU_SOFTRSTS_CON_CNT	11
+
+#define RST_DMA1_MSK		0x4
+#define RST_DMA2_MSK		0x1
+
+#define CRU_CLKSEL_CON		0x60
+#define CRU_CLKSELS_CON(i)	(CRU_CLKSEL_CON + ((i) * 4))
+#define CRU_CLKSELS_CON_CNT	42
+
+#define CRU_CLKGATE_CON		0x160
+#define CRU_CLKGATES_CON(i)	(CRU_CLKGATE_CON + ((i) * 4))
+#define CRU_CLKGATES_CON_CNT	18
+
+#define CRU_GLB_SRST_FST	0x1b0
+#define CRU_GLB_SRST_SND	0x1b4
+#define CRU_GLB_RST_CON		0x1f0
+
+#define CRU_CONS_GATEID(i)	(16 * (i))
+#define GATE_ID(reg, bit)	(((reg) * 16) + (bit))
+
+#define PMU_RST_MASK		0x3
+#define PMU_RST_BY_FIRST_SFT	(0 << 2)
+#define PMU_RST_BY_SECOND_SFT	(1 << 2)
+#define PMU_RST_NOT_BY_SFT	(2 << 2)
+
+/***************************************************************************
+ * pll
+ ***************************************************************************/
+#define PLL_CON_COUNT		4
+#define PLL_CONS(id, i)		((id) * 0x10 + ((i) * 4))
+#define PLL_PWR_DN_MSK		BIT(1)
+#define PLL_PWR_DN		REG_WMSK_BITS(1, 1, 0x1)
+#define PLL_PWR_ON		REG_WMSK_BITS(0, 1, 0x1)
+#define PLL_RESET		REG_WMSK_BITS(1, 5, 0x1)
+#define PLL_RESET_RESUME	REG_WMSK_BITS(0, 5, 0x1)
+#define PLL_BYPASS_MSK		BIT(0)
+#define PLL_BYPASS_W_MSK	(PLL_BYPASS_MSK << 16)
+#define PLL_BYPASS		REG_WMSK_BITS(1, 0, 0x1)
+#define PLL_NO_BYPASS		REG_WMSK_BITS(0, 0, 0x1)
+
+#define PLL_MODE_CON		0x50
+
+struct deepsleep_data_s {
+	uint32_t pll_con[END_PLL_ID][PLL_CON_COUNT];
+	uint32_t pll_mode;
+	uint32_t cru_sel_con[CRU_CLKSELS_CON_CNT];
+	uint32_t cru_gate_con[CRU_CLKGATES_CON_CNT];
+};
+
+#define REG_W_MSK(bits_shift, msk) \
+		((msk) << ((bits_shift) + 16))
+#define REG_VAL_CLRBITS(val, bits_shift, msk) \
+		((val) & (~((msk) << bits_shift)))
+#define REG_SET_BITS(bits, bits_shift, msk) \
+		(((bits) & (msk)) << (bits_shift))
+#define REG_WMSK_BITS(bits, bits_shift, msk) \
+		(REG_W_MSK(bits_shift, msk) | \
+		REG_SET_BITS(bits, bits_shift, msk))
+#define REG_SOC_WMSK		0xffff0000
+
+#define regs_update_bit_set(addr, shift) \
+		regs_update_bits((addr), 0x1, 0x1, (shift))
+#define regs_update_bit_clr(addr, shift) \
+		regs_update_bits((addr), 0x0, 0x1, (shift))
+
+void regs_update_bits(uintptr_t addr, uint32_t val,
+		      uint32_t mask, uint32_t shift);
+void clk_plls_suspend(void);
+void clk_plls_resume(void);
+void clk_gate_con_save(void);
+void clk_gate_con_disable(void);
+void clk_gate_con_restore(void);
+void clk_sel_con_save(void);
+void clk_sel_con_restore(void);
+#endif /* SOC_H */
diff --git a/plat/rockchip/rk3288/include/plat_sip_calls.h b/plat/rockchip/rk3288/include/plat_sip_calls.h
new file mode 100644
index 0000000..66c4868
--- /dev/null
+++ b/plat/rockchip/rk3288/include/plat_sip_calls.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_SIP_CALLS_H
+#define PLAT_SIP_CALLS_H
+
+#define RK_PLAT_SIP_NUM_CALLS	0
+
+#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/rockchip/rk3288/include/plat_sp_min.ld.S b/plat/rockchip/rk3288/include/plat_sp_min.ld.S
new file mode 100644
index 0000000..2878437
--- /dev/null
+++ b/plat/rockchip/rk3288/include/plat_sp_min.ld.S
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ROCKCHIP_PLAT_LD_S
+#define ROCKCHIP_PLAT_LD_S
+
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+MEMORY {
+    SRAM (rwx): ORIGIN = SRAM_BASE, LENGTH = SRAM_SIZE
+    PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
+}
+
+SECTIONS
+{
+	. = SRAM_BASE;
+	ASSERT(. == ALIGN(PAGE_SIZE),
+		"SRAM_BASE address is not aligned on a page boundary.")
+
+	.text_sram : ALIGN(PAGE_SIZE) {
+		__bl32_sram_text_start = .;
+		*(.sram.text)
+		*(.sram.rodata)
+		__bl32_sram_text_real_end = .;
+		. = ALIGN(PAGE_SIZE);
+		__bl32_sram_text_end = .;
+	} >SRAM
+	ASSERT((__bl32_sram_text_real_end - __bl32_sram_text_start) <=
+		SRAM_TEXT_LIMIT, ".text_sram has exceeded its limit")
+
+	.data_sram : ALIGN(PAGE_SIZE) {
+		__bl32_sram_data_start = .;
+		*(.sram.data)
+		__bl32_sram_data_real_end = .;
+		. = ALIGN(PAGE_SIZE);
+		__bl32_sram_data_end = .;
+	} >SRAM
+	ASSERT((__bl32_sram_data_real_end - __bl32_sram_data_start) <=
+		SRAM_DATA_LIMIT, ".data_sram has exceeded its limit")
+
+	.stack_sram : ALIGN(PAGE_SIZE) {
+		__bl32_sram_stack_start = .;
+		. += PAGE_SIZE;
+		__bl32_sram_stack_end = .;
+	} >SRAM
+
+	. = PMUSRAM_BASE;
+
+	/*
+	 * pmu_cpuson_entrypoint request address
+	 * align 64K when resume, so put it in the
+	 * start of pmusram
+	 */
+	.pmusram : {
+		ASSERT(. == ALIGN(64 * 1024),
+			".pmusram.entry request 64K aligned.");
+		*(.pmusram.entry)
+
+		__bl32_pmusram_text_start = .;
+		*(.pmusram.text)
+		*(.pmusram.rodata)
+		__bl32_pmusram_text_end = .;
+
+		__bl32_pmusram_data_start = .;
+		*(.pmusram.data)
+		__bl32_pmusram_data_end = .;
+	} >PMUSRAM
+}
+
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3288/include/platform_def.h b/plat/rockchip/rk3288/include/platform_def.h
new file mode 100644
index 0000000..d9e0bc6
--- /dev/null
+++ b/plat/rockchip/rk3288/include/platform_def.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014-2018, 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 <plat/common/common_def.h>
+
+#include <bl32_param.h>
+#include <rk3288_def.h>
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT		"elf32-littlearm"
+#define PLATFORM_LINKER_ARCH		arm
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL1)
+#define PLATFORM_STACK_SIZE 0x440
+#elif defined(IMAGE_BL2)
+#define PLATFORM_STACK_SIZE 0x400
+#elif defined(IMAGE_BL32)
+#define PLATFORM_STACK_SIZE 0x800
+#endif
+
+#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+
+#define PLATFORM_MAX_AFFLVL		MPIDR_AFFLVL2
+#define PLATFORM_SYSTEM_COUNT		1
+#define PLATFORM_CLUSTER_COUNT		1
+#define PLATFORM_CLUSTER0_CORE_COUNT	4
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	4
+#define PLATFORM_NUM_AFFS		(PLATFORM_SYSTEM_COUNT +	\
+					 PLATFORM_CLUSTER_COUNT +	\
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_RK_CLST_TO_CPUID_SHIFT	6
+
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE		U(1)
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define MAX_XLAT_TABLES			8
+#define MAX_MMAP_REGIONS		18
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * 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. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT		6
+#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Define GICD and GICC and GICR base
+ */
+#define PLAT_RK_GICD_BASE		RK3288_GICD_BASE
+#define PLAT_RK_GICC_BASE		RK3288_GICC_BASE
+
+#define PLAT_RK_UART_BASE		RK3288_UART2_BASE
+#define PLAT_RK_UART_CLOCK		RK3288_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE		RK3288_BAUDRATE
+
+/* ClusterId is always 0x5 on rk3288, filter it */
+#define PLAT_RK_MPIDR_CLUSTER_MASK	0
+#define PLAT_RK_PRIMARY_CPU		0x0
+
+#define PSRAM_DO_DDR_RESUME		0
+#define PSRAM_CHECK_WAKEUP_CPU		0
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/rockchip/rk3288/include/shared/bl32_param.h b/plat/rockchip/rk3288/include/shared/bl32_param.h
new file mode 100644
index 0000000..743dad4
--- /dev/null
+++ b/plat/rockchip/rk3288/include/shared/bl32_param.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BL32_PARAM_H
+#define BL32_PARAM_H
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+/* TF txet, ro, rw, Size: 2MB */
+#define TZRAM_BASE		(0x0)
+#define TZRAM_SIZE		(0x200000)
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL32 at the top of the Trusted RAM
+ */
+#define BL32_BASE			(TZRAM_BASE + 0x100000)
+#define BL32_LIMIT			(TZRAM_BASE + TZRAM_SIZE)
+
+#endif /* BL32_PARAM_H */
diff --git a/plat/rockchip/rk3288/plat_sip_calls.c b/plat/rockchip/rk3288/plat_sip_calls.c
new file mode 100644
index 0000000..5918d58
--- /dev/null
+++ b/plat/rockchip/rk3288/plat_sip_calls.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+
+#include <plat_sip_calls.h>
+#include <rockchip_sip_svc.h>
+
+uintptr_t rockchip_plat_sip_handler(uint32_t smc_fid,
+				   u_register_t x1,
+				   u_register_t x2,
+				   u_register_t x3,
+				   u_register_t x4,
+				   void *cookie,
+				   void *handle,
+				   u_register_t flags)
+{
+	ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+	SMC_RET1(handle, SMC_UNK);
+}
diff --git a/plat/rockchip/rk3288/platform.mk b/plat/rockchip/rk3288/platform.mk
new file mode 100644
index 0000000..1a0a617
--- /dev/null
+++ b/plat/rockchip/rk3288/platform.mk
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ARM_CORTEX_A12		:=	yes
+ARM_ARCH_MAJOR		:=	7
+
+RK_PLAT			:=	plat/rockchip
+RK_PLAT_SOC		:=	${RK_PLAT}/${PLAT}
+RK_PLAT_COMMON		:=	${RK_PLAT}/common
+
+include lib/libfdt/libfdt.mk
+
+PLAT_INCLUDES		:=	-I${RK_PLAT_COMMON}/				\
+				-I${RK_PLAT_COMMON}/include/			\
+				-I${RK_PLAT_COMMON}/aarch32/			\
+				-I${RK_PLAT_COMMON}/drivers/pmu/		\
+				-I${RK_PLAT_SOC}/				\
+				-I${RK_PLAT_SOC}/drivers/pmu/			\
+				-I${RK_PLAT_SOC}/drivers/secure/		\
+				-I${RK_PLAT_SOC}/drivers/soc/			\
+				-I${RK_PLAT_SOC}/include/			\
+				-I${RK_PLAT_SOC}/include/shared/		\
+
+RK_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			\
+				${RK_PLAT}/common/rockchip_gicv2.c
+
+PLAT_BL_COMMON_SOURCES	:=	plat/common/aarch32/crash_console_helpers.S	\
+				plat/common/plat_psci_common.c
+
+PLAT_BL_COMMON_SOURCES	+=	lib/xlat_tables/xlat_tables_common.c		\
+				lib/xlat_tables/aarch32/xlat_tables.c
+
+BL32_SOURCES		+=	${RK_GIC_SOURCES}				\
+				drivers/arm/cci/cci.c				\
+				drivers/ti/uart/aarch32/16550_console.S		\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				lib/cpus/aarch32/cortex_a12.S			\
+				$(LIBFDT_SRCS)					\
+				${RK_PLAT_COMMON}/aarch32/plat_helpers.S	\
+				${RK_PLAT_COMMON}/params_setup.c		\
+				${RK_PLAT_COMMON}/aarch32/pmu_sram_cpus_on.S	\
+				${RK_PLAT_COMMON}/plat_pm.c			\
+				${RK_PLAT_COMMON}/plat_topology.c		\
+				${RK_PLAT_COMMON}/aarch32/platform_common.c	\
+				${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
+				${RK_PLAT_SOC}/plat_sip_calls.c			\
+				${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
+				${RK_PLAT_SOC}/drivers/secure/secure.c		\
+				${RK_PLAT_SOC}/drivers/soc/soc.c		\
+
+MULTI_CONSOLE_API	:=	1
+
+include lib/coreboot/coreboot.mk
+
+$(eval $(call add_define,PLAT_SP_MIN_EXTRA_LD_SCRIPT))
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS	:=	0
+
+WORKAROUND_CVE_2017_5715	:=	0
diff --git a/plat/rockchip/rk3288/rk3288_def.h b/plat/rockchip/rk3288/rk3288_def.h
new file mode 100644
index 0000000..7b5018c
--- /dev/null
+++ b/plat/rockchip/rk3288/rk3288_def.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RK3288_DEF_H
+#define RK3288_DEF_H
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define RK_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
+
+#define SIZE_K(n)		((n) * 1024)
+#define SIZE_M(n)		((n) * 1024 * 1024)
+
+#define SRAM_TEXT_LIMIT		(4 * 1024)
+#define SRAM_DATA_LIMIT		(4 * 1024)
+
+#define DDR_PCTL0_BASE		0xff610000
+#define DDR_PCTL0_SIZE		SIZE_K(64)
+
+#define DDR_PHY0_BASE		0xff620000
+#define DDR_PHY0_SIZE		SIZE_K(64)
+
+#define DDR_PCTL1_BASE		0xff630000
+#define DDR_PCTL1_SIZE		SIZE_K(64)
+
+#define DDR_PHY1_BASE		0xff640000
+#define DDR_PHY1_SIZE		SIZE_K(64)
+
+#define UART_DBG_BASE		0xff690000
+#define UART_DBG_SIZE		SIZE_K(64)
+
+/* 96k instead of 64k? */
+#define SRAM_BASE		0xff700000
+#define SRAM_SIZE		SIZE_K(64)
+
+#define PMUSRAM_BASE		0xff720000
+#define PMUSRAM_SIZE		SIZE_K(4)
+#define PMUSRAM_RSIZE		SIZE_K(4)
+
+#define PMU_BASE		0xff730000
+#define PMU_SIZE		SIZE_K(64)
+
+#define SGRF_BASE		0xff740000
+#define SGRF_SIZE		SIZE_K(64)
+
+#define CRU_BASE		0xff760000
+#define CRU_SIZE		SIZE_K(64)
+
+#define GRF_BASE		0xff770000
+#define GRF_SIZE		SIZE_K(64)
+
+/* timer 6+7 can be set as secure in SGRF */
+#define STIME_BASE		0xff810000
+#define STIME_SIZE		SIZE_K(64)
+
+#define SERVICE_BUS_BASE	0xffac0000
+#define SERVICE_BUS_SIZE	SIZE_K(64)
+
+#define TZPC_BASE		0xffb00000
+#define TZPC_SIZE		SIZE_K(64)
+
+#define GIC400_BASE		0xffc00000
+#define GIC400_SIZE		SIZE_K(64)
+
+#define CORE_AXI_BUS_BASE	0xffd00000
+#define CORE_AXI_BUS_SIZE	SIZE_M(1)
+
+#define COLD_BOOT_BASE		0xffff0000
+/**************************************************************************
+ * UART related constants
+ **************************************************************************/
+#define RK3288_UART2_BASE	UART_DBG_BASE
+#define RK3288_BAUDRATE		115200
+#define RK3288_UART_CLOCK	24000000
+
+/******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_TICKS	24000000
+
+/******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+
+/* Base rk_platform compatible GIC memory map */
+#define RK3288_GICD_BASE		(GIC400_BASE + 0x1000)
+#define RK3288_GICC_BASE		(GIC400_BASE + 0x2000)
+#define RK3288_GICR_BASE		0	/* no GICR in GIC-400 */
+
+/******************************************************************************
+ * sgi, ppi
+ ******************************************************************************/
+#define RK_IRQ_SEC_PHY_TIMER	29
+
+/* what are these, and are they present on rk3288? */
+#define RK_IRQ_SEC_SGI_0	8
+#define RK_IRQ_SEC_SGI_1	9
+#define RK_IRQ_SEC_SGI_2	10
+#define RK_IRQ_SEC_SGI_3	11
+#define RK_IRQ_SEC_SGI_4	12
+#define RK_IRQ_SEC_SGI_5	13
+#define RK_IRQ_SEC_SGI_6	14
+#define RK_IRQ_SEC_SGI_7	15
+
+/*
+ * Define a list of Group 0 interrupts.
+ */
+#define PLAT_RK_GICV2_G0_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,	\
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),		\
+	INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+#endif /* RK3288_DEF_H */
diff --git a/plat/rockchip/rk3288/sp_min/sp_min-rk3288.mk b/plat/rockchip/rk3288/sp_min/sp_min-rk3288.mk
new file mode 100644
index 0000000..befdca3
--- /dev/null
+++ b/plat/rockchip/rk3288/sp_min/sp_min-rk3288.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES		+=	plat/common/aarch32/platform_mp_stack.S		\
+				plat/rockchip/common/sp_min_plat_setup.c
diff --git a/plat/rockchip/rk3328/drivers/pmu/pmu.h b/plat/rockchip/rk3328/drivers/pmu/pmu.h
index d98f53c..dfb8912 100644
--- a/plat/rockchip/rk3328/drivers/pmu/pmu.h
+++ b/plat/rockchip/rk3328/drivers/pmu/pmu.h
@@ -49,8 +49,6 @@
 
 extern void *pmu_cpuson_entrypoint_start;
 extern void *pmu_cpuson_entrypoint_end;
-extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT];
-extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
 
 #define CORES_PM_DISABLE	0x0
 
diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk
index 18b1b94..ce8693a 100644
--- a/plat/rockchip/rk3328/platform.mk
+++ b/plat/rockchip/rk3328/platform.mk
@@ -14,7 +14,7 @@
 				-Idrivers/arm/gic/v2/			\
 				-I${RK_PLAT_COMMON}/                            \
 				-I${RK_PLAT_COMMON}/include/                    \
-				-I${RK_PLAT_COMMON}/pmusram                     \
+				-I${RK_PLAT_COMMON}/aarch64/			\
 				-I${RK_PLAT_COMMON}/drivers/pmu/                \
 				-I${RK_PLAT_COMMON}/drivers/parameter/		\
 				-I${RK_PLAT_SOC}/				\
@@ -44,7 +44,7 @@
 				${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c	\
 				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
 				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
-				${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S	\
+				${RK_PLAT_COMMON}/aarch64/pmu_sram_cpus_on.S	\
 				${RK_PLAT_COMMON}/plat_pm.c			\
 				${RK_PLAT_COMMON}/plat_topology.c		\
 				${RK_PLAT_COMMON}/aarch64/platform_common.c	\
diff --git a/plat/rockchip/rk3368/platform.mk b/plat/rockchip/rk3368/platform.mk
index d1315fc..8988dc5 100644
--- a/plat/rockchip/rk3368/platform.mk
+++ b/plat/rockchip/rk3368/platform.mk
@@ -12,7 +12,7 @@
 
 PLAT_INCLUDES		:=	-I${RK_PLAT_COMMON}/				\
 				-I${RK_PLAT_COMMON}/include/			\
-				-I${RK_PLAT_COMMON}/pmusram			\
+				-I${RK_PLAT_COMMON}/aarch64/			\
 				-I${RK_PLAT_COMMON}/drivers/pmu/			\
 				-I${RK_PLAT_SOC}/				\
 				-I${RK_PLAT_SOC}/drivers/pmu/			\
@@ -41,7 +41,7 @@
 				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
 				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
 				${RK_PLAT_COMMON}/params_setup.c                \
-				${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S		\
+				${RK_PLAT_COMMON}/aarch64/pmu_sram_cpus_on.S	\
 				${RK_PLAT_COMMON}/plat_pm.c			\
 				${RK_PLAT_COMMON}/plat_topology.c		\
 				${RK_PLAT_COMMON}/aarch64/platform_common.c	\
diff --git a/plat/rockchip/rk3399/drivers/m0/src/dram.c b/plat/rockchip/rk3399/drivers/m0/src/dram.c
index b939a96..84e8884 100644
--- a/plat/rockchip/rk3399/drivers/m0/src/dram.c
+++ b/plat/rockchip/rk3399/drivers/m0/src/dram.c
@@ -55,7 +55,7 @@
 	mmio_write_32(CRU_BASE + CRU_DPLL_CON3, PLL_MODE(PLL_NORMAL_MODE));
 }
 
-__attribute__((noreturn)) void main(void)
+__attribute__((noreturn)) void m0_main(void)
 {
 	mmio_setbits_32(PHY_REG(0, 927), (1 << 22));
 	mmio_setbits_32(PHY_REG(1, 927), (1 << 22));
diff --git a/plat/rockchip/rk3399/drivers/m0/src/startup.c b/plat/rockchip/rk3399/drivers/m0/src/startup.c
index dba0313..dfd8af2 100644
--- a/plat/rockchip/rk3399/drivers/m0/src/startup.c
+++ b/plat/rockchip/rk3399/drivers/m0/src/startup.c
@@ -23,7 +23,7 @@
 void WEAK pend_sv_handler(void);
 void WEAK systick_handler(void);
 
-extern int main(void);
+extern int m0_main(void);
 
 /* Function prototypes */
 static void default_reset_handler(void);
@@ -59,12 +59,12 @@
  * This is the code that gets called when the processor first
  * starts execution following a reset event. Only the absolutely
  * necessary set is performed, after which the application
- * supplied main() routine is called.
+ * supplied m0_main() routine is called.
  */
 static void default_reset_handler(void)
 {
 	/* call the application's entry point */
-	main();
+	m0_main();
 }
 
 /**
diff --git a/plat/rockchip/rk3399/drivers/m0/src/suspend.c b/plat/rockchip/rk3399/drivers/m0/src/suspend.c
index 39dfd11..9ad2fa2 100644
--- a/plat/rockchip/rk3399/drivers/m0/src/suspend.c
+++ b/plat/rockchip/rk3399/drivers/m0/src/suspend.c
@@ -11,7 +11,7 @@
 
 #define SCR_SLEEPDEEP_SHIFT	(1 << 2)
 
-__attribute__((noreturn)) void main(void)
+__attribute__((noreturn)) void m0_main(void)
 {
 	unsigned int status_value;
 
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index 1013598..3dfafc9 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -12,7 +12,7 @@
 
 PLAT_INCLUDES		:=	-I${RK_PLAT_COMMON}/			\
 				-I${RK_PLAT_COMMON}/include/		\
-				-I${RK_PLAT_COMMON}/pmusram		\
+				-I${RK_PLAT_COMMON}/aarch64/		\
 				-I${RK_PLAT_COMMON}/drivers/pmu/	\
 				-I${RK_PLAT_SOC}/			\
 				-I${RK_PLAT_SOC}/drivers/pmu/		\
@@ -49,7 +49,7 @@
 			${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
 			${RK_PLAT_COMMON}/bl31_plat_setup.c		\
 			${RK_PLAT_COMMON}/params_setup.c		\
-			${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S	\
+			${RK_PLAT_COMMON}/aarch64/pmu_sram_cpus_on.S	\
 			${RK_PLAT_COMMON}/plat_pm.c			\
 			${RK_PLAT_COMMON}/plat_topology.c		\
 			${RK_PLAT_COMMON}/aarch64/platform_common.c	\
diff --git a/plat/rpi3/rpi3_trusted_boot.c b/plat/rpi3/rpi3_trusted_boot.c
index b306c45..f6c669f 100644
--- a/plat/rpi3/rpi3_trusted_boot.c
+++ b/plat/rpi3/rpi3_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,3 +29,8 @@
 {
 	return 1;
 }
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/socionext/uniphier/uniphier_tbbr.c b/plat/socionext/uniphier/uniphier_tbbr.c
index 962a8d2..e31ca03 100644
--- a/plat/socionext/uniphier/uniphier_tbbr.c
+++ b/plat/socionext/uniphier/uniphier_tbbr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,3 +33,8 @@
 {
 	return 0;
 }
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index f172160..38b2a0b 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -54,10 +54,27 @@
 static uintptr_t storage_dev_handle;
 static const io_dev_connector_t *mmc_dev_con;
 
+#ifdef AARCH32_SP_OPTEE
+static const struct stm32image_part_info optee_header_partition_spec = {
+	.name = OPTEE_HEADER_IMAGE_NAME,
+	.binary_type = OPTEE_HEADER_BINARY_TYPE,
+};
+
+static const struct stm32image_part_info optee_pager_partition_spec = {
+	.name = OPTEE_PAGER_IMAGE_NAME,
+	.binary_type = OPTEE_PAGER_BINARY_TYPE,
+};
+
+static const struct stm32image_part_info optee_paged_partition_spec = {
+	.name = OPTEE_PAGED_IMAGE_NAME,
+	.binary_type = OPTEE_PAGED_BINARY_TYPE,
+};
+#else
 static const io_block_spec_t bl32_block_spec = {
 	.offset = BL32_BASE,
 	.length = STM32MP_BL32_SIZE
 };
+#endif
 
 static const io_block_spec_t bl2_block_spec = {
 	.offset = BL2_BASE,
@@ -71,6 +88,11 @@
 
 enum {
 	IMG_IDX_BL33,
+#ifdef AARCH32_SP_OPTEE
+	IMG_IDX_OPTEE_HEADER,
+	IMG_IDX_OPTEE_PAGER,
+	IMG_IDX_OPTEE_PAGED,
+#endif
 	IMG_IDX_NUM
 };
 
@@ -80,6 +102,20 @@
 		.name = BL33_IMAGE_NAME,
 		.binary_type = BL33_BINARY_TYPE,
 	},
+#ifdef AARCH32_SP_OPTEE
+	.part_info[IMG_IDX_OPTEE_HEADER] = {
+		.name = OPTEE_HEADER_IMAGE_NAME,
+		.binary_type = OPTEE_HEADER_BINARY_TYPE,
+	},
+	.part_info[IMG_IDX_OPTEE_PAGER] = {
+		.name = OPTEE_PAGER_IMAGE_NAME,
+		.binary_type = OPTEE_PAGER_BINARY_TYPE,
+	},
+	.part_info[IMG_IDX_OPTEE_PAGED] = {
+		.name = OPTEE_PAGED_IMAGE_NAME,
+		.binary_type = OPTEE_PAGED_BINARY_TYPE,
+	},
+#endif
 };
 
 static io_block_spec_t stm32image_block_spec = {
@@ -105,11 +141,29 @@
 		.image_spec = (uintptr_t)&bl2_block_spec,
 		.check = open_dummy
 	},
+#ifdef AARCH32_SP_OPTEE
+	[BL32_IMAGE_ID] = {
+		.dev_handle = &image_dev_handle,
+		.image_spec = (uintptr_t)&optee_header_partition_spec,
+		.check = open_image
+	},
+	[BL32_EXTRA1_IMAGE_ID] = {
+		.dev_handle = &image_dev_handle,
+		.image_spec = (uintptr_t)&optee_pager_partition_spec,
+		.check = open_image
+	},
+	[BL32_EXTRA2_IMAGE_ID] = {
+		.dev_handle = &image_dev_handle,
+		.image_spec = (uintptr_t)&optee_paged_partition_spec,
+		.check = open_image
+	},
+#else
 	[BL32_IMAGE_ID] = {
 		.dev_handle = &dummy_dev_handle,
 		.image_spec = (uintptr_t)&bl32_block_spec,
 		.check = open_dummy
 	},
+#endif
 	[BL33_IMAGE_ID] = {
 		.dev_handle = &image_dev_handle,
 		.image_spec = (uintptr_t)&bl33_partition_spec,
@@ -162,122 +216,125 @@
 	}
 }
 
-void stm32mp_io_setup(void)
+static void boot_mmc(enum mmc_device_type mmc_dev_type,
+		     uint16_t boot_interface_instance)
 {
 	int io_result __unused;
 	uint8_t idx;
 	struct stm32image_part_info *part;
 	struct stm32_sdmmc2_params params;
 	struct mmc_device_info device_info;
-	uintptr_t mmc_default_instance;
 	const partition_entry_t *entry;
-	boot_api_context_t *boot_context =
-		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
 
-	print_boot_device(boot_context);
+	zeromem(&device_info, sizeof(struct mmc_device_info));
+	zeromem(&params, sizeof(struct stm32_sdmmc2_params));
 
-	if ((boot_context->boot_partition_used_toboot == 1U) ||
-	    (boot_context->boot_partition_used_toboot == 2U)) {
-		INFO("Boot used partition fsbl%d\n",
-		     boot_context->boot_partition_used_toboot);
+	device_info.mmc_dev_type = mmc_dev_type;
+
+	switch (boot_interface_instance) {
+	case 1:
+		params.reg_base = STM32MP_SDMMC1_BASE;
+		break;
+	case 2:
+		params.reg_base = STM32MP_SDMMC2_BASE;
+		break;
+	case 3:
+		params.reg_base = STM32MP_SDMMC3_BASE;
+		break;
+	default:
+		WARN("SDMMC instance not found, using default\n");
+		if (mmc_dev_type == MMC_IS_SD) {
+			params.reg_base = STM32MP_SDMMC1_BASE;
+		} else {
+			params.reg_base = STM32MP_SDMMC2_BASE;
+		}
+		break;
 	}
 
-	io_result = register_io_dev_dummy(&dummy_dev_con);
-	assert(io_result == 0);
+	params.device_info = &device_info;
+	if (stm32_sdmmc2_mmc_init(&params) != 0) {
+		ERROR("SDMMC%u init failed\n", boot_interface_instance);
+		panic();
+	}
 
-	io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
-				&dummy_dev_handle);
-	assert(io_result == 0);
+	/* Open MMC as a block device to read GPT table */
+	io_result = register_io_dev_block(&mmc_dev_con);
+	if (io_result != 0) {
+		panic();
+	}
 
-	switch (boot_context->boot_interface_selected) {
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
-		dmbsy();
+	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
+				&storage_dev_handle);
+	assert(io_result == 0);
 
-		zeromem(&device_info, sizeof(struct mmc_device_info));
-		zeromem(&params, sizeof(struct stm32_sdmmc2_params));
+	partition_init(GPT_IMAGE_ID);
 
-		if (boot_context->boot_interface_selected ==
-		    BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC) {
-			device_info.mmc_dev_type = MMC_IS_EMMC;
-			mmc_default_instance = STM32MP_SDMMC2_BASE;
-		} else {
-			device_info.mmc_dev_type = MMC_IS_SD;
-			mmc_default_instance = STM32MP_SDMMC1_BASE;
-		}
+	io_result = io_dev_close(storage_dev_handle);
+	assert(io_result == 0);
 
-		switch (boot_context->boot_interface_instance) {
-		case 1:
-			params.reg_base = STM32MP_SDMMC1_BASE;
-			break;
-		case 2:
-			params.reg_base = STM32MP_SDMMC2_BASE;
-			break;
-		case 3:
-			params.reg_base = STM32MP_SDMMC3_BASE;
-			break;
-		default:
-			WARN("SDMMC instance not found, using default\n");
-			params.reg_base = mmc_default_instance;
-			break;
-		}
+	stm32image_dev_info_spec.device_size =
+		stm32_sdmmc2_mmc_get_device_size();
 
-		params.device_info = &device_info;
-		if (stm32_sdmmc2_mmc_init(&params) != 0) {
-			ERROR("SDMMC%u init failed\n",
-			      boot_context->boot_interface_instance);
+	for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
+		part = &stm32image_dev_info_spec.part_info[idx];
+		entry = get_partition_entry(part->name);
+		if (entry == NULL) {
+			ERROR("Partition %s not found\n", part->name);
 			panic();
 		}
 
-		/* Open MMC as a block device to read GPT table */
-		io_result = register_io_dev_block(&mmc_dev_con);
-		if (io_result != 0) {
-			panic();
-		}
+		part->part_offset = entry->start;
+		part->bkp_offset = 0U;
+	}
 
-		io_result = io_dev_open(mmc_dev_con,
-					(uintptr_t)&mmc_block_dev_spec,
-					&storage_dev_handle);
-		assert(io_result == 0);
+	/*
+	 * Re-open MMC with io_mmc, for better perfs compared to
+	 * io_block.
+	 */
+	io_result = register_io_dev_mmc(&mmc_dev_con);
+	assert(io_result == 0);
 
-		partition_init(GPT_IMAGE_ID);
+	io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle);
+	assert(io_result == 0);
 
-		io_result = io_dev_close(storage_dev_handle);
-		assert(io_result == 0);
+	io_result = register_io_dev_stm32image(&stm32image_dev_con);
+	assert(io_result == 0);
 
-		stm32image_dev_info_spec.device_size =
-			stm32_sdmmc2_mmc_get_device_size();
+	io_result = io_dev_open(stm32image_dev_con,
+				(uintptr_t)&stm32image_dev_info_spec,
+				&image_dev_handle);
+	assert(io_result == 0);
+}
 
-		for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
-			part = &stm32image_dev_info_spec.part_info[idx];
-			entry = get_partition_entry(part->name);
-			if (entry == NULL) {
-				ERROR("Partition %s not found\n",
-				      part->name);
-				panic();
-			}
+void stm32mp_io_setup(void)
+{
+	int io_result __unused;
+	boot_api_context_t *boot_context =
+		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
 
-			part->part_offset = entry->start;
-			part->bkp_offset = 0U;
-		}
+	print_boot_device(boot_context);
 
-		/*
-		 * Re-open MMC with io_mmc, for better perfs compared to
-		 * io_block.
-		 */
-		io_result = register_io_dev_mmc(&mmc_dev_con);
-		assert(io_result == 0);
+	if ((boot_context->boot_partition_used_toboot == 1U) ||
+	    (boot_context->boot_partition_used_toboot == 2U)) {
+		INFO("Boot used partition fsbl%d\n",
+		     boot_context->boot_partition_used_toboot);
+	}
 
-		io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle);
-		assert(io_result == 0);
+	io_result = register_io_dev_dummy(&dummy_dev_con);
+	assert(io_result == 0);
 
-		io_result = register_io_dev_stm32image(&stm32image_dev_con);
-		assert(io_result == 0);
+	io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
+				&dummy_dev_handle);
+	assert(io_result == 0);
 
-		io_result = io_dev_open(stm32image_dev_con,
-					(uintptr_t)&stm32image_dev_info_spec,
-					&image_dev_handle);
-		assert(io_result == 0);
+	switch (boot_context->boot_interface_selected) {
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+		dmbsy();
+		boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
+		break;
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+		dmbsy();
+		boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
 		break;
 
 	default:
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 2477954..b54486e 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -22,6 +22,7 @@
 #include <drivers/st/stm32mp1_pwr.h>
 #include <drivers/st/stm32mp1_ram.h>
 #include <lib/mmio.h>
+#include <lib/optee_utils.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
@@ -136,7 +137,13 @@
 		panic();
 	}
 
+#ifdef AARCH32_SP_OPTEE
+	INFO("BL2 runs OP-TEE setup\n");
+	/* Initialize tzc400 after DDR initialization */
+	stm32mp1_security_setup();
+#else
 	INFO("BL2 runs SP_MIN setup\n");
+#endif
 }
 
 void bl2_el3_plat_arch_setup(void)
@@ -154,11 +161,25 @@
 			BL_CODE_END - BL_CODE_BASE,
 			MT_CODE | MT_SECURE);
 
+#ifdef AARCH32_SP_OPTEE
+	/* OP-TEE image needs post load processing: keep RAM read/write */
+	mmap_add_region(STM32MP_DDR_BASE + dt_get_ddr_size() -
+			STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE,
+			STM32MP_DDR_BASE + dt_get_ddr_size() -
+			STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE,
+			STM32MP_DDR_S_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE);
+
+	mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE,
+			STM32MP_OPTEE_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE);
+#else
 	/* Prevent corruption of preloaded BL32 */
 	mmap_add_region(BL32_BASE, BL32_BASE,
 			BL32_LIMIT - BL32_BASE,
 			MT_MEMORY | MT_RO | MT_SECURE);
 
+#endif
 	/* Map non secure DDR for BL33 load and DDR training area restore */
 	mmap_add_region(STM32MP_DDR_BASE,
 			STM32MP_DDR_BASE,
@@ -261,3 +282,69 @@
 
 	stm32mp_io_setup();
 }
+
+#if defined(AARCH32_SP_OPTEE)
+/*******************************************************************************
+ * This function can be used by the platforms to update/use image
+ * information for given `image_id`.
+ ******************************************************************************/
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	int err = 0;
+	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+	bl_mem_params_node_t *bl32_mem_params;
+	bl_mem_params_node_t *pager_mem_params;
+	bl_mem_params_node_t *paged_mem_params;
+
+	assert(bl_mem_params != NULL);
+
+	switch (image_id) {
+	case BL32_IMAGE_ID:
+		bl_mem_params->ep_info.pc =
+					bl_mem_params->image_info.image_base;
+
+		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+		assert(pager_mem_params != NULL);
+		pager_mem_params->image_info.image_base = STM32MP_OPTEE_BASE;
+		pager_mem_params->image_info.image_max_size =
+			STM32MP_OPTEE_SIZE;
+
+		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+		assert(paged_mem_params != NULL);
+		paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
+			(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
+			 STM32MP_DDR_SHMEM_SIZE);
+		paged_mem_params->image_info.image_max_size =
+			STM32MP_DDR_S_SIZE;
+
+		err = parse_optee_header(&bl_mem_params->ep_info,
+					 &pager_mem_params->image_info,
+					 &paged_mem_params->image_info);
+		if (err) {
+			ERROR("OPTEE header parse error.\n");
+			panic();
+		}
+
+		/* Set optee boot info from parsed header data */
+		bl_mem_params->ep_info.pc =
+				pager_mem_params->image_info.image_base;
+		bl_mem_params->ep_info.args.arg0 =
+				paged_mem_params->image_info.image_base;
+		bl_mem_params->ep_info.args.arg1 = 0; /* Unused */
+		bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */
+		break;
+
+	case BL33_IMAGE_ID:
+		bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
+		assert(bl32_mem_params != NULL);
+		bl32_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
+		break;
+
+	default:
+		/* Do nothing in default case */
+		break;
+	}
+
+	return err;
+}
+#endif
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 5019b1a..263e6d6 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -25,6 +25,15 @@
 #define PLATFORM_STACK_SIZE		0xC00
 #endif
 
+#ifdef AARCH32_SP_OPTEE
+#define OPTEE_HEADER_IMAGE_NAME		"teeh"
+#define OPTEE_PAGED_IMAGE_NAME		"teed"
+#define OPTEE_PAGER_IMAGE_NAME		"teex"
+#define OPTEE_HEADER_BINARY_TYPE	U(0x20)
+#define OPTEE_PAGER_BINARY_TYPE		U(0x21)
+#define OPTEE_PAGED_BINARY_TYPE		U(0x22)
+#endif
+
 /* SSBL = second stage boot loader */
 #define BL33_IMAGE_NAME			"ssbl"
 #define BL33_BINARY_TYPE		U(0x0)
@@ -57,9 +66,11 @@
 /*******************************************************************************
  * BL32 specific defines.
  ******************************************************************************/
+#ifndef AARCH32_SP_OPTEE
 #define BL32_BASE			STM32MP_BL32_BASE
 #define BL32_LIMIT			(STM32MP_BL32_BASE + \
 					 STM32MP_BL32_SIZE)
+#endif
 
 /*******************************************************************************
  * BL33 specific defines.
diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
index 0da93e4..1d407bb 100644
--- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
@@ -27,7 +27,9 @@
 				      VERSION_2, entry_point_info_t,
 				      SECURE | EXECUTABLE | EP_FIRST_EXE),
 
+#if !defined(AARCH32_SP_OPTEE)
 		.ep_info.pc = BL32_BASE,
+#endif
 		.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
 					    SPSR_E_LITTLE,
 					    DISABLE_ALL_EXCEPTIONS),
@@ -35,12 +37,47 @@
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
 				      VERSION_2, image_info_t,
 				      IMAGE_ATTRIB_PLAT_SETUP),
-
+#if defined(AARCH32_SP_OPTEE)
+		/* optee header is loaded in SYSRAM above BL2 */
+		.image_info.image_base = STM32MP_OPTEE_BASE,
+		.image_info.image_max_size = STM32MP_OPTEE_SIZE,
+#else
 		.image_info.image_base = BL32_BASE,
 		.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
-
+#endif
 		.next_handoff_image_id = BL33_IMAGE_ID,
 	},
+
+#if defined(AARCH32_SP_OPTEE)
+	/* Fill BL32 external 1 image related information */
+	{
+		.image_id = BL32_EXTRA1_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+	/* Fill BL32 external 2 image related information */
+	{
+		.image_id = BL32_EXTRA2_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+#endif /* AARCH32_SP_OPTEE */
 
 	/* Fill BL33 related information */
 	{
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 3e34601..4796e91 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -18,7 +18,11 @@
 # Number of TF-A copies in the device
 STM32_TF_A_COPIES		:=	2
 $(eval $(call add_define,STM32_TF_A_COPIES))
+ifeq ($(AARCH32_SP),optee)
+PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + 4)))
+else
 PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + 1)))
+endif
 $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
 
 PLAT_INCLUDES		:=	-Iplat/st/common/include/
@@ -84,6 +88,10 @@
 				plat/st/stm32mp1/plat_bl2_mem_params_desc.c		\
 				plat/st/stm32mp1/plat_image_load.c
 
+ifeq ($(AARCH32_SP),optee)
+BL2_SOURCES		+=	lib/optee/optee_utils.c
+endif
+
 # Macros and rules to build TF binary
 STM32_TF_ELF_LDFLAGS	:=	--hash-style=gnu --as-needed
 STM32_DT_BASENAME	:=	$(DTB_FILE_NAME:.dtb=)
diff --git a/plat/st/stm32mp1/stm32mp1.ld.S b/plat/st/stm32mp1/stm32mp1.ld.S
index c041fb6..b347bad 100644
--- a/plat/st/stm32mp1/stm32mp1.ld.S
+++ b/plat/st/stm32mp1/stm32mp1.ld.S
@@ -58,6 +58,7 @@
         *(.bl2_image*)
         __BL2_IMAGE_END__ = .;
 
+#ifndef AARCH32_SP_OPTEE
         /*
          * bl32 will be settled by bl2.
          * The strongest and only alignment constraint is 8 words to simplify
@@ -67,6 +68,7 @@
         __BL32_IMAGE_START__ = .;
         *(.bl32_image*)
         __BL32_IMAGE_END__ = .;
+#endif
 
         __DATA_END__ = .;
     } >RAM
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 1c897bd..cff7ddb 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -34,7 +34,10 @@
 /* DDR configuration */
 #define STM32MP_DDR_BASE		U(0xC0000000)
 #define STM32MP_DDR_MAX_SIZE		U(0x40000000)	/* Max 1GB */
-#define STM32MP_DDR_SPEED_DFLT		528
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_DDR_S_SIZE		U(0x01E00000)	/* 30 MB */
+#define STM32MP_DDR_SHMEM_SIZE		U(0x00200000)	/* 2 MB */
+#endif
 
 /* DDR power initializations */
 #ifndef __ASSEMBLY__
@@ -57,21 +60,38 @@
 					 (STM32MP_PARAM_LOAD_SIZE +	\
 					  STM32MP_HEADER_SIZE))
 
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_BL32_SIZE		U(0)
+
+#define STM32MP_OPTEE_BASE		STM32MP_SYSRAM_BASE
+
+#define STM32MP_OPTEE_SIZE		(STM32MP_DTB_BASE -  \
+					 STM32MP_OPTEE_BASE)
+#else
 #if STACK_PROTECTOR_ENABLED
 #define STM32MP_BL32_SIZE		U(0x00012000)	/* 72 Ko for BL32 */
 #else
 #define STM32MP_BL32_SIZE		U(0x00011000)	/* 68 Ko for BL32 */
 #endif
+#endif
 
 #define STM32MP_BL32_BASE		(STM32MP_SYSRAM_BASE + \
 					 STM32MP_SYSRAM_SIZE - \
 					 STM32MP_BL32_SIZE)
 
+#ifdef AARCH32_SP_OPTEE
+#if STACK_PROTECTOR_ENABLED
+#define STM32MP_BL2_SIZE		U(0x00019000)	/* 100 Ko for BL2 */
+#else
+#define STM32MP_BL2_SIZE		U(0x00017000)	/* 92 Ko for BL2 */
+#endif
+#else
 #if STACK_PROTECTOR_ENABLED
 #define STM32MP_BL2_SIZE		U(0x00015000)	/* 84 Ko for BL2 */
 #else
 #define STM32MP_BL2_SIZE		U(0x00013000)	/* 76 Ko for BL2 */
 #endif
+#endif
 
 #define STM32MP_BL2_BASE		(STM32MP_BL32_BASE - \
 					 STM32MP_BL2_SIZE)
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
index 0ad43e4..61db2e7 100644
--- a/plat/st/stm32mp1/stm32mp1_security.c
+++ b/plat/st/stm32mp1/stm32mp1_security.c
@@ -14,6 +14,19 @@
 #include <dt-bindings/clock/stm32mp1-clks.h>
 #include <lib/mmio.h>
 
+#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \
+	TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID)
+
 /*******************************************************************************
  * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access
  * and allow Non-Secure masters full access.
@@ -23,31 +36,55 @@
 	unsigned long long region_base, region_top;
 	unsigned long long ddr_base = STM32MP_DDR_BASE;
 	unsigned long long ddr_size = (unsigned long long)dt_get_ddr_size();
+	unsigned long long ddr_top = ddr_base + (ddr_size - 1U);
 
 	tzc400_init(STM32MP1_TZC_BASE);
 
 	tzc400_disable_filters();
 
+#ifdef AARCH32_SP_OPTEE
+	/*
+	 * Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the
+	 * same configuration to all filters in the TZC.
+	 */
+	region_base = ddr_base;
+	region_top = ddr_top - STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE;
+	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
+				region_base,
+				region_top,
+				TZC_REGION_S_NONE,
+				TZC_REGION_NSEC_ALL_ACCESS_RDWR);
+
-	/* Region 1 set to cover all DRAM at 0xC000_0000. Apply the
+	/* Region 2 set to cover all secure DRAM. */
+	region_base = region_top + 1U;
+	region_top = ddr_top - STM32MP_DDR_SHMEM_SIZE;
+	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 2,
+				region_base,
+				region_top,
+				TZC_REGION_S_RDWR,
+				0);
+
+	/* Region 3 set to cover non-secure shared memory DRAM. */
+	region_base = region_top + 1U;
+	region_top = ddr_top;
+	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 3,
+				region_base,
+				region_top,
+				TZC_REGION_S_NONE,
+				TZC_REGION_NSEC_ALL_ACCESS_RDWR);
+#else
+	/*
+	 * Region 1 set to cover all DRAM at 0xC000_0000. Apply the
 	 * same configuration to all filters in the TZC.
 	 */
 	region_base = ddr_base;
-	region_top = ddr_base + (ddr_size - 1U);
+	region_top = ddr_top;
 	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
-			region_base,
-			region_top,
-			TZC_REGION_S_RDWR,
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) |
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID));
+				region_base,
+				region_top,
+				TZC_REGION_S_NONE,
+				TZC_REGION_NSEC_ALL_ACCESS_RDWR);
+#endif
 
 	/* Raise an exception if a NS device tries to access secure memory */
 	tzc400_set_action(TZC_ACTION_ERR);
@@ -69,15 +106,12 @@
 
 	tzc400_disable_filters();
 
-	/*
-	 * Region 1 set to cover Non-Secure DRAM at 0x8000_0000. Apply the
-	 * same configuration to all filters in the TZC.
-	 */
+	/* Region 1 set to cover Non-Secure DRAM at 0xC000_0000 */
 	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
 				STM32MP_DDR_BASE,
 				STM32MP_DDR_BASE +
 				(STM32MP_DDR_MAX_SIZE - 1U),
-				TZC_REGION_S_RDWR,
+				TZC_REGION_S_NONE,
 				TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
 				TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID));
 
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
index 49cecd4..ee1eecf 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
@@ -51,14 +51,14 @@
 };
 
 /**
- * struct k3_sec_proxy_thread - Description of a secure proxy Thread
- * @id:		Thread ID
+ * struct k3_sec_proxy_thread - Description of a Secure Proxy Thread
+ * @name:	Thread Name
  * @data:	Thread Data path region for target
  * @scfg:	Secure Config Region for Thread
  * @rt:		RealTime Region for Thread
  */
 struct k3_sec_proxy_thread {
-	uint32_t id;
+	const char *name;
 	uintptr_t data;
 	uintptr_t scfg;
 	uintptr_t rt;
@@ -83,7 +83,7 @@
  */
 #define SP_THREAD(_x) \
 	[_x] = { \
-		.id = _x, \
+		.name = #_x, \
 		.data = SEC_PROXY_THREAD(SEC_PROXY_DATA_BASE, _x), \
 		.scfg = SEC_PROXY_THREAD(SEC_PROXY_SCFG_BASE, _x), \
 		.rt = SEC_PROXY_THREAD(SEC_PROXY_RT_BASE, _x), \
@@ -131,19 +131,19 @@
 	/* Check for any errors already available */
 	if (mmio_read_32(spt->rt + RT_THREAD_STATUS) &
 	    RT_THREAD_STATUS_ERROR_MASK) {
-		ERROR("Thread %d is corrupted, cannot send data\n", spt->id);
+		ERROR("Thread %s is corrupted, cannot send data\n", spt->name);
 		return -EINVAL;
 	}
 
 	/* Make sure thread is configured for right direction */
 	if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)
 	    != (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) {
-		if (dir)
-			ERROR("Trying to send data on RX Thread %d\n",
-			      spt->id);
+		if (dir == THREAD_IS_TX)
+			ERROR("Trying to send data on RX Thread %s\n",
+			      spt->name);
 		else
-			ERROR("Trying to receive data on TX Thread %d\n",
-			      spt->id);
+			ERROR("Trying to receive data on TX Thread %s\n",
+			      spt->name);
 		return -EINVAL;
 	}
 
@@ -151,10 +151,12 @@
 	uint32_t tick_start = (uint32_t)read_cntpct_el0();
 	uint32_t ticks_per_us = SYS_COUNTER_FREQ_IN_TICKS / 1000000;
 	while (!(mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK)) {
-		VERBOSE("Waiting for thread %d to clear\n", spt->id);
+		VERBOSE("Waiting for thread %s to %s\n",
+			spt->name, (dir == THREAD_IS_TX) ? "empty" : "fill");
 		if (((uint32_t)read_cntpct_el0() - tick_start) >
 		    (spm.desc.timeout_us * ticks_per_us)) {
-			ERROR("Timeout waiting for thread %d to clear\n", spt->id);
+			ERROR("Timeout waiting for thread %s to %s\n",
+				spt->name, (dir == THREAD_IS_TX) ? "empty" : "fill");
 			return -ETIMEDOUT;
 		}
 	}
@@ -176,13 +178,13 @@
 	/* Check for any errors already available */
 	if (mmio_read_32(spt->rt + RT_THREAD_STATUS) &
 	    RT_THREAD_STATUS_ERROR_MASK) {
-		ERROR("Thread %d is corrupted, cannot send data\n", spt->id);
+		ERROR("Thread %s is corrupted, cannot send data\n", spt->name);
 		return -EINVAL;
 	}
 
 	/* Make sure thread is configured for right direction */
 	if (!(mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)) {
-		ERROR("Cannot clear a transmit thread %d\n", spt->id);
+		ERROR("Cannot clear a transmit thread %s\n", spt->name);
 		return -EINVAL;
 	}
 
@@ -190,10 +192,10 @@
 	uint32_t try_count = 10;
 	while (mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK) {
 		if (!(try_count--)) {
-			ERROR("Could not clear all messages from thread %d\n", spt->id);
+			ERROR("Could not clear all messages from thread %s\n", spt->name);
 			return -ETIMEDOUT;
 		}
-		WARN("Clearing message from thread %d\n", spt->id);
+		WARN("Clearing message from thread %s\n", spt->name);
 		mmio_read_32(spt->data + spm.desc.data_end_offset);
 	}
 
@@ -216,14 +218,14 @@
 
 	ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_TX);
 	if (ret) {
-		ERROR("Thread %d verification failed (%d)\n", spt->id, ret);
+		ERROR("Thread %s verification failed (%d)\n", spt->name, ret);
 		return ret;
 	}
 
 	/* Check the message size */
 	if (msg->len + sizeof(secure_header) > spm.desc.max_msg_size) {
-		ERROR("Thread %d message length %lu > max msg size\n",
-		      spt->id, msg->len);
+		ERROR("Thread %s message length %lu > max msg size\n",
+		      spt->name, msg->len);
 		return -EINVAL;
 	}
 
@@ -263,7 +265,7 @@
 	if (data_reg <= spm.desc.data_end_offset)
 		mmio_write_32(spt->data + spm.desc.data_end_offset, 0);
 
-	VERBOSE("Message successfully sent on thread %ud\n", id);
+	VERBOSE("Message successfully sent on thread %s\n", spt->name);
 
 	return 0;
 }
@@ -275,7 +277,7 @@
  *
  * Return: 0 if all goes well, else appropriate error message
  */
-int k3_sec_proxy_recv(uint32_t id, struct k3_sec_proxy_msg *msg)
+int k3_sec_proxy_recv(enum k3_sec_proxy_chan_id id, struct k3_sec_proxy_msg *msg)
 {
 	struct k3_sec_proxy_thread *spt = &spm.threads[id];
 	union sec_msg_hdr secure_header;
@@ -284,7 +286,7 @@
 
 	ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_RX);
 	if (ret) {
-		ERROR("Thread %d verification failed (%d)\n", spt->id, ret);
+		ERROR("Thread %s verification failed (%d)\n", spt->name, ret);
 		return ret;
 	}
 
@@ -323,7 +325,7 @@
 	/* TODO: Verify checksum */
 	(void)secure_header.checksum;
 
-	VERBOSE("Message successfully received from thread %ud\n", id);
+	VERBOSE("Message successfully received from thread %s\n", spt->name);
 
 	return 0;
 }
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index df0b794..ac33278 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -45,7 +45,6 @@
 		.host_id = TI_SCI_HOST_ID,
 		.max_msg_size = TI_SCI_MAX_MESSAGE_SIZE,
 	},
-	.seq = 0x0a,
 };
 
 /**
@@ -89,10 +88,8 @@
 	    tx_message_size < sizeof(*hdr))
 		return -ERANGE;
 
-	info.seq++;
-
 	hdr = (struct ti_sci_msg_hdr *)tx_buf;
-	hdr->seq = info.seq;
+	hdr->seq = ++info.seq;
 	hdr->type = msg_type;
 	hdr->host = info.desc.host_id;
 	hdr->flags = msg_flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
@@ -119,21 +116,28 @@
 {
 	struct k3_sec_proxy_msg *msg = &xfer->rx_message;
 	struct ti_sci_msg_hdr *hdr;
+	unsigned int retry = 5;
 	int ret;
 
-	/* Receive the response */
-	ret = k3_sec_proxy_recv(chan, msg);
-	if (ret) {
-		ERROR("Message receive failed (%d)\n", ret);
-		return ret;
-	}
+	for (; retry > 0; retry--) {
+		/* Receive the response */
+		ret = k3_sec_proxy_recv(chan, msg);
+		if (ret) {
+			ERROR("Message receive failed (%d)\n", ret);
+			return ret;
+		}
 
-	/* msg is updated by Secure Proxy driver */
-	hdr = (struct ti_sci_msg_hdr *)msg->buf;
+		/* msg is updated by Secure Proxy driver */
+		hdr = (struct ti_sci_msg_hdr *)msg->buf;
 
-	/* Sanity check for message response */
-	if (hdr->seq != info.seq) {
-		ERROR("Message for %d is not expected\n", hdr->seq);
+		/* Sanity check for message response */
+		if (hdr->seq == info.seq)
+			break;
+		else
+			WARN("Message with sequence ID %u is not expected\n", hdr->seq);
+	}
+	if (!retry) {
+		ERROR("Timed out waiting for message\n");
 		return -EINVAL;
 	}
 
@@ -425,7 +429,7 @@
 		return -ERANGE;
 
 	hdr = (struct ti_sci_msg_hdr *)&req;
-	hdr->seq = info.seq;
+	hdr->seq = ++info.seq;
 	hdr->type = TI_SCI_MSG_SET_DEVICE_STATE;
 	hdr->host = info.desc.host_id;
 	/* Setup with NORESPONSE flag to keep response queue clean */
@@ -1408,7 +1412,7 @@
 		return -ERANGE;
 
 	hdr = (struct ti_sci_msg_hdr *)&req;
-	hdr->seq = info.seq;
+	hdr->seq = ++info.seq;
 	hdr->type = TISCI_MSG_SET_PROC_BOOT_CTRL;
 	hdr->host = info.desc.host_id;
 	/* Setup with NORESPONSE flag to keep response queue clean */
@@ -1650,7 +1654,7 @@
 		return -ERANGE;
 
 	hdr = (struct ti_sci_msg_hdr *)&req;
-	hdr->seq = info.seq;
+	hdr->seq = ++info.seq;
 	hdr->type = TISCI_MSG_WAIT_PROC_BOOT_STATUS;
 	hdr->host = info.desc.host_id;
 	/* Setup with NORESPONSE flag to keep response queue clean */
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index 78fb696..b4ec374 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -21,10 +21,9 @@
 
 /* Table of regions to map using the MMU */
 const mmap_region_t plat_k3_mmap[] = {
-	MAP_REGION_FLAT(SHARED_RAM_BASE, SHARED_RAM_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(K3_GIC_BASE, K3_GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(SEC_PROXY_RT_BASE, SEC_PROXY_RT_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(K3_USART_BASE,       K3_USART_SIZE,       MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(K3_GIC_BASE,         K3_GIC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(SEC_PROXY_RT_BASE,   SEC_PROXY_RT_SIZE,   MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	{ /* sentinel */ }
@@ -100,13 +99,10 @@
 void bl31_plat_arch_setup(void)
 {
 	const mmap_region_t bl_regions[] = {
-		MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
-				MT_MEMORY | MT_RW | MT_SECURE),
-		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
-				MT_CODE | MT_SECURE),
-		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_END,
-				MT_RO_DATA | MT_SECURE),
-		{0}
+		MAP_REGION_FLAT(BL31_START,      BL31_END       - BL31_START,     MT_MEMORY  | MT_RW | MT_SECURE),
+		MAP_REGION_FLAT(BL_CODE_BASE,    BL_CODE_END    - BL_CODE_BASE,   MT_CODE    | MT_RO | MT_SECURE),
+		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_END, MT_RO_DATA | MT_RO | MT_SECURE),
+		{ /* sentinel */ }
 	};
 
 	setup_page_tables(bl_regions, plat_k3_mmap);
diff --git a/plat/ti/k3/common/k3_console.c b/plat/ti/k3/common/k3_console.c
index 31c9632..ba0ddac 100644
--- a/plat/ti/k3/common/k3_console.c
+++ b/plat/ti/k3/common/k3_console.c
@@ -16,6 +16,6 @@
 	static console_16550_t console;
 
 	/* Initialize the console to provide early debug support */
-	console_16550_register(K3_USART_BASE_ADDRESS, K3_USART_CLK_SPEED,
+	console_16550_register(K3_USART_BASE, K3_USART_CLK_SPEED,
 			       K3_USART_BAUD, &console);
 }
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index c91a035..29fcafd 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -22,6 +22,9 @@
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+# Split out RO data into a non-executable section
+SEPARATE_CODE_AND_RODATA :=    1
+
 # Leave the caches enabled on core powerdown path
 TI_AM65X_WORKAROUND	:=	1
 $(eval $(call add_define,TI_AM65X_WORKAROUND))
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index f1511c1..68fdae7 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -74,20 +74,14 @@
 
 /*
  * ARM-TF lives in SRAM, partition it here
- */
-
-#define SHARED_RAM_BASE			BL31_LIMIT
-#define SHARED_RAM_SIZE			0x00001000
-
-/*
+ *
  * BL3-1 specific defines.
  *
- * Put BL3-1 at the base of the Trusted SRAM, before SHARED_RAM.
+ * Put BL3-1 at the base of the Trusted SRAM.
  */
 #define BL31_BASE			SEC_SRAM_BASE
-#define BL31_SIZE			(SEC_SRAM_SIZE - SHARED_RAM_SIZE)
+#define BL31_SIZE			SEC_SRAM_SIZE
 #define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
-#define BL31_PROGBITS_LIMIT		BL31_LIMIT
 
 /*
  * Defines the maximum number of translation tables that are allocated by the
@@ -125,8 +119,8 @@
 #define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
 
 /* Platform default console definitions */
-#ifndef K3_USART_BASE_ADDRESS
-#define K3_USART_BASE_ADDRESS 0x02800000
+#ifndef K3_USART_BASE
+#define K3_USART_BASE 0x02800000
 #endif
 
 /* USART has a default size for address space */
@@ -137,7 +131,7 @@
 #endif
 
 /* Crash console defaults */
-#define CRASH_CONSOLE_BASE K3_USART_BASE_ADDRESS
+#define CRASH_CONSOLE_BASE K3_USART_BASE
 #define CRASH_CONSOLE_CLK K3_USART_CLK_SPEED
 #define CRASH_CONSOLE_BAUD_RATE K3_USART_BAUD
 
diff --git a/readme.rst b/readme.rst
index 849bbb3..fc03555 100644
--- a/readme.rst
+++ b/readme.rst
@@ -1,13 +1,18 @@
 Trusted Firmware-A - version 2.1
 ================================
 
+.. section-numbering::
+    :suffix: .
+
+.. contents::
+
 Trusted Firmware-A (TF-A) provides a reference implementation of secure world
 software for `Armv7-A and Armv8-A`_, including a `Secure Monitor`_ executing
 at Exception Level 3 (EL3). It implements various Arm interface standards,
 such as:
 
 -  The `Power State Coordination Interface (PSCI)`_
--  Trusted Board Boot Requirements (TBBR, Arm DEN0006C-1)
+-  `Trusted Board Boot Requirements CLIENT (TBBR-CLIENT)`_
 -  `SMC Calling Convention`_
 -  `System Control and Management Interface (SCMI)`_
 -  `Software Delegated Exception Interface (SDEI)`_
@@ -27,6 +32,12 @@
 to the benefit of all developers working with Armv7-A and Armv8-A TrustZone
 technology.
 
+Documentation contents
+----------------------
+
+The `Trusted Firmware-A Documentation Contents`_ page contains an overview of
+the documentation that is available, with links to facilitate easier browsing.
+
 License
 -------
 
@@ -185,6 +196,8 @@
 -  ``FVP_Base_Cortex-A73x4``
 -  ``FVP_Base_Cortex-A75x4``
 -  ``FVP_Base_Cortex-A76x4``
+-  ``FVP_Base_Cortex-A76AEx4`` (Tested with internal model)
+-  ``FVP_Base_Cortex-A76AEx8`` (Tested with internal model)
 -  ``FVP_Base_Neoverse-N1x4`` (Tested with internal model)
 -  ``FVP_Base_Deimos``
 -  ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
@@ -269,12 +282,6 @@
 project and the `Acknowledgments`_ file for a list of contributors to the
 project.
 
-Documentation contents
-~~~~~~~~~~~~~~~~~~~~~~
-
-The `Trusted Firmware-A Documentation Contents`_ page contains an overview of
-the documentation that is available, with links to facilitate easier browsing.
-
 IRC channel
 ~~~~~~~~~~~
 
@@ -313,6 +320,7 @@
 .. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php
 .. _Power State Coordination Interface (PSCI): PSCI_
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
 .. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
 .. _System Control and Management Interface (SCMI): SCMI_
 .. _SCMI: http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
@@ -326,7 +334,7 @@
 .. _NVIDIA Trusted Little Kernel: http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary
 .. _Trusty Secure OS: https://source.android.com/security/trusty
 .. _trustedfirmware.org: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
-.. _issue tracker: http://issues.trustedfirmware.org
+.. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
 .. _Security Center: ./docs/security-center.rst
 .. _license: ./license.rst
 .. _Contributing Guidelines: ./contributing.rst
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index aa7bd04..3a63f1c 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -104,7 +104,7 @@
 		     rdsvc = rdsvc->next) {
 			uint32_t *rd_uuid = (uint32_t *)(rdsvc->uuid);
 
-			if (memcmp(rd_uuid, svc_uuid, sizeof(rd_uuid)) == 0) {
+			if (memcmp(rd_uuid, svc_uuid, sizeof(*svc_uuid)) == 0) {
 				return sp_ctx;
 			}
 		}