Merge "feat(handoff): add transfer entry printer" into integration
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 3f1fff2..decb2f9 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -42,7 +42,7 @@
     groups:
       dev-deps:
         patterns: ["*"]
-        update-types: ["major", "minor", "patch"]
+        update-types: ["minor", "patch"]
 
   - target-branch: "lts-v2.10"
     package-ecosystem: "pip"
diff --git a/Makefile b/Makefile
index 5682f93..413ce46 100644
--- a/Makefile
+++ b/Makefile
@@ -433,28 +433,12 @@
 ################################################################################
 
 ifneq (${SPD},none)
-	ifeq (${ARCH},aarch32)
-                $(error "Error: SPD is incompatible with AArch32.")
-	endif
-
-	ifdef EL3_PAYLOAD_BASE
-                $(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
-                $(warning "The SPD and its BL32 companion will be present but \
-                ignored.")
-	endif
-
 	ifeq (${SPD},spmd)
 	# SPMD is located in std_svc directory
 		SPD_DIR := std_svc
 
 		ifeq ($(SPMD_SPM_AT_SEL2),1)
 			CTX_INCLUDE_EL2_REGS := 1
-			ifeq ($(SPMC_AT_EL3),1)
-                                $(error SPM cannot be enabled in both S-EL2 and EL3.)
-			endif
-			ifeq ($(CTX_INCLUDE_SVE_REGS),1)
-                                $(error SVE context management not needed with Hafnium SPMC.)
-			endif
 		endif
 
 		ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
@@ -476,12 +460,6 @@
 		ifneq ($(SP_LAYOUT_FILE),)
 		BL2_ENABLE_SP_LOAD := 1
 		endif
-
-		ifeq ($(SPMC_AT_EL3_SEL0_SP),1)
-			ifneq ($(SPMC_AT_EL3),1)
-			$(error SEL0 SP cannot be enabled without SPMC at EL3)
-			endif
-		endif
 	else
 		# All other SPDs in spd directory
 		SPD_DIR := spd
@@ -507,15 +485,6 @@
 	# over the sources.
 endif #(SPD=none)
 
-ifeq (${ENABLE_SPMD_LP}, 1)
-ifneq (${SPD},spmd)
-        $(error Error: ENABLE_SPMD_LP requires SPD=spmd.)
-endif
-ifeq ($(SPMC_AT_EL3),1)
-        $(error SPMC at EL3 not supported when enabling SPMD Logical partitions.)
-endif
-endif
-
 ################################################################################
 # Include the platform specific Makefile after the SPD Makefile (the platform
 # makefile may use all previous definitions in this file)
@@ -774,6 +743,42 @@
 # Check incompatible options and dependencies
 ################################################################################
 
+# Handle all invalid build configurations with SPMD usage.
+ifeq (${ENABLE_SPMD_LP}, 1)
+ifneq (${SPD},spmd)
+	$(error Error: ENABLE_SPMD_LP requires SPD=spmd.)
+endif
+ifeq ($(SPMC_AT_EL3),1)
+	$(error SPMC at EL3 not supported when enabling SPMD Logical partitions.)
+endif
+endif
+
+ifneq (${SPD},none)
+ifeq (${ARCH},aarch32)
+	$(error "Error: SPD is incompatible with AArch32.")
+endif
+ifdef EL3_PAYLOAD_BASE
+	$(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
+	$(warning "The SPD and its BL32 companion will be present but ignored.")
+endif
+ifeq (${SPD},spmd)
+ifeq ($(SPMD_SPM_AT_SEL2),1)
+	ifeq ($(SPMC_AT_EL3),1)
+		$(error SPM cannot be enabled in both S-EL2 and EL3.)
+	endif
+	ifeq ($(CTX_INCLUDE_SVE_REGS),1)
+		$(error SVE context management not needed with Hafnium SPMC.)
+	endif
+endif
+
+ifeq ($(SPMC_AT_EL3_SEL0_SP),1)
+	ifneq ($(SPMC_AT_EL3),1)
+		$(error SEL0 SP cannot be enabled without SPMC at EL3)
+	endif
+endif
+endif #(SPD=spmd)
+endif #(SPD!=none)
+
 # USE_DEBUGFS experimental feature recommended only in debug builds
 ifeq (${USE_DEBUGFS},1)
         ifeq (${DEBUG},1)
@@ -1185,7 +1190,6 @@
 	DYN_DISABLE_AUTH \
 	EL3_EXCEPTION_HANDLING \
 	ENABLE_AMU_AUXILIARY_COUNTERS \
-	ENABLE_AMU_FCONF \
 	AMU_RESTRICT_COUNTERS \
 	ENABLE_ASSERTIONS \
 	ENABLE_PIE \
@@ -1252,7 +1256,6 @@
 	PSA_FWU_METADATA_FW_STORE_DESC \
 	ENABLE_MPMM \
 	FEAT_PABANDON \
-	ENABLE_MPMM_FCONF \
 	FEATURE_DETECTION \
 	TRNG_SUPPORT \
 	ENABLE_ERRATA_ALL \
@@ -1361,7 +1364,6 @@
 	DISABLE_MTPMU \
 	ENABLE_FEAT_AMU \
 	ENABLE_AMU_AUXILIARY_COUNTERS \
-	ENABLE_AMU_FCONF \
 	AMU_RESTRICT_COUNTERS \
 	ENABLE_ASSERTIONS \
 	ENABLE_BTI \
@@ -1454,7 +1456,6 @@
 	ENABLE_FEAT_HCX \
 	ENABLE_MPMM \
 	FEAT_PABANDON \
-	ENABLE_MPMM_FCONF \
 	ENABLE_FEAT_FGT \
 	ENABLE_FEAT_FGT2 \
 	ENABLE_FEAT_FPMR \
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index 91ea75d..fce17e1 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -245,26 +245,30 @@
  */
 func ea_proceed
 	/*
-	 * If the ESR loaded earlier is not zero, we were processing an EA
-	 * already, and this is a double fault.
+	 * If it is a double fault invoke platform handler.
+	 * Double fault scenario would arise when platform is handling a fault in
+	 * lower EL using plat_ea_handler() and another fault happens which would
+	 * trap into EL3 as FFH_SUPPORT is enabled for the platform.
 	 */
-	ldr	x5, [sp, #CTX_EL3STATE_OFFSET + CTX_ESR_EL3]
+	ldr	x5, [sp, #CTX_EL3STATE_OFFSET + CTX_DOUBLE_FAULT_ESR]
 	cbz	x5, 1f
 	no_ret	plat_handle_double_fault
 
 1:
-	/* Save EL3 state */
+	/* Save EL3 state as handling might involve lower ELs */
 	mrs	x2, spsr_el3
 	mrs	x3, elr_el3
 	stp	x2, x3, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+	mrs	x4, scr_el3
+	str	x4, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
 
 	/*
-	 * Save ESR as handling might involve lower ELs, and returning back to
-	 * EL3 from there would trample the original ESR.
+	 * Save CTX_DOUBLE_FAULT_ESR, so that if another fault happens in lower EL, we
+	 * catch it as DoubleFault in next invocation of ea_proceed() along with
+	 * preserving original ESR_EL3.
 	 */
-	mrs	x4, scr_el3
 	mrs	x5, esr_el3
-	stp	x4, x5, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+	str	x5, [sp, #CTX_EL3STATE_OFFSET + CTX_DOUBLE_FAULT_ESR]
 
 	/*
 	 * Setup rest of arguments, and call platform External Abort handler.
@@ -305,23 +309,15 @@
 	/* Make SP point to context */
 	msr	spsel, #MODE_SP_ELX
 
-	/* Restore EL3 state and ESR */
+	/* Clear Double Fault storage */
+	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_DOUBLE_FAULT_ESR]
+
+	/* Restore EL3 state */
 	ldp	x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
 	msr	spsr_el3, x1
 	msr	elr_el3, x2
-
-	/* Restore ESR_EL3 and SCR_EL3 */
-	ldp	x3, x4, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+	ldr	x3, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
 	msr	scr_el3, x3
-	msr	esr_el3, x4
-
-#if ENABLE_ASSERTIONS
-	cmp	x4, xzr
-	ASM_ASSERT(ne)
-#endif
-
-	/* Clear ESR storage */
-	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_ESR_EL3]
 
 	ret	x29
 endfunc ea_proceed
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 9b2b139..e390915 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -24,7 +24,6 @@
 endif
 
 include lib/extensions/amu/amu.mk
-include lib/mpmm/mpmm.mk
 
 ifeq (${SPMC_AT_EL3},1)
   $(info Including EL3 SPMC makefile)
@@ -114,10 +113,6 @@
 BL31_SOURCES		+=	lib/extensions/tcr/tcr2.c
 endif
 
-ifeq (${ENABLE_MPMM},1)
-BL31_SOURCES		+=	${MPMM_SOURCES}
-endif
-
 ifneq (${ENABLE_SME_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/sme/sme.c
 endif
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 83be0f6..db0ea6c 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -127,7 +127,7 @@
 void bl31_main(void)
 {
 	/* Init registers that never change for the lifetime of TF-A */
-	cm_manage_extensions_el3();
+	cm_manage_extensions_el3(plat_my_core_pos());
 
 	/* Init per-world context registers for non-secure world */
 	manage_extensions_nonsecure_per_world();
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 210ae7e..3e33824 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -387,7 +387,7 @@
 
 Firmware Encryption Framework
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Sumit Garg <sumit.garg@linaro.org>
+:|M|: Sumit Garg <sumit.garg@kernel.org>
 :|G|: `b49020`_
 :|F|: drivers/io/io_encrypted.c
 :|F|: include/drivers/io/io_encrypted.h
@@ -447,8 +447,7 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Chris Kay <chris.kay@arm.com>
 :|G|: `CJKay`_
-:|F|: include/lib/mpmm/
-:|F|: lib/mpmm/
+:|F|: include/lib/cpus/aarch64/cpu_macros.S
 
 Granule Protection Tables Library (GPT-RME)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -896,7 +895,7 @@
 
 Synquacer platform port
 ^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Sumit Garg <sumit.garg@linaro.org>
+:|M|: Sumit Garg <sumit.garg@kernel.org>
 :|G|: `b49020`_
 :|M|: Masahisa Kojima <kojima.masahisa@socionext.com>
 :|G|: `masahisak`_
@@ -997,7 +996,7 @@
 
 Encrypt_fw tool
 ^^^^^^^^^^^^^^^
-:|M|: Sumit Garg <sumit.garg@linaro.org>
+:|M|: Sumit Garg <sumit.garg@kernel.org>
 :|G|: `b49020`_
 :|F|: tools/encrypt_fw/
 
diff --git a/docs/components/activity-monitors.rst b/docs/components/activity-monitors.rst
index 5c1c2c2..4c33d42 100644
--- a/docs/components/activity-monitors.rst
+++ b/docs/components/activity-monitors.rst
@@ -20,15 +20,9 @@
 build option.
 
 As a security precaution, Trusted Firmware-A does not enable these by default.
-Instead, platforms may configure their auxiliary counters through one of two
-possible mechanisms:
-
-- |FCONF|, controlled by the ``ENABLE_AMU_FCONF`` build option.
-- A platform implementation of the ``plat_amu_topology`` function (the default).
-
-See :ref:`Activity Monitor Unit (AMU) Bindings` for documentation on the |FCONF|
-device tree bindings.
+Instead, platforms must configure their auxiliary counters through the
+``plat_amu_aux_enables`` platform hook.
 
 --------------
 
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2025, Arm Limited. All rights reserved.*
diff --git a/docs/components/context-management-library.rst b/docs/components/context-management-library.rst
index 6a76ada..8cb1ace 100644
--- a/docs/components/context-management-library.rst
+++ b/docs/components/context-management-library.rst
@@ -498,7 +498,6 @@
 
 	typedef struct per_world_context {
 		uint64_t ctx_cptr_el3;
-		uint64_t ctx_zcr_el3;
 		uint64_t ctx_mpam3_el3;
 	} per_world_context_t;
 
@@ -555,7 +554,7 @@
 EL3 execution context needs to setup at both boot time (cold and warm boot)
 entrypaths and at all the possible exception handlers routing to EL3 at runtime.
 
-*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.*
 
 .. |Context Memory Allocation| image:: ../resources/diagrams/context_memory_allocation.png
 .. |CPU Context Memory Configuration| image:: ../resources/diagrams/cpu_data_config_context_memory.png
diff --git a/docs/components/fconf/amu-bindings.rst b/docs/components/fconf/amu-bindings.rst
deleted file mode 100644
index 047f75e..0000000
--- a/docs/components/fconf/amu-bindings.rst
+++ /dev/null
@@ -1,142 +0,0 @@
-Activity Monitor Unit (AMU) Bindings
-====================================
-
-To support platform-defined Activity Monitor Unit (|AMU|) auxiliary counters
-through FCONF, the ``HW_CONFIG`` device tree accepts several |AMU|-specific
-nodes and properties.
-
-Bindings
-^^^^^^^^
-
-.. contents::
-    :local:
-
-``/cpus/cpus/cpu*`` node properties
-"""""""""""""""""""""""""""""""""""
-
-The ``cpu`` node has been augmented to support a handle to an associated |AMU|
-view, which should describe the counters offered by the core.
-
-+---------------+-------+---------------+-------------------------------------+
-| Property name | Usage | Value type    | Description                         |
-+===============+=======+===============+=====================================+
-| ``amu``       | O     | ``<phandle>`` | If present, indicates that an |AMU| |
-|               |       |               | is available and its counters are   |
-|               |       |               | described by the node provided.     |
-+---------------+-------+---------------+-------------------------------------+
-
-``/cpus/amus`` node properties
-""""""""""""""""""""""""""""""
-
-The ``amus`` node describes the |AMUs| implemented by the cores in the system.
-This node does not have any properties.
-
-``/cpus/amus/amu*`` node properties
-"""""""""""""""""""""""""""""""""""
-
-An ``amu`` node describes the layout and meaning of the auxiliary counter
-registers of one or more |AMUs|, and may be shared by multiple cores.
-
-+--------------------+-------+------------+------------------------------------+
-| Property name      | Usage | Value type | Description                        |
-+====================+=======+============+====================================+
-| ``#address-cells`` | R     | ``<u32>``  | Value shall be 1. Specifies that   |
-|                    |       |            | the ``reg`` property array of      |
-|                    |       |            | children of this node uses a       |
-|                    |       |            | single cell.                       |
-+--------------------+-------+------------+------------------------------------+
-| ``#size-cells``    | R     | ``<u32>``  | Value shall be 0. Specifies that   |
-|                    |       |            | no size is required in the ``reg`` |
-|                    |       |            | property in children of this node. |
-+--------------------+-------+------------+------------------------------------+
-
-``/cpus/amus/amu*/counter*`` node properties
-""""""""""""""""""""""""""""""""""""""""""""
-
-A ``counter`` node describes an auxiliary counter belonging to the parent |AMU|
-view.
-
-+-------------------+-------+-------------+------------------------------------+
-| Property name     | Usage | Value type  | Description                        |
-+===================+=======+=============+====================================+
-| ``reg``           | R     | array       | Represents the counter register    |
-|                   |       |             | index, and must be a single cell.  |
-+-------------------+-------+-------------+------------------------------------+
-| ``enable-at-el3`` | O     | ``<empty>`` | The presence of this property      |
-|                   |       |             | indicates that this counter should |
-|                   |       |             | be enabled prior to EL3 exit.      |
-+-------------------+-------+-------------+------------------------------------+
-
-Example
-^^^^^^^
-
-An example system offering four cores made up of two clusters, where the cores
-of each cluster share different |AMUs|, may use something like the following:
-
-.. code-block::
-
-    cpus {
-        #address-cells = <2>;
-        #size-cells = <0>;
-
-        amus {
-            amu0: amu-0 {
-                #address-cells = <1>;
-                #size-cells = <0>;
-
-                counterX: counter@0 {
-                    reg = <0>;
-
-                    enable-at-el3;
-                };
-
-                counterY: counter@1 {
-                    reg = <1>;
-
-                    enable-at-el3;
-                };
-            };
-
-            amu1: amu-1 {
-                #address-cells = <1>;
-                #size-cells = <0>;
-
-                counterZ: counter@0 {
-                    reg = <0>;
-
-                    enable-at-el3;
-                };
-            };
-        };
-
-        cpu0@00000 {
-            ...
-
-            amu = <&amu0>;
-        };
-
-        cpu1@00100 {
-            ...
-
-            amu = <&amu0>;
-        };
-
-        cpu2@10000 {
-            ...
-
-            amu = <&amu1>;
-        };
-
-        cpu3@10100 {
-            ...
-
-            amu = <&amu1>;
-        };
-    }
-
-In this situation, ``cpu0`` and ``cpu1`` (the two cores in the first cluster),
-share the view of their AMUs defined by ``amu0``. Likewise, ``cpu2`` and
-``cpu3`` (the two cores in the second cluster), share the view of their |AMUs|
-defined by ``amu1``. This will cause ``counterX`` and ``counterY`` to be enabled
-for both ``cpu0`` and ``cpu1``, and ``counterZ`` to be enabled for both ``cpu2``
-and ``cpu3``.
diff --git a/docs/components/fconf/index.rst b/docs/components/fconf/index.rst
index b8b4519..6cb6774 100644
--- a/docs/components/fconf/index.rst
+++ b/docs/components/fconf/index.rst
@@ -145,6 +145,4 @@
   :maxdepth: 1
 
   fconf_properties
-  amu-bindings
-  mpmm-bindings
   tb_fw_bindings
diff --git a/docs/components/fconf/mpmm-bindings.rst b/docs/components/fconf/mpmm-bindings.rst
deleted file mode 100644
index d3cc857..0000000
--- a/docs/components/fconf/mpmm-bindings.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-Maximum Power Mitigation Mechanism (MPMM) Bindings
-==================================================
-
-|MPMM| support cannot be determined at runtime by the firmware. Instead, these
-DTB bindings allow the platform to communicate per-core support for |MPMM| via
-the ``HW_CONFIG`` device tree blob.
-
-Bindings
-^^^^^^^^
-
-.. contents::
-    :local:
-
-``/cpus/cpus/cpu*`` node properties
-"""""""""""""""""""""""""""""""""""
-
-The ``cpu`` node has been augmented to allow the platform to indicate support
-for |MPMM| on a given core.
-
-+-------------------+-------+-------------+------------------------------------+
-| Property name     | Usage | Value type  | Description                        |
-+===================+=======+=============+====================================+
-| ``supports-mpmm`` | O     | ``<empty>`` | If present, indicates that |MPMM|  |
-|                   |       |             | is available on this core.         |
-+-------------------+-------+-------------+------------------------------------+
-
-Example
-^^^^^^^
-
-An example system offering two cores, one with support for |MPMM| and one
-without, can be described as follows:
-
-.. code-block::
-
-    cpus {
-        #address-cells = <2>;
-        #size-cells = <0>;
-
-        cpu0@00000 {
-            ...
-
-            supports-mpmm;
-        };
-
-        cpu1@00100 {
-            ...
-        };
-    }
diff --git a/docs/components/mpmm.rst b/docs/components/mpmm.rst
index 1b1c6d8..aaa9481 100644
--- a/docs/components/mpmm.rst
+++ b/docs/components/mpmm.rst
@@ -8,16 +8,7 @@
 triggering of whole-rail (i.e. clock chopping) responses to overcurrent
 conditions.
 
-|MPMM| is enabled on a per-core basis by the EL3 runtime firmware. The presence
-of |MPMM| cannot be determined at runtime by the firmware, and therefore the
-platform must expose this information through one of two possible mechanisms:
-
-- |FCONF|, controlled by the ``ENABLE_MPMM_FCONF`` build option.
-- A platform implementation of the ``plat_mpmm_topology`` function (the
-  default).
-
-See :ref:`Maximum Power Mitigation Mechanism (MPMM) Bindings` for documentation
-on the |FCONF| device tree bindings.
+|MPMM| is enabled on a per-core basis by the EL3 runtime firmware.
 
 .. warning::
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 8840e7f..2b36fda 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -258,10 +258,6 @@
    (also known as group 1 counters). These are implementation-defined counters,
    and as such require additional platform configuration. Default is 0.
 
--  ``ENABLE_AMU_FCONF``: Enables configuration of the AMU through FCONF, which
-   allows platforms with auxiliary counters to describe them via the
-   ``HW_CONFIG`` device tree blob. Default is 0.
-
 -  ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()``
    are compiled out. For debug builds, this option defaults to 1, and calls to
    ``assert()`` are left in place. For release builds, this option defaults to 0
@@ -532,10 +528,6 @@
    introduces a performance penalty. Once this is removed, this option will be
    removed and the feature will be enabled by default. Defaults to ``0``.
 
--  ``ENABLE_MPMM_FCONF``: Enables configuration of MPMM through FCONF, which
-   allows platforms with cores supporting MPMM to describe them via the
-   ``HW_CONFIG`` device tree blob. Default is 0.
-
 -  ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE)
    support within generic code in TF-A. This option is currently only supported
    in BL2, BL31, and BL32 (TSP) for AARCH64 binaries, and
diff --git a/docs/plat/arm/fvp/fvp-support.rst b/docs/plat/arm/fvp/fvp-support.rst
index ad76cf1..0ce1905 100644
--- a/docs/plat/arm/fvp/fvp-support.rst
+++ b/docs/plat/arm/fvp/fvp-support.rst
@@ -9,24 +9,22 @@
 (64-bit host machine only).
 
 .. note::
-   The FVP models used are Version 11.26 Build 11, unless otherwise stated.
+   The FVP models used are version 11.28 Build 23.
 
 -  ``FVP_Base_AEMvA-AEMvA``
 -  ``FVP_Base_RevC-2xAEMvA``
--  ``FVP_Base_Cortex-A32x4``
--  ``FVP_Base_Cortex-A35x4``
--  ``FVP_Base_Cortex-A53x4``
+-  ``FVP_Base_Cortex-A32``
+-  ``FVP_Base_Cortex-A35``
+-  ``FVP_Base_Cortex-A53``
 -  ``FVP_Base_Cortex-A55``
 -  ``FVP_Base_Cortex-A57x1-A53x1``
 -  ``FVP_Base_Cortex-A57x2-A53x4``
--  ``FVP_Base_Cortex-A57x4``
+-  ``FVP_Base_Cortex-A57``
 -  ``FVP_Base_Cortex-A57x4-A53x4``
--  ``FVP_Base_Cortex-A65`` (Version 11.24/24)
--  ``FVP_Base_Cortex-A65AE`` (Version 11.24/24)
--  ``FVP_Base_Cortex-A710``
--  ``FVP_Base_Cortex-A72x4``
--  ``FVP_Base_Cortex-A72x4-A53x4``
--  ``FVP_Base_Cortex-A73x4``
+-  ``FVP_Base_Cortex-A65``
+-  ``FVP_Base_Cortex-A65AE``
+-  ``FVP_Base_Cortex-A72``
+-  ``FVP_Base_Cortex-A73``
 -  ``FVP_Base_Cortex-A73x4-A53x4``
 -  ``FVP_Base_Cortex-A75``
 -  ``FVP_Base_Cortex-A76``
@@ -35,17 +33,17 @@
 -  ``FVP_Base_Cortex-A78``
 -  ``FVP_Base_Cortex-A78AE``
 -  ``FVP_Base_Cortex-A78C``
+-  ``FVP_Base_Cortex-A710``
 -  ``FVP_Base_Cortex-X2``
--  ``FVP_Base_Neoverse-E1`` (Version 11.24/24)
+-  ``FVP_Base_Cortex-X4``
+-  ``FVP_Base_Cortex-X925``
+-  ``FVP_Base_Neoverse-E1``
 -  ``FVP_Base_Neoverse-N1``
 -  ``FVP_Base_Neoverse-N2``
 -  ``FVP_Base_Neoverse-V1``
 -  ``FVP_BaseR_AEMv8R``
--  ``FVP_Morello`` (Version 0.11/33)
--  ``FVP_RD_V1``
--  ``FVP_RD_1_AE`` (Version 11.27/20)
--  ``FVP_TC3`` (Version 11.26/16)
--  ``FVP_TC4`` (Version 0.0/8404)
+-  ``FVP_RD_1_AE``
+-  ``FVP_TC4``
 
 The latest version of the AArch32 build of TF-A has been tested on the
 following Arm FVPs without shifted affinities, and that do not support threaded
@@ -53,7 +51,7 @@
 
 -  ``FVP_Base_AEMvA``
 -  ``FVP_Base_AEMvA-AEMvA``
--  ``FVP_Base_Cortex-A32x4``
+-  ``FVP_Base_Cortex-A32``
 
 .. note::
    The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities, which
@@ -94,7 +92,7 @@
 
 --------------
 
-*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2025, Arm Limited. All rights reserved.*
 
 .. _Arm's website: `FVP models`_
 .. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
index 384cd73..016bed7 100644
--- a/docs/plat/rockchip.rst
+++ b/docs/plat/rockchip.rst
@@ -11,6 +11,7 @@
 -  rk3368: Octa-Core Cortex-A53
 -  rk3399: Hexa-Core Cortex-A53/A72
 -  rk3566/rk3568: Quad-Core Cortex-A55
+-  rk3576: Octa-Core Cortex-A53/A72
 -  rk3588: Octa-Core Cortex-A55/A76
 
 
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 9ca2aa9..d06d153 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -1001,7 +1001,7 @@
 This function returns the size normal-world DCE of the platform.
 
 Function : plat_drtm_get_imp_def_dlme_region_size()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ::
 
@@ -1012,7 +1012,7 @@
 of the platform.
 
 Function : plat_drtm_get_tcb_hash_table_size()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ::
 
@@ -1021,8 +1021,18 @@
 
 This function returns the size of TCB hash table of the platform.
 
+Function : plat_drtm_get_acpi_tables_region_size()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint64_t
+
+This function returns the size of ACPI tables region of the platform.
+
 Function : plat_drtm_get_tcb_hash_features()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ::
 
@@ -1033,6 +1043,17 @@
 platform.
 For more details see section 3.3 Table 6 of `DRTM`_ specification.
 
+Function : plat_drtm_get_dlme_img_auth_features()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint64_t
+
+This function returns the DLME image authentication features.
+For more details see section 3.3 Table 6 of `DRTM`_ specification.
+
 Function : plat_drtm_validate_ns_region()
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/drivers/st/pmic/stpmic2.c b/drivers/st/pmic/stpmic2.c
index 05a80ec..7f233db 100644
--- a/drivers/st/pmic/stpmic2.c
+++ b/drivers/st/pmic/stpmic2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2024-2025, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -247,10 +247,6 @@
 {
 	const struct regul_struct *regul = &regul_table[id];
 
-	if (regul == NULL) {
-		return RET_ERROR_BAD_PARAMETERS;
-	}
-
 	if (levels_count != NULL) {
 		*levels_count = regul->volt_table_size;
 	}
diff --git a/fdts/stm32mp157a-dk1-sp_min-fw-config.dts b/fdts/stm32mp157a-dk1-sp_min-fw-config.dts
new file mode 100644
index 0000000..40164f3
--- /dev/null
+++ b/fdts/stm32mp157a-dk1-sp_min-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE	0x20000000 /* 512MB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157a-dk1-sp_min.dts b/fdts/stm32mp157a-dk1-sp_min.dts
new file mode 100644
index 0000000..ac5c2af
--- /dev/null
+++ b/fdts/stm32mp157a-dk1-sp_min.dts
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (C) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+#include "stm32mp157a-dk1.dts"
+
+/ {
+	model = "STMicroelectronics STM32MP157A-DK1 Discovery Board (SP_MIN)";
+};
+
+&rcc {
+	st,clksrc = <
+		CLK_MPU_PLL1P
+		CLK_AXI_PLL2P
+		CLK_MCU_PLL3P
+		CLK_RTC_LSE
+		CLK_MCO1_DISABLED
+		CLK_MCO2_DISABLED
+		CLK_CKPER_HSE
+		CLK_FMC_ACLK
+		CLK_QSPI_ACLK
+		CLK_ETH_PLL4P
+		CLK_SDMMC12_PLL4P
+		CLK_DSI_DSIPLL
+		CLK_STGEN_HSE
+		CLK_USBPHY_HSE
+		CLK_SPI2S1_PLL3Q
+		CLK_SPI2S23_PLL3Q
+		CLK_SPI45_HSI
+		CLK_SPI6_HSI
+		CLK_I2C46_HSI
+		CLK_SDMMC3_PLL4P
+		CLK_USBO_USBPHY
+		CLK_ADC_CKPER
+		CLK_CEC_LSE
+		CLK_I2C12_HSI
+		CLK_I2C35_HSI
+		CLK_UART1_HSI
+		CLK_UART24_HSI
+		CLK_UART35_HSI
+		CLK_UART6_HSI
+		CLK_UART78_HSI
+		CLK_SPDIF_PLL4P
+		CLK_FDCAN_PLL4R
+		CLK_SAI1_PLL3Q
+		CLK_SAI2_PLL3Q
+		CLK_SAI3_PLL3Q
+		CLK_SAI4_PLL3Q
+		CLK_RNG1_CSI
+		CLK_RNG2_LSI
+		CLK_LPTIM1_PCLK1
+		CLK_LPTIM23_PCLK3
+		CLK_LPTIM45_LSE
+	>;
+
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+};
diff --git a/fdts/stm32mp157c-dk2-sp_min-fw-config.dts b/fdts/stm32mp157c-dk2-sp_min-fw-config.dts
new file mode 100644
index 0000000..40164f3
--- /dev/null
+++ b/fdts/stm32mp157c-dk2-sp_min-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE	0x20000000 /* 512MB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-dk2-sp_min.dts b/fdts/stm32mp157c-dk2-sp_min.dts
new file mode 100644
index 0000000..350cd34
--- /dev/null
+++ b/fdts/stm32mp157c-dk2-sp_min.dts
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (C) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+#include "stm32mp157c-dk2.dts"
+
+/ {
+	model = "STMicroelectronics STM32MP157C-DK2 Discovery Board (SP_MIN)";
+};
+
+&rcc {
+	st,clksrc = <
+		CLK_MPU_PLL1P
+		CLK_AXI_PLL2P
+		CLK_MCU_PLL3P
+		CLK_RTC_LSE
+		CLK_MCO1_DISABLED
+		CLK_MCO2_DISABLED
+		CLK_CKPER_HSE
+		CLK_FMC_ACLK
+		CLK_QSPI_ACLK
+		CLK_ETH_PLL4P
+		CLK_SDMMC12_PLL4P
+		CLK_DSI_DSIPLL
+		CLK_STGEN_HSE
+		CLK_USBPHY_HSE
+		CLK_SPI2S1_PLL3Q
+		CLK_SPI2S23_PLL3Q
+		CLK_SPI45_HSI
+		CLK_SPI6_HSI
+		CLK_I2C46_HSI
+		CLK_SDMMC3_PLL4P
+		CLK_USBO_USBPHY
+		CLK_ADC_CKPER
+		CLK_CEC_LSE
+		CLK_I2C12_HSI
+		CLK_I2C35_HSI
+		CLK_UART1_HSI
+		CLK_UART24_HSI
+		CLK_UART35_HSI
+		CLK_UART6_HSI
+		CLK_UART78_HSI
+		CLK_SPDIF_PLL4P
+		CLK_FDCAN_PLL4R
+		CLK_SAI1_PLL3Q
+		CLK_SAI2_PLL3Q
+		CLK_SAI3_PLL3Q
+		CLK_SAI4_PLL3Q
+		CLK_RNG1_CSI
+		CLK_RNG2_LSI
+		CLK_LPTIM1_PCLK1
+		CLK_LPTIM23_PCLK3
+		CLK_LPTIM45_LSE
+	>;
+
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+};
diff --git a/fdts/stm32mp157c-ed1-sp_min-fw-config.dts b/fdts/stm32mp157c-ed1-sp_min-fw-config.dts
new file mode 100644
index 0000000..5aff97f
--- /dev/null
+++ b/fdts/stm32mp157c-ed1-sp_min-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE	0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-ed1-sp_min.dts b/fdts/stm32mp157c-ed1-sp_min.dts
new file mode 100644
index 0000000..85d4fb1
--- /dev/null
+++ b/fdts/stm32mp157c-ed1-sp_min.dts
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+#include "stm32mp157c-ed1.dts"
+
+/ {
+	model = "STMicroelectronics STM32MP157C eval daughter (SP_MIN)";
+};
+
+&rcc {
+	st,clksrc = <
+		CLK_MPU_PLL1P
+		CLK_AXI_PLL2P
+		CLK_MCU_PLL3P
+		CLK_RTC_LSE
+		CLK_MCO1_DISABLED
+		CLK_MCO2_DISABLED
+		CLK_CKPER_HSE
+		CLK_FMC_ACLK
+		CLK_QSPI_ACLK
+		CLK_ETH_PLL4P
+		CLK_SDMMC12_PLL4P
+		CLK_DSI_DSIPLL
+		CLK_STGEN_HSE
+		CLK_USBPHY_HSE
+		CLK_SPI2S1_PLL3Q
+		CLK_SPI2S23_PLL3Q
+		CLK_SPI45_HSI
+		CLK_SPI6_HSI
+		CLK_I2C46_HSI
+		CLK_SDMMC3_PLL4P
+		CLK_USBO_USBPHY
+		CLK_ADC_CKPER
+		CLK_CEC_LSE
+		CLK_I2C12_HSI
+		CLK_I2C35_HSI
+		CLK_UART1_HSI
+		CLK_UART24_HSI
+		CLK_UART35_HSI
+		CLK_UART6_HSI
+		CLK_UART78_HSI
+		CLK_SPDIF_PLL4P
+		CLK_FDCAN_PLL4R
+		CLK_SAI1_PLL3Q
+		CLK_SAI2_PLL3Q
+		CLK_SAI3_PLL3Q
+		CLK_SAI4_PLL3Q
+		CLK_RNG1_CSI
+		CLK_RNG2_LSI
+		CLK_LPTIM1_PCLK1
+		CLK_LPTIM23_PCLK3
+		CLK_LPTIM45_LSE
+	>;
+
+	st,clkdiv = <
+		DIV(DIV_MPU, 1)
+		DIV(DIV_AXI, 0)
+		DIV(DIV_MCU, 0)
+		DIV(DIV_APB1, 1)
+		DIV(DIV_APB2, 1)
+		DIV(DIV_APB3, 1)
+		DIV(DIV_APB4, 1)
+		DIV(DIV_APB5, 2)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+};
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index fe5f464..dddfe3a 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2025, STMicroelectronics - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
 /dts-v1/;
@@ -195,43 +195,13 @@
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
 		CLK_RTC_LSE
-		CLK_MCO1_DISABLED
-		CLK_MCO2_DISABLED
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
-		CLK_ETH_PLL4P
 		CLK_SDMMC12_PLL4P
-		CLK_DSI_DSIPLL
 		CLK_STGEN_HSE
-		CLK_USBPHY_HSE
-		CLK_SPI2S1_PLL3Q
-		CLK_SPI2S23_PLL3Q
-		CLK_SPI45_HSI
-		CLK_SPI6_HSI
 		CLK_I2C46_HSI
-		CLK_SDMMC3_PLL4P
-		CLK_USBO_USBPHY
-		CLK_ADC_CKPER
-		CLK_CEC_LSE
-		CLK_I2C12_HSI
-		CLK_I2C35_HSI
-		CLK_UART1_HSI
 		CLK_UART24_HSI
-		CLK_UART35_HSI
-		CLK_UART6_HSI
-		CLK_UART78_HSI
-		CLK_SPDIF_PLL4P
-		CLK_FDCAN_PLL4R
-		CLK_SAI1_PLL3Q
-		CLK_SAI2_PLL3Q
-		CLK_SAI3_PLL3Q
-		CLK_SAI4_PLL3Q
-		CLK_RNG1_CSI
-		CLK_RNG2_LSI
-		CLK_LPTIM1_PCLK1
-		CLK_LPTIM23_PCLK3
-		CLK_LPTIM45_LSE
 	>;
 
 	st,clkdiv = <
@@ -244,8 +214,6 @@
 		DIV(DIV_APB4, 1)
 		DIV(DIV_APB5, 2)
 		DIV(DIV_RTC, 23)
-		DIV(DIV_MCO1, 0)
-		DIV(DIV_MCO2, 0)
 	>;
 
 	st,pll_vco {
diff --git a/fdts/stm32mp157c-ev1-sp_min-fw-config.dts b/fdts/stm32mp157c-ev1-sp_min-fw-config.dts
new file mode 100644
index 0000000..5aff97f
--- /dev/null
+++ b/fdts/stm32mp157c-ev1-sp_min-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2025, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE	0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-ev1-sp_min.dts b/fdts/stm32mp157c-ev1-sp_min.dts
new file mode 100644
index 0000000..9513449
--- /dev/null
+++ b/fdts/stm32mp157c-ev1-sp_min.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2017-2025, STMicroelectronics - All Rights Reserved
+ */
+/dts-v1/;
+
+#include "stm32mp157c-ed1-sp_min.dts"
+
+/ {
+	model = "STMicroelectronics STM32MP157C eval daughter on eval mother (SP_MIN)";
+	compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157";
+
+	aliases {
+		serial1 = &usart3;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&fmc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&fmc_pins_a>;
+	status = "okay";
+
+	nand-controller@4,0 {
+		status = "okay";
+
+		nand@0 {
+			reg = <0>;
+			nand-on-flash-bbt;
+			#address-cells = <1>;
+			#size-cells = <1>;
+		};
+	};
+};
+
+&qspi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&qspi_clk_pins_a
+		     &qspi_bk1_pins_a
+		     &qspi_cs1_pins_a>;
+	reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	flash0: flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <108000000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};
+
+&usart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usart3_pins_b>;
+	uart-has-rtscts;
+	status = "disabled";
+};
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index 3115a00..1c7c4c3 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2019-2024, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2025, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
  */
 
@@ -199,43 +199,11 @@
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
 		CLK_RTC_LSE
-		CLK_MCO1_DISABLED
-		CLK_MCO2_DISABLED
 		CLK_CKPER_HSE
-		CLK_FMC_ACLK
-		CLK_QSPI_ACLK
-		CLK_ETH_PLL4P
 		CLK_SDMMC12_PLL4P
-		CLK_DSI_DSIPLL
 		CLK_STGEN_HSE
-		CLK_USBPHY_HSE
-		CLK_SPI2S1_PLL3Q
-		CLK_SPI2S23_PLL3Q
-		CLK_SPI45_HSI
-		CLK_SPI6_HSI
 		CLK_I2C46_HSI
-		CLK_SDMMC3_PLL4P
-		CLK_USBO_USBPHY
-		CLK_ADC_CKPER
-		CLK_CEC_LSE
-		CLK_I2C12_HSI
-		CLK_I2C35_HSI
-		CLK_UART1_HSI
 		CLK_UART24_HSI
-		CLK_UART35_HSI
-		CLK_UART6_HSI
-		CLK_UART78_HSI
-		CLK_SPDIF_PLL4P
-		CLK_FDCAN_PLL4R
-		CLK_SAI1_PLL3Q
-		CLK_SAI2_PLL3Q
-		CLK_SAI3_PLL3Q
-		CLK_SAI4_PLL3Q
-		CLK_RNG1_CSI
-		CLK_RNG2_LSI
-		CLK_LPTIM1_PCLK1
-		CLK_LPTIM23_PCLK3
-		CLK_LPTIM45_LSE
 	>;
 
 	st,clkdiv = <
@@ -248,8 +216,6 @@
 		DIV(DIV_APB4, 1)
 		DIV(DIV_APB5, 2)
 		DIV(DIV_RTC, 23)
-		DIV(DIV_MCO1, 0)
-		DIV(DIV_MCO2, 0)
 	>;
 
 	st,pll_vco {
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
index fc0b3b6..ac08e0b 100644
--- a/fdts/tc-base.dtsi
+++ b/fdts/tc-base.dtsi
@@ -104,28 +104,6 @@
 			};
 		};
 
-		amus {
-			amu: amu-0 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				mpmm_gear0: counter@0 {
-					reg = <0>;
-					enable-at-el3;
-				};
-
-				mpmm_gear1: counter@1 {
-					reg = <1>;
-					enable-at-el3;
-				};
-
-				mpmm_gear2: counter@2 {
-					reg = <2>;
-					enable-at-el3;
-				};
-			};
-		};
-
 		CPU0:cpu@0 {
 			device_type = "cpu";
 			compatible = "arm,armv8";
@@ -134,8 +112,6 @@
 			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <LIT_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU1:cpu@100 {
@@ -146,8 +122,6 @@
 			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <LIT_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU2:cpu@200 {
@@ -156,8 +130,6 @@
 			reg = <0x200>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU3:cpu@300 {
@@ -166,8 +138,6 @@
 			reg = <0x300>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU4:cpu@400 {
@@ -178,8 +148,6 @@
 			clocks = <&scmi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <MID_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU5:cpu@500 {
@@ -190,8 +158,6 @@
 			clocks = <&scmi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
 			capacity-dmips-mhz = <MID_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU6:cpu@600 {
@@ -200,8 +166,6 @@
 			reg = <0x600>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU7:cpu@700 {
@@ -210,8 +174,6 @@
 			reg = <0x700>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 	};
 
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
index 8aa77ce..fa16dcd 100644
--- a/fdts/tc2.dts
+++ b/fdts/tc2.dts
@@ -123,8 +123,6 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
 			capacity-dmips-mhz = <MID_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU9:cpu@900 {
@@ -134,8 +132,6 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 2>;
 			capacity-dmips-mhz = <BIG2_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU10:cpu@A00 {
@@ -145,8 +141,6 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 2>;
 			capacity-dmips-mhz = <BIG2_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU11:cpu@B00 {
@@ -156,8 +150,6 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 2>;
 			capacity-dmips-mhz = <BIG2_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU12:cpu@C00 {
@@ -167,8 +159,6 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 3>;
 			capacity-dmips-mhz = <BIG_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 
 		CPU13:cpu@D00 {
@@ -178,8 +168,6 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 3>;
 			capacity-dmips-mhz = <BIG_CAPACITY>;
-			amu = <&amu>;
-			supports-mpmm;
 		};
 #endif
 	};
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index d2591dd..41be1a1 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -761,7 +761,7 @@
 
 /* AMCNTENSET0 definitions */
 #define AMCNTENSET0_Pn_SHIFT	U(0)
-#define AMCNTENSET0_Pn_MASK	U(0xffff)
+#define AMCNTENSET0_Pn_MASK	U(0xf)
 
 /* AMCNTENSET1 definitions */
 #define AMCNTENSET1_Pn_SHIFT	U(0)
@@ -769,7 +769,7 @@
 
 /* AMCNTENCLR0 definitions */
 #define AMCNTENCLR0_Pn_SHIFT	U(0)
-#define AMCNTENCLR0_Pn_MASK	U(0xffff)
+#define AMCNTENCLR0_Pn_MASK	U(0xf)
 
 /* AMCNTENCLR1 definitions */
 #define AMCNTENCLR1_Pn_SHIFT	U(0)
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index e347240..e80faf2 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -85,6 +85,10 @@
 CREATE_FEATURE_FUNCS(feat_amu, id_pfr0, ID_PFR0_AMU_SHIFT,
 		    ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1, ENABLE_FEAT_AMU)
 
+/* Auxiliary counters for FEAT_AMU */
+CREATE_FEATURE_FUNCS(feat_amu_aux, amcfgr, AMCFGR_NCG_SHIFT,
+		    AMCFGR_NCG_MASK, 1U, ENABLE_AMU_AUXILIARY_COUNTERS)
+
 /* FEAT_AMUV1P1: AMU Extension v1.1 */
 CREATE_FEATURE_FUNCS(feat_amuv1p1, id_pfr0, ID_PFR0_AMU_SHIFT,
 		    ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1)
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index adc96ae..4f80e3a 100644
--- a/include/arch/aarch32/arch_helpers.h
+++ b/include/arch/aarch32/arch_helpers.h
@@ -324,6 +324,23 @@
 DEFINE_COPROCR_RW_FUNCS_64(amevcntr02, AMEVCNTR02)
 DEFINE_COPROCR_RW_FUNCS_64(amevcntr03, AMEVCNTR03)
 
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr10, AMEVCNTR10);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr11, AMEVCNTR11);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr12, AMEVCNTR12);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr13, AMEVCNTR13);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr14, AMEVCNTR14);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr15, AMEVCNTR15);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr16, AMEVCNTR16);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr17, AMEVCNTR17);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr18, AMEVCNTR18);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr19, AMEVCNTR19);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr1a, AMEVCNTR1A);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr1b, AMEVCNTR1B);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr1c, AMEVCNTR1C);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr1d, AMEVCNTR1D);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr1e, AMEVCNTR1E);
+DEFINE_COPROCR_RW_FUNCS_64(amevcntr1f, AMEVCNTR1F);
+
 /*
  * TLBI operation prototypes
  */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index b1d1f09..85b33aa 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1560,12 +1560,10 @@
  ******************************************************************************/
 
 #define CPUPPMCR_EL3			S3_6_C15_C2_0
-#define CPUPPMCR_EL3_MPMMPINCTL_SHIFT	UINT64_C(0)
-#define CPUPPMCR_EL3_MPMMPINCTL_MASK	UINT64_C(0x1)
+#define CPUPPMCR_EL3_MPMMPINCTL_BIT	BIT(0)
 
 #define CPUMPMMCR_EL3			S3_6_C15_C2_1
-#define CPUMPMMCR_EL3_MPMM_EN_SHIFT	UINT64_C(0)
-#define CPUMPMMCR_EL3_MPMM_EN_MASK	UINT64_C(0x1)
+#define CPUMPMMCR_EL3_MPMM_EN_BIT	BIT(0)
 
 /* alternative system register encoding for the "sb" speculation barrier */
 #define SYSREG_SB			S0_3_C3_C0_7
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 1d0a2e0..a580213 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -311,6 +311,10 @@
 CREATE_FEATURE_FUNCS(feat_amu, id_aa64pfr0_el1, ID_AA64PFR0_AMU_SHIFT,
 		     ID_AA64PFR0_AMU_MASK, 1U, ENABLE_FEAT_AMU)
 
+/* Auxiliary counters for FEAT_AMU */
+CREATE_FEATURE_FUNCS(feat_amu_aux, amcfgr_el0, AMCFGR_EL0_NCG_SHIFT,
+		     AMCFGR_EL0_NCG_MASK, 1U, ENABLE_AMU_AUXILIARY_COUNTERS)
+
 /* FEAT_AMUV1P1: AMU Extension v1.1 */
 CREATE_FEATURE_FUNCS(feat_amuv1p1, id_aa64pfr0_el1, ID_AA64PFR0_AMU_SHIFT,
 		     ID_AA64PFR0_AMU_MASK, ID_AA64PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1)
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index abe379d..f85da97 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -564,6 +564,27 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0)
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
 DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0)
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr00_el0, AMEVCNTR00_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr01_el0, AMEVCNTR01_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr02_el0, AMEVCNTR02_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr03_el0, AMEVCNTR03_EL0);
+
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr10_el0, AMEVCNTR10_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr11_el0, AMEVCNTR11_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr12_el0, AMEVCNTR12_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr13_el0, AMEVCNTR13_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr14_el0, AMEVCNTR14_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr15_el0, AMEVCNTR15_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr16_el0, AMEVCNTR16_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr17_el0, AMEVCNTR17_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr18_el0, AMEVCNTR18_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr19_el0, AMEVCNTR19_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr1a_el0, AMEVCNTR1A_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr1b_el0, AMEVCNTR1B_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr1c_el0, AMEVCNTR1C_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr1d_el0, AMEVCNTR1D_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr1e_el0, AMEVCNTR1E_EL0);
+DEFINE_RENAME_SYSREG_RW_FUNCS(amevcntr1f_el0, AMEVCNTR1F_EL0);
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1)
 
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 4864596..2f2aeaf 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -454,6 +454,10 @@
 	 *  Necessary on PMUv3 <= p7 where MDCR_EL3.{SCCD,MCCD} are not
 	 *  available.
 	 *
+	 * CPTR_EL3.EZ: Set to one so that accesses to ZCR_EL3 do not trap
+	 * CPTR_EL3.TFP: Set to zero so that advanced SIMD operations don't trap
+	 * CPTR_EL3.ESM: Set to one so that SME related registers don't trap
+	 *
 	 * PSTATE.DIT: Set to one to enable the Data Independent Timing (DIT)
 	 *  functionality, if implemented in EL3.
 	 * ---------------------------------------------------------------------
@@ -473,6 +477,12 @@
 		orr	x15, x15, #PMCR_EL0_DP_BIT
 		msr	pmcr_el0, x15
 
+		mrs	x15, cptr_el3
+		orr	x15, x15, #CPTR_EZ_BIT
+		orr	x15, x15, #ESM_BIT
+		bic	x15, x15, #TFP_BIT
+		msr	cptr_el3, x15
+
 #if ENABLE_FEAT_DIT
 #if ENABLE_FEAT_DIT > 1
 		mrs	x15, id_aa64pfr0_el1
diff --git a/include/lib/cpus/aarch64/cortex_a320.h b/include/lib/cpus/aarch64/cortex_a320.h
new file mode 100644
index 0000000..5231151
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a320.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A320_H
+#define CORTEX_A320_H
+
+#define CORTEX_A320_MIDR					U(0x410FD8F0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A320_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_A320_CPUECTLR_EL1_EXTLLC_BIT			U(0)
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A320_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_A320_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_A320_H */
diff --git a/include/lib/cpus/aarch64/cortex_arcadia.h b/include/lib/cpus/aarch64/cortex_arcadia.h
deleted file mode 100644
index 8b74de2..0000000
--- a/include/lib/cpus/aarch64/cortex_arcadia.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_ARCADIA_H
-#define CORTEX_ARCADIA_H
-
-#define CORTEX_ARCADIA_MIDR					U(0x410FD8F0)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_ARCADIA_CPUECTLR_EL1				S3_0_C15_C1_4
-#define CORTEX_ARCADIA_CPUECTLR_EL1_EXTLLC_BIT			U(0)
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_ARCADIA_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_ARCADIA_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* CORTEX_ARCADIA_H */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index f3df595..a43746f 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -631,4 +631,21 @@
 	endfunc \_cpu\()_reset_func
 .endm
 
+/*
+ * Helper macro that enables Maximum Power Mitigation Mechanism (MPMM) on
+ * compatible Arm cores.
+ *
+ * Clobbers x0.
+ */
+.macro enable_mpmm
+#if ENABLE_MPMM
+	mrs	x0, CPUPPMCR_EL3
+	/* if CPUPPMCR_EL3.MPMMPINCTL != 0, skip enabling MPMM */
+	ands	x0, x0, CPUPPMCR_EL3_MPMMPINCTL_BIT
+	b.ne	1f
+	sysreg_bit_set CPUPPMCR_EL3, CPUMPMMCR_EL3_MPMM_EN_BIT
+	1:
+#endif
+.endm
+
 #endif /* CPU_MACROS_S */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 87f1541..d9a9188 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -67,25 +67,25 @@
  ******************************************************************************/
 #define CTX_EL3STATE_OFFSET	(CTX_GPREGS_OFFSET + CTX_GPREGS_END)
 #define CTX_SCR_EL3		U(0x0)
-#define CTX_ESR_EL3		U(0x8)
-#define CTX_RUNTIME_SP		U(0x10)
-#define CTX_SPSR_EL3		U(0x18)
-#define CTX_ELR_EL3		U(0x20)
-#define CTX_PMCR_EL0		U(0x28)
-#define CTX_IS_IN_EL3		U(0x30)
-#define CTX_MDCR_EL3		U(0x38)
+#define CTX_RUNTIME_SP		U(0x8)
+#define CTX_SPSR_EL3		U(0x10)
+#define CTX_ELR_EL3		U(0x18)
+#define CTX_PMCR_EL0		U(0x20)
+#define CTX_IS_IN_EL3		U(0x28)
+#define CTX_MDCR_EL3		U(0x30)
 /* Constants required in supporting nested exception in EL3 */
-#define CTX_SAVED_ELR_EL3	U(0x40)
+#define CTX_SAVED_ELR_EL3	U(0x38)
 /*
  * General purpose flag, to save various EL3 states
  * FFH mode : Used to identify if handling nested exception
  * KFH mode : Used as counter value
  */
-#define CTX_NESTED_EA_FLAG	U(0x48)
+#define CTX_NESTED_EA_FLAG	U(0x40)
 #if FFH_SUPPORT
- #define CTX_SAVED_ESR_EL3	U(0x50)
- #define CTX_SAVED_SPSR_EL3	U(0x58)
- #define CTX_SAVED_GPREG_LR	U(0x60)
+ #define CTX_SAVED_ESR_EL3	U(0x48)
+ #define CTX_SAVED_SPSR_EL3	U(0x50)
+ #define CTX_SAVED_GPREG_LR	U(0x58)
+ #define CTX_DOUBLE_FAULT_ESR	U(0x60)
  #define CTX_EL3STATE_END	U(0x70) /* Align to the next 16 byte boundary */
 #else
  #define CTX_EL3STATE_END	U(0x50) /* Align to the next 16 byte boundary */
@@ -167,9 +167,8 @@
  * Registers initialised in a per-world context.
  ******************************************************************************/
 #define CTX_CPTR_EL3			U(0x0)
-#define CTX_ZCR_EL3			U(0x8)
-#define CTX_MPAM3_EL3			U(0x10)
-#define CTX_PERWORLD_EL3STATE_END	U(0x18)
+#define CTX_MPAM3_EL3			U(0x8)
+#define CTX_PERWORLD_EL3STATE_END	U(0x10)
 
 #ifndef __ASSEMBLER__
 
@@ -278,7 +277,6 @@
  */
 typedef struct per_world_context {
 	uint64_t ctx_cptr_el3;
-	uint64_t ctx_zcr_el3;
 	uint64_t ctx_mpam3_el3;
 } per_world_context_t;
 
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index 70dbd46..a48ed96 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,7 +41,7 @@
 
 #ifdef __aarch64__
 #if IMAGE_BL31
-void cm_manage_extensions_el3(void);
+void cm_manage_extensions_el3(unsigned int my_idx);
 void manage_extensions_nonsecure_per_world(void);
 void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx);
 void cm_handle_asymmetric_features(void);
@@ -95,7 +95,7 @@
 #else
 void *cm_get_next_context(void);
 void cm_set_next_context(void *context);
-static inline void cm_manage_extensions_el3(void) {}
+static inline void cm_manage_extensions_el3(unsigned int cpu_idx) {}
 static inline void manage_extensions_nonsecure_per_world(void) {}
 static inline void cm_handle_asymmetric_features(void) {}
 #endif /* __aarch64__ */
diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h
index a396b99..4020331 100644
--- a/include/lib/extensions/amu.h
+++ b/include/lib/extensions/amu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,7 +17,7 @@
 #if ENABLE_FEAT_AMU
 #if __aarch64__
 void amu_enable(cpu_context_t *ctx);
-void amu_init_el3(void);
+void amu_init_el3(unsigned int core_pos);
 void amu_init_el2_unused(void);
 void amu_enable_per_world(per_world_context_t *per_world_ctx);
 #else
@@ -29,7 +29,7 @@
 void amu_enable(cpu_context_t *ctx)
 {
 }
-void amu_init_el3(void)
+void amu_init_el3(unsigned int core_pos)
 {
 }
 void amu_init_el2_unused(void)
@@ -45,28 +45,57 @@
 #endif /*__aarch64__ */
 #endif /* ENABLE_FEAT_AMU */
 
-#if ENABLE_AMU_AUXILIARY_COUNTERS
 /*
- * AMU data for a single core.
+ * Per-core list of the counters to be enabled. Value will be written into
+ * AMCNTENSET1_EL0 verbatim.
  */
-struct amu_core {
-	uint16_t enable; /* Mask of auxiliary counters to enable */
-};
+#if ENABLE_AMU_AUXILIARY_COUNTERS
+extern uint16_t plat_amu_aux_enables[PLATFORM_CORE_COUNT];
+#endif
 
-/*
- * Topological platform data specific to the AMU.
- */
-struct amu_topology {
-	struct amu_core cores[PLATFORM_CORE_COUNT]; /* Per-core data */
-};
+#define CTX_AMU_GRP0_ALL		U(4)
+#define CTX_AMU_GRP1_ALL		U(16)
 
-#if !ENABLE_AMU_FCONF
-/*
- * Retrieve the platform's AMU topology. A `NULL` return value is treated as a
- * non-fatal error, in which case no auxiliary counters will be enabled.
- */
-const struct amu_topology *plat_amu_topology(void);
-#endif /* ENABLE_AMU_FCONF */
-#endif /* ENABLE_AMU_AUXILIARY_COUNTERS */
+typedef struct amu_regs {
+	u_register_t grp0[CTX_AMU_GRP0_ALL];
+#if ENABLE_AMU_AUXILIARY_COUNTERS
+	u_register_t grp1[CTX_AMU_GRP1_ALL];
+#endif
+} amu_regs_t;
+
+static inline u_register_t read_amu_grp0_ctx_reg(amu_regs_t *ctx, size_t index)
+{
+	return ctx->grp0[index];
+}
+
+static inline void write_amu_grp0_ctx_reg(amu_regs_t *ctx, size_t index, u_register_t val)
+{
+	ctx->grp0[index] = val;
+}
+
+static inline uint16_t get_amu_aux_enables(size_t index)
+{
+#if ENABLE_AMU_AUXILIARY_COUNTERS
+	return plat_amu_aux_enables[index];
+#else
+	return 0;
+#endif
+}
+
+static inline u_register_t read_amu_grp1_ctx_reg(amu_regs_t *ctx, size_t index)
+{
+#if ENABLE_AMU_AUXILIARY_COUNTERS
+	return ctx->grp1[index];
+#else
+	return 0;
+#endif
+}
+
+static inline void write_amu_grp1_ctx_reg(amu_regs_t *ctx, size_t index, u_register_t val)
+{
+#if ENABLE_AMU_AUXILIARY_COUNTERS
+	ctx->grp1[index] = val;
+#endif
+}
 
 #endif /* AMU_H */
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index 2979efb..a471efb 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,10 +11,14 @@
 
 #if (ENABLE_SME_FOR_NS || ENABLE_SVE_FOR_NS)
 
+void sve_init_el3(void);
 void sve_init_el2_unused(void);
 void sve_enable_per_world(per_world_context_t *per_world_ctx);
 void sve_disable_per_world(per_world_context_t *per_world_ctx);
 #else
+static inline void sve_init_el3(void)
+{
+}
 static inline void sve_init_el2_unused(void)
 {
 }
diff --git a/include/lib/fconf/fconf_amu_getter.h b/include/lib/fconf/fconf_amu_getter.h
deleted file mode 100644
index 2faee73..0000000
--- a/include/lib/fconf/fconf_amu_getter.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FCONF_AMU_GETTER_H
-#define FCONF_AMU_GETTER_H
-
-#include <lib/extensions/amu.h>
-
-#define amu__config_getter(id)	fconf_amu_config.id
-
-struct fconf_amu_config {
-	const struct amu_topology *topology;
-};
-
-extern struct fconf_amu_config fconf_amu_config;
-
-#endif /* FCONF_AMU_GETTER_H */
diff --git a/include/lib/fconf/fconf_mpmm_getter.h b/include/lib/fconf/fconf_mpmm_getter.h
deleted file mode 100644
index 50d991a..0000000
--- a/include/lib/fconf/fconf_mpmm_getter.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FCONF_MPMM_GETTER_H
-#define FCONF_MPMM_GETTER_H
-
-#include <lib/mpmm/mpmm.h>
-
-#define mpmm__config_getter(id)	fconf_mpmm_config.id
-
-struct fconf_mpmm_config {
-	const struct mpmm_topology *topology;
-};
-
-extern struct fconf_mpmm_config fconf_mpmm_config;
-
-#endif /* FCONF_MPMM_GETTER_H */
diff --git a/include/lib/mpmm/mpmm.h b/include/lib/mpmm/mpmm.h
deleted file mode 100644
index 955c530..0000000
--- a/include/lib/mpmm/mpmm.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MPMM_H
-#define MPMM_H
-
-#include <stdbool.h>
-
-#include <platform_def.h>
-
-/*
- * Enable the Maximum Power Mitigation Mechanism.
- *
- * This function will enable MPMM for the current core. The AMU counters
- * representing the MPMM gears must have been configured and enabled prior to
- * calling this function.
- */
-void mpmm_enable(void);
-
-/*
- * MPMM core data.
- *
- * This structure represents per-core data retrieved from the hardware
- * configuration device tree.
- */
-struct mpmm_core {
-	/*
-	 * Whether MPMM is supported.
-	 *
-	 * Cores with support for MPMM offer one or more auxiliary AMU counters
-	 * representing MPMM gears.
-	 */
-	bool supported;
-};
-
-/*
- * MPMM topology.
- *
- * This topology structure describes the system-wide representation of the
- * information retrieved from the hardware configuration device tree.
- */
-struct mpmm_topology {
-	struct mpmm_core cores[PLATFORM_CORE_COUNT]; /* Per-core data */
-};
-
-#if !ENABLE_MPMM_FCONF
-/*
- * Retrieve the platform's MPMM topology. A `NULL` return value is treated as a
- * non-fatal error, in which case MPMM will not be enabled for any core.
- */
-const struct mpmm_topology *plat_mpmm_topology(void);
-#endif /* ENABLE_MPMM_FCONF */
-
-#endif /* MPMM_H */
diff --git a/include/plat/common/plat_drtm.h b/include/plat/common/plat_drtm.h
index 07545a6..0d6a818 100644
--- a/include/plat/common/plat_drtm.h
+++ b/include/plat/common/plat_drtm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -59,6 +59,8 @@
 uint64_t plat_drtm_get_tcb_hash_table_size(void);
 uint64_t plat_drtm_get_imp_def_dlme_region_size(void);
 uint64_t plat_drtm_get_tcb_hash_features(void);
+uint64_t plat_drtm_get_acpi_tables_region_size(void);
+uint64_t plat_drtm_get_dlme_img_auth_features(void);
 
 /* DRTM error handling functions */
 int plat_set_drtm_error(uint64_t error_code);
diff --git a/include/services/drtm_svc.h b/include/services/drtm_svc.h
index f0d3c63..3503fa4 100644
--- a/include/services/drtm_svc.h
+++ b/include/services/drtm_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -49,6 +49,7 @@
 #define ARM_DRTM_FEATURES_DMA_PROT	U(0x3)
 #define ARM_DRTM_FEATURES_BOOT_PE_ID	U(0x4)
 #define ARM_DRTM_FEATURES_TCB_HASHES	U(0x5)
+#define ARM_DRTM_FEATURES_DLME_IMG_AUTH	U(0x6)
 
 #define is_drtm_fid(_fid) \
 	(((_fid) >= ARM_DRTM_SVC_VERSION) && ((_fid) <= ARM_DRTM_SVC_LOCK_TCB_HASH))
@@ -109,6 +110,9 @@
 #define ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_SHIFT	U(0)
 #define ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_MASK	ULL(0xFF)
 
+#define ARM_DRTM_DLME_IMAGE_AUTH_SUPPORT_SHIFT	U(0)
+#define ARM_DRTM_DLME_IMAGE_AUTH_SUPPORT_MASK	ULL(0x1)
+
 #define ARM_DRTM_TPM_FEATURES_SET_PCR_SCHEMA(reg, val)			\
 	do {								\
 		reg = (((reg) & ~(ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_MASK \
@@ -178,6 +182,16 @@
 		ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_SHIFT));	\
 	} while (false)
 
+#define ARM_DRTM_DLME_IMG_AUTH_SUPPORT(reg, val)		\
+	do {								\
+		reg = (((reg) &						\
+		~(ARM_DRTM_DLME_IMAGE_AUTH_SUPPORT_MASK <<	\
+		ARM_DRTM_DLME_IMAGE_AUTH_SUPPORT_SHIFT)) |	\
+		(((val) &						\
+		ARM_DRTM_DLME_IMAGE_AUTH_SUPPORT_MASK) <<	\
+		ARM_DRTM_DLME_IMAGE_AUTH_SUPPORT_SHIFT));	\
+	} while (false)
+
 /* Definitions for DRTM address map */
 #define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_SHIFT	U(55)
 #define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_MASK	ULL(0x3)
diff --git a/lib/cpus/aarch64/cortex_a320.S b/lib/cpus/aarch64/cortex_a320.S
new file mode 100644
index 0000000..2d38b88
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a320.S
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a320.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A320 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-A320 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_prologue cortex_a320
+
+cpu_reset_func_start cortex_a320
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+	enable_mpmm
+cpu_reset_func_end cortex_a320
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_a320_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_A320_CPUPWRCTLR_EL1, CORTEX_A320_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc cortex_a320_core_pwr_dwn
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-A320 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a320_regs, "aS"
+cortex_a320_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a320_cpu_reg_dump
+	adr	x6, cortex_a320_regs
+	mrs	x8, CORTEX_A320_CPUECTLR_EL1
+	ret
+endfunc cortex_a320_cpu_reg_dump
+
+declare_cpu_ops cortex_a320, CORTEX_A320_MIDR, \
+	cortex_a320_reset_func, \
+	cortex_a320_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index cbeeb2b..81a227b 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -111,25 +111,11 @@
 
 check_erratum_ls cortex_a510, ERRATUM(2218950), CPU_REV(1, 0)
 
-	/* --------------------------------------------------
-	 * This workaround is not a typical errata fix. MPMM
-	 * is disabled here, but this conflicts with the BL31
-	 * MPMM support. So in addition to simply disabling
-	 * the feature, a flag is set in the MPMM library
-	 * indicating that it should not be enabled even if
-	 * ENABLE_MPMM=1.
-	 * --------------------------------------------------
-	 */
 workaround_reset_start cortex_a510, ERRATUM(2250311), ERRATA_A510_2250311
 	/* Disable MPMM */
 	mrs	x0, CPUMPMMCR_EL3
 	bfm	x0, xzr, #0, #0 /* bfc instruction does not work in GCC */
 	msr	CPUMPMMCR_EL3, x0
-
-#if ENABLE_MPMM && IMAGE_BL31
-	/* If ENABLE_MPMM is set, tell the runtime lib to skip enabling it. */
-	bl mpmm_errata_disable
-#endif
 workaround_reset_end cortex_a510, ERRATUM(2250311)
 
 check_erratum_ls cortex_a510, ERRATUM(2250311), CPU_REV(1, 0)
@@ -209,6 +195,15 @@
 cpu_reset_func_start cortex_a510
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	/* skip enabling MPMM if this erratum is present */
+#if ERRATA_A510_2250311
+	/* the cpu_rev_var is kept in x14 */
+	mov	x14, x0
+	bl	check_erratum_cortex_a510_2250311
+	cbz	x0, skip_mpmm
+#endif
+	enable_mpmm
+skip_mpmm:
 cpu_reset_func_end cortex_a510
 
 	/* ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a520.S b/lib/cpus/aarch64/cortex_a520.S
index 6714a53..ac8019e 100644
--- a/lib/cpus/aarch64/cortex_a520.S
+++ b/lib/cpus/aarch64/cortex_a520.S
@@ -58,6 +58,7 @@
 cpu_reset_func_start cortex_a520
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_a520
 
 	/* ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index cb24aa1..e8f5a80 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -250,6 +250,7 @@
 cpu_reset_func_start cortex_a710
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_a710
 
 	/* ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index e50764d..d9c0df2 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -138,6 +138,7 @@
 cpu_reset_func_start cortex_a715
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_a715
 
 	/* ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a720.S b/lib/cpus/aarch64/cortex_a720.S
index 2991f93..e639996 100644
--- a/lib/cpus/aarch64/cortex_a720.S
+++ b/lib/cpus/aarch64/cortex_a720.S
@@ -83,6 +83,7 @@
 cpu_reset_func_start cortex_a720
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_a720
 
 	/* ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a720_ae.S b/lib/cpus/aarch64/cortex_a720_ae.S
index c72a29e..1d51c44 100644
--- a/lib/cpus/aarch64/cortex_a720_ae.S
+++ b/lib/cpus/aarch64/cortex_a720_ae.S
@@ -32,6 +32,7 @@
 cpu_reset_func_start cortex_a720_ae
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_a720_ae
 
 	/* ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a725.S b/lib/cpus/aarch64/cortex_a725.S
index a8c0db2..682ca45 100644
--- a/lib/cpus/aarch64/cortex_a725.S
+++ b/lib/cpus/aarch64/cortex_a725.S
@@ -32,6 +32,7 @@
 cpu_reset_func_start cortex_a725
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_a725
 
 	/* ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_alto.S b/lib/cpus/aarch64/cortex_alto.S
index 97192a6..69a630d 100644
--- a/lib/cpus/aarch64/cortex_alto.S
+++ b/lib/cpus/aarch64/cortex_alto.S
@@ -30,6 +30,7 @@
 cpu_reset_func_start cortex_alto
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_alto
 
 func cortex_alto_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_arcadia.S b/lib/cpus/aarch64/cortex_arcadia.S
deleted file mode 100644
index ae8eb91..0000000
--- a/lib/cpus/aarch64/cortex_arcadia.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <cortex_arcadia.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex-ARCADIA must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex-ARCADIA supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-cpu_reset_prologue cortex_arcadia
-
-cpu_reset_func_start cortex_arcadia
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-cpu_reset_func_end cortex_arcadia
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func cortex_arcadia_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	sysreg_bit_set CORTEX_ARCADIA_CPUPWRCTLR_EL1, CORTEX_ARCADIA_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	isb
-	ret
-endfunc cortex_arcadia_core_pwr_dwn
-
-	/* ---------------------------------------------
-	 * This function provides Cortex-Arcadia specific
-	 * register information for crash reporting.
-	 * It needs to return with x6 pointing to
-	 * a list of register names in ascii and
-	 * x8 - x15 having values of registers to be
-	 * reported.
-	 * ---------------------------------------------
-	 */
-.section .rodata.cortex_arcadia_regs, "aS"
-cortex_arcadia_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func cortex_arcadia_cpu_reg_dump
-	adr	x6, cortex_arcadia_regs
-	mrs	x8, CORTEX_ARCADIA_CPUECTLR_EL1
-	ret
-endfunc cortex_arcadia_cpu_reg_dump
-
-declare_cpu_ops cortex_arcadia, CORTEX_ARCADIA_MIDR, \
-	cortex_arcadia_reset_func, \
-	cortex_arcadia_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_gelas.S b/lib/cpus/aarch64/cortex_gelas.S
index cdf6284..4cdec32 100644
--- a/lib/cpus/aarch64/cortex_gelas.S
+++ b/lib/cpus/aarch64/cortex_gelas.S
@@ -40,6 +40,7 @@
 	/* model bug: not cleared on reset */
 	sysreg_bit_clear 	CORTEX_GELAS_CPUPWRCTLR_EL1, \
 		CORTEX_GELAS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	enable_mpmm
 cpu_reset_func_end cortex_gelas
 
 	/* ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 549beec..b11c37d 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -195,6 +195,7 @@
 cpu_reset_func_start cortex_x2
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_x2
 
 	/* ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index da9e306..3d52dae 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -136,6 +136,7 @@
 cpu_reset_func_start cortex_x3
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_x3
 
 	/* ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index 53461c6..c067981 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -130,6 +130,7 @@
 cpu_reset_func_start cortex_x4
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_x4
 
 	/* ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_x925.S b/lib/cpus/aarch64/cortex_x925.S
index 7dec375..093d91d 100644
--- a/lib/cpus/aarch64/cortex_x925.S
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -63,6 +63,7 @@
 cpu_reset_func_start cortex_x925
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end cortex_x925
 
 	/* ----------------------------------------------------
diff --git a/lib/cpus/aarch64/nevis.S b/lib/cpus/aarch64/nevis.S
index 0d04e65..b2aa26e 100644
--- a/lib/cpus/aarch64/nevis.S
+++ b/lib/cpus/aarch64/nevis.S
@@ -29,6 +29,7 @@
 	 * ----------------------------------------------------
 	 */
 	msr	SSBS, xzr
+	enable_mpmm
 cpu_reset_func_end nevis
 
 func nevis_core_pwr_dwn
diff --git a/lib/cpus/aarch64/travis.S b/lib/cpus/aarch64/travis.S
index 0a95e80..d53e46f 100644
--- a/lib/cpus/aarch64/travis.S
+++ b/lib/cpus/aarch64/travis.S
@@ -40,6 +40,7 @@
 	/* model bug: not cleared on reset */
 	sysreg_bit_clear TRAVIS_IMP_CPUPWRCTLR_EL1, \
 		TRAVIS_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+	enable_mpmm
 cpu_reset_func_end travis
 
 func travis_core_pwr_dwn
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 6415cb3..1e6a42e 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -209,19 +209,6 @@
  */
 func sve_context_save
 .arch_extension sve
-	/* Temporarily enable SVE */
-	mrs	x10, cptr_el3
-	orr	x11, x10, #CPTR_EZ_BIT
-	bic	x11, x11, #TFP_BIT
-	msr	cptr_el3, x11
-	isb
-
-	/* zcr_el3 */
-	mrs	x12, S3_6_C1_C2_0
-	mov	x13, #((SVE_VECTOR_LEN >> 7) - 1)
-	msr	S3_6_C1_C2_0, x13
-	isb
-
 	/* Predicate registers */
 	mov x13, #CTX_SIMD_PREDICATES
 	add	x9, x0, x13
@@ -237,11 +224,6 @@
 	mov x13, #CTX_SIMD_VECTORS
 	add	x9, x0, x13
 	sve_vectors_op  str, x9
-
-	/* Restore SVE enablement */
-	msr	S3_6_C1_C2_0, x12 /* zcr_el3 */
-	msr	cptr_el3, x10
-	isb
 .arch_extension nosve
 
 	/* Save FPSR, FPCR and FPEXC32 */
@@ -260,19 +242,6 @@
  */
 func sve_context_restore
 .arch_extension sve
-	/* Temporarily enable SVE for EL3 */
-	mrs	x10, cptr_el3
-	orr	x11, x10, #CPTR_EZ_BIT
-	bic	x11, x11, #TFP_BIT
-	msr	cptr_el3, x11
-	isb
-
-	/* zcr_el3 */
-	mrs	x12, S3_6_C1_C2_0
-	mov	x13, #((SVE_VECTOR_LEN >> 7) - 1)
-	msr	S3_6_C1_C2_0, x13
-	isb
-
 	/* Restore FFR register before predicates */
 	mov x13, #CTX_SIMD_FFR
 	add	x9, x0, x13
@@ -288,11 +257,6 @@
 	mov x13, #CTX_SIMD_VECTORS
 	add	x9, x0, x13
 	sve_vectors_op	ldr, x9
-
-	/* Restore SVE enablement */
-	msr	S3_6_C1_C2_0, x12 /* zcr_el3 */
-	msr	cptr_el3, x10
-	isb
 .arch_extension nosve
 
 	/* Restore FPSR, FPCR and FPEXC32 */
@@ -604,10 +568,7 @@
 
 	/* ----------------------------------------------------------
 	 * Restore CPTR_EL3.
-	 * ZCR is only restored if SVE is supported and enabled.
-	 * Synchronization is required before zcr_el3 is addressed.
-	 * ----------------------------------------------------------
-	 */
+	 * ---------------------------------------------------------- */
 
 	/* The address of the per_world context is stored in x9 */
 	get_per_world_context x9
@@ -616,13 +577,6 @@
 	msr	cptr_el3, x19
 
 #if IMAGE_BL31
-	ands	x19, x19, #CPTR_EZ_BIT
-	beq	sve_not_enabled
-
-	isb
-	msr	S3_6_C1_C2_0, x20 /* zcr_el3 */
-sve_not_enabled:
-
 	restore_mpam3_el3
 
 #endif /* IMAGE_BL31 */
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index dfd14b6..e28e1c3 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -661,13 +661,17 @@
 /*******************************************************************************
  * Enable architecture extensions for EL3 execution. This function only updates
  * registers in-place which are expected to either never change or be
- * overwritten by el3_exit.
+ * overwritten by el3_exit. Expects the core_pos of the current core as argument.
  ******************************************************************************/
 #if IMAGE_BL31
-void cm_manage_extensions_el3(void)
+void cm_manage_extensions_el3(unsigned int my_idx)
 {
+	if (is_feat_sve_supported()) {
+		sve_init_el3();
+	}
+
 	if (is_feat_amu_supported()) {
-		amu_init_el3();
+		amu_init_el3(my_idx);
 	}
 
 	if (is_feat_sme_supported()) {
@@ -803,6 +807,7 @@
 static void manage_extensions_nonsecure(cpu_context_t *ctx)
 {
 #if IMAGE_BL31
+	/* NOTE: registers are not context switched */
 	if (is_feat_amu_supported()) {
 		amu_enable(ctx);
 	}
diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c
index 351a552..6faef87 100644
--- a/lib/extensions/amu/aarch32/amu.c
+++ b/lib/extensions/amu/aarch32/amu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,6 @@
 #include <cdefs.h>
 #include <stdbool.h>
 
-#include "../amu_private.h"
 #include <arch.h>
 #include <arch_features.h>
 #include <arch_helpers.h>
@@ -18,51 +17,7 @@
 
 #include <plat/common/platform.h>
 
-struct amu_ctx {
-	uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS];
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	uint64_t group1_cnts[AMU_GROUP1_MAX_COUNTERS];
-#endif
-
-	uint16_t group0_enable;
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	uint16_t group1_enable;
-#endif
-};
-
-static struct amu_ctx amu_ctxs_[PLATFORM_CORE_COUNT];
-
-CASSERT((sizeof(amu_ctxs_[0].group0_enable) * CHAR_BIT) <= AMU_GROUP0_MAX_COUNTERS,
-	amu_ctx_group0_enable_cannot_represent_all_group0_counters);
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-CASSERT((sizeof(amu_ctxs_[0].group1_enable) * CHAR_BIT) <= AMU_GROUP1_MAX_COUNTERS,
-	amu_ctx_group1_enable_cannot_represent_all_group1_counters);
-#endif
-
-static inline __unused void write_hcptr_tam(uint32_t value)
-{
-	write_hcptr((read_hcptr() & ~TAM_BIT) |
-		((value << TAM_SHIFT) & TAM_BIT));
-}
-
-static inline __unused void write_amcr_cg1rz(uint32_t value)
-{
-	write_amcr((read_amcr() & ~AMCR_CG1RZ_BIT) |
-		((value << AMCR_CG1RZ_SHIFT) & AMCR_CG1RZ_BIT));
-}
-
-static inline __unused uint32_t read_amcfgr_ncg(void)
-{
-	return (read_amcfgr() >> AMCFGR_NCG_SHIFT) &
-		AMCFGR_NCG_MASK;
-}
-
-static inline __unused uint32_t read_amcgcr_cg0nc(void)
-{
-	return (read_amcgcr() >> AMCGCR_CG0NC_SHIFT) &
-		AMCGCR_CG0NC_MASK;
-}
+amu_regs_t amu_ctx[PLATFORM_CORE_COUNT];
 
 static inline __unused uint32_t read_amcgcr_cg1nc(void)
 {
@@ -70,134 +25,31 @@
 		AMCGCR_CG1NC_MASK;
 }
 
-static inline __unused uint32_t read_amcntenset0_px(void)
-{
-	return (read_amcntenset0() >> AMCNTENSET0_Pn_SHIFT) &
-		AMCNTENSET0_Pn_MASK;
-}
-
-static inline __unused uint32_t read_amcntenset1_px(void)
-{
-	return (read_amcntenset1() >> AMCNTENSET1_Pn_SHIFT) &
-		AMCNTENSET1_Pn_MASK;
-}
-
-static inline __unused void write_amcntenset0_px(uint32_t px)
-{
-	uint32_t value = read_amcntenset0();
-
-	value &= ~AMCNTENSET0_Pn_MASK;
-	value |= (px << AMCNTENSET0_Pn_SHIFT) &
-		AMCNTENSET0_Pn_MASK;
-
-	write_amcntenset0(value);
-}
-
-static inline __unused void write_amcntenset1_px(uint32_t px)
-{
-	uint32_t value = read_amcntenset1();
-
-	value &= ~AMCNTENSET1_Pn_MASK;
-	value |= (px << AMCNTENSET1_Pn_SHIFT) &
-		AMCNTENSET1_Pn_MASK;
-
-	write_amcntenset1(value);
-}
-
-static inline __unused void write_amcntenclr0_px(uint32_t px)
-{
-	uint32_t value = read_amcntenclr0();
-
-	value &= ~AMCNTENCLR0_Pn_MASK;
-	value |= (px << AMCNTENCLR0_Pn_SHIFT) & AMCNTENCLR0_Pn_MASK;
-
-	write_amcntenclr0(value);
-}
-
-static inline __unused void write_amcntenclr1_px(uint32_t px)
-{
-	uint32_t value = read_amcntenclr1();
-
-	value &= ~AMCNTENCLR1_Pn_MASK;
-	value |= (px << AMCNTENCLR1_Pn_SHIFT) & AMCNTENCLR1_Pn_MASK;
-
-	write_amcntenclr1(value);
-}
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-static __unused bool amu_group1_supported(void)
-{
-	return read_amcfgr_ncg() > 0U;
-}
-#endif
-
 /*
  * Enable counters. This function is meant to be invoked by the context
  * management library before exiting from EL3.
  */
 void amu_enable(bool el2_unused)
 {
-	uint32_t amcfgr_ncg;		/* Number of counter groups */
-	uint32_t amcgcr_cg0nc;		/* Number of group 0 counters */
-
-	uint32_t amcntenset0_px = 0x0;	/* Group 0 enable mask */
-	uint32_t amcntenset1_px = 0x0;	/* Group 1 enable mask */
-
 	if (el2_unused) {
 		/*
 		 * HCPTR.TAM: Set to zero so any accesses to the Activity
 		 * Monitor registers do not trap to EL2.
 		 */
-		write_hcptr_tam(0U);
+		write_hcptr(read_hcptr() & ~TAM_BIT);
 	}
 
-	/*
-	 * Retrieve the number of architected counters. All of these counters
-	 * are enabled by default.
-	 */
-
-	amcgcr_cg0nc = read_amcgcr_cg0nc();
-	amcntenset0_px = (UINT32_C(1) << (amcgcr_cg0nc)) - 1U;
-
-	assert(amcgcr_cg0nc <= AMU_AMCGCR_CG0NC_MAX);
-
-	/*
-	 * The platform may opt to enable specific auxiliary counters. This can
-	 * be done via the common FCONF getter, or via the platform-implemented
-	 * function.
-	 */
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	const struct amu_topology *topology;
-
-#if ENABLE_AMU_FCONF
-	topology = FCONF_GET_PROPERTY(amu, config, topology);
-#else
-	topology = plat_amu_topology();
-#endif /* ENABLE_AMU_FCONF */
+	/* Architecture is currently pinned to 4 */
+	assert((read_amcgcr() & AMCGCR_CG0NC_MASK) == CTX_AMU_GRP0_ALL);
 
-	if (topology != NULL) {
+	/* Enable all architected counters by default */
+	write_amcntenset0(AMCNTENSET0_Pn_MASK);
+	if (is_feat_amu_aux_supported()) {
 		unsigned int core_pos = plat_my_core_pos();
 
-		amcntenset1_el0_px = topology->cores[core_pos].enable;
-	} else {
-		ERROR("AMU: failed to generate AMU topology\n");
-	}
-#endif /* ENABLE_AMU_AUXILIARY_COUNTERS */
-
-	/*
-	 * Enable the requested counters.
-	 */
-
-	write_amcntenset0_px(amcntenset0_px);
-
-	amcfgr_ncg = read_amcfgr_ncg();
-	if (amcfgr_ncg > 0U) {
-		write_amcntenset1_px(amcntenset1_px);
-
-#if !ENABLE_AMU_AUXILIARY_COUNTERS
-		VERBOSE("AMU: auxiliary counters detected but support is disabled\n");
-#endif
+		/* Something went wrong if we're trying to write higher bits */
+		assert((get_amu_aux_enables(core_pos) & ~AMCNTENSET1_Pn_MASK) == 0);
+		write_amcntenset1(get_amu_aux_enables(core_pos));
 	}
 
 	/* Bail out if FEAT_AMUv1p1 features are not present. */
@@ -214,180 +66,177 @@
 	 * mapped view are unaffected.
 	 */
 	VERBOSE("AMU group 1 counter access restricted.\n");
-	write_amcr_cg1rz(1U);
+	write_amcr(read_amcr() | 1U);
 #else
-	write_amcr_cg1rz(0U);
+	write_amcr(0);
 #endif
 }
 
-/* Read the group 0 counter identified by the given `idx`. */
-static uint64_t amu_group0_cnt_read(unsigned int idx)
-{
-	assert(is_feat_amu_supported());
-	assert(idx < read_amcgcr_cg0nc());
-
-	return amu_group0_cnt_read_internal(idx);
-}
-
-/* Write the group 0 counter identified by the given `idx` with `val` */
-static void amu_group0_cnt_write(unsigned  int idx, uint64_t val)
-{
-	assert(is_feat_amu_supported());
-	assert(idx < read_amcgcr_cg0nc());
-
-	amu_group0_cnt_write_internal(idx, val);
-	isb();
-}
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-/* Read the group 1 counter identified by the given `idx` */
-static uint64_t amu_group1_cnt_read(unsigned  int idx)
-{
-	assert(is_feat_amu_supported());
-	assert(amu_group1_supported());
-	assert(idx < read_amcgcr_cg1nc());
-
-	return amu_group1_cnt_read_internal(idx);
-}
-
-/* Write the group 1 counter identified by the given `idx` with `val` */
-static void amu_group1_cnt_write(unsigned  int idx, uint64_t val)
-{
-	assert(is_feat_amu_supported());
-	assert(amu_group1_supported());
-	assert(idx < read_amcgcr_cg1nc());
-
-	amu_group1_cnt_write_internal(idx, val);
-	isb();
-}
-#endif
-
 static void *amu_context_save(const void *arg)
 {
-	uint32_t i;
-
-	unsigned int core_pos;
-	struct amu_ctx *ctx;
-
-	uint32_t amcgcr_cg0nc;	/* Number of group 0 counters */
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	uint32_t amcfgr_ncg;	/* Number of counter groups */
-	uint32_t amcgcr_cg1nc;	/* Number of group 1 counters */
-#endif
-
 	if (!is_feat_amu_supported()) {
 		return (void *)0;
 	}
 
-	core_pos = plat_my_core_pos();
-	ctx = &amu_ctxs_[core_pos];
-
-	amcgcr_cg0nc = read_amcgcr_cg0nc();
+	unsigned int core_pos = *(unsigned int *)arg;
+	amu_regs_t *ctx = &amu_ctx[core_pos];
 
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	amcfgr_ncg = read_amcfgr_ncg();
-	amcgcr_cg1nc = (amcfgr_ncg > 0U) ? read_amcgcr_cg1nc() : 0U;
-#endif
-
-	/*
-	 * Disable all AMU counters.
-	 */
-
-	ctx->group0_enable = read_amcntenset0_px();
-	write_amcntenclr0_px(ctx->group0_enable);
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	if (amcfgr_ncg > 0U) {
-		ctx->group1_enable = read_amcntenset1_px();
-		write_amcntenclr1_px(ctx->group1_enable);
+	/* Disable all counters so we can write to them safely later */
+	write_amcntenclr0(AMCNTENCLR0_Pn_MASK);
+	if (is_feat_amu_aux_supported()) {
+		write_amcntenclr1(get_amu_aux_enables(core_pos));
 	}
-#endif
-
-	/*
-	 * Save the counters to the local context.
-	 */
 
 	isb(); /* Ensure counters have been stopped */
 
-	for (i = 0U; i < amcgcr_cg0nc; i++) {
-		ctx->group0_cnts[i] = amu_group0_cnt_read(i);
-	}
+	write_amu_grp0_ctx_reg(ctx, 0, read64_amevcntr00());
+	write_amu_grp0_ctx_reg(ctx, 1, read64_amevcntr01());
+	write_amu_grp0_ctx_reg(ctx, 2, read64_amevcntr02());
+	write_amu_grp0_ctx_reg(ctx, 3, read64_amevcntr03());
+
+	if (is_feat_amu_aux_supported()) {
+		uint8_t num_counters = read_amcgcr_cg1nc();
 
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	for (i = 0U; i < amcgcr_cg1nc; i++) {
-		ctx->group1_cnts[i] = amu_group1_cnt_read(i);
+		switch (num_counters) {
+		case 0x10:
+			write_amu_grp1_ctx_reg(ctx, 0xf, read64_amevcntr1f());
+			__fallthrough;
+		case 0x0f:
+			write_amu_grp1_ctx_reg(ctx, 0xe, read64_amevcntr1e());
+			__fallthrough;
+		case 0x0e:
+			write_amu_grp1_ctx_reg(ctx, 0xd, read64_amevcntr1d());
+			__fallthrough;
+		case 0x0d:
+			write_amu_grp1_ctx_reg(ctx, 0xc, read64_amevcntr1c());
+			__fallthrough;
+		case 0x0c:
+			write_amu_grp1_ctx_reg(ctx, 0xb, read64_amevcntr1b());
+			__fallthrough;
+		case 0x0b:
+			write_amu_grp1_ctx_reg(ctx, 0xa, read64_amevcntr1a());
+			__fallthrough;
+		case 0x0a:
+			write_amu_grp1_ctx_reg(ctx, 0x9, read64_amevcntr19());
+			__fallthrough;
+		case 0x09:
+			write_amu_grp1_ctx_reg(ctx, 0x8, read64_amevcntr18());
+			__fallthrough;
+		case 0x08:
+			write_amu_grp1_ctx_reg(ctx, 0x7, read64_amevcntr17());
+			__fallthrough;
+		case 0x07:
+			write_amu_grp1_ctx_reg(ctx, 0x6, read64_amevcntr16());
+			__fallthrough;
+		case 0x06:
+			write_amu_grp1_ctx_reg(ctx, 0x5, read64_amevcntr15());
+			__fallthrough;
+		case 0x05:
+			write_amu_grp1_ctx_reg(ctx, 0x4, read64_amevcntr14());
+			__fallthrough;
+		case 0x04:
+			write_amu_grp1_ctx_reg(ctx, 0x3, read64_amevcntr13());
+			__fallthrough;
+		case 0x03:
+			write_amu_grp1_ctx_reg(ctx, 0x2, read64_amevcntr12());
+			__fallthrough;
+		case 0x02:
+			write_amu_grp1_ctx_reg(ctx, 0x1, read64_amevcntr11());
+			__fallthrough;
+		case 0x01:
+			write_amu_grp1_ctx_reg(ctx, 0x0, read64_amevcntr10());
+			__fallthrough;
+		case 0x00:
+			break;
+		default:
+			assert(0); /* something is wrong */
+		}
 	}
-#endif
 
 	return (void *)0;
 }
 
 static void *amu_context_restore(const void *arg)
 {
-	uint32_t i;
-
-	unsigned int core_pos;
-	struct amu_ctx *ctx;
-
-	uint32_t amcfgr_ncg;	/* Number of counter groups */
-	uint32_t amcgcr_cg0nc;	/* Number of group 0 counters */
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	uint32_t amcgcr_cg1nc;	/* Number of group 1 counters */
-#endif
-
 	if (!is_feat_amu_supported()) {
 		return (void *)0;
 	}
 
-	core_pos = plat_my_core_pos();
-	ctx = &amu_ctxs_[core_pos];
-
-	amcfgr_ncg = read_amcfgr_ncg();
-	amcgcr_cg0nc = read_amcgcr_cg0nc();
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	amcgcr_cg1nc = (amcfgr_ncg > 0U) ? read_amcgcr_cg1nc() : 0U;
-#endif
-
-	/*
-	 * Sanity check that all counters were disabled when the context was
-	 * previously saved.
-	 */
+	unsigned int core_pos = *(unsigned int *)arg;
+	amu_regs_t *ctx = &amu_ctx[core_pos];
 
-	assert(read_amcntenset0_px() == 0U);
-
-	if (amcfgr_ncg > 0U) {
-		assert(read_amcntenset1_px() == 0U);
-	}
-
-	/*
-	 * Restore the counter values from the local context.
-	 */
+	write64_amevcntr00(read_amu_grp0_ctx_reg(ctx, 0));
+	write64_amevcntr01(read_amu_grp0_ctx_reg(ctx, 1));
+	write64_amevcntr02(read_amu_grp0_ctx_reg(ctx, 2));
+	write64_amevcntr03(read_amu_grp0_ctx_reg(ctx, 3));
 
-	for (i = 0U; i < amcgcr_cg0nc; i++) {
-		amu_group0_cnt_write(i, ctx->group0_cnts[i]);
-	}
+	if (is_feat_amu_aux_supported()) {
+		uint8_t num_counters = read_amcgcr_cg1nc();
 
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	for (i = 0U; i < amcgcr_cg1nc; i++) {
-		amu_group1_cnt_write(i, ctx->group1_cnts[i]);
+		switch (num_counters) {
+		case 0x10:
+			write64_amevcntr1f(read_amu_grp1_ctx_reg(ctx, 0xf));
+			__fallthrough;
+		case 0x0f:
+			write64_amevcntr1e(read_amu_grp1_ctx_reg(ctx, 0xe));
+			__fallthrough;
+		case 0x0e:
+			write64_amevcntr1d(read_amu_grp1_ctx_reg(ctx, 0xd));
+			__fallthrough;
+		case 0x0d:
+			write64_amevcntr1c(read_amu_grp1_ctx_reg(ctx, 0xc));
+			__fallthrough;
+		case 0x0c:
+			write64_amevcntr1b(read_amu_grp1_ctx_reg(ctx, 0xb));
+			__fallthrough;
+		case 0x0b:
+			write64_amevcntr1a(read_amu_grp1_ctx_reg(ctx, 0xa));
+			__fallthrough;
+		case 0x0a:
+			write64_amevcntr19(read_amu_grp1_ctx_reg(ctx, 0x9));
+			__fallthrough;
+		case 0x09:
+			write64_amevcntr18(read_amu_grp1_ctx_reg(ctx, 0x8));
+			__fallthrough;
+		case 0x08:
+			write64_amevcntr17(read_amu_grp1_ctx_reg(ctx, 0x7));
+			__fallthrough;
+		case 0x07:
+			write64_amevcntr16(read_amu_grp1_ctx_reg(ctx, 0x6));
+			__fallthrough;
+		case 0x06:
+			write64_amevcntr15(read_amu_grp1_ctx_reg(ctx, 0x5));
+			__fallthrough;
+		case 0x05:
+			write64_amevcntr14(read_amu_grp1_ctx_reg(ctx, 0x4));
+			__fallthrough;
+		case 0x04:
+			write64_amevcntr13(read_amu_grp1_ctx_reg(ctx, 0x3));
+			__fallthrough;
+		case 0x03:
+			write64_amevcntr12(read_amu_grp1_ctx_reg(ctx, 0x2));
+			__fallthrough;
+		case 0x02:
+			write64_amevcntr11(read_amu_grp1_ctx_reg(ctx, 0x1));
+			__fallthrough;
+		case 0x01:
+			write64_amevcntr10(read_amu_grp1_ctx_reg(ctx, 0x0));
+			__fallthrough;
+		case 0x00:
+			break;
+		default:
+			assert(0); /* something is wrong */
+		}
 	}
-#endif
-
-	/*
-	 * Re-enable counters that were disabled during context save.
-	 */
 
-	write_amcntenset0_px(ctx->group0_enable);
 
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	if (amcfgr_ncg > 0U) {
-		write_amcntenset1_px(ctx->group1_enable);
+	/* now enable them again */
+	write_amcntenset0(AMCNTENSET0_Pn_MASK);
+	if (is_feat_amu_aux_supported()) {
+		write_amcntenset1(get_amu_aux_enables(core_pos));
 	}
-#endif
 
+	isb();
 	return (void *)0;
 }
 
diff --git a/lib/extensions/amu/aarch32/amu_helpers.S b/lib/extensions/amu/aarch32/amu_helpers.S
deleted file mode 100644
index 7090b2d..0000000
--- a/lib/extensions/amu/aarch32/amu_helpers.S
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <assert_macros.S>
-#include <asm_macros.S>
-
-	.globl	amu_group0_cnt_read_internal
-	.globl	amu_group0_cnt_write_internal
-	.globl	amu_group1_cnt_read_internal
-	.globl	amu_group1_cnt_write_internal
-	.globl	amu_group1_set_evtype_internal
-
-/*
- * uint64_t amu_group0_cnt_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU counter
- * and return it in `r0` and `r1`.
- */
-func amu_group0_cnt_read_internal
-#if ENABLE_ASSERTIONS
-	/* `idx` should be between [0, 3] */
-	mov	r1, r0
-	lsr	r1, r1, #2
-	cmp	r1, #0
-	ASM_ASSERT(eq)
-#endif
-
-	/*
-	 * Given `idx` calculate address of ldcopr16/bx lr instruction pair
-	 * in the table below.
-	 */
-	adr	r1, 1f
-	lsl	r0, r0, #3	/* each ldcopr16/bx lr sequence is 8 bytes */
-	add	r1, r1, r0
-	bx	r1
-1:
-	ldcopr16	r0, r1, AMEVCNTR00	/* index 0 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR01	/* index 1 */
-	bx 		lr
-	ldcopr16	r0, r1, AMEVCNTR02	/* index 2 */
-	bx 		lr
-	ldcopr16	r0, r1, AMEVCNTR03	/* index 3 */
-	bx 		lr
-endfunc amu_group0_cnt_read_internal
-
-/*
- * void amu_group0_cnt_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU counter.
- * `idx` is passed in `r0` and `val` is passed in `r2` and `r3`.
- * `r1` is used as a scratch register.
- */
-func amu_group0_cnt_write_internal
-#if ENABLE_ASSERTIONS
-	/* `idx` should be between [0, 3] */
-	mov	r1, r0
-	lsr	r1, r1, #2
-	cmp	r1, #0
-	ASM_ASSERT(eq)
-#endif
-
-	/*
-	 * Given `idx` calculate address of stcopr16/bx lr instruction pair
-	 * in the table below.
-	 */
-	adr	r1, 1f
-	lsl	r0, r0, #3	/* each stcopr16/bx lr sequence is 8 bytes */
-	add	r1, r1, r0
-	bx	r1
-
-1:
-	stcopr16	r2, r3, AMEVCNTR00	/* index 0 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR01	/* index 1 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR02	/* index 2 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR03	/* index 3 */
-	bx		lr
-endfunc amu_group0_cnt_write_internal
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-/*
- * uint64_t amu_group1_cnt_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU counter
- * and return it in `r0` and `r1`.
- */
-func amu_group1_cnt_read_internal
-#if ENABLE_ASSERTIONS
-	/* `idx` should be between [0, 15] */
-	mov	r1, r0
-	lsr	r1, r1, #4
-	cmp	r1, #0
-	ASM_ASSERT(eq)
-#endif
-
-	/*
-	 * Given `idx` calculate address of ldcopr16/bx lr instruction pair
-	 * in the table below.
-	 */
-	adr	r1, 1f
-	lsl	r0, r0, #3	/* each ldcopr16/bx lr sequence is 8 bytes */
-	add	r1, r1, r0
-	bx	r1
-
-1:
-	ldcopr16	r0, r1, AMEVCNTR10	/* index 0 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR11	/* index 1 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR12	/* index 2 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR13	/* index 3 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR14	/* index 4 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR15	/* index 5 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR16	/* index 6 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR17	/* index 7 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR18	/* index 8 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR19	/* index 9 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR1A	/* index 10 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR1B	/* index 11 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR1C	/* index 12 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR1D	/* index 13 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR1E	/* index 14 */
-	bx		lr
-	ldcopr16	r0, r1, AMEVCNTR1F	/* index 15 */
-	bx		lr
-endfunc amu_group1_cnt_read_internal
-
-/*
- * void amu_group1_cnt_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU counter.
- * `idx` is passed in `r0` and `val` is passed in `r2` and `r3`.
- * `r1` is used as a scratch register.
- */
-func amu_group1_cnt_write_internal
-#if ENABLE_ASSERTIONS
-	/* `idx` should be between [0, 15] */
-	mov	r1, r0
-	lsr	r1, r1, #4
-	cmp	r1, #0
-	ASM_ASSERT(eq)
-#endif
-
-	/*
-	 * Given `idx` calculate address of ldcopr16/bx lr instruction pair
-	 * in the table below.
-	 */
-	adr	r1, 1f
-	lsl	r0, r0, #3	/* each stcopr16/bx lr sequence is 8 bytes */
-	add	r1, r1, r0
-	bx	r1
-
-1:
-	stcopr16	r2, r3, AMEVCNTR10	/* index 0 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR11	/* index 1 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR12	/* index 2 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR13	/* index 3 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR14	/* index 4 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR15	/* index 5 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR16	/* index 6 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR17	/* index 7 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR18	/* index 8 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR19	/* index 9 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR1A	/* index 10 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR1B	/* index 11 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR1C	/* index 12 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR1D	/* index 13 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR1E	/* index 14 */
-	bx		lr
-	stcopr16	r2, r3, AMEVCNTR1F	/* index 15 */
-	bx		lr
-endfunc amu_group1_cnt_write_internal
-
-/*
- * void amu_group1_set_evtype_internal(int idx, unsigned int val);
- *
- * Program the AMU event type register indexed by `idx`
- * with the value `val`.
- */
-func amu_group1_set_evtype_internal
-#if ENABLE_ASSERTIONS
-	/* `idx` should be between [0, 15] */
-	mov	r2, r0
-	lsr	r2, r2, #4
-	cmp	r2, #0
-	ASM_ASSERT(eq)
-
-	/* val should be between [0, 65535] */
-	mov	r2, r1
-	lsr	r2, r2, #16
-	cmp	r2, #0
-	ASM_ASSERT(eq)
-#endif
-
-	/*
-	 * Given `idx` calculate address of stcopr/bx lr instruction pair
-	 * in the table below.
-	 */
-	adr	r2, 1f
-	lsl	r0, r0, #3	/* each stcopr/bx lr sequence is 8 bytes */
-	add	r2, r2, r0
-	bx	r2
-
-1:
-	stcopr	r1, AMEVTYPER10 /* index 0 */
-	bx	lr
-	stcopr	r1, AMEVTYPER11 /* index 1 */
-	bx	lr
-	stcopr	r1, AMEVTYPER12 /* index 2 */
-	bx	lr
-	stcopr	r1, AMEVTYPER13 /* index 3 */
-	bx	lr
-	stcopr	r1, AMEVTYPER14 /* index 4 */
-	bx	lr
-	stcopr	r1, AMEVTYPER15 /* index 5 */
-	bx	lr
-	stcopr	r1, AMEVTYPER16 /* index 6 */
-	bx	lr
-	stcopr	r1, AMEVTYPER17 /* index 7 */
-	bx	lr
-	stcopr	r1, AMEVTYPER18 /* index 8 */
-	bx	lr
-	stcopr	r1, AMEVTYPER19 /* index 9 */
-	bx	lr
-	stcopr	r1, AMEVTYPER1A /* index 10 */
-	bx	lr
-	stcopr	r1, AMEVTYPER1B /* index 11 */
-	bx	lr
-	stcopr	r1, AMEVTYPER1C /* index 12 */
-	bx	lr
-	stcopr	r1, AMEVTYPER1D /* index 13 */
-	bx	lr
-	stcopr	r1, AMEVTYPER1E /* index 14 */
-	bx	lr
-	stcopr	r1, AMEVTYPER1F /* index 15 */
-	bx	lr
-endfunc amu_group1_set_evtype_internal
-#endif
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
index cb9a0f2..5f23c07 100644
--- a/lib/extensions/amu/aarch64/amu.c
+++ b/lib/extensions/amu/aarch64/amu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,183 +10,37 @@
 #include <stdbool.h>
 #include <stdint.h>
 
-#include "../amu_private.h"
 #include <arch.h>
 #include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/el3_runtime/pubsub_events.h>
 #include <lib/extensions/amu.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
 
-#include <plat/common/platform.h>
+amu_regs_t amu_ctx[PLATFORM_CORE_COUNT];
 
-#if ENABLE_AMU_FCONF
-#	include <lib/fconf/fconf.h>
-#	include <lib/fconf/fconf_amu_getter.h>
-#endif
-
-#if ENABLE_MPMM
-#	include <lib/mpmm/mpmm.h>
-#endif
-
-struct amu_ctx {
-	uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS];
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	uint64_t group1_cnts[AMU_GROUP1_MAX_COUNTERS];
-#endif
-
-	/* Architected event counter 1 does not have an offset register */
-	uint64_t group0_voffsets[AMU_GROUP0_MAX_COUNTERS - 1U];
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	uint64_t group1_voffsets[AMU_GROUP1_MAX_COUNTERS];
-#endif
-
-	uint16_t group0_enable;
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	uint16_t group1_enable;
-#endif
-};
-
-static struct amu_ctx amu_ctxs_[PLATFORM_CORE_COUNT];
-
-CASSERT((sizeof(amu_ctxs_[0].group0_enable) * CHAR_BIT) <= AMU_GROUP0_MAX_COUNTERS,
-	amu_ctx_group0_enable_cannot_represent_all_group0_counters);
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-CASSERT((sizeof(amu_ctxs_[0].group1_enable) * CHAR_BIT) <= AMU_GROUP1_MAX_COUNTERS,
-	amu_ctx_group1_enable_cannot_represent_all_group1_counters);
-#endif
-
-static inline __unused uint64_t read_hcr_el2_amvoffen(void)
-{
-	return (read_hcr_el2() & HCR_AMVOFFEN_BIT) >>
-		HCR_AMVOFFEN_SHIFT;
-}
-
-static inline __unused void write_cptr_el2_tam(uint64_t value)
-{
-	write_cptr_el2((read_cptr_el2() & ~CPTR_EL2_TAM_BIT) |
-		((value << CPTR_EL2_TAM_SHIFT) & CPTR_EL2_TAM_BIT));
-}
-
-static inline __unused void ctx_write_scr_el3_amvoffen(cpu_context_t *ctx, uint64_t amvoffen)
-{
-	uint64_t value = read_ctx_reg(get_el3state_ctx(ctx), CTX_SCR_EL3);
-
-	value &= ~SCR_AMVOFFEN_BIT;
-	value |= (amvoffen << SCR_AMVOFFEN_SHIFT) & SCR_AMVOFFEN_BIT;
-
-	write_ctx_reg(get_el3state_ctx(ctx), CTX_SCR_EL3, value);
-}
-
-static inline __unused void write_hcr_el2_amvoffen(uint64_t value)
-{
-	write_hcr_el2((read_hcr_el2() & ~HCR_AMVOFFEN_BIT) |
-		((value << HCR_AMVOFFEN_SHIFT) & HCR_AMVOFFEN_BIT));
-}
-
-static inline __unused void write_amcr_el0_cg1rz(uint64_t value)
-{
-	write_amcr_el0((read_amcr_el0() & ~AMCR_CG1RZ_BIT) |
-		((value << AMCR_CG1RZ_SHIFT) & AMCR_CG1RZ_BIT));
-}
-
-static inline __unused uint64_t read_amcfgr_el0_ncg(void)
-{
-	return (read_amcfgr_el0() >> AMCFGR_EL0_NCG_SHIFT) &
-		AMCFGR_EL0_NCG_MASK;
-}
-
-static inline __unused uint64_t read_amcgcr_el0_cg0nc(void)
-{
-	return (read_amcgcr_el0() >> AMCGCR_EL0_CG0NC_SHIFT) &
-		AMCGCR_EL0_CG0NC_MASK;
-}
-
-static inline __unused uint64_t read_amcg1idr_el0_voff(void)
-{
-	return (read_amcg1idr_el0() >> AMCG1IDR_VOFF_SHIFT) &
-		AMCG1IDR_VOFF_MASK;
-}
-
-static inline __unused uint64_t read_amcgcr_el0_cg1nc(void)
+static inline uint8_t read_amcgcr_el0_cg1nc(void)
 {
 	return (read_amcgcr_el0() >> AMCGCR_EL0_CG1NC_SHIFT) &
 		AMCGCR_EL0_CG1NC_MASK;
 }
 
-static inline __unused uint64_t read_amcntenset0_el0_px(void)
-{
-	return (read_amcntenset0_el0() >> AMCNTENSET0_EL0_Pn_SHIFT) &
-		AMCNTENSET0_EL0_Pn_MASK;
-}
-
-static inline __unused uint64_t read_amcntenset1_el0_px(void)
-{
-	return (read_amcntenset1_el0() >> AMCNTENSET1_EL0_Pn_SHIFT) &
-		AMCNTENSET1_EL0_Pn_MASK;
-}
-
-static inline __unused void write_amcntenset0_el0_px(uint64_t px)
-{
-	uint64_t value = read_amcntenset0_el0();
-
-	value &= ~AMCNTENSET0_EL0_Pn_MASK;
-	value |= (px << AMCNTENSET0_EL0_Pn_SHIFT) & AMCNTENSET0_EL0_Pn_MASK;
-
-	write_amcntenset0_el0(value);
-}
-
-static inline __unused void write_amcntenset1_el0_px(uint64_t px)
-{
-	uint64_t value = read_amcntenset1_el0();
-
-	value &= ~AMCNTENSET1_EL0_Pn_MASK;
-	value |= (px << AMCNTENSET1_EL0_Pn_SHIFT) & AMCNTENSET1_EL0_Pn_MASK;
-
-	write_amcntenset1_el0(value);
-}
-
-static inline __unused void write_amcntenclr0_el0_px(uint64_t px)
-{
-	uint64_t value = read_amcntenclr0_el0();
-
-	value &= ~AMCNTENCLR0_EL0_Pn_MASK;
-	value |= (px << AMCNTENCLR0_EL0_Pn_SHIFT) & AMCNTENCLR0_EL0_Pn_MASK;
-
-	write_amcntenclr0_el0(value);
-}
-
-static inline __unused void write_amcntenclr1_el0_px(uint64_t px)
-{
-	uint64_t value = read_amcntenclr1_el0();
-
-	value &= ~AMCNTENCLR1_EL0_Pn_MASK;
-	value |= (px << AMCNTENCLR1_EL0_Pn_SHIFT) & AMCNTENCLR1_EL0_Pn_MASK;
-
-	write_amcntenclr1_el0(value);
-}
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-static __unused bool amu_group1_supported(void)
-{
-	return read_amcfgr_el0_ncg() > 0U;
-}
-#endif
-
-/*
- * Enable counters. This function is meant to be invoked by the context
- * management library before exiting from EL3.
- */
 void amu_enable(cpu_context_t *ctx)
 {
 	/* Initialize FEAT_AMUv1p1 features if present. */
 	if (is_feat_amuv1p1_supported()) {
+		el3_state_t *state = get_el3state_ctx(ctx);
+		u_register_t reg;
+
 		/*
 		 * Set SCR_EL3.AMVOFFEN to one so that accesses to virtual
 		 * offset registers at EL2 do not trap to EL3
 		 */
-		ctx_write_scr_el3_amvoffen(ctx, 1U);
+		reg = read_ctx_reg(state, CTX_SCR_EL3);
+		reg |= SCR_AMVOFFEN_BIT;
+		write_ctx_reg(state, CTX_SCR_EL3, reg);
 	}
 }
 
@@ -202,46 +56,18 @@
 	per_world_ctx->ctx_cptr_el3 = cptr_el3;
 }
 
-void amu_init_el3(void)
+void amu_init_el3(unsigned int core_pos)
 {
-	uint64_t group0_impl_ctr = read_amcgcr_el0_cg0nc();
-	uint64_t group0_en_mask = (1 << (group0_impl_ctr)) - 1U;
-	uint64_t num_ctr_groups = read_amcfgr_el0_ncg();
+	/* architecture is currently pinned to 4 */
+	assert((read_amcgcr_el0() & AMCGCR_EL0_CG0NC_MASK) == CTX_AMU_GRP0_ALL);
 
 	/* Enable all architected counters by default */
-	write_amcntenset0_el0_px(group0_en_mask);
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	if (num_ctr_groups > 0U) {
-		uint64_t amcntenset1_el0_px = 0x0; /* Group 1 enable mask */
-		const struct amu_topology *topology;
-
-		/*
-		 * The platform may opt to enable specific auxiliary counters.
-		 * This can be done via the common FCONF getter, or via the
-		 * platform-implemented function.
-		 */
-#if ENABLE_AMU_FCONF
-		topology = FCONF_GET_PROPERTY(amu, config, topology);
-#else
-		topology = plat_amu_topology();
-#endif /* ENABLE_AMU_FCONF */
-
-		if (topology != NULL) {
-			unsigned int core_pos = plat_my_core_pos();
-
-			amcntenset1_el0_px = topology->cores[core_pos].enable;
-		} else {
-			ERROR("AMU: failed to generate AMU topology\n");
-		}
-
-		write_amcntenset1_el0_px(amcntenset1_el0_px);
-	}
-#else /* ENABLE_AMU_AUXILIARY_COUNTERS */
-	if (num_ctr_groups > 0U) {
-		VERBOSE("AMU: auxiliary counters detected but support is disabled\n");
+	write_amcntenset0_el0(AMCNTENSET0_EL0_Pn_MASK);
+	if (is_feat_amu_aux_supported()) {
+		/* something went wrong if we're trying to write higher bits */
+		assert((get_amu_aux_enables(core_pos) & ~AMCNTENSET1_EL0_Pn_MASK) == 0);
+		write_amcntenset1_el0(get_amu_aux_enables(core_pos));
 	}
-#endif /* ENABLE_AMU_AUXILIARY_COUNTERS */
 
 	if (is_feat_amuv1p1_supported()) {
 #if AMU_RESTRICT_COUNTERS
@@ -253,15 +79,12 @@
 		 * zero. Reads from the memory mapped view are unaffected.
 		 */
 		VERBOSE("AMU group 1 counter access restricted.\n");
-		write_amcr_el0_cg1rz(1U);
+		write_amcr_el0(AMCR_CG1RZ_BIT);
 #else
-		write_amcr_el0_cg1rz(0U);
+		/* HDBG = 0 in both cases */
+		write_amcr_el0(0);
 #endif
 	}
-
-#if ENABLE_MPMM
-	mpmm_enable();
-#endif
 }
 
 void amu_init_el2_unused(void)
@@ -270,230 +93,93 @@
 	 * CPTR_EL2.TAM: Set to zero so any accesses to the Activity Monitor
 	 *  registers do not trap to EL2.
 	 */
-	write_cptr_el2_tam(0U);
+	write_cptr_el2(read_cptr_el2() & ~CPTR_EL2_TAM_BIT);
 
-	/* Initialize FEAT_AMUv1p1 features if present. */
 	if (is_feat_amuv1p1_supported()) {
-		/* Make sure virtual offsets are disabled if EL2 not used. */
-		write_hcr_el2_amvoffen(0U);
+		/* Make sure virtual offsets are disabled */
+		write_hcr_el2(read_hcr_el2() & ~HCR_AMVOFFEN_BIT);
 	}
 }
 
-/* Read the group 0 counter identified by the given `idx`. */
-static uint64_t amu_group0_cnt_read(unsigned int idx)
-{
-	assert(is_feat_amu_supported());
-	assert(idx < read_amcgcr_el0_cg0nc());
-
-	return amu_group0_cnt_read_internal(idx);
-}
-
-/* Write the group 0 counter identified by the given `idx` with `val` */
-static void amu_group0_cnt_write(unsigned  int idx, uint64_t val)
-{
-	assert(is_feat_amu_supported());
-	assert(idx < read_amcgcr_el0_cg0nc());
-
-	amu_group0_cnt_write_internal(idx, val);
-	isb();
-}
-
-/*
- * Unlike with auxiliary counters, we cannot detect at runtime whether an
- * architected counter supports a virtual offset. These are instead fixed
- * according to FEAT_AMUv1p1, but this switch will need to be updated if later
- * revisions of FEAT_AMU add additional architected counters.
- */
-static bool amu_group0_voffset_supported(uint64_t idx)
-{
-	switch (idx) {
-	case 0U:
-	case 2U:
-	case 3U:
-		return true;
-
-	case 1U:
-		return false;
-
-	default:
-		ERROR("AMU: can't set up virtual offset for unknown "
-		      "architected counter %" PRIu64 "!\n", idx);
-
-		panic();
-	}
-}
-
-/*
- * Read the group 0 offset register for a given index. Index must be 0, 2,
- * or 3, the register for 1 does not exist.
- *
- * Using this function requires FEAT_AMUv1p1 support.
- */
-static uint64_t amu_group0_voffset_read(unsigned int idx)
-{
-	assert(is_feat_amuv1p1_supported());
-	assert(idx < read_amcgcr_el0_cg0nc());
-	assert(idx != 1U);
-
-	return amu_group0_voffset_read_internal(idx);
-}
-
-/*
- * Write the group 0 offset register for a given index. Index must be 0, 2, or
- * 3, the register for 1 does not exist.
- *
- * Using this function requires FEAT_AMUv1p1 support.
- */
-static void amu_group0_voffset_write(unsigned int idx, uint64_t val)
-{
-	assert(is_feat_amuv1p1_supported());
-	assert(idx < read_amcgcr_el0_cg0nc());
-	assert(idx != 1U);
-
-	amu_group0_voffset_write_internal(idx, val);
-	isb();
-}
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-/* Read the group 1 counter identified by the given `idx` */
-static uint64_t amu_group1_cnt_read(unsigned int idx)
-{
-	assert(is_feat_amu_supported());
-	assert(amu_group1_supported());
-	assert(idx < read_amcgcr_el0_cg1nc());
-
-	return amu_group1_cnt_read_internal(idx);
-}
-
-/* Write the group 1 counter identified by the given `idx` with `val` */
-static void amu_group1_cnt_write(unsigned int idx, uint64_t val)
-{
-	assert(is_feat_amu_supported());
-	assert(amu_group1_supported());
-	assert(idx < read_amcgcr_el0_cg1nc());
-
-	amu_group1_cnt_write_internal(idx, val);
-	isb();
-}
-
-/*
- * Read the group 1 offset register for a given index.
- *
- * Using this function requires FEAT_AMUv1p1 support.
- */
-static uint64_t amu_group1_voffset_read(unsigned int idx)
-{
-	assert(is_feat_amuv1p1_supported());
-	assert(amu_group1_supported());
-	assert(idx < read_amcgcr_el0_cg1nc());
-	assert((read_amcg1idr_el0_voff() & (UINT64_C(1) << idx)) != 0U);
-
-	return amu_group1_voffset_read_internal(idx);
-}
-
-/*
- * Write the group 1 offset register for a given index.
- *
- * Using this function requires FEAT_AMUv1p1 support.
- */
-static void amu_group1_voffset_write(unsigned int idx, uint64_t val)
-{
-	assert(is_feat_amuv1p1_supported());
-	assert(amu_group1_supported());
-	assert(idx < read_amcgcr_el0_cg1nc());
-	assert((read_amcg1idr_el0_voff() & (UINT64_C(1) << idx)) != 0U);
-
-	amu_group1_voffset_write_internal(idx, val);
-	isb();
-}
-#endif
-
 static void *amu_context_save(const void *arg)
 {
-	uint64_t i, j;
-
-	unsigned int core_pos;
-	struct amu_ctx *ctx;
-
-	uint64_t hcr_el2_amvoffen = 0;	/* AMU virtual offsets enabled */
-	uint64_t amcgcr_el0_cg0nc;	/* Number of group 0 counters */
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	uint64_t amcg1idr_el0_voff;	/* Auxiliary counters with virtual offsets */
-	uint64_t amcfgr_el0_ncg;	/* Number of counter groups */
-	uint64_t amcgcr_el0_cg1nc;	/* Number of group 1 counters */
-#endif
-
 	if (!is_feat_amu_supported()) {
 		return (void *)0;
 	}
-
-	core_pos = plat_my_core_pos();
-	ctx = &amu_ctxs_[core_pos];
-
-	amcgcr_el0_cg0nc = read_amcgcr_el0_cg0nc();
-	if (is_feat_amuv1p1_supported()) {
-		hcr_el2_amvoffen = read_hcr_el2_amvoffen();
-	}
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	amcfgr_el0_ncg = read_amcfgr_el0_ncg();
-	amcgcr_el0_cg1nc = (amcfgr_el0_ncg > 0U) ? read_amcgcr_el0_cg1nc() : 0U;
-	amcg1idr_el0_voff = (hcr_el2_amvoffen != 0U) ? read_amcg1idr_el0_voff() : 0U;
-#endif
-
-	/*
-	 * Disable all AMU counters.
-	 */
-
-	ctx->group0_enable = read_amcntenset0_el0_px();
-	write_amcntenclr0_el0_px(ctx->group0_enable);
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	if (amcfgr_el0_ncg > 0U) {
-		ctx->group1_enable = read_amcntenset1_el0_px();
-		write_amcntenclr1_el0_px(ctx->group1_enable);
-	}
-#endif
 
-	/*
-	 * Save the counters to the local context.
-	 */
+	unsigned int core_pos = *(unsigned int *)arg;
+	amu_regs_t *ctx = &amu_ctx[core_pos];
 
-	isb(); /* Ensure counters have been stopped */
-
-	for (i = 0U; i < amcgcr_el0_cg0nc; i++) {
-		ctx->group0_cnts[i] = amu_group0_cnt_read(i);
-	}
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	for (i = 0U; i < amcgcr_el0_cg1nc; i++) {
-		ctx->group1_cnts[i] = amu_group1_cnt_read(i);
+	/* disable all counters so we can write them safely later */
+	write_amcntenclr0_el0(AMCNTENCLR0_EL0_Pn_MASK);
+	if (is_feat_amu_aux_supported()) {
+		write_amcntenclr1_el0(get_amu_aux_enables(core_pos));
 	}
-#endif
 
-	/*
-	 * Save virtual offsets for counters that offer them.
-	 */
-
-	if (hcr_el2_amvoffen != 0U) {
-		for (i = 0U, j = 0U; i < amcgcr_el0_cg0nc; i++) {
-			if (!amu_group0_voffset_supported(i)) {
-				continue; /* No virtual offset */
-			}
+	isb();
 
-			ctx->group0_voffsets[j++] = amu_group0_voffset_read(i);
-		}
+	write_amu_grp0_ctx_reg(ctx, 0, read_amevcntr00_el0());
+	write_amu_grp0_ctx_reg(ctx, 1, read_amevcntr01_el0());
+	write_amu_grp0_ctx_reg(ctx, 2, read_amevcntr02_el0());
+	write_amu_grp0_ctx_reg(ctx, 3, read_amevcntr03_el0());
 
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-		for (i = 0U, j = 0U; i < amcgcr_el0_cg1nc; i++) {
-			if ((amcg1idr_el0_voff >> i) & 1U) {
-				continue; /* No virtual offset */
-			}
+	if (is_feat_amu_aux_supported()) {
+		uint8_t num_counters = read_amcgcr_el0_cg1nc();
 
-			ctx->group1_voffsets[j++] = amu_group1_voffset_read(i);
+		switch (num_counters) {
+		case 0x10:
+			write_amu_grp1_ctx_reg(ctx, 0xf, read_amevcntr1f_el0());
+			__fallthrough;
+		case 0x0f:
+			write_amu_grp1_ctx_reg(ctx, 0xe, read_amevcntr1e_el0());
+			__fallthrough;
+		case 0x0e:
+			write_amu_grp1_ctx_reg(ctx, 0xd, read_amevcntr1d_el0());
+			__fallthrough;
+		case 0x0d:
+			write_amu_grp1_ctx_reg(ctx, 0xc, read_amevcntr1c_el0());
+			__fallthrough;
+		case 0x0c:
+			write_amu_grp1_ctx_reg(ctx, 0xb, read_amevcntr1b_el0());
+			__fallthrough;
+		case 0x0b:
+			write_amu_grp1_ctx_reg(ctx, 0xa, read_amevcntr1a_el0());
+			__fallthrough;
+		case 0x0a:
+			write_amu_grp1_ctx_reg(ctx, 0x9, read_amevcntr19_el0());
+			__fallthrough;
+		case 0x09:
+			write_amu_grp1_ctx_reg(ctx, 0x8, read_amevcntr18_el0());
+			__fallthrough;
+		case 0x08:
+			write_amu_grp1_ctx_reg(ctx, 0x7, read_amevcntr17_el0());
+			__fallthrough;
+		case 0x07:
+			write_amu_grp1_ctx_reg(ctx, 0x6, read_amevcntr16_el0());
+			__fallthrough;
+		case 0x06:
+			write_amu_grp1_ctx_reg(ctx, 0x5, read_amevcntr15_el0());
+			__fallthrough;
+		case 0x05:
+			write_amu_grp1_ctx_reg(ctx, 0x4, read_amevcntr14_el0());
+			__fallthrough;
+		case 0x04:
+			write_amu_grp1_ctx_reg(ctx, 0x3, read_amevcntr13_el0());
+			__fallthrough;
+		case 0x03:
+			write_amu_grp1_ctx_reg(ctx, 0x2, read_amevcntr12_el0());
+			__fallthrough;
+		case 0x02:
+			write_amu_grp1_ctx_reg(ctx, 0x1, read_amevcntr11_el0());
+			__fallthrough;
+		case 0x01:
+			write_amu_grp1_ctx_reg(ctx, 0x0, read_amevcntr10_el0());
+			__fallthrough;
+		case 0x00:
+			break;
+		default:
+			assert(0); /* something is wrong */
 		}
-#endif
 	}
 
 	return (void *)0;
@@ -501,94 +187,85 @@
 
 static void *amu_context_restore(const void *arg)
 {
-	uint64_t i, j;
-
-	unsigned int core_pos;
-	struct amu_ctx *ctx;
-
-	uint64_t hcr_el2_amvoffen = 0;	/* AMU virtual offsets enabled */
-
-	uint64_t amcgcr_el0_cg0nc;	/* Number of group 0 counters */
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	uint64_t amcfgr_el0_ncg;	/* Number of counter groups */
-	uint64_t amcgcr_el0_cg1nc;	/* Number of group 1 counters */
-	uint64_t amcg1idr_el0_voff;	/* Auxiliary counters with virtual offsets */
-#endif
-
 	if (!is_feat_amu_supported()) {
 		return (void *)0;
 	}
 
-	core_pos = plat_my_core_pos();
-	ctx = &amu_ctxs_[core_pos];
-
-	amcgcr_el0_cg0nc = read_amcgcr_el0_cg0nc();
-
-	if (is_feat_amuv1p1_supported()) {
-		hcr_el2_amvoffen = read_hcr_el2_amvoffen();
-	}
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	amcfgr_el0_ncg = read_amcfgr_el0_ncg();
-	amcgcr_el0_cg1nc = (amcfgr_el0_ncg > 0U) ? read_amcgcr_el0_cg1nc() : 0U;
-	amcg1idr_el0_voff = (hcr_el2_amvoffen != 0U) ? read_amcg1idr_el0_voff() : 0U;
-#endif
+	unsigned int core_pos = *(unsigned int *)arg;
+	amu_regs_t *ctx = &amu_ctx[core_pos];
 
-	/*
-	 * Restore the counter values from the local context.
-	 */
+	write_amevcntr00_el0(read_amu_grp0_ctx_reg(ctx, 0));
+	write_amevcntr01_el0(read_amu_grp0_ctx_reg(ctx, 1));
+	write_amevcntr02_el0(read_amu_grp0_ctx_reg(ctx, 2));
+	write_amevcntr03_el0(read_amu_grp0_ctx_reg(ctx, 3));
 
-	for (i = 0U; i < amcgcr_el0_cg0nc; i++) {
-		amu_group0_cnt_write(i, ctx->group0_cnts[i]);
-	}
+	if (is_feat_amu_aux_supported()) {
+		uint8_t num_counters = read_amcgcr_el0_cg1nc();
 
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	for (i = 0U; i < amcgcr_el0_cg1nc; i++) {
-		amu_group1_cnt_write(i, ctx->group1_cnts[i]);
-	}
-#endif
-
-	/*
-	 * Restore virtual offsets for counters that offer them.
-	 */
-
-	if (hcr_el2_amvoffen != 0U) {
-		for (i = 0U, j = 0U; i < amcgcr_el0_cg0nc; i++) {
-			if (!amu_group0_voffset_supported(i)) {
-				continue; /* No virtual offset */
-			}
-
-			amu_group0_voffset_write(i, ctx->group0_voffsets[j++]);
-		}
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-		for (i = 0U, j = 0U; i < amcgcr_el0_cg1nc; i++) {
-			if ((amcg1idr_el0_voff >> i) & 1U) {
-				continue; /* No virtual offset */
-			}
-
-			amu_group1_voffset_write(i, ctx->group1_voffsets[j++]);
+		switch (num_counters) {
+		case 0x10:
+			write_amevcntr1f_el0(read_amu_grp1_ctx_reg(ctx, 0xf));
+			__fallthrough;
+		case 0x0f:
+			write_amevcntr1e_el0(read_amu_grp1_ctx_reg(ctx, 0xe));
+			__fallthrough;
+		case 0x0e:
+			write_amevcntr1d_el0(read_amu_grp1_ctx_reg(ctx, 0xd));
+			__fallthrough;
+		case 0x0d:
+			write_amevcntr1c_el0(read_amu_grp1_ctx_reg(ctx, 0xc));
+			__fallthrough;
+		case 0x0c:
+			write_amevcntr1b_el0(read_amu_grp1_ctx_reg(ctx, 0xb));
+			__fallthrough;
+		case 0x0b:
+			write_amevcntr1a_el0(read_amu_grp1_ctx_reg(ctx, 0xa));
+			__fallthrough;
+		case 0x0a:
+			write_amevcntr19_el0(read_amu_grp1_ctx_reg(ctx, 0x9));
+			__fallthrough;
+		case 0x09:
+			write_amevcntr18_el0(read_amu_grp1_ctx_reg(ctx, 0x8));
+			__fallthrough;
+		case 0x08:
+			write_amevcntr17_el0(read_amu_grp1_ctx_reg(ctx, 0x7));
+			__fallthrough;
+		case 0x07:
+			write_amevcntr16_el0(read_amu_grp1_ctx_reg(ctx, 0x6));
+			__fallthrough;
+		case 0x06:
+			write_amevcntr15_el0(read_amu_grp1_ctx_reg(ctx, 0x5));
+			__fallthrough;
+		case 0x05:
+			write_amevcntr14_el0(read_amu_grp1_ctx_reg(ctx, 0x4));
+			__fallthrough;
+		case 0x04:
+			write_amevcntr13_el0(read_amu_grp1_ctx_reg(ctx, 0x3));
+			__fallthrough;
+		case 0x03:
+			write_amevcntr12_el0(read_amu_grp1_ctx_reg(ctx, 0x2));
+			__fallthrough;
+		case 0x02:
+			write_amevcntr11_el0(read_amu_grp1_ctx_reg(ctx, 0x1));
+			__fallthrough;
+		case 0x01:
+			write_amevcntr10_el0(read_amu_grp1_ctx_reg(ctx, 0x0));
+			__fallthrough;
+		case 0x00:
+			break;
+		default:
+			assert(0); /* something is wrong */
 		}
-#endif
 	}
 
-	/*
-	 * Re-enable counters that were disabled during context save.
-	 */
-
-	write_amcntenset0_el0_px(ctx->group0_enable);
 
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-	if (amcfgr_el0_ncg > 0) {
-		write_amcntenset1_el0_px(ctx->group1_enable);
+	/* now enable them again */
+	write_amcntenset0_el0(AMCNTENSET0_EL0_Pn_MASK);
+	if (is_feat_amu_aux_supported()) {
+		write_amcntenset1_el0(get_amu_aux_enables(core_pos));
 	}
-#endif
 
-#if ENABLE_MPMM
-	mpmm_enable();
-#endif
-
+	isb();
 	return (void *)0;
 }
 
diff --git a/lib/extensions/amu/aarch64/amu_helpers.S b/lib/extensions/amu/aarch64/amu_helpers.S
deleted file mode 100644
index 95d4ad6..0000000
--- a/lib/extensions/amu/aarch64/amu_helpers.S
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <assert_macros.S>
-#include <asm_macros.S>
-
-	.globl	amu_group0_cnt_read_internal
-	.globl	amu_group0_cnt_write_internal
-	.globl	amu_group1_cnt_read_internal
-	.globl	amu_group1_cnt_write_internal
-	.globl	amu_group1_set_evtype_internal
-
-	/* FEAT_AMUv1p1 virtualisation offset register functions */
-	.globl	amu_group0_voffset_read_internal
-	.globl	amu_group0_voffset_write_internal
-	.globl	amu_group1_voffset_read_internal
-	.globl	amu_group1_voffset_write_internal
-
-/*
- * uint64_t amu_group0_cnt_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU counter
- * and return it in `x0`.
- */
-func amu_group0_cnt_read_internal
-	adr	x1, 1f
-#if ENABLE_ASSERTIONS
-	/*
-	 * It can be dangerous to call this function with an
-	 * out of bounds index.  Ensure `idx` is valid.
-	 */
-	tst	x0, #~3
-	ASM_ASSERT(eq)
-#endif
-	/*
-	 * Given `idx` calculate address of mrs/ret instruction pair
-	 * in the table below.
-	 */
-	add	x1, x1, x0, lsl #3	/* each mrs/ret sequence is 8 bytes */
-#if ENABLE_BTI
-	add	x1, x1, x0, lsl #2	/* + "bti j" instruction */
-#endif
-	br	x1
-
-1:	read	AMEVCNTR00_EL0		/* index 0 */
-	read	AMEVCNTR01_EL0		/* index 1 */
-	read	AMEVCNTR02_EL0		/* index 2 */
-	read	AMEVCNTR03_EL0		/* index 3 */
-endfunc amu_group0_cnt_read_internal
-
-/*
- * void amu_group0_cnt_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU counter.
- */
-func amu_group0_cnt_write_internal
-	adr	x2, 1f
-#if ENABLE_ASSERTIONS
-	/*
-	 * It can be dangerous to call this function with an
-	 * out of bounds index.  Ensure `idx` is valid.
-	 */
-	tst	x0, #~3
-	ASM_ASSERT(eq)
-#endif
-	/*
-	 * Given `idx` calculate address of mrs/ret instruction pair
-	 * in the table below.
-	 */
-	add	x2, x2, x0, lsl #3	/* each msr/ret sequence is 8 bytes */
-#if ENABLE_BTI
-	add	x2, x2, x0, lsl #2	/* + "bti j" instruction */
-#endif
-	br	x2
-
-1:	write	AMEVCNTR00_EL0		/* index 0 */
-	write	AMEVCNTR01_EL0		/* index 1 */
-	write	AMEVCNTR02_EL0		/* index 2 */
-	write	AMEVCNTR03_EL0		/* index 3 */
-endfunc amu_group0_cnt_write_internal
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-/*
- * uint64_t amu_group1_cnt_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU counter
- * and return it in `x0`.
- */
-func amu_group1_cnt_read_internal
-	adr	x1, 1f
-#if ENABLE_ASSERTIONS
-	/*
-	 * It can be dangerous to call this function with an
-	 * out of bounds index.  Ensure `idx` is valid.
-	 */
-	tst	x0, #~0xF
-	ASM_ASSERT(eq)
-#endif
-	/*
-	 * Given `idx` calculate address of mrs/ret instruction pair
-	 * in the table below.
-	 */
-	add	x1, x1, x0, lsl #3	/* each mrs/ret sequence is 8 bytes */
-#if ENABLE_BTI
-	add	x1, x1, x0, lsl #2	/* + "bti j" instruction */
-#endif
-	br	x1
-
-1:	read	AMEVCNTR10_EL0		/* index 0 */
-	read	AMEVCNTR11_EL0		/* index 1 */
-	read	AMEVCNTR12_EL0		/* index 2 */
-	read	AMEVCNTR13_EL0		/* index 3 */
-	read	AMEVCNTR14_EL0		/* index 4 */
-	read	AMEVCNTR15_EL0		/* index 5 */
-	read	AMEVCNTR16_EL0		/* index 6 */
-	read	AMEVCNTR17_EL0		/* index 7 */
-	read	AMEVCNTR18_EL0		/* index 8 */
-	read	AMEVCNTR19_EL0		/* index 9 */
-	read	AMEVCNTR1A_EL0		/* index 10 */
-	read	AMEVCNTR1B_EL0		/* index 11 */
-	read	AMEVCNTR1C_EL0		/* index 12 */
-	read	AMEVCNTR1D_EL0		/* index 13 */
-	read	AMEVCNTR1E_EL0		/* index 14 */
-	read	AMEVCNTR1F_EL0		/* index 15 */
-endfunc amu_group1_cnt_read_internal
-
-/*
- * void amu_group1_cnt_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU counter.
- */
-func amu_group1_cnt_write_internal
-	adr	x2, 1f
-#if ENABLE_ASSERTIONS
-	/*
-	 * It can be dangerous to call this function with an
-	 * out of bounds index.  Ensure `idx` is valid.
-	 */
-	tst	x0, #~0xF
-	ASM_ASSERT(eq)
-#endif
-	/*
-	 * Given `idx` calculate address of mrs/ret instruction pair
-	 * in the table below.
-	 */
-	add	x2, x2, x0, lsl #3	/* each msr/ret sequence is 8 bytes */
-#if ENABLE_BTI
-	add	x2, x2, x0, lsl #2	/* + "bti j" instruction */
-#endif
-	br	x2
-
-1:	write	AMEVCNTR10_EL0		/* index 0 */
-	write	AMEVCNTR11_EL0		/* index 1 */
-	write	AMEVCNTR12_EL0		/* index 2 */
-	write	AMEVCNTR13_EL0		/* index 3 */
-	write	AMEVCNTR14_EL0		/* index 4 */
-	write	AMEVCNTR15_EL0		/* index 5 */
-	write	AMEVCNTR16_EL0		/* index 6 */
-	write	AMEVCNTR17_EL0		/* index 7 */
-	write	AMEVCNTR18_EL0		/* index 8 */
-	write	AMEVCNTR19_EL0		/* index 9 */
-	write	AMEVCNTR1A_EL0		/* index 10 */
-	write	AMEVCNTR1B_EL0		/* index 11 */
-	write	AMEVCNTR1C_EL0		/* index 12 */
-	write	AMEVCNTR1D_EL0		/* index 13 */
-	write	AMEVCNTR1E_EL0		/* index 14 */
-	write	AMEVCNTR1F_EL0		/* index 15 */
-endfunc amu_group1_cnt_write_internal
-
-/*
- * void amu_group1_set_evtype_internal(int idx, unsigned int val);
- *
- * Program the AMU event type register indexed by `idx`
- * with the value `val`.
- */
-func amu_group1_set_evtype_internal
-	adr	x2, 1f
-#if ENABLE_ASSERTIONS
-	/*
-	 * It can be dangerous to call this function with an
-	 * out of bounds index.  Ensure `idx` is valid.
-	 */
-	tst	x0, #~0xF
-	ASM_ASSERT(eq)
-
-	/* val should be between [0, 65535] */
-	tst	x1, #~0xFFFF
-	ASM_ASSERT(eq)
-#endif
-	/*
-	 * Given `idx` calculate address of msr/ret instruction pair
-	 * in the table below.
-	 */
-	add	x2, x2, x0, lsl #3	/* each msr/ret sequence is 8 bytes */
-#if ENABLE_BTI
-	add	x2, x2, x0, lsl #2	/* + "bti j" instruction */
-#endif
-	br	x2
-
-1:	write	AMEVTYPER10_EL0		/* index 0 */
-	write	AMEVTYPER11_EL0		/* index 1 */
-	write	AMEVTYPER12_EL0		/* index 2 */
-	write	AMEVTYPER13_EL0		/* index 3 */
-	write	AMEVTYPER14_EL0		/* index 4 */
-	write	AMEVTYPER15_EL0		/* index 5 */
-	write	AMEVTYPER16_EL0		/* index 6 */
-	write	AMEVTYPER17_EL0		/* index 7 */
-	write	AMEVTYPER18_EL0		/* index 8 */
-	write	AMEVTYPER19_EL0		/* index 9 */
-	write	AMEVTYPER1A_EL0		/* index 10 */
-	write	AMEVTYPER1B_EL0		/* index 11 */
-	write	AMEVTYPER1C_EL0		/* index 12 */
-	write	AMEVTYPER1D_EL0		/* index 13 */
-	write	AMEVTYPER1E_EL0		/* index 14 */
-	write	AMEVTYPER1F_EL0		/* index 15 */
-endfunc amu_group1_set_evtype_internal
-#endif
-
-/*
- * Accessor functions for virtual offset registers added with FEAT_AMUv1p1
- */
-
-/*
- * uint64_t amu_group0_voffset_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU virtual offset register
- * and return it in `x0`.
- */
-func amu_group0_voffset_read_internal
-	adr	x1, 1f
-#if ENABLE_ASSERTIONS
-	/*
-	 * It can be dangerous to call this function with an
-	 * out of bounds index.  Ensure `idx` is valid.
-	 */
-	tst	x0, #~3
-	ASM_ASSERT(eq)
-	/* Make sure idx != 1 since AMEVCNTVOFF01_EL2 does not exist */
-	cmp	x0, #1
-	ASM_ASSERT(ne)
-#endif
-	/*
-	 * Given `idx` calculate address of mrs/ret instruction pair
-	 * in the table below.
-	 */
-	add	x1, x1, x0, lsl #3	/* each mrs/ret sequence is 8 bytes */
-#if ENABLE_BTI
-	add	x1, x1, x0, lsl #2	/* + "bti j" instruction */
-#endif
-	br	x1
-
-1:	read	AMEVCNTVOFF00_EL2	/* index 0 */
-	.skip	8			/* AMEVCNTVOFF01_EL2 does not exist */
-#if ENABLE_BTI
-	.skip	4
-#endif
-	read	AMEVCNTVOFF02_EL2	/* index 2 */
-	read	AMEVCNTVOFF03_EL2	/* index 3 */
-endfunc amu_group0_voffset_read_internal
-
-/*
- * void amu_group0_voffset_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU virtual offset register.
- */
-func amu_group0_voffset_write_internal
-	adr	x2, 1f
-#if ENABLE_ASSERTIONS
-	/*
-	 * It can be dangerous to call this function with an
-	 * out of bounds index.  Ensure `idx` is valid.
-	 */
-	tst	x0, #~3
-	ASM_ASSERT(eq)
-	/* Make sure idx != 1 since AMEVCNTVOFF01_EL2 does not exist */
-	cmp	x0, #1
-	ASM_ASSERT(ne)
-#endif
-	/*
-	 * Given `idx` calculate address of mrs/ret instruction pair
-	 * in the table below.
-	 */
-	add	x2, x2, x0, lsl #3	/* each msr/ret sequence is 8 bytes */
-#if ENABLE_BTI
-	add	x2, x2, x0, lsl #2	/* + "bti j" instruction */
-#endif
-	br	x2
-
-1:	write	AMEVCNTVOFF00_EL2	/* index 0 */
-	.skip	8			/* AMEVCNTVOFF01_EL2 does not exist */
-#if ENABLE_BTI
-	.skip	4
-#endif
-	write	AMEVCNTVOFF02_EL2	/* index 2 */
-	write	AMEVCNTVOFF03_EL2	/* index 3 */
-endfunc amu_group0_voffset_write_internal
-
-#if ENABLE_AMU_AUXILIARY_COUNTERS
-/*
- * uint64_t amu_group1_voffset_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU virtual offset register
- * and return it in `x0`.
- */
-func amu_group1_voffset_read_internal
-	adr	x1, 1f
-#if ENABLE_ASSERTIONS
-	/*
-	 * It can be dangerous to call this function with an
-	 * out of bounds index.  Ensure `idx` is valid.
-	 */
-	tst	x0, #~0xF
-	ASM_ASSERT(eq)
-#endif
-	/*
-	 * Given `idx` calculate address of mrs/ret instruction pair
-	 * in the table below.
-	 */
-	add	x1, x1, x0, lsl #3	/* each mrs/ret sequence is 8 bytes */
-#if ENABLE_BTI
-	add	x1, x1, x0, lsl #2	/* + "bti j" instruction */
-#endif
-	br	x1
-
-1:	read	AMEVCNTVOFF10_EL2	/* index 0 */
-	read	AMEVCNTVOFF11_EL2	/* index 1 */
-	read	AMEVCNTVOFF12_EL2	/* index 2 */
-	read	AMEVCNTVOFF13_EL2	/* index 3 */
-	read	AMEVCNTVOFF14_EL2	/* index 4 */
-	read	AMEVCNTVOFF15_EL2	/* index 5 */
-	read	AMEVCNTVOFF16_EL2	/* index 6 */
-	read	AMEVCNTVOFF17_EL2	/* index 7 */
-	read	AMEVCNTVOFF18_EL2	/* index 8 */
-	read	AMEVCNTVOFF19_EL2	/* index 9 */
-	read	AMEVCNTVOFF1A_EL2	/* index 10 */
-	read	AMEVCNTVOFF1B_EL2	/* index 11 */
-	read	AMEVCNTVOFF1C_EL2	/* index 12 */
-	read	AMEVCNTVOFF1D_EL2	/* index 13 */
-	read	AMEVCNTVOFF1E_EL2	/* index 14 */
-	read	AMEVCNTVOFF1F_EL2	/* index 15 */
-endfunc amu_group1_voffset_read_internal
-
-/*
- * void amu_group1_voffset_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU virtual offset register.
- */
-func amu_group1_voffset_write_internal
-	adr	x2, 1f
-#if ENABLE_ASSERTIONS
-	/*
-	 * It can be dangerous to call this function with an
-	 * out of bounds index.  Ensure `idx` is valid.
-	 */
-	tst	x0, #~0xF
-	ASM_ASSERT(eq)
-#endif
-	/*
-	 * Given `idx` calculate address of mrs/ret instruction pair
-	 * in the table below.
-	 */
-	add	x2, x2, x0, lsl #3	/* each msr/ret sequence is 8 bytes */
-#if ENABLE_BTI
-	add	x2, x2, x0, lsl #2	/* + "bti j" instruction */
-#endif
-	br	x2
-
-1:	write	AMEVCNTVOFF10_EL2	/* index 0 */
-	write	AMEVCNTVOFF11_EL2	/* index 1 */
-	write	AMEVCNTVOFF12_EL2	/* index 2 */
-	write	AMEVCNTVOFF13_EL2	/* index 3 */
-	write	AMEVCNTVOFF14_EL2	/* index 4 */
-	write	AMEVCNTVOFF15_EL2	/* index 5 */
-	write	AMEVCNTVOFF16_EL2	/* index 6 */
-	write	AMEVCNTVOFF17_EL2	/* index 7 */
-	write	AMEVCNTVOFF18_EL2	/* index 8 */
-	write	AMEVCNTVOFF19_EL2	/* index 9 */
-	write	AMEVCNTVOFF1A_EL2	/* index 10 */
-	write	AMEVCNTVOFF1B_EL2	/* index 11 */
-	write	AMEVCNTVOFF1C_EL2	/* index 12 */
-	write	AMEVCNTVOFF1D_EL2	/* index 13 */
-	write	AMEVCNTVOFF1E_EL2	/* index 14 */
-	write	AMEVCNTVOFF1F_EL2	/* index 15 */
-endfunc amu_group1_voffset_write_internal
-#endif
diff --git a/lib/extensions/amu/amu.mk b/lib/extensions/amu/amu.mk
index 868ab12..fba2c78 100644
--- a/lib/extensions/amu/amu.mk
+++ b/lib/extensions/amu/amu.mk
@@ -1,24 +1,13 @@
 #
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2025, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-include lib/fconf/fconf.mk
-
-AMU_SOURCES	:=	lib/extensions/amu/${ARCH}/amu.c \
-			lib/extensions/amu/${ARCH}/amu_helpers.S
+AMU_SOURCES	:=	lib/extensions/amu/${ARCH}/amu.c
 
 ifneq (${ENABLE_AMU_AUXILIARY_COUNTERS},0)
         ifeq (${ENABLE_FEAT_AMU},0)
-                $(error AMU auxiliary counter support (`ENABLE_AMU_AUXILIARY_COUNTERS`) requires AMU support (`ENABLE_FEAT_AMU`))
-        endif
-endif
-
-ifneq (${ENABLE_AMU_FCONF},0)
-        ifeq (${ENABLE_AMU_AUXILIARY_COUNTERS},0)
-                $(error AMU FCONF support (`ENABLE_AMU_FCONF`) is not necessary when auxiliary counter support (`ENABLE_AMU_AUXILIARY_COUNTERS`) is disabled)
+                $(error "ENABLE_AMU_AUXILIARY_COUNTERS requires ENABLE_FEAT_AMU")
         endif
-
-        AMU_SOURCES	+=	${FCONF_AMU_SOURCES}
 endif
diff --git a/lib/extensions/amu/amu_private.h b/lib/extensions/amu/amu_private.h
deleted file mode 100644
index a3b6845..0000000
--- a/lib/extensions/amu/amu_private.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef AMU_PRIVATE_H
-#define AMU_PRIVATE_H
-
-#include <stdint.h>
-
-#include <lib/cassert.h>
-#include <lib/extensions/amu.h>
-#include <lib/utils_def.h>
-
-#include <platform_def.h>
-
-#define AMU_GROUP0_MAX_COUNTERS		U(16)
-#define AMU_GROUP1_MAX_COUNTERS		U(16)
-
-#define AMU_AMCGCR_CG0NC_MAX		U(16)
-
-uint64_t amu_group0_cnt_read_internal(unsigned int idx);
-void amu_group0_cnt_write_internal(unsigned int idx, uint64_t val);
-
-uint64_t amu_group1_cnt_read_internal(unsigned int idx);
-void amu_group1_cnt_write_internal(unsigned int idx, uint64_t val);
-void amu_group1_set_evtype_internal(unsigned int idx, unsigned int val);
-
-#if __aarch64__
-uint64_t amu_group0_voffset_read_internal(unsigned int idx);
-void amu_group0_voffset_write_internal(unsigned int idx, uint64_t val);
-
-uint64_t amu_group1_voffset_read_internal(unsigned int idx);
-void amu_group1_voffset_write_internal(unsigned int idx, uint64_t val);
-#endif
-
-#endif /* AMU_PRIVATE_H */
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index 98d57e9..e477da3 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,13 +40,8 @@
 
 void sme_init_el3(void)
 {
-	u_register_t cptr_el3 = read_cptr_el3();
 	u_register_t smcr_el3;
 
-	/* Set CPTR_EL3.ESM bit so we can access SMCR_EL3 without trapping. */
-	write_cptr_el3(cptr_el3 | ESM_BIT);
-	isb();
-
 	/*
 	 * Set the max LEN value and FA64 bit. This register is set up per_world
 	 * to be the least restrictive, then lower ELs can restrict as needed
@@ -69,10 +64,6 @@
 		smcr_el3 |= SMCR_ELX_EZT0_BIT;
 	}
 	write_smcr_el3(smcr_el3);
-
-	/* Reset CPTR_EL3 value. */
-	write_cptr_el3(cptr_el3);
-	isb();
 }
 
 void sme_init_el2_unused(void)
diff --git a/lib/extensions/sve/sve.c b/lib/extensions/sve/sve.c
index 143717e..4e18cdf 100644
--- a/lib/extensions/sve/sve.c
+++ b/lib/extensions/sve/sve.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,12 @@
  */
 #define CONVERT_SVE_LENGTH(x)	(((x / 128) - 1))
 
+void sve_init_el3(void)
+{
+	/* Restrict maximum SVE vector length (SVE_VECTOR_LEN+1) * 128. */
+	write_zcr_el3(ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(SVE_VECTOR_LEN));
+}
+
 void sve_enable_per_world(per_world_context_t *per_world_ctx)
 {
 	u_register_t cptr_el3;
@@ -30,9 +36,6 @@
 	cptr_el3 = per_world_ctx->ctx_cptr_el3;
 	cptr_el3 = (cptr_el3 | CPTR_EZ_BIT) & ~(TFP_BIT);
 	per_world_ctx->ctx_cptr_el3 = cptr_el3;
-
-	/* Restrict maximum SVE vector length (SVE_VECTOR_LEN+1) * 128. */
-	per_world_ctx->ctx_zcr_el3 = (ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(SVE_VECTOR_LEN));
 }
 
 void sve_init_el2_unused(void)
diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk
index ff781aa..d24f86b 100644
--- a/lib/fconf/fconf.mk
+++ b/lib/fconf/fconf.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -11,9 +11,3 @@
 
 FCONF_DYN_SOURCES	:=	lib/fconf/fconf_dyn_cfg_getter.c
 FCONF_DYN_SOURCES	+=	${FDT_WRAPPERS_SOURCES}
-
-FCONF_AMU_SOURCES	:=	lib/fconf/fconf_amu_getter.c
-FCONF_AMU_SOURCES	+=	${FDT_WRAPPERS_SOURCES}
-
-FCONF_MPMM_SOURCES	:=	lib/fconf/fconf_mpmm_getter.c
-FCONF_MPMM_SOURCES	+=	${FDT_WRAPPERS_SOURCES}
diff --git a/lib/fconf/fconf_amu_getter.c b/lib/fconf/fconf_amu_getter.c
deleted file mode 100644
index eff309c..0000000
--- a/lib/fconf/fconf_amu_getter.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <common/debug.h>
-#include <common/fdt_wrappers.h>
-#include <lib/fconf/fconf.h>
-#include <lib/fconf/fconf_amu_getter.h>
-#include <libfdt.h>
-
-#include <plat/common/platform.h>
-
-struct fconf_amu_config fconf_amu_config;
-static struct amu_topology fconf_amu_topology_;
-
-/*
- * Populate the core-specific AMU structure with information retrieved from a
- * device tree.
- *
- * Returns `0` on success, or a negative integer representing an error code.
- */
-static int fconf_populate_amu_cpu_amu(const void *fdt, int parent,
-				      struct amu_core *amu)
-{
-	int ret = 0;
-	int node = 0;
-
-	fdt_for_each_subnode(node, fdt, parent) {
-		const char *name;
-		const char *value;
-		int len;
-
-		uintptr_t idx = 0U;
-
-		name = fdt_get_name(fdt, node, &len);
-		if (strncmp(name, "counter@", 8) != 0) {
-			continue;
-		}
-
-		ret = fdt_get_reg_props_by_index(fdt, node, 0, &idx, NULL);
-		if (ret < 0) {
-			break;
-		}
-
-		value = fdt_getprop(fdt, node, "enable-at-el3", &len);
-		if ((value == NULL) && (len != -FDT_ERR_NOTFOUND)) {
-			break;
-		}
-
-		if (len != -FDT_ERR_NOTFOUND) {
-			amu->enable |= (1 << idx);
-		}
-	}
-
-	if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) {
-		return node;
-	}
-
-	return ret;
-}
-
-/*
- * Within a `cpu` node, attempt to dereference the `amu` property, and populate
- * the AMU information for the core.
- *
- * Returns `0` on success, or a negative integer representing an error code.
- */
-static int fconf_populate_amu_cpu(const void *fdt, int node, uintptr_t mpidr)
-{
-	int ret;
-	int idx;
-
-	uint32_t amu_phandle;
-	struct amu_core *amu;
-
-	ret = fdt_read_uint32(fdt, node, "amu", &amu_phandle);
-	if (ret < 0) {
-		if (ret == -FDT_ERR_NOTFOUND) {
-			ret = 0;
-		}
-
-		return ret;
-	}
-
-	node = fdt_node_offset_by_phandle(fdt, amu_phandle);
-	if (node < 0) {
-		return node;
-	}
-
-	idx = plat_core_pos_by_mpidr(mpidr);
-	if (idx < 0) {
-		return -FDT_ERR_BADVALUE;
-	}
-
-	amu = &fconf_amu_topology_.cores[idx];
-
-	return fconf_populate_amu_cpu_amu(fdt, node, amu);
-}
-
-/*
- * Populates the global `amu_topology` structure based on what's described by
- * the hardware configuration device tree blob.
- *
- * The device tree is expected to provide an `amu` property for each `cpu` node,
- * like so:
- *
- *     cpu@0 {
- *         amu = <&cpu0_amu>;
- *     };
- *
- *     amus {
- *         cpu0_amu: amu-0 {
- *             counters {
- *                 #address-cells = <2>;
- *                 #size-cells = <0>;
- *
- *                 counter@x,y {
- *                     reg = <x y>; // Group x, counter y
- *                 };
- *             };
- *         };
- *     };
- */
-static int fconf_populate_amu(uintptr_t config)
-{
-	int ret = fdtw_for_each_cpu(
-		(const void *)config, fconf_populate_amu_cpu);
-	if (ret == 0) {
-		fconf_amu_config.topology = &fconf_amu_topology_;
-	} else {
-		ERROR("FCONF: failed to parse AMU information: %d\n", ret);
-	}
-
-	return ret;
-}
-
-FCONF_REGISTER_POPULATOR(HW_CONFIG, amu, fconf_populate_amu);
diff --git a/lib/fconf/fconf_mpmm_getter.c b/lib/fconf/fconf_mpmm_getter.c
deleted file mode 100644
index 02a566d..0000000
--- a/lib/fconf/fconf_mpmm_getter.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <common/debug.h>
-#include <common/fdt_wrappers.h>
-#include <lib/fconf/fconf.h>
-#include <lib/fconf/fconf_mpmm_getter.h>
-#include <libfdt.h>
-
-#include <plat/common/platform.h>
-
-struct fconf_mpmm_config fconf_mpmm_config;
-static struct mpmm_topology fconf_mpmm_topology;
-
-/*
- * Within a `cpu` node, determine support for MPMM via the `supports-mpmm`
- * property.
- *
- * Returns `0` on success, or a negative integer representing an error code.
- */
-static int fconf_populate_mpmm_cpu(const void *fdt, int off, uintptr_t mpidr)
-{
-	int ret, len;
-
-	int core_pos;
-	struct mpmm_core *core;
-
-	core_pos = plat_core_pos_by_mpidr(mpidr);
-	if (core_pos < 0) {
-		return -FDT_ERR_BADVALUE;
-	}
-
-	core = &fconf_mpmm_topology.cores[core_pos];
-
-	fdt_getprop(fdt, off, "supports-mpmm", &len);
-	if (len >= 0) {
-		core->supported = true;
-		ret = 0;
-	} else {
-		core->supported = false;
-		ret = len;
-	}
-
-	return ret;
-}
-
-/*
- * Populates the global `fconf_mpmm_config` structure based on what's described
- * by the hardware configuration device tree blob.
- *
- * The device tree is expected to provide a `supports-mpmm` property for each
- * `cpu` node, like so:
- *
- *     cpu@0 {
- *       supports-mpmm;
- *     };
- *
- * This property indicates whether the core implements MPMM, as we cannot detect
- * support for it dynamically.
- */
-static int fconf_populate_mpmm(uintptr_t config)
-{
-	int ret = fdtw_for_each_cpu(
-		(const void *)config, fconf_populate_mpmm_cpu);
-	if (ret == 0) {
-		fconf_mpmm_config.topology = &fconf_mpmm_topology;
-	} else {
-		ERROR("FCONF: failed to configure MPMM: %d\n", ret);
-	}
-
-	return ret;
-}
-
-FCONF_REGISTER_POPULATOR(HW_CONFIG, mpmm, fconf_populate_mpmm);
diff --git a/lib/mpmm/mpmm.c b/lib/mpmm/mpmm.c
deleted file mode 100644
index dc61cf6..0000000
--- a/lib/mpmm/mpmm.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdbool.h>
-
-#include <common/debug.h>
-#include <lib/mpmm/mpmm.h>
-
-#include <plat/common/platform.h>
-
-#if ENABLE_MPMM_FCONF
-#	include <lib/fconf/fconf.h>
-#	include <lib/fconf/fconf_mpmm_getter.h>
-#endif
-
-static uint64_t read_cpuppmcr_el3_mpmmpinctl(void)
-{
-	return (read_cpuppmcr_el3() >> CPUPPMCR_EL3_MPMMPINCTL_SHIFT) &
-		CPUPPMCR_EL3_MPMMPINCTL_MASK;
-}
-
-static void write_cpumpmmcr_el3_mpmm_en(uint64_t mpmm_en)
-{
-	uint64_t value = read_cpumpmmcr_el3();
-
-	value &= ~(CPUMPMMCR_EL3_MPMM_EN_MASK << CPUMPMMCR_EL3_MPMM_EN_SHIFT);
-	value |= (mpmm_en & CPUMPMMCR_EL3_MPMM_EN_MASK) <<
-		CPUMPMMCR_EL3_MPMM_EN_SHIFT;
-
-	write_cpumpmmcr_el3(value);
-}
-
-static bool mpmm_supported(void)
-{
-	bool supported = false;
-	const struct mpmm_topology *topology;
-
-#if ENABLE_MPMM_FCONF
-	topology = FCONF_GET_PROPERTY(mpmm, config, topology);
-#else
-	topology = plat_mpmm_topology();
-#endif /* ENABLE_MPMM_FCONF */
-
-	/*
-	 * For the current core firstly try to find out if the platform
-	 * configuration has claimed support for MPMM, then make sure that MPMM
-	 * is controllable through the system registers.
-	 */
-
-	if (topology != NULL) {
-		unsigned int core_pos = plat_my_core_pos();
-
-		supported = topology->cores[core_pos].supported &&
-			(read_cpuppmcr_el3_mpmmpinctl() == 0U);
-	} else {
-		ERROR("MPMM: failed to generate MPMM topology\n");
-	}
-
-	return supported;
-}
-
-/* Defaults to false */
-static bool mpmm_disable_for_errata;
-
-void mpmm_enable(void)
-{
-	if (mpmm_supported()) {
-		if (mpmm_disable_for_errata) {
-			WARN("MPMM: disabled by errata workaround\n");
-			return;
-		}
-		write_cpumpmmcr_el3_mpmm_en(1U);
-	}
-}
-
-/*
- * This function is called from assembly code very early in BL31 so it must be
- * small and simple.
- */
-void mpmm_errata_disable(void)
-{
-	mpmm_disable_for_errata = true;
-}
diff --git a/lib/mpmm/mpmm.mk b/lib/mpmm/mpmm.mk
deleted file mode 100644
index 826f925..0000000
--- a/lib/mpmm/mpmm.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Copyright (c) 2021, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-include lib/extensions/amu/amu.mk
-include lib/fconf/fconf.mk
-
-ifneq (${ENABLE_MPMM},0)
-        ifneq ($(ARCH),aarch64)
-                $(error MPMM support (`ENABLE_MPMM`) can only be enabled in AArch64 images (`ARCH`))
-        endif
-
-        ifeq (${ENABLE_AMU_AUXILIARY_COUNTERS},0) # For MPMM gear AMU counters
-                $(error MPMM support (`ENABLE_MPM`) requires auxiliary AMU counter support (`ENABLE_AMU_AUXILIARY_COUNTERS`))
-        endif
-endif
-
-MPMM_SOURCES	:=	lib/mpmm/mpmm.c
-MPMM_SOURCES	+=	${AMU_SOURCES}
-
-ifneq (${ENABLE_MPMM_FCONF},0)
-        ifeq (${ENABLE_MPMM},0)
-                $(error MPMM FCONF support (`ENABLE_MPMM_FCONF`) requires MPMM support (`ENABLE_MPMM`))
-        endif
-
-        MPMM_SOURCES	+= ${FCONF_MPMM_SOURCES}
-endif
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 4bb23af..4c2601e 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -972,7 +972,7 @@
 	psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
 
 	/* Init registers that never change for the lifetime of TF-A */
-	cm_manage_extensions_el3();
+	cm_manage_extensions_el3(cpu_idx);
 
 	/*
 	 * Verify that we have been explicitly turned ON or resumed from
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 05bbe39..0fb1ed3 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -42,12 +42,13 @@
  * This function does generic and platform specific suspend to power down
  * operations.
  ******************************************************************************/
-static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
+static void psci_suspend_to_pwrdown_start(unsigned int idx,
+					  unsigned int end_pwrlvl,
 					  unsigned int max_off_lvl,
 					  const entry_point_info_t *ep,
 					  const psci_power_state_t *state_info)
 {
-	PUBLISH_EVENT(psci_suspend_pwrdown_start);
+	PUBLISH_EVENT_ARG(psci_suspend_pwrdown_start, &idx);
 
 #if PSCI_OS_INIT_MODE
 #ifdef PLAT_MAX_CPU_SUSPEND_PWR_LVL
@@ -223,7 +224,7 @@
 #endif
 #endif
 		max_off_lvl = psci_find_max_off_lvl(state_info);
-		psci_suspend_to_pwrdown_start(end_pwrlvl, max_off_lvl, ep, state_info);
+		psci_suspend_to_pwrdown_start(idx, end_pwrlvl, end_pwrlvl, ep, state_info);
 	}
 
 	/*
@@ -382,5 +383,5 @@
 	/* This loses its meaning when not suspending, reset so it's correct for OFF */
 	psci_set_suspend_pwrlvl(PLAT_MAX_PWR_LVL);
 
-	PUBLISH_EVENT(psci_suspend_pwrdown_finish);
+	PUBLISH_EVENT_ARG(psci_suspend_pwrdown_finish, &cpu_idx);
 }
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index 01a0395..71f4273 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -23,7 +23,14 @@
 # Determine if mbedtls is needed
 ifneq ($(filter $(CRYPTO_SUPPORT),1 2 3),)
     PROCESSED_JMPTBL = $(BUILD_DIR)/jmptbl_processed.i
-    $(shell mkdir -p $(BUILD_DIR) && cat ../../$(PLAT_DIR)/jmptbl.i ../../$(PLAT_DIR)/jmptbl_mbedtls.i > $(BUILD_DIR)/jmptbl_processed.i)
+    CRYPTO_JMPTBL = ../../$(PLAT_DIR)/jmptbl.i ../../$(PLAT_DIR)/jmptbl_mbedtls.i
+
+    ifeq (${PSA_CRYPTO},1)
+        CRYPTO_JMPTBL += ../../$(PLAT_DIR)/jmptbl_mbedtls_psa.i
+    endif # ifeq (${PSA_CRYPTO},1)
+
+    $(shell mkdir -p $(BUILD_DIR) && cat $(CRYPTO_JMPTBL) > $(PROCESSED_JMPTBL))
+
     LIBS += $(LIB_DIR)/libmbedtls.a
 endif
 
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 3c9e136..8dec522 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -291,7 +291,6 @@
 # Feature flags for supporting Activity monitor extensions.
 ENABLE_FEAT_AMU				?=	0
 ENABLE_AMU_AUXILIARY_COUNTERS		?=	0
-ENABLE_AMU_FCONF			?=	0
 AMU_RESTRICT_COUNTERS			?=	1
 
 # Build option to enable MPAM for lower ELs.
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index d514933..ec2aa1b 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -88,9 +88,6 @@
 # Enable support for powerdown abandons
 FEAT_PABANDON			:= 0
 
-# Enable MPMM configuration via FCONF.
-ENABLE_MPMM_FCONF		:= 0
-
 # Flag to Enable Position Independant support (PIE)
 ENABLE_PIE			:= 0
 
diff --git a/plat/arm/board/fvp/fvp_drtm_stub.c b/plat/arm/board/fvp/fvp_drtm_stub.c
index e2bc516..238febd 100644
--- a/plat/arm/board/fvp/fvp_drtm_stub.c
+++ b/plat/arm/board/fvp/fvp_drtm_stub.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,3 +33,13 @@
 {
 	return 0ULL;
 }
+
+uint64_t plat_drtm_get_acpi_tables_region_size(void)
+{
+	return 0ULL;
+}
+
+uint64_t plat_drtm_get_dlme_img_auth_features(void)
+{
+	return 0ULL;
+}
diff --git a/plat/arm/board/fvp/jmptbl_mbedtls_psa.i b/plat/arm/board/fvp/jmptbl_mbedtls_psa.i
new file mode 100644
index 0000000..4eb707b
--- /dev/null
+++ b/plat/arm/board/fvp/jmptbl_mbedtls_psa.i
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2025, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform-specific ROMLIB MbedTLS PSA Crypto functions can be added here.
+# During the build process, this file is appended to jmptbl.i
+# if MbedTLS support is required and PSA Crypto is supported.
+#
+# Format:
+# lib   function        [patch]
+# Example:
+# mbedtls psa_crypto_init
+
+mbedtls mbedtls_pk_get_psa_attributes
+mbedtls mbedtls_pk_import_into_psa
+mbedtls psa_crypto_init
+mbedtls psa_destroy_key
+mbedtls psa_verify_message
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 7bd3e74..1dd0b49 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -225,7 +225,8 @@
 #Include all CPUs to build to support all-errata build.
 ifeq (${ENABLE_ERRATA_ALL},1)
 	BUILD_CPUS_WITH_NO_FVP_MODEL = 1
-	FVP_CPU_LIBS    +=	lib/cpus/aarch64/cortex_a510.S		\
+	FVP_CPU_LIBS    +=    	lib/cpus/aarch64/cortex_a320.S          \
+				lib/cpus/aarch64/cortex_a510.S		\
 				lib/cpus/aarch64/cortex_a520.S		\
 				lib/cpus/aarch64/cortex_a725.S          \
 				lib/cpus/aarch64/cortex_x1.S            \
@@ -241,11 +242,9 @@
 	# travis/gelas need these
 	FEAT_PABANDON	:=	1
 	ERRATA_SME_POWER_DOWN := 1
-	FVP_CPU_LIBS    +=	lib/cpus/aarch64/neoverse_n3.S		\
-				lib/cpus/aarch64/cortex_gelas.S		\
+	FVP_CPU_LIBS    +=	lib/cpus/aarch64/cortex_gelas.S		\
 				lib/cpus/aarch64/nevis.S		\
 				lib/cpus/aarch64/travis.S		\
-				lib/cpus/aarch64/cortex_arcadia.S	\
 				lib/cpus/aarch64/cortex_alto.S
 endif
 
diff --git a/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
index dcee92c..19fb796 100644
--- a/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
+++ b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
@@ -129,8 +129,7 @@
 
 	cpu_info->ErrCtxEl3Reg[0]   = read_ctx_reg(get_el3state_ctx(ctx),
 						   CTX_ELR_EL3);
-	cpu_info->ErrCtxEl3Reg[1]   = read_ctx_reg(get_el3state_ctx(ctx),
-						   CTX_ESR_EL3);
+	cpu_info->ErrCtxEl3Reg[1]   = read_esr_el3();
 	cpu_info->ErrCtxEl3Reg[2]   = read_far_el3();
 	cpu_info->ErrCtxEl3Reg[4]   = read_mair_el3();
 	cpu_info->ErrCtxEl3Reg[5]   = read_sctlr_el3();
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
index 245d930..1ddd0e4 100644
--- a/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
@@ -144,7 +144,7 @@
 			${RDV3_BASE}/fdts/${PLAT}_nt_fw_config.dts
 
 ifeq (${SPMD_SPM_AT_SEL2}, 1)
-BL32_CONFIG_DTS                :=      ${RDV3_BASE}/fdts/${PLAT}_spmc_sp_manifest.dts
+BL32_CONFIG_DTS        :=      ${RDV3_BASE}/fdts/${PLAT}_spmc_sp_manifest.dts
 FDT_SOURCES            +=      ${BL32_CONFIG_DTS}
 TOS_FW_CONFIG          :=      ${BUILD_PLAT}/fdts/$(notdir $(basename ${BL32_CONFIG_DTS})).dtb
 endif
@@ -169,4 +169,14 @@
 
 # FEAT_SVE related flags
 override SVE_VECTOR_LEN		:= 128
-override CTX_INCLUDE_SVE_REGS	:= 1
+
+override CTX_INCLUDE_SVE_REGS   := 1
+
+# Enabling CTX_INCLUDE_SVE_REGS along with SPMD_SPM_AT_SEL2=1 is a invalid
+# combination and will lead to build failure, use them only when SPMD_SPM_AT_SEL2=0
+# In this combination its SPMC responsbility to save SVE regs.
+ifeq (${SPD},spmd)
+ifeq (${SPMD_SPM_AT_SEL2},1)
+override CTX_INCLUDE_SVE_REGS	:= 0
+endif
+endif
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 1e12a12..a056bc2 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -32,10 +32,8 @@
 ENABLE_TRBE_FOR_NS		:=	1
 ENABLE_SYS_REG_TRACE_FOR_NS	:=	1
 ENABLE_FEAT_AMU			:=	1
-ENABLE_AMU_FCONF		:=	1
 ENABLE_AMU_AUXILIARY_COUNTERS	:=	1
 ENABLE_MPMM			:=	1
-ENABLE_MPMM_FCONF		:=	1
 ENABLE_FEAT_MTE2		:=	2
 ENABLE_SPE_FOR_NS		:=	3
 ENABLE_FEAT_TCR2		:=	3
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index c5ebfde..5d19aeb 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -72,6 +72,18 @@
 };
 #endif
 
+/* the bottom 3 AMU group 1 counters */
+#define MPMM_GEARS ((1 << 0) | (1 << 1) | (1 << 2))
+
+uint16_t plat_amu_aux_enables[PLATFORM_CORE_COUNT] = {
+	MPMM_GEARS, MPMM_GEARS, MPMM_GEARS, MPMM_GEARS,
+	MPMM_GEARS, MPMM_GEARS, MPMM_GEARS, MPMM_GEARS,
+#if PLATFORM_CORE_COUNT == 14
+	MPMM_GEARS, MPMM_GEARS, MPMM_GEARS, MPMM_GEARS,
+	MPMM_GEARS, MPMM_GEARS
+#endif
+};
+
 #if (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4)
 static void enable_ns_mcn_pmu(void)
 {
diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c
index c32e59f..4cea0b9 100644
--- a/plat/common/plat_psci_common.c
+++ b/plat/common/plat_psci_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -30,6 +30,12 @@
 #define PSCI_STAT_ID_EXIT_LOW_PWR		1
 #define PSCI_STAT_TOTAL_IDS			2
 
+#if HW_ASSISTED_COHERENCY
+#define CACHE_MAINTENANCE_ATTR	PMF_NO_CACHE_MAINT
+#else
+#define CACHE_MAINTENANCE_ATTR	PMF_CACHE_MAINT
+#endif
+
 PMF_DECLARE_CAPTURE_TIMESTAMP(psci_svc)
 PMF_DECLARE_GET_TIMESTAMP(psci_svc)
 PMF_REGISTER_SERVICE(psci_svc, PMF_PSCI_STAT_SVC_ID, PSCI_STAT_TOTAL_IDS,
@@ -70,7 +76,7 @@
 {
 	assert(state_info != NULL);
 	PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR,
-		PMF_CACHE_MAINT);
+		CACHE_MAINTENANCE_ATTR);
 }
 
 /*
@@ -82,7 +88,7 @@
 {
 	assert(state_info != NULL);
 	PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR,
-		PMF_CACHE_MAINT);
+		CACHE_MAINTENANCE_ATTR);
 }
 
 /*
@@ -93,22 +99,27 @@
 	const psci_power_state_t *state_info,
 	unsigned int last_cpu_idx)
 {
-	plat_local_state_t state;
 	unsigned long long pwrup_ts = 0, pwrdn_ts = 0;
 	unsigned int pmf_flags;
 
 	assert((lvl >= PSCI_CPU_PWR_LVL) && (lvl <= PLAT_MAX_PWR_LVL));
-	assert(state_info != NULL);
 	assert(last_cpu_idx <= PLATFORM_CORE_COUNT);
 
 	if (lvl == PSCI_CPU_PWR_LVL)
 		assert(last_cpu_idx == plat_my_core_pos());
 
+#if HW_ASSISTED_COHERENCY
+	/* HW coherency allows for the capture and access to happen with caches
+	 * ON. So these timestamps don't need cache maintenance */
+	pmf_flags = PMF_NO_CACHE_MAINT;
+#else
 	/*
 	 * If power down is requested, then timestamp capture will
 	 * be with caches OFF.  Hence we have to do cache maintenance
 	 * when reading the timestamp.
 	 */
+	plat_local_state_t state;
+	assert(state_info != NULL);
 	state = state_info->pwr_domain_state[PSCI_CPU_PWR_LVL];
 	if (is_local_state_off(state) != 0) {
 		pmf_flags = PMF_CACHE_MAINT;
@@ -116,6 +127,7 @@
 		assert(is_local_state_retn(state) == 1);
 		pmf_flags = PMF_NO_CACHE_MAINT;
 	}
+#endif
 
 	PMF_GET_TIMESTAMP_BY_INDEX(psci_svc,
 		PSCI_STAT_ID_ENTER_LOW_PWR,
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index df51d89..e88855a 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <string.h>
 
 #include <platform_def.h>
@@ -58,7 +59,18 @@
 
 unsigned int plat_get_syscnt_freq2(void)
 {
+#ifdef SYS_COUNTER_FREQ_IN_TICKS
 	return SYS_COUNTER_FREQ_IN_TICKS;
+#else
+	static int sys_counter_freq_in_hz;
+
+	if (sys_counter_freq_in_hz == 0)
+		sys_counter_freq_in_hz = read_cntfrq_el0();
+
+	assert(sys_counter_freq_in_hz != 0);
+
+	return sys_counter_freq_in_hz;
+#endif
 }
 
 void plat_cci_init(void)
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index 1e13a9e..6388c47 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2025, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,6 +28,9 @@
 extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end;
 extern uint32_t __bl31_sram_stack_start, __bl31_sram_stack_end;
 extern uint32_t __bl31_sram_text_real_end, __bl31_sram_data_real_end;
+extern uint32_t __bl31_pmusram_text_start, __bl31_pmusram_text_end;
+extern uint32_t __bl31_pmusram_data_start, __bl31_pmusram_data_end;
+extern uint32_t __bl31_pmusram_text_real_end, __bl31_pmusram_data_real_end;
 extern uint32_t __sram_incbin_start, __sram_incbin_end;
 extern uint32_t __sram_incbin_real_end;
 
diff --git a/plat/rockchip/common/scmi/rockchip_common_clock.c b/plat/rockchip/common/scmi/rockchip_common_clock.c
new file mode 100644
index 0000000..d77bde3
--- /dev/null
+++ b/plat/rockchip/common/scmi/rockchip_common_clock.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include <scmi_clock.h>
+
+#define MUX_ADDR_INFO			0
+#define MUX_SHIFT_INFO			1
+#define MUX_WIDTH_INFO			2
+#define DIV_ADDR_INFO			3
+#define DIV_SHIFT_INFO			4
+#define DIV_WIDTH_INFO			5
+#define GATE_ADDR_INFO			6
+#define GATE_SHIFT_INFO			7
+
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
+#define abs(x) ({						\
+		long ret;					\
+		if (sizeof(x) == sizeof(long)) {		\
+			long __x = (x);				\
+			ret = (__x < 0) ? -__x : __x;		\
+		} else {					\
+			int __x = (x);				\
+			ret = (__x < 0) ? -__x : __x;		\
+		}						\
+		ret;						\
+	})
+
+static unsigned long clk_scmi_common_get_parent_rate(rk_scmi_clock_t *clock,
+						     int id)
+{
+	rk_scmi_clock_t *p_clock;
+
+	if (clock->is_dynamic_prate != 0) {
+		p_clock = rockchip_scmi_get_clock(0, clock->parent_table[id]);
+		if (p_clock == NULL)
+			return 0;
+		if ((p_clock->clk_ops != NULL) && (p_clock->clk_ops->get_rate != NULL))
+			return  p_clock->clk_ops->get_rate(p_clock);
+		else
+			return 0;
+	} else {
+		return clock->parent_table[id];
+	}
+}
+
+unsigned long clk_scmi_common_get_rate(rk_scmi_clock_t *clock)
+{
+	unsigned long parent_rate, sel, div;
+
+	sel = mmio_read_32(clock->info[MUX_ADDR_INFO]) >>
+	      clock->info[MUX_SHIFT_INFO];
+	sel = sel & (BIT(clock->info[MUX_WIDTH_INFO]) - 1);
+	div = mmio_read_32(clock->info[DIV_ADDR_INFO]) >>
+	      clock->info[DIV_SHIFT_INFO];
+	div = div & (BIT(clock->info[DIV_WIDTH_INFO]) - 1);
+	parent_rate = clk_scmi_common_get_parent_rate(clock, sel);
+
+	return parent_rate / (div + 1);
+}
+
+int clk_scmi_common_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	unsigned long parent_rate, now, best_rate = 0;
+	int i = 0, sel_mask, div_mask, best_sel = 0, best_div = 0, div;
+
+	if ((rate == 0) ||
+	    (clock->info[MUX_WIDTH_INFO] == 0 && clock->info[DIV_WIDTH_INFO] == 0))
+		return SCMI_INVALID_PARAMETERS;
+
+	sel_mask = BIT(clock->info[MUX_WIDTH_INFO]) - 1;
+	div_mask = BIT(clock->info[DIV_WIDTH_INFO]) - 1;
+	if (clock->info[MUX_WIDTH_INFO] == 0) {
+		parent_rate = clk_scmi_common_get_parent_rate(clock, 0);
+		div = DIV_ROUND_UP(parent_rate, rate);
+		if (div > div_mask + 1)
+			div = div_mask + 1;
+		mmio_write_32(clock->info[DIV_ADDR_INFO],
+			      BITS_WITH_WMASK(div - 1, div_mask,
+					      clock->info[DIV_SHIFT_INFO]));
+	} else if (clock->info[DIV_WIDTH_INFO] == 0) {
+		for (i = 0; i <= sel_mask; i++) {
+			parent_rate = clk_scmi_common_get_parent_rate(clock, i);
+			now = parent_rate;
+			if (abs(rate - now) < abs(rate - best_rate)) {
+				best_rate = now;
+				best_sel = i;
+			}
+		}
+		if (best_rate == 0)
+			best_sel = 0;
+		mmio_write_32(clock->info[MUX_ADDR_INFO],
+			      BITS_WITH_WMASK(best_sel, sel_mask,
+					      clock->info[MUX_SHIFT_INFO]));
+	} else {
+		for (i = 0; i <= sel_mask; i++) {
+			parent_rate = clk_scmi_common_get_parent_rate(clock, i);
+			div = DIV_ROUND_UP(parent_rate, rate);
+			if (div > div_mask + 1)
+				div = div_mask + 1;
+			now = parent_rate / div;
+			if (abs(rate - now) < abs(rate - best_rate)) {
+				best_rate = now;
+				best_div = div;
+				best_sel = i;
+			}
+		}
+		if (best_rate == 0) {
+			best_div = div_mask + 1;
+			best_sel = 0;
+		}
+
+		mmio_write_32(clock->info[DIV_ADDR_INFO],
+			      BITS_WITH_WMASK(div_mask, div_mask,
+					      clock->info[DIV_SHIFT_INFO]));
+		mmio_write_32(clock->info[MUX_ADDR_INFO],
+			      BITS_WITH_WMASK(best_sel, sel_mask,
+					      clock->info[MUX_SHIFT_INFO]));
+		mmio_write_32(clock->info[DIV_ADDR_INFO],
+			      BITS_WITH_WMASK(best_div - 1, div_mask,
+					      clock->info[DIV_SHIFT_INFO]));
+	}
+	return 0;
+}
+
+int clk_scmi_common_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(clock->info[GATE_ADDR_INFO],
+		      BITS_WITH_WMASK(!status, 0x1U,
+				      clock->info[GATE_SHIFT_INFO]));
+
+	return 0;
+}
diff --git a/plat/rockchip/common/scmi/scmi_clock.h b/plat/rockchip/common/scmi/scmi_clock.h
index e640fe1..4b94adf 100644
--- a/plat/rockchip/common/scmi/scmi_clock.h
+++ b/plat/rockchip/common/scmi/scmi_clock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ * Copyright (c) 2025, Rockchip, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,11 +23,14 @@
 	char name[SCMI_CLOCK_NAME_LENGTH_MAX];
 	uint8_t enable;
 	int8_t is_security;
+	int8_t is_dynamic_prate;
 	uint32_t id;
 	uint32_t rate_cnt;
 	uint64_t cur_rate;
 	uint32_t enable_count;
 	const struct rk_clk_ops *clk_ops;
+	const unsigned long *parent_table;
+	const uint32_t *info;
 	unsigned long *rate_table;
 } rk_scmi_clock_t;
 
@@ -47,4 +50,7 @@
 rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id,
 					 uint32_t scmi_id);
 
+unsigned long clk_scmi_common_get_rate(rk_scmi_clock_t *clock);
+int clk_scmi_common_set_rate(rk_scmi_clock_t *clock, unsigned long rate);
+int clk_scmi_common_set_status(rk_scmi_clock_t *clock, bool status);
 #endif /* RK_SCMI_CLOCK_H */
diff --git a/plat/rockchip/rk3576/drivers/dmc/dmc_rk3576.h b/plat/rockchip/rk3576/drivers/dmc/dmc_rk3576.h
new file mode 100644
index 0000000..d8c231c
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/dmc/dmc_rk3576.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PLAT_ROCKCHIP_DMC_RK3576_H__
+#define __PLAT_ROCKCHIP_DMC_RK3576_H__
+
+#define MAX_CH_NUM			(2)
+#define CTL_PORT_NUM			(5)
+
+/* DDR_GRF Register */
+#define GRF_CH_CON(ch, n)		((((ch) % 2) * 0x100) + ((n) * 4))
+#define DDR_GRF_CH_STATUS16(ch)		(0x220 + ((ch) * 0x100))
+#define GRF_DDRPHY_CON(n)		(0x530 + ((n) * 4))
+#define GRF_DDRPHY_CON0(ch)		(0x530 + (((ch) % 2) * 0x4))
+#define DDR_GRF_COMMON_CON(n)		(0x540 + ((n) * 4))
+
+/* PMUGRF Register */
+#define PMUGRF_OS_REG(n)		(0x200 + ((n) * 4))
+
+struct low_power_st {
+	uint32_t pwrctl;
+	uint32_t clkgatectl;
+	uint32_t dfi_lp_mode_apb;
+	uint32_t grf_ddr_con0;
+	uint32_t grf_ddr_con1;
+	uint32_t grf_ddr_con6;
+	uint32_t grf_ddr_con7;
+	uint32_t grf_ddr_con9;
+	uint32_t grf_ddrphy_con0;
+	uint32_t hwlp_0;
+	uint32_t hwlp_c;
+	uint32_t pcl_pd;
+};
+
+struct rk3576_dmc_config {
+	struct low_power_st low_power[MAX_CH_NUM];
+};
+
+void dmc_save(void);
+void dmc_restore(void);
+
+#endif /* __PLAT_ROCKCHIP_DMC_RK3576_H__ */
diff --git a/plat/rockchip/rk3576/drivers/dmc/suspend.c b/plat/rockchip/rk3576/drivers/dmc/suspend.c
new file mode 100644
index 0000000..389cc1b
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/dmc/suspend.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+
+#include <dmc_rk3576.h>
+#include <rk3576_def.h>
+#include <soc.h>
+
+struct rk3576_dmc_config dmc_config;
+
+/* DDR_PHY */
+#define LP_CON0				0x0018
+#define DFI_LP_CON0			0x0e04
+/* DDR_CTL */
+#define DDRCTL_STAT			0x10014
+#define DDRCTL_PWRCTL			0x10180
+#define DDRCTL_CLKGATECTL		0x1018c
+
+/* LP_CON0 */
+#define DS_IO_PD			BIT(14)
+#define SCHD_HW_CLOCK_GATING_DISABLE	BIT(13)
+#define PCL_PD				BIT(12)
+#define DQS_ENABLE			BIT(10)
+#define WCK_ENABLE			BIT(9)
+#define CTRL_DQS_DRV_OFF		BIT(8)
+#define CTRL_SCHEDULER_EN		BIT(6)
+
+/* DFI_LP_CON0 0x0e04 */
+#define DFI_LP_MODE_APB			BIT(31)
+
+/* DDRCTL_STAT 0x10014 */
+#define CTL_SELFREF_STATE_SHIFT		(12)
+#define CTL_SELFREF_STATE_MASK		(0x7 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_NOT_IN_SELF_REFRESH		(0x0 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELF_REFRESH_1		(0x1 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELF_REFRESH_POWER_DOWN	(0x2 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELF_REFRESH_2		(0x3 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELF_REFRESH_DEEP_SLEEP	(0x4 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELFREF_TYPE_SHIFT		(4)
+#define CTL_SELFREF_TYPE_MASK		(0x3 << CTL_SELFREF_TYPE_SHIFT)
+#define CTL_SELFREF_NOT_BY_PHY		(0x1 << CTL_SELFREF_TYPE_SHIFT)
+#define CTL_SELFREF_NOT_BY_AUTO		(0x2 << CTL_SELFREF_TYPE_SHIFT)
+#define CTL_SELFREF_BY_AUTO		(0x3 << CTL_SELFREF_TYPE_SHIFT)
+#define CTL_OPERATING_MODE_MASK		(0x7)
+#define CTL_OPERATING_MODE_INIT		(0x0)
+#define CTL_OPERATING_MODE_NORMAL	(0x1)
+#define CTL_OPERATING_MODE_PD		(0x2)
+#define CTL_OPERATING_MODE_SR_SRPD	(0x3)
+
+/* DDRCTL_PWRCTL 0x10180 */
+#define CTL_DSM_EN			BIT(18)
+#define CTL_STAY_IN_SELFREF		BIT(15)
+#define CTL_SELFREF_SW			BIT(11)
+#define CTL_EN_DFI_DRAM_CLK_DISABLE	BIT(9)
+#define CTL_POWERDOWN_EN_MASK		(0xf)
+#define CTL_POWERDOWN_EN_SHIFT		(4)
+#define CTL_SELFREF_EN_MASK		(0xf)
+#define CTL_SELFREF_EN_SHIFT		(0)
+
+#define SYS_REG_DEC_CHINFO(n, ch)	(((n) >> (28 + (ch))) & 0x1)
+#define SYS_REG_DEC_CHINFO_V3(reg2, ch) SYS_REG_DEC_CHINFO(reg2, ch)
+
+#define SYS_REG_DEC_NUM_CH(n)		(1 + (((n) >> 12) & 0x1))
+#define SYS_REG_DEC_NUM_CH_V3(reg2)	SYS_REG_DEC_NUM_CH(reg2)
+
+static void exit_low_power(uint32_t ch, struct rk3576_dmc_config *configs)
+{
+	/* LP_CON0: [12]pcl_pd */
+	configs->low_power[ch].pcl_pd = mmio_read_32(DDRPHY_BASE_CH(0) + LP_CON0) & PCL_PD;
+	mmio_clrbits_32(DDRPHY_BASE_CH(ch) + LP_CON0, PCL_PD);
+
+	/* Disable low power activities */
+	configs->low_power[ch].pwrctl = mmio_read_32(UMCTL_BASE_CH(ch) + DDRCTL_PWRCTL);
+	mmio_clrbits_32(UMCTL_BASE_CH(ch) + DDRCTL_PWRCTL,
+			CTL_DSM_EN | (CTL_POWERDOWN_EN_MASK << CTL_POWERDOWN_EN_SHIFT) |
+			(CTL_SELFREF_EN_MASK << CTL_SELFREF_EN_SHIFT));
+	while ((mmio_read_32(UMCTL_BASE_CH(ch) + DDRCTL_STAT) & CTL_OPERATING_MODE_MASK) !=
+		CTL_OPERATING_MODE_NORMAL)
+		continue;
+
+	/* DDR_GRF_CHA_CON6: [6:0]rd_lat_delay, [14:8]wr_lat_delay, [15]cmd_dly_eq0_en */
+	configs->low_power[ch].grf_ddr_con6 =
+		mmio_read_32(DDR_GRF_BASE + GRF_CH_CON(ch, 6)) & 0xff7f;
+	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 6), (0x1ul << (15 + 16)));
+
+	/* DDR_GRF_CHA_CON0: [12:8]ddrctl_axi_cg_en */
+	configs->low_power[ch].grf_ddr_con0 =
+		mmio_read_32(DDR_GRF_BASE + GRF_CH_CON(ch, 0)) & 0x1f00;
+	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 0), 0x1f000000);
+
+	/*
+	 * DDR_GRF_CHA_CON1:
+	 * [15]ddrctl_apb_pclk_cg_en, [12]ddrmon_pclk_cg_en, [7]dfi_scramble_cg_en,
+	 * [6]ddrctl_mem_cg_en, [5]bsm_clk_cg_en, [2]ddrctl_core_cg_en, [1]ddrctl_apb_cg_en
+	 */
+	configs->low_power[ch].grf_ddr_con1 =
+		mmio_read_32(DDR_GRF_BASE + GRF_CH_CON(ch, 1)) & 0x90e6;
+	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 1), 0x90e60000);
+
+	configs->low_power[ch].hwlp_0 = mmio_read_32(HWLP_BASE_CH(ch) + 0x0);
+	mmio_write_32(HWLP_BASE_CH(ch) + 0x0, 0x0);
+	configs->low_power[ch].hwlp_c = mmio_read_32(HWLP_BASE_CH(ch) + 0xc);
+	mmio_write_32(HWLP_BASE_CH(ch) + 0xc, 0x0);
+
+	/* DDR_GRF_CHA_PHY_CON0: [14]ddrphy_pclk_cg_en */
+	configs->low_power[ch].grf_ddrphy_con0 =
+		mmio_read_32(DDR_GRF_BASE + GRF_DDRPHY_CON0(ch)) & BIT(14);
+	mmio_write_32(DDR_GRF_BASE + GRF_DDRPHY_CON0(ch), BIT(14 + 16));
+
+	/* CLKGATECTL: [5:0]bsm_clk_on */
+	configs->low_power[ch].clkgatectl =
+		mmio_read_32(UMCTL_BASE_CH(ch) + DDRCTL_CLKGATECTL) & 0x3f;
+	/* DFI_LP_CON0: [31]dfi_lp_mode_apb */
+	configs->low_power[ch].dfi_lp_mode_apb =
+		(mmio_read_32(DDRPHY_BASE_CH(ch) + DFI_LP_CON0) >> 31) & 0x1;
+}
+
+static void resume_low_power(uint32_t ch, struct rk3576_dmc_config *configs)
+{
+	/* DFI_LP_CON0: [31]dfi_lp_mode_apb */
+	if (configs->low_power[ch].dfi_lp_mode_apb != 0)
+		mmio_setbits_32(DDRPHY_BASE_CH(ch) + DFI_LP_CON0, DFI_LP_MODE_APB);
+
+	/* CLKGATECTL: [5:0]bsm_clk_on */
+	mmio_clrsetbits_32(UMCTL_BASE_CH(ch) + DDRCTL_CLKGATECTL,
+			   0x3f, configs->low_power[ch].clkgatectl & 0x3f);
+
+	/* DDR_GRF_CHA_CON6: [6:0]rd_lat_delay, [14:8]wr_lat_delay, [15]cmd_dly_eq0_en */
+	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 6),
+		      (0xff7ful << 16) | configs->low_power[ch].grf_ddr_con6);
+
+	mmio_write_32(HWLP_BASE_CH(ch) + 0xc, configs->low_power[ch].hwlp_c);
+	mmio_write_32(HWLP_BASE_CH(ch) + 0x0, configs->low_power[ch].hwlp_0);
+
+	/* DDR_GRF_CHA_CON0: [12:8]ddrctl_axi_cg_en */
+	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 0),
+		      (0x1f00ul << 16) | configs->low_power[ch].grf_ddr_con0);
+
+	/*
+	 * DDR_GRF_CHA_CON1:
+	 * [15]ddrctl_apb_pclk_cg_en, [12]ddrmon_pclk_cg_en, [7]dfi_scramble_cg_en,
+	 * [6]ddrctl_mem_cg_en, [5]bsm_clk_cg_en, [2]ddrctl_core_cg_en, [1]ddrctl_apb_cg_en
+	 */
+	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 1),
+		      (0x90e6ul << 16) | configs->low_power[ch].grf_ddr_con1);
+
+	/* DDR_GRF_CHA_PHY_CON0: [14]ddrphy_pclk_cg_en */
+	mmio_write_32(DDR_GRF_BASE + GRF_DDRPHY_CON0(ch),
+		      BIT(14 + 16) | configs->low_power[ch].grf_ddrphy_con0);
+
+	/* reset low power activities */
+	mmio_write_32(UMCTL_BASE_CH(ch) + DDRCTL_PWRCTL, configs->low_power[ch].pwrctl);
+
+	/* LP_CON0: [12]pcl_pd */
+	if (configs->low_power[ch].pcl_pd != 0)
+		mmio_setbits_32(DDRPHY_BASE_CH(ch) + LP_CON0, PCL_PD);
+}
+
+void dmc_save(void)
+{
+	uint32_t i, channel_num;
+
+	channel_num =
+		SYS_REG_DEC_NUM_CH_V3(mmio_read_32(PMU1_GRF_BASE + PMUGRF_OS_REG(2)));
+
+	for (i = 0; i < channel_num; i++)
+		exit_low_power(i, &dmc_config);
+}
+
+void dmc_restore(void)
+{
+	uint32_t i, channel_num;
+
+	channel_num = SYS_REG_DEC_NUM_CH_V3(mmio_read_32(PMU1_GRF_BASE + PMUGRF_OS_REG(2)));
+
+	for (i = 0; i < channel_num; i++)
+		resume_low_power(i, &dmc_config);
+}
diff --git a/plat/rockchip/rk3576/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3576/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 0000000..717b55c
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+.globl	clst_warmboot_data
+
+.macro	func_rockchip_clst_warmboot
+.endm
+
+.macro rockchip_clst_warmboot_data
+clst_warmboot_data:
+	.rept	PLATFORM_CLUSTER_COUNT
+	.word	0
+	.endr
+.endm
diff --git a/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.c b/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.c
new file mode 100644
index 0000000..de5fa75
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.c
@@ -0,0 +1,451 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <plat_pm_helpers.h>
+#include <plat_private.h>
+#include <pm_pd_regs.h>
+#include <rk3576_clk.h>
+#include <soc.h>
+
+#define WMSK_VAL		0xffff0000
+
+static struct reg_region qos_reg_rgns[] = {
+	[qos_decom] = REG_REGION(0x08, 0x18, 4, 0x27f00000, 0),
+	[qos_dmac0] = REG_REGION(0x08, 0x18, 4, 0x27f00080, 0),
+	[qos_dmac1] = REG_REGION(0x08, 0x18, 4, 0x27f00100, 0),
+	[qos_dmac2] = REG_REGION(0x08, 0x18, 4, 0x27f00180, 0),
+	[qos_bus_mcu] = REG_REGION(0x08, 0x18, 4, 0x27f00200, 0),
+	[qos_can0] = REG_REGION(0x08, 0x18, 4, 0x27f00280, 0),
+	[qos_can1] = REG_REGION(0x08, 0x18, 4, 0x27f00300, 0),
+	[qos_cci_m0] = REG_REGION(0x08, 0x18, 4, 0x27f01000, 0),
+	[qos_cci_m1] = REG_REGION(0x08, 0x18, 4, 0x27f18880, 0),
+	[qos_cci_m2] = REG_REGION(0x08, 0x18, 4, 0x27f18900, 0),
+	[qos_dap_lite] = REG_REGION(0x08, 0x18, 4, 0x27f01080, 0),
+	[qos_hdcp1] = REG_REGION(0x08, 0x18, 4, 0x27f02000, 0),
+	[qos_ddr_mcu] = REG_REGION(0x08, 0x18, 4, 0x27f03000, 0),
+	[qos_fspi1] = REG_REGION(0x08, 0x18, 4, 0x27f04000, 0),
+	[qos_gmac0] = REG_REGION(0x08, 0x18, 4, 0x27f04080, 0),
+	[qos_gmac1] = REG_REGION(0x08, 0x18, 4, 0x27f04100, 0),
+	[qos_sdio] = REG_REGION(0x08, 0x18, 4, 0x27f04180, 0),
+	[qos_sdmmc] = REG_REGION(0x08, 0x18, 4, 0x27f04200, 0),
+	[qos_flexbus] = REG_REGION(0x08, 0x18, 4, 0x27f04280, 0),
+	[qos_gpu] = REG_REGION(0x08, 0x18, 4, 0x27f05000, 0),
+	[qos_vepu1] = REG_REGION(0x08, 0x18, 4, 0x27f06000, 0),
+	[qos_npu_mcu] = REG_REGION(0x08, 0x18, 4, 0x27f08000, 0),
+	[qos_npu_nsp0] = REG_REGION(0x08, 0x18, 4, 0x27f08080, 0),
+	[qos_npu_nsp1] = REG_REGION(0x08, 0x18, 4, 0x27f08100, 0),
+	[qos_npu_m0] = REG_REGION(0x08, 0x18, 4, 0x27f20000, 0),
+	[qos_npu_m1] = REG_REGION(0x08, 0x18, 4, 0x27f21000, 0),
+	[qos_npu_m0ro] = REG_REGION(0x08, 0x18, 4, 0x27f22080, 0),
+	[qos_npu_m1ro] = REG_REGION(0x08, 0x18, 4, 0x27f22100, 0),
+	[qos_emmc] = REG_REGION(0x08, 0x18, 4, 0x27f09000, 0),
+	[qos_fspi0] = REG_REGION(0x08, 0x18, 4, 0x27f09080, 0),
+	[qos_mmu0] = REG_REGION(0x08, 0x18, 4, 0x27f0a000, 0),
+	[qos_mmu1] = REG_REGION(0x08, 0x18, 4, 0x27f0a080, 0),
+	[qos_pmu_mcu] = REG_REGION(0x08, 0x18, 4, 0x27f0b000, 0),
+	[qos_rkvdec] = REG_REGION(0x08, 0x18, 4, 0x27f0c000, 0),
+	[qos_crypto] = REG_REGION(0x08, 0x18, 4, 0x27f0d000, 0),
+	[qos_mmu2] = REG_REGION(0x08, 0x18, 4, 0x27f0e000, 0),
+	[qos_ufshc] = REG_REGION(0x08, 0x18, 4, 0x27f0e080, 0),
+	[qos_vepu0] = REG_REGION(0x08, 0x18, 4, 0x27f0f000, 0),
+	[qos_isp_mro] = REG_REGION(0x08, 0x18, 4, 0x27f10000, 0),
+	[qos_isp_mwo] = REG_REGION(0x08, 0x18, 4, 0x27f10080, 0),
+	[qos_vicap_m0] = REG_REGION(0x08, 0x18, 4, 0x27f10100, 0),
+	[qos_vpss_mro] = REG_REGION(0x08, 0x18, 4, 0x27f10180, 0),
+	[qos_vpss_mwo] = REG_REGION(0x08, 0x18, 4, 0x27f10200, 0),
+	[qos_hdcp0] = REG_REGION(0x08, 0x18, 4, 0x27f11000, 0),
+	[qos_vop_m0] = REG_REGION(0x08, 0x18, 4, 0x27f12800, 0),
+	[qos_vop_m1ro] = REG_REGION(0x08, 0x18, 4, 0x27f12880, 0),
+	[qos_ebc] = REG_REGION(0x08, 0x18, 4, 0x27f13000, 0),
+	[qos_rga0] = REG_REGION(0x08, 0x18, 4, 0x27f13080, 0),
+	[qos_rga1] = REG_REGION(0x08, 0x18, 4, 0x27f13100, 0),
+	[qos_jpeg] = REG_REGION(0x08, 0x18, 4, 0x27f13180, 0),
+	[qos_vdpp] = REG_REGION(0x08, 0x18, 4, 0x27f13200, 0),
+	[qos_dma2ddr] = REG_REGION(0x08, 0x18, 4, 0x27f15880, 0),
+};
+
+static struct reg_region pd_bcore_reg_rgns[] = {
+	/* bcore cru */
+	/* REG_REGION(0x280, 0x280, 4, BIGCORE0CRU_BASE, WMSK_VAL), */
+	REG_REGION(0x300, 0x30c, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x804, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa0c, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xcc0, 0xcc0, 4, BIGCORE_CRU_BASE, 0),
+	REG_REGION(0xf28, 0xf28, 8, BIGCORE_CRU_BASE, 0),
+	REG_REGION(0xf2c, 0xf2c, 8, BIGCORE_CRU_BASE, WMSK_VAL),
+
+	/* bcore_grf */
+	REG_REGION(0x34, 0x3c, 4, BIGCORE_GRF_BASE, WMSK_VAL),
+	REG_REGION(0x44, 0x44, 4, BIGCORE_GRF_BASE, WMSK_VAL),
+};
+
+static struct reg_region pd_core_reg_rgns[] = {
+	/* cci cru */
+	REG_REGION(0x310, 0x310, 4, CCI_CRU_BASE, WMSK_VAL),
+	REG_REGION(0x804, 0x808, 4, CCI_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa04, 0xa08, 4, CCI_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xc50, 0xc58, 4, CCI_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xd00, 0xd00, 8, CCI_CRU_BASE, 0),
+	REG_REGION(0xd04, 0xd04, 8, CCI_CRU_BASE, WMSK_VAL),
+	/* Restore lpll registers after clksel_* registers. Because lpll
+	 * may be turned off during restoring, which cause cci_cru to lost clock.
+	 */
+	REG_REGION(0x040, 0x044, 4, CCI_CRU_BASE, WMSK_VAL),
+	REG_REGION(0x048, 0x048, 4, CCI_CRU_BASE, 0),
+	REG_REGION(0x04c, 0x058, 4, CCI_CRU_BASE, WMSK_VAL),
+
+	/* lcore cru */
+	/* REG_REGION(0x280, 0x280, 4, BIGCORE1CRU_BASE, WMSK_VAL), */
+	REG_REGION(0x300, 0x30c, 4, LITTLE_CRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x804, 4, LITTLE_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa0c, 4, LITTLE_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xcc0, 0xcc0, 4, LITTLE_CRU_BASE, 0),
+	REG_REGION(0xf38, 0xf38, 8, LITTLE_CRU_BASE, 0),
+	REG_REGION(0xf3c, 0xf3c, 8, LITTLE_CRU_BASE, WMSK_VAL),
+
+	/* bcore cru */
+	/* REG_REGION(0x280, 0x280, 4, BIGCORE0CRU_BASE, WMSK_VAL), */
+	REG_REGION(0x300, 0x30c, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x804, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa0c, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xcc0, 0xcc0, 4, BIGCORE_CRU_BASE, 0),
+	REG_REGION(0xf28, 0xf28, 8, BIGCORE_CRU_BASE, 0),
+	REG_REGION(0xf2c, 0xf2c, 8, BIGCORE_CRU_BASE, WMSK_VAL),
+
+	/* cci grf */
+	REG_REGION(0x00, 0x10, 4, CCI_GRF_BASE, WMSK_VAL),
+	REG_REGION(0x54, 0x54, 4, CCI_GRF_BASE, WMSK_VAL),
+
+	/* lcore_grf */
+	REG_REGION(0x34, 0x3c, 4, LITCORE_GRF_BASE, WMSK_VAL),
+	REG_REGION(0x44, 0x44, 4, LITCORE_GRF_BASE, WMSK_VAL),
+
+	/* bcore_grf */
+	REG_REGION(0x34, 0x3c, 4, BIGCORE_GRF_BASE, WMSK_VAL),
+	REG_REGION(0x44, 0x44, 4, BIGCORE_GRF_BASE, WMSK_VAL),
+};
+
+static struct reg_region pd_php_reg_rgns[] = {
+	/* php_grf */
+	REG_REGION(0x004, 0x00c, 4, PHP_GRF_BASE, WMSK_VAL),
+	REG_REGION(0x010, 0x018, 4, PHP_GRF_BASE, 0),
+	REG_REGION(0x01c, 0x020, 4, PHP_GRF_BASE, WMSK_VAL),
+	REG_REGION(0x048, 0x048, 4, PHP_GRF_BASE, 0),
+};
+
+static struct reg_region pd_usb2phy_reg_rgns[] = {
+	/* usb */
+	REG_REGION(0x00, 0x14, 4, USB2PHY0_GRF_BASE, WMSK_VAL),
+	REG_REGION(0x40, 0x40, 4, USB2PHY0_GRF_BASE, WMSK_VAL),
+	REG_REGION(0x44, 0x50, 4, USB2PHY0_GRF_BASE, 0),
+	REG_REGION(0x00, 0x14, 4, USB2PHY1_GRF_BASE, WMSK_VAL),
+	REG_REGION(0x08, 0x08, 4, USBDPPHY_GRF_BASE, WMSK_VAL),
+};
+
+#define PLL_LOCKED_TIMEOUT 600000U
+
+static void pm_pll_wait_lock(uint32_t pll_base)
+{
+	int delay = PLL_LOCKED_TIMEOUT;
+
+	if ((mmio_read_32(pll_base + CRU_PLL_CON(1)) & CRU_PLLCON1_PWRDOWN) != 0)
+		return;
+
+	while (delay-- >= 0) {
+		if ((mmio_read_32(pll_base + CRU_PLL_CON(6)) & CRU_PLLCON6_LOCK_STATUS) != 0)
+			break;
+		udelay(1);
+	}
+
+	if (delay <= 0)
+		ERROR("Can't wait pll(0x%x) lock\n", pll_base);
+}
+
+void qos_save(void)
+{
+	uint32_t pmu_pd_st = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST);
+
+	if ((pmu_pd_st & BIT(pmu_pd_nvm)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_emmc], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_fspi0], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_sd_gmac)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_fspi1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_gmac0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_gmac1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_sdio], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_sdmmc], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_flexbus], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_php)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_mmu0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_mmu1], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_vop)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_vop_m0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_vop_m1ro], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_vo1)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_hdcp1], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_vo0)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_hdcp0], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_usb)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_mmu2], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_ufshc], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_vi)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_isp_mro], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_isp_mwo], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_vicap_m0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_vpss_mro], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_vpss_mwo], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_vepu0)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_vepu0], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_vepu1)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_vepu1], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_vdec)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_rkvdec], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_vpu)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_ebc], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_rga0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_rga1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_jpeg], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_vdpp], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_nputop)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_mcu], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_nsp0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_nsp1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_m0ro], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_m1ro], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_npu0)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_m0], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_npu1)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_m1], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_gpu)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[qos_gpu], 1);
+}
+
+void qos_restore(void)
+{
+	uint32_t pmu_pd_st = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST);
+
+	if ((pmu_pd_st & BIT(pmu_pd_nvm)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_emmc], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_fspi0], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_sd_gmac)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_fspi1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_gmac0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_gmac1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_sdio], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_sdmmc], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_flexbus], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_php)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_mmu0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_mmu1], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_vop)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vop_m0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vop_m1ro], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_vo1)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_hdcp1], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_vo0)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_hdcp0], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_usb)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_mmu2], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_ufshc], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_vi)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_isp_mro], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_isp_mwo], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vicap_m0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vpss_mro], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vpss_mwo], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_vepu0)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vepu0], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_vepu1)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vepu1], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_vdec)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_rkvdec], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_vpu)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_ebc], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_rga0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_rga1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_jpeg], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vdpp], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_nputop)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_mcu], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_nsp0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_nsp1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_m0ro], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_m1ro], 1);
+	}
+
+	if ((pmu_pd_st & BIT(pmu_pd_npu0)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_m0], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_npu1)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_m1], 1);
+
+	if ((pmu_pd_st & BIT(pmu_pd_gpu)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[qos_gpu], 1);
+}
+
+void pd_usb2phy_save(void)
+{
+	rockchip_reg_rgn_save(pd_usb2phy_reg_rgns, ARRAY_SIZE(pd_usb2phy_reg_rgns));
+}
+
+void pd_usb2phy_restore(void)
+{
+	rockchip_reg_rgn_restore(pd_usb2phy_reg_rgns, ARRAY_SIZE(pd_usb2phy_reg_rgns));
+}
+
+static uint32_t b_cru_mode, l_cru_mode;
+static uint32_t bcore_need_restore;
+
+void pd_bcore_save(void)
+{
+	pvtplls_cpub_suspend();
+
+	b_cru_mode = mmio_read_32(BIGCORE_CRU_BASE + 0x280);
+	rockchip_reg_rgn_save(pd_bcore_reg_rgns, ARRAY_SIZE(pd_bcore_reg_rgns));
+
+	bcore_need_restore = 1;
+}
+
+void pd_bcore_restore(void)
+{
+	if (bcore_need_restore == 0)
+		return;
+
+	/* slow mode */
+	mmio_write_32(BIGCORE_CRU_BASE + 0x280, 0x00030000);
+
+	rockchip_reg_rgn_restore(pd_bcore_reg_rgns, ARRAY_SIZE(pd_bcore_reg_rgns));
+
+	/* trigger lcore/bcore mem_cfg */
+	mmio_write_32(BIGCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(1, 0x1, 1));
+	udelay(1);
+	mmio_write_32(BIGCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(0, 0x1, 1));
+
+	/* restore mode */
+	mmio_write_32(BIGCORE_CRU_BASE + 0x280, WITH_16BITS_WMSK(b_cru_mode));
+
+	pvtplls_cpub_resume();
+
+	bcore_need_restore = 0;
+}
+
+void pd_core_save(void)
+{
+	pvtplls_suspend();
+
+	b_cru_mode = mmio_read_32(BIGCORE_CRU_BASE + 0x280);
+	l_cru_mode = mmio_read_32(LITTLE_CRU_BASE + 0x280);
+
+	rockchip_reg_rgn_save(&qos_reg_rgns[qos_cci_m0], 1);
+	rockchip_reg_rgn_save(&qos_reg_rgns[qos_cci_m1], 1);
+	rockchip_reg_rgn_save(&qos_reg_rgns[qos_cci_m2], 1);
+	rockchip_reg_rgn_save(&qos_reg_rgns[qos_dap_lite], 1);
+
+	rockchip_reg_rgn_save(pd_core_reg_rgns, ARRAY_SIZE(pd_core_reg_rgns));
+}
+
+void pd_core_restore(void)
+{
+	/* slow mode */
+	mmio_write_32(BIGCORE_CRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(LITTLE_CRU_BASE + 0x280, 0x00030000);
+
+	rockchip_reg_rgn_restore(pd_core_reg_rgns, ARRAY_SIZE(pd_core_reg_rgns));
+
+	/* trigger lcore/bcore mem_cfg */
+	mmio_write_32(LITCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(1, 0x1, 1));
+	mmio_write_32(BIGCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(1, 0x1, 1));
+	udelay(1);
+	mmio_write_32(LITCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(0, 0x1, 1));
+	mmio_write_32(BIGCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(0, 0x1, 1));
+
+	/* wait lock */
+	pm_pll_wait_lock(CCI_CRU_BASE + 0x40);
+
+	/* restore mode */
+	mmio_write_32(BIGCORE_CRU_BASE + 0x280, WITH_16BITS_WMSK(b_cru_mode));
+	mmio_write_32(LITTLE_CRU_BASE + 0x280, WITH_16BITS_WMSK(l_cru_mode));
+
+	rockchip_reg_rgn_restore(&qos_reg_rgns[qos_cci_m0], 1);
+	rockchip_reg_rgn_restore(&qos_reg_rgns[qos_cci_m1], 1);
+	rockchip_reg_rgn_restore(&qos_reg_rgns[qos_cci_m2], 1);
+	rockchip_reg_rgn_restore(&qos_reg_rgns[qos_dap_lite], 1);
+
+	pvtplls_resume();
+}
+
+void pd_php_save(void)
+{
+	rockchip_reg_rgn_save(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+}
+
+void pd_php_restore(void)
+{
+	rockchip_reg_rgn_restore(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+}
+
+void pm_reg_rgns_init(void)
+{
+	rockchip_alloc_region_mem(qos_reg_rgns, ARRAY_SIZE(qos_reg_rgns));
+	rockchip_alloc_region_mem(pd_bcore_reg_rgns, ARRAY_SIZE(pd_bcore_reg_rgns));
+	rockchip_alloc_region_mem(pd_core_reg_rgns, ARRAY_SIZE(pd_core_reg_rgns));
+	rockchip_alloc_region_mem(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+	rockchip_alloc_region_mem(pd_usb2phy_reg_rgns, ARRAY_SIZE(pd_usb2phy_reg_rgns));
+}
diff --git a/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.h b/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.h
new file mode 100644
index 0000000..5b4f624
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef PM_PD_REGS_H
+#define PM_PD_REGS_H
+
+#include <stdint.h>
+
+void qos_save(void);
+void qos_restore(void);
+void pd_usb2phy_save(void);
+void pd_usb2phy_restore(void);
+void pd_secure_save(void);
+void pd_secure_restore(void);
+void pd_bcore_save(void);
+void pd_bcore_restore(void);
+void pd_core_save(void);
+void pd_core_restore(void);
+void pd_php_save(void);
+void pd_php_restore(void);
+void pd_center_save(void);
+void pd_center_restore(void);
+void pd_bus_save(void);
+void pd_bus_restore(void);
+void pd_pmu1_save(void);
+void pd_pmu1_restore_early(void);
+void pd_pmu1_restore(void);
+void pd_pmu0_save(void);
+void pd_pmu0_restore(void);
+
+void pm_reg_rgns_init(void);
+void pm_regs_rgn_dump(void);
+
+#endif
diff --git a/plat/rockchip/rk3576/drivers/pmu/pmu.c b/plat/rockchip/rk3576/drivers/pmu/pmu.c
new file mode 100644
index 0000000..c7db176
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/pmu.c
@@ -0,0 +1,1069 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <cpus_on_fixed_addr.h>
+#include <dmc_rk3576.h>
+#include <plat_pm_helpers.h>
+#include <plat_private.h>
+#include <pm_pd_regs.h>
+#include <secure.h>
+#include <soc.h>
+
+static struct psram_data_t *psram_sleep_cfg =
+	(struct psram_data_t *)&sys_sleep_flag_sram;
+
+struct rk3576_sleep_ddr_data {
+	uint32_t cru_mode_con, secure_cru_mode;
+	uint32_t gpio0a_iomux_l, gpio0a_iomux_h, gpio0b_iomux_l;
+	uint32_t pmu2_bisr_glb_con;
+	uint32_t pmu2_c0_ack_sel_con0, pmu2_c1_ack_sel_con0, pmu2_c2_ack_sel_con0;
+	uint32_t pmu2_fast_pwr_con, pmu2_pwrgt_sft_con0;
+	uint32_t pmu0grf_soc_con0, pmu0grf_soc_con1, pmu0grf_soc_con5;
+	uint32_t pmu_pd_st, bus_idle_st;
+	uint32_t sys_sgrf_soc_con0;
+	uint32_t ddrgrf_cha_con2, ddrgrf_chb_con2;
+};
+
+static struct rk3576_sleep_ddr_data ddr_data;
+
+void rockchip_plat_mmu_el3(void)
+{
+#ifdef PLAT_EXTRA_LD_SCRIPT
+	size_t sram_size;
+
+	sram_size = (char *)&__bl31_pmusram_text_end -
+		    (char *)PMUSRAM_BASE;
+	mmap_add_region(PMUSRAM_BASE, PMUSRAM_BASE,
+			sram_size, MT_MEMORY | MT_RO | MT_SECURE);
+
+	sram_size = (char *)&__bl31_pmusram_data_end -
+		    (char *)&__bl31_pmusram_data_start;
+	mmap_add_region((unsigned long)&__bl31_pmusram_data_start,
+			(unsigned long)&__bl31_pmusram_data_start,
+			sram_size, MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+}
+
+static int check_cpu_wfie(uint32_t cpu)
+{
+	uint32_t loop = 0;
+
+	while ((mmio_read_32(SYS_GRF_BASE + SYSGRF_STATUS0) & BIT(cpu + 12)) == 0 &&
+	       (mmio_read_32(PMU_BASE + PMU2_CLUSTER_PWR_ST) & BIT(cpu)) == 0 &&
+	       (loop < WFEI_CHECK_LOOP)) {
+		udelay(1);
+		loop++;
+	}
+
+	if (loop >= WFEI_CHECK_LOOP) {
+		WARN("%s: error, cpu%d (0x%x 0x%x)!\n", __func__, cpu,
+		     mmio_read_32(SYS_GRF_BASE + SYSGRF_STATUS0),
+		     mmio_read_32(PMU_BASE + PMU2_CLUSTER_PWR_ST));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline uint32_t cpu_power_domain_st(uint32_t cpu)
+{
+	return !!(mmio_read_32(PMU_BASE + PMU2_CLUSTER_PWR_ST) &
+		  BIT(cpu + 16));
+}
+
+static int cpu_power_domain_ctr(uint32_t cpu, uint32_t pd_state)
+{
+	uint32_t loop = 0;
+	int ret = 0;
+
+	mmio_write_32(PMU_BASE + PMU2_CPU_PWR_SFTCON(cpu),
+		      BITS_WITH_WMASK(pd_state, 0x1, 0));
+
+	dsb();
+	while ((cpu_power_domain_st(cpu) != pd_state) && (loop < PD_CTR_LOOP)) {
+		udelay(1);
+		loop++;
+	}
+
+	if (cpu_power_domain_st(cpu) != pd_state) {
+		WARN("%s: %d, %d, error!\n", __func__, cpu, pd_state);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static inline uint32_t get_cpus_pwr_domain_cfg_info(uint32_t cpu_id)
+{
+	uint32_t val;
+
+	if ((mmio_read_32(PMU_BASE + PMU2_CPU_PWR_SFTCON(cpu_id)) & BIT(0)) != 0)
+		return core_pwr_pd;
+
+	val = mmio_read_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id));
+	if ((val & BIT(pmu_cpu_pm_en)) != 0) {
+		if ((val & BIT(core_pwr_wfi_int)) != 0)
+			return core_pwr_wfi_int;
+		else if ((val & BIT(pmu_cpu_pm_sft_wakeup_en)) != 0)
+			return core_pwr_wfi_reset;
+		else
+			return core_pwr_wfi;
+	} else {
+		return -1;
+	}
+}
+
+static inline void set_cpus_pwr_domain_cfg_info(uint32_t cpu_id, uint32_t value)
+{
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+	uint32_t cfg_info;
+	/*
+	 * There are two ways to powering on or off on core.
+	 * 1) Control it power domain into on or off in PMU_PWRDN_CON reg
+	 * 2) Enable the core power manage in PMU_CORE_PM_CON reg,
+	 *	then, if the core enter into wfi, it power domain will be
+	 *	powered off automatically.
+	 */
+
+	cfg_info = get_cpus_pwr_domain_cfg_info(cpu_id);
+
+	if (cfg_info == core_pwr_pd) {
+		/* disable core_pm cfg */
+		mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+			      BITS_WITH_WMASK(0, 0xf, 0));
+		/* if the cores have be on, power off it firstly */
+		if (cpu_power_domain_st(cpu_id) == pmu_pd_on)
+			cpu_power_domain_ctr(cpu_id, pmu_pd_off);
+
+		cpu_power_domain_ctr(cpu_id, pmu_pd_on);
+	} else {
+		if (cpu_power_domain_st(cpu_id) == pmu_pd_on) {
+			WARN("%s: cpu%d is not in off,!\n", __func__, cpu_id);
+			return -EINVAL;
+		}
+
+		mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+			      BITS_WITH_WMASK(1, 0x1, pmu_cpu_pm_sft_wakeup_en));
+		dsb();
+	}
+
+	return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
+{
+	uint32_t core_pm_value;
+
+	if (cpu_power_domain_st(cpu_id) == pmu_pd_off)
+		return 0;
+
+	if (pd_cfg == core_pwr_pd) {
+		if (check_cpu_wfie(cpu_id))
+			return -EINVAL;
+
+		/* disable core_pm cfg */
+		mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+			      BITS_WITH_WMASK(0, 0xf, 0));
+
+		set_cpus_pwr_domain_cfg_info(cpu_id, pd_cfg);
+		cpu_power_domain_ctr(cpu_id, pmu_pd_off);
+	} else {
+		set_cpus_pwr_domain_cfg_info(cpu_id, pd_cfg);
+
+		core_pm_value = BIT(pmu_cpu_pm_en) | BIT(pmu_cpu_pm_dis_int);
+		if (pd_cfg == core_pwr_wfi_int)
+			core_pm_value |= BIT(pmu_cpu_pm_int_wakeup_en);
+		else if (pd_cfg == core_pwr_wfi_reset)
+			core_pm_value |= BIT(pmu_cpu_pm_sft_wakeup_en);
+
+		mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+			      BITS_WITH_WMASK(core_pm_value, 0xf, 0));
+		dsb();
+	}
+
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
+{
+	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+
+	assert(cpu_id < PLATFORM_CORE_COUNT);
+	assert(cpuson_flags[cpu_id] == 0);
+	cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+	cpuson_entry_point[cpu_id] = entrypoint;
+	dsb();
+
+	cpus_power_domain_on(cpu_id);
+
+	return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_off(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	cpus_power_domain_off(cpu_id, core_pwr_wfi);
+
+	return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(0, 0xf, 0));
+
+	return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_suspend(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	assert(cpu_id < PLATFORM_CORE_COUNT);
+	assert(cpuson_flags[cpu_id] == 0);
+	cpuson_flags[cpu_id] = PMU_CPU_AUTO_PWRDN;
+	cpuson_entry_point[cpu_id] = plat_get_sec_entrypoint();
+	dsb();
+
+	cpus_power_domain_off(cpu_id, core_pwr_wfi_int);
+
+	return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_resume(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	/* Disable core_pm */
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(0, 0xf, 0));
+
+	return PSCI_E_SUCCESS;
+}
+
+void nonboot_cpus_off(void)
+{
+	uint32_t boot_cpu, cpu;
+
+	boot_cpu = plat_my_core_pos();
+
+	/* turn off noboot cpus */
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
+		if (cpu == boot_cpu)
+			continue;
+
+		cpus_power_domain_off(cpu, core_pwr_pd);
+	}
+}
+
+static __pmusramfunc void ddr_resume(void)
+{
+	uint32_t key_upd_msk =
+		mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST) & BIT(pmu_pd_vop) ? 0x3 : 0x7;
+
+	/* hptimer is 24M here */
+	write_cntfrq_el0(24000000);
+
+	/* release cpu1~cpu7 to make pmu1_fsm exit */
+	mmio_write_32(CCI_GRF_BASE + CCIGRF_CON(4), 0xffffffff);
+	mmio_write_32(LITCORE_GRF_BASE + COREGRF_CPU_CON(1),
+		      BITS_WITH_WMASK(0x77, 0xff, 4));
+
+	/* wait pmu1 fsm over */
+	while ((mmio_read_32(PMU_BASE + PMU1_PWR_FSM) & 0xf) != 0)
+		;
+
+	/* SOC_CON19.vop/center/cci_ddr_hash_key_update_en */
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(19), 0x00070000);
+	dsb();
+
+	/* SOC_CON19.vop/center/cci_ddr_hash_key_update_en */
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(19), 0x00070000 | key_upd_msk);
+
+	/* SOC_STATUS.center/cci_ddr_hash_key_shift_ready */
+	while (((mmio_read_32(SYS_SGRF_BASE + SYSSGRF_SOC_STATUS) >> 12) & key_upd_msk) != key_upd_msk)
+		;
+
+	/* CCI_BASE.ctrl_override_reg Attr:W1C addrmap strobe */
+	mmio_setbits_32(CCI_BASE + 0x0, 0x1 << 29);
+
+	/* SOC_CON19.vop/center/cci_ddr_hash_key_auto_update_en */
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(19), 0x00700070);
+}
+
+static uint32_t clk_save[CRU_CLKGATE_CON_CNT + PHP_CRU_CLKGATE_CON_CNT +
+			 SECURE_CRU_CLKGATE_CON_CNT + SECURE_SCRU_CLKGATE_CON_CNT +
+			 PMU1CRU_CLKGATE_CON_CNT + PMU1SCRU_CLKGATE_CON_CNT];
+
+void clk_gate_con_disable(void)
+{
+	int i;
+
+	for (i = 0; i < CRU_CLKGATE_CON_CNT; i++) {
+		/* Don't open wdt0 clk (cru_gate16[7:8] */
+		if (i == 16) {
+			mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i),
+				      0xfe7f0000);
+		} else {
+			mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i),
+				      0xffff0000);
+		}
+	}
+
+	for (i = 0; i < PHP_CRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(PHP_CRU_BASE + PHP_CRU_CLKGATE_CON(i), 0xffff0000);
+
+	for (i = 0; i < SECURE_CRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(SECURE_CRU_BASE + SECURE_CRU_CLKGATE_CON(i), 0xffff0000);
+
+	for (i = 0; i < SECURE_SCRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(SECURE_CRU_BASE + SECURE_SCRU_CLKGATE_CON(i), 0xffff0000);
+
+	for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(PMU1_CRU_BASE + PMU1CRU_CLKGATE_CON(i), 0xffff0000);
+
+	for (i = 0; i < PMU1SCRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(PMU1_CRU_BASE + PMU1SCRU_CLKGATE_CON(i), 0xffff0000);
+}
+
+void clk_gate_con_save(void)
+{
+	int i, j = 0;
+
+	for (i = 0; i < CRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(CRU_BASE + CRU_CLKGATE_CON(i));
+
+	for (i = 0; i < PHP_CRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(PHP_CRU_BASE + PHP_CRU_CLKGATE_CON(i));
+
+	for (i = 0; i < SECURE_CRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(SECURE_CRU_BASE + SECURE_CRU_CLKGATE_CON(i));
+
+	for (i = 0; i < SECURE_SCRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(SECURE_CRU_BASE + SECURE_SCRU_CLKGATE_CON(i));
+
+	for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(PMU1_CRU_BASE + PMU1CRU_CLKGATE_CON(i));
+
+	for (i = 0; i < PMU1SCRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(PMU1_CRU_BASE + PMU1SCRU_CLKGATE_CON(i));
+}
+
+void clk_gate_con_restore(void)
+{
+	int i, j = 0;
+
+	for (i = 0; i < CRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+
+	for (i = 0; i < PHP_CRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(PHP_CRU_BASE + PHP_CRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+
+	for (i = 0; i < SECURE_CRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(SECURE_CRU_BASE + SECURE_CRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+
+	for (i = 0; i < SECURE_SCRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(SECURE_CRU_BASE + SECURE_SCRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+
+	for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(PMU1_CRU_BASE + PMU1CRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+
+	for (i = 0; i < PMU1SCRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(PMU1_CRU_BASE + PMU1SCRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+}
+
+void pmu_bus_idle_req(uint32_t bus, uint32_t state)
+{
+	uint32_t wait_cnt = 0;
+
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_SFTCON(bus / 16),
+		      BITS_WITH_WMASK(state, 0x1, bus % 16));
+
+	while (pmu_bus_idle_st(bus) != state ||
+	       pmu_bus_idle_ack(bus) != state) {
+		if (++wait_cnt > BUS_IDLE_LOOP)
+			break;
+		udelay(1);
+	}
+
+	if (wait_cnt > BUS_IDLE_LOOP)
+		WARN("%s: can't  wait state %d for bus %d (0x%x)\n",
+		     __func__, state, bus,
+		     mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST));
+}
+
+static inline uint32_t pmu_power_domain_st(uint32_t pd)
+{
+	return mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST) & BIT(pd) ?
+	       pmu_pd_off :
+	       pmu_pd_on;
+}
+
+int pmu_power_domain_ctr(uint32_t pd, uint32_t pd_state)
+{
+	uint32_t loop = 0;
+	int ret = 0;
+
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_SFTCON(pd / 16),
+		      BITS_WITH_WMASK(pd_state, 0x1, pd % 16));
+	dsb();
+
+	while ((pmu_power_domain_st(pd) != pd_state) && (loop < PD_CTR_LOOP)) {
+		udelay(1);
+		loop++;
+	}
+
+	if (pmu_power_domain_st(pd) != pd_state) {
+		WARN("%s: %d, %d, (0x%x) error!\n", __func__, pd, pd_state,
+		     mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST));
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int pmu_set_power_domain(uint32_t pd_id, uint32_t pd_state)
+{
+	uint32_t state;
+
+	if (pmu_power_domain_st(pd_id) == pd_state)
+		goto out;
+
+	if (pd_state == pmu_pd_on)
+		pmu_power_domain_ctr(pd_id, pd_state);
+
+	state = (pd_state == pmu_pd_off) ? pmu_bus_idle : pmu_bus_active;
+
+	switch (pd_id) {
+	case pmu_pd_npu:
+		pmu_bus_idle_req(pmu_bus_id_npusys, state);
+		break;
+	case pmu_pd_secure:
+		pmu_bus_idle_req(pmu_bus_id_secure, state);
+		break;
+	case pmu_pd_nvm:
+		pmu_bus_idle_req(pmu_bus_id_nvm, state);
+		break;
+	case pmu_pd_sd_gmac:
+		pmu_bus_idle_req(pmu_bus_id_gmac, state);
+		break;
+	case pmu_pd_audio:
+		pmu_bus_idle_req(pmu_bus_id_audio, state);
+		break;
+	case pmu_pd_php:
+		pmu_bus_idle_req(pmu_bus_id_php, state);
+		break;
+	case pmu_pd_subphp:
+		break;
+	case pmu_pd_vop:
+		pmu_bus_idle_req(pmu_bus_id_vop, state);
+		break;
+	case pmu_pd_vop_smart:
+		break;
+	case pmu_pd_vop_clst:
+		break;
+	case pmu_pd_vo1:
+		pmu_bus_idle_req(pmu_bus_id_vo1, state);
+		break;
+	case pmu_pd_vo0:
+		pmu_bus_idle_req(pmu_bus_id_vo0, state);
+		break;
+	case pmu_pd_usb:
+		pmu_bus_idle_req(pmu_bus_id_usb, state);
+		break;
+	case pmu_pd_vi:
+		pmu_bus_idle_req(pmu_bus_id_vi, state);
+		break;
+	case pmu_pd_vepu0:
+		pmu_bus_idle_req(pmu_bus_id_vepu0, state);
+		break;
+	case pmu_pd_vepu1:
+		pmu_bus_idle_req(pmu_bus_id_vepu1, state);
+		break;
+	case pmu_pd_vdec:
+		pmu_bus_idle_req(pmu_bus_id_vdec, state);
+		break;
+	case pmu_pd_vpu:
+		pmu_bus_idle_req(pmu_bus_id_vpu, state);
+		break;
+	case pmu_pd_nputop:
+		pmu_bus_idle_req(pmu_bus_id_nputop, state);
+		break;
+	case pmu_pd_npu0:
+		pmu_bus_idle_req(pmu_bus_id_npu0, state);
+		break;
+	case pmu_pd_npu1:
+		pmu_bus_idle_req(pmu_bus_id_npu1, state);
+		break;
+	case pmu_pd_gpu:
+		pmu_bus_idle_req(pmu_bus_id_gpu, state);
+		break;
+	default:
+		break;
+	}
+
+	if (pd_state == pmu_pd_off)
+		pmu_power_domain_ctr(pd_id, pd_state);
+
+out:
+	return 0;
+}
+
+static void pmu_power_domains_suspend(void)
+{
+	ddr_data.pmu_pd_st = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST);
+	ddr_data.bus_idle_st = mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST);
+	ddr_data.pmu2_pwrgt_sft_con0 = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_SFTCON(0));
+
+	qos_save();
+
+	pd_usb2phy_save();
+
+	if ((ddr_data.pmu_pd_st & BIT(pmu_pd_php)) == 0)
+		pd_php_save();
+}
+
+static void pmu_power_domains_resume(void)
+{
+	int i;
+
+	for (i = 0; i < pmu_pd_id_max; i++) {
+		/* vop smart/clst pd is not controlled by pmu */
+		if (i == pmu_pd_vop_smart || i == pmu_pd_vop_clst)
+			continue;
+
+		pmu_set_power_domain(i, !!(ddr_data.pmu_pd_st & BIT(i)));
+	}
+
+	/* restore vop smart/clst pd of pmu2_pwrgt_sft_con0 */
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_SFTCON(0),
+		      0x30000000 | ddr_data.pmu2_pwrgt_sft_con0);
+
+	for (i = pmu_bus_id_max - 1; i >= 0; i--)
+		pmu_bus_idle_req(i, !!(ddr_data.bus_idle_st & BIT(i)));
+
+	if ((ddr_data.pmu_pd_st & BIT(pmu_pd_php)) == 0)
+		pd_php_restore();
+
+	pd_usb2phy_restore();
+
+	qos_restore();
+}
+
+static void ddr_sleep_config(void)
+{
+	ddr_data.ddrgrf_cha_con2 =
+		mmio_read_32(DDR_GRF_BASE + DDRGRF_CHA_CON(2));
+	ddr_data.ddrgrf_chb_con2 =
+		mmio_read_32(DDR_GRF_BASE + DDRGRF_CHB_CON(2));
+
+	mmio_write_32(DDR_GRF_BASE + DDRGRF_CHA_CON(2), 0x0a000a00);
+	mmio_write_32(DDR_GRF_BASE + DDRGRF_CHB_CON(2), 0x0a000a00);
+}
+
+static void ddr_sleep_config_restore(void)
+{
+	mmio_write_32(DDR_GRF_BASE + DDRGRF_CHA_CON(2),
+		      WITH_16BITS_WMSK(ddr_data.ddrgrf_cha_con2));
+	mmio_write_32(DDR_GRF_BASE + DDRGRF_CHB_CON(2),
+		      WITH_16BITS_WMSK(ddr_data.ddrgrf_chb_con2));
+}
+
+static void sleep_pin_config(void)
+{
+	/* pwr0 sleep: gpio0_a3 */
+	mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(1),
+		      BITS_WITH_WMASK(0x7, 0xf, 0));
+	mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(0),
+		      BITS_WITH_WMASK(0, 0x1, 7));
+	mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_L,
+		      BITS_WITH_WMASK(9, 0xfu, 12));
+}
+
+static void pmu_sleep_config(void)
+{
+	uint32_t pmu1_wkup_int_con;
+	uint32_t pmu1_pwr_con, pmu1_ddr_pwr_con, pmu1cru_pwr_con, pmu1_pll_pd_con;
+	uint32_t pmu2_bus_idle_con[2], pmu2_pwr_gt_con[2];
+	uint32_t key_upd_msk = ddr_data.pmu_pd_st & BIT(pmu_pd_vop) ? 0x3 : 0x7;
+	uint32_t fw_lkp_upd_msk = ddr_data.pmu_pd_st & BIT(pmu_pd_npu) ? 0x3 : 0x7;
+	uint32_t fw_ddr_upd_msk = key_upd_msk;
+	uint32_t pmu_pd_st = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST);
+	uint32_t bus_idle_st = mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST);
+
+	ddr_data.pmu2_bisr_glb_con = mmio_read_32(PMU_BASE + PMU2_BISR_GLB_CON);
+
+	ddr_data.pmu2_fast_pwr_con =
+		mmio_read_32(PMU_BASE + PMU2_FAST_POWER_CON);
+
+	ddr_data.pmu2_c0_ack_sel_con0 =
+		mmio_read_32(PMU_BASE + PMU2_C0_PWRACK_BYPASS_CON(0));
+	ddr_data.pmu2_c1_ack_sel_con0 =
+		mmio_read_32(PMU_BASE + PMU2_C1_PWRACK_BYPASS_CON(0));
+	ddr_data.pmu2_c2_ack_sel_con0 =
+		mmio_read_32(PMU_BASE + PMU2_C2_PWRACK_BYPASS_CON(0));
+	ddr_data.pmu0grf_soc_con5 =
+		mmio_read_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(5));
+
+	/* set tsadc_shut_m0 pin iomux to gpio */
+	mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_L,
+		      BITS_WITH_WMASK(0, 0xf, 4));
+
+	pmu1_wkup_int_con =
+		BIT(pmu_wkup_cpu0_int) |
+		BIT(pmu_wkup_gpio0_int);
+
+	pmu1_pwr_con =
+		BIT(pmu_powermode_en) |
+		/* BIT(pmu_scu0_byp) | */
+		/* BIT(pmu_scu1_byp) | */
+		/* BIT(pmu_cci_byp) | */
+		/* BIT(pmu_bus_byp) | */
+		/* BIT(pmu_ddr_byp) | */
+		/* BIT(pmu_pwrgt_byp) | */
+		/* BIT(pmu_cru_byp) | */
+		BIT(pmu_qch_byp) |
+		/* BIT(pmu_wfi_byp) | */
+		BIT(pmu_slp_cnt_en);
+
+	pmu1_ddr_pwr_con = 0;
+
+	pmu1_pll_pd_con =
+		BIT(pmu_bpll_pd_en) |
+		BIT(pmu_lpll_pd_en) |
+		BIT(pmu_spll_pd_en) |
+		BIT(pmu_gpll_pd_en) |
+		BIT(pmu_cpll_pd_en) |
+		BIT(pmu_ppll_pd_en) |
+		BIT(pmu_aupll_pd_en) |
+		BIT(pmu_vpll_pd_en);
+
+	pmu1cru_pwr_con =
+		BIT(pmu_alive_osc_mode_en) |
+		BIT(pmu_io_sleep_en) |
+		BIT(pmu_power_off_en);
+
+	pmu2_bus_idle_con[0] = 0xffff & ~(bus_idle_st & 0xffff);
+	pmu2_bus_idle_con[1] = 0x3fff & ~(bus_idle_st >> 16);
+
+	pmu2_pwr_gt_con[0] = 0xffff & ~(pmu_pd_st & 0xffff);
+	pmu2_pwr_gt_con[1] = 0x03ff & ~(pmu_pd_st >> 16);
+
+	pmu2_pwr_gt_con[0] &=
+		~(BIT(pmu_pd_secure) |
+		  BIT(pmu_pd_bus) |
+		  BIT(pmu_pd_center) |
+		  BIT(pmu_pd_ddr));
+
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLEACK_BYPASS_CON, 0x00030003);
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON0, 0x03ff0000);
+
+	/* disable repair */
+	mmio_write_32(PMU_BASE + PMU2_BISR_GLB_CON, 0x00010000);
+
+	/* disable ddr_hash_key update.
+	 * enable disable ddr_hash_key auto update.
+	 * wait ddr_hash_key auto update.
+	 */
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(19),
+		      BITS_WITH_WMASK(key_upd_msk, 0x7, 8));
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON1,
+		      BITS_WITH_WMASK(fw_lkp_upd_msk, 0x7, 10));
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON1,
+		      BITS_WITH_WMASK(fw_ddr_upd_msk, 0x7u, 13));
+
+	mmio_write_32(PMU_BASE + PMU0_PMIC_STABLE_CNT_THRES, 24000 * 5);
+	mmio_write_32(PMU_BASE + PMU0_OSC_STABLE_CNT_THRES, 24000 * 5);
+
+	mmio_write_32(PMU_BASE + PMU1_OSC_STABLE_CNT_THRESH, 24000 * 5);
+	mmio_write_32(PMU_BASE + PMU1_STABLE_CNT_THRESH, 24000 * 5);
+
+	mmio_write_32(PMU_BASE + PMU1_SLEEP_CNT_THRESH, 24000 * 15);
+
+	/* Pmu's clk has switched to 24M back When pmu FSM counts
+	 * the follow counters, so we should use 24M to calculate
+	 * these counters.
+	 */
+	mmio_write_32(PMU_BASE + PMU0_WAKEUP_RST_CLR_CNT_THRES, 12000);
+
+	mmio_write_32(PMU_BASE + PMU1_WAKEUP_RST_CLR_CNT_THRESH, 12000);
+	mmio_write_32(PMU_BASE + PMU1_PLL_LOCK_CNT_THRESH, 12000);
+	mmio_write_32(PMU_BASE + PMU1_PWM_SWITCH_CNT_THRESH,
+		      24000 * 2);
+
+	mmio_write_32(PMU_BASE + PMU2_SCU0_PWRUP_CNT_THRESH, 0);
+	mmio_write_32(PMU_BASE + PMU2_SCU0_PWRDN_CNT_THRESH, 0);
+	mmio_write_32(PMU_BASE + PMU2_SCU0_STABLE_CNT_THRESH, 0);
+
+	mmio_write_32(PMU_BASE + PMU2_FAST_PWRUP_CNT_THRESH_0, 0);
+	mmio_write_32(PMU_BASE + PMU2_FAST_PWRDN_CNT_THRESH_0, 0);
+	mmio_write_32(PMU_BASE + PMU2_FAST_PWRUP_CNT_THRESH_1, 0);
+	mmio_write_32(PMU_BASE + PMU2_FAST_PWRDN_CNT_THRESH_1, 0);
+	mmio_write_32(PMU_BASE + PMU2_FAST_PWRUP_CNT_THRESH_2, 0);
+	mmio_write_32(PMU_BASE + PMU2_FAST_PWRDN_CNT_THRESH_2, 0);
+	mmio_write_32(PMU_BASE + PMU2_FAST_POWER_CON, 0xffff0007);
+
+	/* pmu_clst_idle_con */
+	mmio_write_32(PMU_BASE + PMU2_CLUSTER0_IDLE_CON, 0xffff0007);
+	mmio_write_32(PMU_BASE + PMU2_CLUSTER1_IDLE_CON, 0xffff0007);
+
+	/* pmu_scu_pwr_con */
+	/* L2's flush and idle by hardware, so need to enable wfil2 bypass */
+	mmio_write_32(PMU_BASE + PMU2_SCU0_PWR_CON, 0xffff020f);
+	mmio_write_32(PMU_BASE + PMU2_SCU1_PWR_CON, 0xffff020f);
+	mmio_write_32(PMU_BASE + PMU2_SCU0_AUTO_PWR_CON, 0x00070000);
+	mmio_write_32(PMU_BASE + PMU2_SCU1_AUTO_PWR_CON, 0x00070000);
+
+	mmio_write_32(PMU_BASE + PMU2_CCI_PWR_CON, 0xffff0009);
+
+	/* pmu_int_msk_con */
+	/* mmio_write_32(PMU_BASE + PMU1_INT_MASK_CON, BITS_WITH_WMASK(1, 0x1, 0)); */
+
+	/* pmu_pwr_con */
+	mmio_write_32(PMU_BASE + PMU1_PWR_CON, WITH_16BITS_WMSK(pmu1_pwr_con));
+
+	/* pmu_cru_pwr_conx */
+	mmio_write_32(PMU_BASE + PMU1_CRU_PWR_CON(0), WITH_16BITS_WMSK(pmu1cru_pwr_con));
+
+	/* pmu_ddr_pwr_con */
+	mmio_write_32(PMU_BASE + PMU0_DDR_RET_CON(1), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(0), WITH_16BITS_WMSK(pmu1_ddr_pwr_con));
+	mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(1), WITH_16BITS_WMSK(pmu1_ddr_pwr_con));
+	mmio_write_32(PMU_BASE + PMU1_DDR_AXIPWR_CON(0), 0x03ff03ff);
+	mmio_write_32(PMU_BASE + PMU1_DDR_AXIPWR_CON(1), 0x03ff03ff);
+
+	/* pll_pd */
+	mmio_write_32(PMU_BASE + PMU1_PLLPD_CON(0), WITH_16BITS_WMSK(pmu1_pll_pd_con));
+
+	/* bus idle */
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(0), WITH_16BITS_WMSK(pmu2_bus_idle_con[0]));
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(1), WITH_16BITS_WMSK(pmu2_bus_idle_con[1]));
+
+	/* power gate */
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(0), WITH_16BITS_WMSK(pmu2_pwr_gt_con[0]));
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(1), WITH_16BITS_WMSK(pmu2_pwr_gt_con[1]));
+
+	/* vol gate */
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(0), 0xffff0031);
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(1), 0xffff0200);
+
+	/* wakeup source */
+	mmio_write_32(PMU_BASE + PMU1_WAKEUP_INT_CON, pmu1_wkup_int_con);
+
+	/* ppll clamp */
+	mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(5), 0x00400040);
+
+	/* usbphy clamp */
+	mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(5),
+		      BITS_WITH_WMASK(0x9, 0x9, 2));
+
+	/* big core pwr ack bypass */
+	mmio_write_32(PMU_BASE + PMU2_C0_PWRACK_BYPASS_CON(0), 0x01000100);
+	mmio_write_32(PMU_BASE + PMU2_C1_PWRACK_BYPASS_CON(0), 0x01000100);
+	mmio_write_32(PMU_BASE + PMU2_C2_PWRACK_BYPASS_CON(0), 0x01000100);
+}
+
+static void pmu_sleep_restore(void)
+{
+	mmio_write_32(PMU_BASE + PMU0_INFO_TX_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_DEBUG_INFO_SEL, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_CLUSTER0_IDLE_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_SCU0_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_CCI_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_INT_MASK_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_CRU_PWR_CON(0), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(0), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(1), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_DDR_AXIPWR_CON(0), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_DDR_AXIPWR_CON(1), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_PLLPD_CON(0), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(0), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(1), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(0), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(1), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(0), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(1), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLEACK_BYPASS_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_WAKEUP_INT_CON, 0);
+	mmio_write_32(PMU_BASE + PMU2_FAST_POWER_CON,
+		      WITH_16BITS_WMSK(ddr_data.pmu2_fast_pwr_con));
+	mmio_write_32(PMU_BASE + PMU2_BISR_GLB_CON,
+		      WITH_16BITS_WMSK(ddr_data.pmu2_bisr_glb_con));
+
+	mmio_write_32(PMU_BASE + PMU2_C0_PWRACK_BYPASS_CON(0),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_c0_ack_sel_con0));
+	mmio_write_32(PMU_BASE + PMU2_C1_PWRACK_BYPASS_CON(0),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_c1_ack_sel_con0));
+	mmio_write_32(PMU_BASE + PMU2_C2_PWRACK_BYPASS_CON(0),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_c2_ack_sel_con0));
+
+	mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(5),
+		      WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con5));
+}
+
+static void secure_watchdog_disable(void)
+{
+	ddr_data.sys_sgrf_soc_con0 =
+		mmio_read_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0));
+
+	/* pause wdt_s */
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0),
+		      BITS_WITH_WMASK(1, 0x1, 14));
+}
+
+static void secure_watchdog_restore(void)
+{
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0),
+		      ddr_data.sys_sgrf_soc_con0 |
+		      BITS_WMSK(0x1, 14));
+
+	if (mmio_read_32(WDT_S_BASE + WDT_CR) & WDT_EN)
+		mmio_write_32(WDT_S_BASE + WDT_CRR, 0x76);
+}
+
+static void soc_sleep_config(void)
+{
+	ddr_data.pmu0grf_soc_con0 =
+		mmio_read_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(0));
+	ddr_data.pmu0grf_soc_con1 =
+		mmio_read_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(1));
+
+	ddr_data.gpio0a_iomux_l =
+		mmio_read_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_L);
+	ddr_data.gpio0a_iomux_h =
+		mmio_read_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_H);
+	ddr_data.gpio0b_iomux_l =
+		mmio_read_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0B_IOMUX_SEL_L);
+
+	sleep_pin_config();
+	pmu_sleep_config();
+	ddr_sleep_config();
+	secure_watchdog_disable();
+}
+
+static void soc_sleep_restore(void)
+{
+	secure_watchdog_restore();
+	ddr_sleep_config_restore();
+	pmu_sleep_restore();
+
+	mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_L,
+		      WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l));
+	mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_H,
+		      WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h));
+	mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0B_IOMUX_SEL_L,
+		      WITH_16BITS_WMSK(ddr_data.gpio0b_iomux_l));
+
+	mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(1),
+		      WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con1));
+	mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(0),
+		      WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con0));
+}
+
+static void pm_pll_suspend(void)
+{
+	ddr_data.cru_mode_con = mmio_read_32(CRU_BASE + 0x280);
+	ddr_data.secure_cru_mode = mmio_read_32(SECURE_CRU_BASE + 0x4280);
+
+	/* bpll gpll vpll aupll cpll spll switch to slow mode */
+	mmio_write_32(CRU_BASE + 0x280, 0x03ff0000);
+	mmio_write_32(SECURE_CRU_BASE + 0x4280, 0x00030000);
+
+	/* hclk_pmu_cm0_root_i_sel to 24M */
+	mmio_write_32(PMU1_CRU_BASE + PMU1CRU_CLKSEL_CON(4),
+		      BITS_WITH_WMASK(0x3, 0x3, 2));
+}
+
+static void pm_pll_restore(void)
+{
+	mmio_write_32(CRU_BASE + 0x280, WITH_16BITS_WMSK(ddr_data.cru_mode_con));
+	mmio_write_32(SECURE_CRU_BASE + 0x4280,
+		      WITH_16BITS_WMSK(ddr_data.secure_cru_mode));
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+	psram_sleep_cfg->pm_flag &= ~PM_WARM_BOOT_BIT;
+
+	clk_gate_con_save();
+	clk_gate_con_disable();
+	dmc_save();
+	pmu_power_domains_suspend();
+	soc_sleep_config();
+	pm_pll_suspend();
+	pd_core_save();
+
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+	pd_core_restore();
+	pm_pll_restore();
+	soc_sleep_restore();
+	pmu_power_domains_resume();
+	plat_rockchip_gic_cpuif_enable();
+	dmc_restore();
+	clk_gate_con_restore();
+
+	psram_sleep_cfg->pm_flag |= PM_WARM_BOOT_BIT;
+
+	return 0;
+}
+
+void __dead2 rockchip_soc_cores_pd_pwr_dn_wfi(const
+					      psci_power_state_t *target_state)
+{
+	psci_power_down_wfi();
+	/* should never reach here */
+	panic();
+}
+
+void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
+{
+	psci_power_down_wfi();
+	/* should never reach here */
+	panic();
+}
+
+static int rockchip_reboot_is_rbrom(void)
+{
+	return mmio_read_32(PMU0_GRF_BASE + PMU0GRF_OS_REG(16)) ==
+	       BOOT_BROM_DOWNLOAD;
+}
+
+static void rockchip_soc_soft_reset_check_rstout(void)
+{
+	/*
+	 * Maskrom enter maskrom-usb mode according to os_reg0 which
+	 * will be reset by NPOR. So disable tsadc_shut_m0 if we want
+	 * to maskrom-usb mode.
+	 */
+	if (rockchip_reboot_is_rbrom() != 0) {
+		/* write BOOT_BROM_DOWNLOAD to os_reg0 */
+		mmio_write_32(PMU1_GRF_BASE + PMU1GRF_OS_REG(0), BOOT_BROM_DOWNLOAD);
+
+		/* disable first/tsadc/wdt reset output */
+		mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(0), 0x00070000);
+
+		/* clear reset hold */
+		mmio_write_32(PMU0SGRF_BASE + PMU0SGRF_SOC_CON(1), 0xffff0000);
+		mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(16), 0xffff0000);
+		mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(17), 0xffff0000);
+	}
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+	rockchip_soc_soft_reset_check_rstout();
+
+	/* pll slow mode */
+	mmio_write_32(CRU_BASE + CRU_MODE_CON, 0x003f0000);
+
+	dsb();
+	isb();
+
+	INFO("system reset......\n");
+	mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
+
+	/*
+	 * Maybe the HW needs some times to reset the system,
+	 * so we do not hope the core to execute valid codes.
+	 */
+	psci_power_down_wfi();
+	/* should never reach here */
+	panic();
+}
+
+void __dead2 rockchip_soc_system_off(void)
+{
+	INFO("system poweroff......\n");
+
+	/* gpio0_a3 config output */
+	mmio_write_32(GPIO0_BASE + GPIO_SWPORT_DDR_L,
+		      BITS_WITH_WMASK(1, 0x1, 3));
+
+	/* gpio0_a3 config output high level */
+	mmio_write_32(GPIO0_BASE + GPIO_SWPORT_DR_L,
+		      BITS_WITH_WMASK(1, 0x1, 3));
+	dsb();
+
+	/*
+	 * Maybe the HW needs some times to reset the system,
+	 * so we do not hope the core to execute valid codes.
+	 */
+	psci_power_down_wfi();
+	/* should never reach here */
+	panic();
+}
+
+static void rockchip_pmu_pd_repair_init(void)
+{
+	INFO("enable memory repair\n");
+	/* Enable gpu and npu repair */
+	mmio_write_32(PMU_BASE + PMU2_BISR_PDGEN_CON(1),
+		      BITS_WITH_WMASK(0xf, 0xf, 6));
+}
+
+void plat_rockchip_pmu_init(void)
+{
+	int cpu;
+
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+		cpuson_flags[cpu] = 0;
+
+	psram_sleep_cfg->sp = PSRAM_SP_TOP;
+	psram_sleep_cfg->ddr_func = (uint64_t)ddr_resume;
+	psram_sleep_cfg->ddr_data = 0;
+	psram_sleep_cfg->ddr_flag = 0;
+	psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
+	psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+
+	nonboot_cpus_off();
+
+	/*
+	 * When perform idle operation, corresponding clock can be
+	 * opened or gated automatically.
+	 */
+	mmio_write_32(PMU_BASE + PMU2_NOC_AUTO_CON(0), 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU2_NOC_AUTO_CON(1), 0xffffffff);
+
+	/* remap pmusram to 0x00000000 */
+	mmio_write_32(PMU0SGRF_BASE + PMU0SGRF_SOC_CON(2), BITS_WITH_WMASK(1, 0x3, 0));
+
+	/* enable power off VD_NPU by hrdware */
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(0),
+		      BITS_WITH_WMASK(0x1, 0x1, 0));
+
+	rockchip_pmu_pd_repair_init();
+
+	pm_reg_rgns_init();
+}
diff --git a/plat/rockchip/rk3576/drivers/pmu/pmu.h b/plat/rockchip/rk3576/drivers/pmu/pmu.h
new file mode 100644
index 0000000..6340e3f
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/pmu.h
@@ -0,0 +1,578 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#include <assert.h>
+
+#include <mmio.h>
+
+/* PMU */
+#define PMU1_OFFSET			0x10000
+#define PMU2_OFFSET			0x20000
+
+#define PMU0_PWR_CON			0x0000
+#define PMU0_PWR_STATUS			0x0004
+#define PMU0_WAKEUP_INT_CON		0x0008
+#define PMU0_WAKEUP_INT_ST		0x000c
+#define PMU0_PMIC_STABLE_CNT_THRES	0x0010
+#define PMU0_WAKEUP_RST_CLR_CNT_THRES	0x0014
+#define PMU0_OSC_STABLE_CNT_THRES	0x0018
+#define PMU0_PWR_C0_STABLE_CON		0x001c
+#define PMU0_DDR_RET_CON(i)		(0x0020 + (i) * 4)
+#define PMU0_INFO_TX_CON		0x0030
+
+#define PMU1_VERSION_ID			(PMU1_OFFSET + 0x0000)
+#define PMU1_PWR_CON			(PMU1_OFFSET + 0x0004)
+#define PMU1_PWR_FSM			(PMU1_OFFSET + 0x0008)
+#define PMU1_INT_MASK_CON		(PMU1_OFFSET + 0x000c)
+#define PMU1_WAKEUP_INT_CON		(PMU1_OFFSET + 0x0010)
+#define PMU1_WAKEUP_INT_ST		(PMU1_OFFSET + 0x0014)
+#define PMU1_DDR_PWR_CON(i)		(PMU1_OFFSET + 0x0100 + (i) * 4)
+#define PMU1_DDR_PWR_SFTCON(i)		(PMU1_OFFSET + 0x0110 + (i) * 4)
+#define PMU1_DDR_AXIPWR_CON(i)		(PMU1_OFFSET + 0x0120 + (i) * 4)
+#define PMU1_DDR_AXIPWR_SFTCON(i)	(PMU1_OFFSET + 0x0130 + (i) * 4)
+#define PMU1_DDR_PWR_FSM		(PMU1_OFFSET + 0x0140)
+#define PMU1_DDR_PWR_ST			(PMU1_OFFSET + 0x0144)
+#define PMU1_DDR_AXIPWR_ST		(PMU1_OFFSET + 0x0148)
+#define PMU1_CRU_PWR_CON(i)		(PMU1_OFFSET + 0x0200 + (i) * 4)
+#define PMU1_CRU_PWR_SFTCON(i)		(PMU1_OFFSET + 0x0208 + (i) * 4)
+#define PMU1_CRU_PWR_FSM		(PMU1_OFFSET + 0x0210)
+#define PMU1_PLLPD_CON(i)		(PMU1_OFFSET + 0x0220 + (i) * 4)
+#define PMU1_PLLPD_SFTCON(i)		(PMU1_OFFSET + 0x0228 + (i) * 4)
+#define PMU1_STABLE_CNT_THRESH		(PMU1_OFFSET + 0x0300)
+#define PMU1_OSC_STABLE_CNT_THRESH	(PMU1_OFFSET + 0x0304)
+#define PMU1_WAKEUP_RST_CLR_CNT_THRESH	(PMU1_OFFSET + 0x0308)
+#define PMU1_PLL_LOCK_CNT_THRESH	(PMU1_OFFSET + 0x030c)
+#define PMU1_WAKEUP_TIMEOUT_THRESH	(PMU1_OFFSET + 0x0310)
+#define PMU1_PWM_SWITCH_CNT_THRESH	(PMU1_OFFSET + 0x0314)
+#define PMU1_SLEEP_CNT_THRESH		(PMU1_OFFSET + 0x0318)
+#define PMU1_INFO_TX_CON		(PMU1_OFFSET + 0x0400)
+
+#define PMU2_SCU0_PWR_CON		(PMU2_OFFSET + 0x0000)
+#define PMU2_SCU1_PWR_CON		(PMU2_OFFSET + 0x0004)
+#define PMU2_SCU0_PWR_SFTCON		(PMU2_OFFSET + 0x0008)
+#define PMU2_SCU1_PWR_SFTCON		(PMU2_OFFSET + 0x000c)
+#define PMU2_SCU0_AUTO_PWR_CON		(PMU2_OFFSET + 0x0010)
+#define PMU2_SCU1_AUTO_PWR_CON		(PMU2_OFFSET + 0x0014)
+#define PMU2_SCU_PWR_FSM_STATUS		(PMU2_OFFSET + 0x0018)
+#define PMU2_DBG_PWR_CON(i)		(PMU2_OFFSET + 0x001c + (i) * 4)
+#define PMU2_CLUSTER_PWR_ST		(PMU2_OFFSET + 0x0024)
+#define PMU2_CLUSTER0_IDLE_CON		(PMU2_OFFSET + 0x0028)
+#define PMU2_CLUSTER1_IDLE_CON		(PMU2_OFFSET + 0x002c)
+#define PMU2_CLUSTER0_IDLE_SFTCON	(PMU2_OFFSET + 0x0030)
+#define PMU2_CLUSTER1_IDLE_SFTCON	(PMU2_OFFSET + 0x0034)
+#define PMU2_CLUSTER_IDLE_ACK		(PMU2_OFFSET + 0x0038)
+#define PMU2_CLUSTER_IDLE_ST		(PMU2_OFFSET + 0x003c)
+#define PMU2_SCU0_PWRUP_CNT_THRESH	(PMU2_OFFSET + 0x0040)
+#define PMU2_SCU0_PWRDN_CNT_THRESH	(PMU2_OFFSET + 0x0044)
+#define PMU2_SCU0_STABLE_CNT_THRESH	(PMU2_OFFSET + 0x0048)
+#define PMU2_SCU1_PWRUP_CNT_THRESH	(PMU2_OFFSET + 0x004c)
+#define PMU2_SCU1_PWRDN_CNT_THRESH	(PMU2_OFFSET + 0x0050)
+#define PMU2_SCU1_STABLE_CNT_THRESH	(PMU2_OFFSET + 0x0054)
+#define PMU2_CPU_AUTO_PWR_CON(i)	(PMU2_OFFSET + 0x0080 + ((i)) * 4)
+#define PMU2_CPU_PWR_SFTCON(i)		(PMU2_OFFSET + 0x00a0 + ((i)) * 4)
+#define PMU2_CCI_PWR_CON		(PMU2_OFFSET + 0x00e0)
+#define PMU2_CCI_PWR_SFTCON		(PMU2_OFFSET + 0x00e4)
+#define PMU2_CCI_PWR_ST			(PMU2_OFFSET + 0x00e8)
+#define PMU2_CCI_POWER_STATE		(PMU2_OFFSET + 0x00ec)
+#define PMU2_BUS_IDLE_CON(i)		(PMU2_OFFSET + 0x0100 + (i) * 4)
+#define PMU2_BUS_IDLE_SFTCON(i)		(PMU2_OFFSET + 0x0110 + (i) * 4)
+#define PMU2_BUS_IDLE_ACK		(PMU2_OFFSET + 0x0120)
+#define PMU2_BUS_IDLE_ST		(PMU2_OFFSET + 0x0128)
+#define PMU2_NOC_AUTO_CON(i)		(PMU2_OFFSET + 0x0130 + (i) * 4)
+#define PMU2_NOC_AUTO_SFTCON(i)		(PMU2_OFFSET + 0x0140 + (i) * 4)
+#define PMU2_BUS_IDLEACK_BYPASS_CON	(PMU2_OFFSET + 0x0150)
+#define PMU2_PWR_GATE_CON(i)		(PMU2_OFFSET + 0x0200 + (i) * 4)
+#define PMU2_PWR_GATE_SFTCON(i)		(PMU2_OFFSET + 0x0210 + (i) * 4)
+#define PMU2_VOL_GATE_SFTCON(i)		(PMU2_OFFSET + 0x0220 + (i) * 4)
+#define PMU2_PWR_GATE_ST		(PMU2_OFFSET + 0x0230)
+#define PMU2_PWR_GATE_FSM		(PMU2_OFFSET + 0x0238)
+#define PMU2_PD_DWN_ACK_STATE(i)	(PMU2_OFFSET + 0x0240 + (i) * 4)
+#define PMU2_PD_DWN_LC_ACK_STATE(i)	(PMU2_OFFSET + 0x0248 + (i) * 4)
+#define PMU2_PD_DWN_MEM_ACK_STATE(i)	(PMU2_OFFSET + 0x0250 + (i) * 4)
+#define PMU2_PWR_UP_C0_STABLE_CON(i)	(PMU2_OFFSET + 0x0260 + (i) * 4)
+#define PMU2_PWR_DWN_C0_STABLE_CON(i)	(PMU2_OFFSET + 0x0270 + (i) * 4)
+#define PMU2_PWR_STABLE_C0_CNT_THRES	(PMU2_OFFSET + 0x027c)
+#define PMU2_FAST_POWER_CON		(PMU2_OFFSET + 0x0284)
+#define PMU2_FAST_PWRUP_CNT_THRESH_0	(PMU2_OFFSET + 0x0288)
+#define PMU2_FAST_PWRDN_CNT_THRESH_0	(PMU2_OFFSET + 0x028c)
+#define PMU2_FAST_PWRUP_CNT_THRESH_1	(PMU2_OFFSET + 0x0290)
+#define PMU2_FAST_PWRDN_CNT_THRESH_1	(PMU2_OFFSET + 0x0294)
+#define PMU2_FAST_PWRUP_CNT_THRESH_2	(PMU2_OFFSET + 0x0298)
+#define PMU2_FAST_PWRDN_CNT_THRESH_2	(PMU2_OFFSET + 0x029c)
+#define PMU2_MEM_PWR_GATE_SFTCON(i)	(PMU2_OFFSET + 0x0300)
+#define PMU2_SUBMEM_PWR_GATE_SFTCON(i)	(PMU2_OFFSET + 0x0310)
+#define PMU2_SUBMEM_PWR_ACK_BYPASS_SFTCON(i)	(PMU2_OFFSET + 0x0320)
+#define PMU2_SUBMEM_PWR_GATE_STATUS	(PMU2_OFFSET + 0x0328)
+#define PMU2_QCHANNEL_PWR_CON0		(PMU2_OFFSET + 0x0400)
+#define PMU2_QCHANNEL_PWR_SFTCON0	(PMU2_OFFSET + 0x0404)
+#define PMU2_QCHANNEL_STATUS0		(PMU2_OFFSET + 0x0408)
+#define PMU2_C0_PWRACK_BYPASS_CON(i)	(PMU2_OFFSET + 0x0380 + (i) * 4)
+#define PMU2_C1_PWRACK_BYPASS_CON(i)	(PMU2_OFFSET + 0x0390 + (i) * 4)
+#define PMU2_C2_PWRACK_BYPASS_CON(i)	(PMU2_OFFSET + 0x03a0 + (i) * 4)
+#define PMU2_DEBUG_INFO_SEL		(PMU2_OFFSET + 0x03f0)
+#define PMU2_BISR_GLB_CON		(PMU2_OFFSET + 0x500)
+#define PMU2_BISR_TIMEOUT_THRES		(PMU2_OFFSET + 0x504)
+#define PMU2_BISR_PDGEN_CON(i)		(PMU2_OFFSET + 0x510 + (i) * 4)
+#define PMU2_BISR_PDGEN_SFTCON(i)	(PMU2_OFFSET + 0x520 + (i) * 4)
+#define PMU2_BISR_PDGDONE_CON(i)	(PMU2_OFFSET + 0x530 + (i) * 4)
+#define PMU2_BISR_PDGINIT_CON(i)	(PMU2_OFFSET + 0x540 + (i) * 4)
+#define PMU2_BISR_PDGDONE_STATUS(i)	(PMU2_OFFSET + 0x550 + (i) * 4)
+#define PMU2_BISR_PDGCEDIS_STATUS(i)	(PMU2_OFFSET + 0x560 + (i) * 4)
+#define PMU2_BISR_PWR_REPAIR_STATUS(i)	(PMU2_OFFSET + 0x570 + (i) * 4)
+
+/* PMU1CRU */
+#define PMU1CRU_CLKSEL_CON(i)		((i) * 0x4 + 0x300)
+#define PMU1CRU_CLKSEL_CON_CNT		22
+#define PMU1CRU_CLKGATE_CON(i)		((i) * 0x4 + 0x800)
+#define PMU1CRU_CLKGATE_CON_CNT		8
+#define PMU1CRU_SOFTRST_CON(i)		((i) * 0x4 + 0xa00)
+#define PMU1CRU_SOFTRST_CON_CNT		8
+#define PMU1CRU_DEEPSLOW_DET_CON	0xb40
+#define PMU1CRU_DEEPSLOW_DET_ST		0xb44
+
+/* PMU1SCRU */
+#define PMU1SCRU_CLKSEL_CON(i)		((i) * 0x4 + 0x4000)
+#define PMU1SCRU_CLKSEL_CON_CNT		3
+#define PMU1SCRU_CLKGATE_CON(i)		((i) * 0x4 + 0x4028)
+#define PMU1SCRU_CLKGATE_CON_CNT		3
+#define PMU1SCRU_SOFTRST_CON(i)		((i) * 0x4 + 0x4050)
+#define PMU1SCRU_SOFTRST_CONCNT		3
+
+/* PMU0GRF */
+#define PMU0GRF_SOC_CON(i)		((i) * 4)
+#define PMU0GRF_IO_RET_CON(i)		(0x20 + (i) * 4)
+#define PMU0GRF_OS_REG(i)		((i) * 4)
+
+/* PMU1GRF */
+#define PMU1GRF_SOC_CON(i)		((i) * 4)
+#define PMU1GRF_SOC_ST			0x60
+#define PMU1GRF_MEM_CON(i)		(0x80 + (i) * 4)
+#define PMU1GRF_OS_REG(i)		(0x200 + (i) * 4)
+
+#define PMU_MCU_HALT			BIT(7)
+#define PMU_MCU_SLEEP			BIT(9)
+#define PMU_MCU_DEEPSLEEP		BIT(10)
+#define PMU_MCU_STOP_MSK		\
+	(PMU_MCU_HALT | PMU_MCU_SLEEP | PMU_MCU_DEEPSLEEP)
+
+#define CORES_PM_DISABLE		0x0
+
+/* pmuioc */
+#define PMUIO0_IOC_GPIO0A_IOMUX_SEL_L	0x000
+#define PMUIO0_IOC_GPIO0A_IOMUX_SEL_H	0x004
+#define PMUIO0_IOC_GPIO0B_IOMUX_SEL_L	0x008
+
+#define PMUIO1_IOC_GPIO0B_IOMUX_SEL_H	0x000
+#define PMUIO1_IOC_GPIO0C_IOMUX_SEL_L	0x004
+#define PMUIO1_IOC_GPIO0C_IOMUX_SEL_H	0x008
+#define PMUIO1_IOC_GPIO0D_IOMUX_SEL_L	0x00c
+#define PMUIO1_IOC_GPIO0D_IOMUX_SEL_H	0x010
+
+/* PMU_PWR_CON */
+enum pmu0_pwr_con {
+	pmu_powermode0_en = 0,
+	pmu_pmu1_pd_byp = 1,
+	pmu_pmu1_bus_byp = 2,
+	pmu_pmu0_wkup_byp = 3,
+	pmu_pmu0_pmic_byp = 4,
+	pmu_pmu0_reset_byp = 5,
+	pmu_pmu0_freq_switch_byp = 6,
+	pmu_pmu0_osc_dis_byp = 7,
+	pmu_pmu1_pwrgt = 8,
+	pmu_pmu1_pwrgt_sft = 9,
+	pmu_pmu1_mempwr_sft_gt = 10,
+	pmu_pmu1_idle_en = 11,
+	pmu_pmu1_idle_sft_en = 12,
+	pmu_pmu1_noc_auto_en = 13,
+	pmu_pmu1_off_io_en = 14,
+};
+
+enum pmu1_pwr_con {
+	pmu_powermode_en = 0,
+	pmu_scu0_byp = 1,
+	pmu_scu1_byp = 2,
+	pmu_cci_byp = 3,
+	pmu_bus_byp = 4,
+	pmu_ddr_byp = 5,
+	pmu_pwrgt_byp = 6,
+	pmu_cru_byp = 7,
+	pmu_qch_byp = 8,
+	pmu_wfi_byp = 12,
+	pmu_slp_cnt_en = 13,
+};
+
+enum pmu_wakeup_int {
+	pmu_wkup_cpu0_int = 0,
+	pmu_wkup_cpu1_int = 1,
+	pmu_wkup_cpu2_int = 2,
+	pmu_wkup_cpu3_int = 3,
+	pmu_wkup_cpu4_int = 4,
+	pmu_wkup_cpu5_int = 5,
+	pmu_wkup_cpu6_int = 6,
+	pmu_wkup_cpu7_int = 7,
+	pmu_wkup_gpio0_int = 8,
+	pmu_wkup_sdmmc_int = 9,
+	pmu_wkup_sdio_int = 10,
+	pmu_wkup_usbdev_int = 11,
+	pmu_wkup_uart_int = 12,
+	pmu_wkup_mcu_int = 13,
+	pmu_wkup_timer_int = 14,
+	pmu_wkup_sys_int = 15,
+	pmu_wkup_pwm_int = 16,
+	pmu_wkup_tsadc_int = 17,
+	pmu_wkup_hptimer_int = 18,
+	pmu_wkup_saradc_int = 19,
+	pmu_wkup_timeout = 20,
+};
+
+/* PMU_DDR_PWR_CON */
+enum pmu_ddr_pwr_con {
+	pmu_ddr_sref_c_en = 0,
+	pmu_ddr_ioret_en = 1,
+	pmu_ddr_ioret_exit_en = 2,
+	pmu_ddr_rstiov_en = 3,
+	pmu_ddr_rstiov_exit_en = 4,
+	pmu_ddr_gating_c_en = 5,
+	pmu_ddr_gating_p_en = 6,
+};
+
+/* PMU_CRU_PWR_CON0 */
+enum pmu_cru_pwr_con0 {
+	pmu_alive_32k_en = 0,
+	pmu_osc_dis_en = 1,
+	pmu_wakeup_rst_en = 2,
+	pmu_input_clamp_en = 3,
+	pmu_alive_osc_mode_en = 4,
+	pmu_power_off_en = 5,
+	pmu_pwm_switch_en = 6,
+	pmu_pwm_gpio_ioe_en = 7,
+	pmu_pwm_switch_io = 8,
+	pmu_io_sleep_en = 9,
+};
+
+/* PMU_CRU_PWR_CON1 */
+enum pmu_cru_pwr_con1 {
+	pmu_bus_clksrc_gt_en = 0,
+	pmu_vpu_clksrc_gt_en = 1,
+	pmu_vo_clksrc_gt_en = 2,
+	pmu_gpu_clksrc_gt_en = 3,
+	pmu_rkenc_clksrc_gt_en = 4,
+	pmu_rkvdec_clksrc_gt_en = 5,
+	pmu_core_clksrc_gt_en = 6,
+	pmu_ddr_clksrc_gt_en = 7,
+};
+
+/* PMU_SCU_PWR_CON */
+enum pmu_scu_pwr_con {
+	pmu_l2_flush_en = 0,
+	pmu_l2_ilde_en = 1,
+	pmu_scu_pd_en = 2,
+	pmu_scu_pwroff_en = 3,
+	pmu_clst_cpu_pd_en = 5,
+	pmu_std_wfi_bypass = 8,
+	pmu_std_wfil2_bypass = 9,
+	pmu_scu_vol_gt_en = 10,
+};
+
+/* PMU_PLLPD_CON */
+enum pmu_pllpd_con {
+	pmu_d0apll_pd_en = 0,
+	pmu_d0bpll_pd_en = 1,
+	pmu_d1apll_pd_en = 2,
+	pmu_d1bpll_pd_en = 3,
+	pmu_bpll_pd_en = 4,
+	pmu_lpll_pd_en = 5,
+	pmu_spll_pd_en = 6,
+	pmu_gpll_pd_en = 7,
+	pmu_cpll_pd_en = 8,
+	pmu_ppll_pd_en = 9,
+	pmu_aupll_pd_en = 10,
+	pmu_vpll_pd_en = 11,
+};
+
+/* PMU_CLST_PWR_ST */
+enum pmu_clst_pwr_st {
+	pmu_cpu0_wfi = 0,
+	pmu_cpu1_wfi = 1,
+	pmu_cpu2_wfi = 2,
+	pmu_cpu3_wfi = 3,
+	pmu_cpu4_wfi = 4,
+	pmu_cpu5_wfi = 5,
+	pmu_cpu6_wfi = 6,
+	pmu_cpu7_wfi = 7,
+	pmu_scu0_standbywfil2 = 8,
+	pmu_scu1_standbywfil2 = 9,
+	pmu_scu0_l2flushdone = 10,
+	pmu_scu1_l2flushdone = 11,
+	pmu_cpu0_pd_st = 16,
+	pmu_cpu1_pd_st = 17,
+	pmu_cpu2_pd_st = 18,
+	pmu_cpu3_pd_st = 19,
+	pmu_cpu4_pd_st = 20,
+	pmu_cpu5_pd_st = 21,
+	pmu_cpu6_pd_st = 22,
+	pmu_cpu7_pd_st = 23,
+	pmu_scu0_pd_st = 24,
+	pmu_scu1_pd_st = 25,
+};
+
+/* PMU_CLST_IDLE_CON */
+enum pmu_clst_idle_con {
+	pmu_adb400s_idle_req = 0,
+	pmu_clst_biu_idle_req = 1,
+	pmu_clst_clk_gt_msk = 2,
+};
+
+enum cores_pm_ctr_mode {
+	core_pwr_pd = 0,
+	core_pwr_wfi = 1,
+	core_pwr_wfi_int = 2,
+	core_pwr_wfi_reset = 3,
+};
+
+/* PMU_CPUX_AUTO_PWR_CON */
+enum pmu_cpu_auto_pwr_con {
+	pmu_cpu_pm_en = 0,
+	pmu_cpu_pm_int_wakeup_en = 1,
+	pmu_cpu_pm_dis_int = 2,
+	pmu_cpu_pm_sft_wakeup_en = 3,
+};
+
+enum qos_id {
+	qos_decom = 0,
+	qos_dmac0 = 1,
+	qos_dmac1 = 2,
+	qos_dmac2 = 3,
+	qos_bus_mcu = 4,
+	qos_can0 = 5,
+	qos_can1 = 6,
+	qos_cci_m0 = 7,
+	qos_cci_m1 = 8,
+	qos_cci_m2 = 9,
+	qos_dap_lite = 10,
+	qos_hdcp1 = 11,
+	qos_ddr_mcu = 12,
+	qos_fspi1 = 13,
+	qos_gmac0 = 14,
+	qos_gmac1 = 15,
+	qos_sdio = 16,
+	qos_sdmmc = 17,
+	qos_flexbus = 18,
+	qos_gpu = 19,
+	qos_vepu1 = 20,
+	qos_npu_mcu = 21,
+	qos_npu_nsp0 = 22,
+	qos_npu_nsp1 = 23,
+	qos_npu_m0 = 24,
+	qos_npu_m1 = 25,
+	qos_npu_m0ro = 26,
+	qos_npu_m1ro = 27,
+	qos_emmc = 28,
+	qos_fspi0 = 29,
+	qos_mmu0 = 30,
+	qos_mmu1 = 31,
+	qos_pmu_mcu = 32,
+	qos_rkvdec = 33,
+	qos_crypto = 34,
+	qos_mmu2 = 35,
+	qos_ufshc = 36,
+	qos_vepu0 = 37,
+	qos_isp_mro = 38,
+	qos_isp_mwo = 39,
+	qos_vicap_m0 = 40,
+	qos_vpss_mro = 41,
+	qos_vpss_mwo = 42,
+	qos_hdcp0 = 43,
+	qos_vop_m0 = 44,
+	qos_vop_m1ro = 45,
+	qos_ebc = 46,
+	qos_rga0 = 47,
+	qos_rga1 = 48,
+	qos_jpeg = 49,
+	qos_vdpp = 50,
+	qos_dma2ddr = 51,
+};
+
+enum pmu_bus_id {
+	pmu_bus_id_gpu = 0,
+	pmu_bus_id_npu0 = 1,
+	pmu_bus_id_npu1 = 2,
+	pmu_bus_id_nputop = 3,
+	pmu_bus_id_npusys = 4,
+	pmu_bus_id_vpu = 5,
+	pmu_bus_id_vdec = 6,
+	pmu_bus_id_vepu0 = 7,
+	pmu_bus_id_vepu1 = 8,
+	pmu_bus_id_vi = 9,
+	pmu_bus_id_usb = 10,
+	pmu_bus_id_vo0 = 11,
+	pmu_bus_id_vo1 = 12,
+	pmu_bus_id_vop = 13,
+	pmu_bus_id_vop_nocddrsch = 14,
+	pmu_bus_id_php = 15,
+	pmu_bus_id_audio = 16,
+	pmu_bus_id_gmac = 17,
+	pmu_bus_id_nvm = 18,
+	pmu_bus_id_center_nocddrsch = 19,
+	pmu_bus_id_center_nocmain = 20,
+	pmu_bus_id_ddr = 21,
+	pmu_bus_id_ddrsch0 = 22,
+	pmu_bus_id_ddrsch1 = 23,
+	pmu_bus_id_bus = 24,
+	pmu_bus_id_secure = 25,
+	pmu_bus_id_top = 26,
+	pmu_bus_id_vo0vop_chn = 27,
+	pmu_bus_id_cci = 28,
+	pmu_bus_id_cci_nocddrsch = 29,
+	pmu_bus_id_max,
+};
+
+enum pmu_pd_id {
+	pmu_pd_npu = 0,
+	pmu_pd_bus = 1,
+	pmu_pd_secure = 2,
+	pmu_pd_center = 3,
+	pmu_pd_ddr = 4,
+	pmu_pd_cci = 5,
+	pmu_pd_nvm = 6,
+	pmu_pd_sd_gmac = 7,
+	pmu_pd_audio = 8,
+	pmu_pd_php = 9,
+	pmu_pd_subphp = 10,
+	pmu_pd_vop = 11,
+	pmu_pd_vop_smart = 12,
+	pmu_pd_vop_clst = 13,
+	pmu_pd_vo1 = 14,
+	pmu_pd_vo0 = 15,
+	pmu_pd_usb = 16,
+	pmu_pd_vi = 17,
+	pmu_pd_vepu0 = 18,
+	pmu_pd_vepu1 = 19,
+	pmu_pd_vdec = 20,
+	pmu_pd_vpu = 21,
+	pmu_pd_nputop = 22,
+	pmu_pd_npu0 = 23,
+	pmu_pd_npu1 = 24,
+	pmu_pd_gpu = 25,
+	pmu_pd_id_max,
+};
+
+enum pmu_vd_id {
+	pmu_vd_npu = 0,
+	pmu_vd_ddr = 1,
+	pmu_vd_cci = 2,
+	pmu_vd_gpu = 3,
+};
+
+enum pmu_bus_state {
+	pmu_bus_active = 0,
+	pmu_bus_idle = 1,
+};
+
+enum pmu_pd_state {
+	pmu_pd_on = 0,
+	pmu_pd_off = 1
+};
+
+enum pmu_scu_fsm_st {
+	pmu_scu_fsm_normal = 0,
+	pmu_scu_fsm_cpu_pwr_down = 1,
+	pmu_scu_fsm_l2_flush = 2,
+	pmu_scu_fsm_l2_idle = 3,
+	pmu_scu_fsm_clust_idle = 4,
+	pmu_scu_fsm_scu_pwr_down = 5,
+	pmu_scu_fsm_sleep = 6,
+	pmu_scu_fsm_wkup = 7,
+	pmu_scu_fsm_scu_pwr_up = 8,
+	pmu_scu_fsm_clust_resume = 9,
+	pmu_scu_fsm_cpu_pwr_up = 10,
+};
+
+#define MAX_MEM_OS_REG_NUM		32
+#define MEM_OS_REG_BASE			\
+	(PMUSRAM_BASE + PMUSRAM_RSIZE - MAX_MEM_OS_REG_NUM * 4)
+
+#define PSRAM_SP_TOP			MEM_OS_REG_BASE
+
+#define PD_CTR_LOOP			5000
+#define WFEI_CHECK_LOOP			5000
+#define BUS_IDLE_LOOP			1000
+#define NONBOOT_CPUS_OFF_LOOP		500000
+
+#define REBOOT_FLAG			0x5242C300
+#define BOOT_BROM_DOWNLOAD		0xef08a53c
+
+#define BOOTROM_SUSPEND_MAGIC		0x02468ace
+#define BOOTROM_RESUME_MAGIC		0x13579bdf
+#define WARM_BOOT_MAGIC			0x76543210
+#define VALID_GLB_RST_MSK		0xbfff
+
+#define DEFAULT_BOOT_CPU		0
+
+/*******************************************************
+ *     sleep mode define
+ *******************************************************/
+#define SLP_ARMPD			BIT(0)
+#define SLP_ARMOFF			BIT(1)
+#define SLP_ARMOFF_DDRPD		BIT(2)
+#define SLP_ARMOFF_LOGOFF		BIT(3)
+#define SLP_ARMOFF_PMUOFF		BIT(4)
+#define SLP_FROM_UBOOT			BIT(5)
+
+/* all plls except ddr's pll*/
+#define SLP_PMU_HW_PLLS_PD		BIT(8)
+#define SLP_PMU_PMUALIVE_32K		BIT(9)
+#define SLP_PMU_DIS_OSC			BIT(10)
+
+#define SLP_CLK_GT			BIT(16)
+#define SLP_PMIC_LP			BIT(17)
+
+#define SLP_32K_EXT			BIT(24)
+#define SLP_TIME_OUT_WKUP		BIT(25)
+#define SLP_PMU_DBG			BIT(26)
+#define SLP_ARCH_TIMER_RESET		BIT(27)
+
+#define PM_INVALID_GPIO			0xffff
+#define MAX_GPIO_POWER_CFG_CNT		10
+#define MAX_VIRTUAL_PWROFF_IRQ_CNT	20
+
+enum {
+	RK_PM_VIRT_PWROFF_EN = 0,
+	RK_PM_VIRT_PWROFF_IRQ_CFG = 1,
+	RK_PM_VIRT_PWROFF_MAX,
+};
+
+/* sleep pin */
+#define RKPM_SLEEP_PIN0_EN		BIT(0)	/* GPIO0_A3 */
+#define RKPM_SLEEP_PIN1_EN		BIT(1)	/* GPIO0_A4 */
+#define RKPM_SLEEP_PIN2_EN		BIT(2)	/* GPIO0_A5 */
+
+#define RKPM_SLEEP_PIN0_ACT_LOW		BIT(0)	/* GPIO0_A3 */
+#define RKPM_SLEEP_PIN1_ACT_LOW		BIT(1)	/* GPIO0_A4 */
+#define RKPM_SLEEP_PIN2_ACT_LOW		BIT(2)	/* GPIO0_A5 */
+
+#define pmu_bus_idle_st(id)	\
+	(!!(mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST) & BIT(id)))
+
+#define pmu_bus_idle_ack(id)	\
+	(!!(mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ACK) & BIT(id)))
+
+static inline uint32_t read_mem_os_reg(uint32_t id)
+{
+	assert((id) < MAX_MEM_OS_REG_NUM);
+
+	return mmio_read_32(MEM_OS_REG_BASE + 4 * (id));
+}
+
+static inline void write_mem_os_reg(uint32_t id, uint32_t val)
+{
+	assert((id) < MAX_MEM_OS_REG_NUM);
+
+	mmio_write_32(MEM_OS_REG_BASE + 4 * (id), val);
+}
+#endif /* __PMU_H__ */
diff --git a/plat/rockchip/rk3576/drivers/secure/firewall.c b/plat/rockchip/rk3576/drivers/secure/firewall.c
new file mode 100644
index 0000000..5da9ea8
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/secure/firewall.c
@@ -0,0 +1,693 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <firewall.h>
+#include <soc.h>
+
+enum {
+	FW_NS_A_S_A = 0x0,
+	FW_NS_A_S_NA = 0x1,
+	FW_NS_NA_S_A = 0x2,
+	FW_NS_NA_S_NA = 0x3,
+};
+
+/* group type */
+enum {
+	FW_GRP_TYPE_INV = 0,
+	FW_GRP_TYPE_DDR_RGN = 1,
+	FW_GRP_TYPE_SYSMEM_RGN = 2,
+	FW_GRP_TYPE_CBUF_RGN = 3,
+	FW_GRP_TYPE_SLV = 4,
+	FW_GRP_TYPE_DM = 5,
+};
+
+enum {
+	FW_SLV_TYPE_INV = 0,
+	FW_MST_TYPE_INV = 0,
+	FW_SLV_TYPE_BUS = 1,
+	FW_SLV_TYPE_TOP = 2,
+	FW_SLV_TYPE_CENTER = 3,
+	FW_SLV_TYPE_CCI = 4,
+	FW_SLV_TYPE_PHP = 5,
+	FW_SLV_TYPE_GPU = 6,
+	FW_SLV_TYPE_NPU = 7,
+	FW_SLV_TYPE_PMU = 8,
+	FW_MST_TYPE_SYS = 9,
+	FW_MST_TYPE_PMU = 10,
+};
+
+#define FW_ID(type, id)			\
+	((((type) & 0xff) << 16) | ((id) & 0xffff))
+
+#define FW_MST_ID(type, id)		FW_ID(type, id)
+#define FW_SLV_ID(type, id)		FW_ID(type, id)
+#define FW_GRP_ID(type, id)		FW_ID(type, id)
+
+/* group id */
+#define FW_GRP_ID_DDR_RGN(id)		FW_GRP_ID(FW_GRP_TYPE_DDR_RGN, id)
+#define FW_GRP_ID_SYSMEM_RGN(id)	FW_GRP_ID(FW_GRP_TYPE_SYSMEM_RGN, id)
+#define FW_GRP_ID_CBUF(id)		FW_GRP_ID(FW_GRP_TYPE_CBUF_RGN, id)
+#define FW_GRP_ID_SLV(id)		FW_GRP_ID(FW_GRP_TYPE_SLV, id)
+#define FW_GRP_ID_DM(id)		FW_GRP_ID(FW_GRP_TYPE_DM, id)
+
+#define FW_GRP_ID_SLV_CNT		8
+#define FW_GRP_ID_DM_CNT		8
+
+#define FW_GET_ID(id)			((id) & 0xffff)
+#define FW_GET_TYPE(id)			(((id) >> 16) & 0xff)
+
+#define FW_INVLID_MST_ID		FW_MST_ID(FW_MST_TYPE_INV, 0)
+#define FW_INVLID_SLV_ID		FW_SLV_ID(FW_SLV_TYPE_INV, 0)
+
+typedef struct {
+	uint32_t domain[FW_SGRF_MST_DOMAIN_CON_CNT];
+	uint32_t pmu_domain;
+	uint32_t bus_slv_grp[FW_SGRF_BUS_SLV_CON_CNT];
+	uint32_t top_slv_grp[FW_SGRF_TOP_SLV_CON_CNT];
+	uint32_t center_slv_grp[FW_SGRF_CENTER_SLV_CON_CNT];
+	uint32_t cci_slv_grp[FW_SGRF_CCI_SLV_CON_CNT];
+	uint32_t php_slv_grp[FW_SGRF_PHP_SLV_CON_CNT];
+	uint32_t gpu_slv_grp;
+	uint32_t npu_slv_grp[FW_SGRF_NPU_SLV_CON_CNT];
+	uint32_t pmu_slv_grp[FW_PMU_SGRF_SLV_CON_CNT];
+	uint32_t ddr_rgn[FW_SGRF_DDR_RGN_CNT];
+	uint32_t ddr_size;
+	uint32_t ddr_con;
+	uint32_t sysmem_rgn[FW_SGRF_SYSMEM_RGN_CNT];
+	uint32_t sysmem_con;
+	uint32_t cbuf_rgn[FW_SGRF_CBUF_RGN_CNT];
+	uint32_t cbuf_con;
+	uint32_t ddr_lookup[FW_SGRF_DDR_LOOKUP_CNT];
+	uint32_t sysmem_lookup[FW_SGRF_SYSMEM_LOOKUP_CNT];
+	uint32_t cbuf_lookup[FW_SGRF_CBUF_LOOKUP_CNT];
+	uint32_t slv_lookup[FW_SGRF_SLV_LOOKUP_CNT];
+	uint32_t pmu_slv_lookup[FW_PMU_SGRF_SLV_LOOKUP_CNT];
+} fw_config_t;
+
+static fw_config_t fw_config_buf;
+
+/****************************************************************************
+ * Access rights between domains and groups are as follows:
+ *
+ * 00: NS access,     S access
+ * 01: NS access,     S not access
+ * 10: NS not access, S access
+ * 11: NS not access, S not access
+ * |---------------------------------------------------------|
+ * |                 | d0 | d1 | d2 | d3 | d4 | d5 | d6 | d7 |
+ * |---------------------------------------------------------|
+ * | slave g0        | 00 | 00 | 11 | 11 | 11 | 11 | 11 | 00 |
+ * |---------------------------------------------------------|
+ * | slave g1        | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
+ * |---------------------------------------------------------|
+ * | slave g2~7      | 11 | 11 | 11 | 11 | 11 | 11 | 11 | 11 |
+ * |---------------------------------------------------------|
+ * | ddr region 0~15 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
+ * |---------------------------------------------------------|
+ * | sram region 0~3 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
+ * |---------------------------------------------------------|
+ * | cbuf region 0~7 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
+ * |---------------------------------------------------------|
+ *
+ * PS:
+ * Domain 0/1/7 NS/S can access group 0.
+ * Domain 0/1/7 NS and Domain1 NS/S can't access group 1, domain 0/7 S can access.
+ * Other domains NS/S can't access all groups.
+ *
+ * Domain 0/7 NS can't access ddr/sram/cbuf region and Domain 0/7 S can access.
+ * Other domains NS/S can't access ddr/sram/cbuf region.
+ *
+ ******************************************************************************/
+
+/* Masters in dm1 */
+static const int dm1_mst[] = {
+	FW_MST_ID(FW_MST_TYPE_SYS, 1), /* keylad_apbm */
+	FW_MST_ID(FW_MST_TYPE_SYS, 2), /* dft2apbm */
+	FW_MST_ID(FW_MST_TYPE_SYS, 11), /* dma2ddr */
+	FW_MST_ID(FW_MST_TYPE_SYS, 12), /* dmac0 */
+	FW_MST_ID(FW_MST_TYPE_SYS, 13), /* dmac1 */
+	FW_MST_ID(FW_MST_TYPE_SYS, 14), /* dmac2 */
+	FW_MST_ID(FW_MST_TYPE_SYS, 19), /* gpu */
+	FW_MST_ID(FW_MST_TYPE_SYS, 31), /* vop_m0 */
+	FW_MST_ID(FW_MST_TYPE_SYS, 32), /* vop_m1 */
+	FW_MST_ID(FW_MST_TYPE_SYS, 36), /* bus_mcu */
+	FW_MST_ID(FW_MST_TYPE_SYS, 38), /* npu_mcu */
+	FW_MST_ID(FW_MST_TYPE_SYS, 56), /* dap_lite */
+
+	FW_INVLID_MST_ID
+};
+
+/* Slaves in group1 */
+static const int sec_slv[] = {
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 28), /* crypto_s */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 29), /* keyladder_s */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 30), /* rkrng_s */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 33), /* jtag_lock */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 34), /* otp_s */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 35), /* otpmsk */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 37), /* scru_s */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 38), /* sys_sgrf */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 39), /* bootrom */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 41), /* wdts */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 44), /* sevice_secure */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 61), /* timers0_ch0~5 */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 62),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 63),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 64),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 65),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 66),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 67), /* timers1_ch0~5 */
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 68),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 69),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 70),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 71),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 72),
+	FW_SLV_ID(FW_SLV_TYPE_TOP, 73), /* sys_fw */
+
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 3),  /* ddr grf */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 4),  /* ddr ctl0 */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 5),  /* ddr ctl1 */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 6),  /* ddr phy0 */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 7),  /* ddr0 cru */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 8),  /* ddr phy1 */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 9),  /* ddr1 cru */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 15), /* ddr wdt */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 19), /* service ddr */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 58), /* ddr timer ch0 */
+	FW_SLV_ID(FW_SLV_TYPE_CENTER, 59), /* ddr timer ch1 */
+
+	FW_SLV_ID(FW_SLV_TYPE_PMU, 1),	/* pmu mem */
+	FW_SLV_ID(FW_SLV_TYPE_PMU, 15), /* pmu1_scru */
+	FW_SLV_ID(FW_SLV_TYPE_PMU, 30), /* osc chk */
+	FW_SLV_ID(FW_SLV_TYPE_PMU, 31), /* pmu0_sgrf */
+	FW_SLV_ID(FW_SLV_TYPE_PMU, 32), /* pmu1_sgrf */
+	FW_SLV_ID(FW_SLV_TYPE_PMU, 34), /* scramble key */
+	FW_SLV_ID(FW_SLV_TYPE_PMU, 36), /* pmu remap */
+	FW_SLV_ID(FW_SLV_TYPE_PMU, 43), /* pmu fw */
+
+	FW_INVLID_SLV_ID
+};
+
+static void fw_buf_sys_mst_dm_cfg(int mst_id, uint32_t dm_id)
+{
+	int sft = (mst_id & 0x7) << 2;
+
+	fw_config_buf.domain[mst_id >> 3] &= ~(0xf << sft);
+	fw_config_buf.domain[mst_id >> 3] |= (dm_id & 0xf) << sft;
+}
+
+static void fw_buf_pmu_mst_dm_cfg(int mst_id, uint32_t dm_id)
+{
+	int sft = (mst_id & 0x7) << 2;
+
+	fw_config_buf.pmu_domain &= ~(0xf << sft);
+	fw_config_buf.pmu_domain |= (dm_id & 0xf) << sft;
+}
+
+void fw_buf_mst_dm_cfg(int mst_id, uint32_t dm_id)
+{
+	int type = FW_GET_TYPE(mst_id);
+
+	mst_id = FW_GET_ID(mst_id);
+
+	switch (type) {
+	case FW_MST_TYPE_SYS:
+		fw_buf_sys_mst_dm_cfg(mst_id, dm_id);
+		break;
+	case FW_MST_TYPE_PMU:
+		fw_buf_pmu_mst_dm_cfg(mst_id, dm_id);
+		break;
+
+	default:
+		ERROR("%s: unknown FW_DOMAIN_TYPE (0x%x)\n", __func__, type);
+		break;
+	}
+}
+
+static void fw_buf_ddr_lookup_cfg(int rgn_id, int dm_id, uint32_t priv)
+{
+	int sft = (dm_id << 1) + (rgn_id & 0x1) * 16;
+
+	fw_config_buf.ddr_lookup[rgn_id >> 1] &= ~(0x3 << sft);
+	fw_config_buf.ddr_lookup[rgn_id >> 1] |= (priv & 0x3) << sft;
+}
+
+static void fw_buf_sysmem_lookup_cfg(int rgn_id, int dm_id, uint32_t priv)
+{
+	int sft = (dm_id << 1) + (rgn_id & 0x1) * 16;
+
+	fw_config_buf.sysmem_lookup[rgn_id >> 1] &= ~(0x3 << sft);
+	fw_config_buf.sysmem_lookup[rgn_id >> 1] |= (priv & 0x3) << sft;
+}
+
+static void fw_buf_cbuf_lookup_cfg(int rgn_id, int dm_id, uint32_t priv)
+{
+	int sft = (dm_id << 1) + (rgn_id & 0x1) * 16;
+
+	fw_config_buf.cbuf_lookup[rgn_id >> 1] &= ~(0x3 << sft);
+	fw_config_buf.cbuf_lookup[rgn_id >> 1] |= (priv & 0x3) << sft;
+}
+
+static void fw_buf_slv_lookup_cfg(int grp_id, int dm_id, uint32_t priv)
+{
+	int sft = (dm_id << 1) + (grp_id & 0x1) * 16;
+
+	fw_config_buf.slv_lookup[grp_id >> 1] &= ~(0x3 << sft);
+	fw_config_buf.slv_lookup[grp_id >> 1] |= (priv & 0x3) << sft;
+}
+
+static void fw_buf_pmu_slv_lookup_cfg(int grp_id, int dm_id, uint32_t priv)
+{
+	int sft = (dm_id << 1) + (grp_id & 0x1) * 16;
+
+	fw_config_buf.pmu_slv_lookup[grp_id >> 1] &= ~(0x3 << sft);
+	fw_config_buf.pmu_slv_lookup[grp_id >> 1] |= (priv & 0x3) << sft;
+}
+
+void fw_buf_grp_lookup_cfg(int grp_id, int dm_id, uint32_t priv)
+{
+	uint32_t type = FW_GET_TYPE(grp_id);
+
+	grp_id = FW_GET_ID(grp_id);
+
+	switch (type) {
+	case FW_GRP_TYPE_DDR_RGN:
+		fw_buf_ddr_lookup_cfg(grp_id, dm_id, priv);
+		break;
+	case FW_GRP_TYPE_SYSMEM_RGN:
+		fw_buf_sysmem_lookup_cfg(grp_id, dm_id, priv);
+		break;
+	case FW_GRP_TYPE_CBUF_RGN:
+		fw_buf_cbuf_lookup_cfg(grp_id, dm_id, priv);
+		break;
+	case FW_GRP_TYPE_SLV:
+		fw_buf_slv_lookup_cfg(grp_id, dm_id, priv);
+		fw_buf_pmu_slv_lookup_cfg(grp_id, dm_id, priv);
+		break;
+
+	default:
+		ERROR("%s: unknown FW_LOOKUP_TYPE (0x%x)\n", __func__, type);
+		break;
+	}
+}
+
+static void fw_buf_bus_slv_grp_cfg(int slv_id, int grp_id)
+{
+	int sft = slv_id % 5 << 2;
+
+	fw_config_buf.bus_slv_grp[slv_id / 5] &= ~(0xf << sft);
+	fw_config_buf.bus_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_top_slv_grp_cfg(int slv_id, int grp_id)
+{
+	int sft = slv_id % 5 << 2;
+
+	fw_config_buf.top_slv_grp[slv_id / 5] &= ~(0xf << sft);
+	fw_config_buf.top_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_center_slv_grp_cfg(int slv_id, int grp_id)
+{
+	int sft = slv_id % 5 << 2;
+
+	fw_config_buf.center_slv_grp[slv_id / 5] &= ~(0xf << sft);
+	fw_config_buf.center_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_cci_slv_grp_cfg(int slv_id, int grp_id)
+{
+	int sft = slv_id % 5 << 2;
+
+	fw_config_buf.cci_slv_grp[slv_id / 5] &= ~(0xf << sft);
+	fw_config_buf.cci_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_php_slv_grp_cfg(int slv_id, int grp_id)
+{
+	int sft = slv_id % 5 << 2;
+
+	fw_config_buf.php_slv_grp[slv_id / 5] &= ~(0xf << sft);
+	fw_config_buf.php_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_gpu_slv_grp_cfg(int slv_id, int grp_id)
+{
+	int sft = slv_id % 5 << 2;
+
+	fw_config_buf.gpu_slv_grp &= ~(0xf << sft);
+	fw_config_buf.gpu_slv_grp |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_npu_slv_grp_cfg(int slv_id, int grp_id)
+{
+	int sft = slv_id % 5 << 2;
+
+	fw_config_buf.npu_slv_grp[slv_id / 5] &= ~(0xf << sft);
+	fw_config_buf.npu_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_pmu_slv_grp_cfg(int slv_id, int grp_id)
+{
+	int sft = slv_id % 5 << 2;
+
+	fw_config_buf.pmu_slv_grp[slv_id / 5] &= ~(0xf << sft);
+	fw_config_buf.pmu_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+void fw_buf_slv_grp_cfg(int slv_id, int grp_id)
+{
+	int type = FW_GET_TYPE(slv_id);
+
+	slv_id = FW_GET_ID(slv_id);
+	grp_id = FW_GET_ID(grp_id);
+
+	switch (type) {
+	case FW_SLV_TYPE_BUS:
+		fw_buf_bus_slv_grp_cfg(slv_id, grp_id);
+		break;
+	case FW_SLV_TYPE_TOP:
+		fw_buf_top_slv_grp_cfg(slv_id, grp_id);
+		break;
+	case FW_SLV_TYPE_CENTER:
+		fw_buf_center_slv_grp_cfg(slv_id, grp_id);
+		break;
+	case FW_SLV_TYPE_CCI:
+		fw_buf_cci_slv_grp_cfg(slv_id, grp_id);
+		break;
+	case FW_SLV_TYPE_PHP:
+		fw_buf_php_slv_grp_cfg(slv_id, grp_id);
+		break;
+	case FW_SLV_TYPE_GPU:
+		fw_buf_gpu_slv_grp_cfg(slv_id, grp_id);
+		break;
+	case FW_SLV_TYPE_NPU:
+		fw_buf_npu_slv_grp_cfg(slv_id, grp_id);
+		break;
+	case FW_SLV_TYPE_PMU:
+		fw_buf_pmu_slv_grp_cfg(slv_id, grp_id);
+		break;
+
+	default:
+		ERROR("%s: unknown FW_SLV_TYPE (0x%x)\n", __func__, type);
+		break;
+	}
+}
+
+void fw_buf_add_msts(const int *mst_ids, int dm_id)
+{
+	int i;
+
+	for (i = 0; FW_GET_TYPE(mst_ids[i]) != FW_INVLID_SLV_ID; i++)
+		fw_buf_mst_dm_cfg(mst_ids[i], dm_id);
+}
+
+void fw_buf_add_slvs(const int *slv_ids, int grp_id)
+{
+	int i;
+
+	for (i = 0; FW_GET_TYPE(slv_ids[i]) != FW_INVLID_SLV_ID; i++)
+		fw_buf_slv_grp_cfg(slv_ids[i], grp_id);
+}
+
+/* unit: Mb */
+void fw_buf_ddr_size_cfg(uint64_t base_mb, uint64_t top_mb, int id)
+{
+	fw_config_buf.ddr_size = RG_MAP_SECURE(top_mb, base_mb);
+	fw_config_buf.ddr_con |= BIT(16);
+}
+
+/* unit: Mb */
+void fw_buf_ddr_rgn_cfg(uint64_t base_mb, uint64_t top_mb, int rgn_id)
+{
+	fw_config_buf.ddr_rgn[rgn_id] = RG_MAP_SECURE(top_mb, base_mb);
+	fw_config_buf.ddr_con |= BIT(rgn_id);
+}
+
+/* Unit: kb */
+void fw_buf_sysmem_rgn_cfg(uint64_t base_kb, uint64_t top_kb, int rgn_id)
+{
+	fw_config_buf.sysmem_rgn[rgn_id] = RG_MAP_SRAM_SECURE(top_kb, base_kb);
+	fw_config_buf.sysmem_con |= BIT(rgn_id);
+}
+
+static void fw_domain_init(void)
+{
+	int i;
+
+	/* select to domain0 by default */
+	for (i = 0; i < FW_SGRF_MST_DOMAIN_CON_CNT; i++)
+		fw_config_buf.domain[i] = 0x0;
+
+	/* select to domain0 by default */
+	fw_config_buf.pmu_domain = 0x0;
+}
+
+static void fw_slv_grp_init(void)
+{
+	int i;
+
+	/* select to group0 by default */
+	for (i = 0; i < FW_SGRF_BUS_SLV_CON_CNT; i++)
+		fw_config_buf.bus_slv_grp[i] = 0x0;
+
+	for (i = 0; i < FW_SGRF_TOP_SLV_CON_CNT; i++)
+		fw_config_buf.top_slv_grp[i] = 0x0;
+
+	for (i = 0; i < FW_SGRF_CENTER_SLV_CON_CNT; i++)
+		fw_config_buf.center_slv_grp[i] = 0x0;
+
+	for (i = 0; i < FW_SGRF_CCI_SLV_CON_CNT; i++)
+		fw_config_buf.cci_slv_grp[i] = 0x0;
+
+	for (i = 0; i < FW_SGRF_PHP_SLV_CON_CNT; i++)
+		fw_config_buf.php_slv_grp[i] = 0x0;
+
+	fw_config_buf.gpu_slv_grp = 0x0;
+
+	for (i = 0; i < FW_SGRF_NPU_SLV_CON_CNT; i++)
+		fw_config_buf.npu_slv_grp[i] = 0x0;
+}
+
+static void fw_region_init(void)
+{
+	/* Use FW_DDR_RGN0_REG to config 1024~1025M space to secure */
+	fw_buf_ddr_rgn_cfg(1024, 1025, 0);
+
+	/* Use FW_SYSMEM_RGN0_REG to config 0~32k space to secure */
+	fw_buf_sysmem_rgn_cfg(0, 32, 0);
+}
+
+static void fw_lookup_init(void)
+{
+	int i;
+
+	/*
+	 * Domain 0/7 NS can't access ddr/sram/cbuf region and Domain 0/7 S can access.
+	 * Other domains NS/S can't access ddr/sram/cbuf region.
+	 */
+	for (i = 0; i < FW_SGRF_DDR_LOOKUP_CNT; i++)
+		fw_config_buf.ddr_lookup[i] = 0xbffebffe;
+
+	for (i = 0; i < FW_SGRF_SYSMEM_LOOKUP_CNT; i++)
+		fw_config_buf.sysmem_lookup[i] = 0xbffebffe;
+
+	for (i = 0; i < FW_SGRF_CBUF_LOOKUP_CNT; i++)
+		fw_config_buf.cbuf_lookup[i] = 0xbffebffe;
+
+	/*
+	 * Domain 0/1/7 NS/S can access group 0.
+	 * Domain 0/1/7 NS and Domain1 NS/S can't access group 1, domain 0/7 S can access.
+	 * Other domains NS/S can't access all groups.
+	 */
+	fw_config_buf.slv_lookup[0] = 0xbffe3ff0;
+	fw_config_buf.slv_lookup[1] = 0xffffffff;
+	fw_config_buf.slv_lookup[2] = 0xffffffff;
+	fw_config_buf.slv_lookup[3] = 0xffffffff;
+
+	/*
+	 * Domain 0/1/7 NS/S can access group 0.
+	 * Domain 0/1/7 NS and Domain1 NS/S can't access group 1, domain 0/7 S can access.
+	 * Other domains NS/S can't access all groups.
+	 */
+	fw_config_buf.pmu_slv_lookup[0] = 0xbffe3ff0;
+	fw_config_buf.pmu_slv_lookup[1] = 0xffffffff;
+	fw_config_buf.pmu_slv_lookup[2] = 0xffffffff;
+	fw_config_buf.pmu_slv_lookup[3] = 0xffffffff;
+}
+
+static void fw_config_buf_flush(void)
+{
+	int i;
+
+	/* domain */
+	for (i = 0; i < FW_SGRF_MST_DOMAIN_CON_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_MST_DOMAIN_CON(i),
+			      fw_config_buf.domain[i]);
+
+	mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_DOMAIN_CON,
+		      fw_config_buf.pmu_domain);
+
+	/* slave group */
+	for (i = 0; i < FW_SGRF_BUS_SLV_CON_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_BUS_SLV_CON(i),
+			      fw_config_buf.bus_slv_grp[i]);
+
+	for (i = 0; i < FW_SGRF_TOP_SLV_CON_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_TOP_SLV_CON(i),
+			      fw_config_buf.top_slv_grp[i]);
+
+	for (i = 0; i < FW_SGRF_CENTER_SLV_CON_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CENTER_SLV_CON(i),
+			      fw_config_buf.center_slv_grp[i]);
+
+	for (i = 0; i < FW_SGRF_CCI_SLV_CON_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CCI_SLV_CON(i),
+			      fw_config_buf.cci_slv_grp[i]);
+
+	for (i = 0; i < FW_SGRF_PHP_SLV_CON_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_PHP_SLV_CON(i),
+			      fw_config_buf.php_slv_grp[i]);
+
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_GPU_SLV_CON,
+		      fw_config_buf.gpu_slv_grp);
+
+	for (i = 0; i < FW_SGRF_NPU_SLV_CON_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_NPU_SLV_CON(i),
+			      fw_config_buf.npu_slv_grp[i]);
+
+	for (i = 0; i < FW_PMU_SGRF_SLV_CON_CNT; i++)
+		mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_SLV_CON(i),
+			      fw_config_buf.pmu_slv_grp[i]);
+
+	/* region */
+	for (i = 0; i < FW_SGRF_DDR_RGN_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_RGN(i),
+			      fw_config_buf.ddr_rgn[i]);
+
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_SIZE, fw_config_buf.ddr_size);
+
+	for (i = 0; i < FW_SGRF_SYSMEM_RGN_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_RGN(i),
+			      fw_config_buf.sysmem_rgn[i]);
+
+	for (i = 0; i < FW_SGRF_CBUF_RGN_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_RGN(i),
+			      fw_config_buf.cbuf_rgn[i]);
+
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_CON, fw_config_buf.ddr_con);
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_CON, fw_config_buf.sysmem_con);
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_CON, fw_config_buf.cbuf_con);
+
+	dsb();
+	isb();
+
+	/* lookup */
+	for (i = 0; i < FW_SGRF_DDR_LOOKUP_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_LOOKUP(i),
+			      fw_config_buf.ddr_lookup[i]);
+
+	for (i = 0; i < FW_SGRF_SYSMEM_LOOKUP_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_LOOKUP(i),
+			      fw_config_buf.sysmem_lookup[i]);
+
+	for (i = 0; i < FW_SGRF_CBUF_LOOKUP_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_LOOKUP(i),
+			      fw_config_buf.cbuf_lookup[i]);
+
+	for (i = 0; i < FW_SGRF_SLV_LOOKUP_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SLV_LOOKUP(i),
+			      fw_config_buf.slv_lookup[i]);
+
+	for (i = 0; i < FW_PMU_SGRF_SLV_LOOKUP_CNT; i++)
+		mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_SLV_LOOKUP(i),
+			      fw_config_buf.pmu_slv_lookup[i]);
+
+	dsb();
+	isb();
+}
+
+static __pmusramfunc void pmusram_udelay(uint32_t us)
+{
+	uint64_t orig;
+	uint64_t to_wait;
+
+	orig = read_cntpct_el0();
+	to_wait = read_cntfrq_el0() * us / 1000000;
+
+	while (read_cntpct_el0() - orig <= to_wait)
+		;
+}
+
+__pmusramfunc void pmusram_fw_update_msk(uint32_t msk)
+{
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON0,
+		      BITS_WITH_WMASK(0, 0x3ff, 0));
+	dsb();
+
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON0,
+		      BITS_WITH_WMASK(msk, msk, 0));
+	dsb();
+	isb();
+	pmusram_udelay(20);
+	dsb();
+	isb();
+}
+
+__pmusramfunc void pmusram_all_fw_bypass(void)
+{
+	int i;
+
+	/* disable regions */
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_CON, 0);
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_CON, 0);
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_CON, 0);
+
+	for (i = 0; i < FW_SGRF_DDR_LOOKUP_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_LOOKUP(i), 0x0);
+
+	for (i = 0; i < FW_SGRF_SYSMEM_LOOKUP_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_LOOKUP(i), 0x0);
+
+	for (i = 0; i < FW_SGRF_CBUF_LOOKUP_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_LOOKUP(i), 0x0);
+
+	for (i = 0; i < FW_SGRF_SLV_LOOKUP_CNT; i++)
+		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SLV_LOOKUP(i), 0x0);
+
+	for (i = 0; i < FW_PMU_SGRF_SLV_LOOKUP_CNT; i++)
+		mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_SLV_LOOKUP(i), 0x0);
+
+	dsb();
+
+	pmusram_fw_update_msk(0x3ff);
+}
+
+void fw_init(void)
+{
+	/* Enable all fw auto-update */
+	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON1, 0x03ff03ff);
+
+	pmusram_all_fw_bypass();
+
+	fw_domain_init();
+	fw_slv_grp_init();
+	fw_region_init();
+
+	fw_buf_add_slvs(sec_slv, 1);
+	fw_buf_add_msts(dm1_mst, 1);
+
+	fw_lookup_init();
+
+	fw_config_buf_flush();
+	pmusram_fw_update_msk(0x3ff);
+}
diff --git a/plat/rockchip/rk3576/drivers/secure/firewall.h b/plat/rockchip/rk3576/drivers/secure/firewall.h
new file mode 100644
index 0000000..7b13071
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/secure/firewall.h
@@ -0,0 +1,499 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __FIREWALL_H__
+#define __FIREWALL_H__
+
+#include <plat_private.h>
+
+/* FW SGRF */
+#define FW_SGRF_MST_DOMAIN_CON(i)	((i) * 4)
+#define FW_SGRF_MST_DOMAIN_CON_CNT	8
+#define FW_SGRF_DDR_RGN(i)		(0x0100 + (i) * 4)
+#define FW_SGRF_DDR_RGN_CNT		16
+#define FW_SGRF_DDR_LOOKUP(i)		(0x0140 + (i) * 0x4)
+#define FW_SGRF_DDR_LOOKUP_CNT		8
+#define FW_SGRF_DDR_SIZE		0x0160
+#define FW_SGRF_DDR_CON			0x0168
+#define FW_SGRF_SYSMEM_RGN(i)		(0x0200 + (i) * 4)
+#define FW_SGRF_SYSMEM_RGN_CNT		4
+#define FW_SGRF_SYSMEM_LOOKUP(i)	(0x0210 + (i) * 4)
+#define FW_SGRF_SYSMEM_LOOKUP_CNT	2
+#define FW_SGRF_SYSMEM_CON		0x0218
+#define FW_SGRF_CBUF_RGN(i)		(0x0300 + (i) * 4)
+#define FW_SGRF_CBUF_RGN_CNT		8
+#define FW_SGRF_CBUF_LOOKUP(i)		(0x0320 + (i) * 4)
+#define FW_SGRF_CBUF_LOOKUP_CNT		4
+#define FW_SGRF_CBUF_CON		0x0330
+#define FW_SGRF_SLV_LOOKUP(i)		(0x0400 + (i) * 4)
+#define FW_SGRF_SLV_LOOKUP_CNT		4
+#define FW_SGRF_BUS_SLV_CON(i)		(0x0500 + (i) * 4)
+#define FW_SGRF_BUS_SLV_CON_CNT		25
+#define FW_SGRF_BUS_SLV_STAT		0x0580
+#define FW_SGRF_TOP_SLV_CON(i)		(0x0600 + (i) * 4)
+#define FW_SGRF_TOP_SLV_CON_CNT		16
+#define FW_SGRF_TOP_SLV_STAT		0x0680
+#define FW_SGRF_CENTER_SLV_CON(i)	(0x0700 + (i) * 4)
+#define FW_SGRF_CENTER_SLV_CON_CNT	13
+#define FW_SGRF_CCI_SLV_CON(i)		(0x0800 + (i) * 4)
+#define FW_SGRF_CCI_SLV_CON_CNT		3
+#define FW_SGRF_PHP_SLV_CON(i)		(0x0900 + (i) * 4)
+#define FW_SGRF_PHP_SLV_CON_CNT		4
+#define FW_SGRF_PHP_SLV_STAT		0x0940
+#define FW_SGRF_GPU_SLV_CON		0x0980
+#define FW_SGRF_NPU_SLV_CON(i)		(0x09a0 + (i) * 4)
+#define FW_SGRF_NPU_SLV_CON_CNT		2
+#define FW_SGRF_STATCLR_CON0		0x0a00
+#define FW_SGRF_KEYUPD_CON0		0x0a80
+#define FW_SGRF_KEYUPD_CON1		0x0a84
+#define FW_SGRF_KEYUPD_STAT		0x0ab0
+
+/* FW PMUSGRF */
+#define FW_PMU_SGRF_SLV_CON(i)		((i) * 4)
+#define FW_PMU_SGRF_SLV_CON_CNT		9
+#define FW_PMU_SGRF_SLV_LOOKUP(i)	(0x0080 + (i) * 0x4)
+#define FW_PMU_SGRF_SLV_LOOKUP_CNT	4
+#define FW_PMU_SGRF_DOMAIN_CON		0x00a0
+#define FW_PMU_SGRF_SLV_STAT		0x00c0
+
+/* master id */
+#define FW_MST_ID_USB0			FW_MST_ID(FW_MST_TYPE_SYS, 0)
+#define FW_MST_ID_KEYLAD_APB		FW_MST_ID(FW_MST_TYPE_SYS, 1)
+#define FW_MST_ID_DFT2APB		FW_MST_ID(FW_MST_TYPE_SYS, 2)
+#define FW_MST_ID_PCIE0			FW_MST_ID(FW_MST_TYPE_SYS, 3)
+#define FW_MST_ID_PCIE1			FW_MST_ID(FW_MST_TYPE_SYS, 4)
+#define FW_MST_ID_SATA0			FW_MST_ID(FW_MST_TYPE_SYS, 6)
+#define FW_MST_ID_SATA1			FW_MST_ID(FW_MST_TYPE_SYS, 7)
+#define FW_MST_ID_CRYPTO		FW_MST_ID(FW_MST_TYPE_SYS, 8)
+#define FW_MST_ID_FLEXBUS		FW_MST_ID(FW_MST_TYPE_SYS, 9)
+#define FW_MST_ID_DECOM			FW_MST_ID(FW_MST_TYPE_SYS, 10)
+#define FW_MST_ID_DMA2DDR		FW_MST_ID(FW_MST_TYPE_SYS, 11)
+#define FW_MST_ID_DMAC0			FW_MST_ID(FW_MST_TYPE_SYS, 12)
+#define FW_MST_ID_DMAC1			FW_MST_ID(FW_MST_TYPE_SYS, 13)
+#define FW_MST_ID_DMAC2			FW_MST_ID(FW_MST_TYPE_SYS, 14)
+#define FW_MST_ID_EBC			FW_MST_ID(FW_MST_TYPE_SYS, 15)
+#define FW_MST_ID_EMMC			FW_MST_ID(FW_MST_TYPE_SYS, 16)
+#define FW_MST_ID_GMAC0			FW_MST_ID(FW_MST_TYPE_SYS, 17)
+#define FW_MST_ID_GMAC1			FW_MST_ID(FW_MST_TYPE_SYS, 18)
+#define FW_MST_ID_GPU			FW_MST_ID(FW_MST_TYPE_SYS, 19)
+#define FW_MST_ID_HDCP0			FW_MST_ID(FW_MST_TYPE_SYS, 20)
+#define FW_MST_ID_HDCP1			FW_MST_ID(FW_MST_TYPE_SYS, 21)
+#define FW_MST_ID_ISP			FW_MST_ID(FW_MST_TYPE_SYS, 22)
+#define FW_MST_ID_RGA0			FW_MST_ID(FW_MST_TYPE_SYS, 23)
+#define FW_MST_ID_RGA1			FW_MST_ID(FW_MST_TYPE_SYS, 24)
+#define FW_MST_ID_JPEG			FW_MST_ID(FW_MST_TYPE_SYS, 25)
+#define FW_MST_ID_RKVDEC		FW_MST_ID(FW_MST_TYPE_SYS, 26)
+#define FW_MST_ID_VEPU0			FW_MST_ID(FW_MST_TYPE_SYS, 27)
+#define FW_MST_ID_UFSHC			FW_MST_ID(FW_MST_TYPE_SYS, 28)
+#define FW_MST_ID_VDPP			FW_MST_ID(FW_MST_TYPE_SYS, 29)
+#define FW_MST_ID_VICAP			FW_MST_ID(FW_MST_TYPE_SYS, 30)
+#define FW_MST_ID_VOP_M0		FW_MST_ID(FW_MST_TYPE_SYS, 31)
+#define FW_MST_ID_VOP_M1		FW_MST_ID(FW_MST_TYPE_SYS, 32)
+#define FW_MST_ID_VPSS			FW_MST_ID(FW_MST_TYPE_SYS, 33)
+#define FW_MST_ID_FSPI0			FW_MST_ID(FW_MST_TYPE_SYS, 34)
+#define FW_MST_ID_FSPI1			FW_MST_ID(FW_MST_TYPE_SYS, 35)
+#define FW_MST_ID_BUS_MCU		FW_MST_ID(FW_MST_TYPE_SYS, 36)
+#define FW_MST_ID_DDR_MCU		FW_MST_ID(FW_MST_TYPE_SYS, 37)
+#define FW_MST_ID_NPU_MCU		FW_MST_ID(FW_MST_TYPE_SYS, 38)
+#define FW_MST_ID_CAN0			FW_MST_ID(FW_MST_TYPE_SYS, 39)
+#define FW_MST_ID_CAN1			FW_MST_ID(FW_MST_TYPE_SYS, 40)
+#define FW_MST_ID_SDIO			FW_MST_ID(FW_MST_TYPE_SYS, 41)
+#define FW_MST_ID_SDMMC0		FW_MST_ID(FW_MST_TYPE_SYS, 42)
+#define FW_MST_ID_USB1			FW_MST_ID(FW_MST_TYPE_SYS, 43)
+#define FW_MST_ID_NPU_M0		FW_MST_ID(FW_MST_TYPE_SYS, 44)
+#define FW_MST_ID_NPU_M0RO		FW_MST_ID(FW_MST_TYPE_SYS, 45)
+#define FW_MST_ID_NPU_M1		FW_MST_ID(FW_MST_TYPE_SYS, 46)
+#define FW_MST_ID_NPU_M1RO		FW_MST_ID(FW_MST_TYPE_SYS, 47)
+#define FW_MST_ID_A53_0			FW_MST_ID(FW_MST_TYPE_SYS, 48)
+#define FW_MST_ID_A53_1			FW_MST_ID(FW_MST_TYPE_SYS, 49)
+#define FW_MST_ID_A53_2			FW_MST_ID(FW_MST_TYPE_SYS, 50)
+#define FW_MST_ID_A53_3			FW_MST_ID(FW_MST_TYPE_SYS, 51)
+#define FW_MST_ID_A72_0			FW_MST_ID(FW_MST_TYPE_SYS, 52)
+#define FW_MST_ID_A72_1			FW_MST_ID(FW_MST_TYPE_SYS, 53)
+#define FW_MST_ID_A72_2			FW_MST_ID(FW_MST_TYPE_SYS, 54)
+#define FW_MST_ID_A72_3			FW_MST_ID(FW_MST_TYPE_SYS, 55)
+#define FW_MST_ID_DAP_LITE		FW_MST_ID(FW_MST_TYPE_SYS, 56)
+#define FW_MST_ID_VEPU1			FW_MST_ID(FW_MST_TYPE_SYS, 57)
+#define FW_MST_ID_SYS_CNT		64
+
+#define FW_MST_ID_PMU_MCU		FW_MST_ID(FW_MST_TYPE_PMU, 0)
+#define FW_MST_ID_VDMA			FW_MST_ID(FW_MST_TYPE_PMU, 1)
+#define FW_MST_ID_PMU_CNT		8
+
+/* slave id */
+#define FW_SLV_ID_CAN0			FW_SLV_ID(FW_SLV_TYPE_BUS, 0)
+#define FW_SLV_ID_CAN1			FW_SLV_ID(FW_SLV_TYPE_BUS, 1)
+#define FW_SLV_ID_I3C0			FW_SLV_ID(FW_SLV_TYPE_BUS, 2)
+#define FW_SLV_ID_I3C1			FW_SLV_ID(FW_SLV_TYPE_BUS, 3)
+#define FW_SLV_ID_BUS_IOC		FW_SLV_ID(FW_SLV_TYPE_BUS, 4)
+#define FW_SLV_ID_COMBO_PIPE_PHY0	FW_SLV_ID(FW_SLV_TYPE_BUS, 5)
+#define FW_SLV_ID_COMBO_PIPE_PHY1	FW_SLV_ID(FW_SLV_TYPE_BUS, 6)
+#define FW_SLV_ID_CRU			FW_SLV_ID(FW_SLV_TYPE_BUS, 7)
+#define FW_SLV_ID_DECOM			FW_SLV_ID(FW_SLV_TYPE_BUS, 8)
+#define FW_SLV_ID_CRU_PVTPLL		FW_SLV_ID(FW_SLV_TYPE_BUS, 9)
+#define FW_SLV_ID_I2C1			FW_SLV_ID(FW_SLV_TYPE_BUS, 13)
+#define FW_SLV_ID_I2C2			FW_SLV_ID(FW_SLV_TYPE_BUS, 14)
+#define FW_SLV_ID_I2C3			FW_SLV_ID(FW_SLV_TYPE_BUS, 15)
+#define FW_SLV_ID_I2C4			FW_SLV_ID(FW_SLV_TYPE_BUS, 16)
+#define FW_SLV_ID_I2C5			FW_SLV_ID(FW_SLV_TYPE_BUS, 17)
+#define FW_SLV_ID_I2C6			FW_SLV_ID(FW_SLV_TYPE_BUS, 18)
+#define FW_SLV_ID_I2C7			FW_SLV_ID(FW_SLV_TYPE_BUS, 19)
+#define FW_SLV_ID_I2C8			FW_SLV_ID(FW_SLV_TYPE_BUS, 20)
+#define FW_SLV_ID_I2C9			FW_SLV_ID(FW_SLV_TYPE_BUS, 21)
+#define FW_SLV_ID_INTMUX2BUS		FW_SLV_ID(FW_SLV_TYPE_BUS, 22)
+#define FW_SLV_ID_INTMUX2DDR		FW_SLV_ID(FW_SLV_TYPE_BUS, 23)
+#define FW_SLV_ID_INTMUX2PMU		FW_SLV_ID(FW_SLV_TYPE_BUS, 24)
+#define FW_SLV_ID_PPLL_CRU		FW_SLV_ID(FW_SLV_TYPE_BUS, 25)
+#define FW_SLV_ID_COMBO_PIPE_PHY0_GRF	FW_SLV_ID(FW_SLV_TYPE_BUS, 26)
+#define FW_SLV_ID_COMBO_PIPE_PHY1_GRF	FW_SLV_ID(FW_SLV_TYPE_BUS, 27)
+#define FW_SLV_ID_PMU2			FW_SLV_ID(FW_SLV_TYPE_BUS, 28)
+#define FW_SLV_ID_SARADC		FW_SLV_ID(FW_SLV_TYPE_BUS, 32)
+#define FW_SLV_ID_SPI0			FW_SLV_ID(FW_SLV_TYPE_BUS, 33)
+#define FW_SLV_ID_SPI1			FW_SLV_ID(FW_SLV_TYPE_BUS, 34)
+#define FW_SLV_ID_SPI2			FW_SLV_ID(FW_SLV_TYPE_BUS, 35)
+#define FW_SLV_ID_SPI3			FW_SLV_ID(FW_SLV_TYPE_BUS, 36)
+#define FW_SLV_ID_SPI4			FW_SLV_ID(FW_SLV_TYPE_BUS, 37)
+#define FW_SLV_ID_SYS_GRF		FW_SLV_ID(FW_SLV_TYPE_BUS, 38)
+#define FW_SLV_ID_TSADC			FW_SLV_ID(FW_SLV_TYPE_BUS, 41)
+#define FW_SLV_ID_UART0			FW_SLV_ID(FW_SLV_TYPE_BUS, 42)
+#define FW_SLV_ID_UART10		FW_SLV_ID(FW_SLV_TYPE_BUS, 43)
+#define FW_SLV_ID_UART11		FW_SLV_ID(FW_SLV_TYPE_BUS, 44)
+#define FW_SLV_ID_UART2			FW_SLV_ID(FW_SLV_TYPE_BUS, 45)
+#define FW_SLV_ID_UART3			FW_SLV_ID(FW_SLV_TYPE_BUS, 46)
+#define FW_SLV_ID_UART4			FW_SLV_ID(FW_SLV_TYPE_BUS, 47)
+#define FW_SLV_ID_UART5			FW_SLV_ID(FW_SLV_TYPE_BUS, 48)
+#define FW_SLV_ID_UART6			FW_SLV_ID(FW_SLV_TYPE_BUS, 49)
+#define FW_SLV_ID_UART7			FW_SLV_ID(FW_SLV_TYPE_BUS, 50)
+#define FW_SLV_ID_UART8			FW_SLV_ID(FW_SLV_TYPE_BUS, 51)
+#define FW_SLV_ID_UART9			FW_SLV_ID(FW_SLV_TYPE_BUS, 52)
+#define FW_SLV_ID_VCCIO0_1_3_IOC	FW_SLV_ID(FW_SLV_TYPE_BUS, 53)
+#define FW_SLV_ID_VCCIO2_4_5_IOC	FW_SLV_ID(FW_SLV_TYPE_BUS, 54)
+#define FW_SLV_ID_BUS_WDT		FW_SLV_ID(FW_SLV_TYPE_BUS, 55)
+#define FW_SLV_ID_WDT_NS		FW_SLV_ID(FW_SLV_TYPE_BUS, 56)
+#define FW_SLV_ID_DMAC0_NS		FW_SLV_ID(FW_SLV_TYPE_BUS, 57)
+#define FW_SLV_ID_DMAC1_NS		FW_SLV_ID(FW_SLV_TYPE_BUS, 58)
+#define FW_SLV_ID_DMAC2_NS		FW_SLV_ID(FW_SLV_TYPE_BUS, 59)
+#define FW_SLV_ID_DMAC0_S		FW_SLV_ID(FW_SLV_TYPE_BUS, 60)
+#define FW_SLV_ID_DMAC1_S		FW_SLV_ID(FW_SLV_TYPE_BUS, 61)
+#define FW_SLV_ID_DMAC2_S		FW_SLV_ID(FW_SLV_TYPE_BUS, 62)
+#define FW_SLV_ID_GIC400		FW_SLV_ID(FW_SLV_TYPE_BUS, 63)
+#define FW_SLV_ID_SERVICE_BUS		FW_SLV_ID(FW_SLV_TYPE_BUS, 64)
+#define FW_SLV_ID_SPINLOCK		FW_SLV_ID(FW_SLV_TYPE_BUS, 65)
+#define FW_SLV_ID_MAILBOX_CH0		FW_SLV_ID(FW_SLV_TYPE_BUS, 66)
+#define FW_SLV_ID_MAILBOX_CH1		FW_SLV_ID(FW_SLV_TYPE_BUS, 67)
+#define FW_SLV_ID_MAILBOX_CH2		FW_SLV_ID(FW_SLV_TYPE_BUS, 68)
+#define FW_SLV_ID_MAILBOX_CH3		FW_SLV_ID(FW_SLV_TYPE_BUS, 69)
+#define FW_SLV_ID_MAILBOX_CH4		FW_SLV_ID(FW_SLV_TYPE_BUS, 70)
+#define FW_SLV_ID_MAILBOX_CH5		FW_SLV_ID(FW_SLV_TYPE_BUS, 71)
+#define FW_SLV_ID_MAILBOX_CH6		FW_SLV_ID(FW_SLV_TYPE_BUS, 72)
+#define FW_SLV_ID_MAILBOX_CH7		FW_SLV_ID(FW_SLV_TYPE_BUS, 73)
+#define FW_SLV_ID_MAILBOX_CH8		FW_SLV_ID(FW_SLV_TYPE_BUS, 74)
+#define FW_SLV_ID_MAILBOX_CH9		FW_SLV_ID(FW_SLV_TYPE_BUS, 75)
+#define FW_SLV_ID_MAILBOX_CH10		FW_SLV_ID(FW_SLV_TYPE_BUS, 76)
+#define FW_SLV_ID_MAILBOX_CH11		FW_SLV_ID(FW_SLV_TYPE_BUS, 77)
+#define FW_SLV_ID_MAILBOX_CH12		FW_SLV_ID(FW_SLV_TYPE_BUS, 78)
+#define FW_SLV_ID_MAILBOX_CH13		FW_SLV_ID(FW_SLV_TYPE_BUS, 79)
+#define FW_SLV_ID_PWM1_CH0		FW_SLV_ID(FW_SLV_TYPE_BUS, 82)
+#define FW_SLV_ID_PWM1_CH1		FW_SLV_ID(FW_SLV_TYPE_BUS, 83)
+#define FW_SLV_ID_PWM1_CH2		FW_SLV_ID(FW_SLV_TYPE_BUS, 84)
+#define FW_SLV_ID_PWM1_CH3		FW_SLV_ID(FW_SLV_TYPE_BUS, 85)
+#define FW_SLV_ID_PWM1_CH4		FW_SLV_ID(FW_SLV_TYPE_BUS, 86)
+#define FW_SLV_ID_PWM1_CH5		FW_SLV_ID(FW_SLV_TYPE_BUS, 87)
+#define FW_SLV_ID_PWM2_CH0		FW_SLV_ID(FW_SLV_TYPE_BUS, 88)
+#define FW_SLV_ID_PWM2_CH1		FW_SLV_ID(FW_SLV_TYPE_BUS, 89)
+#define FW_SLV_ID_PWM2_CH2		FW_SLV_ID(FW_SLV_TYPE_BUS, 90)
+#define FW_SLV_ID_PWM2_CH3		FW_SLV_ID(FW_SLV_TYPE_BUS, 91)
+#define FW_SLV_ID_PWM2_CH4		FW_SLV_ID(FW_SLV_TYPE_BUS, 92)
+#define FW_SLV_ID_PWM2_CH5		FW_SLV_ID(FW_SLV_TYPE_BUS, 93)
+#define FW_SLV_ID_PWM2_CH6		FW_SLV_ID(FW_SLV_TYPE_BUS, 94)
+#define FW_SLV_ID_PWM2_CH7		FW_SLV_ID(FW_SLV_TYPE_BUS, 95)
+#define FW_SLV_ID_TIMER_NS_0_CH0	FW_SLV_ID(FW_SLV_TYPE_BUS, 96)
+#define FW_SLV_ID_TIMER_NS_0_CH1	FW_SLV_ID(FW_SLV_TYPE_BUS, 97)
+#define FW_SLV_ID_TIMER_NS_0_CH2	FW_SLV_ID(FW_SLV_TYPE_BUS, 98)
+#define FW_SLV_ID_TIMER_NS_0_CH3	FW_SLV_ID(FW_SLV_TYPE_BUS, 99)
+#define FW_SLV_ID_TIMER_NS_0_CH4	FW_SLV_ID(FW_SLV_TYPE_BUS, 100)
+#define FW_SLV_ID_TIMER_NS_0_CH5	FW_SLV_ID(FW_SLV_TYPE_BUS, 101)
+#define FW_SLV_ID_TIMER_NS_1_CH0	FW_SLV_ID(FW_SLV_TYPE_BUS, 102)
+#define FW_SLV_ID_TIMER_NS_1_CH1	FW_SLV_ID(FW_SLV_TYPE_BUS, 103)
+#define FW_SLV_ID_TIMER_NS_1_CH2	FW_SLV_ID(FW_SLV_TYPE_BUS, 104)
+#define FW_SLV_ID_TIMER_NS_1_CH3	FW_SLV_ID(FW_SLV_TYPE_BUS, 105)
+#define FW_SLV_ID_TIMER_NS_1_CH4	FW_SLV_ID(FW_SLV_TYPE_BUS, 106)
+#define FW_SLV_ID_TIMER_NS_1_CH5	FW_SLV_ID(FW_SLV_TYPE_BUS, 107)
+#define FW_SLV_ID_GPIO1_CH0		FW_SLV_ID(FW_SLV_TYPE_BUS, 108)
+#define FW_SLV_ID_GPIO1_CH1		FW_SLV_ID(FW_SLV_TYPE_BUS, 109)
+#define FW_SLV_ID_GPIO1_CH2		FW_SLV_ID(FW_SLV_TYPE_BUS, 110)
+#define FW_SLV_ID_GPIO1_CH3		FW_SLV_ID(FW_SLV_TYPE_BUS, 111)
+#define FW_SLV_ID_GPIO2_CH0		FW_SLV_ID(FW_SLV_TYPE_BUS, 112)
+#define FW_SLV_ID_GPIO2_CH1		FW_SLV_ID(FW_SLV_TYPE_BUS, 113)
+#define FW_SLV_ID_GPIO2_CH2		FW_SLV_ID(FW_SLV_TYPE_BUS, 114)
+#define FW_SLV_ID_GPIO2_CH3		FW_SLV_ID(FW_SLV_TYPE_BUS, 115)
+#define FW_SLV_ID_GPIO3_CH0		FW_SLV_ID(FW_SLV_TYPE_BUS, 116)
+#define FW_SLV_ID_GPIO3_CH1		FW_SLV_ID(FW_SLV_TYPE_BUS, 117)
+#define FW_SLV_ID_GPIO3_CH2		FW_SLV_ID(FW_SLV_TYPE_BUS, 118)
+#define FW_SLV_ID_GPIO3_CH3		FW_SLV_ID(FW_SLV_TYPE_BUS, 119)
+#define FW_SLV_ID_GPIO4_CH0		FW_SLV_ID(FW_SLV_TYPE_BUS, 120)
+#define FW_SLV_ID_GPIO4_CH1		FW_SLV_ID(FW_SLV_TYPE_BUS, 121)
+#define FW_SLV_ID_GPIO4_CH2		FW_SLV_ID(FW_SLV_TYPE_BUS, 122)
+#define FW_SLV_ID_GPIO4_CH3		FW_SLV_ID(FW_SLV_TYPE_BUS, 123)
+#define FW_SLV_ID_BUS_CNT		125
+
+#define FW_SLV_ID_ACDCDIG_DSM		FW_SLV_ID(FW_SLV_TYPE_TOP, 0)
+#define FW_SLV_ID_ASRC2CH_0		FW_SLV_ID(FW_SLV_TYPE_TOP, 1)
+#define FW_SLV_ID_ASRC2CH_1		FW_SLV_ID(FW_SLV_TYPE_TOP, 2)
+#define FW_SLV_ID_ASRC4CH_0		FW_SLV_ID(FW_SLV_TYPE_TOP, 3)
+#define FW_SLV_ID_ASRC4CH_1		FW_SLV_ID(FW_SLV_TYPE_TOP, 4)
+#define FW_SLV_ID_PDM1			FW_SLV_ID(FW_SLV_TYPE_TOP, 5)
+#define FW_SLV_ID_SAI0_8CH		FW_SLV_ID(FW_SLV_TYPE_TOP, 6)
+#define FW_SLV_ID_SAI1_8CH		FW_SLV_ID(FW_SLV_TYPE_TOP, 7)
+#define FW_SLV_ID_SAI2_8CH		FW_SLV_ID(FW_SLV_TYPE_TOP, 8)
+#define FW_SLV_ID_SAI3_2CH		FW_SLV_ID(FW_SLV_TYPE_TOP, 9)
+#define FW_SLV_ID_SAI4_2CH		FW_SLV_ID(FW_SLV_TYPE_TOP, 10)
+#define FW_SLV_ID_SPDIF_RX0		FW_SLV_ID(FW_SLV_TYPE_TOP, 11)
+#define FW_SLV_ID_SPDIF_RX1		FW_SLV_ID(FW_SLV_TYPE_TOP, 12)
+#define FW_SLV_ID_SPDIF_TX0		FW_SLV_ID(FW_SLV_TYPE_TOP, 13)
+#define FW_SLV_ID_SPDIF_TX1		FW_SLV_ID(FW_SLV_TYPE_TOP, 14)
+#define FW_SLV_ID_DSMC_MEM		FW_SLV_ID(FW_SLV_TYPE_TOP, 15)
+#define FW_SLV_ID_FSPI1			FW_SLV_ID(FW_SLV_TYPE_TOP, 16)
+#define FW_SLV_ID_FLEXBUS		FW_SLV_ID(FW_SLV_TYPE_TOP, 17)
+#define FW_SLV_ID_SDIO			FW_SLV_ID(FW_SLV_TYPE_TOP, 18)
+#define FW_SLV_ID_SDMMC			FW_SLV_ID(FW_SLV_TYPE_TOP, 19)
+#define FW_SLV_ID_DSMC_CFG		FW_SLV_ID(FW_SLV_TYPE_TOP, 20)
+#define FW_SLV_ID_GMAC0			FW_SLV_ID(FW_SLV_TYPE_TOP, 21)
+#define FW_SLV_ID_GMAC1			FW_SLV_ID(FW_SLV_TYPE_TOP, 22)
+#define FW_SLV_ID_SDGMAC_GRF		FW_SLV_ID(FW_SLV_TYPE_TOP, 23)
+#define FW_SLV_ID_EMMC			FW_SLV_ID(FW_SLV_TYPE_TOP, 24)
+#define FW_SLV_ID_FSPI0			FW_SLV_ID(FW_SLV_TYPE_TOP, 25)
+#define FW_SLV_ID_NSCRYPTO		FW_SLV_ID(FW_SLV_TYPE_TOP, 26)
+#define FW_SLV_ID_RKRNG_NS		FW_SLV_ID(FW_SLV_TYPE_TOP, 27)
+#define FW_SLV_ID_SCRYPTO		FW_SLV_ID(FW_SLV_TYPE_TOP, 28)
+#define FW_SLV_ID_KEYLAD		FW_SLV_ID(FW_SLV_TYPE_TOP, 29)
+#define FW_SLV_ID_RKRNG_S		FW_SLV_ID(FW_SLV_TYPE_TOP, 30)
+#define FW_SLV_ID_OTPC_NS		FW_SLV_ID(FW_SLV_TYPE_TOP, 31)
+#define FW_SLV_ID_JTAG_LOCK		FW_SLV_ID(FW_SLV_TYPE_TOP, 33)
+#define FW_SLV_ID_OTPC_S		FW_SLV_ID(FW_SLV_TYPE_TOP, 34)
+#define FW_SLV_ID_OTPMASK		FW_SLV_ID(FW_SLV_TYPE_TOP, 35)
+#define FW_SLV_ID_SECURE_CRU		FW_SLV_ID(FW_SLV_TYPE_TOP, 36)
+#define FW_SLV_ID_SECURE_CRU_S		FW_SLV_ID(FW_SLV_TYPE_TOP, 37)
+#define FW_SLV_ID_SYS_SGRF		FW_SLV_ID(FW_SLV_TYPE_TOP, 38)
+#define FW_SLV_ID_BOOTROM		FW_SLV_ID(FW_SLV_TYPE_TOP, 39)
+#define FW_SLV_ID_WDT_S			FW_SLV_ID(FW_SLV_TYPE_TOP, 41)
+#define FW_SLV_ID_SERVICE_GMAC		FW_SLV_ID(FW_SLV_TYPE_TOP, 42)
+#define FW_SLV_ID_SERVICE_NVM		FW_SLV_ID(FW_SLV_TYPE_TOP, 43)
+#define FW_SLV_ID_SERVICE_SECURE	FW_SLV_ID(FW_SLV_TYPE_TOP, 44)
+#define FW_SLV_ID_SERVICE_VENC		FW_SLV_ID(FW_SLV_TYPE_TOP, 45)
+#define FW_SLV_ID_SERVICE_VI		FW_SLV_ID(FW_SLV_TYPE_TOP, 46)
+#define FW_SLV_ID_SERVICE_VPU		FW_SLV_ID(FW_SLV_TYPE_TOP, 47)
+#define FW_SLV_ID_VEPU0			FW_SLV_ID(FW_SLV_TYPE_TOP, 48)
+#define FW_SLV_ID_ISP			FW_SLV_ID(FW_SLV_TYPE_TOP, 49)
+#define FW_SLV_ID_VICAP			FW_SLV_ID(FW_SLV_TYPE_TOP, 50)
+#define FW_SLV_ID_VPSS			FW_SLV_ID(FW_SLV_TYPE_TOP, 51)
+#define FW_SLV_ID_CSIHOST0		FW_SLV_ID(FW_SLV_TYPE_TOP, 52)
+#define FW_SLV_ID_CSIHOST1		FW_SLV_ID(FW_SLV_TYPE_TOP, 53)
+#define FW_SLV_ID_CSIHOST2		FW_SLV_ID(FW_SLV_TYPE_TOP, 54)
+#define FW_SLV_ID_VI_GRF		FW_SLV_ID(FW_SLV_TYPE_TOP, 55)
+#define FW_SLV_ID_EBC			FW_SLV_ID(FW_SLV_TYPE_TOP, 56)
+#define FW_SLV_ID_JPEG			FW_SLV_ID(FW_SLV_TYPE_TOP, 57)
+#define FW_SLV_ID_RGA0			FW_SLV_ID(FW_SLV_TYPE_TOP, 58)
+#define FW_SLV_ID_RGA1			FW_SLV_ID(FW_SLV_TYPE_TOP, 59)
+#define FW_SLV_ID_VDPP			FW_SLV_ID(FW_SLV_TYPE_TOP, 60)
+#define FW_SLV_ID_TIMER_S_0_CH0		FW_SLV_ID(FW_SLV_TYPE_TOP, 61)
+#define FW_SLV_ID_TIMER_S_0_CH1		FW_SLV_ID(FW_SLV_TYPE_TOP, 62)
+#define FW_SLV_ID_TIMER_S_0_CH2		FW_SLV_ID(FW_SLV_TYPE_TOP, 63)
+#define FW_SLV_ID_TIMER_S_0_CH3		FW_SLV_ID(FW_SLV_TYPE_TOP, 64)
+#define FW_SLV_ID_TIMER_S_0_CH4		FW_SLV_ID(FW_SLV_TYPE_TOP, 65)
+#define FW_SLV_ID_TIMER_S_0_CH5		FW_SLV_ID(FW_SLV_TYPE_TOP, 66)
+#define FW_SLV_ID_TIMER_S_1_CH0		FW_SLV_ID(FW_SLV_TYPE_TOP, 67)
+#define FW_SLV_ID_TIMER_S_1_CH1		FW_SLV_ID(FW_SLV_TYPE_TOP, 68)
+#define FW_SLV_ID_TIMER_S_1_CH2		FW_SLV_ID(FW_SLV_TYPE_TOP, 69)
+#define FW_SLV_ID_TIMER_S_1_CH3		FW_SLV_ID(FW_SLV_TYPE_TOP, 70)
+#define FW_SLV_ID_TIMER_S_1_CH4		FW_SLV_ID(FW_SLV_TYPE_TOP, 71)
+#define FW_SLV_ID_TIMER_S_1_CH5		FW_SLV_ID(FW_SLV_TYPE_TOP, 72)
+#define FW_SLV_ID_SYS_FW		FW_SLV_ID(FW_SLV_TYPE_TOP, 73)
+#define FW_SLV_ID_VEPU1			FW_SLV_ID(FW_SLV_TYPE_TOP, 75)
+#define FW_SLV_ID_SERVICE_VEPU1		FW_SLV_ID(FW_SLV_TYPE_TOP, 76)
+#define FW_SLV_ID_CSIHOST3		FW_SLV_ID(FW_SLV_TYPE_TOP, 77)
+#define FW_SLV_ID_CSIHOST4		FW_SLV_ID(FW_SLV_TYPE_TOP, 78)
+#define FW_SLV_ID_TOP_CNT		80
+
+#define FW_SLV_ID_CENTER_GRF		FW_SLV_ID(FW_SLV_TYPE_CENTER, 0)
+#define FW_SLV_ID_DMA2DDR		FW_SLV_ID(FW_SLV_TYPE_CENTER, 1)
+#define FW_SLV_ID_AHB2APB		FW_SLV_ID(FW_SLV_TYPE_CENTER, 2)
+#define FW_SLV_ID_DDR_GRF		FW_SLV_ID(FW_SLV_TYPE_CENTER, 3)
+#define FW_SLV_ID_DDRCTL0		FW_SLV_ID(FW_SLV_TYPE_CENTER, 4)
+#define FW_SLV_ID_DDRCTL_1		FW_SLV_ID(FW_SLV_TYPE_CENTER, 5)
+#define FW_SLV_ID_DDRPHY0		FW_SLV_ID(FW_SLV_TYPE_CENTER, 6)
+#define FW_SLV_ID_DDR0_CRU		FW_SLV_ID(FW_SLV_TYPE_CENTER, 7)
+#define FW_SLV_ID_DDRPHY1		FW_SLV_ID(FW_SLV_TYPE_CENTER, 8)
+#define FW_SLV_ID_DDR1_CRU		FW_SLV_ID(FW_SLV_TYPE_CENTER, 9)
+#define FW_SLV_ID_DDRMON0		FW_SLV_ID(FW_SLV_TYPE_CENTER, 10)
+#define FW_SLV_ID_DDRMON1		FW_SLV_ID(FW_SLV_TYPE_CENTER, 11)
+#define FW_SLV_ID_HWLP0			FW_SLV_ID(FW_SLV_TYPE_CENTER, 12)
+#define FW_SLV_ID_HWLP1			FW_SLV_ID(FW_SLV_TYPE_CENTER, 13)
+#define FW_SLV_ID_DDR_PVTPLL		FW_SLV_ID(FW_SLV_TYPE_CENTER, 14)
+#define FW_SLV_ID_DDR_WDT		FW_SLV_ID(FW_SLV_TYPE_CENTER, 15)
+#define FW_SLV_ID_RKVDEC		FW_SLV_ID(FW_SLV_TYPE_CENTER, 16)
+#define FW_SLV_ID_SERVICE_CCI2		FW_SLV_ID(FW_SLV_TYPE_CENTER, 17)
+#define FW_SLV_ID_SERVICE_CENTER	FW_SLV_ID(FW_SLV_TYPE_CENTER, 18)
+#define FW_SLV_ID_SERVICE_DDR		FW_SLV_ID(FW_SLV_TYPE_CENTER, 19)
+#define FW_SLV_ID_SERVICE_RKVDEC	FW_SLV_ID(FW_SLV_TYPE_CENTER, 20)
+#define FW_SLV_ID_SERVICE_USB		FW_SLV_ID(FW_SLV_TYPE_CENTER, 21)
+#define FW_SLV_ID_SERVICE_VO0		FW_SLV_ID(FW_SLV_TYPE_CENTER, 22)
+#define FW_SLV_ID_SERVICE_VO1		FW_SLV_ID(FW_SLV_TYPE_CENTER, 23)
+#define FW_SLV_ID_SERVICE_VOP		FW_SLV_ID(FW_SLV_TYPE_CENTER, 24)
+#define FW_SLV_ID_UFS_APBS		FW_SLV_ID(FW_SLV_TYPE_CENTER, 25)
+#define FW_SLV_ID_UFS_AXIS		FW_SLV_ID(FW_SLV_TYPE_CENTER, 26)
+#define FW_SLV_ID_USB0			FW_SLV_ID(FW_SLV_TYPE_CENTER, 27)
+#define FW_SLV_ID_MMU2			FW_SLV_ID(FW_SLV_TYPE_CENTER, 28)
+#define FW_SLV_ID_USB_GRF		FW_SLV_ID(FW_SLV_TYPE_CENTER, 29)
+#define FW_SLV_ID_HDCP0_MMU		FW_SLV_ID(FW_SLV_TYPE_CENTER, 30)
+#define FW_SLV_ID_SAI5_8CH		FW_SLV_ID(FW_SLV_TYPE_CENTER, 31)
+#define FW_SLV_ID_SAI6_8CH		FW_SLV_ID(FW_SLV_TYPE_CENTER, 32)
+#define FW_SLV_ID_SPDIF_RX2		FW_SLV_ID(FW_SLV_TYPE_CENTER, 33)
+#define FW_SLV_ID_SPDIF_TX2		FW_SLV_ID(FW_SLV_TYPE_CENTER, 34)
+#define FW_SLV_ID_HDCP0_KEY		FW_SLV_ID(FW_SLV_TYPE_CENTER, 35)
+#define FW_SLV_ID_DSIHOST		FW_SLV_ID(FW_SLV_TYPE_CENTER, 36)
+#define FW_SLV_ID_EDP0			FW_SLV_ID(FW_SLV_TYPE_CENTER, 37)
+#define FW_SLV_ID_HDCP0			FW_SLV_ID(FW_SLV_TYPE_CENTER, 38)
+#define FW_SLV_ID_HDCP0_TRNG		FW_SLV_ID(FW_SLV_TYPE_CENTER, 39)
+#define FW_SLV_ID_HDMITX		FW_SLV_ID(FW_SLV_TYPE_CENTER, 40)
+#define FW_SLV_ID_VO0_GRF		FW_SLV_ID(FW_SLV_TYPE_CENTER, 41)
+#define FW_SLV_ID_EDP0_S		FW_SLV_ID(FW_SLV_TYPE_CENTER, 42)
+#define FW_SLV_ID_HDCP1_MMU		FW_SLV_ID(FW_SLV_TYPE_CENTER, 43)
+#define FW_SLV_ID_SAI7_8CH		FW_SLV_ID(FW_SLV_TYPE_CENTER, 44)
+#define FW_SLV_ID_SPDIF_TX3		FW_SLV_ID(FW_SLV_TYPE_CENTER, 45)
+#define FW_SLV_ID_HDCP1_KEY		FW_SLV_ID(FW_SLV_TYPE_CENTER, 46)
+#define FW_SLV_ID_DP			FW_SLV_ID(FW_SLV_TYPE_CENTER, 47)
+#define FW_SLV_ID_HDCP1			FW_SLV_ID(FW_SLV_TYPE_CENTER, 48)
+#define FW_SLV_ID_HDCP1_TRNG		FW_SLV_ID(FW_SLV_TYPE_CENTER, 49)
+#define FW_SLV_ID_VO1_GRF		FW_SLV_ID(FW_SLV_TYPE_CENTER, 50)
+#define FW_SLV_ID_VOP_GRF		FW_SLV_ID(FW_SLV_TYPE_CENTER, 52)
+#define FW_SLV_ID_UFS_GRF		FW_SLV_ID(FW_SLV_TYPE_CENTER, 53)
+#define FW_SLV_ID_SPDIF_TX4		FW_SLV_ID(FW_SLV_TYPE_CENTER, 54)
+#define FW_SLV_ID_SPDIF_TX5		FW_SLV_ID(FW_SLV_TYPE_CENTER, 55)
+#define FW_SLV_ID_SAI8_8CH		FW_SLV_ID(FW_SLV_TYPE_CENTER, 56)
+#define FW_SLV_ID_SAI9_8CH		FW_SLV_ID(FW_SLV_TYPE_CENTER, 57)
+#define FW_SLV_ID_DDR_TIMER_CH0		FW_SLV_ID(FW_SLV_TYPE_CENTER, 58)
+#define FW_SLV_ID_DDR_TIMER_CH1		FW_SLV_ID(FW_SLV_TYPE_CENTER, 59)
+#define FW_SLV_ID_VOP_RGN0		FW_SLV_ID(FW_SLV_TYPE_CENTER, 60)
+#define FW_SLV_ID_VOP_RGN1		FW_SLV_ID(FW_SLV_TYPE_CENTER, 61)
+#define FW_SLV_ID_VOP_RGN2		FW_SLV_ID(FW_SLV_TYPE_CENTER, 62)
+#define FW_SLV_ID_VOP_RGN3		FW_SLV_ID(FW_SLV_TYPE_CENTER, 63)
+#define FW_SLV_ID_VOP_OTHERS		FW_SLV_ID(FW_SLV_TYPE_CENTER, 64)
+#define FW_SLV_ID_CENTER_CNT		65
+
+#define FW_SLV_ID_BIGCORE_CRU		FW_SLV_ID(FW_SLV_TYPE_CCI, 0)
+#define FW_SLV_ID_BIGCORE_GRF		FW_SLV_ID(FW_SLV_TYPE_CCI, 1)
+#define FW_SLV_ID_CCI			FW_SLV_ID(FW_SLV_TYPE_CCI, 2)
+#define FW_SLV_ID_CCI_CRU		FW_SLV_ID(FW_SLV_TYPE_CCI, 3)
+#define FW_SLV_ID_CCI_PVTPLL		FW_SLV_ID(FW_SLV_TYPE_CCI, 4)
+#define FW_SLV_ID_CCI_GRF		FW_SLV_ID(FW_SLV_TYPE_CCI, 5)
+#define FW_SLV_ID_DAP_LITE_A53		FW_SLV_ID(FW_SLV_TYPE_CCI, 6)
+#define FW_SLV_ID_DAP_LITE_A72		FW_SLV_ID(FW_SLV_TYPE_CCI, 7)
+#define FW_SLV_ID_LITCORE_GRF		FW_SLV_ID(FW_SLV_TYPE_CCI, 8)
+#define FW_SLV_ID_LITCORE_CRU		FW_SLV_ID(FW_SLV_TYPE_CCI, 9)
+#define FW_SLV_ID_SERVICE_CCI		FW_SLV_ID(FW_SLV_TYPE_CCI, 10)
+#define FW_SLV_ID_BIGCORE_PVTPLL	FW_SLV_ID(FW_SLV_TYPE_CCI, 11)
+#define FW_SLV_ID_LITCORE_PVTPLL	FW_SLV_ID(FW_SLV_TYPE_CCI, 12)
+#define FW_SLV_ID_CCI_CNT		15
+
+#define FW_SLV_ID_PCIE0_DBI		FW_SLV_ID(FW_SLV_TYPE_PHP, 0)
+#define FW_SLV_ID_PCIE0_DBI_L		FW_SLV_ID(FW_SLV_TYPE_PHP, 1)
+#define FW_SLV_ID_PCIE0_S		FW_SLV_ID(FW_SLV_TYPE_PHP, 2)
+#define FW_SLV_ID_PCIE0_S_L		FW_SLV_ID(FW_SLV_TYPE_PHP, 3)
+#define FW_SLV_ID_PCIE1_DBI		FW_SLV_ID(FW_SLV_TYPE_PHP, 4)
+#define FW_SLV_ID_PCIE1_DBI_L		FW_SLV_ID(FW_SLV_TYPE_PHP, 5)
+#define FW_SLV_ID_PCIE1_S		FW_SLV_ID(FW_SLV_TYPE_PHP, 6)
+#define FW_SLV_ID_PCIE1_S_L		FW_SLV_ID(FW_SLV_TYPE_PHP, 7)
+#define FW_SLV_ID_USB1			FW_SLV_ID(FW_SLV_TYPE_PHP, 8)
+#define FW_SLV_ID_PCIE0_APB		FW_SLV_ID(FW_SLV_TYPE_PHP, 9)
+#define FW_SLV_ID_PCIE1_APB		FW_SLV_ID(FW_SLV_TYPE_PHP, 10)
+#define FW_SLV_ID_PHP_GRF		FW_SLV_ID(FW_SLV_TYPE_PHP, 11)
+#define FW_SLV_ID_SATA0			FW_SLV_ID(FW_SLV_TYPE_PHP, 12)
+#define FW_SLV_ID_SATA1			FW_SLV_ID(FW_SLV_TYPE_PHP, 13)
+#define FW_SLV_ID_SERVICE_PHP		FW_SLV_ID(FW_SLV_TYPE_PHP, 14)
+#define FW_SLV_ID_MMU0			FW_SLV_ID(FW_SLV_TYPE_PHP, 15)
+#define FW_SLV_ID_MMU1			FW_SLV_ID(FW_SLV_TYPE_PHP, 16)
+#define FW_SLV_ID_PHP_CNT		20
+
+#define FW_SLV_ID_GPU_GRF		FW_SLV_ID(FW_SLV_TYPE_GPU, 0)
+#define FW_SLV_ID_GPU			FW_SLV_ID(FW_SLV_TYPE_GPU, 1)
+#define FW_SLV_ID_SERVICE_GPU		FW_SLV_ID(FW_SLV_TYPE_GPU, 2)
+#define FW_SLV_ID_GPU_PVTPLL		FW_SLV_ID(FW_SLV_TYPE_GPU, 3)
+#define FW_SLV_ID_GPU_CNT		5
+
+#define FW_SLV_ID_RKNN_TOP		FW_SLV_ID(FW_SLV_TYPE_NPU, 0)
+#define FW_SLV_ID_SERVICE_NPU0		FW_SLV_ID(FW_SLV_TYPE_NPU, 1)
+#define FW_SLV_ID_SERVICE_NPU1		FW_SLV_ID(FW_SLV_TYPE_NPU, 2)
+#define FW_SLV_ID_SERVICE_NPUSUBSYS	FW_SLV_ID(FW_SLV_TYPE_NPU, 3)
+#define FW_SLV_ID_RKNN_NSP		FW_SLV_ID(FW_SLV_TYPE_NPU, 4)
+#define FW_SLV_ID_NPU_GRF		FW_SLV_ID(FW_SLV_TYPE_NPU, 5)
+#define FW_SLV_ID_NPU_PVTPLL		FW_SLV_ID(FW_SLV_TYPE_NPU, 6)
+#define FW_SLV_ID_NPU_WDT		FW_SLV_ID(FW_SLV_TYPE_NPU, 7)
+#define FW_SLV_ID_NPU_TIMER_CH0		FW_SLV_ID(FW_SLV_TYPE_NPU, 8)
+#define FW_SLV_ID_NPU_TIMER_CH1		FW_SLV_ID(FW_SLV_TYPE_NPU, 9)
+#define FW_SLV_ID_NPU_CNT		10
+
+#define FW_SLV_ID_PDM0			FW_SLV_ID(FW_SLV_TYPE_PMU, 0)
+#define FW_SLV_ID_PMU_MEM		FW_SLV_ID(FW_SLV_TYPE_PMU, 1)
+#define FW_SLV_ID_CSIDPHY_GRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 2)
+#define FW_SLV_ID_VDMA			FW_SLV_ID(FW_SLV_TYPE_PMU, 3)
+#define FW_SLV_ID_HDPTXPHY		FW_SLV_ID(FW_SLV_TYPE_PMU, 4)
+#define FW_SLV_ID_HDPTXPHY0_GRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 5)
+#define FW_SLV_ID_I2C0			FW_SLV_ID(FW_SLV_TYPE_PMU, 6)
+#define FW_SLV_ID_DCPHY			FW_SLV_ID(FW_SLV_TYPE_PMU, 7)
+#define FW_SLV_ID_CSIDPHY0		FW_SLV_ID(FW_SLV_TYPE_PMU, 8)
+#define FW_SLV_ID_DCPHY_GRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 9)
+#define FW_SLV_ID_PMU0			FW_SLV_ID(FW_SLV_TYPE_PMU, 10)
+#define FW_SLV_ID_PMU0_GRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 11)
+#define FW_SLV_ID_PMU0_IOC		FW_SLV_ID(FW_SLV_TYPE_PMU, 12)
+#define FW_SLV_ID_PMU1			FW_SLV_ID(FW_SLV_TYPE_PMU, 13)
+#define FW_SLV_ID_PMU1_CRU		FW_SLV_ID(FW_SLV_TYPE_PMU, 14)
+#define FW_SLV_ID_PMU1_CRU_S		FW_SLV_ID(FW_SLV_TYPE_PMU, 15)
+#define FW_SLV_ID_PMU1_GRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 16)
+#define FW_SLV_ID_PMU1_IOC		FW_SLV_ID(FW_SLV_TYPE_PMU, 17)
+#define FW_SLV_ID_PWM0_CH0		FW_SLV_ID(FW_SLV_TYPE_PMU, 18)
+#define FW_SLV_ID_PWM0_CH1		FW_SLV_ID(FW_SLV_TYPE_PMU, 19)
+#define FW_SLV_ID_UART1			FW_SLV_ID(FW_SLV_TYPE_PMU, 20)
+#define FW_SLV_ID_MPHY_GRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 21)
+#define FW_SLV_ID_MPHY			FW_SLV_ID(FW_SLV_TYPE_PMU, 22)
+#define FW_SLV_ID_USB2PHY0_GRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 23)
+#define FW_SLV_ID_USB2PHY1_GRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 24)
+#define FW_SLV_ID_USBDPPHY		FW_SLV_ID(FW_SLV_TYPE_PMU, 25)
+#define FW_SLV_ID_USBDPPHY_GRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 26)
+#define FW_SLV_ID_VCCIO6_IOC		FW_SLV_ID(FW_SLV_TYPE_PMU, 27)
+#define FW_SLV_ID_PMU_WDT		FW_SLV_ID(FW_SLV_TYPE_PMU, 28)
+#define FW_SLV_ID_HPTIMER		FW_SLV_ID(FW_SLV_TYPE_PMU, 29)
+#define FW_SLV_ID_OSC_CHK		FW_SLV_ID(FW_SLV_TYPE_PMU, 30)
+#define FW_SLV_ID_PMU0_SGRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 31)
+#define FW_SLV_ID_PMU1_SGRF		FW_SLV_ID(FW_SLV_TYPE_PMU, 32)
+#define FW_SLV_ID_PMU_PVTM		FW_SLV_ID(FW_SLV_TYPE_PMU, 33)
+#define FW_SLV_ID_SCRAMBLE_KEY		FW_SLV_ID(FW_SLV_TYPE_PMU, 34)
+#define FW_SLV_ID_SERVICE_PMU		FW_SLV_ID(FW_SLV_TYPE_PMU, 35)
+#define FW_SLV_ID_PMU_SRAM_REMAP	FW_SLV_ID(FW_SLV_TYPE_PMU, 36)
+#define FW_SLV_ID_PMU_TIMER_CH0		FW_SLV_ID(FW_SLV_TYPE_PMU, 37)
+#define FW_SLV_ID_PMU_TIMER_CH1		FW_SLV_ID(FW_SLV_TYPE_PMU, 38)
+#define FW_SLV_ID_GPIO0_CH0		FW_SLV_ID(FW_SLV_TYPE_PMU, 39)
+#define FW_SLV_ID_GPIO0_CH1		FW_SLV_ID(FW_SLV_TYPE_PMU, 40)
+#define FW_SLV_ID_GPIO0_CH2		FW_SLV_ID(FW_SLV_TYPE_PMU, 41)
+#define FW_SLV_ID_GPIO0_CH3		FW_SLV_ID(FW_SLV_TYPE_PMU, 42)
+#define FW_SLV_ID_PMU_FW		FW_SLV_ID(FW_SLV_TYPE_PMU, 43)
+#define FW_SLV_ID_PMU_CNT		45
+
+#define PLAT_MAX_DDR_CAPACITY_MB	0x8000	/* for 32Gb */
+#define RG_MAP_SECURE(top, base)	\
+	(((((top) - 1) & 0x7fff) << 16) | ((base) & 0x7fff))
+#define RG_MAP_SRAM_SECURE(top_kb, base_kb)	\
+	(((((top_kb) / 4 - 1) & 0xff) << 8) | ((base_kb) / 4 & 0xff))
+#define RG_MAP_CBUF_SECURE(top_kb, base_kb)	\
+	(((((top_kb) / 4 - 1) & 0xff) << 8) | ((base_kb) / 4 & 0xff))
+
+#define FW_UPDATE_WAIT_LOOP		500000
+
+__pmusramfunc void pmusram_fw_update_msk(uint32_t msk);
+__pmusramfunc void pmusram_all_fw_bypass(void);
+
+void fw_init(void);
+
+#endif /* __FIREWALL_H__ */
diff --git a/plat/rockchip/rk3576/drivers/secure/secure.c b/plat/rockchip/rk3576/drivers/secure/secure.c
new file mode 100644
index 0000000..55b8d93
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/secure/secure.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#include <secure.h>
+#include <soc.h>
+
+static void secure_timer_init(void)
+{
+	/* gpu's cntvalue comes from stimer1 channel_5 */
+	mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG,
+		      TIMER_DIS);
+
+	mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+	/* auto reload & enable the timer */
+	mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG,
+		      TIMER_EN | TIMER_FMODE);
+}
+
+void secure_init(void)
+{
+	secure_timer_init();
+	fw_init();
+
+	/* crypto secure controlled by crypto */
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0), BITS_WITH_WMASK(0, 0x1, 4));
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0), BITS_WITH_WMASK(0, 0x1, 5));
+
+	/* disable DP encryption mode */
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(1), BITS_WITH_WMASK(1, 0x1, 14));
+}
diff --git a/plat/rockchip/rk3576/drivers/secure/secure.h b/plat/rockchip/rk3576/drivers/secure/secure.h
new file mode 100644
index 0000000..f00e519
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/secure/secure.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef SECURE_H
+#define SECURE_H
+
+#include <firewall.h>
+
+/* PMU0SGRF */
+#define PMU0SGRF_SOC_CON(i)		((i) * 4)
+
+ /* PMU1SGRF */
+#define PMU1SGRF_SOC_CON(i)		((i) * 4)
+
+  /* CCISGRF */
+#define CCISGRF_SOC_CON(i)		(0x20 + (i) * 4)
+#define CCISGRF_DDR_HASH_CON(i)		(0x40 + (i) * 4)
+
+ /* SGRF */
+#define SYSSGRF_DDR_BANK_MSK(i)		(0x04 + (i) * 4)
+#define SYSSGRF_DDR_CH_MSK(i)		(0x18 + (i) * 4)
+#define SYSSGRF_SOC_CON(i)		(0x20 + (i) * 4)
+#define SYSSGRF_DMAC_CON(i)		(0x80 + (i) * 4)
+#define SYSSGRF_SOC_STATUS		0x240
+
+void secure_init(void);
+
+#endif /* SECURE_H */
diff --git a/plat/rockchip/rk3576/drivers/soc/soc.c b/plat/rockchip/rk3576/drivers/soc/soc.c
new file mode 100644
index 0000000..a78e82e
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/soc/soc.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <plat_private.h>
+#include <rk3576_clk.h>
+#include <secure.h>
+#include <soc.h>
+
+const mmap_region_t plat_rk_mmap[] = {
+	MAP_REGION_FLAT(RK3576_DEV_RNG0_BASE, RK3576_DEV_RNG0_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DDR_SHARE_MEM, DDR_SHARE_SIZE,
+			MT_DEVICE | MT_RW | MT_NS),
+	{ 0 }
+};
+
+/* The RockChip power domain tree descriptor */
+const unsigned char rockchip_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* No of children for the root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of children for the first cluster node */
+	PLATFORM_CLUSTER0_CORE_COUNT,
+	/* No of children for the second cluster node */
+	PLATFORM_CLUSTER1_CORE_COUNT
+};
+
+static void clear_glb_reset_status(void)
+{
+	uint32_t cru_sel55 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(55));
+
+	/* switch pclk_bus_root to 24M before writing CRU_GLB_RST_ST */
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(55),
+		      BITS_WITH_WMASK(2, 0x3, 2));
+	dsb();
+
+	mmio_write_32(CRU_BASE + CRU_GLB_RST_ST, 0xffff);
+	dsb();
+
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(55),
+		      WITH_16BITS_WMSK(cru_sel55));
+}
+
+static void print_glb_reset_status(void)
+{
+	uint32_t glb_rst_st = 0, warm_boot = 0;
+
+	/* clear CRU_GLB_RST_ST_NCLR if cold boot */
+	if (mmio_read_32(PMU0_GRF_BASE + PMU0GRF_OS_REG(17)) == WARM_BOOT_MAGIC) {
+		/* ignore npu_wdt*/
+		glb_rst_st = mmio_read_32(CRU_BASE + CRU_GLB_RST_ST_NCLR) & VALID_GLB_RST_MSK;
+		warm_boot = 1;
+	} else {
+		mmio_write_32(PMU0_GRF_BASE + PMU0GRF_OS_REG(17), WARM_BOOT_MAGIC);
+	}
+
+	clear_glb_reset_status();
+
+	/* save glb_rst_st in mem_os_reg31 */
+	write_mem_os_reg(31, glb_rst_st);
+
+	if (warm_boot != 0)
+		INFO("soc warm boot, reset status: 0x%x\n", glb_rst_st);
+	else
+		INFO("soc cold boot\n");
+}
+
+static void system_reset_init(void)
+{
+	/*
+	 * enable tsadc trigger global reset and select first reset.
+	 * enable global reset and wdt trigger pmu reset.
+	 * select first reset trigger pmu reset.
+	 */
+	mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, 0xffdf);
+
+	/* enable wdt_s reset */
+	mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0), 0x20002000);
+
+	/* enable wdt_ns reset */
+	mmio_write_32(SYS_GRF_BASE + SYSGRF_SOC_CON(4), 0x01000100);
+
+	/* reset width = 0xffff */
+	mmio_write_32(PMU1_GRF_BASE + PMU1GRF_SOC_CON(6), 0xffffffff);
+
+	/* enable first/tsadc/wdt reset output */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(0), 0x00070007);
+
+	/* pmu0sgrf pmu0_ioc hold */
+	mmio_write_32(PMU0SGRF_BASE + PMU1SGRF_SOC_CON(0), 0xffff1800);
+
+	/* pmu1sgrf pmu1_grf hold */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(16), 0xffff8800);
+
+	/* select tsadc_shut_m0 ionmux*/
+	mmio_write_32(PMU0_IOC_BASE + 0x0, 0x00f00090);
+
+	print_glb_reset_status();
+}
+
+void plat_rockchip_soc_init(void)
+{
+	rockchip_clock_init();
+	system_reset_init();
+	secure_init();
+	rockchip_init_scmi_server();
+
+	/* release cpu1~cpu7 */
+	mmio_write_32(CCI_GRF_BASE + CCIGRF_CON(4), 0xffffffff);
+	mmio_write_32(LITCORE_GRF_BASE + COREGRF_CPU_CON(1),
+		      BITS_WITH_WMASK(0x77, 0xff, 4));
+}
diff --git a/plat/rockchip/rk3576/drivers/soc/soc.h b/plat/rockchip/rk3576/drivers/soc/soc.h
new file mode 100644
index 0000000..f96a42d
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/soc/soc.h
@@ -0,0 +1,271 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __SOC_H__
+#define __SOC_H__
+
+enum pll_id {
+	APLL_ID,
+	CPLL_ID,
+	DPLL_ID,
+	GPLL_ID,
+};
+
+enum cru_mode_con00 {
+	CLK_APLL,
+	CLK_CPLL,
+	CLK_GPLL,
+	CLK_DPLL,
+};
+
+#define KHz				1000
+#define MHz				(1000 * KHz)
+#define OSC_HZ				(24 * MHz)
+
+#define MCU_VALID_START_ADDRESS		0x800000
+
+/* CRU */
+#define GLB_SRST_FST_CFG_VAL		0xfdb9
+
+#define CRU_PLLS_CON(pll_id, i)		((pll_id) * 0x20 + (i) * 0x4)
+#define CRU_PLL_CON(i)			((i) * 0x4)
+#define CRU_MODE_CON			0x280
+#define CRU_CLKSEL_CON(i)		((i) * 0x4 + 0x300)
+#define CRU_CLKSEL_CON_CNT		181
+#define CRU_CLKGATE_CON(i)		((i) * 0x4 + 0x800)
+#define CRU_CLKGATE_CON_CNT		80
+#define CRU_SOFTRST_CON(i)		((i) * 0x4 + 0xa00)
+#define CRU_SOFTRST_CON_CNT		80
+
+#define CRU_GLB_CNT_TH			0xc00
+#define CRU_GLB_RST_ST			0xc04
+#define CRU_GLB_SRST_FST		0xc08
+#define CRU_GLB_SRST_SND		0xc0c
+#define CRU_GLB_RST_CON			0xc10
+#define CRU_GLB_RST_ST_NCLR		0xc14
+#define CRU_LITCOREWFI_CON0		0xc40
+#define CRU_BIGCOREWFI_CON0		0xc44
+#define CRU_NON_SECURE_GT_CON0		0xc48
+
+#define CRU_PLLCON0_M_MASK		0x3ff
+#define CRU_PLLCON0_M_SHIFT		0
+#define CRU_PLLCON1_P_MASK		0x3f
+#define CRU_PLLCON1_P_SHIFT		0
+#define CRU_PLLCON1_S_MASK		0x7
+#define CRU_PLLCON1_S_SHIFT		6
+#define CRU_PLLCON2_K_MASK		0xffff
+#define CRU_PLLCON2_K_SHIFT		0
+#define CRU_PLLCON1_PWRDOWN		BIT(13)
+#define CRU_PLLCON6_LOCK_STATUS		BIT(15)
+
+/* LCORE_CRU */
+#define LCORE_CRU_MODE_CON		0x280
+#define LCORE_CRU_CLKSEL_CON(i)		((i) * 0x4 + 0x300)
+#define LCORE_CRU_CLKSEL_CON_CNT	4
+#define LCORE_CRU_CLKGATE_CON(i)	((i) * 0x4 + 0x800)
+#define LCORE_CRU_CLKGATE_CON_CNT	2
+#define LCORE_CRU_SOFTRST_CON(i)	((i) * 0x4 + 0xa00)
+#define LCORE_CRU_SOFTRST_CON_CNT	4
+
+/* BCORE_CRU */
+#define BCORE_CRU_MODE_CON		0x280
+#define BCORE_CRU_CLKSEL_CON(i)		((i) * 0x4 + 0x300)
+#define BCORE_CRU_CLKSEL_CON_CNT	5
+#define BCORE_CRU_CLKGATE_CON(i)	((i) * 0x4 + 0x800)
+#define BCORE_CRU_CLKGATE_CON_CNT	3
+#define BCORE_CRU_SOFTRST_CON(i)	((i) * 0x4 + 0xa00)
+#define BCORE_CRU_SOFTRST_CON_CNT	4
+
+/* DDRCRU */
+#define DDRCRU_MODE_CON			0x280
+#define DDRCRU_CLKSEL_CON(i)		((i) * 0x4 + 0x300)
+#define DDRCRU_CLKGATE_CON(i)		((i) * 0x4 + 0x800)
+#define DDRCRU_SOFTRST_CON(i)		((i) * 0x4 + 0xa00)
+
+/* CCICRU */
+#define CCICRU_MODE_CON			0x280
+#define CCICRU_CLKSEL_CON(i)		((i) * 0x4 + 0x300)
+#define CCICRU_CLKSEL_CON_CNT		10
+#define CCICRU_CLKGATE_CON(i)		((i) * 0x4 + 0x800)
+#define CCICRU_CLKGATE_CON_CNT		7
+#define CCICRU_SOFTRST_CON(i)		((i) * 0x4 + 0xa00)
+#define CCICRU_SOFTRST_CON_CNT		7
+
+/* CRU AUTOCS */
+#define CRU_AUTOCS_CON(offset)		(CRU_BASE + (offset))
+#define CRU_AUTOCS_SEC_CON(offset)	(SECURE_CRU_BASE + (offset))
+#define CRU_AUTOCS_CCI_CON(offset)	(CCI_CRU_BASE + (offset))
+#define AUTOCS_EN_BIT			BIT(12)
+
+/* PHP_CRU */
+#define PHP_CRU_MODE_CON		0x280
+#define PHP_CRU_CLKSEL_CON(i)		((i) * 0x4 + 0x300)
+#define PHP_CRU_CLKSEL_CON_CNT		2
+#define PHP_CRU_CLKGATE_CON(i)		((i) * 0x4 + 0x800)
+#define PHP_CRU_CLKGATE_CON_CNT		2
+#define PHP_CRU_SOFTRST_CON(i)		((i) * 0x4 + 0xa00)
+#define PHP_CRU_SOFTRST_CON_CNT		2
+
+/* SECURE CRU */
+#define SECURE_CRU_CLKSEL_CON(i)	((i) * 0x4 + 0x300)
+#define SECURE_CRU_CLKSEL_CON_CNT	1
+#define SECURE_CRU_CLKGATE_CON(i)	((i) * 0x4 + 0x800)
+#define SECURE_CRU_CLKGATE_CON_CNT	1
+#define SECURE_CRU_SOFTRST_CON(i)	((i) * 0x4 + 0xa00)
+#define SECURE_CRU_SOFTRST_CON_CNT	1
+
+/* SECURE SCRU */
+#define SECURE_SCRU_CLKSEL_CON(i)	((i) * 0x4 + 0x4000)
+#define SECURE_SCRU_CLKSEL_CON_CNT	7
+#define SECURE_SCRU_CLKGATE_CON(i)	((i) * 0x4 + 0x4028)
+#define SECURE_SCRU_CLKGATE_CON_CNT	6
+#define SECURE_SCRU_SOFTRST_CON(i)	((i) * 0x4 + 0x4050)
+#define SECURE_SCRU_SOFTRST_CON_CNT	6
+#define SECURE_SCRU_MODE_CON		0x4280
+
+/* SYSGRF */
+#define SYSGRF_SOC_CON(i)		((i) * 4)
+#define SYSGRF_SOC_STATUS		0x30
+#define SYSGRF_NOC_CON(i)		(0x40 + (i) * 4)
+#define SYSGRF_NOC_STATUS(i)		(0x60 + (i) * 4)
+#define SYSGRF_MEM_CON(i)		(0x80 + (i) * 4)
+#define SYSGRF_STATUS0			0x140
+#define SYSGRF_STATUS1			0x144
+
+/* COREGRF */
+#define COREGRF_SOC_STATUS(i)		(0x2c + (i) * 4)
+#define COREGRF_CPU_CON(i)		(0x34 + (i) * 4)
+
+/* DDRGRF */
+#define DDRGRF_CHA_CON(i)		((i) * 4)
+#define DDRGRF_CHB_CON(i)		(0x100 + (i) * 4)
+#define DDRGRF_CHA_ST(i)		(0x60 + (i) * 4)
+#define DDRGRF_CHB_ST(i)		(0xb0 + (i) * 4)
+#define DDRGRF_CON(i)			(0x140 + (i) * 4)
+
+/* CCIGRF */
+#define CCIGRF_CON(i)			((i) * 4)
+#define CCIGRF_STATUS(i)		(0x34 + (i) * 4)
+
+/* IOC */
+#define VCCIO_IOC_MISC_CON(i)		(0x400 + (i) * 4)
+
+/* pvtm */
+#define PVTM_CON(i)			(0x4 + (i) * 4)
+#define PVTM_INTEN			0x70
+#define PVTM_INTSTS			0x74
+#define PVTM_STATUS(i)			(0x80 + (i) * 4)
+#define PVTM_CALC_CNT			0x200
+
+enum pvtm_con0 {
+	pvtm_start = 0,
+	pvtm_osc_en = 1,
+	pvtm_osc_sel = 2,
+	pvtm_rnd_seed_en = 5,
+};
+
+/* WDT */
+#define WDT_CR			0x0
+#define WDT_TORR		0x4
+#define WDT_CCVR		0x8
+#define WDT_CRR			0xc
+#define WDT_STAT		0x10
+#define WDT_EOI			0x14
+
+#define WDT_EN			BIT(0)
+#define WDT_RSP_MODE		BIT(1)
+
+/* timer */
+#define TIMER_LOAD_COUNT0		0x00
+#define TIMER_LOAD_COUNT1		0x04
+#define TIMER_CURRENT_VALUE0		0x08
+#define TIMER_CURRENT_VALUE1		0x0c
+#define TIMER_CONTROL_REG		0x10
+#define TIMER_INTSTATUS			0x18
+
+#define TIMER_DIS			0x0
+#define TIMER_EN			0x1
+
+#define TIMER_FMODE			(0x0 << 1)
+#define TIMER_RMODE			(0x1 << 1)
+
+/* hp timer */
+#define TIMER_HP_REVISION		0x00
+#define TIMER_HP_CTRL			0x04
+#define TIMER_HP_INTR_EN		0x08
+#define TIMER_HP_T24_GCD		0x0c
+#define TIMER_HP_T32_GCD		0x10
+#define TIMER_HP_LOAD_COUNT0		0x14
+#define TIMER_HP_LOAD_COUNT1		0x18
+#define TIMER_HP_T24_DELAT_COUNT0	0x1c
+#define TIMER_HP_T24_DELAT_COUNT1	0x20
+#define TIMER_HP_CURR_32K_VALUE0	0x24
+#define TIMER_HP_CURR_32K_VALUE1	0x28
+#define TIMER_HP_CURR_TIMER_VALUE0	0x2c
+#define TIMER_HP_CURR_TIMER_VALUE1	0x30
+#define TIMER_HP_T24_32BEGIN0		0x34
+#define TIMER_HP_T24_32BEGIN1		0x38
+#define TIMER_HP_T32_24END0		0x3c
+#define TIMER_HP_T32_24END1		0x40
+#define TIMER_HP_BEGIN_END_VALID	0x44
+#define TIMER_HP_SYNC_REQ		0x48
+#define TIMER_HP_INTR_STATUS		0x4c
+#define TIMER_HP_UPD_EN			0x50
+
+ /* GPIO */
+#define GPIO_SWPORT_DR_L		0x0000
+#define GPIO_SWPORT_DR_H		0x0004
+#define GPIO_SWPORT_DDR_L		0x0008
+#define GPIO_SWPORT_DDR_H		0x000c
+#define GPIO_INT_EN_L			0x0010
+#define GPIO_INT_EN_H			0x0014
+#define GPIO_INT_MASK_L			0x0018
+#define GPIO_INT_MASK_H			0x001c
+#define GPIO_INT_TYPE_L			0x0020
+#define GPIO_INT_TYPE_H			0x0024
+#define GPIO_INT_POLARITY_L		0x0028
+#define GPIO_INT_POLARITY_H		0x002c
+#define GPIO_INT_BOTHEDGE_L		0x0030
+#define GPIO_INT_BOTHEDGE_H		0x0034
+#define GPIO_DEBOUNCE_L			0x0038
+#define GPIO_DEBOUNCE_H			0x003c
+#define GPIO_DBCLK_DIV_EN_L		0x0040
+#define GPIO_DBCLK_DIV_EN_H		0x0044
+#define GPIO_DBCLK_DIV_CON		0x0048
+#define GPIO_INT_STATUS			0x0050
+#define GPIO_INT_RAWSTATUS		0x0058
+#define GPIO_PORT_EOI_L			0x0060
+#define GPIO_PORT_EOI_H			0x0064
+#define GPIO_EXT_PORT			0x0070
+#define GPIO_VER_ID			0x0078
+#define GPIO_STORE_ST_L			0x0080
+#define GPIO_STORE_ST_H			0x0084
+#define GPIO_REG_GROUP_L		0x0100
+#define GPIO_REG_GROUP_H		0x0104
+#define GPIO_VIRTUAL_EN			0x0108
+#define GPIO_REG_GROUP1_L		0x0110
+#define GPIO_REG_GROUP1_H		0x0114
+#define GPIO_REG_GROUP2_L		0x0118
+#define GPIO_REG_GROUP2_H		0x011c
+#define GPIO_REG_GROUP3_L		0x0120
+#define GPIO_REG_GROUP3_H		0x0124
+
+/* PWM */
+#define PMW_PWRCAPTURE_VAL		0x15c
+
+#define SOC_RK3576A1			0x35760101
+#define SOC_RK3576J1			0x35760a01
+#define SOC_RK3576M1			0x35760d01
+#define SOC_RK3576S1			0x35761301
+#define SOC_UNKNOWN			0xeeee
+#define SOC_ROOT			0x0
+
+int rk_soc_is_(uint32_t soc_id);
+uint32_t timer_hp_get_freq(void);
+int soc_bus_div_sip_handler(uint32_t id, uint32_t cfg, uint32_t enable_msk);
+void autocs_suspend(void);
+void autocs_resume(void);
+
+#endif /* __SOC_H__ */
diff --git a/plat/rockchip/rk3576/include/plat.ld.S b/plat/rockchip/rk3576/include/plat.ld.S
new file mode 100644
index 0000000..4d0096f
--- /dev/null
+++ b/plat/rockchip/rk3576/include/plat.ld.S
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef ROCKCHIP_PLAT_LD_S
+#define ROCKCHIP_PLAT_LD_S
+
+MEMORY {
+	PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
+}
+
+SECTIONS
+{
+	. = PMUSRAM_BASE;
+
+	/*
+	 * pmu_cpuson_entrypoint request address
+	 * align 64K when resume, so put it in the
+	 * start of pmusram
+	 */
+	.text_pmusram : {
+		ASSERT(. == ALIGN(64 * 1024),
+			".pmusram.entry request 64K aligned.");
+		KEEP(*(.pmusram.entry))
+		__bl31_pmusram_text_start = .;
+		*(.pmusram.text)
+		*(.pmusram.rodata)
+		. = ALIGN(PAGE_SIZE);
+		__bl31_pmusram_text_end = .;
+		__bl31_pmusram_data_start = .;
+		*(.pmusram.data)
+		. = ALIGN(PAGE_SIZE);
+		__bl31_pmusram_data_end = .;
+
+		ASSERT(__bl31_pmusram_data_end <= PMUSRAM_BASE + PMUSRAM_RSIZE,
+			".pmusram has exceeded its limit.");
+	} >PMUSRAM
+}
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3576/include/plat_sip_calls.h b/plat/rockchip/rk3576/include/plat_sip_calls.h
new file mode 100644
index 0000000..c33f24f
--- /dev/null
+++ b/plat/rockchip/rk3576/include/plat_sip_calls.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PLAT_SIP_CALLS_H__
+#define __PLAT_SIP_CALLS_H__
+
+#define RK_PLAT_SIP_NUM_CALLS	0
+
+#endif /* __PLAT_SIP_CALLS_H__ */
diff --git a/plat/rockchip/rk3576/include/platform_def.h b/plat/rockchip/rk3576/include/platform_def.h
new file mode 100644
index 0000000..03a80b0
--- /dev/null
+++ b/plat/rockchip/rk3576/include/platform_def.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <rk3576_def.h>
+
+#define DEBUG_XLAT_TABLE 0
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if DEBUG_XLAT_TABLE
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL1
+#define PLATFORM_STACK_SIZE 0x440
+#elif IMAGE_BL2
+#define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL31
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL32
+#define PLATFORM_STACK_SIZE 0x440
+#endif
+
+#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+
+#define PLATFORM_SYSTEM_COUNT		1
+#define PLATFORM_CLUSTER_COUNT		2
+#define PLATFORM_CLUSTER0_CORE_COUNT	4
+#define PLATFORM_CLUSTER1_CORE_COUNT	4
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER1_CORE_COUNT +	\
+					 PLATFORM_CLUSTER0_CORE_COUNT)
+
+#define PLATFORM_NUM_AFFS		(PLATFORM_SYSTEM_COUNT +	\
+					 PLATFORM_CLUSTER_COUNT +	\
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+
+#define PLAT_RK_CLST_TO_CPUID_SHIFT	6
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE		1
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE		2
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+/* TF txet, ro, rw, Size: 512KB */
+#define TZRAM_BASE		RK_DRAM_BASE
+#define TZRAM_SIZE		0x100000
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted RAM
+ */
+#define BL31_BASE		(TZRAM_BASE + 0x40000)
+#define BL31_LIMIT		(TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+
+#define ADDR_SPACE_SIZE			(1ULL << 32)
+#define MAX_XLAT_TABLES			18
+#define MAX_MMAP_REGIONS		27
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT	6
+#define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Define GICD and GICC and GICR base
+ */
+#define PLAT_RK_GICD_BASE	PLAT_GICD_BASE
+#define PLAT_RK_GICC_BASE	PLAT_GICC_BASE
+#define PLAT_RK_GICR_BASE	PLAT_GICR_BASE
+
+#define PLAT_RK_UART_BASE	RK_DBG_UART_BASE
+#define PLAT_RK_UART_CLOCK	RK_DBG_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE	RK_DBG_UART_BAUDRATE
+
+#define PLAT_RK_PRIMARY_CPU	0x0
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/rockchip/rk3576/plat_sip_calls.c b/plat/rockchip/rk3576/plat_sip_calls.c
new file mode 100644
index 0000000..b0ff5fb
--- /dev/null
+++ b/plat/rockchip/rk3576/plat_sip_calls.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
+
+#include <plat_sip_calls.h>
+#include <rockchip_sip_svc.h>
+
+uintptr_t rockchip_plat_sip_handler(uint32_t smc_fid,
+				    u_register_t x1,
+				    u_register_t x2,
+				    u_register_t x3,
+				    u_register_t x4,
+				    void *cookie,
+				    void *handle,
+				    u_register_t flags)
+{
+	switch (smc_fid) {
+	case RK_SIP_SCMI_AGENT0:
+		scmi_smt_fastcall_smc_entry(0);
+		SMC_RET1(handle, 0);
+
+	default:
+		ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
diff --git a/plat/rockchip/rk3576/platform.mk b/plat/rockchip/rk3576/platform.mk
new file mode 100644
index 0000000..861cb4f
--- /dev/null
+++ b/plat/rockchip/rk3576/platform.mk
@@ -0,0 +1,115 @@
+#
+# Copyright (c) 2025, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RK_PLAT			:=	plat/rockchip
+RK_PLAT_SOC		:=	${RK_PLAT}/${PLAT}
+RK_PLAT_COMMON		:=	${RK_PLAT}/common
+
+DISABLE_BIN_GENERATION	:=	1
+
+include drivers/arm/gic/v2/gicv2.mk
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_INCLUDES		:=	-Idrivers/arm/gic/common/			\
+				-Idrivers/arm/gic/v2/				\
+				-Idrivers/scmi-msg/				\
+				-Iinclude/bl31					\
+				-Iinclude/common				\
+				-Iinclude/drivers				\
+				-Iinclude/drivers/arm				\
+				-Iinclude/drivers/io				\
+				-Iinclude/drivers/ti/uart			\
+				-Iinclude/lib					\
+				-Iinclude/lib/cpus/${ARCH}			\
+				-Iinclude/lib/el3_runtime			\
+				-Iinclude/lib/psci				\
+				-Iinclude/plat/common				\
+				-Iinclude/services				\
+				-I${RK_PLAT_COMMON}/				\
+				-I${RK_PLAT_COMMON}/pmusram/			\
+				-I${RK_PLAT_COMMON}/include/			\
+				-I${RK_PLAT_COMMON}/drivers/pmu/		\
+				-I${RK_PLAT_COMMON}/drivers/parameter/		\
+				-I${RK_PLAT_COMMON}/scmi/			\
+				-I${RK_PLAT_SOC}/				\
+				-I${RK_PLAT_SOC}/drivers/dmc/			\
+				-I${RK_PLAT_SOC}/drivers/pmu/			\
+				-I${RK_PLAT_SOC}/drivers/secure/		\
+				-I${RK_PLAT_SOC}/drivers/soc/			\
+				-I${RK_PLAT_SOC}/include/			\
+				-I${RK_PLAT_SOC}/scmi/
+
+RK_GIC_SOURCES		:=	${GICV2_SOURCES}				\
+				plat/common/plat_gicv2.c			\
+				${RK_PLAT}/common/rockchip_gicv2.c
+
+PLAT_BL_COMMON_SOURCES	:=	${XLAT_TABLES_LIB_SRCS}				\
+				common/desc_image_load.c			\
+				lib/bl_aux_params/bl_aux_params.c		\
+				plat/common/aarch64/crash_console_helpers.S	\
+				plat/common/plat_psci_common.c
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES	+=	${RK_PLAT_COMMON}/rockchip_stack_protector.c
+endif
+
+BL31_SOURCES		+=	${RK_GIC_SOURCES}				\
+				drivers/arm/cci/cci.c				\
+				drivers/ti/uart/aarch64/16550_console.S		\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				drivers/scmi-msg/base.c				\
+				drivers/scmi-msg/clock.c			\
+				drivers/scmi-msg/entry.c			\
+				drivers/scmi-msg/reset_domain.c			\
+				drivers/scmi-msg/smt.c				\
+				lib/cpus/aarch64/cortex_a53.S			\
+				lib/cpus/aarch64/cortex_a72.S			\
+				$(LIBFDT_SRCS)					\
+				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
+				${RK_PLAT_COMMON}/aarch64/platform_common.c	\
+				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
+				${RK_PLAT_COMMON}/plat_pm.c			\
+				${RK_PLAT_COMMON}/plat_pm_helpers.c		\
+				${RK_PLAT_COMMON}/plat_topology.c		\
+				${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
+				${RK_PLAT_COMMON}/params_setup.c		\
+				${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S	\
+				${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
+				${RK_PLAT_COMMON}/scmi/rockchip_common_clock.c	\
+				${RK_PLAT_COMMON}/scmi/scmi.c			\
+				${RK_PLAT_COMMON}/scmi/scmi_clock.c		\
+				${RK_PLAT_COMMON}/scmi/scmi_rstd.c		\
+				${RK_PLAT_SOC}/scmi/rk3576_clk.c		\
+				${RK_PLAT_SOC}/plat_sip_calls.c         	\
+				${RK_PLAT_SOC}/drivers/dmc/suspend.c		\
+				${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
+				${RK_PLAT_SOC}/drivers/pmu/pm_pd_regs.c 	\
+				${RK_PLAT_SOC}/drivers/secure/firewall.c	\
+				${RK_PLAT_SOC}/drivers/secure/secure.c		\
+				${RK_PLAT_SOC}/drivers/soc/soc.c
+
+# Enable workarounds for selected Cortex-A53 errata
+ERRATA_A53_835769		:=	1
+ERRATA_A53_843419		:=	1
+ERRATA_A53_855873		:=	1
+ERRATA_A53_1530924		:=	1
+
+ERRATA_A72_1319367		:=	1
+
+ENABLE_PLAT_COMPAT		:=	0
+MULTI_CONSOLE_API		:=	1
+CTX_INCLUDE_EL2_REGS		:=	0
+GICV2_G0_FOR_EL3		:=	1
+CTX_INCLUDE_AARCH32_REGS	:=	0
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS		:=	0
+
+WORKAROUND_CVE_2017_5715	:=	0
+
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
diff --git a/plat/rockchip/rk3576/rk3576_def.h b/plat/rockchip/rk3576/rk3576_def.h
new file mode 100644
index 0000000..35f38ca
--- /dev/null
+++ b/plat/rockchip/rk3576/rk3576_def.h
@@ -0,0 +1,207 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PLAT_DEF_H__
+#define __PLAT_DEF_H__
+
+#define SIZE_K(n)		((n) * 1024)
+#define SIZE_M(n)		((n) * 1024 * 1024)
+
+#define WITH_16BITS_WMSK(bits)	(0xffff0000 | (bits))
+#define BITS_WMSK(msk, shift)	((msk) << ((shift) + REG_MSK_SHIFT))
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define RK_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
+
+#define RK3576_DEV_RNG0_BASE	0x00000000
+#define RK3576_DEV_RNG0_SIZE	0x40000000
+
+#define RK_DRAM_BASE		0x40000000
+
+/* All slave base address declare below */
+#define MCU_TCM_BASE		0x23800000
+#define MCU_CACHE_BASE		0x23810000
+#define MCU_RAM_TEST_BASE	0x23820000
+#define MCU_BOOT_BASE		0x00000000
+#define MCU_MAIN_BASE		0x00010000
+#define PMU0SGRF_BASE		0x26000000
+#define PMU1SGRF_BASE		0x26002000
+#define PMU1SGRF_FW_BASE	0x26003000
+#define SYS_SGRF_BASE		0x26004000
+#define SYS_SGRF_FW_BASE	0x26005000
+#define SYS_GRF_BASE		0x2600a000
+#define BIGCORE_GRF_BASE	0x2600c000
+#define LITCORE_GRF_BASE	0x2600e000
+#define CCI_GRF_BASE		0x26010000
+#define DDR_GRF_BASE		0x26012000
+#define CENTER_GRF_BASE		0x26014000
+#define GPUGRF_BASE		0x26016000
+#define NPUGRF_BASE		0x26018000
+#define VO_GRF_BASE		0x2601a000
+#define VI_GRF_BASE		0x2601c000
+#define USB_GRF_BASE		0x2601e000
+#define PHP_GRF_BASE		0x26020000
+#define VOP_GRF_BASE		0x26022000
+#define PMU0_GRF_BASE		0x26024000
+#define PMU1_GRF_BASE		0x26026000
+#define USBDPPHY_GRF_BASE	0x2602c000
+#define USB2PHY0_GRF_BASE	0x2602e000
+#define USB2PHY1_GRF_BASE	0x26030000
+#define PMU0_IOC_BASE		0x26040000
+#define PMU1_IOC_BASE		0x26042000
+#define TOP_IOC_BASE		0x26044000
+#define VCCIO_IOC_BASE		0x26046000
+#define VCCIO6_IOC_BASE		0x2604a000
+#define VCCIO7_IOC_BASE		0x2604b000
+#define CRU_BASE		0x27200000
+#define PHP_CRU_BASE		0x27208000
+#define SECURE_CRU_BASE		0x27210000
+#define PMU1_CRU_BASE		0x27220000
+#define DDRPHY0_CRU_BASE	0x27228000
+#define DDRPHY1_CRU_BASE	0x27230000
+#define BIGCORE_CRU_BASE	0x27238000
+#define LITTLE_CRU_BASE		0x27240000
+#define CCI_CRU_BASE		0x27248000
+#define PVTPLL_CCI_BASE		0x27250000
+#define PVTPLL_BIGCORE_BASE	0x27258000
+#define PVTPLL_LITCORE_BASE	0x27260000
+#define PVTPLL_GPU_BASE		0x27268000
+#define PVTPLL_NPU_BASE		0x27270000
+#define PVTPLL_CRU_BASE		0x27278000
+#define I2C0_BASE		0x27300000
+#define UART1_BASE		0x27310000
+#define GPIO0_BASE		0x27320000
+#define PWM0_BASE		0x27330000
+#define WDT_PMU_BASE		0x27340000
+#define TIMER_PMU_BASE		0x27350000
+#define PMU_BASE		0x27360000
+#define PMU0_BASE		0x27360000
+#define PMU1_BASE		0x27370000
+#define PMU2_BASE		0x27380000
+#define PVTM_PMU_BASE		0x273f0000
+#define HPTIMER_BASE		0x27400000
+#define CCI_BASE		0x27500000
+#define VOP_BASE		0x27d00000
+#define INTERCONNECT_BASE	0x27f00000
+#define FW_CCI2DDR_BASE		0x27f80000
+#define FW_CENTER2DDR_BASE	0x27f90000
+#define FW_SYSMEM_BASE		0x27fa0000
+#define FW_VOP2DDR_BASE		0x27fb0000
+#define FW_CBUF_BASE		0x27fc0000
+#define FIREWALL_DDR_BASE	0x27f80000
+#define DDRCTL0_BASE		0x28000000
+#define DDRCTL1_BASE		0x29000000
+#define DDR_MONITOR0_BASE	0x2a000000
+#define DDR_MONITOR1_BASE	0x2a010000
+#define DDRPHY0_BASE		0x2a020000
+#define DDRPHY1_BASE		0x2a030000
+#define HWLP0_BASE		0x2a060000
+#define HWLP1_BASE		0x2a070000
+#define KEYLADDER_BASE		0x2a420000
+#define CRYPTO_S_BASE		0x2a430000
+#define OTP_S_BASE		0x2a480000
+#define DCF_BASE		0x2a490000
+#define STIMER0_BASE		0x2a4a0000
+#define STIMER1_BASE		0x2a4b0000
+#define WDT_S_BASE		0x2a4c0000
+#define OTP_MASK_BASE		0x2a4d0000
+#define OTP_NS_BASE		0x2a580000
+#define GIC400_BASE		0x2a700000
+#define I2C1_BASE		0x2ac40000
+#define NSTIMER0_BASE		0x2acc0000
+#define NSTIMER1_BASE		0x2acd0000
+#define WDT_NS_BASE		0x2ace0000
+#define UART0_BASE		0x2ad40000
+#define UART2_BASE		0x2ad50000
+#define UART3_BASE		0x2ad60000
+#define UART4_BASE		0x2ad70000
+#define UART5_BASE		0x2ad80000
+#define UART6_BASE		0x2ad90000
+#define UART7_BASE		0x2ada0000
+#define UART8_BASE		0x2adb0000
+#define UART9_BASE		0x2adc0000
+#define PWM1_BASE		0x2add0000
+#define PWM2_BASE		0x2ade0000
+#define PWM3_BASE		0x2adf0000
+#define GPIO1_BASE		0x2ae10000
+#define GPIO2_BASE		0x2ae20000
+#define GPIO3_BASE		0x2ae30000
+#define GPIO4_BASE		0x2ae40000
+#define TSADC_BASE		0x2ae70000
+
+#define PMUSRAM_BASE		0x3fe70000
+#define PMUSRAM_RSIZE		SIZE_K(32)
+
+#define CBUF_BASE		0x3fe80000
+#define SRAM_BASE		0x3ff80000
+
+#define STIMER0_CHN_BASE(i)	(STIMER0_BASE + 0x1000 * (i))
+#define STIMER1_CHN_BASE(i)	(STIMER1_BASE + 0x1000 * (i))
+
+#define NSTIMER0_CHN_BASE(i)	(NSTIMER0_BASE + 0x1000 * (i))
+#define NSTIMER1_CHN_BASE(i)	(NSTIMER1_BASE + 0x1000 * (i))
+
+#define DDRPHY_BASE_CH(n)	(DDRPHY0_BASE + ((n) * 0x10000))
+#define DDRPHY_CRU_BASE_CH(n)	(DDRPHY0_CRU_BASE + ((n) * 0x8000))
+#define UMCTL_BASE_CH(n)	(DDRCTL0_BASE + ((n) * 0x1000000))
+#define HWLP_BASE_CH(n)		(HWLP0_BASE + ((n) * 0x10000))
+#define MAILBOX1_BASE		(0x2ae50000 + 0xb000)
+
+#define CRYPTO_S_BY_KEYLAD_BASE	CRYPTO_S_BASE
+
+#define DDR_SHARE_MEM		(RK_DRAM_BASE + SIZE_K(1024))
+#define DDR_SHARE_SIZE		SIZE_K(64)
+
+#define SHARE_MEM_BASE		DDR_SHARE_MEM
+#define SHARE_MEM_PAGE_NUM	15
+#define SHARE_MEM_SIZE		SIZE_K(SHARE_MEM_PAGE_NUM * 4)
+
+#define	SCMI_SHARE_MEM_BASE	(SHARE_MEM_BASE + SHARE_MEM_SIZE)
+#define	SCMI_SHARE_MEM_SIZE	SIZE_K(4)
+
+#define SMT_BUFFER_BASE		SCMI_SHARE_MEM_BASE
+#define SMT_BUFFER0_BASE	SMT_BUFFER_BASE
+
+#define ROCKCHIP_PM_REG_REGION_MEM_SIZE		SIZE_K(8)
+
+/******************************************************************************
+ * sgi, ppi
+ ******************************************************************************/
+#define RK_IRQ_SEC_PHY_TIMER	29
+
+#define RK_IRQ_SEC_SGI_0	8
+#define RK_IRQ_SEC_SGI_1	9
+#define RK_IRQ_SEC_SGI_2	10
+#define RK_IRQ_SEC_SGI_3	11
+#define RK_IRQ_SEC_SGI_4	12
+#define RK_IRQ_SEC_SGI_5	13
+#define RK_IRQ_SEC_SGI_6	14
+#define RK_IRQ_SEC_SGI_7	15
+
+/*
+ * Define a list of Group 0 interrupts.
+ */
+#define PLAT_RK_GICV2_G0_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,	\
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),		\
+	INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+/* UART related constants */
+#define RK_DBG_UART_BASE	UART0_BASE
+#define RK_DBG_UART_BAUDRATE	1500000
+#define RK_DBG_UART_CLOCK	24000000
+
+/* Base rk_platform compatible GIC memory map */
+#define PLAT_GICD_BASE		(GIC400_BASE + 0x1000)
+#define PLAT_GICC_BASE		(GIC400_BASE + 0x2000)
+#define PLAT_GICR_BASE		0
+
+/* CCI */
+#define PLAT_RK_CCI_BASE			CCI_BASE
+#define PLAT_RK_CCI_CLUSTER0_SL_IFACE_IX	1
+#define PLAT_RK_CCI_CLUSTER1_SL_IFACE_IX	2
+
+#endif /* __PLAT_DEF_H__ */
diff --git a/plat/rockchip/rk3576/scmi/rk3576_clk.c b/plat/rockchip/rk3576/scmi/rk3576_clk.c
new file mode 100644
index 0000000..7b36a05
--- /dev/null
+++ b/plat/rockchip/rk3576/scmi/rk3576_clk.c
@@ -0,0 +1,1353 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include <rk3576_clk.h>
+#include <rockchip_sip_svc.h>
+#include <scmi_clock.h>
+#include <soc.h>
+
+enum pll_type_sel {
+	PLL_SEL_AUTO, /* all plls (normal pll or pvtpll) */
+	PLL_SEL_PVT,
+	PLL_SEL_NOR,
+	PLL_SEL_AUTO_NOR /* all normal plls (apll/gpll/npll) */
+};
+
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
+#define RK3576_PVTPLL_RING_EN		0x00
+#define RK3576_PVTPLL_RING0_LENGTH	0x04
+#define RK3576_PVTPLL_RING1_LENGTH	0x08
+#define RK3576_PVTPLL_RING2_LENGTH	0x0c
+#define RK3576_PVTPLL_RING3_LENGTH	0x10
+#define RK3576_PVTPLL_GCK_CFG		0x20
+#define RK3576_PVTPLL_GCK_LEN		0x24
+#define RK3576_PVTPLL_GCK_DIV		0x28
+#define RK3576_PVTPLL_GCK_CAL_CNT	0x2c
+#define RK3576_PVTPLL_GCK_REF_VAL	0x30
+#define RK3576_PVTPLL_GCK_CFG_VAL	0x34
+#define RK3576_PVTPLL_GCK_THR		0x38
+#define RK3576_PVTPLL_GFREE_CON		0x3c
+#define RK3576_PVTPLL_ADC_CFG		0x40
+#define RK3576_PVTPLL_ADC_CAL_CNT	0x48
+#define RK3576_PVTPLL_GCK_CNT		0x50
+#define RK3576_PVTPLL_GCK_CNT_AVG	0x54
+#define RK3576_PVTPLL_GCK_STATE		0x5c
+#define RK3576_PVTPLL_ADC_CNT		0x60
+#define RK3576_PVTPLL_ADC_CNT_AVG	0x68
+#define RK3576_PVTPLL_VERSION		0x70
+#define RK3576_PVTPLL_MAX_LENGTH	0x3f
+
+#define GPLL_RATE			1188000000
+#define CPLL_RATE			1000000000
+#define SPLL_RATE			702000000
+#define AUPLL_RATE			786431952
+
+#define MAX_RATE_TABLE			16
+
+#define CLKDIV_6BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3fU, shift)
+#define CLKDIV_5BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1fU, shift)
+#define CLKDIV_4BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0xfU, shift)
+#define CLKDIV_3BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x7U, shift)
+#define CLKDIV_2BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3U, shift)
+#define CLKDIV_1BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1U, shift)
+
+#define CPU_PLL_PATH_SLOWMODE		BITS_WITH_WMASK(0U, 0x3U, 0)
+#define CPU_PLL_PATH_NORMAL		BITS_WITH_WMASK(1U, 0x3U, 0)
+#define CPU_PLL_PATH_DEEP_SLOW		BITS_WITH_WMASK(2U, 0x3U, 0)
+
+#define CRU_PLL_POWER_DOWN		BIT_WITH_WMSK(13)
+#define CRU_PLL_POWER_UP		WMSK_BIT(13)
+
+/* clk_core:
+ * from normal pll(core_i: gpll or apll) path or direct pass from apll
+ */
+
+/* cpul clk path */
+#define CPUL_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(1U, 0x3U, 12)
+#define CPUL_CLK_PATH_NOR_LPLL		BITS_WITH_WMASK(0U, 0x3U, 12)
+#define CPUL_CLK_PATH_NOR_PVTPLL	BITS_WITH_WMASK(2U, 0x3U, 12)
+
+#define CPUL_CLK_PATH_LPLL		BITS_WITH_WMASK(0U, 0x3U, 6)
+#define CPUL_CLK_PATH_DIR_LPLL		BITS_WITH_WMASK(2U, 0x3U, 6)
+#define CPUL_CLK_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x3U, 6)
+
+#define CPUL_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 13)
+#define CPUL_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(0x1, 0x1U, 13)
+
+/* cpub clk path */
+#define CPUB_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(1U, 0x3U, 12)
+#define CPUB_CLK_PATH_NOR_BPLL		BITS_WITH_WMASK(0U, 0x3U, 12)
+#define CPUB_CLK_PATH_NOR_PVTPLL	BITS_WITH_WMASK(2U, 0x3U, 12)
+
+#define CPUB_CLK_PATH_BPLL		BITS_WITH_WMASK(0U, 0x3U, 14)
+#define CPUB_CLK_PATH_DIR_BPLL		BITS_WITH_WMASK(2U, 0x3U, 14)
+#define CPUB_CLK_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x3U, 14)
+
+#define CPUB_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 5)
+#define CPUB_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(0x1, 0x1U, 5)
+
+#define CPUB_PCLK_PATH_100M		BITS_WITH_WMASK(0U, 0x3U, 0)
+#define CPUB_PCLK_PATH_50M		BITS_WITH_WMASK(1U, 0x3U, 0)
+#define CPUB_PCLK_PATH_24M		BITS_WITH_WMASK(2U, 0x3U, 0)
+
+/* cci clk path */
+#define SCLK_CCI_PATH_XIN		BITS_WITH_WMASK(0U, 0x3U, 12)
+#define SCLK_CCI_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x3U, 12)
+#define SCLK_CCI_PATH_NOR_LPLL		BITS_WITH_WMASK(3U, 0x3U, 12)
+#define SCLK_CCI_PATH_NOR_GPLL		BITS_WITH_WMASK(2U, 0x3U, 12)
+
+#define CCI_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 14)
+#define CCI_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x1U, 14)
+
+/* npu clk path */
+#define NPU_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(0U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_CPLL		BITS_WITH_WMASK(1U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_AUPLL		BITS_WITH_WMASK(2U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_SPLL		BITS_WITH_WMASK(3U, 0x7U, 7)
+
+#define NPU_CLK_PATH_NOR_PLL		WMSK_BIT(15)
+#define NPU_CLK_PATH_PVTPLL		BIT_WITH_WMSK(15)
+#define NPU_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 9)
+#define NPU_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x1U, 9)
+
+/* gpu clk path */
+#define GPU_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(0U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_CPLL		BITS_WITH_WMASK(1U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_AUPLL		BITS_WITH_WMASK(2U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_SPLL		BITS_WITH_WMASK(3U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_LPLL		BITS_WITH_WMASK(4U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_PLL		WMSK_BIT(8)
+#define GPU_CLK_PATH_PVTPLL		BIT_WITH_WMSK(8)
+#define GPU_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 9)
+#define GPU_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x1U, 9)
+
+#define PVTPLL_NEED(type, length)	(((type) == PLL_SEL_PVT || \
+					  (type) == PLL_SEL_AUTO) && \
+					 (length))
+/*
+ * [0]:      set intermediate rate
+ *           [1]: scaling up rate or scaling down rate
+ * [1]:      add length for pvtpll
+ *           [2:5]: length
+ * [2]:      use low length for pvtpll
+ * [3:5]:    reserved
+ */
+#define OPP_RATE_MASK			0x3f
+#define OPP_INTERMEDIATE_RATE		BIT(0)
+#define OPP_SCALING_UP_RATE		BIT(1)
+#define OPP_ADD_LENGTH			BIT(1)
+#define OPP_LENGTH_MASK			GENMASK_32(5, 2)
+#define OPP_LENGTH_SHIFT		2
+#define OPP_LENGTH_LOW			BIT(2)
+
+#define PRATE(x) static const unsigned long const x[]
+#define PINFO(x) static const uint32_t const x[]
+
+PRATE(p_24m)			= { OSC_HZ };
+PRATE(p_100m_24m)		= { 100 * MHz, OSC_HZ };
+PRATE(p_350m_175m_116m_24m)	= { 350 * MHz, 175 * MHz, 116 * MHz, OSC_HZ };
+PRATE(p_175m_116m_58m_24m)	= { 175 * MHz, 116 * MHz, 58 * MHz, OSC_HZ };
+PRATE(p_116m_58m_24m)		= { 116 * MHz, 58 * MHz, OSC_HZ };
+PRATE(p_pclk_secure_s)		= { PCLK_SECURE_S };
+PRATE(p_hclk_secure_s)		= { HCLK_SECURE_S };
+PRATE(p_aclk_secure_s)		= { ACLK_SECURE_S };
+PRATE(p_hclk_vo0_s)		= { HCLK_VO0_S };
+PRATE(p_pclk_vo0_s)		= { PCLK_VO0_S };
+PRATE(p_hclk_vo1_s)		= { HCLK_VO1_S };
+PRATE(p_pclk_vo1_s)		= { PCLK_VO1_S };
+
+PINFO(clk_stimer0_root_info)	= { 0x27214004, 6, 1, 0, 0, 0, 0x27214028, 9 };
+PINFO(clk_stimer1_root_info)	= { 0x27214004, 7, 1, 0, 0, 0, 0x2721402c, 1 };
+PINFO(pclk_secure_s_info)	= { 0x27214004, 4, 2, 0, 0, 0, 0x27214028, 2 };
+PINFO(hclk_secure_s_info)	= { 0x27214004, 2, 2, 0, 0, 0, 0x27214028, 1 };
+PINFO(aclk_secure_s_info)	= { 0x27214004, 0, 2, 0, 0, 0, 0x27214028, 0 };
+PINFO(clk_pka_crypto_s_info)	= { 0x27214004, 11, 2, 0, 0, 0, 0x27214030, 11 };
+PINFO(hclk_vo1_s_info)		= { 0x27214010, 0, 2, 0, 0, 0, 0x27214038, 1 };
+PINFO(pclk_vo1_s_info)		= { 0x27214010, 2, 2, 0, 0, 0, 0x27214038, 4 };
+PINFO(hclk_vo0_s_info)		= { 0x27214018, 0, 2, 0, 0, 0, 0x2721403c, 1 };
+PINFO(pclk_vo0_s_info)		= { 0x27214018, 2, 2, 0, 0, 0, 0x2721403c, 4 };
+PINFO(pclk_klad_info)		= { 0, 0, 0, 0, 0, 0, 0x27214030, 7 };
+PINFO(hclk_crypto_s_info)	= { 0, 0, 0, 0, 0, 0, 0x27214030, 8 };
+PINFO(hclk_klad_info)		= { 0, 0, 0, 0, 0, 0, 0x27214030, 9 };
+PINFO(aclk_crypto_s_info)	= { 0, 0, 0, 0, 0, 0, 0x27214030, 12 };
+PINFO(hclk_trng_s_info)		= { 0, 0, 0, 0, 0, 0, 0x27214034, 0 };
+PINFO(pclk_otpc_s_info)		= { 0, 0, 0, 0, 0, 0, 0x27214034, 3 };
+PINFO(clk_otpc_s_info)		= { 0, 0, 0, 0, 0, 0, 0x27214034, 4 };
+PINFO(pclk_wdt_s_info)		= { 0, 0, 0, 0, 0, 0, 0x27214034, 9 };
+PINFO(tclk_wdt_s_info)		= { 0, 0, 0, 0, 0, 0, 0x27214034, 10 };
+PINFO(pclk_hdcp1_trng_info)	= { 0, 0, 0, 0, 0, 0, 0x27214038, 0 };
+PINFO(hclk_hdcp_key1_info)	= { 0, 0, 0, 0, 0, 0, 0x27214038, 3 };
+PINFO(pclk_hdcp0_trng_info)	= { 0, 0, 0, 0, 0, 0, 0x2721403c, 0 };
+PINFO(hclk_hdcp_key0_info)	= { 0, 0, 0, 0, 0, 0, 0x2721403c, 3 };
+PINFO(pclk_edp_s_info)		= { 0, 0, 0, 0, 0, 0, 0x2721403c, 5 };
+
+struct pvtpll_table {
+	unsigned int rate;
+	uint32_t length;
+	uint32_t length_frac;
+	uint32_t length_low;
+	uint32_t length_low_frac;
+	uint32_t ring_sel;
+	uint32_t volt_sel_thr;
+};
+
+struct sys_clk_info_t {
+	struct pvtpll_table *cpul_table;
+	struct pvtpll_table *cci_table;
+	struct pvtpll_table *cpub_table;
+	struct pvtpll_table *gpu_table;
+	struct pvtpll_table *npu_table;
+	unsigned int cpul_rate_count;
+	unsigned int cci_rate_count;
+	unsigned int cpub_rate_count;
+	unsigned int gpu_rate_count;
+	unsigned int npu_rate_count;
+	unsigned long cpul_rate;
+	unsigned long cci_rate;
+	unsigned long cpub_rate;
+	unsigned long gpu_rate;
+	unsigned long npu_rate;
+};
+
+struct otp_opp_info {
+	uint16_t min_freq;
+	uint16_t max_freq;
+	uint8_t volt;
+	uint8_t length;
+} __packed;
+
+#define RK3576_SCMI_CLOCK(_id, _name, _data, _table, _cnt, _is_s)	\
+rk_scmi_clock_t _name = {						\
+	.id	= _id,							\
+	.name = #_name,							\
+	.clk_ops = _data,						\
+	.rate_table = _table,						\
+	.rate_cnt = _cnt,						\
+	.is_security = _is_s,						\
+}
+
+#define RK3576_SCMI_CLOCK_COM(_id, _name,  _parent_table, _info, _data,	\
+			     _table, is_d, _is_s)			\
+rk_scmi_clock_t _name = {						\
+	.id	= _id,							\
+	.name = #_name,							\
+	.parent_table = _parent_table,					\
+	.info = _info,							\
+	.clk_ops = _data,						\
+	.rate_table = _table,						\
+	.rate_cnt = ARRAY_SIZE(_table),					\
+	.is_dynamic_prate = is_d,					\
+	.is_security = _is_s,						\
+}
+
+#define ROCKCHIP_PVTPLL(_rate, _sel, _len, _len_frac)			\
+{									\
+	.rate = _rate##U,						\
+	.ring_sel = _sel,						\
+	.length = _len,							\
+	.length_frac = _len_frac,					\
+}
+
+static struct pvtpll_table rk3576_cpul_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length, length_frac */
+	ROCKCHIP_PVTPLL(2016000000, 0, 6, 0),
+	ROCKCHIP_PVTPLL(1920000000, 0, 6, 1),
+	ROCKCHIP_PVTPLL(1800000000, 0, 6, 1),
+	ROCKCHIP_PVTPLL(1608000000, 0, 6, 1),
+	ROCKCHIP_PVTPLL(1416000000, 0, 8, 0),
+	ROCKCHIP_PVTPLL(1200000000, 0, 11, 0),
+	ROCKCHIP_PVTPLL(1008000000, 0, 17, 0),
+	ROCKCHIP_PVTPLL(816000000, 0, 26, 0),
+	ROCKCHIP_PVTPLL(600000000, 0, 0, 0),
+	ROCKCHIP_PVTPLL(408000000, 0, 0, 0),
+	{ /* sentinel */ },
+};
+
+static struct pvtpll_table rk3576_cci_pvtpll_table[] = {
+	/* cpul_rate_hz, ring_sel, length, length_frac */
+	ROCKCHIP_PVTPLL(2016000000 / 2, 0, 27, 0),
+	ROCKCHIP_PVTPLL(1920000000 / 2, 0, 28, 0),
+	ROCKCHIP_PVTPLL(1800000000 / 2, 0, 28, 0),
+	ROCKCHIP_PVTPLL(1608000000 / 2, 0, 30, 0),
+	ROCKCHIP_PVTPLL(1416000000 / 2, 0, 34, 0),
+	ROCKCHIP_PVTPLL(1200000000 / 2, 0, 34, 0),
+	{ /* sentinel */ },
+};
+
+static struct pvtpll_table rk3576_cpub_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length, length_frac, length_low, length_low_frac */
+	ROCKCHIP_PVTPLL(2208000000, 0, 4, 3),
+	ROCKCHIP_PVTPLL(2112000000, 0, 5, 0),
+	ROCKCHIP_PVTPLL(2016000000, 0, 5, 0),
+	ROCKCHIP_PVTPLL(1800000000, 0, 5, 0),
+	ROCKCHIP_PVTPLL(1608000000, 0, 5, 0),
+	ROCKCHIP_PVTPLL(1416000000, 0, 7, 0),
+	ROCKCHIP_PVTPLL(1200000000, 0, 11, 0),
+	ROCKCHIP_PVTPLL(1008000000, 0, 17, 0),
+	ROCKCHIP_PVTPLL(816000000, 0, 26, 0),
+	ROCKCHIP_PVTPLL(600000000, 0, 0, 0),
+	ROCKCHIP_PVTPLL(408000000, 0, 0, 0),
+	{ /* sentinel */ },
+};
+
+static struct pvtpll_table rk3576_gpu_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length, length_frac, length_low, length_low_frac */
+	ROCKCHIP_PVTPLL(900000000, 0, 20, 0),
+	ROCKCHIP_PVTPLL(800000000, 0, 21, 0),
+	ROCKCHIP_PVTPLL(700000000, 0, 21, 0),
+	ROCKCHIP_PVTPLL(600000000, 0, 23, 0),
+	ROCKCHIP_PVTPLL(500000000, 0, 32, 0),
+	ROCKCHIP_PVTPLL(400000000, 0, 48, 0),
+	ROCKCHIP_PVTPLL(300000000, 0, 63, 0),
+	ROCKCHIP_PVTPLL(200000000, 0, 0, 0),
+	{ /* sentinel */ },
+};
+
+static struct pvtpll_table rk3576_npu_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length, length_frac, length_low, length_low_frac */
+	ROCKCHIP_PVTPLL(950000000, 0, 16, 0),
+	ROCKCHIP_PVTPLL(900000000, 0, 17, 0),
+	ROCKCHIP_PVTPLL(800000000, 0, 18, 0),
+	ROCKCHIP_PVTPLL(700000000, 0, 22, 0),
+	ROCKCHIP_PVTPLL(600000000, 0, 25, 0),
+	ROCKCHIP_PVTPLL(500000000, 0, 35, 0),
+	ROCKCHIP_PVTPLL(400000000, 0, 46, 0),
+	ROCKCHIP_PVTPLL(300000000, 0, 63, 0),
+	ROCKCHIP_PVTPLL(200000000, 0, 0, 0),
+	{ /* sentinel */ },
+};
+
+static unsigned long rk3576_cpul_rates[] = {
+	408000000, 600000000, 816000000, 1008000000,
+	1200000000, 1416000000, 1608000000, 1800000000,
+	2016000000, 2208000000, 2304000063
+};
+
+static unsigned long rk3576_cpub_rates[] = {
+	408000000, 600000000, 816000000, 1008000000,
+	1200000000, 1416000000, 1608000000, 1800000000,
+	2016000000, 2208000000, 2304000000, 2400000063
+};
+
+static unsigned long rk3576_gpu_rates[] = {
+	200000000, 300000000, 400000000, 500000000,
+	600000000, 700000000, 800000000, 900000000,
+	1000000063
+};
+
+static unsigned long rk3576_npu_rates[] = {
+	200000000, 300000000, 400000000, 500000000,
+	600000000, 700000000, 800000000, 900000000,
+	1000000063
+};
+
+static unsigned long rk3576_common_rates[] = {
+	400000, 24000000, 58000000, 100000000, 116000000, 175000000, 350000000,
+};
+
+static unsigned long rk3576_aclk_secure_s_rates[] = {
+	116000000, 175000000, 350000000,
+};
+
+static int aclk_crypto_s_enable;
+static int aclk_klad_enable;
+static spinlock_t crypto_lock;
+static bool cpub_suspended;
+
+static struct sys_clk_info_t sys_clk_info;
+static int clk_scmi_cci_set_rate(rk_scmi_clock_t *clock, unsigned long rate);
+
+static struct pvtpll_table *rkclk_get_pvtpll_config(struct pvtpll_table *table,
+						    unsigned int count,
+						    unsigned int freq_hz)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		if (freq_hz == table[i].rate)
+			return &table[i];
+	}
+	return NULL;
+}
+
+static int clk_scmi_set_low_length(struct pvtpll_table *pvtpll, unsigned int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		if (pvtpll[i].length_low) {
+			pvtpll[i].length = pvtpll[i].length_low;
+			pvtpll[i].length_frac = pvtpll[i].length_low_frac;
+		}
+	}
+
+	return 0;
+}
+
+static int clk_cpul_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpul_table,
+					 sys_clk_info.cpul_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	/*
+	 *               |-\
+	 * -----lpll-----|  \
+	 *               |   \                                        |-\
+	 * -----gpll-----|mux|--litcore unclean src--[div]--[autocs]--|  \
+	 *               |   /                                        |   \
+	 * --pvtpll src--|  /                           --pvtpll src--|mux|--litcore--
+	 *               |-/                                          |   /
+	 *                                       --litcore clean src--|  /
+	 *                                                            |-/
+	 */
+	if (PVTPLL_NEED(type, pvtpll->length)) {
+		/* set ring sel and length */
+		mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_LEN,
+			      0x1dff0000 |
+			      (pvtpll->ring_sel << 10) |
+			      (pvtpll->length << 2) |
+			      (pvtpll->length_frac));
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+		/* enable pvtpll */
+		mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+		/* start pvtpll */
+		mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_CFG,  0x00230023);
+
+		/* set pvtpll_src parent from 24MHz/32KHz to pvtpll */
+		mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1),
+			      CPUL_PVTPLL_PATH_PVTPLL);
+
+		/* set litcore unclean_src parent to pvtpll_src */
+		mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
+			      CPUL_CLK_PATH_NOR_PVTPLL);
+		/*
+		 * set litcore parent from pvtpll_src to unclean_src,
+		 * because autocs is on litcore unclean_src.
+		 */
+		mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1),
+			      CPUL_CLK_PATH_LPLL);
+		/* set litcore unclean_src div to 0 */
+		mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
+			      CLKDIV_5BITS_SHF(0, 7));
+
+		return 0;
+	}
+	/* set litcore unclean_src div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div, 7));
+	/* set litcore unclean_src parent to gpll */
+	mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
+		      CPUL_CLK_PATH_NOR_GPLL);
+	/* set litcore parent to unclean_src */
+	mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1),
+		      CPUL_CLK_PATH_LPLL);
+
+	return 0;
+}
+
+static int clk_scmi_cpul_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_cpul_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0) {
+		sys_clk_info.cpul_rate = rate;
+		ret = clk_scmi_cci_set_rate(clock, rate / 2);
+	}
+
+	return ret;
+}
+
+static unsigned long rk3576_lpll_get_rate(void)
+{
+	unsigned int m, p, s, k;
+	uint64_t rate64 = 24000000, postdiv;
+	int mode;
+
+	mode = mmio_read_32(LITTLE_CRU_BASE + CRU_MODE_CON) &
+	       0x3;
+
+	if (mode == 0)
+		return rate64;
+
+	m = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(16)) >>
+		 CRU_PLLCON0_M_SHIFT) &
+		CRU_PLLCON0_M_MASK;
+	p = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(17)) >>
+		    CRU_PLLCON1_P_SHIFT) &
+		   CRU_PLLCON1_P_MASK;
+	s = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(17)) >>
+		  CRU_PLLCON1_S_SHIFT) &
+		 CRU_PLLCON1_S_MASK;
+	k = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(18)) >>
+		    CRU_PLLCON2_K_SHIFT) &
+		   CRU_PLLCON2_K_MASK;
+
+	rate64 *= m;
+	rate64 = rate64 / p;
+
+	if (k != 0) {
+		/* fractional mode */
+		uint64_t frac_rate64 = 24000000 * k;
+
+		postdiv = p * 65536;
+		frac_rate64 = frac_rate64 / postdiv;
+		rate64 += frac_rate64;
+	}
+	rate64 = rate64 >> s;
+
+	return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpul_get_rate(rk_scmi_clock_t *clock)
+{
+	int src, div;
+
+	src = mmio_read_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1)) & 0x00c0;
+	src = src >> 6;
+	if (src == 1)
+		return sys_clk_info.cpul_rate;
+
+	src = mmio_read_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0)) & 0x3000;
+	src = src >> 12;
+	div = mmio_read_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(6)) & 0x0f80;
+	div = div >> 7;
+	switch (src) {
+	case 0:
+		return rk3576_lpll_get_rate();
+	case 1:
+		/* Make the return rate is equal to the set rate */
+		if (sys_clk_info.cpul_rate != 0)
+			return sys_clk_info.cpul_rate;
+		else
+			return GPLL_RATE / (div + 1);
+	case 2:
+		return sys_clk_info.cpul_rate;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_cpul_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static int clk_cpub_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpub_table,
+					 sys_clk_info.cpub_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	/*
+	 *               |-\
+	 * -----bpll-----|  \
+	 *               |   \                                        |-\
+	 * -----gpll-----|mux|--bigcore unclean src--[div]--[autocs]--|  \
+	 *               |   /                                        |   \
+	 * --pvtpll src--|  /                           --pvtpll src--|mux|--bigcore--
+	 *               |-/                                          |   /
+	 *                                       --bigcore clean src--|  /
+	 *                                                            |-/
+	 */
+	if (PVTPLL_NEED(type, pvtpll->length) != 0) {
+		/* set ring sel and length */
+		mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_LEN,
+			      0x1dff0000 |
+			      (pvtpll->ring_sel << 10) |
+			      (pvtpll->length << 2) |
+			      (pvtpll->length_frac));
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+		/* enable pvtpll */
+		mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+		/* start pvtpll */
+		mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
+
+		/* set pvtpll_src parent from 24MHz/32KHz to pvtpll */
+		mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(2),
+			      CPUB_PVTPLL_PATH_PVTPLL);
+
+		/* set bigcore unclean_src parent to pvtpll_src */
+		mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+			      CPUB_CLK_PATH_NOR_PVTPLL);
+		/*
+		 * set bigcore parent from pvtpll_src to unclean_src,
+		 * because autocs is on bigcore unclean_src.
+		 */
+		mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+			      CPUB_CLK_PATH_BPLL);
+
+		/* set bigcore unclean_src div to 0 */
+		mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+			      CLKDIV_5BITS_SHF(0, 7));
+
+		return 0;
+	}
+
+	/* set bigcore unclean_src div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+		      CLKDIV_5BITS_SHF(div, 7));
+	/* set bigcore unclean_src parent to gpll */
+	mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+		      CPUB_CLK_PATH_NOR_GPLL);
+	/* set bigcore parent to unclean_src */
+	mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+		      CPUB_CLK_PATH_BPLL);
+
+	return 0;
+}
+
+static int clk_scmi_cpub_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	if ((rate & OPP_LENGTH_LOW) != 0) {
+		clk_scmi_set_low_length(sys_clk_info.cpub_table,
+					sys_clk_info.cpub_rate_count);
+		return 0;
+	}
+
+	ret = clk_cpub_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0)
+		sys_clk_info.cpub_rate = rate;
+
+	return ret;
+}
+
+static unsigned long rk3576_bpll_get_rate(void)
+{
+	unsigned int m, p, s, k;
+	uint64_t rate64 = 24000000, postdiv;
+	int mode;
+
+	mode = mmio_read_32(CRU_BASE + CRU_MODE_CON) &
+	       0x3;
+
+	if (mode == 0)
+		return rate64;
+
+	m = (mmio_read_32(CRU_BASE + CRU_PLL_CON(0)) >>
+		 CRU_PLLCON0_M_SHIFT) &
+		CRU_PLLCON0_M_MASK;
+	p = (mmio_read_32(CRU_BASE + CRU_PLL_CON(1)) >>
+		    CRU_PLLCON1_P_SHIFT) &
+		   CRU_PLLCON1_P_MASK;
+	s = (mmio_read_32(CRU_BASE + CRU_PLL_CON(1)) >>
+		  CRU_PLLCON1_S_SHIFT) &
+		 CRU_PLLCON1_S_MASK;
+	k = (mmio_read_32(CRU_BASE + CRU_PLL_CON(2)) >>
+		    CRU_PLLCON2_K_SHIFT) &
+		   CRU_PLLCON2_K_MASK;
+
+	rate64 *= m;
+	rate64 = rate64 / p;
+
+	if (k != 0) {
+		/* fractional mode */
+		uint64_t frac_rate64 = 24000000 * k;
+
+		postdiv = p * 65536;
+		frac_rate64 = frac_rate64 / postdiv;
+		rate64 += frac_rate64;
+	}
+	rate64 = rate64 >> s;
+
+	return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpub_get_rate(rk_scmi_clock_t *clock)
+{
+	int value, src, div;
+
+	if (cpub_suspended != 0)
+		return sys_clk_info.cpub_rate;
+
+	value = mmio_read_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1));
+	src = (value & 0xc000) >> 14;
+	if (src == 1)
+		return sys_clk_info.cpub_rate;
+
+	value = mmio_read_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1));
+	src = (value & 0x3000) >> 12;
+	div = (value & 0x0f80) >> 7;
+	switch (src) {
+	case 0:
+		return rk3576_bpll_get_rate();
+	case 1:
+		/* Make the return rate is equal to the set rate */
+		if (sys_clk_info.cpub_rate != 0)
+			return sys_clk_info.cpub_rate;
+		else
+			return GPLL_RATE / (div + 1);
+	case 2:
+		return sys_clk_info.cpub_rate;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_cpub_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_cci_get_rate(rk_scmi_clock_t *clock)
+{
+	int src, div;
+
+	src = mmio_read_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4)) & 0x3000;
+	src = src >> 12;
+	if (src == 1)
+		return sys_clk_info.cci_rate;
+
+	div = mmio_read_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4)) & 0xf80;
+	div = div >> 7;
+	switch (src) {
+	case 0:
+		return OSC_HZ;
+	case 1:
+		return sys_clk_info.cci_rate;
+	case 2:
+		return GPLL_RATE / (div + 1);
+	case 3:
+		return rk3576_lpll_get_rate() / (div + 1);
+	default:
+		return 0;
+	}
+}
+
+static int clk_cci_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	uint32_t pvtpll_en = 0;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cci_table,
+					 sys_clk_info.cci_rate_count, rate);
+
+	/* set pvtpll */
+	if ((pvtpll != 0) && (PVTPLL_NEED(type, pvtpll->length) != 0)) {
+		/* set ring sel and length */
+		mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_LEN,
+			      0x1dff0000 |
+			      (pvtpll->ring_sel << 10) |
+			      (pvtpll->length << 2) |
+			      (pvtpll->length_frac));
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+		/* enable pvtpll */
+		pvtpll_en = mmio_read_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CFG);
+		if (pvtpll_en && 0x22 != 0x22)
+			mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+		/* start pvtpll */
+		mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
+
+		/* set cci mux pvtpll */
+		mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+			      CCI_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+			      SCLK_CCI_PATH_PVTPLL);
+		mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+			      CLKDIV_5BITS_SHF(0, 7));
+		sys_clk_info.cci_rate = rate;
+		return 0;
+	}
+	sys_clk_info.cci_rate = 594000000;
+	/* set cci div */
+	mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+		      CLKDIV_5BITS_SHF(1, 7));
+	/* set cci mux gpll */
+	mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+		      SCLK_CCI_PATH_NOR_GPLL);
+
+	return 0;
+}
+
+static int clk_scmi_cci_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	return clk_cci_set_rate(rate, PLL_SEL_AUTO);
+}
+
+static int clk_scmi_cci_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_gpu_get_rate(rk_scmi_clock_t *clock)
+{
+	int div, src;
+
+	if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(165)) & 0x100) != 0)
+		return sys_clk_info.gpu_rate;
+
+	div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(165)) & 0x1f;
+	src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(165)) & 0x00e0;
+	src = src >> 5;
+	switch (src) {
+	case 0:
+		/* Make the return rate is equal to the set rate */
+		if (sys_clk_info.gpu_rate != 0)
+			return sys_clk_info.gpu_rate;
+		else
+			return GPLL_RATE / (div + 1);
+	case 1:
+		return CPLL_RATE / (div + 1);
+	case 2:
+		return AUPLL_RATE / (div + 1);
+	case 3:
+		return SPLL_RATE / (div + 1);
+	case 4:
+		return rk3576_lpll_get_rate() / (div + 1);
+	default:
+		return 0;
+	}
+}
+
+static int clk_gpu_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.gpu_table,
+					 sys_clk_info.gpu_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	if (PVTPLL_NEED(type, pvtpll->length) != 0) {
+		/* set ring sel and length */
+		mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_LEN,
+			      0x1dff0000 |
+			      (pvtpll->ring_sel << 10) |
+			      (pvtpll->length << 2) |
+			      (pvtpll->length_frac));
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+		/* enable pvtpll */
+		mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+		/* start pvtpll */
+		mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
+		/* set gpu mux pvtpll */
+		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+			      GPU_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+			      GPU_CLK_PATH_PVTPLL);
+		return 0;
+	}
+
+	/* set gpu div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+		      CLKDIV_5BITS_SHF(div - 1, 0));
+	/* set gpu mux gpll */
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+		      GPU_CLK_PATH_NOR_GPLL);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+		      GPU_CLK_PATH_NOR_PLL);
+
+	return 0;
+}
+
+static int clk_scmi_gpu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	if ((rate & OPP_LENGTH_LOW) != 0) {
+		clk_scmi_set_low_length(sys_clk_info.gpu_table,
+					sys_clk_info.gpu_rate_count);
+		return 0;
+	}
+
+	ret = clk_gpu_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0)
+		sys_clk_info.gpu_rate = rate;
+
+	return ret;
+}
+
+static int clk_scmi_gpu_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_npu_get_rate(rk_scmi_clock_t *clock)
+{
+	int div, src, div_src;
+
+	if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x8000) != 0)
+		return sys_clk_info.npu_rate;
+
+	div_src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x07c;
+	div_src = div_src >> 2;
+	src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x0180;
+	src = src >> 7;
+	div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x7c00;
+	div = div >> 10;
+	switch (src) {
+	case 0:
+		/* Make the return rate is equal to the set rate */
+		if (sys_clk_info.npu_rate != 0)
+			return sys_clk_info.npu_rate;
+		else
+			return GPLL_RATE / (div_src + 1)  / (div + 1);
+	case 1:
+		return CPLL_RATE / (div_src + 1)  / (div + 1);
+	case 2:
+		return AUPLL_RATE / (div_src + 1)  / (div + 1);
+	case 3:
+		return SPLL_RATE / (div_src + 1)  / (div + 1);
+	default:
+		return 0;
+	}
+}
+
+static int clk_npu_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+	struct pvtpll_table *pvtpll;
+	int div;
+
+	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.npu_table,
+					 sys_clk_info.npu_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	if (PVTPLL_NEED(type, pvtpll->length) != 0) {
+		/* set ring sel and length */
+		mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_LEN,
+			      0x1dff0000 |
+			      (pvtpll->ring_sel << 10) |
+			      (pvtpll->length << 2) |
+			      (pvtpll->length_frac));
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+		/* enable pvtpll */
+		mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+		/* start pvtpll */
+		mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
+		/* set npu mux pvtpll */
+		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+			      NPU_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+			      NPU_CLK_PATH_PVTPLL);
+		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+			      CLKDIV_5BITS_SHF(0, 10));
+		return 0;
+	}
+
+	/* set npu div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+		      CLKDIV_5BITS_SHF(div - 1, 2));
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+		      CLKDIV_5BITS_SHF(0, 10));
+	/* set npu mux gpll */
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+		      NPU_CLK_PATH_NOR_GPLL);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+		      NPU_CLK_PATH_NOR_PLL);
+
+	return 0;
+}
+
+static int clk_scmi_npu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	if ((rate & OPP_LENGTH_LOW) != 0) {
+		clk_scmi_set_low_length(sys_clk_info.npu_table,
+					sys_clk_info.npu_rate_count);
+		return 0;
+	}
+
+	ret = clk_npu_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0)
+		sys_clk_info.npu_rate = rate;
+
+	return ret;
+}
+
+static int clk_scmi_npu_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+int clk_scmi_crypto_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	spin_lock(&crypto_lock);
+
+	if (clock->id == ACLK_CRYPTO_S)
+		aclk_crypto_s_enable = status;
+	else
+		aclk_klad_enable = status;
+
+	if ((aclk_crypto_s_enable != 0) || (aclk_klad_enable != 0))
+		clk_scmi_common_set_status(clock, 1);
+	else
+		clk_scmi_common_set_status(clock, 0);
+
+	spin_unlock(&crypto_lock);
+	return 0;
+}
+
+static int clk_scmi_common_set_status_critical(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static const struct rk_clk_ops clk_scmi_cpul_ops = {
+	.get_rate = clk_scmi_cpul_get_rate,
+	.set_rate = clk_scmi_cpul_set_rate,
+	.set_status = clk_scmi_cpul_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cci_ops = {
+	.get_rate = clk_scmi_cci_get_rate,
+	.set_rate = clk_scmi_cci_set_rate,
+	.set_status = clk_scmi_cci_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cpub_ops = {
+	.get_rate = clk_scmi_cpub_get_rate,
+	.set_rate = clk_scmi_cpub_set_rate,
+	.set_status = clk_scmi_cpub_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_gpu_ops = {
+	.get_rate = clk_scmi_gpu_get_rate,
+	.set_rate = clk_scmi_gpu_set_rate,
+	.set_status = clk_scmi_gpu_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_npu_ops = {
+	.get_rate = clk_scmi_npu_get_rate,
+	.set_rate = clk_scmi_npu_set_rate,
+	.set_status = clk_scmi_npu_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_ops_com_critical = {
+	.get_rate = clk_scmi_common_get_rate,
+	.set_rate = clk_scmi_common_set_rate,
+	.set_status = clk_scmi_common_set_status_critical,
+};
+
+static const struct rk_clk_ops clk_scmi_ops_com = {
+	.get_rate = clk_scmi_common_get_rate,
+	.set_rate = clk_scmi_common_set_rate,
+	.set_status = clk_scmi_common_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_ops_gate = {
+	.get_rate = clk_scmi_common_get_rate,
+	.set_status = clk_scmi_common_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_ops_crypto = {
+	.get_rate = clk_scmi_common_get_rate,
+	.set_status = clk_scmi_crypto_set_status,
+};
+
+RK3576_SCMI_CLOCK(ARMCLK_L, scmi_armclkl, &clk_scmi_cpul_ops, rk3576_cpul_rates, ARRAY_SIZE(rk3576_cpul_rates), false);
+RK3576_SCMI_CLOCK(ACLK_CCI_ROOT, scmi_aclk_cci, &clk_scmi_cci_ops, rk3576_cpul_rates, ARRAY_SIZE(rk3576_cpul_rates), false);
+RK3576_SCMI_CLOCK(ARMCLK_B, scmi_armclkb, &clk_scmi_cpub_ops, rk3576_cpub_rates, ARRAY_SIZE(rk3576_cpub_rates), false);
+RK3576_SCMI_CLOCK(CLK_GPU, scmi_clk_gpu, &clk_scmi_gpu_ops, rk3576_gpu_rates, ARRAY_SIZE(rk3576_gpu_rates), false);
+RK3576_SCMI_CLOCK(CLK_RKNN_DSU0, scmi_clk_npu, &clk_scmi_npu_ops, rk3576_npu_rates, ARRAY_SIZE(rk3576_npu_rates), false);
+RK3576_SCMI_CLOCK_COM(CLK_STIMER0_ROOT, clk_stimer0_root, p_100m_24m, clk_stimer0_root_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(CLK_STIMER1_ROOT, clk_stimer1_root, p_100m_24m, clk_stimer1_root_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(PCLK_SECURE_S, pclk_secure_s, p_116m_58m_24m, pclk_secure_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(HCLK_SECURE_S, hclk_secure_s, p_175m_116m_58m_24m, hclk_secure_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(ACLK_SECURE_S, aclk_secure_s, p_350m_175m_116m_24m, aclk_secure_s_info, &clk_scmi_ops_com_critical, rk3576_aclk_secure_s_rates, false, false);
+RK3576_SCMI_CLOCK_COM(CLK_PKA_CRYPTO_S, clk_pka_crypto_s, p_350m_175m_116m_24m, clk_pka_crypto_s_info, &clk_scmi_ops_com, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(HCLK_VO1_S, hclk_vo1_s, p_175m_116m_58m_24m, hclk_vo1_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(PCLK_VO1_S, pclk_vo1_s, p_116m_58m_24m, pclk_vo1_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(HCLK_VO0_S, hclk_vo0_s, p_175m_116m_58m_24m, hclk_vo0_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(PCLK_VO0_S, pclk_vo0_s, p_116m_58m_24m, pclk_vo0_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(PCLK_KLAD, pclk_klad, p_pclk_secure_s, pclk_klad_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(HCLK_CRYPTO_S, hclk_crypto_s, p_hclk_secure_s, hclk_crypto_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(HCLK_KLAD, hclk_klad, p_hclk_secure_s, hclk_klad_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(ACLK_CRYPTO_S, aclk_crypto_s, p_aclk_secure_s, aclk_crypto_s_info, &clk_scmi_ops_crypto, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(HCLK_TRNG_S, hclk_trng_s, p_hclk_secure_s, hclk_trng_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(PCLK_OTPC_S, plk_otpc_s, p_pclk_secure_s, pclk_otpc_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(CLK_OTPC_S, clk_otpc_s, p_24m, clk_otpc_s_info, &clk_scmi_ops_gate, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(PCLK_WDT_S, pclk_wdt_s, p_pclk_secure_s, pclk_wdt_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(TCLK_WDT_S, tclk_wdt_s, p_24m, tclk_wdt_s_info, &clk_scmi_ops_gate, rk3576_common_rates, false, true);
+RK3576_SCMI_CLOCK_COM(PCLK_HDCP0_TRNG, pclk_hdcp0_trng, p_pclk_vo0_s, pclk_hdcp0_trng_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(PCLK_HDCP1_TRNG, pclk_hdcp1_trng, p_pclk_vo1_s, pclk_hdcp1_trng_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(HCLK_HDCP_KEY0, hclk_hdcp_key0, p_hclk_vo0_s, hclk_hdcp_key0_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(HCLK_HDCP_KEY1, hclk_hdcp_key1, p_hclk_vo1_s, hclk_hdcp_key1_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(PCLK_EDP_S, pclk_edp_s, p_pclk_vo0_s, pclk_edp_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+RK3576_SCMI_CLOCK_COM(ACLK_KLAD, aclk_klad, p_aclk_secure_s, aclk_crypto_s_info, &clk_scmi_ops_crypto, rk3576_common_rates, true, true);
+
+rk_scmi_clock_t *clock_table[] = {
+	[ARMCLK_L]		= &scmi_armclkl,
+	[ACLK_CCI_ROOT]		= &scmi_aclk_cci,
+	[ARMCLK_B]		= &scmi_armclkb,
+	[CLK_GPU]		= &scmi_clk_gpu,
+	[CLK_RKNN_DSU0]		= &scmi_clk_npu,
+	[CLK_STIMER0_ROOT]	= &clk_stimer0_root,
+	[CLK_STIMER1_ROOT]	= &clk_stimer1_root,
+	[PCLK_SECURE_S]		= &pclk_secure_s,
+	[HCLK_SECURE_S]		= &hclk_secure_s,
+	[ACLK_SECURE_S]		= &aclk_secure_s,
+	[CLK_PKA_CRYPTO_S]	= &clk_pka_crypto_s,
+	[HCLK_VO1_S]		= &hclk_vo1_s,
+	[PCLK_VO1_S]		= &pclk_vo1_s,
+	[HCLK_VO0_S]		= &hclk_vo0_s,
+	[PCLK_VO0_S]		= &pclk_vo0_s,
+	[PCLK_KLAD]		= &pclk_klad,
+	[HCLK_CRYPTO_S]		= &hclk_crypto_s,
+	[HCLK_KLAD]		= &hclk_klad,
+	[ACLK_CRYPTO_S]		= &aclk_crypto_s,
+	[HCLK_TRNG_S]		= &hclk_trng_s,
+	[PCLK_OTPC_S]		= &plk_otpc_s,
+	[CLK_OTPC_S]		= &clk_otpc_s,
+	[PCLK_WDT_S]		= &pclk_wdt_s,
+	[TCLK_WDT_S]		= &tclk_wdt_s,
+	[PCLK_HDCP0_TRNG]	= &pclk_hdcp0_trng,
+	[PCLK_HDCP1_TRNG]	= &pclk_hdcp1_trng,
+	[HCLK_HDCP_KEY0]	= &hclk_hdcp_key0,
+	[HCLK_HDCP_KEY1]	= &hclk_hdcp_key1,
+	[PCLK_EDP_S]		= &pclk_edp_s,
+	[ACLK_KLAD]		= &aclk_klad,
+};
+
+size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
+{
+	return CLK_NR_CLKS;
+}
+
+rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
+					 uint32_t clock_id)
+{
+	rk_scmi_clock_t *table = NULL;
+
+	if (clock_id < ARRAY_SIZE(clock_table)) {
+		table = clock_table[clock_id];
+		if (table == NULL)
+			return NULL;
+	}
+
+	if ((table != NULL) && (table->is_security == 0))
+		return table;
+	else
+		return NULL;
+
+	return NULL;
+}
+
+void pvtplls_cpub_suspend(void)
+{
+	clk_cpub_set_rate(408000000, PLL_SEL_NOR);
+	cpub_suspended = true;
+}
+
+void pvtplls_cpub_resume(void)
+{
+	cpub_suspended = false;
+	clk_cpub_set_rate(sys_clk_info.cpub_rate, PLL_SEL_AUTO);
+}
+
+void pvtplls_suspend(void)
+{
+	clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+	clk_cci_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub_set_rate(408000000, PLL_SEL_NOR);
+}
+
+void pvtplls_resume(void)
+{
+	clk_cpul_set_rate(sys_clk_info.cpul_rate, PLL_SEL_AUTO);
+	clk_cci_set_rate(sys_clk_info.cci_rate, PLL_SEL_AUTO);
+	clk_cpub_set_rate(sys_clk_info.cpub_rate, PLL_SEL_AUTO);
+}
+
+void sys_reset_pvtplls_prepare(void)
+{
+	clk_gpu_set_rate(200000000, PLL_SEL_NOR);
+	clk_npu_set_rate(200000000, PLL_SEL_NOR);
+	clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+	clk_cci_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub_set_rate(408000000, PLL_SEL_NOR);
+}
+
+int rockchip_opteed_clk_set_rate(uint64_t clk_idx, uint64_t rate)
+{
+	rk_scmi_clock_t *table;
+
+	if (clk_idx > CLK_NR_CLKS) {
+		INFO("%s: clk-%ld, %ld not supported\n", __func__, clk_idx, rate);
+		return SCMI_INVALID_PARAMETERS;
+	}
+
+	table = rockchip_scmi_get_clock(0, clk_idx);
+	if (table != NULL)
+		table->clk_ops->set_rate(table, rate);
+
+	return 0;
+}
+
+int rockchip_opteed_clk_get_rate(uint64_t clk_idx, uint64_t *rate)
+{
+	rk_scmi_clock_t *table;
+
+	if (clk_idx > CLK_NR_CLKS) {
+		INFO("%s: clk-%ld not supported\n", __func__, clk_idx);
+		return SCMI_INVALID_PARAMETERS;
+	}
+
+	table = rockchip_scmi_get_clock(0, clk_idx);
+	if (table != NULL)
+		*rate = (uint64_t)table->clk_ops->get_rate(table);
+	return 0;
+}
+
+int rockchip_opteed_clk_enable(uint64_t clk_idx, uint64_t enable)
+{
+	rk_scmi_clock_t *table;
+
+	if (clk_idx > CLK_NR_CLKS) {
+		INFO("%s: clk-%ld, %ld not supported\n", __func__, clk_idx, enable);
+		return SCMI_INVALID_PARAMETERS;
+	}
+
+	table = rockchip_scmi_get_clock(0, clk_idx);
+	if (table != NULL) {
+		if (enable != 0) {
+			table->clk_ops->set_status(table, enable);
+			table->enable_count++;
+		} else {
+			if (table->enable_count == 0)
+				return 0;
+			if (--table->enable_count > 0)
+				return 0;
+			table->clk_ops->set_status(table, enable);
+		}
+	}
+	return 0;
+}
+
+#define RK3576_CPUB_OPP_INFO_OFFSET	48
+#define RK3576_CPUL_OPP_INFO_OFFSET	54
+#define RK3576_CCI_OPP_INFO_OFFSET	60
+#define RK3576_NPU_OPP_INFO_OFFSET	66
+#define RK3576_GPU_OPP_INFO_OFFSET	72
+
+static void rockchip_init_pvtpll_table(void)
+{
+	sys_clk_info.cpul_table = rk3576_cpul_pvtpll_table;
+	sys_clk_info.cpul_rate_count = ARRAY_SIZE(rk3576_cpul_pvtpll_table);
+	sys_clk_info.cci_table = rk3576_cci_pvtpll_table;
+	sys_clk_info.cci_rate_count = ARRAY_SIZE(rk3576_cci_pvtpll_table);
+	sys_clk_info.cpub_table = rk3576_cpub_pvtpll_table;
+	sys_clk_info.cpub_rate_count = ARRAY_SIZE(rk3576_cpub_pvtpll_table);
+	sys_clk_info.gpu_table = rk3576_gpu_pvtpll_table;
+	sys_clk_info.gpu_rate_count = ARRAY_SIZE(rk3576_gpu_pvtpll_table);
+	sys_clk_info.npu_table = rk3576_npu_pvtpll_table;
+	sys_clk_info.npu_rate_count = ARRAY_SIZE(rk3576_npu_pvtpll_table);
+}
+
+void rockchip_clock_init(void)
+{
+	rockchip_init_pvtpll_table();
+}
+
+static int pvtpll_get_clk(uint64_t clock_id, struct pvtpll_table **table,
+			  unsigned int *count)
+{
+	switch (clock_id) {
+	case ARMCLK_L:
+		*table = sys_clk_info.cpul_table;
+		*count = sys_clk_info.cpul_rate_count;
+		break;
+	case ARMCLK_B:
+		*table = sys_clk_info.cpub_table;
+		*count = sys_clk_info.cpub_rate_count;
+		break;
+	case CLK_GPU:
+		*table = sys_clk_info.gpu_table;
+		*count = sys_clk_info.gpu_rate_count;
+		break;
+	case CLK_RKNN_DSU0:
+		*table = sys_clk_info.npu_table;
+		*count = sys_clk_info.npu_rate_count;
+		break;
+	default:
+		return -1;
+	}
+
+	if ((*table == NULL) || (*count == 0))
+		return -1;
+
+	return 0;
+}
+
+int pvtpll_volt_sel_adjust(uint64_t clock_id, uint64_t volt_sel)
+{
+	struct pvtpll_table *table = NULL;
+	uint32_t delta_len = 0;
+	unsigned int count = 0;
+	int i;
+
+	if (pvtpll_get_clk(clock_id, &table, &count) != 0)
+		return -1;
+
+	for (i = 0; i < count; i++) {
+		if (table[i].volt_sel_thr == 0)
+			continue;
+		if (volt_sel >= table[i].volt_sel_thr) {
+			delta_len = volt_sel - table[i].volt_sel_thr + 1;
+			table[i].length += delta_len;
+			if (table[i].length > RK3576_PVTPLL_MAX_LENGTH)
+				table[i].length = RK3576_PVTPLL_MAX_LENGTH;
+		}
+	}
+
+	return 0;
+}
diff --git a/plat/rockchip/rk3576/scmi/rk3576_clk.h b/plat/rockchip/rk3576/scmi/rk3576_clk.h
new file mode 100644
index 0000000..b2c00b9
--- /dev/null
+++ b/plat/rockchip/rk3576/scmi/rk3576_clk.h
@@ -0,0 +1,1151 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __CLOCK_H__
+#define __CLOCK_H__
+
+/* cru-clocks indices */
+
+/* cru plls */
+#define PLL_BPLL			1
+#define PLL_LPLL			3
+#define PLL_VPLL			4
+#define PLL_AUPLL			5
+#define PLL_CPLL			6
+#define PLL_GPLL			7
+#define PLL_PPLL			9
+#define ARMCLK_L			10
+#define ARMCLK_B			11
+
+/* cru clocks */
+#define CLK_CPLL_DIV20			15
+#define CLK_CPLL_DIV10			16
+#define CLK_GPLL_DIV8			17
+#define CLK_GPLL_DIV6			18
+#define CLK_CPLL_DIV4			19
+#define CLK_GPLL_DIV4			20
+#define CLK_SPLL_DIV2			21
+#define CLK_GPLL_DIV3			22
+#define CLK_CPLL_DIV2			23
+#define CLK_GPLL_DIV2			24
+#define CLK_SPLL_DIV1			25
+#define PCLK_TOP_ROOT			26
+#define ACLK_TOP			27
+#define HCLK_TOP			28
+#define CLK_AUDIO_FRAC_0		29
+#define CLK_AUDIO_FRAC_1		30
+#define CLK_AUDIO_FRAC_2		31
+#define CLK_AUDIO_FRAC_3		32
+#define CLK_UART_FRAC_0			33
+#define CLK_UART_FRAC_1			34
+#define CLK_UART_FRAC_2			35
+#define CLK_UART1_SRC_TOP		36
+#define CLK_AUDIO_INT_0			37
+#define CLK_AUDIO_INT_1			38
+#define CLK_AUDIO_INT_2			39
+#define CLK_PDM0_SRC_TOP		40
+#define CLK_PDM1_OUT			41
+#define CLK_GMAC0_125M_SRC		42
+#define CLK_GMAC1_125M_SRC		43
+#define LCLK_ASRC_SRC_0			44
+#define LCLK_ASRC_SRC_1			45
+#define REF_CLK0_OUT_PLL		46
+#define REF_CLK1_OUT_PLL		47
+#define REF_CLK2_OUT_PLL		48
+#define REFCLKO25M_GMAC0_OUT		49
+#define REFCLKO25M_GMAC1_OUT		50
+#define CLK_CIFOUT_OUT			51
+#define CLK_GMAC0_RMII_CRU		52
+#define CLK_GMAC1_RMII_CRU		53
+#define CLK_OTPC_AUTO_RD_G		54
+#define CLK_OTP_PHY_G			55
+#define CLK_MIPI_CAMERAOUT_M0		56
+#define CLK_MIPI_CAMERAOUT_M1		57
+#define CLK_MIPI_CAMERAOUT_M2		58
+#define MCLK_PDM0_SRC_TOP		59
+#define HCLK_AUDIO_ROOT			60
+#define HCLK_ASRC_2CH_0			61
+#define HCLK_ASRC_2CH_1			62
+#define HCLK_ASRC_4CH_0			63
+#define HCLK_ASRC_4CH_1			64
+#define CLK_ASRC_2CH_0			65
+#define CLK_ASRC_2CH_1			66
+#define CLK_ASRC_4CH_0			67
+#define CLK_ASRC_4CH_1			68
+#define MCLK_SAI0_8CH_SRC		69
+#define MCLK_SAI0_8CH			70
+#define HCLK_SAI0_8CH			71
+#define HCLK_SPDIF_RX0			72
+#define MCLK_SPDIF_RX0			73
+#define HCLK_SPDIF_RX1			74
+#define MCLK_SPDIF_RX1			75
+#define MCLK_SAI1_8CH_SRC		76
+#define MCLK_SAI1_8CH			77
+#define HCLK_SAI1_8CH			78
+#define MCLK_SAI2_2CH_SRC		79
+#define MCLK_SAI2_2CH			80
+#define HCLK_SAI2_2CH			81
+#define MCLK_SAI3_2CH_SRC		82
+#define MCLK_SAI3_2CH			83
+#define HCLK_SAI3_2CH			84
+#define MCLK_SAI4_2CH_SRC		85
+#define MCLK_SAI4_2CH			86
+#define HCLK_SAI4_2CH			87
+#define HCLK_ACDCDIG_DSM		88
+#define MCLK_ACDCDIG_DSM		89
+#define CLK_PDM1			90
+#define HCLK_PDM1			91
+#define MCLK_PDM1			92
+#define HCLK_SPDIF_TX0			93
+#define MCLK_SPDIF_TX0			94
+#define HCLK_SPDIF_TX1			95
+#define MCLK_SPDIF_TX1			96
+#define CLK_SAI1_MCLKOUT		97
+#define CLK_SAI2_MCLKOUT		98
+#define CLK_SAI3_MCLKOUT		99
+#define CLK_SAI4_MCLKOUT		100
+#define CLK_SAI0_MCLKOUT		101
+#define HCLK_BUS_ROOT			102
+#define PCLK_BUS_ROOT			103
+#define ACLK_BUS_ROOT			104
+#define HCLK_CAN0			105
+#define CLK_CAN0			106
+#define HCLK_CAN1			107
+#define CLK_CAN1			108
+#define CLK_KEY_SHIFT			109
+#define PCLK_I2C1			110
+#define PCLK_I2C2			111
+#define PCLK_I2C3			112
+#define PCLK_I2C4			113
+#define PCLK_I2C5			114
+#define PCLK_I2C6			115
+#define PCLK_I2C7			116
+#define PCLK_I2C8			117
+#define PCLK_I2C9			118
+#define PCLK_WDT_BUSMCU			119
+#define TCLK_WDT_BUSMCU			120
+#define ACLK_GIC			121
+#define CLK_I2C1			122
+#define CLK_I2C2			123
+#define CLK_I2C3			124
+#define CLK_I2C4			125
+#define CLK_I2C5			126
+#define CLK_I2C6			127
+#define CLK_I2C7			128
+#define CLK_I2C8			129
+#define CLK_I2C9			130
+#define PCLK_SARADC			131
+#define CLK_SARADC			132
+#define PCLK_TSADC			133
+#define CLK_TSADC			134
+#define PCLK_UART0			135
+#define PCLK_UART2			136
+#define PCLK_UART3			137
+#define PCLK_UART4			138
+#define PCLK_UART5			139
+#define PCLK_UART6			140
+#define PCLK_UART7			141
+#define PCLK_UART8			142
+#define PCLK_UART9			143
+#define PCLK_UART10			144
+#define PCLK_UART11			145
+#define SCLK_UART0			146
+#define SCLK_UART2			147
+#define SCLK_UART3			148
+#define SCLK_UART4			149
+#define SCLK_UART5			150
+#define SCLK_UART6			151
+#define SCLK_UART7			152
+#define SCLK_UART8			153
+#define SCLK_UART9			154
+#define SCLK_UART10			155
+#define SCLK_UART11			156
+#define PCLK_SPI0			157
+#define PCLK_SPI1			158
+#define PCLK_SPI2			159
+#define PCLK_SPI3			160
+#define PCLK_SPI4			161
+#define CLK_SPI0			162
+#define CLK_SPI1			163
+#define CLK_SPI2			164
+#define CLK_SPI3			165
+#define CLK_SPI4			166
+#define PCLK_WDT0			167
+#define TCLK_WDT0			168
+#define PCLK_PWM1			169
+#define CLK_PWM1			170
+#define CLK_OSC_PWM1			171
+#define CLK_RC_PWM1			172
+#define PCLK_BUSTIMER0			173
+#define PCLK_BUSTIMER1			174
+#define CLK_TIMER0_ROOT			175
+#define CLK_TIMER0			176
+#define CLK_TIMER1			177
+#define CLK_TIMER2			178
+#define CLK_TIMER3			179
+#define CLK_TIMER4			180
+#define CLK_TIMER5			181
+#define PCLK_MAILBOX0			182
+#define PCLK_GPIO1			183
+#define DBCLK_GPIO1			184
+#define PCLK_GPIO2			185
+#define DBCLK_GPIO2			186
+#define PCLK_GPIO3			187
+#define DBCLK_GPIO3			188
+#define PCLK_GPIO4			189
+#define DBCLK_GPIO4			190
+#define ACLK_DECOM			191
+#define PCLK_DECOM			192
+#define DCLK_DECOM			193
+#define CLK_TIMER1_ROOT			194
+#define CLK_TIMER6			195
+#define CLK_TIMER7			196
+#define CLK_TIMER8			197
+#define CLK_TIMER9			198
+#define CLK_TIMER10			199
+#define CLK_TIMER11			200
+#define ACLK_DMAC0			201
+#define ACLK_DMAC1			202
+#define ACLK_DMAC2			203
+#define ACLK_SPINLOCK			204
+#define HCLK_I3C0			205
+#define HCLK_I3C1			206
+#define HCLK_BUS_CM0_ROOT		207
+#define FCLK_BUS_CM0_CORE		208
+#define CLK_BUS_CM0_RTC			209
+#define PCLK_PMU2			210
+#define PCLK_PWM2			211
+#define CLK_PWM2			212
+#define CLK_RC_PWM2			213
+#define CLK_OSC_PWM2			214
+#define CLK_FREQ_PWM1			215
+#define CLK_COUNTER_PWM1		216
+#define SAI_SCLKIN_FREQ			217
+#define SAI_SCLKIN_COUNTER		218
+#define CLK_I3C0			219
+#define CLK_I3C1			220
+#define PCLK_CSIDPHY1			221
+#define PCLK_DDR_ROOT			222
+#define PCLK_DDR_MON_CH0		223
+#define TMCLK_DDR_MON_CH0		224
+#define ACLK_DDR_ROOT			225
+#define HCLK_DDR_ROOT			226
+#define FCLK_DDR_CM0_CORE		227
+#define CLK_DDR_TIMER_ROOT		228
+#define CLK_DDR_TIMER0			229
+#define CLK_DDR_TIMER1			230
+#define TCLK_WDT_DDR			231
+#define PCLK_WDT			232
+#define PCLK_TIMER			233
+#define CLK_DDR_CM0_RTC			234
+#define ACLK_RKNN0			235
+#define ACLK_RKNN1			236
+#define HCLK_RKNN_ROOT			237
+#define CLK_RKNN_DSU0			238
+#define PCLK_NPUTOP_ROOT		239
+#define PCLK_NPU_TIMER			240
+#define CLK_NPUTIMER_ROOT		241
+#define CLK_NPUTIMER0			242
+#define CLK_NPUTIMER1			243
+#define PCLK_NPU_WDT			244
+#define TCLK_NPU_WDT			245
+#define ACLK_RKNN_CBUF			246
+#define HCLK_NPU_CM0_ROOT		247
+#define FCLK_NPU_CM0_CORE		248
+#define CLK_NPU_CM0_RTC			249
+#define HCLK_RKNN_CBUF			250
+#define HCLK_NVM_ROOT			251
+#define ACLK_NVM_ROOT			252
+#define SCLK_FSPI_X2			253
+#define HCLK_FSPI			254
+#define CCLK_SRC_EMMC			255
+#define HCLK_EMMC			256
+#define ACLK_EMMC			257
+#define BCLK_EMMC			258
+#define TCLK_EMMC			259
+#define PCLK_PHP_ROOT			260
+#define ACLK_PHP_ROOT			261
+#define PCLK_PCIE0			262
+#define CLK_PCIE0_AUX			263
+#define ACLK_PCIE0_MST			264
+#define ACLK_PCIE0_SLV			265
+#define ACLK_PCIE0_DBI			266
+#define ACLK_USB3OTG1			267
+#define CLK_REF_USB3OTG1		268
+#define CLK_SUSPEND_USB3OTG1		269
+#define ACLK_MMU0			270
+#define ACLK_SLV_MMU0			271
+#define ACLK_MMU1			272
+#define ACLK_SLV_MMU1			273
+#define PCLK_PCIE1			275
+#define CLK_PCIE1_AUX			276
+#define ACLK_PCIE1_MST			277
+#define ACLK_PCIE1_SLV			278
+#define ACLK_PCIE1_DBI			279
+#define CLK_RXOOB0			280
+#define CLK_RXOOB1			281
+#define CLK_PMALIVE0			282
+#define CLK_PMALIVE1			283
+#define ACLK_SATA0			284
+#define ACLK_SATA1			285
+#define CLK_USB3OTG1_PIPE_PCLK		286
+#define CLK_USB3OTG1_UTMI		287
+#define CLK_USB3OTG0_PIPE_PCLK		288
+#define CLK_USB3OTG0_UTMI		289
+#define HCLK_SDGMAC_ROOT		290
+#define ACLK_SDGMAC_ROOT		291
+#define PCLK_SDGMAC_ROOT		292
+#define ACLK_GMAC0			293
+#define ACLK_GMAC1			294
+#define PCLK_GMAC0			295
+#define PCLK_GMAC1			296
+#define CCLK_SRC_SDIO			297
+#define HCLK_SDIO			298
+#define CLK_GMAC1_PTP_REF		299
+#define CLK_GMAC0_PTP_REF		300
+#define CLK_GMAC1_PTP_REF_SRC		301
+#define CLK_GMAC0_PTP_REF_SRC		302
+#define CCLK_SRC_SDMMC0			303
+#define HCLK_SDMMC0			304
+#define SCLK_FSPI1_X2			305
+#define HCLK_FSPI1			306
+#define ACLK_DSMC_ROOT			307
+#define ACLK_DSMC			308
+#define PCLK_DSMC			309
+#define CLK_DSMC_SYS			310
+#define HCLK_HSGPIO			311
+#define CLK_HSGPIO_TX			312
+#define CLK_HSGPIO_RX			313
+#define ACLK_HSGPIO			314
+#define PCLK_PHPPHY_ROOT		315
+#define PCLK_PCIE2_COMBOPHY0		316
+#define PCLK_PCIE2_COMBOPHY1		317
+#define CLK_PCIE_100M_SRC		318
+#define CLK_PCIE_100M_NDUTY_SRC		319
+#define CLK_REF_PCIE0_PHY		320
+#define CLK_REF_PCIE1_PHY		321
+#define CLK_REF_MPHY_26M		322
+#define HCLK_RKVDEC_ROOT		323
+#define ACLK_RKVDEC_ROOT		324
+#define HCLK_RKVDEC			325
+#define CLK_RKVDEC_HEVC_CA		326
+#define CLK_RKVDEC_CORE			327
+#define ACLK_UFS_ROOT			328
+#define ACLK_USB_ROOT			329
+#define PCLK_USB_ROOT			330
+#define ACLK_USB3OTG0			331
+#define CLK_REF_USB3OTG0		332
+#define CLK_SUSPEND_USB3OTG0		333
+#define ACLK_MMU2			334
+#define ACLK_SLV_MMU2			335
+#define ACLK_UFS_SYS			336
+#define ACLK_VPU_ROOT			337
+#define ACLK_VPU_MID_ROOT		338
+#define HCLK_VPU_ROOT			339
+#define ACLK_JPEG_ROOT			340
+#define ACLK_VPU_LOW_ROOT		341
+#define HCLK_RGA2E_0			342
+#define ACLK_RGA2E_0			342
+#define CLK_CORE_RGA2E_0		344
+#define ACLK_JPEG			345
+#define HCLK_JPEG			346
+#define HCLK_VDPP			347
+#define ACLK_VDPP			348
+#define CLK_CORE_VDPP			349
+#define HCLK_RGA2E_1			350
+#define ACLK_RGA2E_1			351
+#define CLK_CORE_RGA2E_1		352
+#define DCLK_EBC_FRAC_SRC		353
+#define HCLK_EBC			354
+#define ACLK_EBC			355
+#define DCLK_EBC			356
+#define HCLK_VEPU0_ROOT			357
+#define ACLK_VEPU0_ROOT			358
+#define HCLK_VEPU0			359
+#define ACLK_VEPU0			360
+#define CLK_VEPU0_CORE			361
+#define ACLK_VI_ROOT			362
+#define HCLK_VI_ROOT			363
+#define PCLK_VI_ROOT			364
+#define DCLK_VICAP			365
+#define ACLK_VICAP			366
+#define HCLK_VICAP			367
+#define CLK_ISP_CORE			368
+#define CLK_ISP_CORE_MARVIN		369
+#define CLK_ISP_CORE_VICAP		370
+#define ACLK_ISP			371
+#define HCLK_ISP			372
+#define ACLK_VPSS			373
+#define HCLK_VPSS			374
+#define CLK_CORE_VPSS			375
+#define PCLK_CSI_HOST_0			376
+#define PCLK_CSI_HOST_1			377
+#define PCLK_CSI_HOST_2			378
+#define PCLK_CSI_HOST_3			379
+#define PCLK_CSI_HOST_4			380
+#define ICLK_CSIHOST01			381
+#define ICLK_CSIHOST0			382
+#define CLK_ISP_PVTPLL_SRC		383
+#define ACLK_VI_ROOT_INTER		384
+#define CLK_VICAP_I0CLK			385
+#define CLK_VICAP_I1CLK			386
+#define CLK_VICAP_I2CLK			387
+#define CLK_VICAP_I3CLK			388
+#define CLK_VICAP_I4CLK			389
+#define ACLK_VOP_ROOT			390
+#define HCLK_VOP_ROOT			391
+#define PCLK_VOP_ROOT			392
+#define HCLK_VOP			393
+#define ACLK_VOP			394
+#define DCLK_VP0_SRC			395
+#define DCLK_VP1_SRC			396
+#define DCLK_VP2_SRC			397
+#define DCLK_VP0			398
+#define DCLK_VP1			400
+#define DCLK_VP2			401
+#define PCLK_VOPGRF			402
+#define ACLK_VO0_ROOT			403
+#define HCLK_VO0_ROOT			404
+#define PCLK_VO0_ROOT			405
+#define PCLK_VO0_GRF			406
+#define ACLK_HDCP0			407
+#define HCLK_HDCP0			408
+#define PCLK_HDCP0			409
+#define CLK_TRNG0_SKP			410
+#define PCLK_DSIHOST0			411
+#define CLK_DSIHOST0			412
+#define PCLK_HDMITX0			413
+#define CLK_HDMITX0_EARC		414
+#define CLK_HDMITX0_REF			415
+#define PCLK_EDP0			416
+#define CLK_EDP0_24M			417
+#define CLK_EDP0_200M			418
+#define MCLK_SAI5_8CH_SRC		419
+#define MCLK_SAI5_8CH			420
+#define HCLK_SAI5_8CH			421
+#define MCLK_SAI6_8CH_SRC		422
+#define MCLK_SAI6_8CH			423
+#define HCLK_SAI6_8CH			424
+#define HCLK_SPDIF_TX2			425
+#define MCLK_SPDIF_TX2			426
+#define HCLK_SPDIF_RX2			427
+#define MCLK_SPDIF_RX2			428
+#define HCLK_SAI8_8CH			429
+#define MCLK_SAI8_8CH_SRC		430
+#define MCLK_SAI8_8CH			431
+#define ACLK_VO1_ROOT			432
+#define HCLK_VO1_ROOT			433
+#define PCLK_VO1_ROOT			434
+#define MCLK_SAI7_8CH_SRC		435
+#define MCLK_SAI7_8CH			436
+#define HCLK_SAI7_8CH			437
+#define HCLK_SPDIF_TX3			438
+#define HCLK_SPDIF_TX4			439
+#define HCLK_SPDIF_TX5			440
+#define MCLK_SPDIF_TX3			441
+#define CLK_AUX16MHZ_0			442
+#define ACLK_DP0			443
+#define PCLK_DP0			444
+#define PCLK_VO1_GRF			445
+#define ACLK_HDCP1			446
+#define HCLK_HDCP1			447
+#define PCLK_HDCP1			448
+#define CLK_TRNG1_SKP			449
+#define HCLK_SAI9_8CH			450
+#define MCLK_SAI9_8CH_SRC		451
+#define MCLK_SAI9_8CH			452
+#define MCLK_SPDIF_TX4			453
+#define MCLK_SPDIF_TX5			454
+#define CLK_GPU_SRC_PRE			455
+#define CLK_GPU				456
+#define PCLK_GPU_ROOT			457
+#define ACLK_CENTER_ROOT		458
+#define ACLK_CENTER_LOW_ROOT		459
+#define HCLK_CENTER_ROOT		460
+#define PCLK_CENTER_ROOT		461
+#define ACLK_DMA2DDR			462
+#define ACLK_DDR_SHAREMEM		463
+#define PCLK_DMA2DDR			464
+#define PCLK_SHAREMEM			465
+#define HCLK_VEPU1_ROOT			466
+#define ACLK_VEPU1_ROOT			467
+#define HCLK_VEPU1			468
+#define ACLK_VEPU1			469
+#define CLK_VEPU1_CORE			470
+#define CLK_JDBCK_DAP			471
+#define PCLK_MIPI_DCPHY			472
+#define CLK_32K_USB2DEBUG		473
+#define PCLK_CSIDPHY			474
+#define PCLK_USBDPPHY			475
+#define CLK_PMUPHY_REF_SRC		476
+#define CLK_USBDP_COMBO_PHY_IMMORTAL	477
+#define CLK_HDMITXHPD			478
+#define PCLK_MPHY			479
+#define CLK_REF_OSC_MPHY		480
+#define CLK_REF_UFS_CLKOUT		481
+#define HCLK_PMU1_ROOT			482
+#define HCLK_PMU_CM0_ROOT		483
+#define CLK_200M_PMU_SRC		484
+#define CLK_100M_PMU_SRC		485
+#define CLK_50M_PMU_SRC			486
+#define FCLK_PMU_CM0_CORE		487
+#define CLK_PMU_CM0_RTC			488
+#define PCLK_PMU1			489
+#define CLK_PMU1			490
+#define PCLK_PMU1WDT			491
+#define TCLK_PMU1WDT			492
+#define PCLK_PMUTIMER			493
+#define CLK_PMUTIMER_ROOT		494
+#define CLK_PMUTIMER0			495
+#define CLK_PMUTIMER1			496
+#define PCLK_PMU1PWM			497
+#define CLK_PMU1PWM			498
+#define CLK_PMU1PWM_OSC			499
+#define PCLK_PMUPHY_ROOT		500
+#define PCLK_I2C0			501
+#define CLK_I2C0			502
+#define SCLK_UART1			503
+#define PCLK_UART1			504
+#define CLK_PMU1PWM_RC			505
+#define CLK_PDM0			506
+#define HCLK_PDM0			507
+#define MCLK_PDM0			508
+#define HCLK_VAD			509
+#define CLK_OSCCHK_PVTM			510
+#define CLK_PDM0_OUT			511
+#define CLK_HPTIMER_SRC			512
+#define PCLK_PMU0_ROOT			516
+#define PCLK_PMU0			517
+#define PCLK_GPIO0			518
+#define DBCLK_GPIO0			519
+#define CLK_OSC0_PMU1			520
+#define PCLK_PMU1_ROOT			521
+#define XIN_OSC0_DIV			522
+#define ACLK_USB			523
+#define ACLK_UFS			524
+#define ACLK_SDGMAC			525
+#define HCLK_SDGMAC			526
+#define PCLK_SDGMAC			527
+#define HCLK_VO1			528
+#define HCLK_VO0			529
+#define PCLK_CCI_ROOT			532
+#define ACLK_CCI_ROOT			533
+#define HCLK_VO0VOP_CHANNEL		534
+#define ACLK_VO0VOP_CHANNEL		535
+#define ACLK_TOP_MID			536
+#define ACLK_SECURE_HIGH		537
+#define CLK_USBPHY_REF_SRC		538
+#define CLK_PHY_REF_SRC			539
+#define CLK_CPLL_REF_SRC		540
+#define CLK_AUPLL_REF_SRC		541
+#define PCLK_SECURE_NS			542
+#define HCLK_SECURE_NS			543
+#define ACLK_SECURE_NS			544
+#define PCLK_OTPC_NS			545
+#define HCLK_CRYPTO_NS			546
+#define HCLK_TRNG_NS			547
+#define CLK_OTPC_NS			548
+#define SCLK_DSU			549
+#define SCLK_DDR			550
+#define ACLK_CRYPTO_NS			551
+#define CLK_PKA_CRYPTO_NS		552
+
+/* secure clk */
+#define CLK_STIMER0_ROOT		600
+#define CLK_STIMER1_ROOT		601
+#define PCLK_SECURE_S			602
+#define HCLK_SECURE_S			603
+#define ACLK_SECURE_S			604
+#define CLK_PKA_CRYPTO_S		605
+#define HCLK_VO1_S			606
+#define PCLK_VO1_S			607
+#define HCLK_VO0_S			608
+#define PCLK_VO0_S			609
+#define PCLK_KLAD			610
+#define HCLK_CRYPTO_S			611
+#define HCLK_KLAD			612
+#define ACLK_CRYPTO_S			613
+#define HCLK_TRNG_S			614
+#define PCLK_OTPC_S			615
+#define CLK_OTPC_S			616
+#define PCLK_WDT_S			617
+#define TCLK_WDT_S			618
+#define PCLK_HDCP0_TRNG			619
+#define PCLK_HDCP1_TRNG			620
+#define HCLK_HDCP_KEY0			621
+#define HCLK_HDCP_KEY1			622
+#define PCLK_EDP_S			623
+#define ACLK_KLAD			624
+
+#define CLK_NR_CLKS			(ACLK_KLAD + 1)
+
+/********Name=SOFTRST_CON01,Offset=0xA04********/
+#define SRST_A_TOP_BIU			19
+#define SRST_P_TOP_BIU			21
+#define SRST_A_TOP_MID_BIU		22
+#define SRST_A_SECURE_HIGH_BIU		23
+#define SRST_H_TOP_BIU			30
+/********Name=SOFTRST_CON02,Offset=0xA08********/
+#define SRST_H_VO0VOP_CHANNEL_BIU	32
+#define SRST_A_VO0VOP_CHANNEL_BIU	33
+/********Name=SOFTRST_CON06,Offset=0xA18********/
+#define SRST_BISRINTF			98
+/********Name=SOFTRST_CON07,Offset=0xA1C********/
+#define SRST_H_AUDIO_BIU		114
+#define SRST_H_ASRC_2CH_0		115
+#define SRST_H_ASRC_2CH_1		116
+#define SRST_H_ASRC_4CH_0		117
+#define SRST_H_ASRC_4CH_1		118
+#define SRST_ASRC_2CH_0			119
+#define SRST_ASRC_2CH_1			120
+#define SRST_ASRC_4CH_0			121
+#define SRST_ASRC_4CH_1			122
+#define SRST_M_SAI0_8CH			124
+#define SRST_H_SAI0_8CH			125
+#define SRST_H_SPDIF_RX0		126
+#define SRST_M_SPDIF_RX0		127
+/********Name=SOFTRST_CON08,Offset=0xA20********/
+#define SRST_H_SPDIF_RX1		128
+#define SRST_M_SPDIF_RX1		129
+#define SRST_M_SAI1_8CH			133
+#define SRST_H_SAI1_8CH			134
+#define SRST_M_SAI2_2CH			136
+#define SRST_H_SAI2_2CH			138
+#define SRST_M_SAI3_2CH			140
+#define SRST_H_SAI3_2CH			142
+/********Name=SOFTRST_CON09,Offset=0xA24********/
+#define SRST_M_SAI4_2CH			144
+#define SRST_H_SAI4_2CH			146
+#define SRST_H_ACDCDIG_DSM		147
+#define SRST_M_ACDCDIG_DSM		148
+#define SRST_PDM1			149
+#define SRST_H_PDM1			151
+#define SRST_M_PDM1			152
+#define SRST_H_SPDIF_TX0		153
+#define SRST_M_SPDIF_TX0		154
+#define SRST_H_SPDIF_TX1		155
+#define SRST_M_SPDIF_TX1		156
+/********Name=SOFTRST_CON11,Offset=0xA2C********/
+#define SRST_A_BUS_BIU			179
+#define SRST_P_BUS_BIU			180
+#define SRST_P_CRU			181
+#define SRST_H_CAN0			182
+#define SRST_CAN0			183
+#define SRST_H_CAN1			184
+#define SRST_CAN1			185
+#define SRST_P_INTMUX2BUS		188
+#define SRST_P_VCCIO_IOC		189
+#define SRST_H_BUS_BIU			190
+#define SRST_KEY_SHIFT			191
+/********Name=SOFTRST_CON12,Offset=0xA30********/
+#define SRST_P_I2C1			192
+#define SRST_P_I2C2			193
+#define SRST_P_I2C3			194
+#define SRST_P_I2C4			195
+#define SRST_P_I2C5			196
+#define SRST_P_I2C6			197
+#define SRST_P_I2C7			198
+#define SRST_P_I2C8			199
+#define SRST_P_I2C9			200
+#define SRST_P_WDT_BUSMCU		201
+#define SRST_T_WDT_BUSMCU		202
+#define SRST_A_GIC			203
+#define SRST_I2C1			204
+#define SRST_I2C2			205
+#define SRST_I2C3			206
+#define SRST_I2C4			207
+/********Name=SOFTRST_CON13,Offset=0xA34********/
+#define SRST_I2C5			208
+#define SRST_I2C6			209
+#define SRST_I2C7			210
+#define SRST_I2C8			211
+#define SRST_I2C9			212
+#define SRST_P_SARADC			214
+#define SRST_SARADC			215
+#define SRST_P_TSADC			216
+#define SRST_TSADC			217
+#define SRST_P_UART0			218
+#define SRST_P_UART2			219
+#define SRST_P_UART3			220
+#define SRST_P_UART4			221
+#define SRST_P_UART5			222
+#define SRST_P_UART6			223
+/********Name=SOFTRST_CON14,Offset=0xA38********/
+#define SRST_P_UART7			224
+#define SRST_P_UART8			225
+#define SRST_P_UART9			226
+#define SRST_P_UART10			227
+#define SRST_P_UART11			228
+#define SRST_S_UART0			229
+#define SRST_S_UART2			230
+#define SRST_S_UART3			233
+#define SRST_S_UART4			236
+#define SRST_S_UART5			239
+/********Name=SOFTRST_CON15,Offset=0xA3C********/
+#define SRST_S_UART6			242
+#define SRST_S_UART7			245
+#define SRST_S_UART8			248
+#define SRST_S_UART9			249
+#define SRST_S_UART10			250
+#define SRST_S_UART11			251
+#define SRST_P_SPI0			253
+#define SRST_P_SPI1			254
+#define SRST_P_SPI2			255
+/********Name=SOFTRST_CON16,Offset=0xA40********/
+#define SRST_P_SPI3			256
+#define SRST_P_SPI4			257
+#define SRST_SPI0			258
+#define SRST_SPI1			259
+#define SRST_SPI2			260
+#define SRST_SPI3			261
+#define SRST_SPI4			262
+#define SRST_P_WDT0			263
+#define SRST_T_WDT0			264
+#define SRST_P_SYS_GRF			265
+#define SRST_P_PWM1			266
+#define SRST_PWM1			267
+
+/********Name=SOFTRST_CON17,Offset=0xA44********/
+#define SRST_P_BUSTIMER0		275
+#define SRST_P_BUSTIMER1		276
+#define SRST_TIMER0			278
+#define SRST_TIMER1			279
+#define SRST_TIMER2			280
+#define SRST_TIMER3			281
+#define SRST_TIMER4			282
+#define SRST_TIMER5			283
+#define SRST_P_BUSIOC			284
+#define SRST_P_MAILBOX0			285
+#define SRST_P_GPIO1			287
+/********Name=SOFTRST_CON18,Offset=0xA48********/
+#define SRST_GPIO1			288
+#define SRST_P_GPIO2			289
+#define SRST_GPIO2			290
+#define SRST_P_GPIO3			291
+#define SRST_GPIO3			292
+#define SRST_P_GPIO4			293
+#define SRST_GPIO4			294
+#define SRST_A_DECOM			295
+#define SRST_P_DECOM			296
+#define SRST_D_DECOM			297
+#define SRST_TIMER6			299
+#define SRST_TIMER7			300
+#define SRST_TIMER8			301
+#define SRST_TIMER9			302
+#define SRST_TIMER10			303
+/********Name=SOFTRST_CON19,Offset=0xA4C********/
+#define SRST_TIMER11			304
+#define SRST_A_DMAC0			305
+#define SRST_A_DMAC1			306
+#define SRST_A_DMAC2			307
+#define SRST_A_SPINLOCK			308
+#define SRST_REF_PVTPLL_BUS		309
+#define SRST_H_I3C0			311
+#define SRST_H_I3C1			313
+#define SRST_H_BUS_CM0_BIU		315
+#define SRST_F_BUS_CM0_CORE		316
+#define SRST_T_BUS_CM0_JTAG		317
+/********Name=SOFTRST_CON20,Offset=0xA50********/
+#define SRST_P_INTMUX2PMU		320
+#define SRST_P_INTMUX2DDR		321
+#define SRST_P_PVTPLL_BUS		323
+#define SRST_P_PWM2			324
+#define SRST_PWM2			325
+#define SRST_FREQ_PWM1			328
+#define SRST_COUNTER_PWM1		329
+#define SRST_I3C0			332
+#define SRST_I3C1			333
+/********Name=SOFTRST_CON21,Offset=0xA54********/
+#define SRST_P_DDR_MON_CH0		337
+#define SRST_P_DDR_BIU			338
+#define SRST_P_DDR_UPCTL_CH0		339
+#define SRST_TM_DDR_MON_CH0		340
+#define SRST_A_DDR_BIU			341
+#define SRST_DFI_CH0			342
+#define SRST_DDR_MON_CH0		346
+#define SRST_P_DDR_HWLP_CH0		349
+#define SRST_P_DDR_MON_CH1		350
+#define SRST_P_DDR_HWLP_CH1		351
+/********Name=SOFTRST_CON22,Offset=0xA58********/
+#define SRST_P_DDR_UPCTL_CH1		352
+#define SRST_TM_DDR_MON_CH1		353
+#define SRST_DFI_CH1			354
+#define SRST_A_DDR01_MSCH0		355
+#define SRST_A_DDR01_MSCH1		356
+#define SRST_DDR_MON_CH1		358
+#define SRST_DDR_SCRAMBLE_CH0		361
+#define SRST_DDR_SCRAMBLE_CH1		362
+#define SRST_P_AHB2APB			364
+#define SRST_H_AHB2APB			365
+#define SRST_H_DDR_BIU			366
+#define SRST_F_DDR_CM0_CORE		367
+/********Name=SOFTRST_CON23,Offset=0xA5C********/
+#define SRST_P_DDR01_MSCH0		369
+#define SRST_P_DDR01_MSCH1		370
+#define SRST_DDR_TIMER0			372
+#define SRST_DDR_TIMER1			373
+#define SRST_T_WDT_DDR			374
+#define SRST_P_WDT			375
+#define SRST_P_TIMER			376
+#define SRST_T_DDR_CM0_JTAG		377
+#define SRST_P_DDR_GRF			379
+/********Name=SOFTRST_CON25,Offset=0xA64********/
+#define SRST_DDR_UPCTL_CH0		401
+#define SRST_A_DDR_UPCTL_0_CH0		402
+#define SRST_A_DDR_UPCTL_1_CH0		403
+#define SRST_A_DDR_UPCTL_2_CH0		404
+#define SRST_A_DDR_UPCTL_3_CH0		405
+#define SRST_A_DDR_UPCTL_4_CH0		406
+/********Name=SOFTRST_CON26,Offset=0xA68********/
+#define SRST_DDR_UPCTL_CH1		417
+#define SRST_A_DDR_UPCTL_0_CH1		418
+#define SRST_A_DDR_UPCTL_1_CH1		419
+#define SRST_A_DDR_UPCTL_2_CH1		420
+#define SRST_A_DDR_UPCTL_3_CH1		421
+#define SRST_A_DDR_UPCTL_4_CH1		422
+/********Name=SOFTRST_CON27,Offset=0xA6C********/
+#define SRST_REF_PVTPLL_DDR		432
+#define SRST_P_PVTPLL_DDR		433
+
+/********Name=SOFTRST_CON28,Offset=0xA70********/
+#define SRST_A_RKNN0			457
+#define SRST_A_RKNN0_BIU		459
+#define SRST_L_RKNN0_BIU		460
+/********Name=SOFTRST_CON29,Offset=0xA74********/
+#define SRST_A_RKNN1			464
+#define SRST_A_RKNN1_BIU		466
+#define SRST_L_RKNN1_BIU		467
+/********Name=SOFTRST_CON31,Offset=0xA7C********/
+#define SRST_NPU_DAP			496
+#define SRST_L_NPUSUBSYS_BIU		497
+#define SRST_P_NPUTOP_BIU		505
+#define SRST_P_NPU_TIMER		506
+#define SRST_NPUTIMER0			508
+#define SRST_NPUTIMER1			509
+#define SRST_P_NPU_WDT			510
+#define SRST_T_NPU_WDT			511
+/********Name=SOFTRST_CON32,Offset=0xA80********/
+#define SRST_A_RKNN_CBUF		512
+#define SRST_A_RVCORE0			513
+#define SRST_P_NPU_GRF			514
+#define SRST_P_PVTPLL_NPU		515
+#define SRST_NPU_PVTPLL			516
+#define SRST_H_NPU_CM0_BIU		518
+#define SRST_F_NPU_CM0_CORE		519
+#define SRST_T_NPU_CM0_JTAG		520
+#define SRST_A_RKNNTOP_BIU		523
+#define SRST_H_RKNN_CBUF		524
+#define SRST_H_RKNNTOP_BIU		525
+/********Name=SOFTRST_CON33,Offset=0xA84********/
+#define SRST_H_NVM_BIU			530
+#define SRST_A_NVM_BIU			531
+#define SRST_S_FSPI			534
+#define SRST_H_FSPI			535
+#define SRST_C_EMMC			536
+#define SRST_H_EMMC			537
+#define SRST_A_EMMC			538
+#define SRST_B_EMMC			539
+#define SRST_T_EMMC			540
+/********Name=SOFTRST_CON34,Offset=0xA88********/
+#define SRST_P_GRF			545
+#define SRST_P_PHP_BIU			549
+#define SRST_A_PHP_BIU			553
+#define SRST_P_PCIE0			557
+#define SRST_PCIE0_POWER_UP		559
+/********Name=SOFTRST_CON35,Offset=0xA8C********/
+#define SRST_A_USB3OTG1			563
+#define SRST_A_MMU0			571
+#define SRST_A_SLV_MMU0			573
+#define SRST_A_MMU1			574
+/********Name=SOFTRST_CON36,Offset=0xA90********/
+#define SRST_A_SLV_MMU1			576
+#define SRST_P_PCIE1			583
+#define SRST_PCIE1_POWER_UP		585
+/********Name=SOFTRST_CON37,Offset=0xA94********/
+#define SRST_RXOOB0			592
+#define SRST_RXOOB1			593
+#define SRST_PMALIVE0			594
+#define SRST_PMALIVE1			595
+#define SRST_A_SATA0			596
+#define SRST_A_SATA1			597
+#define SRST_ASIC1			598
+#define SRST_ASIC0			599
+/********Name=SOFTRST_CON40,Offset=0xAA0********/
+#define SRST_P_CSIDPHY1			642
+#define SRST_SCAN_CSIDPHY1		643
+/********Name=SOFTRST_CON42,Offset=0xAA8********/
+#define SRST_P_SDGMAC_GRF		675
+#define SRST_P_SDGMAC_BIU		676
+#define SRST_A_SDGMAC_BIU		677
+#define SRST_H_SDGMAC_BIU		678
+#define SRST_A_GMAC0			679
+#define SRST_A_GMAC1			680
+#define SRST_P_GMAC0			681
+#define SRST_P_GMAC1			682
+#define SRST_H_SDIO			684
+/********Name=SOFTRST_CON43,Offset=0xAAC********/
+#define SRST_H_SDMMC0			690
+#define SRST_S_FSPI1			691
+#define SRST_H_FSPI1			692
+#define SRST_A_DSMC_BIU			694
+#define SRST_A_DSMC			695
+#define SRST_P_DSMC			696
+#define SRST_H_HSGPIO			698
+#define SRST_HSGPIO			699
+#define SRST_A_HSGPIO			701
+/********Name=SOFTRST_CON45,Offset=0xAB4********/
+#define SRST_H_RKVDEC			723
+#define SRST_H_RKVDEC_BIU		725
+#define SRST_A_RKVDEC_BIU		726
+#define SRST_RKVDEC_HEVC_CA		728
+#define SRST_RKVDEC_CORE		729
+/********Name=SOFTRST_CON47,Offset=0xABC********/
+#define SRST_A_USB_BIU			755
+#define SRST_P_USBUFS_BIU		756
+#define SRST_A_USB3OTG0			757
+#define SRST_A_UFS_BIU			762
+#define SRST_A_MMU2			764
+#define SRST_A_SLV_MMU2			765
+#define SRST_A_UFS_SYS			767
+/********Name=SOFTRST_CON48,Offset=0xAC0********/
+#define SRST_A_UFS			768
+#define SRST_P_USBUFS_GRF		769
+#define SRST_P_UFS_GRF			770
+/********Name=SOFTRST_CON49,Offset=0xAC4********/
+#define SRST_H_VPU_BIU			790
+#define SRST_A_JPEG_BIU			791
+#define SRST_A_RGA_BIU			794
+#define SRST_A_VDPP_BIU			795
+#define SRST_A_EBC_BIU			796
+#define SRST_H_RGA2E_0			797
+#define SRST_A_RGA2E_0			798
+#define SRST_CORE_RGA2E_0		799
+/********Name=SOFTRST_CON50,Offset=0xAC8********/
+#define SRST_A_JPEG			800
+#define SRST_H_JPEG			801
+#define SRST_H_VDPP			802
+#define SRST_A_VDPP			803
+#define SRST_CORE_VDPP			804
+#define SRST_H_RGA2E_1			805
+#define SRST_A_RGA2E_1			806
+#define SRST_CORE_RGA2E_1		807
+#define SRST_H_EBC			810
+#define SRST_A_EBC			811
+#define SRST_D_EBC			812
+/********Name=SOFTRST_CON51,Offset=0xACC********/
+#define SRST_H_VEPU0_BIU		818
+#define SRST_A_VEPU0_BIU		819
+#define SRST_H_VEPU0			820
+#define SRST_A_VEPU0			821
+#define SRST_VEPU0_CORE			822
+/********Name=SOFTRST_CON53,Offset=0xAD4********/
+#define SRST_A_VI_BIU			851
+#define SRST_H_VI_BIU			852
+#define SRST_P_VI_BIU			853
+#define SRST_D_VICAP			854
+#define SRST_A_VICAP			855
+#define SRST_H_VICAP			856
+#define SRST_ISP0			858
+#define SRST_ISP0_VICAP			859
+/********Name=SOFTRST_CON54,Offset=0xAD8********/
+#define SRST_CORE_VPSS			865
+#define SRST_P_CSI_HOST_0		868
+#define SRST_P_CSI_HOST_1		869
+#define SRST_P_CSI_HOST_2		870
+#define SRST_P_CSI_HOST_3		871
+#define SRST_P_CSI_HOST_4		872
+/********Name=SOFTRST_CON59,Offset=0xAEC********/
+#define SRST_CIFIN			944
+#define SRST_VICAP_I0CLK		945
+#define SRST_VICAP_I1CLK		946
+#define SRST_VICAP_I2CLK		947
+#define SRST_VICAP_I3CLK		948
+#define SRST_VICAP_I4CLK		949
+/********Name=SOFTRST_CON61,Offset=0xAF4********/
+#define SRST_A_VOP_BIU			980
+#define SRST_A_VOP2_BIU			981
+#define SRST_H_VOP_BIU			982
+#define SRST_P_VOP_BIU			983
+#define SRST_H_VOP			984
+#define SRST_A_VOP			985
+#define SRST_D_VP0			989
+/********Name=SOFTRST_CON62,Offset=0xAF8********/
+#define SRST_D_VP1			992
+#define SRST_D_VP2			993
+#define SRST_P_VOP2_BIU			994
+#define SRST_P_VOPGRF			995
+/********Name=SOFTRST_CON63,Offset=0xAFC********/
+#define SRST_H_VO0_BIU			1013
+#define SRST_P_VO0_BIU			1015
+#define SRST_A_HDCP0_BIU		1017
+#define SRST_P_VO0_GRF			1018
+#define SRST_A_HDCP0			1020
+#define SRST_H_HDCP0			1021
+#define SRST_HDCP0			1022
+/********Name=SOFTRST_CON64,Offset=0xB00********/
+#define SRST_P_DSIHOST0			1029
+#define SRST_DSIHOST0			1030
+#define SRST_P_HDMITX0			1031
+#define SRST_HDMITX0_REF		1033
+#define SRST_P_EDP0			1037
+#define SRST_EDP0_24M			1038
+/********Name=SOFTRST_CON65,Offset=0xB04********/
+#define SRST_M_SAI5_8CH			1044
+#define SRST_H_SAI5_8CH			1045
+#define SRST_M_SAI6_8CH			1048
+#define SRST_H_SAI6_8CH			1049
+#define SRST_H_SPDIF_TX2		1050
+#define SRST_M_SPDIF_TX2		1053
+#define SRST_H_SPDIF_RX2		1054
+#define SRST_M_SPDIF_RX2		1055
+/********Name=SOFTRST_CON66,Offset=0xB08********/
+#define SRST_H_SAI8_8CH			1056
+#define SRST_M_SAI8_8CH			1058
+/********Name=SOFTRST_CON67,Offset=0xB0C********/
+#define SRST_H_VO1_BIU			1077
+#define SRST_P_VO1_BIU			1078
+#define SRST_M_SAI7_8CH			1081
+#define SRST_H_SAI7_8CH			1082
+#define SRST_H_SPDIF_TX3		1083
+#define SRST_H_SPDIF_TX4		1084
+#define SRST_H_SPDIF_TX5		1085
+#define SRST_M_SPDIF_TX3		1086
+/********Name=SOFTRST_CON68,Offset=0xB10********/
+#define SRST_DP0			1088
+#define SRST_P_VO1_GRF			1090
+#define SRST_A_HDCP1_BIU		1091
+#define SRST_A_HDCP1			1092
+#define SRST_H_HDCP1			1093
+#define SRST_HDCP1			1094
+#define SRST_H_SAI9_8CH			1097
+#define SRST_M_SAI9_8CH			1099
+#define SRST_M_SPDIF_TX4		1100
+#define SRST_M_SPDIF_TX5		1101
+/********Name=SOFTRST_CON69,Offset=0xB14********/
+#define SRST_GPU			1107
+#define SRST_A_S_GPU_BIU		1110
+#define SRST_A_M0_GPU_BIU		1111
+#define SRST_P_GPU_BIU			1113
+#define SRST_P_GPU_GRF			1117
+#define SRST_GPU_PVTPLL			1118
+#define SRST_P_PVTPLL_GPU		1119
+/********Name=SOFTRST_CON72,Offset=0xB20********/
+#define SRST_A_CENTER_BIU		1156
+#define SRST_A_DMA2DDR			1157
+#define SRST_A_DDR_SHAREMEM		1158
+#define SRST_A_DDR_SHAREMEM_BIU		1159
+#define SRST_H_CENTER_BIU		1160
+#define SRST_P_CENTER_GRF		1161
+#define SRST_P_DMA2DDR			1162
+#define SRST_P_SHAREMEM			1163
+#define SRST_P_CENTER_BIU		1164
+/********Name=SOFTRST_CON75,Offset=0xB2C********/
+#define SRST_LINKSYM_HDMITXPHY0		1201
+/********Name=SOFTRST_CON78,Offset=0xB38********/
+#define SRST_DP0_PIXELCLK		1249
+#define SRST_PHY_DP0_TX			1250
+#define SRST_DP1_PIXELCLK		1251
+#define SRST_DP2_PIXELCLK		1252
+/********Name=SOFTRST_CON79,Offset=0xB3C********/
+#define SRST_H_VEPU1_BIU		1265
+#define SRST_A_VEPU1_BIU		1266
+#define SRST_H_VEPU1			1267
+#define SRST_A_VEPU1			1268
+#define SRST_VEPU1_CORE			1269
+
+/********Name=PHPPHYSOFTRST_CON00,Offset=0x8A00********/
+#define SRST_P_PHPPHY_CRU		131073
+#define SRST_P_APB2ASB_SLV_CHIP_TOP	131075
+#define SRST_P_PCIE2_COMBOPHY0		131077
+#define SRST_P_PCIE2_COMBOPHY0_GRF	131078
+#define SRST_P_PCIE2_COMBOPHY1		131079
+#define SRST_P_PCIE2_COMBOPHY1_GRF	131080
+/********Name=PHPPHYSOFTRST_CON01,Offset=0x8A04********/
+#define SRST_PCIE0_PIPE_PHY		131093
+#define SRST_PCIE1_PIPE_PHY		131096
+
+/********Name=SECURENSSOFTRST_CON00,Offset=0x10A00********/
+#define SRST_H_CRYPTO_NS		262147
+#define SRST_H_TRNG_NS			262148
+#define SRST_P_OTPC_NS			262152
+#define SRST_OTPC_NS			262153
+
+/********Name=PMU1SOFTRST_CON00,Offset=0x20A00********/
+#define SRST_P_HDPTX_GRF		524288
+#define SRST_P_HDPTX_APB		524289
+#define SRST_P_MIPI_DCPHY		524290
+#define SRST_P_DCPHY_GRF		524291
+#define SRST_P_BOT0_APB2ASB		524292
+#define SRST_P_BOT1_APB2ASB		524293
+#define SRST_USB2DEBUG			524294
+#define SRST_P_CSIPHY_GRF		524295
+#define SRST_P_CSIPHY			524296
+#define SRST_P_USBPHY_GRF_0		524297
+#define SRST_P_USBPHY_GRF_1		524298
+#define SRST_P_USBDP_GRF		524299
+#define SRST_P_USBDPPHY			524300
+#define SRST_USBDP_COMBO_PHY_INIT 524303
+/********Name=PMU1SOFTRST_CON01,Offset=0x20A04********/
+#define SRST_USBDP_COMBO_PHY_CMN	524304
+#define SRST_USBDP_COMBO_PHY_LANE	524305
+#define SRST_USBDP_COMBO_PHY_PCS	524306
+#define SRST_M_MIPI_DCPHY		524307
+#define SRST_S_MIPI_DCPHY		524308
+#define SRST_SCAN_CSIPHY		524309
+#define SRST_P_VCCIO6_IOC		524310
+#define SRST_OTGPHY_0			524311
+#define SRST_OTGPHY_1			524312
+#define SRST_HDPTX_INIT			524313
+#define SRST_HDPTX_CMN			524314
+#define SRST_HDPTX_LANE			524315
+#define SRST_HDMITXHPD			524317
+/********Name=PMU1SOFTRST_CON02,Offset=0x20A08********/
+#define SRST_MPHY_INIT			524320
+#define SRST_P_MPHY_GRF			524321
+#define SRST_P_VCCIO7_IOC		524323
+/********Name=PMU1SOFTRST_CON03,Offset=0x20A0C********/
+#define SRST_H_PMU1_BIU			524345
+#define SRST_P_PMU1_NIU			524346
+#define SRST_H_PMU_CM0_BIU		524347
+#define SRST_PMU_CM0_CORE		524348
+#define SRST_PMU_CM0_JTAG		524349
+/********Name=PMU1SOFTRST_CON04,Offset=0x20A10********/
+#define SRST_P_CRU_PMU1			524353
+#define SRST_P_PMU1_GRF			524355
+#define SRST_P_PMU1_IOC			524356
+#define SRST_P_PMU1WDT			524357
+#define SRST_T_PMU1WDT			524358
+#define SRST_P_PMUTIMER			524359
+#define SRST_PMUTIMER0			524361
+#define SRST_PMUTIMER1			524362
+#define SRST_P_PMU1PWM			524363
+#define SRST_PMU1PWM			524364
+/********Name=PMU1SOFTRST_CON05,Offset=0x20A14********/
+#define SRST_P_I2C0			524369
+#define SRST_I2C0			524371
+#define SRST_S_UART1			525373
+#define SRST_P_UART1			525374
+#define SRST_PDM0			524381
+#define SRST_H_PDM0			524383
+/********Name=PMU1SOFTRST_CON06,Offset=0xA18********/
+#define SRST_M_PDM0			524384
+#define SRST_H_VAD			524385
+/********Name=PMU1SOFTRST_CON07,Offset=0x20A1C********/
+#define SRST_P_PMU0GRF			524404
+#define SRST_P_PMU0IOC			524405
+#define SRST_P_GPIO0			524406
+#define SRST_DB_GPIO0			524407
+
+#define SRST_NR_RSTS			(SRST_DB_GPIO0 + 1)
+
+void pvtplls_cpub_suspend(void);
+void pvtplls_cpub_resume(void);
+
+void pvtplls_suspend(void);
+void pvtplls_resume(void);
+
+void rockchip_clock_init(void);
+
+#endif
diff --git a/plat/st/common/common_rules.mk b/plat/st/common/common_rules.mk
index 690507e..88c1087 100644
--- a/plat/st/common/common_rules.mk
+++ b/plat/st/common/common_rules.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2023-2025, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -41,7 +41,7 @@
 
 # Create DTB file for BL2
 ${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | $$(@D)/
-	$(q)echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	$(q)echo '#include "$(patsubst %.dts,%$(SP_EXT).dts,$(patsubst fdts/%,%,$<))"' > $@
 	$(q)echo '#include "${BL2_DTSI}"' >> $@
 
 ${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 3d37738..e700823 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -105,8 +105,13 @@
 ifeq ($(AARCH32_SP),sp_min)
 BL32_DTSI		:=	stm32mp15-bl32.dtsi
 FDT_SOURCES		+=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dts,$(DTB_FILE_NAME)))
+ifneq (,$(wildcard $(patsubst %.dtb,fdts/%-sp_min.dts,$(DTB_FILE_NAME))))
+ifeq (,$(findstring -sp_min,$(DTB_FILE_NAME)))
+SP_EXT			:=	-sp_min
 endif
 endif
+endif
+endif
 
 # Macros and rules to build TF binary
 STM32_TF_STM32		:=	$(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME)))
@@ -258,7 +263,7 @@
 ifeq ($(AARCH32_SP),sp_min)
 # Create DTB file for BL32
 ${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | $$(@D)/
-	$(q)echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	$(q)echo '#include "$(patsubst %.dts,%$(SP_EXT).dts,$(patsubst fdts/%,%,$<))"' > $@
 	$(q)echo '#include "${BL32_DTSI}"' >> $@
 
 ${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts | $$(@D)/
diff --git a/plat/st/stm32mp2/include/platform_def.h b/plat/st/stm32mp2/include/platform_def.h
index e720c02..523f9bb 100644
--- a/plat/st/stm32mp2/include/platform_def.h
+++ b/plat/st/stm32mp2/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2025, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -73,8 +73,15 @@
 /*******************************************************************************
  * BL31 specific defines.
  ******************************************************************************/
+#if ENABLE_PIE
 #define BL31_BASE			0
-#define BL31_LIMIT			(STM32MP_SEC_SYSRAM_SIZE / 2)
+#else
+#define BL31_BASE			STM32MP_SYSRAM_BASE
+#endif
+
+#define BL31_LIMIT			(BL31_BASE + (STM32MP_SYSRAM_SIZE / 2))
+
+#define BL31_PROGBITS_LIMIT		(BL31_BASE + STM32MP_BL31_SIZE)
 
 /*******************************************************************************
  * BL33 specific defines.
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index a9f8d8f..d5e2785 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2023-2025, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -11,9 +11,12 @@
 include plat/st/common/common.mk
 
 CRASH_REPORTING			:=	1
-ENABLE_PIE			:=	1
+# Disable PIE by default. To re-enable it, uncomment next line.
+#ENABLE_PIE			:=	1
 PROGRAMMABLE_RESET_ADDRESS	:=	1
+ifeq ($(ENABLE_PIE),1)
 BL2_IN_XIP_MEM			:=	1
+endif
 
 STM32MP_BL33_EL1		?=	1
 ifeq ($(STM32MP_BL33_EL1),1)
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index b441502..3e60cad 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2025, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -76,8 +76,6 @@
 #define RETRAM_BASE				U(0x0E080000)
 #define RETRAM_SIZE				U(0x00020000)
 
-#define STM32MP_SEC_SYSRAM_SIZE			STM32MP_SYSRAM_SIZE
-
 /* DDR configuration */
 #define STM32MP_DDR_BASE			U(0x80000000)
 #define STM32MP_DDR_MAX_SIZE			UL(0x100000000)	/* Max 4GB */
@@ -113,11 +111,9 @@
 #define STM32MP_BL2_SIZE			U(0x00029000) /* 164 KB for BL2 */
 
 /* Allocate remaining sysram to BL31 Binary only */
-#define STM32MP_BL31_SIZE			(STM32MP_SEC_SYSRAM_SIZE - \
+#define STM32MP_BL31_SIZE			(STM32MP_SYSRAM_SIZE - \
 						 STM32MP_BL2_SIZE)
 
-#define BL31_PROGBITS_LIMIT			STM32MP_BL31_SIZE
-
 #define STM32MP_BL2_BASE			(STM32MP_SYSRAM_BASE + \
 						 STM32MP_SYSRAM_SIZE - \
 						 STM32MP_BL2_SIZE)
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
index 37f2a2f..117934f 100644
--- a/services/std_svc/drtm/drtm_main.c
+++ b/services/std_svc/drtm/drtm_main.c
@@ -104,12 +104,16 @@
 	dlme_data_hdr_init.dlme_addr_map_size = drtm_get_address_map_size();
 	dlme_data_hdr_init.dlme_tcb_hashes_table_size =
 				plat_drtm_get_tcb_hash_table_size();
+	dlme_data_hdr_init.dlme_acpi_tables_region_size =
+				plat_drtm_get_acpi_tables_region_size();
 	dlme_data_hdr_init.dlme_impdef_region_size =
 				plat_drtm_get_imp_def_dlme_region_size();
 
-	dlme_data_min_size += dlme_data_hdr_init.dlme_addr_map_size +
+	dlme_data_min_size += sizeof(struct_dlme_data_header) +
+			      dlme_data_hdr_init.dlme_addr_map_size +
 			      ARM_DRTM_MIN_EVENT_LOG_SIZE +
 			      dlme_data_hdr_init.dlme_tcb_hashes_table_size +
+			      dlme_data_hdr_init.dlme_acpi_tables_region_size +
 			      dlme_data_hdr_init.dlme_impdef_region_size;
 
 	/* Fill out platform DRTM features structure */
@@ -130,6 +134,8 @@
 		plat_dma_prot_feat->dma_protection_support);
 	ARM_DRTM_TCB_HASH_FEATURES_SET_MAX_NUM_HASHES(plat_drtm_features.tcb_hash_features,
 		plat_drtm_get_tcb_hash_features());
+	ARM_DRTM_DLME_IMG_AUTH_SUPPORT(plat_drtm_features.dlme_image_auth_features,
+		plat_drtm_get_dlme_img_auth_features());
 
 	return 0;
 }
@@ -171,6 +177,12 @@
 		 plat_drtm_features.tcb_hash_features);
 }
 
+static inline uint64_t drtm_features_dlme_img_auth_features(void *ctx)
+{
+	SMC_RET2(ctx, 1ULL, /* DLME Image auth is supported */
+		 plat_drtm_features.dlme_image_auth_features);
+}
+
 static enum drtm_retc drtm_dl_check_caller_el(void *ctx)
 {
 	uint64_t spsr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3);
@@ -785,6 +797,12 @@
 				return drtm_features_tcb_hashes(handle);
 				break;	/* not reached */
 
+			case ARM_DRTM_FEATURES_DLME_IMG_AUTH:
+				INFO("++ DRTM service handler: "
+				     "DLME Image authentication features\n");
+				return drtm_features_dlme_img_auth_features(handle);
+				break;	/* not reached */
+
 			default:
 				ERROR("Unknown ARM DRTM service feature\n");
 				SMC_RET1(handle, NOT_SUPPORTED);
diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h
index c105b56..44d0d2d 100644
--- a/services/std_svc/drtm/drtm_main.h
+++ b/services/std_svc/drtm/drtm_main.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -45,7 +45,7 @@
  * Range(Min/Max) of DRTM parameter structure versions supported
  */
 #define ARM_DRTM_PARAMS_MIN_VERSION	U(1)
-#define ARM_DRTM_PARAMS_MAX_VERSION	U(1)
+#define ARM_DRTM_PARAMS_MAX_VERSION	U(2)
 
 enum drtm_dlme_el {
 	DLME_AT_EL1 = MODE_EL1,
@@ -74,6 +74,7 @@
 	uint64_t dma_prot_features;
 	uint64_t boot_pe_id;
 	uint64_t tcb_hash_features;
+	uint64_t dlme_image_auth_features;
 } drtm_features_t;
 
 struct __packed drtm_dl_args_v1 {
diff --git a/services/std_svc/drtm/drtm_measurements.c b/services/std_svc/drtm/drtm_measurements.c
index 8d514b7..d4f2b57 100644
--- a/services/std_svc/drtm/drtm_measurements.c
+++ b/services/std_svc/drtm/drtm_measurements.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -198,6 +198,10 @@
 					       PCR_18);
 	CHECK_RC(rc,
 		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR));
+
+	/* Measure no Action event but not extend it in PCR */
+	CHECK_RC(rc,
+		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_NO_ACTION));
 	/*
 	 * If the DCE is unable to log a measurement because there is no available
 	 * space in the event log region, the DCE must extend a hash of the value
diff --git a/services/std_svc/drtm/drtm_measurements.h b/services/std_svc/drtm/drtm_measurements.h
index 6d7a84e..f5a8c7c 100644
--- a/services/std_svc/drtm/drtm_measurements.h
+++ b/services/std_svc/drtm/drtm_measurements.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -25,6 +25,9 @@
 #define DRTM_EVENT_ARM_DCE_SECONDARY	DRTM_EVENT_TYPE(8)
 #define DRTM_EVENT_ARM_TZFW		DRTM_EVENT_TYPE(9)
 #define DRTM_EVENT_ARM_SEPARATOR	DRTM_EVENT_TYPE(10)
+#define DRTM_EVENT_ARM_DLME_PUBKEY	DRTM_EVENT_TYPE(11)
+#define DRTM_EVENT_ARM_DLME_SVN		DRTM_EVENT_TYPE(12)
+#define DRTM_EVENT_ARM_NO_ACTION	DRTM_EVENT_TYPE(13)
 
 #define CHECK_RC(rc, func_call) { \
 	if (rc != 0) { \