Merge changes Id2a538c3,Ifa0339e7,I8b09fab8 into integration

* changes:
  drivers: marvell: comphy-a3700: Set TXDCLK_2X_SEL bit during PCIe initialization
  drivers: marvell: comphy-a3700: Set mask parameter for every reg_set call
  drivers: marvell: comphy-a3700: Fix configuring polarity invert bits
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 14a3b45..0b3f782 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -9,42 +9,45 @@
 
 More details may be found in the `Project Maintenance Process`_ document.
 
+.. |M| replace:: **Mail**
+.. |G| replace:: **GitHub ID**
+.. |F| replace:: **Files**
 
 .. _maintainers:
 
 Maintainers
 -----------
 
-:M: Dan Handley <dan.handley@arm.com>
-:G: `danh-arm`_
-:M: Soby Mathew <soby.mathew@arm.com>
-:G: `soby-mathew`_
-:M: Sandrine Bailleux <sandrine.bailleux@arm.com>
-:G: `sandrine-bailleux-arm`_
-:M: Alexei Fedorov <Alexei.Fedorov@arm.com>
-:G: `AlexeiFedorov`_
-:M: Manish Pandey <manish.pandey2@arm.com>
-:G: `manish-pandey-arm`_
-:M: Mark Dykes <mark.dykes@arm.com>
-:G: `mardyk01`_
-:M: Olivier Deprez <olivier.deprez@arm.com>
-:G: `odeprez`_
-:M: Bipin Ravi <bipin.ravi@arm.com>
-:G: `bipinravi-arm`_
-:M: Joanna Farley <joanna.farley@arm.com>
-:G: `joannafarley-arm`_
-:M: Julius Werner <jwerner@chromium.org>
-:G: `jwerner-chromium`_
-:M: Varun Wadekar <vwadekar@nvidia.com>
-:G: `vwadekar`_
-:M: Andre Przywara <andre.przywara@arm.com>
-:G: `Andre-ARM`_
-:M: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
-:G: `laurenw-arm`_
-:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
-:G: `madhukar-Arm`_
-:M: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
-:G: `raghuncstate`_
+:|M|: Dan Handley <dan.handley@arm.com>
+:|G|: `danh-arm`_
+:|M|: Soby Mathew <soby.mathew@arm.com>
+:|G|: `soby-mathew`_
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
+:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
+:|G|: `AlexeiFedorov`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Mark Dykes <mark.dykes@arm.com>
+:|G|: `mardyk01`_
+:|M|: Olivier Deprez <olivier.deprez@arm.com>
+:|G|: `odeprez`_
+:|M|: Bipin Ravi <bipin.ravi@arm.com>
+:|G|: `bipinravi-arm`_
+:|M|: Joanna Farley <joanna.farley@arm.com>
+:|G|: `joannafarley-arm`_
+:|M|: Julius Werner <jwerner@chromium.org>
+:|G|: `jwerner-chromium`_
+:|M|: Varun Wadekar <vwadekar@nvidia.com>
+:|G|: `vwadekar`_
+:|M|: Andre Przywara <andre.przywara@arm.com>
+:|G|: `Andre-ARM`_
+:|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:|G|: `laurenw-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:|G|: `raghuncstate`_
 
 
 .. _code owners:
@@ -52,59 +55,59 @@
 Code owners
 -----------
 
-Core Code
-~~~~~~~~~
+Common Code
+~~~~~~~~~~~
 
 Armv7-A architecture port
 ^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Etienne Carriere <etienne.carriere@linaro.org>
-:G: `etienne-lms`_
+:|M|: Etienne Carriere <etienne.carriere@linaro.org>
+:|G|: `etienne-lms`_
 
 Build Definitions for CMake Build System
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
-:G: `javieralso-arm`_
-:M: Chris Kay <chris.kay@arm.com>
-:G: `CJkay`_
-:F: /
+:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
+:|G|: `javieralso-arm`_
+:|M|: Chris Kay <chris.kay@arm.com>
+:|G|: `CJKay`_
+:|F|: /
 
 Software Delegated Exception Interface (SDEI)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Mark Dykes <mark.dykes@arm.com>
-:G: `mardyk01`_
-:M: John Powell <John.Powell@arm.com>
-:G: `john-powell-arm`_
-:F: services/std_svc/sdei/
+:|M|: Mark Dykes <mark.dykes@arm.com>
+:|G|: `mardyk01`_
+:|M|: John Powell <John.Powell@arm.com>
+:|G|: `john-powell-arm`_
+:|F|: services/std_svc/sdei/
 
 Trusted Boot
 ^^^^^^^^^^^^
-:M: Sandrine Bailleux <sandrine.bailleux@arm.com>
-:G: `sandrine-bailleux-arm`_
-:M: Manish Pandey <manish.pandey2@arm.com>
-:G: `manish-pandey-arm`_
-:M: Manish Badarkhe <manish.badarkhe@arm.com>
-:G: `ManishVB-Arm`_
-:F: drivers/auth/
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|F|: drivers/auth/
 
 Secure Partition Manager (SPM)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Olivier Deprez <olivier.deprez@arm.com>
-:G: `odeprez`_
-:M: Manish Pandey <manish.pandey2@arm.com>
-:G: `manish-pandey-arm`_
-:M: Maksims Svecovs <maksims.svecovs@arm.com>
-:G: `max-shvetsov`_
-:M: Joao Alves <Joao.Alves@arm.com>
-:G: `J-Alves`_
-:F: services/std_svc/spm\*
+:|M|: Olivier Deprez <olivier.deprez@arm.com>
+:|G|: `odeprez`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Maksims Svecovs <maksims.svecovs@arm.com>
+:|G|: `max-shvetsov`_
+:|M|: Joao Alves <Joao.Alves@arm.com>
+:|G|: `J-Alves`_
+:|F|: services/std_svc/spm\*
 
 Exception Handling Framework (EHF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Manish Badarkhe <manish.badarkhe@arm.com>
-:G: `ManishVB-Arm`_
-:M: John Powell <John.Powell@arm.com>
-:G: `john-powell-arm`_
-:F: bl31/ehf.c
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|M|: John Powell <John.Powell@arm.com>
+:|G|: `john-powell-arm`_
+:|F|: bl31/ehf.c
 
 
 Drivers, Libraries and Framework Code
@@ -112,455 +115,500 @@
 
 Console API framework
 ^^^^^^^^^^^^^^^^^^^^^
-:M: Julius Werner <jwerner@chromium.org>
-:G: `jwerner-chromium`_
-:F: drivers/console/
-:F: include/drivers/console.h
-:F: plat/common/aarch64/crash_console_helpers.S
+:|M|: Julius Werner <jwerner@chromium.org>
+:|G|: `jwerner-chromium`_
+:|F|: drivers/console/
+:|F|: include/drivers/console.h
+:|F|: plat/common/aarch64/crash_console_helpers.S
 
 coreboot support libraries
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Julius Werner <jwerner@chromium.org>
-:G: `jwerner-chromium`_
-:F: drivers/coreboot/
-:F: include/drivers/coreboot/
-:F: include/lib/coreboot.h
-:F: lib/coreboot/
+:|M|: Julius Werner <jwerner@chromium.org>
+:|G|: `jwerner-chromium`_
+:|F|: drivers/coreboot/
+:|F|: include/drivers/coreboot/
+:|F|: include/lib/coreboot.h
+:|F|: lib/coreboot/
 
 eMMC/UFS drivers
 ^^^^^^^^^^^^^^^^
-:M: Haojian Zhuang <haojian.zhuang@linaro.org>
-:G: `hzhuang1`_
-:F: drivers/partition/
-:F: drivers/synopsys/emmc/
-:F: drivers/synopsys/ufs/
-:F: drivers/ufs/
-:F: include/drivers/dw_ufs.h
-:F: include/drivers/ufs.h
-:F: include/drivers/synopsys/dw_mmc.h
+:|M|: Haojian Zhuang <haojian.zhuang@linaro.org>
+:|G|: `hzhuang1`_
+:|F|: drivers/partition/
+:|F|: drivers/synopsys/emmc/
+:|F|: drivers/synopsys/ufs/
+:|F|: drivers/ufs/
+:|F|: include/drivers/dw_ufs.h
+:|F|: include/drivers/ufs.h
+:|F|: include/drivers/synopsys/dw_mmc.h
 
 Power State Coordination Interface (PSCI)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
-:G: `javieralso-arm`_
-:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
-:G: `madhukar-Arm`_
-:M: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
-:G: `laurenw-arm`_
-:M: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:G: `zelalem-aweke`_
-:F: lib/psci/
+:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
+:|G|: `javieralso-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:|G|: `laurenw-arm`_
+:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:|G|: `zelalem-aweke`_
+:|F|: lib/psci/
 
 DebugFS
 ^^^^^^^
