Merge "fix(qti): adding secure rm flag" into integration
diff --git a/Makefile b/Makefile
index afa417b..65955b2 100644
--- a/Makefile
+++ b/Makefile
@@ -842,6 +842,12 @@
     $(info DRTM_SUPPORT is an experimental feature)
 endif
 
+ifeq (${ENABLE_RME},1)
+    ifneq (${SEPARATE_CODE_AND_RODATA},1)
+        $(error `ENABLE_RME=1` requires `SEPARATE_CODE_AND_RODATA=1`)
+    endif
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -1051,7 +1057,7 @@
         ENCRYPT_BL31 \
         ENCRYPT_BL32 \
         ERRATA_SPECULATIVE_AT \
-        RAS_TRAP_LOWER_EL_ERR_ACCESS \
+        RAS_TRAP_NS_ERR_REC_ACCESS \
         COT_DESC_IN_DTB \
         USE_SP804_TIMER \
         PSA_FWU_SUPPORT \
@@ -1191,7 +1197,7 @@
         BL2_INV_DCACHE \
         USE_SPINLOCK_CAS \
         ERRATA_SPECULATIVE_AT \
-        RAS_TRAP_LOWER_EL_ERR_ACCESS \
+        RAS_TRAP_NS_ERR_REC_ACCESS \
         COT_DESC_IN_DTB \
         USE_SP804_TIMER \
         ENABLE_FEAT_RNG \
diff --git a/bl1/aarch32/bl1_entrypoint.S b/bl1/aarch32/bl1_entrypoint.S
index 94dfd37..b22015e 100644
--- a/bl1/aarch32/bl1_entrypoint.S
+++ b/bl1/aarch32/bl1_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,8 +23,8 @@
 	b	bl1_entrypoint
 	b	report_exception	/* Undef */
 	b	bl1_aarch32_smc_handler	/* SMC call */
-	b	report_exception	/* Prefetch abort */
-	b	report_exception	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	report_exception	/* Reserved */
 	b	report_exception	/* IRQ */
 	b	report_exception	/* FIQ */
diff --git a/bl2/aarch32/bl2_el3_exceptions.S b/bl2/aarch32/bl2_el3_exceptions.S
index 087b665..eaa2582 100644
--- a/bl2/aarch32/bl2_el3_exceptions.S
+++ b/bl2/aarch32/bl2_el3_exceptions.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,8 +14,8 @@
 	b	bl2_entrypoint
 	b	report_exception	/* Undef */
 	b	report_exception	/* SVC call */
-	b	report_exception	/* Prefetch abort */
-	b	report_exception	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	report_exception	/* Reserved */
 	b	report_exception	/* IRQ */
 	b	report_exception	/* FIQ */
diff --git a/bl2/aarch32/bl2_entrypoint.S b/bl2/aarch32/bl2_entrypoint.S
index 6e8e2c1..678d9c2 100644
--- a/bl2/aarch32/bl2_entrypoint.S
+++ b/bl2/aarch32/bl2_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,8 +16,8 @@
 	b	bl2_entrypoint
 	b	report_exception	/* Undef */
 	b	report_exception	/* SVC call */
-	b	report_exception	/* Prefetch abort */
-	b	report_exception	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	report_exception	/* Reserved */
 	b	report_exception	/* IRQ */
 	b	report_exception	/* FIQ */
diff --git a/bl2u/aarch32/bl2u_entrypoint.S b/bl2u/aarch32/bl2u_entrypoint.S
index e4dd03d..1063789 100644
--- a/bl2u/aarch32/bl2u_entrypoint.S
+++ b/bl2u/aarch32/bl2u_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,8 +16,8 @@
 	b	bl2u_entrypoint
 	b	report_exception	/* Undef */
 	b	report_exception	/* SVC call */
-	b	report_exception	/* Prefetch abort */
-	b	report_exception	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	report_exception	/* Reserved */
 	b	report_exception	/* IRQ */
 	b	report_exception	/* FIQ */
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index 39f1065..f102967 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -51,8 +51,8 @@
 	b	sp_min_entrypoint
 	b	plat_panic_handler	/* Undef */
 	b	sp_min_handle_smc	/* Syscall */
-	b	plat_panic_handler	/* Prefetch abort */
-	b	plat_panic_handler	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	plat_panic_handler	/* Reserved */
 	b	plat_panic_handler	/* IRQ */
 	b	sp_min_handle_fiq	/* FIQ */
diff --git a/changelog.yaml b/changelog.yaml
index d3e235d..ad1ac25 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -31,7 +31,7 @@
     type: ci
     hidden: true
 
-  - title: Build System
+  - title: Documentation
     description: Documentation-only changes
     type: docs
     hidden: true
@@ -649,6 +649,9 @@
       - title: Context Management
         scope: context mgmt
 
+      - title: Semihosting
+        scope: semihosting
+
   - title: Drivers
 
     subsections:
diff --git a/common/aarch32/debug.S b/common/aarch32/debug.S
index 9d410df..ae0bb7a 100644
--- a/common/aarch32/debug.S
+++ b/common/aarch32/debug.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,8 @@
 	.globl	asm_assert
 	.globl	do_panic
 	.globl	report_exception
+	.globl	report_prefetch_abort
+	.globl	report_data_abort
 
 /* Since the max decimal input number is 65536 */
 #define MAX_DEC_DIVISOR		10000
@@ -205,3 +207,33 @@
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
 endfunc report_exception
+
+	/***********************************************************
+	 * This function is called from the vector table for
+	 * unhandled exceptions. The lr_abt is given as an
+	 * argument to platform handler.
+	 ***********************************************************/
+func report_prefetch_abort
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+	b	report_exception
+#else
+	mrs	r0, lr_abt
+	bl	plat_report_prefetch_abort
+	no_ret	plat_panic_handler
+#endif
+endfunc report_prefetch_abort
+
+	/***********************************************************
+	 * This function is called from the vector table for
+	 * unhandled exceptions. The lr_abt is given as an
+	 * argument to platform handler.
+	 ***********************************************************/
+func report_data_abort
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+	b	report_exception
+#else
+	mrs	r0, lr_abt
+	bl	plat_report_data_abort
+	no_ret	plat_panic_handler
+#endif
+endfunc report_data_abort
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 1f2c310..9ce6ff2 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -470,10 +470,8 @@
 
 Arm Total Compute platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
-:|G|: `arugan02`_
-:|M|: Usama Arif <usama.arif@arm.com>
-:|G|: `uarif1`_
+:|M|: Anders Dellien <anders.dellien@arm.com>
+:|G|: `andersdellien-arm`_
 :|F|: plat/arm/board/tc
 
 HiSilicon HiKey and HiKey960 platform ports
@@ -836,6 +834,7 @@
 :|F|: tools/conventional-changelog-tf-a
 
 .. _AlexeiFedorov: https://github.com/AlexeiFedorov
+.. _andersdellien-arm: https://github.com/andersdellien-arm
 .. _Andre-ARM: https://github.com/Andre-ARM
 .. _Anson-Huang: https://github.com/Anson-Huang
 .. _bijucdas: https://github.com/bijucdas
diff --git a/docs/components/firmware-update.rst b/docs/components/firmware-update.rst
index a591565..1ba1e1c 100644
--- a/docs/components/firmware-update.rst
+++ b/docs/components/firmware-update.rst
@@ -1,22 +1,118 @@
 Firmware Update (FWU)
 =====================
 
+This document describes the design of the various Firmware Update (FWU)
+mechanisms available in TF-A.
+
+1. PSA Firmware Update (PSA FWU)
+2. TBBR Firmware Update (TBBR FWU)
+
+PSA Firmware Update implements the specification of the same name (Arm document
+IHI 0093), which defines a standard firmware interface for installing firmware
+updates.
+On the other hand, TBBR Firmware Update only covers firmware recovery. Arguably,
+its name is somewhat misleading but the TBBR specification and terminology
+predates PSA FWU. Both mechanisms are complementary in the sense that PSA FWU
+assumes that the device has a backup or recovery capability in the event of a
+failed update, which can be fulfilled with TBBR FWU implementation.
+
+.. _PSA Firmware Update:
+
+PSA Firmware Update (PSA FWU)
+-----------------------------
+
 Introduction
-------------
+~~~~~~~~~~~~
+The `PSA FW update specification`_ defines the concepts of ``Firmware Update
+Client`` and ``Firmware Update Agent``.
+The new firmware images are provided by the ``Client`` to the ``Update Agent``
+to flash them in non-volatile storage.
+
+A common system design will place the ``Update Agent`` in the Secure-world
+while the ``Client`` executes in the Normal-world.
+The `PSA FW update specification`_ provides ABIs meant for a Normal-world
+entity aka ``Client`` to transmit the firmware images to the ``Update Agent``.
+
+Scope
+~~~~~
+The design of the ``Client`` and ``Update Agent`` is out of scope of this
+document.
+This document mainly covers ``Platform Boot`` details i.e. the role of
+the second stage Bootloader after FWU has been done by ``Client`` and
+``Update Agent``.
+
+Overview
+~~~~~~~~
+
+There are active and update banks in the non-volatile storage identified
+by the ``active_index`` and the ``update_index`` respectively.
+An active bank stores running firmware, whereas an update bank contains
+firmware updates.
+
+Once Firmwares are updated in the update bank of the non-volatile
+storage, then ``Update Agent`` marks the update bank as the active bank,
+and write updated FWU metadata in non-volatile storage.
+On subsequent reboot, the second stage Bootloader (BL2) performs the
+following actions:
+
+-  Read FWU metadata in memory
+-  Retrieve the image specification (offset and length) of updated images
+   present in non-volatile storage with the help of FWU metadata
+-  Set these image specification in the corresponding I/O policies of the
+   updated images using the FWU platform functions
+   ``plat_fwu_set_images_source()`` and ``plat_fwu_set_metadata_image_source()``,
+   please refer :ref:`Porting Guide`
+-  Use these I/O policies to read the images from this address into the memory
+
+By default, the platform uses the active bank of non-volatile storage to boot
+the images in ``trial state``. If images pass through the authentication check
+and also if the system successfully booted the Normal-world image then
+``Update Agent`` marks this update as accepted after further sanitisation
+checking at Normal-world.
+
+The second stage Bootloader (BL2) avoids upgrading the platform NV-counter until
+it's been confirmed that given update is accepted.
 
-This document describes the design of the Firmware Update (FWU) feature, which
-enables authenticated firmware to update firmware images from external
-interfaces such as USB, UART, SD-eMMC, NAND, NOR or Ethernet to SoC Non-Volatile
-memories such as NAND Flash, LPDDR2-NVM or any memory determined by the
-platform. This feature functions even when the current firmware in the system
-is corrupt or missing; it therefore may be used as a recovery mode. It may also
-be complemented by other, higher level firmware update software.
+The following sequence diagram shows platform-boot flow:
+
+.. image:: ../resources/diagrams/PSA-FWU.png
+
+If the platform fails to boot from active bank due to any reasons such
+as authentication failure or non-fuctionality of Normal-world software then the
+watchdog will reset to give a chance to the platform to fix the issue. This
+boot failure & reset sequence might be repeated up to ``trial state`` times.
+After that, the platform can decide to boot from the ``previous_active_index``
+bank.
+
+If the images still does not boot successfully from the ``previous_active_index``
+bank (e.g. due to ageing effect of non-volatile storage) then the platform can
+choose firmware recovery mechanism :ref:`TBBR Firmware Update` to bring system
+back to life.
+
+.. _TBBR Firmware Update:
+
+TBBR Firmware Update (TBBR FWU)
+-------------------------------
+
+Introduction
+~~~~~~~~~~~~
+
+This technique enables authenticated firmware to update firmware images from
+external interfaces such as USB, UART, SD-eMMC, NAND, NOR or Ethernet to SoC
+Non-Volatile memories such as NAND Flash, LPDDR2-NVM or any memory determined
+by the platform.
+This feature functions even when the current firmware in the system is corrupt
+or missing; it therefore may be used as a recovery mode. It may also be
+complemented by other, higher level firmware update software.
 
 FWU implements a specific part of the Trusted Board Boot Requirements (TBBR)
 specification, Arm DEN0006C-1. It should be used in conjunction with the
 :ref:`Trusted Board Boot` design document, which describes the image
 authentication parts of the Trusted Firmware-A (TF-A) TBBR implementation.
 
+It can be used as a last resort when all firmware updates that are carried out
+as part of the :ref:`PSA Firmware Update` procedure have failed to function.
+
 Scope
 ~~~~~
 
@@ -25,8 +121,8 @@
 FWU images, please refer to the "Non-Trusted Firmware Updater" requirements in
 the TBBR.
 
-FWU Overview
-------------
+Overview
+~~~~~~~~
 
 The FWU boot flow is primarily mediated by BL1. Since BL1 executes in ROM, and
 it is usually desirable to minimize the amount of ROM code, the design allows
@@ -66,7 +162,7 @@
 |Flow Diagram|
 
 Image Identification
---------------------
+~~~~~~~~~~~~~~~~~~~~
 
 Each FWU image and certificate is identified by a unique ID, defined by the
 platform, which BL1 uses to fetch an image descriptor (``image_desc_t``) via a
@@ -93,7 +189,7 @@
 -  Initialize the execution state of the next FWU image.
 
 FWU State Machine
------------------
+~~~~~~~~~~~~~~~~~
 
 BL1 maintains state for each FWU image during FWU execution. FWU images at lower
 Exception Levels raise SMCs to invoke FWU functionality in BL1, which causes
@@ -126,10 +222,10 @@
    requested BL1 to resume normal world execution.
 
 BL1 SMC Interface
------------------
+~~~~~~~~~~~~~~~~~
 
 BL1_SMC_CALL_COUNT
-~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -142,7 +238,7 @@
 This SMC returns the number of SMCs supported by BL1.
 
 BL1_SMC_UID
-~~~~~~~~~~~
+^^^^^^^^^^^
 
 ::
 
@@ -156,7 +252,7 @@
 BL1 SMC service.
 
 BL1_SMC_VERSION
-~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^
 
 ::
 
@@ -170,7 +266,7 @@
 This SMC returns the current version of the BL1 SMC service.
 
 BL1_SMC_RUN_IMAGE
-~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -190,7 +286,7 @@
 this SMC for BL1 to pass execution control to BL31.
 
 FWU_SMC_IMAGE_COPY
-~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -239,7 +335,7 @@
 Once the SMC is handled, BL1 returns from exception to the normal world caller.
 
 FWU_SMC_IMAGE_AUTH
-~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -279,7 +375,7 @@
 the -EAUTH error and sets the image state back to RESET.
 
 FWU_SMC_IMAGE_EXECUTE
-~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -307,7 +403,7 @@
 EXECUTED, and returns from exception to the secure image.
 
 FWU_SMC_IMAGE_RESUME
-~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -334,7 +430,7 @@
 returned to the caller.
 
 FWU_SMC_SEC_IMAGE_DONE
-~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -355,7 +451,7 @@
 world.
 
 FWU_SMC_UPDATE_DONE
-~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -371,7 +467,7 @@
 a ``void *``. The SMC does not return.
 
 FWU_SMC_IMAGE_RESET
-~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -393,8 +489,9 @@
 
 --------------
 
-*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.*
 
 .. _Universally Unique Identifier: https://tools.ietf.org/rfc/rfc4122.txt
 .. |Flow Diagram| image:: ../resources/diagrams/fwu_flow.png
 .. |FWU state machine| image:: ../resources/diagrams/fwu_states.png
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
diff --git a/docs/components/ras.rst b/docs/components/ras.rst
index 02207d8..b435349 100644
--- a/docs/components/ras.rst
+++ b/docs/components/ras.rst
@@ -30,8 +30,8 @@
 
 The build option ``RAS_EXTENSION`` when set to ``1`` includes the RAS in run
 time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST`` must also
-be set ``1``. ``RAS_TRAP_LOWER_EL_ERR_ACCESS`` controls the access to the RAS
-error record registers from lower ELs.
+be set ``1``. ``RAS_TRAP_NS_ERR_REC_ACCESS`` controls the access to the RAS
+error record registers from Non-secure.
 
 .. _ras-figure:
 
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index b767958..8070ff4 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -494,8 +494,11 @@
    #. General purpose registers (x0-x30) and ``sp_el0``, ``sp_el2`` stack pointers
    #. EL2 system register context for all enabled features by EL3. These include system registers with the ``_EL2`` prefix. The EL2 physical and virtual timer registers must not be included in this.
 
-It is the responsibility of EL3 that the above registers will not be leaked to
-the NS Host and to maintain the confidentiality of the Realm World.
+As part of SMC forwarding between the NS world and Realm world, EL3 allows x0-x7 to be passed
+as arguments to Realm and x0-x4 to be used for return arguments back to Non Secure.
+As per SMCCCv1.2, x4 must be preserved if not being used as return argument by the SMC function
+and it is the responsibility of RMM to preserve this or use this as a return argument.
+EL3 will always copy x0-x4 from Realm context to NS Context.
 
 EL3 will not save some registers as mentioned in the below list. It is the
 responsibility of RMM to ensure that these are appropriately saved if the
@@ -506,6 +509,9 @@
    #. SME registers
    #. EL1/0 registers
 
+It is the responsibility of EL3 that any other registers other than the ones mentioned above
+will not be leaked to the NS Host and to maintain the confidentiality of the Realm World.
+
 SMCCC v1.3 allows NS world to specify whether SVE context is in use. In this
 case, RMM could choose to not save the incoming SVE context but must ensure
 to clear SVE registers if they have been used in Realm World. The same applies
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index cca76c6..5980050 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -987,7 +987,7 @@
       implement this workaround due to the behaviour of the errata mentioned
       in new SDEN document which will get published soon.
 
-- ``RAS_TRAP_LOWER_EL_ERR_ACCESS``: This flag enables/disables the SCR_EL3.TERR
+- ``RAS_TRAP_NS_ERR_REC_ACCESS``: This flag enables/disables the SCR_EL3.TERR
   bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs.
   This flag is disabled by default.
 
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index 7ae98b1..fff86a8 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -144,8 +144,12 @@
 
 - | ``DTB_FILE_NAME``: to precise board device-tree blob to be used.
   | Default: stm32mp157c-ev1.dtb
+- | ``DWL_BUFFER_BASE``: the 'serial boot' load address of FIP,
+  | default location (end of the first 128MB) is used when absent
 - | ``STM32MP_EARLY_CONSOLE``: to enable early traces before clock driver is setup.
   | Default: 0 (disabled)
+- | ``STM32MP_RECONFIGURE_CONSOLE``: to re-configure crash console (especially after BL2).
+  | Default: 0 (disabled)
 - | ``STM32MP_UART_BAUDRATE``: to select UART baud rate.
   | Default: 115200
 - | ``STM32_TF_VERSION``: to manage BL2 monotonic counter.
diff --git a/docs/resources/diagrams/Makefile b/docs/resources/diagrams/Makefile
index 4e65569..c951754 100644
--- a/docs/resources/diagrams/Makefile
+++ b/docs/resources/diagrams/Makefile
@@ -73,7 +73,13 @@
 rmm_el3_manifest_struct_layers		= "Background"
 rmm_el3_manifest_struct_opts		=
 
-all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG)
+PSA_FWU_DIA				= PSA-FWU.dia
+PSA_FWU_PNG				= PSA-FWU.png
+
+FWU-update_struct_layers		= "background"
+FWU-update_struct_opts			=
+
+all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG) $(PSA_FWU_PNG)
 
 $(RESET_PNGS):$(RESET_DIA)
 	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
@@ -90,3 +96,6 @@
 
 $(RMM_EL3_MANIFEST_PNG):$(RMM_EL3_MANIFEST_DIA)
 	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
+
+$(PSA_FWU_PNG):$(PSA_FWU_DIA)
+	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
diff --git a/docs/resources/diagrams/PSA-FWU.dia b/docs/resources/diagrams/PSA-FWU.dia
new file mode 100644
index 0000000..aac5276
--- /dev/null
+++ b/docs/resources/diagrams/PSA-FWU.dia
Binary files differ
diff --git a/docs/resources/diagrams/PSA-FWU.png b/docs/resources/diagrams/PSA-FWU.png
new file mode 100644
index 0000000..d58ba86
--- /dev/null
+++ b/docs/resources/diagrams/PSA-FWU.png
Binary files differ
diff --git a/docs/security_advisories/security-advisory-tfv-9.rst b/docs/security_advisories/security-advisory-tfv-9.rst
index a7b5984..a4db17d 100644
--- a/docs/security_advisories/security-advisory-tfv-9.rst
+++ b/docs/security_advisories/security-advisory-tfv-9.rst
@@ -85,7 +85,7 @@
 +----------------------+
 | Neoverse-V1          |
 +----------------------+
-| Neoverse-Demeter     |
+| Neoverse-V2          |
 +----------------------+
 | Neoverse-Poseidon    |
 +----------------------+
diff --git a/drivers/amlogic/crypto/sha_dma.c b/drivers/amlogic/crypto/sha_dma.c
index fceb1c0..5c16d49 100644
--- a/drivers/amlogic/crypto/sha_dma.c
+++ b/drivers/amlogic/crypto/sha_dma.c
@@ -8,6 +8,7 @@
 #include <assert.h>
 #include <crypto/sha_dma.h>
 #include <lib/mmio.h>
+#include <platform_def.h>
 
 #include "aml_private.h"
 
diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c
index 75eb69a..83ef32f 100644
--- a/drivers/arm/gic/v3/gic-x00.c
+++ b/drivers/arm/gic/v3/gic-x00.c
@@ -16,6 +16,7 @@
 #include <assert.h>
 
 #include <arch_helpers.h>
+#include <common/debug.h>
 #include <drivers/arm/arm_gicv3_common.h>
 #include <drivers/arm/gicv3.h>
 
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index f3852d2..446d0ad 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -12,6 +12,8 @@
 #include <common/interrupt_props.h>
 #include <drivers/arm/gic_common.h>
 
+#include <platform_def.h>
+
 #include "../common/gic_common_private.h"
 #include "gicv3_private.h"
 
diff --git a/drivers/arm/mhu/mhu_wrapper_v2_x.c b/drivers/arm/mhu/mhu_wrapper_v2_x.c
index d8b7cfd..60de1d3 100644
--- a/drivers/arm/mhu/mhu_wrapper_v2_x.c
+++ b/drivers/arm/mhu/mhu_wrapper_v2_x.c
@@ -300,3 +300,13 @@
 
 	return MHU_ERR_NONE;
 }
+
+size_t mhu_get_max_message_size(void)
+{
+	struct mhu_v2_x_dev_t *dev = &MHU1_SEH_DEV;
+	uint32_t num_channels = mhu_v2_x_get_num_channel_implemented(dev);
+
+	assert(num_channels != 0);
+
+	return num_channels * sizeof(uint32_t);
+}
diff --git a/drivers/arm/rss/rss_comms.c b/drivers/arm/rss/rss_comms.c
index 28a4925..a1f5daa 100644
--- a/drivers/arm/rss/rss_comms.c
+++ b/drivers/arm/rss/rss_comms.c
@@ -10,199 +10,141 @@
 #include <common/debug.h>
 #include <drivers/arm/mhu.h>
 #include <drivers/arm/rss_comms.h>
-#include <initial_attestation.h>
 #include <psa/client.h>
+#include <rss_comms_protocol.h>
 
-#include <platform_def.h>
-
-#define TYPE_OFFSET	U(16)
-#define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
-#define IN_LEN_OFFSET	U(8)
-#define IN_LEN_MASK	(0xFFUL << IN_LEN_OFFSET)
-#define OUT_LEN_OFFSET	U(0)
-#define OUT_LEN_MASK	(0xFFUL << OUT_LEN_OFFSET)
-
-#define PARAM_PACK(type, in_len, out_len)			  \
-	(((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK)	| \
-	 ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK)	| \
-	 ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
-
-#define PARAM_UNPACK_IN_LEN(ctrl_param) \
-	((size_t)(((ctrl_param) & IN_LEN_MASK) >> IN_LEN_OFFSET))
-
-/* Message types */
-struct __packed packed_psa_call_t {
-	uint8_t protocol_ver;
-	uint8_t seq_num;
-	uint16_t client_id;
-	psa_handle_t handle;
-	uint32_t ctrl_param; /* type, in_len, out_len */
-	uint16_t io_size[4];
-};
-
-struct __packed packed_psa_reply_t {
-	uint8_t protocol_ver;
-	uint8_t seq_num;
-	uint16_t client_id;
-	int32_t return_val;
-	uint16_t out_size[4];
-};
-
-/*
- * In the current implementation the RoT Service request that requires the
- * biggest message buffer is the RSS_ATTEST_GET_TOKEN. The maximum required
- * buffer size is calculated based on the platform-specific needs of
- * this request.
+/* Union as message space and reply space are never used at the same time, and this saves space as
+ * we can overlap them.
  */
-#define MAX_REQUEST_PAYLOAD_SIZE	(PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 \
-					 + PLAT_ATTEST_TOKEN_MAX_SIZE)
-
-/* Buffer to store the messages to be sent/received. */
-static uint8_t message_buf[MAX_REQUEST_PAYLOAD_SIZE] __aligned(4);
+union __packed __attribute__((aligned(4))) rss_comms_io_buffer_t {
+	struct serialized_rss_comms_msg_t msg;
+	struct serialized_rss_comms_reply_t reply;
+};
 
-static int32_t pack_params(const psa_invec *invecs,
-			   size_t in_len,
-			   uint8_t *buf,
-			   size_t *buf_len)
+static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
+				       const psa_outvec *out_vec, size_t out_len)
 {
-	uint32_t i;
-	size_t payload_size = 0U;
+	size_t comms_mhu_msg_size;
+	size_t comms_embed_msg_min_size;
+	size_t comms_embed_reply_min_size;
+	size_t in_size_total = 0;
+	size_t out_size_total = 0;
+	size_t i;
 
 	for (i = 0U; i < in_len; ++i) {
-		if (invecs[i].len > *buf_len - payload_size) {
-			return -1;
-		}
-		memcpy(buf + payload_size, invecs[i].base, invecs[i].len);
-		payload_size += invecs[i].len;
+		in_size_total += in_vec[i].len;
 	}
-
-	*buf_len = payload_size;
-	return 0;
-}
-
-static int serialise_message(const struct packed_psa_call_t *msg,
-			     const psa_invec *invecs,
-			     uint8_t *payload_buf,
-			     size_t *payload_len)
-{
-	size_t message_len = 0U;
-	size_t len;
-
-	/* Copy the message header into the payload buffer. */
-	len = sizeof(*msg);
-	if (len > *payload_len) {
-		ERROR("[RSS-COMMS] Message buffer too small.\n");
-		return -1;
-	}
-	memcpy(payload_buf, (const void *)msg, len);
-	message_len += len;
-
-	/* The input data will follow the message header in the payload buffer. */
-	len = *payload_len - message_len;
-	if (pack_params(invecs, PARAM_UNPACK_IN_LEN(msg->ctrl_param),
-			payload_buf + message_len, &len) != 0) {
-		ERROR("[RSS-COMMS] Message buffer too small.\n");
-		return -1;
-	}
-	message_len += len;
-
-	*payload_len = message_len;
-	return 0;
-}
-
-static void unpack_params(const uint8_t *buf,
-			  psa_outvec *outvecs,
-			  size_t out_len)
-{
-	size_t i;
-
 	for (i = 0U; i < out_len; ++i) {
-		memcpy(outvecs[i].base, buf, outvecs[i].len);
-		buf += outvecs[i].len;
+		out_size_total += out_vec[i].len;
 	}
-}
 
-static void deserialise_reply(struct packed_psa_reply_t *reply,
-			      psa_outvec *outvecs,
-			      size_t outlen,
-			      const uint8_t *message,
-			      size_t message_len)
-{
-	uint32_t i;
+	comms_mhu_msg_size = mhu_get_max_message_size();
 
-	memcpy(reply, message, sizeof(*reply));
+	comms_embed_msg_min_size = sizeof(struct serialized_rss_comms_header_t) +
+				   sizeof(struct rss_embed_msg_t) -
+				   RSS_COMMS_PAYLOAD_MAX_SIZE;
 
-	/* Outvecs */
-	for (i = 0U; i < outlen; ++i) {
-		outvecs[i].len = reply->out_size[i];
-	}
+	comms_embed_reply_min_size = sizeof(struct serialized_rss_comms_header_t) +
+				     sizeof(struct rss_embed_reply_t) -
+				     RSS_COMMS_PAYLOAD_MAX_SIZE;
 
-	unpack_params(message + sizeof(*reply), outvecs, outlen);
+	/* Use embed if we can pack into one message and reply, else use
+	 * pointer_access. The underlying MHU transport protocol uses a
+	 * single uint32_t to track the length, so the amount of data that
+	 * can be in a message is 4 bytes less than mhu_get_max_message_size
+	 * reports.
+	 *
+	 * TODO tune this with real performance numbers, it's possible a
+	 * pointer_access message is less performant than multiple embed
+	 * messages due to ATU configuration costs to allow access to the
+	 * pointers.
+	 */
+	if ((comms_embed_msg_min_size + in_size_total > comms_mhu_msg_size - sizeof(uint32_t))
+	 || (comms_embed_reply_min_size + out_size_total > comms_mhu_msg_size) - sizeof(uint32_t)) {
+		return RSS_COMMS_PROTOCOL_POINTER_ACCESS;
+	} else {
+		return RSS_COMMS_PROTOCOL_EMBED;
+	}
 }
 
-psa_status_t psa_call(psa_handle_t handle, int32_t type,
-		      const psa_invec *in_vec, size_t in_len,
+psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec, size_t in_len,
 		      psa_outvec *out_vec, size_t out_len)
 {
+	/* Declared statically to avoid using huge amounts of stack space. Maybe revisit if
+	 * functions not being reentrant becomes a problem.
+	 */
+	static union rss_comms_io_buffer_t io_buf;
 	enum mhu_error_t err;
-	static uint32_t seq_num = 1U;
-	struct packed_psa_call_t msg = {
-		.protocol_ver = 0U,
-		.seq_num = seq_num,
-		/* No need to distinguish callers (currently concurrent calls are not supported). */
-		.client_id = 1U,
-		.handle = handle,
-		.ctrl_param = PARAM_PACK(type, in_len, out_len),
-	};
+	psa_status_t status;
+	static uint8_t seq_num = 1U;
+	size_t msg_size;
+	size_t reply_size = sizeof(io_buf.reply);
+	psa_status_t return_val;
+	size_t idx;
 
-	struct packed_psa_reply_t reply = {0};
-	size_t message_size;
-	uint32_t i;
-
-	/* Fill msg iovec lengths */
-	for (i = 0U; i < in_len; ++i) {
-		msg.io_size[i] = in_vec[i].len;
+	if (type > INT16_MAX || type < INT16_MIN || in_len > PSA_MAX_IOVEC
+	    || out_len > PSA_MAX_IOVEC) {
+		return PSA_ERROR_INVALID_ARGUMENT;
 	}
-	for (i = 0U; i < out_len; ++i) {
-		msg.io_size[in_len + i] = out_vec[i].len;
+
+	io_buf.msg.header.seq_num = seq_num,
+	/* No need to distinguish callers (currently concurrent calls are not supported). */
+	io_buf.msg.header.client_id = 1U,
+	io_buf.msg.header.protocol_ver = select_protocol_version(in_vec, in_len, out_vec, out_len);
+
+	status = rss_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec,
+					    out_len, &io_buf.msg, &msg_size);
+	if (status != PSA_SUCCESS) {
+		return status;
 	}
 
-	message_size = sizeof(message_buf);
-	if (serialise_message(&msg, in_vec, message_buf, &message_size)) {
-		/* Local buffer is probably too small. */
-		return PSA_ERROR_INSUFFICIENT_MEMORY;
+	VERBOSE("[RSS-COMMS] Sending message\n");
+	VERBOSE("protocol_ver=%u\n", io_buf.msg.header.protocol_ver);
+	VERBOSE("seq_num=%u\n", io_buf.msg.header.seq_num);
+	VERBOSE("client_id=%u\n", io_buf.msg.header.client_id);
+	for (idx = 0; idx < in_len; idx++) {
+		VERBOSE("in_vec[%lu].len=%lu\n", idx, in_vec[idx].len);
+		VERBOSE("in_vec[%lu].buf=%p\n", idx, (void *)in_vec[idx].base);
 	}
 
-	err = mhu_send_data(message_buf, message_size);
+	err = mhu_send_data((uint8_t *)&io_buf.msg, msg_size);
 	if (err != MHU_ERR_NONE) {
 		return PSA_ERROR_COMMUNICATION_FAILURE;
 	}
 
-	message_size = sizeof(message_buf);
 #if DEBUG
 	/*
 	 * Poisoning the message buffer (with a known pattern).
 	 * Helps in detecting hypothetical RSS communication bugs.
 	 */
-	memset(message_buf, 0xA5, message_size);
+	memset(&io_buf.msg, 0xA5, msg_size);
 #endif
-	err = mhu_receive_data(message_buf, &message_size);
+
+	err = mhu_receive_data((uint8_t *)&io_buf.reply, &reply_size);
 	if (err != MHU_ERR_NONE) {
 		return PSA_ERROR_COMMUNICATION_FAILURE;
 	}
 
-	deserialise_reply(&reply, out_vec, out_len, message_buf, message_size);
+	VERBOSE("[RSS-COMMS] Received reply\n");
+	VERBOSE("protocol_ver=%u\n", io_buf.reply.header.protocol_ver);
+	VERBOSE("seq_num=%u\n", io_buf.reply.header.seq_num);
+	VERBOSE("client_id=%u\n", io_buf.reply.header.client_id);
 
-	seq_num++;
+	status = rss_protocol_deserialize_reply(out_vec, out_len, &return_val,
+						&io_buf.reply, reply_size);
+	if (status != PSA_SUCCESS) {
+		return status;
+	}
 
-	VERBOSE("[RSS-COMMS] Received reply\n");
-	VERBOSE("protocol_ver=%d\n", reply.protocol_ver);
-	VERBOSE("seq_num=%d\n", reply.seq_num);
-	VERBOSE("client_id=%d\n", reply.client_id);
-	VERBOSE("return_val=%d\n", reply.return_val);
-	VERBOSE("out_size[0]=%d\n", reply.out_size[0]);
+	VERBOSE("return_val=%d\n", return_val);
+	for (idx = 0U; idx < out_len; idx++) {
+		VERBOSE("out_vec[%lu].len=%lu\n", idx, out_vec[idx].len);
+		VERBOSE("out_vec[%lu].buf=%p\n", idx, (void *)out_vec[idx].base);
+	}
+
+	seq_num++;
 
-	return reply.return_val;
+	return return_val;
 }
 
 int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base)
diff --git a/drivers/arm/rss/rss_comms.mk b/drivers/arm/rss/rss_comms.mk
new file mode 100644
index 0000000..8f19a0b
--- /dev/null
+++ b/drivers/arm/rss/rss_comms.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RSS_COMMS_SOURCES	:=	$(addprefix drivers/arm/rss/,			\
+					rss_comms.c				\
+					rss_comms_protocol.c			\
+					rss_comms_protocol_embed.c		\
+					rss_comms_protocol_pointer_access.c	\
+				)
+
+RSS_COMMS_SOURCES	+=	$(addprefix drivers/arm/mhu/,			\
+					mhu_v2_x.c				\
+					mhu_wrapper_v2_x.c			\
+				)
+
+PLAT_INCLUDES		+=	-Idrivers/arm/rss		\
+				-Idrivers/arm/mhu
diff --git a/drivers/arm/rss/rss_comms_protocol.c b/drivers/arm/rss/rss_comms_protocol.c
new file mode 100644
index 0000000..a8d1dda
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <assert.h>
+
+#include <common/debug.h>
+#include "rss_comms_protocol.h"
+
+psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
+					int16_t type,
+					const psa_invec *in_vec,
+					uint8_t in_len,
+					const psa_outvec *out_vec,
+					uint8_t out_len,
+					struct serialized_rss_comms_msg_t *msg,
+					size_t *msg_len)
+{
+	psa_status_t status;
+
+	assert(msg != NULL);
+	assert(msg_len != NULL);
+	assert(in_vec != NULL);
+	assert(out_vec != NULL);
+
+	switch (msg->header.protocol_ver) {
+	case RSS_COMMS_PROTOCOL_EMBED:
+		status = rss_protocol_embed_serialize_msg(handle, type, in_vec, in_len, out_vec,
+							  out_len, &msg->msg.embed, msg_len);
+		if (status != PSA_SUCCESS) {
+			return status;
+		}
+		break;
+	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
+		status = rss_protocol_pointer_access_serialize_msg(handle, type, in_vec, in_len,
+								   out_vec, out_len,
+								   &msg->msg.pointer_access,
+								   msg_len);
+		if (status != PSA_SUCCESS) {
+			return status;
+		}
+		break;
+	default:
+		return PSA_ERROR_NOT_SUPPORTED;
+	}
+
+	*msg_len += sizeof(struct serialized_rss_comms_header_t);
+
+	return PSA_SUCCESS;
+}
+
+psa_status_t rss_protocol_deserialize_reply(psa_outvec *out_vec,
+					    uint8_t out_len,
+					    psa_status_t *return_val,
+					    const struct serialized_rss_comms_reply_t *reply,
+					    size_t reply_size)
+{
+	assert(reply != NULL);
+	assert(out_vec != NULL);
+	assert(return_val != NULL);
+
+	switch (reply->header.protocol_ver) {
+	case RSS_COMMS_PROTOCOL_EMBED:
+		return rss_protocol_embed_deserialize_reply(out_vec, out_len, return_val,
+							    &reply->reply.embed, reply_size);
+	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
+		return rss_protocol_pointer_access_deserialize_reply(out_vec, out_len, return_val,
+								     &reply->reply.pointer_access,
+								     reply_size);
+	default:
+		return PSA_ERROR_NOT_SUPPORTED;
+	}
+
+	return PSA_SUCCESS;
+}
diff --git a/drivers/arm/rss/rss_comms_protocol.h b/drivers/arm/rss/rss_comms_protocol.h
new file mode 100644
index 0000000..9a38057
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSS_COMMS_PROTOCOL_H__
+#define __RSS_COMMS_PROTOCOL_H__
+
+#include <cdefs.h>
+#include <stdint.h>
+
+#include <psa/client.h>
+#include "rss_comms_protocol_embed.h"
+#include "rss_comms_protocol_pointer_access.h"
+
+enum rss_comms_protocol_version_t {
+	RSS_COMMS_PROTOCOL_EMBED = 0,
+	RSS_COMMS_PROTOCOL_POINTER_ACCESS = 1,
+};
+
+struct __packed serialized_rss_comms_header_t {
+	uint8_t protocol_ver;
+	uint8_t seq_num;
+	uint16_t client_id;
+};
+
+/* MHU message passed from Host to RSS to deliver a PSA client call */
+struct __packed serialized_rss_comms_msg_t {
+	struct serialized_rss_comms_header_t header;
+	union __packed {
+		struct rss_embed_msg_t embed;
+		struct rss_pointer_access_msg_t pointer_access;
+	} msg;
+};
+
+/* MHU reply message to hold the PSA client reply result returned by RSS */
+struct __packed serialized_rss_comms_reply_t {
+	struct serialized_rss_comms_header_t header;
+	union __packed {
+		struct rss_embed_reply_t embed;
+		struct rss_pointer_access_reply_t pointer_access;
+	} reply;
+};
+
+/* in_len and out_len are uint8_ts, therefore if there are more than 255 iovecs
+ * an error may occur.
+ */
+CASSERT(PSA_MAX_IOVEC <= UINT8_MAX, assert_rss_comms_max_iovec_too_large);
+
+psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
+					int16_t type,
+					const psa_invec *in_vec,
+					uint8_t in_len,
+					const psa_outvec *out_vec,
+					uint8_t out_len,
+					struct serialized_rss_comms_msg_t *msg,
+					size_t *msg_len);
+
+psa_status_t rss_protocol_deserialize_reply(psa_outvec *out_vec,
+					    uint8_t out_len,
+					    psa_status_t *return_val,
+					    const struct serialized_rss_comms_reply_t *reply,
+					    size_t reply_size);
+
+#endif /* __RSS_COMMS_PROTOCOL_H__ */
diff --git a/drivers/arm/rss/rss_comms_protocol_embed.c b/drivers/arm/rss/rss_comms_protocol_embed.c
new file mode 100644
index 0000000..d217340
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol_embed.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include "rss_comms_protocol_embed.h"
+
+#define TYPE_OFFSET	(16U)
+#define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
+#define IN_LEN_OFFSET	(8U)
+#define IN_LEN_MASK	(0xFFUL << IN_LEN_OFFSET)
+#define OUT_LEN_OFFSET	(0U)
+#define OUT_LEN_MASK	(0xFFUL << OUT_LEN_OFFSET)
+
+#define PARAM_PACK(type, in_len, out_len)			  \
+	(((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK)	| \
+	 ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK)	| \
+	 ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
+
+psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
+					      int16_t type,
+					      const psa_invec *in_vec,
+					      uint8_t in_len,
+					      const psa_outvec *out_vec,
+					      uint8_t out_len,
+					      struct rss_embed_msg_t *msg,
+					      size_t *msg_len)
+{
+	uint32_t payload_size = 0;
+	uint32_t i;
+
+	assert(msg != NULL);
+	assert(msg_len != NULL);
+	assert(in_vec != NULL);
+	assert(out_vec != NULL);
+
+	msg->ctrl_param = PARAM_PACK(type, in_len, out_len);
+	msg->handle = handle;
+
+	/* Fill msg iovec lengths */
+	for (i = 0U; i < in_len; ++i) {
+		msg->io_size[i] = in_vec[i].len;
+	}
+	for (i = 0U; i < out_len; ++i) {
+		msg->io_size[in_len + i] = out_vec[i].len;
+	}
+
+	for (i = 0U; i < in_len; ++i) {
+		if (in_vec[i].len > sizeof(msg->trailer) - payload_size) {
+			return PSA_ERROR_INVALID_ARGUMENT;
+		}
+		memcpy(msg->trailer + payload_size, in_vec[i].base, in_vec[i].len);
+		payload_size += in_vec[i].len;
+	}
+
+	/* Output the actual size of the message, to optimize sending */
+	*msg_len = sizeof(*msg) - sizeof(msg->trailer) + payload_size;
+
+	return PSA_SUCCESS;
+}
+
+psa_status_t rss_protocol_embed_deserialize_reply(psa_outvec *out_vec,
+						  uint8_t out_len,
+						  psa_status_t *return_val,
+						  const struct rss_embed_reply_t *reply,
+						  size_t reply_size)
+{
+	uint32_t payload_offset = 0;
+	uint32_t i;
+
+	assert(reply != NULL);
+	assert(out_vec != NULL);
+	assert(return_val != NULL);
+
+	for (i = 0U; i < out_len; ++i) {
+		if (sizeof(reply) - sizeof(reply->trailer) + payload_offset > reply_size) {
+			return PSA_ERROR_INVALID_ARGUMENT;
+		}
+
+		memcpy(out_vec[i].base, reply->trailer + payload_offset, out_vec[i].len);
+		payload_offset += out_vec[i].len;
+	}
+
+	*return_val = reply->return_val;
+
+	return PSA_SUCCESS;
+}
diff --git a/drivers/arm/rss/rss_comms_protocol_embed.h b/drivers/arm/rss/rss_comms_protocol_embed.h
new file mode 100644
index 0000000..6c2a7bd
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol_embed.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSS_COMMS_PROTOCOL_EMBED_H__
+#define __RSS_COMMS_PROTOCOL_EMBED_H__
+
+#include <cdefs.h>
+
+#include <initial_attestation.h>
+#include <psa/client.h>
+
+#include <platform_def.h>
+
+/*
+ * In the current implementation the RoT Service request that requires the
+ * biggest message buffer is the RSS_ATTEST_GET_TOKEN. The maximum required
+ * buffer size is calculated based on the platform-specific needs of
+ * this request.
+ */
+#ifndef RSS_COMMS_PAYLOAD_MAX_SIZE
+#define RSS_COMMS_PAYLOAD_MAX_SIZE	(PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 \
+					 + PLAT_ATTEST_TOKEN_MAX_SIZE)
+#endif
+
+struct __packed rss_embed_msg_t {
+	psa_handle_t handle;
+	uint32_t ctrl_param; /* type, in_len, out_len */
+	uint16_t io_size[PSA_MAX_IOVEC];
+	uint8_t trailer[RSS_COMMS_PAYLOAD_MAX_SIZE];
+};
+
+struct __packed rss_embed_reply_t {
+	int32_t return_val;
+	uint16_t out_size[PSA_MAX_IOVEC];
+	uint8_t trailer[RSS_COMMS_PAYLOAD_MAX_SIZE];
+};
+
+psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
+					      int16_t type,
+					      const psa_invec *in_vec,
+					      uint8_t in_len,
+					      const psa_outvec *out_vec,
+					      uint8_t out_len,
+					      struct rss_embed_msg_t *msg,
+					      size_t *msg_len);
+
+psa_status_t rss_protocol_embed_deserialize_reply(psa_outvec *out_vec,
+						  uint8_t out_len,
+						  psa_status_t *return_val,
+						  const struct rss_embed_reply_t *reply,
+						  size_t reply_size);
+
+#endif /* __RSS_COMMS_PROTOCOL_EMBED_H__ */
diff --git a/drivers/arm/rss/rss_comms_protocol_pointer_access.c b/drivers/arm/rss/rss_comms_protocol_pointer_access.c
new file mode 100644
index 0000000..55c2675
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol_pointer_access.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <assert.h>
+
+#include "rss_comms_protocol_pointer_access.h"
+
+#define TYPE_OFFSET	(16U)
+#define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
+#define IN_LEN_OFFSET	(8U)
+#define IN_LEN_MASK	(0xFFUL << IN_LEN_OFFSET)
+#define OUT_LEN_OFFSET	(0U)
+#define OUT_LEN_MASK	(0xFFUL << OUT_LEN_OFFSET)
+
+#define PARAM_PACK(type, in_len, out_len)			  \
+	(((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK)	| \
+	 ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK)	| \
+	 ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
+
+psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+						       int16_t type,
+						       const psa_invec *in_vec,
+						       uint8_t in_len,
+						       const psa_outvec *out_vec,
+						       uint8_t out_len,
+						       struct rss_pointer_access_msg_t *msg,
+						       size_t *msg_len)
+{
+	unsigned int i;
+
+	assert(msg != NULL);
+	assert(msg_len != NULL);
+	assert(in_vec != NULL);
+	assert(out_vec != NULL);
+
+	msg->ctrl_param = PARAM_PACK(type, in_len, out_len);
+	msg->handle = handle;
+
+	/* Fill msg iovec lengths */
+	for (i = 0U; i < in_len; ++i) {
+		msg->io_sizes[i] = in_vec[i].len;
+		msg->host_ptrs[i] = (uint64_t)in_vec[i].base;
+	}
+	for (i = 0U; i < out_len; ++i) {
+		msg->io_sizes[in_len + i] = out_vec[i].len;
+		msg->host_ptrs[in_len + i] = (uint64_t)out_vec[i].base;
+	}
+
+	*msg_len = sizeof(*msg);
+
+	return PSA_SUCCESS;
+}
+
+psa_status_t rss_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
+							   uint8_t out_len,
+							   psa_status_t *return_val,
+							   const struct rss_pointer_access_reply_t *reply,
+							   size_t reply_size)
+{
+	unsigned int i;
+
+	assert(reply != NULL);
+	assert(out_vec != NULL);
+	assert(return_val != NULL);
+
+	for (i = 0U; i < out_len; ++i) {
+		out_vec[i].len = reply->out_sizes[i];
+	}
+
+	*return_val = reply->return_val;
+
+	return PSA_SUCCESS;
+}
diff --git a/drivers/arm/rss/rss_comms_protocol_pointer_access.h b/drivers/arm/rss/rss_comms_protocol_pointer_access.h
new file mode 100644
index 0000000..a4d054b
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol_pointer_access.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
+#define __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
+
+#include <cdefs.h>
+
+#include <psa/client.h>
+
+struct __packed rss_pointer_access_msg_t {
+	psa_handle_t handle;
+	uint32_t ctrl_param;
+	uint32_t io_sizes[PSA_MAX_IOVEC];
+	uint64_t host_ptrs[PSA_MAX_IOVEC];
+};
+
+struct __packed rss_pointer_access_reply_t {
+	int32_t return_val;
+	uint32_t out_sizes[PSA_MAX_IOVEC];
+};
+
+psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+						       int16_t type,
+						       const psa_invec *in_vec,
+						       uint8_t in_len,
+						       const psa_outvec *out_vec,
+						       uint8_t out_len,
+						       struct rss_pointer_access_msg_t *msg,
+						       size_t *msg_len);
+
+psa_status_t rss_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
+							   uint8_t out_len,
+							   psa_status_t *return_val,
+							   const struct rss_pointer_access_reply_t *reply,
+							   size_t reply_size);
+
+#endif /* __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__ */
diff --git a/drivers/auth/cryptocell/713/cryptocell_crypto.c b/drivers/auth/cryptocell/713/cryptocell_crypto.c
index 077317e..3ac16af 100644
--- a/drivers/auth/cryptocell/713/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/713/cryptocell_crypto.c
@@ -8,6 +8,8 @@
 #include <stddef.h>
 #include <string.h>
 
+#include <platform_def.h>
+
 #include <drivers/arm/cryptocell/713/bsv_api.h>
 #include <drivers/arm/cryptocell/713/bsv_crypto_asym_api.h>
 #include <drivers/auth/crypto_mod.h>
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index 08b8e9f..e3fb749 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -5,6 +5,8 @@
  */
 
 #include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
 
 #include <drivers/console.h>
 
@@ -95,10 +97,17 @@
 			if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
 				err = ret;
 		}
-
 	return err;
 }
 
+int putchar(int c)
+{
+	if (console_putc(c) == 0)
+		return c;
+	else
+		return EOF;
+}
+
 int console_getc(void)
 {
 	int err = ERROR_NO_VALID_CONSOLE;
diff --git a/drivers/measured_boot/rss/rss_measured_boot.c b/drivers/measured_boot/rss/rss_measured_boot.c
index fe2baf0..6cbb4dc 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.c
+++ b/drivers/measured_boot/rss/rss_measured_boot.c
@@ -5,6 +5,7 @@
  */
 #include <assert.h>
 #include <stdint.h>
+#include <string.h>
 
 #include <common/debug.h>
 #include <drivers/auth/crypto_mod.h>
diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c
index f938f56..55a8832 100644
--- a/drivers/rpi3/gpio/rpi3_gpio.c
+++ b/drivers/rpi3/gpio/rpi3_gpio.c
@@ -10,6 +10,7 @@
 #include <lib/mmio.h>
 #include <drivers/delay_timer.h>
 #include <drivers/rpi3/gpio/rpi3_gpio.h>
+#include <platform_def.h>
 
 static uintptr_t reg_base;
 
diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c
index 80c2f41..01d1420 100644
--- a/drivers/st/clk/stm32mp_clkfunc.c
+++ b/drivers/st/clk/stm32mp_clkfunc.c
@@ -17,7 +17,6 @@
 
 #include <platform_def.h>
 
-#define DT_UART_COMPAT		"st,stm32h7-uart"
 /*
  * Get the frequency of an oscillator from its name in device tree.
  * @param name: oscillator name
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index e467f09..e3e0e67 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -46,10 +46,16 @@
 	cmp	r0, #0
 	beq	core_init_fail
 #if !defined(IMAGE_BL2)
+#if STM32MP_RECONFIGURE_CONSOLE
+	/* UART clock rate is set to 0 in BL32, skip init in that case */
+	cmp	r1, #0
+	beq	1f
+#else /* STM32MP_RECONFIGURE_CONSOLE */
 	/* Skip UART initialization if it is already enabled */
 	ldr	r3, [r0, #USART_CR1]
 	ands	r3, r3, #USART_CR1_UE
 	bne	1f
+#endif /* STM32MP_RECONFIGURE_CONSOLE */
 #endif /* IMAGE_BL2 */
 	/* Check baud rate and uart clock for sanity */
 	cmp	r1, #0
diff --git a/drivers/st/uart/stm32_uart.c b/drivers/st/uart/stm32_uart.c
index e2e5405..63970c7 100644
--- a/drivers/st/uart/stm32_uart.c
+++ b/drivers/st/uart/stm32_uart.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,9 @@
 #include <string.h>
 
 #include <common/bl_common.h>
+#include <drivers/clk.h>
 #include <drivers/delay_timer.h>
+#include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32_uart.h>
 #include <drivers/st/stm32_uart_regs.h>
 #include <drivers/st/stm32mp_clkfunc.h>
@@ -106,7 +108,33 @@
 {
 	uint32_t tmpreg;
 	unsigned long clockfreq;
+	unsigned long int_div;
 	uint32_t brrtemp;
+	uint32_t over_sampling;
+
+	/*---------------------- USART BRR configuration --------------------*/
+	clockfreq = uart_get_clock_freq(huart);
+	if (clockfreq == 0UL) {
+		return -ENODEV;
+	}
+
+	int_div = clockfreq / init->baud_rate;
+	if (int_div < 16U) {
+		uint32_t usartdiv = uart_div_sampling8(clockfreq,
+						       init->baud_rate,
+						       init->prescaler);
+
+		brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) |
+			  ((usartdiv & USART_BRR_DIV_FRACTION) >> 1);
+		over_sampling = USART_CR1_OVER8;
+	} else {
+		brrtemp = uart_div_sampling16(clockfreq,
+					      init->baud_rate,
+					      init->prescaler) &
+			  (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA);
+		over_sampling = 0x0U;
+	}
+	mmio_write_32(huart->base + USART_BRR, brrtemp);
 
 	/*
 	 * ---------------------- USART CR1 Configuration --------------------
@@ -115,12 +143,12 @@
 	 * - set the M bits according to init->word_length value,
 	 * - set PCE and PS bits according to init->parity value,
 	 * - set TE and RE bits according to init->mode value,
-	 * - set OVER8 bit according to init->over_sampling value.
+	 * - set OVER8 bit according baudrate and clock.
 	 */
 	tmpreg = init->word_length |
 		 init->parity |
 		 init->mode |
-		 init->over_sampling |
+		 over_sampling |
 		 init->fifo_mode;
 	mmio_clrsetbits_32(huart->base + USART_CR1, STM32_UART_CR1_FIELDS, tmpreg);
 
@@ -161,27 +189,6 @@
 	mmio_clrsetbits_32(huart->base + USART_PRESC, USART_PRESC_PRESCALER,
 			   init->prescaler);
 
-	/*---------------------- USART BRR configuration --------------------*/
-	clockfreq = uart_get_clock_freq(huart);
-	if (clockfreq == 0UL) {
-		return -ENODEV;
-	}
-
-	if (init->over_sampling == STM32_UART_OVERSAMPLING_8) {
-		uint32_t usartdiv = uart_div_sampling8(clockfreq,
-						       init->baud_rate,
-						       init->prescaler);
-
-		brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) |
-			  ((usartdiv & USART_BRR_DIV_FRACTION) >> 1);
-	} else {
-		brrtemp = uart_div_sampling16(clockfreq,
-					      init->baud_rate,
-					      init->prescaler) &
-			  (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA);
-	}
-	mmio_write_32(huart->base + USART_BRR, brrtemp);
-
 	return 0;
 }
 
@@ -295,12 +302,14 @@
  * @param  init: UART initialization parameter.
  * @retval UART status.
  */
-
 int stm32_uart_init(struct stm32_uart_handle_s *huart,
 		    uintptr_t base_addr,
 		    const struct stm32_uart_init_s *init)
 {
 	int ret;
+	int uart_node;
+	int clk;
+	void *fdt = NULL;
 
 	if (huart == NULL || init == NULL || base_addr == 0U) {
 		return -EINVAL;
@@ -308,6 +317,32 @@
 
 	huart->base = base_addr;
 
+	/* Search UART instance in DT */
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if (fdt == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	uart_node = dt_match_instance_by_compatible(DT_UART_COMPAT, base_addr);
+	if (uart_node == -FDT_ERR_NOTFOUND) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	/* Pinctrl initialization */
+	if (dt_set_pinctrl_config(uart_node) != 0) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	/* Clock initialization */
+	clk = fdt_get_clock_id(uart_node);
+	if (clk < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+	clk_enable(clk);
+
 	/* Disable the peripheral */
 	stm32_uart_stop(huart->base);
 
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 2099229..5a8792e 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -336,6 +336,15 @@
 		status = "okay";
 	};
 
+	rtc0: rtc@1C170000 {
+		compatible = "arm,pl031", "arm,primecell";
+		reg = <0x0 0x1C170000 0x0 0x1000>;
+		interrupts = <0x0 100 0x4>;
+		clocks = <&soc_refclk100mhz>;
+		clock-names = "apb_pclk";
+		wakeup-source;
+	};
+
 	vencoder {
 		compatible = "drm,virtual-encoder";
 
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index bdff25b..8678bf3 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -617,6 +617,12 @@
 #define ICC_ASGI1R_EL1_64	p15, 1, c12
 #define ICC_SGI0R_EL1_64	p15, 2, c12
 
+/* Fault registers. The format is: coproc, opt1, CRn, CRm, opt2 */
+#define DFSR		p15, 0, c5, c0, 0
+#define IFSR		p15, 0, c5, c0, 1
+#define DFAR		p15, 0, c6, c0, 0
+#define IFAR		p15, 0, c6, c0, 2
+
 /*******************************************************************************
  * Definitions of MAIR encodings for device and normal memory
  ******************************************************************************/
diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h
index 694f1f0..21af112 100644
--- a/include/bl31/interrupt_mgmt.h
+++ b/include/bl31/interrupt_mgmt.h
@@ -107,7 +107,7 @@
 
 static inline int32_t validate_el3_interrupt_rm(uint32_t x)
 {
-#if defined (EL3_EXCEPTION_HANDLING) && !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1))
+#if EL3_EXCEPTION_HANDLING && !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1))
 	/*
 	 * With EL3 exception handling, EL3 interrupts are always routed to EL3
 	 * from both Secure and Non-secure, when the SPMC does not live in S-EL2.
diff --git a/include/bl32/sp_min/platform_sp_min.h b/include/bl32/sp_min/platform_sp_min.h
index 971f661..a7dffff 100644
--- a/include/bl32/sp_min/platform_sp_min.h
+++ b/include/bl32/sp_min/platform_sp_min.h
@@ -9,6 +9,8 @@
 
 #include <stdint.h>
 
+#include <common/bl_common.h>
+
 /*******************************************************************************
  * Mandatory SP_MIN functions
  ******************************************************************************/
diff --git a/include/drivers/arm/mhu.h b/include/drivers/arm/mhu.h
index 7745bd9..31c6a81 100644
--- a/include/drivers/arm/mhu.h
+++ b/include/drivers/arm/mhu.h
@@ -76,4 +76,11 @@
  */
 enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size);
 
+/**
+ * Gets the maximum amount of bytes that can be transmitted in a single send by MHU.
+ *
+ * Returns The amount of bytes that can be sent or received in a single message.
+ */
+size_t mhu_get_max_message_size(void);
+
 #endif /* MHU_H */
diff --git a/include/drivers/st/stm32_uart.h b/include/drivers/st/stm32_uart.h
index 212968f..866e158 100644
--- a/include/drivers/st/stm32_uart.h
+++ b/include/drivers/st/stm32_uart.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,10 +34,6 @@
 #define STM32_UART_HWCONTROL_CTS		USART_CR3_CTSE
 #define STM32_UART_HWCONTROL_RTS_CTS		(USART_CR3_RTSE | USART_CR3_CTSE)
 
-/* UART over sampling */
-#define STM32_UART_OVERSAMPLING_16		0x00000000U
-#define STM32_UART_OVERSAMPLING_8		USART_CR1_OVER8
-
 /* UART prescaler */
 #define STM32_UART_PRESCALER_DIV1		0x00000000U
 #define STM32_UART_PRESCALER_DIV2		0x00000001U
@@ -112,13 +108,6 @@
 					 * value of @ref STM32_UARTHWCONTROL_*.
 					 */
 
-	uint32_t over_sampling;		/*
-					 * Specifies whether the over sampling
-					 * 8 is enabled or disabled.
-					 * This parameter can be a value of
-					 * @ref STM32_UART_OVERSAMPLING_*.
-					 */
-
 	uint32_t one_bit_sampling;	/*
 					 * Specifies whether a single sample
 					 * or three samples' majority vote is
diff --git a/include/lib/cpus/aarch64/neoverse_demeter.h b/include/lib/cpus/aarch64/neoverse_demeter.h
deleted file mode 100644
index f1afae7..0000000
--- a/include/lib/cpus/aarch64/neoverse_demeter.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef NEOVERSE_DEMETER_H
-#define NEOVERSE_DEMETER_H
-
-#define NEOVERSE_DEMETER_MIDR				U(0x410FD4F0)
-
-/* Neoverse Demeter loop count for CVE-2022-23960 mitigation */
-#define NEOVERSE_DEMETER_BHB_LOOP_COUNT			U(132)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define NEOVERSE_DEMETER_CPUECTLR_EL1			S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define NEOVERSE_DEMETER_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define NEOVERSE_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
-
-#endif /* NEOVERSE_DEMETER_H */
diff --git a/include/lib/cpus/aarch64/neoverse_v2.h b/include/lib/cpus/aarch64/neoverse_v2.h
new file mode 100644
index 0000000..efb960e
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_v2.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_V2_H
+#define NEOVERSE_V2_H
+
+#define NEOVERSE_V2_MIDR				U(0x410FD4F0)
+
+/* Neoverse V2 loop count for CVE-2022-23960 mitigation */
+#define NEOVERSE_V2_BHB_LOOP_COUNT			U(132)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_V2_CPUECTLR_EL1			S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_V2_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+#endif /* NEOVERSE_V2_H */
diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h
index 917e053..131c542 100644
--- a/include/lib/fconf/fconf.h
+++ b/include/lib/fconf/fconf.h
@@ -7,6 +7,7 @@
 #ifndef FCONF_H
 #define FCONF_H
 
+#include <stddef.h>
 #include <stdint.h>
 
 /* Public API */
diff --git a/include/lib/libc/aarch32/inttypes_.h b/include/lib/libc/aarch32/inttypes_.h
index 11d2d35..ef3fb8f 100644
--- a/include/lib/libc/aarch32/inttypes_.h
+++ b/include/lib/libc/aarch32/inttypes_.h
@@ -18,4 +18,11 @@
 #define PRIx64		"llx"	/* uint64_t */
 #define PRIX64		"llX"	/* uint64_t */
 
+#define PRIdPTR         "d"     /* intptr_t */
+#define PRIiPTR         "i"     /* intptr_t */
+#define PRIoPTR         "o"     /* intptr_t */
+#define PRIuPTR         "u"     /* uintptr_t */
+#define PRIxPTR         "x"     /* uintptr_t */
+#define PRIXPTR         "X"     /* uintptr_t */
+
 #endif /* INTTYPES__H */
diff --git a/include/lib/libc/aarch64/inttypes_.h b/include/lib/libc/aarch64/inttypes_.h
index 197d627..f25882f 100644
--- a/include/lib/libc/aarch64/inttypes_.h
+++ b/include/lib/libc/aarch64/inttypes_.h
@@ -18,4 +18,11 @@
 #define PRIx64		"lx"	/* uint64_t */
 #define PRIX64		"lX"	/* uint64_t */
 
+#define PRIdPTR         "ld"    /* intptr_t */
+#define PRIiPTR         "li"    /* intptr_t */
+#define PRIoPTR         "lo"    /* intptr_t */
+#define PRIuPTR         "lu"    /* uintptr_t */
+#define PRIxPTR         "lx"    /* uintptr_t */
+#define PRIXPTR         "lX"    /* uintptr_t */
+
 #endif /* INTTYPES__H */
diff --git a/include/lib/libc/assert.h b/include/lib/libc/assert.h
index 486bbc2..462bb43 100644
--- a/include/lib/libc/assert.h
+++ b/include/lib/libc/assert.h
@@ -9,8 +9,6 @@
 
 #include <cdefs.h>
 
-#include <platform_def.h>
-
 #include <common/debug.h>
 
 #ifndef PLAT_LOG_LEVEL_ASSERT
@@ -18,9 +16,7 @@
 #endif
 
 #if ENABLE_ASSERTIONS
-# if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
-#  define assert(e)	((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))
-# elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
+# if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
 #  define assert(e)	((e) ? (void)0 : __assert(__FILE__, __LINE__))
 # else
 #  define assert(e)	((e) ? (void)0 : __assert())
@@ -29,10 +25,7 @@
 #define assert(e)	((void)0)
 #endif /* ENABLE_ASSERTIONS */
 
-#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
-void __dead2 __assert(const char *file, unsigned int line,
-		      const char *assertion);
-#elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
+#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
 void __dead2 __assert(const char *file, unsigned int line);
 #else
 void __dead2 __assert(void);
diff --git a/include/lib/libc/inttypes.h b/include/lib/libc/inttypes.h
index 0f9e8c6..6ad1c9e 100644
--- a/include/lib/libc/inttypes.h
+++ b/include/lib/libc/inttypes.h
@@ -17,31 +17,25 @@
 #define PRId8		"d"	/* int8_t */
 #define PRId16		"d"	/* int16_t */
 #define PRId32		"d"	/* int32_t */
-#define PRIdPTR		"d"	/* intptr_t */
 
 #define PRIi8		"i"	/* int8_t */
 #define PRIi16		"i"	/* int16_t */
 #define PRIi32		"i"	/* int32_t */
-#define PRIiPTR		"i"	/* intptr_t */
 
 #define PRIo8		"o"	/* int8_t */
 #define PRIo16		"o"	/* int16_t */
 #define PRIo32		"o"	/* int32_t */
-#define PRIoPTR		"o"	/* intptr_t */
 
 #define PRIu8		"u"	/* uint8_t */
 #define PRIu16		"u"	/* uint16_t */
 #define PRIu32		"u"	/* uint32_t */
-#define PRIuPTR		"u"	/* uintptr_t */
 
 #define PRIx8		"x"	/* uint8_t */
 #define PRIx16		"x"	/* uint16_t */
 #define PRIx32		"x"	/* uint32_t */
-#define PRIxPTR		"x"	/* uintptr_t */
 
 #define PRIX8		"X"	/* uint8_t */
 #define PRIX16		"X"	/* uint16_t */
 #define PRIX32		"X"	/* uint32_t */
-#define PRIXPTR		"X"	/* uintptr_t */
 
 #endif
diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h
index aa628df..96ed963 100644
--- a/include/plat/arm/common/fconf_arm_sp_getter.h
+++ b/include/plat/arm/common/fconf_arm_sp_getter.h
@@ -7,6 +7,7 @@
 #ifndef FCONF_ARM_SP_GETTER_H
 #define FCONF_ARM_SP_GETTER_H
 
+#include <common/tbbr/tbbr_img_def.h>
 #include <lib/fconf/fconf.h>
 #include <tools_share/uuid.h>
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 31607c2..da74624 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -118,6 +118,8 @@
  ******************************************************************************/
 uintptr_t plat_get_my_stack(void);
 void plat_report_exception(unsigned int exception_type);
+void plat_report_prefetch_abort(unsigned int fault_address);
+void plat_report_data_abort(unsigned int fault_address);
 int plat_crash_console_init(void);
 int plat_crash_console_putc(int c);
 void plat_crash_console_flush(void);
diff --git a/include/plat/marvell/armada/a8k/common/plat_marvell.h b/include/plat/marvell/armada/a8k/common/plat_marvell.h
index 5d805a7..bec21a0 100644
--- a/include/plat/marvell/armada/a8k/common/plat_marvell.h
+++ b/include/plat/marvell/armada/a8k/common/plat_marvell.h
@@ -10,6 +10,7 @@
 
 #include <stdint.h>
 
+#include <common/bl_common.h>
 #include <lib/cassert.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/utils.h>
diff --git a/lib/cpus/aarch64/neoverse_demeter.S b/lib/cpus/aarch64/neoverse_demeter.S
deleted file mode 100644
index 41cb4ee..0000000
--- a/lib/cpus/aarch64/neoverse_demeter.S
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <neoverse_demeter.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-#include "wa_cve_2022_23960_bhb_vector.S"
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Neoverse Demeter must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Neoverse Demeter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-#if WORKAROUND_CVE_2022_23960
-	wa_cve_2022_23960_bhb_vector_table NEOVERSE_DEMETER_BHB_LOOP_COUNT, neoverse_demeter
-#endif /* WORKAROUND_CVE_2022_23960 */
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func neoverse_demeter_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, NEOVERSE_DEMETER_CPUPWRCTLR_EL1
-	orr	x0, x0, #NEOVERSE_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	NEOVERSE_DEMETER_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc neoverse_demeter_core_pwr_dwn
-
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func neoverse_demeter_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Neoverse Demeter vectors are overridden to apply
-	 * errata mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_neoverse_demeter
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-	isb
-	ret
-endfunc neoverse_demeter_reset_func
-
-#if REPORT_ERRATA
-/*
- * Errata printing function for Neoverse Demeter. Must follow AAPCS.
- */
-func neoverse_demeter_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, neoverse_demeter, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc neoverse_demeter_errata_report
-#endif
-
-	/* ---------------------------------------------
-	 * This function provides Neoverse Demeter-
-	 * 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.neoverse_demeter_regs, "aS"
-neoverse_demeter_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func neoverse_demeter_cpu_reg_dump
-	adr	x6, neoverse_demeter_regs
-	mrs	x8, NEOVERSE_DEMETER_CPUECTLR_EL1
-	ret
-endfunc neoverse_demeter_cpu_reg_dump
-
-declare_cpu_ops neoverse_demeter, NEOVERSE_DEMETER_MIDR, \
-	neoverse_demeter_reset_func, \
-	neoverse_demeter_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
new file mode 100644
index 0000000..4ea887f
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <neoverse_v2.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse V2 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Neoverse V2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V2_BHB_LOOP_COUNT, neoverse_v2
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func neoverse_v2_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, NEOVERSE_V2_CPUPWRCTLR_EL1
+	orr	x0, x0, #NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	NEOVERSE_V2_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc neoverse_v2_core_pwr_dwn
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_cve_2022_23960
+
+func neoverse_v2_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Neoverse V2 vectors are overridden to apply
+	 * errata mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_neoverse_v2
+	msr	vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+	isb
+	ret
+endfunc neoverse_v2_reset_func
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Neoverse V2. Must follow AAPCS.
+ */
+func neoverse_v2_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata WORKAROUND_CVE_2022_23960, neoverse_v2, cve_2022_23960
+
+	ldp	x8, x30, [sp], #16
+	ret
+endfunc neoverse_v2_errata_report
+#endif
+
+	/* ---------------------------------------------
+	 * This function provides Neoverse V2-
+	 * 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.neoverse_v2_regs, "aS"
+neoverse_v2_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func neoverse_v2_cpu_reg_dump
+	adr	x6, neoverse_v2_regs
+	mrs	x8, NEOVERSE_V2_CPUECTLR_EL1
+	ret
+endfunc neoverse_v2_cpu_reg_dump
+
+declare_cpu_ops neoverse_v2, NEOVERSE_V2_MIDR, \
+	neoverse_v2_reset_func, \
+	neoverse_v2_core_pwr_dwn
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 4355b12..8213cbe 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -16,6 +16,7 @@
 #include <arch_features.h>
 #include <bl31/interrupt_mgmt.h>
 #include <common/bl_common.h>
+#include <common/debug.h>
 #include <context.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/el3_runtime/context_mgmt.h>
@@ -205,6 +206,17 @@
 	/* Allow access to Allocation Tags when MTE is implemented. */
 	scr_el3 |= SCR_ATA_BIT;
 
+#if RAS_TRAP_NS_ERR_REC_ACCESS
+	/*
+	 * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
+	 * and RAS ERX registers from EL1 and EL2(from any security state)
+	 * are trapped to EL3.
+	 * Set here to trap only for NS EL1/EL2
+	 *
+	 */
+	scr_el3 |= SCR_TERR_BIT;
+#endif
+
 #ifdef IMAGE_BL31
 	/*
 	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
@@ -305,14 +317,6 @@
 	scr_el3 |= SCR_TRNDR_BIT;
 #endif
 
-#if RAS_TRAP_LOWER_EL_ERR_ACCESS
-	/*
-	 * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
-	 * and RAS ERX registers from EL1 and EL2 are trapped to EL3.
-	 */
-	scr_el3 |= SCR_TERR_BIT;
-#endif
-
 #if !HANDLE_EA_EL3_FIRST
 	/*
 	 * SCR_EL3.EA: Do not route External Abort and SError Interrupt External
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
index 3038c09..351772e 100644
--- a/lib/fconf/fconf_dyn_cfg_getter.c
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -12,6 +12,8 @@
 #include <lib/object_pool.h>
 #include <libfdt.h>
 
+#include <platform_def.h>
+
 /* We currently use FW, TB_FW, SOC_FW, TOS_FW, NT_FW and HW configs  */
 #define MAX_DTB_INFO	U(6)
 /*
diff --git a/lib/libc/assert.c b/lib/libc/assert.c
index c199de6..8973ed5 100644
--- a/lib/libc/assert.c
+++ b/lib/libc/assert.c
@@ -17,16 +17,7 @@
  * LOG_LEVEL_INFO, which is the default value for builds with DEBUG=1.
  */
 
-#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
-void __dead2 __assert(const char *file, unsigned int line,
-		      const char *assertion)
-{
-	printf("ASSERT: %s:%u:%s\n", file, line, assertion);
-	backtrace("assert");
-	console_flush();
-	plat_panic_handler();
-}
-#elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
+#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
 void __dead2 __assert(const char *file, unsigned int line)
 {
 	printf("ASSERT: %s:%u\n", file, line);
diff --git a/lib/libc/printf.c b/lib/libc/printf.c
index 45e153e..e52cbed 100644
--- a/lib/libc/printf.c
+++ b/lib/libc/printf.c
@@ -7,9 +7,9 @@
 #include <assert.h>
 #include <stdarg.h>
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
-
-#include <common/debug.h>
+#include <stdio.h>
 
 #define get_num_va_args(_args, _lcount)				\
 	(((_lcount) > 1)  ? va_arg(_args, long long int) :	\
@@ -43,6 +43,12 @@
 	int i = 0, count = 0;
 	unsigned int rem;
 
+	/* num_buf is only large enough for radix >= 10 */
+	if (radix < 10) {
+		assert(0);
+		return 0;
+	}
+
 	do {
 		rem = unum % radix;
 		if (rem < 0xa)
diff --git a/lib/libc/putchar.c b/lib/libc/putchar.c
index 037e28a..3472b24 100644
--- a/lib/libc/putchar.c
+++ b/lib/libc/putchar.c
@@ -6,15 +6,9 @@
 
 #include <stdio.h>
 
-#include <drivers/console.h>
-
-int putchar(int c)
+int __putchar(int c)
 {
-	int res;
-	if (console_putc((unsigned char)c) >= 0)
-		res = c;
-	else
-		res = EOF;
-
-	return res;
+	return c;
 }
+
+int putchar(int c) __attribute__((weak,alias("__putchar")));
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
index 12f51c0..6a2f0ba 100644
--- a/lib/libc/snprintf.c
+++ b/lib/libc/snprintf.c
@@ -6,11 +6,10 @@
 
 #include <assert.h>
 #include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
 
-#include <common/debug.h>
-#include <plat/common/platform.h>
-
 #define get_num_va_args(_args, _lcount)				\
 	(((_lcount) > 1)  ? va_arg(_args, long long int) :	\
 	(((_lcount) == 1) ? va_arg(_args, long int) :		\
@@ -51,10 +50,10 @@
 	unsigned int rem;
 	char ascii_a = capitalise ? 'A' : 'a';
 
+	/* num_buf is only large enough for radix >= 10 */
 	if (radix < 10) {
-		ERROR("snprintf: unsupported radix '%u'.", radix);
-		plat_panic_handler();
-		assert(0); /* Unreachable */
+		assert(0);
+		return;
 	}
 
 	do {
@@ -218,11 +217,8 @@
 				break;
 
 			default:
-				/* Panic on any other format specifier. */
-				ERROR("snprintf: specifier with ASCII code '%d' not supported.",
-				      *fmt);
-				plat_panic_handler();
-				assert(0); /* Unreachable */
+				CHECK_AND_PUT_CHAR(s, n, chars_printed, '%');
+				CHECK_AND_PUT_CHAR(s, n, chars_printed, *fmt);
 			}
 			fmt++;
 			continue;
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index d30248f..6c87b0d 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -9,6 +9,8 @@
 #include <common/debug.h>
 #include <lib/optee_utils.h>
 
+#include <platform_def.h>
+
 /*
  * load_addr_hi and load_addr_lo: image load address.
  * image_id: 0 - pager, 1 - paged
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index efcfed8..8d736cc 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -156,25 +156,26 @@
 /*******************************************************************************
  * This function verifies that the all the other cores in the system have been
  * turned OFF and the current CPU is the last running CPU in the system.
- * Returns 1 (true) if the current CPU is the last ON CPU or 0 (false)
- * otherwise.
+ * Returns true, if the current CPU is the last ON CPU or false otherwise.
  ******************************************************************************/
-unsigned int psci_is_last_on_cpu(void)
+bool psci_is_last_on_cpu(void)
 {
 	unsigned int cpu_idx, my_idx = plat_my_core_pos();
 
-	for (cpu_idx = 0; cpu_idx < psci_plat_core_count;
-			cpu_idx++) {
+	for (cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
 		if (cpu_idx == my_idx) {
 			assert(psci_get_aff_info_state() == AFF_STATE_ON);
 			continue;
 		}
 
-		if (psci_get_aff_info_state_by_idx(cpu_idx) != AFF_STATE_OFF)
-			return 0;
+		if (psci_get_aff_info_state_by_idx(cpu_idx) != AFF_STATE_OFF) {
+			VERBOSE("core=%u other than current core=%u %s\n",
+				cpu_idx, my_idx, "running in the system");
+			return false;
+		}
 	}
 
-	return 1;
+	return true;
 }
 
 /*******************************************************************************
@@ -1009,11 +1010,11 @@
 
 	/* Need to wait for other cores to shutdown */
 	if (wait_ms != 0U) {
-		while ((wait_ms-- != 0U) && (psci_is_last_on_cpu() != 0U)) {
+		while ((wait_ms-- != 0U) && (!psci_is_last_on_cpu())) {
 			mdelay(1U);
 		}
 
-		if (psci_is_last_on_cpu() != 0U) {
+		if (!psci_is_last_on_cpu()) {
 			WARN("Failed to stop all cores!\n");
 			psci_print_power_domain_map();
 			return PSCI_E_DENIED;
@@ -1030,48 +1031,22 @@
  *
  * This API has following differences with psci_is_last_on_cpu
  *  1. PSCI states are locked
- *  2. It caters for "forest" topology instead of just "tree"
- *  TODO : Revisit both API's and unify them
  ******************************************************************************/
 bool psci_is_last_on_cpu_safe(void)
 {
 	unsigned int this_core = plat_my_core_pos();
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
-	unsigned int i = 0;
-
-	/*
-	 * Traverse the forest of PSCI nodes, nodes with no parents
-	 * (invalid-nodes) are the root nodes.
-	 */
-	while ((i < PSCI_NUM_NON_CPU_PWR_DOMAINS) &&
-	       (psci_non_cpu_pd_nodes[i].parent_node ==
-	       PSCI_PARENT_NODE_INVALID)) {
-		psci_get_parent_pwr_domain_nodes(
-				psci_non_cpu_pd_nodes[i].cpu_start_idx,
-				PLAT_MAX_PWR_LVL, parent_nodes);
 
-		psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+	psci_get_parent_pwr_domain_nodes(this_core, PLAT_MAX_PWR_LVL, parent_nodes);
 
-		for (unsigned int core = 0U;
-		     core < psci_non_cpu_pd_nodes[i].ncpus; core++) {
-			if (core == this_core) {
-				continue;
-			}
+	psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
 
-			if (psci_get_aff_info_state_by_idx(core) !=
-			    AFF_STATE_OFF) {
-				psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL,
-							      parent_nodes);
-				VERBOSE("core=%u other than boot core=%u %s\n",
-				       core, this_core, "running in the system");
-
-				return false;
-			}
-		}
-
+	if (!psci_is_last_on_cpu()) {
 		psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
-		i++;
+		return false;
 	}
 
+	psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+
 	return true;
 }
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 52a8b8a..a631f3f 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -158,7 +158,7 @@
 	entry_point_info_t ep;
 
 	/* Check if the current CPU is the last ON CPU in the system */
-	if (psci_is_last_on_cpu() == 0U)
+	if (!psci_is_last_on_cpu())
 		return PSCI_E_DENIED;
 
 	/* Validate the entry point and get the entry_point_info */
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index caade9c..1901c17 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -294,7 +294,7 @@
 unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info);
 void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl);
 void psci_print_power_domain_map(void);
-unsigned int psci_is_last_on_cpu(void);
+bool psci_is_last_on_cpu(void);
 int psci_spd_migrate_info(u_register_t *mpidr);
 
 /*
diff --git a/lib/semihosting/semihosting.c b/lib/semihosting/semihosting.c
index e0845c1..163a82d 100644
--- a/lib/semihosting/semihosting.c
+++ b/lib/semihosting/semihosting.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -64,8 +64,10 @@
 
 	result = semihosting_call(SEMIHOSTING_SYS_SEEK, (uintptr_t)&seek_block);
 
-	if (result != 0) {
+	if (result < 0) {
 		result = semihosting_call(SEMIHOSTING_SYS_ERRNO, 0);
+	} else  {
+		result = 0;
 	}
 
 	return result;
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 5e73120..65ceb7f 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -413,8 +413,8 @@
 # Select workaround for AT speculative behaviour.
 ERRATA_SPECULATIVE_AT		:= 0
 
-# Trap RAS error record access from lower EL
-RAS_TRAP_LOWER_EL_ERR_ACCESS	:= 0
+# Trap RAS error record access from Non secure
+RAS_TRAP_NS_ERR_REC_ACCESS	:= 0
 
 # Build option to create cot descriptors using fconf
 COT_DESC_IN_DTB			:= 0
diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c
index 8f3e7b7..e780f21 100644
--- a/plat/arm/board/fvp/fvp_gicv3.c
+++ b/plat/arm/board/fvp/fvp_gicv3.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <platform_def.h>
 
+#include <common/debug.h>
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <fconf_hw_config_getter.h>
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index 1b0854b..4dd37a4 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -10,294 +10,88 @@
 
 /* Using hardcoded token values for AEM FVP */
 static uint8_t platform_token[] = {
-	0xD2, 0x84, 0x40, 0xA0, 0x59, 0x08, 0xB1, 0xD9,
-	0x61, 0xA8, 0xA9, 0x0A, 0x58, 0x40, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x3A, 0x00,
-	0x01, 0x24, 0xFA, 0x58, 0x40, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x3A, 0x00, 0x01,
-	0x25, 0x00, 0x58, 0x41, 0x01, 0x0B, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x12, 0x78, 0x1C,
-	0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61,
-	0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x43,
-	0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F, 0x31,
-	0x2E, 0x30, 0x2E, 0x30, 0x0B, 0x58, 0x19, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0x3A, 0x00, 0x01, 0x24, 0xF7, 0x78, 0x1C, 0x68,
-	0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61, 0x72,
-	0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x43, 0x43,
-	0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F, 0x31, 0x2E,
-	0x30, 0x2E, 0x30, 0x3A, 0x00, 0x01, 0x25, 0x01,
-	0x78, 0x18, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A,
-	0x2F, 0x2F, 0x63, 0x63, 0x61, 0x5F, 0x76, 0x65,
-	0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x2E, 0x6F,
-	0x72, 0x67, 0x3A, 0x00, 0x01, 0x24, 0xF9, 0x19,
-	0x30, 0x00, 0x3A, 0x00, 0x01, 0x24, 0xFD, 0x8D,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0x58, 0x40, 0xD3, 0x8A, 0x41, 0xA6, 0xC1, 0x29,
-	0x98, 0x18, 0xB5, 0x16, 0x9C, 0x21, 0x78, 0xB7,
-	0x92, 0xF8, 0x26, 0x82, 0x76, 0x2F, 0x26, 0x45,
-	0x21, 0x6D, 0x0C, 0x21, 0x06, 0xF4, 0xB5, 0xE3,
-	0xA8, 0x07, 0xD1, 0xD6, 0x8C, 0x73, 0xA5, 0xC8,
-	0x16, 0xD8, 0x30, 0x68, 0xC0, 0xA4, 0x77, 0xE2,
-	0x1E, 0xD2, 0x17, 0x86, 0xC3, 0x68, 0x82, 0xDD,
-	0x21, 0x1B, 0xA3, 0xE2, 0xC7, 0xF7, 0x06, 0x33,
-	0xB0, 0x3A
+	0xD2, 0x84, 0x40, 0xA0, 0x59, 0x02, 0x46, 0xA9,
+	0x19, 0x01, 0x09, 0x78, 0x1C, 0x68, 0x74, 0x74,
+	0x70, 0x3A, 0x2F, 0x2F, 0x61, 0x72, 0x6D, 0x2E,
+	0x63, 0x6F, 0x6D, 0x2F, 0x43, 0x43, 0x41, 0x2D,
+	0x53, 0x53, 0x44, 0x2F, 0x31, 0x2E, 0x30, 0x2E,
+	0x30, 0x0A, 0x58, 0x20, 0x07, 0x06, 0x05, 0x04,
+	0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C,
+	0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14,
+	0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C,
+	0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09, 0x5C, 0x58,
+	0x40, 0x7F, 0x45, 0x4C, 0x46, 0x02, 0x01, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x00, 0x3E, 0x00, 0x01, 0x00, 0x00,
+	0x00, 0x50, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0xA0, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38,
+	0x00, 0x09, 0x00, 0x40, 0x00, 0x1C, 0x00, 0x1B,
+	0x00, 0x19, 0x01, 0x00, 0x58, 0x21, 0x01, 0x07,
+	0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F,
+	0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17,
+	0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F,
+	0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19,
+	0x09, 0x61, 0x58, 0x21, 0x01, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09, 0x5B,
+	0x19, 0x30, 0x03, 0x19, 0x09, 0x62, 0x67, 0x73,
+	0x68, 0x61, 0x2D, 0x32, 0x35, 0x36, 0x19, 0x09,
+	0x5F, 0x84, 0xA5, 0x01, 0x62, 0x42, 0x4C, 0x05,
+	0x58, 0x20, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
+	0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A,
+	0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12,
+	0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A,
+	0x19, 0x18, 0x04, 0x65, 0x33, 0x2E, 0x34, 0x2E,
+	0x32, 0x02, 0x58, 0x20, 0x07, 0x06, 0x05, 0x04,
+	0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C,
+	0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14,
+	0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C,
+	0x1B, 0x1A, 0x19, 0x18, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2D, 0x32, 0x35, 0x36, 0xA4, 0x01, 0x62,
+	0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63, 0x31,
+	0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01, 0x62,
+	0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65, 0x31,
+	0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20, 0x07,
+	0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F,
+	0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17,
+	0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F,
+	0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4,
+	0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20, 0x07,
+	0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F,
+	0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17,
+	0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F,
+	0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04,
+	0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09, 0x60,
+	0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76, 0x65,
+	0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x40, 0x84,
+	0x32, 0x12, 0x5B, 0x92, 0x6B, 0x20, 0xD8, 0x14,
+	0xC1, 0xC1, 0x8C, 0x3C, 0x73, 0xB8, 0x29, 0x0F,
+	0x42, 0xBC, 0x0B, 0x25, 0x87, 0x5C, 0x4F, 0xA4,
+	0xFA, 0xD9, 0xDE, 0xC1, 0x2B, 0x20, 0xED, 0xDF,
+	0x1C, 0xDD, 0x1A, 0x09, 0xBD, 0xA0, 0x25, 0x48,
+	0xC6, 0xBB, 0x99, 0xA1, 0x30, 0x4F, 0x2C, 0xDC,
+	0x89, 0xE8, 0xB7, 0xFF, 0x32, 0xE9, 0x3F, 0xBB,
+	0xC6, 0xBF, 0x9D, 0x38, 0x68, 0xE1, 0xB2,
 };
 
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 2539712..a20343b 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -132,7 +132,7 @@
 					lib/cpus/aarch64/neoverse_n2.S		\
 					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/neoverse_v1.S		\
-					lib/cpus/aarch64/neoverse_demeter.S	\
+					lib/cpus/aarch64/neoverse_v2.S	\
 					lib/cpus/aarch64/cortex_a78_ae.S	\
 					lib/cpus/aarch64/cortex_a510.S		\
 					lib/cpus/aarch64/cortex_a710.S		\
@@ -394,9 +394,23 @@
 PLAT_INCLUDES		+=	-Iinclude/lib/psa
 
 # RSS is not supported on FVP right now. Thus, we use the mocked version
-# of PSA Measured Boot APIs. They return with success and hard-coded data.
+# of the provided PSA APIs. They return with success and hard-coded data.
 PLAT_RSS_NOT_SUPPORTED	:= 1
 
+# Even though RSS is not supported on FVP (see above), we support overriding
+# PLAT_RSS_NOT_SUPPORTED from the command line, just for the purpose of building
+# the code to detect any build regressions. The resulting firmware will not be
+# functional.
+ifneq (${PLAT_RSS_NOT_SUPPORTED},1)
+    $(warning "RSS is not supported on FVP. The firmware will not be functional.")
+    include drivers/arm/rss/rss_comms.mk
+    BL1_SOURCES		+=	${RSS_COMMS_SOURCES}
+    BL2_SOURCES		+=	${RSS_COMMS_SOURCES}
+
+    BL1_CFLAGS		+=	-DPLAT_ATTEST_TOKEN_MAX_SIZE=0
+    BL2_CFLAGS		+=	-DPLAT_ATTEST_TOKEN_MAX_SIZE=0
+endif
+
 endif
 
 ifeq (${TRUSTED_BOARD_BOOT}, 1)
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 3265b0b..409d7a6 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -196,12 +196,6 @@
 # define PLATFORM_STACK_SIZE		UL(0x440)
 #endif
 
-/*
- * Since free SRAM space is scant, enable the ASSERTION message size
- * optimization by fixing the PLAT_LOG_LEVEL_ASSERT to LOG_LEVEL_INFO (40).
- */
-#define PLAT_LOG_LEVEL_ASSERT		40
-
 /* CCI related constants */
 #define PLAT_ARM_CCI_BASE		UL(0x2c090000)
 #define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX	4
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index cfe4e28..9728a08 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -34,7 +34,7 @@
 PLAT_INCLUDES		+=	-I${RDN2_BASE}/include/
 
 SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n2.S \
-				lib/cpus/aarch64/neoverse_demeter.S
+				lib/cpus/aarch64/neoverse_v2.S
 
 PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat_v2.c
 
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 7a9e04d..7000236 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -11,6 +11,7 @@
 #include <arch.h>
 #include <bl1/bl1.h>
 #include <common/bl_common.h>
+#include <common/debug.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/utils.h>
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 6a2a6f8..e88ea65 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 
+#include <common/debug.h>
 #if MEASURED_BOOT
 #include <common/desc_image_load.h>
 #endif
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index 4a3a22e..469e22a 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <platform_def.h>
 
+#include <common/debug.h>
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
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 22870c4..c1fadc6 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -19,7 +19,7 @@
 					CSS_SGI_MAX_CPUS_PER_CLUSTER *	\
 					CSS_SGI_MAX_PE_PER_CPU)
 
-#define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00040000	/* 256 KB */
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00080000	/* 512 KB */
 
 /* Remote chip address offset */
 #define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n)	\
@@ -99,10 +99,16 @@
 
 /*
  * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
- * calculated using the current BL31 PROGBITS debug size plus the sizes of
- * BL2 and BL1-RW
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
+ * and BL1-RW. CSS_SGI_BL31_SIZE - is tuned with respect to the actual BL31
+ * PROGBITS size which is around 64-68KB at the time this change is being made.
+ * A buffer of ~35KB is added to account for future expansion of the image,
+ * making it a total of 100KB.
  */
-#define PLAT_ARM_MAX_BL31_SIZE		0x48000
+#define CSS_SGI_BL31_SIZE		(100 * 1024)	/* 100 KB */
+#define PLAT_ARM_MAX_BL31_SIZE		(CSS_SGI_BL31_SIZE +		\
+						PLAT_ARM_MAX_BL2_SIZE +	\
+						PLAT_ARM_MAX_BL1_RW_SIZE)
 
 /*
  * Size of cacheable stacks
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
index 41467f7..223ac3e 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/css/sgi/include/sgi_variant.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,9 +23,9 @@
 /* SID Version values for RD-N2 variants */
 #define RD_N2_CFG1_SID_VER_PART_NUM		0x07B6
 
-/* SID Version values for RD-Edmunds */
-#define RD_EDMUNDS_SID_VER_PART_NUM		0x07F2
-#define RD_EDMUNDS_CONFIG_ID			0x1
+/* SID Version values for RD-V2 */
+#define RD_V2_SID_VER_PART_NUM			0x07F2
+#define RD_V2_CONFIG_ID				0x1
 
 /* Structure containing SGI platform variant information */
 typedef struct sgi_platform_info {
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 4af579e..6c1a2dd 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -69,7 +69,6 @@
 
 override CSS_LOAD_SCP_IMAGES	:=	0
 override NEED_BL2U		:=	no
-override ARM_BL31_IN_DRAM	:=	1
 override ARM_PLAT_MT		:=	1
 override PSCI_EXTENDED_STATE_ID	:=	1
 override ARM_RECOM_STATE_ID_ENC	:=	1
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 7ef7e6f..27cf183 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -79,7 +79,7 @@
 	if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_EDMUNDS_SID_VER_PART_NUM ||
+		sgi_plat_info.platform_id == RD_V2_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM) {
 		if (channel_id >= ARRAY_SIZE(plat_rd_scmi_info))
 			panic();
diff --git a/plat/brcm/board/common/cmn_plat_def.h b/plat/brcm/board/common/cmn_plat_def.h
index 8aa7fd4..79d9a29 100644
--- a/plat/brcm/board/common/cmn_plat_def.h
+++ b/plat/brcm/board/common/cmn_plat_def.h
@@ -8,6 +8,7 @@
 #define CMN_PLAT_DEF_H
 
 #include <bcm_elog.h>
+#include <platform_def.h>
 
 #ifndef GET_LOG_LEVEL
 #define GET_LOG_LEVEL() LOG_LEVEL
@@ -57,9 +58,6 @@
 			}						 \
 		} while (0)
 
-/* Print file and line number on assert */
-#define PLAT_LOG_LEVEL_ASSERT LOG_LEVEL_INFO
-
 /*
  * The number of regions like RO(code), coherent and data required by
  * different BL stages which need to be mapped in the MMU.
diff --git a/plat/common/aarch32/platform_helpers.S b/plat/common/aarch32/platform_helpers.S
index 5b9cb59..75cc456 100644
--- a/plat/common/aarch32/platform_helpers.S
+++ b/plat/common/aarch32/platform_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,8 @@
 #include <asm_macros.S>
 
 	.weak	plat_report_exception
+	.weak	plat_report_prefetch_abort
+	.weak	plat_report_data_abort
 	.weak	plat_reset_handler
 	.weak	plat_disable_acp
 	.weak	bl1_plat_prepare_exit
@@ -28,6 +30,24 @@
 	 * each platform.
 	 * -----------------------------------------------------
 	 */
+func plat_report_prefetch_abort
+	bx	lr
+endfunc plat_report_prefetch_abort
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform.
+	 * -----------------------------------------------------
+	 */
+func plat_report_data_abort
+	bx	lr
+endfunc plat_report_data_abort
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform.
+	 * -----------------------------------------------------
+	 */
 func plat_reset_handler
 	bx	lr
 endfunc plat_reset_handler
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index e807660..8f998af 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <arch_helpers.h>
+#include <common/debug.h>
 #include <drivers/console.h>
 #if RAS_EXTENSION
 #include <lib/extensions/ras.h>
diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c
index 2c3a067..e1420bb 100644
--- a/plat/common/plat_gicv3.c
+++ b/plat/common/plat_gicv3.c
@@ -10,6 +10,7 @@
 
 #include <arch_helpers.h>
 #include <common/bl_common.h>
+#include <common/debug.h>
 #include <bl31/interrupt_mgmt.h>
 #include <drivers/arm/gic_common.h>
 #include <drivers/arm/gicv3.h>
diff --git a/plat/imx/imx8m/imx8m_dyn_cfg_helpers.c b/plat/imx/imx8m/imx8m_dyn_cfg_helpers.c
index 8b2fdd6..5d65ef2 100644
--- a/plat/imx/imx8m/imx8m_dyn_cfg_helpers.c
+++ b/plat/imx/imx8m/imx8m_dyn_cfg_helpers.c
@@ -13,6 +13,7 @@
 #endif
 #include <common/fdt_wrappers.h>
 #include <libfdt.h>
+#include <platform_def.h>
 
 #define DTB_PROP_HW_LOG_ADDR	"tpm_event_log_addr"
 #define DTB_PROP_HW_LOG_SIZE	"tpm_event_log_size"
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index eacc4dd..facee0f 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -979,7 +979,7 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	if (data_size >= src_size) {
+	if (data_size > src_size) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 778d4af..79817e6 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -236,7 +236,7 @@
 
 		/* copy response data to input buffer if applicable */
 		ret_resp_len = MBOX_RESP_LEN(mailbox_resp_ctr.payload->header);
-		if ((ret_resp_len > 0) && (response == NULL) && resp_len) {
+		if ((ret_resp_len > 0) && (response != NULL) && (resp_len != NULL)) {
 			if (*resp_len > ret_resp_len) {
 				*resp_len = ret_resp_len;
 			}
diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk
index eb579e5..7b63a3e 100644
--- a/plat/mediatek/build_helpers/options.mk
+++ b/plat/mediatek/build_helpers/options.mk
@@ -15,3 +15,10 @@
 $(eval $(call add_defined_option,MTK_SOC))
 $(eval $(call add_defined_option,UART_CLOCK))
 $(eval $(call add_defined_option,UART_BAUDRATE))
+$(eval $(call add_defined_option,CONFIG_MTK_MCUSYS))
+$(eval $(call add_defined_option,CONFIG_MTK_PM_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_CPU_PM_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_SMP_EN))
+$(eval $(call add_defined_option,CONFIG_MTK_CPU_SUSPEND_EN))
+$(eval $(call add_defined_option,CONFIG_MTK_PM_ARCH))
+$(eval $(call add_defined_option,CONFIG_MTK_CPU_PM_ARCH))
diff --git a/plat/mediatek/common/cold_boot.c b/plat/mediatek/common/cold_boot.c
deleted file mode 100644
index ff585fe..0000000
--- a/plat/mediatek/common/cold_boot.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (c) 2022, Mediatek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/el3_runtime/context_mgmt.h>
-
-/* Vendors headers */
-#include <cold_boot.h>
-#include <lib/mtk_init/mtk_init.h>
-#include <mtk_sip_svc.h>
-
-static struct kernel_info k_info;
-static entry_point_info_t bl32_image_ep_info;
-static entry_point_info_t bl33_image_ep_info;
-static bool el1_is_2nd_bootloader = true;
-static struct atf_arg_t atfarg;
-
-static int init_mtk_bl32_arg(void)
-{
-	struct mtk_bl_param_t *p_mtk_bl_param;
-	struct atf_arg_t *p_atfarg;
-
-	p_mtk_bl_param = (struct mtk_bl_param_t *) get_mtk_bl31_fw_config(BOOT_ARG_FROM_BL2);
-	if (p_mtk_bl_param == NULL) {
-		ERROR("p_mtk_bl_param is NULL!\n");
-		return -1;
-	}
-	p_atfarg = (struct atf_arg_t *)p_mtk_bl_param->atf_arg_addr;
-	if (p_atfarg == NULL) {
-		ERROR("bl32 argument is NULL!\n");
-		return -1;
-	}
-	memcpy((void *)&atfarg, (void *)p_atfarg, sizeof(struct atf_arg_t));
-	return 0;
-}
-MTK_EARLY_PLAT_INIT(init_mtk_bl32_arg);
-
-static void save_kernel_info(uint64_t pc, uint64_t r0, uint64_t r1, uint64_t k32_64)
-{
-	k_info.k32_64 = k32_64;
-	k_info.pc = pc;
-
-	if (k32_64 == LINUX_KERNEL_32) {
-		/* for 32 bits kernel */
-		k_info.r0 = 0;
-		/* machtype */
-		k_info.r1 = r0;
-		/* tags */
-		k_info.r2 = r1;
-	} else {
-		/* for 64 bits kernel */
-		k_info.r0 = r0;
-		k_info.r1 = r1;
-	}
-}
-
-static uint32_t plat_get_spsr_for_bl32_64_entry(void)
-{
-	return SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
-}
-
-#if MTK_BL33_IS_64BIT
-static uint32_t plat_get_spsr_for_bl33_entry(void)
-{
-	uint32_t spsr;
-	uint32_t mode;
-
-	mode = MODE_EL1;
-	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
-	return spsr;
-}
-#else
-static uint32_t plat_get_spsr_for_bl33_entry(void)
-{
-	unsigned int mode;
-	uint32_t spsr;
-	unsigned int ee;
-	unsigned long daif;
-
-	INFO("Secondary bootloader is AArch32\n");
-	mode = MODE32_svc;
-	ee = 0;
-	/*
-	 * TODO: Choose async. exception bits if HYP mode is not
-	 * implemented according to the values of SCR.{AW, FW} bits
-	 */
-	daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
-
-	spsr = SPSR_MODE32(mode, 0, ee, daif);
-	return spsr;
-}
-#endif
-
-static void populate_bl32_image_ep(entry_point_info_t *bl32_ep_instance,
-		struct mtk_bl_param_t *p_mtk_bl_param)
-{
-	entry_point_info_t *populated_ep_bl32 = bl32_ep_instance;
-
-	if (p_mtk_bl_param == NULL) {
-		ERROR("p_mtk_bl_param is NULL!\n");
-		panic();
-	}
-	SET_SECURITY_STATE(bl32_ep_instance->h.attr, SECURE);
-	SET_PARAM_HEAD(populated_ep_bl32,
-		       PARAM_EP,
-		       VERSION_1,
-		       populated_ep_bl32->h.attr);
-	populated_ep_bl32->pc = atfarg.tee_entry;
-	populated_ep_bl32->spsr = plat_get_spsr_for_bl32_64_entry();
-}
-
-static void populate_bl33_image_ep(entry_point_info_t *bl33_ep_instance,
-		struct mtk_bl_param_t *p_mtk_bl_param)
-{
-	entry_point_info_t *populated_ep_bl33 = bl33_ep_instance;
-
-	if (p_mtk_bl_param == NULL) {
-		ERROR("p_mtk_bl_param is NULL!\n");
-		panic();
-	}
-	SET_SECURITY_STATE(bl33_ep_instance->h.attr, NON_SECURE);
-	SET_PARAM_HEAD(populated_ep_bl33,
-		       PARAM_EP,
-		       VERSION_1,
-		       populated_ep_bl33->h.attr);
-	populated_ep_bl33->pc = p_mtk_bl_param->bl33_start_addr;
-	/* standardize 2nd bootloader input argument */
-	populated_ep_bl33->args.arg0 = p_mtk_bl_param->bootarg_loc;
-	/* compatible to old GZ version */
-	populated_ep_bl33->args.arg4 = p_mtk_bl_param->bootarg_loc;
-	populated_ep_bl33->args.arg5 = p_mtk_bl_param->bootarg_size;
-	populated_ep_bl33->spsr = plat_get_spsr_for_bl33_entry();
-}
-
-static int populate_bl_images_ep(struct mtk_bl_param_t *p_mtk_bl_param)
-{
-	/*
-	 * Tell BL31 where the non-trusted software image
-	 * is located and the entry state information
-	 */
-	populate_bl33_image_ep(&bl33_image_ep_info, p_mtk_bl_param);
-	populate_bl32_image_ep(&bl32_image_ep_info, p_mtk_bl_param);
-	return 0;
-}
-
-static int populate_bl_images_ep_init(void)
-{
-	return populate_bl_images_ep(get_mtk_bl31_fw_config(BOOT_ARG_FROM_BL2));
-}
-MTK_PLAT_SETUP_0_INIT(populate_bl_images_ep_init);
-
-static entry_point_info_t *bl31_plat_get_next_kernel64_ep_info(void)
-{
-	entry_point_info_t *next_image_info;
-	unsigned long el_status;
-	unsigned int mode;
-
-	el_status = 0;
-	mode = 0;
-
-	/* Kernel image is always non-secured */
-	next_image_info = &bl33_image_ep_info;
-
-	/* Figure out what mode we enter the non-secure world in */
-	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
-	el_status &= ID_AA64PFR0_ELX_MASK;
-
-	INFO("Kernel_EL %d\n", el_status?2:1);
-	if (el_status) {
-		mode = MODE_EL2;
-	} else {
-		mode = MODE_EL1;
-	}
-	INFO("Kernel is 64Bit\n");
-	next_image_info->spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
-	next_image_info->pc = k_info.pc;
-	next_image_info->args.arg0 = k_info.r0;
-	next_image_info->args.arg1 = k_info.r1;
-
-	INFO("pc=0x%lx, r0=0x%" PRIx64 ", r1=0x%" PRIx64 "\n",
-	     next_image_info->pc,
-	     next_image_info->args.arg0,
-	     next_image_info->args.arg1);
-
-	SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
-	/* None of the images on this platform can have 0x0 as the entrypoint */
-	if (next_image_info->pc) {
-		return next_image_info;
-	}
-
-	return NULL;
-}
-
-static entry_point_info_t *bl31_plat_get_next_kernel32_ep_info(void)
-{
-	entry_point_info_t *next_image_info;
-	unsigned int mode;
-
-	mode = 0;
-
-	/* Kernel image is always non-secured */
-	next_image_info = &bl33_image_ep_info;
-
-	/* Figure out what mode we enter the non-secure world in */
-	mode = MODE32_hyp;
-	/*
-	 * TODO: Consider the possibility of specifying the SPSR in
-	 * the FIP ToC and allowing the platform to have a say as
-	 * well.
-	 */
-
-	INFO("Kernel is 32Bit\n");
-	next_image_info->spsr = SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE,
-					    (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT));
-	next_image_info->pc = k_info.pc;
-	next_image_info->args.arg0 = k_info.r0;
-	next_image_info->args.arg1 = k_info.r1;
-	next_image_info->args.arg2 = k_info.r2;
-
-	INFO("pc=0x%lx, r0=0x%" PRIx64 ", r1=0x%" PRIx64 ", r2=0x%" PRIx64 "\n",
-	     next_image_info->pc,
-	     next_image_info->args.arg0,
-	     next_image_info->args.arg1,
-	     next_image_info->args.arg2);
-
-	SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
-	/* None of the images on this platform can have 0x0 as the entrypoint */
-	if (next_image_info->pc) {
-		return next_image_info;
-	}
-
-	return NULL;
-}
-
-static void bl31_prepare_kernel_entry(uint64_t k32_64)
-{
-	entry_point_info_t *next_image_info = NULL;
-	uint32_t image_type;
-
-	/* Determine which image to execute next */
-	image_type = NON_SECURE; /* bl31_get_next_image_type(); */
-
-	/* Leave 2nd bootloader then jump to kernel */
-	el1_is_2nd_bootloader = false;
-
-	/* Program EL3 registers to enable entry into the next EL */
-	if (k32_64 == LINUX_KERNEL_32) {
-		next_image_info = bl31_plat_get_next_kernel32_ep_info();
-	} else {
-		next_image_info = bl31_plat_get_next_kernel64_ep_info();
-	}
-
-	assert(next_image_info);
-	assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));
-
-	INFO("BL31: Preparing for EL3 exit to %s world, Kernel\n",
-	     (image_type == SECURE) ? "secure" : "normal");
-	INFO("BL31: Next image address = 0x%" PRIx64 "\n",
-	     next_image_info->pc);
-	INFO("BL31: Next image spsr = 0x%x\n", next_image_info->spsr);
-	cm_init_my_context(next_image_info);
-	cm_prepare_el3_exit(image_type);
-}
-
-bool is_el1_2nd_bootloader(void)
-{
-	return el1_is_2nd_bootloader;
-}
-
-/*******************************************************************************
- * Return a pointer to the 'entry_point_info' structure of the next image for
- * the security state specified. BL33 corresponds to the non-secure image type
- * while BL32 corresponds to the secure image type. A NULL pointer is returned
- * if the image does not exist.
- ******************************************************************************/
-entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
-{
-	entry_point_info_t *next_image_info;
-
-	next_image_info = (type == NON_SECURE) ? &bl33_image_ep_info : &bl32_image_ep_info;
-
-	/* None of the images on this platform can have 0x0 as the entrypoint */
-	if (next_image_info->pc) {
-		return next_image_info;
-	}
-	return NULL;
-}
-
-u_register_t boot_to_kernel(u_register_t x1,
-			    u_register_t x2,
-			    u_register_t x3,
-			    u_register_t x4,
-			    void *handle,
-			    struct smccc_res *smccc_ret)
-{
-	static uint8_t kernel_boot_once_flag;
-
-	/* only support in booting flow */
-	if (kernel_boot_once_flag == 0) {
-		kernel_boot_once_flag = 1;
-
-		INFO("save kernel info\n");
-		save_kernel_info(x1, x2, x3, x4);
-		bl31_prepare_kernel_entry(x4);
-		INFO("el3_exit\n");
-		/*
-		 * FIXME: no better way so far to prevent from
-		 * SiP root handler wipe x0~x3 if not assign smccc_ret
-		 * return register
-		 */
-		smccc_ret->a1 = x3;
-
-		mtk_init_one_level(MTK_INIT_LVL_BL33_DEFER);
-
-#if MTK_CONSOLE_RUNTIME_DISABLE
-		INFO("Turn off BL31 console\n");
-		mtk_console_core_end();
-#endif
-
-		/* Re-assign as x0 register entering Linux kernel */
-		return x2;
-	}
-	return 0;
-}
-/* Register SiP SMC service */
-DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_BOOT, boot_to_kernel);
diff --git a/plat/mediatek/drivers/lpm/mt_lp_rm.c b/plat/mediatek/common/lpm/mt_lp_rm.c
similarity index 100%
rename from plat/mediatek/drivers/lpm/mt_lp_rm.c
rename to plat/mediatek/common/lpm/mt_lp_rm.c
diff --git a/plat/mediatek/drivers/lpm/mt_lp_rm.h b/plat/mediatek/common/lpm/mt_lp_rm.h
similarity index 100%
rename from plat/mediatek/drivers/lpm/mt_lp_rm.h
rename to plat/mediatek/common/lpm/mt_lp_rm.h
diff --git a/plat/mediatek/common/lpm/rules.mk b/plat/mediatek/common/lpm/rules.mk
new file mode 100644
index 0000000..87a212a
--- /dev/null
+++ b/plat/mediatek/common/lpm/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := lpm
+LOCAL_SRCS-y := $(LOCAL_DIR)/mt_lp_rm.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/common/mtk_smc_handlers.c b/plat/mediatek/common/mtk_smc_handlers.c
index 24b978c..51a960f 100644
--- a/plat/mediatek/common/mtk_smc_handlers.c
+++ b/plat/mediatek/common/mtk_smc_handlers.c
@@ -6,9 +6,11 @@
 
 #include <assert.h>
 #include <errno.h>
+#if MTK_SIP_KERNEL_BOOT_ENABLE
+#include <cold_boot.h>
+#endif
 #include <common/debug.h>
 #include <common/runtime_svc.h>
-#include <cold_boot.h>
 #include <lib/mtk_init/mtk_init.h>
 #include <mtk_sip_svc.h>
 
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c
new file mode 100644
index 0000000..313ad47
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <lib/spinlock.h>
+
+#include <lib/mtk_init/mtk_init.h>
+#include <lib/pm/mtk_pm.h>
+#include "mt_cpu_pm.h"
+#include "mt_cpu_pm_cpc.h"
+#include "mt_cpu_pm_mbox.h"
+#include <mt_lp_rm.h>
+#include "mt_smp.h"
+#include <mtk_mmap_pool.h>
+#include <platform_def.h>
+
+/*
+ * The locker must use the bakery locker when cache turns off.
+ * Using spin_lock will gain better performance.
+ */
+#ifdef MT_CPU_PM_USING_BAKERY_LOCK
+DEFINE_BAKERY_LOCK(mt_cpu_pm_lock);
+#define plat_cpu_pm_lock_init()	bakery_lock_init(&mt_cpu_pm_lock)
+#define plat_cpu_pm_lock()	bakery_lock_get(&mt_cpu_pm_lock)
+#define plat_cpu_pm_unlock()	bakery_lock_release(&mt_cpu_pm_lock)
+#else
+spinlock_t mt_cpu_pm_lock;
+#define plat_cpu_pm_lock_init()
+#define plat_cpu_pm_lock()	spin_lock(&mt_cpu_pm_lock)
+#define plat_cpu_pm_unlock()	spin_unlock(&mt_cpu_pm_lock)
+#endif
+
+enum mt_pwr_node {
+	MT_PWR_NONMCUSYS = 0,
+	MT_PWR_MCUSYS_PDN,
+	MT_PWR_SUSPEND,
+	MT_PWR_SYSTEM_MEM,
+	MT_PWR_SYSTEM_PLL,
+	MT_PWR_SYSTEM_BUS,
+	MT_PWR_MAX,
+};
+
+#define CPU_PM_DEPD_INIT	BIT(0)
+#define CPU_PM_DEPD_READY	BIT(1)
+#define CPU_PM_PLAT_READY	BIT(2)
+
+#ifdef CPU_PM_TINYSYS_SUPPORT
+#define CPU_PM_INIT_READY	(CPU_PM_DEPD_INIT | CPU_PM_DEPD_READY)
+#define CPU_PM_LP_READY		(CPU_PM_INIT_READY | CPU_PM_PLAT_READY)
+#else
+#define CPU_PM_LP_READY		(CPU_PM_PLAT_READY)
+#endif
+
+#if CONFIG_MTK_PM_SUPPORT
+
+#if CONFIG_MTK_CPU_SUSPEND_EN || CONFIG_MTK_SMP_EN
+static void cpupm_cpu_resume_common(const struct mtk_cpupm_pwrstate *state)
+{
+	CPU_PM_ASSERT(state != NULL);
+	mtk_cpc_core_on_hint_clr(state->info.cpuid);
+}
+#endif
+
+#if CONFIG_MTK_SMP_EN
+static int cpupm_cpu_pwr_on_prepare(unsigned int cpu, uintptr_t entry)
+{
+	struct cpu_pwr_ctrl pwr_ctrl;
+
+	PER_CPU_PWR_CTRL(pwr_ctrl, cpu);
+	mt_smp_core_bootup_address_set(&pwr_ctrl, entry);
+	mt_smp_core_init_arch(0, cpu, 1, &pwr_ctrl);
+
+	return mt_smp_power_core_on(cpu, &pwr_ctrl);
+}
+
+static void cpupm_cpu_resume_smp(const struct mtk_cpupm_pwrstate *state)
+{
+	CPU_PM_ASSERT(state != NULL);
+
+	plat_cpu_pm_lock();
+	mmio_clrbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
+			GIC_WAKEUP_IGNORE(state->info.cpuid));
+	plat_cpu_pm_unlock();
+	cpupm_cpu_resume_common(state);
+}
+
+static void cpupm_cpu_suspend_smp(const struct mtk_cpupm_pwrstate *state)
+{
+	struct cpu_pwr_ctrl pwr_ctrl;
+
+	CPU_PM_ASSERT(state != NULL);
+
+	PER_CPU_PWR_CTRL(pwr_ctrl, state->info.cpuid);
+	mt_smp_power_core_off(&pwr_ctrl);
+	mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
+			GIC_WAKEUP_IGNORE(state->info.cpuid));
+}
+
+static void cpupm_smp_init(unsigned int cpu, uintptr_t sec_entrypoint)
+{
+	unsigned int reg;
+	struct mtk_cpupm_pwrstate state = {
+		.info = {
+			.cpuid = cpu,
+			.mode = MTK_CPU_PM_SMP,
+		},
+		.pwr = {
+			.afflv = 0,
+			.state_id = 0,
+		},
+	};
+
+	reg = mmio_read_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG);
+	if ((reg & CPC_MCUSYS_CPC_RESET_PWR_ON_EN) != 0) {
+		INFO("[%s:%d][CPU_PM] reset pwr on is enabled then clear it!\n",
+		     __func__, __LINE__);
+		mmio_clrbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_MCUSYS_CPC_RESET_PWR_ON_EN);
+	}
+
+	cpupm_cpu_pwr_on_prepare(cpu, sec_entrypoint);
+	cpupm_cpu_resume_smp(&state);
+}
+
+static struct mtk_cpu_smp_ops cpcv3_2_cpu_smp = {
+	.init = cpupm_smp_init,
+	.cpu_pwr_on_prepare = cpupm_cpu_pwr_on_prepare,
+	.cpu_on = cpupm_cpu_resume_smp,
+	.cpu_off = cpupm_cpu_suspend_smp,
+};
+
+#endif /* CONFIG_MTK_SMP_EN */
+
+#if CONFIG_MTK_CPU_SUSPEND_EN
+#define CPUPM_READY_MS		(40000)
+#define CPUPM_ARCH_TIME_MS(ms)	(ms * 1000 * SYS_COUNTER_FREQ_IN_MHZ)
+#define CPUPM_BOOTUP_TIME_THR	CPUPM_ARCH_TIME_MS(CPUPM_READY_MS)
+
+static int mt_pwr_nodes[MT_PWR_MAX];
+static int plat_mt_lp_cpu_rc;
+static unsigned int cpu_pm_status;
+static unsigned int plat_prev_stateid;
+
+static int mcusys_prepare_suspend(const struct mtk_cpupm_pwrstate *state)
+{
+	unsigned int stateid = state->pwr.state_id;
+
+	if (mtk_cpc_mcusys_off_prepare() != CPC_SUCCESS) {
+		goto mt_pwr_mcusysoff_break;
+	}
+
+	if (!IS_PLAT_SUSPEND_ID(stateid)) {
+		if (mt_pwr_nodes[MT_PWR_SYSTEM_MEM] != 0) {
+			stateid = MT_PLAT_PWR_STATE_SYSTEM_MEM;
+		} else if (mt_pwr_nodes[MT_PWR_SYSTEM_PLL] != 0) {
+			stateid = MT_PLAT_PWR_STATE_SYSTEM_PLL;
+		} else if (mt_pwr_nodes[MT_PWR_SYSTEM_BUS] != 0) {
+			stateid = MT_PLAT_PWR_STATE_SYSTEM_BUS;
+		} else if (mt_pwr_nodes[MT_PWR_SUSPEND] != 0) {
+			stateid = MT_PLAT_PWR_STATE_SUSPEND;
+		} else {
+			stateid = MT_PLAT_PWR_STATE_MCUSYS;
+		}
+	}
+
+	plat_prev_stateid = stateid;
+	plat_mt_lp_cpu_rc = mt_lp_rm_find_and_run_constraint(0, state->info.cpuid, stateid, NULL);
+
+	if (plat_mt_lp_cpu_rc < 0) {
+		goto mt_pwr_mcusysoff_reflect;
+	}
+
+#ifdef CPU_PM_TINYSYS_SUPPORT
+	mtk_set_cpu_pm_preffered_cpu(state->info.cpuid);
+#endif
+	return MTK_CPUPM_E_OK;
+
+mt_pwr_mcusysoff_reflect:
+	mtk_cpc_mcusys_off_reflect();
+mt_pwr_mcusysoff_break:
+	plat_mt_lp_cpu_rc = -1;
+
+	return MTK_CPUPM_E_FAIL;
+}
+
+static int mcusys_prepare_resume(const struct mtk_cpupm_pwrstate *state)
+{
+	if (plat_mt_lp_cpu_rc < 0) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+	mt_lp_rm_reset_constraint(plat_mt_lp_cpu_rc, state->info.cpuid, plat_prev_stateid);
+	mtk_cpc_mcusys_off_reflect();
+	return MTK_CPUPM_E_OK;
+}
+
+static unsigned int cpupm_do_pstate_off(const mtk_pstate_type psci_state,
+					const struct mtk_cpupm_pwrstate *state)
+{
+	unsigned int pstate = MT_CPUPM_PWR_DOMAIN_CORE;
+
+	if (!state || (state->pwr.afflv > PLAT_MAX_PWR_LVL)) {
+		CPU_PM_ASSERT(0);
+	}
+
+	switch (state->pwr.state_id) {
+	case MT_PLAT_PWR_STATE_SYSTEM_MEM:
+		mt_pwr_nodes[MT_PWR_SYSTEM_MEM] += 1;
+		break;
+	case MT_PLAT_PWR_STATE_SYSTEM_PLL:
+		mt_pwr_nodes[MT_PWR_SYSTEM_PLL] += 1;
+		break;
+	case MT_PLAT_PWR_STATE_SYSTEM_BUS:
+		mt_pwr_nodes[MT_PWR_SYSTEM_BUS] += 1;
+		break;
+	case MT_PLAT_PWR_STATE_SUSPEND:
+		mt_pwr_nodes[MT_PWR_SUSPEND] += 1;
+		break;
+	default:
+		if (!IS_MT_PLAT_PWR_STATE_MCUSYS(state->pwr.state_id) &&
+		    !IS_PLAT_SYSTEM_SUSPEND(state->pwr.afflv)) {
+			plat_cpu_pm_lock();
+			mt_pwr_nodes[MT_PWR_NONMCUSYS] += 1;
+			flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_NONMCUSYS],
+					   sizeof(mt_pwr_nodes[MT_PWR_NONMCUSYS]));
+			plat_cpu_pm_unlock();
+		}
+		break;
+	}
+
+	if ((mt_pwr_nodes[MT_PWR_NONMCUSYS] == 0) && IS_PLAT_MCUSYSOFF_AFFLV(state->pwr.afflv)) {
+		/* Prepare to power down mcusys */
+		if (mcusys_prepare_suspend(state) == MTK_CPUPM_E_OK) {
+			mt_pwr_nodes[MT_PWR_MCUSYS_PDN] += 1;
+			flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_MCUSYS_PDN],
+					   sizeof(mt_pwr_nodes[MT_PWR_MCUSYS_PDN]));
+			pstate |= (MT_CPUPM_PWR_DOMAIN_MCUSYS | MT_CPUPM_PWR_DOMAIN_CLUSTER);
+		}
+	}
+
+	if (state->pwr.afflv >= PLAT_MT_CPU_SUSPEND_CLUSTER) {
+		pstate |= MT_CPUPM_PWR_DOMAIN_CLUSTER;
+	}
+
+	if (psci_get_pstate_pwrlvl(psci_state) >= PLAT_MT_CPU_SUSPEND_CLUSTER) {
+		pstate |= MT_CPUPM_PWR_DOMAIN_PERCORE_DSU;
+	}
+
+	return pstate;
+}
+
+static unsigned int cpupm_do_pstate_on(const mtk_pstate_type psci_state,
+				       const struct mtk_cpupm_pwrstate *state)
+{
+	unsigned int pstate = MT_CPUPM_PWR_DOMAIN_CORE;
+
+	CPU_PM_ASSERT(state != NULL);
+
+	if (state->pwr.afflv > PLAT_MAX_PWR_LVL) {
+		CPU_PM_ASSERT(0);
+	}
+
+	if (mt_pwr_nodes[MT_PWR_MCUSYS_PDN] != 0) {
+		mt_pwr_nodes[MT_PWR_MCUSYS_PDN] = 0;
+		flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_MCUSYS_PDN],
+				   sizeof(mt_pwr_nodes[MT_PWR_MCUSYS_PDN]));
+		pstate |= (MT_CPUPM_PWR_DOMAIN_MCUSYS | MT_CPUPM_PWR_DOMAIN_CLUSTER);
+		mcusys_prepare_resume(state);
+	}
+
+	if (state->pwr.afflv >= PLAT_MT_CPU_SUSPEND_CLUSTER) {
+		pstate |= MT_CPUPM_PWR_DOMAIN_CLUSTER;
+	}
+
+	switch (state->pwr.state_id) {
+	case MT_PLAT_PWR_STATE_SYSTEM_MEM:
+		mt_pwr_nodes[MT_PWR_SYSTEM_MEM] -= 1;
+		CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SYSTEM_MEM] >= 0);
+		break;
+	case MT_PLAT_PWR_STATE_SYSTEM_PLL:
+		mt_pwr_nodes[MT_PWR_SYSTEM_PLL] -= 1;
+		CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SYSTEM_PLL] >= 0);
+		break;
+	case MT_PLAT_PWR_STATE_SYSTEM_BUS:
+		mt_pwr_nodes[MT_PWR_SYSTEM_BUS] -= 1;
+		CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SYSTEM_BUS] >= 0);
+		break;
+	case MT_PLAT_PWR_STATE_SUSPEND:
+		mt_pwr_nodes[MT_PWR_SUSPEND] -= 1;
+		CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SUSPEND] >= 0);
+		break;
+	default:
+		if (!IS_MT_PLAT_PWR_STATE_MCUSYS(state->pwr.state_id) &&
+		    !IS_PLAT_SYSTEM_SUSPEND(state->pwr.afflv)) {
+			plat_cpu_pm_lock();
+			mt_pwr_nodes[MT_PWR_NONMCUSYS] -= 1;
+			flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_NONMCUSYS],
+					   sizeof(mt_pwr_nodes[MT_PWR_NONMCUSYS]));
+			plat_cpu_pm_unlock();
+		}
+		break;
+	}
+
+	if (IS_PLAT_SYSTEM_SUSPEND(state->pwr.afflv) ||
+	    (IS_PLAT_SYSTEM_RETENTION(state->pwr.afflv) && (mt_pwr_nodes[MT_PWR_SUSPEND] > 0))) {
+		mtk_cpc_time_sync();
+	}
+
+	if (mt_pwr_nodes[MT_PWR_NONMCUSYS] < 0) {
+		CPU_PM_ASSERT(0);
+	}
+
+	pstate |= MT_CPUPM_PWR_DOMAIN_PERCORE_DSU;
+
+	return pstate;
+}
+
+static void cpupm_cpu_resume(const struct mtk_cpupm_pwrstate *state)
+{
+	cpupm_cpu_resume_common(state);
+}
+
+static void cpupm_mcusys_resume(const struct mtk_cpupm_pwrstate *state)
+{
+	assert(state != NULL);
+}
+
+static void cpupm_mcusys_suspend(const struct mtk_cpupm_pwrstate *state)
+{
+	assert(state != NULL);
+}
+
+static unsigned int cpupm_get_pstate(enum mt_cpupm_pwr_domain domain,
+				     const mtk_pstate_type psci_state,
+				     const struct mtk_cpupm_pwrstate *state)
+{
+	unsigned int pstate = 0;
+
+	if (state == NULL) {
+		return 0;
+	}
+
+	if (state->info.mode == MTK_CPU_PM_SMP) {
+		pstate = MT_CPUPM_PWR_DOMAIN_CORE;
+	} else {
+		if (domain == CPUPM_PWR_OFF) {
+			pstate = cpupm_do_pstate_off(psci_state, state);
+		} else if (domain == CPUPM_PWR_ON) {
+			pstate = cpupm_do_pstate_on(psci_state, state);
+		} else {
+			INFO("[%s:%d][CPU_PM] unknown pwr domain :%d\n",
+			     __func__, __LINE__, domain);
+			assert(0);
+		}
+	}
+	return pstate;
+}
+
+static int cpupm_init(void)
+{
+	int ret = MTK_CPUPM_E_OK;
+
+#ifdef CPU_PM_TINYSYS_SUPPORT
+	int status;
+
+	if ((cpu_pm_status & CPU_PM_INIT_READY) == CPU_PM_INIT_READY) {
+		return MTK_CPUPM_E_OK;
+	}
+
+	if (!(cpu_pm_status & CPU_PM_DEPD_INIT)) {
+		status = mtk_lp_depd_condition(CPUPM_MBOX_WAIT_DEV_INIT);
+		if (status == 0) {
+			plat_cpu_pm_lock();
+			cpu_pm_status |= CPU_PM_DEPD_INIT;
+			plat_cpu_pm_unlock();
+		}
+	}
+
+	if ((cpu_pm_status & CPU_PM_DEPD_INIT) && !(cpu_pm_status & CPU_PM_DEPD_READY)) {
+		status = mtk_lp_depd_condition(CPUPM_MBOX_WAIT_TASK_READY);
+		if (status == 0) {
+			plat_cpu_pm_lock();
+			cpu_pm_status |= CPU_PM_DEPD_READY;
+			plat_cpu_pm_unlock();
+		}
+	}
+
+	ret = ((cpu_pm_status & CPU_PM_INIT_READY) == CPU_PM_INIT_READY) ?
+	      MTK_CPUPM_E_OK : MTK_CPUPM_E_FAIL;
+#endif
+	return ret;
+}
+
+static int cpupm_pwr_state_valid(unsigned int afflv, unsigned int state)
+{
+	if (cpu_pm_status == CPU_PM_LP_READY) {
+		return MTK_CPUPM_E_OK;
+	}
+
+	if (cpupm_init() != MTK_CPUPM_E_OK) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+	if (read_cntpct_el0() >= (uint64_t)CPUPM_BOOTUP_TIME_THR) {
+		plat_cpu_pm_lock();
+		cpu_pm_status |= CPU_PM_PLAT_READY;
+		plat_cpu_pm_unlock();
+	}
+
+	if (!IS_PLAT_SYSTEM_SUSPEND(afflv) && (cpu_pm_status & CPU_PM_PLAT_READY) == 0) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+	return MTK_CPUPM_E_OK;
+}
+
+static struct mtk_cpu_pm_ops cpcv3_2_mcdi = {
+	.get_pstate = cpupm_get_pstate,
+	.pwr_state_valid = cpupm_pwr_state_valid,
+	.cpu_resume = cpupm_cpu_resume,
+	.mcusys_suspend = cpupm_mcusys_suspend,
+	.mcusys_resume = cpupm_mcusys_resume,
+};
+#endif /* CONFIG_MTK_CPU_SUSPEND_EN */
+
+#endif /* CONFIG_MTK_PM_SUPPORT */
+
+/*
+ * Depend on mtk pm methodology, the psci op init must
+ * be invoked after cpu pm to avoid initialization fail.
+ */
+int mt_plat_cpu_pm_init(void)
+{
+	plat_cpu_pm_lock_init();
+
+	mtk_cpc_init();
+#if CONFIG_MTK_PM_SUPPORT
+
+#if CONFIG_MTK_CPU_SUSPEND_EN
+	register_cpu_pm_ops(CPU_PM_FN, &cpcv3_2_mcdi);
+#endif /* CONFIG_MTK_CPU_SUSPEND_EN */
+
+#if CONFIG_MTK_SMP_EN
+	register_cpu_smp_ops(CPU_PM_FN, &cpcv3_2_cpu_smp);
+#endif /* CONFIG_MTK_SMP_EN */
+
+#endif /* CONFIG_MTK_PM_SUPPORT */
+
+	INFO("[%s:%d] - CPU PM INIT finished\n", __func__, __LINE__);
+	return 0;
+}
+MTK_ARCH_INIT(mt_plat_cpu_pm_init);
+
+static const mmap_region_t cpu_pm_mmap[] MTK_MMAP_SECTION = {
+#ifdef CPU_PM_TINYSYS_SUPPORT
+#if CONFIG_MTK_PM_SUPPORT && CONFIG_MTK_CPU_SUSPEND_EN
+	MAP_REGION_FLAT(CPU_EB_TCM_BASE, CPU_EB_TCM_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+#endif
+#endif
+	{0}
+};
+DECLARE_MTK_MMAP_REGIONS(cpu_pm_mmap);
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.h
new file mode 100644
index 0000000..4d99df1
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_CPU_PM_H
+#define MT_CPU_PM_H
+
+#include <assert.h>
+#include <mcucfg.h>
+#include <platform_def.h>
+
+/*
+ * After ARM v8.2, the cache will turn off automatically when powering down CPU. Therefore, there
+ * is no doubt to use the spin_lock here.
+ */
+#if !HW_ASSISTED_COHERENCY
+#define MT_CPU_PM_USING_BAKERY_LOCK
+#endif
+
+#define CPU_PM_FN (MTK_CPUPM_FN_CPUPM_GET_PWR_STATE | \
+		   MTK_CPUPM_FN_PWR_STATE_VALID | \
+		   MTK_CPUPM_FN_PWR_ON_CORE_PREPARE | \
+		   MTK_CPUPM_FN_RESUME_CORE | \
+		   MTK_CPUPM_FN_SUSPEND_MCUSYS | \
+		   MTK_CPUPM_FN_RESUME_MCUSYS | \
+		   MTK_CPUPM_FN_SMP_INIT | \
+		   MTK_CPUPM_FN_SMP_CORE_ON | \
+		   MTK_CPUPM_FN_SMP_CORE_OFF)
+
+#define CPU_PM_ASSERT(_cond) ({ \
+	if (!(_cond)) { \
+		INFO("[%s:%d] - %s\n", __func__, __LINE__, #_cond); \
+		panic(); \
+	} })
+
+#define CPC_PWR_MASK_MCUSYS_MP0		(0xC001)
+
+#define PER_CPU_PWR_DATA(ctrl, cluster, core) \
+	do { \
+		ctrl.rvbaraddr_l = CORE_RVBRADDR_##cluster##_##core##_L; \
+		ctrl.arch_addr = MCUCFG_MP0_CLUSTER_CFG5; \
+		ctrl.pwpr = SPM_MP##cluster##_CPU##core##_PWR_CON; \
+	} while (0)
+
+#define PER_CPU_PWR_CTRL(ctrl, cpu) ({ \
+	switch (cpu) { \
+	case 0: \
+		PER_CPU_PWR_DATA(ctrl, 0, 0); \
+		break; \
+	case 1: \
+		PER_CPU_PWR_DATA(ctrl, 0, 1); \
+		break; \
+	case 2: \
+		PER_CPU_PWR_DATA(ctrl, 0, 2); \
+		break; \
+	case 3: \
+		PER_CPU_PWR_DATA(ctrl, 0, 3); \
+		break; \
+	case 4: \
+		PER_CPU_PWR_DATA(ctrl, 0, 4); \
+		break; \
+	case 5: \
+		PER_CPU_PWR_DATA(ctrl, 0, 5); \
+		break; \
+	case 6: \
+		PER_CPU_PWR_DATA(ctrl, 0, 6); \
+		break; \
+	case 7: \
+		PER_CPU_PWR_DATA(ctrl, 0, 7); \
+		break; \
+	default: \
+		assert(0); \
+		break; \
+	} })
+
+
+/* MCUSYS DREQ BIG VPROC ISO control */
+#define DREQ20_BIG_VPROC_ISO		(MCUCFG_BASE + 0xad8c)
+
+/* Definition about bootup address for each core CORE_RVBRADDR_clusterid_cpuid */
+#define CORE_RVBRADDR_0_0_L		(MCUCFG_BASE + 0xc900)
+#define CORE_RVBRADDR_0_1_L		(MCUCFG_BASE + 0xc908)
+#define CORE_RVBRADDR_0_2_L		(MCUCFG_BASE + 0xc910)
+#define CORE_RVBRADDR_0_3_L		(MCUCFG_BASE + 0xc918)
+#define CORE_RVBRADDR_0_4_L		(MCUCFG_BASE + 0xc920)
+#define CORE_RVBRADDR_0_5_L		(MCUCFG_BASE + 0xc928)
+#define CORE_RVBRADDR_0_6_L		(MCUCFG_BASE + 0xc930)
+#define CORE_RVBRADDR_0_7_L		(MCUCFG_BASE + 0xc938)
+#define MCUCFG_MP0_CLUSTER_CFG5		(MCUCFG_BASE + 0xc8e4)
+
+struct cpu_pwr_ctrl {
+	unsigned int rvbaraddr_l;
+	unsigned int arch_addr;
+	unsigned int pwpr;
+};
+
+#define MCUSYS_STATUS_PDN		BIT(0)
+#define MCUSYS_STATUS_CPUSYS_PROTECT	BIT(8)
+#define MCUSYS_STATUS_MCUSYS_PROTECT	BIT(9)
+
+/* cpu_pm function ID */
+enum mt_cpu_pm_user_id {
+	MCUSYS_STATUS,
+	CPC_COMMAND,
+};
+
+/* cpu_pm lp function ID */
+enum mt_cpu_pm_lp_smc_id {
+	LP_CPC_COMMAND,
+	IRQS_REMAIN_ALLOC,
+	IRQS_REMAIN_CTRL,
+	IRQS_REMAIN_IRQ,
+	IRQS_REMAIN_WAKEUP_CAT,
+	IRQS_REMAIN_WAKEUP_SRC,
+};
+
+#endif /* MT_CPU_PM_H */
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.c
new file mode 100644
index 0000000..4cc2203
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <drivers/delay_timer.h>
+
+#include "mt_cpu_pm.h"
+#include "mt_cpu_pm_cpc.h"
+#include "mt_smp.h"
+#include <mt_timer.h>
+
+struct mtk_cpc_dev {
+	int auto_off;
+	unsigned int auto_thres_tick;
+};
+
+static struct mtk_cpc_dev cpc;
+
+static int mtk_cpc_last_core_prot(int prot_req, int resp_reg, int resp_ofs)
+{
+	unsigned int staus;
+	unsigned int retry = 0;
+
+	while (retry < RETRY_CNT_MAX) {
+		retry++;
+
+		mmio_write_32(CPC_MCUSYS_LAST_CORE_REQ, prot_req);
+
+		udelay(1);
+
+		staus = (mmio_read_32(resp_reg) >> resp_ofs) & CPC_PROT_RESP_MASK;
+
+		if (staus == PROT_SUCCESS) {
+			return CPC_SUCCESS;
+		} else if (staus == PROT_GIVEUP) {
+			return CPC_ERR_FAIL;
+		}
+	}
+
+	return CPC_ERR_TIMEOUT;
+}
+
+static int mtk_cpu_pm_mcusys_prot_aquire(void)
+{
+	return mtk_cpc_last_core_prot(MCUSYS_PROT_SET, CPC_MCUSYS_LAST_CORE_RESP, MCUSYS_RESP_OFS);
+}
+
+static void mtk_cpu_pm_mcusys_prot_release(void)
+{
+	mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, MCUSYS_PROT_CLR);
+}
+
+int mtk_cpu_pm_cluster_prot_aquire(void)
+{
+	return mtk_cpc_last_core_prot(CPUSYS_PROT_SET, CPC_MCUSYS_MP_LAST_CORE_RESP,
+				      CPUSYS_RESP_OFS);
+}
+
+void mtk_cpu_pm_cluster_prot_release(void)
+{
+	mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, CPUSYS_PROT_CLR);
+}
+
+static void mtk_cpc_cluster_cnt_backup(void)
+{
+	/* single cluster */
+	uint32_t backup_cnt = mmio_read_32(CPC_CLUSTER_CNT_BACKUP);
+	uint32_t curr_cnt = mmio_read_32(CPC_MCUSYS_CLUSTER_COUNTER);
+
+	if ((curr_cnt & 0x7fff) == 0) {
+		curr_cnt = (curr_cnt >> 16) & 0x7fff;
+	} else {
+		curr_cnt = curr_cnt & 0x7fff;
+	}
+
+	mmio_write_32(CPC_CLUSTER_CNT_BACKUP, backup_cnt + curr_cnt);
+	mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, 0x3);
+}
+
+static inline void mtk_cpc_mcusys_off_enable(bool enable)
+{
+	mmio_write_32(CPC_MCUSYS_PWR_CTRL, enable ? 1 : 0);
+}
+
+void mtk_cpc_mcusys_off_reflect(void)
+{
+	mtk_cpc_mcusys_off_enable(false);
+	mtk_cpu_pm_mcusys_prot_release();
+}
+
+int mtk_cpc_mcusys_off_prepare(void)
+{
+	if (mtk_cpu_pm_mcusys_prot_aquire() != CPC_SUCCESS) {
+		return CPC_ERR_FAIL;
+	}
+
+	mtk_cpc_cluster_cnt_backup();
+	mtk_cpc_mcusys_off_enable(true);
+
+	return CPC_SUCCESS;
+}
+
+void mtk_cpc_core_on_hint_set(int cpu)
+{
+	mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_SET, BIT(cpu));
+}
+
+void mtk_cpc_core_on_hint_clr(int cpu)
+{
+	mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_CLR, BIT(cpu));
+}
+
+static void mtk_cpc_dump_timestamp(void)
+{
+	unsigned int id;
+
+	for (id = 0; id < CPC_TRACE_ID_NUM; id++) {
+		mmio_write_32(CPC_MCUSYS_TRACE_SEL, id);
+
+		memcpy((void *)(uintptr_t)CPC_TRACE_SRAM(id),
+		       (const void *)(uintptr_t)CPC_MCUSYS_TRACE_DATA,
+		       CPC_TRACE_SIZE);
+	}
+}
+
+void mtk_cpc_time_sync(void)
+{
+	uint64_t kt;
+	uint32_t systime_l, systime_h;
+
+	kt = sched_clock();
+	systime_l = mmio_read_32(CNTSYS_L_REG);
+	systime_h = mmio_read_32(CNTSYS_H_REG);
+
+	/* sync kernel timer to cpc */
+	mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE, (uint32_t)kt);
+	mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE, (uint32_t)(kt >> 32));
+
+	/* sync system timer to cpc */
+	mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE, systime_l);
+	mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE, systime_h);
+}
+
+static void mtk_cpc_config(unsigned int cfg, unsigned int data)
+{
+	switch (cfg) {
+	case CPC_SMC_CONFIG_PROF:
+		if (data) {
+			mmio_setbits_32(CPC_MCUSYS_CPC_DBG_SETTING, CPC_PROF_EN);
+		} else {
+			mmio_clrbits_32(CPC_MCUSYS_CPC_DBG_SETTING, CPC_PROF_EN);
+		}
+		break;
+	case CPC_SMC_CONFIG_AUTO_OFF:
+		if (data) {
+			mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_AUTO_OFF_EN);
+			cpc.auto_off = 1;
+		} else {
+			mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_AUTO_OFF_EN);
+			cpc.auto_off = 0;
+		}
+		break;
+	case CPC_SMC_CONFIG_AUTO_OFF_THRES:
+		cpc.auto_thres_tick = US_TO_TICKS(data);
+		mmio_write_32(CPC_MCUSYS_CPC_OFF_THRES, cpc.auto_thres_tick);
+		break;
+	case CPC_SMC_CONFIG_CNT_CLR:
+		mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, 0x3);
+		break;
+	case CPC_SMC_CONFIG_TIME_SYNC:
+		mtk_cpc_time_sync();
+		break;
+	default:
+		break;
+	}
+}
+
+static unsigned int mtk_cpc_read_config(unsigned int cfg)
+{
+	unsigned int res = 0;
+
+	switch (cfg) {
+	case CPC_SMC_CONFIG_PROF:
+		res = (mmio_read_32(CPC_MCUSYS_CPC_DBG_SETTING) & CPC_PROF_EN) ? 1 : 0;
+		break;
+	case CPC_SMC_CONFIG_AUTO_OFF:
+		res = cpc.auto_off;
+		break;
+	case CPC_SMC_CONFIG_AUTO_OFF_THRES:
+		res = TICKS_TO_US(cpc.auto_thres_tick);
+		break;
+	case CPC_SMC_CONFIG_CNT_CLR:
+	default:
+		break;
+	}
+
+	return res;
+}
+
+uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2)
+{
+	uint64_t res = 0;
+
+	switch (act) {
+	case CPC_SMC_EVENT_CPC_CONFIG:
+		mtk_cpc_config((unsigned int)arg1, (unsigned int)arg2);
+		break;
+	case CPC_SMC_EVENT_READ_CONFIG:
+		res = mtk_cpc_read_config((unsigned int)arg1);
+		break;
+	case CPC_SMC_EVENT_GIC_DPG_SET:
+		/* isolated_status = x2; */
+	default:
+		break;
+	}
+
+	return res;
+}
+
+uint64_t mtk_cpc_trace_dump(uint64_t act, uint64_t arg1, uint64_t arg2)
+{
+	switch (act) {
+	case CPC_SMC_EVENT_DUMP_TRACE_DATA:
+		mtk_cpc_dump_timestamp();
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+void mtk_cpc_init(void)
+{
+#if CONFIG_MTK_SMP_EN
+	mt_smp_init();
+#endif
+	mmio_setbits_32(CPC_MCUSYS_CPC_DBG_SETTING, (CPC_DBG_EN | CPC_CALC_EN));
+
+	cpc.auto_off = 1;
+	mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, (CPC_OFF_PRE_EN |
+						      ((cpc.auto_off > 0) ? CPC_AUTO_OFF_EN : 0)));
+
+	mtk_cpc_config(CPC_SMC_CONFIG_AUTO_OFF_THRES, 8000);
+
+	/* enable CPC */
+	mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_CTRL_ENABLE);
+	mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, SSPM_CORE_PWR_ON_EN);
+}
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.h
new file mode 100644
index 0000000..3004f41
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_CPU_PM_CPC_H
+#define MT_CPU_PM_CPC_H
+
+#include <lib/mmio.h>
+
+#include <mcucfg.h>
+#include <platform_def.h>
+
+#define NEED_CPUSYS_PROT_WORKAROUND	(1)
+
+/* system sram registers */
+#define CPUIDLE_SRAM_REG(r)	(CPU_IDLE_SRAM_BASE + (r))
+
+/* db dump */
+#define CPC_TRACE_SIZE		(0x20)
+#define CPC_TRACE_ID_NUM	(10)
+#define CPC_TRACE_SRAM(id)	(CPUIDLE_SRAM_REG(0x10) + (id) * CPC_TRACE_SIZE)
+
+/* buckup off count */
+#define CPC_CLUSTER_CNT_BACKUP	CPUIDLE_SRAM_REG(0x1f0)
+#define CPC_MCUSYS_CNT		CPUIDLE_SRAM_REG(0x1f4)
+
+/* CPC_MCUSYS_CPC_FLOW_CTRL_CFG (0xA814): debug setting */
+#define CPC_PWR_ON_SEQ_DIS	BIT(1)
+#define CPC_PWR_ON_PRIORITY	BIT(2)
+#define CPC_AUTO_OFF_EN		BIT(5)
+#define CPC_DORMANT_WAIT_EN	BIT(14)
+#define CPC_CTRL_EN		BIT(16)
+#define CPC_OFF_PRE_EN		BIT(29)
+
+/* CPC_MCUSYS_LAST_CORE_REQ (0xA818) : last core protection */
+#define CPUSYS_PROT_SET		BIT(0)
+#define MCUSYS_PROT_SET		BIT(8)
+#define CPUSYS_PROT_CLR		BIT(8)
+#define MCUSYS_PROT_CLR		BIT(9)
+
+#define CPC_PROT_RESP_MASK	(0x3)
+#define CPUSYS_RESP_OFS		(16)
+#define MCUSYS_RESP_OFS		(30)
+
+#define RETRY_CNT_MAX		(1000)
+
+#define PROT_RETRY		(0)
+#define PROT_SUCCESS		(1)
+#define PROT_GIVEUP		(2)
+
+/* CPC_MCUSYS_CPC_DBG_SETTING (0xAB00): debug setting */
+#define CPC_PROF_EN		BIT(0)
+#define CPC_DBG_EN		BIT(1)
+#define CPC_FREEZE		BIT(2)
+#define CPC_CALC_EN		BIT(3)
+
+enum mcusys_cpc_lastcore_prot_status {
+	CPC_SUCCESS = 0,
+	CPC_ERR_FAIL,
+	CPC_ERR_TIMEOUT,
+	NF_CPC_ERR,
+};
+
+enum mcusys_cpc_smc_events {
+	CPC_SMC_EVENT_DUMP_TRACE_DATA,
+	CPC_SMC_EVENT_GIC_DPG_SET,
+	CPC_SMC_EVENT_CPC_CONFIG,
+	CPC_SMC_EVENT_READ_CONFIG,
+	NF_CPC_SMC_EVENT,
+};
+
+enum mcusys_cpc_smc_config {
+	CPC_SMC_CONFIG_PROF,
+	CPC_SMC_CONFIG_AUTO_OFF,
+	CPC_SMC_CONFIG_AUTO_OFF_THRES,
+	CPC_SMC_CONFIG_CNT_CLR,
+	CPC_SMC_CONFIG_TIME_SYNC,
+	NF_CPC_SMC_CONFIG,
+};
+
+#define US_TO_TICKS(us)		((us) * 13)
+#define TICKS_TO_US(tick)	((tick) / 13)
+
+int mtk_cpu_pm_cluster_prot_aquire(void);
+void mtk_cpu_pm_cluster_prot_release(void);
+
+void mtk_cpc_mcusys_off_reflect(void);
+int mtk_cpc_mcusys_off_prepare(void);
+
+void mtk_cpc_core_on_hint_set(int cpu);
+void mtk_cpc_core_on_hint_clr(int cpu);
+void mtk_cpc_time_sync(void);
+
+uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2);
+uint64_t mtk_cpc_trace_dump(uint64_t act, uint64_t arg1, uint64_t arg2);
+void mtk_cpc_init(void);
+
+#endif /* MT_CPU_PM_CPC_H */
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.c
new file mode 100644
index 0000000..4d67e7b
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <lib/mmio.h>
+
+#include "mt_cpu_pm_mbox.h"
+#include <platform_def.h>
+
+#ifdef __GNUC__
+#define MCDI_LIKELY(x)		__builtin_expect(!!(x), 1)
+#define MCDI_UNLIKELY(x)	__builtin_expect(!!(x), 0)
+#else
+#define MCDI_LIKELY(x)		(x)
+#define MCDI_UNLIKELY(x)	(x)
+#endif
+
+#define MCUPM_MBOX_3_BASE		(CPU_EB_TCM_BASE + CPU_EB_MBOX3_OFFSET)
+#define MCUPM_MBOX_WRITE(id, val)	mmio_write_32(MCUPM_MBOX_3_BASE + 4 * (id), val)
+#define MCUPM_MBOX_READ(id)		mmio_read_32(MCUPM_MBOX_3_BASE + 4 * (id))
+
+void mtk_set_mcupm_pll_mode(unsigned int mode)
+{
+	if (mode < NF_MCUPM_ARMPLL_MODE) {
+		MCUPM_MBOX_WRITE(MCUPM_MBOX_ARMPLL_MODE, mode);
+	}
+}
+
+int mtk_get_mcupm_pll_mode(void)
+{
+	return MCUPM_MBOX_READ(MCUPM_MBOX_ARMPLL_MODE);
+}
+
+void mtk_set_mcupm_buck_mode(unsigned int mode)
+{
+	if (mode < NF_MCUPM_BUCK_MODE) {
+		MCUPM_MBOX_WRITE(MCUPM_MBOX_BUCK_MODE, mode);
+	}
+}
+
+int mtk_get_mcupm_buck_mode(void)
+{
+	return MCUPM_MBOX_READ(MCUPM_MBOX_BUCK_MODE);
+}
+
+void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid)
+{
+	return MCUPM_MBOX_WRITE(MCUPM_MBOX_WAKEUP_CPU, cpuid);
+}
+
+unsigned int mtk_get_cpu_pm_preffered_cpu(void)
+{
+	return MCUPM_MBOX_READ(MCUPM_MBOX_WAKEUP_CPU);
+}
+
+static int mtk_wait_mbox_init_done(void)
+{
+	int status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA);
+
+	if (status != MCUPM_TASK_INIT) {
+		return status;
+	}
+
+	mtk_set_mcupm_pll_mode(MCUPM_ARMPLL_OFF);
+	mtk_set_mcupm_buck_mode(MCUPM_BUCK_OFF_MODE);
+
+	MCUPM_MBOX_WRITE(MCUPM_MBOX_PWR_CTRL_EN, (MCUPM_MCUSYS_CTRL | MCUPM_CM_CTRL |
+						 MCUPM_BUCK_CTRL | MCUPM_ARMPLL_CTRL));
+
+	return status;
+}
+
+int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type)
+{
+	int status;
+
+	if (type == CPUPM_MBOX_WAIT_DEV_INIT) {
+		status = mtk_wait_mbox_init_done();
+		if (MCDI_UNLIKELY(status != MCUPM_TASK_INIT)) {
+			return -ENXIO;
+		}
+		MCUPM_MBOX_WRITE(MCUPM_MBOX_AP_READY, 1);
+	} else if (type == CPUPM_MBOX_WAIT_TASK_READY) {
+		status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA);
+		if (MCDI_UNLIKELY((status != MCUPM_TASK_WAIT) &&
+				  (status != MCUPM_TASK_INIT_FINISH))) {
+			return -ENXIO;
+		}
+	}
+	return 0;
+}
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.h
new file mode 100644
index 0000000..72be6bd
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_CPU_PM_MBOX_H
+#define MT_CPU_PM_MBOX_H
+
+#include <lib/utils_def.h>
+
+/* MCUPM Mbox */
+/* AP Write */
+#define MCUPM_MBOX_AP_READY		(0)
+#define MCUPM_MBOX_RESERVED_1		(1)
+#define MCUPM_MBOX_RESERVED_2		(2)
+#define MCUPM_MBOX_RESERVED_3		(3)
+#define MCUPM_MBOX_PWR_CTRL_EN		(4)
+#define MCUPM_MBOX_L3_CACHE_MODE	(5)
+#define MCUPM_MBOX_BUCK_MODE		(6)
+#define MCUPM_MBOX_ARMPLL_MODE		(7)
+/* AP Read */
+#define MCUPM_MBOX_TASK_STA		(8)
+#define MCUPM_MBOX_RESERVED_9		(9)
+#define MCUPM_MBOX_RESERVED_10		(10)
+#define MCUPM_MBOX_RESERVED_11		(11)
+#define MCUPM_MBOX_WAKEUP_CPU		(12)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_PWR_CTRL_EN (4) */
+#define MCUPM_MCUSYS_CTRL		BIT(0)
+#define MCUPM_BUCK_CTRL			BIT(1)
+#define MCUPM_ARMPLL_CTRL		BIT(2)
+#define MCUPM_CM_CTRL			BIT(3)
+#define MCUPM_PWR_CTRL_MASK		(BIT(3) - 1)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_L3_CACHE_MODE (5) */
+#define MCUPM_L3_OFF_MODE		(0) /* default */
+#define MCUPM_L3_DORMANT_MODE		(1)
+#define NF_MCUPM_L3_MODE		(2)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_BUCK_MODE (6) */
+#define MCUPM_BUCK_NORMAL_MODE		(0) /* default */
+#define MCUPM_BUCK_LP_MODE		(1)
+#define MCUPM_BUCK_OFF_MODE		(2)
+#define NF_MCUPM_BUCK_MODE		(3)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_ARMPLL_MODE (7) */
+#define MCUPM_ARMPLL_ON			(0) /* default */
+#define MCUPM_ARMPLL_GATING		(1)
+#define MCUPM_ARMPLL_OFF		(2)
+#define NF_MCUPM_ARMPLL_MODE		(3)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_TASK_STA (9) */
+#define MCUPM_TASK_UNINIT		(0)
+#define MCUPM_TASK_INIT			(1)
+#define MCUPM_TASK_INIT_FINISH		(2)
+#define MCUPM_TASK_WAIT			(3)
+#define MCUPM_TASK_RUN			(4)
+#define MCUPM_TASK_PAUSE		(5)
+
+
+void mtk_set_mcupm_pll_mode(unsigned int mode);
+int mtk_get_mcupm_pll_mode(void);
+
+void mtk_set_mcupm_buck_mode(unsigned int mode);
+int mtk_get_mcupm_buck_mode(void);
+
+void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid);
+unsigned int mtk_get_cpu_pm_preffered_cpu(void);
+
+enum cpupm_mbox_depd_type {
+	CPUPM_MBOX_WAIT_DEV_INIT,
+	CPUPM_MBOX_WAIT_TASK_READY,
+};
+
+int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type);
+
+#endif /* MT_CPU_PM_MBOX_H */
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c
new file mode 100644
index 0000000..a1d9c31
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <plat/common/platform.h>
+
+#include <lib/pm/mtk_pm.h>
+#include <mcucfg.h>
+#include "mt_cpu_pm.h"
+#include "mt_smp.h"
+
+static inline int is_core_power_status_on(unsigned int cpuid)
+{
+	return !!(mmio_read_32(CPU_PWR_STATUS) & BIT(cpuid));
+}
+
+void mt_smp_core_init_arch(unsigned int cluster, unsigned int cpu, int arm64,
+			   struct cpu_pwr_ctrl *pwr_ctrl)
+{
+	CPU_PM_ASSERT(cluster == 0);
+	CPU_PM_ASSERT(pwr_ctrl != NULL);
+
+	/* aa64naa32 in bits[16:23] */
+	if (arm64 != 0) {
+		mmio_setbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu));
+	} else {
+		mmio_clrbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu));
+	}
+}
+
+void mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl *pwr_ctrl, uintptr_t entry)
+{
+	CPU_PM_ASSERT(pwr_ctrl != NULL);
+
+	/* Set bootup address */
+	mmio_write_32(pwr_ctrl->rvbaraddr_l, entry);
+}
+
+int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl)
+{
+	unsigned int val = is_core_power_status_on(cpu_id);
+
+	CPU_PM_ASSERT(pwr_ctrl);
+
+	mmio_clrbits_32(pwr_ctrl->pwpr, RESETPWRON_CONFIG);
+	if (val == 0) {
+		/*
+		 * Set to 0 after BIG VPROC bulk powered on (configure in MCUPM) and
+		 * before big core power-on sequence.
+		 */
+		if (cpu_id >= PLAT_CPU_PM_B_BUCK_ISO_ID) {
+			mmio_write_32(DREQ20_BIG_VPROC_ISO, 0);
+		}
+
+		mmio_setbits_32(pwr_ctrl->pwpr, PWR_RST_B);
+		dsbsy();
+
+		/* set mp0_spmc_pwr_on_cpuX = 1 */
+		mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON);
+
+		val = 0;
+		while (is_core_power_status_on(cpu_id) == 0) {
+			DO_SMP_CORE_ON_WAIT_TIMEOUT(val);
+			mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON);
+			mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON);
+		}
+	} else {
+		INFO("[%s:%d] - core_%u haven been power on\n", __func__, __LINE__, cpu_id);
+	}
+
+	return MTK_CPUPM_E_OK;
+}
+
+int mt_smp_power_core_off(struct cpu_pwr_ctrl *pwr_ctrl)
+{
+	/* set mp0_spmc_pwr_on_cpuX = 1 */
+	mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON);
+	return MTK_CPUPM_E_OK;
+}
+
+void mt_smp_init(void)
+{
+	/* clear RESETPWRON_CONFIG of mcusys/cluster/core0 */
+	mmio_clrbits_32(SPM_MCUSYS_PWR_CON, RESETPWRON_CONFIG);
+	mmio_clrbits_32(SPM_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG);
+}
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.h
new file mode 100644
index 0000000..4c2f8d2
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SMP_H
+#define MT_SMP_H
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define CPU_PWR_STATUS			(MCUCFG_BASE + 0xA840)
+
+#define SMP_CORE_TIMEOUT_MAX		(50000)
+#define DO_SMP_CORE_ON_WAIT_TIMEOUT(k_cnt) ({ \
+		CPU_PM_ASSERT(k_cnt < SMP_CORE_TIMEOUT_MAX); \
+		k_cnt++; udelay(1); })
+
+void mt_smp_core_init_arch(unsigned int cluster, unsigned int cpu, int arm64,
+			   struct cpu_pwr_ctrl *pwr_ctrl);
+void mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl *pwr_ctrl, uintptr_t entry);
+int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl);
+int mt_smp_power_core_off(struct cpu_pwr_ctrl *pwr_ctrl);
+void mt_smp_init(void);
+
+#endif /* MT_SMP_H */
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/rules.mk b/plat/mediatek/drivers/cpu_pm/cpcv3_2/rules.mk
new file mode 100644
index 0000000..858cf38
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/rules.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := cpcv${CONFIG_MTK_CPU_PM_ARCH}
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/mt_cpu_pm.c ${LOCAL_DIR}/mt_cpu_pm_cpc.c
+
+LOCAL_SRCS-$(CPU_PM_TINYSYS_SUPPORT) += ${LOCAL_DIR}/mt_cpu_pm_mbox.c
+LOCAL_SRCS-$(CONFIG_MTK_SMP_EN) += ${LOCAL_DIR}/mt_smp.c
+
+$(eval $(call add_defined_option,CPU_PM_TINYSYS_SUPPORT))
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
+
diff --git a/plat/mediatek/drivers/cpu_pm/rules.mk b/plat/mediatek/drivers/cpu_pm/rules.mk
new file mode 100644
index 0000000..8df4f21
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := cpu_pm
+
+SUB_RULES-${CONFIG_MTK_CPU_PM_SUPPORT} := $(LOCAL_DIR)/cpcv${CONFIG_MTK_CPU_PM_ARCH}
+
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.c b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.c
new file mode 100644
index 0000000..c054de9
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <mtk_dcm_utils.h>
+
+#define MP_CPUSYS_TOP_ADB_DCM_REG0_MASK		BIT(17)
+#define MP_CPUSYS_TOP_ADB_DCM_REG1_MASK		(BIT(15) | BIT(16) | BIT(17) | \
+						 BIT(18) | BIT(21))
+#define MP_CPUSYS_TOP_ADB_DCM_REG2_MASK		(BIT(15) | BIT(16) | BIT(17) | BIT(18))
+#define MP_CPUSYS_TOP_ADB_DCM_REG0_ON		BIT(17)
+#define MP_CPUSYS_TOP_ADB_DCM_REG1_ON		(BIT(15) | BIT(16) | BIT(17) | \
+						 BIT(18) | BIT(21))
+#define MP_CPUSYS_TOP_ADB_DCM_REG2_ON		(BIT(15) | BIT(16) | BIT(17) | BIT(18))
+#define MP_CPUSYS_TOP_ADB_DCM_REG0_OFF		(0x0 << 17)
+#define MP_CPUSYS_TOP_ADB_DCM_REG1_OFF		((0x0 << 15) | (0x0 << 16) | \
+						 (0x0 << 17) | (0x0 << 18) | \
+						 (0x0 << 21))
+#define MP_CPUSYS_TOP_ADB_DCM_REG2_OFF		((0x0 << 15) | (0x0 << 16) | \
+						 (0x0 << 17) | (0x0 << 18))
+
+bool dcm_mp_cpusys_top_adb_dcm_is_on(void)
+{
+	bool ret = true;
+
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0,
+			       MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4,
+			       MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
+			       MP_CPUSYS_TOP_ADB_DCM_REG1_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+			       MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
+			       MP_CPUSYS_TOP_ADB_DCM_REG2_ON);
+
+	return ret;
+}
+
+void dcm_mp_cpusys_top_adb_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_adb_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0,
+				   MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4,
+				   MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG1_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+				   MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG2_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_adb_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0,
+				   MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG0_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4,
+				   MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG1_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+				   MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG2_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_APB_DCM_REG0_MASK	BIT(5)
+#define MP_CPUSYS_TOP_APB_DCM_REG1_MASK	BIT(8)
+#define MP_CPUSYS_TOP_APB_DCM_REG2_MASK	BIT(16)
+#define MP_CPUSYS_TOP_APB_DCM_REG0_ON	BIT(5)
+#define MP_CPUSYS_TOP_APB_DCM_REG1_ON	BIT(8)
+#define MP_CPUSYS_TOP_APB_DCM_REG2_ON	BIT(16)
+#define MP_CPUSYS_TOP_APB_DCM_REG0_OFF	(0x0 << 5)
+#define MP_CPUSYS_TOP_APB_DCM_REG1_OFF	(0x0 << 8)
+#define MP_CPUSYS_TOP_APB_DCM_REG2_OFF	(0x0 << 16)
+
+bool dcm_mp_cpusys_top_apb_dcm_is_on(void)
+{
+	bool ret = true;
+
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+			       MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_APB_DCM_REG0_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+			       MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
+			       MP_CPUSYS_TOP_APB_DCM_REG1_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+			       MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
+			       MP_CPUSYS_TOP_APB_DCM_REG2_ON);
+
+	return ret;
+}
+
+void dcm_mp_cpusys_top_apb_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_apb_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG0_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG1_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG2_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_apb_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG0_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG1_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG2_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK (BIT(11) | BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON (BIT(11) | BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF ((0x0 << 11) | \
+						(0x0 << 24) | \
+						(0x0 << 25))
+
+bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+			       MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_bus_pll_div_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+				   MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_bus_pll_div_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+				   MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK	BIT(0)
+#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON	BIT(0)
+#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF	(0x0 << 0)
+
+bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+			       MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_core_stall_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_core_stall_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+				   MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_core_stall_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+				   MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK	(0xffff << 0)
+#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON	(0xffff << 0)
+#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF	(0x0 << 0)
+
+bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_MCSIC_DCM0,
+			       MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_cpubiu_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpubiu_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSIC_DCM0,
+				   MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpubiu_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSIC_DCM0,
+				   MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK (BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON (BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF ((0x0 << 24) | (0x0 << 25))
+
+bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0,
+			       MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK (BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON (BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF ((0x0 << 24) | (0x0 << 25))
+
+bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1,
+			       MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK	BIT(4)
+#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON	BIT(4)
+#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF	(0x0 << 4)
+
+bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+			       MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_fcm_stall_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_fcm_stall_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+				   MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_fcm_stall_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+				   MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK	BIT(31)
+#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON		BIT(31)
+#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF	(0x0U << 31)
+
+bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+			       MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_last_cor_idle_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+				   MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_last_cor_idle_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+				   MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_MISC_DCM_REG0_MASK (BIT(1) | BIT(4))
+#define MP_CPUSYS_TOP_MISC_DCM_REG0_ON (BIT(1) | BIT(4))
+#define MP_CPUSYS_TOP_MISC_DCM_REG0_OFF ((0x0 << 1) | (0x0 << 4))
+
+bool dcm_mp_cpusys_top_misc_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+			       MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_MISC_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_misc_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_misc_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_MISC_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_misc_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_MISC_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK BIT(3)
+#define MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG0_ON BIT(3)
+#define MP_CPUSYS_TOP_MP0_QDCM_REG1_ON (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF ((0x0 << 3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF ((0x0 << 0) | (0x0 << 1) | \
+					 (0x0 << 2) | (0x0 << 3))
+
+bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void)
+{
+	bool ret = true;
+
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+			       MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
+			       MP_CPUSYS_TOP_MP0_QDCM_REG0_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+			       MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
+			       MP_CPUSYS_TOP_MP0_QDCM_REG1_ON);
+
+	return ret;
+}
+
+void dcm_mp_cpusys_top_mp0_qdcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_mp0_qdcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG0_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG1_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_mp0_qdcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF);
+	}
+}
+
+#define CPCCFG_REG_EMI_WFIFO_REG0_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define CPCCFG_REG_EMI_WFIFO_REG0_ON (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define CPCCFG_REG_EMI_WFIFO_REG0_OFF ((0x0 << 0) | (0x0 << 1) | \
+				       (0x0 << 2) | (0x0 << 3))
+
+bool dcm_cpccfg_reg_emi_wfifo_is_on(void)
+{
+	return dcm_check_state(CPCCFG_REG_EMI_WFIFO,
+			       CPCCFG_REG_EMI_WFIFO_REG0_MASK,
+			       CPCCFG_REG_EMI_WFIFO_REG0_ON);
+}
+
+void dcm_cpccfg_reg_emi_wfifo(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'cpccfg_reg_emi_wfifo'" */
+		mmio_clrsetbits_32(CPCCFG_REG_EMI_WFIFO,
+				   CPCCFG_REG_EMI_WFIFO_REG0_MASK,
+				   CPCCFG_REG_EMI_WFIFO_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'cpccfg_reg_emi_wfifo'" */
+		mmio_clrsetbits_32(CPCCFG_REG_EMI_WFIFO,
+				   CPCCFG_REG_EMI_WFIFO_REG0_MASK,
+				   CPCCFG_REG_EMI_WFIFO_REG0_OFF);
+	}
+}
diff --git a/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.h b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.h
new file mode 100644
index 0000000..5d758dd
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_DCM_UTILS_H
+#define MTK_DCM_UTILS_H
+
+#include <stdbool.h>
+
+#include <mtk_dcm.h>
+#include <platform_def.h>
+
+/* Base */
+#define MP_CPUSYS_TOP_BASE	(MCUCFG_BASE + 0x8000)
+#define CPCCFG_REG_BASE		(MCUCFG_BASE + 0xA800)
+
+/* Register Definition */
+#define CPCCFG_REG_EMI_WFIFO		(CPCCFG_REG_BASE + 0x100)
+#define MP_CPUSYS_TOP_CPU_PLLDIV_CFG0	(MP_CPUSYS_TOP_BASE + 0x22a0)
+#define MP_CPUSYS_TOP_CPU_PLLDIV_CFG1	(MP_CPUSYS_TOP_BASE + 0x22a4)
+#define MP_CPUSYS_TOP_BUS_PLLDIV_CFG	(MP_CPUSYS_TOP_BASE + 0x22e0)
+#define MP_CPUSYS_TOP_MCSIC_DCM0	(MP_CPUSYS_TOP_BASE + 0x2440)
+#define MP_CPUSYS_TOP_MP_ADB_DCM_CFG0	(MP_CPUSYS_TOP_BASE + 0x2500)
+#define MP_CPUSYS_TOP_MP_ADB_DCM_CFG4	(MP_CPUSYS_TOP_BASE + 0x2510)
+#define MP_CPUSYS_TOP_MP_MISC_DCM_CFG0	(MP_CPUSYS_TOP_BASE + 0x2518)
+#define MP_CPUSYS_TOP_MCUSYS_DCM_CFG0	(MP_CPUSYS_TOP_BASE + 0x25c0)
+#define MP_CPUSYS_TOP_MP0_DCM_CFG0	(MP_CPUSYS_TOP_BASE + 0x4880)
+#define MP_CPUSYS_TOP_MP0_DCM_CFG7	(MP_CPUSYS_TOP_BASE + 0x489c)
+
+/* MP_CPUSYS_TOP */
+bool dcm_mp_cpusys_top_adb_dcm_is_on(void);
+void dcm_mp_cpusys_top_adb_dcm(bool on);
+bool dcm_mp_cpusys_top_apb_dcm_is_on(void);
+void dcm_mp_cpusys_top_apb_dcm(bool on);
+bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void);
+void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on);
+bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void);
+void dcm_mp_cpusys_top_core_stall_dcm(bool on);
+bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpubiu_dcm(bool on);
+bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on);
+bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on);
+bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void);
+void dcm_mp_cpusys_top_fcm_stall_dcm(bool on);
+bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void);
+void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on);
+bool dcm_mp_cpusys_top_misc_dcm_is_on(void);
+void dcm_mp_cpusys_top_misc_dcm(bool on);
+bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void);
+void dcm_mp_cpusys_top_mp0_qdcm(bool on);
+/* CPCCFG_REG */
+bool dcm_cpccfg_reg_emi_wfifo_is_on(void);
+void dcm_cpccfg_reg_emi_wfifo(bool on);
+
+#endif
diff --git a/plat/mediatek/drivers/dcm/mtk_dcm.c b/plat/mediatek/drivers/dcm/mtk_dcm.c
new file mode 100644
index 0000000..ca79a20
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/mtk_dcm.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <mtk_dcm.h>
+#include <mtk_dcm_utils.h>
+
+static void dcm_armcore(bool mode)
+{
+	dcm_mp_cpusys_top_bus_pll_div_dcm(mode);
+	dcm_mp_cpusys_top_cpu_pll_div_0_dcm(mode);
+	dcm_mp_cpusys_top_cpu_pll_div_1_dcm(mode);
+}
+
+static void dcm_mcusys(bool on)
+{
+	dcm_mp_cpusys_top_adb_dcm(on);
+	dcm_mp_cpusys_top_apb_dcm(on);
+	dcm_mp_cpusys_top_cpubiu_dcm(on);
+	dcm_mp_cpusys_top_misc_dcm(on);
+	dcm_mp_cpusys_top_mp0_qdcm(on);
+
+	/* CPCCFG_REG */
+	dcm_cpccfg_reg_emi_wfifo(on);
+	dcm_mp_cpusys_top_last_cor_idle_dcm(on);
+}
+
+static void dcm_stall(bool on)
+{
+	dcm_mp_cpusys_top_core_stall_dcm(on);
+	dcm_mp_cpusys_top_fcm_stall_dcm(on);
+}
+
+static bool check_dcm_state(void)
+{
+	bool ret = true;
+
+	ret &= dcm_mp_cpusys_top_bus_pll_div_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on();
+
+	ret &= dcm_mp_cpusys_top_adb_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_apb_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_cpubiu_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_misc_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_mp0_qdcm_is_on();
+	ret &= dcm_cpccfg_reg_emi_wfifo_is_on();
+	ret &= dcm_mp_cpusys_top_last_cor_idle_dcm_is_on();
+
+	ret &= dcm_mp_cpusys_top_core_stall_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_fcm_stall_dcm_is_on();
+
+	return ret;
+}
+
+bool dcm_check_state(uintptr_t addr, unsigned int mask, unsigned int compare)
+{
+	return ((mmio_read_32(addr) & mask) == compare);
+}
+
+int dcm_set_init(void)
+{
+	int ret;
+
+	dcm_armcore(true);
+	dcm_mcusys(true);
+	dcm_stall(true);
+
+	if (check_dcm_state() == false) {
+		ERROR("Failed to set default dcm on!!\n");
+		ret = -1;
+	} else {
+		INFO("%s, dcm pass\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+MTK_PLAT_SETUP_0_INIT(dcm_set_init);
diff --git a/plat/mediatek/drivers/dcm/mtk_dcm.h b/plat/mediatek/drivers/dcm/mtk_dcm.h
new file mode 100644
index 0000000..05f8d45
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/mtk_dcm.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_DCM_H
+#define MTK_DCM_H
+
+#include <stdbool.h>
+
+bool dcm_check_state(uintptr_t addr, unsigned int mask, unsigned int compare);
+int dcm_set_init(void);
+
+#endif /* #ifndef MTK_DCM_H */
diff --git a/plat/mediatek/drivers/dcm/rules.mk b/plat/mediatek/drivers/dcm/rules.mk
new file mode 100644
index 0000000..a8ee05e
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mtk_dcm
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_dcm.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/mtk_dcm_utils.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/dfd/dfd.c b/plat/mediatek/drivers/dfd/dfd.c
new file mode 100644
index 0000000..5770d50
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/dfd.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <dfd.h>
+#include <mtk_sip_svc.h>
+#include <plat_dfd.h>
+
+static u_register_t dfd_smc_dispatcher(u_register_t arg0, u_register_t arg1,
+				       u_register_t arg2, u_register_t arg3,
+				       void *handle, struct smccc_res *smccc_ret)
+{
+	int ret = MTK_SIP_E_SUCCESS;
+
+	switch (arg0) {
+	case PLAT_MTK_DFD_SETUP_MAGIC:
+		INFO("[%s] DFD setup call from kernel\n", __func__);
+		dfd_setup(arg1, arg2, arg3);
+		break;
+	case PLAT_MTK_DFD_READ_MAGIC:
+		/* only allow to access DFD register base + 0x200 */
+		if (arg1 <= 0x200) {
+			ret = mmio_read_32(MISC1_CFG_BASE + arg1);
+		}
+		break;
+	case PLAT_MTK_DFD_WRITE_MAGIC:
+		/* only allow to access DFD register base + 0x200 */
+		if (arg1 <= 0x200) {
+			sync_writel(MISC1_CFG_BASE + arg1, arg2);
+		}
+		break;
+	default:
+		ret = MTK_SIP_E_INVALID_PARAM;
+		break;
+	}
+
+	return ret;
+}
+DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_DFD, dfd_smc_dispatcher);
diff --git a/plat/mediatek/drivers/dfd/dfd.h b/plat/mediatek/drivers/dfd/dfd.h
new file mode 100644
index 0000000..c088bd0
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/dfd.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DFD_H
+#define DFD_H
+
+#include <arch_helpers.h>
+#include <lib/mmio.h>
+
+void dfd_resume(void);
+void dfd_setup(uint64_t base_addr, uint64_t chain_length, uint64_t cache_dump);
+
+#endif /* DFD_H */
diff --git a/plat/mediatek/drivers/dfd/mt8188/plat_dfd.c b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.c
new file mode 100644
index 0000000..1aa68f5
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <dfd.h>
+#include <plat_dfd.h>
+
+static uint64_t dfd_cache_dump;
+static bool dfd_enabled;
+static uint64_t dfd_base_addr;
+static uint64_t dfd_chain_length;
+
+void dfd_setup(uint64_t base_addr, uint64_t chain_length, uint64_t cache_dump)
+{
+	mmio_write_32(MTK_DRM_LATCH_CTL1, MTK_DRM_LATCH_CTL1_VAL);
+	mmio_write_32(MTK_DRM_LATCH_CTL2, MTK_DRM_LATCH_CTL2_VAL);
+	mmio_write_32(MTK_WDT_LATCH_CTL2, MTK_WDT_LATCH_CTL2_VAL);
+
+	mmio_clrbits_32(DFD_O_INTRF_MCU_PWR_CTL_MASK, BIT(2));
+	mmio_setbits_32(DFD_V50_GROUP_0_63_DIFF, 0x1);
+	sync_writel(DFD_INTERNAL_CTL, 0x5);
+	mmio_setbits_32(DFD_INTERNAL_CTL, BIT(13));
+	mmio_setbits_32(DFD_INTERNAL_CTL, 0x1F << 3);
+	mmio_setbits_32(DFD_INTERNAL_CTL, 0x3 << 9);
+	mmio_setbits_32(DFD_INTERNAL_CTL, 0x3 << 19);
+
+	mmio_write_32(DFD_INTERNAL_PWR_ON, 0xB);
+	mmio_write_32(DFD_CHAIN_LENGTH0, chain_length);
+	mmio_write_32(DFD_INTERNAL_SHIFT_CLK_RATIO, 0x0);
+	mmio_write_32(DFD_INTERNAL_TEST_SO_OVER_64, 0x1);
+
+	mmio_write_32(DFD_TEST_SI_0, 0x0);
+	mmio_write_32(DFD_TEST_SI_1, 0x0);
+	mmio_write_32(DFD_TEST_SI_2, 0x0);
+	mmio_write_32(DFD_TEST_SI_3, 0x0);
+
+	sync_writel(DFD_POWER_CTL, 0xF9);
+	sync_writel(DFD_READ_ADDR, DFD_READ_ADDR_VAL);
+	sync_writel(DFD_V30_CTL, 0xD);
+
+	mmio_write_32(DFD_O_SET_BASEADDR_REG, base_addr >> 24);
+	mmio_write_32(DFD_O_REG_0, 0);
+
+	/* setup global variables for suspend and resume */
+	dfd_enabled = true;
+	dfd_base_addr = base_addr;
+	dfd_chain_length = chain_length;
+	dfd_cache_dump = cache_dump;
+
+	if ((cache_dump & DFD_CACHE_DUMP_ENABLE) != 0UL) {
+		mmio_write_32(MTK_DRM_LATCH_CTL2, MTK_DRM_LATCH_CTL2_CACHE_VAL);
+		sync_writel(DFD_V35_ENABLE, 0x1);
+		sync_writel(DFD_V35_TAP_NUMBER, 0xB);
+		sync_writel(DFD_V35_TAP_EN, DFD_V35_TAP_EN_VAL);
+		sync_writel(DFD_V35_SEQ0_0, DFD_V35_SEQ0_0_VAL);
+
+		/* Cache dump only mode */
+		sync_writel(DFD_V35_CTL, 0x1);
+		mmio_write_32(DFD_INTERNAL_NUM_OF_TEST_SO_GROUP, 0xF);
+		mmio_write_32(DFD_CHAIN_LENGTH0, DFD_CHAIN_LENGTH_VAL);
+		mmio_write_32(DFD_CHAIN_LENGTH1, DFD_CHAIN_LENGTH_VAL);
+		mmio_write_32(DFD_CHAIN_LENGTH2, DFD_CHAIN_LENGTH_VAL);
+		mmio_write_32(DFD_CHAIN_LENGTH3, DFD_CHAIN_LENGTH_VAL);
+
+		if ((cache_dump & DFD_PARITY_ERR_TRIGGER) != 0UL) {
+			sync_writel(DFD_HW_TRIGGER_MASK, 0xC);
+			mmio_setbits_32(DFD_INTERNAL_CTL, 0x1 << 4);
+		}
+	}
+	dsbsy();
+}
+
+void dfd_resume(void)
+{
+	if (dfd_enabled == true) {
+		dfd_setup(dfd_base_addr, dfd_chain_length, dfd_cache_dump);
+	}
+}
diff --git a/plat/mediatek/drivers/dfd/mt8188/plat_dfd.h b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.h
new file mode 100644
index 0000000..5b98024
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DFD_H
+#define PLAT_DFD_H
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define sync_writel(addr, val) do { mmio_write_32((addr), (val)); dsbsy(); } while (0)
+
+#define PLAT_MTK_DFD_SETUP_MAGIC		(0x99716150)
+#define PLAT_MTK_DFD_READ_MAGIC			(0x99716151)
+#define PLAT_MTK_DFD_WRITE_MAGIC		(0x99716152)
+
+#define MTK_DRM_LATCH_CTL1			(DRM_BASE + 0x40)
+#define MTK_DRM_LATCH_CTL2			(DRM_BASE + 0x44)
+
+#define MTK_WDT_BASE				(RGU_BASE)
+#define MTK_WDT_INTERVAL			(MTK_WDT_BASE + 0x10)
+#define MTK_WDT_LATCH_CTL2			(MTK_WDT_BASE + 0x48)
+
+#define MCU_BIU_BASE				(MCUCFG_BASE)
+#define MISC1_CFG_BASE				(MCU_BIU_BASE + 0xE040)
+#define DFD_INTERNAL_CTL			(MISC1_CFG_BASE + 0x00)
+#define DFD_INTERNAL_PWR_ON			(MISC1_CFG_BASE + 0x08)
+#define DFD_CHAIN_LENGTH0			(MISC1_CFG_BASE + 0x0C)
+#define DFD_INTERNAL_SHIFT_CLK_RATIO		(MISC1_CFG_BASE + 0x10)
+#define DFD_CHAIN_LENGTH1			(MISC1_CFG_BASE + 0x1C)
+#define DFD_CHAIN_LENGTH2			(MISC1_CFG_BASE + 0x20)
+#define DFD_CHAIN_LENGTH3			(MISC1_CFG_BASE + 0x24)
+#define DFD_INTERNAL_TEST_SO_0			(MISC1_CFG_BASE + 0x28)
+#define DFD_INTERNAL_NUM_OF_TEST_SO_GROUP	(MISC1_CFG_BASE + 0x30)
+#define DFD_INTERNAL_TEST_SO_OVER_64		(MISC1_CFG_BASE + 0x34)
+#define DFD_INTERNAL_SW_NS_TRIGGER		(MISC1_CFG_BASE + 0x3c)
+#define DFD_V30_CTL				(MISC1_CFG_BASE + 0x48)
+#define DFD_V30_BASE_ADDR			(MISC1_CFG_BASE + 0x4C)
+#define DFD_POWER_CTL				(MISC1_CFG_BASE + 0x50)
+#define DFD_TEST_SI_0				(MISC1_CFG_BASE + 0x58)
+#define DFD_TEST_SI_1				(MISC1_CFG_BASE + 0x5C)
+#define DFD_CLEAN_STATUS			(MISC1_CFG_BASE + 0x60)
+#define DFD_TEST_SI_2				(MISC1_CFG_BASE + 0x1D8)
+#define DFD_TEST_SI_3				(MISC1_CFG_BASE + 0x1DC)
+#define DFD_READ_ADDR				(MISC1_CFG_BASE + 0x1E8)
+#define DFD_HW_TRIGGER_MASK			(MISC1_CFG_BASE + 0xBC)
+
+#define DFD_V35_ENABLE				(MCU_BIU_BASE + 0xE0A8)
+#define DFD_V35_TAP_NUMBER			(MCU_BIU_BASE + 0xE0AC)
+#define DFD_V35_TAP_EN				(MCU_BIU_BASE + 0xE0B0)
+#define DFD_V35_CTL				(MCU_BIU_BASE + 0xE0B4)
+#define DFD_V35_SEQ0_0				(MCU_BIU_BASE + 0xE0C0)
+#define DFD_V35_SEQ0_1				(MCU_BIU_BASE + 0xE0C4)
+#define DFD_V50_GROUP_0_63_DIFF			(MCU_BIU_BASE + 0xE2AC)
+
+#define DFD_O_PROTECT_EN_REG			(0x10001220)
+#define DFD_O_INTRF_MCU_PWR_CTL_MASK		(0x10001A3C)
+#define DFD_O_SET_BASEADDR_REG			(0x10043000)
+#define DFD_O_REG_0				(0x10001390)
+
+#define DFD_CACHE_DUMP_ENABLE			(1U)
+#define DFD_PARITY_ERR_TRIGGER			(2U)
+
+#define DFD_V35_TAP_EN_VAL			(0x43FF)
+#define DFD_V35_SEQ0_0_VAL			(0x63668820)
+#define DFD_READ_ADDR_VAL			(0x40000008)
+#define DFD_CHAIN_LENGTH_VAL			(0xFFFFFFFF)
+
+#define MTK_WDT_LATCH_CTL2_VAL			(0x9507FFFF)
+#define MTK_WDT_INTERVAL_VAL			(0x6600000A)
+#define MTK_DRM_LATCH_CTL2_VAL			(0x950607D0)
+#define MTK_DRM_LATCH_CTL2_CACHE_VAL		(0x95065DC0)
+
+#define MTK_DRM_LATCH_CTL1_VAL			(0x95000013)
+
+#endif /* PLAT_DFD_H */
diff --git a/plat/mediatek/drivers/dfd/rules.mk b/plat/mediatek/drivers/dfd/rules.mk
new file mode 100644
index 0000000..60fbc88
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mtk_dfd
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/dfd.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/$(MTK_SOC)/plat_dfd.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC)
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
new file mode 100644
index 0000000..66a369e
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EMI_MPU_H
+#define EMI_MPU_H
+
+#include <emi_mpu_priv.h>
+#include <platform_def.h>
+
+#define NO_PROTECTION			(0)
+#define SEC_RW				(1)
+#define SEC_RW_NSEC_R			(2)
+#define SEC_RW_NSEC_W			(3)
+#define SEC_R_NSEC_R			(4)
+#define FORBIDDEN			(5)
+#define SEC_R_NSEC_RW			(6)
+
+#define LOCK				(1)
+#define UNLOCK				(0)
+
+#if (EMI_MPU_DGROUP_NUM == 1)
+#define SET_ACCESS_PERMISSION(apc_ary, lock, d7, d6, d5, d4, d3, d2, d1, d0) \
+do { \
+	apc_ary[1] = 0; \
+	apc_ary[0] = \
+		(((unsigned int)  d7) << 21) | (((unsigned int)  d6) << 18) | \
+		(((unsigned int)  d5) << 15) | (((unsigned int)  d4) << 12) | \
+		(((unsigned int)  d3) <<  9) | (((unsigned int)  d2) <<  6) | \
+		(((unsigned int)  d1) <<  3) |  ((unsigned int)  d0) | \
+		((unsigned int) lock << 31); \
+} while (0)
+#elif (EMI_MPU_DGROUP_NUM == 2)
+#define SET_ACCESS_PERMISSION(apc_ary, lock, d15, d14, d13, d12, d11, d10, \
+				d9, d8, d7, d6, d5, d4, d3, d2, d1, d0) \
+do { \
+	apc_ary[1] = \
+		(((unsigned int) d15) << 21) | (((unsigned int) d14) << 18) | \
+		(((unsigned int) d13) << 15) | (((unsigned int) d12) << 12) | \
+		(((unsigned int) d11) <<  9) | (((unsigned int) d10) <<  6) | \
+		(((unsigned int)  d9) <<  3) |  ((unsigned int)  d8); \
+	apc_ary[0] = \
+		(((unsigned int)  d7) << 21) | (((unsigned int)  d6) << 18) | \
+		(((unsigned int)  d5) << 15) | (((unsigned int)  d4) << 12) | \
+		(((unsigned int)  d3) <<  9) | (((unsigned int)  d2) <<  6) | \
+		(((unsigned int)  d1) <<  3) |  ((unsigned int)  d0) | \
+		((unsigned int) lock << 31); \
+} while (0)
+#endif
+
+struct emi_region_info_t {
+	unsigned long long start;
+	unsigned long long end;
+	unsigned int region;
+	unsigned int apc[EMI_MPU_DGROUP_NUM];
+};
+
+int emi_mpu_init(void);
+int emi_mpu_set_protection(struct emi_region_info_t *region_info);
+void set_emi_mpu_regions(void);
+
+#endif
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
new file mode 100644
index 0000000..27b2b07
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <emi_mpu.h>
+#include <lib/mtk_init/mtk_init.h>
+
+#if ENABLE_EMI_MPU_SW_LOCK
+static unsigned char region_lock_state[EMI_MPU_REGION_NUM];
+#endif
+
+#define EMI_MPU_START_MASK		(0x00FFFFFF)
+#define EMI_MPU_END_MASK		(0x00FFFFFF)
+#define EMI_MPU_APC_SW_LOCK_MASK	(0x00FFFFFF)
+#define EMI_MPU_APC_HW_LOCK_MASK	(0x80FFFFFF)
+
+static int _emi_mpu_set_protection(unsigned int start, unsigned int end,
+					unsigned int apc)
+{
+	unsigned int dgroup;
+	unsigned int region;
+
+	region = (start >> 24) & 0xFF;
+	start &= EMI_MPU_START_MASK;
+	dgroup = (end >> 24) & 0xFF;
+	end &= EMI_MPU_END_MASK;
+
+	if  ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) {
+		WARN("invalid region, domain\n");
+		return -1;
+	}
+
+#if ENABLE_EMI_MPU_SW_LOCK
+	if (region_lock_state[region] == 1) {
+		WARN("invalid region\n");
+		return -1;
+	}
+
+	if ((dgroup == 0) && ((apc >> 31) & 0x1)) {
+		region_lock_state[region] = 1;
+	}
+
+	apc &= EMI_MPU_APC_SW_LOCK_MASK;
+#else
+	apc &= EMI_MPU_APC_HW_LOCK_MASK;
+#endif
+
+	if ((start >= DRAM_OFFSET) && (end >= start)) {
+		start -= DRAM_OFFSET;
+		end -= DRAM_OFFSET;
+	} else {
+		WARN("invalid range\n");
+		return -1;
+	}
+
+	mmio_write_32(EMI_MPU_SA(region), start);
+	mmio_write_32(EMI_MPU_EA(region), end);
+	mmio_write_32(EMI_MPU_APC(region, dgroup), apc);
+
+#if defined(SUB_EMI_MPU_BASE)
+	mmio_write_32(SUB_EMI_MPU_SA(region), start);
+	mmio_write_32(SUB_EMI_MPU_EA(region), end);
+	mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), apc);
+#endif
+	return 0;
+}
+
+static void dump_emi_mpu_regions(void)
+{
+	int region, i;
+
+	/* Only dump 8 regions(max: EMI_MPU_REGION_NUM --> 32) */
+	for (region = 0; region < 8; ++region) {
+		INFO("region %d:\n", region);
+		INFO("\tsa: 0x%x, ea: 0x%x\n",
+		     mmio_read_32(EMI_MPU_SA(region)), mmio_read_32(EMI_MPU_EA(region)));
+
+		for (i = 0; i < EMI_MPU_DGROUP_NUM; ++i) {
+			INFO("\tapc%d: 0x%x\n", i, mmio_read_32(EMI_MPU_APC(region, i)));
+		}
+	}
+}
+
+int emi_mpu_set_protection(struct emi_region_info_t *region_info)
+{
+	unsigned int start, end;
+	int i;
+
+	if (region_info->region >= EMI_MPU_REGION_NUM) {
+		WARN("invalid region\n");
+		return -1;
+	}
+
+	start = (unsigned int)(region_info->start >> EMI_MPU_ALIGN_BITS) |
+		(region_info->region << 24);
+
+	for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) {
+		end = (unsigned int)(region_info->end >> EMI_MPU_ALIGN_BITS) | (i << 24);
+
+		if (_emi_mpu_set_protection(start, end, region_info->apc[i]) < 0) {
+			WARN("Failed to set emi mpu protection(%d, %d, %d)\n",
+			     start, end, region_info->apc[i]);
+		}
+	}
+
+	return 0;
+}
+
+int emi_mpu_init(void)
+{
+	INFO("[%s] emi mpu initialization\n", __func__);
+
+	set_emi_mpu_regions();
+	dump_emi_mpu_regions();
+
+	return 0;
+}
+MTK_PLAT_SETUP_0_INIT(emi_mpu_init);
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
new file mode 100644
index 0000000..558533d
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <emi_mpu.h>
+
+void set_emi_mpu_regions(void)
+{
+	/* TODO: set emi mpu region */
+	INFO("%s, emi mpu is not setting currently\n", __func__);
+}
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
new file mode 100644
index 0000000..1ee7397
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EMI_MPU_PRIV_H
+#define EMI_MPU_PRIV_H
+
+#define ENABLE_EMI_MPU_SW_LOCK		(1)
+
+#define EMI_MPU_CTRL			(EMI_MPU_BASE + 0x000)
+#define EMI_MPU_DBG			(EMI_MPU_BASE + 0x004)
+#define EMI_MPU_SA0			(EMI_MPU_BASE + 0x100)
+#define EMI_MPU_EA0			(EMI_MPU_BASE + 0x200)
+#define EMI_MPU_SA(region)		(EMI_MPU_SA0 + (region * 4))
+#define EMI_MPU_EA(region)		(EMI_MPU_EA0 + (region * 4))
+#define EMI_MPU_APC0			(EMI_MPU_BASE + 0x300)
+#define EMI_MPU_APC(region, dgroup)	(EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100))
+#define EMI_MPU_CTRL_D0			(EMI_MPU_BASE + 0x800)
+#define EMI_MPU_CTRL_D(domain)		(EMI_MPU_CTRL_D0 + (domain * 4))
+#define EMI_RG_MASK_D0			(EMI_MPU_BASE + 0x900)
+#define EMI_RG_MASK_D(domain)		(EMI_RG_MASK_D0 + (domain * 4))
+
+#define SUB_EMI_MPU_CTRL		(SUB_EMI_MPU_BASE + 0x000)
+#define SUB_EMI_MPU_DBG			(SUB_EMI_MPU_BASE + 0x004)
+#define SUB_EMI_MPU_SA0			(SUB_EMI_MPU_BASE + 0x100)
+#define SUB_EMI_MPU_EA0			(SUB_EMI_MPU_BASE + 0x200)
+#define SUB_EMI_MPU_SA(region)		(SUB_EMI_MPU_SA0 + (region * 4))
+#define SUB_EMI_MPU_EA(region)		(SUB_EMI_MPU_EA0 + (region * 4))
+#define SUB_EMI_MPU_APC0		(SUB_EMI_MPU_BASE + 0x300)
+#define SUB_EMI_MPU_APC(region, dgroup)	(SUB_EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100))
+#define SUB_EMI_MPU_CTRL_D0		(SUB_EMI_MPU_BASE + 0x800)
+#define SUB_EMI_MPU_CTRL_D(domain)	(SUB_EMI_MPU_CTRL_D0 + (domain * 4))
+#define SUB_EMI_RG_MASK_D0		(SUB_EMI_MPU_BASE + 0x900)
+#define SUB_EMI_RG_MASK_D(domain)	(SUB_EMI_RG_MASK_D0 + (domain * 4))
+
+#define EMI_MPU_DOMAIN_NUM		(16)
+#define EMI_MPU_REGION_NUM		(32)
+#define EMI_MPU_ALIGN_BITS		(16)
+#define DRAM_OFFSET			(0x40000000 >> EMI_MPU_ALIGN_BITS)
+
+#define EMI_MPU_DGROUP_NUM		(EMI_MPU_DOMAIN_NUM / 8)
+
+#endif
diff --git a/plat/mediatek/drivers/emi_mpu/rules.mk b/plat/mediatek/drivers/emi_mpu/rules.mk
new file mode 100644
index 0000000..ed3d777
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/rules.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := emi_mpu
+LOCAL_SRCS-y := $(LOCAL_DIR)/emi_mpu_common.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/emi_mpu.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/mcusys/mcusys.c b/plat/mediatek/drivers/mcusys/mcusys.c
new file mode 100644
index 0000000..63edb23
--- /dev/null
+++ b/plat/mediatek/drivers/mcusys/mcusys.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <mtk_mmap_pool.h>
+#include <platform_def.h>
+
+static const mmap_region_t mcusys_mmap[] MTK_MMAP_SECTION = {
+	MAP_REGION_FLAT(MCUCFG_BASE, MCUCFG_REG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	{0}
+};
+DECLARE_MTK_MMAP_REGIONS(mcusys_mmap);
diff --git a/plat/mediatek/drivers/mcusys/rules.mk b/plat/mediatek/drivers/mcusys/rules.mk
new file mode 100644
index 0000000..5438998
--- /dev/null
+++ b/plat/mediatek/drivers/mcusys/rules.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mcusys
+
+PLAT_INCLUDES += -I$(LOCAL_DIR)/$(MCUSYS_VERSION)
+
+LOCAL_SRCS-y := $(LOCAL_DIR)/mcusys.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/mcusys/v1/mcucfg.h b/plat/mediatek/drivers/mcusys/v1/mcucfg.h
new file mode 100644
index 0000000..7aced5a
--- /dev/null
+++ b/plat/mediatek/drivers/mcusys/v1/mcucfg.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MCUCFG_V1_H
+#define MCUCFG_V1_H
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif /*__ASSEMBLER__*/
+
+#include <platform_def.h>
+
+#define MP2_MISC_CONFIG_BOOT_ADDR_L(cpu)	(MCUCFG_BASE + 0x2290 + ((cpu) * 8))
+#define MP2_MISC_CONFIG_BOOT_ADDR_H(cpu)	(MCUCFG_BASE + 0x2294 + ((cpu) * 8))
+
+#define MP2_CPUCFG				(MCUCFG_BASE + 0x2208)
+
+#define MP0_CPUTOP_SPMC_CTL			(MCUCFG_BASE + 0x788)
+#define MP1_CPUTOP_SPMC_CTL			(MCUCFG_BASE + 0x78C)
+#define MP1_CPUTOP_SPMC_SRAM_CTL		(MCUCFG_BASE + 0x790)
+
+#define CPUSYSx_CPUx_SPMC_CTL(cluster, cpu)	(MCUCFG_BASE + 0x1C30 + \
+						 (cluster) * 0x2000 + (cpu) * 4)
+
+#define CPUSYS0_CPU0_SPMC_CTL			(MCUCFG_BASE + 0x1C30)
+#define CPUSYS0_CPU1_SPMC_CTL			(MCUCFG_BASE + 0x1C34)
+#define CPUSYS0_CPU2_SPMC_CTL			(MCUCFG_BASE + 0x1C38)
+#define CPUSYS0_CPU3_SPMC_CTL			(MCUCFG_BASE + 0x1C3C)
+
+#define CPUSYS1_CPU0_SPMC_CTL			(MCUCFG_BASE + 0x3C30)
+#define CPUSYS1_CPU1_SPMC_CTL			(MCUCFG_BASE + 0x3C34)
+#define CPUSYS1_CPU2_SPMC_CTL			(MCUCFG_BASE + 0x3C38)
+#define CPUSYS1_CPU3_SPMC_CTL			(MCUCFG_BASE + 0x3C3C)
+
+/* CPC related registers */
+#define CPC_MCUSYS_CPC_OFF_THRES		(MCUCFG_BASE + 0xA714)
+#define CPC_MCUSYS_PWR_CTRL			(MCUCFG_BASE + 0xA804)
+#define CPC_MCUSYS_CPC_FLOW_CTRL_CFG		(MCUCFG_BASE + 0xA814)
+#define CPC_MCUSYS_LAST_CORE_REQ		(MCUCFG_BASE + 0xA818)
+#define CPC_MCUSYS_MP_LAST_CORE_RESP		(MCUCFG_BASE + 0xA81C)
+#define CPC_MCUSYS_LAST_CORE_RESP		(MCUCFG_BASE + 0xA824)
+#define CPC_MCUSYS_PWR_ON_MASK			(MCUCFG_BASE + 0xA828)
+#define CPC_SPMC_PWR_STATUS			(MCUCFG_BASE + 0xA840)
+#define CPC_MCUSYS_CPU_ON_SW_HINT_SET		(MCUCFG_BASE + 0xA8A8)
+#define CPC_MCUSYS_CPU_ON_SW_HINT_CLR		(MCUCFG_BASE + 0xA8AC)
+#define CPC_MCUSYS_CPC_DBG_SETTING		(MCUCFG_BASE + 0xAB00)
+#define CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE	(MCUCFG_BASE + 0xAB04)
+#define CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE	(MCUCFG_BASE + 0xAB08)
+#define CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE	(MCUCFG_BASE + 0xAB0C)
+#define CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE	(MCUCFG_BASE + 0xAB10)
+#define CPC_MCUSYS_TRACE_SEL			(MCUCFG_BASE + 0xAB14)
+#define CPC_MCUSYS_TRACE_DATA			(MCUCFG_BASE + 0xAB20)
+#define CPC_MCUSYS_CLUSTER_COUNTER		(MCUCFG_BASE + 0xAB70)
+#define CPC_MCUSYS_CLUSTER_COUNTER_CLR		(MCUCFG_BASE + 0xAB74)
+
+/* CPC_MCUSYS_CPC_FLOW_CTRL_CFG bit control */
+#define CPC_CTRL_ENABLE				BIT(16)
+#define SSPM_CORE_PWR_ON_EN			BIT(7) /* for cpu-hotplug */
+#define SSPM_ALL_PWR_CTRL_EN			BIT(13) /* for cpu-hotplug */
+#define GIC_WAKEUP_IGNORE(cpu)			BIT(21 + cpu)
+
+#define CPC_MCUSYS_CPC_RESET_ON_KEEP_ON		BIT(17)
+#define CPC_MCUSYS_CPC_RESET_PWR_ON_EN		BIT(20)
+
+/* SPMC related registers */
+#define SPM_MCUSYS_PWR_CON			(MCUCFG_BASE + 0xD200)
+#define SPM_MP0_CPUTOP_PWR_CON			(MCUCFG_BASE + 0xD204)
+#define SPM_MP0_CPU0_PWR_CON			(MCUCFG_BASE + 0xD208)
+#define SPM_MP0_CPU1_PWR_CON			(MCUCFG_BASE + 0xD20C)
+#define SPM_MP0_CPU2_PWR_CON			(MCUCFG_BASE + 0xD210)
+#define SPM_MP0_CPU3_PWR_CON			(MCUCFG_BASE + 0xD214)
+#define SPM_MP0_CPU4_PWR_CON			(MCUCFG_BASE + 0xD218)
+#define SPM_MP0_CPU5_PWR_CON			(MCUCFG_BASE + 0xD21C)
+#define SPM_MP0_CPU6_PWR_CON			(MCUCFG_BASE + 0xD220)
+#define SPM_MP0_CPU7_PWR_CON			(MCUCFG_BASE + 0xD224)
+
+/* bit fields of SPM_*_PWR_CON */
+#define PWR_ON_ACK				BIT(31)
+#define VPROC_EXT_OFF				BIT(7)
+#define DORMANT_EN				BIT(6)
+#define RESETPWRON_CONFIG			BIT(5)
+#define PWR_CLK_DIS				BIT(4)
+#define PWR_ON					BIT(2)
+#define PWR_RST_B				BIT(0)
+
+#define SPARK2LDO				(MCUCFG_BASE + 0x2700)
+/* APB Module mcucfg */
+#define MP0_CA7_CACHE_CONFIG			(MCUCFG_BASE + 0x000)
+#define MP0_AXI_CONFIG				(MCUCFG_BASE + 0x02C)
+#define MP0_MISC_CONFIG0			(MCUCFG_BASE + 0x030)
+#define MP0_MISC_CONFIG1			(MCUCFG_BASE + 0x034)
+#define MP0_MISC_CONFIG2			(MCUCFG_BASE + 0x038)
+#define MP0_MISC_CONFIG_BOOT_ADDR(cpu)		(MCUCFG_BASE + 0x038 + ((cpu) * 8))
+#define MP0_MISC_CONFIG3			(MCUCFG_BASE + 0x03C)
+#define MP0_MISC_CONFIG9			(MCUCFG_BASE + 0x054)
+#define MP0_CA7_MISC_CONFIG			(MCUCFG_BASE + 0x064)
+
+#define MP0_RW_RSVD0				(MCUCFG_BASE + 0x06C)
+#define MP1_CA7_CACHE_CONFIG			(MCUCFG_BASE + 0x200)
+#define MP1_AXI_CONFIG				(MCUCFG_BASE + 0x22C)
+#define MP1_MISC_CONFIG0			(MCUCFG_BASE + 0x230)
+#define MP1_MISC_CONFIG1			(MCUCFG_BASE + 0x234)
+#define MP1_MISC_CONFIG2			(MCUCFG_BASE + 0x238)
+#define MP1_MISC_CONFIG_BOOT_ADDR(cpu)		(MCUCFG_BASE + 0x238 + ((cpu) * 8))
+#define MP1_MISC_CONFIG3			(MCUCFG_BASE + 0x23C)
+#define MP1_MISC_CONFIG9			(MCUCFG_BASE + 0x254)
+#define MP1_CA7_MISC_CONFIG			(MCUCFG_BASE + 0x264)
+
+#define CCI_ADB400_DCM_CONFIG			(MCUCFG_BASE + 0x740)
+#define SYNC_DCM_CONFIG				(MCUCFG_BASE + 0x744)
+
+#define MP0_CLUSTER_CFG0			(MCUCFG_BASE + 0xC8D0)
+
+#define MP0_SPMC				(MCUCFG_BASE + 0x788)
+#define MP1_SPMC				(MCUCFG_BASE + 0x78C)
+#define MP2_AXI_CONFIG				(MCUCFG_BASE + 0x220C)
+#define MP2_AXI_CONFIG_ACINACTM			BIT(0)
+#define MP2_AXI_CONFIG_AINACTS			BIT(4)
+
+#define MPx_AXI_CONFIG_ACINACTM			BIT(4)
+#define MPx_AXI_CONFIG_AINACTS			BIT(5)
+
+#define MPx_CA7_MISC_CONFIG_standbywfil2	BIT(28)
+
+#define MP0_CPU0_STANDBYWFE			BIT(20)
+#define MP0_CPU1_STANDBYWFE			BIT(21)
+#define MP0_CPU2_STANDBYWFE			BIT(22)
+#define MP0_CPU3_STANDBYWFE			BIT(23)
+
+#define MP1_CPU0_STANDBYWFE			BIT(20)
+#define MP1_CPU1_STANDBYWFE			BIT(21)
+#define MP1_CPU2_STANDBYWFE			BIT(22)
+#define MP1_CPU3_STANDBYWFE			BIT(23)
+
+#define CPUSYS0_SPARKVRETCNTRL			(MCUCFG_BASE+0x1c00)
+#define CPUSYS0_SPARKEN				(MCUCFG_BASE+0x1c04)
+#define CPUSYS0_AMUXSEL				(MCUCFG_BASE+0x1c08)
+#define CPUSYS1_SPARKVRETCNTRL			(MCUCFG_BASE+0x3c00)
+#define CPUSYS1_SPARKEN				(MCUCFG_BASE+0x3c04)
+#define CPUSYS1_AMUXSEL				(MCUCFG_BASE+0x3c08)
+
+#define MP2_PWR_RST_CTL				(MCUCFG_BASE + 0x2008)
+#define MP2_PTP3_CPUTOP_SPMC0			(MCUCFG_BASE + 0x22A0)
+#define MP2_PTP3_CPUTOP_SPMC1			(MCUCFG_BASE + 0x22A4)
+
+#define MP2_COQ					(MCUCFG_BASE + 0x22BC)
+#define MP2_COQ_SW_DIS				BIT(0)
+
+#define MP2_CA15M_MON_SEL			(MCUCFG_BASE + 0x2400)
+#define MP2_CA15M_MON_L				(MCUCFG_BASE + 0x2404)
+
+#define CPUSYS2_CPU0_SPMC_CTL			(MCUCFG_BASE + 0x2430)
+#define CPUSYS2_CPU1_SPMC_CTL			(MCUCFG_BASE + 0x2438)
+#define CPUSYS2_CPU0_SPMC_STA			(MCUCFG_BASE + 0x2434)
+#define CPUSYS2_CPU1_SPMC_STA			(MCUCFG_BASE + 0x243C)
+
+#define MP0_CA7L_DBG_PWR_CTRL			(MCUCFG_BASE + 0x068)
+#define MP1_CA7L_DBG_PWR_CTRL			(MCUCFG_BASE + 0x268)
+#define BIG_DBG_PWR_CTRL			(MCUCFG_BASE + 0x75C)
+
+#define MP2_SW_RST_B				BIT(0)
+#define MP2_TOPAON_APB_MASK			BIT(1)
+#define B_SW_HOT_PLUG_RESET			BIT(30)
+#define B_SW_PD_OFFSET				(18)
+#define B_SW_PD					(0x3F << B_SW_PD_OFFSET)
+
+#define B_SW_SRAM_SLEEPB_OFFSET			(12)
+#define B_SW_SRAM_SLEEPB			(0x3F << B_SW_SRAM_SLEEPB_OFFSET)
+
+#define B_SW_SRAM_ISOINTB			BIT(9)
+#define B_SW_ISO				BIT(8)
+#define B_SW_LOGIC_PDB				BIT(7)
+#define B_SW_LOGIC_PRE2_PDB			BIT(6)
+#define B_SW_LOGIC_PRE1_PDB			BIT(5)
+#define B_SW_FSM_OVERRIDE			BIT(4)
+#define B_SW_PWR_ON				BIT(3)
+#define B_SW_PWR_ON_OVERRIDE_EN			BIT(2)
+
+#define B_FSM_STATE_OUT_OFFSET			(6)
+#define B_FSM_STATE_OUT_MASK			(0x1F << B_FSM_STATE_OUT_OFFSET)
+#define B_SW_LOGIC_PDBO_ALL_OFF_ACK		BIT(5)
+#define B_SW_LOGIC_PDBO_ALL_ON_ACK		BIT(4)
+#define B_SW_LOGIC_PRE2_PDBO_ALL_ON_ACK		BIT(3)
+#define B_SW_LOGIC_PRE1_PDBO_ALL_ON_ACK		BIT(2)
+
+
+#define B_FSM_OFF				(0U << B_FSM_STATE_OUT_OFFSET)
+#define B_FSM_ON				(1U << B_FSM_STATE_OUT_OFFSET)
+#define B_FSM_RET				(2U << B_FSM_STATE_OUT_OFFSET)
+
+#ifndef __ASSEMBLER__
+/* cpu boot mode */
+enum mp0_coucfg_64bit_ctrl {
+	MP0_CPUCFG_64BIT_SHIFT = 12,
+	MP1_CPUCFG_64BIT_SHIFT = 28,
+	MP0_CPUCFG_64BIT = 0xfu << MP0_CPUCFG_64BIT_SHIFT,
+	MP1_CPUCFG_64BIT = 0xfu << MP1_CPUCFG_64BIT_SHIFT,
+};
+
+enum mp1_dis_rgu0_ctrl {
+	MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT = 0,
+	MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT = 4,
+	MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT = 8,
+	MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT = 12,
+	MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT = 16,
+	MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT,
+	MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT,
+	MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT,
+	MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT,
+	MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT,
+};
+
+enum mp1_ainacts_ctrl {
+	MP1_AINACTS_SHIFT = 4,
+	MP1_AINACTS = 1U << MP1_AINACTS_SHIFT,
+};
+
+enum mp1_sw_cg_gen {
+	MP1_SW_CG_GEN_SHIFT = 12,
+	MP1_SW_CG_GEN = 1U << MP1_SW_CG_GEN_SHIFT,
+};
+
+enum mp1_l2rstdisable {
+	MP1_L2RSTDISABLE_SHIFT = 14,
+	MP1_L2RSTDISABLE = 1U << MP1_L2RSTDISABLE_SHIFT,
+};
+#endif /*__ASSEMBLER__*/
+
+#endif  /* MCUCFG_V1_H */
diff --git a/plat/mediatek/helpers/armv8_2/arch_helpers.S b/plat/mediatek/helpers/armv8_2/arch_helpers.S
new file mode 100644
index 0000000..02d8d53
--- /dev/null
+++ b/plat/mediatek/helpers/armv8_2/arch_helpers.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cpu_macros.S>
+#if CONFIG_MTK_MCUSYS
+#include <mcucfg.h>
+#endif
+#include <platform_def.h>
+	/*
+	 * Declare as weak function so that can be
+	 * overwritten by platform helpers
+	 */
+	.weak platform_mem_init
+	.weak plat_core_pos_by_mpidr
+	.weak plat_my_core_pos
+	.weak plat_mediatek_calc_core_pos
+	.global plat_mpidr_by_core_pos
+	.global plat_reset_handler
+
+	/* -----------------------------------------------------
+	 * unsigned long plat_mpidr_by_core_pos(uint32_t cpuid)
+	 * This function calcuate mpidr by cpu pos if cpu
+	 * topology is linear.
+	 *
+	 * Clobbers: x0-x1
+	 * -----------------------------------------------------
+	 */
+func plat_mpidr_by_core_pos
+	lsl x0, x0, #MPIDR_AFF1_SHIFT
+	mrs x1, mpidr_el1
+	and x1, x1, #MPIDR_MT_MASK
+	orr x0, x0, x1
+	ret
+endfunc plat_mpidr_by_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_arm_calc_core_pos()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b plat_mediatek_calc_core_pos
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 * int plat_mediatek_calc_core_pos(u_register_t mpidr);
+	 *
+	 * In ARMv8.2, AFF2 is cluster id, AFF1 is core id and
+	 * AFF0 is thread id. There is only one cluster in ARMv8.2
+	 * and one thread in current implementation.
+	 *
+	 * With this function: CorePos = CoreID (AFF1)
+	 * we do it with x0 = (x0 >> 8) & 0xff
+	 * -----------------------------------------------------
+	 */
+func plat_mediatek_calc_core_pos
+	b plat_core_pos_by_mpidr
+endfunc plat_mediatek_calc_core_pos
+
+	/* ------------------------------------------------------
+	 * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+	 *
+	 * This function implements a part of the critical
+	 * interface between the psci generic layer and the
+	 * platform that allows the former to query the platform
+	 * to convert an MPIDR to a unique linear index.
+	 *
+	 * Clobbers: x0-x1
+	 * ------------------------------------------------------
+	 */
+func plat_core_pos_by_mpidr
+	mov	x1, #MPIDR_AFFLVL_MASK
+	and	x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
+	ret
+endfunc plat_core_pos_by_mpidr
+
+	/* --------------------------------------------------------
+	 * void platform_mem_init (void);
+	 *
+	 * Any memory init, relocation to be done before the
+	 * platform boots. Called very early in the boot process.
+	 * --------------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
+
+func plat_reset_handler
+#if CONFIG_MTK_MCUSYS
+	mov	x10, x30
+	bl	plat_my_core_pos
+	mov	x30, x10
+	mov     w1, #0x1
+	lsl     w1, w1, w0
+	ldr	x0, =CPC_MCUSYS_CPU_ON_SW_HINT_SET
+	str     w1, [x0]
+	dsb     sy
+#endif
+
+#if CONFIG_MTK_ECC
+	mov x10, x30
+	/* enable sequence of ecc for cpus */
+	bl disable_core_ecc
+	bl ft_ecc_clear_per_core
+	bl enable_core_ecc
+	mov x30, x10
+#endif
+
+	ret
+endfunc plat_reset_handler
diff --git a/plat/mediatek/helpers/rules.mk b/plat/mediatek/helpers/rules.mk
new file mode 100644
index 0000000..ae8068e
--- /dev/null
+++ b/plat/mediatek/helpers/rules.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := helpers
+LOCAL_SRCS-y += $(LOCAL_DIR)/$(ARCH_VERSION)/arch_helpers.S
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/include/armv8_2/arch_def.h b/plat/mediatek/include/armv8_2/arch_def.h
new file mode 100644
index 0000000..61f818f
--- /dev/null
+++ b/plat/mediatek/include/armv8_2/arch_def.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARCH_DEF_H
+#define ARCH_DEF_H
+
+/* Topology constants */
+#define PLAT_MAX_PWR_LVL		(2)
+#define PLAT_MAX_RET_STATE		(1)
+#define PLAT_MAX_OFF_STATE		(2)
+
+#define PLATFORM_SYSTEM_COUNT		(1)
+#define PLATFORM_CLUSTER_COUNT		(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	(8)
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	(8)
+#define PLATFORM_NUM_AFFS		(PLATFORM_SYSTEM_COUNT + \
+					 PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+/* Cachline size */
+#define CACHE_WRITEBACK_SHIFT		(6)
+#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
+
+#endif /* ARCH_DEF_H */
+
diff --git a/plat/mediatek/include/cold_boot.h b/plat/mediatek/include/cold_boot.h
deleted file mode 100644
index 6b94b57..0000000
--- a/plat/mediatek/include/cold_boot.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2022, Mediatek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef COLD_BOOT_H
-#define COLD_BOOT_H
-
-#include <stdint.h>
-
-/*******************************************************************************
- * Function and variable prototypes
- ******************************************************************************/
-#define LINUX_KERNEL_32	(0)
-#define LINUX_KERNEL_64	(1)
-#define DEVINFO_SIZE	(4)
-
-struct atf_arg_t {
-	uint32_t atf_magic;
-	uint32_t tee_support;
-	uint64_t tee_entry;
-	uint64_t tee_boot_arg_addr;
-	uint32_t hwuid[4]; /* HW Unique id for t-base used */
-	uint32_t HRID[8]; /* HW random id for t-base used */
-	uint32_t devinfo[DEVINFO_SIZE];
-};
-
-struct mtk_bl31_fw_config {
-	void *from_bl2; /* MTK boot tag */
-	void *soc_fw_config;
-	void *hw_config;
-	void *reserved;
-};
-
-enum {
-	BOOT_ARG_FROM_BL2,
-	BOOT_ARG_SOC_FW_CONFIG,
-	BOOT_ARG_HW_CONFIG,
-	BOOT_ARG_RESERVED
-};
-
-struct kernel_info {
-	uint64_t pc;
-	uint64_t r0;
-	uint64_t r1;
-	uint64_t r2;
-	uint64_t k32_64;
-};
-
-struct mtk_bl_param_t {
-	uint64_t bootarg_loc;
-	uint64_t bootarg_size;
-	uint64_t bl33_start_addr;
-	uint64_t atf_arg_addr;
-};
-
-void *get_mtk_bl31_fw_config(int index);
-bool is_el1_2nd_bootloader(void);
-
-#endif /* COLD_BOOT_H */
diff --git a/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c b/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c
new file mode 100644
index 0000000..ccd04e6
--- /dev/null
+++ b/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/arm/gicv3.h>
+#include <lib/psci/psci.h>
+#include <lib/utils.h>
+#ifdef MTK_PUBEVENT_ENABLE
+#include <mtk_event/mtk_pubsub_events.h>
+#endif
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+#include <dfd.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <lib/pm/mtk_pm.h>
+#include <mt_gic_v3.h>
+#include <platform_def.h>
+
+#define IS_AFFLV_PUBEVENT(_pstate) \
+	((_pstate & (MT_CPUPM_PWR_DOMAIN_MCUSYS | MT_CPUPM_PWR_DOMAIN_CLUSTER)) != 0)
+
+#ifdef MTK_PUBEVENT_ENABLE
+#define MT_CPUPM_EVENT_PWR_ON(x) ({ \
+	PUBLISH_EVENT_ARG(mt_cpupm_publish_pwr_on, (const void *)(x)); })
+
+#define MT_CPUPM_EVENT_PWR_OFF(x) ({ \
+	PUBLISH_EVENT_ARG(mt_cpupm_publish_pwr_off, (const void *)(x)); })
+
+#define MT_CPUPM_EVENT_AFFLV_PWR_ON(x) ({ \
+	PUBLISH_EVENT_ARG(mt_cpupm_publish_afflv_pwr_on, (const void *)(x)); })
+
+#define MT_CPUPM_EVENT_AFFLV_PWR_OFF(x) ({ \
+	PUBLISH_EVENT_ARG(mt_cpupm_publish_afflv_pwr_off, (const void *)(x)); })
+
+#else
+#define MT_CPUPM_EVENT_PWR_ON(x) ({ (void)x; })
+#define MT_CPUPM_EVENT_PWR_OFF(x) ({ (void)x; })
+#define MT_CPUPM_EVENT_AFFLV_PWR_ON(x) ({ (void)x; })
+#define MT_CPUPM_EVENT_AFFLV_PWR_OFF(x) ({ (void)x; })
+#endif
+
+/*
+ * The cpu require to cluster power stattus
+ * [0] : The cpu require cluster power down
+ * [1] : The cpu require cluster power on
+ */
+#define coordinate_cluster(onoff) write_clusterpwrdn_el1(onoff)
+#define coordinate_cluster_pwron() coordinate_cluster(1)
+#define coordinate_cluster_pwroff() coordinate_cluster(0)
+
+/* defaultly disable all functions */
+#define MTK_CPUPM_FN_MASK_DEFAULT	(0)
+
+struct mtk_cpu_pwr_ctrl {
+	unsigned int fn_mask;
+	struct mtk_cpu_pm_ops *ops;
+	struct mtk_cpu_smp_ops *smp;
+};
+
+static struct mtk_cpu_pwr_ctrl mtk_cpu_pwr = {
+	.fn_mask = MTK_CPUPM_FN_MASK_DEFAULT,
+	.ops = NULL,
+};
+
+#define IS_CPUIDLE_FN_ENABLE(x)	((mtk_cpu_pwr.ops != NULL) && ((mtk_cpu_pwr.fn_mask & x) != 0))
+#define IS_CPUSMP_FN_ENABLE(x)	((mtk_cpu_pwr.smp != NULL) && ((mtk_cpu_pwr.fn_mask & x) != 0))
+
+/* per-cpu power state */
+static unsigned int armv8_2_power_state[PLATFORM_CORE_COUNT];
+
+#define armv8_2_get_pwr_stateid(cpu) psci_get_pstate_id(armv8_2_power_state[cpu])
+
+static unsigned int get_mediatek_pstate(unsigned int domain, unsigned int psci_state,
+					struct mtk_cpupm_pwrstate *state)
+{
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_CPUPM_GET_PWR_STATE)) {
+		return mtk_cpu_pwr.ops->get_pstate(domain, psci_state, state);
+	}
+
+	return 0;
+}
+
+unsigned int armv8_2_get_pwr_afflv(const psci_power_state_t *state_info)
+{
+	int i;
+
+	for (i = (int)PLAT_MAX_PWR_LVL; i >= (int)PSCI_CPU_PWR_LVL; i--) {
+		if (is_local_state_run(state_info->pwr_domain_state[i]) == 0) {
+			return (unsigned int) i;
+		}
+	}
+
+	return PSCI_INVALID_PWR_LVL;
+}
+
+/* MediaTek mcusys power on control interface */
+static void armv8_2_mcusys_pwr_on_common(const struct mtk_cpupm_pwrstate *state)
+{
+	mt_gic_init();
+	mt_gic_distif_restore();
+	gic_sgi_restore_all();
+
+	dfd_resume();
+
+	/* Add code here that behavior before system enter mcusys'on */
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_RESUME_MCUSYS)) {
+		mtk_cpu_pwr.ops->mcusys_resume(state);
+	}
+}
+
+/* MediaTek mcusys power down control interface */
+static void armv8_2_mcusys_pwr_dwn_common(const struct mtk_cpupm_pwrstate *state)
+{
+	mt_gic_distif_save();
+	gic_sgi_save_all();
+
+	/* Add code here that behaves before entering mcusys off */
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_SUSPEND_MCUSYS)) {
+		mtk_cpu_pwr.ops->mcusys_suspend(state);
+	}
+}
+
+/* MediaTek Cluster power on control interface */
+static void armv8_2_cluster_pwr_on_common(const struct mtk_cpupm_pwrstate *state)
+{
+	/* Add code here that behavior before system enter cluster'on */
+#if defined(MTK_CM_MGR) && !defined(MTK_FPGA_EARLY_PORTING)
+	/* init cpu stall counter */
+	init_cpu_stall_counter_all();
+#endif
+
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_RESUME_CLUSTER)) {
+		mtk_cpu_pwr.ops->cluster_resume(state);
+	}
+}
+
+/* MediaTek Cluster power down control interface */
+static void armv8_2_cluster_pwr_dwn_common(const struct mtk_cpupm_pwrstate *state)
+{
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_SUSPEND_CLUSTER)) {
+		mtk_cpu_pwr.ops->cluster_suspend(state);
+	}
+}
+
+/* MediaTek CPU power on control interface */
+static void armv8_2_cpu_pwr_on_common(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	coordinate_cluster_pwron();
+
+	gicv3_rdistif_on(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+	mt_gic_rdistif_init();
+
+	/* If MCUSYS has been powered down then restore GIC redistributor for all CPUs. */
+	if (IS_PLAT_SYSTEM_RETENTION(state->pwr.afflv)) {
+		mt_gic_rdistif_restore_all();
+	} else {
+		mt_gic_rdistif_restore();
+	}
+}
+
+/* MediaTek CPU power down control interface */
+static void armv8_2_cpu_pwr_dwn_common(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_PERCORE_DSU) != 0) {
+		coordinate_cluster_pwroff();
+	}
+
+	mt_gic_rdistif_save();
+	gicv3_cpuif_disable(plat_my_core_pos());
+	gicv3_rdistif_off(plat_my_core_pos());
+}
+
+static void armv8_2_cpu_pwr_resume(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	armv8_2_cpu_pwr_on_common(state, pstate);
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_RESUME_CORE)) {
+		mtk_cpu_pwr.ops->cpu_resume(state);
+	}
+}
+
+static void armv8_2_cpu_pwr_suspend(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_SUSPEND_CORE)) {
+		mtk_cpu_pwr.ops->cpu_suspend(state);
+	}
+	armv8_2_cpu_pwr_dwn_common(state, pstate);
+}
+
+static void armv8_2_cpu_pwr_on(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	armv8_2_cpu_pwr_on_common(state, pstate);
+
+	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_SMP_CORE_ON)) {
+		mtk_cpu_pwr.smp->cpu_on(state);
+	}
+}
+
+static void armv8_2_cpu_pwr_off(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_SMP_CORE_OFF)) {
+		mtk_cpu_pwr.smp->cpu_off(state);
+	}
+	armv8_2_cpu_pwr_dwn_common(state, pstate);
+}
+
+/* MediaTek PSCI power domain */
+static int armv8_2_power_domain_on(u_register_t mpidr)
+{
+	int ret = PSCI_E_SUCCESS;
+	int cpu = plat_core_pos_by_mpidr(mpidr);
+	uintptr_t entry = plat_pm_get_warm_entry();
+
+	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_PWR_ON_CORE_PREPARE)) {
+		if (mtk_cpu_pwr.smp->cpu_pwr_on_prepare(cpu, entry) != 0) {
+			ret = PSCI_E_DENIED;
+		}
+	}
+	INFO("CPU %u power domain prepare on\n", cpu);
+	return ret;
+}
+
+/* MediaTek PSCI power domain */
+static void armv8_2_power_domain_on_finish(const psci_power_state_t *state)
+{
+	struct mt_cpupm_event_data nb;
+	unsigned int pstate = (MT_CPUPM_PWR_DOMAIN_CORE | MT_CPUPM_PWR_DOMAIN_PERCORE_DSU);
+	struct mtk_cpupm_pwrstate pm_state = {
+		.info = {
+			.cpuid = plat_my_core_pos(),
+			.mode = MTK_CPU_PM_SMP,
+		},
+		.pwr = {
+			.afflv = armv8_2_get_pwr_afflv(state),
+			.state_id = 0x0,
+		},
+	};
+
+	armv8_2_cpu_pwr_on(&pm_state, pstate);
+
+	nb.cpuid = pm_state.info.cpuid;
+	nb.pwr_domain = pstate;
+	MT_CPUPM_EVENT_PWR_ON(&nb);
+
+	INFO("CPU %u power domain on finished\n", pm_state.info.cpuid);
+}
+
+/* MediaTek PSCI power domain */
+static void armv8_2_power_domain_off(const psci_power_state_t *state)
+{
+	struct mt_cpupm_event_data nb;
+	unsigned int pstate = (MT_CPUPM_PWR_DOMAIN_CORE | MT_CPUPM_PWR_DOMAIN_PERCORE_DSU);
+	struct mtk_cpupm_pwrstate pm_state = {
+		.info = {
+			.cpuid = plat_my_core_pos(),
+			.mode = MTK_CPU_PM_SMP,
+		},
+		.pwr = {
+			.afflv = armv8_2_get_pwr_afflv(state),
+			.state_id = 0x0,
+		},
+	};
+	armv8_2_cpu_pwr_off(&pm_state, pstate);
+
+	nb.cpuid = pm_state.info.cpuid;
+	nb.pwr_domain = pstate;
+	MT_CPUPM_EVENT_PWR_OFF(&nb);
+
+	INFO("CPU %u power domain off\n", pm_state.info.cpuid);
+}
+
+/* MediaTek PSCI power domain */
+static void armv8_2_power_domain_suspend(const psci_power_state_t *state)
+{
+	unsigned int pstate = 0;
+	struct mt_cpupm_event_data nb;
+	struct mtk_cpupm_pwrstate pm_state = {
+		.info = {
+			.cpuid = plat_my_core_pos(),
+			.mode = MTK_CPU_PM_CPUIDLE,
+		},
+	};
+
+	pm_state.pwr.state_id = armv8_2_get_pwr_stateid(pm_state.info.cpuid);
+	pm_state.pwr.afflv = armv8_2_get_pwr_afflv(state);
+	pm_state.pwr.raw = state;
+
+	pstate = get_mediatek_pstate(CPUPM_PWR_OFF,
+				     armv8_2_power_state[pm_state.info.cpuid], &pm_state);
+
+	armv8_2_cpu_pwr_suspend(&pm_state, pstate);
+
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_CLUSTER) != 0) {
+		armv8_2_cluster_pwr_dwn_common(&pm_state);
+	}
+
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_MCUSYS) != 0) {
+		armv8_2_mcusys_pwr_dwn_common(&pm_state);
+	}
+
+	nb.cpuid = pm_state.info.cpuid;
+	nb.pwr_domain = pstate;
+	MT_CPUPM_EVENT_PWR_OFF(&nb);
+
+	if (IS_AFFLV_PUBEVENT(pstate)) {
+		MT_CPUPM_EVENT_AFFLV_PWR_OFF(&nb);
+	}
+}
+
+/* MediaTek PSCI power domain */
+static void armv8_2_power_domain_suspend_finish(const psci_power_state_t *state)
+{
+	unsigned int pstate = 0;
+	struct mt_cpupm_event_data nb;
+	struct mtk_cpupm_pwrstate pm_state = {
+		.info = {
+			.cpuid = plat_my_core_pos(),
+			.mode = MTK_CPU_PM_CPUIDLE,
+		},
+	};
+
+	pm_state.pwr.state_id = armv8_2_get_pwr_stateid(pm_state.info.cpuid);
+	pm_state.pwr.afflv = armv8_2_get_pwr_afflv(state);
+	pm_state.pwr.raw = state;
+
+	pstate = get_mediatek_pstate(CPUPM_PWR_ON,
+				     armv8_2_power_state[pm_state.info.cpuid], &pm_state);
+
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_MCUSYS) != 0) {
+		armv8_2_mcusys_pwr_on_common(&pm_state);
+	}
+
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_CLUSTER) != 0) {
+		armv8_2_cluster_pwr_on_common(&pm_state);
+	}
+
+	armv8_2_cpu_pwr_resume(&pm_state, pstate);
+
+	nb.cpuid = pm_state.info.cpuid;
+	nb.pwr_domain = pstate;
+	MT_CPUPM_EVENT_PWR_ON(&nb);
+
+	if (IS_AFFLV_PUBEVENT(pstate)) {
+		MT_CPUPM_EVENT_AFFLV_PWR_ON(&nb);
+	}
+}
+
+/* MediaTek PSCI power domain */
+static int armv8_2_validate_power_state(unsigned int power_state, psci_power_state_t *req_state)
+{
+	unsigned int i;
+	unsigned int pstate = psci_get_pstate_type(power_state);
+	unsigned int aff_lvl = psci_get_pstate_pwrlvl(power_state);
+	unsigned int my_core_pos = plat_my_core_pos();
+
+	if (mtk_cpu_pwr.ops == NULL) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_PWR_STATE_VALID)) {
+		if (mtk_cpu_pwr.ops->pwr_state_valid(aff_lvl, pstate) != 0) {
+			return PSCI_E_INVALID_PARAMS;
+		}
+	}
+
+	if (pstate == PSTATE_TYPE_STANDBY) {
+		req_state->pwr_domain_state[0] = PLAT_MAX_RET_STATE;
+	} else {
+		for (i = PSCI_CPU_PWR_LVL; i <= aff_lvl; i++) {
+			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+		}
+	}
+	armv8_2_power_state[my_core_pos] = power_state;
+
+	return PSCI_E_SUCCESS;
+}
+
+/* MediaTek PSCI power domain */
+#if CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND
+static void armv8_2_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	unsigned int i;
+	int ret;
+	unsigned int power_state;
+	unsigned int my_core_pos = plat_my_core_pos();
+
+	ret = mtk_cpu_pwr.ops->pwr_state_valid(PLAT_MAX_PWR_LVL,
+						PSTATE_TYPE_POWERDOWN);
+
+	if (ret != MTK_CPUPM_E_OK) {
+		/* Avoid suspend due to platform is not ready. */
+		req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] =
+						PLAT_MAX_RET_STATE;
+		for (i = PSCI_CPU_PWR_LVL + 1; i <= PLAT_MAX_PWR_LVL; i++) {
+			req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
+		}
+
+		power_state = psci_make_powerstate(0, PSTATE_TYPE_STANDBY, PSCI_CPU_PWR_LVL);
+	} else {
+		for (i = PSCI_CPU_PWR_LVL; i <= PLAT_MAX_PWR_LVL; i++) {
+			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+		}
+
+		power_state = psci_make_powerstate(MT_PLAT_PWR_STATE_SUSPEND,
+						   PSTATE_TYPE_POWERDOWN, PLAT_MAX_PWR_LVL);
+	}
+
+	armv8_2_power_state[my_core_pos] = power_state;
+	flush_dcache_range((uintptr_t)&armv8_2_power_state[my_core_pos],
+			   sizeof(armv8_2_power_state[my_core_pos]));
+}
+#endif
+static void armv8_2_pm_smp_init(unsigned int cpu_id, uintptr_t entry_point)
+{
+	if (entry_point == 0) {
+		ERROR("%s, warm_entry_point is null\n", __func__);
+		panic();
+	}
+	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_SMP_INIT)) {
+		mtk_cpu_pwr.smp->init(cpu_id, entry_point);
+	}
+	INFO("[%s:%d] - Initialize finished\n", __func__, __LINE__);
+}
+
+static struct plat_pm_pwr_ctrl armv8_2_pwr_ops = {
+	.pwr_domain_suspend = armv8_2_power_domain_suspend,
+	.pwr_domain_suspend_finish = armv8_2_power_domain_suspend_finish,
+	.validate_power_state = armv8_2_validate_power_state,
+#if CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND
+	.get_sys_suspend_power_state = armv8_2_get_sys_suspend_power_state,
+#endif
+};
+
+struct plat_pm_smp_ctrl armv8_2_smp_ops = {
+	.init = armv8_2_pm_smp_init,
+	.pwr_domain_on = armv8_2_power_domain_on,
+	.pwr_domain_off = armv8_2_power_domain_off,
+	.pwr_domain_on_finish = armv8_2_power_domain_on_finish,
+};
+
+#define ISSUE_CPU_PM_REG_FAIL(_success) ({ _success = false; assert(0); })
+
+#define CPM_PM_FN_CHECK(_fns, _ops, _id, _func, _result, _flag) ({ \
+	if ((_fns & _id)) { \
+		if (_ops->_func) \
+			_flag |= _id; \
+		else { \
+			ISSUE_CPU_PM_REG_FAIL(_result); \
+		} \
+	} })
+
+int register_cpu_pm_ops(unsigned int fn_flags, struct mtk_cpu_pm_ops *ops)
+{
+	bool success = true;
+	unsigned int fns = 0;
+
+	if ((ops == NULL) || (mtk_cpu_pwr.ops != NULL)) {
+		ERROR("[%s:%d] register cpu_pm fail !!\n", __FILE__, __LINE__);
+		return MTK_CPUPM_E_ERR;
+	}
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_RESUME_CORE,
+			cpu_resume, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SUSPEND_CORE,
+			cpu_suspend, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_RESUME_CLUSTER,
+			cluster_resume, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SUSPEND_CLUSTER,
+			cluster_suspend, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_RESUME_MCUSYS,
+			mcusys_resume, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SUSPEND_MCUSYS,
+			mcusys_suspend, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_CPUPM_GET_PWR_STATE,
+			get_pstate, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_PWR_STATE_VALID,
+			pwr_state_valid, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_INIT,
+			init, success, fns);
+
+	if (success) {
+		mtk_cpu_pwr.ops = ops;
+		mtk_cpu_pwr.fn_mask |= fns;
+		plat_pm_ops_setup_pwr(&armv8_2_pwr_ops);
+		INFO("[%s:%d] CPU pwr ops register success, support:0x%x\n",
+		     __func__, __LINE__, fns);
+	} else {
+		ERROR("[%s:%d] register cpu_pm ops fail !, fn:0x%x\n",
+		      __func__, __LINE__, fn_flags);
+		assert(0);
+	}
+	return MTK_CPUPM_E_OK;
+}
+
+int register_cpu_smp_ops(unsigned int fn_flags, struct mtk_cpu_smp_ops *ops)
+{
+	bool success = true;
+	unsigned int fns = 0;
+
+	if ((ops == NULL) || (mtk_cpu_pwr.smp != NULL)) {
+		ERROR("[%s:%d] register cpu_smp fail !!\n", __FILE__, __LINE__);
+		return MTK_CPUPM_E_ERR;
+	}
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SMP_INIT,
+			init, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_PWR_ON_CORE_PREPARE,
+			cpu_pwr_on_prepare, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SMP_CORE_ON,
+			cpu_on, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SMP_CORE_OFF,
+			cpu_off, success, fns);
+
+	if (success == true) {
+		mtk_cpu_pwr.smp = ops;
+		mtk_cpu_pwr.fn_mask |= fns;
+		plat_pm_ops_setup_smp(&armv8_2_smp_ops);
+		INFO("[%s:%d] CPU smp ops register success, support:0x%x\n",
+		     __func__, __LINE__, fns);
+	} else {
+		ERROR("[%s:%d] register cpu_smp ops fail !, fn:0x%x\n",
+		      __func__, __LINE__, fn_flags);
+		assert(0);
+	}
+	return MTK_CPUPM_E_OK;
+}
diff --git a/plat/mediatek/lib/pm/armv8_2/rules.mk b/plat/mediatek/lib/pm/armv8_2/rules.mk
new file mode 100644
index 0000000..0e065c5
--- /dev/null
+++ b/plat/mediatek/lib/pm/armv8_2/rules.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := armv${CONFIG_MTK_PM_ARCH}
+LOCAL_SRCS-y := ${LOCAL_DIR}/pwr_ctrl.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/lib/pm/mtk_pm.c b/plat/mediatek/lib/pm/mtk_pm.c
index 632a1e7..3dbeb51 100644
--- a/plat/mediatek/lib/pm/mtk_pm.c
+++ b/plat/mediatek/lib/pm/mtk_pm.c
@@ -4,15 +4,117 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <lib/psci/psci.h>
+#include <assert.h>
+#include <plat/common/platform.h>
+#include <lib/pm/mtk_pm.h>
 
-static const plat_psci_ops_t plat_psci_ops = {
-};
+#define MTK_PM_ST_SMP_READY	BIT(0)
+#define MTK_PM_ST_PWR_READY	BIT(1)
+#define MTK_PM_ST_RESET_READY	BIT(2)
+
+static uintptr_t mtk_secure_entrypoint;
+static plat_init_func mtk_plat_smp_init;
+static plat_psci_ops_t mtk_pm_ops;
+static unsigned int mtk_pm_status;
+
+uintptr_t plat_pm_get_warm_entry(void)
+{
+	return mtk_secure_entrypoint;
+}
+
+int plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl *ops)
+{
+	if (!ops) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+#if CONFIG_MTK_CPU_SUSPEND_EN
+	if (!mtk_pm_ops.pwr_domain_suspend) {
+		mtk_pm_ops.pwr_domain_suspend = ops->pwr_domain_suspend;
+	}
+
+	if (!mtk_pm_ops.pwr_domain_suspend_finish) {
+		mtk_pm_ops.pwr_domain_suspend_finish = ops->pwr_domain_suspend_finish;
+	}
+
+	if (!mtk_pm_ops.validate_power_state) {
+		mtk_pm_ops.validate_power_state = ops->validate_power_state;
+	}
+
+	if (!mtk_pm_ops.get_sys_suspend_power_state) {
+		mtk_pm_ops.get_sys_suspend_power_state = ops->get_sys_suspend_power_state;
+	}
+
+	mtk_pm_status |= MTK_PM_ST_PWR_READY;
+#endif
+	return MTK_CPUPM_E_OK;
+}
+
+int plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl *ops)
+{
+	if (!ops) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+#if CONFIG_MTK_SMP_EN
+	if (!mtk_pm_ops.pwr_domain_on) {
+		mtk_pm_ops.pwr_domain_on = ops->pwr_domain_on;
+	}
+
+	if (!mtk_pm_ops.pwr_domain_on_finish) {
+		mtk_pm_ops.pwr_domain_on_finish = ops->pwr_domain_on_finish;
+	}
+
+	if (!mtk_pm_ops.pwr_domain_off) {
+		mtk_pm_ops.pwr_domain_off = ops->pwr_domain_off;
+	}
+
+	if (!mtk_plat_smp_init) {
+		mtk_plat_smp_init = ops->init;
+	}
+
+	mtk_pm_status |= MTK_PM_ST_SMP_READY;
+#endif
+	return MTK_CPUPM_E_OK;
+}
+
+int plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl *ops)
+{
+	if (!ops) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+	if (!mtk_pm_ops.system_off) {
+		mtk_pm_ops.system_off = ops->system_off;
+	}
+
+	if (!mtk_pm_ops.system_reset) {
+		mtk_pm_ops.system_reset = ops->system_reset;
+	}
+
+	if (!mtk_pm_ops.system_reset2) {
+		mtk_pm_ops.system_reset2 = ops->system_reset2;
+	}
+
+	mtk_pm_status |= MTK_PM_ST_RESET_READY;
+
+	return MTK_CPUPM_E_OK;
+}
 
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
 			const plat_psci_ops_t **psci_ops)
 {
-	*psci_ops = &plat_psci_ops;
+	*psci_ops = &mtk_pm_ops;
+	mtk_secure_entrypoint = sec_entrypoint;
+
+	if (mtk_plat_smp_init) {
+		unsigned int cpu_id = plat_my_core_pos();
 
+		mtk_plat_smp_init(cpu_id, mtk_secure_entrypoint);
+	}
+	INFO("%s, smp:(%d), pwr_ctrl:(%d), system_reset:(%d)\n", __func__,
+	     !!(mtk_pm_status & MTK_PM_ST_SMP_READY),
+	     !!(mtk_pm_status & MTK_PM_ST_PWR_READY),
+	     !!(mtk_pm_status & MTK_PM_ST_RESET_READY));
 	return 0;
 }
diff --git a/plat/mediatek/lib/pm/mtk_pm.h b/plat/mediatek/lib/pm/mtk_pm.h
new file mode 100644
index 0000000..892a0b0
--- /dev/null
+++ b/plat/mediatek/lib/pm/mtk_pm.h
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_PM_H
+#define MTK_PM_H
+#include <lib/psci/psci.h>
+
+#if MTK_PUBEVENT_ENABLE
+#include <mtk_event/mtk_pubsub_events.h>
+#endif
+
+#define MTK_CPUPM_E_OK			(0)
+#define MTK_CPUPM_E_UNKNOWN		(-1)
+#define MTK_CPUPM_E_ERR			(-2)
+#define MTK_CPUPM_E_FAIL		(-3)
+#define MTK_CPUPM_E_NOT_SUPPORT		(-4)
+
+
+#define MTK_CPUPM_FN_PWR_LOCK_AQUIRE		BIT(0)
+#define MTK_CPUPM_FN_INIT			BIT(1)
+#define MTK_CPUPM_FN_PWR_STATE_VALID		BIT(2)
+#define MTK_CPUPM_FN_PWR_ON_CORE_PREPARE	BIT(3)
+#define MTK_CPUPM_FN_SUSPEND_CORE		BIT(4)
+#define MTK_CPUPM_FN_RESUME_CORE		BIT(5)
+#define MTK_CPUPM_FN_SUSPEND_CLUSTER		BIT(6)
+#define MTK_CPUPM_FN_RESUME_CLUSTER		BIT(7)
+#define MTK_CPUPM_FN_SUSPEND_MCUSYS		BIT(8)
+#define MTK_CPUPM_FN_RESUME_MCUSYS		BIT(9)
+#define MTK_CPUPM_FN_CPUPM_GET_PWR_STATE	BIT(10)
+#define MTK_CPUPM_FN_SMP_INIT			BIT(11)
+#define MTK_CPUPM_FN_SMP_CORE_ON		BIT(12)
+#define MTK_CPUPM_FN_SMP_CORE_OFF		BIT(13)
+
+enum mtk_cpupm_pstate {
+	MTK_CPUPM_CORE_ON,
+	MTK_CPUPM_CORE_OFF,
+	MTK_CPUPM_CORE_SUSPEND,
+	MTK_CPUPM_CORE_RESUME,
+	MTK_CPUPM_CLUSTER_SUSPEND,
+	MTK_CPUPM_CLUSTER_RESUME,
+	MTK_CPUPM_MCUSYS_SUSPEND,
+	MTK_CPUPM_MCUSYS_RESUME,
+};
+
+enum mtk_cpu_pm_mode {
+	MTK_CPU_PM_CPUIDLE,
+	MTK_CPU_PM_SMP,
+};
+
+#define MT_IRQ_REMAIN_MAX	(32)
+#define MT_IRQ_REMAIN_CAT_LOG	BIT(31)
+
+struct mt_irqremain {
+	unsigned int count;
+	unsigned int irqs[MT_IRQ_REMAIN_MAX];
+	unsigned int wakeupsrc_cat[MT_IRQ_REMAIN_MAX];
+	unsigned int wakeupsrc[MT_IRQ_REMAIN_MAX];
+};
+
+typedef void (*plat_init_func)(unsigned int, uintptr_t);
+
+struct plat_pm_smp_ctrl {
+	plat_init_func init;
+	int (*pwr_domain_on)(u_register_t mpidr);
+	void (*pwr_domain_off)(const psci_power_state_t *target_state);
+	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
+};
+
+struct plat_pm_pwr_ctrl {
+	void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
+	void (*pwr_domain_on_finish_late)(const psci_power_state_t *target_state);
+	void (*pwr_domain_suspend_finish)(const psci_power_state_t *target_state);
+	int (*validate_power_state)(unsigned int power_state, psci_power_state_t *req_state);
+	void (*get_sys_suspend_power_state)(psci_power_state_t *req_state);
+};
+
+struct plat_pm_reset_ctrl {
+	__dead2 void (*system_off)();
+	__dead2 void (*system_reset)();
+	int (*system_reset2)(int is_vendor, int reset_type, u_register_t cookie);
+};
+
+struct mtk_cpu_pm_info {
+	unsigned int cpuid;
+	unsigned int mode;
+};
+
+struct mtk_cpu_pm_state {
+	unsigned int afflv;
+	unsigned int state_id;
+	const psci_power_state_t *raw;
+};
+
+struct mtk_cpupm_pwrstate {
+	struct mtk_cpu_pm_info info;
+	struct mtk_cpu_pm_state pwr;
+};
+
+struct mtk_cpu_smp_ops {
+	void (*init)(unsigned int cpu, uintptr_t sec_entrypoint);
+	int (*cpu_pwr_on_prepare)(unsigned int cpu, uintptr_t entry);
+	void (*cpu_on)(const struct mtk_cpupm_pwrstate *state);
+	void (*cpu_off)(const struct mtk_cpupm_pwrstate *state);
+	int (*invoke)(unsigned int funcID, void *priv);
+};
+
+#define MT_CPUPM_PWR_DOMAIN_CORE		BIT(0)
+#define MT_CPUPM_PWR_DOMAIN_PERCORE_DSU		BIT(1)
+#define MT_CPUPM_PWR_DOMAIN_PERCORE_DSU_MEM	BIT(2)
+#define MT_CPUPM_PWR_DOMAIN_CLUSTER		BIT(3)
+#define MT_CPUPM_PWR_DOMAIN_MCUSYS		BIT(4)
+#define MT_CPUPM_PWR_DOMAIN_SUSPEND		BIT(5)
+
+enum mt_cpupm_pwr_domain {
+	CPUPM_PWR_ON,
+	CPUPM_PWR_OFF,
+};
+
+typedef	unsigned int mtk_pstate_type;
+
+struct mtk_cpu_pm_ops {
+	void (*init)(unsigned int cpu, uintptr_t sec_entrypoint);
+	unsigned int (*get_pstate)(enum mt_cpupm_pwr_domain domain,
+				   const mtk_pstate_type psci_state,
+				   const struct mtk_cpupm_pwrstate *state);
+	int (*pwr_state_valid)(unsigned int afflv, unsigned int state);
+	void (*cpu_suspend)(const struct mtk_cpupm_pwrstate *state);
+	void (*cpu_resume)(const struct mtk_cpupm_pwrstate *state);
+	void (*cluster_suspend)(const struct mtk_cpupm_pwrstate *state);
+	void (*cluster_resume)(const struct mtk_cpupm_pwrstate *state);
+	void (*mcusys_suspend)(const struct mtk_cpupm_pwrstate *state);
+	void (*mcusys_resume)(const struct mtk_cpupm_pwrstate *state);
+	int (*invoke)(unsigned int funcID, void *priv);
+};
+
+int register_cpu_pm_ops(unsigned int fn_flags, struct mtk_cpu_pm_ops *ops);
+int register_cpu_smp_ops(unsigned int fn_flags, struct mtk_cpu_smp_ops *ops);
+
+struct mt_cpupm_event_data {
+	unsigned int cpuid;
+	unsigned int pwr_domain;
+};
+
+/* Extension event for platform driver */
+#if MTK_PUBEVENT_ENABLE
+/* [PUB_EVENT] Core power on */
+#define MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_pwr_on, _fn)
+
+/* [PUB_EVENT] Core power off */
+#define MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_pwr_off, _fn)
+
+/* [PUB_EVENT] Cluster power on */
+#define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_ON(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_on, _fn)
+
+/* [PUB_EVENT] Cluster power off */
+#define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_OFF(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_off, _fn)
+
+/* [PUB_EVENT] Mcusys power on */
+#define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_ON(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_on, _fn)
+
+/* [PUB_EVENT] Mcusys power off */
+#define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_OFF(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_off, _fn)
+
+#else
+#define MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(_fn)
+#define MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(_fn)
+#define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_ON(_fn)
+#define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_OFF(_fn)
+#define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_ON(_fn)
+#define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_OFF(_fn)
+#endif
+
+/*
+ * Definition c-state power domain.
+ * bit[7:4] (main state id):
+ *  - 1: Cluster.
+ *  - 2: Mcusys.
+ *  - 3: Memory.
+ *  - 4: System pll.
+ *  - 5: System bus.
+ *  - 6: SoC 26m/DCXO.
+ *  - 7: Vcore buck.
+ *  - 15: Suspend.
+ * bit[3:0] (reserved for state_id extension):
+ *  - 4: CPU buck.
+ */
+#define MT_PLAT_PWR_STATE_CLUSTER	(0x0010)
+#define MT_PLAT_PWR_STATE_MCUSYS	(0x0020)
+#define MT_PLAT_PWR_STATE_MCUSYS_BUCK	(0x0024)
+#define MT_PLAT_PWR_STATE_SYSTEM_MEM	(0x0030)
+#define MT_PLAT_PWR_STATE_SYSTEM_PLL	(0x0040)
+#define MT_PLAT_PWR_STATE_SYSTEM_BUS	(0x0050)
+#define MT_PLAT_PWR_STATE_SUSPEND	(0x00f0)
+
+#define IS_MT_PLAT_PWR_STATE(state, target_state)	((state & target_state) == target_state)
+#define IS_MT_PLAT_PWR_STATE_MCUSYS(state)  IS_MT_PLAT_PWR_STATE(state, MT_PLAT_PWR_STATE_MCUSYS)
+
+#define PLAT_MT_SYSTEM_SUSPEND		PLAT_MAX_OFF_STATE
+#define PLAT_MT_CPU_SUSPEND_CLUSTER	PLAT_MAX_RET_STATE
+#define PLAT_MT_CPU_SUSPEND_MCUSYS	PLAT_MAX_RET_STATE
+
+#define IS_PLAT_SYSTEM_SUSPEND(aff)	(aff == PLAT_MT_SYSTEM_SUSPEND)
+#define IS_PLAT_SYSTEM_RETENTION(aff)	(aff >= PLAT_MAX_RET_STATE)
+
+#define IS_PLAT_SUSPEND_ID(stateid)	(stateid == MT_PLAT_PWR_STATE_SUSPEND)
+
+#define IS_PLAT_MCUSYSOFF_AFFLV(afflv)	(afflv >= PLAT_MT_CPU_SUSPEND_MCUSYS)
+
+int plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl *ops);
+int plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl *ops);
+int plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl *ops);
+uintptr_t plat_pm_get_warm_entry(void);
+
+#endif
diff --git a/plat/mediatek/lib/pm/rules.mk b/plat/mediatek/lib/pm/rules.mk
index 77d0408..29265c4 100644
--- a/plat/mediatek/lib/pm/rules.mk
+++ b/plat/mediatek/lib/pm/rules.mk
@@ -12,3 +12,6 @@
 LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_pm.c
 
 $(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
+
+SUB_RULES-$(CONFIG_MTK_PM_SUPPORT) := $(LOCAL_DIR)/armv${CONFIG_MTK_PM_ARCH}
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/lib/system_reset/reset_cros.c b/plat/mediatek/lib/system_reset/reset_cros.c
new file mode 100644
index 0000000..40e68ba
--- /dev/null
+++ b/plat/mediatek/lib/system_reset/reset_cros.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/gpio.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <lib/pm/mtk_pm.h>
+#include <plat_params.h>
+#include <pmic.h>
+#include <rtc.h>
+
+static void __dead2 mtk_system_reset_cros(void)
+{
+	struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset();
+
+	INFO("MTK System Reset\n");
+
+	gpio_set_value(gpio_reset->index, gpio_reset->polarity);
+
+	wfi();
+	ERROR("MTK System Reset: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 mtk_system_off_cros(void)
+{
+	INFO("MTK System Off\n");
+
+	rtc_power_off_sequence();
+	pmic_power_off();
+
+	wfi();
+	ERROR("MTK System Off: operation not handled.\n");
+	panic();
+}
+
+static struct plat_pm_reset_ctrl lib_reset_ctrl = {
+	.system_off = mtk_system_off_cros,
+	.system_reset = mtk_system_reset_cros,
+	.system_reset2 = NULL,
+};
+
+static int lib_reset_ctrl_init(void)
+{
+	INFO("Reset init\n");
+
+	plat_pm_ops_setup_reset(&lib_reset_ctrl);
+
+	return 0;
+}
+MTK_ARCH_INIT(lib_reset_ctrl_init);
diff --git a/plat/mediatek/lib/system_reset/rules.mk b/plat/mediatek/lib/system_reset/rules.mk
new file mode 100644
index 0000000..4f20663
--- /dev/null
+++ b/plat/mediatek/lib/system_reset/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := system_reset
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/reset_cros.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/mt8186/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8186/drivers/emi_mpu/emi_mpu.c
index 989ecf1..f2864a1 100644
--- a/plat/mediatek/mt8186/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8186/drivers/emi_mpu/emi_mpu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -96,5 +96,38 @@
 
 void emi_mpu_init(void)
 {
-	/* TODO: more setting for EMI MPU. */
+	struct emi_region_info_t region_info;
+
+	/* SCP DRAM */
+	region_info.start = 0x50000000ULL;
+	region_info.end = 0x5109FFFFULL;
+	region_info.region = 2;
+	SET_ACCESS_PERMISSION(region_info.apc, 1,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
+	emi_mpu_set_protection(&region_info);
+
+	/* DSP protect address */
+	region_info.start = 0x60000000ULL;	/* dram base addr */
+	region_info.end = 0x610FFFFFULL;
+	region_info.region = 3;
+	SET_ACCESS_PERMISSION(region_info.apc, 1,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
+	emi_mpu_set_protection(&region_info);
+
+	/* Forbidden All */
+	region_info.start = 0x40000000ULL;	/* dram base addr */
+	region_info.end = 0x1FFFF0000ULL;
+	region_info.region = 4;
+	SET_ACCESS_PERMISSION(region_info.apc, 1,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
+	emi_mpu_set_protection(&region_info);
 }
diff --git a/plat/mediatek/mt8186/platform.mk b/plat/mediatek/mt8186/platform.mk
index 6587970..68f4a1f 100644
--- a/plat/mediatek/mt8186/platform.mk
+++ b/plat/mediatek/mt8186/platform.mk
@@ -8,10 +8,10 @@
 MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
+                 -I${MTK_PLAT}/common/lpm                         \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/gic600/                    \
                  -I${MTK_PLAT}/drivers/gpio/                      \
-                 -I${MTK_PLAT}/drivers/lpm/                       \
                  -I${MTK_PLAT}/drivers/msdc/                      \
                  -I${MTK_PLAT}/drivers/msdc/${PLAT}               \
                  -I${MTK_PLAT}/drivers/pmic_wrap/                 \
@@ -51,10 +51,10 @@
                 ${MTK_PLAT}/common/mtk_plat_common.c                  \
                 ${MTK_PLAT}/common/mtk_sip_svc.c                      \
                 ${MTK_PLAT}/common/params_setup.c                     \
+                ${MTK_PLAT}/common/lpm/mt_lp_rm.c                     \
                 ${MTK_PLAT}/drivers/cirq/mt_cirq.c                    \
                 ${MTK_PLAT}/drivers/gic600/mt_gic_v3.c                \
                 ${MTK_PLAT}/drivers/gpio/mtgpio_common.c              \
-                ${MTK_PLAT}/drivers/lpm/mt_lp_rm.c                    \
                 ${MTK_PLAT}/drivers/msdc/mt_msdc.c                    \
                 ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init.c        \
                 ${MTK_PLAT}/drivers/rtc/rtc_common.c                  \
diff --git a/plat/mediatek/mt8188/aarch64/plat_helpers.S b/plat/mediatek/mt8188/aarch64/plat_helpers.S
deleted file mode 100644
index 7073ab1..0000000
--- a/plat/mediatek/mt8188/aarch64/plat_helpers.S
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <platform_def.h>
-
-	.globl plat_is_my_cpu_primary
-	.globl plat_my_core_pos
-	.globl plat_mediatek_calc_core_pos
-
-func plat_is_my_cpu_primary
-	mrs	x0, mpidr_el1
-	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
-	cmp	x0, #PLAT_PRIMARY_CPU
-	cset	x0, eq
-	ret
-endfunc plat_is_my_cpu_primary
-
-	/* -----------------------------------------------------
-	 *  unsigned int plat_my_core_pos(void)
-	 *  This function uses the plat_mediatek_calc_core_pos()
-	 *  definition to get the index of the calling CPU.
-	 * -----------------------------------------------------
-	 */
-func plat_my_core_pos
-	mrs	x0, mpidr_el1
-	b	plat_mediatek_calc_core_pos
-endfunc plat_my_core_pos
-
-	/* -----------------------------------------------------
-	 * unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
-	 *
-	 * With this function: CorePos = CoreID (AFF1)
-	 * we do it with x0 = (x0 >> 8) & 0xff
-	 * -----------------------------------------------------
-	 */
-func plat_mediatek_calc_core_pos
-	mov	x1, #MPIDR_AFFLVL_MASK
-	and	x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
-	ret
-endfunc plat_mediatek_calc_core_pos
diff --git a/plat/mediatek/include/mt8188/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
similarity index 86%
rename from plat/mediatek/include/mt8188/platform_def.h
rename to plat/mediatek/mt8188/include/platform_def.h
index 962d952..ee507fd 100644
--- a/plat/mediatek/include/mt8188/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -7,10 +7,13 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
+#include <arch_def.h>
+
 #define PLAT_PRIMARY_CPU	(0x0)
 
 #define MT_GIC_BASE		(0x0C000000)
 #define MCUCFG_BASE		(0x0C530000)
+#define MCUCFG_REG_SIZE		(0x10000)
 #define IO_PHYS			(0x10000000)
 
 /* Aggregate of all devices for MMU mapping */
@@ -23,6 +26,8 @@
  * GPIO related constants
  ******************************************************************************/
 #define GPIO_BASE		(IO_PHYS + 0x00005000)
+#define RGU_BASE		(IO_PHYS + 0x00007000)
+#define DRM_BASE		(IO_PHYS + 0x0000D000)
 #define IOCFG_RM_BASE		(IO_PHYS + 0x01C00000)
 #define IOCFG_LT_BASE		(IO_PHYS + 0x01E10000)
 #define IOCFG_LM_BASE		(IO_PHYS + 0x01E20000)
@@ -101,6 +106,12 @@
 #define DP_SEC_SIZE		(0x1000)
 
 /*******************************************************************************
+ * EMI MPU related constants
+ *******************************************************************************/
+#define EMI_MPU_BASE		(IO_PHYS + 0x00226000)
+#define SUB_EMI_MPU_BASE	(IO_PHYS + 0x00225000)
+
+/*******************************************************************************
  * System counter frequency related constants
  ******************************************************************************/
 #define SYS_COUNTER_FREQ_IN_HZ	(13000000)
@@ -116,22 +127,7 @@
  * Generic platform constants
  ******************************************************************************/
 #define PLATFORM_STACK_SIZE		(0x800)
-
 #define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
-
-#define PLAT_MAX_PWR_LVL		U(3)
-#define PLAT_MAX_RET_STATE		U(1)
-#define PLAT_MAX_OFF_STATE		U(9)
-
-#define PLATFORM_SYSTEM_COUNT		U(1)
-#define PLATFORM_MCUSYS_COUNT		U(1)
-#define PLATFORM_CLUSTER_COUNT		U(1)
-#define PLATFORM_CLUSTER0_CORE_COUNT	U(8)
-#define PLATFORM_CLUSTER1_CORE_COUNT	U(0)
-
-#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER0_CORE_COUNT)
-#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(8)
-
 #define SOC_CHIP_ID			U(0x8188)
 
 /*******************************************************************************
@@ -160,15 +156,17 @@
 #define MAX_MMAP_REGIONS		(16)
 
 /*******************************************************************************
- * Declarations and constants to access the mailboxes safely. Each mailbox is
- * aligned on the biggest cache line size in the platform. This is known only
- * to the platform as it might have a combination of integrated and external
- * caches. Such alignment ensures that two maiboxes do not sit on the same cache
- * line at any cache level. They could belong to different cpus/clusters &
- * get written while being protected by different locks causing corruption of
- * a valid mailbox address.
+ * CPU_EB TCM handling related constants
  ******************************************************************************/
-#define CACHE_WRITEBACK_SHIFT		(6)
-#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
+#define CPU_EB_TCM_BASE		(0x0C550000)
+#define CPU_EB_TCM_SIZE		(0x10000)
+#define CPU_EB_MBOX3_OFFSET	(0xFCE0)
+
+/*******************************************************************************
+ * CPU PM definitions
+ *******************************************************************************/
+#define PLAT_CPU_PM_B_BUCK_ISO_ID	(6)
+#define PLAT_CPU_PM_ILDO_ID		(6)
+#define CPU_IDLE_SRAM_BASE		(0x11B000)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt8188/plat_config.mk b/plat/mediatek/mt8188/plat_config.mk
index 0c1e7cd..cff97cb 100644
--- a/plat/mediatek/mt8188/plat_config.mk
+++ b/plat/mediatek/mt8188/plat_config.mk
@@ -29,6 +29,19 @@
 ERRATA_A78_1821534 := 1
 ERRATA_A78_2132060 := 1
 ERRATA_A78_2242635 := 1
+ERRATA_A78_2376745 := 1
+ERRATA_A78_2395406 := 1
+
+CONFIG_ARCH_ARM_V8_2 := y
+CONFIG_MTK_MCUSYS := y
+MCUSYS_VERSION := v1
+CONFIG_MTK_PM_SUPPORT := y
+CONFIG_MTK_PM_ARCH := 8_2
+CONFIG_MTK_CPU_PM_SUPPORT := y
+CONFIG_MTK_CPU_PM_ARCH := 3_2
+CONFIG_MTK_SMP_EN := y
+CONFIG_MTK_CPU_SUSPEND_EN := y
+CPU_PM_TINYSYS_SUPPORT := y
 
 MACH_MT8188 := 1
 $(eval $(call add_define,MACH_MT8188))
diff --git a/plat/mediatek/mt8188/plat_topology.c b/plat/mediatek/mt8188/plat_topology.c
deleted file mode 100644
index 9fa2855..0000000
--- a/plat/mediatek/mt8188/plat_topology.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <lib/psci/psci.h>
-
-#include <plat_helpers.h>
-#include <platform_def.h>
-
-const unsigned char mtk_power_domain_tree_desc[] = {
-	/* Number of root nodes */
-	PLATFORM_SYSTEM_COUNT,
-	/* Number of children for the root node */
-	PLATFORM_MCUSYS_COUNT,
-	/* Number of children for the mcusys node */
-	PLATFORM_CLUSTER_COUNT,
-	/* Number of children for the first cluster node */
-	PLATFORM_CLUSTER0_CORE_COUNT,
-};
-
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
-	return mtk_power_domain_tree_desc;
-}
-
-/*******************************************************************************
- * This function implements a part of the critical interface between the psci
- * generic layer and the platform that allows the former to query the platform
- * to convert an MPIDR to a unique linear index. An error code (-1) is returned
- * in case the MPIDR is invalid.
- ******************************************************************************/
-int plat_core_pos_by_mpidr(u_register_t mpidr)
-{
-	unsigned int cluster_id, cpu_id;
-
-	if ((read_mpidr() & MPIDR_MT_MASK) != 0) {
-		/* ARMv8.2 arch */
-		if ((mpidr & (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)) != 0) {
-			return -1;
-		}
-		return plat_mediatek_calc_core_pos(mpidr);
-	}
-
-	mpidr &= MPIDR_AFFINITY_MASK;
-
-	if ((mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0) {
-		return -1;
-	}
-
-	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
-
-	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
-		return -1;
-	}
-
-	/*
-	 * Validate cpu_id by checking whether it represents a CPU in
-	 * one of the two clusters present on the platform.
-	 */
-	if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
-		return -1;
-	}
-
-	return (cpu_id + (cluster_id * 8));
-}
diff --git a/plat/mediatek/mt8188/platform.mk b/plat/mediatek/mt8188/platform.mk
index 84bcfac..b509edc 100644
--- a/plat/mediatek/mt8188/platform.mk
+++ b/plat/mediatek/mt8188/platform.mk
@@ -14,23 +14,32 @@
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common \
 		 -I${MTK_PLAT}/include \
-		 -I${MTK_PLAT}/include/${MTK_SOC} \
+		 -I${MTK_PLAT}/include/${ARCH_VERSION} \
 		 -I${MTK_PLAT} \
 		 -I${MTK_PLAT_SOC}/include \
 		 -Idrivers/arm/gic \
 
 MODULES-y += $(MTK_PLAT)/common
+MODULES-y += $(MTK_PLAT)/common/lpm
 MODULES-y += $(MTK_PLAT)/lib/mtk_init
 MODULES-y += $(MTK_PLAT)/lib/pm
+MODULES-y += $(MTK_PLAT)/lib/system_reset
 MODULES-y += $(MTK_PLAT)/drivers/cirq
+MODULES-y += $(MTK_PLAT)/drivers/cpu_pm
+MODULES-y += $(MTK_PLAT)/drivers/dcm
+MODULES-y += $(MTK_PLAT)/drivers/dfd
 MODULES-y += $(MTK_PLAT)/drivers/dp
+MODULES-y += $(MTK_PLAT)/drivers/emi_mpu
 MODULES-y += $(MTK_PLAT)/drivers/gic600
 MODULES-y += $(MTK_PLAT)/drivers/gpio
 MODULES-y += $(MTK_PLAT)/drivers/iommu
+MODULES-y += $(MTK_PLAT)/drivers/mcusys
 MODULES-y += $(MTK_PLAT)/drivers/pmic
 MODULES-y += $(MTK_PLAT)/drivers/pmic_wrap
 MODULES-y += $(MTK_PLAT)/drivers/rtc
 MODULES-y += $(MTK_PLAT)/drivers/timer
+MODULES-y += $(MTK_PLAT)/helpers
+MODULES-y += $(MTK_PLAT)/topology
 
 PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \
 			  drivers/ti/uart/aarch64/16550_console.S \
@@ -47,9 +56,7 @@
 		plat/common/aarch64/crash_console_helpers.S \
 		${MTK_PLAT}/common/mtk_plat_common.c \
 		${MTK_PLAT}/common/params_setup.c \
-		${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
-		$(MTK_PLAT)/$(MTK_SOC)/plat_mmap.c \
-		$(MTK_PLAT)/$(MTK_SOC)/plat_topology.c
+		$(MTK_PLAT)/$(MTK_SOC)/plat_mmap.c
 
 include plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
 
diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk
index efc14ec..a19fc45 100644
--- a/plat/mediatek/mt8192/platform.mk
+++ b/plat/mediatek/mt8192/platform.mk
@@ -8,10 +8,10 @@
 MTK_PLAT_SOC  := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
+                 -I${MTK_PLAT}/common/lpm/                        \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/gic600/                    \
                  -I${MTK_PLAT}/drivers/gpio/                      \
-                 -I${MTK_PLAT}/drivers/lpm/                       \
                  -I${MTK_PLAT}/drivers/pmic/                      \
                  -I${MTK_PLAT}/drivers/pmic_wrap/                 \
                  -I${MTK_PLAT}/drivers/rtc/                       \
@@ -52,10 +52,10 @@
                    ${MTK_PLAT}/common/mtk_plat_common.c                  \
                    ${MTK_PLAT}/common/mtk_sip_svc.c                      \
                    ${MTK_PLAT}/common/params_setup.c                     \
+                   ${MTK_PLAT}/common/lpm/mt_lp_rm.c                     \
                    ${MTK_PLAT}/drivers/cirq/mt_cirq.c                    \
                    ${MTK_PLAT}/drivers/gic600/mt_gic_v3.c                \
                    ${MTK_PLAT}/drivers/gpio/mtgpio_common.c              \
-                   ${MTK_PLAT}/drivers/lpm/mt_lp_rm.c                    \
                    ${MTK_PLAT}/drivers/pmic/pmic.c                       \
                    ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init_v2.c     \
                    ${MTK_PLAT}/drivers/rtc/rtc_common.c                  \
diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk
index 414d655..80dfa53 100644
--- a/plat/mediatek/mt8195/platform.mk
+++ b/plat/mediatek/mt8195/platform.mk
@@ -8,11 +8,11 @@
 MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
+                 -I${MTK_PLAT}/common/lpm/                        \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/dp/                        \
                  -I${MTK_PLAT}/drivers/gic600/                    \
                  -I${MTK_PLAT}/drivers/gpio/                      \
-                 -I${MTK_PLAT}/drivers/lpm/                       \
                  -I${MTK_PLAT}/drivers/pmic/                      \
                  -I${MTK_PLAT}/drivers/pmic_wrap/                 \
                  -I${MTK_PLAT}/drivers/rtc/                       \
@@ -52,11 +52,11 @@
                 ${MTK_PLAT}/common/mtk_plat_common.c                  \
                 ${MTK_PLAT}/common/mtk_sip_svc.c                      \
                 ${MTK_PLAT}/common/params_setup.c                     \
+                ${MTK_PLAT}/common/lpm/mt_lp_rm.c                     \
                 ${MTK_PLAT}/drivers/cirq/mt_cirq.c                    \
                 ${MTK_PLAT}/drivers/dp/mt_dp.c                        \
                 ${MTK_PLAT}/drivers/gic600/mt_gic_v3.c                \
                 ${MTK_PLAT}/drivers/gpio/mtgpio_common.c              \
-                ${MTK_PLAT}/drivers/lpm/mt_lp_rm.c                    \
                 ${MTK_PLAT}/drivers/pmic/pmic.c                       \
                 ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init_v2.c     \
                 ${MTK_PLAT}/drivers/rtc/rtc_common.c                  \
diff --git a/plat/mediatek/topology/armv8_2/topology.c b/plat/mediatek/topology/armv8_2/topology.c
new file mode 100644
index 0000000..1627bbd
--- /dev/null
+++ b/plat/mediatek/topology/armv8_2/topology.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <lib/psci/psci.h>
+#include <platform_def.h>
+
+#pragma weak plat_get_power_domain_tree_desc
+
+static const unsigned char mtk_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* Number of children for the root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first cluster node */
+	PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+/*******************************************************************************
+ * This function returns the default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return mtk_power_domain_tree_desc;
+}
diff --git a/plat/mediatek/topology/rules.mk b/plat/mediatek/topology/rules.mk
new file mode 100644
index 0000000..29f15bb
--- /dev/null
+++ b/plat/mediatek/topology/rules.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := topology
+LOCAL_SRCS-y := $(LOCAL_DIR)/$(ARCH_VERSION)/topology.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/nxp/common/nv_storage/plat_nv_storage.c b/plat/nxp/common/nv_storage/plat_nv_storage.c
index 7ec4fdb..af3b966 100644
--- a/plat/nxp/common/nv_storage/plat_nv_storage.c
+++ b/plat/nxp/common/nv_storage/plat_nv_storage.c
@@ -13,6 +13,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <platform_def.h>
 #include <common/debug.h>
 #ifndef NXP_COINED_BB
 #include <flash_info.h>
diff --git a/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c b/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c
index 2231c18..28e2dab 100644
--- a/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c
+++ b/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c
@@ -85,32 +85,36 @@
 	return 0;
 }
 
-/* DDR model number: MT40A512M8HX-093E */
+/* DDR model number: MT40A1G8SA-062E:R */
 struct dimm_params ddr_raw_timing = {
 	.n_ranks = U(1),
 	.rank_density = ULL(2147483648),
 	.capacity = ULL(2147483648),
 	.primary_sdram_width = U(32),
-	.n_row_addr = U(15),
+	.ec_sdram_width = U(4),
+	.rdimm = U(0),
+	.mirrored_dimm = U(0),
+	.n_row_addr = U(16),
 	.n_col_addr = U(10),
 	.bank_group_bits = U(2),
+	.edc_config = U(2),
 	.burst_lengths_bitmask = U(0x0c),
-	.tckmin_x_ps = 938,
-	.tckmax_ps = 1500,
-	.caslat_x = U(0x000DFA00),
+	.tckmin_x_ps = 625,
+	.tckmax_ps = 2200,
+	.caslat_x = U(0x0001FFE00),
 	.taa_ps = 13500,
 	.trcd_ps = 13500,
 	.trp_ps = 13500,
-	.tras_ps = 33000,
-	.trc_ps = 46500,
+	.tras_ps = 32000,
+	.trc_ps = 45500,
 	.twr_ps = 15000,
-	.trfc1_ps = 260000,
-	.trfc2_ps = 160000,
-	.trfc4_ps = 110000,
+	.trfc1_ps = 350000,
+	.trfc2_ps = 260000,
+	.trfc4_ps = 160000,
 	.tfaw_ps = 21000,
-	.trrds_ps = 3700,
-	.trrdl_ps = 5300,
-	.tccdl_ps = 5355,
+	.trrds_ps = 3000,
+	.trrdl_ps = 4900,
+	.tccdl_ps = 5000,
 	.refresh_rate_ps = U(7800000),
 	.rc = U(0x1f),
 };
diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c b/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c
index 6d1707c..89c9c0a 100644
--- a/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c
+++ b/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c
@@ -12,6 +12,7 @@
 #include <lib/utils.h>
 
 #include <errata.h>
+#include "platform_def.h"
 
 static const struct rc_timing rce[] = {
 	{U(1600), U(8), U(7)},
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index e0b5271..6becc32 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -259,5 +259,8 @@
 ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
-# Do not enable SVE
-ENABLE_SVE_FOR_NS	:=	0
+# Later QEMU versions support SME and SVE.
+ifneq (${ARCH},aarch32)
+	ENABLE_SVE_FOR_NS	:= 1
+	ENABLE_SME_FOR_NS	:= 1
+endif
diff --git a/plat/qemu/qemu/qemu_helpers.c b/plat/qemu/qemu/qemu_helpers.c
index 01b8249..1b31ab5 100644
--- a/plat/qemu/qemu/qemu_helpers.c
+++ b/plat/qemu/qemu/qemu_helpers.c
@@ -6,10 +6,12 @@
 
 #include <assert.h>
 
+#include <common/bl_common.h>
 #if MEASURED_BOOT
 #include <common/desc_image_load.h>
 #endif
 #include <common/fdt_wrappers.h>
+#include <platform_def.h>
 
 #include <libfdt.h>
 
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index bbfa169..f85db8d 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -574,7 +574,7 @@
 		goto err;
 	}
 
-	node = ret = fdt_add_subnode(fdt, node, "rpc@ee200000");
+	node = ret = fdt_add_subnode(fdt, node, "spi@ee200000");
 	if (ret < 0) {
 		goto err;
 	}
diff --git a/plat/st/common/stm32cubeprogrammer_uart.c b/plat/st/common/stm32cubeprogrammer_uart.c
index 46ac9cf..d004dcf 100644
--- a/plat/st/common/stm32cubeprogrammer_uart.c
+++ b/plat/st/common/stm32cubeprogrammer_uart.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -486,13 +486,12 @@
 
 /* Init UART: 115200, 8bit 1stop parity even and enable FIFO mode */
 const struct stm32_uart_init_s init = {
-	.baud_rate = U(115200),
+	.baud_rate = STM32MP_UART_BAUDRATE,
 	.word_length = STM32_UART_WORDLENGTH_9B,
 	.stop_bits = STM32_UART_STOPBITS_1,
 	.parity = STM32_UART_PARITY_EVEN,
 	.hw_flow_control = STM32_UART_HWCONTROL_NONE,
 	.mode = STM32_UART_MODE_TX_RX,
-	.over_sampling = STM32_UART_OVERSAMPLING_16,
 	.fifo_mode = STM32_UART_FIFOMODE_EN,
 };
 
diff --git a/plat/st/common/stm32cubeprogrammer_usb.c b/plat/st/common/stm32cubeprogrammer_usb.c
index 19a6bba..75e8038 100644
--- a/plat/st/common/stm32cubeprogrammer_usb.c
+++ b/plat/st/common/stm32cubeprogrammer_usb.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 #include <errno.h>
+#include <string.h>
 
 #include <tools_share/firmware_image_package.h>
 
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index d922d3c..eee983f 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -274,8 +274,11 @@
 #if STM32MP_EARLY_CONSOLE
 void stm32mp_setup_early_console(void)
 {
+#if defined(IMAGE_BL2) || STM32MP_RECONFIGURE_CONSOLE
 	plat_crash_console_init();
+#endif
 	set_console(STM32MP_DEBUG_USART_BASE, STM32MP_DEBUG_USART_CLK_FRQ);
+	NOTICE("Early console setup\n");
 }
 #endif /* STM32MP_EARLY_CONSOLE */
 
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 8ecb4c3..fe4ef3d 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -103,8 +103,7 @@
 #define PLAT_STM32MP_NS_IMAGE_OFFSET	BL33_BASE
 
 /* Needed by STM32CubeProgrammer support */
-#define DWL_BUFFER_BASE			(STM32MP_DDR_BASE + U(0x08000000))
-#define DWL_BUFFER_SIZE			U(0x08000000)
+#define DWL_BUFFER_SIZE			U(0x01000000)
 
 /*
  * SSBL offset in case it's stored in eMMC boot partition.
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 7203de8..def2898 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -10,6 +10,7 @@
 USE_COHERENT_MEM	:=	0
 
 STM32MP_EARLY_CONSOLE	?=	0
+STM32MP_RECONFIGURE_CONSOLE ?=	0
 STM32MP_UART_BAUDRATE	?=	115200
 
 # Allow TF-A to concatenate BL2 & BL32 binaries in a single file,
@@ -121,6 +122,9 @@
 STM32MP_USB_PROGRAMMER	?=	0
 STM32MP_UART_PROGRAMMER	?=	0
 
+# Download load address for serial boot devices
+DWL_BUFFER_BASE 	?=	0xC7000000
+
 # Device tree
 ifeq ($(STM32MP13),1)
 BL2_DTSI		:=	stm32mp13-bl2.dtsi
@@ -205,6 +209,7 @@
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \
+		STM32MP_RECONFIGURE_CONSOLE \
 		STM32MP_SDMMC \
 		STM32MP_SPI_NAND \
 		STM32MP_SPI_NOR \
@@ -225,6 +230,7 @@
 
 $(eval $(call add_defines,\
 	$(sort \
+		DWL_BUFFER_BASE \
 		PLAT_PARTITION_MAX_ENTRIES \
 		PLAT_XLAT_TABLES_DYNAMIC \
 		STM32_TF_A_COPIES \
@@ -235,6 +241,7 @@
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \
+		STM32MP_RECONFIGURE_CONSOLE \
 		STM32MP_SDMMC \
 		STM32MP_SPI_NAND \
 		STM32MP_SPI_NOR \
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index 8106795..325666f 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-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,6 +40,8 @@
  ******************************************************************************/
 void sp_min_plat_fiq_handler(uint32_t id)
 {
+	(void)plat_crash_console_init();
+
 	switch (id & INT_ID_MASK) {
 	case STM32MP1_IRQ_TZC400:
 		tzc400_init(STM32MP1_TZC_BASE);
@@ -51,7 +53,7 @@
 		panic();
 		break;
 	default:
-		ERROR("SECURE IT handler not define for it : %u", id);
+		ERROR("SECURE IT handler not define for it : %u\n", id);
 		break;
 	}
 }
@@ -119,6 +121,8 @@
 	uintptr_t dt_addr = arg1;
 #endif
 
+	stm32mp_setup_early_console();
+
 	/* Imprecise aborts can be masked in NonSecure */
 	write_scr(read_scr() | SCR_AW_BIT);
 
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 116bd5d..a74d58c 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -666,5 +666,6 @@
 #define DT_RCC_SEC_CLK_COMPAT		"st,stm32mp1-rcc-secure"
 #endif
 #define DT_SDMMC2_COMPAT		"st,stm32-sdmmc2"
+#define DT_UART_COMPAT			"st,stm32h7-uart"
 
 #endif /* STM32MP1_DEF_H */
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
index cac9752..eb8823b 100644
--- a/plat/st/stm32mp1/stm32mp1_helper.S
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,8 @@
 
 	.globl	platform_mem_init
 	.globl	plat_report_exception
+	.globl	plat_report_prefetch_abort
+	.globl	plat_report_data_abort
 	.globl	plat_get_my_entrypoint
 	.globl	plat_secondary_cold_boot_setup
 	.globl	plat_reset_handler
@@ -30,20 +32,18 @@
 	bx	lr
 endfunc platform_mem_init
 
-func plat_report_exception
 #if DEBUG
+func plat_report_exception
 	mov	r8, lr
 
-	/* Test if an abort occurred */
+	/*
+	 * Test if an abort occurred
+	 * In this case the error message has already been displayed
+	 * by dedicated functions
+	 */
 	cmp	r0, #MODE32_abt
-	bne	undef_inst_lbl
-	ldr	r4, =abort_str
-	bl	asm_print_str
-	mrs	r4, lr_abt
-	sub	r4, r4, #4
-	b	print_exception_info
+	beq	1f
 
-undef_inst_lbl:
 	/* Test for an undefined instruction */
 	cmp	r0, #MODE32_und
 	bne	other_exception_lbl
@@ -69,12 +69,69 @@
 	ldr	r4, =end_error_str
 	bl	asm_print_str
 
+1:
 	bx	r8
-#else
-	bx	lr
-#endif
 endfunc plat_report_exception
 
+func plat_report_prefetch_abort
+	mov	r8, lr
+	mov	r9, r0
+
+	ldr	r4, =prefetch_abort_str
+	bl	asm_print_str
+
+	mov	r4, r9
+	sub	r4, r4, #4
+	bl	asm_print_hex
+
+	ldr	r4, =ifsr_str
+	bl	asm_print_str
+
+	ldcopr	r4, IFSR
+	bl	asm_print_hex
+
+	ldr	r4, =ifar_str
+	bl	asm_print_str
+
+	ldcopr	r4, IFAR
+	bl	asm_print_hex
+
+	ldr	r4, =end_error_str
+	bl	asm_print_str
+
+	bx	r8
+endfunc plat_report_prefetch_abort
+
+func plat_report_data_abort
+	mov	r8, lr
+	mov	r9, r0
+
+	ldr	r4, =data_abort_str
+	bl	asm_print_str
+
+	mov	r4, r9
+	sub	r4, r4, #8
+	bl	asm_print_hex
+
+	ldr	r4, =dfsr_str
+	bl	asm_print_str
+
+	ldcopr	r4, DFSR
+	bl	asm_print_hex
+
+	ldr	r4, =dfar_str
+	bl	asm_print_str
+
+	ldcopr	r4, DFAR
+	bl	asm_print_hex
+
+	ldr	r4, =end_error_str
+	bl	asm_print_str
+
+	bx	r8
+endfunc plat_report_data_abort
+#endif /* DEBUG */
+
 func plat_reset_handler
 	bx	lr
 endfunc plat_reset_handler
@@ -256,14 +313,24 @@
 
 #if DEBUG
 .section .rodata.rev_err_str, "aS"
-abort_str:
-	.asciz "\nAbort at: 0x"
+prefetch_abort_str:
+	.asciz "\nPrefetch Abort at: 0x"
+data_abort_str:
+	.asciz "\nData Abort at: 0x"
 undefined_str:
 	.asciz "\nUndefined instruction at: 0x"
 exception_start_str:
 	.asciz "\nException mode=0x"
 exception_end_str:
 	.asciz " at: 0x"
+dfsr_str:
+	.asciz " DFSR = 0x"
+dfar_str:
+	.asciz " DFAR = 0x"
+ifsr_str:
+	.asciz " IFSR = 0x"
+ifar_str:
+	.asciz " IFAR = 0x"
 end_error_str:
 	.asciz "\n\r"
 #endif
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index 5ccb774..1733930 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -7,6 +7,8 @@
 #ifndef PLAT_STARTUP_H
 #define PLAT_STARTUP_H
 
+#include <common/bl_common.h>
+
 /* For FSBL handover */
 enum fsbl_handoff {
 	FSBL_HANDOFF_SUCCESS = 0,
diff --git a/plat/xilinx/versal_net/plat_psci.c b/plat/xilinx/versal_net/plat_psci.c
index 299eca4..c5833a9 100644
--- a/plat/xilinx/versal_net/plat_psci.c
+++ b/plat/xilinx/versal_net/plat_psci.c
@@ -18,7 +18,6 @@
 
 #include <plat_private.h>
 
-#define FUNCID_MASK	U(0xffff)
 #define PM_RET_ERROR_NOFEATURE U(19)
 
 #define PM_IOCTL	34U
@@ -194,7 +193,7 @@
 	api_id = smc_fid & FUNCID_NUM_MASK;
 	VERBOSE("%s: smc_fid: %x, api_id=0x%x\n", __func__, smc_fid, api_id);
 
-	switch (smc_fid & FUNCID_MASK) {
+	switch (api_id) {
 	case PM_IOCTL:
 	{
 		ret = no_pm_ioctl(arg[0], arg[1], arg[2], arg[3]);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 0099070..e61310a 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -21,51 +21,51 @@
 #include "pm_common.h"
 #include "pm_ipi.h"
 
-#define CLK_NODE_MAX			U(6)
+#define CLK_NODE_MAX			(6U)
 
-#define CLK_PARENTS_ID_LEN		U(16)
-#define CLK_TOPOLOGY_NODE_OFFSET	U(16)
-#define CLK_TOPOLOGY_PAYLOAD_LEN	U(12)
-#define CLK_PARENTS_PAYLOAD_LEN		U(12)
-#define CLK_TYPE_SHIFT			U(2)
-#define CLK_CLKFLAGS_SHIFT		U(8)
-#define CLK_TYPEFLAGS_SHIFT		U(24)
-#define CLK_TYPEFLAGS2_SHIFT		U(4)
-#define CLK_TYPEFLAGS_BITS_MASK		U(0xFF)
-#define CLK_TYPEFLAGS2_BITS_MASK	U(0x0F00)
-#define CLK_TYPEFLAGS_BITS		U(8)
+#define CLK_PARENTS_ID_LEN		(16U)
+#define CLK_TOPOLOGY_NODE_OFFSET	(16U)
+#define CLK_TOPOLOGY_PAYLOAD_LEN	(12U)
+#define CLK_PARENTS_PAYLOAD_LEN		(12U)
+#define CLK_TYPE_SHIFT			(2U)
+#define CLK_CLKFLAGS_SHIFT		(8U)
+#define CLK_TYPEFLAGS_SHIFT		(24U)
+#define CLK_TYPEFLAGS2_SHIFT		(4U)
+#define CLK_TYPEFLAGS_BITS_MASK		(0xFFU)
+#define CLK_TYPEFLAGS2_BITS_MASK	(0x0F00U)
+#define CLK_TYPEFLAGS_BITS		(8U)
 
 #define CLK_EXTERNAL_PARENT	(PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
 
-#define NA_MULT					U(0)
-#define NA_DIV					U(0)
-#define NA_SHIFT				U(0)
-#define NA_WIDTH				U(0)
-#define NA_CLK_FLAGS				U(0)
-#define NA_TYPE_FLAGS				U(0)
+#define NA_MULT					(0U)
+#define NA_DIV					(0U)
+#define NA_SHIFT				(0U)
+#define NA_WIDTH				(0U)
+#define NA_CLK_FLAGS				(0U)
+#define NA_TYPE_FLAGS				(0U)
 
 /* PLL nodes related definitions */
-#define PLL_PRESRC_MUX_SHIFT			U(20)
-#define PLL_PRESRC_MUX_WIDTH			U(3)
-#define PLL_POSTSRC_MUX_SHIFT			U(24)
-#define PLL_POSTSRC_MUX_WIDTH			U(3)
-#define PLL_DIV2_MUX_SHIFT			U(16)
-#define PLL_DIV2_MUX_WIDTH			U(1)
-#define PLL_BYPASS_MUX_SHIFT			U(3)
-#define PLL_BYPASS_MUX_WIDTH			U(1)
+#define PLL_PRESRC_MUX_SHIFT			(20U)
+#define PLL_PRESRC_MUX_WIDTH			(3U)
+#define PLL_POSTSRC_MUX_SHIFT			(24U)
+#define PLL_POSTSRC_MUX_WIDTH			(3U)
+#define PLL_DIV2_MUX_SHIFT			(16U)
+#define PLL_DIV2_MUX_WIDTH			(1U)
+#define PLL_BYPASS_MUX_SHIFT			(3U)
+#define PLL_BYPASS_MUX_WIDTH			(1U)
 
 /* Peripheral nodes related definitions */
 /* Peripheral Clocks */
-#define PERIPH_MUX_SHIFT			U(0)
-#define PERIPH_MUX_WIDTH			U(3)
-#define PERIPH_DIV1_SHIFT			U(8)
-#define PERIPH_DIV1_WIDTH			U(6)
-#define PERIPH_DIV2_SHIFT			U(16)
-#define PERIPH_DIV2_WIDTH			U(6)
-#define PERIPH_GATE_SHIFT			U(24)
-#define PERIPH_GATE_WIDTH			U(1)
+#define PERIPH_MUX_SHIFT			(0U)
+#define PERIPH_MUX_WIDTH			(3U)
+#define PERIPH_DIV1_SHIFT			(8U)
+#define PERIPH_DIV1_WIDTH			(6U)
+#define PERIPH_DIV2_SHIFT			(16U)
+#define PERIPH_DIV2_WIDTH			(6U)
+#define PERIPH_GATE_SHIFT			(24U)
+#define PERIPH_GATE_WIDTH			(1U)
 
-#define USB_GATE_SHIFT				U(25)
+#define USB_GATE_SHIFT				(25U)
 
 /* External clock related definitions */
 
@@ -87,20 +87,20 @@
 
 
 #define PLLCTRL_BP_MASK				BIT(3)
-#define PLLCTRL_RESET_MASK			U(1)
-#define PLL_FRAC_OFFSET				U(8)
-#define PLL_FRAC_MODE				U(1)
-#define PLL_INT_MODE				U(0)
-#define PLL_FRAC_MODE_MASK			U(0x80000000)
-#define PLL_FRAC_MODE_SHIFT			U(31)
-#define PLL_FRAC_DATA_MASK			U(0xFFFF)
-#define PLL_FRAC_DATA_SHIFT			U(0)
-#define PLL_FBDIV_MASK				U(0x7F00)
-#define PLL_FBDIV_WIDTH				U(7)
-#define PLL_FBDIV_SHIFT				U(8)
+#define PLLCTRL_RESET_MASK			(1U)
+#define PLL_FRAC_OFFSET				(8U)
+#define PLL_FRAC_MODE				(1U)
+#define PLL_INT_MODE				(0U)
+#define PLL_FRAC_MODE_MASK			(0x80000000U)
+#define PLL_FRAC_MODE_SHIFT			(31U)
+#define PLL_FRAC_DATA_MASK			(0xFFFFU)
+#define PLL_FRAC_DATA_SHIFT			(0U)
+#define PLL_FBDIV_MASK				(0x7F00U)
+#define PLL_FBDIV_WIDTH				(7U)
+#define PLL_FBDIV_SHIFT				(8U)
 
-#define CLK_PLL_RESET_ASSERT			U(1)
-#define CLK_PLL_RESET_RELEASE			U(2)
+#define CLK_PLL_RESET_ASSERT			(1U)
+#define CLK_PLL_RESET_RELEASE			(2U)
 #define CLK_PLL_RESET_PULSE	(CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE)
 
 /* Common topology definitions */
@@ -2672,9 +2672,9 @@
 		if (nodes[i].type == div_type) {
 			if (CLK_DIVIDER_POWER_OF_TWO &
 					nodes[i].typeflags) {
-				*max_div = (1 << (BIT(nodes[i].width) - 1));
+				*max_div = (1U << (BIT(nodes[i].width) - 1U));
 			} else {
-				*max_div = BIT(nodes[i].width) - 1;
+				*max_div = BIT(nodes[i].width) - 1U;
 			}
 			return PM_RET_SUCCESS;
 		}
@@ -2815,7 +2815,7 @@
  */
 enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll)
 {
-	if (!pll) {
+	if (pll == NULL) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2838,7 +2838,7 @@
  */
 enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
 {
-	if (!pll) {
+	if (pll == NULL) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2862,7 +2862,7 @@
 	enum pm_ret_status status;
 	enum pm_pll_mode mode;
 
-	if (!pll || !state) {
+	if ((pll == NULL) || !state) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2896,7 +2896,7 @@
 					   enum clock_id clock_id,
 					   uint32_t parent_index)
 {
-	if (!pll) {
+	if (pll == NULL) {
 		return PM_RET_ERROR_ARGS;
 	}
 	if (pll->pre_src == clock_id) {
@@ -2929,7 +2929,7 @@
 					   enum clock_id clock_id,
 					   uint32_t *parent_index)
 {
-	if (!pll) {
+	if (pll == NULL) {
 		return PM_RET_ERROR_ARGS;
 	}
 	if (pll->pre_src == clock_id) {
@@ -2966,7 +2966,7 @@
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
+	if ((pll == NULL) || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
 		return PM_RET_ERROR_ARGS;
 	}
 	pll->mode = mode;
@@ -2988,7 +2988,7 @@
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if (!pll || !mode) {
+	if ((pll == NULL) || !mode) {
 		return PM_RET_ERROR_ARGS;
 	}
 	*mode = pll->mode;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index db476e8..cc0dacc 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -57,224 +57,224 @@
 
 //CLock Ids
 enum clock_id {
-	CLK_IOPLL,
-	CLK_RPLL,
-	CLK_APLL,
-	CLK_DPLL,
-	CLK_VPLL,
-	CLK_IOPLL_TO_FPD,
-	CLK_RPLL_TO_FPD,
-	CLK_APLL_TO_LPD,
-	CLK_DPLL_TO_LPD,
-	CLK_VPLL_TO_LPD,
-	CLK_ACPU,
-	CLK_ACPU_HALF,
-	CLK_DBG_FPD,
-	CLK_DBG_LPD,
-	CLK_DBG_TRACE,
-	CLK_DBG_TSTMP,
-	CLK_DP_VIDEO_REF,
-	CLK_DP_AUDIO_REF,
-	CLK_DP_STC_REF,
-	CLK_GDMA_REF,
-	CLK_DPDMA_REF,
-	CLK_DDR_REF,
-	CLK_SATA_REF,
-	CLK_PCIE_REF,
-	CLK_GPU_REF,
-	CLK_GPU_PP0_REF,
-	CLK_GPU_PP1_REF,
-	CLK_TOPSW_MAIN,
-	CLK_TOPSW_LSBUS,
-	CLK_GTGREF0_REF,
-	CLK_LPD_SWITCH,
-	CLK_LPD_LSBUS,
-	CLK_USB0_BUS_REF,
-	CLK_USB1_BUS_REF,
-	CLK_USB3_DUAL_REF,
-	CLK_USB0,
-	CLK_USB1,
-	CLK_CPU_R5,
-	CLK_CPU_R5_CORE,
-	CLK_CSU_SPB,
-	CLK_CSU_PLL,
-	CLK_PCAP,
-	CLK_IOU_SWITCH,
-	CLK_GEM_TSU_REF,
-	CLK_GEM_TSU,
-	CLK_GEM0_TX,
-	CLK_GEM1_TX,
-	CLK_GEM2_TX,
-	CLK_GEM3_TX,
-	CLK_GEM0_RX,
-	CLK_GEM1_RX,
-	CLK_GEM2_RX,
-	CLK_GEM3_RX,
-	CLK_QSPI_REF,
-	CLK_SDIO0_REF,
-	CLK_SDIO1_REF,
-	CLK_UART0_REF,
-	CLK_UART1_REF,
-	CLK_SPI0_REF,
-	CLK_SPI1_REF,
-	CLK_NAND_REF,
-	CLK_I2C0_REF,
-	CLK_I2C1_REF,
-	CLK_CAN0_REF,
-	CLK_CAN1_REF,
-	CLK_CAN0,
-	CLK_CAN1,
-	CLK_DLL_REF,
-	CLK_ADMA_REF,
-	CLK_TIMESTAMP_REF,
-	CLK_AMS_REF,
-	CLK_PL0_REF,
-	CLK_PL1_REF,
-	CLK_PL2_REF,
-	CLK_PL3_REF,
-	CLK_FPD_WDT,
-	CLK_IOPLL_INT,
-	CLK_IOPLL_PRE_SRC,
-	CLK_IOPLL_HALF,
-	CLK_IOPLL_INT_MUX,
-	CLK_IOPLL_POST_SRC,
-	CLK_RPLL_INT,
-	CLK_RPLL_PRE_SRC,
-	CLK_RPLL_HALF,
-	CLK_RPLL_INT_MUX,
-	CLK_RPLL_POST_SRC,
-	CLK_APLL_INT,
-	CLK_APLL_PRE_SRC,
-	CLK_APLL_HALF,
-	CLK_APLL_INT_MUX,
-	CLK_APLL_POST_SRC,
-	CLK_DPLL_INT,
-	CLK_DPLL_PRE_SRC,
-	CLK_DPLL_HALF,
-	CLK_DPLL_INT_MUX,
-	CLK_DPLL_POST_SRC,
-	CLK_VPLL_INT,
-	CLK_VPLL_PRE_SRC,
-	CLK_VPLL_HALF,
-	CLK_VPLL_INT_MUX,
-	CLK_VPLL_POST_SRC,
-	CLK_CAN0_MIO,
-	CLK_CAN1_MIO,
-	CLK_ACPU_FULL,
-	CLK_GEM0_REF,
-	CLK_GEM1_REF,
-	CLK_GEM2_REF,
-	CLK_GEM3_REF,
-	CLK_GEM0_REF_UNGATED,
-	CLK_GEM1_REF_UNGATED,
-	CLK_GEM2_REF_UNGATED,
-	CLK_GEM3_REF_UNGATED,
-	CLK_LPD_WDT,
-	END_OF_OUTPUT_CLKS,
+	CLK_IOPLL = (0U),
+	CLK_RPLL  = (1U),
+	CLK_APLL  = (2U),
+	CLK_DPLL  = (3U),
+	CLK_VPLL  = (4U),
+	CLK_IOPLL_TO_FPD = (5U),
+	CLK_RPLL_TO_FPD = (6U),
+	CLK_APLL_TO_LPD = (7U),
+	CLK_DPLL_TO_LPD = (8U),
+	CLK_VPLL_TO_LPD = (9U),
+	CLK_ACPU = (10U),
+	CLK_ACPU_HALF = (11U),
+	CLK_DBG_FPD = (12U),
+	CLK_DBG_LPD = (13U),
+	CLK_DBG_TRACE = (14U),
+	CLK_DBG_TSTMP = (15U),
+	CLK_DP_VIDEO_REF = (16U),
+	CLK_DP_AUDIO_REF = (17U),
+	CLK_DP_STC_REF = (18U),
+	CLK_GDMA_REF = (19U),
+	CLK_DPDMA_REF = (20U),
+	CLK_DDR_REF = (21U),
+	CLK_SATA_REF = (22U),
+	CLK_PCIE_REF = (23U),
+	CLK_GPU_REF = (24U),
+	CLK_GPU_PP0_REF = (25U),
+	CLK_GPU_PP1_REF = (26U),
+	CLK_TOPSW_MAIN = (27U),
+	CLK_TOPSW_LSBUS = (28U),
+	CLK_GTGREF0_REF = (29U),
+	CLK_LPD_SWITCH = (30U),
+	CLK_LPD_LSBUS = (31U),
+	CLK_USB0_BUS_REF = (32U),
+	CLK_USB1_BUS_REF = (33U),
+	CLK_USB3_DUAL_REF = (34U),
+	CLK_USB0 = (35U),
+	CLK_USB1 = (36U),
+	CLK_CPU_R5 = (37U),
+	CLK_CPU_R5_CORE = (38U),
+	CLK_CSU_SPB = (39U),
+	CLK_CSU_PLL = (40U),
+	CLK_PCAP = (41U),
+	CLK_IOU_SWITCH = (42U),
+	CLK_GEM_TSU_REF = (43U),
+	CLK_GEM_TSU = (44U),
+	CLK_GEM0_TX = (45U),
+	CLK_GEM1_TX = (46U),
+	CLK_GEM2_TX = (47U),
+	CLK_GEM3_TX = (48U),
+	CLK_GEM0_RX = (49U),
+	CLK_GEM1_RX = (50U),
+	CLK_GEM2_RX = (51U),
+	CLK_GEM3_RX = (52U),
+	CLK_QSPI_REF = (53U),
+	CLK_SDIO0_REF = (54U),
+	CLK_SDIO1_REF = (55U),
+	CLK_UART0_REF = (56U),
+	CLK_UART1_REF = (57U),
+	CLK_SPI0_REF = (58U),
+	CLK_SPI1_REF = (59U),
+	CLK_NAND_REF = (60U),
+	CLK_I2C0_REF = (61U),
+	CLK_I2C1_REF = (62U),
+	CLK_CAN0_REF = (63U),
+	CLK_CAN1_REF = (64U),
+	CLK_CAN0 = (65U),
+	CLK_CAN1 = (66U),
+	CLK_DLL_REF = (67U),
+	CLK_ADMA_REF = (68U),
+	CLK_TIMESTAMP_REF = (69U),
+	CLK_AMS_REF = (70U),
+	CLK_PL0_REF = (71U),
+	CLK_PL1_REF = (72U),
+	CLK_PL2_REF = (73U),
+	CLK_PL3_REF = (74U),
+	CLK_FPD_WDT = (75U),
+	CLK_IOPLL_INT = (76U),
+	CLK_IOPLL_PRE_SRC = (77U),
+	CLK_IOPLL_HALF = (78U),
+	CLK_IOPLL_INT_MUX = (79U),
+	CLK_IOPLL_POST_SRC = (80U),
+	CLK_RPLL_INT = (81U),
+	CLK_RPLL_PRE_SRC = (82U),
+	CLK_RPLL_HALF = (83U),
+	CLK_RPLL_INT_MUX = (84U),
+	CLK_RPLL_POST_SRC = (85U),
+	CLK_APLL_INT = (86U),
+	CLK_APLL_PRE_SRC = (87U),
+	CLK_APLL_HALF = (88U),
+	CLK_APLL_INT_MUX = (89U),
+	CLK_APLL_POST_SRC = (90U),
+	CLK_DPLL_INT = (91U),
+	CLK_DPLL_PRE_SRC = (92U),
+	CLK_DPLL_HALF = (93U),
+	CLK_DPLL_INT_MUX = (94U),
+	CLK_DPLL_POST_SRC = (95U),
+	CLK_VPLL_INT = (96U),
+	CLK_VPLL_PRE_SRC = (97U),
+	CLK_VPLL_HALF = (98U),
+	CLK_VPLL_INT_MUX = (99U),
+	CLK_VPLL_POST_SRC = (100U),
+	CLK_CAN0_MIO = (101U),
+	CLK_CAN1_MIO = (102U),
+	CLK_ACPU_FULL = (103U),
+	CLK_GEM0_REF = (104U),
+	CLK_GEM1_REF = (105U),
+	CLK_GEM2_REF = (106U),
+	CLK_GEM3_REF = (107U),
+	CLK_GEM0_REF_UNGATED = (108U),
+	CLK_GEM1_REF_UNGATED = (109U),
+	CLK_GEM2_REF_UNGATED = (110U),
+	CLK_GEM3_REF_UNGATED = (111U),
+	CLK_LPD_WDT = (112U),
+	END_OF_OUTPUT_CLKS = (113U),
 };
 
-#define CLK_MAX_OUTPUT_CLK (unsigned int)(END_OF_OUTPUT_CLKS)
+#define CLK_MAX_OUTPUT_CLK END_OF_OUTPUT_CLKS
 
 //External clock ids
 enum {
 	EXT_CLK_PSS_REF = END_OF_OUTPUT_CLKS,
-	EXT_CLK_VIDEO,
-	EXT_CLK_PSS_ALT_REF,
-	EXT_CLK_AUX_REF,
-	EXT_CLK_GT_CRX_REF,
-	EXT_CLK_SWDT0,
-	EXT_CLK_SWDT1,
-	EXT_CLK_GEM0_TX_EMIO,
-	EXT_CLK_GEM1_TX_EMIO,
-	EXT_CLK_GEM2_TX_EMIO,
-	EXT_CLK_GEM3_TX_EMIO,
-	EXT_CLK_GEM0_RX_EMIO,
-	EXT_CLK_GEM1_RX_EMIO,
-	EXT_CLK_GEM2_RX_EMIO,
-	EXT_CLK_GEM3_RX_EMIO,
-	EXT_CLK_MIO50_OR_MIO51,
-	EXT_CLK_MIO0,
-	EXT_CLK_MIO1,
-	EXT_CLK_MIO2,
-	EXT_CLK_MIO3,
-	EXT_CLK_MIO4,
-	EXT_CLK_MIO5,
-	EXT_CLK_MIO6,
-	EXT_CLK_MIO7,
-	EXT_CLK_MIO8,
-	EXT_CLK_MIO9,
-	EXT_CLK_MIO10,
-	EXT_CLK_MIO11,
-	EXT_CLK_MIO12,
-	EXT_CLK_MIO13,
-	EXT_CLK_MIO14,
-	EXT_CLK_MIO15,
-	EXT_CLK_MIO16,
-	EXT_CLK_MIO17,
-	EXT_CLK_MIO18,
-	EXT_CLK_MIO19,
-	EXT_CLK_MIO20,
-	EXT_CLK_MIO21,
-	EXT_CLK_MIO22,
-	EXT_CLK_MIO23,
-	EXT_CLK_MIO24,
-	EXT_CLK_MIO25,
-	EXT_CLK_MIO26,
-	EXT_CLK_MIO27,
-	EXT_CLK_MIO28,
-	EXT_CLK_MIO29,
-	EXT_CLK_MIO30,
-	EXT_CLK_MIO31,
-	EXT_CLK_MIO32,
-	EXT_CLK_MIO33,
-	EXT_CLK_MIO34,
-	EXT_CLK_MIO35,
-	EXT_CLK_MIO36,
-	EXT_CLK_MIO37,
-	EXT_CLK_MIO38,
-	EXT_CLK_MIO39,
-	EXT_CLK_MIO40,
-	EXT_CLK_MIO41,
-	EXT_CLK_MIO42,
-	EXT_CLK_MIO43,
-	EXT_CLK_MIO44,
-	EXT_CLK_MIO45,
-	EXT_CLK_MIO46,
-	EXT_CLK_MIO47,
-	EXT_CLK_MIO48,
-	EXT_CLK_MIO49,
-	EXT_CLK_MIO50,
-	EXT_CLK_MIO51,
-	EXT_CLK_MIO52,
-	EXT_CLK_MIO53,
-	EXT_CLK_MIO54,
-	EXT_CLK_MIO55,
-	EXT_CLK_MIO56,
-	EXT_CLK_MIO57,
-	EXT_CLK_MIO58,
-	EXT_CLK_MIO59,
-	EXT_CLK_MIO60,
-	EXT_CLK_MIO61,
-	EXT_CLK_MIO62,
-	EXT_CLK_MIO63,
-	EXT_CLK_MIO64,
-	EXT_CLK_MIO65,
-	EXT_CLK_MIO66,
-	EXT_CLK_MIO67,
-	EXT_CLK_MIO68,
-	EXT_CLK_MIO69,
-	EXT_CLK_MIO70,
-	EXT_CLK_MIO71,
-	EXT_CLK_MIO72,
-	EXT_CLK_MIO73,
-	EXT_CLK_MIO74,
-	EXT_CLK_MIO75,
-	EXT_CLK_MIO76,
-	EXT_CLK_MIO77,
-	END_OF_CLKS,
+	EXT_CLK_VIDEO = (114U),
+	EXT_CLK_PSS_ALT_REF = (115U),
+	EXT_CLK_AUX_REF = (116U),
+	EXT_CLK_GT_CRX_REF = (117U),
+	EXT_CLK_SWDT0 = (118U),
+	EXT_CLK_SWDT1 = (119U),
+	EXT_CLK_GEM0_TX_EMIO = (120U),
+	EXT_CLK_GEM1_TX_EMIO = (121U),
+	EXT_CLK_GEM2_TX_EMIO = (122U),
+	EXT_CLK_GEM3_TX_EMIO = (123U),
+	EXT_CLK_GEM0_RX_EMIO = (124U),
+	EXT_CLK_GEM1_RX_EMIO = (125U),
+	EXT_CLK_GEM2_RX_EMIO = (126U),
+	EXT_CLK_GEM3_RX_EMIO = (127U),
+	EXT_CLK_MIO50_OR_MIO51 = (128U),
+	EXT_CLK_MIO0 = (129U),
+	EXT_CLK_MIO1 = (130U),
+	EXT_CLK_MIO2 = (131U),
+	EXT_CLK_MIO3 = (132U),
+	EXT_CLK_MIO4 = (133U),
+	EXT_CLK_MIO5 = (134U),
+	EXT_CLK_MIO6 = (135U),
+	EXT_CLK_MIO7 = (136U),
+	EXT_CLK_MIO8 = (137U),
+	EXT_CLK_MIO9 = (138U),
+	EXT_CLK_MIO10 = (139U),
+	EXT_CLK_MIO11 = (140U),
+	EXT_CLK_MIO12 = (141U),
+	EXT_CLK_MIO13 = (142U),
+	EXT_CLK_MIO14 = (143U),
+	EXT_CLK_MIO15 = (144U),
+	EXT_CLK_MIO16 = (145U),
+	EXT_CLK_MIO17 = (146U),
+	EXT_CLK_MIO18 = (147U),
+	EXT_CLK_MIO19 = (148U),
+	EXT_CLK_MIO20 = (149U),
+	EXT_CLK_MIO21 = (150U),
+	EXT_CLK_MIO22 = (151U),
+	EXT_CLK_MIO23 = (152U),
+	EXT_CLK_MIO24 = (153U),
+	EXT_CLK_MIO25 = (154U),
+	EXT_CLK_MIO26 = (155U),
+	EXT_CLK_MIO27 = (156U),
+	EXT_CLK_MIO28 = (157U),
+	EXT_CLK_MIO29 = (158U),
+	EXT_CLK_MIO30 = (159U),
+	EXT_CLK_MIO31 = (160U),
+	EXT_CLK_MIO32 = (161U),
+	EXT_CLK_MIO33 = (162U),
+	EXT_CLK_MIO34 = (163U),
+	EXT_CLK_MIO35 = (164U),
+	EXT_CLK_MIO36 = (165U),
+	EXT_CLK_MIO37 = (166U),
+	EXT_CLK_MIO38 = (167U),
+	EXT_CLK_MIO39 = (168U),
+	EXT_CLK_MIO40 = (169U),
+	EXT_CLK_MIO41 = (170U),
+	EXT_CLK_MIO42 = (171U),
+	EXT_CLK_MIO43 = (172U),
+	EXT_CLK_MIO44 = (173U),
+	EXT_CLK_MIO45 = (174U),
+	EXT_CLK_MIO46 = (175U),
+	EXT_CLK_MIO47 = (176U),
+	EXT_CLK_MIO48 = (177U),
+	EXT_CLK_MIO49 = (178U),
+	EXT_CLK_MIO50 = (179U),
+	EXT_CLK_MIO51 = (180U),
+	EXT_CLK_MIO52 = (181U),
+	EXT_CLK_MIO53 = (182U),
+	EXT_CLK_MIO54 = (183U),
+	EXT_CLK_MIO55 = (184U),
+	EXT_CLK_MIO56 = (185U),
+	EXT_CLK_MIO57 = (186U),
+	EXT_CLK_MIO58 = (187U),
+	EXT_CLK_MIO59 = (188U),
+	EXT_CLK_MIO60 = (189U),
+	EXT_CLK_MIO61 = (190U),
+	EXT_CLK_MIO62 = (191U),
+	EXT_CLK_MIO63 = (192U),
+	EXT_CLK_MIO64 = (193U),
+	EXT_CLK_MIO65 = (194U),
+	EXT_CLK_MIO66 = (195U),
+	EXT_CLK_MIO67 = (196U),
+	EXT_CLK_MIO68 = (197U),
+	EXT_CLK_MIO69 = (198U),
+	EXT_CLK_MIO70 = (199U),
+	EXT_CLK_MIO71 = (200U),
+	EXT_CLK_MIO72 = (201U),
+	EXT_CLK_MIO73 = (202U),
+	EXT_CLK_MIO74 = (203U),
+	EXT_CLK_MIO75 = (204U),
+	EXT_CLK_MIO76 = (205U),
+	EXT_CLK_MIO77 = (206U),
+	END_OF_CLKS = (207U),
 };
 
-#define CLK_MAX (unsigned int)(END_OF_CLKS)
+#define CLK_MAX END_OF_CLKS
 
 //CLock types
 #define CLK_TYPE_OUTPUT 0U
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index 48e1b8d..c0bfd51 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -759,7 +759,7 @@
 		}
 		ret = check_api_dependency(ioctl_id);
 		if (ret == PM_RET_SUCCESS) {
-			bit_mask[ioctl_id / 32] |= BIT(ioctl_id % 32);
+			bit_mask[ioctl_id / 32U] |= BIT(ioctl_id % 32U);
 		}
 	}
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 945d060..8f37341 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -27,7 +27,7 @@
 };
 
 /* Max groups for one pin */
-#define MAX_PIN_GROUPS	U(13)
+#define MAX_PIN_GROUPS	(13U)
 
 struct zynqmp_pin_group {
 	uint16_t (*groups)[];
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
index 1b46375..5c4cb45 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
@@ -22,67 +22,67 @@
 
 //pinctrl function ids
 enum {
-	PINCTRL_FUNC_CAN0,
-	PINCTRL_FUNC_CAN1,
-	PINCTRL_FUNC_ETHERNET0,
-	PINCTRL_FUNC_ETHERNET1,
-	PINCTRL_FUNC_ETHERNET2,
-	PINCTRL_FUNC_ETHERNET3,
-	PINCTRL_FUNC_GEMTSU0,
-	PINCTRL_FUNC_GPIO0,
-	PINCTRL_FUNC_I2C0,
-	PINCTRL_FUNC_I2C1,
-	PINCTRL_FUNC_MDIO0,
-	PINCTRL_FUNC_MDIO1,
-	PINCTRL_FUNC_MDIO2,
-	PINCTRL_FUNC_MDIO3,
-	PINCTRL_FUNC_QSPI0,
-	PINCTRL_FUNC_QSPI_FBCLK,
-	PINCTRL_FUNC_QSPI_SS,
-	PINCTRL_FUNC_SPI0,
-	PINCTRL_FUNC_SPI1,
-	PINCTRL_FUNC_SPI0_SS,
-	PINCTRL_FUNC_SPI1_SS,
-	PINCTRL_FUNC_SDIO0,
-	PINCTRL_FUNC_SDIO0_PC,
-	PINCTRL_FUNC_SDIO0_CD,
-	PINCTRL_FUNC_SDIO0_WP,
-	PINCTRL_FUNC_SDIO1,
-	PINCTRL_FUNC_SDIO1_PC,
-	PINCTRL_FUNC_SDIO1_CD,
-	PINCTRL_FUNC_SDIO1_WP,
-	PINCTRL_FUNC_NAND0,
-	PINCTRL_FUNC_NAND0_CE,
-	PINCTRL_FUNC_NAND0_RB,
-	PINCTRL_FUNC_NAND0_DQS,
-	PINCTRL_FUNC_TTC0_CLK,
-	PINCTRL_FUNC_TTC0_WAV,
-	PINCTRL_FUNC_TTC1_CLK,
-	PINCTRL_FUNC_TTC1_WAV,
-	PINCTRL_FUNC_TTC2_CLK,
-	PINCTRL_FUNC_TTC2_WAV,
-	PINCTRL_FUNC_TTC3_CLK,
-	PINCTRL_FUNC_TTC3_WAV,
-	PINCTRL_FUNC_UART0,
-	PINCTRL_FUNC_UART1,
-	PINCTRL_FUNC_USB0,
-	PINCTRL_FUNC_USB1,
-	PINCTRL_FUNC_SWDT0_CLK,
-	PINCTRL_FUNC_SWDT0_RST,
-	PINCTRL_FUNC_SWDT1_CLK,
-	PINCTRL_FUNC_SWDT1_RST,
-	PINCTRL_FUNC_PMU0,
-	PINCTRL_FUNC_PCIE0,
-	PINCTRL_FUNC_CSU0,
-	PINCTRL_FUNC_DPAUX0,
-	PINCTRL_FUNC_PJTAG0,
-	PINCTRL_FUNC_TRACE0,
-	PINCTRL_FUNC_TRACE0_CLK,
-	PINCTRL_FUNC_TESTSCAN0,
-	END_FUNCTION,
+	PINCTRL_FUNC_CAN0 = (0U),
+	PINCTRL_FUNC_CAN1 = (1U),
+	PINCTRL_FUNC_ETHERNET0 = (2U),
+	PINCTRL_FUNC_ETHERNET1 = (3U),
+	PINCTRL_FUNC_ETHERNET2 = (4U),
+	PINCTRL_FUNC_ETHERNET3 = (5U),
+	PINCTRL_FUNC_GEMTSU0 = (6U),
+	PINCTRL_FUNC_GPIO0 = (7U),
+	PINCTRL_FUNC_I2C0 = (8U),
+	PINCTRL_FUNC_I2C1 = (9U),
+	PINCTRL_FUNC_MDIO0 = (10U),
+	PINCTRL_FUNC_MDIO1 = (11U),
+	PINCTRL_FUNC_MDIO2 = (12U),
+	PINCTRL_FUNC_MDIO3 = (13U),
+	PINCTRL_FUNC_QSPI0 = (14U),
+	PINCTRL_FUNC_QSPI_FBCLK = (15U),
+	PINCTRL_FUNC_QSPI_SS = (16U),
+	PINCTRL_FUNC_SPI0 = (17U),
+	PINCTRL_FUNC_SPI1 = (18U),
+	PINCTRL_FUNC_SPI0_SS = (19U),
+	PINCTRL_FUNC_SPI1_SS = (20U),
+	PINCTRL_FUNC_SDIO0 = (21U),
+	PINCTRL_FUNC_SDIO0_PC = (22U),
+	PINCTRL_FUNC_SDIO0_CD = (23U),
+	PINCTRL_FUNC_SDIO0_WP = (24U),
+	PINCTRL_FUNC_SDIO1 = (25U),
+	PINCTRL_FUNC_SDIO1_PC = (26U),
+	PINCTRL_FUNC_SDIO1_CD = (27U),
+	PINCTRL_FUNC_SDIO1_WP = (28U),
+	PINCTRL_FUNC_NAND0 = (29U),
+	PINCTRL_FUNC_NAND0_CE = (30U),
+	PINCTRL_FUNC_NAND0_RB = (31U),
+	PINCTRL_FUNC_NAND0_DQS = (32U),
+	PINCTRL_FUNC_TTC0_CLK = (33U),
+	PINCTRL_FUNC_TTC0_WAV = (34U),
+	PINCTRL_FUNC_TTC1_CLK = (35U),
+	PINCTRL_FUNC_TTC1_WAV = (36U),
+	PINCTRL_FUNC_TTC2_CLK = (37U),
+	PINCTRL_FUNC_TTC2_WAV = (38U),
+	PINCTRL_FUNC_TTC3_CLK = (39U),
+	PINCTRL_FUNC_TTC3_WAV = (40U),
+	PINCTRL_FUNC_UART0 = (41U),
+	PINCTRL_FUNC_UART1 = (42U),
+	PINCTRL_FUNC_USB0 = (43U),
+	PINCTRL_FUNC_USB1 = (44U),
+	PINCTRL_FUNC_SWDT0_CLK = (45U),
+	PINCTRL_FUNC_SWDT0_RST = (46U),
+	PINCTRL_FUNC_SWDT1_CLK = (47U),
+	PINCTRL_FUNC_SWDT1_RST = (48U),
+	PINCTRL_FUNC_PMU0 = (49U),
+	PINCTRL_FUNC_PCIE0 = (50U),
+	PINCTRL_FUNC_CSU0 = (51U),
+	PINCTRL_FUNC_DPAUX0 = (52U),
+	PINCTRL_FUNC_PJTAG0 = (53U),
+	PINCTRL_FUNC_TRACE0 = (54U),
+	PINCTRL_FUNC_TRACE0_CLK = (55U),
+	PINCTRL_FUNC_TESTSCAN0 = (56U),
+	END_FUNCTION = (57U),
 };
 
-#define MAX_FUNCTION (unsigned int)(END_FUNCTION)
+#define MAX_FUNCTION END_FUNCTION
 
 // pinctrl pin numbers
 enum {
@@ -164,10 +164,10 @@
 	PINCTRL_PIN_75,
 	PINCTRL_PIN_76,
 	PINCTRL_PIN_77,
-	END_PINS,
+	END_PINS = (78U),
 };
 
-#define MAX_PIN (unsigned int)(END_PINS)
+#define MAX_PIN END_PINS
 
 // pinctrl group ids
 enum  {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index d3e9a34..9ba9475 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -126,7 +126,7 @@
 				    uint32_t address_high,
 				    uint32_t size,
 				    uint32_t flags);
-unsigned int pm_get_shutdown_scope(void);
+uint32_t pm_get_shutdown_scope(void);
 void pm_get_callbackdata(uint32_t *data, size_t count);
 enum pm_ret_status pm_ioctl(enum pm_node_id nid,
 			    uint32_t ioctl_id,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 34b931e..a853e38 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -25,12 +25,12 @@
 #include "pm_client.h"
 #include "pm_ipi.h"
 
-#define IRQ_MAX		84
-#define NUM_GICD_ISENABLER	((IRQ_MAX >> 5) + 1)
-#define UNDEFINED_CPUID		(~0)
+#define IRQ_MAX		84U
+#define NUM_GICD_ISENABLER	((IRQ_MAX >> 5U) + 1U)
+#define UNDEFINED_CPUID		(~0U)
 
-#define PM_SUSPEND_MODE_STD		0
-#define PM_SUSPEND_MODE_POWER_OFF	1
+#define PM_SUSPEND_MODE_STD		0U
+#define PM_SUSPEND_MODE_POWER_OFF	1U
 
 DEFINE_BAKERY_LOCK(pm_client_secure_lock);
 
@@ -69,7 +69,7 @@
 };
 
 /* Interrupt to PM node ID map */
-static enum pm_node_id irq_node_map[IRQ_MAX + 1] = {
+static enum pm_node_id irq_node_map[IRQ_MAX + 1U] = {
 	NODE_UNKNOWN,
 	NODE_UNKNOWN,
 	NODE_UNKNOWN,
@@ -177,13 +177,13 @@
 {
 	uint32_t reg_num;
 	uint8_t pm_wakeup_nodes_set[NODE_MAX];
-	uintptr_t isenabler1 = BASE_GICD_BASE + GICD_ISENABLER + 4;
+	uintptr_t isenabler1 = BASE_GICD_BASE + GICD_ISENABLER + 4U;
 
 	/* In case of power-off suspend, only NODE_EXTERN must be set */
 	if (suspend_mode == PM_SUSPEND_MODE_POWER_OFF) {
 		enum pm_ret_status ret;
 
-		ret = pm_set_wakeup_source(NODE_APU, NODE_EXTERN, 1);
+		ret = pm_set_wakeup_source(NODE_APU, NODE_EXTERN, 1U);
 		/**
 		 * If NODE_EXTERN could not be set as wake source, proceed with
 		 * standard suspend (no one will wake the system otherwise)
@@ -195,11 +195,11 @@
 
 	zeromem(&pm_wakeup_nodes_set, sizeof(pm_wakeup_nodes_set));
 
-	for (reg_num = 0; reg_num < NUM_GICD_ISENABLER; reg_num++) {
+	for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
 		uint32_t base_irq = reg_num << ISENABLER_SHIFT;
-		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
+		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2U));
 
-		if (!reg) {
+		if (reg == 0) {
 			continue;
 		}
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 82da57c..b91878e 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -267,7 +267,7 @@
 	uint32_t api_id;
 
 	/* Handle case where PM wasn't initialized properly */
-	if (!pm_up)
+	if (pm_up == 0)
 		SMC_RET1(handle, SMC_UNK);
 
 	pm_arg[0] = (uint32_t)x1;
@@ -293,10 +293,10 @@
 	case PM_REQ_WAKEUP:
 	{
 		/* Use address flag is encoded in the 1st bit of the low-word */
-		uint32_t set_addr = pm_arg[1] & 0x1;
-		uint64_t address = (uint64_t)pm_arg[2] << 32;
+		uint32_t set_addr = pm_arg[1] & 0x1U;
+		uint64_t address = (uint64_t)pm_arg[2] << 32U;
 
-		address |= pm_arg[1] & (~0x1);
+		address |= pm_arg[1] & (~0x1U);
 		ret = pm_req_wakeup(pm_arg[0], set_addr, address,
 				    pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
@@ -330,7 +330,7 @@
 	case PM_GET_API_VERSION:
 		/* Check is PM API version already verified */
 		if (pm_ctx.api_version >= PM_VERSION) {
-			if (!ipi_irq_flag) {
+			if (ipi_irq_flag == 0U) {
 				/*
 				 * Enable IPI IRQ
 				 * assume the rich OS is OK to handle callback IRQs now.
@@ -338,7 +338,7 @@
 				 * the GIC.
 				 */
 				pm_ipi_irq_enable(primary_proc);
-				ipi_irq_flag = 1;
+				ipi_irq_flag = 1U;
 			}
 			SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
 				 ((uint64_t)pm_ctx.api_version << 32));
@@ -439,12 +439,12 @@
 		uint32_t value;
 
 		ret = pm_clock_getparent(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_GET_TRUSTZONE_VERSION:
 		SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
-			 ((uint64_t)ZYNQMP_TZ_VERSION << 32));
+			 ((uint64_t)ZYNQMP_TZ_VERSION << 32U));
 
 	case PM_SET_SUSPEND_MODE:
 		ret = pm_set_suspend_mode(pm_arg[0]);
@@ -464,7 +464,7 @@
 	{
 		ret = pm_secure_image(pm_arg[0], pm_arg[1], pm_arg[2],
 				      pm_arg[3], &result[0]);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
+		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
 			 result[1]);
 	}
 
@@ -474,7 +474,7 @@
 
 		ret = pm_fpga_read(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
 				   &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_SECURE_AES:
@@ -482,7 +482,7 @@
 		uint32_t value;
 
 		ret = pm_aes_engine(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_PLL_SET_PARAMETER:
@@ -494,7 +494,7 @@
 		uint32_t value;
 
 		ret = pm_pll_get_parameter(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32));
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32U));
 	}
 
 	case PM_PLL_SET_MODE:
@@ -506,7 +506,7 @@
 		uint32_t mode;
 
 		ret = pm_pll_get_mode(pm_arg[0], &mode);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32));
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32U));
 	}
 
 	case PM_REGISTER_ACCESS:
@@ -515,7 +515,7 @@
 
 		ret = pm_register_access(pm_arg[0], pm_arg[1], pm_arg[2],
 					 pm_arg[3], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_EFUSE_ACCESS:
@@ -525,12 +525,12 @@
 #if defined(ZYNQMP_SECURE_EFUSES)
 		if (is_caller_non_secure(flags)) {
 			SMC_RET1(handle,
-				 (((uint64_t)PM_RET_ERROR_NOT_ENABLED) << 32) |
+				 (((uint64_t)PM_RET_ERROR_NOT_ENABLED) << 32U) |
 				 (uint64_t)PM_RET_ERROR_ACCESS);
 		}
 #endif
 		ret = pm_efuse_access(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_FPGA_GET_VERSION:
@@ -541,8 +541,8 @@
 		PM_PACK_PAYLOAD5(payload, smc_fid & FUNCID_NUM_MASK,
 				 pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
 		ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, 3U);
-		SMC_RET2(handle, (uint64_t)ret | (uint64_t)ret_payload[0] << 32,
-			 (uint64_t)ret_payload[1] | (uint64_t)ret_payload[2] << 32);
+		SMC_RET2(handle, (uint64_t)ret | (uint64_t)ret_payload[0] << 32U,
+			 (uint64_t)ret_payload[1] | (uint64_t)ret_payload[2] << 32U);
 	}
 
 	case PM_FEATURE_CHECK:
@@ -552,8 +552,8 @@
 
 		ret = pm_feature_check(pm_arg[0], &version, bit_mask,
 				       ARRAY_SIZE(bit_mask));
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)version << 32),
-			 (uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32));
+		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)version << 32U),
+			 (uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32U));
 	}
 
 	default:
@@ -562,8 +562,8 @@
 				 pm_arg[2], pm_arg[3], pm_arg[4]);
 		ret = pm_ipi_send_sync(primary_proc, payload, result,
 				       PAYLOAD_ARG_CNT);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
-			 (uint64_t)result[1] | ((uint64_t)result[2] << 32));
+		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
+			 (uint64_t)result[1] | ((uint64_t)result[2] << 32U));
 	}
 }
 
@@ -595,7 +595,7 @@
 		uint32_t value;
 
 		ret = em_set_action(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case EM_REMOVE_ACTION:
@@ -603,7 +603,7 @@
 		uint32_t value;
 
 		ret = em_remove_action(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case EM_SEND_ERRORS:
@@ -611,7 +611,7 @@
 		uint32_t value;
 
 		ret = em_send_errors(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	default:
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 7cb76de..6bd9fdf 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -242,10 +242,12 @@
  * Forward SMC to the other security state
  ******************************************************************************/
 static uint64_t	rmmd_smc_forward(uint32_t src_sec_state,
-					uint32_t dst_sec_state, uint64_t x0,
-					uint64_t x1, uint64_t x2, uint64_t x3,
-					uint64_t x4, void *handle)
+				 uint32_t dst_sec_state, uint64_t x0,
+				 uint64_t x1, uint64_t x2, uint64_t x3,
+				 uint64_t x4, void *handle)
 {
+	cpu_context_t *ctx = cm_get_context(dst_sec_state);
+
 	/* Save incoming security state */
 	cm_el1_sysregs_context_save(src_sec_state);
 	cm_el2_sysregs_context_save(src_sec_state);
@@ -256,19 +258,21 @@
 	cm_set_next_eret_context(dst_sec_state);
 
 	/*
-	 * As per SMCCCv1.1, we need to preserve x4 to x7 unless
+	 * As per SMCCCv1.2, we need to preserve x4 to x7 unless
 	 * being used as return args. Hence we differentiate the
 	 * onward and backward path. Support upto 8 args in the
 	 * onward path and 4 args in return path.
+	 * Register x4 will be preserved by RMM in case it is not
+	 * used in return path.
 	 */
 	if (src_sec_state == NON_SECURE) {
-		SMC_RET8(cm_get_context(dst_sec_state), x0, x1, x2, x3, x4,
-				SMC_GET_GP(handle, CTX_GPREG_X5),
-				SMC_GET_GP(handle, CTX_GPREG_X6),
-				SMC_GET_GP(handle, CTX_GPREG_X7));
-	} else {
-		SMC_RET4(cm_get_context(dst_sec_state), x0, x1, x2, x3);
+		SMC_RET8(ctx, x0, x1, x2, x3, x4,
+			 SMC_GET_GP(handle, CTX_GPREG_X5),
+			 SMC_GET_GP(handle, CTX_GPREG_X6),
+			 SMC_GET_GP(handle, CTX_GPREG_X7));
 	}
+
+	SMC_RET5(ctx, x0, x1, x2, x3, x4);
 }
 
 /*******************************************************************************
@@ -276,8 +280,8 @@
  * either forwarded to the other security state or handled by the RMM dispatcher
  ******************************************************************************/
 uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
-				uint64_t x3, uint64_t x4, void *cookie,
-				void *handle, uint64_t flags)
+			  uint64_t x3, uint64_t x4, void *cookie,
+			  void *handle, uint64_t flags)
 {
 	uint32_t src_sec_state;
 
@@ -311,10 +315,12 @@
 	}
 
 	switch (smc_fid) {
-	case RMM_RMI_REQ_COMPLETE:
-		return rmmd_smc_forward(REALM, NON_SECURE, x1,
-					x2, x3, x4, 0, handle);
+	case RMM_RMI_REQ_COMPLETE: {
+		uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 
+		return rmmd_smc_forward(REALM, NON_SECURE, x1,
+					x2, x3, x4, x5, handle);
+	}
 	default:
 		WARN("RMMD: Unsupported RMM call 0x%08x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index d62be91..5233650 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -9,6 +9,7 @@
 
 #include <stdint.h>
 
+#include <common/bl_common.h>
 #include <lib/psci/psci.h>
 #include <lib/spinlock.h>
 #include <services/el3_spmc_logical_sp.h>
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 07fecb6..d21a622 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -7,6 +7,7 @@
 #ifndef SPMD_PRIVATE_H
 #define SPMD_PRIVATE_H
 
+#include <common/bl_common.h>
 #include <context.h>
 
 /*******************************************************************************