-:M: Olivier Deprez <olivier.deprez@arm.com>
-:G: `odeprez`_
-:F: lib/debugfs/
+:|M|: Olivier Deprez <olivier.deprez@arm.com>
+:|G|: `odeprez`_
+:|F|: lib/debugfs/
 
 Firmware Configuration Framework (FCONF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
-:G: `madhukar-Arm`_
-:M: Manish Badarkhe <manish.badarkhe@arm.com>
-:G: `ManishVB-Arm`_
-:M: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
-:G: `laurenw-arm`_
-:F: lib/fconf/
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:|G|: `laurenw-arm`_
+:|F|: lib/fconf/
 
 Performance Measurement Framework (PMF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Joao Alves <Joao.Alves@arm.com>
-:G: `J-Alves`_
-:M: Jimmy Brisson <Jimmy.Brisson@arm.com>
-:G: `theotherjimmy`_
-:F: lib/pmf/
+:|M|: Joao Alves <Joao.Alves@arm.com>
+:|G|: `J-Alves`_
+:|M|: Jimmy Brisson <Jimmy.Brisson@arm.com>
+:|G|: `theotherjimmy`_
+:|F|: lib/pmf/
 
 Arm CPU libraries
 ^^^^^^^^^^^^^^^^^
-:M: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
-:G: `laurenw-arm`_
-:M: John Powell <John.Powell@arm.com>
-:G: `john-powell-arm`_
-:F: lib/cpus/
+:|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:|G|: `laurenw-arm`_
+:|M|: John Powell <John.Powell@arm.com>
+:|G|: `john-powell-arm`_
+:|F|: lib/cpus/
 
 Reliability Availability Serviceabilty (RAS) framework
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Olivier Deprez <olivier.deprez@arm.com>
-:G: `odeprez`_
-:M: Manish Pandey <manish.pandey2@arm.com>
-:G: `manish-pandey-arm`_
-:F: lib/extensions/ras/
+:|M|: Olivier Deprez <olivier.deprez@arm.com>
+:|G|: `odeprez`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|F|: lib/extensions/ras/
 
 Activity Monitors Unit (AMU) extensions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Alexei Fedorov <Alexei.Fedorov@arm.com>
-:G: `AlexeiFedorov`_
-:F: lib/extensions/amu/
+:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
+:|G|: `AlexeiFedorov`_
+:|F|: lib/extensions/amu/
 
 Memory Partitioning And Monitoring (MPAM) extensions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:G: `zelalem-aweke`_
-:M: Jimmy Brisson <Jimmy.Brisson@arm.com>
-:G: `theotherjimmy`_
-:F: lib/extensions/mpam/
+:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:|G|: `zelalem-aweke`_
+:|M|: Jimmy Brisson <Jimmy.Brisson@arm.com>
+:|G|: `theotherjimmy`_
+:|F|: lib/extensions/mpam/
 
 Pointer Authentication (PAuth) and Branch Target Identification (BTI) extensions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Alexei Fedorov <Alexei.Fedorov@arm.com>
-:G: `AlexeiFedorov`_
-:M: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:G: `zelalem-aweke`_
-:F: lib/extensions/pauth/
+:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
+:|G|: `AlexeiFedorov`_
+:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:|G|: `zelalem-aweke`_
+:|F|: lib/extensions/pauth/
 
 Statistical Profiling Extension (SPE)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:G: `zelalem-aweke`_
-:M: Jimmy Brisson <Jimmy.Brisson@arm.com>
-:G: `theotherjimmy`_
-:F: lib/extensions/spe/
+:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:|G|: `zelalem-aweke`_
+:|M|: Jimmy Brisson <Jimmy.Brisson@arm.com>
+:|G|: `theotherjimmy`_
+:|F|: lib/extensions/spe/
 
 Scalable Vector Extension (SVE)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Jimmy Brisson <Jimmy.Brisson@arm.com>
-:G: `theotherjimmy`_
-:F: lib/extensions/sve/
+:|M|: Jimmy Brisson <Jimmy.Brisson@arm.com>
+:|G|: `theotherjimmy`_
+:|F|: lib/extensions/sve/
 
 Standard C library
 ^^^^^^^^^^^^^^^^^^
-:M: Alexei Fedorov <Alexei.Fedorov@arm.com>
-:G: `AlexeiFedorov`_
-:M: John Powell <John.Powell@arm.com>
-:G: `john-powell-arm`_
-:F: lib/libc/
+:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
+:|G|: `AlexeiFedorov`_
+:|M|: John Powell <John.Powell@arm.com>
+:|G|: `john-powell-arm`_
+:|F|: lib/libc/
 
 Library At ROM (ROMlib)
 ^^^^^^^^^^^^^^^^^^^^^^^
-:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
-:G: `madhukar-Arm`_
-:F: lib/romlib/
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: lib/romlib/
 
 Translation tables (``xlat_tables``) library
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
-:G: `javieralso-arm`_
-:M: Joao Alves <Joao.Alves@arm.com>
-:G: `J-Alves`_
-:F: lib/xlat\_tables_\*/
+:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
+:|G|: `javieralso-arm`_
+:|M|: Joao Alves <Joao.Alves@arm.com>
+:|G|: `J-Alves`_
+:|F|: lib/xlat\_tables_\*/
 
 IO abstraction layer
 ^^^^^^^^^^^^^^^^^^^^
-:M: Manish Pandey <manish.pandey2@arm.com>
-:G: `manish-pandey-arm`_
-:M: Olivier Deprez <olivier.deprez@arm.com>
-:G: `odeprez`_
-:F: drivers/io/
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Olivier Deprez <olivier.deprez@arm.com>
+:|G|: `odeprez`_
+:|F|: drivers/io/
 
 GIC driver
 ^^^^^^^^^^
-:M: Alexei Fedorov <Alexei.Fedorov@arm.com>
-:G: `AlexeiFedorov`_
-:M: Manish Pandey <manish.pandey2@arm.com>
-:G: `manish-pandey-arm`_
-:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
-:G: `madhukar-Arm`_
-:M: Olivier Deprez <olivier.deprez@arm.com>
-:G: `odeprez`_
-:F: drivers/arm/gic/
+:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
+:|G|: `AlexeiFedorov`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|M|: Olivier Deprez <olivier.deprez@arm.com>
+:|G|: `odeprez`_
+:|F|: drivers/arm/gic/
 
 Libfdt wrappers
 ^^^^^^^^^^^^^^^
-:M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
-:G: `madhukar-Arm`_
-:M: Manish Badarkhe <manish.badarkhe@arm.com>
-:G: `ManishVB-Arm`_
-:F: common/fdt_wrappers.c
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|F|: common/fdt_wrappers.c
 
 Firmware Encryption Framework
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Sumit Garg <sumit.garg@linaro.org>
-:G: `b49020`_
-:F: drivers/io/io_encrypted.c
-:F: include/drivers/io/io_encrypted.h
-:F: include/tools_share/firmware_encrypted.h
+:|M|: Sumit Garg <sumit.garg@linaro.org>
+:|G|: `b49020`_
+:|F|: drivers/io/io_encrypted.c
+:|F|: include/drivers/io/io_encrypted.h
+:|F|: include/tools_share/firmware_encrypted.h
 
 Measured Boot
 ^^^^^^^^^^^^^
-:M: Alexei Fedorov <Alexei.Fedorov@arm.com>
-:G: `AlexeiFedorov`_
-:M: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
-:G: `javieralso-arm`_
-:F: drivers/measured_boot
-:F: include/drivers/measured_boot
-:F: plat/arm/board/fvp/fvp_measured_boot.c
+:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
+:|G|: `AlexeiFedorov`_
+:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
+:|G|: `javieralso-arm`_
+:|F|: drivers/measured_boot
+:|F|: include/drivers/measured_boot
+:|F|: plat/arm/board/fvp/fvp_measured_boot.c
 
 System Control and Management Interface (SCMI) Server
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Etienne Carriere <etienne.carriere@st.com>
-:G: `etienne-lms`_
-:M: Peng Fan <peng.fan@nxp.com>
-:G: `MrVan`_
-:F: drivers/scmi-msg
-:F: include/drivers/scmi\*
+:|M|: Etienne Carriere <etienne.carriere@st.com>
+:|G|: `etienne-lms`_
+:|M|: Peng Fan <peng.fan@nxp.com>
+:|G|: `MrVan`_
+:|F|: drivers/scmi-msg
+:|F|: include/drivers/scmi\*
 
 Platform Ports
 ~~~~~~~~~~~~~~
 
 Allwinner ARMv8 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Andre Przywara <andre.przywara@arm.com>
-:G: `Andre-ARM`_
-:M: Samuel Holland <samuel@sholland.org>
-:G: `smaeul`_
-:F: docs/plat/allwinner.rst
-:F: plat/allwinner/
-:F: drivers/allwinner/
+:|M|: Andre Przywara <andre.przywara@arm.com>
+:|G|: `Andre-ARM`_
+:|M|: Samuel Holland <samuel@sholland.org>
+:|G|: `smaeul`_
+:|F|: docs/plat/allwinner.rst
+:|F|: plat/allwinner/
+:|F|: drivers/allwinner/
 
 Amlogic Meson S905 (GXBB) platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Andre Przywara <andre.przywara@arm.com>
-:G: `Andre-ARM`_
-:F: docs/plat/meson-gxbb.rst
-:F: drivers/amlogic/
-:F: plat/amlogic/gxbb/
+:|M|: Andre Przywara <andre.przywara@arm.com>
+:|G|: `Andre-ARM`_
+:|F|: docs/plat/meson-gxbb.rst
+:|F|: drivers/amlogic/
+:|F|: plat/amlogic/gxbb/
 
 Amlogic Meson S905x (GXL) platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Remi Pommarel <repk@triplefau.lt>
-:G: `remi-triplefault`_
-:F: docs/plat/meson-gxl.rst
-:F: plat/amlogic/gxl/
+:|M|: Remi Pommarel <repk@triplefau.lt>
+:|G|: `remi-triplefault`_
+:|F|: docs/plat/meson-gxl.rst
+:|F|: plat/amlogic/gxl/
 
 Amlogic Meson S905X2 (G12A) platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Carlo Caione <ccaione@baylibre.com>
-:G: `carlocaione`_
-:F: docs/plat/meson-g12a.rst
-:F: plat/amlogic/g12a/
+:|M|: Carlo Caione <ccaione@baylibre.com>
+:|G|: `carlocaione`_
+:|F|: docs/plat/meson-g12a.rst
+:|F|: plat/amlogic/g12a/
 
 Amlogic Meson A113D (AXG) platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Carlo Caione <ccaione@baylibre.com>
-:G: `carlocaione`_
-:F: docs/plat/meson-axg.rst
-:F: plat/amlogic/axg/
+:|M|: Carlo Caione <ccaione@baylibre.com>
+:|G|: `carlocaione`_
+:|F|: docs/plat/meson-axg.rst
+:|F|: plat/amlogic/axg/
 
 Arm FPGA platform port
 ^^^^^^^^^^^^^^^^^^^^^^
-:M: Andre Przywara <andre.przywara@arm.com>
-:G: `Andre-ARM`_
-:M: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
-:G: `javieralso-arm`_
-:F: plat/arm/board/arm_fpga
+:|M|: Andre Przywara <andre.przywara@arm.com>
+:|G|: `Andre-ARM`_
+:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
+:|G|: `javieralso-arm`_
+:|F|: plat/arm/board/arm_fpga
 
-Arm System Guidance for Infrastructure / Mobile FVP platforms
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Nariman Poushin <nariman.poushin@linaro.org>
-:G: `npoushin`_
-:M: Thomas Abraham <thomas.abraham@arm.com>
-:G: `thomas-arm`_
-:F: plat/arm/css/sgi/
-:F: plat/arm/css/sgm/
-:F: plat/arm/board/sgi575/
-:F: plat/arm/board/sgm775/
+Arm FVP Platform port
+^^^^^^^^^^^^^^^^^^^^^
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: plat/arm/board/fvp
+
+Arm Juno Platform port
+^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Chris Kay <chris.kay@arm.com>
+:|G|: `CJKay`_
+:|F|: plat/arm/board/juno
+
+Arm Morello and N1SDP Platform ports
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Manoj Kumar <manoj.kumar3@arm.com>
+:|G|: `manojkumar-arm`_
+:|M|: Chandni Cherukuri <chandni.cherukuri@arm.com>
+:|G|: `chandnich`_
+:|F|: plat/arm/board/morello
+:|F|: plat/arm/board/n1sdp
+
+Arm Rich IoT Platform ports
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+:|G|: `abdellatif-elkhlifi`_
+:|M|: Vishnu Banavath <vishnu.banavath@arm.com>
+:|G|: `vishnu-banavath`_
+:|F|: plat/arm/board/corstone700
+:|F|: plat/arm/board/a5ds
+
+Arm Reference Design platform ports
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Thomas Abraham <thomas.abraham@arm.com>
+:|G|: `thomas-arm`_
+:|M|: Vijayenthiran Subramaniam <vijayenthiran.subramaniam@arm.com>
+:|G|: `vijayenthiran-arm`_
+:|F|: plat/arm/css/sgi/
+:|F|: plat/arm/board/rde1edge/
+:|F|: plat/arm/board/rdn1edge/
+:|F|: plat/arm/board/rdn2/
+:|F|: plat/arm/board/rdv1/
+:|F|: plat/arm/board/rdv1mc/
+:|F|: plat/arm/board/sgi575/
+
+Arm Total Compute(tc0) platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
+:|G|: `arugan02`_
+:|M|: Usama Arif <usama.arif@arm.com>
+:|G|: `uarif1`_
+:|F|: plat/arm/board/tc0
 
 HiSilicon HiKey and HiKey960 platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Haojian Zhuang <haojian.zhuang@linaro.org>
-:G: `hzhuang1`_
-:F: docs/plat/hikey.rst
-:F: docs/plat/hikey960.rst
-:F: plat/hisilicon/hikey/
-:F: plat/hisilicon/hikey960/
+:|M|: Haojian Zhuang <haojian.zhuang@linaro.org>
+:|G|: `hzhuang1`_
+:|F|: docs/plat/hikey.rst
+:|F|: docs/plat/hikey960.rst
+:|F|: plat/hisilicon/hikey/
+:|F|: plat/hisilicon/hikey960/
 
 HiSilicon Poplar platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Shawn Guo <shawn.guo@linaro.org>
-:G: `shawnguo2`_
-:F: docs/plat/poplar.rst
-:F: plat/hisilicon/poplar/
+:|M|: Shawn Guo <shawn.guo@linaro.org>
+:|G|: `shawnguo2`_
+:|F|: docs/plat/poplar.rst
+:|F|: plat/hisilicon/poplar/
 
 Intel SocFPGA platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Tien Hock Loh <tien.hock.loh@intel.com>
-:G: `thloh85-intel`_
-:M: Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
-:G: mabdulha
-:F: plat/intel/soc
-:F: drivers/intel/soc/
+:|M|: Tien Hock Loh <tien.hock.loh@intel.com>
+:|G|: `thloh85-intel`_
+:|M|: Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
+:|G|: mabdulha
+:|F|: plat/intel/soc
+:|F|: drivers/intel/soc/
 
 MediaTek platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^
-:M: Yidi Lin (林以廸) <yidi.lin@mediatek.com>
-:G: `mtk09422`_
-:F: plat/mediatek/
+:|M|: Yidi Lin (林以廸) <yidi.lin@mediatek.com>
+:|G|: `mtk09422`_
+:|F|: plat/mediatek/
 
 Marvell platform ports and SoC drivers
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Konstantin Porotchkin <kostap@marvell.com>
-:G: `kostapr`_
-:F: docs/plat/marvell/
-:F: plat/marvell/
-:F: drivers/marvell/
-:F: tools/marvell/
+:|M|: Konstantin Porotchkin <kostap@marvell.com>
+:|G|: `kostapr`_
+:|F|: docs/plat/marvell/
+:|F|: plat/marvell/
+:|F|: drivers/marvell/
+:|F|: tools/marvell/
 
 NVidia platform ports
 ^^^^^^^^^^^^^^^^^^^^^
-:M: Varun Wadekar <vwadekar@nvidia.com>
-:G: `vwadekar`_
-:F: docs/plat/nvidia-tegra.rst
-:F: include/lib/cpus/aarch64/denver.h
-:F: lib/cpus/aarch64/denver.S
-:F: plat/nvidia/
+:|M|: Varun Wadekar <vwadekar@nvidia.com>
+:|G|: `vwadekar`_
+:|F|: docs/plat/nvidia-tegra.rst
+:|F|: include/lib/cpus/aarch64/denver.h
+:|F|: lib/cpus/aarch64/denver.S
+:|F|: plat/nvidia/
 
 NXP QorIQ Layerscape platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Jiafei Pan <jiafei.pan@nxp.com>
-:G: `qoriq-open-source`_
-:F: docs/plat/ls1043a.rst
-:F: plat/layerscape/
+:|M|: Jiafei Pan <jiafei.pan@nxp.com>
+:|G|: `qoriq-open-source`_
+:|F|: docs/plat/ls1043a.rst
+:|F|: plat/layerscape/
 
 NXP i.MX 7 WaRP7 platform port and SoC drivers
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
-:G: `bryanodonoghue`_
-:M: Jun Nie <jun.nie@linaro.org>
-:G: `niej`_
-:F: docs/plat/warp7.rst
-:F: plat/imx/common/
-:F: plat/imx/imx7/
-:F: drivers/imx/timer/
-:F: drivers/imx/uart/
-:F: drivers/imx/usdhc/
+:|M|: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+:|G|: `bryanodonoghue`_
+:|M|: Jun Nie <jun.nie@linaro.org>
+:|G|: `niej`_
+:|F|: docs/plat/warp7.rst
+:|F|: plat/imx/common/
+:|F|: plat/imx/imx7/
+:|F|: drivers/imx/timer/
+:|F|: drivers/imx/uart/
+:|F|: drivers/imx/usdhc/
 
 NXP i.MX 8 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Anson Huang <Anson.Huang@nxp.com>
-:G: `Anson-Huang`_
-:F: docs/plat/imx8.rst
-:F: plat/imx/
+:|M|: Anson Huang <Anson.Huang@nxp.com>
+:|G|: `Anson-Huang`_
+:|F|: docs/plat/imx8.rst
+:|F|: plat/imx/
 
 NXP i.MX8M platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Jacky Bai <ping.bai@nxp.com>
-:G: `JackyBai`_
-:F: docs/plat/imx8m.rst
-:F: plat/imx/imx8m/
+:|M|: Jacky Bai <ping.bai@nxp.com>
+:|G|: `JackyBai`_
+:|F|: docs/plat/imx8m.rst
+:|F|: plat/imx/imx8m/
 
 QEMU platform port
 ^^^^^^^^^^^^^^^^^^
-:M: Jens Wiklander <jens.wiklander@linaro.org>
-:G: `jenswi-linaro`_
-:F: docs/plat/qemu.rst
-:F: plat/qemu/
+:|M|: Jens Wiklander <jens.wiklander@linaro.org>
+:|G|: `jenswi-linaro`_
+:|F|: docs/plat/qemu.rst
+:|F|: plat/qemu/
 
 QTI platform port
 ^^^^^^^^^^^^^^^^^
-:M: Saurabh Gorecha <sgorecha@codeaurora.org>
-:G: `sgorecha`_
-:M: Debasish Mandal <dmandal@codeaurora.org>
-:M: QTI TF Maintainers <qti.trustedfirmware.maintainers@codeaurora.org>
-:F: docs/plat/qti.rst
-:F: plat/qti/
+:|M|: Saurabh Gorecha <sgorecha@codeaurora.org>
+:|G|: `sgorecha`_
+:|M|: Debasish Mandal <dmandal@codeaurora.org>
+:|M|: QTI TF Maintainers <qti.trustedfirmware.maintainers@codeaurora.org>
+:|F|: docs/plat/qti.rst
+:|F|: plat/qti/
 
 Raspberry Pi 3 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
-:G: `grandpaul`_
-:F: docs/plat/rpi3.rst
-:F: plat/rpi/rpi3/
-:F: plat/rpi/common/
-:F: drivers/rpi3/
-:F: include/drivers/rpi3/
+:|M|: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+:|G|: `grandpaul`_
+:|F|: docs/plat/rpi3.rst
+:|F|: plat/rpi/rpi3/
+:|F|: plat/rpi/common/
+:|F|: drivers/rpi3/
+:|F|: include/drivers/rpi3/
 
 Raspberry Pi 4 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Andre Przywara <andre.przywara@arm.com>
-:G: `Andre-ARM`_
-:F: docs/plat/rpi4.rst
-:F: plat/rpi/rpi4/
-:F: plat/rpi/common/
-:F: drivers/rpi3/
-:F: include/drivers/rpi3/
+:|M|: Andre Przywara <andre.przywara@arm.com>
+:|G|: `Andre-ARM`_
+:|F|: docs/plat/rpi4.rst
+:|F|: plat/rpi/rpi4/
+:|F|: plat/rpi/common/
+:|F|: drivers/rpi3/
+:|F|: include/drivers/rpi3/
 
 Renesas rcar-gen3 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Jorge Ramirez-Ortiz  <jramirez@baylibre.com>
-:G: `ldts`_
-:M: Marek Vasut <marek.vasut@gmail.com>
-:G: `marex`_
-:F: docs/plat/rcar-gen3.rst
-:F: plat/renesas/common
-:F: plat/renesas/rcar
-:F: drivers/renesas/common
-:F: drivers/renesas/rcar
-:F: tools/renesas/rcar_layout_create
+:|M|: Jorge Ramirez-Ortiz  <jramirez@baylibre.com>
+:|G|: `ldts`_
+:|M|: Marek Vasut <marek.vasut@gmail.com>
+:|G|: `marex`_
+:|F|: docs/plat/rcar-gen3.rst
+:|F|: plat/renesas/common
+:|F|: plat/renesas/rcar
+:|F|: drivers/renesas/common
+:|F|: drivers/renesas/rcar
+:|F|: tools/renesas/rcar_layout_create
 
 Renesas RZ/G2 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Biju Das <biju.das.jz@bp.renesas.com>
-:G: `bijucdas`_
-:M: Marek Vasut <marek.vasut@gmail.com>
-:G: `marex`_
-:M: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
-:G: `prabhakarlad`_
-:F: docs/plat/rz-g2.rst
-:F: plat/renesas/common
-:F: plat/renesas/rzg
-:F: drivers/renesas/common
-:F: drivers/renesas/rzg
-:F: tools/renesas/rzg_layout_create
+:|M|: Biju Das <biju.das.jz@bp.renesas.com>
+:|G|: `bijucdas`_
+:|M|: Marek Vasut <marek.vasut@gmail.com>
+:|G|: `marex`_
+:|M|: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+:|G|: `prabhakarlad`_
+:|F|: docs/plat/rz-g2.rst
+:|F|: plat/renesas/common
+:|F|: plat/renesas/rzg
+:|F|: drivers/renesas/common
+:|F|: drivers/renesas/rzg
+:|F|: tools/renesas/rzg_layout_create
 
 RockChip platform port
 ^^^^^^^^^^^^^^^^^^^^^^
-:M: Tony Xie <tony.xie@rock-chips.com>
-:G: `TonyXie06`_
-:G: `rockchip-linux`_
-:M: Heiko Stuebner <heiko@sntech.de>
-:G: `mmind`_
-:F: plat/rockchip/
+:|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
 ^^^^^^^^^^^^^^^^^^^^^^
-:M: Yann Gautier <yann.gautier@st.com>
-:G: `Yann-lms`_
-:F: docs/plat/stm32mp1.rst
-:F: drivers/st/
-:F: fdts/stm32\*
-:F: include/drivers/st/
-:F: include/dt-bindings/\*/stm32\*
-:F: plat/st/
-:F: tools/stm32image/
+:|M|: Yann Gautier <yann.gautier@st.com>
+:|G|: `Yann-lms`_
+:|F|: docs/plat/stm32mp1.rst
+:|F|: drivers/st/
+:|F|: fdts/stm32\*
+:|F|: include/drivers/st/
+:|F|: include/dt-bindings/\*/stm32\*
+:|F|: plat/st/
+:|F|: tools/stm32image/
 
 Synquacer platform port
 ^^^^^^^^^^^^^^^^^^^^^^^
-:M: Sumit Garg <sumit.garg@linaro.org>
-:G: `b49020`_
-:F: docs/plat/synquacer.rst
-:F: plat/socionext/synquacer/
+:|M|: Sumit Garg <sumit.garg@linaro.org>
+:|G|: `b49020`_
+:|F|: docs/plat/synquacer.rst
+:|F|: plat/socionext/synquacer/
 
 Texas Instruments platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Nishanth Menon <nm@ti.com>
-:G: `nmenon`_
-:F: docs/plat/ti-k3.rst
-:F: plat/ti/
+:|M|: Nishanth Menon <nm@ti.com>
+:|G|: `nmenon`_
+:|F|: docs/plat/ti-k3.rst
+:|F|: plat/ti/
 
 UniPhier platform port
 ^^^^^^^^^^^^^^^^^^^^^^
-:M: Orphan
-:F: docs/plat/socionext-uniphier.rst
-:F: plat/socionext/uniphier/
+:|M|: Orphan
+:|F|: docs/plat/socionext-uniphier.rst
+:|F|: plat/socionext/uniphier/
 
 Xilinx platform port
 ^^^^^^^^^^^^^^^^^^^^
-:M: Michal Simek <michal.simek@xilinx.com>
-:G: `michalsimek`_
-:M: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@xilinx.com>
-:G: `venkatesh`_
-:F: docs/plat/xilinx-zynqmp.rst
-:F: plat/xilinx/
+:|M|: Michal Simek <michal.simek@xilinx.com>
+:|G|: `michalsimek`_
+:|M|: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@xilinx.com>
+:|G|: `venkatesh`_
+:|F|: docs/plat/xilinx-zynqmp.rst
+:|F|: plat/xilinx/
 
 
 Secure Payloads and Dispatchers
@@ -568,61 +616,61 @@
 
 OP-TEE dispatcher
 ^^^^^^^^^^^^^^^^^
-:M: Jens Wiklander <jens.wiklander@linaro.org>
-:G: `jenswi-linaro`_
-:F: docs/components/spd/optee-dispatcher.rst
-:F: services/spd/opteed/
+:|M|: Jens Wiklander <jens.wiklander@linaro.org>
+:|G|: `jenswi-linaro`_
+:|F|: docs/components/spd/optee-dispatcher.rst
+:|F|: services/spd/opteed/
 
 TLK/Trusty secure payloads
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Varun Wadekar <vwadekar@nvidia.com>
-:G: `vwadekar`_
-:F: docs/components/spd/tlk-dispatcher.rst
-:F: docs/components/spd/trusty-dispatcher.rst
-:F: include/bl32/payloads/tlk.h
-:F: services/spd/tlkd/
-:F: services/spd/trusty/
+:|M|: Varun Wadekar <vwadekar@nvidia.com>
+:|G|: `vwadekar`_
+:|F|: docs/components/spd/tlk-dispatcher.rst
+:|F|: docs/components/spd/trusty-dispatcher.rst
+:|F|: include/bl32/payloads/tlk.h
+:|F|: services/spd/tlkd/
+:|F|: services/spd/trusty/
 
 Test Secure Payload (TSP)
 ^^^^^^^^^^^^^^^^^^^^^^^^^
-:M: Manish Badarkhe <manish.badarkhe@arm.com>
-:G: `ManishVB-Arm`_
-:F: bl32/tsp/
-:F: services/spd/tspd/
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|F|: bl32/tsp/
+:|F|: services/spd/tspd/
 
 Tools
 ~~~~~
 
 Fiptool
 ^^^^^^^
-:M: Joao Alves <Joao.Alves@arm.com>
-:G: `J-Alves`_
-:F: tools/fiptool/
+:|M|: Joao Alves <Joao.Alves@arm.com>
+:|G|: `J-Alves`_
+:|F|: tools/fiptool/
 
 Cert_create tool
 ^^^^^^^^^^^^^^^^
-:M: Sandrine Bailleux <sandrine.bailleux@arm.com>
-:G: `sandrine-bailleux-arm`_
-:F: tools/cert_create/
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
+:|F|: tools/cert_create/
 
 Encrypt_fw tool
 ^^^^^^^^^^^^^^^
-:M: Sumit Garg <sumit.garg@linaro.org>
-:G: `b49020`_
-:F: tools/encrypt_fw/
+:|M|: Sumit Garg <sumit.garg@linaro.org>
+:|G|: `b49020`_
+:|F|: tools/encrypt_fw/
 
 Sptool
 ^^^^^^
-:M: Manish Pandey <manish.pandey2@arm.com>
-:G: `manish-pandey-arm`_
-:F: tools/sptool/
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|F|: tools/sptool/
 
 Build system
 ^^^^^^^^^^^^
-:M: Manish Pandey <manish.pandey2@arm.com>
-:G: `manish-pandey-arm`_
-:F: Makefile
-:F: make_helpers/
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|F|: Makefile
+:|F|: make_helpers/
 
 .. _AlexeiFedorov: https://github.com/AlexeiFedorov
 .. _Andre-ARM: https://github.com/Andre-ARM
@@ -681,5 +729,12 @@
 .. _raghuncstate: https://github.com/raghuncstate
 .. _CJKay: https://github.com/cjkay
 .. _nmenon: https://github.com/nmenon
+.. _manojkumar-arm: https://github.com/manojkumar-arm
+.. _chandnich: https://github.com/chandnich
+.. _abdellatif-elkhlifi: https://github.com/abdellatif-elkhlifi
+.. _vishnu-banavath: https://github.com/vishnu-banavath
+.. _vijayenthiran-arm: https://github.com/vijayenthiran-arm
+.. _arugan02: https://github.com/arugan02
+.. _uarif1: https://github.com/uarif1
 
 .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
diff --git a/docs/plat/allwinner.rst b/docs/plat/allwinner.rst
index d82380d..b696989 100644
--- a/docs/plat/allwinner.rst
+++ b/docs/plat/allwinner.rst
@@ -5,22 +5,8 @@
 SoCs with ARMv8 cores. Only BL31 is used to provide proper EL3 setup and
 PSCI runtime services.
 
-U-Boot's SPL acts as a loader, loading both BL31 and BL33 (typically U-Boot).
-Loading is done from SD card, eMMC or SPI flash, also via an USB debug
-interface (FEL).
-
-BL31 lives in SRAM A2, which is documented to be accessible from secure
-world only.
-
-Current limitations:
-
--  Missing PMIC support
-
-After building bl31.bin, the binary must be fed to the U-Boot build system
-to include it in the FIT image that the SPL loader will process.
-bl31.bin can be either copied (or sym-linked) into U-Boot's root directory,
-or the environment variable BL31 must contain the binary's path.
-See the respective `U-Boot documentation`_ for more details.
+Building TF-A
+-------------
 
 To build for machines with an A64 or H5 SoC:
 
@@ -34,8 +20,75 @@
 
     make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sun50i_h6 DEBUG=1 bl31
 
+To build for machines with an H616 or H313 SoC:
+
+.. code:: shell
+
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sun50i_h616 DEBUG=1 bl31
+
+
+Installation
+------------
+
+U-Boot's SPL acts as a loader, loading both BL31 and BL33 (typically U-Boot).
+Loading is done from SD card, eMMC or SPI flash, also via an USB debug
+interface (FEL).
+
+After building bl31.bin, the binary must be fed to the U-Boot build system
+to include it in the FIT image that the SPL loader will process.
+bl31.bin can be either copied (or sym-linked) into U-Boot's root directory,
+or the environment variable BL31 must contain the binary's path.
+See the respective `U-Boot documentation`_ for more details.
+
 .. _U-Boot documentation: https://gitlab.denx.de/u-boot/u-boot/-/blob/master/board/sunxi/README.sunxi64
 
+Memory layout
+-------------
+
+A64, H5 and H6 SoCs
+~~~~~~~~~~~~~~~~~~~
+
+BL31 lives in SRAM A2, which is documented to be accessible from secure
+world only. Since this SRAM region is very limited (48 KB), we take
+several measures to reduce memory consumption. One of them is to confine
+BL31 to only 28 bits of virtual address space, which reduces the number
+of required page tables (each occupying 4KB of memory).
+The mapping we use on those SoCs is as follows:
+
+::
+
+   0 64K         16M             1GB         1G+160M     physical address
+   +-+------+-+---+------+--...---+-------+----+------+----------
+   |B|      |S|///|      |//...///|       |////|      |
+   |R| SRAM |C|///| dev  |//...///| (sec) |////| BL33 |  DRAM ...
+   |O|      |P|///| MMIO |//...///| DRAM  |////|      |
+   |M|      | |///|      |//...///| (32M) |////|      |
+   +-+------+-+---+------+--...---+-------+----+------+----------
+   | |      | |   |      |       /       /   /      /
+   | |      | |   |      |      /       /  /      /
+   | |      | |   |      |     /       / /      /
+   | |      | |   |      |    /       //      /
+   | |      | |   |      |   /       /      /
+   +-+------+-+---+------+--+-------+------+
+   |B|      |S|///|      |//|       |      |
+   |R| SRAM |C|///| dev  |//|  sec  | BL33 |
+   |O|      |P|///| MMIO |//| DRAM  |      |
+   |M|      | |///|      |//|       |      |
+   +-+------+-+---+------+--+-------+------+
+   0 64K         16M       160M    192M  256M             virtual address
+
+
+H616 SoC
+~~~~~~~~
+
+The H616 lacks the secure SRAM region present on the other SoCs, also
+lacks the "ARISC" management processor (SCP) we use. BL31 thus needs to
+run from DRAM, which prevents our compressed virtual memory map described
+above. Since running in DRAM also lifts the restriction of the limited
+SRAM size, we use the normal 1:1 mapping with 32 bits worth of virtual
+address space. So the virtual addresses used in BL31 match the physical
+addresses as presented above.
+
 Trusted OS dispatcher
 ---------------------
 
diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c
index 9798ed4..9fc1578 100644
--- a/drivers/arm/tzc/tzc400.c
+++ b/drivers/arm/tzc/tzc400.c
@@ -10,6 +10,7 @@
 #include <common/debug.h>
 #include <drivers/arm/tzc400.h>
 #include <lib/mmio.h>
+#include <lib/utils_def.h>
 
 #include "tzc_common_private.h"
 
@@ -70,6 +71,77 @@
 DEFINE_TZC_COMMON_CONFIGURE_REGION0(400)
 DEFINE_TZC_COMMON_CONFIGURE_REGION(400)
 
+static void _tzc400_clear_it(uintptr_t base, uint32_t filter)
+{
+	mmio_write_32(base + INT_CLEAR, BIT_32(filter));
+}
+
+static uint32_t _tzc400_get_int_by_filter(uintptr_t base, uint32_t filter)
+{
+	return mmio_read_32(base + INT_STATUS) & BIT_32(filter);
+}
+
+#if DEBUG
+static unsigned long _tzc400_get_fail_address(uintptr_t base, uint32_t filter)
+{
+	unsigned long fail_address;
+
+	fail_address = mmio_read_32(base + FAIL_ADDRESS_LOW_OFF +
+				    (filter * FILTER_OFFSET));
+#ifdef __aarch64__
+	fail_address += (unsigned long)mmio_read_32(base + FAIL_ADDRESS_HIGH_OFF +
+						    (filter * FILTER_OFFSET)) << 32;
+#endif
+
+	return fail_address;
+}
+
+static uint32_t _tzc400_get_fail_id(uintptr_t base, uint32_t filter)
+{
+	return mmio_read_32(base + FAIL_ID + (filter * FILTER_OFFSET));
+}
+
+static uint32_t _tzc400_get_fail_control(uintptr_t base, uint32_t filter)
+{
+	return mmio_read_32(base + FAIL_CONTROL_OFF + (filter * FILTER_OFFSET));
+}
+
+static void _tzc400_dump_fail_filter(uintptr_t base, uint32_t filter)
+{
+	uint32_t control_fail;
+	uint32_t fail_id;
+	unsigned long address_fail;
+
+	address_fail = _tzc400_get_fail_address(base, filter);
+	ERROR("Illegal access to 0x%lx:\n", address_fail);
+
+	fail_id = _tzc400_get_fail_id(base, filter);
+	ERROR("\tFAIL_ID = 0x%x\n", fail_id);
+
+	control_fail = _tzc400_get_fail_control(base, filter);
+	if (((control_fail & BIT_32(FAIL_CONTROL_NS_SHIFT)) >> FAIL_CONTROL_NS_SHIFT) ==
+	    FAIL_CONTROL_NS_NONSECURE) {
+		ERROR("\tNon-Secure\n");
+	} else {
+		ERROR("\tSecure\n");
+	}
+
+	if (((control_fail & BIT_32(FAIL_CONTROL_PRIV_SHIFT)) >> FAIL_CONTROL_PRIV_SHIFT) ==
+	    FAIL_CONTROL_PRIV_PRIV) {
+		ERROR("\tPrivilege\n");
+	} else {
+		ERROR("\tUnprivilege\n");
+	}
+
+	if (((control_fail & BIT_32(FAIL_CONTROL_DIR_SHIFT)) >> FAIL_CONTROL_DIR_SHIFT) ==
+	    FAIL_CONTROL_DIR_WRITE) {
+		ERROR("\tWrite\n");
+	} else {
+		ERROR("\tRead\n");
+	}
+}
+#endif /* DEBUG */
+
 static unsigned int _tzc400_get_gate_keeper(uintptr_t base,
 				unsigned int filter)
 {
@@ -108,11 +180,6 @@
 	assert(tzc400.base != 0U);
 	assert(action <= TZC_ACTION_ERR_INT);
 
-	/*
-	 * - Currently no handler is provided to trap an error via interrupt
-	 *   or exception.
-	 * - The interrupt action has not been tested.
-	 */
 	_tzc400_write_action(tzc400.base, action);
 }
 
@@ -245,3 +312,31 @@
 	for (filter = 0; filter < tzc400.num_filters; filter++)
 		_tzc400_set_gate_keeper(tzc400.base, filter, 0);
 }
+
+int tzc400_it_handler(void)
+{
+	uint32_t filter;
+	uint32_t filter_it_pending = tzc400.num_filters;
+
+	assert(tzc400.base != 0U);
+
+	for (filter = 0U; filter < tzc400.num_filters; filter++) {
+		if (_tzc400_get_int_by_filter(tzc400.base, filter) != 0U) {
+			filter_it_pending = filter;
+			break;
+		}
+	}
+
+	if (filter_it_pending == tzc400.num_filters) {
+		ERROR("TZC-400: No interrupt pending!\n");
+		return -1;
+	}
+
+#if DEBUG
+	_tzc400_dump_fail_filter(tzc400.base, filter_it_pending);
+#endif
+
+	_tzc400_clear_it(tzc400.base, filter_it_pending);
+
+	return 0;
+}
diff --git a/drivers/brcm/i2c/i2c.c b/drivers/brcm/i2c/i2c.c
new file mode 100644
index 0000000..2096a82
--- /dev/null
+++ b/drivers/brcm/i2c/i2c.c
@@ -0,0 +1,886 @@
+/*
+ * Copyright (c) 2016 - 2021, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <i2c.h>
+#include <i2c_regs.h>
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/* Max instances */
+#define MAX_I2C					2U
+
+/* Transaction error codes defined in Master command register (0x30) */
+#define MSTR_STS_XACT_SUCCESS			0U
+#define MSTR_STS_LOST_ARB			1U
+#define MSTR_STS_NACK_FIRST_BYTE		2U
+ /* NACK on a byte other than the first byte */
+#define MSTR_STS_NACK_NON_FIRST_BYTE		3U
+
+#define MSTR_STS_TTIMEOUT_EXCEEDED		4U
+#define MSTR_STS_TX_TLOW_MEXT_EXCEEDED		5U
+#define MSTR_STS_RX_TLOW_MEXT_EXCEEDED		6U
+
+/* SMBUS protocol values defined in register 0x30 */
+#define SMBUS_PROT_QUICK_CMD			0U
+#define SMBUS_PROT_SEND_BYTE			1U
+#define SMBUS_PROT_RECV_BYTE			2U
+#define SMBUS_PROT_WR_BYTE			3U
+#define SMBUS_PROT_RD_BYTE			4U
+#define SMBUS_PROT_WR_WORD			5U
+#define SMBUS_PROT_RD_WORD			6U
+#define SMBUS_PROT_BLK_WR			7U
+#define SMBUS_PROT_BLK_RD			8U
+#define SMBUS_PROT_PROC_CALL			9U
+#define SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL	10U
+
+/* Number can be changed later */
+#define BUS_BUSY_COUNT				100000U
+
+#define IPROC_I2C_INVALID_ADDR			0xFFU
+
+#define I2C_SMBUS_BLOCK_MAX			32U
+
+/*
+ * Enum to specify clock speed. The user will provide it during initialization.
+ * If needed, it can be changed dynamically
+ */
+typedef enum iproc_smb_clk_freq {
+	IPROC_SMB_SPEED_100KHz = 0,
+	IPROC_SMB_SPEED_400KHz = 1,
+	IPROC_SMB_SPEED_INVALID = 255
+} smb_clk_freq_t;
+
+/* Structure used to pass information to read/write functions. */
+struct iproc_xact_info {
+	/* Bus Identifier */
+	uint32_t bus_id;
+	/* Device Address */
+	uint8_t devaddr;
+	/* Passed by caller to send SMBus command cod e*/
+	uint8_t command;
+	/* actual data passed by the caller */
+	uint8_t *data;
+	/* Size of data buffer passed */
+	uint32_t size;
+	/* Sent by caller specifying PEC, 10-bit addresses */
+	uint16_t flags;
+	/* SMBus protocol to use to perform transaction */
+	uint8_t smb_proto;
+	/* true if command field below is valid. Otherwise, false */
+	uint32_t cmd_valid;
+};
+
+static const uintptr_t smbus_base_reg_addr[MAX_I2C] = {
+	SMBUS0_REGS_BASE,
+	SMBUS1_REGS_BASE
+};
+
+/* Function to read a value from specified register. */
+static uint32_t iproc_i2c_reg_read(uint32_t bus_id, unsigned long reg_addr)
+{
+	uint32_t val;
+	uintptr_t smbus;
+
+	smbus = smbus_base_reg_addr[bus_id];
+
+	val = mmio_read_32(smbus + reg_addr);
+	VERBOSE("i2c %u: reg %p read 0x%x\n", bus_id,
+		(void *)(smbus + reg_addr), val);
+	return val;
+}
+
+/* Function to write a value ('val') in to a specified register. */
+static void iproc_i2c_reg_write(uint32_t bus_id,
+				unsigned long reg_addr,
+				uint32_t val)
+{
+	uintptr_t smbus;
+
+	smbus = smbus_base_reg_addr[bus_id];
+
+	mmio_write_32((smbus + reg_addr), val);
+	VERBOSE("i2c %u: reg %p wrote 0x%x\n", bus_id,
+		(void *)(smbus + reg_addr), val);
+}
+
+/* Function to clear and set bits in a specified register. */
+static void iproc_i2c_reg_clearset(uint32_t bus_id,
+				   unsigned long reg_addr,
+				   uint32_t clear,
+				   uint32_t set)
+{
+	uintptr_t smbus;
+
+	smbus = smbus_base_reg_addr[bus_id];
+
+	mmio_clrsetbits_32((smbus + reg_addr), clear, set);
+	VERBOSE("i2c %u: reg %p clear 0x%x, set 0x%x\n", bus_id,
+		(void *)(smbus + reg_addr), clear, set);
+}
+
+/* Function to dump all SMBUS register */
+#ifdef BCM_I2C_DEBUG
+static int iproc_dump_i2c_regs(uint32_t bus_id)
+{
+	uint32_t regval;
+
+	if (bus_id > MAX_I2C) {
+		return -1;
+	}
+
+	INFO("----------------------------------------------\n");
+	INFO("%s: Dumping SMBus %u registers...\n", __func__, bus_id);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_CFG_REG);
+	INFO("SMB_CFG_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_TIMGCFG_REG);
+	INFO("SMB_TIMGCFG_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_ADDR_REG);
+	INFO("SMB_ADDR_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_MSTRFIFOCTL_REG);
+	INFO("SMB_MSTRFIFOCTL_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_SLVFIFOCTL_REG);
+	INFO("SMB_SLVFIFOCTL_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_BITBANGCTL_REG);
+	INFO("SMB_BITBANGCTL_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_MSTRCMD_REG);
+	INFO("SMB_MSTRCMD_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_SLVCMD_REG);
+	INFO("SMB_SLVCMD_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_EVTEN_REG);
+	INFO("SMB_EVTEN_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_EVTSTS_REG);
+	INFO("SMB_EVTSTS_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_MSTRDATAWR_REG);
+	INFO("SMB_MSTRDATAWR_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_MSTRDATARD_REG);
+	INFO("SMB_MSTRDATARD_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_SLVDATAWR_REG);
+	INFO("SMB_SLVDATAWR_REG=0x%x\n", regval);
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_SLVDATARD_REG);
+	INFO("SMB_SLVDATARD_REG=0x%x\n", regval);
+
+	INFO("----------------------------------------------\n");
+	return 0;
+}
+#endif
+
+/*
+ * Function to ensure that the previous transaction was completed before
+ * initiating a new transaction. It can also be used in polling mode to
+ * check status of completion of a command
+ */
+static int iproc_i2c_startbusy_wait(uint32_t bus_id)
+{
+	uint32_t regval;
+	uint32_t retry = 0U;
+
+	/*
+	 * Check if an operation is in progress. During probe it won't be.
+	 * Want to make sure that the transaction in progress is completed.
+	 */
+	do {
+		udelay(1U);
+		regval = iproc_i2c_reg_read(bus_id, SMB_MSTRCMD_REG);
+		regval &= SMB_MSTRSTARTBUSYCMD_MASK;
+		if (retry++ > BUS_BUSY_COUNT) {
+			ERROR("%s: START_BUSY bit didn't clear, exiting\n",
+			      __func__);
+			return -1;
+		}
+
+	} while (regval != 0U);
+
+	return 0;
+}
+
+/*
+ * This function copies data to SMBus's Tx FIFO. Valid for write transactions
+ * info: Data to copy in to Tx FIFO. For read commands, the size should be
+ * set to zero by the caller
+ */
+static void iproc_i2c_write_trans_data(struct iproc_xact_info *info)
+{
+	uint32_t regval;
+	uint8_t devaddr;
+	uint32_t i;
+	uint32_t num_data_bytes = 0U;
+
+#ifdef BCM_I2C_DEBUG
+	INFO("%s:dev_addr=0x%x,cmd_valid=%d, cmd=0x%x, size=%u proto=%d\n",
+	     __func__, info->devaddr, info->cmd_valid, info->command,
+	     info->size, info->smb_proto);
+#endif
+	/* Shift devaddr by 1 bit since SMBus uses the low bit[0] for R/W_n */
+	devaddr = (info->devaddr << 1);
+
+	/*
+	 * Depending on the SMBus protocol, we need to write additional
+	 * transaction data in to Tx FIFO. Refer to section 5.5 of SMBus spec
+	 * for sequence for a transaction
+	 */
+	switch (info->smb_proto) {
+	case SMBUS_PROT_RECV_BYTE:
+		/* No additional data to be written */
+		iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
+				    devaddr | 0x1U | SMB_MSTRWRSTS_MASK);
+		break;
+	case SMBUS_PROT_SEND_BYTE:
+		num_data_bytes = info->size;
+		iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
+				    devaddr);
+		break;
+	case SMBUS_PROT_RD_BYTE:
+	case SMBUS_PROT_RD_WORD:
+	case SMBUS_PROT_BLK_RD:
+		/* Write slave address with R/W~ set (bit #0) */
+		iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
+				    devaddr | 0x1U);
+		break;
+	case SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL:
+		iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
+				    devaddr | 0x1U | SMB_MSTRWRSTS_MASK);
+		break;
+	case SMBUS_PROT_WR_BYTE:
+	case SMBUS_PROT_WR_WORD:
+		iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
+				    devaddr);
+		/*
+		 * No additional bytes to be written. Data portion is written
+		 * in the 'for' loop below
+		 */
+		num_data_bytes = info->size;
+		break;
+	case SMBUS_PROT_BLK_WR:
+		iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
+				    devaddr);
+		/* 3rd byte is byte count */
+		iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
+				    info->size);
+		num_data_bytes = info->size;
+		break;
+	default:
+		return;
+	}
+
+	/* If the protocol needs command code, copy it */
+	if (info->cmd_valid) {
+		iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
+				    info->command);
+	}
+
+	/*
+	 * Copy actual data from caller. In general, for reads,
+	 * no data is copied.
+	 */
+	for (i = 0U; num_data_bytes; --num_data_bytes, i++) {
+		/* For the last byte, set MASTER_WR_STATUS bit */
+		regval = (num_data_bytes == 1U) ?
+			 info->data[i] | SMB_MSTRWRSTS_MASK : info->data[i];
+		iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
+				    regval);
+	}
+}
+
+/*
+ * This function writes to the master command register and
+ * then polls for completion
+ */
+static int iproc_i2c_write_master_command(uint32_t mastercmd,
+					  struct iproc_xact_info *info)
+{
+	uint32_t retry = 0U;
+	uint32_t regval;
+
+	iproc_i2c_reg_write(info->bus_id, SMB_MSTRCMD_REG, mastercmd);
+
+	/* Check for Master Busy status */
+	regval = iproc_i2c_reg_read(info->bus_id, SMB_MSTRCMD_REG);
+	while ((regval & SMB_MSTRSTARTBUSYCMD_MASK) != 0U) {
+		udelay(1U);
+		if (retry++ > BUS_BUSY_COUNT) {
+			ERROR("%s: START_BUSY bit didn't clear, exiting\n",
+				__func__);
+			return -1;
+		}
+		regval = iproc_i2c_reg_read(info->bus_id, SMB_MSTRCMD_REG);
+	}
+
+	/* If start_busy bit cleared, check if there are any errors */
+	if (!(regval & SMB_MSTRSTARTBUSYCMD_MASK)) {
+		/* start_busy bit cleared, check master_status field now */
+		regval &= SMB_MSTRSTS_MASK;
+		regval >>= SMB_MSTRSTS_SHIFT;
+		if (regval != MSTR_STS_XACT_SUCCESS) {
+			/* Error We can flush Tx FIFO here */
+			ERROR("%s: ERROR: %u exiting\n", __func__, regval);
+			return -1;
+		}
+	}
+	return 0;
+
+}
+/* Function to initiate data send and verify completion status */
+static int iproc_i2c_data_send(struct iproc_xact_info *info)
+{
+	int rc;
+	uint32_t mastercmd;
+
+	/* Make sure the previous transaction completed */
+	rc = iproc_i2c_startbusy_wait(info->bus_id);
+
+	if (rc < 0) {
+		WARN("%s: Send: bus is busy, exiting\n", __func__);
+		return rc;
+	}
+	/* Write transaction bytes to Tx FIFO */
+	iproc_i2c_write_trans_data(info);
+
+	/*
+	 * Program master command register (0x30) with protocol type and set
+	 * start_busy_command bit to initiate the write transaction
+	 */
+	mastercmd = (info->smb_proto << SMB_MSTRSMBUSPROTO_SHIFT) |
+	    SMB_MSTRSTARTBUSYCMD_MASK;
+
+	if (iproc_i2c_write_master_command(mastercmd, info)) {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Function to initiate data receive, verify completion status,
+ * and read from SMBUS Read FIFO
+ */
+static int iproc_i2c_data_recv(struct iproc_xact_info *info,
+			       uint32_t *num_bytes_read)
+{
+	int rc;
+	uint32_t mastercmd;
+	uint32_t regval;
+
+	/* Make sure the previous transaction completed */
+	rc = iproc_i2c_startbusy_wait(info->bus_id);
+
+	if (rc < 0) {
+		WARN("%s: Receive: Bus is busy, exiting\n", __func__);
+		return rc;
+	}
+
+	/* Program all transaction bytes into master Tx FIFO */
+	iproc_i2c_write_trans_data(info);
+
+	/*
+	 * Program master command register (0x30) with protocol type and set
+	 * start_busy_command bit to initiate the write transaction
+	 */
+	mastercmd = (info->smb_proto << SMB_MSTRSMBUSPROTO_SHIFT) |
+		     SMB_MSTRSTARTBUSYCMD_MASK | info->size;
+
+	if (iproc_i2c_write_master_command(mastercmd, info)) {
+		return -1;
+	}
+
+	/* Read received byte(s), after TX out address etc */
+	regval = iproc_i2c_reg_read(info->bus_id, SMB_MSTRDATARD_REG);
+
+	/* For block read, protocol (hw) returns byte count,as the first byte */
+	if (info->smb_proto == SMBUS_PROT_BLK_RD) {
+		uint32_t i;
+
+		*num_bytes_read = regval & SMB_MSTRRDDATA_MASK;
+		/*
+		 * Limit to reading a max of 32 bytes only; just a safeguard.
+		 * If # bytes read is a number > 32, check transaction set up,
+		 * and contact hw engg.
+		 * Assumption: PEC is disabled
+		 */
+		for (i = 0U; (i < *num_bytes_read) &&
+		     (i < I2C_SMBUS_BLOCK_MAX); i++) {
+			/* Read Rx FIFO for data bytes */
+			regval = iproc_i2c_reg_read(info->bus_id,
+						    SMB_MSTRDATARD_REG);
+			info->data[i] = regval & SMB_MSTRRDDATA_MASK;
+		}
+	} else {
+		/* 1 Byte data */
+		*info->data = regval & SMB_MSTRRDDATA_MASK;
+		*num_bytes_read = 1U;
+	}
+
+	return 0;
+}
+
+/*
+ * This function set clock frequency for SMBus block. As per hardware
+ * engineering, the clock frequency can be changed dynamically.
+ */
+static int iproc_i2c_set_clk_freq(uint32_t bus_id, smb_clk_freq_t freq)
+{
+	uint32_t val;
+
+	switch (freq) {
+	case IPROC_SMB_SPEED_100KHz:
+		val = 0U;
+		break;
+	case IPROC_SMB_SPEED_400KHz:
+		val = 1U;
+		break;
+	default:
+		return -1;
+	}
+
+	iproc_i2c_reg_clearset(bus_id, SMB_TIMGCFG_REG,
+			       SMB_TIMGCFG_MODE400_MASK,
+			       val << SMB_TIMGCFG_MODE400_SHIFT);
+
+	return 0;
+}
+
+/* Helper function to fill the iproc_xact_info structure */
+static void iproc_i2c_fill_info(struct iproc_xact_info *info, uint32_t bus_id,
+				uint8_t devaddr, uint8_t cmd, uint8_t *value,
+				uint8_t smb_proto, uint32_t cmd_valid)
+{
+	info->bus_id = bus_id;
+	info->devaddr = devaddr;
+	info->command = (uint8_t)cmd;
+	info->smb_proto = smb_proto;
+	info->data = value;
+	info->size = 1U;
+	info->flags = 0U;
+	info->cmd_valid = cmd_valid;
+}
+
+/* This function initializes the SMBUS */
+static void iproc_i2c_init(uint32_t bus_id, int speed)
+{
+	uint32_t regval;
+
+#ifdef BCM_I2C_DEBUG
+	INFO("%s: Enter Init\n", __func__);
+#endif
+
+	/* Put controller in reset */
+	regval = iproc_i2c_reg_read(bus_id, SMB_CFG_REG);
+	regval |= BIT(SMB_CFG_RST_SHIFT);
+	regval &= ~(BIT(SMB_CFG_SMBEN_SHIFT));
+	iproc_i2c_reg_write(bus_id, SMB_CFG_REG, regval);
+
+	/* Wait 100 usec per spec */
+	udelay(100U);
+
+	/* Bring controller out of reset */
+	regval &= ~(BIT(SMB_CFG_RST_SHIFT));
+	iproc_i2c_reg_write(bus_id, SMB_CFG_REG, regval);
+
+	/*
+	 * Flush Tx, Rx FIFOs. Note we are setting the Rx FIFO threshold to 0.
+	 * May be OK since we are setting RX_EVENT and RX_FIFO_FULL interrupts
+	 */
+	regval = SMB_MSTRRXFIFOFLSH_MASK | SMB_MSTRTXFIFOFLSH_MASK;
+	iproc_i2c_reg_write(bus_id, SMB_MSTRFIFOCTL_REG, regval);
+
+	/*
+	 * Enable SMbus block. Note, we are setting MASTER_RETRY_COUNT to zero
+	 * since there will be only one master
+	 */
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_CFG_REG);
+	regval |= SMB_CFG_SMBEN_MASK;
+	iproc_i2c_reg_write(bus_id, SMB_CFG_REG, regval);
+	/* Wait a minimum of 50 Usec, as per SMB hw doc. But we wait longer */
+	mdelay(10U);
+
+	/* If error then set default speed */
+	if (i2c_set_bus_speed(bus_id, speed)) {
+		i2c_set_bus_speed(bus_id, I2C_SPEED_DEFAULT);
+	}
+
+	/* Disable intrs */
+	regval = 0x0U;
+	iproc_i2c_reg_write(bus_id, SMB_EVTEN_REG, regval);
+
+	/* Clear intrs (W1TC) */
+	regval = iproc_i2c_reg_read(bus_id, SMB_EVTSTS_REG);
+	iproc_i2c_reg_write(bus_id, SMB_EVTSTS_REG, regval);
+
+#ifdef BCM_I2C_DEBUG
+	iproc_dump_i2c_regs(bus_id);
+
+	INFO("%s: Exit Init Successfully\n", __func__);
+#endif
+}
+
+/*
+ * Function Name:    i2c_init
+ *
+ * Description:
+ *	This function initializes the SMBUS.
+ *
+ * Parameters:
+ *	bus_id - I2C bus ID
+ *	speed  - I2C bus speed in Hz
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_init(uint32_t bus_id, int speed)
+{
+	if (bus_id > MAX_I2C) {
+		WARN("%s: Invalid Bus %u\n", __func__, bus_id);
+		return -1;
+	}
+
+	iproc_i2c_init(bus_id, speed);
+	return 0U;
+}
+
+/*
+ * Function Name:    i2c_probe
+ *
+ * Description:
+ *	This function probes the I2C bus for the existence of the specified
+ *	device.
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_probe(uint32_t bus_id, uint8_t devaddr)
+{
+	uint32_t regval;
+	int rc;
+
+	/*
+	 * i2c_init() Initializes internal regs, disable intrs (and then clear intrs),
+	 * set fifo thresholds, etc.
+	 * Shift devaddr by 1 bit since SMBus uses the low bit[0] for R/W_n
+	 */
+	regval = (devaddr << 1U);
+	iproc_i2c_reg_write(bus_id, SMB_MSTRDATAWR_REG, regval);
+
+	regval = ((SMBUS_PROT_QUICK_CMD << SMB_MSTRSMBUSPROTO_SHIFT) |
+		  SMB_MSTRSTARTBUSYCMD_MASK);
+	iproc_i2c_reg_write(bus_id, SMB_MSTRCMD_REG, regval);
+
+	rc = iproc_i2c_startbusy_wait(bus_id);
+
+	if (rc < 0) {
+		WARN("%s: Probe: bus is busy, exiting\n", __func__);
+		return rc;
+	}
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_MSTRCMD_REG);
+	if (((regval & SMB_MSTRSTS_MASK) >> SMB_MSTRSTS_SHIFT) == 0)
+		VERBOSE("i2c device address: 0x%x\n", devaddr);
+	else
+		return -1;
+
+#ifdef BCM_I2C_DEBUG
+	iproc_dump_i2c_regs(bus_id);
+#endif
+	return 0;
+}
+
+/*
+ * Function Name:    i2c_recv_byte
+ *
+ * Description:
+ *	This function reads I2C data from a device without specifying
+ *	a command regsiter.
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *	value   - Data Read
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_recv_byte(uint32_t bus_id, uint8_t devaddr, uint8_t *value)
+{
+	int rc;
+	struct iproc_xact_info info;
+	uint32_t num_bytes_read = 0;
+
+	iproc_i2c_fill_info(&info, bus_id, devaddr, 0U, value,
+			    SMBUS_PROT_RECV_BYTE, 0U);
+
+	/* Refer to i2c_smbus_read_byte for params passed. */
+	rc = iproc_i2c_data_recv(&info, &num_bytes_read);
+
+	if (rc < 0) {
+		printf("%s: %s error accessing device 0x%x\n",
+		__func__, "Read", devaddr);
+	}
+
+	return rc;
+}
+
+/*
+ * Function Name:    i2c_send_byte
+ *
+ * Description:
+ *	This function send I2C data to a device without specifying
+ *	a command regsiter.
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *	value   - Data Send
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_send_byte(uint32_t bus_id, uint8_t devaddr, uint8_t value)
+{
+	int rc;
+	struct iproc_xact_info info;
+
+	iproc_i2c_fill_info(&info, bus_id, devaddr, 0U, &value,
+			    SMBUS_PROT_SEND_BYTE, 0U);
+
+	/* Refer to i2c_smbus_write_byte params passed. */
+	rc = iproc_i2c_data_send(&info);
+
+	if (rc < 0) {
+		ERROR("%s: %s error accessing device 0x%x\n",
+		__func__, "Write", devaddr);
+	}
+
+	return rc;
+}
+
+/* Helper function to read a single byte */
+static int i2c_read_byte(uint32_t bus_id,
+			 uint8_t devaddr,
+			 uint8_t regoffset,
+			 uint8_t *value)
+{
+	int rc;
+	struct iproc_xact_info info;
+	uint32_t num_bytes_read = 0U;
+
+	iproc_i2c_fill_info(&info, bus_id, devaddr, regoffset, value,
+			    SMBUS_PROT_RD_BYTE, 1U);
+
+	/* Refer to i2c_smbus_read_byte for params passed. */
+	rc = iproc_i2c_data_recv(&info, &num_bytes_read);
+
+	if (rc < 0) {
+		ERROR("%s: %s error accessing device 0x%x\n",
+		       __func__, "Read", devaddr);
+	}
+	return rc;
+}
+
+/*
+ * Function Name:    i2c_read
+ *
+ * Description:
+ *	This function reads I2C data from a device with a designated
+ *	command register
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *	addr    - Register Offset
+ *	alen    - Address Length, 1 for byte, 2 for word (not supported)
+ *	buffer  - Data Buffer
+ *	len     - Data Length in bytes
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_read(uint32_t bus_id,
+	     uint8_t devaddr,
+	     uint32_t addr,
+	     int alen,
+	     uint8_t *buffer,
+	     int len)
+{
+	uint32_t i;
+
+	if (alen > 1) {
+		WARN("I2C read: addr len %d not supported\n", alen);
+		return -1;
+	}
+
+	if (addr + len > 256) {
+		WARN("I2C read: address out of range\n");
+		return -1;
+	}
+
+	for (i = 0U; i < len; i++) {
+		if (i2c_read_byte(bus_id, devaddr, addr + i, &buffer[i])) {
+			ERROR("I2C read: I/O error\n");
+			iproc_i2c_init(bus_id, i2c_get_bus_speed(bus_id));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/* Helper function to write a single byte */
+static int i2c_write_byte(uint32_t bus_id,
+			  uint8_t devaddr,
+			  uint8_t regoffset,
+			  uint8_t value)
+{
+	int rc;
+	struct iproc_xact_info info;
+
+	iproc_i2c_fill_info(&info, bus_id, devaddr, regoffset, &value,
+			    SMBUS_PROT_WR_BYTE, 1U);
+
+	/* Refer to i2c_smbus_write_byte params passed. */
+	rc = iproc_i2c_data_send(&info);
+
+	if (rc < 0) {
+		ERROR("%s: %s error accessing device 0x%x\n",
+		       __func__, "Write", devaddr);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Function Name:    i2c_write
+ *
+ * Description:
+ *	This function write I2C data to a device with a designated
+ *	command register
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *	addr    - Register Offset
+ *	alen    - Address Length, 1 for byte, 2 for word (not supported)
+ *	buffer  - Data Buffer
+ *	len     - Data Length in bytes
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_write(uint32_t bus_id,
+	      uint8_t devaddr,
+	      uint32_t addr,
+	      int alen,
+	      uint8_t *buffer,
+	      int len)
+{
+	uint32_t i;
+
+	if (alen > 1) {
+		WARN("I2C write: addr len %d not supported\n", alen);
+		return -1;
+	}
+
+	if (addr + len > 256U) {
+		WARN("I2C write: address out of range\n");
+		return -1;
+	}
+
+	for (i = 0U; i < len; i++) {
+		if (i2c_write_byte(bus_id, devaddr, addr + i, buffer[i])) {
+			ERROR("I2C write: I/O error\n");
+			iproc_i2c_init(bus_id, i2c_get_bus_speed(bus_id));
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Function Name:    i2c_set_bus_speed
+ *
+ * Description:
+ *	This function configures the SMBUS speed
+ *
+ * Parameters:
+ *	bus_id - I2C bus ID
+ *	speed  - I2C bus speed in Hz
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_set_bus_speed(uint32_t bus_id, uint32_t speed)
+{
+	switch (speed) {
+	case I2C_SPEED_100KHz:
+		iproc_i2c_set_clk_freq(bus_id, IPROC_SMB_SPEED_100KHz);
+		break;
+
+	case I2C_SPEED_400KHz:
+		iproc_i2c_set_clk_freq(bus_id, IPROC_SMB_SPEED_400KHz);
+		break;
+
+	default:
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * Function Name:    i2c_get_bus_speed
+ *
+ * Description:
+ *	This function returns the SMBUS speed.
+ *
+ * Parameters:
+ *	bus_id - I2C bus ID
+ *
+ * Return:
+ *	Bus speed in Hz, 0 on failure
+ */
+uint32_t i2c_get_bus_speed(uint32_t bus_id)
+{
+	uint32_t regval;
+	uint32_t retval = 0U;
+
+	regval = iproc_i2c_reg_read(bus_id, SMB_TIMGCFG_REG);
+	regval &= SMB_TIMGCFG_MODE400_MASK;
+	regval >>= SMB_TIMGCFG_MODE400_SHIFT;
+
+	switch (regval) {
+	case IPROC_SMB_SPEED_100KHz:
+		retval = I2C_SPEED_100KHz;
+		break;
+
+	case IPROC_SMB_SPEED_400KHz:
+		retval = I2C_SPEED_400KHz;
+		break;
+
+	default:
+		break;
+	}
+	return retval;
+}
+
diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h
index aacd5df..5f8a48f 100644
--- a/include/drivers/arm/tzc400.h
+++ b/include/drivers/arm/tzc400.h
@@ -90,6 +90,8 @@
 #define TZC_400_REGION_SIZE			U(0x20)
 #define TZC_400_ACTION_OFF			U(0x4)
 
+#define FILTER_OFFSET				U(0x10)
+
 #ifndef __ASSEMBLER__
 
 #include <cdefs.h>
@@ -110,6 +112,7 @@
 void tzc400_set_action(unsigned int action);
 void tzc400_enable_filters(void);
 void tzc400_disable_filters(void);
+int tzc400_it_handler(void);
 
 static inline void tzc_init(uintptr_t base)
 {
diff --git a/include/drivers/brcm/i2c/i2c.h b/include/drivers/brcm/i2c/i2c.h
new file mode 100644
index 0000000..24d42e2
--- /dev/null
+++ b/include/drivers/brcm/i2c/i2c.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2016 - 2021, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef I2C_H
+#define I2C_H
+
+#include <stdint.h>
+
+#define I2C_SPEED_100KHz	100000
+#define I2C_SPEED_400KHz	400000
+#define I2C_SPEED_DEFAULT	I2C_SPEED_100KHz
+
+/*
+ * Function Name:    i2c_probe
+ *
+ * Description:
+ *	This function probes the I2C bus for the existence of the specified
+ *	device.
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_probe(uint32_t bus_id, uint8_t devaddr);
+
+/*
+ * Function Name:    i2c_init
+ *
+ * Description:
+ *	This function initializes the SMBUS.
+ *
+ * Parameters:
+ *	bus_id - I2C bus ID
+ *	speed  - I2C bus speed in Hz
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_init(uint32_t bus_id, int speed);
+
+/*
+ * Function Name:    i2c_set_bus_speed
+ *
+ * Description:
+ *	This function configures the SMBUS speed
+ *
+ * Parameters:
+ *	bus_id - I2C bus ID
+ *	speed  - I2C bus speed in Hz
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_set_bus_speed(uint32_t bus_id, uint32_t speed);
+
+/*
+ * Function Name:    i2c_get_bus_speed
+ *
+ * Description:
+ *	This function returns the SMBUS speed.
+ *
+ * Parameters:
+ *	bus_id - I2C bus ID
+ *
+ * Return:
+ *	Bus speed in Hz, 0 on failure
+ */
+uint32_t i2c_get_bus_speed(uint32_t bus_id);
+
+/*
+ * Function Name:    i2c_recv_byte
+ *
+ * Description:
+ *	This function reads I2C data from a device without specifying
+ *	a command regsiter.
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *	value   - Data Read
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_recv_byte(uint32_t bus_id, uint8_t devaddr, uint8_t *value);
+
+/*
+ * Function Name:    i2c_send_byte
+ *
+ * Description:
+ *	This function send I2C data to a device without specifying
+ *	a command regsiter.
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *	value   - Data Send
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_send_byte(uint32_t bus_id, uint8_t devaddr, uint8_t value);
+
+/*
+ * Function Name:    i2c_read
+ *
+ * Description:
+ *	This function reads I2C data from a device with a designated
+ *	command register
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *	addr    - Register Offset
+ *	alen    - Address Length, 1 for byte, 2 for word (not supported)
+ *	buffer  - Data Buffer
+ *	len     - Data Length in bytes
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_read(uint32_t bus_id,
+	     uint8_t devaddr,
+	     uint32_t addr,
+	     int alen,
+	     uint8_t *buffer,
+	     int len);
+
+/*
+ * Function Name:    i2c_write
+ *
+ * Description:
+ *	This function write I2C data to a device with a designated
+ *	command register
+ *
+ * Parameters:
+ *	bus_id  - I2C bus ID
+ *	devaddr - Device Address
+ *	addr    - Register Offset
+ *	alen    - Address Length, 1 for byte, 2 for word (not supported)
+ *	buffer  - Data Buffer
+ *	len     - Data Length in bytes
+ *
+ * Return:
+ *	0 on success, or -1 on failure.
+ */
+int i2c_write(uint32_t bus_id,
+	      uint8_t devaddr,
+	      uint32_t addr,
+	      int alen,
+	      uint8_t *buffer,
+	      int len);
+
+
+#endif /* I2C_H */
diff --git a/include/drivers/brcm/i2c/i2c_regs.h b/include/drivers/brcm/i2c/i2c_regs.h
new file mode 100644
index 0000000..74ea824
--- /dev/null
+++ b/include/drivers/brcm/i2c/i2c_regs.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2016 - 2021, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef I2C_REGS
+#define I2C_REGS
+
+/* SMBUS Config register */
+#define SMB_CFG_REG				0x0U
+
+#define SMB_CFG_RST_MASK			0x80000000U
+#define SMB_CFG_RST_SHIFT			31U
+
+#define SMB_CFG_SMBEN_MASK			0x40000000U
+#define SMB_CFG_SMBEN_SHIFT			30U
+
+#define SMB_CFG_BITBANGEN_MASK			0x20000000U
+#define SMB_CFG_BITBANGEN_SHIFT			29U
+
+#define SMB_CFG_EN_NIC_SMBADDR0_MASK		0x10000000U
+#define SMB_CFG_EN_NIC_SMBADDR0_SHIFT		28U
+
+#define SMB_CFG_PROMISCMODE_MASK		0x08000000U
+#define SMB_CFG_PROMISCMODE_SHIFT		27U
+
+#define SMB_CFG_TSTMPCNTEN_MASK			0x04000000U
+#define SMB_CFG_TSTMPCNTEN_SHIFT		26U
+
+#define SMB_CFG_MSTRRTRYCNT_MASK		0x000F0000U
+#define SMB_CFG_MSTRRTRYCNT_SHIFT		16U
+
+/* SMBUS Timing config register */
+#define SMB_TIMGCFG_REG				0x4U
+
+#define SMB_TIMGCFG_MODE400_MASK		0x80000000U
+#define SMB_TIMGCFG_MODE400_SHIFT		31U
+
+#define SMB_TIMGCFG_RNDSLVSTR_MASK		0x7F000000U
+#define SMB_TIMGCFG_RNDSLVSTR_SHIFT		24U
+
+#define SMB_TIMGCFG_PERSLVSTR_MASK		0x00FF0000U
+#define SMB_TIMGCFG_PERSLVSTR_SHIFT		16U
+
+#define SMB_TIMGCFG_IDLTIME_MASK		0x0000FF00U
+#define SMB_TIMGCFG_IDLTIME_SHIFT		8U
+
+/* SMBUS Slave address register */
+#define SMB_ADDR_REG				0x8U
+
+#define SMB_EN_NIC_SMBADDR3_MASK		0x80000000U
+#define SMB_EN_NIC_SMBADDR3_SHIFT		31U
+
+#define SMB_NIC_SMBADDR3_MASK			0x7F000000U
+#define SMB_NIC_SMBADDR3_SHIFT			24U
+
+#define SMB_EN_NIC_SMBADDR2_MASK		0x00800000U
+#define SMB_EN_NIC_SMBADDR2_SHIFT		23U
+
+#define SMB_NIC_SMBADDR2_MASK			0x007F0000U
+#define SMB_NIC_SMBADDR2_SHIFT			16U
+
+#define SMB_EN_NIC_SMBADDR1_MASK		0x00008000U
+#define SMB_EN_NIC_SMBADDR1_SHIFT		15U
+
+#define SMB_NIC_SMBADDR1_MASK			0x00007F00U
+#define SMB_NIC_SMBADDR1_SHIFT			8U
+
+#define SMB_EN_NIC_SMBADDR0_MASK		0x00000080U
+#define SMB_EN_NIC_SMBADDR0_SHIFT		7U
+
+#define SMB_NIC_SMBADDR0_MASK			0x0000007FU
+#define SMB_NIC_SMBADDR0_SHIFT			0U
+
+/* SMBUS Master FIFO control register */
+#define SMB_MSTRFIFOCTL_REG			0xCU
+
+#define SMB_MSTRRXFIFOFLSH_MASK			0x80000000U
+#define SMB_MSTRRXFIFOFLSH_SHIFT		31U
+
+#define SMB_MSTRTXFIFOFLSH_MASK			0x40000000U
+#define SMB_MSTRTXFIFOFLSH_SHIFT		30U
+
+#define SMB_MSTRRXPKTCNT_MASK			0x007F0000U
+#define SMB_MSTRRXPKTCNT_SHIFT			16U
+
+#define SMB_MSTRRXFIFOTHR_MASK			0x00003F00U
+#define SMB_MSTRRXFIFOTHR_SHIFT			8U
+
+/* SMBUS Slave FIFO control register */
+#define SMB_SLVFIFOCTL_REG			0x10U
+
+#define SMB_SLVRXFIFOFLSH_MASK			0x80000000U
+#define SMB_SLVRXFIFOFLSH_SHIFT			31U
+
+#define SMB_SLVTXFIFOFLSH_MASK			0x40000000U
+#define SMB_SLVTXFIFOFLSH_SHIFT			30U
+
+#define SMB_SLVRXPKTCNT_MASK			0x007F0000U
+#define SMB_SLVRXPKTCNT_SHIFT			16U
+
+#define SMB_SLVRXFIFOTHR_MASK			0x00003F00U
+#define SMB_SLVRXFIFOTHR_SHIFT			8U
+
+/* SMBUS Bit-bang mode control register */
+#define SMB_BITBANGCTL_REG			0x14U
+
+#define SMB_SMBCLKIN_MASK			0x80000000U
+#define SMB_SMBCLKIN_SHIFT			31U
+
+#define SMB_SMBCLKOUTEN_MASK			0x40000000U
+#define SMB_SMBCLKOUTEN_SHIFT			30U
+
+#define SMB_SMBDATAIN_MASK			0x20000000U
+#define SMB_SMBDATAIN_SHIFT			29U
+
+#define SMB_SMBDATAOUTEN_MASK			0x10000000U
+#define SMB_SMBDATAOUTEN_SHIFT			28U
+
+/* SMBUS Master command register */
+#define SMB_MSTRCMD_REG				0x30U
+
+#define SMB_MSTRSTARTBUSYCMD_MASK		0x80000000U
+#define SMB_MSTRSTARTBUSYCMD_SHIFT		31U
+
+#define SMB_MSTRABORT_MASK			0x40000000U
+#define SMB_MSTRABORT_SHIFT			30U
+
+#define SMB_MSTRSTS_MASK			0x0E000000U
+#define SMB_MSTRSTS_SHIFT			25U
+
+#define SMB_MSTRSMBUSPROTO_MASK			0x00001E00U
+#define SMB_MSTRSMBUSPROTO_SHIFT		9U
+
+#define SMB_MSTRPEC_MASK			0x00000100U
+#define SMB_MSTRPEC_SHIFT			8U
+
+#define SMB_MSTRRDBYTECNT_MASK			0x000000FFU
+#define SMB_MSTRRDBYTECNT_SHIFT			0U
+
+/* SMBUS Slave command register */
+#define SMB_SLVCMD_REG				0x34U
+
+#define SMB_SLVSTARTBUSYCMD_MASK		0x80000000U
+#define SMB_SLVSTARTBUSYCMD_SHIFT		31U
+
+#define SMB_SLVABORT_MASK			0x40000000U
+#define SMB_SLVABORT_SHIFT			30U
+
+#define SMB_SLVSTS_MASK				0x03800000U
+#define SMB_SLVSTS_SHIFT			23U
+
+#define SMB_SLVPEC_MASK				0x00000100U
+#define SMB_SLVPEC_SHIFT			8U
+
+/* SMBUS Event enable register */
+#define SMB_EVTEN_REG				0x38U
+
+#define SMB_MSTRRXFIFOFULLEN_MASK		0x80000000U
+#define SMB_MSTRRXFIFOFULLEN_SHIFT		31U
+
+#define SMB_MSTRRXFIFOTHRHITEN_MASK		0x40000000U
+#define SMB_MSTRRXFIFOTHRHITEN_SHIFT		30U
+
+#define SMB_MSTRRXEVTEN_MASK			0x20000000U
+#define SMB_MSTRRXEVTEN_SHIFT			29U
+
+#define SMB_MSTRSTARTBUSYEN_MASK		0x10000000U
+#define SMB_MSTRSTARTBUSYEN_SHIFT		28U
+
+#define SMB_MSTRTXUNDEN_MASK			0x08000000U
+#define SMB_MSTRTXUNDEN_SHIFT			27U
+
+#define SMB_SLVRXFIFOFULLEN_MASK		0x04000000U
+#define SMB_SLVRXFIFOFULLEN_SHIFT		26U
+
+#define SMB_SLVRXFIFOTHRHITEN_MASK		0x02000000U
+#define SMB_SLVRXFIFOTHRHITEN_SHIFT		25U
+
+#define SMB_SLVRXEVTEN_MASK			0x01000000U
+#define SMB_SLVRXEVTEN_SHIFT			24U
+
+#define SMB_SLVSTARTBUSYEN_MASK			0x00800000U
+#define SMB_SLVSTARTBUSYEN_SHIFT		23U
+
+#define SMB_SLVTXUNDEN_MASK			0x00400000U
+#define SMB_SLVTXUNDEN_SHIFT			22U
+
+#define SMB_SLVRDEVTEN_MASK			0x00200000U
+#define SMB_SLVRDEVTEN_SHIFT			21U
+
+/* SMBUS Event status register */
+#define SMB_EVTSTS_REG				0x3CU
+
+#define SMB_MSTRRXFIFOFULLSTS_MASK		0x80000000U
+#define SMB_MSTRRXFIFOFULLSTS_SHIFT		31U
+
+#define SMB_MSTRRXFIFOTHRHITSTS_MASK		0x40000000U
+#define SMB_MSTRRXFIFOTHRHITSTS_SHIFT		30U
+
+#define SMB_MSTRRXEVTSTS_MASK			0x20000000U
+#define SMB_MSTRRXEVTSTS_SHIFT			29U
+
+#define SMB_MSTRSTARTBUSYSTS_MASK		0x10000000U
+#define SMB_MSTRSTARTBUSYSTS_SHIFT		28U
+
+#define SMB_MSTRTXUNDSTS_MASK			0x08000000U
+#define SMB_MSTRTXUNDSTS_SHIFT			27U
+
+#define SMB_SLVRXFIFOFULLSTS_MASK		0x04000000U
+#define SMB_SLVRXFIFOFULLSTS_SHIFT		26U
+
+#define SMB_SLVRXFIFOTHRHITSTS_MASK		0x02000000U
+#define SMB_SLVRXFIFOTHRHITSTS_SHIFT		25U
+
+#define SMB_SLVRXEVTSTS_MASK			0x01000000U
+#define SMB_SLVRXEVTSTS_SHIFT			24U
+
+#define SMB_SLVSTARTBUSYSTS_MASK		0x00800000U
+#define SMB_SLVSTARTBUSYSTS_SHIFT		23U
+
+#define SMB_SLVTXUNDSTS_MASK			0x00400000U
+#define SMB_SLVTXUNDSTS_SHIFT			22U
+
+#define SMB_SLVRDEVTSTS_MASK			0x00200000U
+#define SMB_SLVRDEVTSTS_SHIFT			21U
+
+/* SMBUS Master data write register */
+#define SMB_MSTRDATAWR_REG			0x40U
+
+#define SMB_MSTRWRSTS_MASK			0x80000000U
+#define SMB_MSTRWRSTS_SHIFT			31U
+
+#define SMB_MSTRWRDATA_MASK			0x000000FFU
+#define SMB_MSTRWRDATA_SHIFT			0U
+
+/* SMBUS Master data read register */
+#define SMB_MSTRDATARD_REG			0x44U
+
+#define SMB_MSTRRDSTS_MASK			0xC0000000U
+#define SMB_MSTRRDSTS_SHIFT			30U
+
+#define SMB_MSTRRDPECERR_MASK			0x20000000U
+#define SMB_MSTRRDPECERR_SHIFT			29U
+
+#define SMB_MSTRRDDATA_MASK			0x000000FFU
+#define SMB_MSTRRDDATA_SHIFT			0U
+
+/* SMBUS Slave data write register */
+#define SMB_SLVDATAWR_REG			0x48U
+
+#define SMB_SLVWRSTS_MASK			0x80000000U
+#define SMB_SLVWRSTS_SHIFT			31U
+
+#define SMB_SLVWRDATA_MASK			0x000000FFU
+#define SMB_SLVWRDATA_SHIFT			0U
+
+/* SMBUS Slave data read register */
+#define SMB_SLVDATARD_REG			0x4CU
+
+#define SMB_SLVRDSTS_MASK			0xC0000000U
+#define SMB_SLVRDSTS_SHIFT			30U
+
+#define SMB_SLVRDERRSTS_MASK			0x30000000U
+#define SMB_SLVRDERRSTS_SHIFT			28U
+
+#define SMB_SLVRDDATA_MASK			0x000000FFU
+#define SMB_SLVRDDATA_SHIFT			0U
+
+#endif /* I2C_REGS */
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
new file mode 100644
index 0000000..adb13bc
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a78c.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A78C_H
+#define CORTEX_A78C_H
+
+
+#define CORTEX_A78C_MIDR			        U(0x410FD4B1)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A78C_CPUECTLR_EL1		        S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A78C_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT	U(1)
+
+#endif /* CORTEX_A78C_H */
diff --git a/include/lib/cpus/aarch64/cortex_makalu_elp.h b/include/lib/cpus/aarch64/cortex_makalu_elp.h
new file mode 100644
index 0000000..4a16996
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_makalu_elp.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_MAKALU_ELP_H
+#define CORTEX_MAKALU_ELP_H
+
+#define CORTEX_MAKALU_ELP_MIDR					U(0x410FD4E0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_MAKALU_ELP_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_MAKALU_ELP_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define CORTEX_MAKALU_ELP_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_MAKALU_ELP_H */
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
new file mode 100644
index 0000000..1b170fe
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a78c.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "cortex_a78c must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_a78c_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_A78C_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+	msr	CORTEX_A78C_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_a78c_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex A78C. Must follow AAPCS.
+ */
+func cortex_a78c_errata_report
+        ret
+endfunc cortex_a78c_errata_report
+#endif
+
+	/* ---------------------------------------------
+	 * This function provides cortex_a78c 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_a78c_regs, "aS"
+cortex_a78c_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a78c_cpu_reg_dump
+	adr	x6, cortex_a78c_regs
+	mrs	x8, CORTEX_A78C_CPUECTLR_EL1
+	ret
+endfunc cortex_a78c_cpu_reg_dump
+
+declare_cpu_ops cortex_a78c, CORTEX_A78C_MIDR, \
+	CPU_NO_RESET_FUNC, \
+	cortex_a78c_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_makalu_elp.S b/lib/cpus/aarch64/cortex_makalu_elp.S
new file mode 100644
index 0000000..e3a3e9d
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_makalu_elp.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_makalu_elp.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex Makalu ELP must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex Makalu ELP supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_makalu_elp_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_MAKALU_ELP_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_MAKALU_ELP_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_MAKALU_ELP_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_makalu_elp_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex Makalu ELP. Must follow AAPCS.
+ */
+func cortex_makalu_elp_errata_report
+	ret
+endfunc cortex_makalu_elp_errata_report
+#endif
+
+func cortex_makalu_elp_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+	isb
+	ret
+endfunc cortex_makalu_elp_reset_func
+
+	/* ---------------------------------------------
+	 * This function provides Cortex Makalu ELP-
+	 * 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_makalu_elp_regs, "aS"
+cortex_makalu_elp_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_makalu_elp_cpu_reg_dump
+	adr	x6, cortex_makalu_elp_regs
+	mrs	x8, CORTEX_MAKALU_ELP_CPUECTLR_EL1
+	ret
+endfunc cortex_makalu_elp_cpu_reg_dump
+
+declare_cpu_ops cortex_makalu_elp, CORTEX_MAKALU_ELP_MIDR, \
+	cortex_makalu_elp_reset_func, \
+	cortex_makalu_elp_core_pwr_dwn
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index da83b5e..61ae9b6 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -85,9 +85,6 @@
 # Allow mapping read-only data as execute-never.
 SEPARATE_CODE_AND_RODATA	:=	1
 
-# Put NOBITS memory in SRAM A1, overwriting U-Boot's SPL.
-SEPARATE_NOBITS_REGION		:=	1
-
 # BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
 RESET_TO_BL31			:=	1
 
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index 93720ff..4893368 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -13,18 +13,36 @@
 
 #include <sunxi_mmap.h>
 
+/* The SCP firmware is allocated the last 16KiB of SRAM A2. */
+#define SUNXI_SCP_SIZE			0x4000
+
+#ifdef SUNXI_BL31_IN_DRAM
+
+#define BL31_BASE			SUNXI_DRAM_BASE
+#define BL31_LIMIT			(SUNXI_DRAM_BASE + 0x40000)
+
+#define MAX_XLAT_TABLES			4
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+
+#define SUNXI_BL33_VIRT_BASE		PRELOADED_BL33_BASE
+
+#else	/* !SUNXI_BL31_IN_DRAM */
+
 #define BL31_BASE			(SUNXI_SRAM_A2_BASE + 0x4000)
 #define BL31_LIMIT			(SUNXI_SRAM_A2_BASE + \
 					 SUNXI_SRAM_A2_SIZE - SUNXI_SCP_SIZE)
-
-/* The SCP firmware is allocated the last 16KiB of SRAM A2. */
 #define SUNXI_SCP_BASE			BL31_LIMIT
-#define SUNXI_SCP_SIZE			0x4000
 
 /* Overwrite U-Boot SPL, but reserve the first page for the SPL header. */
 #define BL31_NOBITS_BASE		(SUNXI_SRAM_A1_BASE + 0x1000)
 #define BL31_NOBITS_LIMIT		(SUNXI_SRAM_A1_BASE + SUNXI_SRAM_A1_SIZE)
 
+#define MAX_XLAT_TABLES			1
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 28)
+#define SUNXI_BL33_VIRT_BASE		(SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE)
+
+#endif /* SUNXI_BL31_IN_DRAM */
+
 /* How much memory to reserve as secure for BL32, if configured */
 #define SUNXI_DRAM_SEC_SIZE		(32U << 20)
 
@@ -35,7 +53,6 @@
 #define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
 
 #define MAX_MMAP_REGIONS		(3 + PLATFORM_MMAP_REGIONS)
-#define MAX_XLAT_TABLES			1
 
 #define PLAT_CSS_SCP_COM_SHARED_MEM_BASE \
 	(SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE - 0x200)
@@ -50,7 +67,6 @@
 					 PLATFORM_CORE_COUNT)
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 28)
 
 #define PLATFORM_CLUSTER_COUNT		U(1)
 #define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index 73c4453..f036816 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -17,5 +17,6 @@
 #define SUNXI_SOC_A64			0x1689
 #define SUNXI_SOC_H5			0x1718
 #define SUNXI_SOC_H6			0x1728
+#define SUNXI_SOC_H616			0x1823
 
 #endif /* SUNXI_DEF_H */
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index b68d23f..6cf4670 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -41,4 +41,12 @@
 int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
 void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param);
 
+#ifdef SUNXI_BL31_IN_DRAM
+void sunxi_prepare_dtb(void *fdt);
+#else
+static inline void sunxi_prepare_dtb(void *fdt)
+{
+}
+#endif
+
 #endif /* SUNXI_PRIVATE_H */
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index b619b18..72bfbd9 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -13,6 +13,8 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/console.h>
 #include <drivers/generic_delay_timer.h>
@@ -52,7 +54,7 @@
 	uint64_t *u_boot_base;
 	int i;
 
-	u_boot_base = (void *)(SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE);
+	u_boot_base = (void *)SUNXI_BL33_VIRT_BASE;
 
 	for (i = 0; i < 2048 / sizeof(uint64_t); i++) {
 		uint32_t *dtb_base;
@@ -123,6 +125,9 @@
 	case SUNXI_SOC_H6:
 		soc_name = "H6";
 		break;
+	case SUNXI_SOC_H616:
+		soc_name = "H616";
+		break;
 	default:
 		soc_name = "unknown";
 		break;
@@ -172,6 +177,8 @@
 
 	sunxi_pmic_setup(soc_id, fdt);
 
+	sunxi_prepare_dtb(fdt);
+
 	INFO("BL31: Platform setup done\n");
 }
 
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 5b536a0..d47d360 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -6,13 +6,9 @@
 
 #include <errno.h>
 
-#include <platform_def.h>
-
-#include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
-#include <plat/common/platform.h>
 
 #include <sunxi_def.h>
 #include <sunxi_mmap.h>
@@ -21,16 +17,16 @@
 static const mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = {
 	MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE,
 			MT_RW_DATA | MT_SECURE),
+#ifdef SUNXI_SCP_BASE
 	MAP_REGION_FLAT(SUNXI_SCP_BASE, SUNXI_SCP_SIZE,
 			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
+#endif
 	MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE,
 			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
 	MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE,
 		   MT_RW_DATA | MT_SECURE),
-	MAP_REGION(PRELOADED_BL33_BASE,
-		   SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE,
-		   SUNXI_DRAM_MAP_SIZE,
-		   MT_RO_DATA | MT_NS),
+	MAP_REGION(PRELOADED_BL33_BASE, SUNXI_BL33_VIRT_BASE,
+		   SUNXI_DRAM_MAP_SIZE, MT_RW_DATA | MT_NS),
 	{},
 };
 
@@ -116,6 +112,7 @@
 		device_bit = BIT(6);
 		break;
 	case SUNXI_SOC_H6:
+	case SUNXI_SOC_H616:
 		pin_func = use_rsb ? 0x22 : 0x33;
 		device_bit = BIT(16);
 		reset_offset = use_rsb ? 0x1bc : 0x19c;
@@ -130,7 +127,7 @@
 	}
 
 	/* un-gate R_PIO clock */
-	if (socid != SUNXI_SOC_H6)
+	if (socid != SUNXI_SOC_H6 && socid != SUNXI_SOC_H616)
 		mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, BIT(0));
 
 	/* switch pins PL0 and PL1 to the desired function */
@@ -143,7 +140,7 @@
 	mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U);
 
 	/* un-gate clock */
-	if (socid != SUNXI_SOC_H6)
+	if (socid != SUNXI_SOC_H6 && socid != SUNXI_SOC_H616)
 		mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit);
 	else
 		mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, BIT(0));
@@ -154,50 +151,3 @@
 
 	return 0;
 }
-
-/* This lock synchronises access to the arisc management processor. */
-DEFINE_BAKERY_LOCK(arisc_lock);
-
-/*
- * Tell the "arisc" SCP core (an OpenRISC core) to execute some code.
- * We don't have any service running there, so we place some OpenRISC code
- * in SRAM, put the address of that into the reset vector and release the
- * arisc reset line. The SCP will execute that code and pull the line up again.
- */
-void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param)
-{
-	uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE + 0x100;
-
-	do {
-		bakery_lock_get(&arisc_lock);
-		/* Wait until the arisc is in reset state. */
-		if (!(mmio_read_32(SUNXI_R_CPUCFG_BASE) & BIT(0)))
-			break;
-
-		bakery_lock_release(&arisc_lock);
-	} while (1);
-
-	/* Patch up the code to feed in an input parameter. */
-	code[0] = (code[0] & ~0xffff) | param;
-	clean_dcache_range((uintptr_t)code, size);
-
-	/*
-	 * The OpenRISC unconditional branch has opcode 0, the branch offset
-	 * is in the lower 26 bits, containing the distance to the target,
-	 * in instruction granularity (32 bits).
-	 */
-	mmio_write_32(arisc_reset_vec, ((uintptr_t)code - arisc_reset_vec) / 4);
-	clean_dcache_range(arisc_reset_vec, 4);
-
-	/* De-assert the arisc reset line to let it run. */
-	mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0));
-
-	/*
-	 * We release the lock here, although the arisc is still busy.
-	 * But as long as it runs, the reset line is high, so other users
-	 * won't leave the loop above.
-	 * Once it has finished, the code is supposed to clear the reset line,
-	 * to signal this to other users.
-	 */
-	bakery_lock_release(&arisc_lock);
-}
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index 43c03ac..420b507 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -19,10 +19,6 @@
 #include <sunxi_mmap.h>
 #include <sunxi_private.h>
 
-#ifndef SUNXI_CPUIDLE_EN_REG
-#include <core_off_arisc.h>
-#endif
-
 static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core)
 {
 	if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff)
@@ -67,32 +63,6 @@
 	sunxi_cpu_disable_power(cluster, core);
 }
 
-void sunxi_cpu_power_off_self(void)
-{
-	u_register_t mpidr = read_mpidr();
-	unsigned int core  = MPIDR_AFFLVL0_VAL(mpidr);
-
-	/* Simplifies assembly, all SoCs so far are single cluster anyway. */
-	assert(MPIDR_AFFLVL1_VAL(mpidr) == 0);
-
-#ifdef SUNXI_CPUIDLE_EN_REG
-	/* Enable the CPUIDLE hardware (only really needs to be done once). */
-	mmio_write_32(SUNXI_CPUIDLE_EN_REG, 0x16aa0000);
-	mmio_write_32(SUNXI_CPUIDLE_EN_REG, 0xaa160001);
-
-	/* Trigger power off for this core. */
-	mmio_write_32(SUNXI_CORE_CLOSE_REG, BIT_32(core));
-#else
-	/*
-	 * If we are supposed to turn ourself off, tell the arisc SCP
-	 * to do that work for us. The code expects the core mask to be
-	 * patched into the first instruction.
-	 */
-	sunxi_execute_arisc_code(arisc_core_off, sizeof(arisc_core_off),
-				 BIT_32(core));
-#endif
-}
-
 void sunxi_cpu_on(u_register_t mpidr)
 {
 	unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr);
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index 5f41035..e3c7c52 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -12,3 +12,6 @@
 
 FDT_ASSUME_MASK := "(ASSUME_LATEST | ASSUME_NO_ROLLBACK | ASSUME_LIBFDT_ORDER)"
 $(eval $(call add_define,FDT_ASSUME_MASK))
+
+# Put NOBITS memory in SRAM A1, overwriting U-Boot's SPL.
+SEPARATE_NOBITS_REGION	:=	1
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index 80a69c3..0fdb62d 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -14,6 +14,7 @@
 #include <drivers/allwinner/sunxi_rsb.h>
 #include <lib/mmio.h>
 
+#include <core_off_arisc.h>
 #include <sunxi_def.h>
 #include <sunxi_mmap.h>
 #include <sunxi_private.h>
@@ -205,3 +206,55 @@
 	}
 
 }
+
+/* This lock synchronises access to the arisc management processor. */
+static DEFINE_BAKERY_LOCK(arisc_lock);
+
+/*
+ * If we are supposed to turn ourself off, tell the arisc SCP to do that
+ * work for us. Without any SCPI provider running there, we place some
+ * OpenRISC code into SRAM, put the address of that into the reset vector
+ * and release the arisc reset line. The SCP will wait for the core to enter
+ * WFI, then execute that code and pull the line up again.
+ * The code expects the core mask to be patched into the first instruction.
+ */
+void sunxi_cpu_power_off_self(void)
+{
+	u_register_t mpidr = read_mpidr();
+	unsigned int core  = MPIDR_AFFLVL0_VAL(mpidr);
+	uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE + 0x100;
+	uint32_t *code = arisc_core_off;
+
+	do {
+		bakery_lock_get(&arisc_lock);
+		/* Wait until the arisc is in reset state. */
+		if (!(mmio_read_32(SUNXI_R_CPUCFG_BASE) & BIT(0)))
+			break;
+
+		bakery_lock_release(&arisc_lock);
+	} while (1);
+
+	/* Patch up the code to feed in an input parameter. */
+	code[0] = (code[0] & ~0xffff) | BIT_32(core);
+	clean_dcache_range((uintptr_t)code, sizeof(arisc_core_off));
+
+	/*
+	 * The OpenRISC unconditional branch has opcode 0, the branch offset
+	 * is in the lower 26 bits, containing the distance to the target,
+	 * in instruction granularity (32 bits).
+	 */
+	mmio_write_32(arisc_reset_vec, ((uintptr_t)code - arisc_reset_vec) / 4);
+	clean_dcache_range(arisc_reset_vec, 4);
+
+	/* De-assert the arisc reset line to let it run. */
+	mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0));
+
+	/*
+	 * We release the lock here, although the arisc is still busy.
+	 * But as long as it runs, the reset line is high, so other users
+	 * won't leave the loop above.
+	 * Once it has finished, the code is supposed to clear the reset line,
+	 * to signal this to other users.
+	 */
+	bakery_lock_release(&arisc_lock);
+}
diff --git a/plat/allwinner/sun50i_h6/include/core_off_arisc.h b/plat/allwinner/sun50i_h6/include/core_off_arisc.h
deleted file mode 100644
index 63a5d8d..0000000
--- a/plat/allwinner/sun50i_h6/include/core_off_arisc.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-static uint32_t arisc_core_off[] = {
-	0x18600000, /* l.movhi	r3, <corenr>	*/
-	0x18000000, /* l.movhi	r0, 0x0		*/
-	0x19a00901, /* l.movhi	r13, 0x901	*/
-	0x84ad0080, /* l.lwz	r5, 0x80(r13)	*/
-	0xe0a51803, /* l.and	r5, r5, r3	*/
-	0xe4050000, /* l.sfeq	r5, r0		*/
-	0x13fffffd, /* l.bf	-12		*/
-	0xb8c30050, /* l.srli	r6, r3, 16	*/
-
-	0xbc060001, /* l.sfeqi	r6, 1		*/
-	0x10000005, /* l.bf	+20		*/
-	0x19a00700, /* l.movhi	r13, 0x700	*/
-	0x84ad0444, /* l.lwz	r5, 0x0444(r13)	*/
-	0xe0a53004, /* l.or	r5, r5, r6	*/
-	0xd40d2c44, /* l.sw	0x0444(r13), r5	*/
-
-	0x84ad0440, /* l.lwz	r5, 0x0440(r13)	*/
-	0xacc6ffff, /* l.xori	r6, r6, -1	*/
-	0xe0a53003, /* l.and	r5, r5, r6	*/
-	0xd40d2c40, /* l.sw	0x0440(r13), r5	*/
-
-	0xe0c3000f, /* l.ff1	r6, r3		*/
-	0x9cc6ffef, /* l.addi	r6, r6, -17	*/
-	0xb8c60002, /* l.slli	r6, r6, 2	*/
-	0xe0c66800, /* l.add	r6, r6, r13	*/
-	0xa8a000ff, /* l.ori	r5, r0, 0xff	*/
-	0xd4062c50, /* l.sw	0x0450(r6), r5	*/
-
-	0xd40d0400, /* l.sw	0x0400(r13), r0	*/
-	0x03ffffff, /* l.j	-1		*/
-	0x15000000, /* l.nop			*/
-};
diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk
index 1c98919..e13e8cb 100644
--- a/plat/allwinner/sun50i_h6/platform.mk
+++ b/plat/allwinner/sun50i_h6/platform.mk
@@ -9,3 +9,6 @@
 
 BL31_SOURCES		+=	drivers/allwinner/axp/axp805.c		\
 				drivers/allwinner/sunxi_rsb.c
+
+# Put NOBITS memory in SRAM A1, overwriting U-Boot's SPL.
+SEPARATE_NOBITS_REGION	:=	1
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index a7865a5..d298e6b 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -10,7 +10,9 @@
 #include <common/debug.h>
 #include <drivers/allwinner/axp.h>
 #include <drivers/allwinner/sunxi_rsb.h>
+#include <lib/mmio.h>
 
+#include <sunxi_cpucfg.h>
 #include <sunxi_def.h>
 #include <sunxi_mmap.h>
 #include <sunxi_private.h>
@@ -102,3 +104,16 @@
 		break;
 	}
 }
+
+void sunxi_cpu_power_off_self(void)
+{
+	u_register_t mpidr = read_mpidr();
+	unsigned int core  = MPIDR_AFFLVL0_VAL(mpidr);
+
+	/* Enable the CPUIDLE hardware (only really needs to be done once). */
+	mmio_write_32(SUNXI_CPUIDLE_EN_REG, 0x16aa0000);
+	mmio_write_32(SUNXI_CPUIDLE_EN_REG, 0xaa160001);
+
+	/* Trigger power off for this core. */
+	mmio_write_32(SUNXI_CORE_CLOSE_REG, BIT_32(core));
+}
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_ccu.h b/plat/allwinner/sun50i_h616/include/sunxi_ccu.h
new file mode 100644
index 0000000..85fbb90
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/include/sunxi_ccu.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CCU_H
+#define SUNXI_CCU_H
+
+#define SUNXI_CCU_SEC_SWITCH_REG	(SUNXI_CCU_BASE + 0x0f00)
+
+#define SUNXI_R_PRCM_SEC_SWITCH_REG	(SUNXI_R_PRCM_BASE + 0x0290)
+
+#endif /* SUNXI_CCU_H */
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
new file mode 100644
index 0000000..a637554
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017-2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CPUCFG_H
+#define SUNXI_CPUCFG_H
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10)
+#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_CPUCFG_BASE + 0x0024)
+#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x00c0)
+
+#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
+
+#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
+					(c) * 0x10 + (n) * 4)
+
+#define SUNXI_CPUIDLE_EN_REG		(SUNXI_R_CPUCFG_BASE + 0x0100)
+#define SUNXI_CORE_CLOSE_REG		(SUNXI_R_CPUCFG_BASE + 0x0104)
+#define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
+#define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
+
+#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_mmap.h b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
new file mode 100644
index 0000000..3b4f4a0
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_MMAP_H
+#define SUNXI_MMAP_H
+
+/* Memory regions */
+#define SUNXI_ROM_BASE			0x00000000
+#define SUNXI_ROM_SIZE			0x00010000
+#define SUNXI_SRAM_BASE			0x00020000
+#define SUNXI_SRAM_SIZE			0x00038000
+#define SUNXI_SRAM_A1_BASE		0x00020000
+#define SUNXI_SRAM_A1_SIZE		0x00008000
+#define SUNXI_SRAM_C_BASE		0x00028000
+#define SUNXI_SRAM_C_SIZE		0x00030000
+#define SUNXI_DEV_BASE			0x01000000
+#define SUNXI_DEV_SIZE			0x09000000
+#define SUNXI_DRAM_BASE			0x40000000
+#define SUNXI_DRAM_VIRT_BASE		SUNXI_DRAM_BASE
+
+/* Memory-mapped devices */
+#define SUNXI_SYSCON_BASE		0x03000000
+#define SUNXI_CCU_BASE			0x03001000
+#define SUNXI_DMA_BASE			0x03002000
+#define SUNXI_SID_BASE			0x03006000
+#define SUNXI_SPC_BASE			0x03008000
+#define SUNXI_WDOG_BASE			0x030090a0
+#define SUNXI_PIO_BASE			0x0300b000
+#define SUNXI_GICD_BASE			0x03021000
+#define SUNXI_GICC_BASE			0x03022000
+#define SUNXI_UART0_BASE		0x05000000
+#define SUNXI_SPI0_BASE			0x05010000
+#define SUNXI_R_CPUCFG_BASE		0x07000400
+#define SUNXI_R_PRCM_BASE		0x07010000
+//#define SUNXI_R_WDOG_BASE		0x07020400
+#define SUNXI_R_WDOG_BASE		SUNXI_WDOG_BASE
+#define SUNXI_R_PIO_BASE		0x07022000
+#define SUNXI_R_UART_BASE		0x07080000
+#define SUNXI_R_I2C_BASE		0x07081400
+#define SUNXI_R_RSB_BASE		0x07083000
+#define SUNXI_CPUCFG_BASE		0x09010000
+
+#endif /* SUNXI_MMAP_H */
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_spc.h b/plat/allwinner/sun50i_h616/include/sunxi_spc.h
new file mode 100644
index 0000000..0f5965b
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/include/sunxi_spc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_SPC_H
+#define SUNXI_SPC_H
+
+#define SUNXI_SPC_NUM_PORTS		14
+
+#define SUNXI_SPC_DECPORT_STA_REG(p)	(SUNXI_SPC_BASE + 0x0000 + 0x10 * (p))
+#define SUNXI_SPC_DECPORT_SET_REG(p)	(SUNXI_SPC_BASE + 0x0004 + 0x10 * (p))
+#define SUNXI_SPC_DECPORT_CLR_REG(p)	(SUNXI_SPC_BASE + 0x0008 + 0x10 * (p))
+
+#endif /* SUNXI_SPC_H */
diff --git a/plat/allwinner/sun50i_h616/platform.mk b/plat/allwinner/sun50i_h616/platform.mk
new file mode 100644
index 0000000..fc09af7
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/platform.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2017-2020, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Without a management processor there is no SCPI support.
+SUNXI_PSCI_USE_SCPI	:=	0
+SUNXI_PSCI_USE_NATIVE	:=	1
+
+# The differences between the platforms are covered by the include files.
+include plat/allwinner/common/allwinner-common.mk
+
+# the above could be overwritten on the command line
+ifeq (${SUNXI_PSCI_USE_SCPI}, 1)
+    $(error "H616 does not support SCPI PSCI ops")
+endif
+
+BL31_SOURCES		+=	drivers/allwinner/axp/axp805.c		\
+				drivers/allwinner/sunxi_rsb.c		\
+				common/fdt_fixup.c			\
+				${AW_PLAT}/${PLAT}/prepare_dtb.c
+
+$(eval $(call add_define,SUNXI_BL31_IN_DRAM))
diff --git a/plat/allwinner/sun50i_h616/prepare_dtb.c b/plat/allwinner/sun50i_h616/prepare_dtb.c
new file mode 100644
index 0000000..e94b0b4
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/prepare_dtb.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <libfdt.h>
+
+#include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
+
+#include <sunxi_private.h>
+
+void sunxi_prepare_dtb(void *fdt)
+{
+	int ret;
+
+	if (fdt == NULL || fdt_check_header(fdt) != 0) {
+		return;
+	}
+	ret = fdt_open_into(fdt, fdt, 0x100000);
+	if (ret < 0) {
+		ERROR("Preparing devicetree at %p: error %d\n", fdt, ret);
+		return;
+	}
+
+	/* Reserve memory used by Trusted Firmware. */
+	if (fdt_add_reserved_memory(fdt, "tf-a@40000000", BL31_BASE,
+				    BL31_LIMIT - BL31_BASE)) {
+		WARN("Failed to add reserved memory nodes to DT.\n");
+		return;
+	}
+
+	ret = fdt_pack(fdt);
+	if (ret < 0) {
+		ERROR("Failed to pack devicetree at %p: error %d\n",
+		      fdt, ret);
+	} else {
+		clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
+		INFO("Changed devicetree to reserve BL31 memory.\n");
+	}
+}
diff --git a/plat/allwinner/sun50i_h616/sunxi_power.c b/plat/allwinner/sun50i_h616/sunxi_power.c
new file mode 100644
index 0000000..dd6ebba
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/sunxi_power.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2017-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/allwinner/axp.h>
+#include <drivers/allwinner/sunxi_rsb.h>
+#include <lib/mmio.h>
+
+#include <sunxi_cpucfg.h>
+#include <sunxi_def.h>
+#include <sunxi_mmap.h>
+#include <sunxi_private.h>
+
+#define AXP305_I2C_ADDR	0x36
+#define AXP305_HW_ADDR	0x745
+#define AXP305_RT_ADDR	0x3a
+
+static enum pmic_type {
+	UNKNOWN,
+	AXP305,
+} pmic;
+
+int axp_read(uint8_t reg)
+{
+	return rsb_read(AXP305_RT_ADDR, reg);
+}
+
+int axp_write(uint8_t reg, uint8_t val)
+{
+	return rsb_write(AXP305_RT_ADDR, reg, val);
+}
+
+static int rsb_init(void)
+{
+	int ret;
+
+	ret = rsb_init_controller();
+	if (ret)
+		return ret;
+
+	/* Switch to the recommended 3 MHz bus clock. */
+	ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
+	if (ret)
+		return ret;
+
+	/* Initiate an I2C transaction to switch the PMIC to RSB mode. */
+	ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8);
+	if (ret)
+		return ret;
+
+	/* Associate the 8-bit runtime address with the 12-bit bus address. */
+	ret = rsb_assign_runtime_address(AXP305_HW_ADDR, AXP305_RT_ADDR);
+	if (ret)
+		return ret;
+
+	return axp_check_id();
+}
+
+int sunxi_pmic_setup(uint16_t socid, const void *fdt)
+{
+	int ret;
+
+	INFO("PMIC: Probing AXP305 on RSB\n");
+
+	ret = sunxi_init_platform_r_twi(socid, true);
+	if (ret) {
+		INFO("Could not init platform bus: %d\n", ret);
+		return ret;
+	}
+
+	ret = rsb_init();
+	if (ret) {
+		INFO("Could not init RSB: %d\n", ret);
+		return ret;
+	}
+
+	pmic = AXP305;
+	axp_setup_regulators(fdt);
+
+	/* Switch the PMIC back to I2C mode. */
+	ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+void sunxi_power_down(void)
+{
+	switch (pmic) {
+	case AXP305:
+		/* Re-initialise after rich OS might have used it. */
+		sunxi_init_platform_r_twi(SUNXI_SOC_H616, true);
+		rsb_init();
+		axp_power_off();
+		break;
+	default:
+		break;
+	}
+}
+
+void sunxi_cpu_power_off_self(void)
+{
+	u_register_t mpidr = read_mpidr();
+	unsigned int core  = MPIDR_AFFLVL0_VAL(mpidr);
+
+	/* Enable the CPUIDLE hardware (only really needs to be done once). */
+	mmio_write_32(SUNXI_CPUIDLE_EN_REG, 0x16aa0000);
+	mmio_write_32(SUNXI_CPUIDLE_EN_REG, 0xaa160001);
+
+	/* Trigger power off for this core. */
+	mmio_write_32(SUNXI_CORE_CLOSE_REG, BIT_32(core));
+}
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 7bc6a40..7ce4ba3 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -69,7 +69,9 @@
 				lib/cpus/aarch64/cortex_a65ae.S		\
 				lib/cpus/aarch64/cortex_klein.S		\
 				lib/cpus/aarch64/cortex_matterhorn.S	\
-				lib/cpus/aarch64/cortex_makalu.S
+				lib/cpus/aarch64/cortex_makalu.S	\
+				lib/cpus/aarch64/cortex_makalu_elp.S    \
+				lib/cpus/aarch64/cortex_a78c.S
 
 # AArch64/AArch32 cores
 	FPGA_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S	\
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 3bcfe91..20d80ed 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -131,11 +131,13 @@
 					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/neoverse_v1.S		\
 					lib/cpus/aarch64/cortex_a78_ae.S	\
-					lib/cpus/aarch64/cortex_klein.S	        \
+					lib/cpus/aarch64/cortex_klein.S		\
 					lib/cpus/aarch64/cortex_matterhorn.S	\
 					lib/cpus/aarch64/cortex_makalu.S	\
+					lib/cpus/aarch64/cortex_makalu_elp.S	\
 					lib/cpus/aarch64/cortex_a65.S		\
-					lib/cpus/aarch64/cortex_a65ae.S
+					lib/cpus/aarch64/cortex_a65ae.S		\
+					lib/cpus/aarch64/cortex_a78c.S
 	endif
 	# AArch64/AArch32 cores
 	FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S		\
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
index c39fe2b..a9b30a4 100644
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ b/plat/arm/board/rde1edge/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 
 #include <lib/utils_def.h>
 
+#include <sgi_sdei.h>
 #include <sgi_soc_platform_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		U(2)
diff --git a/plat/arm/board/rde1edge/rde1edge_security.c b/plat/arm/board/rde1edge/rde1edge_security.c
index 2123e09..35f81d1 100644
--- a/plat/arm/board/rde1edge/rde1edge_security.c
+++ b/plat/arm/board/rde1edge/rde1edge_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
-#include <drivers/arm/tzc_dmc620.h>
+#include <sgi_dmc620_tzc_regions.h>
 
 uintptr_t rde1edge_dmc_base[] = {
 	RDE1EDGE_DMC620_BASE0,
@@ -20,11 +20,7 @@
 };
 
 static const tzc_dmc620_acc_addr_data_t rde1edge_acc_addr_data[] = {
-	{
-		.region_base = ARM_AP_TZC_DRAM1_BASE,
-		.region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1,
-		.sec_attr = TZC_DMC620_REGION_S_RDWR
-	}
+	CSS_SGI_DMC620_TZC_REGIONS_DEF
 };
 
 static const tzc_dmc620_config_data_t rde1edge_plat_config_data = {
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
index b167c46..a61b0d5 100644
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ b/plat/arm/board/rdn1edge/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 
 #include <lib/utils_def.h>
 
+#include <sgi_sdei.h>
 #include <sgi_soc_platform_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		U(2)
diff --git a/plat/arm/board/rdn1edge/rdn1edge_security.c b/plat/arm/board/rdn1edge/rdn1edge_security.c
index ffa8935..4943532 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_security.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
-#include <drivers/arm/tzc_dmc620.h>
+#include <sgi_dmc620_tzc_regions.h>
 
 uintptr_t rdn1edge_dmc_base[] = {
 	RDN1EDGE_DMC620_BASE0,
@@ -20,11 +20,7 @@
 };
 
 static const tzc_dmc620_acc_addr_data_t rdn1edge_acc_addr_data[] = {
-	{
-		.region_base = ARM_AP_TZC_DRAM1_BASE,
-		.region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1,
-		.sec_attr = TZC_DMC620_REGION_S_RDWR
-	}
+	CSS_SGI_DMC620_TZC_REGIONS_DEF
 };
 
 static const tzc_dmc620_config_data_t rdn1edge_plat_config_data = {
diff --git a/plat/arm/board/rdv1mc/include/platform_def.h b/plat/arm/board/rdv1mc/include/platform_def.h
index 112b210..12ce806 100644
--- a/plat/arm/board/rdv1mc/include/platform_def.h
+++ b/plat/arm/board/rdv1mc/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,6 +20,29 @@
 #define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
 
+/* TZC Related Constants */
+#define PLAT_ARM_TZC_BASE		UL(0x21830000)
+#define TZC400_BASE(n)			(PLAT_ARM_TZC_BASE + \
+					 (n * TZC400_OFFSET))
+#define TZC400_OFFSET			UL(0x1000000)
+#define TZC400_COUNT			U(8)
+#define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+#define TZC_NSAID_ALL_AP		U(0)
+#define TZC_NSAID_PCI			U(1)
+#define TZC_NSAID_HDLCD0		U(2)
+#define TZC_NSAID_CLCD			U(7)
+#define TZC_NSAID_AP			U(9)
+#define TZC_NSAID_VIRTIO		U(15)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS	\
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI))    | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP))     | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD))   | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
+
 /* Virtual address used by dynamic mem_protect for chunk_base */
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
 
diff --git a/plat/arm/board/rdv1mc/platform.mk b/plat/arm/board/rdv1mc/platform.mk
index 5072841..fb05793 100644
--- a/plat/arm/board/rdv1mc/platform.mk
+++ b/plat/arm/board/rdv1mc/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -23,6 +23,8 @@
 BL2_SOURCES		+=	${RDV1MC_BASE}/rdv1mc_plat.c	\
 				${RDV1MC_BASE}/rdv1mc_security.c	\
 				${RDV1MC_BASE}/rdv1mc_err.c	\
+				drivers/arm/tzc/tzc400.c	\
+				plat/arm/common/arm_tzc400.c	\
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
diff --git a/plat/arm/board/rdv1mc/rdv1mc_security.c b/plat/arm/board/rdv1mc/rdv1mc_security.c
index 541f800..adc0bf8 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_security.c
+++ b/plat/arm/board/rdv1mc/rdv1mc_security.c
@@ -1,10 +1,64 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+/* TZC memory regions for the first chip */
+static const arm_tzc_regions_info_t tzc_regions[] = {
+	ARM_TZC_REGIONS_DEF,
+	{}
+};
+
+#if CSS_SGI_CHIP_COUNT > 1
+static const arm_tzc_regions_info_t tzc_regions_mc[][CSS_SGI_CHIP_COUNT - 1] = {
+	{
+		/* TZC memory regions for second chip */
+		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(1),
+		{}
+	},
+#if CSS_SGI_CHIP_COUNT > 2
+	{
+		/* TZC memory regions for third chip */
+		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(2),
+		{}
+	},
+#endif
+#if CSS_SGI_CHIP_COUNT > 3
+	{
+		/* TZC memory regions for fourth chip */
+		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(3),
+		{}
+	},
+#endif
+};
+#endif /* CSS_SGI_CHIP_COUNT */
+
 /* Initialize the secure environment */
 void plat_arm_security_setup(void)
 {
+	unsigned int i;
+
+	INFO("Configuring TrustZone Controller for Chip 0\n");
+
+	for (i = 0; i < TZC400_COUNT; i++) {
+		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
+	}
+
+#if CSS_SGI_CHIP_COUNT > 1
+	unsigned int j;
+
+	for (i = 1; i < CSS_SGI_CHIP_COUNT; i++) {
+		INFO("Configuring TrustZone Controller for Chip %u\n", i);
+
+		for (j = 0; j < TZC400_COUNT; j++) {
+			arm_tzc400_setup(CSS_SGI_REMOTE_CHIP_MEM_OFFSET(i)
+				+ TZC400_BASE(j), tzc_regions_mc[i-1]);
+		}
+	}
+#endif
 }
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index c929334..72d5f7c 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 
 #include <lib/utils_def.h>
 
+#include <sgi_sdei.h>
 #include <sgi_soc_platform_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		U(2)
diff --git a/plat/arm/board/sgi575/sgi575_security.c b/plat/arm/board/sgi575/sgi575_security.c
index 440f18d..17d07d1 100644
--- a/plat/arm/board/sgi575/sgi575_security.c
+++ b/plat/arm/board/sgi575/sgi575_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,7 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
-#include <drivers/arm/tzc_dmc620.h>
-#include <plat/arm/common/plat_arm.h>
+#include <sgi_dmc620_tzc_regions.h>
 
 uintptr_t sgi575_dmc_base[] = {
 	SGI575_DMC620_BASE0,
@@ -21,11 +20,7 @@
 };
 
 static const tzc_dmc620_acc_addr_data_t sgi575_acc_addr_data[] = {
-	{
-		.region_base = ARM_AP_TZC_DRAM1_BASE,
-		.region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1,
-		.sec_attr = TZC_DMC620_REGION_S_RDWR
-	}
+	CSS_SGI_DMC620_TZC_REGIONS_DEF
 };
 
 static const tzc_dmc620_config_data_t sgi575_plat_config_data = {
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index ed7f1f5..ebf6dff 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.c
@@ -38,38 +38,36 @@
  ******************************************************************************/
 static void plat_add_sp_images_load_info(struct bl_load_info *load_info)
 {
-	bl_load_info_node_t *node_info = load_info->head;
-	unsigned int index = 0;
+	bl_load_info_node_t *curr_node = load_info->head;
+	bl_load_info_node_t *prev_node;
 
-	if (sp_mem_params_descs[index].image_id == 0) {
+	/* Shortcut for empty SP list */
+	if (sp_mem_params_descs[0].image_id == 0) {
 		ERROR("No Secure Partition Image available\n");
 		return;
 	}
 
 	/* Traverse through the bl images list */
 	do {
-		node_info = node_info->next_load_info;
-	} while (node_info->next_load_info != NULL);
+		curr_node = curr_node->next_load_info;
+	} while (curr_node->next_load_info != NULL);
 
-	for (; index < MAX_SP_IDS; index++) {
+	prev_node = curr_node;
+
+	for (unsigned int index = 0; index < MAX_SP_IDS; index++) {
+		if (sp_mem_params_descs[index].image_id == 0) {
+			return;
+		}
+		curr_node = &sp_mem_params_descs[index].load_node_mem;
 		/* Populate the image information */
-		node_info->image_id = sp_mem_params_descs[index].image_id;
-		node_info->image_info = &sp_mem_params_descs[index].image_info;
+		curr_node->image_id = sp_mem_params_descs[index].image_id;
+		curr_node->image_info = &sp_mem_params_descs[index].image_info;
 
-		if ((index + 1U) == MAX_SP_IDS) {
-			INFO("Reached Max number of SPs\n");
-			return;
-		}
-
-		if (sp_mem_params_descs[index + 1U].image_id == 0) {
-			return;
-		}
-
-		node_info->next_load_info =
-			&sp_mem_params_descs[index + 1U].load_node_mem;
-		node_info = node_info->next_load_info;
-
+		prev_node->next_load_info = curr_node;
+		prev_node = curr_node;
 	}
+
+	INFO("Reached Max number of SPs\n");
 }
 #endif
 
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 b805746..d795f25 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,14 +26,17 @@
 
 /*
  * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
- * plat_arm_mmap array defined for each BL stage.
+ * plat_arm_mmap array defined for each BL stage. In addition to that, on
+ * multi-chip platforms, address regions on each of the remote chips are
+ * also mapped. In BL31, for instance, three address regions on the remote
+ * chips are accessed - secure ram, css device and soc device regions.
  */
 #if defined(IMAGE_BL31)
 # if SPM_MM
-#  define PLAT_ARM_MMAP_ENTRIES		9
-#  define MAX_XLAT_TABLES		7
-#  define PLAT_SP_IMAGE_MMAP_REGIONS	7
-#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	10
+#  define PLAT_ARM_MMAP_ENTRIES		(9  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(7  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
+#  define PLAT_SP_IMAGE_MMAP_REGIONS	9
+#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	11
 # else
 #  define PLAT_ARM_MMAP_ENTRIES		(5 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
 #  define MAX_XLAT_TABLES		(6 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
@@ -41,6 +44,17 @@
 #elif defined(IMAGE_BL32)
 # define PLAT_ARM_MMAP_ENTRIES		8
 # define MAX_XLAT_TABLES		5
+#elif defined(IMAGE_BL2)
+# define PLAT_ARM_MMAP_ENTRIES		(11 + (CSS_SGI_CHIP_COUNT - 1))
+
+/*
+ * MAX_XLAT_TABLES entries need to be doubled because when the address width
+ * exceeds 40 bits an additional level of translation is required. In case of
+ * multichip platforms peripherals also fall into address space with width
+ * > 40 bits
+ *
+ */
+# define MAX_XLAT_TABLES		(7  + ((CSS_SGI_CHIP_COUNT - 1) * 2))
 #elif !USE_ROMLIB
 # define PLAT_ARM_MMAP_ENTRIES		11
 # define MAX_XLAT_TABLES		7
@@ -69,12 +83,17 @@
 
 /*
  * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
- * little space for growth.
+ * little space for growth. Additional 8KiB space is added per chip in
+ * order to accommodate the additional level of translation required for "TZC"
+ * peripheral access which lies in >4TB address space.
+ *
  */
 #if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE		0x1D000
+# define PLAT_ARM_MAX_BL2_SIZE		(0x1D000 + ((CSS_SGI_CHIP_COUNT - 1) * \
+							0x2000))
 #else
-# define PLAT_ARM_MAX_BL2_SIZE		0x14000
+# define PLAT_ARM_MAX_BL2_SIZE		(0x14000 + ((CSS_SGI_CHIP_COUNT - 1) * \
+							0x2000))
 #endif
 
 /*
@@ -165,48 +184,36 @@
 
 #define PLAT_SP_PRI				PLAT_RAS_PRI
 
-#if RAS_EXTENSION
-/* Allocate 128KB for CPER buffers */
-#define PLAT_SP_BUF_BASE			ULL(0x20000)
-
-#define PLAT_ARM_SP_IMAGE_STACK_BASE		(PLAT_SP_IMAGE_NS_BUF_BASE + \
-						PLAT_SP_IMAGE_NS_BUF_SIZE + \
-						PLAT_SP_BUF_BASE)
-
-/* Platform specific SMC FID's used for RAS */
-#define SP_DMC_ERROR_INJECT_EVENT_AARCH64	0xC4000042
-#define SP_DMC_ERROR_INJECT_EVENT_AARCH32	0x84000042
-
-#define SP_DMC_ERROR_OVERFLOW_EVENT_AARCH64	0xC4000043
-#define SP_DMC_ERROR_OVERFLOW_EVENT_AARCH32	0x84000043
-
-#define SP_DMC_ERROR_ECC_EVENT_AARCH64		0xC4000044
-#define SP_DMC_ERROR_ECC_EVENT_AARCH32		0x84000044
-
-/* ARM SDEI dynamic shared event numbers */
-#define SGI_SDEI_DS_EVENT_0			804
-#define SGI_SDEI_DS_EVENT_1			805
-
-#define PLAT_ARM_PRIVATE_SDEI_EVENTS	\
-	SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI), \
-	SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_0, SDEI_MAPF_CRITICAL), \
-	SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL),
-#define PLAT_ARM_SHARED_SDEI_EVENTS
-
-#define ARM_SP_CPER_BUF_BASE			(PLAT_SP_IMAGE_NS_BUF_BASE + \
-						PLAT_SP_IMAGE_NS_BUF_SIZE)
-#define ARM_SP_CPER_BUF_SIZE			ULL(0x20000)
-#define ARM_SP_CPER_BUF_MMAP			MAP_REGION2(		\
-						ARM_SP_CPER_BUF_BASE,	\
-						ARM_SP_CPER_BUF_BASE,	\
-						ARM_SP_CPER_BUF_SIZE,	\
-						MT_RW_DATA | MT_NS | MT_USER, \
+#if SPM_MM && RAS_EXTENSION
+/*
+ * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
+ * memory shared between EL3 and S-EL0.
+ */
+#define CSS_SGI_SP_CPER_BUF_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE + \
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
+#define CSS_SGI_SP_CPER_BUF_SIZE	ULL(0x20000)
+#define CSS_SGI_SP_CPER_BUF_MMAP	MAP_REGION2(			       \
+						CSS_SGI_SP_CPER_BUF_BASE,      \
+						CSS_SGI_SP_CPER_BUF_BASE,      \
+						CSS_SGI_SP_CPER_BUF_SIZE,      \
+						MT_RW_DATA | MT_NS | MT_USER,  \
 						PAGE_SIZE)
 
-#else
+/*
+ * Secure partition stack follows right after the memory space reserved for
+ * CPER buffer memory.
+ */
+#define PLAT_ARM_SP_IMAGE_STACK_BASE		(PLAT_SP_IMAGE_NS_BUF_BASE +   \
+						 PLAT_SP_IMAGE_NS_BUF_SIZE +   \
+						 CSS_SGI_SP_CPER_BUF_SIZE)
+#elif SPM_MM
+/*
+ * Secure partition stack follows right after the memory region that is shared
+ * between EL3 and S-EL0.
+ */
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
-#endif /* RAS_EXTENSION */
+#endif /* SPM_MM && RAS_EXTENSION */
 
 /* Platform ID address */
 #define SSC_VERSION                     (SSC_REG_BASE + SSC_VERSION_OFFSET)
@@ -238,4 +245,17 @@
 /* Number of SCMI channels on the platform */
 #define PLAT_ARM_SCMI_CHANNEL_COUNT	CSS_SGI_CHIP_COUNT
 
+/*
+ * Mapping definition of the TrustZone Controller for ARM SGI/RD platforms
+ * where both the DRAM regions are marked for non-secure access. This applies
+ * to multi-chip platforms.
+ */
+#define SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(n)				\
+	{CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_BASE,		\
+		CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_END,	\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},	\
+	{CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_BASE,		\
+		CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_END,	\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
+
 #endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_dmc620_tzc_regions.h b/plat/arm/css/sgi/include/sgi_dmc620_tzc_regions.h
new file mode 100644
index 0000000..e939163
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_dmc620_tzc_regions.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_DMC620_TZC_REGIONS_H
+#define SGI_DMC620_TZC_REGIONS_H
+
+#include <drivers/arm/tzc_dmc620.h>
+
+#if SPM_MM
+#define CSS_SGI_DMC620_TZC_REGIONS_DEF				\
+	{							\
+		.region_base = ARM_AP_TZC_DRAM1_BASE,		\
+		.region_top = PLAT_SP_IMAGE_NS_BUF_BASE - 1,	\
+		.sec_attr = TZC_DMC620_REGION_S_RDWR		\
+	}, {							\
+		.region_base = PLAT_SP_IMAGE_NS_BUF_BASE,	\
+		.region_top = PLAT_ARM_SP_IMAGE_STACK_BASE - 1,	\
+		.sec_attr = TZC_DMC620_REGION_S_NS_RDWR		\
+	}, {							\
+		.region_base = PLAT_ARM_SP_IMAGE_STACK_BASE,	\
+		.region_top = ARM_AP_TZC_DRAM1_END,		\
+		.sec_attr = TZC_DMC620_REGION_S_RDWR		\
+	}
+#else
+#define CSS_SGI_DMC620_TZC_REGIONS_DEF				\
+	{							\
+		.region_base = ARM_AP_TZC_DRAM1_BASE,		\
+		.region_top = ARM_AP_TZC_DRAM1_END,		\
+		.sec_attr = TZC_DMC620_REGION_S_RDWR		\
+	}
+#endif /* SPM_MM */
+
+#endif /* SGI_DMC620_TZC_REGIONS_H */
diff --git a/plat/arm/css/sgi/include/sgi_ras.h b/plat/arm/css/sgi/include/sgi_ras.h
index a449eae..4b8a0d1 100644
--- a/plat/arm/css/sgi/include/sgi_ras.h
+++ b/plat/arm/css/sgi/include/sgi_ras.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,10 @@
 #ifndef SGI_RAS_H
 #define SGI_RAS_H
 
+/* Platform specific SMC FID's used for DMC-620 RAS error handling */
+#define SP_DMC_ERROR_OVERFLOW_EVENT_AARCH64	0xC4000043
+#define SP_DMC_ERROR_ECC_EVENT_AARCH64		0xC4000044
+
 /*
  * Mapping the RAS interrupt with SDEI event number and the event
  * id used with Standalone MM code
diff --git a/plat/arm/css/sgi/include/sgi_sdei.h b/plat/arm/css/sgi/include/sgi_sdei.h
new file mode 100644
index 0000000..f380122
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_sdei.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_SDEI_H
+#define SGI_SDEI_H
+
+#if SDEI_SUPPORT
+
+/* ARM SDEI dynamic shared event numbers */
+#define SGI_SDEI_DS_EVENT_0		U(804)
+#define SGI_SDEI_DS_EVENT_1		U(805)
+
+#define PLAT_ARM_PRIVATE_SDEI_EVENTS					      \
+		SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI),			      \
+		SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_0, SDEI_MAPF_CRITICAL), \
+		SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL),
+
+#define PLAT_ARM_SHARED_SDEI_EVENTS
+
+#endif /* SDEI_SUPPORT */
+
+#endif /* SGI_SDEI_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
index 03f1073..103dd9a 100644
--- a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
+++ b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -70,6 +70,18 @@
 						SOC_PLATFORM_PERIPH_SIZE, 	\
 						MT_DEVICE | MT_RW | MT_SECURE)
 
+#if SPM_MM
+/*
+ * Memory map definition for the platform peripheral memory region that is
+ * accessible from S-EL0 (with secure user mode access).
+ */
+#define SOC_PLATFORM_PERIPH_MAP_DEVICE_USER				       \
+		MAP_REGION_FLAT(					       \
+			SOC_PLATFORM_PERIPH_BASE,			       \
+			SOC_PLATFORM_PERIPH_SIZE,			       \
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+#endif
+
 #define SOC_SYSTEM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(			\
 						SOC_SYSTEM_PERIPH_BASE,		\
 						SOC_SYSTEM_PERIPH_SIZE,		\
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def.h b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
index d7a839a..405d62f 100644
--- a/plat/arm/css/sgi/include/sgi_soc_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,4 +12,22 @@
 #include <plat/arm/board/common/v2m_def.h>
 #include <plat/arm/soc/common/soc_css_def.h>
 
+/* Map the System registers to access from S-EL0 */
+#define CSS_SYSTEMREG_DEVICE_BASE	(0x1C010000)
+#define CSS_SYSTEMREG_DEVICE_SIZE	(0x00010000)
+#define PLAT_ARM_SECURE_MAP_SYSTEMREG	MAP_REGION_FLAT(		    \
+						CSS_SYSTEMREG_DEVICE_BASE,  \
+						CSS_SYSTEMREG_DEVICE_SIZE,  \
+						(MT_DEVICE | MT_RW |	    \
+						 MT_SECURE | MT_USER))
+
+/* Map the NOR2 Flash to access from S-EL0 */
+#define CSS_NOR2_FLASH_DEVICE_BASE	(0x10000000)
+#define CSS_NOR2_FLASH_DEVICE_SIZE	(0x04000000)
+#define PLAT_ARM_SECURE_MAP_NOR2	MAP_REGION_FLAT(                    \
+						CSS_NOR2_FLASH_DEVICE_BASE, \
+						CSS_NOR2_FLASH_DEVICE_SIZE, \
+						(MT_DEVICE | MT_RW |	    \
+						 MT_SECURE | MT_USER))
+
 #endif /* SGI_SOC_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
index cb747c3..20dd682 100644
--- a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
+++ b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,4 +10,22 @@
 #include <sgi_base_platform_def.h>
 #include <sgi_soc_css_def_v2.h>
 
+/* Map the System registers to access from S-EL0 */
+#define CSS_SYSTEMREG_DEVICE_BASE	(0x0C010000)
+#define CSS_SYSTEMREG_DEVICE_SIZE	(0x00010000)
+#define PLAT_ARM_SECURE_MAP_SYSTEMREG	MAP_REGION_FLAT(                    \
+						CSS_SYSTEMREG_DEVICE_BASE,  \
+						CSS_SYSTEMREG_DEVICE_SIZE,  \
+						(MT_DEVICE | MT_RW |	    \
+						 MT_SECURE | MT_USER))
+
+/* Map the NOR2 Flash to access from S-EL0 */
+#define CSS_NOR2_FLASH_DEVICE_BASE	(0x001054000000)
+#define CSS_NOR2_FLASH_DEVICE_SIZE	(0x000004000000)
+#define PLAT_ARM_SECURE_MAP_NOR2	MAP_REGION_FLAT(                    \
+						CSS_NOR2_FLASH_DEVICE_BASE, \
+						CSS_NOR2_FLASH_DEVICE_SIZE, \
+						(MT_DEVICE | MT_RW |	    \
+						 MT_SECURE | MT_USER))
+
 #endif /* SGI_SOC_PLATFORM_DEF_V2_H */
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 39eb89e..20c52e9 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -49,6 +49,15 @@
 	CSS_SGI_MAP_DEVICE,
 	SOC_CSS_MAP_DEVICE,
 	ARM_MAP_NS_DRAM1,
+#if CSS_SGI_CHIP_COUNT > 1
+	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
+#endif
+#if CSS_SGI_CHIP_COUNT > 2
+	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2),
+#endif
+#if CSS_SGI_CHIP_COUNT > 3
+	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3),
+#endif
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
 #endif
@@ -78,10 +87,14 @@
 
 #if SPM_MM && defined(IMAGE_BL31)
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
+	PLAT_ARM_SECURE_MAP_SYSTEMREG,
+	PLAT_ARM_SECURE_MAP_NOR2,
 	PLAT_ARM_SECURE_MAP_DEVICE,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
-	ARM_SP_CPER_BUF_MMAP,
+#if RAS_EXTENSION
+	CSS_SGI_SP_CPER_BUF_MMAP,
+#endif
 	ARM_SP_IMAGE_RW_MMAP,
 	ARM_SPM_BUF_EL0_MMAP,
 	{0}
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
index a770255..131cdf2 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,10 @@
 #include <plat/common/platform.h>
 #include <drivers/arm/sbsa.h>
 
+#if SPM_MM
+#include <services/spm_mm_partition.h>
+#endif
+
 /*
  * Table of regions for different BL stages to map using the MMU.
  */
@@ -41,6 +45,9 @@
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
 #endif
+#if SPM_MM
+	ARM_SP_IMAGE_MMAP,
+#endif
 #if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
 	ARM_MAP_BL1_RW,
 #endif
@@ -57,13 +64,86 @@
 	CSS_SGI_MAP_DEVICE,
 	SOC_PLATFORM_PERIPH_MAP_DEVICE,
 	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+#if SPM_MM
+	ARM_SPM_BUF_EL3_MMAP,
+#endif
 	{0}
 };
 
+#if SPM_MM && defined(IMAGE_BL31)
+const mmap_region_t plat_arm_secure_partition_mmap[] = {
+	PLAT_ARM_SECURE_MAP_SYSTEMREG,
+	PLAT_ARM_SECURE_MAP_NOR2,
+	SOC_PLATFORM_PERIPH_MAP_DEVICE_USER,
+	ARM_SP_IMAGE_MMAP,
+	ARM_SP_IMAGE_NS_BUF_MMAP,
+	ARM_SP_IMAGE_RW_MMAP,
+	ARM_SPM_BUF_EL0_MMAP,
+	{0}
+};
+#endif /* SPM_MM && defined(IMAGE_BL31) */
 #endif
 
 ARM_CASSERT_MMAP
 
+#if SPM_MM && defined(IMAGE_BL31)
+/*
+ * Boot information passed to a secure partition during initialisation. Linear
+ * indices in MP information will be filled at runtime.
+ */
+static spm_mm_mp_info_t sp_mp_info[] = {
+	[0] = {0x81000000, 0},
+	[1] = {0x81010000, 0},
+	[2] = {0x81020000, 0},
+	[3] = {0x81030000, 0},
+	[4] = {0x81040000, 0},
+	[5] = {0x81050000, 0},
+	[6] = {0x81060000, 0},
+	[7] = {0x81070000, 0},
+	[8] = {0x81080000, 0},
+	[9] = {0x81090000, 0},
+	[10] = {0x810a0000, 0},
+	[11] = {0x810b0000, 0},
+	[12] = {0x810c0000, 0},
+	[13] = {0x810d0000, 0},
+	[14] = {0x810e0000, 0},
+	[15] = {0x810f0000, 0},
+};
+
+const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
+	.h.type              = PARAM_SP_IMAGE_BOOT_INFO,
+	.h.version           = VERSION_1,
+	.h.size              = sizeof(spm_mm_boot_info_t),
+	.h.attr              = 0,
+	.sp_mem_base         = ARM_SP_IMAGE_BASE,
+	.sp_mem_limit        = ARM_SP_IMAGE_LIMIT,
+	.sp_image_base       = ARM_SP_IMAGE_BASE,
+	.sp_stack_base       = PLAT_SP_IMAGE_STACK_BASE,
+	.sp_heap_base        = ARM_SP_IMAGE_HEAP_BASE,
+	.sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
+	.sp_shared_buf_base  = PLAT_SPM_BUF_BASE,
+	.sp_image_size       = ARM_SP_IMAGE_SIZE,
+	.sp_pcpu_stack_size  = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+	.sp_heap_size        = ARM_SP_IMAGE_HEAP_SIZE,
+	.sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
+	.sp_shared_buf_size  = PLAT_SPM_BUF_SIZE,
+	.num_sp_mem_regions  = ARM_SP_IMAGE_NUM_MEM_REGIONS,
+	.num_cpus            = PLATFORM_CORE_COUNT,
+	.mp_info             = &sp_mp_info[0],
+};
+
+const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
+{
+	return plat_arm_secure_partition_mmap;
+}
+
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
+		void *cookie)
+{
+	return &plat_arm_secure_partition_boot_info;
+}
+#endif /* SPM_MM && defined(IMAGE_BL31) */
+
 #if TRUSTED_BOARD_BOOT
 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
 {
diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk
index 3069f91..2945749 100644
--- a/plat/brcm/board/common/board_common.mk
+++ b/plat/brcm/board/common/board_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015 - 2020, Broadcom
+# Copyright (c) 2015 - 2021, Broadcom
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -36,6 +36,10 @@
 DRIVER_SPI_ENABLE := 0
 endif
 
+ifeq (${DRIVER_I2C_ENABLE},)
+DRIVER_I2C_ENABLE := 0
+endif
+
 # By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set
 ifeq (${BRCM_DISABLE_TRUSTED_WDOG},)
 BRCM_DISABLE_TRUSTED_WDOG	:=	0
@@ -181,6 +185,12 @@
 				drivers/brcm/spi_flash.c
 endif
 
+ifeq (${DRIVER_I2C_ENABLE},1)
+$(eval $(call add_define,DRIVER_I2C_ENABLE))
+BL2_SOURCES		+= 	drivers/brcm/i2c/i2c.c
+PLAT_INCLUDES		+=	-Iinclude/drivers/brcm/i2c
+endif
+
 ifeq (${DRIVER_OCOTP_ENABLE},1)
 $(eval $(call add_define,DRIVER_OCOTP_ENABLE))
 BL2_SOURCES		+= drivers/brcm/ocotp.c
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_image_load.c b/plat/imx/imx8m/imx8mm/imx8mm_image_load.c
new file mode 100644
index 0000000..3a03069
--- /dev/null
+++ b/plat/imx/imx8m/imx8mm/imx8mm_image_load.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+
+#include <platform_def.h>
+#include <plat/common/platform.h>
+
+void plat_flush_next_bl_params(void)
+{
+	flush_bl_params_desc();
+}
+
+bl_load_info_t *plat_get_bl_image_load_info(void)
+{
+	return get_bl_load_info_from_mem_params_desc();
+}
+
+bl_params_t *plat_get_next_bl_params(void)
+{
+	return get_next_bl_params_from_mem_params_desc();
+}
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_io_storage.c b/plat/imx/imx8m/imx8mm/imx8mm_io_storage.c
new file mode 100644
index 0000000..ff6687e
--- /dev/null
+++ b/plat/imx/imx8m/imx8mm/imx8mm_io_storage.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <drivers/io/io_block.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_fip.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_memmap.h>
+#include <drivers/mmc.h>
+#include <lib/utils_def.h>
+#include <tbbr_img_def.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <platform_def.h>
+
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_handle;
+
+#ifndef IMX8MM_FIP_MMAP
+static const io_dev_connector_t *mmc_dev_con;
+static uintptr_t mmc_dev_handle;
+
+static const io_block_spec_t mmc_fip_spec = {
+	.offset = IMX8MM_FIP_MMC_BASE,
+	.length = IMX8MM_FIP_SIZE
+};
+
+static const io_block_dev_spec_t mmc_dev_spec = {
+	/* It's used as temp buffer in block driver. */
+	.buffer		= {
+		.offset	= IMX8MM_FIP_BASE,
+		/* do we need a new value? */
+		.length = IMX8MM_FIP_SIZE
+	},
+	.ops		= {
+		.read	= mmc_read_blocks,
+		.write	= mmc_write_blocks,
+	},
+	.block_size	= MMC_BLOCK_SIZE,
+};
+
+static int open_mmc(const uintptr_t spec);
+
+#else
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fip_block_spec = {
+	.offset = IMX8MM_FIP_BASE,
+	.length = IMX8MM_FIP_SIZE
+};
+static int open_memmap(const uintptr_t spec);
+#endif
+
+static int open_fip(const uintptr_t spec);
+
+static const io_uuid_spec_t bl31_uuid_spec = {
+	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+};
+
+static const io_uuid_spec_t bl32_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32,
+};
+
+static const io_uuid_spec_t bl32_extra1_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
+};
+
+static const io_uuid_spec_t bl32_extra2_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
+};
+
+static const io_uuid_spec_t bl33_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
+};
+
+static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
+	.uuid = UUID_SOC_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t soc_fw_content_cert_uuid_spec = {
+	.uuid = UUID_SOC_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
+struct plat_io_policy {
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+#ifndef IMX8MM_FIP_MMAP
+	[FIP_IMAGE_ID] = {
+		&mmc_dev_handle,
+		(uintptr_t)&mmc_fip_spec,
+		open_mmc
+	},
+#else
+	[FIP_IMAGE_ID] = {
+		&memmap_dev_handle,
+		(uintptr_t)&fip_block_spec,
+		open_memmap
+	},
+#endif
+	[BL31_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl31_uuid_spec,
+		open_fip
+	},
+	[BL32_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_uuid_spec,
+		open_fip
+	},
+	[BL32_EXTRA1_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_extra1_uuid_spec,
+		open_fip
+	},
+	[BL32_EXTRA2_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_extra2_uuid_spec,
+		open_fip
+	},
+	[BL33_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl33_uuid_spec,
+		open_fip
+	},
+#if TRUSTED_BOARD_BOOT
+	[TRUSTED_BOOT_FW_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&tb_fw_cert_uuid_spec,
+		open_fip
+	},
+	[SOC_FW_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&soc_fw_key_cert_uuid_spec,
+		open_fip
+	},
+	[TRUSTED_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&trusted_key_cert_uuid_spec,
+		open_fip
+	},
+	[TRUSTED_OS_FW_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&tos_fw_key_cert_uuid_spec,
+		open_fip
+	},
+	[NON_TRUSTED_FW_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&nt_fw_key_cert_uuid_spec,
+		open_fip
+	},
+	[SOC_FW_CONTENT_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&soc_fw_content_cert_uuid_spec,
+		open_fip
+	},
+	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&tos_fw_cert_uuid_spec,
+		open_fip
+	},
+	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&nt_fw_cert_uuid_spec,
+		open_fip
+	},
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+static int open_fip(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_image_handle;
+
+	/* See if a Firmware Image Package is available */
+	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+	if (result == 0) {
+		result = io_open(fip_dev_handle, spec, &local_image_handle);
+		if (result == 0) {
+			VERBOSE("Using FIP\n");
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+#ifndef IMX8MM_FIP_MMAP
+static int open_mmc(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_handle;
+
+	result = io_dev_init(mmc_dev_handle, (uintptr_t)NULL);
+	if (result == 0) {
+		result = io_open(mmc_dev_handle, spec, &local_handle);
+		if (result == 0) {
+			io_close(local_handle);
+		}
+	}
+	return result;
+}
+#else
+static int open_memmap(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_image_handle;
+
+	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
+	if (result == 0) {
+		result = io_open(memmap_dev_handle, spec, &local_image_handle);
+		if (result == 0) {
+			VERBOSE("Using Memmap\n");
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+#endif
+
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	int result;
+	const struct plat_io_policy *policy;
+
+	assert(image_id < ARRAY_SIZE(policies));
+
+	policy = &policies[image_id];
+	result = policy->check(policy->image_spec);
+	assert(result == 0);
+
+	*image_spec = policy->image_spec;
+	*dev_handle = *policy->dev_handle;
+
+	return result;
+}
+
+void plat_imx8mm_io_setup(void)
+{
+	int result __unused;
+
+#ifndef IMX8MM_FIP_MMAP
+	result = register_io_dev_block(&mmc_dev_con);
+	assert(result == 0);
+
+	result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_dev_spec,
+			     &mmc_dev_handle);
+	assert(result == 0);
+
+#else
+	result = register_io_dev_memmap(&memmap_dev_con);
+	assert(result == 0);
+
+	result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
+			     &memmap_dev_handle);
+	assert(result == 0);
+#endif
+
+	result = register_io_dev_fip(&fip_dev_con);
+	assert(result == 0);
+
+	result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+			     &fip_dev_handle);
+	assert(result == 0);
+}
diff --git a/plat/imx/imx8m/imx8mm/include/imx8mm_private.h b/plat/imx/imx8m/imx8mm/include/imx8mm_private.h
new file mode 100644
index 0000000..52d13f0
--- /dev/null
+++ b/plat/imx/imx8m/imx8mm/include/imx8mm_private.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8MM_PRIVATE_H
+#define IMX8MM_PRIVATE_H
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void plat_imx8mm_io_setup(void);
+
+#endif /* IMX8MM_PRIVATE_H */
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 1041459..ec915ad 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -1,9 +1,11 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/tbbr/tbbr_img_def.h>
+
 #define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
 #define PLATFORM_LINKER_ARCH		aarch64
 
@@ -34,11 +36,27 @@
 #define PLAT_SDEI_NORMAL_PRI		0x20
 #define PLAT_SDEI_SGI_PRIVATE		U(9)
 
+#if defined(NEED_BL2)
+#define BL2_BASE			U(0x920000)
+#define BL2_LIMIT			U(0x940000)
+#define BL31_BASE			U(0x900000)
+#define BL31_LIMIT			U(0x920000)
+#define IMX8MM_FIP_BASE			U(0x40310000)
+#define IMX8MM_FIP_SIZE			U(0x000200000)
+#define IMX8MM_FIP_LIMIT		U(FIP_BASE + FIP_SIZE)
+
+/* Define FIP image location on eMMC */
+#define IMX8MM_FIP_MMC_BASE		U(0x100000)
+
+#define PLAT_IMX8MM_BOOT_MMC_BASE	U(0x30B50000) /* SD */
+#else
 #define BL31_BASE			U(0x920000)
 #define BL31_LIMIT			U(0x940000)
+#endif
 
 /* non-secure uboot base */
 #define PLAT_NS_IMAGE_OFFSET		U(0x40200000)
+#define PLAT_NS_IMAGE_SIZE		U(0x00100000)
 
 /* GICv3 base address */
 #define PLAT_GICD_BASE			U(0x38800000)
@@ -127,3 +145,7 @@
 #define COUNTER_FREQUENCY		8000000 /* 8MHz */
 
 #define IMX_WDOG_B_RESET
+
+#define MAX_IO_HANDLES			3U
+#define MAX_IO_DEVICES			2U
+#define MAX_IO_BLOCK_DEVICES		1U
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index b639fcb..9b8c3ea 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,7 +45,7 @@
 {
 	switch (id & INT_ID_MASK) {
 	case STM32MP1_IRQ_TZC400:
-		ERROR("STM32MP1_IRQ_TZC400 generated\n");
+		(void)tzc400_it_handler();
 		panic();
 		break;
 	case STM32MP1_IRQ_AXIERRIRQ:
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index ee04a23..f4aeab5 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -381,7 +381,8 @@
 #define STM32MP1_TZC_ETH_ID		U(10)
 #define STM32MP1_TZC_DAP_ID		U(15)
 
-#define STM32MP1_FILTER_BIT_ALL		U(3)
+#define STM32MP1_FILTER_BIT_ALL		(TZC_400_REGION_ATTR_FILTER_BIT(0) | \
+					 TZC_400_REGION_ATTR_FILTER_BIT(1))
 
 /*******************************************************************************
  * STM32MP1 SDMMC
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
index 3a29ba9..195b3a5 100644
--- a/plat/st/stm32mp1/stm32mp1_security.c
+++ b/plat/st/stm32mp1/stm32mp1_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -75,8 +75,7 @@
 				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);
+	tzc400_set_action(TZC_ACTION_INT);
 
 	tzc400_enable_filters();
 }